summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdk-pixbuf/io-ico.c33
-rw-r--r--tests/pixbuf-save.c33
-rw-r--r--tests/test-common.c2
3 files changed, 50 insertions, 18 deletions
diff --git a/gdk-pixbuf/io-ico.c b/gdk-pixbuf/io-ico.c
index 7d8ce316a..e4faef501 100644
--- a/gdk-pixbuf/io-ico.c
+++ b/gdk-pixbuf/io-ico.c
@@ -269,6 +269,8 @@ static void DecodeHeader(guchar *Data, gint Bytes,
for (I=0;I<IconCount;I++) {
entry = g_new0 (struct ico_direntry_data, 1);
entry->ImageScore = (Ptr[11] << 24) + (Ptr[10] << 16) + (Ptr[9] << 8) + (Ptr[8]);
+ if (entry->ImageScore == 0)
+ entry->ImageScore = 256;
entry->x_hot = (Ptr[5] << 8) + Ptr[4];
entry->y_hot = (Ptr[7] << 8) + Ptr[6];
entry->DIBoffset = (Ptr[15]<<24)+(Ptr[14]<<16)+
@@ -349,23 +351,14 @@ static void DecodeHeader(guchar *Data, gint Bytes,
State->Header.width =
(int)(BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) + (BIH[4]);
- if (State->Header.width == 0) {
- g_set_error_literal (error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("Icon has zero width"));
- return;
- }
+ if (State->Header.width == 0)
+ State->Header.width = 256;
+
State->Header.height =
(int)((BIH[11] << 24) + (BIH[10] << 16) + (BIH[9] << 8) + (BIH[8]))/2;
/* /2 because the BIH height includes the transparency mask */
- if (State->Header.height == 0) {
- g_set_error_literal (error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("Icon has zero height"));
- return;
- }
+ if (State->Header.height == 0)
+ State->Header.height = 256;
State->Header.depth = (BIH[15] << 8) + (BIH[14]);
State->Type = State->Header.depth;
@@ -993,7 +986,7 @@ fill_entry (IconEntry *icon,
guchar *p, *pixels, *and, *xor;
gint n_channels, v, x, y;
- if (icon->width > 255 || icon->height > 255) {
+ if (icon->width > 256 || icon->height > 256) {
g_set_error_literal (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_BAD_OPTION,
@@ -1132,8 +1125,14 @@ write_icon (FILE *f, GSList *entries)
size = 40 + icon->height * (icon->and_rowstride + icon->xor_rowstride);
/* directory entry */
- bytes[0] = icon->width;
- bytes[1] = icon->height;
+ if (icon->width == 256)
+ bytes[0] = 0;
+ else
+ bytes[0] = icon->width;
+ if (icon->height == 256)
+ bytes[1] = 0;
+ else
+ bytes[1] = icon->height;
bytes[2] = icon->n_colors;
bytes[3] = 0;
write8 (f, bytes, 4);
diff --git a/tests/pixbuf-save.c b/tests/pixbuf-save.c
index 72a7aea4b..61ef07baf 100644
--- a/tests/pixbuf-save.c
+++ b/tests/pixbuf-save.c
@@ -98,6 +98,38 @@ test_save_roundtrip (void)
}
static void
+test_save_ico (void)
+{
+ GError *error = NULL;
+ GdkPixbuf *ref, *ref2;
+ GdkPixbuf *pixbuf;
+
+ if (!format_supported ("ico") || !format_supported ("png"))
+ {
+ g_test_skip ("format not supported");
+ return;
+ }
+
+ ref = gdk_pixbuf_new_from_file (g_test_get_filename (G_TEST_DIST, "test-image.png", NULL), &error);
+ g_assert_no_error (error);
+
+ ref2 = gdk_pixbuf_scale_simple (ref, 256, 256, GDK_INTERP_NEAREST);
+ g_object_unref (ref);
+ ref = ref2;
+
+ gdk_pixbuf_save (ref, "pixbuf-save-roundtrip", "ico", &error, NULL);
+ g_assert_no_error (error);
+
+ pixbuf = gdk_pixbuf_new_from_file ("pixbuf-save-roundtrip", &error);
+ g_assert_no_error (error);
+
+ g_assert (pixbuf_equal (pixbuf, ref));
+
+ g_object_unref (pixbuf);
+ g_object_unref (ref);
+}
+
+static void
test_save_options (void)
{
GdkPixbuf *ref;
@@ -142,6 +174,7 @@ main (int argc, char **argv)
g_test_add_func ("/pixbuf/save/roundtrip", test_save_roundtrip);
g_test_add_func ("/pixbuf/save/options", test_save_options);
+ g_test_add_func ("/pixbuf/save/ico", test_save_ico);
return g_test_run ();
}
diff --git a/tests/test-common.c b/tests/test-common.c
index c7673e395..a7107a114 100644
--- a/tests/test-common.c
+++ b/tests/test-common.c
@@ -33,7 +33,7 @@ format_supported (const gchar *filename)
GSList *formats, *l;
gboolean retval;
const gchar *names[] = { "png", "jpeg", "bmp", "gif", "ras",
- "tga", "xpm", "xbm" };
+ "tga", "xpm", "xbm", "ico" };
gint i;
for (i = 0; i < G_N_ELEMENTS (names); i++)