Added loader for jpeg->RGB.

Based really loosely on imlib's io-jpeg.c
This commit is contained in:
Michael Zucci 1999-06-29 11:13:31 +00:00
parent 42311804a4
commit a0b1a437cc
2 changed files with 139 additions and 2 deletions

View File

@ -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
View 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:
*/