1 /*
2 * BMP image routines for CUPS.
3 *
4 * Copyright 2007-2011 by Apple Inc.
5 * Copyright 1993-2007 by Easy Software Products.
6 *
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law. Distribution and use rights are outlined in the file "COPYING"
10 * which should have been included with this file.
11 *
12 * Contents:
13 *
14 * _cupsImageReadBMP() - Read a BMP image file.
15 * read_word() - Read a 16-bit unsigned integer.
16 * read_dword() - Read a 32-bit unsigned integer.
17 * read_long() - Read a 32-bit signed integer.
18 */
19
20 /*
21 * Include necessary headers...
22 */
23
24 #include "image-private.h"
25
26
27 /*
28 * Constants for the bitmap compression...
29 */
30
31 # define BI_RGB 0 /* No compression - straight BGR data */
32 # define BI_RLE8 1 /* 8-bit run-length compression */
33 # define BI_RLE4 2 /* 4-bit run-length compression */
34 # define BI_BITFIELDS 3 /* RGB bitmap with RGB masks */
35
36
37 /*
38 * Local functions...
39 */
40
41 static unsigned short read_word(FILE *fp);
42 static unsigned int read_dword(FILE *fp);
43 static int read_long(FILE *fp);
44
45
46 /*
47 * '_cupsImageReadBMP()' - Read a BMP image file.
48 */
49
50 int /* O - Read status */
_cupsImageReadBMP(cups_image_t * img,FILE * fp,cups_icspace_t primary,cups_icspace_t secondary,int saturation,int hue,const cups_ib_t * lut)51 _cupsImageReadBMP(
52 cups_image_t *img, /* IO - cupsImage */
53 FILE *fp, /* I - cupsImage file */
54 cups_icspace_t primary, /* I - Primary choice for colorspace */
55 cups_icspace_t secondary, /* I - Secondary choice for colorspace */
56 int saturation, /* I - Color saturation (%) */
57 int hue, /* I - Color hue (degrees) */
58 const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
59 {
60 int offset, /* Offset to bitmap data */
61 info_size, /* Size of info header */
62 planes, /* Number of planes (always 1) */
63 depth, /* Depth of image (bits) */
64 compression, /* Type of compression */
65 image_size, /* Size of image in bytes */
66 colors_used, /* Number of colors used */
67 colors_important, /* Number of important colors */
68 bpp, /* Bytes per pixel */
69 x, y, /* Looping vars */
70 color, /* Color of RLE pixel */
71 count, /* Number of times to repeat */
72 temp, /* Temporary color */
73 align; /* Alignment bytes */
74 cups_ib_t bit, /* Bit in image */
75 byte; /* Byte in image */
76 cups_ib_t *in, /* Input pixels */
77 *out, /* Output pixels */
78 *ptr; /* Pointer into pixels */
79 cups_ib_t colormap[256][4]; /* Colormap */
80
81
82 (void)secondary;
83
84 /*
85 * Get the header...
86 */
87
88 getc(fp); /* Skip "BM" sync chars */
89 getc(fp);
90 read_dword(fp); /* Skip size */
91 read_word(fp); /* Skip reserved stuff */
92 read_word(fp);
93 offset = read_dword(fp);
94
95 fprintf(stderr, "DEBUG: offset = %d\n", offset);
96
97 if (offset < 0)
98 {
99 fprintf(stderr, "DEBUG: Bad BMP offset %d\n", offset);
100 fclose(fp);
101 return (1);
102 }
103
104 /*
105 * Then the bitmap information...
106 */
107
108 info_size = read_dword(fp);
109 img->xsize = read_long(fp);
110 img->ysize = read_long(fp);
111 planes = read_word(fp);
112 depth = read_word(fp);
113 compression = read_dword(fp);
114 image_size = read_dword(fp);
115 img->xppi = read_long(fp) * 0.0254 + 0.5;
116 img->yppi = read_long(fp) * 0.0254 + 0.5;
117 colors_used = read_dword(fp);
118 colors_important = read_dword(fp);
119
120 if (img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH ||
121 img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT ||
122 (depth != 1 && depth != 4 && depth != 8 && depth != 24))
123 {
124 fprintf(stderr, "DEBUG: Bad BMP dimensions %ux%ux%d\n",
125 img->xsize, img->ysize, depth);
126 fclose(fp);
127 return (1);
128 }
129
130 if (colors_used < 0 || colors_used > 256)
131 {
132 fprintf(stderr, "DEBUG: Bad BMP colormap size %d\n", colors_used);
133 fclose(fp);
134 return (1);
135 }
136
137 if (img->xppi == 0 || img->yppi == 0)
138 {
139 fprintf(stderr, "DEBUG: Bad BMP resolution %dx%d PPI.\n",
140 img->xppi, img->yppi);
141 img->xppi = img->yppi = 200;
142 }
143
144 /*
145 * Make sure the resolution info is valid...
146 */
147
148 fprintf(stderr, "info_size = %d, xsize = %d, ysize = %d, planes = %d, depth = %d\n",
149 info_size, img->xsize, img->ysize, planes, depth);
150 fprintf(stderr, "compression = %d, image_size = %d, xppi = %d, yppi = %d\n",
151 compression, image_size, img->xppi, img->yppi);
152 fprintf(stderr, "colors_used = %d, colors_important = %d\n", colors_used,
153 colors_important);
154
155 if (info_size > 40)
156 for (info_size -= 40; info_size > 0; info_size --)
157 getc(fp);
158
159 /*
160 * Get colormap...
161 */
162
163 if (colors_used == 0 && depth <= 8)
164 colors_used = 1 << depth;
165
166 if (colors_used > 0) {
167 if (fread(colormap, colors_used, 4, fp) == 0 && ferror(fp))
168 DEBUG_printf(("Error reading file!"));
169 } else
170 memset(colormap, 0, sizeof(colormap));
171
172 /*
173 * Setup image and buffers...
174 */
175
176 img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
177
178 cupsImageSetMaxTiles(img, 0);
179
180 bpp = cupsImageGetDepth(img);
181
182 if ((in = malloc(img->xsize * 3)) == NULL)
183 {
184 fputs("DEBUG: Unable to allocate memory!\n", stderr);
185 fclose(fp);
186 return (1);
187 }
188
189 if ((out = malloc(img->xsize * bpp)) == NULL)
190 {
191 fputs("DEBUG: Unable to allocate memory!\n", stderr);
192 free(in);
193 fclose(fp);
194 return (1);
195 }
196
197 /*
198 * Read the image data...
199 */
200
201 color = 0;
202 count = 0;
203 align = 0;
204
205 for (y = img->ysize - 1; y >= 0; y --)
206 {
207 ptr = in;
208
209 switch (depth)
210 {
211 case 1 : /* Bitmap */
212 for (x = img->xsize, bit = 128, byte = 0; x > 0; x --)
213 {
214 if (bit == 128)
215 byte = getc(fp);
216
217 if (byte & bit)
218 {
219 *ptr++ = colormap[1][2];
220 *ptr++ = colormap[1][1];
221 *ptr++ = colormap[1][0];
222 }
223 else
224 {
225 *ptr++ = colormap[0][2];
226 *ptr++ = colormap[0][1];
227 *ptr++ = colormap[0][0];
228 }
229
230 if (bit > 1)
231 bit >>= 1;
232 else
233 bit = 128;
234 }
235
236 /*
237 * Read remaining bytes to align to 32 bits...
238 */
239
240 for (temp = (img->xsize + 7) / 8; temp & 3; temp ++)
241 getc(fp);
242 break;
243
244 case 4 : /* 16-color */
245 for (x = img->xsize, bit = 0xf0, temp = 0; x > 0; x --)
246 {
247 /*
248 * Get a new count as needed...
249 */
250
251 if (compression != BI_RLE4 && count == 0)
252 {
253 count = 2;
254 color = -1;
255 }
256
257 if (count == 0)
258 {
259 while (align > 0)
260 {
261 align --;
262 getc(fp);
263 }
264
265 if ((count = getc(fp)) == 0)
266 {
267 if ((count = getc(fp)) == 0)
268 {
269 /*
270 * End of line...
271 */
272
273 x ++;
274 continue;
275 }
276 else if (count == 1)
277 {
278 /*
279 * End of image...
280 */
281
282 break;
283 }
284 else if (count == 2)
285 {
286 /*
287 * Delta...
288 */
289
290 count = getc(fp) * getc(fp) * img->xsize;
291 color = 0;
292 }
293 else
294 {
295 /*
296 * Absolute...
297 */
298
299 color = -1;
300 align = ((4 - (count & 3)) / 2) & 1;
301 }
302 }
303 else
304 color = getc(fp);
305 }
306
307 /*
308 * Get a new color as needed...
309 */
310
311 count --;
312
313 if (bit == 0xf0)
314 {
315 if (color < 0)
316 temp = getc(fp);
317 else
318 temp = color;
319
320 /*
321 * Copy the color value...
322 */
323
324 *ptr++ = colormap[temp >> 4][2];
325 *ptr++ = colormap[temp >> 4][1];
326 *ptr++ = colormap[temp >> 4][0];
327 bit = 0x0f;
328 }
329 else
330 {
331 /*
332 * Copy the color value...
333 */
334
335 *ptr++ = colormap[temp & 15][2];
336 *ptr++ = colormap[temp & 15][1];
337 *ptr++ = colormap[temp & 15][0];
338 bit = 0xf0;
339 }
340 }
341 break;
342
343 case 8 : /* 256-color */
344 for (x = img->xsize; x > 0; x --)
345 {
346 /*
347 * Get a new count as needed...
348 */
349
350 if (compression != BI_RLE8)
351 {
352 count = 1;
353 color = -1;
354 }
355
356 if (count == 0)
357 {
358 while (align > 0)
359 {
360 align --;
361 getc(fp);
362 }
363
364 if ((count = getc(fp)) == 0)
365 {
366 if ((count = getc(fp)) == 0)
367 {
368 /*
369 * End of line...
370 */
371
372 x ++;
373 continue;
374 }
375 else if (count == 1)
376 {
377 /*
378 * End of image...
379 */
380
381 break;
382 }
383 else if (count == 2)
384 {
385 /*
386 * Delta...
387 */
388
389 count = getc(fp) * getc(fp) * img->xsize;
390 color = 0;
391 }
392 else
393 {
394 /*
395 * Absolute...
396 */
397
398 color = -1;
399 align = (2 - (count & 1)) & 1;
400 }
401 }
402 else
403 color = getc(fp);
404 }
405
406 /*
407 * Get a new color as needed...
408 */
409
410 if (color < 0)
411 temp = getc(fp);
412 else
413 temp = color;
414
415 count --;
416
417 /*
418 * Copy the color value...
419 */
420
421 *ptr++ = colormap[temp][2];
422 *ptr++ = colormap[temp][1];
423 *ptr++ = colormap[temp][0];
424 }
425 break;
426
427 case 24 : /* 24-bit RGB */
428 for (x = img->xsize; x > 0; x --, ptr += 3)
429 {
430 ptr[2] = getc(fp);
431 ptr[1] = getc(fp);
432 ptr[0] = getc(fp);
433 }
434
435 /*
436 * Read remaining bytes to align to 32 bits...
437 */
438
439 for (temp = img->xsize * 3; temp & 3; temp ++)
440 getc(fp);
441 break;
442 }
443
444 if (saturation != 100 || hue != 0)
445 cupsImageRGBAdjust(in, img->xsize, saturation, hue);
446
447 switch (img->colorspace)
448 {
449 default :
450 break;
451
452 case CUPS_IMAGE_WHITE :
453 cupsImageRGBToWhite(in, out, img->xsize);
454 break;
455
456 case CUPS_IMAGE_RGB :
457 cupsImageRGBToRGB(in, out, img->xsize);
458 break;
459
460 case CUPS_IMAGE_BLACK :
461 cupsImageRGBToBlack(in, out, img->xsize);
462 break;
463
464 case CUPS_IMAGE_CMY :
465 cupsImageRGBToCMY(in, out, img->xsize);
466 break;
467
468 case CUPS_IMAGE_CMYK :
469 cupsImageRGBToCMYK(in, out, img->xsize);
470 break;
471 }
472
473 if (lut)
474 cupsImageLut(out, img->xsize * bpp, lut);
475
476 _cupsImagePutRow(img, 0, y, img->xsize, out);
477 }
478
479 fclose(fp);
480 free(in);
481 free(out);
482
483 return (0);
484 }
485
486
487 /*
488 * 'read_word()' - Read a 16-bit unsigned integer.
489 */
490
491 static unsigned short /* O - 16-bit unsigned integer */
read_word(FILE * fp)492 read_word(FILE *fp) /* I - File to read from */
493 {
494 unsigned char b0, b1; /* Bytes from file */
495
496 b0 = getc(fp);
497 b1 = getc(fp);
498
499 return ((b1 << 8) | b0);
500 }
501
502
503 /*
504 * 'read_dword()' - Read a 32-bit unsigned integer.
505 */
506
507 static unsigned int /* O - 32-bit unsigned integer */
read_dword(FILE * fp)508 read_dword(FILE *fp) /* I - File to read from */
509 {
510 unsigned char b0, b1, b2, b3; /* Bytes from file */
511
512 b0 = getc(fp);
513 b1 = getc(fp);
514 b2 = getc(fp);
515 b3 = getc(fp);
516
517 return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
518 }
519
520
521 /*
522 * 'read_long()' - Read a 32-bit signed integer.
523 */
524
525 static int /* O - 32-bit signed integer */
read_long(FILE * fp)526 read_long(FILE *fp) /* I - File to read from */
527 {
528 unsigned char b0, b1, b2, b3; /* Bytes from file */
529
530 b0 = getc(fp);
531 b1 = getc(fp);
532 b2 = getc(fp);
533 b3 = getc(fp);
534
535 return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
536 }
537
538