Removed the unref_fn field. Now all memory management of the buffer is
1999-10-20 Federico Mena Quintero <federico@redhat.com> * src/gdk-pixbuf.h (GdkPixbuf): Removed the unref_fn field. Now all memory management of the buffer is done by libart. * src/gdk-pixbuf.c (gdk_pixbuf_unref): Do destruction here. Removed gdk_pixbuf_destroy, gdk_pixbuf_duplicate. * src/gdk-pixbuf-data.c (gdk_pixbuf_new_from_data): Implemented in terms of the libart functions. Removed the old code. * src/gdk-pixbuf-io.c (image_handler_load): Removed the save symbols. Saving will not be implemented in GdkPixbuf. * src/io-gif.c: Removed the saving stub. (image_load): Fixed memory management to fail gracefully if we run out of memory while loading the image. Close the gif file when we are done. This still needs more error handling for the DGif functions. * src/io-jpeg.c (image_load): Some robustness fixes. * src/io-png.c: Removed the saving stuff. (image_load): Some memory management fixes. * src/io-tiff.c (image_load): Ditto. * src/io-xpm.c (pixbuf_create_from_xpm): Ditto.
This commit is contained in:

committed by
Arturo Espinosa

parent
46da5c2bec
commit
7ef5dec32d
@ -185,7 +185,6 @@ static void
|
|||||||
expose_func (GtkWidget *drawing_area, GdkEventExpose *event, gpointer data)
|
expose_func (GtkWidget *drawing_area, GdkEventExpose *event, gpointer data)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
gint x1, y1, x2, y2;
|
|
||||||
|
|
||||||
pixbuf = (GdkPixbuf *)gtk_object_get_data(GTK_OBJECT(drawing_area), "pixbuf");
|
pixbuf = (GdkPixbuf *)gtk_object_get_data(GTK_OBJECT(drawing_area), "pixbuf");
|
||||||
|
|
||||||
@ -217,16 +216,17 @@ expose_func (GtkWidget *drawing_area, GdkEventExpose *event, gpointer data)
|
|||||||
static void
|
static void
|
||||||
config_func (GtkWidget *drawing_area, GdkEventConfigure *event, gpointer data)
|
config_func (GtkWidget *drawing_area, GdkEventConfigure *event, gpointer data)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf, *spb;
|
GdkPixbuf *pixbuf;
|
||||||
|
|
||||||
pixbuf = (GdkPixbuf *)gtk_object_get_data(GTK_OBJECT(drawing_area), "pixbuf");
|
pixbuf = (GdkPixbuf *)gtk_object_get_data(GTK_OBJECT(drawing_area), "pixbuf");
|
||||||
|
|
||||||
g_print("X:%d Y:%d\n", event->width, event->height);
|
g_print("X:%d Y:%d\n", event->width, event->height);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (((event->width) != (pixbuf->art_pixbuf->width)) ||
|
if (((event->width) != (pixbuf->art_pixbuf->width)) ||
|
||||||
((event->height) != (pixbuf->art_pixbuf->height)))
|
((event->height) != (pixbuf->art_pixbuf->height)))
|
||||||
gdk_pixbuf_scale(pixbuf, event->width, event->height);
|
gdk_pixbuf_scale(pixbuf, event->width, event->height);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -299,18 +299,18 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
pixbuf = gdk_pixbuf_load_image_from_rgb_d(default_image,
|
pixbuf = gdk_pixbuf_new_from_data ((guchar *) default_image, ART_PIX_RGB, FALSE,
|
||||||
DEFAULT_WIDTH,
|
DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_WIDTH * 3,
|
||||||
DEFAULT_HEIGHT);
|
NULL, NULL);
|
||||||
if (pixbuf) {
|
new_testrgb_window (pixbuf);
|
||||||
new_testrgb_window (pixbuf);
|
found_valid = TRUE;
|
||||||
found_valid = TRUE;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
pixbuf = gdk_pixbuf_load_image (argv[i]);
|
pixbuf = gdk_pixbuf_new_from_file (argv[i]);
|
||||||
|
#if 0
|
||||||
pixbuf = gdk_pixbuf_rotate(pixbuf, 10.0);
|
pixbuf = gdk_pixbuf_rotate(pixbuf, 10.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pixbuf) {
|
if (pixbuf) {
|
||||||
new_testrgb_window (pixbuf);
|
new_testrgb_window (pixbuf);
|
||||||
found_valid = TRUE;
|
found_valid = TRUE;
|
||||||
|
@ -1,3 +1,32 @@
|
|||||||
|
1999-10-20 Federico Mena Quintero <federico@redhat.com>
|
||||||
|
|
||||||
|
* src/gdk-pixbuf.h (GdkPixbuf): Removed the unref_fn field. Now
|
||||||
|
all memory management of the buffer is done by libart.
|
||||||
|
|
||||||
|
* src/gdk-pixbuf.c (gdk_pixbuf_unref): Do destruction here.
|
||||||
|
Removed gdk_pixbuf_destroy, gdk_pixbuf_duplicate.
|
||||||
|
|
||||||
|
* src/gdk-pixbuf-data.c (gdk_pixbuf_new_from_data): Implemented in
|
||||||
|
terms of the libart functions. Removed the old code.
|
||||||
|
|
||||||
|
* src/gdk-pixbuf-io.c (image_handler_load): Removed the save
|
||||||
|
symbols. Saving will not be implemented in GdkPixbuf.
|
||||||
|
|
||||||
|
* src/io-gif.c: Removed the saving stub.
|
||||||
|
(image_load): Fixed memory management to fail gracefully if we run
|
||||||
|
out of memory while loading the image. Close the gif file when we
|
||||||
|
are done. This still needs more error handling for the DGif
|
||||||
|
functions.
|
||||||
|
|
||||||
|
* src/io-jpeg.c (image_load): Some robustness fixes.
|
||||||
|
|
||||||
|
* src/io-png.c: Removed the saving stuff.
|
||||||
|
(image_load): Some memory management fixes.
|
||||||
|
|
||||||
|
* src/io-tiff.c (image_load): Ditto.
|
||||||
|
|
||||||
|
* src/io-xpm.c (pixbuf_create_from_xpm): Ditto.
|
||||||
|
|
||||||
1999-10-18 Havoc Pennington <hp@pobox.com>
|
1999-10-18 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
* subautogen.sh: New name for macros/autogen.sh
|
* subautogen.sh: New name for macros/autogen.sh
|
||||||
@ -6,7 +35,9 @@
|
|||||||
|
|
||||||
1999-10-18 Federico Mena Quintero <federico@redhat.com>
|
1999-10-18 Federico Mena Quintero <federico@redhat.com>
|
||||||
|
|
||||||
* src/*: Reindented to use the GNOME Indentation.
|
* src/*: Reindented to use the GNOME Indentation. Renamed
|
||||||
|
GdkPixBuf to GdkPixbuf, for consistency with the function names
|
||||||
|
(and it is also easier to type) :-)
|
||||||
|
|
||||||
1999-10-18 Havoc Pennington <hp@pobox.com>
|
1999-10-18 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
lib_LTLIBRARIES = \
|
lib_LTLIBRARIES = \
|
||||||
libgdk_pixbuf.la
|
libgdk_pixbuf.la
|
||||||
|
|
||||||
@ -49,8 +48,7 @@ libgdk_pixbuf_la_SOURCES = \
|
|||||||
gdk-pixbuf-data.c
|
gdk-pixbuf-data.c
|
||||||
|
|
||||||
libgdk_pixbufinclude_HEADERS = \
|
libgdk_pixbufinclude_HEADERS = \
|
||||||
gdk-pixbuf.h \
|
gdk-pixbuf.h
|
||||||
gdk-pixbuf-io.h
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# The PNG plugin.
|
# The PNG plugin.
|
||||||
|
@ -1,49 +1,69 @@
|
|||||||
/*
|
/* GdkPixbuf library - Image creation from in-memory buffers
|
||||||
* gdk-pixbuf-data.c: Code to load images into GdkPixbufs from constant data
|
|
||||||
*
|
*
|
||||||
* Author:
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
* Michael Fulbright (drmike@redhat.com)
|
*
|
||||||
* Copyright (C) 1999 Red Hat, Inc.
|
* Author: Federico Mena-Quintero <federico@gimp.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library 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
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
#include "gdk-pixbuf.h"
|
#include "gdk-pixbuf.h"
|
||||||
|
|
||||||
/* This function does all the work. */
|
|
||||||
|
|
||||||
static GdkPixbuf *
|
|
||||||
_pixbuf_create_from_rgb_d(unsigned char *data, int w, int h)
|
|
||||||
{
|
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
ArtPixBuf *art_pixbuf;
|
|
||||||
art_u8 *pixels;
|
|
||||||
|
|
||||||
pixels = art_alloc (w*h*3);
|
|
||||||
if (!pixels) {
|
|
||||||
g_warning ("RGBD: Cannot alloc ArtBuf");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (pixels, data, w*h*3);
|
|
||||||
|
|
||||||
art_pixbuf = art_pixbuf_new_rgb (pixels, w, h, (w*3));
|
|
||||||
pixbuf = gdk_pixbuf_new (art_pixbuf, NULL);
|
|
||||||
|
|
||||||
if (!pixbuf)
|
|
||||||
art_free (pixels);
|
|
||||||
|
|
||||||
return pixbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_pixbuf_new_from_data:
|
||||||
|
* @data: Image data in 8-bit/sample packed format.
|
||||||
|
* @format: Color format used for the data.
|
||||||
|
* @has_alpha: Whether the data has an opacity channel.
|
||||||
|
* @width: Width of the image in pixels.
|
||||||
|
* @height: Height of the image in pixels.
|
||||||
|
* @rowstride: Distance in bytes between rows.
|
||||||
|
* @dfunc: Function used to free the data when the pixbuf's reference count
|
||||||
|
* drops to zero, or NULL if the data should not be freed.
|
||||||
|
* @dfunc_data: Closure data to pass to the destroy notification function.
|
||||||
|
*
|
||||||
|
* Creates a new &GdkPixbuf out of in-memory RGB data.
|
||||||
|
*
|
||||||
|
* Return value: A newly-created &GdkPixbuf structure with a reference count of
|
||||||
|
* 1.
|
||||||
|
**/
|
||||||
GdkPixbuf *
|
GdkPixbuf *
|
||||||
gdk_pixbuf_load_image_from_rgb_d (unsigned char *data, int rgb_width, int rgb_height)
|
gdk_pixbuf_new_from_data (guchar *data, ArtPixFormat format, gboolean has_alpha,
|
||||||
|
int width, int height, int rowstride,
|
||||||
|
ArtDestroyNotify dfunc, gpointer dfunc_data)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (data != NULL, NULL);
|
ArtPixBuf *art_pixbuf;
|
||||||
|
|
||||||
return _pixbuf_create_from_rgb_d(data, rgb_width, rgb_height);
|
/* Only 8-bit/sample RGB buffers are supported for now */
|
||||||
|
|
||||||
|
g_return_val_if_fail (data != NULL, NULL);
|
||||||
|
g_return_val_if_fail (format == ART_PIX_RGB, NULL);
|
||||||
|
g_return_val_if_fail (width > 0, NULL);
|
||||||
|
g_return_val_if_fail (height > 0, NULL);
|
||||||
|
|
||||||
|
if (has_alpha)
|
||||||
|
art_pixbuf = art_pixbuf_new_rgba_dnotify (data, width, height, rowstride,
|
||||||
|
dfunc_data, dfunc);
|
||||||
|
else
|
||||||
|
art_pixbuf = art_pixbuf_new_rgb_dnotify (data, width, height, rowstride,
|
||||||
|
dfunc_data, dfunc);
|
||||||
|
|
||||||
|
g_assert (art_pixbuf != NULL);
|
||||||
|
|
||||||
|
return gdk_pixbuf_new_from_art_pixbuf (art_pixbuf);
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,36 @@
|
|||||||
/*
|
/* GdkPixbuf library - Main loading interface.
|
||||||
* gdk-pixbuf-io.c: Code to load images into GdkPixbufs
|
|
||||||
*
|
*
|
||||||
* Author:
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
* Miguel de Icaza (miguel@gnu.org)
|
*
|
||||||
|
* Authors: Miguel de Icaza <miguel@gnu.org>
|
||||||
|
* Federico Mena-Quintero <federico@gimp.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library 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
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <glib.h>
|
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
#include "gdk-pixbuf.h"
|
#include "gdk-pixbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
pixbuf_check_png (unsigned char *buffer, int size)
|
pixbuf_check_png (guchar *buffer, int size)
|
||||||
{
|
{
|
||||||
if (size < 28)
|
if (size < 28)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -32,7 +49,7 @@ pixbuf_check_png (unsigned char *buffer, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
pixbuf_check_jpeg (unsigned char *buffer, int size)
|
pixbuf_check_jpeg (guchar *buffer, int size)
|
||||||
{
|
{
|
||||||
if (size < 10)
|
if (size < 10)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -44,7 +61,7 @@ pixbuf_check_jpeg (unsigned char *buffer, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
pixbuf_check_tiff (unsigned char *buffer, int size)
|
pixbuf_check_tiff (guchar *buffer, int size)
|
||||||
{
|
{
|
||||||
if (size < 10)
|
if (size < 10)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -65,7 +82,7 @@ pixbuf_check_tiff (unsigned char *buffer, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
pixbuf_check_gif (unsigned char *buffer, int size)
|
pixbuf_check_gif (guchar *buffer, int size)
|
||||||
{
|
{
|
||||||
if (size < 20)
|
if (size < 20)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -77,7 +94,7 @@ pixbuf_check_gif (unsigned char *buffer, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
pixbuf_check_xpm (unsigned char *buffer, int size)
|
pixbuf_check_xpm (guchar *buffer, int size)
|
||||||
{
|
{
|
||||||
if (size < 20)
|
if (size < 20)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -89,7 +106,7 @@ pixbuf_check_xpm (unsigned char *buffer, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
pixbuf_check_bmp (unsigned char *buffer, int size)
|
pixbuf_check_bmp (guchar *buffer, int size)
|
||||||
{
|
{
|
||||||
if (size < 20)
|
if (size < 20)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -101,7 +118,7 @@ pixbuf_check_bmp (unsigned char *buffer, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
pixbuf_check_ppm (unsigned char *buffer, int size)
|
pixbuf_check_ppm (guchar *buffer, int size)
|
||||||
{
|
{
|
||||||
if (size < 20)
|
if (size < 20)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -119,20 +136,21 @@ pixbuf_check_ppm (unsigned char *buffer, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
char *module_name;
|
char *module_name;
|
||||||
gboolean (*format_check)(unsigned char *buffer, int size);
|
gboolean (* format_check) (guchar *buffer, int size);
|
||||||
GModule *module;
|
GModule *module;
|
||||||
GdkPixbuf *(*load)(FILE *f);
|
GdkPixbuf *(* load) (FILE *f);
|
||||||
int (*save)(GdkPixbuf *p, FILE *f, ...);
|
|
||||||
} file_formats [] = {
|
} file_formats [] = {
|
||||||
{ "png", pixbuf_check_png, NULL, NULL, NULL },
|
{ "png", pixbuf_check_png, NULL, NULL },
|
||||||
{ "jpeg", pixbuf_check_jpeg, NULL, NULL, NULL },
|
{ "jpeg", pixbuf_check_jpeg, NULL, NULL },
|
||||||
{ "tiff", pixbuf_check_tiff, NULL, NULL, NULL },
|
{ "tiff", pixbuf_check_tiff, NULL, NULL },
|
||||||
{ "gif", pixbuf_check_gif, NULL, NULL, NULL },
|
{ "gif", pixbuf_check_gif, NULL, NULL },
|
||||||
{ "xpm", pixbuf_check_xpm, NULL, NULL, NULL },
|
{ "xpm", pixbuf_check_xpm, NULL, NULL },
|
||||||
/* { "bmp", pixbuf_check_bmp, NULL, NULL, NULL },
|
#if 0
|
||||||
{ "ppm", pixbuf_check_ppm, NULL, NULL, NULL },*/
|
{ "bmp", pixbuf_check_bmp, NULL, NULL },
|
||||||
{ NULL, NULL, NULL, NULL, NULL }
|
{ "ppm", pixbuf_check_ppm, NULL, NULL },
|
||||||
|
#endif
|
||||||
|
{ NULL, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -141,10 +159,9 @@ image_handler_load (int idx)
|
|||||||
char *module_name;
|
char *module_name;
|
||||||
char *path;
|
char *path;
|
||||||
GModule *module;
|
GModule *module;
|
||||||
void *load_sym, *save_sym;
|
void *load_sym;
|
||||||
|
|
||||||
module_name = g_strconcat ("pixbuf-",
|
module_name = g_strconcat ("pixbuf-", file_formats [idx].module_name, NULL);
|
||||||
file_formats [idx].module_name, NULL);
|
|
||||||
path = g_module_build_path (PIXBUF_LIBDIR, module_name);
|
path = g_module_build_path (PIXBUF_LIBDIR, module_name);
|
||||||
g_free (module_name);
|
g_free (module_name);
|
||||||
|
|
||||||
@ -158,22 +175,22 @@ image_handler_load (int idx)
|
|||||||
|
|
||||||
if (g_module_symbol (module, "image_load", &load_sym))
|
if (g_module_symbol (module, "image_load", &load_sym))
|
||||||
file_formats [idx].load = load_sym;
|
file_formats [idx].load = load_sym;
|
||||||
|
|
||||||
if (g_module_symbol (module, "image_save", &save_sym))
|
|
||||||
file_formats [idx].save = save_sym;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GdkPixbuf *
|
GdkPixbuf *
|
||||||
gdk_pixbuf_load_image (const char *file)
|
gdk_pixbuf_new_from_file (const char *filename)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
gint n, i;
|
gint n, i;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char buffer [128];
|
char buffer [128];
|
||||||
|
|
||||||
f = fopen (file, "r");
|
f = fopen (filename, "r");
|
||||||
if (!f)
|
if (!f)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
n = fread (&buffer, 1, sizeof (buffer), f);
|
n = fread (&buffer, 1, sizeof (buffer), f);
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
@ -182,7 +199,7 @@ gdk_pixbuf_load_image (const char *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; file_formats [i].module_name; i++) {
|
for (i = 0; file_formats [i].module_name; i++) {
|
||||||
if ((*file_formats [i].format_check)(buffer, n)) {
|
if ((* file_formats [i].format_check) (buffer, n)) {
|
||||||
if (!file_formats [i].load)
|
if (!file_formats [i].load)
|
||||||
image_handler_load (i);
|
image_handler_load (i);
|
||||||
|
|
||||||
@ -191,15 +208,18 @@ gdk_pixbuf_load_image (const char *file)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek (f, 0, SEEK_SET);
|
||||||
pixbuf = (*file_formats [i].load)(f);
|
pixbuf = (* file_formats [i].load) (f);
|
||||||
fclose (f);
|
fclose (f);
|
||||||
g_assert (pixbuf->ref_count != 0);
|
|
||||||
|
if (pixbuf)
|
||||||
|
g_assert (pixbuf->ref_count != 0);
|
||||||
|
|
||||||
return pixbuf;
|
return pixbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose (f);
|
fclose (f);
|
||||||
g_warning ("Unable to find handler for file: %s", file);
|
g_warning ("Unable to find handler for file: %s", filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
95
gdk-pixbuf/gdk-pixbuf-xform.c
Normal file
95
gdk-pixbuf/gdk-pixbuf-xform.c
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
GdkPixbuf *
|
||||||
|
gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h)
|
||||||
|
{
|
||||||
|
art_u8 *pixels;
|
||||||
|
gint rowstride;
|
||||||
|
double affine[6];
|
||||||
|
ArtAlphaGamma *alphagamma;
|
||||||
|
ArtPixBuf *art_pixbuf = NULL;
|
||||||
|
GdkPixbuf *copy = NULL;
|
||||||
|
|
||||||
|
alphagamma = NULL;
|
||||||
|
|
||||||
|
affine[1] = affine[2] = affine[4] = affine[5] = 0;
|
||||||
|
|
||||||
|
affine[0] = w / (double)(pixbuf->art_pixbuf->width);
|
||||||
|
affine[3] = h / (double)(pixbuf->art_pixbuf->height);
|
||||||
|
|
||||||
|
/* rowstride = w * pixbuf->art_pixbuf->n_channels; */
|
||||||
|
rowstride = w * 3;
|
||||||
|
|
||||||
|
pixels = art_alloc (h * rowstride);
|
||||||
|
art_rgb_pixbuf_affine (pixels, 0, 0, w, h, rowstride,
|
||||||
|
pixbuf->art_pixbuf,
|
||||||
|
affine, ART_FILTER_NEAREST, alphagamma);
|
||||||
|
|
||||||
|
if (pixbuf->art_pixbuf->has_alpha)
|
||||||
|
/* should be rgba */
|
||||||
|
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
|
||||||
|
else
|
||||||
|
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
|
||||||
|
|
||||||
|
copy = gdk_pixbuf_new (art_pixbuf, NULL);
|
||||||
|
|
||||||
|
if (!copy)
|
||||||
|
art_free (pixels);
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
GdkPixbuf *
|
||||||
|
gdk_pixbuf_rotate (GdkPixbuf *pixbuf, gdouble angle)
|
||||||
|
{
|
||||||
|
art_u8 *pixels;
|
||||||
|
gint rowstride, w, h;
|
||||||
|
gdouble rad;
|
||||||
|
double rot[6], trans[6], affine[6];
|
||||||
|
ArtAlphaGamma *alphagamma = NULL;
|
||||||
|
ArtPixBuf *art_pixbuf = NULL;
|
||||||
|
|
||||||
|
w = pixbuf->art_pixbuf->width;
|
||||||
|
h = pixbuf->art_pixbuf->height;
|
||||||
|
|
||||||
|
rad = (M_PI * angle / 180.0);
|
||||||
|
|
||||||
|
rot[0] = cos(rad);
|
||||||
|
rot[1] = sin(rad);
|
||||||
|
rot[2] = -sin(rad);
|
||||||
|
rot[3] = cos(rad);
|
||||||
|
rot[4] = rot[5] = 0;
|
||||||
|
|
||||||
|
trans[0] = trans[3] = 1;
|
||||||
|
trans[1] = trans[2] = 0;
|
||||||
|
trans[4] = -(double)w / 2.0;
|
||||||
|
trans[5] = -(double)h / 2.0;
|
||||||
|
|
||||||
|
art_affine_multiply(rot, trans, rot);
|
||||||
|
|
||||||
|
trans[0] = trans[3] = 1;
|
||||||
|
trans[1] = trans[2] = 0;
|
||||||
|
trans[4] = (double)w / 2.0;
|
||||||
|
trans[5] = (double)h / 2.0;
|
||||||
|
|
||||||
|
art_affine_multiply(affine, rot, trans);
|
||||||
|
|
||||||
|
g_print("Affine: %e %e %e %e %e %e\n", affine[0], affine[1], affine[2],
|
||||||
|
affine[3], affine[4], affine[5]);
|
||||||
|
|
||||||
|
/* rowstride = w * pixbuf->art_pixbuf->n_channels; */
|
||||||
|
rowstride = w * 3;
|
||||||
|
|
||||||
|
pixels = art_alloc (h * rowstride);
|
||||||
|
art_rgb_pixbuf_affine (pixels, 0, 0, w, h, rowstride,
|
||||||
|
pixbuf->art_pixbuf,
|
||||||
|
affine, ART_FILTER_NEAREST, alphagamma);
|
||||||
|
if (pixbuf->art_pixbuf->has_alpha)
|
||||||
|
/* should be rgba */
|
||||||
|
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
|
||||||
|
else
|
||||||
|
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
|
||||||
|
|
||||||
|
art_pixbuf_free (pixbuf->art_pixbuf);
|
||||||
|
pixbuf->art_pixbuf = art_pixbuf;
|
||||||
|
|
||||||
|
return pixbuf;
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
/* GdkPixbuf library
|
/* GdkPixbuf library - Basic memory management
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 The Free Software Foundation
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
*
|
*
|
||||||
* Authors: Mark Crichton <crichton@gimp.org>
|
* Authors: Mark Crichton <crichton@gimp.org>
|
||||||
* Miguel de Icaza <miguel@gnu.org>
|
* Miguel de Icaza <miguel@gnu.org>
|
||||||
* Federico Mena-Quintero <federico@gimp.org>
|
* Federico Mena-Quintero <federico@gimp.org>
|
||||||
* Carsten Haitzler <raster@rasterman.com>
|
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -25,7 +24,6 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <glib.h>
|
|
||||||
#include <libart_lgpl/art_misc.h>
|
#include <libart_lgpl/art_misc.h>
|
||||||
#include <libart_lgpl/art_affine.h>
|
#include <libart_lgpl/art_affine.h>
|
||||||
#include <libart_lgpl/art_pixbuf.h>
|
#include <libart_lgpl/art_pixbuf.h>
|
||||||
@ -35,30 +33,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
/* Reference counting */
|
||||||
gdk_pixbuf_destroy (GdkPixbuf *pixbuf)
|
|
||||||
{
|
|
||||||
art_pixbuf_free (pixbuf->art_pixbuf);
|
|
||||||
pixbuf->art_pixbuf = NULL;
|
|
||||||
g_free (pixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
GdkPixbuf *
|
|
||||||
gdk_pixbuf_new (ArtPixBuf *art_pixbuf, GdkPixbufUnrefFunc *unref_fn)
|
|
||||||
{
|
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
|
|
||||||
if (!art_pixbuf)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
pixbuf = g_new (GdkPixbuf, 1);
|
|
||||||
pixbuf->ref_count = 1;
|
|
||||||
pixbuf->unref_fn = unref_fn;
|
|
||||||
pixbuf->art_pixbuf = art_pixbuf;
|
|
||||||
|
|
||||||
return pixbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_pixbuf_ref:
|
||||||
|
* @pixbuf: A pixbuf.
|
||||||
|
*
|
||||||
|
* Adds a reference to a pixbuf. It must be released afterwards using
|
||||||
|
* gdk_pixbuf_unref().
|
||||||
|
**/
|
||||||
void
|
void
|
||||||
gdk_pixbuf_ref (GdkPixbuf *pixbuf)
|
gdk_pixbuf_ref (GdkPixbuf *pixbuf)
|
||||||
{
|
{
|
||||||
@ -68,6 +51,13 @@ gdk_pixbuf_ref (GdkPixbuf *pixbuf)
|
|||||||
pixbuf->ref_count++;
|
pixbuf->ref_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_pixbuf_unref:
|
||||||
|
* @pixbuf: A pixbuf.
|
||||||
|
*
|
||||||
|
* Removes a reference from a pixbuf. It will be destroyed when the reference
|
||||||
|
* count drops to zero.
|
||||||
|
**/
|
||||||
void
|
void
|
||||||
gdk_pixbuf_unref (GdkPixbuf *pixbuf)
|
gdk_pixbuf_unref (GdkPixbuf *pixbuf)
|
||||||
{
|
{
|
||||||
@ -76,113 +66,35 @@ gdk_pixbuf_unref (GdkPixbuf *pixbuf)
|
|||||||
|
|
||||||
pixbuf->ref_count--;
|
pixbuf->ref_count--;
|
||||||
|
|
||||||
if (pixbuf->ref_count == 0)
|
if (pixbuf->ref_count == 0) {
|
||||||
gdk_pixbuf_destroy (pixbuf);
|
art_pixbuf_free (pixbuf->art_pixbuf);
|
||||||
|
pixbuf->art_pixbuf = NULL;
|
||||||
|
g_free (pixbuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Wrap a libart pixbuf */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_pixbuf_new_from_art_pixbuf:
|
||||||
|
* @art_pixbuf: A libart pixbuf.
|
||||||
|
*
|
||||||
|
* Creates a &GdkPixbuf by wrapping a libart pixbuf.
|
||||||
|
*
|
||||||
|
* Return value: A newly-created &GdkPixbuf structure with a reference count of
|
||||||
|
* 1.
|
||||||
|
**/
|
||||||
GdkPixbuf *
|
GdkPixbuf *
|
||||||
gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h)
|
gdk_pixbuf_new_from_art_pixbuf (ArtPixBuf *art_pixbuf)
|
||||||
{
|
{
|
||||||
art_u8 *pixels;
|
GdkPixbuf *pixbuf;
|
||||||
gint rowstride;
|
|
||||||
double affine[6];
|
|
||||||
ArtAlphaGamma *alphagamma;
|
|
||||||
ArtPixBuf *art_pixbuf = NULL;
|
|
||||||
GdkPixbuf *copy = NULL;
|
|
||||||
|
|
||||||
alphagamma = NULL;
|
g_return_val_if_fail (art_pixbuf != NULL, NULL);
|
||||||
|
|
||||||
affine[1] = affine[2] = affine[4] = affine[5] = 0;
|
pixbuf = g_new (GdkPixbuf, 1);
|
||||||
|
pixbuf->ref_count = 1;
|
||||||
affine[0] = w / (double)(pixbuf->art_pixbuf->width);
|
|
||||||
affine[3] = h / (double)(pixbuf->art_pixbuf->height);
|
|
||||||
|
|
||||||
/* rowstride = w * pixbuf->art_pixbuf->n_channels; */
|
|
||||||
rowstride = w * 3;
|
|
||||||
|
|
||||||
pixels = art_alloc (h * rowstride);
|
|
||||||
art_rgb_pixbuf_affine (pixels, 0, 0, w, h, rowstride,
|
|
||||||
pixbuf->art_pixbuf,
|
|
||||||
affine, ART_FILTER_NEAREST, alphagamma);
|
|
||||||
|
|
||||||
if (pixbuf->art_pixbuf->has_alpha)
|
|
||||||
/* should be rgba */
|
|
||||||
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
|
|
||||||
else
|
|
||||||
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
|
|
||||||
|
|
||||||
copy = gdk_pixbuf_new (art_pixbuf, NULL);
|
|
||||||
|
|
||||||
if (!copy)
|
|
||||||
art_free (pixels);
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
GdkPixbuf *
|
|
||||||
gdk_pixbuf_duplicate (const GdkPixbuf *pixbuf)
|
|
||||||
{
|
|
||||||
GdkPixbuf *copy = g_new (GdkPixbuf, 1);
|
|
||||||
|
|
||||||
copy->ref_count = 1;
|
|
||||||
copy->unref_fn = pixbuf->unref_fn;
|
|
||||||
copy->art_pixbuf = art_pixbuf_duplicate (pixbuf->art_pixbuf);
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
GdkPixbuf *
|
|
||||||
gdk_pixbuf_rotate (GdkPixbuf *pixbuf, gdouble angle)
|
|
||||||
{
|
|
||||||
art_u8 *pixels;
|
|
||||||
gint rowstride, w, h;
|
|
||||||
gdouble rad;
|
|
||||||
double rot[6], trans[6], affine[6];
|
|
||||||
ArtAlphaGamma *alphagamma = NULL;
|
|
||||||
ArtPixBuf *art_pixbuf = NULL;
|
|
||||||
|
|
||||||
w = pixbuf->art_pixbuf->width;
|
|
||||||
h = pixbuf->art_pixbuf->height;
|
|
||||||
|
|
||||||
rad = (M_PI * angle / 180.0);
|
|
||||||
|
|
||||||
rot[0] = cos(rad);
|
|
||||||
rot[1] = sin(rad);
|
|
||||||
rot[2] = -sin(rad);
|
|
||||||
rot[3] = cos(rad);
|
|
||||||
rot[4] = rot[5] = 0;
|
|
||||||
|
|
||||||
trans[0] = trans[3] = 1;
|
|
||||||
trans[1] = trans[2] = 0;
|
|
||||||
trans[4] = -(double)w / 2.0;
|
|
||||||
trans[5] = -(double)h / 2.0;
|
|
||||||
|
|
||||||
art_affine_multiply(rot, trans, rot);
|
|
||||||
|
|
||||||
trans[0] = trans[3] = 1;
|
|
||||||
trans[1] = trans[2] = 0;
|
|
||||||
trans[4] = (double)w / 2.0;
|
|
||||||
trans[5] = (double)h / 2.0;
|
|
||||||
|
|
||||||
art_affine_multiply(affine, rot, trans);
|
|
||||||
|
|
||||||
g_print("Affine: %e %e %e %e %e %e\n", affine[0], affine[1], affine[2],
|
|
||||||
affine[3], affine[4], affine[5]);
|
|
||||||
|
|
||||||
/* rowstride = w * pixbuf->art_pixbuf->n_channels; */
|
|
||||||
rowstride = w * 3;
|
|
||||||
|
|
||||||
pixels = art_alloc (h * rowstride);
|
|
||||||
art_rgb_pixbuf_affine (pixels, 0, 0, w, h, rowstride,
|
|
||||||
pixbuf->art_pixbuf,
|
|
||||||
affine, ART_FILTER_NEAREST, alphagamma);
|
|
||||||
if (pixbuf->art_pixbuf->has_alpha)
|
|
||||||
/* should be rgba */
|
|
||||||
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
|
|
||||||
else
|
|
||||||
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
|
|
||||||
|
|
||||||
art_pixbuf_free (pixbuf->art_pixbuf);
|
|
||||||
pixbuf->art_pixbuf = art_pixbuf;
|
pixbuf->art_pixbuf = art_pixbuf;
|
||||||
|
|
||||||
return pixbuf;
|
return pixbuf;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
/* GdkPixbuf library
|
/* GdkPixbuf library - Main header file
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 The Free Software Foundation
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
*
|
*
|
||||||
* Authors: Mark Crichton <crichton@gimp.org>
|
* Authors: Mark Crichton <crichton@gimp.org>
|
||||||
* Miguel de Icaza <miguel@gnu.org>
|
* Miguel de Icaza <miguel@gnu.org>
|
||||||
* Federico Mena-Quintero <federico@gimp.org>
|
* Federico Mena-Quintero <federico@gimp.org>
|
||||||
* Carsten Haitzler <raster@rasterman.com>
|
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -36,32 +35,41 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* GdkPixbuf structure */
|
||||||
|
|
||||||
typedef struct _GdkPixbuf GdkPixbuf;
|
typedef struct _GdkPixbuf GdkPixbuf;
|
||||||
typedef void (* GdkPixbufUnrefFunc) (GdkPixbuf *pixbuf);
|
|
||||||
|
|
||||||
struct _GdkPixbuf {
|
struct _GdkPixbuf {
|
||||||
|
/* Reference count */
|
||||||
int ref_count;
|
int ref_count;
|
||||||
|
|
||||||
|
/* Libart pixbuf */
|
||||||
ArtPixBuf *art_pixbuf;
|
ArtPixBuf *art_pixbuf;
|
||||||
GdkPixbufUnrefFunc *unref_fn;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GdkPixbuf *gdk_pixbuf_load_image (const char *file);
|
/* Reference counting */
|
||||||
void gdk_pixbuf_save_image (const char *format_id, const char *file, ...);
|
|
||||||
|
|
||||||
GdkPixbuf *gdk_pixbuf_new (ArtPixBuf *art_pixbuf, GdkPixbufUnrefFunc *unref_fn);
|
|
||||||
|
|
||||||
void gdk_pixbuf_ref (GdkPixbuf *pixbuf);
|
void gdk_pixbuf_ref (GdkPixbuf *pixbuf);
|
||||||
void gdk_pixbuf_unref (GdkPixbuf *pixbuf);
|
void gdk_pixbuf_unref (GdkPixbuf *pixbuf);
|
||||||
|
|
||||||
GdkPixbuf *gdk_pixbuf_duplicate (const GdkPixbuf *pixbuf);
|
/* Wrap a libart pixbuf */
|
||||||
|
|
||||||
|
GdkPixbuf *gdk_pixbuf_new_from_art_pixbuf (ArtPixBuf *art_pixbuf);
|
||||||
|
|
||||||
|
/* Simple loading */
|
||||||
|
|
||||||
|
GdkPixbuf *gdk_pixbuf_new_from_file (const char *filename);
|
||||||
|
GdkPixbuf *gdk_pixbuf_new_from_data (guchar *data, ArtPixFormat format, gboolean has_alpha,
|
||||||
|
int width, int height, int rowstride,
|
||||||
|
ArtDestroyNotify dfunc, gpointer dfunc_data);
|
||||||
|
|
||||||
|
/* Transformations */
|
||||||
|
#if 0
|
||||||
GdkPixbuf *gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h);
|
GdkPixbuf *gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h);
|
||||||
GdkPixbuf *gdk_pixbuf_rotate (GdkPixbuf *pixbuf, gdouble angle);
|
GdkPixbuf *gdk_pixbuf_rotate (GdkPixbuf *pixbuf, gdouble angle);
|
||||||
|
#endif
|
||||||
void gdk_pixbuf_destroy (GdkPixbuf *pixbuf);
|
|
||||||
|
|
||||||
GdkPixbuf *gdk_pixbuf_load_image_from_rgb_d (unsigned char *data, int rgb_width, int rgb_height);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
/*
|
/* GdkPixbuf library - GIF image loader
|
||||||
* io-gif.c: GdkPixbuf I/O for GIF files.
|
|
||||||
* ...second verse, same as the first...
|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 Mark Crichton
|
* Copyright (C) 1999 Mark Crichton
|
||||||
* Author: Mark Crichton <crichton@gimp.org>
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
|
*
|
||||||
|
* Authors: Mark Crichton <crichton@gimp.org>
|
||||||
|
* Federico Mena-Quintero <federico@gimp.org>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -16,162 +17,169 @@
|
|||||||
* Library General Public License for more details.
|
* Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Library General Public
|
* You should have received a copy of the GNU Library General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
*
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "gdk-pixbuf.h"
|
|
||||||
#include "gdk-pixbuf-io.h"
|
|
||||||
#include <gif_lib.h>
|
#include <gif_lib.h>
|
||||||
|
#include "gdk-pixbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Destroy notification function for the libart pixbuf */
|
||||||
|
static void
|
||||||
|
free_buffer (gpointer user_data, gpointer data)
|
||||||
|
{
|
||||||
|
free (data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Shared library entry point */
|
/* Shared library entry point */
|
||||||
GdkPixbuf *
|
GdkPixbuf *
|
||||||
image_load(FILE *f)
|
image_load (FILE *f)
|
||||||
{
|
{
|
||||||
gint fn, is_trans = FALSE;
|
gint fn, is_trans = FALSE;
|
||||||
gint done = 0;
|
gint done = 0;
|
||||||
gint t_color = -1;
|
gint t_color = -1;
|
||||||
gint w, h, i, j;
|
gint w, h, i, j;
|
||||||
art_u8 *pixels, *tmpptr;
|
guchar *pixels, *tmpptr;
|
||||||
GifFileType *gif;
|
GifFileType *gif;
|
||||||
GifRowType *rows;
|
GifRowType *rows;
|
||||||
GifRecordType rec;
|
GifRecordType rec;
|
||||||
ColorMapObject *cmap;
|
ColorMapObject *cmap;
|
||||||
int intoffset[] =
|
int intoffset[] = { 0, 4, 2, 1 };
|
||||||
{0, 4, 2, 1};
|
int intjump[] = { 8, 8, 4, 2 };
|
||||||
int intjump[] =
|
|
||||||
{8, 8, 4, 2};
|
|
||||||
|
|
||||||
GdkPixbuf *pixbuf;
|
fn = fileno (f);
|
||||||
ArtPixBuf *art_pixbuf;
|
gif = DGifOpenFileHandle (fn);
|
||||||
|
|
||||||
g_return_val_if_fail(f != NULL, NULL);
|
|
||||||
|
|
||||||
fn = fileno(f);
|
|
||||||
/* lseek(fn, 0, 0);*/
|
|
||||||
gif = DGifOpenFileHandle(fn);
|
|
||||||
|
|
||||||
if (!gif) {
|
if (!gif) {
|
||||||
g_error("DGifOpenFilehandle FAILED");
|
g_warning ("DGifOpenFilehandle FAILED");
|
||||||
PrintGifError();
|
PrintGifError ();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Now we do the ungodly mess of loading a GIF image
|
|
||||||
* I used to remember when I liked this file format...
|
/* Now we do the ungodly mess of loading a GIF image I used to remember
|
||||||
* of course, I still coded in assembler then.
|
* when I liked this file format... of course, I still coded in
|
||||||
* This comes from gdk_imlib, with some cleanups.
|
* assembler then. This comes from gdk_imlib, with some cleanups.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
|
if (DGifGetRecordType (gif, &rec) == GIF_ERROR) {
|
||||||
PrintGifError();
|
PrintGifError ();
|
||||||
rec = TERMINATE_RECORD_TYPE;
|
DGifCloseFile (gif);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done)) {
|
|
||||||
if (DGifGetImageDesc(gif) == GIF_ERROR) {
|
if (rec == IMAGE_DESC_RECORD_TYPE && !done) {
|
||||||
PrintGifError();
|
if (DGifGetImageDesc (gif) == GIF_ERROR) {
|
||||||
rec = TERMINATE_RECORD_TYPE;
|
PrintGifError ();
|
||||||
}
|
DGifCloseFile (gif);
|
||||||
w = gif->Image.Width;
|
|
||||||
h = gif->Image.Height;
|
|
||||||
rows = g_malloc0(h * sizeof(GifRowType *));
|
|
||||||
if (!rows) {
|
|
||||||
DGifCloseFile(gif);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note the careful use of malloc/calloc vs. g_malloc;
|
||||||
|
* we want to fail gracefully if we run out of memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
w = gif->Image.Width;
|
||||||
|
h = gif->Image.Height;
|
||||||
|
rows = calloc (sizeof (GifRowType *), h);
|
||||||
|
if (!rows) {
|
||||||
|
DGifCloseFile (gif);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < h; i++) {
|
for (i = 0; i < h; i++) {
|
||||||
rows[i] = g_malloc0(w * sizeof(GifPixelType));
|
rows[i] = calloc (sizeof (GifPixelType), w);
|
||||||
if (!rows[i]) {
|
if (!rows[i]) {
|
||||||
DGifCloseFile(gif);
|
DGifCloseFile (gif);
|
||||||
for (i = 0; i < h; i++)
|
for (j = 0; j < h; j++)
|
||||||
if (rows[i])
|
if (rows[j])
|
||||||
g_free(rows[i]);
|
free (rows[j]);
|
||||||
free(rows);
|
|
||||||
|
free (rows);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gif->Image.Interlace) {
|
|
||||||
|
if (gif->Image.Interlace)
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
for (j = intoffset[i]; j < h; j += intjump[i])
|
for (j = intoffset[i]; j < h; j += intjump[i])
|
||||||
DGifGetLine(gif, rows[j], w);
|
DGifGetLine (gif, rows[j], w);
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
for (i = 0; i < h; i++)
|
for (i = 0; i < h; i++)
|
||||||
DGifGetLine(gif, rows[i], w);
|
DGifGetLine (gif, rows[i], w);
|
||||||
}
|
|
||||||
done = 1;
|
done = 1;
|
||||||
} else if (rec == EXTENSION_RECORD_TYPE) {
|
} else if (rec == EXTENSION_RECORD_TYPE) {
|
||||||
gint ext_code;
|
gint ext_code;
|
||||||
GifByteType *ext;
|
GifByteType *ext;
|
||||||
|
|
||||||
DGifGetExtension(gif, &ext_code, &ext);
|
DGifGetExtension (gif, &ext_code, &ext);
|
||||||
while (ext) {
|
while (ext) {
|
||||||
if ((ext_code == 0xf9) &&
|
if ((ext_code == 0xf9) && (ext[1] & 1) && (t_color < 0)) {
|
||||||
(ext[1] & 1) && (t_color < 0)) {
|
|
||||||
is_trans = TRUE;
|
is_trans = TRUE;
|
||||||
t_color = (gint) ext[4];
|
t_color = (gint) ext[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
ext = NULL;
|
ext = NULL;
|
||||||
DGifGetExtensionNext(gif, &ext);
|
DGifGetExtensionNext (gif, &ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} while (rec != TERMINATE_RECORD_TYPE);
|
||||||
while (rec != TERMINATE_RECORD_TYPE);
|
|
||||||
|
|
||||||
/* Ok, we're loaded, now to convert from indexed -> RGB
|
/* Ok, we're loaded, now to convert from indexed -> RGB with alpha if necessary */
|
||||||
* with alpha if necessary
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (is_trans)
|
if (is_trans)
|
||||||
pixels = art_alloc(h * w * 4);
|
pixels = malloc (h * w * 4);
|
||||||
else
|
else
|
||||||
pixels = art_alloc(h * w * 3);
|
pixels = malloc (h * w * 3);
|
||||||
|
|
||||||
tmpptr = pixels;
|
tmpptr = pixels;
|
||||||
|
|
||||||
if (!pixels)
|
if (!pixels) {
|
||||||
return NULL;
|
DGifCloseFile (gif);
|
||||||
|
for (i = 0; i < h; i++)
|
||||||
|
if (rows[i])
|
||||||
|
free (rows[i]);
|
||||||
|
|
||||||
|
free (rows);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* The meat of the transformation */
|
|
||||||
/* Get the right palette */
|
|
||||||
cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
|
cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
|
||||||
|
|
||||||
/* Unindex the data, and pack it in RGB(A) order.
|
/* Unindex the data, and pack it in RGB(A) order */
|
||||||
* Note for transparent GIFs, the alpha is set to 0
|
|
||||||
* for the transparent color, and 0xFF for everything else.
|
|
||||||
* I think that's right...
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = 0; i < h; i++) {
|
for (i = 0; i < h; i++) {
|
||||||
for (j = 0; j < w; j++) {
|
for (j = 0; j < w; j++) {
|
||||||
tmpptr[0] = cmap->Colors[rows[i][j]].Red;
|
tmpptr[0] = cmap->Colors[rows[i][j]].Red;
|
||||||
tmpptr[1] = cmap->Colors[rows[i][j]].Green;
|
tmpptr[1] = cmap->Colors[rows[i][j]].Green;
|
||||||
tmpptr[2] = cmap->Colors[rows[i][j]].Blue;
|
tmpptr[2] = cmap->Colors[rows[i][j]].Blue;
|
||||||
if (is_trans && (rows[i][j] == t_color))
|
|
||||||
tmpptr[3] = 0;
|
if (is_trans) {
|
||||||
else
|
if (rows[i][j] == t_color)
|
||||||
tmpptr[3] = 0xFF;
|
tmpptr[3] = 0;
|
||||||
tmpptr += (is_trans ? 4 : 3);
|
else
|
||||||
|
tmpptr[3] = 0xFF;
|
||||||
|
|
||||||
|
tmpptr += 4;
|
||||||
|
} else
|
||||||
|
tmpptr += 3;
|
||||||
}
|
}
|
||||||
g_free(rows[i]);
|
|
||||||
|
free (rows[i]);
|
||||||
}
|
}
|
||||||
g_free(rows);
|
|
||||||
|
|
||||||
if (is_trans)
|
free (rows);
|
||||||
art_pixbuf = art_pixbuf_new_rgba(pixels, w, h, (w * 4));
|
DGifCloseFile (gif);
|
||||||
else
|
|
||||||
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
|
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new (art_pixbuf, NULL);
|
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, is_trans,
|
||||||
|
w, h, is_trans ? (w * 4) : (w * 3),
|
||||||
/* Ok, I'm anal...shoot me */
|
free_buffer, NULL);
|
||||||
if (!pixbuf)
|
|
||||||
art_free(pixels);
|
|
||||||
|
|
||||||
return pixbuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
image_save() {}
|
|
||||||
|
@ -1,129 +1,144 @@
|
|||||||
/*
|
/* GdkPixbuf library - JPEG image loader
|
||||||
io-jpeg.c: GdkPixbuf loader for jpeg files.
|
*
|
||||||
|
* Copyright (C) 1999 Michael Zucchi
|
||||||
Based on io-jpeg from gdk_imlib, but not much.
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
|
*
|
||||||
This code is licensed under the Lesser GNU
|
* Authors: Michael Zucchi <zucchi@zedzone.mmc.com.au>
|
||||||
General Public License, version 2.1.
|
* Federico Mena-Quintero <federico@gimp.org>
|
||||||
|
*
|
||||||
Author:
|
* This library is free software; you can redistribute it and/or
|
||||||
Michael Zucchi <zucchi@zedzone.mmc.com.au>
|
* modify it under the terms of the GNU Library 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
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library 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.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <glib.h>
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include "gdk-pixbuf.h"
|
|
||||||
/*#include "gdk-pixbuf-io.h"*/
|
|
||||||
#include <jpeglib.h>
|
#include <jpeglib.h>
|
||||||
|
#include "gdk-pixbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* error handler data */
|
/* error handler data */
|
||||||
struct iojpeg_JPEG_error_mgr {
|
struct error_handler_data {
|
||||||
struct jpeg_error_mgr pub;
|
struct jpeg_error_mgr pub;
|
||||||
sigjmp_buf setjmp_buffer;
|
sigjmp_buf setjmp_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_JPEGFatalErrorHandler(j_common_ptr cinfo)
|
fatal_error_handler (j_common_ptr cinfo)
|
||||||
{
|
{
|
||||||
/* FIXME:
|
/* FIXME:
|
||||||
* We should somehow signal what error occurred to the caller so the
|
* We should somehow signal what error occurred to the caller so the
|
||||||
* caller can handle the error message */
|
* caller can handle the error message */
|
||||||
struct iojpeg_JPEG_error_mgr *errmgr;
|
struct error_handler_data *errmgr;
|
||||||
|
|
||||||
errmgr = (struct iojpeg_JPEG_error_mgr *) cinfo->err;
|
errmgr = (struct error_handler_data *) cinfo->err;
|
||||||
cinfo->err->output_message(cinfo);
|
cinfo->err->output_message (cinfo);
|
||||||
siglongjmp(errmgr->setjmp_buffer, 1);
|
siglongjmp (errmgr->setjmp_buffer, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkPixbuf *
|
/* Destroy notification function for the libart pixbuf */
|
||||||
image_load(FILE *f)
|
static void
|
||||||
|
free_buffer (gpointer user_data, gpointer data)
|
||||||
{
|
{
|
||||||
int w,h,i,j;
|
free (data);
|
||||||
art_u8 *pixels=NULL, *dptr;
|
}
|
||||||
unsigned char *lines[4], /* Used to expand rows, via rec_outbuf_height, from
|
|
||||||
the header file:
|
/* Shared library entry point */
|
||||||
"* Usually rec_outbuf_height will be 1 or 2, at most 4." */
|
GdkPixbuf *
|
||||||
**lptr;
|
image_load (FILE *f)
|
||||||
|
{
|
||||||
|
int w, h, i, j;
|
||||||
|
guchar *pixels = NULL, *dptr;
|
||||||
|
guchar *lines[4]; /* Used to expand rows, via rec_outbuf_height, from the header file:
|
||||||
|
* "* Usually rec_outbuf_height will be 1 or 2, at most 4."
|
||||||
|
*/
|
||||||
|
guchar **lptr;
|
||||||
struct jpeg_decompress_struct cinfo;
|
struct jpeg_decompress_struct cinfo;
|
||||||
struct iojpeg_JPEG_error_mgr jerr;
|
struct error_handler_data jerr;
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
|
|
||||||
/* setup error handler */
|
/* setup error handler */
|
||||||
cinfo.err = jpeg_std_error(&(jerr.pub));
|
cinfo.err = jpeg_std_error (&jerr.pub);
|
||||||
jerr.pub.error_exit = g_JPEGFatalErrorHandler;
|
jerr.pub.error_exit = fatal_error_handler;
|
||||||
|
|
||||||
if (sigsetjmp(jerr.setjmp_buffer, 1)) {
|
if (sigsetjmp (jerr.setjmp_buffer, 1)) {
|
||||||
/* Whoops there was a jpeg error */
|
/* Whoops there was a jpeg error */
|
||||||
if (pixels != NULL)
|
if (pixels)
|
||||||
art_free(pixels);
|
free (pixels);
|
||||||
jpeg_destroy_decompress(&cinfo);
|
|
||||||
|
jpeg_destroy_decompress (&cinfo);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load header, setup */
|
/* load header, setup */
|
||||||
jpeg_create_decompress(&cinfo);
|
jpeg_create_decompress (&cinfo);
|
||||||
jpeg_stdio_src(&cinfo, f);
|
jpeg_stdio_src (&cinfo, f);
|
||||||
jpeg_read_header(&cinfo, TRUE);
|
jpeg_read_header (&cinfo, TRUE);
|
||||||
jpeg_start_decompress(&cinfo);
|
jpeg_start_decompress (&cinfo);
|
||||||
cinfo.do_fancy_upsampling = FALSE;
|
cinfo.do_fancy_upsampling = FALSE;
|
||||||
cinfo.do_block_smoothing = FALSE;
|
cinfo.do_block_smoothing = FALSE;
|
||||||
|
|
||||||
w = cinfo.output_width;
|
w = cinfo.output_width;
|
||||||
h = cinfo.output_height;
|
h = cinfo.output_height;
|
||||||
g_print("w: %d h: %d\n", w, h);
|
|
||||||
|
|
||||||
pixels = art_alloc(h * w * 3);
|
pixels = malloc (h * w * 3);
|
||||||
if (pixels == NULL) {
|
if (!pixels) {
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress (&cinfo);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dptr = pixels;
|
dptr = pixels;
|
||||||
|
|
||||||
/* decompress all the lines, a few at a time */
|
/* decompress all the lines, a few at a time */
|
||||||
|
|
||||||
while (cinfo.output_scanline < cinfo.output_height) {
|
while (cinfo.output_scanline < cinfo.output_height) {
|
||||||
lptr = lines;
|
lptr = lines;
|
||||||
for (i=0;i<cinfo.rec_outbuf_height;i++) {
|
for (i = 0; i < cinfo.rec_outbuf_height; i++) {
|
||||||
*lptr++=dptr;
|
*lptr++ = dptr;
|
||||||
dptr+=w*3;
|
dptr += w * 3;
|
||||||
}
|
}
|
||||||
jpeg_read_scanlines(&cinfo, lines, cinfo.rec_outbuf_height);
|
|
||||||
if (cinfo.output_components==1) {
|
jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);
|
||||||
/* expand grey->colour */
|
if (cinfo.output_components == 1) {
|
||||||
/* expand from the end of the memory down, so we can use
|
/* Expand grey->colour. Expand from the end of the
|
||||||
the same buffer */
|
* memory down, so we can use the same buffer.
|
||||||
for (i=cinfo.rec_outbuf_height-1;i>=0;i--) {
|
*/
|
||||||
unsigned char *from, *to;
|
for (i = cinfo.rec_outbuf_height - 1; i >= 0; i--) {
|
||||||
from = lines[i]+w-1;
|
guchar *from, *to;
|
||||||
to = lines[i]+w*3-3;
|
|
||||||
for (j=w-1;j>=0;j--) {
|
from = lines[i] + w - 1;
|
||||||
|
to = lines[i] + w * 3 - 3;
|
||||||
|
for (j = w - 1; j >= 0; j--) {
|
||||||
to[0] = from[0];
|
to[0] = from[0];
|
||||||
to[1] = from[0];
|
to[1] = from[0];
|
||||||
to[2] = from[0];
|
to[2] = from[0];
|
||||||
to-=3;
|
to -= 3;
|
||||||
from--;
|
from--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jpeg_finish_decompress(&cinfo);
|
jpeg_finish_decompress (&cinfo);
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress (&cinfo);
|
||||||
|
|
||||||
|
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, FALSE,
|
||||||
|
w, h, w * 3,
|
||||||
|
free_buffer, NULL);
|
||||||
|
|
||||||
/* finish off, create the pixbuf */
|
|
||||||
pixbuf = gdk_pixbuf_new (art_pixbuf_new_rgb (pixels, w, h, (w * 3)),
|
|
||||||
NULL);
|
|
||||||
if (!pixbuf)
|
|
||||||
art_free (pixels);
|
|
||||||
|
|
||||||
return pixbuf;
|
return pixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Local variables:
|
|
||||||
* c-basic-offset: 8
|
|
||||||
* End:
|
|
||||||
*/
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
/*
|
/* GdkPixbuf library - JPEG image loader
|
||||||
* io-png.c: GdkPixbuf I/O for PNG files.
|
*
|
||||||
* Copyright (C) 1999 Mark Crichton
|
* Copyright (C) 1999 Mark Crichton
|
||||||
* Author: Mark Crichton <crichton@gimp.org>
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
|
*
|
||||||
|
* Authors: Mark Crichton <crichton@gimp.org>
|
||||||
|
* Federico Mena-Quintero <federico@gimp.org>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -14,16 +17,24 @@
|
|||||||
* Library General Public License for more details.
|
* Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Library General Public
|
* You should have received a copy of the GNU Library General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
*
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <glib.h>
|
|
||||||
#include "gdk-pixbuf.h"
|
|
||||||
#include "gdk-pixbuf-io.h"
|
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
#include "gdk-pixbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Destroy notification function for the libart pixbuf */
|
||||||
|
static void
|
||||||
|
free_buffer (gpointer user_data, gpointer data)
|
||||||
|
{
|
||||||
|
free (data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Shared library entry point */
|
/* Shared library entry point */
|
||||||
GdkPixbuf *
|
GdkPixbuf *
|
||||||
@ -31,17 +42,12 @@ image_load (FILE *f)
|
|||||||
{
|
{
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr, end_info;
|
png_infop info_ptr, end_info;
|
||||||
gint i, depth, ctype, inttype, passes, bpp; /* bpp = BYTES/pixel */
|
gint i, depth, ctype, inttype, passes, bpp;
|
||||||
png_uint_32 w, h, x, y;
|
png_uint_32 w, h, x, y;
|
||||||
png_bytepp rows;
|
png_bytepp rows;
|
||||||
art_u8 *pixels, *temp, *rowdata;
|
guchar *pixels, *temp, *rowdata;
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
ArtPixBuf *art_pixbuf;
|
|
||||||
|
|
||||||
g_return_val_if_fail (f != NULL, NULL);
|
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
|
|
||||||
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
if (!png_ptr)
|
if (!png_ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -62,10 +68,9 @@ image_load (FILE *f)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
png_init_io (png_ptr, f);
|
png_init_io (png_ptr, f);
|
||||||
png_read_info (png_ptr, info_ptr);
|
png_read_info (png_ptr, info_ptr);
|
||||||
png_get_IHDR (png_ptr, info_ptr, &w, &h, &depth, &ctype, &inttype,
|
png_get_IHDR (png_ptr, info_ptr, &w, &h, &depth, &ctype, &inttype, NULL, NULL);
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
/* Ok, we want to work with 24 bit images.
|
/* Ok, we want to work with 24 bit images.
|
||||||
* However, PNG can vary depth per channel.
|
* However, PNG can vary depth per channel.
|
||||||
@ -108,21 +113,30 @@ image_load (FILE *f)
|
|||||||
else
|
else
|
||||||
bpp = 3;
|
bpp = 3;
|
||||||
|
|
||||||
pixels = art_alloc (w * h * bpp);
|
pixels = malloc (w * h * bpp);
|
||||||
rows = g_malloc (h * sizeof(png_bytep));
|
rows = malloc (h * sizeof (png_bytep));
|
||||||
|
|
||||||
if (!pixels || !rows) {
|
if (!pixels || !rows) {
|
||||||
|
if (pixels)
|
||||||
|
free (pixels);
|
||||||
|
|
||||||
|
if (rows)
|
||||||
|
free (rows);
|
||||||
|
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
|
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Icky code, but it has to be done... */
|
/* Icky code, but it has to be done... */
|
||||||
for (i = 0; i < h; i++) {
|
for (i = 0; i < h; i++) {
|
||||||
if ((rows[i] = g_malloc (w * sizeof (art_u8) * bpp)) == NULL) {
|
if ((rows[i] = malloc (w * bpp)) == NULL) {
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
for (n = 0; n < i; n++)
|
for (n = 0; n < i; n++)
|
||||||
g_free (rows[i]);
|
free (rows[i]);
|
||||||
g_free (rows);
|
|
||||||
art_free (pixels);
|
free (rows);
|
||||||
|
free (pixels);
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
|
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -137,105 +151,27 @@ image_load (FILE *f)
|
|||||||
temp = pixels;
|
temp = pixels;
|
||||||
|
|
||||||
for (y = 0; y < h; y++) {
|
for (y = 0; y < h; y++) {
|
||||||
(png_bytep) rowdata = rows[y];
|
rowdata = rows[y];
|
||||||
for (x = 0; x < w; x++) {
|
for (x = 0; x < w; x++) {
|
||||||
temp[0] = rowdata[(x * bpp)];
|
temp[0] = rowdata[(x * bpp)];
|
||||||
temp[1] = rowdata[(x * bpp) + 1];
|
temp[1] = rowdata[(x * bpp) + 1];
|
||||||
temp[2] = rowdata[(x * bpp) + 2];
|
temp[2] = rowdata[(x * bpp) + 2];
|
||||||
|
|
||||||
if (bpp == 4)
|
if (bpp == 4)
|
||||||
temp[3] = rowdata[(x * bpp) + 3];
|
temp[3] = rowdata[(x * bpp) + 3];
|
||||||
|
|
||||||
temp += bpp;
|
temp += bpp;
|
||||||
}
|
}
|
||||||
g_free (rows[y]);
|
free (rows[y]);
|
||||||
}
|
}
|
||||||
g_free (rows);
|
free (rows);
|
||||||
|
|
||||||
if (ctype & PNG_COLOR_MASK_ALPHA)
|
if (ctype & PNG_COLOR_MASK_ALPHA)
|
||||||
art_pixbuf = art_pixbuf_new_rgba (pixels, w, h, (w * 4));
|
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, TRUE,
|
||||||
|
w, h, w * 4,
|
||||||
|
free_buffer, NULL);
|
||||||
else
|
else
|
||||||
art_pixbuf = art_pixbuf_new_rgb (pixels, w, h, (w * 3));
|
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, FALSE,
|
||||||
|
w, h, w * 3,
|
||||||
pixbuf = gdk_pixbuf_new (art_pixbuf, NULL);
|
free_buffer, NULL);
|
||||||
|
|
||||||
if (!pixbuf)
|
|
||||||
art_free (pixels);
|
|
||||||
|
|
||||||
return pixbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
image_save (GdkPixbuf *pixbuf, FILE *file)
|
|
||||||
{
|
|
||||||
png_structp png_ptr;
|
|
||||||
png_infop info_ptr;
|
|
||||||
art_u8 *data;
|
|
||||||
gint y, h, w;
|
|
||||||
png_bytepp row_ptr;
|
|
||||||
png_color_8 sig_bit;
|
|
||||||
gint type;
|
|
||||||
|
|
||||||
g_return_val_if_fail(file != NULL, FALSE);
|
|
||||||
g_return_val_if_fail(pixbuf != NULL, FALSE);
|
|
||||||
|
|
||||||
h = pixbuf->art_pixbuf->height;
|
|
||||||
w = pixbuf->art_pixbuf->width;
|
|
||||||
|
|
||||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
if (png_ptr == NULL) {
|
|
||||||
fclose(file);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
info_ptr = png_create_info_struct(png_ptr);
|
|
||||||
if (info_ptr == NULL) {
|
|
||||||
fclose(file);
|
|
||||||
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setjmp(png_ptr->jmpbuf)) {
|
|
||||||
fclose(file);
|
|
||||||
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
png_init_io(png_ptr, file);
|
|
||||||
if (pixbuf->art_pixbuf->has_alpha) {
|
|
||||||
sig_bit.alpha = 8;
|
|
||||||
type = PNG_COLOR_TYPE_RGB_ALPHA;
|
|
||||||
} else {
|
|
||||||
sig_bit.alpha = 0;
|
|
||||||
type = PNG_COLOR_TYPE_RGB;
|
|
||||||
}
|
|
||||||
|
|
||||||
sig_bit.red = sig_bit.green = sig_bit.blue = 8;
|
|
||||||
png_set_IHDR(png_ptr, info_ptr, w, h, 8, type, PNG_INTERLACE_NONE,
|
|
||||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
|
||||||
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
|
||||||
png_write_info(png_ptr, info_ptr);
|
|
||||||
png_set_shift(png_ptr, &sig_bit);
|
|
||||||
png_set_packing(png_ptr);
|
|
||||||
|
|
||||||
data = pixbuf->art_pixbuf->pixels;
|
|
||||||
row_ptr = g_new(png_byte *, h);
|
|
||||||
|
|
||||||
for (y = 0; y < h; y++)
|
|
||||||
row_ptr[y] = data + y * pixbuf->art_pixbuf->rowstride;
|
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
if (pixbuf->art_pixbuf->has_alpha)
|
|
||||||
row_ptr[y] = data + (w * y * 4);
|
|
||||||
else
|
|
||||||
row_ptr[y] = data + (w * y * 3);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_write_image(png_ptr, row_ptr);
|
|
||||||
g_free (row_ptr);
|
|
||||||
|
|
||||||
png_write_end(png_ptr, info_ptr);
|
|
||||||
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
/*
|
/* GdkPixbuf library - JPEG image loader
|
||||||
* io-tiff.c: GdkPixbuf I/O for TIFF files.
|
*
|
||||||
* Copyright (C) 1999 Mark Crichton
|
* Copyright (C) 1999 Mark Crichton
|
||||||
* Author: Mark Crichton <crichton@gimp.org>
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
|
*
|
||||||
|
* Authors: Mark Crichton <crichton@gimp.org>
|
||||||
|
* Federico Mena-Quintero <federico@gimp.org>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -14,56 +17,59 @@
|
|||||||
* Library General Public License for more details.
|
* Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Library General Public
|
* You should have received a copy of the GNU Library General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
*
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Following code (almost) blatantly ripped from Imlib */
|
/* Following code (almost) blatantly ripped from Imlib */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <glib.h>
|
|
||||||
#include <tiffio.h>
|
#include <tiffio.h>
|
||||||
|
|
||||||
#include "gdk-pixbuf.h"
|
#include "gdk-pixbuf.h"
|
||||||
/*#include "gdk-pixbuf-io.h" */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Destroy notification function for the libart pixbuf */
|
||||||
|
static void
|
||||||
|
free_buffer (gpointer user_data, gpointer data)
|
||||||
|
{
|
||||||
|
free (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shared library entry point */
|
||||||
GdkPixbuf *
|
GdkPixbuf *
|
||||||
image_load (FILE *f)
|
image_load (FILE *f)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
TIFF *tiff;
|
TIFF *tiff;
|
||||||
art_u8 *pixels, *tmppix;
|
guchar *pixels, *tmppix;
|
||||||
gint w, h, x, y, num_pixs, fd;
|
gint w, h, x, y, num_pixs, fd;
|
||||||
uint32 *rast, *tmp_rast;
|
uint32 *rast, *tmp_rast;
|
||||||
|
|
||||||
g_return_val_if_fail(f != NULL, NULL);
|
fd = fileno (f);
|
||||||
|
tiff = TIFFFdOpen (fd, "libpixbuf-tiff", "r");
|
||||||
fd = fileno(f);
|
|
||||||
tiff = TIFFFdOpen(fd, "libpixbuf-tiff", "r");
|
|
||||||
|
|
||||||
if (!tiff)
|
if (!tiff)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
|
TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &w);
|
||||||
TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
|
TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &h);
|
||||||
num_pixs = w * h;
|
num_pixs = w * h;
|
||||||
|
|
||||||
/* Yes, it needs to be _TIFFMalloc... */
|
/* Yes, it needs to be _TIFFMalloc... */
|
||||||
rast = (uint32 *) _TIFFmalloc(num_pixs * sizeof(uint32));
|
rast = (uint32 *) _TIFFmalloc (num_pixs * sizeof (uint32));
|
||||||
|
|
||||||
if (!rast) {
|
if (!rast) {
|
||||||
TIFFClose(tiff);
|
TIFFClose (tiff);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TIFFReadRGBAImage(tiff, w, h, rast, 0)) {
|
if (TIFFReadRGBAImage (tiff, w, h, rast, 0)) {
|
||||||
pixels = art_alloc(num_pixs * 4);
|
pixels = malloc (num_pixs * 4);
|
||||||
if (!pixels) {
|
if (!pixels) {
|
||||||
_TIFFfree(rast);
|
_TIFFfree (rast);
|
||||||
TIFFClose(tiff);
|
TIFFClose (tiff);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
tmppix = pixels;
|
tmppix = pixels;
|
||||||
@ -76,23 +82,19 @@ image_load (FILE *f)
|
|||||||
*/
|
*/
|
||||||
tmp_rast = rast + ((h - y - 1) * w);
|
tmp_rast = rast + ((h - y - 1) * w);
|
||||||
for (x = 0; x < w; x++) {
|
for (x = 0; x < w; x++) {
|
||||||
tmppix[0] = TIFFGetR(*tmp_rast);
|
tmppix[0] = TIFFGetR (*tmp_rast);
|
||||||
tmppix[1] = TIFFGetG(*tmp_rast);
|
tmppix[1] = TIFFGetG (*tmp_rast);
|
||||||
tmppix[2] = TIFFGetB(*tmp_rast);
|
tmppix[2] = TIFFGetB (*tmp_rast);
|
||||||
tmppix[3] = TIFFGetA(*tmp_rast);
|
tmppix[3] = TIFFGetA (*tmp_rast);
|
||||||
tmp_rast++;
|
tmp_rast++;
|
||||||
tmppix += 4;
|
tmppix += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_TIFFfree(rast);
|
_TIFFfree (rast);
|
||||||
TIFFClose(tiff);
|
TIFFClose (tiff);
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new (art_pixbuf_new_rgba (pixels, w, h, (w * 4)),
|
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, TRUE,
|
||||||
NULL);
|
w, h, w * 4,
|
||||||
|
free_buffer, NULL);
|
||||||
if (!pixbuf)
|
|
||||||
art_free (pixels);
|
|
||||||
|
|
||||||
return pixbuf;
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
/*
|
/* GdkPixbuf library - JPEG image loader
|
||||||
* io-xpm.c: GdkPixbuf I/O for XPM files.
|
*
|
||||||
* Copyright (C) 1999 Mark Crichton
|
* Copyright (C) 1999 Mark Crichton
|
||||||
* Author: Mark Crichton <crichton@gimp.org>
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
|
*
|
||||||
|
* Authors: Mark Crichton <crichton@gimp.org>
|
||||||
|
* Federico Mena-Quintero <federico@gimp.org>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -14,21 +17,19 @@
|
|||||||
* Library General Public License for more details.
|
* Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Library General Public
|
* You should have received a copy of the GNU Library General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
*
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
/* We need gdk.h since we might need to parse X color names */
|
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
|
||||||
#include "gdk-pixbuf.h"
|
#include "gdk-pixbuf.h"
|
||||||
/*#include "gdk-pixbuf-io.h" */
|
|
||||||
|
|
||||||
|
|
||||||
/* I have must have done something to deserve this.
|
/* I have must have done something to deserve this.
|
||||||
* XPM is such a crappy format to handle.
|
* XPM is such a crappy format to handle.
|
||||||
@ -53,27 +54,28 @@ struct file_handle {
|
|||||||
FILE *infile;
|
FILE *infile;
|
||||||
gchar *buffer;
|
gchar *buffer;
|
||||||
guint buffer_size;
|
guint buffer_size;
|
||||||
} file_handle;
|
};
|
||||||
|
|
||||||
struct mem_handle {
|
struct mem_handle {
|
||||||
gchar **data;
|
gchar **data;
|
||||||
int offset;
|
int offset;
|
||||||
} mem_handle;
|
};
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
xpm_seek_string(FILE *infile, const gchar *str, gint skip_comments)
|
xpm_seek_string (FILE *infile, const gchar *str, gint skip_comments)
|
||||||
{
|
{
|
||||||
char instr[1024];
|
char instr[1024];
|
||||||
|
|
||||||
while (!feof(infile)) {
|
while (!feof (infile)) {
|
||||||
fscanf(infile, "%1023s", instr);
|
fscanf (infile, "%1023s", instr);
|
||||||
if (skip_comments == TRUE && strcmp(instr, "/*") == 0) {
|
if (skip_comments == TRUE && strcmp (instr, "/*") == 0) {
|
||||||
fscanf(infile, "%1023s", instr);
|
fscanf (infile, "%1023s", instr);
|
||||||
while (!feof(infile) && strcmp(instr, "*/") != 0)
|
while (!feof (infile) && strcmp (instr, "*/") != 0)
|
||||||
fscanf(infile, "%1023s", instr);
|
fscanf (infile, "%1023s", instr);
|
||||||
fscanf(infile, "%1023s", instr);
|
fscanf (infile, "%1023s", instr);
|
||||||
}
|
}
|
||||||
if (strcmp(instr, str) == 0)
|
|
||||||
|
if (strcmp (instr, str) == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,33 +83,34 @@ xpm_seek_string(FILE *infile, const gchar *str, gint skip_comments)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
xpm_seek_char(FILE *infile, gchar c)
|
xpm_seek_char (FILE *infile, gchar c)
|
||||||
{
|
{
|
||||||
gint b, oldb;
|
gint b, oldb;
|
||||||
|
|
||||||
while ((b = getc(infile)) != EOF) {
|
while ((b = getc (infile)) != EOF) {
|
||||||
if (c != b && b == '/') {
|
if (c != b && b == '/') {
|
||||||
b = getc(infile);
|
b = getc (infile);
|
||||||
if (b == EOF)
|
if (b == EOF)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
else if (b == '*') { /* we have a comment */
|
else if (b == '*') { /* we have a comment */
|
||||||
b = -1;
|
b = -1;
|
||||||
do {
|
do {
|
||||||
oldb = b;
|
oldb = b;
|
||||||
b = getc(infile);
|
b = getc (infile);
|
||||||
if (b == EOF)
|
if (b == EOF)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
} while (!(oldb == '*' && b == '/'));
|
||||||
while (!(oldb == '*' && b == '/'));
|
|
||||||
}
|
}
|
||||||
} else if (c == b)
|
} else if (c == b)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
xpm_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
|
xpm_read_string (FILE *infile, gchar **buffer, guint *buffer_size)
|
||||||
{
|
{
|
||||||
gint c;
|
gint c;
|
||||||
guint cnt = 0, bufsiz, ret = FALSE;
|
guint cnt = 0, bufsiz, ret = FALSE;
|
||||||
@ -116,28 +119,30 @@ xpm_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
|
|||||||
buf = *buffer;
|
buf = *buffer;
|
||||||
bufsiz = *buffer_size;
|
bufsiz = *buffer_size;
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
bufsiz = 10 * sizeof(gchar);
|
bufsiz = 10 * sizeof (gchar);
|
||||||
buf = g_new(gchar, bufsiz);
|
buf = g_new (gchar, bufsiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
c = getc(infile);
|
c = getc (infile);
|
||||||
} while (c != EOF && c != '"');
|
} while (c != EOF && c != '"');
|
||||||
|
|
||||||
if (c != '"')
|
if (c != '"')
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
while ((c = getc(infile)) != EOF) {
|
while ((c = getc (infile)) != EOF) {
|
||||||
if (cnt == bufsiz) {
|
if (cnt == bufsiz) {
|
||||||
guint new_size = bufsiz * 2;
|
guint new_size = bufsiz * 2;
|
||||||
|
|
||||||
if (new_size > bufsiz)
|
if (new_size > bufsiz)
|
||||||
bufsiz = new_size;
|
bufsiz = new_size;
|
||||||
else
|
else
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
buf = (gchar *) g_realloc(buf, bufsiz);
|
buf = g_realloc (buf, bufsiz);
|
||||||
buf[bufsiz - 1] = '\0';
|
buf[bufsiz - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c != '"')
|
if (c != '"')
|
||||||
buf[cnt++] = c;
|
buf[cnt++] = c;
|
||||||
else {
|
else {
|
||||||
@ -155,7 +160,7 @@ xpm_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
xpm_skip_whitespaces(gchar *buffer)
|
xpm_skip_whitespaces (gchar *buffer)
|
||||||
{
|
{
|
||||||
gint32 index = 0;
|
gint32 index = 0;
|
||||||
|
|
||||||
@ -166,7 +171,7 @@ xpm_skip_whitespaces(gchar *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
xpm_skip_string(gchar *buffer)
|
xpm_skip_string (gchar *buffer)
|
||||||
{
|
{
|
||||||
gint32 index = 0;
|
gint32 index = 0;
|
||||||
|
|
||||||
@ -180,12 +185,13 @@ xpm_skip_string(gchar *buffer)
|
|||||||
#define MAX_COLOR_LEN 120
|
#define MAX_COLOR_LEN 120
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
xpm_extract_color(gchar *buffer)
|
xpm_extract_color (gchar *buffer)
|
||||||
{
|
{
|
||||||
gint counter, numnames;
|
gint counter, numnames;
|
||||||
gchar *ptr = NULL, ch, temp[128];
|
gchar *ptr = NULL, ch, temp[128];
|
||||||
gchar color[MAX_COLOR_LEN], *retcol;
|
gchar color[MAX_COLOR_LEN], *retcol;
|
||||||
gint space;
|
gint space;
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
while (ptr == NULL) {
|
while (ptr == NULL) {
|
||||||
if (buffer[counter] == 'c') {
|
if (buffer[counter] == 'c') {
|
||||||
@ -197,7 +203,7 @@ xpm_extract_color(gchar *buffer)
|
|||||||
|
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
ptr = xpm_skip_whitespaces(ptr);
|
ptr = xpm_skip_whitespaces (ptr);
|
||||||
|
|
||||||
if (ptr[0] == 0)
|
if (ptr[0] == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -208,8 +214,8 @@ xpm_extract_color(gchar *buffer)
|
|||||||
(ptr[counter] >= 'a' && ptr[counter] <= 'f') ||
|
(ptr[counter] >= 'a' && ptr[counter] <= 'f') ||
|
||||||
(ptr[counter] >= 'A' && ptr[counter] <= 'F')))
|
(ptr[counter] >= 'A' && ptr[counter] <= 'F')))
|
||||||
counter++;
|
counter++;
|
||||||
retcol = g_new(gchar, counter + 1);
|
retcol = g_new (gchar, counter + 1);
|
||||||
strncpy(retcol, ptr, counter);
|
strncpy (retcol, ptr, counter);
|
||||||
|
|
||||||
retcol[counter] = 0;
|
retcol[counter] = 0;
|
||||||
|
|
||||||
@ -220,60 +226,65 @@ xpm_extract_color(gchar *buffer)
|
|||||||
|
|
||||||
space = MAX_COLOR_LEN - 1;
|
space = MAX_COLOR_LEN - 1;
|
||||||
while (space > 0) {
|
while (space > 0) {
|
||||||
sscanf(ptr, "%127s", temp);
|
sscanf (ptr, "%127s", temp);
|
||||||
|
|
||||||
if (((gint) ptr[0] == 0) ||
|
if (((gint) ptr[0] == 0) ||
|
||||||
(strcmp("s", temp) == 0) || (strcmp("m", temp) == 0) ||
|
(strcmp ("s", temp) == 0) || (strcmp ("m", temp) == 0) ||
|
||||||
(strcmp("g", temp) == 0) || (strcmp("g4", temp) == 0)) {
|
(strcmp ("g", temp) == 0) || (strcmp ("g4", temp) == 0))
|
||||||
break;
|
break;
|
||||||
} else {
|
else {
|
||||||
if (numnames > 0) {
|
if (numnames > 0) {
|
||||||
space -= 1;
|
space -= 1;
|
||||||
strcat(color, " ");
|
strcat (color, " ");
|
||||||
}
|
}
|
||||||
strncat(color, temp, space);
|
|
||||||
space -= MIN(space, strlen(temp));
|
strncat (color, temp, space);
|
||||||
ptr = xpm_skip_string(ptr);
|
space -= MIN (space, strlen (temp));
|
||||||
ptr = xpm_skip_whitespaces(ptr);
|
ptr = xpm_skip_string (ptr);
|
||||||
|
ptr = xpm_skip_whitespaces (ptr);
|
||||||
numnames++;
|
numnames++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
retcol = g_strdup(color);
|
retcol = g_strdup (color);
|
||||||
return retcol;
|
return retcol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (almost) direct copy from gdkpixmap.c... loads an XPM from a file */
|
/* (almost) direct copy from gdkpixmap.c... loads an XPM from a file */
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
file_buffer(enum buf_op op, gpointer handle)
|
file_buffer (enum buf_op op, gpointer handle)
|
||||||
{
|
{
|
||||||
struct file_handle *h = handle;
|
struct file_handle *h = handle;
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case op_header:
|
case op_header:
|
||||||
if (xpm_seek_string(h->infile, "XPM", FALSE) != TRUE)
|
if (xpm_seek_string (h->infile, "XPM", FALSE) != TRUE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (xpm_seek_char(h->infile, '{') != TRUE)
|
if (xpm_seek_char (h->infile, '{') != TRUE)
|
||||||
break;
|
break;
|
||||||
/* Fall through to the next xpm_seek_char. */
|
/* Fall through to the next xpm_seek_char. */
|
||||||
|
|
||||||
case op_cmap:
|
case op_cmap:
|
||||||
xpm_seek_char(h->infile, '"');
|
xpm_seek_char (h->infile, '"');
|
||||||
fseek(h->infile, -1, SEEK_CUR);
|
fseek (h->infile, -1, SEEK_CUR);
|
||||||
/* Fall through to the xpm_read_string. */
|
/* Fall through to the xpm_read_string. */
|
||||||
|
|
||||||
case op_body:
|
case op_body:
|
||||||
xpm_read_string(h->infile, &h->buffer, &h->buffer_size);
|
xpm_read_string (h->infile, &h->buffer, &h->buffer_size);
|
||||||
return h->buffer;
|
return h->buffer;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This reads from memory */
|
/* This reads from memory */
|
||||||
static gchar *
|
static gchar *
|
||||||
mem_buffer(enum buf_op op, gpointer handle)
|
mem_buffer (enum buf_op op, gpointer handle)
|
||||||
{
|
{
|
||||||
struct mem_handle *h = handle;
|
struct mem_handle *h = handle;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@ -282,14 +293,24 @@ mem_buffer(enum buf_op op, gpointer handle)
|
|||||||
case op_body:
|
case op_body:
|
||||||
if (h->data[h->offset])
|
if (h->data[h->offset])
|
||||||
return h->data[h->offset++];
|
return h->data[h->offset++];
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function does all the work. */
|
/* Destroy notification function for the libart pixbuf */
|
||||||
|
static void
|
||||||
|
free_buffer (gpointer user_data, gpointer data)
|
||||||
|
{
|
||||||
|
free (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function does all the work. */
|
||||||
static GdkPixbuf *
|
static GdkPixbuf *
|
||||||
_pixbuf_create_from_xpm(gchar * (*get_buf) (enum buf_op op, gpointer handle), gpointer handle)
|
pixbuf_create_from_xpm (gchar * (*get_buf) (enum buf_op op, gpointer handle), gpointer handle)
|
||||||
{
|
{
|
||||||
gint w, h, n_col, cpp;
|
gint w, h, n_col, cpp;
|
||||||
gint cnt, xcnt, ycnt, wbytes, n, ns;
|
gint cnt, xcnt, ycnt, wbytes, n, ns;
|
||||||
@ -298,117 +319,108 @@ _pixbuf_create_from_xpm(gchar * (*get_buf) (enum buf_op op, gpointer handle), gp
|
|||||||
gchar pixel_str[32];
|
gchar pixel_str[32];
|
||||||
GHashTable *color_hash;
|
GHashTable *color_hash;
|
||||||
_XPMColor *colors, *color, *fallbackcolor;
|
_XPMColor *colors, *color, *fallbackcolor;
|
||||||
art_u8 *pixels, *pixtmp;
|
guchar *pixels, *pixtmp;
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
ArtPixBuf *art_pixbuf;
|
|
||||||
|
|
||||||
buffer = (*get_buf) (op_header, handle);
|
buffer = (*get_buf) (op_header, handle);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
g_warning("No XPM header found");
|
g_warning ("No XPM header found");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sscanf(buffer, "%d %d %d %d", &w, &h, &n_col, &cpp);
|
sscanf (buffer, "%d %d %d %d", &w, &h, &n_col, &cpp);
|
||||||
if (cpp >= 32) {
|
if (cpp >= 32) {
|
||||||
g_warning("XPM has more than 31 chars per pixel.");
|
g_warning ("XPM has more than 31 chars per pixel.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* The hash is used for fast lookups of color from chars */
|
|
||||||
color_hash = g_hash_table_new(g_str_hash, g_str_equal);
|
|
||||||
|
|
||||||
name_buf = g_new(gchar, n_col * (cpp + 1));
|
/* The hash is used for fast lookups of color from chars */
|
||||||
colors = g_new(_XPMColor, n_col);
|
color_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
|
|
||||||
|
name_buf = g_new (gchar, n_col * (cpp + 1));
|
||||||
|
colors = g_new (_XPMColor, n_col);
|
||||||
|
|
||||||
for (cnt = 0; cnt < n_col; cnt++) {
|
for (cnt = 0; cnt < n_col; cnt++) {
|
||||||
gchar *color_name;
|
gchar *color_name;
|
||||||
|
|
||||||
buffer = (*get_buf) (op_cmap, handle);
|
buffer = (*get_buf) (op_cmap, handle);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
g_warning("Can't load XPM colormap");
|
g_warning ("Can't load XPM colormap");
|
||||||
g_hash_table_destroy(color_hash);
|
g_hash_table_destroy (color_hash);
|
||||||
g_free(name_buf);
|
g_free (name_buf);
|
||||||
g_free(colors);
|
g_free (colors);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
color = &colors[cnt];
|
color = &colors[cnt];
|
||||||
color->color_string = &name_buf[cnt * (cpp + 1)];
|
color->color_string = &name_buf[cnt * (cpp + 1)];
|
||||||
strncpy(color->color_string, buffer, cpp);
|
strncpy (color->color_string, buffer, cpp);
|
||||||
color->color_string[cpp] = 0;
|
color->color_string[cpp] = 0;
|
||||||
buffer += strlen(color->color_string);
|
buffer += strlen (color->color_string);
|
||||||
color->transparent = FALSE;
|
color->transparent = FALSE;
|
||||||
|
|
||||||
color_name = xpm_extract_color(buffer);
|
color_name = xpm_extract_color (buffer);
|
||||||
|
|
||||||
if ((color_name == NULL) || (g_strcasecmp(color_name, "None") == 0)
|
if ((color_name == NULL) || (g_strcasecmp (color_name, "None") == 0)
|
||||||
|| (gdk_color_parse(color_name, &color->color) == FALSE)) {
|
|| (gdk_color_parse (color_name, &color->color) == FALSE)) {
|
||||||
color->transparent = TRUE;
|
color->transparent = TRUE;
|
||||||
is_trans = TRUE;
|
is_trans = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(color_name);
|
g_free (color_name);
|
||||||
g_hash_table_insert(color_hash, color->color_string, color);
|
g_hash_table_insert (color_hash, color->color_string, color);
|
||||||
|
|
||||||
if (cnt == 0)
|
if (cnt == 0)
|
||||||
fallbackcolor = color;
|
fallbackcolor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_trans)
|
if (is_trans)
|
||||||
pixels = art_alloc(w * h * 4);
|
pixels = malloc (w * h * 4);
|
||||||
else
|
else
|
||||||
pixels = art_alloc(w * h * 3);
|
pixels = malloc (w * h * 3);
|
||||||
|
|
||||||
if (!pixels) {
|
if (!pixels) {
|
||||||
g_warning("XPM: Cannot alloc ArtBuf");
|
g_hash_table_destroy (color_hash);
|
||||||
g_hash_table_destroy(color_hash);
|
g_free (colors);
|
||||||
g_free(colors);
|
g_free (name_buf);
|
||||||
g_free(name_buf);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wbytes = w * cpp;
|
wbytes = w * cpp;
|
||||||
pixtmp = pixels;
|
pixtmp = pixels;
|
||||||
|
|
||||||
for (ycnt = 0; ycnt < h; ycnt++) {
|
for (ycnt = 0; ycnt < h; ycnt++) {
|
||||||
buffer = (*get_buf) (op_body, handle);
|
buffer = (*get_buf) (op_body, handle);
|
||||||
if ((!buffer) || (strlen(buffer) < wbytes))
|
if ((!buffer) || (strlen (buffer) < wbytes))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (n = 0, cnt = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) {
|
for (n = 0, cnt = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) {
|
||||||
strncpy(pixel_str, &buffer[n], cpp);
|
strncpy (pixel_str, &buffer[n], cpp);
|
||||||
pixel_str[cpp] = 0;
|
pixel_str[cpp] = 0;
|
||||||
ns = 0;
|
ns = 0;
|
||||||
|
|
||||||
color = g_hash_table_lookup(color_hash, pixel_str);
|
color = g_hash_table_lookup (color_hash, pixel_str);
|
||||||
|
|
||||||
/* Bad XPM...punt */
|
/* Bad XPM...punt */
|
||||||
if (!color)
|
if (!color)
|
||||||
color = fallbackcolor;
|
color = fallbackcolor;
|
||||||
|
|
||||||
*pixtmp++ = (color->color.red)>>8;
|
*pixtmp++ = color->color.red >> 8;
|
||||||
*pixtmp++ = (color->color.green)>>8;
|
*pixtmp++ = color->color.green >> 8;
|
||||||
*pixtmp++ = (color->color.blue)>>8;
|
*pixtmp++ = color->color.blue >> 8;
|
||||||
|
|
||||||
if ((is_trans) && (color->transparent)) {
|
if (is_trans && color->transparent)
|
||||||
*pixtmp++ = 0;
|
*pixtmp++ = 0;
|
||||||
} else if (is_trans) {
|
else if (is_trans)
|
||||||
*pixtmp++ = 0xFF;
|
*pixtmp++ = 0xFF;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_hash_table_destroy(color_hash);
|
|
||||||
g_free(colors);
|
|
||||||
g_free(name_buf);
|
|
||||||
|
|
||||||
/* Ok, now stuff the GdkPixbuf with goodies */
|
g_hash_table_destroy (color_hash);
|
||||||
|
g_free (colors);
|
||||||
|
g_free (name_buf);
|
||||||
|
|
||||||
if (is_trans)
|
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, is_trans,
|
||||||
art_pixbuf = art_pixbuf_new_rgba(pixels, w, h, (w * 4));
|
w, h, is_trans ? (w * 4) : (w * 3),
|
||||||
else
|
free_buffer, NULL);
|
||||||
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
|
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new (art_pixbuf, NULL);
|
|
||||||
|
|
||||||
if (!pixbuf)
|
|
||||||
art_free(pixels);
|
|
||||||
|
|
||||||
return pixbuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shared library entry point for file loading */
|
/* Shared library entry point for file loading */
|
||||||
@ -418,16 +430,10 @@ image_load (FILE *f)
|
|||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
struct file_handle h;
|
struct file_handle h;
|
||||||
|
|
||||||
g_return_val_if_fail(f != NULL, NULL);
|
memset (&h, 0, sizeof (h));
|
||||||
|
|
||||||
memset(&h, 0, sizeof(h));
|
|
||||||
h.infile = f;
|
h.infile = f;
|
||||||
pixbuf = _pixbuf_create_from_xpm(file_buffer, &h);
|
pixbuf = pixbuf_create_from_xpm (file_buffer, &h);
|
||||||
g_free(h.buffer);
|
g_free (h.buffer);
|
||||||
|
|
||||||
return pixbuf;
|
return pixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
image_save()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user