[gimp/gimp-2-8] Bug 674391 - Indexed colours not exported when save a .bmp
- From: Téo Mazars <teom src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-8] Bug 674391 - Indexed colours not exported when save a .bmp
- Date: Sat, 3 Aug 2013 17:53:29 +0000 (UTC)
commit d59a31867ab9cde8eff81ad5f68968ba08b4f07c
Author: Téo Mazars <teo mazars ensimag fr>
Date: Sat Apr 13 17:16:56 2013 +0200
Bug 674391 - Indexed colours not exported when save a .bmp
It's about importing in fact.
Parse BITMAPV4HEADER / BITMAPV5HEADER and use GIMP's BMP
implementation instead of using gdk_pixbuf.
Also, remove an old hack about 32bits bmp v3 + alpha. The alpha
channel is already ignored in that case.
(cherry picked from commit 56f065321ce42f907879dfa4a76e57de18b058eb)
plug-ins/file-bmp/bmp-read.c | 199 +++++++++++++++++++-----------------------
1 files changed, 91 insertions(+), 108 deletions(-)
---
diff --git a/plug-ins/file-bmp/bmp-read.c b/plug-ins/file-bmp/bmp-read.c
index 30251c1..7e70fbd 100644
--- a/plug-ins/file-bmp/bmp-read.c
+++ b/plug-ins/file-bmp/bmp-read.c
@@ -55,6 +55,58 @@ static gint32 ReadImage (FILE *fd,
GError **error);
+static void
+setMasksDefault (gushort biBitCnt, Bitmap_Channel *masks)
+{
+ switch (biBitCnt)
+ {
+ case 32:
+ masks[0].mask = 0x00ff0000;
+ masks[0].shiftin = 16;
+ masks[0].max_value= (gfloat)255.0;
+ masks[1].mask = 0x0000ff00;
+ masks[1].shiftin = 8;
+ masks[1].max_value= (gfloat)255.0;
+ masks[2].mask = 0x000000ff;
+ masks[2].shiftin = 0;
+ masks[2].max_value= (gfloat)255.0;
+ masks[3].mask = 0x00000000;
+ masks[3].shiftin = 0;
+ masks[3].max_value= (gfloat)0.0;
+ break;
+ case 24:
+ masks[0].mask = 0xff0000;
+ masks[0].shiftin = 16;
+ masks[0].max_value= (gfloat)255.0;
+ masks[1].mask = 0x00ff00;
+ masks[1].shiftin = 8;
+ masks[1].max_value= (gfloat)255.0;
+ masks[2].mask = 0x0000ff;
+ masks[2].shiftin = 0;
+ masks[2].max_value= (gfloat)255.0;
+ masks[3].mask = 0x0;
+ masks[3].shiftin = 0;
+ masks[3].max_value= (gfloat)0.0;
+ break;
+ case 16:
+ masks[0].mask = 0x7c00;
+ masks[0].shiftin = 10;
+ masks[0].max_value= (gfloat)31.0;
+ masks[1].mask = 0x03e0;
+ masks[1].shiftin = 5;
+ masks[1].max_value= (gfloat)31.0;
+ masks[2].mask = 0x001f;
+ masks[2].shiftin = 0;
+ masks[2].max_value= (gfloat)31.0;
+ masks[3].mask = 0x0;
+ masks[3].shiftin = 0;
+ masks[3].max_value= (gfloat)0.0;
+ break;
+ default:
+ break;
+ }
+}
+
static gint32
ToL (const guchar *puffer)
{
@@ -137,7 +189,7 @@ ReadBMP (const gchar *name,
GError **error)
{
FILE *fd;
- guchar buffer[64];
+ guchar buffer[124];
gint ColormapSize, rowbytes, Maps;
gboolean Grey = FALSE;
guchar ColorMap[256][3];
@@ -257,7 +309,7 @@ ReadBMP (const gchar *name,
Bitmap_Head.biWidth = ToL (&buffer[0x00]); /* 12 */
Bitmap_Head.biHeight = ToL (&buffer[0x04]); /* 16 */
- Bitmap_Head.biPlanes = ToS (&buffer[0x08]); /* 1A */
+ Bitmap_Head.biPlanes = ToS (&buffer[0x08]); /* 1A */
Bitmap_Head.biBitCnt = ToS (&buffer[0x0A]); /* 1C */
Bitmap_Head.biCompr = ToL (&buffer[0x0C]); /* 1E */
Bitmap_Head.biSizeIm = ToL (&buffer[0x10]); /* 22 */
@@ -290,55 +342,9 @@ ReadBMP (const gchar *name,
}
else if (Bitmap_Head.biCompr == BI_RGB)
{
- switch (Bitmap_Head.biBitCnt)
- {
- case 32:
- masks[0].mask = 0x00ff0000;
- masks[0].shiftin = 16;
- masks[0].max_value= (gfloat)255.0;
- masks[1].mask = 0x0000ff00;
- masks[1].shiftin = 8;
- masks[1].max_value= (gfloat)255.0;
- masks[2].mask = 0x000000ff;
- masks[2].shiftin = 0;
- masks[2].max_value= (gfloat)255.0;
- masks[3].mask = 0x00000000;
- masks[3].shiftin = 0;
- masks[3].max_value= (gfloat)0.0;
- break;
- case 24:
- masks[0].mask = 0xff0000;
- masks[0].shiftin = 16;
- masks[0].max_value= (gfloat)255.0;
- masks[1].mask = 0x00ff00;
- masks[1].shiftin = 8;
- masks[1].max_value= (gfloat)255.0;
- masks[2].mask = 0x0000ff;
- masks[2].shiftin = 0;
- masks[2].max_value= (gfloat)255.0;
- masks[3].mask = 0x0;
- masks[3].shiftin = 0;
- masks[3].max_value= (gfloat)0.0;
- break;
- case 16:
- masks[0].mask = 0x7c00;
- masks[0].shiftin = 10;
- masks[0].max_value= (gfloat)31.0;
- masks[1].mask = 0x03e0;
- masks[1].shiftin = 5;
- masks[1].max_value= (gfloat)31.0;
- masks[2].mask = 0x001f;
- masks[2].shiftin = 0;
- masks[2].max_value= (gfloat)31.0;
- masks[3].mask = 0x0;
- masks[3].shiftin = 0;
- masks[3].max_value= (gfloat)0.0;
- break;
- default:
- break;
- }
+ setMasksDefault (Bitmap_Head.biBitCnt, masks);
}
- else
+ else if ((Bitmap_Head.biCompr != BI_RLE4) && (Bitmap_Head.biCompr != BI_RLE8))
{
/* BI_ALPHABITFIELDS, etc. */
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
@@ -376,38 +382,51 @@ ReadBMP (const gchar *name,
Maps = 4;
ReadChannelMasks (&Bitmap_Head.masks[0], masks, 4);
}
- else
+ else if (Bitmap_File_Head.biSize == 108 || Bitmap_File_Head.biSize == 124)
+ /* BMP Version 4 or 5 */
{
- GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
-
- if (pixbuf)
+ if (!ReadOK (fd, buffer, Bitmap_File_Head.biSize - 4))
{
- gint32 layer_ID;
- image_ID = gimp_image_new (gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- GIMP_RGB);
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Error reading BMP file header from '%s'"),
+ gimp_filename_to_utf8 (filename));
+ return -1;
+ }
- layer_ID = gimp_layer_new_from_pixbuf (image_ID, _("Background"),
- pixbuf,
- 100.,
- GIMP_NORMAL_MODE, 0, 0);
- g_object_unref (pixbuf);
+ Bitmap_Head.biWidth = ToL (&buffer[0x00]);
+ Bitmap_Head.biHeight = ToL (&buffer[0x04]);
+ Bitmap_Head.biPlanes = ToS (&buffer[0x08]);
+ Bitmap_Head.biBitCnt = ToS (&buffer[0x0A]);
+ Bitmap_Head.biCompr = ToL (&buffer[0x0C]);
+ Bitmap_Head.biSizeIm = ToL (&buffer[0x10]);
+ Bitmap_Head.biXPels = ToL (&buffer[0x14]);
+ Bitmap_Head.biYPels = ToL (&buffer[0x18]);
+ Bitmap_Head.biClrUsed = ToL (&buffer[0x1C]);
+ Bitmap_Head.biClrImp = ToL (&buffer[0x20]);
+ Bitmap_Head.masks[0] = ToL (&buffer[0x24]);
+ Bitmap_Head.masks[1] = ToL (&buffer[0x28]);
+ Bitmap_Head.masks[2] = ToL (&buffer[0x2C]);
+ Bitmap_Head.masks[3] = ToL (&buffer[0x30]);
- gimp_image_set_filename (image_ID, filename);
- gimp_image_insert_layer (image_ID, layer_ID, -1, -1);
+ Maps = 4;
- return image_ID;
+ if (Bitmap_Head.biCompr == BI_BITFIELDS)
+ {
+ ReadChannelMasks (&Bitmap_Head.masks[0], masks, 4);
}
- else
+ else if (Bitmap_Head.biCompr == BI_RGB)
{
-
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
- _("Error reading BMP file header from '%s'"),
- gimp_filename_to_utf8 (filename));
- return -1;
+ setMasksDefault (Bitmap_Head.biBitCnt, masks);
}
}
+ else
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Error reading BMP file header from '%s'"),
+ gimp_filename_to_utf8 (filename));
+ return -1;
+ }
/* Valid bit depth is 1, 4, 8, 16, 24, 32 */
/* 16 is awful, we should probably shoot whoever invented it */
@@ -699,42 +718,6 @@ ReadImage (FILE *fd,
gimp_progress_update ((gdouble) cur_progress /
(gdouble) max_progress);
}
-
- if (channels == 4)
- {
- gboolean has_alpha = FALSE;
-
- /* at least one pixel should have nonzero alpha */
- for (ypos = 0; ypos < height; ypos++)
- {
- temp = dest + (ypos * rowstride);
- for (xpos = 0; xpos < width; xpos++)
- {
- if (temp[3])
- {
- has_alpha = TRUE;
- break;
- }
- temp += 4;
- }
- if (has_alpha)
- break;
- }
-
- /* workaround unwanted behaviour when all alpha pixels are zero */
- if (!has_alpha)
- {
- for (ypos = 0; ypos < height; ypos++)
- {
- temp = dest + (ypos * rowstride);
- for (xpos = 0; xpos < width; xpos++)
- {
- temp[3] = 255;
- temp += 4;
- }
- }
- }
- }
}
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]