plug-ins: Add support for loading 64bpp BMPs
Adds support for loading BMPs with 64bpp. Each channel uses 13 bits (2^13 max value), so it's scaled to fit our 16 bit integer image mode.
This commit is contained in:
@ -486,6 +486,7 @@ load_image (GFile *file,
|
|||||||
case 16:
|
case 16:
|
||||||
case 24:
|
case 24:
|
||||||
case 32:
|
case 32:
|
||||||
|
case 64:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||||
@ -655,7 +656,10 @@ ReadImage (FILE *fd,
|
|||||||
GimpImage *image;
|
GimpImage *image;
|
||||||
GimpLayer *layer;
|
GimpLayer *layer;
|
||||||
GeglBuffer *buffer;
|
GeglBuffer *buffer;
|
||||||
guchar *dest, *temp, *row_buf;
|
guchar *dest = NULL;
|
||||||
|
gushort *dest16 = NULL;
|
||||||
|
guchar *temp, *row_buf;
|
||||||
|
gushort *temp16;
|
||||||
guchar gimp_cmap[768];
|
guchar gimp_cmap[768];
|
||||||
gushort rgb;
|
gushort rgb;
|
||||||
glong rowstride, channels;
|
glong rowstride, channels;
|
||||||
@ -663,6 +667,8 @@ ReadImage (FILE *fd,
|
|||||||
gint total_bytes_read;
|
gint total_bytes_read;
|
||||||
GimpImageBaseType base_type;
|
GimpImageBaseType base_type;
|
||||||
GimpImageType image_type;
|
GimpImageType image_type;
|
||||||
|
GimpPrecision precision_type = GIMP_PRECISION_U8_NON_LINEAR;
|
||||||
|
const Babl *format = NULL;
|
||||||
guint32 px32;
|
guint32 px32;
|
||||||
|
|
||||||
if (! (compression == BI_RGB || compression == BI_BITFIELDS ||
|
if (! (compression == BI_RGB || compression == BI_BITFIELDS ||
|
||||||
@ -679,6 +685,14 @@ ReadImage (FILE *fd,
|
|||||||
|
|
||||||
switch (bpp)
|
switch (bpp)
|
||||||
{
|
{
|
||||||
|
case 64:
|
||||||
|
base_type = GIMP_RGB;
|
||||||
|
image_type = GIMP_RGBA_IMAGE;
|
||||||
|
channels = 4;
|
||||||
|
format = babl_format ("R'G'B'A u16");
|
||||||
|
precision_type = GIMP_PRECISION_U16_NON_LINEAR;
|
||||||
|
break;
|
||||||
|
|
||||||
case 32:
|
case 32:
|
||||||
case 24:
|
case 24:
|
||||||
case 16:
|
case 16:
|
||||||
@ -734,7 +748,9 @@ ReadImage (FILE *fd,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = gimp_image_new (width, height, base_type);
|
image = gimp_image_new_with_precision (width, height, base_type,
|
||||||
|
precision_type);
|
||||||
|
|
||||||
layer = gimp_layer_new (image, _("Background"),
|
layer = gimp_layer_new (image, _("Background"),
|
||||||
width, height,
|
width, height,
|
||||||
image_type, 100,
|
image_type, 100,
|
||||||
@ -744,7 +760,11 @@ ReadImage (FILE *fd,
|
|||||||
/* use g_malloc0 to initialize the dest buffer so that unspecified
|
/* use g_malloc0 to initialize the dest buffer so that unspecified
|
||||||
pixels in RLE bitmaps show up as the zeroth element in the palette.
|
pixels in RLE bitmaps show up as the zeroth element in the palette.
|
||||||
*/
|
*/
|
||||||
dest = g_malloc0 (width * height * channels);
|
if (bpp != 64)
|
||||||
|
dest = g_malloc0 (width * height * channels);
|
||||||
|
else
|
||||||
|
dest16 = g_malloc0 (width * height * channels * 2);
|
||||||
|
|
||||||
row_buf = g_malloc (rowbytes);
|
row_buf = g_malloc (rowbytes);
|
||||||
rowstride = width * channels;
|
rowstride = width * channels;
|
||||||
|
|
||||||
@ -754,6 +774,63 @@ ReadImage (FILE *fd,
|
|||||||
|
|
||||||
switch (bpp)
|
switch (bpp)
|
||||||
{
|
{
|
||||||
|
case 64:
|
||||||
|
{
|
||||||
|
guint16 signed_short;
|
||||||
|
gint fixed_integer;
|
||||||
|
gdouble fixed_fraction;
|
||||||
|
gdouble converted_fixed_point;
|
||||||
|
|
||||||
|
while (ReadOK (fd, row_buf, rowbytes))
|
||||||
|
{
|
||||||
|
temp16 = dest16 + (ypos * rowstride);
|
||||||
|
|
||||||
|
for (xpos = 0; xpos < width; ++xpos)
|
||||||
|
{
|
||||||
|
/* Values are stored in fixed point format;
|
||||||
|
* 1 bit for sign, 2 bits for integer,
|
||||||
|
* 13 bits for decimal value. Then we multiply
|
||||||
|
* by 2^13 to get the scaled value */
|
||||||
|
for (i = 4; i >= 0; i -= 2)
|
||||||
|
{
|
||||||
|
rgb = ToS (&row_buf[(xpos * 8) + i]);
|
||||||
|
|
||||||
|
signed_short = rgb & 0x7FFF;
|
||||||
|
fixed_integer = signed_short >> 13;
|
||||||
|
fixed_fraction = signed_short & 0x1FFF;
|
||||||
|
|
||||||
|
converted_fixed_point = fixed_integer + (fixed_fraction / 0x1FFF);
|
||||||
|
converted_fixed_point *= 8192;
|
||||||
|
|
||||||
|
*(temp16++) = (converted_fixed_point / 8192.0) * G_MAXUINT16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alpha Channel */
|
||||||
|
rgb = ToS (&row_buf[(xpos * 8) + 6]);
|
||||||
|
|
||||||
|
signed_short = rgb & 0x7FFF;
|
||||||
|
fixed_integer = signed_short >> 13;
|
||||||
|
fixed_fraction = signed_short & 0x1FFF;
|
||||||
|
|
||||||
|
converted_fixed_point = fixed_integer + (fixed_fraction / 0x1FFF);
|
||||||
|
converted_fixed_point *= 8192;
|
||||||
|
|
||||||
|
*(temp16++) = (converted_fixed_point / 8192.0) * G_MAXUINT16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ypos == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
--ypos; /* next line */
|
||||||
|
|
||||||
|
cur_progress++;
|
||||||
|
if ((cur_progress % 5) == 0)
|
||||||
|
gimp_progress_update ((gdouble) cur_progress /
|
||||||
|
(gdouble) max_progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 32:
|
case 32:
|
||||||
{
|
{
|
||||||
while (ReadOK (fd, row_buf, rowbytes))
|
while (ReadOK (fd, row_buf, rowbytes))
|
||||||
@ -1008,12 +1085,17 @@ ReadImage (FILE *fd,
|
|||||||
|
|
||||||
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
|
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
|
||||||
|
|
||||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0,
|
if (bpp != 64)
|
||||||
NULL, dest, GEGL_AUTO_ROWSTRIDE);
|
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0,
|
||||||
|
NULL, dest, GEGL_AUTO_ROWSTRIDE);
|
||||||
|
else
|
||||||
|
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0,
|
||||||
|
format, dest16, GEGL_AUTO_ROWSTRIDE);
|
||||||
|
|
||||||
g_object_unref (buffer);
|
g_object_unref (buffer);
|
||||||
|
|
||||||
g_free (dest);
|
g_free (dest);
|
||||||
|
g_free (dest16);
|
||||||
|
|
||||||
if ((! gray) && (bpp <= 8))
|
if ((! gray) && (bpp <= 8))
|
||||||
gimp_palette_set_colormap (gimp_image_get_palette (image), babl_format ("R'G'B' u8"), gimp_cmap, ncols * 3);
|
gimp_palette_set_colormap (gimp_image_get_palette (image), babl_format ("R'G'B' u8"), gimp_cmap, ncols * 3);
|
||||||
|
Reference in New Issue
Block a user