Re: [gtk-list] Re: Image Libraries
- From: "David N. Welton" <davidw linuxcare com>
- To: gtk-list redhat com
- Subject: Re: [gtk-list] Re: Image Libraries
- Date: Thu, 3 Feb 2000 16:06:00 -0800
On Tue, Feb 01, 2000 at 08:11:04PM -0800, Timothy M. Shead wrote:
> My concern with gdk-pixbuf is that it seems to wrap libart, which is
> drawing-oriented. It may make sense to use its' interface as a
> starting point, however. On that note, we should probably take this
> off the list ... anyone who's interested in this topic is welcome
> to drop me a line directly.
Ok, but just for fun, I'm publishing my (ugly) patch, in case anyone
else is interested in hacking on gdk-pixbuf directly, or you want to
use this as a start.
Ciao,
--
David N. Welton, Developer, Linuxcare, Inc.
415.354.4878 x241 tel, 415.701.7457 fax
davidw@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
diff -r -u /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-data.c gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf-data.c
--- /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-data.c Thu Dec 2 12:44:41 1999
+++ gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf-data.c Mon Jan 31 21:07:54 2000
@@ -67,3 +67,11 @@
return gdk_pixbuf_new_from_art_pixbuf (art_pixbuf);
}
+
+GdkPixbuf *
+gdk_pixbuf_clone(GdkPixbuf *pixbuf)
+{
+ g_assert(pixbuf != NULL);
+ g_assert(pixbuf->art_pixbuf != NULL);
+ return gdk_pixbuf_new_from_art_pixbuf (pixbuf->art_pixbuf);
+}
diff -r -u /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-io.c gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf-io.c
--- /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-io.c Sat Jan 1 19:59:22 2000
+++ gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf-io.c Tue Feb 1 17:20:11 2000
@@ -168,17 +168,17 @@
GdkPixbufModule file_formats [] = {
- { "png", pixbuf_check_png, NULL, NULL, NULL, NULL, NULL, NULL },
- { "jpeg", pixbuf_check_jpeg, NULL, NULL, NULL, NULL, NULL, NULL },
- { "tiff", pixbuf_check_tiff, NULL, NULL, NULL, NULL, NULL, NULL },
- { "gif", pixbuf_check_gif, NULL, NULL, NULL, NULL, NULL, NULL },
+ { "png", pixbuf_check_png, NULL,NULL, NULL, NULL, NULL, NULL, NULL },
+ { "jpeg", pixbuf_check_jpeg, NULL, NULL,NULL, NULL, NULL, NULL, NULL },
+ { "tiff", pixbuf_check_tiff, NULL,NULL, NULL, NULL, NULL, NULL, NULL },
+ { "gif", pixbuf_check_gif, NULL,NULL, NULL, NULL, NULL, NULL, NULL },
#define XPM_FILE_FORMAT_INDEX 4
- { "xpm", pixbuf_check_xpm, NULL, NULL, NULL, NULL, NULL, NULL },
- { "pnm", pixbuf_check_pnm, NULL, NULL, NULL, NULL, NULL, NULL },
- { "ras", pixbuf_check_sunras, NULL, NULL, NULL, NULL, NULL, NULL },
- { "ico", pixbuf_check_ico, NULL, NULL, NULL, NULL, NULL, NULL },
- { "bmp", pixbuf_check_bmp, NULL, NULL, NULL, NULL, NULL, NULL },
- { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+ { "xpm", pixbuf_check_xpm, NULL,NULL, NULL, NULL, NULL, NULL, NULL },
+ { "pnm", pixbuf_check_pnm, NULL,NULL, NULL, NULL, NULL, NULL, NULL },
+ { "ras", pixbuf_check_sunras, NULL,NULL, NULL, NULL, NULL, NULL, NULL },
+ { "ico", pixbuf_check_ico, NULL,NULL, NULL, NULL, NULL, NULL, NULL },
+ { "bmp", pixbuf_check_bmp, NULL,NULL, NULL, NULL, NULL, NULL, NULL },
+ { NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
@@ -223,6 +223,8 @@
if (g_module_symbol (module, "image_load", &load_sym))
image_module->load = load_sym;
+ if (g_module_symbol (module, "image_save", &load_sym))
+ image_module->save = load_sym;
if (g_module_symbol (module, "image_load_xpm_data", &load_sym))
image_module->load_xpm_data = load_sym;
@@ -341,4 +343,50 @@
pixbuf = (* load_xpm_data) (data);
return pixbuf;
+}
+
+/**
+ * gdk_pixbuf_save_to_file:
+ * @filename: Name of file to save.
+ *
+ * Saves pixbuf to a file.
+ *
+ **/
+int gdk_pixbuf_save_to_file (const char *filename, GdkPixbuf *pixbuf, char *format)
+{
+ int size;
+ int i;
+ FILE *f;
+ guchar buffer [128];
+ GdkPixbufModule *image_module = NULL;
+
+ f = fopen (filename, "w");
+ if (!f)
+ {
+ g_warning ("Cannot open for write: %s", filename);
+ return -1;
+ }
+
+ for (i = 0; file_formats [i].module_name; i++) {
+ if(!strncmp((file_formats [i].module_name), format, strlen(format)))
+ image_module = &(file_formats[i]);
+ }
+
+ if (!image_module) {
+ g_warning ("Unable to find handler for file: %s", filename);
+ fclose (f);
+ return -1;
+ }
+
+ if (image_module->module == NULL)
+ gdk_pixbuf_load_module (image_module);
+
+ if (image_module->save == NULL) {
+ fclose (f);
+ return -1;
+ }
+
+ (* image_module->save) (f, pixbuf);
+ fclose (f);
+ return 0;
}
diff -r -u /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-io.h gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf-io.h
--- /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-io.h Fri Jan 7 10:29:13 2000
+++ gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf-io.h Wed Jan 26 21:52:49 2000
@@ -55,6 +55,7 @@
gboolean (* format_check) (guchar *buffer, int size);
GModule *module;
GdkPixbuf *(* load) (FILE *f);
+ int (* save) (FILE *f, GdkPixbuf *pixbuf);
GdkPixbuf *(* load_xpm_data) (const char **data);
/* Incremental loading */
diff -r -u /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf.c gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf.c
--- /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf.c Fri Jan 21 14:54:44 2000
+++ gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf.c Tue Feb 1 12:59:43 2000
@@ -98,7 +98,7 @@
pixbuf = g_new (GdkPixbuf, 1);
pixbuf->ref_count = 1;
- pixbuf->art_pixbuf = art_pixbuf;
+ pixbuf->art_pixbuf = art_pixbuf_duplicate(art_pixbuf);
return pixbuf;
}
diff -r -u /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf.h gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf.h
--- /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/gdk-pixbuf.h Fri Jan 21 14:54:44 2000
+++ gdk-pixbuf-0.5.0/gdk-pixbuf/gdk-pixbuf.h Wed Jan 26 23:48:20 2000
@@ -110,6 +110,8 @@
/* Simple loading */
GdkPixbuf *gdk_pixbuf_new_from_file (const char *filename);
+
+int gdk_pixbuf_save_to_file (const char *filename, GdkPixbuf *pixbuf, char *format);
GdkPixbuf *gdk_pixbuf_new_from_data (guchar *data,
ArtPixFormat format,
@@ -118,6 +120,8 @@
int rowstride,
ArtDestroyNotify dfunc,
gpointer dfunc_data);
+GdkPixbuf *gdk_pixbuf_clone(GdkPixbuf *pixbuf);
+
GdkPixbuf *gdk_pixbuf_new_from_xpm_data (const char **data);
diff -r -u /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/io-jpeg.c gdk-pixbuf-0.5.0/gdk-pixbuf/io-jpeg.c
--- /home/davidw/gnome/gdk-pixbuf/gdk-pixbuf/io-jpeg.c Wed Jan 5 15:06:13 2000
+++ gdk-pixbuf-0.5.0/gdk-pixbuf/io-jpeg.c Tue Feb 1 17:42:23 2000
@@ -87,6 +87,7 @@
struct error_handler_data jerr;
} JpegProgContext;
+int image_save (FILE *f, GdkPixbuf *pixbuf);
GdkPixbuf *image_load (FILE *f);
gpointer image_begin_load (ModulePreparedNotifyFunc func,
ModuleUpdatedNotifyFunc func2,
@@ -547,4 +548,143 @@
}
return TRUE;
+}
+
+#define DATABIG unsigned long long
+#define DATA64 unsigned long long
+#define DATA32 unsigned int
+#define DATA16 unsigned short
+#define DATA8 unsigned char
+
+struct ImLib_JPEG_error_mgr
+{
+ struct jpeg_error_mgr pub;
+ sigjmp_buf setjmp_buffer;
+};
+typedef struct ImLib_JPEG_error_mgr *emptr;
+void _JPEGFatalErrorHandler(j_common_ptr cinfo);
+void _JPEGErrorHandler(j_common_ptr cinfo);
+void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
+
+void
+_JPEGFatalErrorHandler(j_common_ptr cinfo)
+{
+ emptr errmgr;
+
+ errmgr = (emptr) cinfo->err;
+/* cinfo->err->output_message(cinfo);*/
+ siglongjmp(errmgr->setjmp_buffer, 1);
+ return;
+}
+
+void
+_JPEGErrorHandler(j_common_ptr cinfo)
+{
+ emptr errmgr;
+
+ errmgr = (emptr) cinfo->err;
+/* cinfo->err->output_message(cinfo);*/
+/* siglongjmp(errmgr->setjmp_buffer, 1);*/
+ return;
+}
+
+void
+_JPEGErrorHandler2(j_common_ptr cinfo, int msg_level)
+{
+ emptr errmgr;
+
+ errmgr = (emptr) cinfo->err;
+/* cinfo->err->output_message(cinfo);*/
+/* siglongjmp(errmgr->setjmp_buffer, 1);*/
+ return;
+ msg_level = 0;
+}
+
+
+int image_save(FILE *f, GdkPixbuf *pixbuf)
+{
+ struct jpeg_compress_struct cinfo;
+ DATA8 *buf;
+ DATA8 *ptr;
+ JSAMPROW *jbuf;
+ int y = 0, quality = 100;
+ int i, j, pl = 0;
+ int w, h = 0;
+ char pper = 0;
+ struct ImLib_JPEG_error_mgr jerr;
+
+ ArtPixBuf *apixbuf;
+
+ apixbuf = pixbuf->art_pixbuf;
+ w = apixbuf->width;
+ h = apixbuf->height;
+
+ /* no image data? abort */
+ if (!apixbuf->pixels)
+ return 0;
+ /* allocate a small buffer to convert image data */
+ buf = malloc(w * 3 * sizeof(DATA8));
+ if (!buf)
+ return 0;
+
+ /* set up error handling */
+ jerr.pub.error_exit = _JPEGFatalErrorHandler;
+ jerr.pub.emit_message = _JPEGErrorHandler2;
+ jerr.pub.output_message = _JPEGErrorHandler;
+ cinfo.err = jpeg_std_error(&(jerr.pub));
+ if (sigsetjmp(jerr.setjmp_buffer, 1))
+ {
+ jpeg_destroy_compress(&cinfo);
+ free(buf);
+ fclose(f);
+ return 1;
+ }
+
+ /* setup compress params */
+ jpeg_create_compress(&cinfo);
+ jpeg_stdio_dest(&cinfo, f);
+ cinfo.image_width = w;
+ cinfo.image_height = h;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+
+ /* look for tags attached to image to get extra parameters liek quality */
+ /* settigns etc. - thsi si the "api" to hint for extra information for */
+ /* saver modules */
+/* tag = __imlib_GetTag(im, "quality");
+ if (tag)
+ quality = tag->val;
+ if (quality < 1)
+ quality = 1;
+ if (quality > 100)
+ quality = 100; */
+
+ /* set up jepg compression parameters */
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, quality, TRUE);
+ jpeg_start_compress(&cinfo, TRUE);
+ /* get the start pointer */
+ ptr = apixbuf->pixels;
+ /* go one scanline at a time... and save */
+ i = 0;
+ while (cinfo.next_scanline < cinfo.image_height)
+ {
+ /* convert scanline from ARGB to RGB packed */
+ for (j = 0; j < w; j++)
+ {
+
+ buf[j*3] = ptr[i*w*3 + j*3] ;
+ *(&buf[j*3] + 1) = *(&ptr[i*w*3 + j*3] + 1);
+ *(&buf[j*3] + 2) = *(&ptr[i*w*3 + j*3] + 2) ;
+ }
+ /* write scanline */
+ jbuf = (JSAMPROW *)(&buf);
+ jpeg_write_scanlines(&cinfo, jbuf, 1);
+ i++;
+ y++;
+ }
+ /* finish off */
+ jpeg_finish_compress(&cinfo);
+ free(buf);
+ return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]