forked from AuroraMiddleware/gtk
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:
parent
46da5c2bec
commit
7ef5dec32d
@ -185,7 +185,6 @@ static void
|
||||
expose_func (GtkWidget *drawing_area, GdkEventExpose *event, gpointer data)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
gint x1, y1, x2, y2;
|
||||
|
||||
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
|
||||
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");
|
||||
|
||||
g_print("X:%d Y:%d\n", event->width, event->height);
|
||||
|
||||
#if 0
|
||||
if (((event->width) != (pixbuf->art_pixbuf->width)) ||
|
||||
((event->height) != (pixbuf->art_pixbuf->height)))
|
||||
gdk_pixbuf_scale(pixbuf, event->width, event->height);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -299,18 +299,18 @@ main (int argc, char **argv)
|
||||
|
||||
i = 1;
|
||||
if (argc == 1) {
|
||||
pixbuf = gdk_pixbuf_load_image_from_rgb_d(default_image,
|
||||
DEFAULT_WIDTH,
|
||||
DEFAULT_HEIGHT);
|
||||
if (pixbuf) {
|
||||
new_testrgb_window (pixbuf);
|
||||
found_valid = TRUE;
|
||||
}
|
||||
pixbuf = gdk_pixbuf_new_from_data ((guchar *) default_image, ART_PIX_RGB, FALSE,
|
||||
DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_WIDTH * 3,
|
||||
NULL, NULL);
|
||||
new_testrgb_window (pixbuf);
|
||||
found_valid = TRUE;
|
||||
} else {
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
if (pixbuf) {
|
||||
new_testrgb_window (pixbuf);
|
||||
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>
|
||||
|
||||
* subautogen.sh: New name for macros/autogen.sh
|
||||
@ -6,7 +35,9 @@
|
||||
|
||||
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>
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
lib_LTLIBRARIES = \
|
||||
libgdk_pixbuf.la
|
||||
|
||||
@ -49,8 +48,7 @@ libgdk_pixbuf_la_SOURCES = \
|
||||
gdk-pixbuf-data.c
|
||||
|
||||
libgdk_pixbufinclude_HEADERS = \
|
||||
gdk-pixbuf.h \
|
||||
gdk-pixbuf-io.h
|
||||
gdk-pixbuf.h
|
||||
|
||||
#
|
||||
# The PNG plugin.
|
||||
|
@ -1,49 +1,69 @@
|
||||
/*
|
||||
* gdk-pixbuf-data.c: Code to load images into GdkPixbufs from constant data
|
||||
/* GdkPixbuf library - Image creation from in-memory buffers
|
||||
*
|
||||
* Author:
|
||||
* Michael Fulbright (drmike@redhat.com)
|
||||
* Copyright (C) 1999 Red Hat, Inc.
|
||||
* Copyright (C) 1999 The Free Software Foundation
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.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 *
|
||||
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 @@
|
||||
/*
|
||||
* gdk-pixbuf-io.c: Code to load images into GdkPixbufs
|
||||
/* GdkPixbuf library - Main loading interface.
|
||||
*
|
||||
* Author:
|
||||
* Miguel de Icaza (miguel@gnu.org)
|
||||
* Copyright (C) 1999 The Free Software Foundation
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include "gdk-pixbuf.h"
|
||||
|
||||
|
||||
|
||||
static gboolean
|
||||
pixbuf_check_png (unsigned char *buffer, int size)
|
||||
pixbuf_check_png (guchar *buffer, int size)
|
||||
{
|
||||
if (size < 28)
|
||||
return FALSE;
|
||||
@ -32,7 +49,7 @@ pixbuf_check_png (unsigned char *buffer, int size)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pixbuf_check_jpeg (unsigned char *buffer, int size)
|
||||
pixbuf_check_jpeg (guchar *buffer, int size)
|
||||
{
|
||||
if (size < 10)
|
||||
return FALSE;
|
||||
@ -44,7 +61,7 @@ pixbuf_check_jpeg (unsigned char *buffer, int size)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pixbuf_check_tiff (unsigned char *buffer, int size)
|
||||
pixbuf_check_tiff (guchar *buffer, int size)
|
||||
{
|
||||
if (size < 10)
|
||||
return FALSE;
|
||||
@ -65,7 +82,7 @@ pixbuf_check_tiff (unsigned char *buffer, int size)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pixbuf_check_gif (unsigned char *buffer, int size)
|
||||
pixbuf_check_gif (guchar *buffer, int size)
|
||||
{
|
||||
if (size < 20)
|
||||
return FALSE;
|
||||
@ -77,7 +94,7 @@ pixbuf_check_gif (unsigned char *buffer, int size)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pixbuf_check_xpm (unsigned char *buffer, int size)
|
||||
pixbuf_check_xpm (guchar *buffer, int size)
|
||||
{
|
||||
if (size < 20)
|
||||
return FALSE;
|
||||
@ -89,7 +106,7 @@ pixbuf_check_xpm (unsigned char *buffer, int size)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pixbuf_check_bmp (unsigned char *buffer, int size)
|
||||
pixbuf_check_bmp (guchar *buffer, int size)
|
||||
{
|
||||
if (size < 20)
|
||||
return FALSE;
|
||||
@ -101,7 +118,7 @@ pixbuf_check_bmp (unsigned char *buffer, int size)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pixbuf_check_ppm (unsigned char *buffer, int size)
|
||||
pixbuf_check_ppm (guchar *buffer, int size)
|
||||
{
|
||||
if (size < 20)
|
||||
return FALSE;
|
||||
@ -119,20 +136,21 @@ pixbuf_check_ppm (unsigned char *buffer, int size)
|
||||
}
|
||||
|
||||
static struct {
|
||||
char *module_name;
|
||||
gboolean (*format_check)(unsigned char *buffer, int size);
|
||||
GModule *module;
|
||||
GdkPixbuf *(*load)(FILE *f);
|
||||
int (*save)(GdkPixbuf *p, FILE *f, ...);
|
||||
char *module_name;
|
||||
gboolean (* format_check) (guchar *buffer, int size);
|
||||
GModule *module;
|
||||
GdkPixbuf *(* load) (FILE *f);
|
||||
} file_formats [] = {
|
||||
{ "png", pixbuf_check_png, NULL, NULL, NULL },
|
||||
{ "jpeg", pixbuf_check_jpeg, NULL, NULL, NULL },
|
||||
{ "tiff", pixbuf_check_tiff, NULL, NULL, NULL },
|
||||
{ "gif", pixbuf_check_gif, NULL, NULL, NULL },
|
||||
{ "xpm", pixbuf_check_xpm, NULL, NULL, NULL },
|
||||
/* { "bmp", pixbuf_check_bmp, NULL, NULL, NULL },
|
||||
{ "ppm", pixbuf_check_ppm, NULL, NULL, NULL },*/
|
||||
{ NULL, NULL, NULL, NULL, NULL }
|
||||
{ "png", pixbuf_check_png, NULL, NULL },
|
||||
{ "jpeg", pixbuf_check_jpeg, NULL, NULL },
|
||||
{ "tiff", pixbuf_check_tiff, NULL, NULL },
|
||||
{ "gif", pixbuf_check_gif, NULL, NULL },
|
||||
{ "xpm", pixbuf_check_xpm, NULL, NULL },
|
||||
#if 0
|
||||
{ "bmp", pixbuf_check_bmp, NULL, NULL },
|
||||
{ "ppm", pixbuf_check_ppm, NULL, NULL },
|
||||
#endif
|
||||
{ NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
@ -141,10 +159,9 @@ image_handler_load (int idx)
|
||||
char *module_name;
|
||||
char *path;
|
||||
GModule *module;
|
||||
void *load_sym, *save_sym;
|
||||
void *load_sym;
|
||||
|
||||
module_name = g_strconcat ("pixbuf-",
|
||||
file_formats [idx].module_name, NULL);
|
||||
module_name = g_strconcat ("pixbuf-", file_formats [idx].module_name, NULL);
|
||||
path = g_module_build_path (PIXBUF_LIBDIR, module_name);
|
||||
g_free (module_name);
|
||||
|
||||
@ -158,22 +175,22 @@ image_handler_load (int idx)
|
||||
|
||||
if (g_module_symbol (module, "image_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 *
|
||||
gdk_pixbuf_load_image (const char *file)
|
||||
gdk_pixbuf_new_from_file (const char *filename)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
gint n, i;
|
||||
FILE *f;
|
||||
char buffer [128];
|
||||
|
||||
f = fopen (file, "r");
|
||||
f = fopen (filename, "r");
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
n = fread (&buffer, 1, sizeof (buffer), f);
|
||||
|
||||
if (n == 0) {
|
||||
@ -182,7 +199,7 @@ gdk_pixbuf_load_image (const char *file)
|
||||
}
|
||||
|
||||
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)
|
||||
image_handler_load (i);
|
||||
|
||||
@ -191,15 +208,18 @@ gdk_pixbuf_load_image (const char *file)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_SET);
|
||||
pixbuf = (*file_formats [i].load)(f);
|
||||
fseek (f, 0, SEEK_SET);
|
||||
pixbuf = (* file_formats [i].load) (f);
|
||||
fclose (f);
|
||||
g_assert (pixbuf->ref_count != 0);
|
||||
|
||||
if (pixbuf)
|
||||
g_assert (pixbuf->ref_count != 0);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
g_warning ("Unable to find handler for file: %s", file);
|
||||
g_warning ("Unable to find handler for file: %s", filename);
|
||||
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
|
||||
*
|
||||
* Authors: Mark Crichton <crichton@gimp.org>
|
||||
* Miguel de Icaza <miguel@gnu.org>
|
||||
* Federico Mena-Quintero <federico@gimp.org>
|
||||
* Carsten Haitzler <raster@rasterman.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -25,7 +24,6 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <math.h>
|
||||
#include <glib.h>
|
||||
#include <libart_lgpl/art_misc.h>
|
||||
#include <libart_lgpl/art_affine.h>
|
||||
#include <libart_lgpl/art_pixbuf.h>
|
||||
@ -35,30 +33,15 @@
|
||||
|
||||
|
||||
|
||||
void
|
||||
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;
|
||||
}
|
||||
/* Reference counting */
|
||||
|
||||
/**
|
||||
* gdk_pixbuf_ref:
|
||||
* @pixbuf: A pixbuf.
|
||||
*
|
||||
* Adds a reference to a pixbuf. It must be released afterwards using
|
||||
* gdk_pixbuf_unref().
|
||||
**/
|
||||
void
|
||||
gdk_pixbuf_ref (GdkPixbuf *pixbuf)
|
||||
{
|
||||
@ -68,6 +51,13 @@ gdk_pixbuf_ref (GdkPixbuf *pixbuf)
|
||||
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
|
||||
gdk_pixbuf_unref (GdkPixbuf *pixbuf)
|
||||
{
|
||||
@ -76,113 +66,35 @@ gdk_pixbuf_unref (GdkPixbuf *pixbuf)
|
||||
|
||||
pixbuf->ref_count--;
|
||||
|
||||
if (pixbuf->ref_count == 0)
|
||||
gdk_pixbuf_destroy (pixbuf);
|
||||
if (pixbuf->ref_count == 0) {
|
||||
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 *
|
||||
gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h)
|
||||
gdk_pixbuf_new_from_art_pixbuf (ArtPixBuf *art_pixbuf)
|
||||
{
|
||||
art_u8 *pixels;
|
||||
gint rowstride;
|
||||
double affine[6];
|
||||
ArtAlphaGamma *alphagamma;
|
||||
ArtPixBuf *art_pixbuf = NULL;
|
||||
GdkPixbuf *copy = NULL;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
alphagamma = NULL;
|
||||
g_return_val_if_fail (art_pixbuf != NULL, 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_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 = g_new (GdkPixbuf, 1);
|
||||
pixbuf->ref_count = 1;
|
||||
pixbuf->art_pixbuf = art_pixbuf;
|
||||
|
||||
return pixbuf;
|
||||
|
@ -1,11 +1,10 @@
|
||||
/* GdkPixbuf library
|
||||
/* GdkPixbuf library - Main header file
|
||||
*
|
||||
* Copyright (C) 1999 The Free Software Foundation
|
||||
*
|
||||
* Authors: Mark Crichton <crichton@gimp.org>
|
||||
* Miguel de Icaza <miguel@gnu.org>
|
||||
* Federico Mena-Quintero <federico@gimp.org>
|
||||
* Carsten Haitzler <raster@rasterman.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -36,32 +35,41 @@ extern "C" {
|
||||
|
||||
|
||||
|
||||
/* GdkPixbuf structure */
|
||||
|
||||
typedef struct _GdkPixbuf GdkPixbuf;
|
||||
typedef void (* GdkPixbufUnrefFunc) (GdkPixbuf *pixbuf);
|
||||
|
||||
struct _GdkPixbuf {
|
||||
/* Reference count */
|
||||
int ref_count;
|
||||
|
||||
/* Libart pixbuf */
|
||||
ArtPixBuf *art_pixbuf;
|
||||
GdkPixbufUnrefFunc *unref_fn;
|
||||
};
|
||||
|
||||
|
||||
|
||||
GdkPixbuf *gdk_pixbuf_load_image (const char *file);
|
||||
void gdk_pixbuf_save_image (const char *format_id, const char *file, ...);
|
||||
|
||||
GdkPixbuf *gdk_pixbuf_new (ArtPixBuf *art_pixbuf, GdkPixbufUnrefFunc *unref_fn);
|
||||
/* Reference counting */
|
||||
|
||||
void gdk_pixbuf_ref (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_rotate (GdkPixbuf *pixbuf, gdouble angle);
|
||||
|
||||
void gdk_pixbuf_destroy (GdkPixbuf *pixbuf);
|
||||
|
||||
GdkPixbuf *gdk_pixbuf_load_image_from_rgb_d (unsigned char *data, int rgb_width, int rgb_height);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
/*
|
||||
* io-gif.c: GdkPixbuf I/O for GIF files.
|
||||
* ...second verse, same as the first...
|
||||
/* GdkPixbuf library - GIF image loader
|
||||
*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -16,162 +17,169 @@
|
||||
* 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, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <glib.h>
|
||||
#include "gdk-pixbuf.h"
|
||||
#include "gdk-pixbuf-io.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 */
|
||||
GdkPixbuf *
|
||||
image_load(FILE *f)
|
||||
image_load (FILE *f)
|
||||
{
|
||||
gint fn, is_trans = FALSE;
|
||||
gint done = 0;
|
||||
gint t_color = -1;
|
||||
gint w, h, i, j;
|
||||
art_u8 *pixels, *tmpptr;
|
||||
guchar *pixels, *tmpptr;
|
||||
GifFileType *gif;
|
||||
GifRowType *rows;
|
||||
GifRecordType rec;
|
||||
ColorMapObject *cmap;
|
||||
int intoffset[] =
|
||||
{0, 4, 2, 1};
|
||||
int intjump[] =
|
||||
{8, 8, 4, 2};
|
||||
int intoffset[] = { 0, 4, 2, 1 };
|
||||
int intjump[] = { 8, 8, 4, 2 };
|
||||
|
||||
GdkPixbuf *pixbuf;
|
||||
ArtPixBuf *art_pixbuf;
|
||||
|
||||
g_return_val_if_fail(f != NULL, NULL);
|
||||
|
||||
fn = fileno(f);
|
||||
/* lseek(fn, 0, 0);*/
|
||||
gif = DGifOpenFileHandle(fn);
|
||||
fn = fileno (f);
|
||||
gif = DGifOpenFileHandle (fn);
|
||||
|
||||
if (!gif) {
|
||||
g_error("DGifOpenFilehandle FAILED");
|
||||
PrintGifError();
|
||||
g_warning ("DGifOpenFilehandle FAILED");
|
||||
PrintGifError ();
|
||||
return NULL;
|
||||
}
|
||||
/* Now we do the ungodly mess of loading a GIF image
|
||||
* I used to remember when I liked this file format...
|
||||
* of course, I still coded in assembler then.
|
||||
* This comes from gdk_imlib, with some cleanups.
|
||||
|
||||
/* Now we do the ungodly mess of loading a GIF image I used to remember
|
||||
* when I liked this file format... of course, I still coded in
|
||||
* assembler then. This comes from gdk_imlib, with some cleanups.
|
||||
*/
|
||||
|
||||
do {
|
||||
if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
rec = TERMINATE_RECORD_TYPE;
|
||||
if (DGifGetRecordType (gif, &rec) == GIF_ERROR) {
|
||||
PrintGifError ();
|
||||
DGifCloseFile (gif);
|
||||
return NULL;
|
||||
}
|
||||
if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done)) {
|
||||
if (DGifGetImageDesc(gif) == GIF_ERROR) {
|
||||
PrintGifError();
|
||||
rec = TERMINATE_RECORD_TYPE;
|
||||
}
|
||||
w = gif->Image.Width;
|
||||
h = gif->Image.Height;
|
||||
rows = g_malloc0(h * sizeof(GifRowType *));
|
||||
if (!rows) {
|
||||
DGifCloseFile(gif);
|
||||
|
||||
if (rec == IMAGE_DESC_RECORD_TYPE && !done) {
|
||||
if (DGifGetImageDesc (gif) == GIF_ERROR) {
|
||||
PrintGifError ();
|
||||
DGifCloseFile (gif);
|
||||
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++) {
|
||||
rows[i] = g_malloc0(w * sizeof(GifPixelType));
|
||||
rows[i] = calloc (sizeof (GifPixelType), w);
|
||||
if (!rows[i]) {
|
||||
DGifCloseFile(gif);
|
||||
for (i = 0; i < h; i++)
|
||||
if (rows[i])
|
||||
g_free(rows[i]);
|
||||
free(rows);
|
||||
DGifCloseFile (gif);
|
||||
for (j = 0; j < h; j++)
|
||||
if (rows[j])
|
||||
free (rows[j]);
|
||||
|
||||
free (rows);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (gif->Image.Interlace) {
|
||||
|
||||
if (gif->Image.Interlace)
|
||||
for (i = 0; i < 4; 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++)
|
||||
DGifGetLine(gif, rows[i], w);
|
||||
}
|
||||
DGifGetLine (gif, rows[i], w);
|
||||
|
||||
done = 1;
|
||||
} else if (rec == EXTENSION_RECORD_TYPE) {
|
||||
gint ext_code;
|
||||
GifByteType *ext;
|
||||
|
||||
DGifGetExtension(gif, &ext_code, &ext);
|
||||
DGifGetExtension (gif, &ext_code, &ext);
|
||||
while (ext) {
|
||||
if ((ext_code == 0xf9) &&
|
||||
(ext[1] & 1) && (t_color < 0)) {
|
||||
if ((ext_code == 0xf9) && (ext[1] & 1) && (t_color < 0)) {
|
||||
is_trans = TRUE;
|
||||
t_color = (gint) ext[4];
|
||||
}
|
||||
|
||||
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
|
||||
* with alpha if necessary
|
||||
*/
|
||||
/* Ok, we're loaded, now to convert from indexed -> RGB with alpha if necessary */
|
||||
|
||||
if (is_trans)
|
||||
pixels = art_alloc(h * w * 4);
|
||||
pixels = malloc (h * w * 4);
|
||||
else
|
||||
pixels = art_alloc(h * w * 3);
|
||||
pixels = malloc (h * w * 3);
|
||||
|
||||
tmpptr = pixels;
|
||||
|
||||
if (!pixels)
|
||||
return NULL;
|
||||
if (!pixels) {
|
||||
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);
|
||||
|
||||
/* 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...
|
||||
*/
|
||||
/* Unindex the data, and pack it in RGB(A) order */
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
for (j = 0; j < w; j++) {
|
||||
tmpptr[0] = cmap->Colors[rows[i][j]].Red;
|
||||
tmpptr[1] = cmap->Colors[rows[i][j]].Green;
|
||||
tmpptr[2] = cmap->Colors[rows[i][j]].Blue;
|
||||
if (is_trans && (rows[i][j] == t_color))
|
||||
tmpptr[3] = 0;
|
||||
else
|
||||
tmpptr[3] = 0xFF;
|
||||
tmpptr += (is_trans ? 4 : 3);
|
||||
|
||||
if (is_trans) {
|
||||
if (rows[i][j] == t_color)
|
||||
tmpptr[3] = 0;
|
||||
else
|
||||
tmpptr[3] = 0xFF;
|
||||
|
||||
tmpptr += 4;
|
||||
} else
|
||||
tmpptr += 3;
|
||||
}
|
||||
g_free(rows[i]);
|
||||
|
||||
free (rows[i]);
|
||||
}
|
||||
g_free(rows);
|
||||
|
||||
if (is_trans)
|
||||
art_pixbuf = art_pixbuf_new_rgba(pixels, w, h, (w * 4));
|
||||
else
|
||||
art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
|
||||
free (rows);
|
||||
DGifCloseFile (gif);
|
||||
|
||||
pixbuf = gdk_pixbuf_new (art_pixbuf, NULL);
|
||||
|
||||
/* Ok, I'm anal...shoot me */
|
||||
if (!pixbuf)
|
||||
art_free(pixels);
|
||||
|
||||
return pixbuf;
|
||||
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, is_trans,
|
||||
w, h, is_trans ? (w * 4) : (w * 3),
|
||||
free_buffer, NULL);
|
||||
}
|
||||
|
||||
image_save() {}
|
||||
|
@ -1,129 +1,144 @@
|
||||
/*
|
||||
io-jpeg.c: GdkPixbuf loader for jpeg files.
|
||||
|
||||
Based on io-jpeg from gdk_imlib, but not much.
|
||||
|
||||
This code is licensed under the Lesser GNU
|
||||
General Public License, version 2.1.
|
||||
|
||||
Author:
|
||||
Michael Zucchi <zucchi@zedzone.mmc.com.au>
|
||||
*/
|
||||
/* GdkPixbuf library - JPEG image loader
|
||||
*
|
||||
* Copyright (C) 1999 Michael Zucchi
|
||||
* Copyright (C) 1999 The Free Software Foundation
|
||||
*
|
||||
* Authors: Michael Zucchi <zucchi@zedzone.mmc.com.au>
|
||||
* 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 <stdio.h>
|
||||
#include <glib.h>
|
||||
#include <setjmp.h>
|
||||
#include "gdk-pixbuf.h"
|
||||
/*#include "gdk-pixbuf-io.h"*/
|
||||
#include <jpeglib.h>
|
||||
#include "gdk-pixbuf.h"
|
||||
|
||||
|
||||
|
||||
/* error handler data */
|
||||
struct iojpeg_JPEG_error_mgr {
|
||||
struct error_handler_data {
|
||||
struct jpeg_error_mgr pub;
|
||||
sigjmp_buf setjmp_buffer;
|
||||
};
|
||||
|
||||
static void
|
||||
g_JPEGFatalErrorHandler(j_common_ptr cinfo)
|
||||
fatal_error_handler (j_common_ptr cinfo)
|
||||
{
|
||||
/* FIXME:
|
||||
* We should somehow signal what error occurred to the caller so the
|
||||
* 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;
|
||||
cinfo->err->output_message(cinfo);
|
||||
siglongjmp(errmgr->setjmp_buffer, 1);
|
||||
errmgr = (struct error_handler_data *) cinfo->err;
|
||||
cinfo->err->output_message (cinfo);
|
||||
siglongjmp (errmgr->setjmp_buffer, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
image_load(FILE *f)
|
||||
/* Destroy notification function for the libart pixbuf */
|
||||
static void
|
||||
free_buffer (gpointer user_data, gpointer data)
|
||||
{
|
||||
int w,h,i,j;
|
||||
art_u8 *pixels=NULL, *dptr;
|
||||
unsigned char *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." */
|
||||
**lptr;
|
||||
free (data);
|
||||
}
|
||||
|
||||
/* Shared library entry point */
|
||||
GdkPixbuf *
|
||||
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 iojpeg_JPEG_error_mgr jerr;
|
||||
struct error_handler_data jerr;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
/* setup error handler */
|
||||
cinfo.err = jpeg_std_error(&(jerr.pub));
|
||||
jerr.pub.error_exit = g_JPEGFatalErrorHandler;
|
||||
cinfo.err = jpeg_std_error (&jerr.pub);
|
||||
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 */
|
||||
if (pixels != NULL)
|
||||
art_free(pixels);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
if (pixels)
|
||||
free (pixels);
|
||||
|
||||
jpeg_destroy_decompress (&cinfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* load header, setup */
|
||||
jpeg_create_decompress(&cinfo);
|
||||
jpeg_stdio_src(&cinfo, f);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
jpeg_start_decompress(&cinfo);
|
||||
jpeg_create_decompress (&cinfo);
|
||||
jpeg_stdio_src (&cinfo, f);
|
||||
jpeg_read_header (&cinfo, TRUE);
|
||||
jpeg_start_decompress (&cinfo);
|
||||
cinfo.do_fancy_upsampling = FALSE;
|
||||
cinfo.do_block_smoothing = FALSE;
|
||||
|
||||
w = cinfo.output_width;
|
||||
h = cinfo.output_height;
|
||||
g_print("w: %d h: %d\n", w, h);
|
||||
|
||||
pixels = art_alloc(h * w * 3);
|
||||
if (pixels == NULL) {
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
pixels = malloc (h * w * 3);
|
||||
if (!pixels) {
|
||||
jpeg_destroy_decompress (&cinfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dptr = pixels;
|
||||
|
||||
/* decompress all the lines, a few at a time */
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
lptr = lines;
|
||||
for (i=0;i<cinfo.rec_outbuf_height;i++) {
|
||||
*lptr++=dptr;
|
||||
dptr+=w*3;
|
||||
for (i = 0; i < cinfo.rec_outbuf_height; i++) {
|
||||
*lptr++ = dptr;
|
||||
dptr += w * 3;
|
||||
}
|
||||
jpeg_read_scanlines(&cinfo, lines, cinfo.rec_outbuf_height);
|
||||
if (cinfo.output_components==1) {
|
||||
/* expand grey->colour */
|
||||
/* expand from the end of the memory down, so we can use
|
||||
the same buffer */
|
||||
for (i=cinfo.rec_outbuf_height-1;i>=0;i--) {
|
||||
unsigned char *from, *to;
|
||||
from = lines[i]+w-1;
|
||||
to = lines[i]+w*3-3;
|
||||
for (j=w-1;j>=0;j--) {
|
||||
|
||||
jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);
|
||||
if (cinfo.output_components == 1) {
|
||||
/* Expand grey->colour. Expand from the end of the
|
||||
* memory down, so we can use the same buffer.
|
||||
*/
|
||||
for (i = cinfo.rec_outbuf_height - 1; i >= 0; i--) {
|
||||
guchar *from, *to;
|
||||
|
||||
from = lines[i] + w - 1;
|
||||
to = lines[i] + w * 3 - 3;
|
||||
for (j = w - 1; j >= 0; j--) {
|
||||
to[0] = from[0];
|
||||
to[1] = from[0];
|
||||
to[2] = from[0];
|
||||
to-=3;
|
||||
to -= 3;
|
||||
from--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
jpeg_finish_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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
||||
|
@ -1,7 +1,10 @@
|
||||
/*
|
||||
* io-png.c: GdkPixbuf I/O for PNG files.
|
||||
/* GdkPixbuf library - JPEG image loader
|
||||
*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -14,16 +17,24 @@
|
||||
* 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, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <glib.h>
|
||||
#include "gdk-pixbuf.h"
|
||||
#include "gdk-pixbuf-io.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 */
|
||||
GdkPixbuf *
|
||||
@ -31,17 +42,12 @@ image_load (FILE *f)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
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_bytepp rows;
|
||||
art_u8 *pixels, *temp, *rowdata;
|
||||
GdkPixbuf *pixbuf;
|
||||
ArtPixBuf *art_pixbuf;
|
||||
guchar *pixels, *temp, *rowdata;
|
||||
|
||||
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)
|
||||
return NULL;
|
||||
|
||||
@ -62,10 +68,9 @@ image_load (FILE *f)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
png_init_io (png_ptr, f);
|
||||
png_init_io (png_ptr, f);
|
||||
png_read_info (png_ptr, info_ptr);
|
||||
png_get_IHDR (png_ptr, info_ptr, &w, &h, &depth, &ctype, &inttype,
|
||||
NULL, NULL);
|
||||
png_get_IHDR (png_ptr, info_ptr, &w, &h, &depth, &ctype, &inttype, NULL, NULL);
|
||||
|
||||
/* Ok, we want to work with 24 bit images.
|
||||
* However, PNG can vary depth per channel.
|
||||
@ -108,21 +113,30 @@ image_load (FILE *f)
|
||||
else
|
||||
bpp = 3;
|
||||
|
||||
pixels = art_alloc (w * h * bpp);
|
||||
rows = g_malloc (h * sizeof(png_bytep));
|
||||
pixels = malloc (w * h * bpp);
|
||||
rows = malloc (h * sizeof (png_bytep));
|
||||
|
||||
if (!pixels || !rows) {
|
||||
if (pixels)
|
||||
free (pixels);
|
||||
|
||||
if (rows)
|
||||
free (rows);
|
||||
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Icky code, but it has to be done... */
|
||||
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;
|
||||
|
||||
for (n = 0; n < i; n++)
|
||||
g_free (rows[i]);
|
||||
g_free (rows);
|
||||
art_free (pixels);
|
||||
free (rows[i]);
|
||||
|
||||
free (rows);
|
||||
free (pixels);
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
|
||||
return NULL;
|
||||
}
|
||||
@ -137,105 +151,27 @@ image_load (FILE *f)
|
||||
temp = pixels;
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
(png_bytep) rowdata = rows[y];
|
||||
rowdata = rows[y];
|
||||
for (x = 0; x < w; x++) {
|
||||
temp[0] = rowdata[(x * bpp)];
|
||||
temp[1] = rowdata[(x * bpp) + 1];
|
||||
temp[2] = rowdata[(x * bpp) + 2];
|
||||
|
||||
if (bpp == 4)
|
||||
temp[3] = rowdata[(x * bpp) + 3];
|
||||
|
||||
temp += bpp;
|
||||
}
|
||||
g_free (rows[y]);
|
||||
free (rows[y]);
|
||||
}
|
||||
g_free (rows);
|
||||
free (rows);
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, FALSE,
|
||||
w, h, w * 3,
|
||||
free_buffer, NULL);
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
/*
|
||||
* io-tiff.c: GdkPixbuf I/O for TIFF files.
|
||||
/* GdkPixbuf library - JPEG image loader
|
||||
*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -14,56 +17,59 @@
|
||||
* 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, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Following code (almost) blatantly ripped from Imlib */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <tiffio.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 *
|
||||
image_load (FILE *f)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
TIFF *tiff;
|
||||
art_u8 *pixels, *tmppix;
|
||||
guchar *pixels, *tmppix;
|
||||
gint w, h, x, y, num_pixs, fd;
|
||||
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)
|
||||
return NULL;
|
||||
|
||||
TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
|
||||
TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
|
||||
TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &w);
|
||||
TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &h);
|
||||
num_pixs = w * h;
|
||||
|
||||
/* Yes, it needs to be _TIFFMalloc... */
|
||||
rast = (uint32 *) _TIFFmalloc(num_pixs * sizeof(uint32));
|
||||
rast = (uint32 *) _TIFFmalloc (num_pixs * sizeof (uint32));
|
||||
|
||||
if (!rast) {
|
||||
TIFFClose(tiff);
|
||||
TIFFClose (tiff);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (TIFFReadRGBAImage(tiff, w, h, rast, 0)) {
|
||||
pixels = art_alloc(num_pixs * 4);
|
||||
if (TIFFReadRGBAImage (tiff, w, h, rast, 0)) {
|
||||
pixels = malloc (num_pixs * 4);
|
||||
if (!pixels) {
|
||||
_TIFFfree(rast);
|
||||
TIFFClose(tiff);
|
||||
_TIFFfree (rast);
|
||||
TIFFClose (tiff);
|
||||
return NULL;
|
||||
}
|
||||
tmppix = pixels;
|
||||
@ -76,23 +82,19 @@ image_load (FILE *f)
|
||||
*/
|
||||
tmp_rast = rast + ((h - y - 1) * w);
|
||||
for (x = 0; x < w; x++) {
|
||||
tmppix[0] = TIFFGetR(*tmp_rast);
|
||||
tmppix[1] = TIFFGetG(*tmp_rast);
|
||||
tmppix[2] = TIFFGetB(*tmp_rast);
|
||||
tmppix[3] = TIFFGetA(*tmp_rast);
|
||||
tmppix[0] = TIFFGetR (*tmp_rast);
|
||||
tmppix[1] = TIFFGetG (*tmp_rast);
|
||||
tmppix[2] = TIFFGetB (*tmp_rast);
|
||||
tmppix[3] = TIFFGetA (*tmp_rast);
|
||||
tmp_rast++;
|
||||
tmppix += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
_TIFFfree(rast);
|
||||
TIFFClose(tiff);
|
||||
_TIFFfree (rast);
|
||||
TIFFClose (tiff);
|
||||
|
||||
pixbuf = gdk_pixbuf_new (art_pixbuf_new_rgba (pixels, w, h, (w * 4)),
|
||||
NULL);
|
||||
|
||||
if (!pixbuf)
|
||||
art_free (pixels);
|
||||
|
||||
return pixbuf;
|
||||
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, TRUE,
|
||||
w, h, w * 4,
|
||||
free_buffer, NULL);
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
/*
|
||||
* io-xpm.c: GdkPixbuf I/O for XPM files.
|
||||
/* GdkPixbuf library - JPEG image loader
|
||||
*
|
||||
* 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
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -14,21 +17,19 @@
|
||||
* 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, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
|
||||
/* We need gdk.h since we might need to parse X color names */
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdk-pixbuf.h"
|
||||
/*#include "gdk-pixbuf-io.h" */
|
||||
|
||||
|
||||
|
||||
/* I have must have done something to deserve this.
|
||||
* XPM is such a crappy format to handle.
|
||||
@ -53,27 +54,28 @@ struct file_handle {
|
||||
FILE *infile;
|
||||
gchar *buffer;
|
||||
guint buffer_size;
|
||||
} file_handle;
|
||||
};
|
||||
|
||||
struct mem_handle {
|
||||
gchar **data;
|
||||
int offset;
|
||||
} mem_handle;
|
||||
};
|
||||
|
||||
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];
|
||||
|
||||
while (!feof(infile)) {
|
||||
fscanf(infile, "%1023s", instr);
|
||||
if (skip_comments == TRUE && strcmp(instr, "/*") == 0) {
|
||||
fscanf(infile, "%1023s", instr);
|
||||
while (!feof(infile) && strcmp(instr, "*/") != 0)
|
||||
fscanf(infile, "%1023s", instr);
|
||||
fscanf(infile, "%1023s", instr);
|
||||
while (!feof (infile)) {
|
||||
fscanf (infile, "%1023s", instr);
|
||||
if (skip_comments == TRUE && strcmp (instr, "/*") == 0) {
|
||||
fscanf (infile, "%1023s", instr);
|
||||
while (!feof (infile) && strcmp (instr, "*/") != 0)
|
||||
fscanf (infile, "%1023s", instr);
|
||||
fscanf (infile, "%1023s", instr);
|
||||
}
|
||||
if (strcmp(instr, str) == 0)
|
||||
|
||||
if (strcmp (instr, str) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -81,33 +83,34 @@ xpm_seek_string(FILE *infile, const gchar *str, gint skip_comments)
|
||||
}
|
||||
|
||||
static gint
|
||||
xpm_seek_char(FILE *infile, gchar c)
|
||||
xpm_seek_char (FILE *infile, gchar c)
|
||||
{
|
||||
gint b, oldb;
|
||||
|
||||
while ((b = getc(infile)) != EOF) {
|
||||
while ((b = getc (infile)) != EOF) {
|
||||
if (c != b && b == '/') {
|
||||
b = getc(infile);
|
||||
b = getc (infile);
|
||||
if (b == EOF)
|
||||
return FALSE;
|
||||
|
||||
else if (b == '*') { /* we have a comment */
|
||||
b = -1;
|
||||
do {
|
||||
oldb = b;
|
||||
b = getc(infile);
|
||||
b = getc (infile);
|
||||
if (b == EOF)
|
||||
return FALSE;
|
||||
}
|
||||
while (!(oldb == '*' && b == '/'));
|
||||
} while (!(oldb == '*' && b == '/'));
|
||||
}
|
||||
} else if (c == b)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gint
|
||||
xpm_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
|
||||
xpm_read_string (FILE *infile, gchar **buffer, guint *buffer_size)
|
||||
{
|
||||
gint c;
|
||||
guint cnt = 0, bufsiz, ret = FALSE;
|
||||
@ -116,28 +119,30 @@ xpm_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
|
||||
buf = *buffer;
|
||||
bufsiz = *buffer_size;
|
||||
if (buf == NULL) {
|
||||
bufsiz = 10 * sizeof(gchar);
|
||||
buf = g_new(gchar, bufsiz);
|
||||
bufsiz = 10 * sizeof (gchar);
|
||||
buf = g_new (gchar, bufsiz);
|
||||
}
|
||||
|
||||
do {
|
||||
c = getc(infile);
|
||||
c = getc (infile);
|
||||
} while (c != EOF && c != '"');
|
||||
|
||||
if (c != '"')
|
||||
goto out;
|
||||
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
while ((c = getc (infile)) != EOF) {
|
||||
if (cnt == bufsiz) {
|
||||
guint new_size = bufsiz * 2;
|
||||
|
||||
if (new_size > bufsiz)
|
||||
bufsiz = new_size;
|
||||
else
|
||||
goto out;
|
||||
|
||||
buf = (gchar *) g_realloc(buf, bufsiz);
|
||||
buf = g_realloc (buf, bufsiz);
|
||||
buf[bufsiz - 1] = '\0';
|
||||
}
|
||||
|
||||
if (c != '"')
|
||||
buf[cnt++] = c;
|
||||
else {
|
||||
@ -155,7 +160,7 @@ xpm_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
|
||||
}
|
||||
|
||||
static gchar *
|
||||
xpm_skip_whitespaces(gchar *buffer)
|
||||
xpm_skip_whitespaces (gchar *buffer)
|
||||
{
|
||||
gint32 index = 0;
|
||||
|
||||
@ -166,7 +171,7 @@ xpm_skip_whitespaces(gchar *buffer)
|
||||
}
|
||||
|
||||
static gchar *
|
||||
xpm_skip_string(gchar *buffer)
|
||||
xpm_skip_string (gchar *buffer)
|
||||
{
|
||||
gint32 index = 0;
|
||||
|
||||
@ -180,12 +185,13 @@ xpm_skip_string(gchar *buffer)
|
||||
#define MAX_COLOR_LEN 120
|
||||
|
||||
static gchar *
|
||||
xpm_extract_color(gchar *buffer)
|
||||
xpm_extract_color (gchar *buffer)
|
||||
{
|
||||
gint counter, numnames;
|
||||
gchar *ptr = NULL, ch, temp[128];
|
||||
gchar color[MAX_COLOR_LEN], *retcol;
|
||||
gint space;
|
||||
|
||||
counter = 0;
|
||||
while (ptr == NULL) {
|
||||
if (buffer[counter] == 'c') {
|
||||
@ -197,7 +203,7 @@ xpm_extract_color(gchar *buffer)
|
||||
|
||||
counter++;
|
||||
}
|
||||
ptr = xpm_skip_whitespaces(ptr);
|
||||
ptr = xpm_skip_whitespaces (ptr);
|
||||
|
||||
if (ptr[0] == 0)
|
||||
return NULL;
|
||||
@ -208,8 +214,8 @@ xpm_extract_color(gchar *buffer)
|
||||
(ptr[counter] >= 'a' && ptr[counter] <= 'f') ||
|
||||
(ptr[counter] >= 'A' && ptr[counter] <= 'F')))
|
||||
counter++;
|
||||
retcol = g_new(gchar, counter + 1);
|
||||
strncpy(retcol, ptr, counter);
|
||||
retcol = g_new (gchar, counter + 1);
|
||||
strncpy (retcol, ptr, counter);
|
||||
|
||||
retcol[counter] = 0;
|
||||
|
||||
@ -220,60 +226,65 @@ xpm_extract_color(gchar *buffer)
|
||||
|
||||
space = MAX_COLOR_LEN - 1;
|
||||
while (space > 0) {
|
||||
sscanf(ptr, "%127s", temp);
|
||||
sscanf (ptr, "%127s", temp);
|
||||
|
||||
if (((gint) ptr[0] == 0) ||
|
||||
(strcmp("s", temp) == 0) || (strcmp("m", temp) == 0) ||
|
||||
(strcmp("g", temp) == 0) || (strcmp("g4", temp) == 0)) {
|
||||
(strcmp ("s", temp) == 0) || (strcmp ("m", temp) == 0) ||
|
||||
(strcmp ("g", temp) == 0) || (strcmp ("g4", temp) == 0))
|
||||
break;
|
||||
} else {
|
||||
else {
|
||||
if (numnames > 0) {
|
||||
space -= 1;
|
||||
strcat(color, " ");
|
||||
strcat (color, " ");
|
||||
}
|
||||
strncat(color, temp, space);
|
||||
space -= MIN(space, strlen(temp));
|
||||
ptr = xpm_skip_string(ptr);
|
||||
ptr = xpm_skip_whitespaces(ptr);
|
||||
|
||||
strncat (color, temp, space);
|
||||
space -= MIN (space, strlen (temp));
|
||||
ptr = xpm_skip_string (ptr);
|
||||
ptr = xpm_skip_whitespaces (ptr);
|
||||
numnames++;
|
||||
}
|
||||
}
|
||||
|
||||
retcol = g_strdup(color);
|
||||
retcol = g_strdup (color);
|
||||
return retcol;
|
||||
}
|
||||
|
||||
/* (almost) direct copy from gdkpixmap.c... loads an XPM from a file */
|
||||
|
||||
static gchar *
|
||||
file_buffer(enum buf_op op, gpointer handle)
|
||||
file_buffer (enum buf_op op, gpointer handle)
|
||||
{
|
||||
struct file_handle *h = handle;
|
||||
|
||||
switch (op) {
|
||||
case op_header:
|
||||
if (xpm_seek_string(h->infile, "XPM", FALSE) != TRUE)
|
||||
if (xpm_seek_string (h->infile, "XPM", FALSE) != TRUE)
|
||||
break;
|
||||
|
||||
if (xpm_seek_char(h->infile, '{') != TRUE)
|
||||
if (xpm_seek_char (h->infile, '{') != TRUE)
|
||||
break;
|
||||
/* Fall through to the next xpm_seek_char. */
|
||||
|
||||
case op_cmap:
|
||||
xpm_seek_char(h->infile, '"');
|
||||
fseek(h->infile, -1, SEEK_CUR);
|
||||
xpm_seek_char (h->infile, '"');
|
||||
fseek (h->infile, -1, SEEK_CUR);
|
||||
/* Fall through to the xpm_read_string. */
|
||||
|
||||
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;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
return 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This reads from memory */
|
||||
static gchar *
|
||||
mem_buffer(enum buf_op op, gpointer handle)
|
||||
mem_buffer (enum buf_op op, gpointer handle)
|
||||
{
|
||||
struct mem_handle *h = handle;
|
||||
switch (op) {
|
||||
@ -282,14 +293,24 @@ mem_buffer(enum buf_op op, gpointer handle)
|
||||
case op_body:
|
||||
if (h->data[h->offset])
|
||||
return h->data[h->offset++];
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
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 *
|
||||
_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 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];
|
||||
GHashTable *color_hash;
|
||||
_XPMColor *colors, *color, *fallbackcolor;
|
||||
art_u8 *pixels, *pixtmp;
|
||||
GdkPixbuf *pixbuf;
|
||||
ArtPixBuf *art_pixbuf;
|
||||
guchar *pixels, *pixtmp;
|
||||
|
||||
buffer = (*get_buf) (op_header, handle);
|
||||
if (!buffer) {
|
||||
g_warning("No XPM header found");
|
||||
g_warning ("No XPM header found");
|
||||
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) {
|
||||
g_warning("XPM has more than 31 chars per pixel.");
|
||||
g_warning ("XPM has more than 31 chars per pixel.");
|
||||
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));
|
||||
colors = g_new(_XPMColor, n_col);
|
||||
/* 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));
|
||||
colors = g_new (_XPMColor, n_col);
|
||||
|
||||
for (cnt = 0; cnt < n_col; cnt++) {
|
||||
gchar *color_name;
|
||||
|
||||
buffer = (*get_buf) (op_cmap, handle);
|
||||
if (!buffer) {
|
||||
g_warning("Can't load XPM colormap");
|
||||
g_hash_table_destroy(color_hash);
|
||||
g_free(name_buf);
|
||||
g_free(colors);
|
||||
g_warning ("Can't load XPM colormap");
|
||||
g_hash_table_destroy (color_hash);
|
||||
g_free (name_buf);
|
||||
g_free (colors);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
color = &colors[cnt];
|
||||
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;
|
||||
buffer += strlen(color->color_string);
|
||||
buffer += strlen (color->color_string);
|
||||
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)
|
||||
|| (gdk_color_parse(color_name, &color->color) == FALSE)) {
|
||||
if ((color_name == NULL) || (g_strcasecmp (color_name, "None") == 0)
|
||||
|| (gdk_color_parse (color_name, &color->color) == FALSE)) {
|
||||
color->transparent = TRUE;
|
||||
is_trans = TRUE;
|
||||
}
|
||||
|
||||
g_free(color_name);
|
||||
g_hash_table_insert(color_hash, color->color_string, color);
|
||||
g_free (color_name);
|
||||
g_hash_table_insert (color_hash, color->color_string, color);
|
||||
|
||||
if (cnt == 0)
|
||||
fallbackcolor = color;
|
||||
}
|
||||
|
||||
if (is_trans)
|
||||
pixels = art_alloc(w * h * 4);
|
||||
pixels = malloc (w * h * 4);
|
||||
else
|
||||
pixels = art_alloc(w * h * 3);
|
||||
pixels = malloc (w * h * 3);
|
||||
|
||||
if (!pixels) {
|
||||
g_warning("XPM: Cannot alloc ArtBuf");
|
||||
g_hash_table_destroy(color_hash);
|
||||
g_free(colors);
|
||||
g_free(name_buf);
|
||||
g_hash_table_destroy (color_hash);
|
||||
g_free (colors);
|
||||
g_free (name_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wbytes = w * cpp;
|
||||
pixtmp = pixels;
|
||||
|
||||
for (ycnt = 0; ycnt < h; ycnt++) {
|
||||
buffer = (*get_buf) (op_body, handle);
|
||||
if ((!buffer) || (strlen(buffer) < wbytes))
|
||||
if ((!buffer) || (strlen (buffer) < wbytes))
|
||||
continue;
|
||||
|
||||
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;
|
||||
ns = 0;
|
||||
|
||||
color = g_hash_table_lookup(color_hash, pixel_str);
|
||||
color = g_hash_table_lookup (color_hash, pixel_str);
|
||||
|
||||
/* Bad XPM...punt */
|
||||
if (!color)
|
||||
color = fallbackcolor;
|
||||
|
||||
*pixtmp++ = (color->color.red)>>8;
|
||||
*pixtmp++ = (color->color.green)>>8;
|
||||
*pixtmp++ = (color->color.blue)>>8;
|
||||
*pixtmp++ = color->color.red >> 8;
|
||||
*pixtmp++ = color->color.green >> 8;
|
||||
*pixtmp++ = color->color.blue >> 8;
|
||||
|
||||
if ((is_trans) && (color->transparent)) {
|
||||
if (is_trans && color->transparent)
|
||||
*pixtmp++ = 0;
|
||||
} else if (is_trans) {
|
||||
else if (is_trans)
|
||||
*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)
|
||||
art_pixbuf = art_pixbuf_new_rgba(pixels, w, h, (w * 4));
|
||||
else
|
||||
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;
|
||||
return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, is_trans,
|
||||
w, h, is_trans ? (w * 4) : (w * 3),
|
||||
free_buffer, NULL);
|
||||
}
|
||||
|
||||
/* Shared library entry point for file loading */
|
||||
@ -418,16 +430,10 @@ image_load (FILE *f)
|
||||
GdkPixbuf *pixbuf;
|
||||
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;
|
||||
pixbuf = _pixbuf_create_from_xpm(file_buffer, &h);
|
||||
g_free(h.buffer);
|
||||
pixbuf = pixbuf_create_from_xpm (file_buffer, &h);
|
||||
g_free (h.buffer);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
image_save()
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user