Gif now owns its data.
This commit is contained in:
57
src/gif.cc
57
src/gif.cc
@ -59,6 +59,8 @@
|
|||||||
* connection, if necessary).
|
* connection, if necessary).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include "dgif.hh"
|
#include "dgif.hh"
|
||||||
@ -94,7 +96,7 @@ struct DilloGif {
|
|||||||
uint_t Flags;
|
uint_t Flags;
|
||||||
|
|
||||||
uchar_t input_code_size;
|
uchar_t input_code_size;
|
||||||
uchar_t *linebuf;
|
std::vector< uchar_t > linebuf;
|
||||||
int pass;
|
int pass;
|
||||||
|
|
||||||
uint_t y;
|
uint_t y;
|
||||||
@ -129,7 +131,7 @@ struct DilloGif {
|
|||||||
int bits_in_window;
|
int bits_in_window;
|
||||||
uint_t last_code; /**< Last "compressed" code in the look up table */
|
uint_t last_code; /**< Last "compressed" code in the look up table */
|
||||||
uint_t line_index;
|
uint_t line_index;
|
||||||
uchar_t **spill_lines;
|
std::vector< std::vector< uchar_t > > spill_lines;
|
||||||
int num_spill_lines_max;
|
int num_spill_lines_max;
|
||||||
int length[(1 << MAX_LWZ_BITS) + 1];
|
int length[(1 << MAX_LWZ_BITS) + 1];
|
||||||
int code_and_byte[(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->Flags = 0;
|
||||||
gif->state = 0;
|
gif->state = 0;
|
||||||
gif->Start_Ofs = 0;
|
gif->Start_Ofs = 0;
|
||||||
gif->linebuf = NULL;
|
|
||||||
gif->Background = Image->bg_color;
|
gif->Background = Image->bg_color;
|
||||||
gif->transparent = -1;
|
gif->transparent = -1;
|
||||||
gif->num_spill_lines_max = 0;
|
gif->num_spill_lines_max = 0;
|
||||||
gif->spill_lines = NULL;
|
|
||||||
gif->window = 0;
|
gif->window = 0;
|
||||||
gif->packet_size = 0;
|
gif->packet_size = 0;
|
||||||
gif->ColorMap_ofs = 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.
|
* Free the gif-decoding data structure.
|
||||||
*/
|
*/
|
||||||
DilloGif::~DilloGif()
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is a cache client, it receives data from the cache
|
* 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)
|
static void Gif_lwz_init(DilloGif *gif)
|
||||||
{
|
{
|
||||||
gif->num_spill_lines_max = 1;
|
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;
|
gif->bits_in_window = 0;
|
||||||
|
|
||||||
/* First code in table = clear_code +1
|
/* 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;
|
gif->linebuf[gif->line_index++] = code;
|
||||||
if (gif->line_index >= gif->Width) {
|
if (gif->line_index >= gif->Width) {
|
||||||
Gif_emit_line(gif, gif->linebuf);
|
Gif_emit_line(gif, gif->linebuf.data());
|
||||||
gif->line_index = 0;
|
gif->line_index = 0;
|
||||||
}
|
}
|
||||||
gif->length[gif->last_code + 1] = 2;
|
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. */
|
* fit entirely within the present scan line. */
|
||||||
if (line_index + sequence_length <= gif->Width) {
|
if (line_index + sequence_length <= gif->Width) {
|
||||||
num_spill_lines = 0;
|
num_spill_lines = 0;
|
||||||
obuf = gif->linebuf;
|
obuf = gif->linebuf.data();
|
||||||
o_index = line_index + sequence_length;
|
o_index = line_index + sequence_length;
|
||||||
o_size = sequence_length - 1;
|
o_size = sequence_length - 1;
|
||||||
} else {
|
} else {
|
||||||
@ -478,17 +466,14 @@ static void Gif_sequence(DilloGif *gif, uint_t code)
|
|||||||
/* Allocate more spill lines. */
|
/* Allocate more spill lines. */
|
||||||
spill_line_index = gif->num_spill_lines_max;
|
spill_line_index = gif->num_spill_lines_max;
|
||||||
gif->num_spill_lines_max = num_spill_lines << 1;
|
gif->num_spill_lines_max = num_spill_lines << 1;
|
||||||
gif->spill_lines = reinterpret_cast< unsigned char ** >( dRealloc(gif->spill_lines,
|
gif->spill_lines.resize( gif->num_spill_lines_max );
|
||||||
gif->num_spill_lines_max *
|
|
||||||
sizeof(uchar_t *)) );
|
|
||||||
|
|
||||||
for (; spill_line_index < gif->num_spill_lines_max;
|
for (; spill_line_index < gif->num_spill_lines_max;
|
||||||
spill_line_index++)
|
spill_line_index++)
|
||||||
gif->spill_lines[spill_line_index] =
|
gif->spill_lines[spill_line_index].resize(gif->Width);
|
||||||
reinterpret_cast< unsigned char * >( dMalloc(gif->Width) );
|
|
||||||
}
|
}
|
||||||
spill_line_index = num_spill_lines - 1;
|
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;
|
o_size = o_index;
|
||||||
}
|
}
|
||||||
gif->line_index = o_index; /* for afterwards */
|
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 (o_index == 0) {
|
||||||
if (spill_line_index > 0) {
|
if (spill_line_index > 0) {
|
||||||
spill_line_index--;
|
spill_line_index--;
|
||||||
obuf = gif->spill_lines[spill_line_index];
|
obuf = gif->spill_lines[spill_line_index].data();
|
||||||
o_size = gif->Width;
|
o_size = gif->Width;
|
||||||
} else {
|
} else {
|
||||||
obuf = gif->linebuf;
|
obuf = gif->linebuf.data();
|
||||||
o_size = sequence_length - 1;
|
o_size = sequence_length - 1;
|
||||||
}
|
}
|
||||||
o_index = gif->Width;
|
o_index = gif->Width;
|
||||||
@ -540,24 +525,22 @@ static void Gif_sequence(DilloGif *gif, uint_t code)
|
|||||||
|
|
||||||
/* Output any full lines. */
|
/* Output any full lines. */
|
||||||
if (gif->line_index >= gif->Width) {
|
if (gif->line_index >= gif->Width) {
|
||||||
Gif_emit_line(gif, gif->linebuf);
|
Gif_emit_line(gif, gif->linebuf.data());
|
||||||
gif->line_index = 0;
|
gif->line_index = 0;
|
||||||
}
|
}
|
||||||
if (num_spill_lines) {
|
if (num_spill_lines) {
|
||||||
if (gif->line_index)
|
if (gif->line_index)
|
||||||
Gif_emit_line(gif, gif->linebuf);
|
Gif_emit_line(gif, gif->linebuf.data());
|
||||||
for (spill_line_index = 0;
|
for (spill_line_index = 0;
|
||||||
spill_line_index < num_spill_lines - (gif->line_index ? 1 : 0);
|
spill_line_index < num_spill_lines - (gif->line_index ? 1 : 0);
|
||||||
spill_line_index++)
|
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) {
|
if (num_spill_lines) {
|
||||||
/* Swap the last spill line with the gif line, using
|
/* Swap the last spill line with the gif line, using
|
||||||
* linebuf as the swap temporary. */
|
* linebuf as the swap temporary. */
|
||||||
uchar_t *linebuf = gif->spill_lines[num_spill_lines - 1];
|
using std::swap;
|
||||||
|
swap( gif->spill_lines[num_spill_lines - 1], gif->linebuf );
|
||||||
gif->spill_lines[num_spill_lines - 1] = gif->linebuf;
|
|
||||||
gif->linebuf = linebuf;
|
|
||||||
}
|
}
|
||||||
gif->spill_line_index = spill_line_index;
|
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->y = 0;
|
||||||
Gif_lwz_init(gif);
|
Gif_lwz_init(gif);
|
||||||
gif->spill_line_index = 0;
|
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 */
|
gif->state = 3; /*Process the lzw data next */
|
||||||
if (gif->ColorMap_ofs) {
|
if (gif->ColorMap_ofs) {
|
||||||
a_Dicache_set_cmap(gif->url, gif->version, gif->Background,
|
a_Dicache_set_cmap(gif->url, gif->version, gif->Background,
|
||||||
|
|||||||
Reference in New Issue
Block a user