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