From 565ead32b81b8dc62d71a5dff1c3076c1f59f1cb Mon Sep 17 00:00:00 2001 From: Rupert Date: Sun, 22 Dec 2024 13:35:18 +0100 Subject: [PATCH] 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. --- plug-ins/file-bmp/bmp-load.c | 92 ++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 52 deletions(-) diff --git a/plug-ins/file-bmp/bmp-load.c b/plug-ins/file-bmp/bmp-load.c index 96d618f79d..55082567ee 100644 --- a/plug-ins/file-bmp/bmp-load.c +++ b/plug-ins/file-bmp/bmp-load.c @@ -68,8 +68,6 @@ struct Fileinfo guchar *rowbuf; guint64 bytes_per_row; gint bpp; - guchar *dest; - gsize rowstride; gint channels; gint bytesperchannel; gint ncolors; @@ -94,15 +92,15 @@ static GimpImage * ReadImage (struct Fileinfo *fi, GError **error); static gint load_rgb_64 (struct Fileinfo *fi, - gsize offset); + guchar *dest); static gint load_rgb (struct Fileinfo *fi, - gsize offset); + guchar *dest); static gint load_indexed (struct Fileinfo *fi, - gsize offset); + guchar *dest); static gint load_rle (struct Fileinfo *fi, - gsize offset); + guchar *dest); static gint load_huffman (struct Fileinfo *fi, - gsize offset); + guchar *dest); static gint huff_decode (guint32 *bitbuf, gint *buflen, @@ -679,7 +677,9 @@ ReadImage (struct Fileinfo *fi, GimpImageType image_type; GimpPrecision precision_type = GIMP_PRECISION_U8_NON_LINEAR; const Babl *format = NULL; + guchar *dest = NULL; gsize dest_size = 0; + gsize rowstride; gint maxbits; gint eof = FALSE; 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)) { 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)); } - if (! (fi->dest && fi->rowbuf)) + if (! (dest && fi->rowbuf)) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Image dimensions too large: width %d x height %d"), fi->width, fi->height); - g_free (fi->dest); + g_free (dest); g_free (fi->rowbuf); return NULL; } @@ -813,7 +813,7 @@ ReadImage (struct Fileinfo *fi, gimp_image_insert_layer (image, layer, NULL, 0); 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; max_progress = fi->height; @@ -823,22 +823,22 @@ ReadImage (struct Fileinfo *fi, 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) { case BMPFMT_RGB: - if (! load_rgb (fi, offset)) + if (! load_rgb (fi, dest + offset)) eof = TRUE; break; case BMPFMT_RGB_64: - if (! load_rgb_64 (fi, offset)) + if (! load_rgb_64 (fi, dest + offset)) eof = TRUE; break; case BMPFMT_INDEXED: - if (! load_indexed (fi, offset)) + if (! load_indexed (fi, dest + offset)) eof = TRUE; break; @@ -846,12 +846,12 @@ ReadImage (struct Fileinfo *fi, if (fi->file_ypos < ypos) break; - if (! load_rle (fi, offset)) + if (! load_rle (fi, dest + offset)) eof = TRUE; break; case BMPFMT_HUFFMAN: - if (! load_huffman (fi, offset)) + if (! load_huffman (fi, dest + offset)) eof = TRUE; break; } @@ -865,18 +865,18 @@ ReadImage (struct Fileinfo *fi, /* 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) */ - 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, - fi->dest + offs, GEGL_AUTO_ROWSTRIDE); - memset (fi->dest, 0, dest_size); + dest + offset, GEGL_AUTO_ROWSTRIDE); + memset (dest, 0, dest_size); fi->tile_n = 0; } } g_object_unref (buffer); - g_free (fi->dest); + g_free (dest); if (! fi->gray && fi->bpp <= 8) 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 -load_rgb (struct Fileinfo *fi, gsize offset) +load_rgb (struct Fileinfo *fi, guchar *dest) { gint xpos, i; gint32 px; gdouble d; - guchar *dest8; guint16 *dest16; guint32 *dest32; if (! ReadOK (fi->file, fi->rowbuf, fi->bytes_per_row)) return FALSE; - dest8 = fi->dest + fi->bytesperchannel * offset; - dest16 = (guint16 *) dest8; - dest32 = (guint32 *) dest8; + dest16 = (guint16 *) dest; + dest32 = (guint32 *) dest; 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; if (fi->bytesperchannel == 1) - *dest8++ = d * 0x00ff + 0.5; + *dest++ = d * 0x00ff + 0.5; else if (fi->bytesperchannel == 2) *dest16++ = d * 0xffffUL + 0.5; else @@ -926,7 +924,7 @@ load_rgb (struct Fileinfo *fi, gsize offset) } static gint -load_rgb_64 (struct Fileinfo *fi, gsize offset) +load_rgb_64 (struct Fileinfo *fi, guchar *dest) { gint xpos, i; gfloat *destflt; @@ -934,7 +932,7 @@ load_rgb_64 (struct Fileinfo *fi, gsize offset) if (! ReadOK (fi->file, fi->rowbuf, fi->bytes_per_row)) return FALSE; - destflt = (gfloat *) fi->dest + offset; + destflt = (gfloat *) dest; for (xpos = 0; xpos < fi->width; ++xpos) { @@ -953,15 +951,13 @@ load_rgb_64 (struct Fileinfo *fi, gsize offset) } static gint -load_indexed (struct Fileinfo *fi, gsize offset) +load_indexed (struct Fileinfo *fi, guchar *dest) { - gint xpos, val, shift; - guchar *dest; + gint xpos, val, shift; if (! ReadOK (fi->file, fi->rowbuf, fi->bytes_per_row)) return FALSE; - dest = fi->dest + offset; for (xpos = 0; xpos < fi->width; xpos++) { val = fi->rowbuf[xpos / (8 / fi->bpp)]; @@ -977,7 +973,7 @@ load_indexed (struct Fileinfo *fi, gsize offset) } static gint -load_rle (struct Fileinfo *fi, gsize offset) +load_rle (struct Fileinfo *fi, guchar *basedest) { gint shift, i, j; guchar *dest; @@ -1005,13 +1001,13 @@ load_rle (struct Fileinfo *fi, gsize offset) i++, fi->xpos++, j++) { 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] = MIN (dest[0], fi->ncolors - 1); if (fi->gray) dest[0] = fi->colormap[dest[0] * 3]; 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++) { - dest = fi->dest + offset + fi->xpos * fi->channels; + dest = basedest + fi->xpos * fi->channels; for (gint c = 0; c < 3; c++) - { - dest[2 - c] = fi->rowbuf[c + 1]; - } + dest[2 - c] = fi->rowbuf[1 + c]; 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) { case 8: @@ -1063,10 +1057,8 @@ load_rle (struct Fileinfo *fi, gsize offset) dest[0] = (fi->rowbuf[0] >> (4 * ((i + 1) % 2))) & 0x0f; break; case 24: - for (int c = 0; c < 3; c++) - { - dest[2 - c] = fi->rowbuf[c]; - } + for (gint c = 0; c < 3; c++) + dest[2 - c] = fi->rowbuf[c]; break; } dest[fi->channels - 1] = 0xff; /* alpha */ @@ -1133,10 +1125,9 @@ load_rle (struct Fileinfo *fi, gsize offset) } static gint -load_huffman (struct Fileinfo *fi, gsize offset) +load_huffman (struct Fileinfo *fi, guchar *dest) { - gint xpos = 0, len, i; - guchar *dest; + gint xpos = 0, len, i; 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); if (len >= 0 && len <= fi->width - xpos) { - dest = fi->dest + offset + xpos; for (i = 0; i < len; i++, xpos++) - { - dest[i] = fi->black; - } + *dest++ = fi->black; fi->black = ! fi->black; continue; }