summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-04-03 13:11:55 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-04-03 13:11:55 +1000
commita83758e5ab818c6f144f8b7e39f367bb122fd56b (patch)
treeab75b20eed13db1a95310707f7c40da7af0769a0
parentc485ccb40d72cf3ec286af30a66ae68632ed572c (diff)
Add simple jpeg loader based on libjpeg
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--Makefile.am5
-rw-r--r--configure.ac21
-rw-r--r--libtwin/twin_jpeg.c170
-rw-r--r--libtwin/twin_jpeg.h28
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_ */