• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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