Gif now owns its data.

This commit is contained in:
2025-08-02 00:55:08 -04:00
parent 019f151588
commit bd11b90200

View File

@ -59,6 +59,8 @@
* connection, if necessary).
*/
#include <vector>
#include <config.h>
#include "dgif.hh"
@ -94,7 +96,7 @@ struct DilloGif {
uint_t Flags;
uchar_t input_code_size;
uchar_t *linebuf;
std::vector< uchar_t > linebuf;
int pass;
uint_t y;
@ -129,7 +131,7 @@ struct DilloGif {
int bits_in_window;
uint_t last_code; /**< Last "compressed" code in the look up table */
uint_t line_index;
uchar_t **spill_lines;
std::vector< std::vector< uchar_t > > spill_lines;
int num_spill_lines_max;
int length[(1 << MAX_LWZ_BITS) + 1];
int code_and_byte[(1 << MAX_LWZ_BITS) + 1];
@ -167,11 +169,9 @@ DilloGif *a_Gif_new(DilloImage *Image, DilloUrl *url, int version)
gif->Flags = 0;
gif->state = 0;
gif->Start_Ofs = 0;
gif->linebuf = NULL;
gif->Background = Image->bg_color;
gif->transparent = -1;
gif->num_spill_lines_max = 0;
gif->spill_lines = NULL;
gif->window = 0;
gif->packet_size = 0;
gif->ColorMap_ofs = 0;
@ -182,19 +182,7 @@ DilloGif *a_Gif_new(DilloImage *Image, DilloUrl *url, int version)
/**
* Free the gif-decoding data structure.
*/
DilloGif::~DilloGif()
{
int i;
_MSG("Gif_free: gif=%p\n", gif);
dFree(linebuf);
if (spill_lines != NULL) {
for (i = 0; i < num_spill_lines_max; i++)
dFree(spill_lines[i]);
dFree(spill_lines);
}
}
DilloGif::~DilloGif() {}
/**
* This function is a cache client, it receives data from the cache
@ -372,9 +360,9 @@ static size_t Gif_do_extension(DilloGif *gif, uint_t Label,
static void Gif_lwz_init(DilloGif *gif)
{
gif->num_spill_lines_max = 1;
gif->spill_lines = reinterpret_cast< unsigned char ** >( dMalloc(sizeof(uchar_t *) * gif->num_spill_lines_max) );
gif->spill_lines.resize( gif->num_spill_lines_max );
gif->spill_lines[0] = reinterpret_cast< unsigned char * >( dMalloc(gif->Width) );
gif->spill_lines[0].resize( gif->Width );
gif->bits_in_window = 0;
/* First code in table = clear_code +1
@ -438,7 +426,7 @@ static void Gif_literal(DilloGif *gif, uint_t code)
{
gif->linebuf[gif->line_index++] = code;
if (gif->line_index >= gif->Width) {
Gif_emit_line(gif, gif->linebuf);
Gif_emit_line(gif, gif->linebuf.data());
gif->line_index = 0;
}
gif->length[gif->last_code + 1] = 2;
@ -467,7 +455,7 @@ static void Gif_sequence(DilloGif *gif, uint_t code)
* fit entirely within the present scan line. */
if (line_index + sequence_length <= gif->Width) {
num_spill_lines = 0;
obuf = gif->linebuf;
obuf = gif->linebuf.data();
o_index = line_index + sequence_length;
o_size = sequence_length - 1;
} else {
@ -478,17 +466,14 @@ static void Gif_sequence(DilloGif *gif, uint_t code)
/* Allocate more spill lines. */
spill_line_index = gif->num_spill_lines_max;
gif->num_spill_lines_max = num_spill_lines << 1;
gif->spill_lines = reinterpret_cast< unsigned char ** >( dRealloc(gif->spill_lines,
gif->num_spill_lines_max *
sizeof(uchar_t *)) );
gif->spill_lines.resize( gif->num_spill_lines_max );
for (; spill_line_index < gif->num_spill_lines_max;
spill_line_index++)
gif->spill_lines[spill_line_index] =
reinterpret_cast< unsigned char * >( dMalloc(gif->Width) );
gif->spill_lines[spill_line_index].resize(gif->Width);
}
spill_line_index = num_spill_lines - 1;
obuf = gif->spill_lines[spill_line_index];
obuf = gif->spill_lines[spill_line_index].data();
o_size = o_index;
}
gif->line_index = o_index; /* for afterwards */
@ -516,10 +501,10 @@ static void Gif_sequence(DilloGif *gif, uint_t code)
if (o_index == 0) {
if (spill_line_index > 0) {
spill_line_index--;
obuf = gif->spill_lines[spill_line_index];
obuf = gif->spill_lines[spill_line_index].data();
o_size = gif->Width;
} else {
obuf = gif->linebuf;
obuf = gif->linebuf.data();
o_size = sequence_length - 1;
}
o_index = gif->Width;
@ -540,24 +525,22 @@ static void Gif_sequence(DilloGif *gif, uint_t code)
/* Output any full lines. */
if (gif->line_index >= gif->Width) {
Gif_emit_line(gif, gif->linebuf);
Gif_emit_line(gif, gif->linebuf.data());
gif->line_index = 0;
}
if (num_spill_lines) {
if (gif->line_index)
Gif_emit_line(gif, gif->linebuf);
Gif_emit_line(gif, gif->linebuf.data());
for (spill_line_index = 0;
spill_line_index < num_spill_lines - (gif->line_index ? 1 : 0);
spill_line_index++)
Gif_emit_line(gif, gif->spill_lines[spill_line_index]);
Gif_emit_line(gif, gif->spill_lines[spill_line_index].data());
}
if (num_spill_lines) {
/* Swap the last spill line with the gif line, using
* linebuf as the swap temporary. */
uchar_t *linebuf = gif->spill_lines[num_spill_lines - 1];
gif->spill_lines[num_spill_lines - 1] = gif->linebuf;
gif->linebuf = linebuf;
using std::swap;
swap( gif->spill_lines[num_spill_lines - 1], gif->linebuf );
}
gif->spill_line_index = spill_line_index;
}
@ -849,7 +832,7 @@ static size_t Gif_do_img_desc(DilloGif *gif, void *Buf,
gif->y = 0;
Gif_lwz_init(gif);
gif->spill_line_index = 0;
gif->linebuf = reinterpret_cast< unsigned char * >( dMalloc(gif->Width) );
gif->linebuf.resize( gif->Width );
gif->state = 3; /*Process the lzw data next */
if (gif->ColorMap_ofs) {
a_Dicache_set_cmap(gif->url, gif->version, gif->Background,