ensure bmp.c read_packed() calls va_end()
[imager.git] / bmp.c
1 #define IMAGER_NO_CONTEXT
2 #include <stdarg.h>
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 i_writebmp_wiol(i_img *im, io_glue *ig) {
80   dIMCTXim(im);
81   i_clear_error();
82
83   /* pick a format */
84   if (im->type == i_direct_type) {
85     return write_24bit_data(ig, im);
86   }
87   else {
88     int pal_size;
89
90     /* must be paletted */
91     pal_size = i_colorcount(im);
92     if (pal_size <= 2) {
93       return write_1bit_data(ig, im);
94     }
95     else if (pal_size <= 16) {
96       return write_4bit_data(ig, im);
97     }
98     else {
99       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 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   dIMCTXio(ig);
122
123   im_log((aIMCTX, 1, "i_readbmp_wiol(ig %p)\n", ig));
124   
125   i_clear_error();
126
127   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     i_push_error(0, "file too short to be a BMP file");
133     return 0;
134   }
135   if (b_magic != 'B' || m_magic != 'M' || infohead_size != INFOHEAD_SIZE
136       || planes != 1) {
137     i_push_error(0, "not a BMP file");
138     return 0;
139   }
140
141   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   if (!i_int_check_image_file_limits(xsize, abs(ysize), 3, sizeof(i_sample_t))) {
149     im_log((aIMCTX, 1, "i_readbmp_wiol: image size exceeds limits\n"));
150     return NULL;
151   }
152   
153   switch (bit_count) {
154   case 1:
155     im = read_1bit_bmp(ig, xsize, ysize, clr_used, compression, offbits, 
156                        allow_incomplete);
157     break;
158
159   case 4:
160     im = read_4bit_bmp(ig, xsize, ysize, clr_used, compression, offbits, 
161                        allow_incomplete);
162     break;
163
164   case 8:
165     im = read_8bit_bmp(ig, xsize, ysize, clr_used, compression, offbits, 
166                        allow_incomplete);
167     break;
168
169   case 32:
170   case 24:
171   case 16:
172     im = read_direct_bmp(ig, xsize, ysize, bit_count, clr_used, compression,
173                          offbits, allow_incomplete);
174     break;
175
176   default:
177     im_push_errorf(aIMCTX, 0, "unknown bit count for BMP file (%d)", (int)bit_count);
178     return NULL;
179   }
180
181   if (im) {
182     /* store the resolution */
183     if (xres && !yres)
184       yres = xres;
185     else if (yres && !xres)
186       xres = yres;
187     if (xres) {
188       i_tags_set_float2(&im->tags, "i_xres", 0, xres * 0.0254, 4);
189       i_tags_set_float2(&im->tags, "i_yres", 0, yres * 0.0254, 4);
190     }
191     i_tags_addn(&im->tags, "bmp_compression", 0, compression);
192     i_tags_addn(&im->tags, "bmp_important_colors", 0, clr_important);
193     i_tags_addn(&im->tags, "bmp_used_colors", 0, clr_used);
194     i_tags_addn(&im->tags, "bmp_filesize", 0, filesize);
195     i_tags_addn(&im->tags, "bmp_bit_count", 0, bit_count);
196     i_tags_add(&im->tags, "i_format", 0, "bmp", 3, 0);
197   }
198
199   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 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   va_start(ap, format);
231
232   while (*format) {
233     p = va_arg(ap, i_packed_t *);
234
235     code = *format++;
236     shrieking = *format == '!';
237     if (shrieking) ++format;
238
239     switch (code) {
240     case 'v':
241       if (i_io_read(ig, buf, 2) != 2)
242         goto fail;
243       work = buf[0] + ((i_packed_t)buf[1] << 8);
244       if (shrieking)
245         *p = (work ^ SIGNBIT16) - SIGNBIT16;
246       else
247         *p = work;
248       break;
249
250     case 'V':
251       if (i_io_read(ig, buf, 4) != 4)
252         goto fail;
253       work = buf[0] + (buf[1] << 8) + ((i_packed_t)buf[2] << 16) + ((i_packed_t)buf[3] << 24);
254       if (shrieking)
255         *p = (work ^ SIGNBIT32) - SIGNBIT32;
256       else
257         *p = work;
258       break;
259
260     case 'C':
261       if (i_io_read(ig, buf, 1) != 1)
262         goto fail;
263       *p = buf[0];
264       break;
265
266     case 'c':
267       if (i_io_read(ig, buf, 1) != 1)
268         goto fail;
269       *p = (char)buf[0];
270       break;
271       
272     case '3': /* extension - 24-bit number */
273       if (i_io_read(ig, buf, 3) != 3)
274         goto fail;
275       *p = buf[0] + (buf[1] << 8) + ((i_packed_t)buf[2] << 16);
276       break;
277       
278     default:
279       {
280         dIMCTXio(ig);
281         im_fatal(aIMCTX, 1, "Unknown read_packed format code 0x%02x", code);
282       }
283     }
284   }
285   va_end(ap);
286   return 1;
287
288  fail:
289   va_end(ap);
290   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 write_packed(io_glue *ig, char *format, ...) {
305   unsigned char buf[4];
306   va_list ap;
307   int i;
308
309   va_start(ap, format);
310
311   while (*format) {
312     i = va_arg(ap, i_upacked_t);
313
314     switch (*format) {
315     case 'v':
316       buf[0] = i & 255;
317       buf[1] = i / 256;
318       if (i_io_write(ig, buf, 2) == -1)
319         goto fail;
320       break;
321
322     case 'V':
323       buf[0] = i & 0xFF;
324       buf[1] = (i >> 8) & 0xFF;
325       buf[2] = (i >> 16) & 0xFF;
326       buf[3] = (i >> 24) & 0xFF;
327       if (i_io_write(ig, buf, 4) == -1)
328         goto fail;
329       break;
330
331     case 'C':
332     case 'c':
333       buf[0] = i & 0xFF;
334       if (i_io_write(ig, buf, 1) == -1)
335         goto fail;
336       break;
337
338     default:
339       {
340         dIMCTXio(ig);
341         im_fatal(aIMCTX, 1, "Unknown write_packed format code 0x%02x", *format);
342       }
343     }
344     ++format;
345   }
346   va_end(ap);
347
348   return 1;
349
350  fail:
351   va_end(ap);
352   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 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   int colors_used = 0;
370   int offset = FILEHEAD_SIZE + INFOHEAD_SIZE;
371   dIMCTXim(im);
372
373   if (im->xsize > SIGNMAX32 || im->ysize > SIGNMAX32) {
374     i_push_error(0, "image too large to write to BMP");
375     return 0;
376   }
377
378   got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
379   got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
380   if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
381     aspect_only = 0;
382   if (!got_xres) {
383     if (!got_yres)
384       xres = yres = 72;
385     else
386       xres = yres;
387   }
388   else {
389     if (!got_yres)
390       yres = xres;
391   }
392   if (xres <= 0 || yres <= 0)
393     xres = yres = 72;
394   if (aspect_only) {
395     /* scale so the smaller value is 72 */
396     double ratio;
397     if (xres < yres) {
398       ratio = 72.0 / xres;
399     }
400     else {
401       ratio = 72.0 / yres;
402     }
403     xres *= ratio;
404     yres *= ratio;
405   }
406   /* now to pels/meter */
407   xres *= 100.0/2.54;
408   yres *= 100.0/2.54;
409
410   if (im->type == i_palette_type) {
411     colors_used = i_colorcount(im);
412     offset += 4 * colors_used;
413   }
414
415   if (!write_packed(ig, "CCVvvVVVVvvVVVVVV", 'B', 'M', 
416                     (i_upacked_t)(data_size+offset), 
417                     (i_upacked_t)0, (i_upacked_t)0, (i_upacked_t)offset,
418                     (i_upacked_t)INFOHEAD_SIZE, (i_upacked_t)im->xsize,
419                     (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                     (i_upacked_t)(xres+0.5), (i_upacked_t)(yres+0.5), 
423                     (i_upacked_t)colors_used, (i_upacked_t)colors_used)){
424     i_push_error(0, "cannot write bmp header");
425     return 0;
426   }
427   if (im->type == i_palette_type) {
428     int i;
429     i_color c;
430
431     for (i = 0; i < colors_used; ++i) {
432       i_getcolors(im, i, &c, 1);
433       if (im->channels >= 3) {
434         if (!write_packed(ig, "CCCC", (i_upacked_t)(c.channel[2]), 
435                           (i_upacked_t)(c.channel[1]), 
436                           (i_upacked_t)(c.channel[0]), (i_upacked_t)0)) {
437           i_push_error(0, "cannot write palette entry");
438           return 0;
439         }
440       }
441       else {
442         i_upacked_t v = c.channel[0];
443         if (!write_packed(ig, "CCCC", v, v, v, 0)) {
444           i_push_error(0, "cannot write palette entry");
445           return 0;
446         }
447       }
448     }
449   }
450
451   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 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   int line_size = (im->xsize+7) / 8;
471   int x, y;
472   int unpacked_size;
473   dIMCTXim(im);
474
475   /* round up to nearest multiple of four */
476   line_size = (line_size + 3) / 4 * 4;
477
478   if (!write_bmphead(ig, im, 1, line_size * im->ysize))
479     return 0;
480
481   /* this shouldn't be an issue, but let's be careful */
482   unpacked_size = im->xsize + 8;
483   if (unpacked_size < im->xsize) {
484     i_push_error(0, "integer overflow during memory allocation");
485     return 0;
486   }
487   line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
488   memset(line + im->xsize, 0, 8);
489
490   /* size allocated here is always much smaller than xsize, hence
491      can't overflow int */
492   packed = mymalloc(line_size); /* checked 29jun05 tonyc */
493   memset(packed, 0, line_size);
494   
495   for (y = im->ysize-1; y >= 0; --y) {
496     i_gpal(im, 0, im->xsize, y, line);
497     mask = 0x80;
498     byte = 0;
499     out = packed;
500     for (x = 0; x < im->xsize; ++x) {
501       if (line[x])
502         byte |= mask;
503       if ((mask >>= 1) == 0) {
504         *out++ = byte;
505         byte = 0;
506         mask = 0x80;
507       }
508     }
509     if (mask != 0x80) {
510       *out++ = byte;
511     }
512     if (i_io_write(ig, packed, line_size) < 0) {
513       myfree(packed);
514       myfree(line);
515       i_push_error(0, "writing 1 bit/pixel packed data");
516       return 0;
517     }
518   }
519   myfree(packed);
520   myfree(line);
521
522   if (i_io_close(ig))
523     return 0;
524
525   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 write_4bit_data(io_glue *ig, i_img *im) {
539   i_palidx *line;
540   unsigned char *packed;
541   unsigned char *out;
542   int line_size = (im->xsize+1) / 2;
543   int x, y;
544   int unpacked_size;
545   dIMCTXim(im);
546
547   /* round up to nearest multiple of four */
548   line_size = (line_size + 3) / 4 * 4;
549
550   if (!write_bmphead(ig, im, 4, line_size * im->ysize))
551     return 0;
552
553   /* this shouldn't be an issue, but let's be careful */
554   unpacked_size = im->xsize + 2;
555   if (unpacked_size < im->xsize) {
556     i_push_error(0, "integer overflow during memory allocation");
557     return 0;
558   }
559   line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
560   memset(line + im->xsize, 0, 2);
561   
562   /* size allocated here is always much smaller than xsize, hence
563      can't overflow int */
564   packed = mymalloc(line_size); /* checked 29jun05 tonyc */
565   memset(packed, 0, line_size);
566   
567   for (y = im->ysize-1; y >= 0; --y) {
568     i_gpal(im, 0, im->xsize, y, line);
569     out = packed;
570     for (x = 0; x < im->xsize; x += 2) {
571       *out++ = (line[x] << 4) + line[x+1];
572     }
573     if (i_io_write(ig, packed, line_size) < 0) {
574       myfree(packed);
575       myfree(line);
576       i_push_error(0, "writing 4 bit/pixel packed data");
577       return 0;
578     }
579   }
580   myfree(packed);
581   myfree(line);
582
583   if (i_io_close(ig))
584     return 0;
585
586   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 write_8bit_data(io_glue *ig, i_img *im) {
600   i_palidx *line;
601   int line_size = im->xsize;
602   int y;
603   int unpacked_size;
604   dIMCTXim(im);
605
606   /* round up to nearest multiple of four */
607   line_size = (line_size + 3) / 4 * 4;
608
609   if (!write_bmphead(ig, im, 8, line_size * im->ysize))
610     return 0;
611
612   /* this shouldn't be an issue, but let's be careful */
613   unpacked_size = im->xsize + 4;
614   if (unpacked_size < im->xsize) {
615     i_push_error(0, "integer overflow during memory allocation");
616     return 0;
617   }
618   line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
619   memset(line + im->xsize, 0, 4);
620   
621   for (y = im->ysize-1; y >= 0; --y) {
622     i_gpal(im, 0, im->xsize, y, line);
623     if (i_io_write(ig, line, line_size) < 0) {
624       myfree(line);
625       i_push_error(0, "writing 8 bit/pixel packed data");
626       return 0;
627     }
628   }
629   myfree(line);
630
631   if (i_io_close(ig))
632     return 0;
633
634   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 write_24bit_data(io_glue *ig, i_img *im) {
648   unsigned char *samples;
649   int y;
650   int line_size = 3 * im->xsize;
651   i_color bg;
652   dIMCTXim(im);
653
654   i_get_file_background(im, &bg);
655
656   /* just in case we implement a direct format with 2bytes/pixel
657      (unlikely though) */
658   if (line_size / 3 != im->xsize) {
659     i_push_error(0, "integer overflow during memory allocation");
660     return 0;
661   }
662   
663   line_size = (line_size + 3) / 4 * 4;
664   
665   if (!write_bmphead(ig, im, 24, line_size * im->ysize))
666     return 0;
667   samples = mymalloc(4 * im->xsize);
668   memset(samples, 0, line_size);
669   for (y = im->ysize-1; y >= 0; --y) {
670     unsigned char *samplep = samples;
671     int x;
672     i_gsamp_bg(im, 0, im->xsize, y, samples, 3, &bg);
673     for (x = 0; x < im->xsize; ++x) {
674       unsigned char tmp = samplep[2];
675       samplep[2] = samplep[0];
676       samplep[0] = tmp;
677       samplep += 3;
678     }
679     if (i_io_write(ig, samples, line_size) < 0) {
680       i_push_error(0, "writing image data");
681       myfree(samples);
682       return 0;
683     }
684   }
685   myfree(samples);
686
687   if (i_io_close(ig))
688     return 0;
689
690   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 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   dIMCTXio(ig);
708   
709   for (i = 0; i < count; ++i) {
710     if (!read_packed(ig, "CCCC", &b, &g, &r, &x)) {
711       i_push_error(0, "reading BMP palette");
712       return 0;
713     }
714     c.channel[0] = r;
715     c.channel[1] = g;
716     c.channel[2] = b;
717     if (i_addcolors(im, &c, 1) < 0) {
718       i_push_error(0, "out of space in image palette");
719       return 0;
720     }
721   }
722   
723   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 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   int line_size = (xsize + 7)/8;
743   int bit;
744   unsigned char *in;
745   long base_offset;
746   dIMCTXio(ig);
747
748   if (compression != BI_RGB) {
749     im_push_errorf(aIMCTX, 0, "unknown 1-bit BMP compression (%d)", compression);
750     return NULL;
751   }
752
753   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     i_push_error(0, "integer overflow during memory allocation");
757     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   line_size = (line_size+3) / 4 * 4;
763
764   if (ysize > 0) {
765     start_y = ysize-1;
766     lasty = -1;
767     yinc = -1;
768   }
769   else {
770     /* when ysize is -ve it's a top-down image */
771     ysize = -ysize;
772     start_y = 0;
773     lasty = ysize;
774     yinc = 1;
775   }
776   y = start_y;
777   if (!clr_used)
778     clr_used = 2;
779   if (clr_used < 0 || clr_used > 2) {
780     im_push_errorf(aIMCTX, 0, "out of range colors used (%d)", clr_used);
781     return NULL;
782   }
783
784   base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE + clr_used * 4;
785   if (offbits < base_offset) {
786     im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
787     return NULL;
788   }
789
790   im = i_img_pal_new(xsize, ysize, 3, 256);
791   if (!im)
792     return NULL;
793   if (!read_bmp_pal(ig, im, clr_used)) {
794     i_img_destroy(im);
795     return NULL;
796   }
797
798   if (offbits > base_offset) {
799     /* this will be slow if the offset is large, but that should be
800        rare */
801     char buffer;
802     while (base_offset < offbits) {
803       if (i_io_read(ig, &buffer, 1) != 1) {
804         i_img_destroy(im);
805         i_push_error(0, "failed skipping to image data offset");
806         return NULL;
807       }
808       ++base_offset;
809     }
810   }
811   
812   i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
813
814   packed = mymalloc(line_size); /* checked 29jun05 tonyc */
815   line = mymalloc(xsize+8); /* checked 29jun05 tonyc */
816   while (y != lasty) {
817     if (i_io_read(ig, packed, line_size) != line_size) {
818       myfree(packed);
819       myfree(line);
820       if (allow_incomplete) {
821         i_tags_setn(&im->tags, "i_incomplete", 1);
822         i_tags_setn(&im->tags, "i_lines_read", abs(start_y - y));
823         return im;
824       }
825       else {
826         i_push_error(0, "failed reading 1-bit bmp data");
827         i_img_destroy(im);
828         return NULL;
829       }
830     }
831     in = packed;
832     bit = 0x80;
833     p = line;
834     for (x = 0; x < xsize; ++x) {
835       *p++ = (*in & bit) ? 1 : 0;
836       bit >>= 1;
837       if (!bit) {
838         ++in;
839         bit = 0x80;
840       }
841     }
842     i_ppal(im, 0, xsize, y, line);
843     y += yinc;
844   }
845
846   myfree(packed);
847   myfree(line);
848   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 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   int line_size = (xsize + 1)/2;
871   unsigned char *in;
872   int size, i;
873   long base_offset;
874   int starty;
875   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   line_size = (line_size+3) / 4 * 4;
880
881   if (ysize > 0) {
882     starty = ysize-1;
883     lasty = -1;
884     yinc = -1;
885   }
886   else {
887     /* when ysize is -ve it's a top-down image */
888     ysize = -ysize;
889     starty = 0;
890     lasty = ysize;
891     yinc = 1;
892   }
893   y = starty;
894   if (!clr_used)
895     clr_used = 16;
896
897   if (clr_used > 16 || clr_used < 0) {
898     im_push_errorf(aIMCTX, 0, "out of range colors used (%d)", clr_used);
899     return NULL;
900   }
901
902   base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE + clr_used * 4;
903   if (offbits < base_offset) {
904     im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
905     return NULL;
906   }
907
908   im = i_img_pal_new(xsize, ysize, 3, 256);
909   if (!im) /* error should have been pushed already */
910     return NULL;
911   if (!read_bmp_pal(ig, im, clr_used)) {
912     i_img_destroy(im);
913     return NULL;
914   }
915
916   if (offbits > base_offset) {
917     /* this will be slow if the offset is large, but that should be
918        rare */
919     char buffer;
920     while (base_offset < offbits) {
921       if (i_io_read(ig, &buffer, 1) != 1) {
922         i_img_destroy(im);
923         i_push_error(0, "failed skipping to image data offset");
924         return NULL;
925       }
926       ++base_offset;
927     }
928   }
929   
930   if (line_size < 260)
931     packed = mymalloc(260); /* checked 29jun05 tonyc */
932   else
933     packed = mymalloc(line_size); /* checked 29jun05 tonyc */
934   /* xsize won't approach MAXINT */
935   line = mymalloc(xsize+1); /* checked 29jun05 tonyc */
936   if (compression == BI_RGB) {
937     i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
938     while (y != lasty) {
939       if (i_io_read(ig, packed, line_size) != line_size) {
940         myfree(packed);
941         myfree(line);
942         if (allow_incomplete) {
943           i_tags_setn(&im->tags, "i_incomplete", 1);
944           i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
945           return im;
946         }
947         else {
948           i_push_error(0, "failed reading 4-bit bmp data");
949           i_img_destroy(im);
950           return NULL;
951         }
952       }
953       in = packed;
954       p = line;
955       for (x = 0; x < xsize; x+=2) {
956         *p++ = *in >> 4;
957         *p++ = *in & 0x0F;
958         ++in;
959       }
960       i_ppal(im, 0, xsize, y, line);
961       y += yinc;
962     }
963     myfree(packed);
964     myfree(line);
965   }
966   else if (compression == BI_RLE4) {
967     int read_size;
968     int count;
969     i_img_dim xlimit = (xsize + 1) / 2 * 2; /* rounded up */
970
971     i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RLE4", -1, 0);
972     x = 0;
973     while (1) {
974       /* there's always at least 2 bytes in a sequence */
975       if (i_io_read(ig, packed, 2) != 2) {
976         myfree(packed);
977         myfree(line);
978         if (allow_incomplete) {
979           i_tags_setn(&im->tags, "i_incomplete", 1);
980           i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
981           return im;
982         }
983         else {
984           i_push_error(0, "missing data during decompression");
985           i_img_destroy(im);
986           return NULL;
987         }
988       }
989       else if (packed[0]) {
990         int count = packed[0];
991         if (x + count > xlimit) {
992           /* this file is corrupt */
993           myfree(packed);
994           myfree(line);
995           i_push_error(0, "invalid data during decompression");
996           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           i_img_destroy(im);
999           return NULL;
1000         }
1001         /* fill in the line */
1002         for (i = 0; i < count; i += 2)
1003           line[i] = packed[1] >> 4;
1004         for (i = 1; i < count; i += 2)
1005           line[i] = packed[1] & 0x0F;
1006         i_ppal(im, x, x+count, y, line);
1007         x += count;
1008       } else {
1009         switch (packed[1]) {
1010         case BMPRLE_ENDOFLINE:
1011           x = 0;
1012           y += yinc;
1013           break;
1014
1015         case BMPRLE_ENDOFBMP:
1016           myfree(packed);
1017           myfree(line);
1018           return im;
1019
1020         case BMPRLE_DELTA:
1021           if (i_io_read(ig, packed, 2) != 2) {
1022             myfree(packed);
1023             myfree(line);
1024             if (allow_incomplete) {
1025               i_tags_setn(&im->tags, "i_incomplete", 1);
1026               i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
1027               return im;
1028             }
1029             else {
1030               i_push_error(0, "missing data during decompression");
1031               i_img_destroy(im);
1032               return NULL;
1033             }
1034           }
1035           x += packed[0];
1036           y += yinc * packed[1];
1037           break;
1038
1039         default:
1040           count = packed[1];
1041           if (x + count > xlimit) {
1042             /* this file is corrupt */
1043             myfree(packed);
1044             myfree(line);
1045             i_push_error(0, "invalid data during decompression");
1046             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             i_img_destroy(im);
1049             return NULL;
1050           }
1051           size = (count + 1) / 2;
1052           read_size = (size+1) / 2 * 2;
1053           if (i_io_read(ig, packed, read_size) != read_size) {
1054             myfree(packed);
1055             myfree(line);
1056             if (allow_incomplete) {
1057               i_tags_setn(&im->tags, "i_incomplete", 1);
1058               i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
1059               return im;
1060             }
1061             else {
1062               i_push_error(0, "missing data during decompression");
1063               i_img_destroy(im);
1064               return NULL;
1065             }
1066           }
1067           for (i = 0; i < size; ++i) {
1068             line[0] = packed[i] >> 4;
1069             line[1] = packed[i] & 0xF;
1070             i_ppal(im, x, x+2, y, line);
1071             x += 2;
1072           }
1073           break;
1074         }
1075       }
1076     }
1077   }
1078   else { /*if (compression == BI_RLE4) {*/
1079     myfree(packed);
1080     myfree(line);
1081     im_push_errorf(aIMCTX, 0, "unknown 4-bit BMP compression (%d)", compression);
1082     i_img_destroy(im);
1083     return NULL;
1084   }
1085
1086   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 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   int line_size = xsize;
1105   long base_offset;
1106   dIMCTXio(ig);
1107
1108   line_size = (line_size+3) / 4 * 4;
1109   if (line_size < xsize) { /* if it overflowed (unlikely, but check) */
1110     i_push_error(0, "integer overflow during memory allocation");
1111     return NULL;
1112   }
1113
1114   if (ysize > 0) {
1115     start_y = ysize-1;
1116     lasty = -1;
1117     yinc = -1;
1118   }
1119   else {
1120     /* when ysize is -ve it's a top-down image */
1121     ysize = -ysize;
1122     start_y = 0;
1123     lasty = ysize;
1124     yinc = 1;
1125   }
1126   y = start_y;
1127   if (!clr_used)
1128     clr_used = 256;
1129   if (clr_used > 256 || clr_used < 0) {
1130     im_push_errorf(aIMCTX, 0, "out of range colors used (%d)", clr_used);
1131     return NULL;
1132   }
1133
1134   base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE + clr_used * 4;
1135   if (offbits < base_offset) {
1136     im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
1137     return NULL;
1138   }
1139
1140   im = i_img_pal_new(xsize, ysize, 3, 256);
1141   if (!im)
1142     return NULL;
1143   if (!read_bmp_pal(ig, im, clr_used)) {
1144     i_img_destroy(im);
1145     return NULL;
1146   }
1147
1148   if (offbits > base_offset) {
1149     /* this will be slow if the offset is large, but that should be
1150        rare */
1151     char buffer;
1152     while (base_offset < offbits) {
1153       if (i_io_read(ig, &buffer, 1) != 1) {
1154         i_img_destroy(im);
1155         i_push_error(0, "failed skipping to image data offset");
1156         return NULL;
1157       }
1158       ++base_offset;
1159     }
1160   }
1161   
1162   line = mymalloc(line_size); /* checked 29jun05 tonyc */
1163   if (compression == BI_RGB) {
1164     i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
1165     while (y != lasty) {
1166       if (i_io_read(ig, line, line_size) != line_size) {
1167         myfree(line);
1168         if (allow_incomplete) {
1169           i_tags_setn(&im->tags, "i_incomplete", 1);
1170           i_tags_setn(&im->tags, "i_lines_read", abs(start_y - y));
1171           return im;
1172         }
1173         else {
1174           i_push_error(0, "failed reading 8-bit bmp data");
1175           i_img_destroy(im);
1176           return NULL;
1177         }
1178       }
1179       i_ppal(im, 0, xsize, y, line);
1180       y += yinc;
1181     }
1182     myfree(line);
1183   }
1184   else if (compression == BI_RLE8) {
1185     int read_size;
1186     int count;
1187     unsigned char packed[2];
1188
1189     i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RLE8", -1, 0);
1190     x = 0;
1191     while (1) {
1192       /* there's always at least 2 bytes in a sequence */
1193       if (i_io_read(ig, packed, 2) != 2) {
1194         myfree(line);
1195         if (allow_incomplete) {
1196           i_tags_setn(&im->tags, "i_incomplete", 1);
1197           i_tags_setn(&im->tags, "i_lines_read", abs(start_y-y));
1198           return im;
1199         }
1200         else {
1201           i_push_error(0, "missing data during decompression");
1202           i_img_destroy(im);
1203           return NULL;
1204         }
1205       }
1206       if (packed[0]) {
1207         if (x + packed[0] > xsize) {
1208           /* this file isn't incomplete, it's corrupt */
1209           myfree(line);
1210           i_push_error(0, "invalid data during decompression");
1211           i_img_destroy(im);
1212           return NULL;
1213         }
1214         memset(line, packed[1], packed[0]);
1215         i_ppal(im, x, x+packed[0], y, line);
1216         x += packed[0];
1217       } else {
1218         switch (packed[1]) {
1219         case BMPRLE_ENDOFLINE:
1220           x = 0;
1221           y += yinc;
1222           break;
1223
1224         case BMPRLE_ENDOFBMP:
1225           myfree(line);
1226           return im;
1227
1228         case BMPRLE_DELTA:
1229           if (i_io_read(ig, packed, 2) != 2) {
1230             myfree(line);
1231             if (allow_incomplete) {
1232               i_tags_setn(&im->tags, "i_incomplete", 1);
1233               i_tags_setn(&im->tags, "i_lines_read", abs(start_y-y));
1234               return im;
1235             }
1236             else {
1237               i_push_error(0, "missing data during decompression");
1238               i_img_destroy(im);
1239               return NULL;
1240             }
1241           }
1242           x += packed[0];
1243           y += yinc * packed[1];
1244           break;
1245
1246         default:
1247           count = packed[1];
1248           if (x + count > xsize) {
1249             /* runs shouldn't cross a line boundary */
1250             /* this file isn't incomplete, it's corrupt */
1251             myfree(line);
1252             i_push_error(0, "invalid data during decompression");
1253             i_img_destroy(im);
1254             return NULL;
1255           }
1256           read_size = (count+1) / 2 * 2;
1257           if (i_io_read(ig, line, read_size) != read_size) {
1258             myfree(line);
1259             if (allow_incomplete) {
1260               i_tags_setn(&im->tags, "i_incomplete", 1);
1261               i_tags_setn(&im->tags, "i_lines_read", abs(start_y-y));
1262               return im;
1263             }
1264             else {
1265               i_push_error(0, "missing data during decompression");
1266               i_img_destroy(im);
1267               return NULL;
1268             }
1269           }
1270           i_ppal(im, x, x+count, y, line);
1271           x += count;
1272           break;
1273         }
1274       }
1275     }
1276   }
1277   else { 
1278     myfree(line);
1279     im_push_errorf(aIMCTX, 0, "unknown 8-bit BMP compression (%d)", compression);
1280     i_img_destroy(im);
1281     return NULL;
1282   }
1283
1284   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 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   int pix_size = bit_count / 8;
1343   int line_size = xsize * pix_size;
1344   struct bm_masks masks;
1345   char unpack_code[2] = "";
1346   int i;
1347   int extras;
1348   char junk[4];
1349   const char *compression_name;
1350   int bytes;
1351   long base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE;
1352   dIMCTXio(ig);
1353   
1354   unpack_code[0] = *("v3V"+pix_size-2);
1355   unpack_code[1] = '\0';
1356
1357   line_size = (line_size+3) / 4 * 4;
1358   extras = line_size - xsize * pix_size;
1359
1360   if (ysize > 0) {
1361     starty = ysize-1;
1362     lasty = -1;
1363     yinc = -1;
1364   }
1365   else {
1366     /* when ysize is -ve it's a top-down image */
1367     ysize = -ysize;
1368     starty = 0;
1369     lasty = ysize;
1370     yinc = 1;
1371   }
1372   y = starty;
1373   if (compression == BI_RGB) {
1374     compression_name = "BI_RGB";
1375     masks = std_masks[pix_size-2];
1376     
1377     /* there's a potential "palette" after the header */
1378     for (i = 0; i < clr_used; ++clr_used) {
1379       char buf[4];
1380       if (i_io_read(ig, buf, 4) != 4) {
1381         i_push_error(0, "skipping colors");
1382         return 0;
1383       }
1384       base_offset += 4;
1385     }
1386   }
1387   else if (compression == BI_BITFIELDS) {
1388     int pos;
1389     unsigned bits;
1390     compression_name = "BI_BITFIELDS";
1391
1392     for (i = 0; i < 3; ++i) {
1393       i_packed_t rmask;
1394       if (!read_packed(ig, "V", &rmask)) {
1395         i_push_error(0, "reading pixel masks");
1396         return 0;
1397       }
1398       if (rmask == 0) {
1399         im_push_errorf(aIMCTX, 0, "Zero mask for channel %d", i);
1400         return NULL;
1401       }
1402       masks.masks[i] = rmask;
1403       /* work out a shift for the mask */
1404       pos = 0;
1405       bits = masks.masks[i];
1406       while (!(bits & 1)) {
1407         ++pos;
1408         bits >>= 1;
1409       }
1410       masks.shifts[i] = pos;
1411       pos = 0;
1412       while (bits & 1) {
1413         ++pos;
1414         bits >>= 1;
1415       }
1416       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     base_offset += 3 * 4;
1421   }
1422   else {
1423     im_push_errorf(aIMCTX, 0, "unknown 24-bit BMP compression (%d)", compression);
1424     return NULL;
1425   }
1426
1427   if (offbits < base_offset) {
1428     im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
1429     return NULL;
1430   }
1431
1432   if (offbits > base_offset) {
1433     /* this will be slow if the offset is large, but that should be
1434        rare */
1435     char buffer;
1436     while (base_offset < offbits) {
1437       if (i_io_read(ig, &buffer, 1) != 1) {
1438         i_push_error(0, "failed skipping to image data offset");
1439         return NULL;
1440       }
1441       ++base_offset;
1442     }
1443   }
1444   
1445   im = i_img_empty(NULL, xsize, ysize);
1446   if (!im)
1447     return NULL;
1448
1449   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   bytes = sizeof(i_color) * xsize;
1454   if (bytes / sizeof(i_color) != xsize) {
1455     i_img_destroy(im);
1456     i_push_error(0, "integer overflow calculating buffer size");
1457     return NULL;
1458   }
1459   line = mymalloc(bytes); /* checked 29jun05 tonyc */
1460   while (y != lasty) {
1461     p = line;
1462     for (x = 0; x < xsize; ++x) {
1463       i_packed_t pixel;
1464       if (!read_packed(ig, unpack_code, &pixel)) {
1465         myfree(line);
1466         if (allow_incomplete) {
1467           i_tags_setn(&im->tags, "i_incomplete", 1);
1468           i_tags_setn(&im->tags, "i_lines_read", abs(starty - y));
1469           return im;
1470         }
1471         else {
1472           i_push_error(0, "failed reading image data");
1473           i_img_destroy(im);
1474           return NULL;
1475         }
1476       }
1477       for (i = 0; i < 3; ++i) {
1478         int sample = (pixel & masks.masks[i]) >> masks.shifts[i];
1479         int bits = masks.bits[i];
1480         if (bits < 8) {
1481           sample = (sample * samp_converts[bits-1].mult) >> samp_converts[bits-1].shift;
1482         }
1483         else if (bits) {
1484           sample >>= bits - 8;
1485         }
1486         p->channel[i] = sample;
1487       }
1488       ++p;
1489     }
1490     i_plin(im, 0, xsize, y, line);
1491     if (extras)
1492       i_io_read(ig, junk, extras);
1493     y += yinc;
1494   }
1495   myfree(line);
1496
1497   return im;
1498 }
1499
1500 /*
1501 =head1 SEE ALSO
1502
1503 Imager(3)
1504
1505 =head1 AUTHOR
1506
1507 Tony Cook <tony@develop-help.com>
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 */