1 /* bmpread.c    reads any bitmap I could get for testing */
2 /* Alexander.Schulz@stud.uni-karlsruhe.de                */
3 
4 /*
5  * GIMP - The GNU Image Manipulation Program
6  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  * ----------------------------------------------------------------------------
21  */
22 
23 #include "config.h"
24 
25 #include <errno.h>
26 #include <string.h>
27 
28 #include <glib/gstdio.h>
29 
30 #include <libgimp/gimp.h>
31 
32 #include "bmp.h"
33 #include "bmp-load.h"
34 
35 #include "libgimp/stdplugins-intl.h"
36 
37 
38 #if !defined(WIN32) || defined(__MINGW32__)
39 #define BI_RGB            0
40 #define BI_RLE8           1
41 #define BI_RLE4           2
42 #define BI_BITFIELDS      3
43 #define BI_ALPHABITFIELDS 4
44 #endif
45 
46 
47 static gint32 ReadImage (FILE                 *fd,
48                          const gchar          *filename,
49                          gint                  width,
50                          gint                  height,
51                          guchar                cmap[256][3],
52                          gint                  ncols,
53                          gint                  bpp,
54                          gint                  compression,
55                          gint                  rowbytes,
56                          gboolean              gray,
57                          const BitmapChannel  *masks,
58                          GError              **error);
59 
60 
61 static void
setMasksDefault(gushort biBitCnt,BitmapChannel * masks)62 setMasksDefault (gushort        biBitCnt,
63                  BitmapChannel *masks)
64 {
65   switch (biBitCnt)
66     {
67     case 32:
68       masks[0].mask      = 0x00ff0000;
69       masks[0].shiftin   = 16;
70       masks[0].max_value = (gfloat)255.0;
71       masks[1].mask      = 0x0000ff00;
72       masks[1].shiftin   = 8;
73       masks[1].max_value = (gfloat)255.0;
74       masks[2].mask      = 0x000000ff;
75       masks[2].shiftin   = 0;
76       masks[2].max_value = (gfloat)255.0;
77       masks[3].mask      = 0x00000000;
78       masks[3].shiftin   = 0;
79       masks[3].max_value = (gfloat)0.0;
80       break;
81 
82     case 24:
83       masks[0].mask      = 0xff0000;
84       masks[0].shiftin   = 16;
85       masks[0].max_value = (gfloat)255.0;
86       masks[1].mask      = 0x00ff00;
87       masks[1].shiftin   = 8;
88       masks[1].max_value = (gfloat)255.0;
89       masks[2].mask      = 0x0000ff;
90       masks[2].shiftin   = 0;
91       masks[2].max_value = (gfloat)255.0;
92       masks[3].mask      = 0x0;
93       masks[3].shiftin   = 0;
94       masks[3].max_value = (gfloat)0.0;
95       break;
96 
97     case 16:
98       masks[0].mask      = 0x7c00;
99       masks[0].shiftin   = 10;
100       masks[0].max_value = (gfloat)31.0;
101       masks[1].mask      = 0x03e0;
102       masks[1].shiftin   = 5;
103       masks[1].max_value = (gfloat)31.0;
104       masks[2].mask      = 0x001f;
105       masks[2].shiftin   = 0;
106       masks[2].max_value = (gfloat)31.0;
107       masks[3].mask      = 0x0;
108       masks[3].shiftin   = 0;
109       masks[3].max_value = (gfloat)0.0;
110       break;
111 
112     default:
113       break;
114     }
115 }
116 
117 static gint32
ToL(const guchar * buffer)118 ToL (const guchar *buffer)
119 {
120   return (buffer[0] | buffer[1] << 8 | buffer[2] << 16 | buffer[3] << 24);
121 }
122 
123 static gint16
ToS(const guchar * buffer)124 ToS (const guchar *buffer)
125 {
126   return (buffer[0] | buffer[1] << 8);
127 }
128 
129 static gboolean
ReadColorMap(FILE * fd,guchar buffer[256][3],gint number,gint size,gboolean * gray)130 ReadColorMap (FILE     *fd,
131               guchar    buffer[256][3],
132               gint      number,
133               gint      size,
134               gboolean *gray)
135 {
136   gint i;
137 
138   *gray = (number > 2);
139 
140   for (i = 0; i < number ; i++)
141     {
142       guchar rgb[4];
143 
144       if (! ReadOK (fd, rgb, size))
145         {
146           g_message (_("Bad colormap"));
147           return FALSE;
148         }
149 
150       /* Bitmap save the colors in another order! But change only once! */
151 
152       buffer[i][0] = rgb[2];
153       buffer[i][1] = rgb[1];
154       buffer[i][2] = rgb[0];
155 
156       *gray = ((*gray) && (rgb[0] == rgb[1]) && (rgb[1] == rgb[2]));
157     }
158 
159   return TRUE;
160 }
161 
162 static gboolean
ReadChannelMasks(guint32 * tmp,BitmapChannel * masks,guint channels)163 ReadChannelMasks (guint32       *tmp,
164                   BitmapChannel *masks,
165                   guint          channels)
166 {
167   gint i;
168 
169   for (i = 0; i < channels; i++)
170     {
171       guint32 mask;
172       gint    nbits, offset, bit;
173 
174       mask = tmp[i];
175       masks[i].mask = mask;
176       nbits = 0;
177       offset = -1;
178 
179       for (bit = 0; bit < 32; bit++)
180         {
181           if (mask & 1)
182             {
183               nbits++;
184               if (offset == -1)
185                 offset = bit;
186             }
187 
188           mask = mask >> 1;
189         }
190 
191       masks[i].shiftin   = offset;
192       masks[i].max_value = (gfloat) ((1 << nbits) - 1);
193 
194 #ifdef DEBUG
195       g_print ("Channel %d mask %08x in %d max_val %d\n",
196                i, masks[i].mask, masks[i].shiftin, (gint)masks[i].max_value);
197 #endif
198     }
199 
200   return TRUE;
201 }
202 
203 gint32
load_image(const gchar * filename,GError ** error)204 load_image (const gchar  *filename,
205             GError      **error)
206 {
207   FILE           *fd;
208   BitmapFileHead  bitmap_file_head;
209   BitmapHead      bitmap_head;
210   guchar          buffer[124];
211   gint            ColormapSize, rowbytes, Maps;
212   gboolean        gray = FALSE;
213   guchar          ColorMap[256][3];
214   gint32          image_ID = -1;
215   gchar           magick[2];
216   BitmapChannel   masks[4];
217 
218   gimp_progress_init_printf (_("Opening '%s'"),
219                              gimp_filename_to_utf8 (filename));
220 
221   fd = g_fopen (filename, "rb");
222 
223   if (!fd)
224     {
225       g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
226                    _("Could not open '%s' for reading: %s"),
227                    gimp_filename_to_utf8 (filename), g_strerror (errno));
228       goto out;
229     }
230 
231   /* It is a File. Now is it a Bitmap? Read the shortest possible header */
232 
233   if (! ReadOK (fd, magick, 2) ||
234       ! (! strncmp (magick, "BA", 2) ||
235          ! strncmp (magick, "BM", 2) ||
236          ! strncmp (magick, "IC", 2) ||
237          ! strncmp (magick, "PT", 2) ||
238          ! strncmp (magick, "CI", 2) ||
239          ! strncmp (magick, "CP", 2)))
240     {
241       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
242                    _("'%s' is not a valid BMP file"),
243                    gimp_filename_to_utf8 (filename));
244       goto out;
245     }
246 
247   while (! strncmp (magick, "BA", 2))
248     {
249       if (! ReadOK (fd, buffer, 12))
250         {
251           g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
252                        _("'%s' is not a valid BMP file"),
253                        gimp_filename_to_utf8 (filename));
254           goto out;
255         }
256 
257       if (! ReadOK (fd, magick, 2))
258         {
259           g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
260                        _("'%s' is not a valid BMP file"),
261                        gimp_filename_to_utf8 (filename));
262           goto out;
263         }
264     }
265 
266   if (! ReadOK (fd, buffer, 12))
267     {
268       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
269                    _("'%s' is not a valid BMP file"),
270                    gimp_filename_to_utf8 (filename));
271       goto out;
272     }
273 
274   /* bring them to the right byteorder. Not too nice, but it should work */
275 
276   bitmap_file_head.bfSize = ToL (&buffer[0x00]);
277   bitmap_file_head.zzHotX = ToS (&buffer[0x04]);
278   bitmap_file_head.zzHotY = ToS (&buffer[0x06]);
279   bitmap_file_head.bfOffs = ToL (&buffer[0x08]);
280 
281   if (! ReadOK (fd, buffer, 4))
282     {
283       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
284                    _("'%s' is not a valid BMP file"),
285                    gimp_filename_to_utf8 (filename));
286       goto out;
287     }
288 
289   bitmap_file_head.biSize = ToL (&buffer[0x00]);
290 
291   /* What kind of bitmap is it? */
292 
293   if (bitmap_file_head.biSize == 12) /* OS/2 1.x ? */
294     {
295       if (! ReadOK (fd, buffer, 8))
296         {
297           g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
298                        _("Error reading BMP file header from '%s'"),
299                        gimp_filename_to_utf8 (filename));
300           goto out;
301         }
302 
303       bitmap_head.biWidth   = ToS (&buffer[0x00]);       /* 12 */
304       bitmap_head.biHeight  = ToS (&buffer[0x02]);       /* 14 */
305       bitmap_head.biPlanes  = ToS (&buffer[0x04]);       /* 16 */
306       bitmap_head.biBitCnt  = ToS (&buffer[0x06]);       /* 18 */
307       bitmap_head.biCompr   = 0;
308       bitmap_head.biSizeIm  = 0;
309       bitmap_head.biXPels   = bitmap_head.biYPels = 0;
310       bitmap_head.biClrUsed = 0;
311       bitmap_head.biClrImp  = 0;
312       bitmap_head.masks[0]  = 0;
313       bitmap_head.masks[1]  = 0;
314       bitmap_head.masks[2]  = 0;
315       bitmap_head.masks[3]  = 0;
316 
317       memset (masks, 0, sizeof (masks));
318       Maps = 3;
319     }
320   else if (bitmap_file_head.biSize == 40) /* Windows 3.x */
321     {
322       if (! ReadOK (fd, buffer, 36))
323         {
324           g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
325                        _("Error reading BMP file header from '%s'"),
326                        gimp_filename_to_utf8 (filename));
327           goto out;
328         }
329 
330       bitmap_head.biWidth   = ToL (&buffer[0x00]);      /* 12 */
331       bitmap_head.biHeight  = ToL (&buffer[0x04]);      /* 16 */
332       bitmap_head.biPlanes  = ToS (&buffer[0x08]);      /* 1A */
333       bitmap_head.biBitCnt  = ToS (&buffer[0x0A]);      /* 1C */
334       bitmap_head.biCompr   = ToL (&buffer[0x0C]);      /* 1E */
335       bitmap_head.biSizeIm  = ToL (&buffer[0x10]);      /* 22 */
336       bitmap_head.biXPels   = ToL (&buffer[0x14]);      /* 26 */
337       bitmap_head.biYPels   = ToL (&buffer[0x18]);      /* 2A */
338       bitmap_head.biClrUsed = ToL (&buffer[0x1C]);      /* 2E */
339       bitmap_head.biClrImp  = ToL (&buffer[0x20]);      /* 32 */
340       bitmap_head.masks[0]  = 0;
341       bitmap_head.masks[1]  = 0;
342       bitmap_head.masks[2]  = 0;
343       bitmap_head.masks[3]  = 0;
344 
345       Maps = 4;
346       memset (masks, 0, sizeof (masks));
347 
348       if (bitmap_head.biCompr == BI_BITFIELDS)
349         {
350 #ifdef DEBUG
351           g_print ("Got BI_BITFIELDS compression\n");
352 #endif
353 
354           if (! ReadOK (fd, buffer, 3 * sizeof (guint32)))
355             {
356               g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
357                            _("Error reading BMP file header from '%s'"),
358                            gimp_filename_to_utf8 (filename));
359               goto out;
360             }
361 
362           bitmap_head.masks[0] = ToL (&buffer[0x00]);
363           bitmap_head.masks[1] = ToL (&buffer[0x04]);
364           bitmap_head.masks[2] = ToL (&buffer[0x08]);
365 
366           ReadChannelMasks (&bitmap_head.masks[0], masks, 3);
367         }
368       else if (bitmap_head.biCompr == BI_RGB)
369         {
370 #ifdef DEBUG
371           g_print ("Got BI_RGB compression\n");
372 #endif
373 
374           setMasksDefault (bitmap_head.biBitCnt, masks);
375         }
376       else if ((bitmap_head.biCompr != BI_RLE4) &&
377                (bitmap_head.biCompr != BI_RLE8))
378         {
379           /* BI_ALPHABITFIELDS, etc. */
380           g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
381                        _("Unsupported compression (%u) in BMP file from '%s'"),
382                        bitmap_head.biCompr,
383                        gimp_filename_to_utf8 (filename));
384         }
385 
386 #ifdef DEBUG
387       g_print ("Got BI_RLE4 or BI_RLE8 compression\n");
388 #endif
389     }
390   else if (bitmap_file_head.biSize >= 56 &&
391            bitmap_file_head.biSize <= 64)
392     {
393       /* enhanced Windows format with bit masks */
394 
395       if (! ReadOK (fd, buffer, bitmap_file_head.biSize - 4))
396         {
397           g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
398                        _("Error reading BMP file header from '%s'"),
399                        gimp_filename_to_utf8 (filename));
400           goto out;
401         }
402 
403       bitmap_head.biWidth   = ToL (&buffer[0x00]);       /* 12 */
404       bitmap_head.biHeight  = ToL (&buffer[0x04]);       /* 16 */
405       bitmap_head.biPlanes  = ToS (&buffer[0x08]);       /* 1A */
406       bitmap_head.biBitCnt  = ToS (&buffer[0x0A]);       /* 1C */
407       bitmap_head.biCompr   = ToL (&buffer[0x0C]);       /* 1E */
408       bitmap_head.biSizeIm  = ToL (&buffer[0x10]);       /* 22 */
409       bitmap_head.biXPels   = ToL (&buffer[0x14]);       /* 26 */
410       bitmap_head.biYPels   = ToL (&buffer[0x18]);       /* 2A */
411       bitmap_head.biClrUsed = ToL (&buffer[0x1C]);       /* 2E */
412       bitmap_head.biClrImp  = ToL (&buffer[0x20]);       /* 32 */
413       bitmap_head.masks[0]  = ToL (&buffer[0x24]);       /* 36 */
414       bitmap_head.masks[1]  = ToL (&buffer[0x28]);       /* 3A */
415       bitmap_head.masks[2]  = ToL (&buffer[0x2C]);       /* 3E */
416       bitmap_head.masks[3]  = ToL (&buffer[0x30]);       /* 42 */
417 
418       Maps = 4;
419       ReadChannelMasks (&bitmap_head.masks[0], masks, 4);
420     }
421   else if (bitmap_file_head.biSize == 108 ||
422            bitmap_file_head.biSize == 124)
423     {
424       /* BMP Version 4 or 5 */
425 
426       if (! ReadOK (fd, buffer, bitmap_file_head.biSize - 4))
427         {
428           g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
429                        _("Error reading BMP file header from '%s'"),
430                        gimp_filename_to_utf8 (filename));
431           goto out;
432         }
433 
434       bitmap_head.biWidth   = ToL (&buffer[0x00]);
435       bitmap_head.biHeight  = ToL (&buffer[0x04]);
436       bitmap_head.biPlanes  = ToS (&buffer[0x08]);
437       bitmap_head.biBitCnt  = ToS (&buffer[0x0A]);
438       bitmap_head.biCompr   = ToL (&buffer[0x0C]);
439       bitmap_head.biSizeIm  = ToL (&buffer[0x10]);
440       bitmap_head.biXPels   = ToL (&buffer[0x14]);
441       bitmap_head.biYPels   = ToL (&buffer[0x18]);
442       bitmap_head.biClrUsed = ToL (&buffer[0x1C]);
443       bitmap_head.biClrImp  = ToL (&buffer[0x20]);
444       bitmap_head.masks[0]  = ToL (&buffer[0x24]);
445       bitmap_head.masks[1]  = ToL (&buffer[0x28]);
446       bitmap_head.masks[2]  = ToL (&buffer[0x2C]);
447       bitmap_head.masks[3]  = ToL (&buffer[0x30]);
448 
449       Maps = 4;
450 
451       if (bitmap_head.biCompr == BI_BITFIELDS)
452         {
453 #ifdef DEBUG
454           g_print ("Got BI_BITFIELDS compression\n");
455 #endif
456 
457           ReadChannelMasks (&bitmap_head.masks[0], masks, 4);
458         }
459       else if (bitmap_head.biCompr == BI_RGB)
460         {
461 #ifdef DEBUG
462           g_print ("Got BI_RGB compression\n");
463 #endif
464 
465           setMasksDefault (bitmap_head.biBitCnt, masks);
466         }
467     }
468   else
469     {
470       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
471                    _("Error reading BMP file header from '%s'"),
472                    gimp_filename_to_utf8 (filename));
473       goto out;
474     }
475 
476   /* Valid bit depth is 1, 4, 8, 16, 24, 32 */
477   /* 16 is awful, we should probably shoot whoever invented it */
478 
479   switch (bitmap_head.biBitCnt)
480     {
481     case 1:
482     case 2:
483     case 4:
484     case 8:
485     case 16:
486     case 24:
487     case 32:
488       break;
489     default:
490       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
491                    _("'%s' is not a valid BMP file"),
492                    gimp_filename_to_utf8 (filename));
493       goto out;
494     }
495 
496   /* There should be some colors used! */
497 
498   ColormapSize =
499     (bitmap_file_head.bfOffs - bitmap_file_head.biSize - 14) / Maps;
500 
501   if ((bitmap_head.biClrUsed == 0) &&
502       (bitmap_head.biBitCnt  <= 8))
503     {
504       ColormapSize = bitmap_head.biClrUsed = 1 << bitmap_head.biBitCnt;
505     }
506 
507   if (ColormapSize > 256)
508     ColormapSize = 256;
509 
510   /* Sanity checks */
511 
512   if (bitmap_head.biHeight == 0 ||
513       bitmap_head.biWidth  == 0)
514     {
515       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
516                    _("'%s' is not a valid BMP file"),
517                    gimp_filename_to_utf8 (filename));
518       goto out;
519     }
520 
521   /* biHeight may be negative, but G_MININT32 is dangerous because:
522      G_MININT32 == -(G_MININT32) */
523   if (bitmap_head.biWidth  <  0 ||
524       bitmap_head.biHeight == G_MININT32)
525     {
526       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
527                    _("'%s' is not a valid BMP file"),
528                    gimp_filename_to_utf8 (filename));
529       goto out;
530     }
531 
532   if (bitmap_head.biPlanes != 1)
533     {
534       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
535                    _("'%s' is not a valid BMP file"),
536                    gimp_filename_to_utf8 (filename));
537       goto out;
538     }
539 
540   if (bitmap_head.biClrUsed >  256 &&
541       bitmap_head.biBitCnt  <= 8)
542     {
543       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
544                    _("'%s' is not a valid BMP file"),
545                    gimp_filename_to_utf8 (filename));
546       goto out;
547     }
548 
549   /* protect against integer overflows caused by malicious BMPs */
550   /* use divisions in comparisons to avoid type overflows */
551 
552   if (((guint64) bitmap_head.biWidth) > G_MAXINT32 / bitmap_head.biBitCnt ||
553       ((guint64) bitmap_head.biWidth) > (G_MAXINT32 / ABS (bitmap_head.biHeight)) / 4)
554     {
555       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
556                    _("'%s' is not a valid BMP file"),
557                    gimp_filename_to_utf8 (filename));
558       goto out;
559     }
560 
561   /* Windows and OS/2 declare filler so that rows are a multiple of
562    * word length (32 bits == 4 bytes)
563    */
564 
565   rowbytes = ((bitmap_head.biWidth * bitmap_head.biBitCnt - 1) / 32) * 4 + 4;
566 
567 #ifdef DEBUG
568   printf ("\nSize: %lu, Colors: %lu, Bits: %hu, Width: %ld, Height: %ld, "
569           "Comp: %lu, Zeile: %d\n",
570           bitmap_file_head.bfSize,
571           bitmap_head.biClrUsed,
572           bitmap_head.biBitCnt,
573           bitmap_head.biWidth,
574           bitmap_head.biHeight,
575           bitmap_head.biCompr,
576           rowbytes);
577 #endif
578 
579   if (bitmap_head.biBitCnt <= 8)
580     {
581 #ifdef DEBUG
582       printf ("Colormap read\n");
583 #endif
584       /* Get the Colormap */
585       if (! ReadColorMap (fd, ColorMap, ColormapSize, Maps, &gray))
586         goto out;
587     }
588 
589   fseek (fd, bitmap_file_head.bfOffs, SEEK_SET);
590 
591   /* Get the Image and return the ID or -1 on error*/
592   image_ID = ReadImage (fd,
593                         filename,
594                         bitmap_head.biWidth,
595                         ABS (bitmap_head.biHeight),
596                         ColorMap,
597                         bitmap_head.biClrUsed,
598                         bitmap_head.biBitCnt,
599                         bitmap_head.biCompr,
600                         rowbytes,
601                         gray,
602                         masks,
603                         error);
604 
605   if (image_ID < 0)
606     goto out;
607 
608   if (bitmap_head.biXPels > 0 &&
609       bitmap_head.biYPels > 0)
610     {
611       /* Fixed up from scott@asofyet's changes last year, njl195 */
612       gdouble xresolution;
613       gdouble yresolution;
614 
615       /* I don't agree with scott's feeling that Gimp should be trying
616        * to "fix" metric resolution translations, in the long term
617        * Gimp should be SI (metric) anyway, but we haven't told the
618        * Americans that yet
619        */
620 
621       xresolution = bitmap_head.biXPels * 0.0254;
622       yresolution = bitmap_head.biYPels * 0.0254;
623 
624       gimp_image_set_resolution (image_ID, xresolution, yresolution);
625     }
626 
627   if (bitmap_head.biHeight < 0)
628     gimp_image_flip (image_ID, GIMP_ORIENTATION_VERTICAL);
629 
630 out:
631   if (fd)
632     fclose (fd);
633 
634   return image_ID;
635 }
636 
637 static gint32
ReadImage(FILE * fd,const gchar * filename,gint width,gint height,guchar cmap[256][3],gint ncols,gint bpp,gint compression,gint rowbytes,gboolean gray,const BitmapChannel * masks,GError ** error)638 ReadImage (FILE                 *fd,
639            const gchar          *filename,
640            gint                  width,
641            gint                  height,
642            guchar                cmap[256][3],
643            gint                  ncols,
644            gint                  bpp,
645            gint                  compression,
646            gint                  rowbytes,
647            gboolean              gray,
648            const BitmapChannel  *masks,
649            GError              **error)
650 {
651   guchar             v, n;
652   gint               xpos = 0;
653   gint               ypos = 0;
654   gint32             image;
655   gint32             layer;
656   GeglBuffer        *buffer;
657   guchar            *dest, *temp, *row_buf;
658   guchar             gimp_cmap[768];
659   gushort            rgb;
660   glong              rowstride, channels;
661   gint               i, i_max, j, cur_progress, max_progress;
662   gint               total_bytes_read;
663   GimpImageBaseType  base_type;
664   GimpImageType      image_type;
665   guint32            px32;
666 
667   if (! (compression == BI_RGB || compression == BI_BITFIELDS ||
668       (bpp == 8 && compression == BI_RLE8) ||
669       (bpp == 4 && compression == BI_RLE4)))
670     {
671       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
672                    "%s",
673                    _("Unrecognized or invalid BMP compression format."));
674       return -1;
675     }
676 
677   /* Make a new image in GIMP */
678 
679   switch (bpp)
680     {
681     case 32:
682     case 24:
683     case 16:
684       base_type = GIMP_RGB;
685       if (masks[3].mask != 0)
686         {
687           image_type = GIMP_RGBA_IMAGE;
688           channels = 4;
689         }
690       else
691         {
692           image_type = GIMP_RGB_IMAGE;
693           channels = 3;
694         }
695       if (bpp == 24 && compression == BI_BITFIELDS)
696         g_printerr ("Loading BMP with invalid combination of 24 bpp and BI_BITFIELDS compression.\n");
697       break;
698 
699     case 8:
700     case 4:
701     case 1:
702       if (gray)
703         {
704           base_type = GIMP_GRAY;
705           image_type = GIMP_GRAY_IMAGE;
706         }
707       else
708         {
709           base_type = GIMP_INDEXED;
710           image_type = GIMP_INDEXED_IMAGE;
711         }
712       if (compression == BI_BITFIELDS)
713         g_printerr ("Loading BMP with invalid combination of %d bpp and BI_BITFIELDS compression.\n",
714                     bpp);
715 
716       channels = 1;
717       break;
718 
719     default:
720       g_message (_("Unsupported or invalid bitdepth."));
721       return -1;
722     }
723 
724   if ((width < 0) || (width > GIMP_MAX_IMAGE_SIZE))
725     {
726       g_message (_("Unsupported or invalid image width: %d"), width);
727       return -1;
728     }
729 
730   if ((height < 0) || (height > GIMP_MAX_IMAGE_SIZE))
731     {
732       g_message (_("Unsupported or invalid image height: %d"), height);
733       return -1;
734     }
735 
736   image = gimp_image_new (width, height, base_type);
737   layer = gimp_layer_new (image, _("Background"),
738                           width, height,
739                           image_type, 100,
740                           gimp_image_get_default_new_layer_mode (image));
741 
742   gimp_image_set_filename (image, filename);
743 
744   gimp_image_insert_layer (image, layer, -1, 0);
745 
746   /* use g_malloc0 to initialize the dest buffer so that unspecified
747      pixels in RLE bitmaps show up as the zeroth element in the palette.
748   */
749   dest      = g_malloc0 (width * height * channels);
750   row_buf   = g_malloc (rowbytes);
751   rowstride = width * channels;
752 
753   ypos = height - 1;  /* Bitmaps begin in the lower left corner */
754   cur_progress = 0;
755   max_progress = height;
756 
757   switch (bpp)
758     {
759     case 32:
760       {
761         while (ReadOK (fd, row_buf, rowbytes))
762           {
763             temp = dest + (ypos * rowstride);
764 
765             for (xpos= 0; xpos < width; ++xpos)
766               {
767                 px32 = ToL(&row_buf[xpos*4]);
768                 *(temp++) = ((px32 & masks[0].mask) >> masks[0].shiftin) * 255.0 / masks[0].max_value + 0.5;
769                 *(temp++) = ((px32 & masks[1].mask) >> masks[1].shiftin) * 255.0 / masks[1].max_value + 0.5;
770                 *(temp++) = ((px32 & masks[2].mask) >> masks[2].shiftin) * 255.0 / masks[2].max_value + 0.5;
771                 if (channels > 3)
772                   *(temp++) = ((px32 & masks[3].mask) >> masks[3].shiftin) * 255.0 / masks[3].max_value + 0.5;
773               }
774 
775             if (ypos == 0)
776               break;
777 
778             --ypos; /* next line */
779 
780             cur_progress++;
781             if ((cur_progress % 5) == 0)
782               gimp_progress_update ((gdouble) cur_progress /
783                                     (gdouble) max_progress);
784           }
785       }
786       break;
787 
788     case 24:
789       {
790         while (ReadOK (fd, row_buf, rowbytes))
791           {
792             temp = dest + (ypos * rowstride);
793 
794             for (xpos= 0; xpos < width; ++xpos)
795               {
796                 *(temp++) = row_buf[xpos * 3 + 2];
797                 *(temp++) = row_buf[xpos * 3 + 1];
798                 *(temp++) = row_buf[xpos * 3];
799               }
800 
801             if (ypos == 0)
802               break;
803 
804             --ypos; /* next line */
805 
806             cur_progress++;
807             if ((cur_progress % 5) == 0)
808               gimp_progress_update ((gdouble) cur_progress /
809                                     (gdouble) max_progress);
810           }
811       }
812       break;
813 
814     case 16:
815       {
816         while (ReadOK (fd, row_buf, rowbytes))
817           {
818             temp = dest + (ypos * rowstride);
819 
820             for (xpos= 0; xpos < width; ++xpos)
821               {
822                 rgb= ToS(&row_buf[xpos * 2]);
823                 *(temp++) = ((rgb & masks[0].mask) >> masks[0].shiftin) * 255.0 / masks[0].max_value + 0.5;
824                 *(temp++) = ((rgb & masks[1].mask) >> masks[1].shiftin) * 255.0 / masks[1].max_value + 0.5;
825                 *(temp++) = ((rgb & masks[2].mask) >> masks[2].shiftin) * 255.0 / masks[2].max_value + 0.5;
826                 if (channels > 3)
827                   *(temp++) = ((rgb & masks[3].mask) >> masks[3].shiftin) * 255.0 / masks[3].max_value + 0.5;
828               }
829 
830             if (ypos == 0)
831               break;
832 
833             --ypos; /* next line */
834 
835             cur_progress++;
836             if ((cur_progress % 5) == 0)
837               gimp_progress_update ((gdouble) cur_progress /
838                                     (gdouble) max_progress);
839           }
840       }
841       break;
842 
843     case 8:
844     case 4:
845     case 1:
846       {
847         if (compression == BI_RGB || compression == BI_BITFIELDS)
848           /* no compression */
849           {
850             while (ReadOK (fd, &v, 1))
851               {
852                 for (i = 1; (i <= (8 / bpp)) && (xpos < width); i++, xpos++)
853                   {
854                     temp = dest + (ypos * rowstride) + (xpos * channels);
855                     *temp=( v & ( ((1<<bpp)-1) << (8-(i*bpp)) ) ) >> (8-(i*bpp));
856                     if (gray)
857                       *temp = cmap[*temp][0];
858                   }
859 
860                 if (xpos == width)
861                   {
862                     fread (row_buf, rowbytes - 1 - (width * bpp - 1) / 8, 1, fd);
863 
864                     if (ypos == 0)
865                       break;
866 
867                     ypos--;
868                     xpos = 0;
869 
870                     cur_progress++;
871                     if ((cur_progress % 5) == 0)
872                       gimp_progress_update ((gdouble) cur_progress /
873                                             (gdouble) max_progress);
874                   }
875 
876                 if (ypos < 0)
877                   break;
878               }
879             break;
880           }
881         else
882           {
883             /* compressed image (either RLE8 or RLE4) */
884             while (ypos >= 0 && xpos <= width)
885               {
886                 if (! ReadOK (fd, row_buf, 2))
887                   {
888                     g_message (_("The bitmap ends unexpectedly."));
889                     break;
890                   }
891 
892                 if (row_buf[0] != 0)
893                   /* Count + Color - record */
894                   {
895                     /* encoded mode run -
896                      *   row_buf[0] == run_length
897                      *   row_buf[1] == pixel data
898                      */
899                     for (j = 0;
900                          ((guchar) j < row_buf[0]) && (xpos < width);)
901                       {
902 #ifdef DEBUG2
903                         printf("%u %u | ",xpos,width);
904 #endif
905                         for (i = 1;
906                              ((i <= (8 / bpp)) &&
907                               (xpos < width) &&
908                               ((guchar) j < row_buf[0]));
909                              i++, xpos++, j++)
910                           {
911                             temp = dest + (ypos * rowstride) + (xpos * channels);
912                             *temp = (row_buf[1] &
913                                      (((1<<bpp)-1) << (8 - (i * bpp)))) >> (8 - (i * bpp));
914                             if (gray)
915                               *temp = cmap[*temp][0];
916                           }
917                       }
918                   }
919 
920                 if ((row_buf[0] == 0) && (row_buf[1] > 2))
921                   /* uncompressed record */
922                   {
923                     n = row_buf[1];
924                     total_bytes_read = 0;
925 
926                     for (j = 0; j < n; j += (8 / bpp))
927                       {
928                         /* read the next byte in the record */
929                         if (! ReadOK (fd, &v, 1))
930                           {
931                             g_message (_("The bitmap ends unexpectedly."));
932                             break;
933                           }
934 
935                         total_bytes_read++;
936 
937                         /* read all pixels from that byte */
938                         i_max = 8 / bpp;
939                         if (n - j < i_max)
940                           {
941                             i_max = n - j;
942                           }
943 
944                         i = 1;
945                         while ((i <= i_max) && (xpos < width))
946                           {
947                             temp =
948                               dest + (ypos * rowstride) + (xpos * channels);
949                             *temp = (v >> (8-(i*bpp))) & ((1<<bpp)-1);
950                             if (gray)
951                               *temp = cmap[*temp][0];
952                             i++;
953                             xpos++;
954                           }
955                       }
956 
957                     /* absolute mode runs are padded to 16-bit alignment */
958                     if (total_bytes_read % 2)
959                       fread (&v, 1, 1, fd);
960                   }
961 
962                 if ((row_buf[0] == 0) && (row_buf[1] == 0))
963                   /* Line end */
964                   {
965                     ypos--;
966                     xpos = 0;
967 
968                     cur_progress++;
969                     if ((cur_progress % 5) == 0)
970                       gimp_progress_update ((gdouble) cur_progress /
971                                             (gdouble)  max_progress);
972                   }
973 
974                 if ((row_buf[0] == 0) && (row_buf[1] == 1))
975                   /* Bitmap end */
976                   {
977                     break;
978                   }
979 
980                 if ((row_buf[0] == 0) && (row_buf[1] == 2))
981                   /* Deltarecord */
982                   {
983                     if (! ReadOK (fd, row_buf, 2))
984                       {
985                         g_message (_("The bitmap ends unexpectedly."));
986                         break;
987                       }
988 
989                     xpos += row_buf[0];
990                     ypos -= row_buf[1];
991                   }
992               }
993             break;
994           }
995       }
996       break;
997 
998     default:
999       g_assert_not_reached ();
1000       break;
1001     }
1002 
1003   if (bpp <= 8)
1004     for (i = 0, j = 0; i < ncols; i++)
1005       {
1006         gimp_cmap[j++] = cmap[i][0];
1007         gimp_cmap[j++] = cmap[i][1];
1008         gimp_cmap[j++] = cmap[i][2];
1009       }
1010 
1011   buffer = gimp_drawable_get_buffer (layer);
1012 
1013   gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0,
1014                    NULL, dest, GEGL_AUTO_ROWSTRIDE);
1015 
1016   g_object_unref (buffer);
1017 
1018   g_free (dest);
1019 
1020   if ((! gray) && (bpp <= 8))
1021     gimp_image_set_colormap (image, gimp_cmap, ncols);
1022 
1023   gimp_progress_update (1.0);
1024 
1025   return image;
1026 }
1027