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