1 /* leaftoppm.c - read an ileaf img file and write a PPM
2 *
3 * Copyright (C) 1994 by Bill O'Donnell.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation for any purpose and without fee is hereby granted, provided
7 * that the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation. This software is provided "as is" without express or
10 * implied warranty.
11 *
12 * known problems: doesn't do compressed ileaf images.
13 *
14 */
15
16 #include <stdio.h>
17 #include "ppm.h"
18
19 #define MAXCOLORS 256
20 #define LEAF_MAXVAL 255
21
22 static void
leaf_init(FILE * const fp,int * const colsP,int * const rowsP,int * const depthP,int * const ncolorsP,pixel * const colors)23 leaf_init(FILE * const fp,
24 int * const colsP,
25 int * const rowsP,
26 int * const depthP,
27 int * const ncolorsP,
28 pixel * const colors) {
29
30 unsigned char buf[256];
31 unsigned char compressed;
32 short version;
33 short cols;
34 short rows;
35 short depth;
36 long magic;
37
38 pm_readbiglong(fp, &magic);
39 if ((uint32_t)magic != 0x894f5053)
40 pm_error("Bad magic number. First 4 bytes should be "
41 "0x894f5053 but are instead 0x%08x", (unsigned)magic);
42
43 /* version = 2 bytes
44 hres = 2
45 vres = 2
46 unique id = 4
47 offset x = 2
48 offset y = 2
49 TOTAL = 14 bytes
50 */
51
52 pm_readbigshort(fp, &version);
53
54 if (fread(buf, 1, 12, fp) != 12)
55 pm_error("bad header, short file?");
56
57 pm_readbigshort(fp, &cols);
58 *colsP = cols;
59 pm_readbigshort(fp, &rows);
60 *rowsP = rows;
61 pm_readbigshort(fp, &depth);
62 *depthP = depth;
63
64 if ((compressed = fgetc(fp)) != 0)
65 pm_error("Can't do compressed images.");
66
67 if ((*depthP == 1) && (version < 4)) {
68 fgetc(fp);
69 *ncolorsP = 0;
70 } else if ((*depthP == 8) && (version < 4)) {
71 fgetc(fp);
72 *ncolorsP = 0;
73 } else {
74 long format;
75 pm_readbiglong(fp, &format);
76 if (format == 0x29000000) {
77 /* color image */
78 short ncolors;
79 pm_readbigshort(fp, &ncolors);
80
81 if (ncolors > 0) {
82 /* 8-bit image */
83 unsigned int i;
84
85 if (ncolors > 256)
86 pm_error("Can't have > 256 colors in colormap.");
87 /* read colormap */
88 for (i=0; i < 256; ++i)
89 PPM_PUTR(colors[i], fgetc(fp));
90 for (i=0; i < 256; ++i)
91 PPM_PUTG(colors[i], fgetc(fp));
92 for (i=0; i < 256; ++i)
93 PPM_PUTB(colors[i], fgetc(fp));
94 *ncolorsP = ncolors;
95 } else {
96 /* 24-bit image */
97 *ncolorsP = 0;
98 }
99 } else if (*depthP ==1) {
100 /* mono image */
101 short dummy;
102 pm_readbigshort(fp, &dummy); /* must toss cmap size */
103 *ncolorsP = 0;
104 } else {
105 /* gray image */
106 short dummy;
107 pm_readbigshort(fp, &dummy); /* must toss cmap size */
108 *ncolorsP = 0;
109 }
110 }
111 }
112
113
114
115 int
main(int argc,char * argv[])116 main(int argc, char * argv[]) {
117
118 pixval const maxval = LEAF_MAXVAL;
119
120 FILE *ifd;
121 pixel colormap[MAXCOLORS];
122 int rows, cols, row, col, depth, ncolors;
123
124
125 ppm_init(&argc, argv);
126
127 if (argc-1 > 1)
128 pm_error("Too many arguments. Only argument is ileaf file name");
129
130 if (argc-1 == 1)
131 ifd = pm_openr(argv[1]);
132 else
133 ifd = stdin;
134
135 leaf_init(ifd, &cols, &rows, &depth, &ncolors, colormap);
136
137 if ((depth == 8) && (ncolors == 0)) {
138 /* gray image */
139 gray * grayrow;
140 unsigned int row;
141 pgm_writepgminit( stdout, cols, rows, maxval, 0 );
142 grayrow = pgm_allocrow(cols);
143 for (row = 0; row < rows; ++row) {
144 unsigned int col;
145 for ( col = 0; col < cols; ++col)
146 grayrow[col] = (gray)fgetc(ifd);
147 if (cols % 2)
148 fgetc (ifd); /* padding */
149 pgm_writepgmrow(stdout, grayrow, cols, maxval, 0);
150 }
151 pgm_freerow(grayrow);
152 } else if (depth == 24) {
153 pixel * pixrow;
154 unsigned int row;
155 ppm_writeppminit(stdout, cols, rows, maxval, 0);
156 pixrow = ppm_allocrow(cols);
157 /* true color */
158 for (row = 0; row < rows; ++row) {
159 for (col = 0; col < cols; ++col)
160 PPM_PUTR(pixrow[col], fgetc(ifd));
161 if (cols % 2)
162 fgetc (ifd); /* padding */
163 for (col = 0; col < cols; ++col)
164 PPM_PUTG(pixrow[col], fgetc(ifd));
165 if (cols % 2)
166 fgetc (ifd); /* padding */
167 for (col = 0; col < cols; ++col)
168 PPM_PUTB(pixrow[col], fgetc(ifd));
169 if (cols % 2)
170 fgetc (ifd); /* padding */
171 ppm_writeppmrow(stdout, pixrow, cols, maxval, 0);
172 }
173 ppm_freerow(pixrow);
174 } else if (depth == 8) {
175 /* 8-bit (color mapped) image */
176 pixel * pixrow;
177
178 ppm_writeppminit(stdout, cols, rows, (pixval) maxval, 0);
179 pixrow = ppm_allocrow( cols );
180
181 for (row = 0; row < rows; ++row) {
182 for (col = 0; col < cols; ++col)
183 pixrow[col] = colormap[fgetc(ifd)];
184 if (cols %2)
185 fgetc(ifd); /* padding */
186 ppm_writeppmrow(stdout, pixrow, cols, maxval, 0);
187 }
188 ppm_freerow(pixrow);
189 } else if (depth == 1) {
190 /* mono image */
191 bit *bitrow;
192 unsigned int row;
193
194 pbm_writepbminit(stdout, cols, rows, 0);
195 bitrow = pbm_allocrow(cols);
196
197 for (row = 0; row < rows; ++row) {
198 unsigned char bits;
199 bits = 0x00; /* initial value */
200 for (col = 0; col < cols; ++col) {
201 int const shift = col % 8;
202 if (shift == 0)
203 bits = (unsigned char) fgetc(ifd);
204 bitrow[col] = (bits & (unsigned char)(0x01 << (7 - shift))) ?
205 PBM_WHITE : PBM_BLACK;
206 }
207 if ((cols % 16) && (cols % 16) <= 8)
208 fgetc(ifd); /* 16 bit pad */
209 pbm_writepbmrow(stdout, bitrow, cols, 0);
210 }
211 pbm_freerow(bitrow);
212 }
213 pm_close(ifd);
214
215 return 0;
216 }
217