Merge 16- and 32-bit ico support from the stable branch. (#61179)

* io-ico.c: Merge 16- and 32-bit ico support from the stable
        branch.  (#61179)

        * io-gif.c: Recomposite all images if the animation size changes
        while loading.  (#70055)

        * gdk-pixbuf.c (gdk-pixbuf-fill): Make it work for subpixbufs.
        (#70055)
This commit is contained in:
Matthias Clasen 2002-02-01 23:43:07 +00:00
parent 4eb836706c
commit 50e6308388
4 changed files with 127 additions and 26 deletions

View File

@ -1,3 +1,14 @@
2002-02-01 Matthias Clasen <matthiasc@poet.de>
* io-ico.c: Merge 16- and 32-bit ico support from the stable
branch. (#61179)
* io-gif.c: Recomposite all images if the animation size changes
while loading. (#70055)
* gdk-pixbuf.c (gdk-pixbuf-fill): Make it work for subpixbufs.
(#70055)
Sat Jan 19 20:49:20 2002 Manish Singh <yosh@gimp.org>
* io-jpeg.c, io-png.c: Made sure all the error cases involving

View File

@ -428,7 +428,9 @@ gdk_pixbuf_fill (GdkPixbuf *pixbuf,
guchar *pixels;
gboolean all_the_same = FALSE;
guint r, g, b, a;
guchar *p;
gint n;
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
if (pixbuf->width == 0 || pixbuf->height == 0)
@ -449,12 +451,13 @@ gdk_pixbuf_fill (GdkPixbuf *pixbuf,
}
if (all_the_same) {
memset (pixels, r,
pixbuf->rowstride * pixbuf->height);
if (pixbuf->has_alpha)
memset (pixels, r, pixbuf->width * 4);
else
memset (pixels, r, pixbuf->width * 3);
} else {
guchar *p;
guchar c[4];
gint n;
c[0] = r; c[1] = g; c[2] = b; c[3] = a;
@ -472,12 +475,12 @@ gdk_pixbuf_fill (GdkPixbuf *pixbuf,
} while (--n);
}
p = pixels;
n = pixbuf->height - 1;
while (n--) {
p += pixbuf->rowstride;
memcpy (p, pixels, pixbuf->width * pixbuf->n_channels);
}
}
p = pixels;
n = pixbuf->height - 1;
while (n--) {
p += pixbuf->rowstride;
memcpy (p, pixels, pixbuf->width * pixbuf->n_channels);
}
}

View File

@ -725,6 +725,14 @@ gif_fill_in_lines (GifContext *context, guchar *dest, guchar v)
}
}
static void
set_need_recomposite (gpointer data, gpointer user_data)
{
GdkPixbufFrame *frame = (GdkPixbufFrame *)data;
frame->need_recomposite = TRUE;
}
static int
gif_get_lzw (GifContext *context)
{
@ -802,6 +810,9 @@ gif_get_lzw (GifContext *context)
gdk_pixbuf_get_width (context->frame->pixbuf);
h = context->frame->y_offset +
gdk_pixbuf_get_height (context->frame->pixbuf);
if (w > context->animation->width || h > context->animation->height) {
g_list_foreach (context->animation->frames, set_need_recomposite, NULL);
}
if (w > context->animation->width)
context->animation->width = w;
if (h > context->animation->height)

View File

@ -139,8 +139,11 @@ struct ico_progressive_state {
gint Lines; /* # of finished lines */
gint Type; /*
32 = RGBA
24 = RGB
16 = 555 RGB
8 = 8 bit colormapped
4 = 4 bpp colormapped
1 = 1 bit bitonal
*/
@ -247,9 +250,9 @@ static void DecodeHeader(guchar *Data, gint Bytes,
/* Step 1: The ICO header */
IconCount = (Data[5] << 8) + (Data[4]);
State->HeaderSize = 6 + IconCount*16;
if (State->HeaderSize>State->BytesInHeaderBuf) {
State->HeaderBuf=g_try_realloc(State->HeaderBuf,State->HeaderSize);
if (!State->HeaderBuf) {
@ -396,17 +399,26 @@ static void DecodeHeader(guchar *Data, gint Bytes,
g_assert (State->Header.width > 0);
g_assert (State->Header.height > 0);
if (State->Type == 24)
if (State->Type == 32)
State->LineWidth = State->Header.width * 4;
else if (State->Type == 24)
State->LineWidth = State->Header.width * 3;
if (State->Type == 8)
else if (State->Type == 16)
State->LineWidth = State->Header.height * 2;
else if (State->Type == 8)
State->LineWidth = State->Header.width * 1;
if (State->Type == 4) {
else if (State->Type == 4)
State->LineWidth = (State->Header.width+1)/2;
}
if (State->Type == 1) {
else if (State->Type == 1) {
State->LineWidth = State->Header.width / 8;
if ((State->Header.width & 7) != 0)
State->LineWidth++;
} else {
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Unsupported icon type"));
return;
}
/* Pad to a 32 bit boundary */
@ -421,8 +433,8 @@ static void DecodeHeader(guchar *Data, gint Bytes,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
_("Not enough memory to load icon"));
return;
}
return;
}
g_assert(State->LineBuf != NULL);
@ -513,6 +525,29 @@ gboolean gdk_pixbuf__ico_image_stop_load(gpointer data,
return TRUE;
}
static void
OneLine32 (struct ico_progressive_state *context)
{
gint X;
guchar *Pixels;
X = 0;
if (context->Header.Negative == 0)
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->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 ico_progressive_state *context)
{
@ -537,6 +572,44 @@ static void OneLine24(struct ico_progressive_state *context)
}
static void
OneLine16 (struct ico_progressive_state *context)
{
int i;
guchar *pixels;
guchar *src;
if (context->Header.Negative == 0)
pixels = (context->pixbuf->pixels +
context->pixbuf->rowstride * (context->Header.height - context->Lines - 1));
else
pixels = (context->pixbuf->pixels +
context->pixbuf->rowstride * context->Lines);
src = context->LineBuf;
for (i = 0; i < context->Header.width; i++) {
int v, r, g, b;
v = (int) src[0] | ((int) src[1] << 8);
src += 2;
/* Extract 5-bit RGB values */
r = (v >> 10) & 0x1f;
g = (v >> 5) & 0x1f;
b = v & 0x1f;
/* Fill the rightmost bits to form 8-bit values */
*pixels++ = (r << 3) | (r >> 2);
*pixels++ = (g << 3) | (g >> 2);
*pixels++ = (b << 3) | (b >> 2);
pixels++; /* skip alpha channel */
}
}
static void OneLine8(struct ico_progressive_state *context)
{
gint X;
@ -674,19 +747,22 @@ static void OneLine(struct ico_progressive_state *context)
}
if (context->Lines <context->Header.height) {
if (context->Type == 24)
if (context->Type == 32)
OneLine32 (context);
else if (context->Type == 24)
OneLine24(context);
if (context->Type == 8)
else if (context->Type == 16)
OneLine16 (context);
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 ();
} else
{
OneLineTransp(context);
}
context->Lines++;
if (context->Lines>=context->Header.height) {