mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-11 21:20:09 +00:00
add support for conditional icns gdk-pixbuf loader (Closes: #395738)
2007-11-20 Bastien Nocera <hadess@hadess.net> * configure.in: add support for conditional icns gdk-pixbuf loader (Closes: #395738) 2007-11-20 Bastien Nocera <hadess@hadess.net> * Makefile.am: * io-icns.c: Add icns (MacOS X icons) loader, based on work by Lyonel Vincent <lyonel@ezix.org> (Closes: #395738) svn path=/trunk/; revision=19007
This commit is contained in:
parent
cec5f34557
commit
18d12ffe75
@ -1,3 +1,8 @@
|
|||||||
|
2007-11-20 Bastien Nocera <hadess@hadess.net>
|
||||||
|
|
||||||
|
* configure.in: add support for conditional icns gdk-pixbuf loader
|
||||||
|
(Closes: #395738)
|
||||||
|
|
||||||
2007-11-19 10:31:26 Tim Janik <timj@imendio.com>
|
2007-11-19 10:31:26 Tim Janik <timj@imendio.com>
|
||||||
|
|
||||||
* configure.in: updated version number to 2.15.0 for development.
|
* configure.in: updated version number to 2.15.0 for development.
|
||||||
|
@ -886,7 +886,7 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
all_loaders="png,bmp,wbmp,gif,ico,ani,jpeg,pnm,ras,tiff,xpm,xbm,tga,pcx"
|
all_loaders="png,bmp,wbmp,gif,ico,ani,jpeg,pnm,ras,tiff,xpm,xbm,tga,pcx,icns"
|
||||||
included_loaders=""
|
included_loaders=""
|
||||||
# If no loaders specified, include all
|
# If no loaders specified, include all
|
||||||
if test "x$with_included_loaders" = xyes ; then
|
if test "x$with_included_loaders" = xyes ; then
|
||||||
@ -930,6 +930,7 @@ AM_CONDITIONAL(INCLUDE_XPM, [test x"$INCLUDE_xpm" = xyes])
|
|||||||
AM_CONDITIONAL(INCLUDE_XBM, [test x"$INCLUDE_xbm" = xyes])
|
AM_CONDITIONAL(INCLUDE_XBM, [test x"$INCLUDE_xbm" = xyes])
|
||||||
AM_CONDITIONAL(INCLUDE_TGA, [test x"$INCLUDE_tga" = xyes])
|
AM_CONDITIONAL(INCLUDE_TGA, [test x"$INCLUDE_tga" = xyes])
|
||||||
AM_CONDITIONAL(INCLUDE_PCX, [test x"$INCLUDE_pcx" = xyes])
|
AM_CONDITIONAL(INCLUDE_PCX, [test x"$INCLUDE_pcx" = xyes])
|
||||||
|
AM_CONDITIONAL(INCLUDE_ICNS, [test x"$INCLUDE_icns" = xyes])
|
||||||
|
|
||||||
AC_HEADER_SYS_WAIT
|
AC_HEADER_SYS_WAIT
|
||||||
|
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2007-11-20 Bastien Nocera <hadess@hadess.net>
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
* io-icns.c: Add icns (MacOS X icons) loader, based on work by
|
||||||
|
Lyonel Vincent <lyonel@ezix.org> (Closes: #395738)
|
||||||
|
|
||||||
2007-11-10 Matthias Clasen <mclasen@redhat.com>
|
2007-11-10 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* io-jpeg.c: Avoid unaligned accesses that cause
|
* io-jpeg.c: Avoid unaligned accesses that cause
|
||||||
@ -147,7 +153,7 @@ Sat Jul 7 17:34:33 2007 Tim Janik <timj@gtk.org>
|
|||||||
|
|
||||||
* gdk-pixbuf-simple-anim.c (gdk_pixbuf_simple_anim_add_frame):
|
* gdk-pixbuf-simple-anim.c (gdk_pixbuf_simple_anim_add_frame):
|
||||||
Don't double the delay time of the first frame. (#431997,
|
Don't double the delay time of the first frame. (#431997,
|
||||||
Bj顤n Lindqvist)
|
Bj?rn Lindqvist)
|
||||||
|
|
||||||
2007-04-25 Matthias Clasen <mclasen@redhat.com>
|
2007-04-25 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
@ -1583,7 +1589,7 @@ Mon Aug 18 10:25:29 2003 Owen Taylor <otaylor@redhat.com>
|
|||||||
|
|
||||||
* pixops/pixops.c (correct_total): Split correction into multiple
|
* pixops/pixops.c (correct_total): Split correction into multiple
|
||||||
pieces if no single weight is large enough to apply the unsplit
|
pieces if no single weight is large enough to apply the unsplit
|
||||||
correction. (#117431, problem reported by Tomas 狿ren)
|
correction. (#117431, problem reported by Tomas ?gren)
|
||||||
|
|
||||||
2003-07-13 Matthias Clasen <maclas@gmx.de>
|
2003-07-13 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
@ -2371,7 +2377,7 @@ Wed Feb 27 18:33:04 2002 Owen Taylor <otaylor@redhat.com>
|
|||||||
|
|
||||||
* gdk-pixdata.c (gdk_pixdata_to_csource): Use {} not
|
* gdk-pixdata.c (gdk_pixdata_to_csource): Use {} not
|
||||||
() to group around string assigned to char[]. (#72767,
|
() to group around string assigned to char[]. (#72767,
|
||||||
Tomas 狿ren)
|
Tomas ?gren)
|
||||||
|
|
||||||
2002-02-21 Havoc Pennington <hp@pobox.com>
|
2002-02-21 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
@ -3594,7 +3600,7 @@ Wed Jun 21 16:02:48 2000 Owen Taylor <otaylor@redhat.com>
|
|||||||
2000-06-05 Mathieu Lacage <mathieu@gnome.org>
|
2000-06-05 Mathieu Lacage <mathieu@gnome.org>
|
||||||
|
|
||||||
* configure.in: add some gtk parameters to the
|
* configure.in: add some gtk parameters to the
|
||||||
GDK_PIXBUF_LIB鏖蕭淞 and GDK_PIXBUG_INCLUDEDIR vars. One more
|
GDK_PIXBUF_LIB?<3F>?S and GDK_PIXBUG_INCLUDEDIR vars. One more
|
||||||
fight in my crusade for strange prefix compile...
|
fight in my crusade for strange prefix compile...
|
||||||
|
|
||||||
2000-05-30 Not Zed <NotZed@HelixCode.com>
|
2000-05-30 Not Zed <NotZed@HelixCode.com>
|
||||||
@ -3691,7 +3697,7 @@ Fri May 5 12:16:32 2000 Owen Taylor <otaylor@redhat.com>
|
|||||||
* gdk-pixbuf/Makefile.am (INCLUDES): Add $(GNOME_CFLAGS).
|
* gdk-pixbuf/Makefile.am (INCLUDES): Add $(GNOME_CFLAGS).
|
||||||
Reported by Jens Finke.
|
Reported by Jens Finke.
|
||||||
|
|
||||||
2000-04-14 Tomasz K鏖蕭這pczko <kloczek@pld.org.pl>
|
2000-04-14 Tomasz K?<3F>?opczko <kloczek@pld.org.pl>
|
||||||
|
|
||||||
* gdk-pixbuf/pixops/makefile.am: $(LIBART_CFLAGS) replaced by
|
* gdk-pixbuf/pixops/makefile.am: $(LIBART_CFLAGS) replaced by
|
||||||
$(GTK_CFLAGS) - now gdk-pixbuf compiles correctly.
|
$(GTK_CFLAGS) - now gdk-pixbuf compiles correctly.
|
||||||
|
@ -164,6 +164,14 @@ libpixbufloader_tga_la_SOURCES = io-tga.c
|
|||||||
libpixbufloader_tga_la_LDFLAGS = -avoid-version -module $(no_undefined)
|
libpixbufloader_tga_la_LDFLAGS = -avoid-version -module $(no_undefined)
|
||||||
libpixbufloader_tga_la_LIBADD = $(module_libs)
|
libpixbufloader_tga_la_LIBADD = $(module_libs)
|
||||||
|
|
||||||
|
#
|
||||||
|
# The .icns loader
|
||||||
|
#
|
||||||
|
libpixbufloader_static_icns_la_SOURCES = io-icns.c
|
||||||
|
libpixbufloader_icns_la_SOURCES = io-icns.c
|
||||||
|
libpixbufloader_icns_la_LDFLAGS = -avoid-version -module $(no_undefined)
|
||||||
|
libpixbufloader_icns_la_LIBADD = $(module_libs)
|
||||||
|
|
||||||
#
|
#
|
||||||
# The PCX loader
|
# The PCX loader
|
||||||
#
|
#
|
||||||
@ -262,6 +270,12 @@ else
|
|||||||
PCX_LIB = libpixbufloader-pcx.la
|
PCX_LIB = libpixbufloader-pcx.la
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if INCLUDE_ICNS
|
||||||
|
STATIC_ICNS_LIB = libpixbufloader-static-icns.la
|
||||||
|
else
|
||||||
|
ICNS_LIB = libpixbufloader-icns.la
|
||||||
|
endif
|
||||||
|
|
||||||
if BUILD_DYNAMIC_MODULES
|
if BUILD_DYNAMIC_MODULES
|
||||||
|
|
||||||
loader_LTLIBRARIES = \
|
loader_LTLIBRARIES = \
|
||||||
@ -278,6 +292,7 @@ loader_LTLIBRARIES = \
|
|||||||
$(XPM_LIB) \
|
$(XPM_LIB) \
|
||||||
$(XBM_LIB) \
|
$(XBM_LIB) \
|
||||||
$(TGA_LIB) \
|
$(TGA_LIB) \
|
||||||
|
$(ICNS_LIB) \
|
||||||
$(PCX_LIB)
|
$(PCX_LIB)
|
||||||
|
|
||||||
|
|
||||||
@ -297,6 +312,7 @@ noinst_LTLIBRARIES = \
|
|||||||
$(STATIC_XPM_LIB) \
|
$(STATIC_XPM_LIB) \
|
||||||
$(STATIC_XBM_LIB) \
|
$(STATIC_XBM_LIB) \
|
||||||
$(STATIC_TGA_LIB) \
|
$(STATIC_TGA_LIB) \
|
||||||
|
$(STATIC_ICNS_LIB) \
|
||||||
$(STATIC_PCX_LIB)
|
$(STATIC_PCX_LIB)
|
||||||
|
|
||||||
builtin_objs = @INCLUDED_LOADER_OBJ@
|
builtin_objs = @INCLUDED_LOADER_OBJ@
|
||||||
|
396
gdk-pixbuf/io-icns.c
Normal file
396
gdk-pixbuf/io-icns.c
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
/* Mac OS X .icns icons loader
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007 Lyonel Vincent <lyonel@ezix.org>
|
||||||
|
* Copyright (c) 2007 Bastien Nocera <hadess@hadess.net>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "gdk-pixbuf-private.h"
|
||||||
|
#include "gdk-pixbuf-io.h"
|
||||||
|
|
||||||
|
G_MODULE_EXPORT void fill_vtable (GdkPixbufModule * module);
|
||||||
|
G_MODULE_EXPORT void fill_info (GdkPixbufFormat * info);
|
||||||
|
|
||||||
|
#define IN /**/
|
||||||
|
#define OUT /**/
|
||||||
|
#define INOUT /**/
|
||||||
|
|
||||||
|
struct IcnsBlockHeader
|
||||||
|
{
|
||||||
|
char id[4];
|
||||||
|
guint32 size; /* caution: bigendian */
|
||||||
|
};
|
||||||
|
typedef struct IcnsBlockHeader IcnsBlockHeader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* load raw icon data from 'icns' resource
|
||||||
|
*
|
||||||
|
* returns TRUE when successful
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
load_resources (unsigned size, IN gpointer data, gsize datalen,
|
||||||
|
OUT guchar ** picture, OUT gsize * plen,
|
||||||
|
OUT guchar ** mask, OUT gsize * mlen)
|
||||||
|
{
|
||||||
|
IcnsBlockHeader *header = NULL;
|
||||||
|
const char *bytes = NULL;
|
||||||
|
const char *current = NULL;
|
||||||
|
guint32 blocklen = 0;
|
||||||
|
guint32 icnslen = 0;
|
||||||
|
gboolean needs_mask = TRUE;
|
||||||
|
|
||||||
|
if (datalen < 2 * sizeof (guint32))
|
||||||
|
return FALSE;
|
||||||
|
if (!data)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*picture = *mask = NULL;
|
||||||
|
*plen = *mlen = 0;
|
||||||
|
|
||||||
|
bytes = data;
|
||||||
|
header = (IcnsBlockHeader *) data;
|
||||||
|
if (memcmp (header->id, "icns", 4) != 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
icnslen = GUINT32_FROM_BE (header->size);
|
||||||
|
if ((icnslen > datalen) || (icnslen < 2 * sizeof (guint32)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
current = bytes + sizeof (IcnsBlockHeader);
|
||||||
|
while ((current - bytes < icnslen) && (icnslen - (current - bytes) >= sizeof (IcnsBlockHeader)))
|
||||||
|
{
|
||||||
|
header = (IcnsBlockHeader *) current;
|
||||||
|
blocklen = GUINT32_FROM_BE (header->size);
|
||||||
|
|
||||||
|
/* Check that blocklen isn't garbage */
|
||||||
|
if (blocklen > icnslen - (current - bytes))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 256:
|
||||||
|
if (memcmp (header->id, "ic08", 4) == 0) /* 256x256 icon */
|
||||||
|
{
|
||||||
|
*picture = (gpointer) (current + sizeof (IcnsBlockHeader));
|
||||||
|
*plen = blocklen - sizeof (IcnsBlockHeader);
|
||||||
|
}
|
||||||
|
needs_mask = FALSE;
|
||||||
|
break;
|
||||||
|
case 128:
|
||||||
|
if (memcmp (header->id, "it32", 4) == 0) /* 128x128 icon */
|
||||||
|
{
|
||||||
|
*picture = (gpointer) (current + sizeof (IcnsBlockHeader));
|
||||||
|
*plen = blocklen - sizeof (IcnsBlockHeader);
|
||||||
|
if (memcmp (*picture, "\0\0\0\0", 4) == 0)
|
||||||
|
{
|
||||||
|
*picture += 4;
|
||||||
|
*plen -= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (memcmp (header->id, "t8mk", 4) == 0) /* 128x128 mask */
|
||||||
|
{
|
||||||
|
*mask = (gpointer) (current + sizeof (IcnsBlockHeader));
|
||||||
|
*mlen = blocklen - sizeof (IcnsBlockHeader);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 48:
|
||||||
|
if (memcmp (header->id, "ih32", 4) == 0) /* 48x48 icon */
|
||||||
|
{
|
||||||
|
*picture = (gpointer) (current + sizeof (IcnsBlockHeader));
|
||||||
|
*plen = blocklen - sizeof (IcnsBlockHeader);
|
||||||
|
}
|
||||||
|
if (memcmp (header->id, "h8mk", 4) == 0) /* 48x48 mask */
|
||||||
|
{
|
||||||
|
*mask = (gpointer) (current + sizeof (IcnsBlockHeader));
|
||||||
|
*mlen = blocklen - sizeof (IcnsBlockHeader);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
if (memcmp (header->id, "il32", 4) == 0) /* 32x32 icon */
|
||||||
|
{
|
||||||
|
*picture = (gpointer) (current + sizeof (IcnsBlockHeader));
|
||||||
|
*plen = blocklen - sizeof (IcnsBlockHeader);
|
||||||
|
}
|
||||||
|
if (memcmp (header->id, "l8mk", 4) == 0) /* 32x32 mask */
|
||||||
|
{
|
||||||
|
*mask = (gpointer) (current + sizeof (IcnsBlockHeader));
|
||||||
|
*mlen = blocklen - sizeof (IcnsBlockHeader);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
if (memcmp (header->id, "is32", 4) == 0) /* 16x16 icon */
|
||||||
|
{
|
||||||
|
*picture = (gpointer) (current + sizeof (IcnsBlockHeader));
|
||||||
|
*plen = blocklen - sizeof (IcnsBlockHeader);
|
||||||
|
}
|
||||||
|
if (memcmp (header->id, "s8mk", 4) == 0) /* 16x16 mask */
|
||||||
|
{
|
||||||
|
*mask = (gpointer) (current + sizeof (IcnsBlockHeader));
|
||||||
|
*mlen = blocklen - sizeof (IcnsBlockHeader);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
current += blocklen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*picture)
|
||||||
|
return FALSE;
|
||||||
|
if (needs_mask && !*mask)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* uncompress RLE-encoded bytes into RGBA scratch zone:
|
||||||
|
* if firstbyte >= 0x80, it indicates the number of identical bytes + 125
|
||||||
|
* (repeated value is stored next: 1 byte)
|
||||||
|
* otherwise, it indicates the number of non-repeating bytes - 1
|
||||||
|
* (non-repeating values are stored next: n bytes)
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
uncompress (unsigned size, INOUT guchar ** source, OUT guchar * target, INOUT gsize * _remaining)
|
||||||
|
{
|
||||||
|
guchar *data = *source;
|
||||||
|
gsize remaining;
|
||||||
|
gsize i = 0;
|
||||||
|
|
||||||
|
/* The first time we're called, set remaining */
|
||||||
|
if (*_remaining == 0) {
|
||||||
|
remaining = size * size;
|
||||||
|
} else {
|
||||||
|
remaining = *_remaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (remaining > 0)
|
||||||
|
{
|
||||||
|
guint8 count = 0;
|
||||||
|
|
||||||
|
if (data[0] & 0x80) /* repeating byte */
|
||||||
|
{
|
||||||
|
count = data[0] - 125;
|
||||||
|
|
||||||
|
if (count > remaining)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
*target = data[1];
|
||||||
|
target += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
data += 2;
|
||||||
|
}
|
||||||
|
else /* non-repeating bytes */
|
||||||
|
{
|
||||||
|
count = data[0] + 1;
|
||||||
|
|
||||||
|
if (count > remaining)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
*target = data[i + 1];
|
||||||
|
target += 4;
|
||||||
|
}
|
||||||
|
data += count + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining -= count;
|
||||||
|
}
|
||||||
|
|
||||||
|
*source = data;
|
||||||
|
*_remaining = remaining;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkPixbuf *
|
||||||
|
load_icon (unsigned size, IN gpointer data, gsize datalen)
|
||||||
|
{
|
||||||
|
guchar *icon = NULL;
|
||||||
|
guchar *mask = NULL;
|
||||||
|
gsize isize = 0, msize = 0, i;
|
||||||
|
guchar *image = NULL;
|
||||||
|
|
||||||
|
if (!load_resources (size, data, datalen, &icon, &isize, &mask, &msize))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* 256x256 icons don't use RLE or uncompressed data,
|
||||||
|
* They're usually JPEG 2000 images */
|
||||||
|
if (size == 256)
|
||||||
|
{
|
||||||
|
GdkPixbufLoader *loader;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
|
||||||
|
loader = gdk_pixbuf_loader_new ();
|
||||||
|
if (!gdk_pixbuf_loader_write (loader, icon, isize, NULL)
|
||||||
|
|| !gdk_pixbuf_loader_close (loader, NULL))
|
||||||
|
{
|
||||||
|
g_object_unref (loader);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
|
||||||
|
g_object_ref (pixbuf);
|
||||||
|
g_object_unref (loader);
|
||||||
|
|
||||||
|
return pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (mask);
|
||||||
|
|
||||||
|
if (msize != size * size) /* wrong mask size */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
image = (guchar *) g_try_malloc0 (size * size * 4); /* 4 bytes/pixel = RGBA */
|
||||||
|
|
||||||
|
if (!image)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (isize == size * size * 4) /* icon data is uncompressed */
|
||||||
|
for (i = 0; i < size * size; i++) /* 4 bytes/pixel = ARGB (A: ignored) */
|
||||||
|
{
|
||||||
|
image[i * 4] = icon[4 * i + 1]; /* R */
|
||||||
|
image[i * 4 + 1] = icon[4 * i + 2]; /* G */
|
||||||
|
image[i * 4 + 2] = icon[4 * i + 3]; /* B */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
guchar *data = icon;
|
||||||
|
gsize remaining = 0;
|
||||||
|
|
||||||
|
/* R */
|
||||||
|
if (!uncompress (size, &data, image, &remaining))
|
||||||
|
goto bail;
|
||||||
|
/* G */
|
||||||
|
if (!uncompress (size, &data, image + 1, &remaining))
|
||||||
|
goto bail;
|
||||||
|
/* B */
|
||||||
|
if (!uncompress (size, &data, image + 2, &remaining))
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < size * size; i++) /* copy mask to alpha channel */
|
||||||
|
image[i * 4 + 3] = mask[i];
|
||||||
|
|
||||||
|
return gdk_pixbuf_new_from_data ((guchar *) image, GDK_COLORSPACE_RGB, /* RGB image */
|
||||||
|
TRUE, /* with alpha channel */
|
||||||
|
8, /* 8 bits per sample */
|
||||||
|
size, /* width */
|
||||||
|
size, /* height */
|
||||||
|
size * 4, /* no gap between rows */
|
||||||
|
(GdkPixbufDestroyNotify)g_free, /* free() function */
|
||||||
|
NULL); /* param to free() function */
|
||||||
|
|
||||||
|
bail:
|
||||||
|
g_free (image);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sizes[] = {
|
||||||
|
256, /* late-Tiger icons */
|
||||||
|
128, /* Standard OS X */
|
||||||
|
48, /* Not very common */
|
||||||
|
32, /* Standard Mac OS Classic (8 & 9) */
|
||||||
|
24, /* OS X toolbars */
|
||||||
|
16 /* used in Mac OS Classic and dialog boxes */
|
||||||
|
};
|
||||||
|
|
||||||
|
static GdkPixbuf *
|
||||||
|
icns_image_load (FILE *f, GError ** error)
|
||||||
|
{
|
||||||
|
GByteArray *data;
|
||||||
|
GdkPixbuf *pixbuf = NULL;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
data = g_byte_array_new ();
|
||||||
|
while (!feof (f))
|
||||||
|
{
|
||||||
|
gint save_errno;
|
||||||
|
guchar buf[4096];
|
||||||
|
gsize bytes;
|
||||||
|
|
||||||
|
bytes = fread (buf, 1, sizeof (buf), f);
|
||||||
|
save_errno = errno;
|
||||||
|
data = g_byte_array_append (data, buf, bytes);
|
||||||
|
|
||||||
|
if (ferror (f))
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_FILE_ERROR,
|
||||||
|
g_file_error_from_errno (save_errno),
|
||||||
|
_("Error reading ICNS image: %s"),
|
||||||
|
g_strerror (save_errno));
|
||||||
|
|
||||||
|
g_byte_array_free (data, TRUE);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS(sizes) && !pixbuf; i++)
|
||||||
|
pixbuf = load_icon (sizes[i], data->data, data->len);
|
||||||
|
|
||||||
|
g_byte_array_free (data, TRUE);
|
||||||
|
|
||||||
|
if (!pixbuf)
|
||||||
|
g_set_error (error, GDK_PIXBUF_ERROR,
|
||||||
|
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||||
|
_("Could not decode ICNS file"));
|
||||||
|
|
||||||
|
return pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fill_vtable (GdkPixbufModule * module)
|
||||||
|
{
|
||||||
|
module->load = icns_image_load;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fill_info (GdkPixbufFormat * info)
|
||||||
|
{
|
||||||
|
static GdkPixbufModulePattern signature[] = {
|
||||||
|
{"icns", NULL, 100}, /* file begins with 'icns' */
|
||||||
|
{NULL, NULL, 0}
|
||||||
|
};
|
||||||
|
static gchar *mime_types[] = {
|
||||||
|
"image/x-icns",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
static gchar *extensions[] = {
|
||||||
|
"icns",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
info->name = "icns";
|
||||||
|
info->signature = signature;
|
||||||
|
info->description = N_("The ICNS image format");
|
||||||
|
info->mime_types = mime_types;
|
||||||
|
info->extensions = extensions;
|
||||||
|
info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
|
||||||
|
info->license = "GPL";
|
||||||
|
info->disabled = FALSE;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user