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