1 /* $NetBSD: chrpicontoppm.c,v 1.1.1.1 1999/11/19 00:43:20 lonhyn 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 <stdlib.h> 58 59 #include <pbm.h> 60 #include <ppm.h> 61 62 #include "chrpicon.h" 63 64 65 int 66 main(int argc, char *argv[]) 67 { 68 FILE *ifp; 69 CHRPI_spec_rec img_rec; 70 CHRPI_spec img = &img_rec; 71 pixel *pixelrow; 72 pixel *pP; 73 chrpi_pixel *imgP; 74 int row, col; 75 pixval maxval = 255; 76 77 78 ppm_init(&argc, argv); 79 80 if (argc > 2) 81 pm_usage("[chrpiconfile]"); 82 83 /* either use stdin or open a file */ 84 if (argc > 1) { 85 if ((ifp = fopen(argv[1], "r")) == NULL) { 86 perror("ppmfile open"); 87 exit(1); 88 } 89 } 90 else 91 ifp = stdin; 92 93 if (CHRPI_getheader(ifp, img)) 94 pm_error("can't find <ICON...> header in boot icon file"); 95 96 if (CHRPI_getbitmap(ifp, img)) 97 pm_error("can't read <BITMAP...> section in boot icon file"); 98 99 if (img->rbits != 3 || img->gbits != 3 || img->bbits != 2) 100 pm_error("can only handle RGB 3:3:2 colorspace icon files"); 101 102 ppm_writeppminit(stdout, img->width, img->height, maxval, PLAIN_PPM); 103 pixelrow = ppm_allocrow(img->width); 104 105 for (row = 0; row < img->height; row++) { 106 107 pixval r, g, b; 108 109 pP = pixelrow; 110 imgP = img->pixels[row]; 111 112 for (col = 0; col < img->width; col++) { 113 114 r = ((*imgP >> 5) & 7); 115 g = ((*imgP >> 2) & 7); 116 b = (*imgP & 3); 117 118 r = (r << 5) | (r << 2) | (r >> 1); 119 g = (g << 5) | (g << 2) | (g >> 1); 120 b = (b << 6) | (b << 4) | (b >> 4) | b; 121 122 PPM_ASSIGN(*pP, r, g, b); 123 124 pP++; 125 imgP++; 126 } 127 128 ppm_writeppmrow(stdout, pixelrow, img->width, maxval, PLAIN_PPM); 129 } 130 131 ppm_freerow(pixelrow); 132 133 pm_close(ifp); 134 pm_close(stdout); 135 exit(0); 136 } 137 138 139 chrpi_pixel * 140 CHRPI_allocrow(int cols) 141 { 142 return calloc(cols, sizeof(chrpi_pixel)); 143 } 144 145 int 146 CHRPI_getheader(FILE *fp, CHRPI_spec img) 147 { 148 char line[MAX_LINE_LENGTH + 1]; 149 150 while (fgets(line, MAX_LINE_LENGTH, fp)) { 151 if (strstr(line, ICON_TAG)) { 152 /* found the ICON identifier, primitively parse it */ 153 if (sscanf(line, " %*s SIZE=%d,%d COLOR-SPACE=%d,%d,%d", 154 &img->height, &img->width, 155 &img->rbits, &img->gbits, &img->bbits 156 ) != 5) 157 return -1; 158 159 return 0; 160 } 161 } 162 163 return -1; 164 } 165 166 167 int 168 CHRPI_getbitmap(FILE *fp, CHRPI_spec img) 169 { 170 char line[MAX_LINE_LENGTH + 1]; 171 int foundtag = 0; 172 char hexstr[3] = { 0, 0, 0 }; 173 char *p; 174 int r, c; 175 176 177 /* first find the BITMAP tag */ 178 while (fgets(line, MAX_LINE_LENGTH, fp)) { 179 if (strncmp(line, BITMAP_TAG, strlen(BITMAP_TAG)) == 0) { 180 foundtag++; 181 break; 182 } 183 } 184 185 if (!foundtag) 186 return -1; 187 188 if ((img->pixels = calloc(img->height, sizeof(chrpi_pixel *))) == NULL) 189 return -1; 190 191 for (r = 0; r < img->height; r++) 192 if ((img->pixels[r] = CHRPI_allocrow(img->width)) == NULL) 193 return -1; 194 195 for (r = 0; r < img->height; r++) { 196 197 /* get a row */ 198 if ((p = fgets(line, MAX_LINE_LENGTH, fp)) == NULL) { 199 return -1; 200 } 201 202 /* go down the pixels and convert them */ 203 for (c = 0; c < img->width; c++) { 204 hexstr[0] = *p++; 205 hexstr[1] = *p++; 206 207 img->pixels[r][c] = (chrpi_pixel)(strtoul(hexstr, NULL, 16)); 208 } 209 } 210 211 return 0; 212 } 213