]> git.imager.perl.org - imager.git/blob - bmp.c
avoid a possible sign-extension for offsets/sizes in SGI
[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         return 0;
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         return 0;
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         return 0;
263       *p = buf[0];
264       break;
265
266     case 'c':
267       if (i_io_read(ig, buf, 1) != 1)
268         return 0;
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         return 0;
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   return 1;
286 }
287
288 /*
289 =item write_packed(ig, format, ...)
290
291 Writes packed data to the specified io_glue.
292
293 Returns non-zero on success.
294
295 =cut
296 */
297
298 static int
299 write_packed(io_glue *ig, char *format, ...) {
300   unsigned char buf[4];
301   va_list ap;
302   int i;
303
304   va_start(ap, format);
305
306   while (*format) {
307     i = va_arg(ap, i_upacked_t);
308
309     switch (*format) {
310     case 'v':
311       buf[0] = i & 255;
312       buf[1] = i / 256;
313       if (i_io_write(ig, buf, 2) == -1)
314         goto fail;
315       break;
316
317     case 'V':
318       buf[0] = i & 0xFF;
319       buf[1] = (i >> 8) & 0xFF;
320       buf[2] = (i >> 16) & 0xFF;
321       buf[3] = (i >> 24) & 0xFF;
322       if (i_io_write(ig, buf, 4) == -1)
323         goto fail;
324       break;
325
326     case 'C':
327     case 'c':
328       buf[0] = i & 0xFF;
329       if (i_io_write(ig, buf, 1) == -1)
330         goto fail;
331       break;
332
333     default:
334       {
335         dIMCTXio(ig);
336         im_fatal(aIMCTX, 1, "Unknown write_packed format code 0x%02x", *format);
337       }
338     }
339     ++format;
340   }
341   va_end(ap);
342
343   return 1;
344
345  fail:
346   va_end(ap);
347   return 0;
348 }
349
350 /*
351 =item write_bmphead(ig, im, bit_count, data_size)
352
353 Writes a Windows BMP header to the file.
354
355 Returns non-zero on success.
356
357 =cut
358 */
359
360 static
361 int write_bmphead(io_glue *ig, i_img *im, int bit_count, int data_size) {
362   double xres, yres;
363   int got_xres, got_yres, aspect_only;
364   int colors_used = 0;
365   int offset = FILEHEAD_SIZE + INFOHEAD_SIZE;
366   dIMCTXim(im);
367
368   if (im->xsize > SIGNMAX32 || im->ysize > SIGNMAX32) {
369     i_push_error(0, "image too large to write to BMP");
370     return 0;
371   }
372
373   got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
374   got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
375   if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
376     aspect_only = 0;
377   if (!got_xres) {
378     if (!got_yres)
379       xres = yres = 72;
380     else
381       xres = yres;
382   }
383   else {
384     if (!got_yres)
385       yres = xres;
386   }
387   if (xres <= 0 || yres <= 0)
388     xres = yres = 72;
389   if (aspect_only) {
390     /* scale so the smaller value is 72 */
391     double ratio;
392     if (xres < yres) {
393       ratio = 72.0 / xres;
394     }
395     else {
396       ratio = 72.0 / yres;
397     }
398     xres *= ratio;
399     yres *= ratio;
400   }
401   /* now to pels/meter */
402   xres *= 100.0/2.54;
403   yres *= 100.0/2.54;
404
405   if (im->type == i_palette_type) {
406     colors_used = i_colorcount(im);
407     offset += 4 * colors_used;
408   }
409
410   if (!write_packed(ig, "CCVvvVVVVvvVVVVVV", 'B', 'M', 
411                     (i_upacked_t)(data_size+offset), 
412                     (i_upacked_t)0, (i_upacked_t)0, (i_upacked_t)offset,
413                     (i_upacked_t)INFOHEAD_SIZE, (i_upacked_t)im->xsize,
414                     (i_upacked_t)im->ysize, (i_upacked_t)1, 
415                     (i_upacked_t)bit_count, (i_upacked_t)BI_RGB,
416                     (i_upacked_t)data_size, 
417                     (i_upacked_t)(xres+0.5), (i_upacked_t)(yres+0.5), 
418                     (i_upacked_t)colors_used, (i_upacked_t)colors_used)){
419     i_push_error(0, "cannot write bmp header");
420     return 0;
421   }
422   if (im->type == i_palette_type) {
423     int i;
424     i_color c;
425
426     for (i = 0; i < colors_used; ++i) {
427       i_getcolors(im, i, &c, 1);
428       if (im->channels >= 3) {
429         if (!write_packed(ig, "CCCC", (i_upacked_t)(c.channel[2]), 
430                           (i_upacked_t)(c.channel[1]), 
431                           (i_upacked_t)(c.channel[0]), (i_upacked_t)0)) {
432           i_push_error(0, "cannot write palette entry");
433           return 0;
434         }
435       }
436       else {
437         i_upacked_t v = c.channel[0];
438         if (!write_packed(ig, "CCCC", v, v, v, 0)) {
439           i_push_error(0, "cannot write palette entry");
440           return 0;
441         }
442       }
443     }
444   }
445
446   return 1;
447 }
448
449 /*
450 =item write_1bit_data(ig, im)
451
452 Writes the image data as a 1-bit/pixel image.
453
454 Returns non-zero on success.
455
456 =cut
457 */
458 static int
459 write_1bit_data(io_glue *ig, i_img *im) {
460   i_palidx *line;
461   unsigned char *packed;
462   int byte;
463   int mask;
464   unsigned char *out;
465   int line_size = (im->xsize+7) / 8;
466   int x, y;
467   int unpacked_size;
468   dIMCTXim(im);
469
470   /* round up to nearest multiple of four */
471   line_size = (line_size + 3) / 4 * 4;
472
473   if (!write_bmphead(ig, im, 1, line_size * im->ysize))
474     return 0;
475
476   /* this shouldn't be an issue, but let's be careful */
477   unpacked_size = im->xsize + 8;
478   if (unpacked_size < im->xsize) {
479     i_push_error(0, "integer overflow during memory allocation");
480     return 0;
481   }
482   line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
483   memset(line + im->xsize, 0, 8);
484
485   /* size allocated here is always much smaller than xsize, hence
486      can't overflow int */
487   packed = mymalloc(line_size); /* checked 29jun05 tonyc */
488   memset(packed, 0, line_size);
489   
490   for (y = im->ysize-1; y >= 0; --y) {
491     i_gpal(im, 0, im->xsize, y, line);
492     mask = 0x80;
493     byte = 0;
494     out = packed;
495     for (x = 0; x < im->xsize; ++x) {
496       if (line[x])
497         byte |= mask;
498       if ((mask >>= 1) == 0) {
499         *out++ = byte;
500         byte = 0;
501         mask = 0x80;
502       }
503     }
504     if (mask != 0x80) {
505       *out++ = byte;
506     }
507     if (i_io_write(ig, packed, line_size) < 0) {
508       myfree(packed);
509       myfree(line);
510       i_push_error(0, "writing 1 bit/pixel packed data");
511       return 0;
512     }
513   }
514   myfree(packed);
515   myfree(line);
516
517   if (i_io_close(ig))
518     return 0;
519
520   return 1;
521 }
522
523 /*
524 =item write_4bit_data(ig, im)
525
526 Writes the image data as a 4-bit/pixel image.
527
528 Returns non-zero on success.
529
530 =cut
531 */
532 static int
533 write_4bit_data(io_glue *ig, i_img *im) {
534   i_palidx *line;
535   unsigned char *packed;
536   unsigned char *out;
537   int line_size = (im->xsize+1) / 2;
538   int x, y;
539   int unpacked_size;
540   dIMCTXim(im);
541
542   /* round up to nearest multiple of four */
543   line_size = (line_size + 3) / 4 * 4;
544
545   if (!write_bmphead(ig, im, 4, line_size * im->ysize))
546     return 0;
547
548   /* this shouldn't be an issue, but let's be careful */
549   unpacked_size = im->xsize + 2;
550   if (unpacked_size < im->xsize) {
551     i_push_error(0, "integer overflow during memory allocation");
552     return 0;
553   }
554   line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
555   memset(line + im->xsize, 0, 2);
556   
557   /* size allocated here is always much smaller than xsize, hence
558      can't overflow int */
559   packed = mymalloc(line_size); /* checked 29jun05 tonyc */
560   memset(packed, 0, line_size);
561   
562   for (y = im->ysize-1; y >= 0; --y) {
563     i_gpal(im, 0, im->xsize, y, line);
564     out = packed;
565     for (x = 0; x < im->xsize; x += 2) {
566       *out++ = (line[x] << 4) + line[x+1];
567     }
568     if (i_io_write(ig, packed, line_size) < 0) {
569       myfree(packed);
570       myfree(line);
571       i_push_error(0, "writing 4 bit/pixel packed data");
572       return 0;
573     }
574   }
575   myfree(packed);
576   myfree(line);
577
578   if (i_io_close(ig))
579     return 0;
580
581   return 1;
582 }
583
584 /*
585 =item write_8bit_data(ig, im)
586
587 Writes the image data as a 8-bit/pixel image.
588
589 Returns non-zero on success.
590
591 =cut
592 */
593 static int
594 write_8bit_data(io_glue *ig, i_img *im) {
595   i_palidx *line;
596   int line_size = im->xsize;
597   int y;
598   int unpacked_size;
599   dIMCTXim(im);
600
601   /* round up to nearest multiple of four */
602   line_size = (line_size + 3) / 4 * 4;
603
604   if (!write_bmphead(ig, im, 8, line_size * im->ysize))
605     return 0;
606
607   /* this shouldn't be an issue, but let's be careful */
608   unpacked_size = im->xsize + 4;
609   if (unpacked_size < im->xsize) {
610     i_push_error(0, "integer overflow during memory allocation");
611     return 0;
612   }
613   line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
614   memset(line + im->xsize, 0, 4);
615   
616   for (y = im->ysize-1; y >= 0; --y) {
617     i_gpal(im, 0, im->xsize, y, line);
618     if (i_io_write(ig, line, line_size) < 0) {
619       myfree(line);
620       i_push_error(0, "writing 8 bit/pixel packed data");
621       return 0;
622     }
623   }
624   myfree(line);
625
626   if (i_io_close(ig))
627     return 0;
628
629   return 1;
630 }
631
632 /*
633 =item write_24bit_data(ig, im)
634
635 Writes the image data as a 24-bit/pixel image.
636
637 Returns non-zero on success.
638
639 =cut
640 */
641 static int
642 write_24bit_data(io_glue *ig, i_img *im) {
643   unsigned char *samples;
644   int y;
645   int line_size = 3 * im->xsize;
646   i_color bg;
647   dIMCTXim(im);
648
649   i_get_file_background(im, &bg);
650
651   /* just in case we implement a direct format with 2bytes/pixel
652      (unlikely though) */
653   if (line_size / 3 != im->xsize) {
654     i_push_error(0, "integer overflow during memory allocation");
655     return 0;
656   }
657   
658   line_size = (line_size + 3) / 4 * 4;
659   
660   if (!write_bmphead(ig, im, 24, line_size * im->ysize))
661     return 0;
662   samples = mymalloc(4 * im->xsize);
663   memset(samples, 0, line_size);
664   for (y = im->ysize-1; y >= 0; --y) {
665     unsigned char *samplep = samples;
666     int x;
667     i_gsamp_bg(im, 0, im->xsize, y, samples, 3, &bg);
668     for (x = 0; x < im->xsize; ++x) {
669       unsigned char tmp = samplep[2];
670       samplep[2] = samplep[0];
671       samplep[0] = tmp;
672       samplep += 3;
673     }
674     if (i_io_write(ig, samples, line_size) < 0) {
675       i_push_error(0, "writing image data");
676       myfree(samples);
677       return 0;
678     }
679   }
680   myfree(samples);
681
682   if (i_io_close(ig))
683     return 0;
684
685   return 1;
686 }
687
688 /*
689 =item read_bmp_pal(ig, im, count)
690
691 Reads count palette entries from the file and add them to the image.
692
693 Returns non-zero on success.
694
695 =cut
696 */
697 static int
698 read_bmp_pal(io_glue *ig, i_img *im, int count) {
699   int i;
700   i_packed_t r, g, b, x;
701   i_color c;
702   dIMCTXio(ig);
703   
704   for (i = 0; i < count; ++i) {
705     if (!read_packed(ig, "CCCC", &b, &g, &r, &x)) {
706       i_push_error(0, "reading BMP palette");
707       return 0;
708     }
709     c.channel[0] = r;
710     c.channel[1] = g;
711     c.channel[2] = b;
712     if (i_addcolors(im, &c, 1) < 0) {
713       i_push_error(0, "out of space in image palette");
714       return 0;
715     }
716   }
717   
718   return 1;
719 }
720
721 /*
722 =item read_1bit_bmp(ig, xsize, ysize, clr_used, compression, offbits)
723
724 Reads in the palette and image data for a 1-bit/pixel image.
725
726 Returns the image or NULL.
727
728 =cut
729 */
730 static i_img *
731 read_1bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used, 
732               int compression, long offbits, int allow_incomplete) {
733   i_img *im;
734   int x, y, lasty, yinc, start_y;
735   i_palidx *line, *p;
736   unsigned char *packed;
737   int line_size = (xsize + 7)/8;
738   int bit;
739   unsigned char *in;
740   long base_offset;
741   dIMCTXio(ig);
742
743   if (compression != BI_RGB) {
744     im_push_errorf(aIMCTX, 0, "unknown 1-bit BMP compression (%d)", compression);
745     return NULL;
746   }
747
748   if ((i_img_dim)((i_img_dim_u)xsize + 8) < xsize) { /* if there was overflow */
749     /* we check with 8 because we allocate that much for the decoded 
750        line buffer */
751     i_push_error(0, "integer overflow during memory allocation");
752     return NULL;
753   }
754
755   /* if xsize+7 is ok then (xsize+7)/8 will be and the minor
756      adjustments below won't make it overflow */
757   line_size = (line_size+3) / 4 * 4;
758
759   if (ysize > 0) {
760     start_y = ysize-1;
761     lasty = -1;
762     yinc = -1;
763   }
764   else {
765     /* when ysize is -ve it's a top-down image */
766     ysize = -ysize;
767     start_y = 0;
768     lasty = ysize;
769     yinc = 1;
770   }
771   y = start_y;
772   if (!clr_used)
773     clr_used = 2;
774   if (clr_used < 0 || clr_used > 2) {
775     im_push_errorf(aIMCTX, 0, "out of range colors used (%d)", clr_used);
776     return NULL;
777   }
778
779   base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE + clr_used * 4;
780   if (offbits < base_offset) {
781     im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
782     return NULL;
783   }
784
785   im = i_img_pal_new(xsize, ysize, 3, 256);
786   if (!im)
787     return NULL;
788   if (!read_bmp_pal(ig, im, clr_used)) {
789     i_img_destroy(im);
790     return NULL;
791   }
792
793   if (offbits > base_offset) {
794     /* this will be slow if the offset is large, but that should be
795        rare */
796     char buffer;
797     while (base_offset < offbits) {
798       if (i_io_read(ig, &buffer, 1) != 1) {
799         i_img_destroy(im);
800         i_push_error(0, "failed skipping to image data offset");
801         return NULL;
802       }
803       ++base_offset;
804     }
805   }
806   
807   i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
808
809   packed = mymalloc(line_size); /* checked 29jun05 tonyc */
810   line = mymalloc(xsize+8); /* checked 29jun05 tonyc */
811   while (y != lasty) {
812     if (i_io_read(ig, packed, line_size) != line_size) {
813       myfree(packed);
814       myfree(line);
815       if (allow_incomplete) {
816         i_tags_setn(&im->tags, "i_incomplete", 1);
817         i_tags_setn(&im->tags, "i_lines_read", abs(start_y - y));
818         return im;
819       }
820       else {
821         i_push_error(0, "failed reading 1-bit bmp data");
822         i_img_destroy(im);
823         return NULL;
824       }
825     }
826     in = packed;
827     bit = 0x80;
828     p = line;
829     for (x = 0; x < xsize; ++x) {
830       *p++ = (*in & bit) ? 1 : 0;
831       bit >>= 1;
832       if (!bit) {
833         ++in;
834         bit = 0x80;
835       }
836     }
837     i_ppal(im, 0, xsize, y, line);
838     y += yinc;
839   }
840
841   myfree(packed);
842   myfree(line);
843   return im;
844 }
845
846 /*
847 =item read_4bit_bmp(ig, xsize, ysize, clr_used, compression)
848
849 Reads in the palette and image data for a 4-bit/pixel image.
850
851 Returns the image or NULL.
852
853 Hopefully this will be combined with the following function at some
854 point.
855
856 =cut
857 */
858 static i_img *
859 read_4bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used, 
860               int compression, long offbits, int allow_incomplete) {
861   i_img *im;
862   int x, y, lasty, yinc;
863   i_palidx *line, *p;
864   unsigned char *packed;
865   int line_size = (xsize + 1)/2;
866   unsigned char *in;
867   int size, i;
868   long base_offset;
869   int starty;
870   dIMCTXio(ig);
871
872   /* line_size is going to be smaller than xsize in most cases (and
873      when it's not, xsize is itself small), and hence not overflow */
874   line_size = (line_size+3) / 4 * 4;
875
876   if (ysize > 0) {
877     starty = ysize-1;
878     lasty = -1;
879     yinc = -1;
880   }
881   else {
882     /* when ysize is -ve it's a top-down image */
883     ysize = -ysize;
884     starty = 0;
885     lasty = ysize;
886     yinc = 1;
887   }
888   y = starty;
889   if (!clr_used)
890     clr_used = 16;
891
892   if (clr_used > 16 || clr_used < 0) {
893     im_push_errorf(aIMCTX, 0, "out of range colors used (%d)", clr_used);
894     return NULL;
895   }
896
897   base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE + clr_used * 4;
898   if (offbits < base_offset) {
899     im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
900     return NULL;
901   }
902
903   im = i_img_pal_new(xsize, ysize, 3, 256);
904   if (!im) /* error should have been pushed already */
905     return NULL;
906   if (!read_bmp_pal(ig, im, clr_used)) {
907     i_img_destroy(im);
908     return NULL;
909   }
910
911   if (offbits > base_offset) {
912     /* this will be slow if the offset is large, but that should be
913        rare */
914     char buffer;
915     while (base_offset < offbits) {
916       if (i_io_read(ig, &buffer, 1) != 1) {
917         i_img_destroy(im);
918         i_push_error(0, "failed skipping to image data offset");
919         return NULL;
920       }
921       ++base_offset;
922     }
923   }
924   
925   if (line_size < 260)
926     packed = mymalloc(260); /* checked 29jun05 tonyc */
927   else
928     packed = mymalloc(line_size); /* checked 29jun05 tonyc */
929   /* xsize won't approach MAXINT */
930   line = mymalloc(xsize+1); /* checked 29jun05 tonyc */
931   if (compression == BI_RGB) {
932     i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
933     while (y != lasty) {
934       if (i_io_read(ig, packed, line_size) != line_size) {
935         myfree(packed);
936         myfree(line);
937         if (allow_incomplete) {
938           i_tags_setn(&im->tags, "i_incomplete", 1);
939           i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
940           return im;
941         }
942         else {
943           i_push_error(0, "failed reading 4-bit bmp data");
944           i_img_destroy(im);
945           return NULL;
946         }
947       }
948       in = packed;
949       p = line;
950       for (x = 0; x < xsize; x+=2) {
951         *p++ = *in >> 4;
952         *p++ = *in & 0x0F;
953         ++in;
954       }
955       i_ppal(im, 0, xsize, y, line);
956       y += yinc;
957     }
958     myfree(packed);
959     myfree(line);
960   }
961   else if (compression == BI_RLE4) {
962     int read_size;
963     int count;
964     i_img_dim xlimit = (xsize + 1) / 2 * 2; /* rounded up */
965
966     i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RLE4", -1, 0);
967     x = 0;
968     while (1) {
969       /* there's always at least 2 bytes in a sequence */
970       if (i_io_read(ig, packed, 2) != 2) {
971         myfree(packed);
972         myfree(line);
973         if (allow_incomplete) {
974           i_tags_setn(&im->tags, "i_incomplete", 1);
975           i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
976           return im;
977         }
978         else {
979           i_push_error(0, "missing data during decompression");
980           i_img_destroy(im);
981           return NULL;
982         }
983       }
984       else if (packed[0]) {
985         int count = packed[0];
986         if (x + count > xlimit) {
987           /* this file is corrupt */
988           myfree(packed);
989           myfree(line);
990           i_push_error(0, "invalid data during decompression");
991           im_log((aIMCTX, 1, "read 4-bit: scanline overflow x %d + count %d vs xlimit %d (y %d)\n",
992                   (int)x, count, (int)xlimit, (int)y));
993           i_img_destroy(im);
994           return NULL;
995         }
996         /* fill in the line */
997         for (i = 0; i < count; i += 2)
998           line[i] = packed[1] >> 4;
999         for (i = 1; i < count; i += 2)
1000           line[i] = packed[1] & 0x0F;
1001         i_ppal(im, x, x+count, y, line);
1002         x += count;
1003       } else {
1004         switch (packed[1]) {
1005         case BMPRLE_ENDOFLINE:
1006           x = 0;
1007           y += yinc;
1008           break;
1009
1010         case BMPRLE_ENDOFBMP:
1011           myfree(packed);
1012           myfree(line);
1013           return im;
1014
1015         case BMPRLE_DELTA:
1016           if (i_io_read(ig, packed, 2) != 2) {
1017             myfree(packed);
1018             myfree(line);
1019             if (allow_incomplete) {
1020               i_tags_setn(&im->tags, "i_incomplete", 1);
1021               i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
1022               return im;
1023             }
1024             else {
1025               i_push_error(0, "missing data during decompression");
1026               i_img_destroy(im);
1027               return NULL;
1028             }
1029           }
1030           x += packed[0];
1031           y += yinc * packed[1];
1032           break;
1033
1034         default:
1035           count = packed[1];
1036           if (x + count > xlimit) {
1037             /* this file is corrupt */
1038             myfree(packed);
1039             myfree(line);
1040             i_push_error(0, "invalid data during decompression");
1041             im_log((aIMCTX, 1, "read 4-bit: scanline overflow (unpacked) x %d + count %d vs xlimit %d (y %d)\n",
1042                   (int)x, count, (int)xlimit, (int)y));
1043             i_img_destroy(im);
1044             return NULL;
1045           }
1046           size = (count + 1) / 2;
1047           read_size = (size+1) / 2 * 2;
1048           if (i_io_read(ig, packed, read_size) != read_size) {
1049             myfree(packed);
1050             myfree(line);
1051             if (allow_incomplete) {
1052               i_tags_setn(&im->tags, "i_incomplete", 1);
1053               i_tags_setn(&im->tags, "i_lines_read", abs(y - starty));
1054               return im;
1055             }
1056             else {
1057               i_push_error(0, "missing data during decompression");
1058               i_img_destroy(im);
1059               return NULL;
1060             }
1061           }
1062           for (i = 0; i < size; ++i) {
1063             line[0] = packed[i] >> 4;
1064             line[1] = packed[i] & 0xF;
1065             i_ppal(im, x, x+2, y, line);
1066             x += 2;
1067           }
1068           break;
1069         }
1070       }
1071     }
1072   }
1073   else { /*if (compression == BI_RLE4) {*/
1074     myfree(packed);
1075     myfree(line);
1076     im_push_errorf(aIMCTX, 0, "unknown 4-bit BMP compression (%d)", compression);
1077     i_img_destroy(im);
1078     return NULL;
1079   }
1080
1081   return im;
1082 }
1083
1084 /*
1085 =item read_8bit_bmp(ig, xsize, ysize, clr_used, compression, allow_incomplete)
1086
1087 Reads in the palette and image data for a 8-bit/pixel image.
1088
1089 Returns the image or NULL.
1090
1091 =cut
1092 */
1093 static i_img *
1094 read_8bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used, 
1095               int compression, long offbits, int allow_incomplete) {
1096   i_img *im;
1097   int x, y, lasty, yinc, start_y;
1098   i_palidx *line;
1099   int line_size = xsize;
1100   long base_offset;
1101   dIMCTXio(ig);
1102
1103   line_size = (line_size+3) / 4 * 4;
1104   if (line_size < xsize) { /* if it overflowed (unlikely, but check) */
1105     i_push_error(0, "integer overflow during memory allocation");
1106     return NULL;
1107   }
1108
1109   if (ysize > 0) {
1110     start_y = ysize-1;
1111     lasty = -1;
1112     yinc = -1;
1113   }
1114   else {
1115     /* when ysize is -ve it's a top-down image */
1116     ysize = -ysize;
1117     start_y = 0;
1118     lasty = ysize;
1119     yinc = 1;
1120   }
1121   y = start_y;
1122   if (!clr_used)
1123     clr_used = 256;
1124   if (clr_used > 256 || clr_used < 0) {
1125     im_push_errorf(aIMCTX, 0, "out of range colors used (%d)", clr_used);
1126     return NULL;
1127   }
1128
1129   base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE + clr_used * 4;
1130   if (offbits < base_offset) {
1131     im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
1132     return NULL;
1133   }
1134
1135   im = i_img_pal_new(xsize, ysize, 3, 256);
1136   if (!im)
1137     return NULL;
1138   if (!read_bmp_pal(ig, im, clr_used)) {
1139     i_img_destroy(im);
1140     return NULL;
1141   }
1142
1143   if (offbits > base_offset) {
1144     /* this will be slow if the offset is large, but that should be
1145        rare */
1146     char buffer;
1147     while (base_offset < offbits) {
1148       if (i_io_read(ig, &buffer, 1) != 1) {
1149         i_img_destroy(im);
1150         i_push_error(0, "failed skipping to image data offset");
1151         return NULL;
1152       }
1153       ++base_offset;
1154     }
1155   }
1156   
1157   line = mymalloc(line_size); /* checked 29jun05 tonyc */
1158   if (compression == BI_RGB) {
1159     i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
1160     while (y != lasty) {
1161       if (i_io_read(ig, line, line_size) != line_size) {
1162         myfree(line);
1163         if (allow_incomplete) {
1164           i_tags_setn(&im->tags, "i_incomplete", 1);
1165           i_tags_setn(&im->tags, "i_lines_read", abs(start_y - y));
1166           return im;
1167         }
1168         else {
1169           i_push_error(0, "failed reading 8-bit bmp data");
1170           i_img_destroy(im);
1171           return NULL;
1172         }
1173       }
1174       i_ppal(im, 0, xsize, y, line);
1175       y += yinc;
1176     }
1177     myfree(line);
1178   }
1179   else if (compression == BI_RLE8) {
1180     int read_size;
1181     int count;
1182     unsigned char packed[2];
1183
1184     i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RLE8", -1, 0);
1185     x = 0;
1186     while (1) {
1187       /* there's always at least 2 bytes in a sequence */
1188       if (i_io_read(ig, packed, 2) != 2) {
1189         myfree(line);
1190         if (allow_incomplete) {
1191           i_tags_setn(&im->tags, "i_incomplete", 1);
1192           i_tags_setn(&im->tags, "i_lines_read", abs(start_y-y));
1193           return im;
1194         }
1195         else {
1196           i_push_error(0, "missing data during decompression");
1197           i_img_destroy(im);
1198           return NULL;
1199         }
1200       }
1201       if (packed[0]) {
1202         if (x + packed[0] > xsize) {
1203           /* this file isn't incomplete, it's corrupt */
1204           myfree(line);
1205           i_push_error(0, "invalid data during decompression");
1206           i_img_destroy(im);
1207           return NULL;
1208         }
1209         memset(line, packed[1], packed[0]);
1210         i_ppal(im, x, x+packed[0], y, line);
1211         x += packed[0];
1212       } else {
1213         switch (packed[1]) {
1214         case BMPRLE_ENDOFLINE:
1215           x = 0;
1216           y += yinc;
1217           break;
1218
1219         case BMPRLE_ENDOFBMP:
1220           myfree(line);
1221           return im;
1222
1223         case BMPRLE_DELTA:
1224           if (i_io_read(ig, packed, 2) != 2) {
1225             myfree(line);
1226             if (allow_incomplete) {
1227               i_tags_setn(&im->tags, "i_incomplete", 1);
1228               i_tags_setn(&im->tags, "i_lines_read", abs(start_y-y));
1229               return im;
1230             }
1231             else {
1232               i_push_error(0, "missing data during decompression");
1233               i_img_destroy(im);
1234               return NULL;
1235             }
1236           }
1237           x += packed[0];
1238           y += yinc * packed[1];
1239           break;
1240
1241         default:
1242           count = packed[1];
1243           if (x + count > xsize) {
1244             /* runs shouldn't cross a line boundary */
1245             /* this file isn't incomplete, it's corrupt */
1246             myfree(line);
1247             i_push_error(0, "invalid data during decompression");
1248             i_img_destroy(im);
1249             return NULL;
1250           }
1251           read_size = (count+1) / 2 * 2;
1252           if (i_io_read(ig, line, read_size) != read_size) {
1253             myfree(line);
1254             if (allow_incomplete) {
1255               i_tags_setn(&im->tags, "i_incomplete", 1);
1256               i_tags_setn(&im->tags, "i_lines_read", abs(start_y-y));
1257               return im;
1258             }
1259             else {
1260               i_push_error(0, "missing data during decompression");
1261               i_img_destroy(im);
1262               return NULL;
1263             }
1264           }
1265           i_ppal(im, x, x+count, y, line);
1266           x += count;
1267           break;
1268         }
1269       }
1270     }
1271   }
1272   else { 
1273     myfree(line);
1274     im_push_errorf(aIMCTX, 0, "unknown 8-bit BMP compression (%d)", compression);
1275     i_img_destroy(im);
1276     return NULL;
1277   }
1278
1279   return im;
1280 }
1281
1282 struct bm_masks {
1283   unsigned masks[3];
1284   int shifts[3];
1285   int bits[3];
1286 };
1287 static struct bm_masks std_masks[] =
1288 {
1289   { /* 16-bit */
1290     { 0076000, 00001740, 00000037, },
1291     { 10, 5, 0, },
1292     { 5, 5, 5, }
1293   },
1294   { /* 24-bit */
1295     { 0xFF0000, 0x00FF00, 0x0000FF, },
1296     {       16,        8,        0, },
1297     {        8,        8,        8, },
1298   },
1299   { /* 32-bit */
1300     { 0xFF0000, 0x00FF00, 0x0000FF, },
1301     {       16,        8,        0, },
1302     {        8,        8,        8, },
1303   },
1304 };
1305
1306 /* multiplier and shift for converting from N bits to 8 bits */
1307 struct bm_sampconverts {
1308   int mult;
1309   int shift;
1310 };
1311 static struct bm_sampconverts samp_converts[] = {
1312   { 0xff, 0 }, /* 1 bit samples */
1313   { 0x55, 0 },
1314   { 0111, 1 },
1315   { 0x11, 0 },
1316   { 0x21, 2 },
1317   { 0x41, 4 },
1318   { 0x81, 6 }  /* 7 bit samples */
1319 };
1320
1321 /*
1322 =item read_direct_bmp(ig, xsize, ysize, bit_count, clr_used, compression, allow_incomplete)
1323
1324 Skips the palette and reads in the image data for a direct colour image.
1325
1326 Returns the image or NULL.
1327
1328 =cut
1329 */
1330 static i_img *
1331 read_direct_bmp(io_glue *ig, int xsize, int ysize, int bit_count, 
1332                 int clr_used, int compression, long offbits, 
1333                 int allow_incomplete) {
1334   i_img *im;
1335   int x, y, starty, lasty, yinc;
1336   i_color *line, *p;
1337   int pix_size = bit_count / 8;
1338   int line_size = xsize * pix_size;
1339   struct bm_masks masks;
1340   char unpack_code[2] = "";
1341   int i;
1342   int extras;
1343   char junk[4];
1344   const char *compression_name;
1345   int bytes;
1346   long base_offset = FILEHEAD_SIZE + INFOHEAD_SIZE;
1347   dIMCTXio(ig);
1348   
1349   unpack_code[0] = *("v3V"+pix_size-2);
1350   unpack_code[1] = '\0';
1351
1352   line_size = (line_size+3) / 4 * 4;
1353   extras = line_size - xsize * pix_size;
1354
1355   if (ysize > 0) {
1356     starty = ysize-1;
1357     lasty = -1;
1358     yinc = -1;
1359   }
1360   else {
1361     /* when ysize is -ve it's a top-down image */
1362     ysize = -ysize;
1363     starty = 0;
1364     lasty = ysize;
1365     yinc = 1;
1366   }
1367   y = starty;
1368   if (compression == BI_RGB) {
1369     compression_name = "BI_RGB";
1370     masks = std_masks[pix_size-2];
1371     
1372     /* there's a potential "palette" after the header */
1373     for (i = 0; i < clr_used; ++clr_used) {
1374       char buf[4];
1375       if (i_io_read(ig, buf, 4) != 4) {
1376         i_push_error(0, "skipping colors");
1377         return 0;
1378       }
1379       base_offset += 4;
1380     }
1381   }
1382   else if (compression == BI_BITFIELDS) {
1383     int pos;
1384     unsigned bits;
1385     compression_name = "BI_BITFIELDS";
1386
1387     for (i = 0; i < 3; ++i) {
1388       i_packed_t rmask;
1389       if (!read_packed(ig, "V", &rmask)) {
1390         i_push_error(0, "reading pixel masks");
1391         return 0;
1392       }
1393       if (rmask == 0) {
1394         im_push_errorf(aIMCTX, 0, "Zero mask for channel %d", i);
1395         return NULL;
1396       }
1397       masks.masks[i] = rmask;
1398       /* work out a shift for the mask */
1399       pos = 0;
1400       bits = masks.masks[i];
1401       while (!(bits & 1)) {
1402         ++pos;
1403         bits >>= 1;
1404       }
1405       masks.shifts[i] = pos;
1406       pos = 0;
1407       while (bits & 1) {
1408         ++pos;
1409         bits >>= 1;
1410       }
1411       masks.bits[i] = pos;
1412       /*fprintf(stderr, "%d: mask %08x shift %d bits %d\n", i, masks.masks[i], masks.shifts[i], masks.bits[i]);*/
1413     }
1414     /* account for the masks */
1415     base_offset += 3 * 4;
1416   }
1417   else {
1418     im_push_errorf(aIMCTX, 0, "unknown 24-bit BMP compression (%d)", compression);
1419     return NULL;
1420   }
1421
1422   if (offbits < base_offset) {
1423     im_push_errorf(aIMCTX, 0, "image data offset too small (%ld)", offbits);
1424     return NULL;
1425   }
1426
1427   if (offbits > base_offset) {
1428     /* this will be slow if the offset is large, but that should be
1429        rare */
1430     char buffer;
1431     while (base_offset < offbits) {
1432       if (i_io_read(ig, &buffer, 1) != 1) {
1433         i_push_error(0, "failed skipping to image data offset");
1434         return NULL;
1435       }
1436       ++base_offset;
1437     }
1438   }
1439   
1440   im = i_img_empty(NULL, xsize, ysize);
1441   if (!im)
1442     return NULL;
1443
1444   i_tags_add(&im->tags, "bmp_compression_name", 0, compression_name, -1, 0);
1445
1446   /* I wasn't able to make this overflow in testing, but better to be
1447      safe */
1448   bytes = sizeof(i_color) * xsize;
1449   if (bytes / sizeof(i_color) != xsize) {
1450     i_img_destroy(im);
1451     i_push_error(0, "integer overflow calculating buffer size");
1452     return NULL;
1453   }
1454   line = mymalloc(bytes); /* checked 29jun05 tonyc */
1455   while (y != lasty) {
1456     p = line;
1457     for (x = 0; x < xsize; ++x) {
1458       i_packed_t pixel;
1459       if (!read_packed(ig, unpack_code, &pixel)) {
1460         myfree(line);
1461         if (allow_incomplete) {
1462           i_tags_setn(&im->tags, "i_incomplete", 1);
1463           i_tags_setn(&im->tags, "i_lines_read", abs(starty - y));
1464           return im;
1465         }
1466         else {
1467           i_push_error(0, "failed reading image data");
1468           i_img_destroy(im);
1469           return NULL;
1470         }
1471       }
1472       for (i = 0; i < 3; ++i) {
1473         int sample = (pixel & masks.masks[i]) >> masks.shifts[i];
1474         int bits = masks.bits[i];
1475         if (bits < 8) {
1476           sample = (sample * samp_converts[bits-1].mult) >> samp_converts[bits-1].shift;
1477         }
1478         else if (bits) {
1479           sample >>= bits - 8;
1480         }
1481         p->channel[i] = sample;
1482       }
1483       ++p;
1484     }
1485     i_plin(im, 0, xsize, y, line);
1486     if (extras)
1487       i_io_read(ig, junk, extras);
1488     y += yinc;
1489   }
1490   myfree(line);
1491
1492   return im;
1493 }
1494
1495 /*
1496 =head1 SEE ALSO
1497
1498 Imager(3)
1499
1500 =head1 AUTHOR
1501
1502 Tony Cook <tony@develop-help.com>
1503
1504 =head1 RESTRICTIONS
1505
1506 Cannot save as compressed BMP.
1507
1508 =head1 BUGS
1509
1510 Doesn't handle OS/2 bitmaps.
1511
1512 16-bit/pixel images haven't been tested.  (I need an image).
1513
1514 BI_BITFIELDS compression hasn't been tested (I need an image).
1515
1516 The header handling for paletted images needs to be refactored
1517
1518 =cut
1519 */