File Coverage

bmp.c
Criterion Covered Total %
statement 623 729 85.4
branch 282 370 76.2
condition n/a
subroutine n/a
pod n/a
total 905 1099 82.3


line stmt bran cond sub pod time code
1             #define IMAGER_NO_CONTEXT
2             #include
3             #include "imageri.h"
4              
5             /*
6             =head1 NAME
7              
8             bmp.c - read and write windows BMP files
9              
10             =head1 SYNOPSIS
11              
12             i_img *im;
13             io_glue *ig;
14              
15             if (!i_writebmp_wiol(im, ig)) {
16             ... error ...
17             }
18             im = i_readbmp(ig);
19              
20             =head1 DESCRIPTION
21              
22             Reads and writes Windows BMP files.
23              
24             =over
25              
26             =cut
27             */
28              
29             #define FILEHEAD_SIZE 14
30             #define INFOHEAD_SIZE 40
31             #define BI_RGB 0
32             #define BI_RLE8 1
33             #define BI_RLE4 2
34             #define BI_BITFIELDS 3
35             #define BMPRLE_ENDOFLINE 0
36             #define BMPRLE_ENDOFBMP 1
37             #define BMPRLE_DELTA 2
38              
39             #define SIGNBIT32 ((i_upacked_t)1U << 31)
40             #define SIGNBIT16 ((i_upacked_t)1U << 15)
41              
42             #define SIGNMAX32 ((1UL << 31) - 1)
43              
44             static int read_packed(io_glue *ig, char *format, ...);
45             static int write_packed(io_glue *ig, char *format, ...);
46             static int write_bmphead(io_glue *ig, i_img *im, int bit_count,
47             int data_size);
48             static int write_1bit_data(io_glue *ig, i_img *im);
49             static int write_4bit_data(io_glue *ig, i_img *im);
50             static int write_8bit_data(io_glue *ig, i_img *im);
51             static int write_24bit_data(io_glue *ig, i_img *im);
52             static int read_bmp_pal(io_glue *ig, i_img *im, int count);
53             static i_img *read_1bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
54             int compression, long offbits, int allow_incomplete);
55             static i_img *read_4bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
56             int compression, long offbits, int allow_incomplete);
57             static i_img *read_8bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
58             int compression, long offbits, int allow_incomplete);
59             static i_img *read_direct_bmp(io_glue *ig, int xsize, int ysize,
60             int bit_count, int clr_used, int compression,
61             long offbits, int allow_incomplete);
62              
63             /* used for the read_packed() and write_packed() functions, an integer
64             * type */
65             typedef long i_packed_t;
66             typedef unsigned long i_upacked_t;
67              
68             /*
69             =item i_writebmp_wiol(im, io_glue)
70              
71             Writes the image as a BMP file. Uses 1-bit, 4-bit, 8-bit or 24-bit
72             formats depending on the image.
73              
74             Never compresses the image.
75              
76             =cut
77             */
78             int
79 25           i_writebmp_wiol(i_img *im, io_glue *ig) {
80 25           dIMCTXim(im);
81 25           i_clear_error();
82              
83             /* pick a format */
84 25 100         if (im->type == i_direct_type) {
85 13           return write_24bit_data(ig, im);
86             }
87             else {
88             int pal_size;
89              
90             /* must be paletted */
91 12 50         pal_size = i_colorcount(im);
92 12 100         if (pal_size <= 2) {
93 4           return write_1bit_data(ig, im);
94             }
95 8 100         else if (pal_size <= 16) {
96 4           return write_4bit_data(ig, im);
97             }
98             else {
99 4           return write_8bit_data(ig, im);
100             }
101             }
102             }
103              
104             /*
105             =item i_readbmp_wiol(ig)
106              
107             Reads a Windows format bitmap from the given file.
108              
109             Handles BI_RLE4 and BI_RLE8 compressed images. Attempts to handle
110             BI_BITFIELDS images too, but I need a test image.
111              
112             =cut
113             */
114              
115             i_img *
116 104           i_readbmp_wiol(io_glue *ig, int allow_incomplete) {
117             i_packed_t b_magic, m_magic, filesize, res1, res2, infohead_size;
118             i_packed_t xsize, ysize, planes, bit_count, compression, size_image, xres, yres;
119             i_packed_t clr_used, clr_important, offbits;
120             i_img *im;
121 104           dIMCTXio(ig);
122              
123 104           im_log((aIMCTX, 1, "i_readbmp_wiol(ig %p)\n", ig));
124            
125 104           i_clear_error();
126              
127 104 100         if (!read_packed(ig, "CCVvvVVV!V!vvVVVVVV", &b_magic, &m_magic, &filesize,
128             &res1, &res2, &offbits, &infohead_size,
129             &xsize, &ysize, &planes,
130             &bit_count, &compression, &size_image, &xres, &yres,
131             &clr_used, &clr_important)) {
132 1           i_push_error(0, "file too short to be a BMP file");
133 1           return 0;
134             }
135 103 50         if (b_magic != 'B' || m_magic != 'M' || infohead_size != INFOHEAD_SIZE
    50          
    50          
136 103 100         || planes != 1) {
137 1           i_push_error(0, "not a BMP file");
138 1           return 0;
139             }
140              
141 102           im_log((aIMCTX, 1, " bmp header: filesize %d offbits %d xsize %d ysize %d planes %d "
142             "bit_count %d compression %d size %d xres %d yres %d clr_used %d "
143             "clr_important %d\n", (int)filesize, (int)offbits, (int)xsize,
144             (int)ysize, (int)planes, (int)bit_count, (int)compression,
145             (int)size_image, (int)xres, (int)yres, (int)clr_used,
146             (int)clr_important));
147              
148 102 100         if (!i_int_check_image_file_limits(xsize, abs((int)ysize), 3, sizeof(i_sample_t))) {
149 8           im_log((aIMCTX, 1, "i_readbmp_wiol: image size exceeds limits\n"));
150 8           return NULL;
151             }
152            
153 94           switch (bit_count) {
154             case 1:
155 16           im = read_1bit_bmp(ig, xsize, ysize, clr_used, compression, offbits,
156             allow_incomplete);
157 16           break;
158              
159             case 4:
160 26           im = read_4bit_bmp(ig, xsize, ysize, clr_used, compression, offbits,
161             allow_incomplete);
162 26           break;
163              
164             case 8:
165 25           im = read_8bit_bmp(ig, xsize, ysize, clr_used, compression, offbits,
166             allow_incomplete);
167 25           break;
168              
169             case 32:
170             case 24:
171             case 16:
172 26           im = read_direct_bmp(ig, xsize, ysize, bit_count, clr_used, compression,
173             offbits, allow_incomplete);
174 26           break;
175              
176             default:
177 1           im_push_errorf(aIMCTX, 0, "unknown bit count for BMP file (%d)", (int)bit_count);
178 1           return NULL;
179             }
180              
181 93 100         if (im) {
182             /* store the resolution */
183 58 50         if (xres && !yres)
    50          
184 0           yres = xres;
185 58 50         else if (yres && !xres)
    50          
186 0           xres = yres;
187 58 50         if (xres) {
188 58           i_tags_set_float2(&im->tags, "i_xres", 0, xres * 0.0254, 4);
189 58           i_tags_set_float2(&im->tags, "i_yres", 0, yres * 0.0254, 4);
190             }
191 58           i_tags_addn(&im->tags, "bmp_compression", 0, compression);
192 58           i_tags_addn(&im->tags, "bmp_important_colors", 0, clr_important);
193 58           i_tags_addn(&im->tags, "bmp_used_colors", 0, clr_used);
194 58           i_tags_addn(&im->tags, "bmp_filesize", 0, filesize);
195 58           i_tags_addn(&im->tags, "bmp_bit_count", 0, bit_count);
196 58           i_tags_add(&im->tags, "i_format", 0, "bmp", 3, 0);
197             }
198              
199 104           return im;
200             }
201              
202             /*
203             =back
204              
205             =head1 IMPLEMENTATION FUNCTIONS
206              
207             Internal functions used in the implementation.
208              
209             =over
210              
211             =item read_packed(ig, format, ...)
212              
213             Reads from the specified "file" the specified sizes. The format codes
214             match those used by perl's pack() function, though only a few are
215             implemented. In all cases the vararg arguement is an int *.
216              
217             Returns non-zero if all of the arguments were read.
218              
219             =cut
220             */
221             static int
222 125199           read_packed(io_glue *ig, char *format, ...) {
223             unsigned char buf[4];
224             va_list ap;
225             i_packed_t *p;
226             i_packed_t work;
227             int code;
228             int shrieking; /* format code has a ! flag */
229              
230 125199           va_start(ap, format);
231              
232 270697 100         while (*format) {
233 145505 100         p = va_arg(ap, i_packed_t *);
234              
235 145505           code = *format++;
236 145505           shrieking = *format == '!';
237 145505 100         if (shrieking) ++format;
238              
239 145505           switch (code) {
240             case 'v':
241 414 50         if (i_io_read(ig, buf, 2) != 2)
242 0           goto fail;
243 414           work = buf[0] + ((i_packed_t)buf[1] << 8);
244 414 50         if (shrieking)
245 0           *p = (work ^ SIGNBIT16) - SIGNBIT16;
246             else
247 414           *p = work;
248 414           break;
249              
250             case 'V':
251 1137 100         if (i_io_read(ig, buf, 4) != 4)
252 1           goto fail;
253 1136           work = buf[0] + (buf[1] << 8) + ((i_packed_t)buf[2] << 16) + ((i_packed_t)buf[3] << 24);
254 1136 100         if (shrieking)
255 206           *p = (work ^ SIGNBIT32) - SIGNBIT32;
256             else
257 930           *p = work;
258 1136           break;
259              
260             case 'C':
261 25077 100         if (i_io_read(ig, buf, 1) != 1)
262 3           goto fail;
263 25074           *p = buf[0];
264 25074           break;
265              
266             case 'c':
267 0 0         if (i_io_read(ig, buf, 1) != 1)
268 0           goto fail;
269 0           *p = (char)buf[0];
270 0           break;
271            
272             case '3': /* extension - 24-bit number */
273 118877 100         if (i_io_read(ig, buf, 3) != 3)
274 3           goto fail;
275 118874           *p = buf[0] + (buf[1] << 8) + ((i_packed_t)buf[2] << 16);
276 118874           break;
277            
278             default:
279             {
280 0           dIMCTXio(ig);
281 0           im_fatal(aIMCTX, 1, "Unknown read_packed format code 0x%02x", code);
282             }
283             }
284             }
285 125192           va_end(ap);
286 125192           return 1;
287              
288             fail:
289 7           va_end(ap);
290 125199           return 0;
291             }
292              
293             /*
294             =item write_packed(ig, format, ...)
295              
296             Writes packed data to the specified io_glue.
297              
298             Returns non-zero on success.
299              
300             =cut
301             */
302              
303             static int
304 532           write_packed(io_glue *ig, char *format, ...) {
305             unsigned char buf[4];
306             va_list ap;
307             int i;
308              
309 532           va_start(ap, format);
310              
311 2915 100         while (*format) {
312 2390 100         i = va_arg(ap, i_upacked_t);
313              
314 2390           switch (*format) {
315             case 'v':
316 84           buf[0] = i & 255;
317 84           buf[1] = i / 256;
318 84 50         if (i_io_write(ig, buf, 2) == -1)
319 0           goto fail;
320 84           break;
321              
322             case 'V':
323 231           buf[0] = i & 0xFF;
324 231           buf[1] = (i >> 8) & 0xFF;
325 231           buf[2] = (i >> 16) & 0xFF;
326 231           buf[3] = (i >> 24) & 0xFF;
327 231 50         if (i_io_write(ig, buf, 4) == -1)
328 0           goto fail;
329 231           break;
330              
331             case 'C':
332             case 'c':
333 2075           buf[0] = i & 0xFF;
334 2075 100         if (i_io_write(ig, buf, 1) == -1)
335 7           goto fail;
336 2068           break;
337              
338             default:
339             {
340 0           dIMCTXio(ig);
341 0           im_fatal(aIMCTX, 1, "Unknown write_packed format code 0x%02x", *format);
342             }
343             }
344 2383           ++format;
345             }
346 525           va_end(ap);
347              
348 525           return 1;
349              
350             fail:
351 7           va_end(ap);
352 532           return 0;
353             }
354              
355             /*
356             =item write_bmphead(ig, im, bit_count, data_size)
357              
358             Writes a Windows BMP header to the file.
359              
360             Returns non-zero on success.
361              
362             =cut
363             */
364              
365             static
366 25           int write_bmphead(io_glue *ig, i_img *im, int bit_count, int data_size) {
367             double xres, yres;
368             int got_xres, got_yres, aspect_only;
369 25           int colors_used = 0;
370 25           int offset = FILEHEAD_SIZE + INFOHEAD_SIZE;
371 25           dIMCTXim(im);
372              
373 25 50         if (im->xsize > SIGNMAX32 || im->ysize > SIGNMAX32) {
    50          
374 0           i_push_error(0, "image too large to write to BMP");
375 0           return 0;
376             }
377              
378 25           got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
379 25           got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
380 25 50         if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
381 25           aspect_only = 0;
382 25 100         if (!got_xres) {
383 12 50         if (!got_yres)
384 12           xres = yres = 72;
385             else
386 12           xres = yres;
387             }
388             else {
389 13 50         if (!got_yres)
390 0           yres = xres;
391             }
392 25 50         if (xres <= 0 || yres <= 0)
    50          
393 0           xres = yres = 72;
394 25 50         if (aspect_only) {
395             /* scale so the smaller value is 72 */
396             double ratio;
397 0 0         if (xres < yres) {
398 0           ratio = 72.0 / xres;
399             }
400             else {
401 0           ratio = 72.0 / yres;
402             }
403 0           xres *= ratio;
404 0           yres *= ratio;
405             }
406             /* now to pels/meter */
407 25           xres *= 100.0/2.54;
408 25           yres *= 100.0/2.54;
409              
410 25 100         if (im->type == i_palette_type) {
411 12 50         colors_used = i_colorcount(im);
412 12           offset += 4 * colors_used;
413             }
414              
415 25 100         if (!write_packed(ig, "CCVvvVVVVvvVVVVVV", 'B', 'M',
416 25           (i_upacked_t)(data_size+offset),
417             (i_upacked_t)0, (i_upacked_t)0, (i_upacked_t)offset,
418 25           (i_upacked_t)INFOHEAD_SIZE, (i_upacked_t)im->xsize,
419 25           (i_upacked_t)im->ysize, (i_upacked_t)1,
420             (i_upacked_t)bit_count, (i_upacked_t)BI_RGB,
421             (i_upacked_t)data_size,
422 50           (i_upacked_t)(xres+0.5), (i_upacked_t)(yres+0.5),
423             (i_upacked_t)colors_used, (i_upacked_t)colors_used)){
424 4           i_push_error(0, "cannot write bmp header");
425 4           return 0;
426             }
427 21 100         if (im->type == i_palette_type) {
428             int i;
429             i_color c;
430              
431 513 100         for (i = 0; i < colors_used; ++i) {
432 507 50         i_getcolors(im, i, &c, 1);
433 507 50         if (im->channels >= 3) {
434 507 100         if (!write_packed(ig, "CCCC", (i_upacked_t)(c.channel[2]),
435 507           (i_upacked_t)(c.channel[1]),
436 507           (i_upacked_t)(c.channel[0]), (i_upacked_t)0)) {
437 3           i_push_error(0, "cannot write palette entry");
438 3           return 0;
439             }
440             }
441             else {
442 0           i_upacked_t v = c.channel[0];
443 0 0         if (!write_packed(ig, "CCCC", v, v, v, 0)) {
444 0           i_push_error(0, "cannot write palette entry");
445 0           return 0;
446             }
447             }
448             }
449             }
450              
451 25           return 1;
452             }
453              
454             /*
455             =item write_1bit_data(ig, im)
456              
457             Writes the image data as a 1-bit/pixel image.
458              
459             Returns non-zero on success.
460              
461             =cut
462             */
463             static int
464 4           write_1bit_data(io_glue *ig, i_img *im) {
465             i_palidx *line;
466             unsigned char *packed;
467             int byte;
468             int mask;
469             unsigned char *out;
470 4           int line_size = (im->xsize+7) / 8;
471             int x, y;
472             int unpacked_size;
473 4           dIMCTXim(im);
474              
475             /* round up to nearest multiple of four */
476 4           line_size = (line_size + 3) / 4 * 4;
477              
478 4 100         if (!write_bmphead(ig, im, 1, line_size * im->ysize))
479 2           return 0;
480              
481             /* this shouldn't be an issue, but let's be careful */
482 2           unpacked_size = im->xsize + 8;
483 2 50         if (unpacked_size < im->xsize) {
484 0           i_push_error(0, "integer overflow during memory allocation");
485 0           return 0;
486             }
487 2           line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
488 2           memset(line + im->xsize, 0, 8);
489              
490             /* size allocated here is always much smaller than xsize, hence
491             can't overflow int */
492 2           packed = mymalloc(line_size); /* checked 29jun05 tonyc */
493 2           memset(packed, 0, line_size);
494            
495 152 100         for (y = im->ysize-1; y >= 0; --y) {
496 151 50         i_gpal(im, 0, im->xsize, y, line);
497 151           mask = 0x80;
498 151           byte = 0;
499 151           out = packed;
500 22671 100         for (x = 0; x < im->xsize; ++x) {
501 22520 100         if (line[x])
502 6962           byte |= mask;
503 22520 100         if ((mask >>= 1) == 0) {
504 2702           *out++ = byte;
505 2702           byte = 0;
506 2702           mask = 0x80;
507             }
508             }
509 151 50         if (mask != 0x80) {
510 151           *out++ = byte;
511             }
512 151 100         if (i_io_write(ig, packed, line_size) < 0) {
513 1           myfree(packed);
514 1           myfree(line);
515 1           i_push_error(0, "writing 1 bit/pixel packed data");
516 1           return 0;
517             }
518             }
519 1           myfree(packed);
520 1           myfree(line);
521              
522 1 50         if (i_io_close(ig))
523 0           return 0;
524              
525 1           return 1;
526             }
527              
528             /*
529             =item write_4bit_data(ig, im)
530              
531             Writes the image data as a 4-bit/pixel image.
532              
533             Returns non-zero on success.
534              
535             =cut
536             */
537             static int
538 4           write_4bit_data(io_glue *ig, i_img *im) {
539             i_palidx *line;
540             unsigned char *packed;
541             unsigned char *out;
542 4           int line_size = (im->xsize+1) / 2;
543             int x, y;
544             int unpacked_size;
545 4           dIMCTXim(im);
546              
547             /* round up to nearest multiple of four */
548 4           line_size = (line_size + 3) / 4 * 4;
549              
550 4 100         if (!write_bmphead(ig, im, 4, line_size * im->ysize))
551 2           return 0;
552              
553             /* this shouldn't be an issue, but let's be careful */
554 2           unpacked_size = im->xsize + 2;
555 2 50         if (unpacked_size < im->xsize) {
556 0           i_push_error(0, "integer overflow during memory allocation");
557 0           return 0;
558             }
559 2           line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
560 2           memset(line + im->xsize, 0, 2);
561            
562             /* size allocated here is always much smaller than xsize, hence
563             can't overflow int */
564 2           packed = mymalloc(line_size); /* checked 29jun05 tonyc */
565 2           memset(packed, 0, line_size);
566            
567 152 100         for (y = im->ysize-1; y >= 0; --y) {
568 151 50         i_gpal(im, 0, im->xsize, y, line);
569 151           out = packed;
570 11411 100         for (x = 0; x < im->xsize; x += 2) {
571 11260           *out++ = (line[x] << 4) + line[x+1];
572             }
573 151 100         if (i_io_write(ig, packed, line_size) < 0) {
574 1           myfree(packed);
575 1           myfree(line);
576 1           i_push_error(0, "writing 4 bit/pixel packed data");
577 1           return 0;
578             }
579             }
580 1           myfree(packed);
581 1           myfree(line);
582              
583 1 50         if (i_io_close(ig))
584 0           return 0;
585              
586 1           return 1;
587             }
588              
589             /*
590             =item write_8bit_data(ig, im)
591              
592             Writes the image data as a 8-bit/pixel image.
593              
594             Returns non-zero on success.
595              
596             =cut
597             */
598             static int
599 4           write_8bit_data(io_glue *ig, i_img *im) {
600             i_palidx *line;
601 4           int line_size = im->xsize;
602             int y;
603             int unpacked_size;
604 4           dIMCTXim(im);
605              
606             /* round up to nearest multiple of four */
607 4           line_size = (line_size + 3) / 4 * 4;
608              
609 4 100         if (!write_bmphead(ig, im, 8, line_size * im->ysize))
610 2           return 0;
611              
612             /* this shouldn't be an issue, but let's be careful */
613 2           unpacked_size = im->xsize + 4;
614 2 50         if (unpacked_size < im->xsize) {
615 0           i_push_error(0, "integer overflow during memory allocation");
616 0           return 0;
617             }
618 2           line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
619 2           memset(line + im->xsize, 0, 4);
620            
621 152 100         for (y = im->ysize-1; y >= 0; --y) {
622 151 50         i_gpal(im, 0, im->xsize, y, line);
623 151 100         if (i_io_write(ig, line, line_size) < 0) {
624 1           myfree(line);
625 1           i_push_error(0, "writing 8 bit/pixel packed data");
626 1           return 0;
627             }
628             }
629 1           myfree(line);
630              
631 1 50         if (i_io_close(ig))
632 0           return 0;
633              
634 1           return 1;
635             }
636              
637             /*
638             =item write_24bit_data(ig, im)
639              
640             Writes the image data as a 24-bit/pixel image.
641              
642             Returns non-zero on success.
643              
644             =cut
645             */
646             static int
647 13           write_24bit_data(io_glue *ig, i_img *im) {
648             unsigned char *samples;
649             int y;
650 13           int line_size = 3 * im->xsize;
651             i_color bg;
652 13           dIMCTXim(im);
653              
654 13           i_get_file_background(im, &bg);
655              
656             /* just in case we implement a direct format with 2bytes/pixel
657             (unlikely though) */
658 13 50         if (line_size / 3 != im->xsize) {
659 0           i_push_error(0, "integer overflow during memory allocation");
660 0           return 0;
661             }
662            
663 13           line_size = (line_size + 3) / 4 * 4;
664            
665 13 100         if (!write_bmphead(ig, im, 24, line_size * im->ysize))
666 1           return 0;
667 12           samples = mymalloc(4 * im->xsize);
668 12           memset(samples, 0, line_size);
669 1544 100         for (y = im->ysize-1; y >= 0; --y) {
670 1533           unsigned char *samplep = samples;
671             int x;
672 1533           i_gsamp_bg(im, 0, im->xsize, y, samples, 3, &bg);
673 239665 100         for (x = 0; x < im->xsize; ++x) {
674 238132           unsigned char tmp = samplep[2];
675 238132           samplep[2] = samplep[0];
676 238132           samplep[0] = tmp;
677 238132           samplep += 3;
678             }
679 1533 100         if (i_io_write(ig, samples, line_size) < 0) {
680 1           i_push_error(0, "writing image data");
681 1           myfree(samples);
682 1           return 0;
683             }
684             }
685 11           myfree(samples);
686              
687 11 100         if (i_io_close(ig))
688 1           return 0;
689              
690 13           return 1;
691             }
692              
693             /*
694             =item read_bmp_pal(ig, im, count)
695              
696             Reads count palette entries from the file and add them to the image.
697              
698             Returns non-zero on success.
699              
700             =cut
701             */
702             static int
703 59           read_bmp_pal(io_glue *ig, i_img *im, int count) {
704             int i;
705             i_packed_t r, g, b, x;
706             i_color c;
707 59           dIMCTXio(ig);
708            
709 6274 100         for (i = 0; i < count; ++i) {
710 6218 100         if (!read_packed(ig, "CCCC", &b, &g, &r, &x)) {
711 3           i_push_error(0, "reading BMP palette");
712 3           return 0;
713             }
714 6215           c.channel[0] = r;
715 6215           c.channel[1] = g;
716 6215           c.channel[2] = b;
717 6215 50         if (i_addcolors(im, &c, 1) < 0) {
    50          
718 0           i_push_error(0, "out of space in image palette");
719 0           return 0;
720             }
721             }
722            
723 59           return 1;
724             }
725              
726             /*
727             =item read_1bit_bmp(ig, xsize, ysize, clr_used, compression, offbits)
728              
729             Reads in the palette and image data for a 1-bit/pixel image.
730              
731             Returns the image or NULL.
732              
733             =cut
734             */
735             static i_img *
736 16           read_1bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
737             int compression, long offbits, int allow_incomplete) {
738             i_img *im;
739             int x, y, lasty, yinc, start_y;
740             i_palidx *line, *p;
741             unsigned char *packed;
742 16           int line_size = (xsize + 7)/8;
743             int bit;
744             unsigned char *in;
745             long base_offset;
746 16           dIMCTXio(ig);
747              
748 16 100         if (compression != BI_RGB) {
749 1           im_push_errorf(aIMCTX, 0, "unknown 1-bit BMP compression (%d)", compression);
750 1           return NULL;
751             }
752              
753 15 50         if ((i_img_dim)((i_img_dim_u)xsize + 8) < xsize) { /* if there was overflow */
754             /* we check with 8 because we allocate that much for the decoded
755             line buffer */
756 0           i_push_error(0, "integer overflow during memory allocation");
757 0           return NULL;
758             }
759              
760             /* if xsize+7 is ok then (xsize+7)/8 will be and the minor
761             adjustments below won't make it overflow */
762 15           line_size = (line_size+3) / 4 * 4;
763              
764 15 100         if (ysize > 0) {
765 14           start_y = ysize-1;
766 14           lasty = -1;
767 14           yinc = -1;
768             }
769             else {
770             /* when ysize is -ve it's a top-down image */
771 1           ysize = -ysize;
772 1           start_y = 0;
773 1           lasty = ysize;
774 1           yinc = 1;
775             }
776 15           y = start_y;
777 15 50         if (!clr_used)
778 0           clr_used = 2;
779 15 50         if (clr_used < 0 || clr_used > 2) {
    100          
780 1           im_push_errorf(aIMCTX, 0, "out of range colors used (%d)", clr_used);
781 1           return NULL;
782             }
783              
784 14           base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE + clr_used * 4;
785 14 100         if (offbits < base_offset) {
786 1           im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
787 1           return NULL;
788             }
789              
790 13           im = i_img_pal_new(xsize, ysize, 3, 256);
791 13 50         if (!im)
792 0           return NULL;
793 13 100         if (!read_bmp_pal(ig, im, clr_used)) {
794 1           i_img_destroy(im);
795 1           return NULL;
796             }
797              
798 12 100         if (offbits > base_offset) {
799             /* this will be slow if the offset is large, but that should be
800             rare */
801             char buffer;
802 8 100         while (base_offset < offbits) {
803 7 100         if (i_io_read(ig, &buffer, 1) != 1) {
804 1           i_img_destroy(im);
805 1           i_push_error(0, "failed skipping to image data offset");
806 1           return NULL;
807             }
808 6           ++base_offset;
809             }
810             }
811            
812 11           i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
813              
814 11           packed = mymalloc(line_size); /* checked 29jun05 tonyc */
815 11           line = mymalloc(xsize+8); /* checked 29jun05 tonyc */
816 336 100         while (y != lasty) {
817 328 100         if (i_io_read(ig, packed, line_size) != line_size) {
818 3           myfree(packed);
819 3           myfree(line);
820 3 100         if (allow_incomplete) {
821 1           i_tags_setn(&im->tags, "i_incomplete", 1);
822 1           i_tags_setn(&im->tags, "i_lines_read", abs(start_y - y));
823 1           return im;
824             }
825             else {
826 2           i_push_error(0, "failed reading 1-bit bmp data");
827 2           i_img_destroy(im);
828 2           return NULL;
829             }
830             }
831 325           in = packed;
832 325           bit = 0x80;
833 325           p = line;
834 26325 100         for (x = 0; x < xsize; ++x) {
835 26000           *p++ = (*in & bit) ? 1 : 0;
836 26000           bit >>= 1;
837 26000 100         if (!bit) {
838 3050           ++in;
839 3050           bit = 0x80;
840             }
841             }
842 325 50         i_ppal(im, 0, xsize, y, line);
843 325           y += yinc;
844             }
845              
846 8           myfree(packed);
847 8           myfree(line);
848 8           return im;
849             }
850              
851             /*
852             =item read_4bit_bmp(ig, xsize, ysize, clr_used, compression)
853              
854             Reads in the palette and image data for a 4-bit/pixel image.
855              
856             Returns the image or NULL.
857              
858             Hopefully this will be combined with the following function at some
859             point.
860              
861             =cut
862             */
863             static i_img *
864 26           read_4bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
865             int compression, long offbits, int allow_incomplete) {
866             i_img *im;
867             int x, y, lasty, yinc;
868             i_palidx *line, *p;
869             unsigned char *packed;
870 26           int line_size = (xsize + 1)/2;
871             unsigned char *in;
872             int size, i;
873             long base_offset;
874             int starty;
875 26           dIMCTXio(ig);
876              
877             /* line_size is going to be smaller than xsize in most cases (and
878             when it's not, xsize is itself small), and hence not overflow */
879 26           line_size = (line_size+3) / 4 * 4;
880              
881 26 100         if (ysize > 0) {
882 24           starty = ysize-1;
883 24           lasty = -1;
884 24           yinc = -1;
885             }
886             else {
887             /* when ysize is -ve it's a top-down image */
888 2           ysize = -ysize;
889 2           starty = 0;
890 2           lasty = ysize;
891 2           yinc = 1;
892             }
893 26           y = starty;
894 26 50         if (!clr_used)
895 0           clr_used = 16;
896              
897 26 100         if (clr_used > 16 || clr_used < 0) {
    50          
898 2           im_push_errorf(aIMCTX, 0, "out of range colors used (%d)", clr_used);
899 2           return NULL;
900             }
901              
902 24           base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE + clr_used * 4;
903 24 100         if (offbits < base_offset) {
904 1           im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
905 1           return NULL;
906             }
907              
908 23           im = i_img_pal_new(xsize, ysize, 3, 256);
909 23 50         if (!im) /* error should have been pushed already */
910 0           return NULL;
911 23 100         if (!read_bmp_pal(ig, im, clr_used)) {
912 1           i_img_destroy(im);
913 1           return NULL;
914             }
915              
916 22 100         if (offbits > base_offset) {
917             /* this will be slow if the offset is large, but that should be
918             rare */
919             char buffer;
920 8 100         while (base_offset < offbits) {
921 7 100         if (i_io_read(ig, &buffer, 1) != 1) {
922 1           i_img_destroy(im);
923 1           i_push_error(0, "failed skipping to image data offset");
924 1           return NULL;
925             }
926 6           ++base_offset;
927             }
928             }
929            
930 21 50         if (line_size < 260)
931 21           packed = mymalloc(260); /* checked 29jun05 tonyc */
932             else
933 0           packed = mymalloc(line_size); /* checked 29jun05 tonyc */
934             /* xsize won't approach MAXINT */
935 21           line = mymalloc(xsize+1); /* checked 29jun05 tonyc */
936 21 100         if (compression == BI_RGB) {
937 11           i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
938 331 100         while (y != lasty) {
939 323 100         if (i_io_read(ig, packed, line_size) != line_size) {
940 3           myfree(packed);
941 3           myfree(line);
942 3 100         if (allow_incomplete) {
943 1           i_tags_setn(&im->tags, "i_incomplete", 1);
944 1           i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
945 1           return im;
946             }
947             else {
948 2           i_push_error(0, "failed reading 4-bit bmp data");
949 2           i_img_destroy(im);
950 2           return NULL;
951             }
952             }
953 320           in = packed;
954 320           p = line;
955 13270 100         for (x = 0; x < xsize; x+=2) {
956 12950           *p++ = *in >> 4;
957 12950           *p++ = *in & 0x0F;
958 12950           ++in;
959             }
960 320 50         i_ppal(im, 0, xsize, y, line);
961 320           y += yinc;
962             }
963 8           myfree(packed);
964 8           myfree(line);
965             }
966 10 100         else if (compression == BI_RLE4) {
967             int read_size;
968             int count;
969 9           i_img_dim xlimit = (xsize + 1) / 2 * 2; /* rounded up */
970              
971 9           i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RLE4", -1, 0);
972 9           x = 0;
973             while (1) {
974             /* there's always at least 2 bytes in a sequence */
975 3588 100         if (i_io_read(ig, packed, 2) != 2) {
976 2           myfree(packed);
977 2           myfree(line);
978 2 100         if (allow_incomplete) {
979 1           i_tags_setn(&im->tags, "i_incomplete", 1);
980 1           i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
981 1           return im;
982             }
983             else {
984 1           i_push_error(0, "missing data during decompression");
985 1           i_img_destroy(im);
986 1           return NULL;
987             }
988             }
989 3586 100         else if (packed[0]) {
990 2726           int count = packed[0];
991 2726 100         if (x + count > xlimit) {
992             /* this file is corrupt */
993 1           myfree(packed);
994 1           myfree(line);
995 1           i_push_error(0, "invalid data during decompression");
996 1           im_log((aIMCTX, 1, "read 4-bit: scanline overflow x %d + count %d vs xlimit %d (y %d)\n",
997             (int)x, count, (int)xlimit, (int)y));
998 1           i_img_destroy(im);
999 1           return NULL;
1000             }
1001             /* fill in the line */
1002 43151 100         for (i = 0; i < count; i += 2)
1003 40426           line[i] = packed[1] >> 4;
1004 43151 100         for (i = 1; i < count; i += 2)
1005 40426           line[i] = packed[1] & 0x0F;
1006 2725 50         i_ppal(im, x, x+count, y, line);
1007 2725           x += count;
1008             } else {
1009 860           switch (packed[1]) {
1010             case BMPRLE_ENDOFLINE:
1011 562           x = 0;
1012 562           y += yinc;
1013 562           break;
1014              
1015             case BMPRLE_ENDOFBMP:
1016 3           myfree(packed);
1017 3           myfree(line);
1018 3           return im;
1019              
1020             case BMPRLE_DELTA:
1021 0 0         if (i_io_read(ig, packed, 2) != 2) {
1022 0           myfree(packed);
1023 0           myfree(line);
1024 0 0         if (allow_incomplete) {
1025 0           i_tags_setn(&im->tags, "i_incomplete", 1);
1026 0           i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
1027 0           return im;
1028             }
1029             else {
1030 0           i_push_error(0, "missing data during decompression");
1031 0           i_img_destroy(im);
1032 0           return NULL;
1033             }
1034             }
1035 0           x += packed[0];
1036 0           y += yinc * packed[1];
1037 0           break;
1038              
1039             default:
1040 295           count = packed[1];
1041 295 100         if (x + count > xlimit) {
1042             /* this file is corrupt */
1043 1           myfree(packed);
1044 1           myfree(line);
1045 1           i_push_error(0, "invalid data during decompression");
1046 1           im_log((aIMCTX, 1, "read 4-bit: scanline overflow (unpacked) x %d + count %d vs xlimit %d (y %d)\n",
1047             (int)x, count, (int)xlimit, (int)y));
1048 1           i_img_destroy(im);
1049 1           return NULL;
1050             }
1051 294           size = (count + 1) / 2;
1052 294           read_size = (size+1) / 2 * 2;
1053 294 100         if (i_io_read(ig, packed, read_size) != read_size) {
1054 2           myfree(packed);
1055 2           myfree(line);
1056 2 100         if (allow_incomplete) {
1057 1           i_tags_setn(&im->tags, "i_incomplete", 1);
1058 1           i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
1059 1           return im;
1060             }
1061             else {
1062 1           i_push_error(0, "missing data during decompression");
1063 1           i_img_destroy(im);
1064 1           return NULL;
1065             }
1066             }
1067 1156 100         for (i = 0; i < size; ++i) {
1068 864           line[0] = packed[i] >> 4;
1069 864           line[1] = packed[i] & 0xF;
1070 864 50         i_ppal(im, x, x+2, y, line);
1071 864           x += 2;
1072             }
1073 292           break;
1074             }
1075             }
1076 3579           }
1077             }
1078             else { /*if (compression == BI_RLE4) {*/
1079 1           myfree(packed);
1080 1           myfree(line);
1081 1           im_push_errorf(aIMCTX, 0, "unknown 4-bit BMP compression (%d)", compression);
1082 1           i_img_destroy(im);
1083 1           return NULL;
1084             }
1085              
1086 8           return im;
1087             }
1088              
1089             /*
1090             =item read_8bit_bmp(ig, xsize, ysize, clr_used, compression, allow_incomplete)
1091              
1092             Reads in the palette and image data for a 8-bit/pixel image.
1093              
1094             Returns the image or NULL.
1095              
1096             =cut
1097             */
1098             static i_img *
1099 25           read_8bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
1100             int compression, long offbits, int allow_incomplete) {
1101             i_img *im;
1102             int x, y, lasty, yinc, start_y;
1103             i_palidx *line;
1104 25           int line_size = xsize;
1105             long base_offset;
1106 25           dIMCTXio(ig);
1107              
1108 25           line_size = (line_size+3) / 4 * 4;
1109 25 50         if (line_size < xsize) { /* if it overflowed (unlikely, but check) */
1110 0           i_push_error(0, "integer overflow during memory allocation");
1111 0           return NULL;
1112             }
1113              
1114 25 100         if (ysize > 0) {
1115 23           start_y = ysize-1;
1116 23           lasty = -1;
1117 23           yinc = -1;
1118             }
1119             else {
1120             /* when ysize is -ve it's a top-down image */
1121 2           ysize = -ysize;
1122 2           start_y = 0;
1123 2           lasty = ysize;
1124 2           yinc = 1;
1125             }
1126 25           y = start_y;
1127 25 50         if (!clr_used)
1128 0           clr_used = 256;
1129 25 100         if (clr_used > 256 || clr_used < 0) {
    50          
1130 1           im_push_errorf(aIMCTX, 0, "out of range colors used (%d)", clr_used);
1131 1           return NULL;
1132             }
1133              
1134 24           base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE + clr_used * 4;
1135 24 100         if (offbits < base_offset) {
1136 1           im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
1137 1           return NULL;
1138             }
1139              
1140 23           im = i_img_pal_new(xsize, ysize, 3, 256);
1141 23 50         if (!im)
1142 0           return NULL;
1143 23 100         if (!read_bmp_pal(ig, im, clr_used)) {
1144 1           i_img_destroy(im);
1145 1           return NULL;
1146             }
1147              
1148 22 100         if (offbits > base_offset) {
1149             /* this will be slow if the offset is large, but that should be
1150             rare */
1151             char buffer;
1152 8 100         while (base_offset < offbits) {
1153 7 100         if (i_io_read(ig, &buffer, 1) != 1) {
1154 1           i_img_destroy(im);
1155 1           i_push_error(0, "failed skipping to image data offset");
1156 1           return NULL;
1157             }
1158 6           ++base_offset;
1159             }
1160             }
1161            
1162 21           line = mymalloc(line_size); /* checked 29jun05 tonyc */
1163 21 100         if (compression == BI_RGB) {
1164 11           i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
1165 328 100         while (y != lasty) {
1166 320 100         if (i_io_read(ig, line, line_size) != line_size) {
1167 3           myfree(line);
1168 3 100         if (allow_incomplete) {
1169 1           i_tags_setn(&im->tags, "i_incomplete", 1);
1170 1           i_tags_setn(&im->tags, "i_lines_read", abs(start_y - y));
1171 1           return im;
1172             }
1173             else {
1174 2           i_push_error(0, "failed reading 8-bit bmp data");
1175 2           i_img_destroy(im);
1176 2           return NULL;
1177             }
1178             }
1179 317 50         i_ppal(im, 0, xsize, y, line);
1180 317           y += yinc;
1181             }
1182 8           myfree(line);
1183             }
1184 10 100         else if (compression == BI_RLE8) {
1185             int read_size;
1186             int count;
1187             unsigned char packed[2];
1188              
1189 9           i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RLE8", -1, 0);
1190 9           x = 0;
1191             while (1) {
1192             /* there's always at least 2 bytes in a sequence */
1193 3610 100         if (i_io_read(ig, packed, 2) != 2) {
1194 2           myfree(line);
1195 2 100         if (allow_incomplete) {
1196 1           i_tags_setn(&im->tags, "i_incomplete", 1);
1197 1           i_tags_setn(&im->tags, "i_lines_read", abs(start_y-y));
1198 1           return im;
1199             }
1200             else {
1201 1           i_push_error(0, "missing data during decompression");
1202 1           i_img_destroy(im);
1203 1           return NULL;
1204             }
1205             }
1206 3608 100         if (packed[0]) {
1207 2296 100         if (x + packed[0] > xsize) {
1208             /* this file isn't incomplete, it's corrupt */
1209 1           myfree(line);
1210 1           i_push_error(0, "invalid data during decompression");
1211 1           i_img_destroy(im);
1212 1           return NULL;
1213             }
1214 2295           memset(line, packed[1], packed[0]);
1215 2295 50         i_ppal(im, x, x+packed[0], y, line);
1216 2295           x += packed[0];
1217             } else {
1218 1312           switch (packed[1]) {
1219             case BMPRLE_ENDOFLINE:
1220 540           x = 0;
1221 540           y += yinc;
1222 540           break;
1223              
1224             case BMPRLE_ENDOFBMP:
1225 3           myfree(line);
1226 3           return im;
1227              
1228             case BMPRLE_DELTA:
1229 0 0         if (i_io_read(ig, packed, 2) != 2) {
1230 0           myfree(line);
1231 0 0         if (allow_incomplete) {
1232 0           i_tags_setn(&im->tags, "i_incomplete", 1);
1233 0           i_tags_setn(&im->tags, "i_lines_read", abs(start_y-y));
1234 0           return im;
1235             }
1236             else {
1237 0           i_push_error(0, "missing data during decompression");
1238 0           i_img_destroy(im);
1239 0           return NULL;
1240             }
1241             }
1242 0           x += packed[0];
1243 0           y += yinc * packed[1];
1244 0           break;
1245              
1246             default:
1247 769           count = packed[1];
1248 769 100         if (x + count > xsize) {
1249             /* runs shouldn't cross a line boundary */
1250             /* this file isn't incomplete, it's corrupt */
1251 1           myfree(line);
1252 1           i_push_error(0, "invalid data during decompression");
1253 1           i_img_destroy(im);
1254 1           return NULL;
1255             }
1256 768           read_size = (count+1) / 2 * 2;
1257 768 100         if (i_io_read(ig, line, read_size) != read_size) {
1258 2           myfree(line);
1259 2 100         if (allow_incomplete) {
1260 1           i_tags_setn(&im->tags, "i_incomplete", 1);
1261 1           i_tags_setn(&im->tags, "i_lines_read", abs(start_y-y));
1262 1           return im;
1263             }
1264             else {
1265 1           i_push_error(0, "missing data during decompression");
1266 1           i_img_destroy(im);
1267 1           return NULL;
1268             }
1269             }
1270 766 50         i_ppal(im, x, x+count, y, line);
1271 766           x += count;
1272 766           break;
1273             }
1274             }
1275 3610           }
1276             }
1277             else {
1278 1           myfree(line);
1279 1           im_push_errorf(aIMCTX, 0, "unknown 8-bit BMP compression (%d)", compression);
1280 1           i_img_destroy(im);
1281 1           return NULL;
1282             }
1283              
1284 8           return im;
1285             }
1286              
1287             struct bm_masks {
1288             unsigned masks[3];
1289             int shifts[3];
1290             int bits[3];
1291             };
1292             static struct bm_masks std_masks[] =
1293             {
1294             { /* 16-bit */
1295             { 0076000, 00001740, 00000037, },
1296             { 10, 5, 0, },
1297             { 5, 5, 5, }
1298             },
1299             { /* 24-bit */
1300             { 0xFF0000, 0x00FF00, 0x0000FF, },
1301             { 16, 8, 0, },
1302             { 8, 8, 8, },
1303             },
1304             { /* 32-bit */
1305             { 0xFF0000, 0x00FF00, 0x0000FF, },
1306             { 16, 8, 0, },
1307             { 8, 8, 8, },
1308             },
1309             };
1310              
1311             /* multiplier and shift for converting from N bits to 8 bits */
1312             struct bm_sampconverts {
1313             int mult;
1314             int shift;
1315             };
1316             static struct bm_sampconverts samp_converts[] = {
1317             { 0xff, 0 }, /* 1 bit samples */
1318             { 0x55, 0 },
1319             { 0111, 1 },
1320             { 0x11, 0 },
1321             { 0x21, 2 },
1322             { 0x41, 4 },
1323             { 0x81, 6 } /* 7 bit samples */
1324             };
1325              
1326             /*
1327             =item read_direct_bmp(ig, xsize, ysize, bit_count, clr_used, compression, allow_incomplete)
1328              
1329             Skips the palette and reads in the image data for a direct colour image.
1330              
1331             Returns the image or NULL.
1332              
1333             =cut
1334             */
1335             static i_img *
1336 26           read_direct_bmp(io_glue *ig, int xsize, int ysize, int bit_count,
1337             int clr_used, int compression, long offbits,
1338             int allow_incomplete) {
1339             i_img *im;
1340             int x, y, starty, lasty, yinc;
1341             i_color *line, *p;
1342 26           int pix_size = bit_count / 8;
1343 26           int line_size = xsize * pix_size;
1344             struct bm_masks masks;
1345 26           char unpack_code[2] = "";
1346             int i;
1347             int extras;
1348             char junk[4];
1349             const char *compression_name;
1350             int bytes;
1351 26           long base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE;
1352 26           dIMCTXio(ig);
1353            
1354 26           unpack_code[0] = "v3V"[pix_size-2];
1355 26           unpack_code[1] = '\0';
1356              
1357 26           line_size = (line_size+3) / 4 * 4;
1358 26           extras = line_size - xsize * pix_size;
1359              
1360 26 100         if (ysize > 0) {
1361 25           starty = ysize-1;
1362 25           lasty = -1;
1363 25           yinc = -1;
1364             }
1365             else {
1366             /* when ysize is -ve it's a top-down image */
1367 1           ysize = -ysize;
1368 1           starty = 0;
1369 1           lasty = ysize;
1370 1           yinc = 1;
1371             }
1372 26           y = starty;
1373 26 100         if (compression == BI_RGB) {
1374 25           compression_name = "BI_RGB";
1375 25           masks = std_masks[pix_size-2];
1376            
1377             /* there's a potential "palette" after the header */
1378 25 50         for (i = 0; i < clr_used; ++clr_used) {
1379             char buf[4];
1380 0 0         if (i_io_read(ig, buf, 4) != 4) {
1381 0           i_push_error(0, "skipping colors");
1382 0           return 0;
1383             }
1384 0           base_offset += 4;
1385             }
1386             }
1387 1 50         else if (compression == BI_BITFIELDS) {
1388             int pos;
1389             unsigned bits;
1390 0           compression_name = "BI_BITFIELDS";
1391              
1392 0 0         for (i = 0; i < 3; ++i) {
1393             i_packed_t rmask;
1394 0 0         if (!read_packed(ig, "V", &rmask)) {
1395 0           i_push_error(0, "reading pixel masks");
1396 0           return 0;
1397             }
1398 0 0         if (rmask == 0) {
1399 0           im_push_errorf(aIMCTX, 0, "Zero mask for channel %d", i);
1400 0           return NULL;
1401             }
1402 0           masks.masks[i] = rmask;
1403             /* work out a shift for the mask */
1404 0           pos = 0;
1405 0           bits = masks.masks[i];
1406 0 0         while (!(bits & 1)) {
1407 0           ++pos;
1408 0           bits >>= 1;
1409             }
1410 0           masks.shifts[i] = pos;
1411 0           pos = 0;
1412 0 0         while (bits & 1) {
1413 0           ++pos;
1414 0           bits >>= 1;
1415             }
1416 0           masks.bits[i] = pos;
1417             /*fprintf(stderr, "%d: mask %08x shift %d bits %d\n", i, masks.masks[i], masks.shifts[i], masks.bits[i]);*/
1418             }
1419             /* account for the masks */
1420 0           base_offset += 3 * 4;
1421             }
1422             else {
1423 1           im_push_errorf(aIMCTX, 0, "unknown 24-bit BMP compression (%d)", compression);
1424 1           return NULL;
1425             }
1426              
1427 25 100         if (offbits < base_offset) {
1428 1           im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
1429 1           return NULL;
1430             }
1431              
1432 24 100         if (offbits > base_offset) {
1433             /* this will be slow if the offset is large, but that should be
1434             rare */
1435             char buffer;
1436 8 100         while (base_offset < offbits) {
1437 7 100         if (i_io_read(ig, &buffer, 1) != 1) {
1438 1           i_push_error(0, "failed skipping to image data offset");
1439 1           return NULL;
1440             }
1441 6           ++base_offset;
1442             }
1443             }
1444            
1445 23           im = i_img_empty(NULL, xsize, ysize);
1446 23 50         if (!im)
1447 0           return NULL;
1448              
1449 23           i_tags_add(&im->tags, "bmp_compression_name", 0, compression_name, -1, 0);
1450              
1451             /* I wasn't able to make this overflow in testing, but better to be
1452             safe */
1453 23           bytes = sizeof(i_color) * xsize;
1454 23 50         if (bytes / sizeof(i_color) != xsize) {
1455 0           i_img_destroy(im);
1456 0           i_push_error(0, "integer overflow calculating buffer size");
1457 0           return NULL;
1458             }
1459 23           line = mymalloc(bytes); /* checked 29jun05 tonyc */
1460 1096 100         while (y != lasty) {
1461 1076           p = line;
1462 119950 100         for (x = 0; x < xsize; ++x) {
1463             i_packed_t pixel;
1464 118877 100         if (!read_packed(ig, unpack_code, &pixel)) {
1465 3           myfree(line);
1466 3 100         if (allow_incomplete) {
1467 1           i_tags_setn(&im->tags, "i_incomplete", 1);
1468 1           i_tags_setn(&im->tags, "i_lines_read", abs(starty - y));
1469 3           return im;
1470             }
1471             else {
1472 2           i_push_error(0, "failed reading image data");
1473 2           i_img_destroy(im);
1474 2           return NULL;
1475             }
1476             }
1477 475496 100         for (i = 0; i < 3; ++i) {
1478 356622           int sample = (pixel & masks.masks[i]) >> masks.shifts[i];
1479 356622           int bits = masks.bits[i];
1480 356622 50         if (bits < 8) {
1481 0           sample = (sample * samp_converts[bits-1].mult) >> samp_converts[bits-1].shift;
1482             }
1483 356622 50         else if (bits) {
1484 356622           sample >>= bits - 8;
1485             }
1486 356622           p->channel[i] = sample;
1487             }
1488 118874           ++p;
1489             }
1490 1073           i_plin(im, 0, xsize, y, line);
1491 1073 100         if (extras)
1492 750           i_io_read(ig, junk, extras);
1493 1073           y += yinc;
1494             }
1495 20           myfree(line);
1496              
1497 26           return im;
1498             }
1499              
1500             /*
1501             =head1 SEE ALSO
1502              
1503             Imager(3)
1504              
1505             =head1 AUTHOR
1506              
1507             Tony Cook
1508              
1509             =head1 RESTRICTIONS
1510              
1511             Cannot save as compressed BMP.
1512              
1513             =head1 BUGS
1514              
1515             Doesn't handle OS/2 bitmaps.
1516              
1517             16-bit/pixel images haven't been tested. (I need an image).
1518              
1519             BI_BITFIELDS compression hasn't been tested (I need an image).
1520              
1521             The header handling for paletted images needs to be refactored
1522              
1523             =cut
1524             */