The main function.
50 {
51
52
53
54
55 char file_format[3];
56 unsigned filesize;
57 unsigned char rsvd_hdr[4];
58 unsigned image_start;
59
60
61
62
63
64
65
66
67
68 int dib_length;
69 int image_width = 0;
70 int image_height = 0;
71 int num_planes = 0;
72 int bits_per_pixel = 0;
73
74
75
76
77 int compression_method=0;
78 int image_size = 0;
79 int hres = 0;
80 int vres = 0;
81 int num_colors = 0;
82 int important_colors = 0;
83
84 int true_colors = 0;
85
86
87
88
89
90 unsigned char color_map[2][4];
91
92
93
94
95
96 unsigned image_bytes[544*72];
97
98
99
100
101 int verbose = 0;
102 unsigned image_xor = 0x00;
103
104
105
106
107 int i, j, k;
108
109
111 "BI_RGB",
112 "BI_RLE8",
113 "BI_RLE4",
114 "BI_BITFIELDS",
115 "BI_JPEG",
116 "BI_PNG",
117 "BI_ALPHABITFIELDS",
118 "", "", "", "",
119 "BI_CMYK",
120 "BI_CMYKRLE8",
121 "BI_CMYKRLE4",
122 };
123
124
125 unsigned standard_header [62] = {
126 0x42, 0x4d, 0x3e, 0x99, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x28, 0x00,
128 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x20, 0x02,
129 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0xc4, 0x0e,
131 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0xff, 0xff, 0xff, 0x00
134 };
135
138
139 char *infile="", *outfile="";
140 FILE *infp, *outfp;
141
142
143
144
145 if (argc > 1) {
146 for (i = 1; i < argc; i++) {
147 if (argv[i][0] == '-') {
148 switch (argv[i][1]) {
149 case 'i':
150 infile = &argv[i][2];
151 break;
152 case 'o':
153 outfile = &argv[i][2];
154 break;
155 case 'v':
156 verbose = 1;
157 break;
158 case 'V':
159 fprintf (stderr,
"unibmpbump version %s\n\n",
VERSION);
160 exit (EXIT_SUCCESS);
161 break;
162 case '-':
163 if (strcmp (argv[i], "--verbose") == 0) {
164 verbose = 1;
165 }
166 else if (strcmp (argv[i], "--version") == 0) {
167 fprintf (stderr,
"unibmpbump version %s\n\n",
VERSION);
168 exit (EXIT_SUCCESS);
169 }
170 break;
171 default:
172 fprintf (stderr, "\nSyntax:\n\n");
173 fprintf (stderr, " unibmpbump ");
174 fprintf (stderr, "-i<Input_File> -o<Output_File>\n\n");
175 fprintf (stderr, "-v or --verbose gives verbose output");
176 fprintf (stderr, " on stderr\n\n");
177 fprintf (stderr, "-V or --version prints version");
178 fprintf (stderr, " on stderr and exits\n\n");
179 fprintf (stderr, "\nExample:\n\n");
180 fprintf (stderr, " unibmpbump -iuni0101.bmp");
181 fprintf (stderr, " -onew-uni0101.bmp\n\n");
182 exit (EXIT_SUCCESS);
183 }
184 }
185 }
186 }
187
188
189
190
191
192 if (strlen (infile) > 0) {
193 if ((infp = fopen (infile, "r")) == NULL) {
194 fprintf (stderr, "Error: can't open %s for input.\n", infile);
195 exit (EXIT_FAILURE);
196 }
197 }
198 else {
199 infp = stdin;
200 }
201 if (strlen (outfile) > 0) {
202 if ((outfp = fopen (outfile, "w")) == NULL) {
203 fprintf (stderr, "Error: can't open %s for output.\n", outfile);
204 exit (EXIT_FAILURE);
205 }
206 }
207 else {
208 outfp = stdout;
209 }
210
211
212
215 file_format[2] = '\0';
216
217
219
220
225
226
228
229
230
231
232
233 if (strncmp (file_format, "BM", 2) != 0) {
234 fprintf (stderr, "\nInvalid file format: not file type \"BM\".\n\n");
235 exit (EXIT_FAILURE);
236 }
237
238 if (verbose) {
239 fprintf (stderr, "\nFile Header:\n");
240 fprintf (stderr, " File Type: \"%s\"\n", file_format);
241 fprintf (stderr, " File Size: %d bytes\n", filesize);
242 fprintf (stderr, " Reserved: ");
243 for (i = 0; i < 4; i++) fprintf (stderr, " 0x%02X", rsvd_hdr[i]);
244 fputc ('\n', stderr);
245 fprintf (stderr, " Image Start: %d. = 0x%02X = 0%05o\n\n",
246 image_start, image_start, image_start);
247 }
248
249
250
251
252
254
255
256
257
258
259
260
261
262
263
264
265 if (dib_length == 12) {
270 }
271 else if (dib_length >= 40) {
276 compression_method =
get_bytes (infp, 4);
282
283
284 if (num_colors == 0)
285 true_colors = 1 << bits_per_pixel;
286 else
287 true_colors = num_colors;
288
289
290
291
292
293
294
295 for (i = 40; i < dib_length; i++) (
void)
get_bytes (infp, 1);
296 }
297
298 if (verbose) {
299 fprintf (stderr, "Device Independent Bitmap (DIB) Header:\n");
300 fprintf (stderr, " DIB Length: %9d bytes (version = ", dib_length);
301
302 if (dib_length == 12) fprintf (stderr, "\"BITMAPCOREHEADER\")\n");
303 else if (dib_length == 40) fprintf (stderr, "\"BITMAPINFOHEADER\")\n");
304 else if (dib_length == 108) fprintf (stderr, "\"BITMAPV4HEADER\")\n");
305 else if (dib_length == 124) fprintf (stderr, "\"BITMAPV5HEADER\")\n");
306 else fprintf (stderr, "unknown)");
307 fprintf (stderr, " Bitmap Width: %6d pixels\n", image_width);
308 fprintf (stderr, " Bitmap Height: %6d pixels\n", image_height);
309 fprintf (stderr, " Color Planes: %6d\n", num_planes);
310 fprintf (stderr, " Bits per Pixel: %6d\n", bits_per_pixel);
311 fprintf (stderr, " Compression Method: %2d --> ", compression_method);
313 fprintf (stderr, "%s", compression_type [compression_method]);
314 }
315
316
317
318
319
320 if (compression_method == 0 || compression_method == 11) {
321 fprintf (stderr, " (no compression)");
322 }
323 else {
324 fprintf (stderr, "Image uses compression; this is unsupported.\n\n");
325 exit (EXIT_FAILURE);
326 }
327 fprintf (stderr, "\n");
328 fprintf (stderr, " Image Size: %5d bytes\n", image_size);
329 fprintf (stderr, " Horizontal Resolution: %5d pixels/meter\n", hres);
330 fprintf (stderr, " Vertical Resolution: %5d pixels/meter\n", vres);
331 fprintf (stderr, " Number of Colors: %5d", num_colors);
332 if (num_colors != true_colors) {
333 fprintf (stderr, " --> %d", true_colors);
334 }
335 fputc ('\n', stderr);
336 fprintf (stderr, " Important Colors: %5d", important_colors);
337 if (important_colors == 0)
338 fprintf (stderr, " (all colors are important)");
339 fprintf (stderr, "\n\n");
340 }
341
342
343
344
345 if (bits_per_pixel <= 8) {
346 for (i = 0; i < 2; i++) {
351 }
352
353 while (i < true_colors) {
355 i++;
356 }
357
358 if (color_map [0][0] >= 128) image_xor = 0xFF;
359 }
360
361 if (verbose) {
362 fprintf (stderr, "Color Palette [R, G, B, %s] Values:\n",
363 (dib_length <= 40) ? "reserved" : "Alpha");
364 for (i = 0; i < 2; i++) {
365 fprintf (stderr, "%7d: [", i);
366 fprintf (stderr, "%3d,", color_map [i][0] & 0xFF);
367 fprintf (stderr, "%3d,", color_map [i][1] & 0xFF);
368 fprintf (stderr, "%3d,", color_map [i][2] & 0xFF);
369 fprintf (stderr, "%3d]\n", color_map [i][3] & 0xFF);
370 }
371 if (image_xor == 0xFF) fprintf (stderr, "Will Invert Colors.\n");
372 fputc ('\n', stderr);
373
374 }
375
376
377
378
379
380 if (image_width != 560 && image_width != 576) {
381 fprintf (stderr, "\nUnsupported image width: %d\n", image_width);
382 fprintf (stderr, "Width should be 560 or 576 pixels.\n\n");
383 exit (EXIT_FAILURE);
384 }
385
386 if (image_height != 544) {
387 fprintf (stderr, "\nUnsupported image height: %d\n", image_height);
388 fprintf (stderr, "Height should be 544 pixels.\n\n");
389 exit (EXIT_FAILURE);
390 }
391
392 if (num_planes != 1) {
393 fprintf (stderr, "\nUnsupported number of planes: %d\n", num_planes);
394 fprintf (stderr, "Number of planes should be 1.\n\n");
395 exit (EXIT_FAILURE);
396 }
397
398 if (bits_per_pixel != 1) {
399 fprintf (stderr, "\nUnsupported number of bits per pixel: %d\n",
400 bits_per_pixel);
401 fprintf (stderr, "Bits per pixel should be 1.\n\n");
402 exit (EXIT_FAILURE);
403 }
404
405 if (compression_method != 0 && compression_method != 11) {
406 fprintf (stderr, "\nUnsupported compression method: %d\n",
407 compression_method);
408 fprintf (stderr, "Compression method should be 1 or 11.\n\n");
409 exit (EXIT_FAILURE);
410 }
411
412 if (true_colors != 2) {
413 fprintf (stderr, "\nUnsupported number of colors: %d\n", true_colors);
414 fprintf (stderr, "Number of colors should be 2.\n\n");
415 exit (EXIT_FAILURE);
416 }
417
418
419
420
421
422
423 for (i = 0; i < 62; i++) fputc (standard_header[i], outfp);
424
425
426
427
428
429
430 k = 0;
431 for (i = 0; i < 544; i++) {
432
433
434
435
436 if (image_width == 560) {
437 image_bytes[k++] = 0xFF;
438 image_bytes[k++] = 0xFF;
439 }
440 for (j = 0; j < 70; j++) {
441 image_bytes[k++] = (
get_bytes (infp, 1) & 0xFF) ^ image_xor;
442 }
443
444
445
446
447
448 if (image_width == 560) {
450 }
451 else {
452 image_bytes[k++] = (
get_bytes (infp, 1) & 0xFF) ^ image_xor;
453 image_bytes[k++] = (
get_bytes (infp, 1) & 0xFF) ^ image_xor;
454 }
455 }
456
457
458
459
460
461 if (image_width == 560) {
463 }
464
465 for (i = 0; i < 544 * 576 / 8; i++) {
466 fputc (image_bytes[i], outfp);
467 }
468
469
470
471
472
473 fclose (infp);
474 fclose (outfp);
475
476 exit (EXIT_SUCCESS);
477}
#define VERSION
Version of this program.
void regrid(unsigned *image_bytes)
After reading in the image, shift it.
#define MAX_COMPRESSION_METHOD
Maximum supported compression method.
unsigned get_bytes(FILE *infp, int nbytes)
Get from 1 to 4 bytes, inclusive, from input file.