diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2007-04-03 13:11:55 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2007-04-03 13:11:55 +1000 |
commit | a83758e5ab818c6f144f8b7e39f367bb122fd56b (patch) | |
tree | ab75b20eed13db1a95310707f7c40da7af0769a0 | |
parent | c485ccb40d72cf3ec286af30a66ae68632ed572c (diff) | |
download | libtwin-a83758e5ab818c6f144f8b7e39f367bb122fd56b.tar.gz |
Add simple jpeg loader based on libjpeg
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | Makefile.am | 5 | ||||
-rw-r--r-- | configure.ac | 21 | ||||
-rw-r--r-- | libtwin/twin_jpeg.c | 170 | ||||
-rw-r--r-- | libtwin/twin_jpeg.h | 28 |
4 files changed, 223 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 6db1c65..3a471ff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -61,6 +61,11 @@ pkginclude_HEADERS += libtwin/twin_png.h libtwin_libtwin_la_SOURCES += libtwin/twin_png.c endif +if TWIN_JPEG +pkginclude_HEADERS += libtwin/twin_jpeg.h +libtwin_libtwin_la_SOURCES += libtwin/twin_jpeg.c +endif + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libtwin.pc diff --git a/configure.ac b/configure.ac index 9f10821..6e1c323 100644 --- a/configure.ac +++ b/configure.ac @@ -91,9 +91,26 @@ if test "x$twin_png" = "xyes" then PKG_CHECK_MODULES(PNG, libpng12, twin_png="yes", twin_png="no") fi + AC_SUBST(PNG_CFLAGS) AC_SUBST(PNG_LIBS) +# jpeg support +AC_ARG_ENABLE(jpeg, + AC_HELP_STRING([--disable-jpeg], + [Disable jpeg support (default=enabled)]), + twin_jpeg="$enableval", twin_jpeg="yes") + +if test "x$twin_jpeg" = "xyes" +then + AC_CHECK_HEADER(jpeglib.h, twin_jpeg="yes", twin_jpeg="no") +fi + +if test "x$twin_jpeg" = "xyes" +then + JPEG_LIBS=-ljpeg +fi + # Check for freetype AC_ARG_ENABLE(twin-ttf, AC_HELP_STRING([--disable-twin-ttf], @@ -139,7 +156,7 @@ AC_SUBST(ALTIVEC_CFLAGS) # TWIN_DEP_*FLAGS define all flags required by dependencies of libtwin -TWIN_DEP_LDFLAGS="$X_LIBS $PNG_LIBS -lm" +TWIN_DEP_LDFLAGS="$X_LIBS $PNG_LIBS $JPEG_LIBS -lm" TWIN_DEPCFLAGS="$X_CFLAGS $PNG_CFLAGS" AC_SUBST(TWIN_DEP_CFLAGS) AC_SUBST(TWIN_DEP_LDFLAGS) @@ -147,12 +164,14 @@ AC_SUBST(TWIN_DEP_LDFLAGS) AM_CONDITIONAL(TWIN_X11, test x$twin_x11 = xyes) AM_CONDITIONAL(TWIN_FB, test x$twin_fb = xyes) AM_CONDITIONAL(TWIN_PNG, test x$twin_png = xyes) +AM_CONDITIONAL(TWIN_JPEG, test x$twin_jpeg = xyes) AM_CONDITIONAL(TWIN_TTF, test x$twin_ttf = xyes) AM_CONDITIONAL(TWIN_MOUSE, test x$twin_mouse = xyes) AC_MSG_NOTICE([x11 support: $twin_x11]) AC_MSG_NOTICE([fbdev support: $twin_fb]) AC_MSG_NOTICE([png support: $twin_png]) +AC_MSG_NOTICE([jpeg support: $twin_jpeg]) AC_MSG_NOTICE([twin_ttf tool: $twin_ttf]) AC_MSG_NOTICE([linux mouse: $twin_mouse]) AC_MSG_NOTICE([altivec: $twin_altivec]) diff --git a/libtwin/twin_jpeg.c b/libtwin/twin_jpeg.c new file mode 100644 index 0000000..48574e8 --- /dev/null +++ b/libtwin/twin_jpeg.c @@ -0,0 +1,170 @@ +/* + * libjpeg interface to twin + * + * Copyright 2007 Benjamin Herrenschmidt <benh@kernel.crashing.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 the Twin Library; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <setjmp.h> +#include <jpeglib.h> + +#include "twin_jpeg.h" + + +#if BITS_IN_JSAMPLE != 8 +#error supports only libjpeg with 8 bits per sample +#endif + +#if 1 +#define DEBUG(fmt...) printf(fmt) +#else +#define DEBUG(fmt...) +#endif + +struct twin_jpeg_err_mgr { + struct jpeg_error_mgr mgr; + jmp_buf jbuf; +}; + +static void twin_jpeg_error_exit(j_common_ptr cinfo) +{ + struct twin_jpeg_err_mgr *jerr = + (struct twin_jpeg_err_mgr *)cinfo->err; + + /* Do we want to display crap ? Maybe make that an option... */ + (*cinfo->err->output_message)(cinfo); + + longjmp(jerr->jbuf, 1); +} + + +twin_pixmap_t *twin_jpeg_to_pixmap(const char *filepath, twin_format_t fmt) +{ + struct jpeg_decompress_struct cinfo; + struct twin_jpeg_err_mgr jerr; + FILE *infile; + JSAMPARRAY rowbuf; + int rowstride; + twin_pixmap_t *pix = NULL; + twin_coord_t width, height; + + /* Current implementation only produces TWIN_ARGB32 + * and TWIN_A8 + */ + if (fmt != TWIN_ARGB32 && fmt != TWIN_A8) + return NULL; + + /* Open file first, as example */ + infile = fopen(filepath, "rb"); + if (infile == NULL) { + fprintf(stderr, "can't open %s\n", filepath); + return NULL; + } + + /* Error handling crap */ + memset(&cinfo, 0, sizeof(cinfo)); + cinfo.err = jpeg_std_error(&jerr.mgr); + jerr.mgr.error_exit = twin_jpeg_error_exit; + if (setjmp(jerr.jbuf)) { + fprintf(stderr, "failure decoding %s\n", filepath); + if (pix) + twin_pixmap_destroy(pix); + jpeg_destroy_decompress(&cinfo); + fclose(infile); + return NULL; + } + + /* Init libjpeg, hook it up to file and read header */ + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, infile); + (void)jpeg_read_header(&cinfo, TRUE); + + /* Settings */ + width = cinfo.image_width; + height = cinfo.image_height; + if (fmt == TWIN_ARGB32) + cinfo.out_color_space = JCS_RGB; + else + cinfo.out_color_space = JCS_GRAYSCALE; + DEBUG("cinfo.image_width = %d\n", cinfo.image_width); + DEBUG("cinfo.image_height = %d\n", cinfo.image_height); + + /* Allocate pixmap */ + pix = twin_pixmap_create(fmt, width, height); + if (pix == NULL) + longjmp(jerr.jbuf, 1); + + /* Start decompression engine */ + (void)jpeg_start_decompress(&cinfo); + + DEBUG("cinfo.output_width = %d\n", cinfo.output_width); + DEBUG("cinfo.output_height = %d\n", cinfo.output_height); + DEBUG("cinfo.output_components = %d\n", cinfo.output_components); + DEBUG("cinfo.output_color_comp = %d\n", cinfo.out_color_components); + DEBUG("cinfo.rec_outbuf_height = %d\n", cinfo.rec_outbuf_height); + DEBUG("cinfo.out_color_space = %d\n", cinfo.out_color_space); + + if ((fmt == TWIN_A8 && cinfo.output_components != 1) || + (fmt == TWIN_ARGB32 && (cinfo.output_components != 3 && + cinfo.output_components != 4))) + longjmp(jerr.jbuf, 1); + + rowstride = cinfo.output_width * cinfo.output_components; + DEBUG("rowstride = %d\n", rowstride); + + rowbuf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, rowstride, 1); + + /* Process rows */ + while (cinfo.output_scanline < cinfo.output_height) { + twin_pointer_t p = + twin_pixmap_pointer(pix, 0, cinfo.output_scanline); + (void)jpeg_read_scanlines(&cinfo, rowbuf, 1); + if (fmt == TWIN_A8 || cinfo.output_components == 4) + memcpy(p.a8, rowbuf, rowstride); + else { + JSAMPLE *s = *rowbuf; + unsigned int i; + + for (i = 0; i < width; i++) { + unsigned int r, g, b; + r = *(s++); + g = *(s++); + b = *(s++); + *(p.argb32++) = 0xff000000u | + (r << 16) | (g << 8) | b; + } + } + } + + /* Cleanup */ + (void)jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(infile); + + return pix; +} + diff --git a/libtwin/twin_jpeg.h b/libtwin/twin_jpeg.h new file mode 100644 index 0000000..828e361 --- /dev/null +++ b/libtwin/twin_jpeg.h @@ -0,0 +1,28 @@ +/* + * Libjpeg interface to twin + * + * Copyright 2007 Benjamin Herrenschmidt <benh@kernel.crashing.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 the Twin Library; see the file COPYING. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _TWIN_JPEG_H_ +#define _TWIN_JPEG_H_ + +#include <libtwin/twin.h> + +twin_pixmap_t *twin_jpeg_to_pixmap(const char *filepath, twin_format_t fmt); + +#endif /* _TWIN_JPEG_H_ */ |