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