forked from AuroraMiddleware/gtk
Added loader for jpeg->RGB.
Based really loosely on imlib's io-jpeg.c
This commit is contained in:
parent
42311804a4
commit
a0b1a437cc
@ -1,7 +1,8 @@
|
||||
|
||||
lib_LTLIBRARIES = \
|
||||
libgdk-pixbuf.la \
|
||||
libpixbuf-png.la
|
||||
libpixbuf-png.la \
|
||||
libpixbuf-jpeg.la
|
||||
|
||||
#
|
||||
# The GdkPixBuf library
|
||||
@ -19,4 +20,11 @@ libgdk_pixbufinclude_HEADERS = \
|
||||
# The PNG plugin.
|
||||
#
|
||||
libpixbuf_png_la_SOURCES = \
|
||||
io-png.c
|
||||
io-png.c
|
||||
|
||||
#
|
||||
# The JPEG loader
|
||||
#
|
||||
libpixbuf_jpeg_la_SOURCES = \
|
||||
io-jpeg.c
|
||||
|
||||
|
129
gdk-pixbuf/io-jpeg.c
Normal file
129
gdk-pixbuf/io-jpeg.c
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
#include <setjmp.h>
|
||||
#include "gdk-pixbuf.h"
|
||||
/*#include "gdk-pixbuf-io.h"*/
|
||||
#include <jpeglib.h>
|
||||
|
||||
/* error handler data */
|
||||
struct iojpeg_JPEG_error_mgr
|
||||
{
|
||||
struct jpeg_error_mgr pub;
|
||||
sigjmp_buf setjmp_buffer;
|
||||
};
|
||||
|
||||
static void
|
||||
g_JPEGFatalErrorHandler(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;
|
||||
|
||||
errmgr = (struct iojpeg_JPEG_error_mgr *) cinfo->err;
|
||||
cinfo->err->output_message(cinfo);
|
||||
siglongjmp(errmgr->setjmp_buffer, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
GdkPixBuf *image_load(FILE *f)
|
||||
{
|
||||
int w,h,i,j;
|
||||
art_u8 *pixels=NULL, *dptr, *fptr, *pptr;
|
||||
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;
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct iojpeg_JPEG_error_mgr jerr;
|
||||
GdkPixBuf *pixbuf;
|
||||
|
||||
/* setup error handler */
|
||||
cinfo.err = jpeg_std_error(&(jerr.pub));
|
||||
jerr.pub.error_exit = g_JPEGFatalErrorHandler;
|
||||
|
||||
if (sigsetjmp(jerr.setjmp_buffer, 1)) {
|
||||
/* Whoops there was a jpeg error */
|
||||
if (pixels != NULL)
|
||||
art_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);
|
||||
cinfo.do_fancy_upsampling = FALSE;
|
||||
cinfo.do_block_smoothing = FALSE;
|
||||
w = cinfo.output_width;
|
||||
h = cinfo.output_height;
|
||||
|
||||
pixels = art_alloc(h * w * 3);
|
||||
if (pixels == NULL) {
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return NULL;
|
||||
}
|
||||
dptr = pixels;
|
||||
|
||||
/* decompress all the lines, a few at a time */
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
lptr = lines;
|
||||
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++) {
|
||||
to[0] = from[0];
|
||||
to[1] = from[0];
|
||||
to[2] = from[0];
|
||||
to-=3;
|
||||
from--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
/* finish off, create the pixbuf */
|
||||
pixbuf = g_new(GdkPixBuf, 1);
|
||||
pixbuf->art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
|
||||
if (!(pixbuf->art_pixbuf))
|
||||
return NULL;
|
||||
pixbuf->ref_count = 0;
|
||||
pixbuf->unref_func = NULL;
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
Loading…
Reference in New Issue
Block a user