1 /* $NetBSD: chrpicontoppm.c,v 1.4 2008/04/28 20:23:33 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lonhyn T. Jasinskyj. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * chrpicontoppm.c - read a CHRP style boot icon file and convert 34 * it to a PPM. 35 */ 36 37 /* 38 * Usage: 39 * 40 * chrpicontoppm [chrpiconfile] 41 * 42 * This programs reads from either a single file given as an argument 43 * or from stdin if no args are given. It expects a true color 44 * PPM file as the input. The image should be 64x64, otherwise it 45 * is cropped to that size. 46 * 47 * It then produces a CHRP style boot icon file on stdout. 48 */ 49 50 #include <sys/cdefs.h> 51 __RCSID("$NetBSD: chrpicontoppm.c,v 1.4 2008/04/28 20:23:33 martin Exp $"); 52 53 #include <stdlib.h> 54 55 #include <pbm.h> 56 #include <ppm.h> 57 58 #include "chrpicon.h" 59 60 61 int 62 main(int argc, char *argv[]) 63 { 64 FILE *ifp; 65 CHRPI_spec_rec img_rec; 66 CHRPI_spec img = &img_rec; 67 pixel *pixelrow; 68 pixel *pP; 69 chrpi_pixel *imgP; 70 int row, col; 71 pixval maxval = 255; 72 73 74 ppm_init(&argc, argv); 75 76 if (argc > 2) 77 pm_usage("[chrpiconfile]"); 78 79 /* either use stdin or open a file */ 80 if (argc > 1) { 81 if ((ifp = fopen(argv[1], "r")) == NULL) { 82 perror("ppmfile open"); 83 exit(1); 84 } 85 } 86 else 87 ifp = stdin; 88 89 if (CHRPI_getheader(ifp, img)) 90 pm_error("can't find <ICON...> header in boot icon file"); 91 92 if (CHRPI_getbitmap(ifp, img)) 93 pm_error("can't read <BITMAP...> section in boot icon file"); 94 95 if (img->rbits != 3 || img->gbits != 3 || img->bbits != 2) 96 pm_error("can only handle RGB 3:3:2 colorspace icon files"); 97 98 ppm_writeppminit(stdout, img->width, img->height, maxval, PLAIN_PPM); 99 pixelrow = ppm_allocrow(img->width); 100 101 for (row = 0; row < img->height; row++) { 102 103 pixval r, g, b; 104 105 pP = pixelrow; 106 imgP = img->pixels[row]; 107 108 for (col = 0; col < img->width; col++) { 109 110 r = ((*imgP >> 5) & 7); 111 g = ((*imgP >> 2) & 7); 112 b = (*imgP & 3); 113 114 r = (r << 5) | (r << 2) | (r >> 1); 115 g = (g << 5) | (g << 2) | (g >> 1); 116 b = (b << 6) | (b << 4) | (b >> 4) | b; 117 118 PPM_ASSIGN(*pP, r, g, b); 119 120 pP++; 121 imgP++; 122 } 123 124 ppm_writeppmrow(stdout, pixelrow, img->width, maxval, PLAIN_PPM); 125 } 126 127 ppm_freerow(pixelrow); 128 129 pm_close(ifp); 130 pm_close(stdout); 131 exit(0); 132 } 133 134 135 chrpi_pixel * 136 CHRPI_allocrow(int cols) 137 { 138 return calloc(cols, sizeof(chrpi_pixel)); 139 } 140 141 int 142 CHRPI_getheader(FILE *fp, CHRPI_spec img) 143 { 144 char line[MAX_LINE_LENGTH + 1]; 145 146 while (fgets(line, MAX_LINE_LENGTH, fp)) { 147 if (strstr(line, ICON_TAG)) { 148 /* found the ICON identifier, primitively parse it */ 149 if (sscanf(line, " %*s SIZE=%d,%d COLOR-SPACE=%d,%d,%d", 150 &img->height, &img->width, 151 &img->rbits, &img->gbits, &img->bbits 152 ) != 5) 153 return -1; 154 155 return 0; 156 } 157 } 158 159 return -1; 160 } 161 162 163 int 164 CHRPI_getbitmap(FILE *fp, CHRPI_spec img) 165 { 166 char line[MAX_LINE_LENGTH + 1]; 167 int foundtag = 0; 168 char hexstr[3] = { 0, 0, 0 }; 169 char *p; 170 int r, c; 171 172 173 /* first find the BITMAP tag */ 174 while (fgets(line, MAX_LINE_LENGTH, fp)) { 175 if (strncmp(line, BITMAP_TAG, strlen(BITMAP_TAG)) == 0) { 176 foundtag++; 177 break; 178 } 179 } 180 181 if (!foundtag) 182 return -1; 183 184 if ((img->pixels = calloc(img->height, sizeof(chrpi_pixel *))) == NULL) 185 return -1; 186 187 for (r = 0; r < img->height; r++) 188 if ((img->pixels[r] = CHRPI_allocrow(img->width)) == NULL) 189 return -1; 190 191 for (r = 0; r < img->height; r++) { 192 193 /* get a row */ 194 if ((p = fgets(line, MAX_LINE_LENGTH, fp)) == NULL) { 195 return -1; 196 } 197 198 /* go down the pixels and convert them */ 199 for (c = 0; c < img->width; c++) { 200 hexstr[0] = *p++; 201 hexstr[1] = *p++; 202 203 img->pixels[r][c] = (chrpi_pixel)(strtoul(hexstr, NULL, 16)); 204 } 205 } 206 207 return 0; 208 } 209