Fix Ximian bug #12125; merged from gdk-pixbuf stable.
2001-11-21 Federico Mena Quintero <federico@ximian.com> Fix Ximian bug #12125; merged from gdk-pixbuf stable. * gdk-pixbuf/io-bmp.c (gdk_pixbuf__bmp_image_load_increment): Use a simple state machine instead of a scary if/else chain. (DecodeHeader): Set the reading state. (DecodeColormap): Set the reading state. (decode_bitmasks): New function, decodes the bitmasks for BI_BITFIELDS coding. (OneLine32): Handle BI_BITFIELDS coding. (OneLine16): Likewise.
This commit is contained in:
committed by
Federico Mena Quintero
parent
3e3322608c
commit
ab13c8803d
@ -1,3 +1,16 @@
|
||||
2001-11-21 Federico Mena Quintero <federico@ximian.com>
|
||||
|
||||
Fix Ximian bug #12125; merged from gdk-pixbuf stable.
|
||||
|
||||
* gdk-pixbuf/io-bmp.c (gdk_pixbuf__bmp_image_load_increment): Use
|
||||
a simple state machine instead of a scary if/else chain.
|
||||
(DecodeHeader): Set the reading state.
|
||||
(DecodeColormap): Set the reading state.
|
||||
(decode_bitmasks): New function, decodes the bitmasks for
|
||||
BI_BITFIELDS coding.
|
||||
(OneLine32): Handle BI_BITFIELDS coding.
|
||||
(OneLine16): Likewise.
|
||||
|
||||
2001-11-18 Hans Breuer <hans@breuer.org>
|
||||
|
||||
* io-xpm.c : use g_strcasecmp(), some poor platforms
|
||||
|
||||
@ -34,48 +34,54 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
These structures are actually dummies. These are according to
|
||||
the "Windows API reference guide volume II" as written by
|
||||
Borland International, but GCC fiddles with the alignment of
|
||||
the internal members, so these aren't actually usable.
|
||||
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/* If these structures were unpacked, they would define the two headers of the
|
||||
* BMP file. After them comes the palette, and then the image data.
|
||||
*
|
||||
* We do not use these structures; we just keep them here for reference.
|
||||
*/
|
||||
struct BitmapFileHeader {
|
||||
gushort bfType;
|
||||
guint bfSize;
|
||||
guint reserverd;
|
||||
guint bfOffbits;
|
||||
guint16 magic;
|
||||
guint32 file_size;
|
||||
guint32 reserved;
|
||||
guint32 data_offset;
|
||||
};
|
||||
|
||||
struct BitmapInfoHeader {
|
||||
guint biSize;
|
||||
guint biWidth;
|
||||
guint biHeight;
|
||||
gushort biPlanes;
|
||||
gushort biBitCount;
|
||||
guint biCompression;
|
||||
guint biSizeImage;
|
||||
guint biXPelsPerMeter;
|
||||
guint biYPelsPerMeter;
|
||||
guint biClrUsed;
|
||||
guint biClrImportant;
|
||||
guint32 header_size;
|
||||
guint32 width;
|
||||
guint32 height;
|
||||
guint16 planes;
|
||||
guint16 bpp;
|
||||
guint32 compression;
|
||||
guint32 data_size;
|
||||
guint32 x_ppm;
|
||||
guint32 y_ppm;
|
||||
guint32 n_colors;
|
||||
guint32 n_important_colors;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* biCompression values */
|
||||
/* Compression values */
|
||||
|
||||
#define BI_RGB 0
|
||||
#define BI_RLE8 1
|
||||
#define BI_RLE4 2
|
||||
#define BI_BITFIELDS 3
|
||||
#define BI_JPEG 4
|
||||
#define BI_PNG 5
|
||||
|
||||
/*
|
||||
/* State machine */
|
||||
typedef enum {
|
||||
READ_STATE_HEADERS, /* Reading the bitmap file header and bitmap info header */
|
||||
READ_STATE_PALETTE, /* Reading the palette */
|
||||
READ_STATE_BITMASKS, /* Reading the bitmasks for BI_BITFIELDS */
|
||||
READ_STATE_DATA, /* Reading the actual image data */
|
||||
READ_STATE_ERROR, /* An error occurred; further data will be ignored */
|
||||
READ_STATE_DONE /* Done reading the image; further data will be ignored */
|
||||
} ReadState;
|
||||
|
||||
DumpBIH printf's the values in a BitmapInfoHeader to the screen, for
|
||||
/*
|
||||
|
||||
DumpBIH printf's the values in a BitmapInfoHeader to the screen, for
|
||||
debugging purposes.
|
||||
|
||||
*/
|
||||
@ -121,13 +127,13 @@ struct headerpair {
|
||||
gint32 width;
|
||||
gint32 height;
|
||||
guint depth;
|
||||
guint Negative; /* Negative = 1 -> top down BMP,
|
||||
guint Negative; /* Negative = 1 -> top down BMP,
|
||||
Negative = 0 -> bottom up BMP */
|
||||
};
|
||||
|
||||
/* Data needed for the "state" during decompression */
|
||||
struct bmp_compression_state {
|
||||
gint phase;
|
||||
gint phase;
|
||||
gint RunCount;
|
||||
|
||||
guchar *linebuff;
|
||||
@ -142,6 +148,8 @@ struct bmp_progressive_state {
|
||||
ModuleUpdatedNotifyFunc updated_func;
|
||||
gpointer user_data;
|
||||
|
||||
ReadState read_state;
|
||||
|
||||
guint LineWidth;
|
||||
guint Lines; /* # of finished lines */
|
||||
|
||||
@ -151,13 +159,13 @@ struct bmp_progressive_state {
|
||||
|
||||
guchar (*Colormap)[3];
|
||||
|
||||
gint Type; /*
|
||||
gint Type; /*
|
||||
32 = RGB + alpha
|
||||
24 = RGB
|
||||
16 = RGB
|
||||
4 = 4 bpp colormapped
|
||||
8 = 8 bpp colormapped
|
||||
1 = 1 bit bitonal
|
||||
1 = 1 bit bitonal
|
||||
*/
|
||||
gint Compressed;
|
||||
struct bmp_compression_state compr;
|
||||
@ -165,6 +173,10 @@ struct bmp_progressive_state {
|
||||
|
||||
struct headerpair Header; /* Decoded (BE->CPU) header */
|
||||
|
||||
/* Bit masks, shift amounts, and significant bits for BI_BITFIELDS coding */
|
||||
int r_mask, r_shift, r_bits;
|
||||
int g_mask, g_shift, g_bits;
|
||||
int b_mask, b_shift, b_bits;
|
||||
|
||||
GdkPixbuf *pixbuf; /* Our "target" */
|
||||
};
|
||||
@ -199,9 +211,9 @@ static GdkPixbuf *gdk_pixbuf__bmp_image_load(FILE * f, GError **error)
|
||||
|
||||
if (State == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
while (feof(f) == 0) {
|
||||
length = fread(membuf, 1, 4096, f);
|
||||
length = fread(membuf, 1, sizeof (membuf), f);
|
||||
if (length > 0)
|
||||
if (!gdk_pixbuf__bmp_image_load_increment(State,
|
||||
membuf,
|
||||
@ -226,7 +238,7 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
|
||||
GError **error)
|
||||
{
|
||||
/* FIXME this is totally unrobust against bogus image data. */
|
||||
|
||||
|
||||
if (State->BufferSize < GUINT32_FROM_LE (* (guint32 *) &BIH[0]) + 14) {
|
||||
State->BufferSize = GUINT32_FROM_LE (* (guint32 *) &BIH[0]) + 14;
|
||||
State->buff = g_realloc (State->buff, State->BufferSize);
|
||||
@ -247,12 +259,13 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
|
||||
State->Header.width = GUINT16_FROM_LE (* (guint16 *) &BIH[4]);
|
||||
State->Header.height = GUINT16_FROM_LE (* (guint16 *) &BIH[6]);
|
||||
State->Header.depth = GUINT16_FROM_LE (* (guint16 *) &BIH[10]);
|
||||
State->Compressed = 0;
|
||||
State->Compressed = BI_RGB;
|
||||
} else {
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||
_("BMP image has unsupported header size"));
|
||||
State->read_state = READ_STATE_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -271,11 +284,13 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
|
||||
if (State->Header.width == 0 || State->Header.height == 0 ||
|
||||
(State->Compressed == BI_RLE4 && State->Type != 4) ||
|
||||
(State->Compressed == BI_RLE8 && State->Type != 8) ||
|
||||
State->Compressed > BI_RLE4) {
|
||||
(State->Compressed == BI_BITFIELDS && !(State->Type == 16 || State->Type == 32)) ||
|
||||
State->Compressed > BI_BITFIELDS) {
|
||||
g_set_error (error,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||
_("BMP image has bogus header data"));
|
||||
State->read_state = READ_STATE_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -298,14 +313,15 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||
_("BMP image has bogus header data"));
|
||||
State->read_state = READ_STATE_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Pad to a 32 bit boundary */
|
||||
if (((State->LineWidth % 4) > 0) && (State->Compressed == BI_RGB))
|
||||
if (((State->LineWidth % 4) > 0)
|
||||
&& (State->Compressed == BI_RGB || State->Compressed == BI_BITFIELDS))
|
||||
State->LineWidth = (State->LineWidth / 4) * 4 + 4;
|
||||
|
||||
|
||||
if (State->pixbuf == NULL) {
|
||||
if (State->Type == 32)
|
||||
State->pixbuf =
|
||||
@ -323,16 +339,17 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
|
||||
GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
|
||||
_("Not enough memory to load bitmap image"));
|
||||
State->read_state = READ_STATE_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (State->prepared_func != NULL)
|
||||
/* Notify the client that we are ready to go */
|
||||
(*State->prepared_func) (State->pixbuf, NULL, State->user_data);
|
||||
|
||||
}
|
||||
|
||||
if (State->Compressed != BI_RGB) {
|
||||
if (!(State->Compressed == BI_RGB || State->Compressed == BI_BITFIELDS)) {
|
||||
State->compr.linebuffdone = 0;
|
||||
State->compr.linebuffsize = State->Header.width;
|
||||
if (State->Type == 8)
|
||||
@ -341,12 +358,18 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
|
||||
}
|
||||
|
||||
State->BufferDone = 0;
|
||||
if (State->Type <= 8)
|
||||
if (State->Type <= 8) {
|
||||
State->read_state = READ_STATE_PALETTE;
|
||||
State->BufferSize = GUINT32_FROM_LE (* (guint32 *) &BFH[10]) - 14 - State->Header.size;
|
||||
else if (State->Compressed != BI_RGB)
|
||||
State->BufferSize = 2;
|
||||
else
|
||||
} else if (State->Compressed == BI_RGB) {
|
||||
State->read_state = READ_STATE_DATA;
|
||||
State->BufferSize = State->LineWidth;
|
||||
} else if (State->Compressed == BI_BITFIELDS) {
|
||||
State->read_state = READ_STATE_BITMASKS;
|
||||
State->BufferSize = 12;
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
|
||||
State->buff = g_realloc (State->buff, State->BufferSize);
|
||||
|
||||
return TRUE;
|
||||
@ -358,6 +381,8 @@ static void DecodeColormap (guchar *buff,
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_assert (State->read_state == READ_STATE_PALETTE);
|
||||
|
||||
State->Colormap = g_malloc ((1 << State->Header.depth) * sizeof (*State->Colormap));
|
||||
|
||||
for (i = 0; i < (1 << State->Header.depth); i++)
|
||||
@ -367,15 +392,66 @@ static void DecodeColormap (guchar *buff,
|
||||
State->Colormap[i][2] = buff[i * (State->Header.size == 12 ? 3 : 4) + 2];
|
||||
}
|
||||
|
||||
State->read_state = READ_STATE_DATA;
|
||||
|
||||
State->BufferDone = 0;
|
||||
if (State->Compressed != BI_RGB)
|
||||
if (!(State->Compressed == BI_RGB || State->Compressed == BI_BITFIELDS))
|
||||
State->BufferSize = 2;
|
||||
else
|
||||
State->BufferSize = State->LineWidth;
|
||||
|
||||
State->buff = g_realloc (State->buff, State->BufferSize);
|
||||
}
|
||||
|
||||
/*
|
||||
/* Finds the lowest set bit and the number of set bits */
|
||||
static void
|
||||
find_bits (int n, int *lowest, int *n_set)
|
||||
{
|
||||
int i;
|
||||
|
||||
*n_set = 0;
|
||||
|
||||
for (i = 31; i >= 0; i--)
|
||||
if (n & (1 << i)) {
|
||||
*lowest = i;
|
||||
(*n_set)++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decodes the 3 shorts that follow for the bitmasks for BI_BITFIELDS coding */
|
||||
static void
|
||||
decode_bitmasks (struct bmp_progressive_state *State, guchar *buf)
|
||||
{
|
||||
State->r_mask = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
||||
buf += 4;
|
||||
|
||||
State->g_mask = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
||||
buf += 4;
|
||||
|
||||
State->b_mask = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
||||
|
||||
find_bits (State->r_mask, &State->r_shift, &State->r_bits);
|
||||
find_bits (State->g_mask, &State->g_shift, &State->g_bits);
|
||||
find_bits (State->b_mask, &State->b_shift, &State->b_bits);
|
||||
|
||||
if (State->r_bits == 0 || State->g_bits == 0 || State->b_bits == 0) {
|
||||
State->r_mask = 0x7c00;
|
||||
State->r_shift = 10;
|
||||
State->g_mask = 0x03e0;
|
||||
State->g_shift = 5;
|
||||
State->b_mask = 0x001f;
|
||||
State->b_shift = 0;
|
||||
|
||||
State->r_bits = State->g_bits = State->b_bits = 5;
|
||||
}
|
||||
|
||||
State->read_state = READ_STATE_DATA;
|
||||
State->BufferDone = 0;
|
||||
State->BufferSize = State->LineWidth;
|
||||
State->buff = g_realloc (State->buff, State->BufferSize);
|
||||
}
|
||||
|
||||
/*
|
||||
* func - called when we have pixmap created (but no image data)
|
||||
* user_data - passed as arg 1 to func
|
||||
* return context (opaque to user)
|
||||
@ -394,10 +470,12 @@ gdk_pixbuf__bmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
||||
context->updated_func = updated_func;
|
||||
context->user_data = user_data;
|
||||
|
||||
context->read_state = READ_STATE_HEADERS;
|
||||
|
||||
context->BufferSize = 26;
|
||||
context->buff = g_malloc(26);
|
||||
context->BufferDone = 0;
|
||||
/* 14 for the BitmapFileHeader, 12 for the BitmapImageHeader */
|
||||
/* 14 for the BitmapFileHeader, 12 for the BitmapImageHeader */
|
||||
|
||||
context->Colormap = NULL;
|
||||
|
||||
@ -427,7 +505,7 @@ static gboolean gdk_pixbuf__bmp_image_stop_load(gpointer data, GError **error)
|
||||
|
||||
/* FIXME this thing needs to report errors if
|
||||
* we have unused image data
|
||||
*/
|
||||
*/
|
||||
|
||||
g_return_val_if_fail(context != NULL, TRUE);
|
||||
|
||||
@ -453,26 +531,57 @@ OneLine24 is the 24 bpp-version.
|
||||
*/
|
||||
static void OneLine32(struct bmp_progressive_state *context)
|
||||
{
|
||||
gint X;
|
||||
guchar *Pixels;
|
||||
gint X; int i;
|
||||
guchar *pixels;
|
||||
guchar *src;
|
||||
|
||||
X = 0;
|
||||
if (context->Header.Negative == 0)
|
||||
Pixels = (context->pixbuf->pixels +
|
||||
context->pixbuf->rowstride *
|
||||
(context->Header.height - context->Lines - 1));
|
||||
if (!context->Header.Negative)
|
||||
pixels = (context->pixbuf->pixels +
|
||||
context->pixbuf->rowstride * (context->Header.height - context->Lines - 1));
|
||||
else
|
||||
Pixels = (context->pixbuf->pixels +
|
||||
context->pixbuf->rowstride *
|
||||
context->Lines);
|
||||
while (X < context->Header.width) {
|
||||
Pixels[X * 4 + 0] = context->buff[X * 4 + 2];
|
||||
Pixels[X * 4 + 1] = context->buff[X * 4 + 1];
|
||||
Pixels[X * 4 + 2] = context->buff[X * 4 + 0];
|
||||
Pixels[X * 4 + 3] = context->buff[X * 4 + 3];
|
||||
X++;
|
||||
}
|
||||
pixels = (context->pixbuf->pixels +
|
||||
context->pixbuf->rowstride * context->Lines);
|
||||
|
||||
src = context->buff;
|
||||
|
||||
if (context->Compressed == BI_BITFIELDS) {
|
||||
int r_lshift, r_rshift;
|
||||
int g_lshift, g_rshift;
|
||||
int b_lshift, b_rshift;
|
||||
|
||||
r_lshift = 8 - context->r_bits;
|
||||
g_lshift = 8 - context->g_bits;
|
||||
b_lshift = 8 - context->b_bits;
|
||||
|
||||
r_rshift = context->r_bits - r_lshift;
|
||||
g_rshift = context->g_bits - g_lshift;
|
||||
b_rshift = context->b_bits - b_lshift;
|
||||
|
||||
for (i = 0; i < context->Header.width; i++) {
|
||||
int v, r, g, b;
|
||||
|
||||
v = src[0] | (src[1] << 8) | (src[2] << 16);
|
||||
|
||||
r = (v & context->r_mask) >> context->r_shift;
|
||||
g = (v & context->g_mask) >> context->g_shift;
|
||||
b = (v & context->b_mask) >> context->b_shift;
|
||||
|
||||
*pixels++ = (r << r_lshift) | (r >> r_rshift);
|
||||
*pixels++ = (g << g_lshift) | (g >> g_rshift);
|
||||
*pixels++ = (b << b_lshift) | (b >> b_rshift);
|
||||
*pixels++ = src[3]; /* alpha */
|
||||
|
||||
src += 4;
|
||||
}
|
||||
} else
|
||||
for (i = 0; i < context->Header.width; i++) {
|
||||
*pixels++ = src[2];
|
||||
*pixels++ = src[1];
|
||||
*pixels++ = src[0];
|
||||
*pixels++ = src[3];
|
||||
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void OneLine24(struct bmp_progressive_state *context)
|
||||
@ -500,24 +609,61 @@ static void OneLine24(struct bmp_progressive_state *context)
|
||||
|
||||
static void OneLine16(struct bmp_progressive_state *context)
|
||||
{
|
||||
gint X;
|
||||
guchar *Pixels;
|
||||
int i;
|
||||
guchar *pixels;
|
||||
guchar *src;
|
||||
|
||||
X = 0;
|
||||
if (context->Header.Negative == 0)
|
||||
Pixels = (context->pixbuf->pixels +
|
||||
context->pixbuf->rowstride *
|
||||
(context->Header.height - context->Lines - 1));
|
||||
if (!context->Header.Negative)
|
||||
pixels = (context->pixbuf->pixels +
|
||||
context->pixbuf->rowstride * (context->Header.height - context->Lines - 1));
|
||||
else
|
||||
Pixels = (context->pixbuf->pixels +
|
||||
context->pixbuf->rowstride *
|
||||
context->Lines);
|
||||
while (X < context->Header.width) {
|
||||
Pixels[X * 3 + 0] = (GUINT16_FROM_LE (* (guint16 *) &context->buff[X * 2]) & 0x7C00) >> 7;
|
||||
Pixels[X * 3 + 1] = (GUINT16_FROM_LE (* (guint16 *) &context->buff[X * 2]) & 0x03E0) >> 2;
|
||||
Pixels[X * 3 + 2] = (GUINT16_FROM_LE (* (guint16 *) &context->buff[X * 2]) & 0x001F) << 3;
|
||||
X++;
|
||||
}
|
||||
pixels = (context->pixbuf->pixels +
|
||||
context->pixbuf->rowstride * context->Lines);
|
||||
|
||||
src = context->buff;
|
||||
|
||||
if (context->Compressed == BI_BITFIELDS) {
|
||||
int r_lshift, r_rshift;
|
||||
int g_lshift, g_rshift;
|
||||
int b_lshift, b_rshift;
|
||||
|
||||
r_lshift = 8 - context->r_bits;
|
||||
g_lshift = 8 - context->g_bits;
|
||||
b_lshift = 8 - context->b_bits;
|
||||
|
||||
r_rshift = context->r_bits - r_lshift;
|
||||
g_rshift = context->g_bits - g_lshift;
|
||||
b_rshift = context->b_bits - b_lshift;
|
||||
|
||||
for (i = 0; i < context->Header.width; i++) {
|
||||
int v, r, g, b;
|
||||
|
||||
v = (int) src[0] | ((int) src[1] << 8);
|
||||
|
||||
r = (v & context->r_mask) >> context->r_shift;
|
||||
g = (v & context->g_mask) >> context->g_shift;
|
||||
b = (v & context->b_mask) >> context->b_shift;
|
||||
|
||||
*pixels++ = (r << r_lshift) | (r >> r_rshift);
|
||||
*pixels++ = (g << g_lshift) | (g >> g_rshift);
|
||||
*pixels++ = (b << b_lshift) | (b >> b_rshift);
|
||||
|
||||
src += 2;
|
||||
}
|
||||
} else
|
||||
for (i = 0; i < context->Header.width; i++) {
|
||||
int v, r, g, b;
|
||||
|
||||
v = src[0] | (src[1] << 8);
|
||||
|
||||
r = (v >> 10) & 0x1f;
|
||||
g = (v >> 5) & 0x1f;
|
||||
b = v & 0x1f;
|
||||
|
||||
*pixels++ = (r << 3) | (r >> 2);
|
||||
*pixels++ = (g << 3) | (g >> 2);
|
||||
*pixels++ = (b << 3) | (b >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void OneLine8(struct bmp_progressive_state *context)
|
||||
@ -621,16 +767,18 @@ static void OneLine(struct bmp_progressive_state *context)
|
||||
|
||||
if (context->Type == 32)
|
||||
OneLine32(context);
|
||||
if (context->Type == 24)
|
||||
else if (context->Type == 24)
|
||||
OneLine24(context);
|
||||
if (context->Type == 16)
|
||||
else if (context->Type == 16)
|
||||
OneLine16(context);
|
||||
if (context->Type == 8)
|
||||
else if (context->Type == 8)
|
||||
OneLine8(context);
|
||||
if (context->Type == 4)
|
||||
else if (context->Type == 4)
|
||||
OneLine4(context);
|
||||
if (context->Type == 1)
|
||||
else if (context->Type == 1)
|
||||
OneLine1(context);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
context->Lines++;
|
||||
|
||||
@ -792,8 +940,13 @@ gdk_pixbuf__bmp_image_load_increment(gpointer data,
|
||||
|
||||
gint BytesToCopy;
|
||||
|
||||
if (context->read_state == READ_STATE_DONE)
|
||||
return TRUE;
|
||||
else if (context->read_state == READ_STATE_ERROR)
|
||||
return FALSE;
|
||||
|
||||
while (size > 0) {
|
||||
if (context->BufferDone < context->BufferSize) { /* We still
|
||||
if (context->BufferDone < context->BufferSize) { /* We still
|
||||
have headerbytes to do */
|
||||
BytesToCopy =
|
||||
context->BufferSize - context->BufferDone;
|
||||
@ -811,19 +964,32 @@ gdk_pixbuf__bmp_image_load_increment(gpointer data,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!context->Header.size) {
|
||||
if (!DecodeHeader (context->buff,
|
||||
context->buff + 14, context,
|
||||
error))
|
||||
switch (context->read_state) {
|
||||
case READ_STATE_HEADERS:
|
||||
if (!DecodeHeader (context->buff, context->buff + 14, context))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case READ_STATE_PALETTE:
|
||||
DecodeColormap (context->buff, context);
|
||||
break;
|
||||
|
||||
case READ_STATE_BITMASKS:
|
||||
decode_bitmasks (context, context->buff);
|
||||
break;
|
||||
|
||||
case READ_STATE_DATA:
|
||||
if (context->Compressed == BI_RGB || context->Compressed == BI_BITFIELDS)
|
||||
OneLine (context);
|
||||
else
|
||||
DoCompressed (context);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
else if (context->Type <= 8 && context->Colormap == NULL)
|
||||
DecodeColormap (context->buff, context, error);
|
||||
else if (context->Compressed != BI_RGB)
|
||||
DoCompressed(context);
|
||||
else
|
||||
/* Uncompressed pixeldata */
|
||||
OneLine(context);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
Reference in New Issue
Block a user