Blame gdk-pixbuf/io-icns.c

Packit a4058c
/* Mac OS X .icns icons loader
Packit a4058c
 *
Packit a4058c
 * Copyright (c) 2007 Lyonel Vincent <lyonel@ezix.org>
Packit a4058c
 * Copyright (c) 2007 Bastien Nocera <hadess@hadess.net>
Packit a4058c
 *
Packit a4058c
 * This library is free software; you can redistribute it and/or
Packit a4058c
 * modify it under the terms of the GNU Lesser General Public
Packit a4058c
 * License as published by the Free Software Foundation; either
Packit a4058c
 * version 2 of the License, or (at your option) any later version.
Packit a4058c
 *
Packit a4058c
 * This library is distributed in the hope that it will be useful,
Packit a4058c
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a4058c
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a4058c
 * Lesser General Public License for more details.
Packit a4058c
 *
Packit a4058c
 * You should have received a copy of the GNU Lesser General Public
Packit a4058c
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit a4058c
 */
Packit a4058c
Packit a4058c
#ifndef _WIN32
Packit a4058c
#define _GNU_SOURCE
Packit a4058c
#endif
Packit a4058c
#include "config.h"
Packit a4058c
Packit a4058c
#include <stdlib.h>
Packit a4058c
#include <string.h>
Packit a4058c
#include <errno.h>
Packit a4058c
Packit a4058c
#include "gdk-pixbuf-private.h"
Packit a4058c
#include "gdk-pixbuf-loader.h"
Packit a4058c
Packit a4058c
G_MODULE_EXPORT void fill_vtable (GdkPixbufModule * module);
Packit a4058c
G_MODULE_EXPORT void fill_info (GdkPixbufFormat * info);
Packit a4058c
Packit a4058c
#define IN /**/
Packit a4058c
#define OUT /**/
Packit a4058c
#define INOUT /**/
Packit a4058c
Packit a4058c
struct IcnsBlockHeader
Packit a4058c
{
Packit a4058c
  char id[4];
Packit a4058c
  guint32 size;			/* caution: bigendian */
Packit a4058c
};
Packit a4058c
typedef struct IcnsBlockHeader IcnsBlockHeader;
Packit a4058c
Packit a4058c
typedef struct
Packit a4058c
{
Packit a4058c
  GdkPixbufModuleSizeFunc size_func;
Packit a4058c
  GdkPixbufModulePreparedFunc prepared_func;
Packit a4058c
  GdkPixbufModuleUpdatedFunc updated_func;
Packit a4058c
  gpointer user_data;
Packit a4058c
Packit a4058c
  GByteArray *byte_array;
Packit a4058c
  GdkPixbuf *pixbuf;      /* Our "target" */
Packit a4058c
} IcnsProgressiveState;
Packit a4058c
Packit a4058c
/*
Packit a4058c
 * load raw icon data from 'icns' resource
Packit a4058c
 *
Packit a4058c
 * returns TRUE when successful
Packit a4058c
 */
Packit a4058c
static gboolean
Packit a4058c
load_resources (unsigned size, IN gpointer data, gsize datalen,
Packit a4058c
		OUT guchar ** picture, OUT gsize * plen,
Packit a4058c
		OUT guchar ** mask, OUT gsize * mlen)
Packit a4058c
{
Packit a4058c
  IcnsBlockHeader *header = NULL;
Packit a4058c
  const char *bytes = NULL;
Packit a4058c
  const char *current = NULL;
Packit a4058c
  guint32 blocklen = 0;
Packit a4058c
  guint32 icnslen = 0;
Packit a4058c
  gboolean needs_mask = TRUE;
Packit a4058c
Packit a4058c
  if (datalen < 2 * sizeof (guint32))
Packit a4058c
    return FALSE;
Packit a4058c
  if (!data)
Packit a4058c
    return FALSE;
Packit a4058c
Packit a4058c
  *picture = *mask = NULL;
Packit a4058c
  *plen = *mlen = 0;
Packit a4058c
Packit a4058c
  bytes = data;
Packit a4058c
  header = (IcnsBlockHeader *) data;
Packit a4058c
  if (memcmp (header->id, "icns", 4) != 0)
Packit a4058c
    return FALSE;
Packit a4058c
Packit a4058c
  icnslen = GUINT32_FROM_BE (header->size);
Packit a4058c
  if ((icnslen > datalen) || (icnslen < 2 * sizeof (guint32)))
Packit a4058c
    return FALSE;
Packit a4058c
Packit a4058c
  current = bytes + sizeof (IcnsBlockHeader);
Packit a4058c
  while ((current - bytes < icnslen) && (icnslen - (current - bytes) >= sizeof (IcnsBlockHeader)))
Packit a4058c
    {
Packit a4058c
      header = (IcnsBlockHeader *) current;
Packit a4058c
      blocklen = GUINT32_FROM_BE (header->size);
Packit a4058c
Packit a4058c
      /* Check that blocklen isn't garbage */
Packit a4058c
      if (blocklen > icnslen - (current - bytes))
Packit a4058c
        return FALSE;
Packit a4058c
Packit a4058c
      switch (size)
Packit a4058c
	{
Packit a4058c
	case 256:
Packit a4058c
	case 512:
Packit a4058c
          if (memcmp (header->id, "ic08", 4) == 0	/* 256x256 icon */
Packit a4058c
              || memcmp (header->id, "ic09", 4) == 0)	/* 512x512 icon */
Packit a4058c
            {
Packit a4058c
	      *picture = (gpointer) (current + sizeof (IcnsBlockHeader));
Packit a4058c
	      *plen = blocklen - sizeof (IcnsBlockHeader);
Packit a4058c
	    }
Packit a4058c
	    needs_mask = FALSE;
Packit a4058c
	  break;
Packit a4058c
	case 128:
Packit a4058c
	  if (memcmp (header->id, "it32", 4) == 0)	/* 128x128 icon */
Packit a4058c
	    {
Packit a4058c
	      *picture = (gpointer) (current + sizeof (IcnsBlockHeader));
Packit a4058c
	      *plen = blocklen - sizeof (IcnsBlockHeader);
Packit a4058c
	      if (memcmp (*picture, "\0\0\0\0", 4) == 0)
Packit a4058c
		{
Packit a4058c
		  *picture += 4;
Packit a4058c
		  *plen -= 4;
Packit a4058c
		}
Packit a4058c
	    }
Packit a4058c
	  if (memcmp (header->id, "t8mk", 4) == 0)	/* 128x128 mask */
Packit a4058c
	    {
Packit a4058c
	      *mask = (gpointer) (current + sizeof (IcnsBlockHeader));
Packit a4058c
	      *mlen = blocklen - sizeof (IcnsBlockHeader);
Packit a4058c
	    }
Packit a4058c
	  break;
Packit a4058c
	case 48:
Packit a4058c
	  if (memcmp (header->id, "ih32", 4) == 0)	/* 48x48 icon */
Packit a4058c
	    {
Packit a4058c
	      *picture = (gpointer) (current + sizeof (IcnsBlockHeader));
Packit a4058c
	      *plen = blocklen - sizeof (IcnsBlockHeader);
Packit a4058c
	    }
Packit a4058c
	  if (memcmp (header->id, "h8mk", 4) == 0)	/* 48x48 mask */
Packit a4058c
	    {
Packit a4058c
	      *mask = (gpointer) (current + sizeof (IcnsBlockHeader));
Packit a4058c
	      *mlen = blocklen - sizeof (IcnsBlockHeader);
Packit a4058c
	    }
Packit a4058c
	  break;
Packit a4058c
	case 32:
Packit a4058c
	  if (memcmp (header->id, "il32", 4) == 0)	/* 32x32 icon */
Packit a4058c
	    {
Packit a4058c
	      *picture = (gpointer) (current + sizeof (IcnsBlockHeader));
Packit a4058c
	      *plen = blocklen - sizeof (IcnsBlockHeader);
Packit a4058c
	    }
Packit a4058c
	  if (memcmp (header->id, "l8mk", 4) == 0)	/* 32x32 mask */
Packit a4058c
	    {
Packit a4058c
	      *mask = (gpointer) (current + sizeof (IcnsBlockHeader));
Packit a4058c
	      *mlen = blocklen - sizeof (IcnsBlockHeader);
Packit a4058c
	    }
Packit a4058c
	  break;
Packit a4058c
	case 16:
Packit a4058c
	  if (memcmp (header->id, "is32", 4) == 0)	/* 16x16 icon */
Packit a4058c
	    {
Packit a4058c
	      *picture = (gpointer) (current + sizeof (IcnsBlockHeader));
Packit a4058c
	      *plen = blocklen - sizeof (IcnsBlockHeader);
Packit a4058c
	    }
Packit a4058c
	  if (memcmp (header->id, "s8mk", 4) == 0)	/* 16x16 mask */
Packit a4058c
	    {
Packit a4058c
	      *mask = (gpointer) (current + sizeof (IcnsBlockHeader));
Packit a4058c
	      *mlen = blocklen - sizeof (IcnsBlockHeader);
Packit a4058c
	    }
Packit a4058c
	  break;
Packit a4058c
	default:
Packit a4058c
	  return FALSE;
Packit a4058c
	}
Packit a4058c
Packit a4058c
      current += blocklen;
Packit a4058c
    }
Packit a4058c
Packit a4058c
  if (!*picture)
Packit a4058c
    return FALSE;
Packit a4058c
  if (needs_mask && !*mask)
Packit a4058c
    return FALSE;
Packit a4058c
  return TRUE;
Packit a4058c
}
Packit a4058c
Packit a4058c
/*
Packit a4058c
 * uncompress RLE-encoded bytes into RGBA scratch zone:
Packit a4058c
 * if firstbyte >= 0x80, it indicates the number of identical bytes + 125
Packit a4058c
 * 	(repeated value is stored next: 1 byte)
Packit a4058c
 * otherwise, it indicates the number of non-repeating bytes - 1
Packit a4058c
 *	(non-repeating values are stored next: n bytes)
Packit a4058c
 */
Packit a4058c
static gboolean
Packit a4058c
uncompress (unsigned size, INOUT guchar ** source, OUT guchar * target, INOUT gsize * _remaining)
Packit a4058c
{
Packit a4058c
  guchar *data = *source;
Packit a4058c
  gsize remaining;
Packit a4058c
  gsize i = 0;
Packit a4058c
Packit a4058c
  /* The first time we're called, set remaining */
Packit a4058c
  if (*_remaining == 0) {
Packit a4058c
    remaining = size * size;
Packit a4058c
  } else {
Packit a4058c
    remaining = *_remaining;
Packit a4058c
  }
Packit a4058c
Packit a4058c
  while (remaining > 0)
Packit a4058c
    {
Packit a4058c
      guint8 count = 0;
Packit a4058c
Packit a4058c
      if (data[0] & 0x80)	/* repeating byte */
Packit a4058c
	{
Packit a4058c
	  count = data[0] - 125;
Packit a4058c
Packit a4058c
	  if (count > remaining)
Packit a4058c
	    return FALSE;
Packit a4058c
Packit a4058c
	  for (i = 0; i < count; i++)
Packit a4058c
	    {
Packit a4058c
	      *target = data[1];
Packit a4058c
	      target += 4;
Packit a4058c
	    }
Packit a4058c
Packit a4058c
	  data += 2;
Packit a4058c
	}
Packit a4058c
      else			/* non-repeating bytes */
Packit a4058c
	{
Packit a4058c
	  count = data[0] + 1;
Packit a4058c
Packit a4058c
	  if (count > remaining)
Packit a4058c
	    return FALSE;
Packit a4058c
Packit a4058c
	  for (i = 0; i < count; i++)
Packit a4058c
	    {
Packit a4058c
	      *target = data[i + 1];
Packit a4058c
	      target += 4;
Packit a4058c
	    }
Packit a4058c
	  data += count + 1;
Packit a4058c
	}
Packit a4058c
Packit a4058c
      remaining -= count;
Packit a4058c
    }
Packit a4058c
Packit a4058c
  *source = data;
Packit a4058c
  *_remaining = remaining;
Packit a4058c
  return TRUE;
Packit a4058c
}
Packit a4058c
Packit a4058c
static GdkPixbuf *
Packit a4058c
load_icon (unsigned size, IN gpointer data, gsize datalen)
Packit a4058c
{
Packit a4058c
  guchar *icon = NULL;
Packit a4058c
  guchar *mask = NULL;
Packit a4058c
  gsize isize = 0, msize = 0, i;
Packit a4058c
  guchar *image = NULL;
Packit a4058c
Packit a4058c
  if (!load_resources (size, data, datalen, &icon, &isize, &mask, &msize))
Packit a4058c
    return NULL;
Packit a4058c
Packit a4058c
  /* 256x256 icons don't use RLE or uncompressed data,
Packit a4058c
   * They're usually JPEG 2000 images */
Packit a4058c
  if (size == 256)
Packit a4058c
    {
Packit a4058c
      GdkPixbufLoader *loader;
Packit a4058c
      GdkPixbuf *pixbuf;
Packit a4058c
Packit a4058c
      loader = gdk_pixbuf_loader_new ();
Packit a4058c
      if (!gdk_pixbuf_loader_write (loader, icon, isize, NULL)
Packit a4058c
	  || !gdk_pixbuf_loader_close (loader, NULL))
Packit a4058c
        {
Packit a4058c
          g_object_unref (loader);
Packit a4058c
          return NULL;
Packit a4058c
	}
Packit a4058c
Packit a4058c
      pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
Packit a4058c
      g_object_ref (pixbuf);
Packit a4058c
      g_object_unref (loader);
Packit a4058c
Packit a4058c
      return pixbuf;
Packit a4058c
    }
Packit a4058c
Packit a4058c
  g_assert (mask);
Packit a4058c
Packit a4058c
  if (msize != size * size)	/* wrong mask size */
Packit a4058c
    return NULL;
Packit a4058c
Packit a4058c
  image = (guchar *) g_try_malloc0 (size * size * 4);	/* 4 bytes/pixel = RGBA */
Packit a4058c
Packit a4058c
  if (!image)
Packit a4058c
    return NULL;
Packit a4058c
Packit a4058c
  if (isize == size * size * 4)	/* icon data is uncompressed */
Packit a4058c
    for (i = 0; i < size * size; i++)	/* 4 bytes/pixel = ARGB (A: ignored) */
Packit a4058c
      {
Packit a4058c
	image[i * 4] = icon[4 * i + 1];	/* R */
Packit a4058c
	image[i * 4 + 1] = icon[4 * i + 2];	/* G */
Packit a4058c
	image[i * 4 + 2] = icon[4 * i + 3];	/* B */
Packit a4058c
      }
Packit a4058c
  else
Packit a4058c
    {
Packit a4058c
      guchar *data = icon;
Packit a4058c
      gsize remaining = 0;
Packit a4058c
Packit a4058c
      /* R */
Packit a4058c
      if (!uncompress (size, &data, image, &remaining))
Packit a4058c
        goto bail;
Packit a4058c
      /* G */
Packit a4058c
      if (!uncompress (size, &data, image + 1, &remaining))
Packit a4058c
        goto bail;
Packit a4058c
      /* B */
Packit a4058c
      if (!uncompress (size, &data, image + 2, &remaining))
Packit a4058c
        goto bail;
Packit a4058c
    }
Packit a4058c
Packit a4058c
  for (i = 0; i < size * size; i++)	/* copy mask to alpha channel */
Packit a4058c
    image[i * 4 + 3] = mask[i];
Packit a4058c
Packit a4058c
  return gdk_pixbuf_new_from_data ((guchar *) image, GDK_COLORSPACE_RGB,	/* RGB image */
Packit a4058c
				   TRUE,	/* with alpha channel */
Packit a4058c
				   8,	/* 8 bits per sample */
Packit a4058c
				   size,	/* width */
Packit a4058c
				   size,	/* height */
Packit a4058c
				   size * 4,	/* no gap between rows */
Packit a4058c
				   (GdkPixbufDestroyNotify)g_free,	/* free() function */
Packit a4058c
				   NULL);	/* param to free() function */
Packit a4058c
Packit a4058c
bail:
Packit a4058c
  g_free (image);
Packit a4058c
  return NULL;
Packit a4058c
}
Packit a4058c
Packit a4058c
static int sizes[] = {
Packit a4058c
  256, /* late-Tiger icons */
Packit a4058c
  128, /* Standard OS X */
Packit a4058c
  48,  /* Not very common */
Packit a4058c
  32,  /* Standard Mac OS Classic (8 & 9) */
Packit a4058c
  24,  /* OS X toolbars */
Packit a4058c
  16   /* used in Mac OS Classic and dialog boxes */
Packit a4058c
};
Packit a4058c
Packit a4058c
static GdkPixbuf *
Packit a4058c
icns_image_load (FILE *f, GError ** error)
Packit a4058c
{
Packit a4058c
  GByteArray *data;
Packit a4058c
  GdkPixbuf *pixbuf = NULL;
Packit a4058c
  guint i;
Packit a4058c
Packit a4058c
  data = g_byte_array_new ();
Packit a4058c
  while (!feof (f))
Packit a4058c
    {
Packit a4058c
      gint save_errno;
Packit a4058c
      guchar buf[4096];
Packit a4058c
      gsize bytes;
Packit a4058c
Packit a4058c
      bytes = fread (buf, 1, sizeof (buf), f);
Packit a4058c
      save_errno = errno;
Packit a4058c
      data = g_byte_array_append (data, buf, bytes);
Packit a4058c
Packit a4058c
      if (ferror (f))
Packit a4058c
        {
Packit a4058c
	  g_set_error (error,
Packit a4058c
		       G_FILE_ERROR,
Packit a4058c
		       g_file_error_from_errno (save_errno),
Packit a4058c
		       _("Error reading ICNS image: %s"),
Packit a4058c
		       g_strerror (save_errno));
Packit a4058c
Packit a4058c
	  g_byte_array_free (data, TRUE);
Packit a4058c
Packit a4058c
	  return NULL;
Packit a4058c
	}
Packit a4058c
    }
Packit a4058c
Packit a4058c
  for (i = 0; i < G_N_ELEMENTS(sizes) && !pixbuf; i++)
Packit a4058c
    pixbuf = load_icon (sizes[i], data->data, data->len);
Packit a4058c
Packit a4058c
  g_byte_array_free (data, TRUE);
Packit a4058c
Packit a4058c
  if (!pixbuf)
Packit a4058c
    g_set_error_literal (error, GDK_PIXBUF_ERROR,
Packit a4058c
                         GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
Packit a4058c
                         _("Could not decode ICNS file"));
Packit a4058c
Packit a4058c
  return pixbuf;
Packit a4058c
}
Packit a4058c
Packit a4058c
static void
Packit a4058c
context_free (IcnsProgressiveState *context)
Packit a4058c
{
Packit a4058c
  g_byte_array_free (context->byte_array, TRUE);
Packit a4058c
  g_clear_object (&context->pixbuf);
Packit a4058c
  g_free (context);
Packit a4058c
}
Packit a4058c
Packit a4058c
static gpointer
Packit a4058c
gdk_pixbuf__icns_image_begin_load (GdkPixbufModuleSizeFunc      size_func,
Packit a4058c
				   GdkPixbufModulePreparedFunc  prepared_func,
Packit a4058c
				   GdkPixbufModuleUpdatedFunc   updated_func,
Packit a4058c
				   gpointer                     user_data,
Packit a4058c
				   GError                     **error)
Packit a4058c
{
Packit a4058c
  IcnsProgressiveState *context;
Packit a4058c
Packit a4058c
  context = g_new0 (IcnsProgressiveState, 1);
Packit a4058c
  context->size_func = size_func;
Packit a4058c
  context->prepared_func = prepared_func;
Packit a4058c
  context->updated_func = updated_func;
Packit a4058c
  context->user_data = user_data;
Packit a4058c
  context->byte_array = g_byte_array_new ();
Packit a4058c
Packit a4058c
  return context;
Packit a4058c
}
Packit a4058c
Packit a4058c
static gboolean
Packit a4058c
gdk_pixbuf__icns_image_stop_load (gpointer   data,
Packit a4058c
                                  GError   **error)
Packit a4058c
{
Packit a4058c
  IcnsProgressiveState *context = data;
Packit a4058c
Packit a4058c
  g_return_val_if_fail (context != NULL, TRUE);
Packit a4058c
Packit a4058c
  context_free (context);
Packit a4058c
  return TRUE;
Packit a4058c
}
Packit a4058c
Packit a4058c
static gboolean
Packit a4058c
gdk_pixbuf__icns_image_load_increment (gpointer       data,
Packit a4058c
                                       const guchar  *buf,
Packit a4058c
                                       guint          size,
Packit a4058c
                                       GError       **error)
Packit a4058c
{
Packit a4058c
  IcnsProgressiveState *context = data;
Packit a4058c
  int i;
Packit a4058c
  int filesize;
Packit a4058c
  gint w, h;
Packit a4058c
Packit a4058c
  context->byte_array = g_byte_array_append (context->byte_array, buf, size);
Packit a4058c
Packit a4058c
  if (context->byte_array->len < 8)
Packit a4058c
    return TRUE;
Packit a4058c
Packit a4058c
  filesize = (context->byte_array->data[4] << 24) |
Packit a4058c
    (context->byte_array->data[5] << 16) |
Packit a4058c
    (context->byte_array->data[6] << 8) |
Packit a4058c
    (context->byte_array->data[7]);
Packit a4058c
Packit a4058c
  if (context->byte_array->len < filesize)
Packit a4058c
    return TRUE;
Packit a4058c
Packit a4058c
  for (i = 0; i < G_N_ELEMENTS(sizes) && !context->pixbuf; i++)
Packit a4058c
    context->pixbuf = load_icon (sizes[i],
Packit a4058c
				 context->byte_array->data,
Packit a4058c
				 context->byte_array->len);
Packit a4058c
Packit a4058c
  if (!context->pixbuf)
Packit a4058c
    {
Packit a4058c
      g_set_error_literal (error, GDK_PIXBUF_ERROR,
Packit a4058c
                           GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
Packit a4058c
                           _("Could not decode ICNS file"));
Packit a4058c
      return FALSE;
Packit a4058c
    }
Packit a4058c
Packit a4058c
  w = gdk_pixbuf_get_width (context->pixbuf);
Packit a4058c
  h = gdk_pixbuf_get_height (context->pixbuf);
Packit a4058c
Packit a4058c
  if (context->size_func != NULL)
Packit a4058c
    (*context->size_func) (&w,
Packit a4058c
			   &h,
Packit a4058c
			   context->user_data);
Packit a4058c
Packit a4058c
  if (context->prepared_func != NULL)
Packit a4058c
    (*context->prepared_func) (context->pixbuf,
Packit a4058c
			       NULL,
Packit a4058c
			       context->user_data);
Packit a4058c
Packit a4058c
  if (context->updated_func != NULL)
Packit a4058c
    (*context->updated_func) (context->pixbuf,
Packit a4058c
			      0,
Packit a4058c
			      0,
Packit a4058c
			      gdk_pixbuf_get_width (context->pixbuf),
Packit a4058c
			      gdk_pixbuf_get_height (context->pixbuf),
Packit a4058c
			      context->user_data);
Packit a4058c
Packit a4058c
  return TRUE;
Packit a4058c
}
Packit a4058c
Packit a4058c
#ifndef INCLUDE_icns
Packit a4058c
#define MODULE_ENTRY(function) G_MODULE_EXPORT void function
Packit a4058c
#else
Packit a4058c
#define MODULE_ENTRY(function) void _gdk_pixbuf__icns_ ## function
Packit a4058c
#endif
Packit a4058c
Packit a4058c
MODULE_ENTRY (fill_vtable) (GdkPixbufModule * module)
Packit a4058c
{
Packit a4058c
  module->load = icns_image_load;
Packit a4058c
  module->begin_load = gdk_pixbuf__icns_image_begin_load;
Packit a4058c
  module->stop_load = gdk_pixbuf__icns_image_stop_load;
Packit a4058c
  module->load_increment = gdk_pixbuf__icns_image_load_increment;
Packit a4058c
}
Packit a4058c
Packit a4058c
MODULE_ENTRY (fill_info) (GdkPixbufFormat * info)
Packit a4058c
{
Packit a4058c
  static const GdkPixbufModulePattern signature[] = {
Packit a4058c
    {"icns", NULL, 100},	/* file begins with 'icns' */
Packit a4058c
    {NULL, NULL, 0}
Packit a4058c
  };
Packit a4058c
  static const gchar *mime_types[] = {
Packit a4058c
    "image/x-icns",
Packit a4058c
    NULL
Packit a4058c
  };
Packit a4058c
  static const gchar *extensions[] = {
Packit a4058c
    "icns",
Packit a4058c
    NULL
Packit a4058c
  };
Packit a4058c
Packit a4058c
  info->name = "icns";
Packit a4058c
  info->signature = (GdkPixbufModulePattern *) signature;
Packit a4058c
  info->description = NC_("image format", "MacOS X icon");
Packit a4058c
  info->mime_types = (gchar **) mime_types;
Packit a4058c
  info->extensions = (gchar **) extensions;
Packit a4058c
  info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
Packit a4058c
  info->license = "GPL";
Packit a4058c
  info->disabled = FALSE;
Packit a4058c
}
Packit a4058c