mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-03 17:33:25 +00:00
plug-ins: bmp import - simplify dest/offset handling
the offset to the dest buffer passed to the line-reading functions wasn't counting bytes but items/values, which was slightly confusing. Changed to not pass the offset at all, but rather a pointer to the start of a line inside the buffer. Also made rowstride count bytes, not values. Made dest and rowstride local vars, as they are not used anywhere else.
This commit is contained in:
parent
373f4821c3
commit
565ead32b8
1 changed files with 40 additions and 52 deletions
|
@ -68,8 +68,6 @@ struct Fileinfo
|
||||||
guchar *rowbuf;
|
guchar *rowbuf;
|
||||||
guint64 bytes_per_row;
|
guint64 bytes_per_row;
|
||||||
gint bpp;
|
gint bpp;
|
||||||
guchar *dest;
|
|
||||||
gsize rowstride;
|
|
||||||
gint channels;
|
gint channels;
|
||||||
gint bytesperchannel;
|
gint bytesperchannel;
|
||||||
gint ncolors;
|
gint ncolors;
|
||||||
|
@ -94,15 +92,15 @@ static GimpImage * ReadImage (struct Fileinfo *fi,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
static gint load_rgb_64 (struct Fileinfo *fi,
|
static gint load_rgb_64 (struct Fileinfo *fi,
|
||||||
gsize offset);
|
guchar *dest);
|
||||||
static gint load_rgb (struct Fileinfo *fi,
|
static gint load_rgb (struct Fileinfo *fi,
|
||||||
gsize offset);
|
guchar *dest);
|
||||||
static gint load_indexed (struct Fileinfo *fi,
|
static gint load_indexed (struct Fileinfo *fi,
|
||||||
gsize offset);
|
guchar *dest);
|
||||||
static gint load_rle (struct Fileinfo *fi,
|
static gint load_rle (struct Fileinfo *fi,
|
||||||
gsize offset);
|
guchar *dest);
|
||||||
static gint load_huffman (struct Fileinfo *fi,
|
static gint load_huffman (struct Fileinfo *fi,
|
||||||
gsize offset);
|
guchar *dest);
|
||||||
|
|
||||||
static gint huff_decode (guint32 *bitbuf,
|
static gint huff_decode (guint32 *bitbuf,
|
||||||
gint *buflen,
|
gint *buflen,
|
||||||
|
@ -679,7 +677,9 @@ ReadImage (struct Fileinfo *fi,
|
||||||
GimpImageType image_type;
|
GimpImageType image_type;
|
||||||
GimpPrecision precision_type = GIMP_PRECISION_U8_NON_LINEAR;
|
GimpPrecision precision_type = GIMP_PRECISION_U8_NON_LINEAR;
|
||||||
const Babl *format = NULL;
|
const Babl *format = NULL;
|
||||||
|
guchar *dest = NULL;
|
||||||
gsize dest_size = 0;
|
gsize dest_size = 0;
|
||||||
|
gsize rowstride;
|
||||||
gint maxbits;
|
gint maxbits;
|
||||||
gint eof = FALSE;
|
gint eof = FALSE;
|
||||||
enum Bmpformat bmpfmt = 0;
|
enum Bmpformat bmpfmt = 0;
|
||||||
|
@ -790,16 +790,16 @@ ReadImage (struct Fileinfo *fi,
|
||||||
if ((guint64) fi->width * fi->tile_height < G_MAXSIZE / (fi->channels * fi->bytesperchannel))
|
if ((guint64) fi->width * fi->tile_height < G_MAXSIZE / (fi->channels * fi->bytesperchannel))
|
||||||
{
|
{
|
||||||
dest_size = (gsize) fi->width * fi->tile_height * fi->channels * fi->bytesperchannel;
|
dest_size = (gsize) fi->width * fi->tile_height * fi->channels * fi->bytesperchannel;
|
||||||
fi->dest = g_try_malloc0 (dest_size);
|
dest = g_try_malloc0 (dest_size);
|
||||||
fi->rowbuf = g_try_malloc (MAX (4, fi->bytes_per_row));
|
fi->rowbuf = g_try_malloc (MAX (4, fi->bytes_per_row));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (fi->dest && fi->rowbuf))
|
if (! (dest && fi->rowbuf))
|
||||||
{
|
{
|
||||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||||
_("Image dimensions too large: width %d x height %d"),
|
_("Image dimensions too large: width %d x height %d"),
|
||||||
fi->width, fi->height);
|
fi->width, fi->height);
|
||||||
g_free (fi->dest);
|
g_free (dest);
|
||||||
g_free (fi->rowbuf);
|
g_free (fi->rowbuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -813,7 +813,7 @@ ReadImage (struct Fileinfo *fi,
|
||||||
gimp_image_insert_layer (image, layer, NULL, 0);
|
gimp_image_insert_layer (image, layer, NULL, 0);
|
||||||
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
|
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
|
||||||
|
|
||||||
fi->rowstride = (gsize) fi->width * fi->channels;
|
rowstride = (gsize) fi->width * fi->channels * fi->bytesperchannel;
|
||||||
|
|
||||||
cur_progress = 0;
|
cur_progress = 0;
|
||||||
max_progress = fi->height;
|
max_progress = fi->height;
|
||||||
|
@ -823,22 +823,22 @@ ReadImage (struct Fileinfo *fi,
|
||||||
|
|
||||||
for (ypos = fi->height - 1; ypos >= 0 && ! eof; ypos--)
|
for (ypos = fi->height - 1; ypos >= 0 && ! eof; ypos--)
|
||||||
{
|
{
|
||||||
gsize offset = (fi->tile_height - fi->tile_n - 1) * fi->rowstride;
|
gsize offset = (fi->tile_height - fi->tile_n - 1) * rowstride;
|
||||||
|
|
||||||
switch (bmpfmt)
|
switch (bmpfmt)
|
||||||
{
|
{
|
||||||
case BMPFMT_RGB:
|
case BMPFMT_RGB:
|
||||||
if (! load_rgb (fi, offset))
|
if (! load_rgb (fi, dest + offset))
|
||||||
eof = TRUE;
|
eof = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMPFMT_RGB_64:
|
case BMPFMT_RGB_64:
|
||||||
if (! load_rgb_64 (fi, offset))
|
if (! load_rgb_64 (fi, dest + offset))
|
||||||
eof = TRUE;
|
eof = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMPFMT_INDEXED:
|
case BMPFMT_INDEXED:
|
||||||
if (! load_indexed (fi, offset))
|
if (! load_indexed (fi, dest + offset))
|
||||||
eof = TRUE;
|
eof = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -846,12 +846,12 @@ ReadImage (struct Fileinfo *fi,
|
||||||
if (fi->file_ypos < ypos)
|
if (fi->file_ypos < ypos)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (! load_rle (fi, offset))
|
if (! load_rle (fi, dest + offset))
|
||||||
eof = TRUE;
|
eof = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMPFMT_HUFFMAN:
|
case BMPFMT_HUFFMAN:
|
||||||
if (! load_huffman (fi, offset))
|
if (! load_huffman (fi, dest + offset))
|
||||||
eof = TRUE;
|
eof = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -865,18 +865,18 @@ ReadImage (struct Fileinfo *fi,
|
||||||
/* we are filling the dest buffer backwards, so we need an offset to dest in
|
/* we are filling the dest buffer backwards, so we need an offset to dest in
|
||||||
* case the tile_height isn't fully used (when tile_n < tile_height)
|
* case the tile_height isn't fully used (when tile_n < tile_height)
|
||||||
*/
|
*/
|
||||||
gsize offs = (fi->tile_height - fi->tile_n) * fi->rowstride * fi->bytesperchannel;
|
offset = (fi->tile_height - fi->tile_n) * rowstride;
|
||||||
|
|
||||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, ypos, fi->width, fi->tile_n), 0, format,
|
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, ypos, fi->width, fi->tile_n), 0, format,
|
||||||
fi->dest + offs, GEGL_AUTO_ROWSTRIDE);
|
dest + offset, GEGL_AUTO_ROWSTRIDE);
|
||||||
memset (fi->dest, 0, dest_size);
|
memset (dest, 0, dest_size);
|
||||||
fi->tile_n = 0;
|
fi->tile_n = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (buffer);
|
g_object_unref (buffer);
|
||||||
|
|
||||||
g_free (fi->dest);
|
g_free (dest);
|
||||||
|
|
||||||
if (! fi->gray && fi->bpp <= 8)
|
if (! fi->gray && fi->bpp <= 8)
|
||||||
gimp_palette_set_colormap (gimp_image_get_palette (image), babl_format ("R'G'B' u8"),
|
gimp_palette_set_colormap (gimp_image_get_palette (image), babl_format ("R'G'B' u8"),
|
||||||
|
@ -891,21 +891,19 @@ ReadImage (struct Fileinfo *fi,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
load_rgb (struct Fileinfo *fi, gsize offset)
|
load_rgb (struct Fileinfo *fi, guchar *dest)
|
||||||
{
|
{
|
||||||
gint xpos, i;
|
gint xpos, i;
|
||||||
gint32 px;
|
gint32 px;
|
||||||
gdouble d;
|
gdouble d;
|
||||||
guchar *dest8;
|
|
||||||
guint16 *dest16;
|
guint16 *dest16;
|
||||||
guint32 *dest32;
|
guint32 *dest32;
|
||||||
|
|
||||||
if (! ReadOK (fi->file, fi->rowbuf, fi->bytes_per_row))
|
if (! ReadOK (fi->file, fi->rowbuf, fi->bytes_per_row))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
dest8 = fi->dest + fi->bytesperchannel * offset;
|
dest16 = (guint16 *) dest;
|
||||||
dest16 = (guint16 *) dest8;
|
dest32 = (guint32 *) dest;
|
||||||
dest32 = (guint32 *) dest8;
|
|
||||||
|
|
||||||
for (xpos = 0; xpos < fi->width; xpos++)
|
for (xpos = 0; xpos < fi->width; xpos++)
|
||||||
{
|
{
|
||||||
|
@ -915,7 +913,7 @@ load_rgb (struct Fileinfo *fi, gsize offset)
|
||||||
d = ((px & fi->masks[i].mask) >> fi->masks[i].shiftin) / fi->masks[i].max_value;
|
d = ((px & fi->masks[i].mask) >> fi->masks[i].shiftin) / fi->masks[i].max_value;
|
||||||
|
|
||||||
if (fi->bytesperchannel == 1)
|
if (fi->bytesperchannel == 1)
|
||||||
*dest8++ = d * 0x00ff + 0.5;
|
*dest++ = d * 0x00ff + 0.5;
|
||||||
else if (fi->bytesperchannel == 2)
|
else if (fi->bytesperchannel == 2)
|
||||||
*dest16++ = d * 0xffffUL + 0.5;
|
*dest16++ = d * 0xffffUL + 0.5;
|
||||||
else
|
else
|
||||||
|
@ -926,7 +924,7 @@ load_rgb (struct Fileinfo *fi, gsize offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
load_rgb_64 (struct Fileinfo *fi, gsize offset)
|
load_rgb_64 (struct Fileinfo *fi, guchar *dest)
|
||||||
{
|
{
|
||||||
gint xpos, i;
|
gint xpos, i;
|
||||||
gfloat *destflt;
|
gfloat *destflt;
|
||||||
|
@ -934,7 +932,7 @@ load_rgb_64 (struct Fileinfo *fi, gsize offset)
|
||||||
if (! ReadOK (fi->file, fi->rowbuf, fi->bytes_per_row))
|
if (! ReadOK (fi->file, fi->rowbuf, fi->bytes_per_row))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
destflt = (gfloat *) fi->dest + offset;
|
destflt = (gfloat *) dest;
|
||||||
|
|
||||||
for (xpos = 0; xpos < fi->width; ++xpos)
|
for (xpos = 0; xpos < fi->width; ++xpos)
|
||||||
{
|
{
|
||||||
|
@ -953,15 +951,13 @@ load_rgb_64 (struct Fileinfo *fi, gsize offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
load_indexed (struct Fileinfo *fi, gsize offset)
|
load_indexed (struct Fileinfo *fi, guchar *dest)
|
||||||
{
|
{
|
||||||
gint xpos, val, shift;
|
gint xpos, val, shift;
|
||||||
guchar *dest;
|
|
||||||
|
|
||||||
if (! ReadOK (fi->file, fi->rowbuf, fi->bytes_per_row))
|
if (! ReadOK (fi->file, fi->rowbuf, fi->bytes_per_row))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
dest = fi->dest + offset;
|
|
||||||
for (xpos = 0; xpos < fi->width; xpos++)
|
for (xpos = 0; xpos < fi->width; xpos++)
|
||||||
{
|
{
|
||||||
val = fi->rowbuf[xpos / (8 / fi->bpp)];
|
val = fi->rowbuf[xpos / (8 / fi->bpp)];
|
||||||
|
@ -977,7 +973,7 @@ load_indexed (struct Fileinfo *fi, gsize offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
load_rle (struct Fileinfo *fi, gsize offset)
|
load_rle (struct Fileinfo *fi, guchar *basedest)
|
||||||
{
|
{
|
||||||
gint shift, i, j;
|
gint shift, i, j;
|
||||||
guchar *dest;
|
guchar *dest;
|
||||||
|
@ -1005,13 +1001,13 @@ load_rle (struct Fileinfo *fi, gsize offset)
|
||||||
i++, fi->xpos++, j++)
|
i++, fi->xpos++, j++)
|
||||||
{
|
{
|
||||||
shift = 8 - i * fi->bpp;
|
shift = 8 - i * fi->bpp;
|
||||||
dest = fi->dest + offset + fi->xpos * fi->channels;
|
dest = basedest + fi->xpos * fi->channels;
|
||||||
|
|
||||||
dest[0] = (fi->rowbuf[1] & (((1 << fi->bpp) - 1) << shift)) >> shift;
|
dest[0] = (fi->rowbuf[1] & (((1 << fi->bpp) - 1) << shift)) >> shift;
|
||||||
dest[0] = MIN (dest[0], fi->ncolors - 1);
|
dest[0] = MIN (dest[0], fi->ncolors - 1);
|
||||||
if (fi->gray)
|
if (fi->gray)
|
||||||
dest[0] = fi->colormap[dest[0] * 3];
|
dest[0] = fi->colormap[dest[0] * 3];
|
||||||
dest[1] = 0xff; /* alpha */
|
dest[1] = 0xff; /* alpha */
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1026,11 +1022,9 @@ load_rle (struct Fileinfo *fi, gsize offset)
|
||||||
}
|
}
|
||||||
for (i = 0; (i < fi->rowbuf[0]) && (fi->xpos < fi->width); i++, fi->xpos++)
|
for (i = 0; (i < fi->rowbuf[0]) && (fi->xpos < fi->width); i++, fi->xpos++)
|
||||||
{
|
{
|
||||||
dest = fi->dest + offset + fi->xpos * fi->channels;
|
dest = basedest + fi->xpos * fi->channels;
|
||||||
for (gint c = 0; c < 3; c++)
|
for (gint c = 0; c < 3; c++)
|
||||||
{
|
dest[2 - c] = fi->rowbuf[1 + c];
|
||||||
dest[2 - c] = fi->rowbuf[c + 1];
|
|
||||||
}
|
|
||||||
dest[3] = 0xff; /* alpha */
|
dest[3] = 0xff; /* alpha */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1053,7 +1047,7 @@ load_rle (struct Fileinfo *fi, gsize offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dest = fi->dest + offset + fi->xpos * fi->channels;
|
dest = basedest + fi->xpos * fi->channels;
|
||||||
switch (fi->bpp)
|
switch (fi->bpp)
|
||||||
{
|
{
|
||||||
case 8:
|
case 8:
|
||||||
|
@ -1063,10 +1057,8 @@ load_rle (struct Fileinfo *fi, gsize offset)
|
||||||
dest[0] = (fi->rowbuf[0] >> (4 * ((i + 1) % 2))) & 0x0f;
|
dest[0] = (fi->rowbuf[0] >> (4 * ((i + 1) % 2))) & 0x0f;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
for (int c = 0; c < 3; c++)
|
for (gint c = 0; c < 3; c++)
|
||||||
{
|
|
||||||
dest[2 - c] = fi->rowbuf[c];
|
dest[2 - c] = fi->rowbuf[c];
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dest[fi->channels - 1] = 0xff; /* alpha */
|
dest[fi->channels - 1] = 0xff; /* alpha */
|
||||||
|
@ -1133,10 +1125,9 @@ load_rle (struct Fileinfo *fi, gsize offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
load_huffman (struct Fileinfo *fi, gsize offset)
|
load_huffman (struct Fileinfo *fi, guchar *dest)
|
||||||
{
|
{
|
||||||
gint xpos = 0, len, i;
|
gint xpos = 0, len, i;
|
||||||
guchar *dest;
|
|
||||||
|
|
||||||
while (xpos < fi->width)
|
while (xpos < fi->width)
|
||||||
{
|
{
|
||||||
|
@ -1158,11 +1149,8 @@ load_huffman (struct Fileinfo *fi, gsize offset)
|
||||||
len = huff_decode (&fi->bitbuf, &fi->buflen, fi->file, fi->black);
|
len = huff_decode (&fi->bitbuf, &fi->buflen, fi->file, fi->black);
|
||||||
if (len >= 0 && len <= fi->width - xpos)
|
if (len >= 0 && len <= fi->width - xpos)
|
||||||
{
|
{
|
||||||
dest = fi->dest + offset + xpos;
|
|
||||||
for (i = 0; i < len; i++, xpos++)
|
for (i = 0; i < len; i++, xpos++)
|
||||||
{
|
*dest++ = fi->black;
|
||||||
dest[i] = fi->black;
|
|
||||||
}
|
|
||||||
fi->black = ! fi->black;
|
fi->black = ! fi->black;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue