Major cleanup, added support for 32 bpp and 4 bpp (uncompressed) images,

1999-12-04  Arjan van de Ven <arjan@fenrus.demon.nl>

	* gdk-pixbuf/io-bmp.c: Major cleanup, added support for
	32 bpp and 4 bpp (uncompressed) images, fixed 1bpp.

	* gdk-pixbuf/io-ras.c: Minor cleanup, ran through lclint

	* gdk-pixbuf/io-ico.c: Minor cleanup, fixed 1bpp icons,
 	ran through lclint.

	* gdk-pixbuf/gdk-pixbuf-io.c: Added detection of .CUR files
	(Windows Cursor files). These are identical to .ICO files,
	except for the signature and 2 extra fields for the hotspot.
This commit is contained in:
Arjan van de Ven 1999-12-04 18:17:52 +00:00 committed by Arjan van de Ven
parent d8b35eab3e
commit 631f507f58
5 changed files with 347 additions and 277 deletions

View File

@ -1,3 +1,17 @@
1999-12-04 Arjan van de Ven <arjan@fenrus.demon.nl>
* gdk-pixbuf/io-bmp.c: Major cleanup, added support for
32 bpp and 4 bpp (uncompressed) images, fixed 1bpp.
* gdk-pixbuf/io-ras.c: Minor cleanup, ran through lclint
* gdk-pixbuf/io-ico.c: Minor cleanup, fixed 1bpp icons,
ran through lclint.
* gdk-pixbuf/gdk-pixbuf-io.c: Added detection of .CUR files
(Windows Cursor files). These are identical to .ICO files,
except for the signature and 2 extra fields for the hotspot.
1999-12-03 Jonathan Blandford <jrb@redhat.com>
* gdk-pixbuf/io-gif.c (gif_fill_in_lines): added a comment to

View File

@ -145,7 +145,7 @@ pixbuf_check_ico (guchar *buffer, int size)
return FALSE;
if (buffer [0] != 0x0 ||
buffer [1] != 0x0 ||
buffer [2] != 0x1 ||
((buffer [2] != 0x1)&&(buffer[2]!=0x2)) ||
buffer [3] != 0x0 ||
buffer [5] != 0x0 )
return FALSE;

View File

@ -26,33 +26,27 @@
/*
Known bugs:
* Compressed files don't work yet
* bi-tonal files aren't tested
* 4bpp compressed files don't work
* bi-tonal files aren't tested with palettes
*/
#include <config.h>
#include <stdio.h>
#include <unistd.h>
#include "gdk-pixbuf.h"
#include "gdk-pixbuf-io.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk-pixbuf/gdk-pixbuf-io.h>
struct headerpair {
guint width;
guint height;
guint depth;
guint Negative; /* Negative = 1 -> top down BMP,
Negative = 0 -> bottom up BMP */
};
/*
These structures are actually dummies. These are according to
the "Windows API reference guide volume II" as written by Borland,
but GCC fiddles with the alignment of the internal members.
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.
*/
@ -77,57 +71,56 @@ struct BitmapInfoHeader {
guint biClrImportant;
};
/*
DumpBIH printf's the values in a BitmapInfoHeader to the screen, for
debugging purposes.
*/
#if DUMPBIH
static void DumpBIH(unsigned char *BIH)
{ /* For debugging */
{
printf("biSize = %i \n",
(BIH[3] << 24) + (BIH[2] << 16) + (BIH[1] << 8) + (BIH[0]));
(int) (BIH[3] << 24) + (BIH[2] << 16) + (BIH[1] << 8) +
(BIH[0]));
printf("biWidth = %i \n",
(BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) + (BIH[4]));
(int) (BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) +
(BIH[4]));
printf("biHeight = %i \n",
(BIH[11] << 24) + (BIH[10] << 16) + (BIH[9] << 8) +
(int) (BIH[11] << 24) + (BIH[10] << 16) + (BIH[9] << 8) +
(BIH[8]));
printf("biPlanes = %i \n", (BIH[13] << 8) + (BIH[12]));
printf("biBitCount = %i \n", (BIH[15] << 8) + (BIH[14]));
printf("biPlanes = %i \n", (int) (BIH[13] << 8) + (BIH[12]));
printf("biBitCount = %i \n", (int) (BIH[15] << 8) + (BIH[14]));
printf("biCompress = %i \n",
(BIH[19] << 24) + (BIH[18] << 16) + (BIH[17] << 8) +
(int) (BIH[19] << 24) + (BIH[18] << 16) + (BIH[17] << 8) +
(BIH[16]));
printf("biSizeImage = %i \n",
(BIH[23] << 24) + (BIH[22] << 16) + (BIH[21] << 8) +
(int) (BIH[23] << 24) + (BIH[22] << 16) + (BIH[21] << 8) +
(BIH[20]));
printf("biXPels = %i \n",
(BIH[27] << 24) + (BIH[26] << 16) + (BIH[25] << 8) +
(int) (BIH[27] << 24) + (BIH[26] << 16) + (BIH[25] << 8) +
(BIH[24]));
printf("biYPels = %i \n",
(BIH[31] << 24) + (BIH[30] << 16) + (BIH[29] << 8) +
(int) (BIH[31] << 24) + (BIH[30] << 16) + (BIH[29] << 8) +
(BIH[28]));
printf("biClrUsed = %i \n",
(BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) +
(int) (BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) +
(BIH[32]));
printf("biClrImprtnt= %i \n",
(BIH[39] << 24) + (BIH[38] << 16) + (BIH[37] << 8) +
(int) (BIH[39] << 24) + (BIH[38] << 16) + (BIH[37] << 8) +
(BIH[36]));
}
#endif
/* struct headerpair contains the decoded width/height/depth info for
the current bitmap */
/*
This does a byte-order swap. Does glib have something like
be32_to_cpu() ??
*/
static unsigned int le32_to_cpu(guint i)
{
unsigned int i2;
return i2;
}
/*
Destroy notification function for the libart pixbuf
*/
static void free_buffer(gpointer user_data, gpointer data)
{
free(data);
}
struct headerpair {
guint width;
guint height;
guint depth;
guint Negative; /* Negative = 1 -> top down BMP,
Negative = 0 -> bottom up BMP */
};
/* Data needed for the "state" during decompression */
struct bmp_compression_state {
@ -161,8 +154,10 @@ struct bmp_progressive_state {
gint Lines; /* # of finished lines */
gint Type; /*
32 = RGB + alpha
24 = RGB
8 = 8 bit colormapped
4 = 4 bpp colormapped
8 = 8 bpp colormapped
1 = 1 bit bitonal
*/
gint Compressed;
@ -183,13 +178,13 @@ gboolean image_load_increment(gpointer data, guchar * buf, guint size);
/* Shared library entry point */
/* Shared library entry point --> This should be removed when
generic_image_load enters gdk-pixbuf-io. */
GdkPixbuf *image_load(FILE * f)
{
guchar *membuf;
size_t length;
struct bmp_progressive_state *State;
int fd;
GdkPixbuf *pb;
@ -202,7 +197,7 @@ GdkPixbuf *image_load(FILE * f)
while (feof(f) == 0) {
length = fread(membuf, 1, 4096, f);
if (length > 0)
image_load_increment(State, membuf, length);
(void) image_load_increment(State, membuf, length);
}
g_free(membuf);
@ -212,31 +207,38 @@ GdkPixbuf *image_load(FILE * f)
pb = State->pixbuf;
image_stop_load(State);
return State->pixbuf;
return pb;
}
static void DecodeHeader(unsigned char *BFH, unsigned char *BIH,
struct bmp_progressive_state *State)
{
/* DumpBIH(BIH);*/
#if DUMPBIH
DumpBIH(BIH);
#endif
State->Header.width =
(BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) + (BIH[4]);
(int) (BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) +
(BIH[4]);
State->Header.height =
(BIH[11] << 24) + (BIH[10] << 16) + (BIH[9] << 8) + (BIH[8]);
State->Header.depth = (BIH[15] << 8) + (BIH[14]);;
(int) (BIH[11] << 24) + (BIH[10] << 16) + (BIH[9] << 8) +
(BIH[8]);
State->Header.depth = (int) (BIH[15] << 8) + (BIH[14]);;
State->Type = State->Header.depth; /* This may be less trivial someday */
State->HeaderSize =
((BFH[13] << 24) + (BFH[12] << 16) + (BFH[11] << 8) +
(BFH[10]));
if (State->HeaderSize >= 14 + 40 + 768 + 512)
State->HeaderSize = 14 + 40 + 768 + 512 - 1;
(int) ((BFH[13] << 24) + (BFH[12] << 16) + (BFH[11] << 8) +
(BFH[10]));
if (State->HeaderSize >= 14 + 40 + 1024)
State->HeaderBuf =
g_realloc(State->HeaderBuf, State->HeaderSize);
if ((BIH[16] != 0) || (BIH[17] != 0) || (BIH[18] != 0)
|| (BIH[19] != 0)) {
State->Compressed = 1;
}
/* Negative heights indicates bottom-down pixelorder */
if (State->Header.height < 0) {
State->Header.height = -State->Header.height;
State->Header.Negative = 1;
@ -246,10 +248,14 @@ static void DecodeHeader(unsigned char *BFH, unsigned char *BIH,
State->Header.Negative = 0;
}
if (State->Type == 32)
State->LineWidth = State->Header.width * 4;
if (State->Type == 24)
State->LineWidth = State->Header.width * 3;
if (State->Type == 8)
State->LineWidth = State->Header.width * 1;
if (State->Type == 4)
State->LineWidth = (State->Header.width + 1) / 2;
if (State->Type == 1) {
State->LineWidth = State->Header.width / 8;
if ((State->Header.width & 7) != 0)
@ -268,10 +274,16 @@ static void DecodeHeader(unsigned char *BFH, unsigned char *BIH,
if (State->pixbuf == NULL) {
State->pixbuf =
gdk_pixbuf_new(ART_PIX_RGB, FALSE, 8,
(gint) State->Header.width,
(gint) State->Header.height);
if (State->Type == 32)
State->pixbuf =
gdk_pixbuf_new(ART_PIX_RGB, TRUE, 8,
(gint) State->Header.width,
(gint) State->Header.height);
else
State->pixbuf =
gdk_pixbuf_new(ART_PIX_RGB, FALSE, 8,
(gint) State->Header.width,
(gint) State->Header.height);
if (State->prepared_func != NULL)
/* Notify the client that we are ready to go */
@ -300,8 +312,10 @@ image_begin_load(ModulePreparedNotifyFunc prepared_func,
context->user_data = user_data;
context->HeaderSize = 54;
context->HeaderBuf = g_malloc(14 + 40 + 768 + 512);
/* 768 for the colormap */
context->HeaderBuf = g_malloc(14 + 40 + 1024);
/* 14 for the BitmapFileHeader, 40 for the BitmapImageHeader and
1024 for the colormap */
context->HeaderDone = 0;
context->LineWidth = 0;
@ -337,8 +351,10 @@ void image_stop_load(gpointer data)
if (context->LineBuf != NULL)
g_free(context->LineBuf);
context->LineBuf = NULL;
if (context->HeaderBuf != NULL)
g_free(context->HeaderBuf);
context->LineBuf = NULL;
if (context->pixbuf)
gdk_pixbuf_unref(context->pixbuf);
@ -347,6 +363,34 @@ void image_stop_load(gpointer data)
}
/*
The OneLineXX functions are called when 1 line worth of data is present.
OneLine24 is the 24 bpp-version.
*/
static void OneLine32(struct bmp_progressive_state *context)
{
gint X;
guchar *Pixels;
X = 0;
if (context->Header.Negative == 0)
Pixels = context->pixbuf->art_pixbuf->pixels +
gdk_pixbuf_get_rowstride(context->pixbuf) *
(context->Header.height - context->Lines - 1);
else
Pixels = context->pixbuf->art_pixbuf->pixels +
gdk_pixbuf_get_rowstride(context->pixbuf) *
context->Lines;
while (X < context->Header.width) {
Pixels[X * 4 + 0] = context->LineBuf[X * 4 + 2];
Pixels[X * 4 + 1] = context->LineBuf[X * 4 + 1];
Pixels[X * 4 + 2] = context->LineBuf[X * 4 + 0];
Pixels[X * 4 + 3] = context->LineBuf[X * 4 + 3];
X++;
}
}
static void OneLine24(struct bmp_progressive_state *context)
{
gint X;
@ -385,7 +429,6 @@ static void OneLine8(struct bmp_progressive_state *context)
gdk_pixbuf_get_rowstride(context->pixbuf) *
context->Lines;
while (X < context->Header.width) {
/* The joys of having a BGR byteorder */
Pixels[X * 3 + 0] =
context->HeaderBuf[4 * context->LineBuf[X] + 56];
Pixels[X * 3 + 1] =
@ -396,6 +439,47 @@ static void OneLine8(struct bmp_progressive_state *context)
}
}
static void OneLine4(struct bmp_progressive_state *context)
{
gint X;
guchar *Pixels;
X = 0;
if (context->Header.Negative == 0)
Pixels = context->pixbuf->art_pixbuf->pixels +
gdk_pixbuf_get_rowstride(context->pixbuf) *
(context->Header.height - context->Lines - 1);
else
Pixels = context->pixbuf->art_pixbuf->pixels +
gdk_pixbuf_get_rowstride(context->pixbuf) *
context->Lines;
while (X < context->Header.width) {
guchar Pix;
Pix = context->LineBuf[X / 2];
Pixels[X * 3 + 0] =
context->HeaderBuf[4 * (Pix >> 4) + 56];
Pixels[X * 3 + 1] =
context->HeaderBuf[4 * (Pix >> 4) + 55];
Pixels[X * 3 + 2] =
context->HeaderBuf[4 * (Pix >> 4) + 54];
X++;
if (X < context->Header.width) {
/* Handle the other 4 bit pixel only when there is one */
Pixels[X * 3 + 0] =
context->HeaderBuf[4 * (Pix & 15) + 56];
Pixels[X * 3 + 1] =
context->HeaderBuf[4 * (Pix & 15) + 55];
Pixels[X * 3 + 2] =
context->HeaderBuf[4 * (Pix & 15) + 54];
X++;
}
}
}
static void OneLine1(struct bmp_progressive_state *context)
{
gint X;
@ -411,14 +495,13 @@ static void OneLine1(struct bmp_progressive_state *context)
gdk_pixbuf_get_rowstride(context->pixbuf) *
context->Lines;
while (X < context->Header.width) {
int Bit;
gint Bit;
Bit = (context->LineBuf[X / 8]) >> (7 - (X & 7));
Bit = Bit & 1;
/* The joys of having a BGR byteorder */
Pixels[X * 3 + 0] = context->HeaderBuf[Bit + 32];
Pixels[X * 3 + 1] = context->HeaderBuf[Bit + 2 + 32];
Pixels[X * 3 + 2] = context->HeaderBuf[Bit + 4 + 32];
Pixels[X * 3 + 0] = Bit*255;
Pixels[X * 3 + 1] = Bit*255;
Pixels[X * 3 + 2] = Bit*255;
X++;
}
}
@ -430,10 +513,14 @@ static void OneLine(struct bmp_progressive_state *context)
if (context->Lines >= context->Header.height)
return;
if (context->Type == 32)
OneLine32(context);
if (context->Type == 24)
OneLine24(context);
if (context->Type == 8)
OneLine8(context);
if (context->Type == 4)
OneLine4(context);
if (context->Type == 1)
OneLine1(context);
@ -450,6 +537,113 @@ static void OneLine(struct bmp_progressive_state *context)
}
}
/* DoCompressedByte handles 1 byte of incomming compressed data */
void DoCompressedByte(struct bmp_progressive_state *context, guchar ** buf,
gint * size)
{
gint BytesToCopy;
switch (context->compr.phase) {
case 0: /* Neutral state */
if (buf[0] != 0) { /* run count */
context->compr.phase = 1;
context->compr.RunCount = (*buf)[0];
} else { /* Escape */
context->compr.phase = 2;
}
(*buf)++;
(*size)--;
break;
case 1: /* Run count received.... */
while (context->compr.RunCount > 0) {
BytesToCopy =
context->LineWidth - context->LineDone;
if (BytesToCopy > context->compr.RunCount)
BytesToCopy = context->compr.RunCount;
if (BytesToCopy > 0) {
memset(context->LineBuf +
context->LineDone,
(*buf)[0], BytesToCopy);
context->compr.RunCount -= BytesToCopy;
context->LineDone += BytesToCopy;
}
if ((context->LineDone >= context->LineWidth)
&& (context->LineWidth > 0)) {
OneLine(context);
}
}
context->compr.phase = 0;
(*buf)++;
(*size)--;
break;
case 2: /* Escape received */
if ((*buf)[0] == 0) { /* End of line */
context->compr.phase = 0;
if (context->LineDone > 0)
OneLine(context);
} else if ((*buf)[0] == 1) { /* End of image */
OneLine(context);
context->compr.phase = 6;
(*size) = 0;
break;
} else if ((*buf)[0] == 2) { /* Cursor displacement */
context->compr.phase = 4;
} else {
context->compr.phase = 3;
context->compr.RunCount = (*buf)[0];
}
(*buf)++;
(*size)--;
break;
case 3:
while ((context->compr.RunCount > 0)
&& (size > 0)) {
BytesToCopy =
context->LineWidth - context->LineDone;
if (BytesToCopy > context->compr.RunCount)
BytesToCopy = context->compr.RunCount;
if (BytesToCopy > *size)
BytesToCopy = *size;
if (BytesToCopy > 0) {
memcpy(context->LineBuf +
context->LineDone,
*buf, BytesToCopy);
context->compr.RunCount -= BytesToCopy;
(*buf) += BytesToCopy;
(*size) -= BytesToCopy;
context->LineDone += BytesToCopy;
}
if ((context->LineDone >= context->LineWidth)
&& (context->LineWidth > 0))
OneLine(context);
}
if (context->compr.RunCount <= 0)
context->compr.phase = 0;
break;
case 4:
context->compr.phase = 5;
context->compr.XDelta = (*buf)[0];
(*buf)++;
(*size)--;
break;
case 5:
context->compr.phase = 0;
context->compr.YDelta = (*buf)[0];
g_assert(0); /* No implementatio of this yet */
/* If this happens, please email me (arjan@fenrus.demon.nl)
the image concerned. */
(*buf)++;
(*size)--;
break;
case 6:
(*size) = 0;
}
}
/*
* context - from image_begin_load
* buf - new image data
@ -473,7 +667,7 @@ gboolean image_load_increment(gpointer data, guchar * buf, guint size)
if (BytesToCopy > size)
BytesToCopy = size;
memcpy(context->HeaderBuf + context->HeaderDone,
memmove(context->HeaderBuf + context->HeaderDone,
buf, BytesToCopy);
size -= BytesToCopy;
@ -481,132 +675,18 @@ gboolean image_load_increment(gpointer data, guchar * buf, guint size)
context->HeaderDone += BytesToCopy;
} else if (context->Compressed) {
/* Compression is done 1 at a time for now */
switch (context->compr.phase) {
case 0:
if (buf[0] != 0) { /* run count */
context->compr.phase = 1;
context->compr.RunCount = buf[0];
} else { /* Escape */
context->compr.phase = 2;
}
buf++;
size--;
break;
case 1: /* Run count received.... */
while (context->compr.RunCount > 0) {
BytesToCopy =
context->LineWidth -
context->LineDone;
if (BytesToCopy >
context->compr.
RunCount) BytesToCopy =
context->compr.
RunCount;
if (BytesToCopy > 0) {
memset(context->LineBuf +
context->LineDone,
buf[0],
BytesToCopy);
context->compr.RunCount -=
BytesToCopy;
context->LineDone +=
BytesToCopy;
}
if (
(context->LineDone >=
context->LineWidth)
&& (context->LineWidth > 0)) {
OneLine(context);
}
}
context->compr.phase = 0;
buf++;
size--;
break;
case 2: /* Escape received */
if (buf[0] == 0) { /* End of line */
context->compr.phase = 0;
if (context->LineDone > 0)
OneLine(context);
} else if (buf[0] == 1) { /* End of image */
OneLine(context);
context->compr.phase = 6;
size = 0;
break;
} else if (buf[0] == 2) { /* Cursor displacement */
context->compr.phase = 4;
} else {
context->compr.phase = 3;
context->compr.RunCount = buf[0];
}
buf++;
size--;
break;
case 3:
while ((context->compr.RunCount > 0)
&& (size > 0)) {
BytesToCopy =
context->LineWidth -
context->LineDone;
if (BytesToCopy >
context->compr.
RunCount) BytesToCopy =
context->compr.
RunCount;
if (BytesToCopy > size)
BytesToCopy = size;
if (BytesToCopy > 0) {
memcpy(context->LineBuf +
context->LineDone,
buf, BytesToCopy);
context->compr.RunCount -=
BytesToCopy;
buf += BytesToCopy;
size -= BytesToCopy;
context->LineDone +=
BytesToCopy;
}
if (
(context->LineDone >=
context->LineWidth)
&& (context->LineWidth > 0))
OneLine(context);
}
if (context->compr.RunCount <= 0)
context->compr.phase = 0;
break;
case 4:
context->compr.phase = 5;
context->compr.XDelta = buf[0];
buf++;
size--;
break;
case 5:
context->compr.phase = 0;
context->compr.YDelta = buf[0];
g_assert(0); /* No implementatio of this yet */
buf++;
size--;
break;
case 6:
size = 0;
}
/* Compression is done 1 byte at a time for now */
DoCompressedByte(context, &buf, &size);
} else {
/* Pixeldata only */
/* Uncompressed pixeldata */
BytesToCopy =
context->LineWidth - context->LineDone;
if (BytesToCopy > size)
BytesToCopy = size;
if (BytesToCopy > 0) {
memcpy(context->LineBuf +
memmove(context->LineBuf +
context->LineDone, buf,
BytesToCopy);

View File

@ -1,4 +1,4 @@
/* GdkPixbuf library - Windows Bitmap image loader
/* GdkPixbuf library - Windows Icon/Cursor image loader
*
* Copyright (C) 1999 The Free Software Foundation
*
@ -23,6 +23,7 @@
* Boston, MA 02111-1307, USA.
*/
#undef DUMPBIH
/*
Icons are just like BMP's, except for the header.
@ -40,19 +41,13 @@ Known bugs:
struct headerpair {
guint width;
guint height;
guint depth;
guint Negative; /* Negative = 1 -> top down BMP,
Negative = 0 -> bottom up BMP */
};
/*
These structures are actually dummies. These are according to
the "Windows API reference guide volume II" as written by Borland,
but GCC fiddles with the alignment of the internal members.
the "Windows API reference guide volume II" as written by
Borland International, but GCC fiddles with the alignment of
the internal members.
*/
@ -77,59 +72,53 @@ struct BitmapInfoHeader {
guint biClrImportant;
};
#ifdef DUMPBIH
/*
DumpBIH printf's the values in a BitmapInfoHeader to the screen, for
debugging purposes.
*/
static void DumpBIH(unsigned char *BIH)
{ /* For debugging */
{
printf("biSize = %i \n",
(BIH[3] << 24) + (BIH[2] << 16) + (BIH[1] << 8) + (BIH[0]));
(int)(BIH[3] << 24) + (BIH[2] << 16) + (BIH[1] << 8) + (BIH[0]));
printf("biWidth = %i \n",
(BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) + (BIH[4]));
(int)(BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) + (BIH[4]));
printf("biHeight = %i \n",
(BIH[11] << 24) + (BIH[10] << 16) + (BIH[9] << 8) +
(int)(BIH[11] << 24) + (BIH[10] << 16) + (BIH[9] << 8) +
(BIH[8]));
printf("biPlanes = %i \n", (BIH[13] << 8) + (BIH[12]));
printf("biBitCount = %i \n", (BIH[15] << 8) + (BIH[14]));
printf("biPlanes = %i \n", (int)(BIH[13] << 8) + (BIH[12]));
printf("biBitCount = %i \n", (int)(BIH[15] << 8) + (BIH[14]));
printf("biCompress = %i \n",
(BIH[19] << 24) + (BIH[18] << 16) + (BIH[17] << 8) +
(int)(BIH[19] << 24) + (BIH[18] << 16) + (BIH[17] << 8) +
(BIH[16]));
printf("biSizeImage = %i \n",
(BIH[23] << 24) + (BIH[22] << 16) + (BIH[21] << 8) +
(int)(BIH[23] << 24) + (BIH[22] << 16) + (BIH[21] << 8) +
(BIH[20]));
printf("biXPels = %i \n",
(BIH[27] << 24) + (BIH[26] << 16) + (BIH[25] << 8) +
(int)(BIH[27] << 24) + (BIH[26] << 16) + (BIH[25] << 8) +
(BIH[24]));
printf("biYPels = %i \n",
(BIH[31] << 24) + (BIH[30] << 16) + (BIH[29] << 8) +
(int)(BIH[31] << 24) + (BIH[30] << 16) + (BIH[29] << 8) +
(BIH[28]));
printf("biClrUsed = %i \n",
(BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) +
(int)(BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) +
(BIH[32]));
printf("biClrImprtnt= %i \n",
(BIH[39] << 24) + (BIH[38] << 16) + (BIH[37] << 8) +
(int)(BIH[39] << 24) + (BIH[38] << 16) + (BIH[37] << 8) +
(BIH[36]));
}
/*
This does a byte-order swap. Does glib have something like
be32_to_cpu() ??
*/
static unsigned int le32_to_cpu(guint i)
{
unsigned int i2;
return i2;
}
/*
Destroy notification function for the libart pixbuf
*/
static void free_buffer(gpointer user_data, gpointer data)
{
free(data);
}
#endif
/* Progressive loading */
struct headerpair {
guint width;
guint height;
guint depth;
guint Negative; /* Negative = 1 -> top down BMP,
Negative = 0 -> bottom up BMP */
};
struct ico_progressive_state {
ModulePreparedNotifyFunc prepared_func;
@ -170,13 +159,13 @@ gboolean image_load_increment(gpointer data, guchar * buf, guint size);
/* Shared library entry point */
/* Shared library entry point --> Can go when generic_image_load
enters gdk-pixbuf-io */
GdkPixbuf *image_load(FILE * f)
{
guchar *membuf;
size_t length;
struct ico_progressive_state *State;
int fd;
GdkPixbuf *pb;
@ -189,7 +178,7 @@ GdkPixbuf *image_load(FILE * f)
while (feof(f) == 0) {
length = fread(membuf, 1, 4096, f);
if (length > 0)
image_load_increment(State, membuf, length);
(void)image_load_increment(State, membuf, length);
}
g_free(membuf);
@ -199,7 +188,7 @@ GdkPixbuf *image_load(FILE * f)
pb = State->pixbuf;
image_stop_load(State);
return State->pixbuf;
return pb;
}
static void DecodeHeader(guchar *Data, gint Bytes,
@ -220,7 +209,6 @@ static void DecodeHeader(guchar *Data, gint Bytes,
IconCount = (Data[5] << 8) + (Data[4]);
/* printf("There are %i icons in this file \n",IconCount);*/
State->HeaderSize = 6 + IconCount*16;
if (State->HeaderSize>State->BytesInHeaderBuf) {
@ -244,21 +232,17 @@ static void DecodeHeader(guchar *Data, gint Bytes,
ThisHeight = Ptr[1];
ThisColors = (Ptr[2]);
if (ThisColors==0)
ThisColors=256; /* Yes, this is in the spec */
ThisColors=256; /* Yes, this is in the spec, ugh */
/* printf("Option: %ix%ix%i ",ThisWidth,ThisHeight,ThisColors);*/
ThisScore = ThisColors*1024+ThisWidth*ThisHeight;
if (ThisScore>State->ImageScore) {
State->ImageScore = ThisScore;
State->DIBoffset = (Ptr[15]<<24)+(Ptr[14]<<16)+
(Ptr[13]<<8) + (Ptr[12]);
/* printf("*");*/
}
/* printf("\n");*/
Ptr += 16;
}
@ -277,22 +261,29 @@ static void DecodeHeader(guchar *Data, gint Bytes,
BIH = Data+State->DIBoffset;
/* DumpBIH(BIH);*/
#ifdef DUMPBIH
DumpBIH(BIH);
#endif
/* Add the palette to the headersize */
State->Header.width =
(BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) + (BIH[4]);
(int)(BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) + (BIH[4]);
State->Header.height =
(BIH[11] << 24) + (BIH[10] << 16) + (BIH[9] << 8) + (BIH[8])/2;
(int)(BIH[11] << 24) + (BIH[10] << 16) + (BIH[9] << 8) + (BIH[8])/2;
/* /2 because the BIH height includes the transparency mask */
State->Header.depth = (BIH[15] << 8) + (BIH[14]);;
State->Type = State->Header.depth; /* This may be less trivial someday */
State->Type = State->Header.depth;
if (State->Lines>=State->Header.height)
State->Type = 1;
State->Type = 1; /* The transparency mask is 1 bpp */
I =(BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) + (BIH[32]);
/* Determine the palette size. If the header indicates 0, it
is actually the maximum for the bpp. You have to love the
guys who made the spec. */
I =(int)(BIH[35] << 24) + (BIH[34] << 16) + (BIH[33] << 8) + (BIH[32]);
if ((I==0)&&(State->Type==1))
I = 2*4;
if ((I==0)&&(State->Type==4))
@ -314,13 +305,13 @@ static void DecodeHeader(guchar *Data, gint Bytes,
g_assert(0); /* Compressed icons aren't allowed */
}
/* Negative heights mean top-down pixel-order */
if (State->Header.height < 0) {
State->Header.height = -State->Header.height;
State->Header.Negative = 1;
}
if (State->Header.width < 0) {
State->Header.width = -State->Header.width;
State->Header.Negative = 0;
}
if (State->Type == 24)
@ -328,9 +319,7 @@ static void DecodeHeader(guchar *Data, gint Bytes,
if (State->Type == 8)
State->LineWidth = State->Header.width * 1;
if (State->Type == 4) {
State->LineWidth = State->Header.width/2;
if ((State->Header.width & 1) != 0)
State->LineWidth++;
State->LineWidth = (State->Header.width+1)/2;
}
if (State->Type == 1) {
State->LineWidth = State->Header.width / 8;
@ -340,7 +329,7 @@ static void DecodeHeader(guchar *Data, gint Bytes,
/* Pad to a 32 bit boundary */
if (((State->LineWidth % 4) > 0))
State->LineWidth = (State->LineWidth / 3) * 3 + 3;
State->LineWidth = (State->LineWidth / 4) * 4 + 4;
if (State->LineBuf == NULL)
@ -538,9 +527,9 @@ static void OneLine1(struct ico_progressive_state *context)
Bit = (context->LineBuf[X / 8]) >> (7 - (X & 7));
Bit = Bit & 1;
/* The joys of having a BGR byteorder */
Pixels[X * 4 + 0] = context->HeaderBuf[Bit + 32];
Pixels[X * 4 + 1] = context->HeaderBuf[Bit + 2 + 32];
Pixels[X * 4 + 2] = context->HeaderBuf[Bit + 4 + 32];
Pixels[X * 4 + 0] = Bit*255;
Pixels[X * 4 + 1] = Bit*255;
Pixels[X * 4 + 2] = Bit*255;
X++;
}
}
@ -642,7 +631,6 @@ gboolean image_load_increment(gpointer data, guchar * buf, guint size)
gint BytesToCopy;
while (size > 0) {
/* printf("Y=%i C=%i H=%i\n",context->Lines,context->Type,context->Header.height);*/
g_assert(context->LineDone >= 0);
if (context->HeaderDone < context->HeaderSize) { /* We still
have headerbytes to do */
@ -651,7 +639,7 @@ gboolean image_load_increment(gpointer data, guchar * buf, guint size)
if (BytesToCopy > size)
BytesToCopy = size;
memcpy(context->HeaderBuf + context->HeaderDone,
memmove(context->HeaderBuf + context->HeaderDone,
buf, BytesToCopy);
size -= BytesToCopy;
@ -666,7 +654,7 @@ gboolean image_load_increment(gpointer data, guchar * buf, guint size)
BytesToCopy = size;
if (BytesToCopy > 0) {
memcpy(context->LineBuf +
memmove(context->LineBuf +
context->LineDone, buf,
BytesToCopy);

View File

@ -71,17 +71,6 @@ static unsigned int be32_to_cpu(guint i)
return i2;
}
/*
Destroy notification function for the libart pixbuf
*/
static void free_buffer(gpointer user_data, gpointer data)
{
free(data);
}
/* Progressive loading */
@ -126,7 +115,6 @@ GdkPixbuf *image_load(FILE * f)
guchar *membuf;
size_t length;
struct ras_progressive_state *State;
int fd;
GdkPixbuf *pb;
@ -138,7 +126,7 @@ GdkPixbuf *image_load(FILE * f)
while (feof(f) == 0) {
length = fread(membuf, 1, 4096, f);
image_load_increment(State, membuf, length);
(void)image_load_increment(State, membuf, length);
}
g_free(membuf);
if (State->pixbuf != NULL)
@ -147,7 +135,7 @@ GdkPixbuf *image_load(FILE * f)
pb = State->pixbuf;
image_stop_load(State);
return State->pixbuf;
return pb;
}
static void RAS2State(struct rasterfile *RAS,
@ -416,7 +404,7 @@ gboolean image_load_increment(gpointer data, guchar * buf, guint size)
if (BytesToCopy > size)
BytesToCopy = size;
memcpy(context->HeaderBuf + context->HeaderDone,
memmove(context->HeaderBuf + context->HeaderDone,
buf, BytesToCopy);
size -= BytesToCopy;
@ -431,7 +419,7 @@ gboolean image_load_increment(gpointer data, guchar * buf, guint size)
BytesToCopy = size;
if (BytesToCopy > 0) {
memcpy(context->LineBuf +
memmove(context->LineBuf +
context->LineDone, buf,
BytesToCopy);