guint depth;
guint Negative; /* Negative = 1 -> top down BMP,
Negative = 0 -> bottom up BMP */
+ guint n_colors;
};
/* Data needed for the "state" during decompression */
guint Lines; /* # of finished lines */
guchar *buff;
- gint BufferSize;
- gint BufferDone;
+ guint BufferSize;
+ guint BufferDone;
guchar (*Colormap)[3];
struct bmp_progressive_state *State,
GError **error)
{
+ gint clrUsed;
+
/* FIXME this is totally unrobust against bogus image data. */
if (State->BufferSize < lsb_32 (&BIH[0]) + 14) {
#if DUMPBIH
DumpBIH(BIH);
-#endif
+#endif
State->Header.size = lsb_32 (&BIH[0]);
if (State->Header.size == 40) {
return FALSE;
}
+ clrUsed = (int) (BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) + (BIH[32]);
+ if (clrUsed != 0)
+ State->Header.n_colors = clrUsed;
+ else
+ State->Header.n_colors = 1 << State->Header.depth;
+
+ if (State->Header.n_colors > 1 << State->Header.depth) {
+ 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;
+ }
+
State->Type = State->Header.depth; /* This may be less trivial someday */
/* Negative heights indicates bottom-down pixelorder */
GError **error)
{
gint i;
+ gint samples;
g_assert (State->read_state == READ_STATE_PALETTE);
+ samples = (State->Header.size == 12 ? 3 : 4);
+ if (State->BufferSize < State->Header.n_colors * samples) {
+ State->BufferSize = State->Header.n_colors * samples;
+ if (!grow_buffer (State, error))
+ return FALSE;
+ return TRUE;
+ }
+
State->Colormap = g_malloc ((1 << State->Header.depth) * sizeof (*State->Colormap));
+ for (i = 0; i < State->Header.n_colors; i++)
- for (i = 0; i < (1 << State->Header.depth); i++)
{
- State->Colormap[i][0] = buff[i * (State->Header.size == 12 ? 3 : 4)];
- State->Colormap[i][1] = buff[i * (State->Header.size == 12 ? 3 : 4) + 1];
- State->Colormap[i][2] = buff[i * (State->Header.size == 12 ? 3 : 4) + 2];
+ State->Colormap[i][0] = buff[i * samples];
+ State->Colormap[i][1] = buff[i * samples + 1];
+ State->Colormap[i][2] = buff[i * samples + 2];
#ifdef DUMPCMAP
g_print ("color %d %x %x %x\n", i,
State->Colormap[i][0],
* return context (opaque to user)
*/
+static struct bmp_progressive_state *d;
+
static gpointer
gdk_pixbuf__bmp_image_begin_load(GdkPixbufModuleSizeFunc size_func,
GdkPixbufModulePreparedFunc prepared_func,
GError **error)
{
struct bmp_progressive_state *context;
-
+
context = g_new0(struct bmp_progressive_state, 1);
context->size_func = size_func;
context->prepared_func = prepared_func;
context->pixbuf = NULL;
-
-
+
+ d = context;
return (gpointer) context;
}
/* FIXME this thing needs to report errors if
* we have unused image data
*/
-
+
g_return_val_if_fail(context != NULL, TRUE);
if (context->Colormap != NULL)
* buf - new image data
* size - length of new image data
*
- * append image data onto inrecrementally built output image
+ * append image data onto incrementally built output image
*/
static gboolean
gdk_pixbuf__bmp_image_load_increment(gpointer data,