[poppler] CMakeLists.txt cmake/modules configure.ac poppler/JPEG2000Stream.cc poppler/JPEG2000Stream.h poppler/Makefile.am poppler/Stream.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Fri Jun 13 15:55:17 PDT 2008


 CMakeLists.txt                      |   30 +++++
 cmake/modules/FindLIBOPENJPEG.cmake |   44 ++++++++
 configure.ac                        |   33 ++++++
 poppler/JPEG2000Stream.cc           |  181 ++++++++++++++++++++++++++++++++++++
 poppler/JPEG2000Stream.h            |   48 +++++++++
 poppler/Makefile.am                 |   22 +++-
 poppler/Stream.cc                   |    7 +
 7 files changed, 360 insertions(+), 5 deletions(-)

New commits:
commit 99d2361032cbaafd69bd796170757ed6482f208d
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Jun 14 00:53:38 2008 +0200

    Add a JPEG2000 decoder based on OpenJPEG
    
    Enabled by default since it's generally better than xpdf one
    See http://lists.freedesktop.org/archives/poppler/2008-June/003874.html for more information

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 01a25b7..3c70684 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,6 +21,7 @@ option(BUILD_QT4_TESTS "Whether compile the Qt4 test programs." ON)
 option(ENABLE_SPLASH "Build the Splash graphics backend." ON)
 option(ENABLE_UTILS "Compile poppler command line utils." ON)
 option(ENABLE_ABIWORD "Build the Abiword backend." ON)
+option(ENABLE_LIBOPENJPEG "Use libopenjpeg for JPX streams." ON)
 option(ENABLE_ZLIB "TODO" OFF)
 option(USE_EXCEPTIONS "Throw exceptions to deal with not enough memory and similar problems." OFF)
 option(USE_FIXEDPOINT "Use fixed point arithmetic" OFF)
@@ -64,6 +65,10 @@ if(ENABLE_ABIWORD)
   find_package(LibXml2)
   set(ENABLE_ABIWORD ${LIBXML2_FOUND})
 endif(ENABLE_ABIWORD)
+if(ENABLE_LIBOPENJPEG)
+  find_package(LIBOPENJPEG)
+  set(ENABLE_LIBOPENJPEG ${LIBOPENJPEG_FOUND})
+endif(ENABLE_LIBOPENJPEG)
 
 add_definitions(-DHAVE_CONFIG_H=1 ${FONTCONFIG_DEFINITIONS})
 include_directories(
@@ -88,6 +93,9 @@ if(ENABLE_ABIWORD)
   include_directories(${LIBXML2_INCLUDE_DIR})
   add_definitions(${LIBXML2_DEFINITIONS})
 endif(ENABLE_ABIWORD)
+if(ENABLE_LIBOPENJPEG)
+  include_directories(${LIBOPENJPEG_INCLUDE_DIR})
+endif(ENABLE_LIBOPENJPEG)
 
 if(DEFINED COMPILE_WARNINGS)
 else(DEFINED COMPILE_WARNINGS)
@@ -144,7 +152,6 @@ set(poppler_SRCS
   poppler/GlobalParams.cc
   poppler/JArithmeticDecoder.cc
   poppler/JBIG2Stream.cc
-  poppler/JPXStream.cc
   poppler/Lexer.cc
   poppler/Link.cc
   poppler/NameToCharCode.cc
@@ -209,6 +216,16 @@ if(ENABLE_ZLIB)
   )
   set(poppler_LIBS ${poppler_LIBS} ${ZLIB_LIBRARIES})
 endif(ENABLE_ZLIB)
+if(ENABLE_LIBOPENJPEG)
+  set(poppler_SRCS ${poppler_SRCS}
+    poppler/JPEG2000Stream.cc
+  )
+  set(poppler_LIBS ${poppler_LIBS} ${LIBOPENJPEG_LIBRARIES})
+else (ENABLE_LIBOPENJPEG)
+  set(poppler_SRCS ${poppler_SRCS}
+    poppler/JPXStream.cc
+  )
+endif(ENABLE_LIBOPENJPEG)
 if(ENABLE_ABIWORD)
   set(poppler_SRCS ${poppler_SRCS}
     poppler/ABWOutputDev.cc
@@ -264,7 +281,6 @@ if(ENABLE_XPDF_HEADERS)
     poppler/GlobalParams.h
     poppler/JArithmeticDecoder.h
     poppler/JBIG2Stream.h
-    poppler/JPXStream.h
     poppler/Lexer.h
     poppler/Link.h
     poppler/NameToCharCode.h
@@ -301,6 +317,15 @@ if(ENABLE_XPDF_HEADERS)
     poppler/Movie.h
     ${CMAKE_CURRENT_BINARY_DIR}/poppler/poppler-config.h
     DESTINATION include/poppler)
+  if(ENABLE_LIBOPENJPEG)
+    install(FILES
+      poppler/JPEG2000Stream.h
+      DESTINATION include/poppler)
+  else (ENABLE_LIBOPENJPEG)
+    install(FILES
+      poppler/JPXStream.h
+      DESTINATION include/poppler)
+  endif(ENABLE_LIBOPENJPEG)
   if(ENABLE_SPLASH)
     install(FILES
       poppler/SplashOutputDev.h
@@ -389,4 +414,5 @@ show_end_message("glib wrapper" GLIB_FOUND)
 # message("  use gtk-doc:        $enable_gtk_doc") # TODO
 show_end_message("use libjpeg" ENABLE_LIBJPEG)
 show_end_message("use zlib" ENABLE_ZLIB)
+show_end_message("use libopenjpeg" ENABLE_LIBOPENJPEG)
 show_end_message("command line utils" ENABLE_UTILS)
diff --git a/cmake/modules/FindLIBOPENJPEG.cmake b/cmake/modules/FindLIBOPENJPEG.cmake
new file mode 100644
index 0000000..d883a4c
--- /dev/null
+++ b/cmake/modules/FindLIBOPENJPEG.cmake
@@ -0,0 +1,44 @@
+# - Try to find the libopenjpeg library
+# Once done this will define
+#
+#  LIBOPENJPEG_FOUND - system has libopenjpeg
+#  LIBOPENJPEG_INCLUDE_DIRS - the libopenjpeg include directories
+#  LIBOPENJPEG_LIBRARIES - Link these to use libopenjpeg
+#  LIBOPENJPEG_INCLUDE_DIR is internal and deprecated for use
+
+# Copyright (c) 2008, Albert Astals Cid, <aacid at kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+if (LIBOPENJPEG_LIBRARIES AND LIBOPENJPEG_INCLUDE_DIR)
+
+  # in cache already
+  set(LIBOPENJPEG_FOUND TRUE)
+
+else (LIBOPENJPEG_LIBRARIES AND LIBOPENJPEG_INCLUDE_DIR)
+
+  #reset vars
+  set(LIBOPENJPEG_LIBRARIES)
+  set(LIBOPENJPEG_INCLUDE_DIR)
+
+  find_path (LIBOPENJPEG_INCLUDE_DIR openjpeg.h)
+  find_library(LIBOPENJPEG_LIBRARIES openjpeg)
+  if(LIBOPENJPEG_INCLUDE_DIR AND LIBOPENJPEG_LIBRARIES)
+    set(LIBOPENJPEG_FOUND TRUE)
+  endif(LIBOPENJPEG_INCLUDE_DIR AND LIBOPENJPEG_LIBRARIES)
+
+  IF (LIBOPENJPEG_FOUND)
+    IF (NOT LIBOPENJPEG_FIND_QUIETLY)
+       MESSAGE(STATUS "Found libopenjpeg: ${LIBOPENJPEG_LIBRARIES}")
+    ENDIF (NOT LIBOPENJPEG_FIND_QUIETLY)
+  ELSE (LIBOPENJPEG_FOUND)
+    IF (LIBOPENJPEG_FIND_REQUIRED)
+       MESSAGE(FATAL_ERROR "Could not find libopenjpeg library")
+    ENDIF (LIBOPENJPEG_FIND_REQUIRED)
+  ENDIF (LIBOPENJPEG_FOUND)
+
+endif (LIBOPENJPEG_LIBRARIES AND LIBOPENJPEG_INCLUDE_DIR)
+
+set(LIBOPENJPEG_INCLUDE_DIRS ${LIBOPENJPEG_INCLUDE_DIR})
diff --git a/configure.ac b/configure.ac
index dccba6e..43572e4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,6 +114,38 @@ AM_CONDITIONAL(BUILD_ZLIB, test x$enable_zlib = xyes)
 AH_TEMPLATE([ENABLE_ZLIB],
 	    [Use zlib instead of builtin zlib decoder.])
 
+
+dnl Test for libopenjpeg
+AC_ARG_ENABLE(libopenjpeg,
+	      AC_HELP_STRING([--disable-libopenjpeg],
+	                     [Don't build against libopenjpeg.]),
+              enable_libopenjpeg=$enableval,
+              enable_libopenjpeg="try")
+if test x$enable_libopenjpeg = xyes; then
+  AC_CHECK_LIB([openjpeg], [opj_cio_open],,
+	       AC_MSG_ERROR("*** libopenjpeg library not found ***"))
+  AC_CHECK_HEADERS([openjpeg.h],,
+		   AC_MSG_ERROR("*** libopenjpeg headers not found ***"))
+elif test x$enable_libopenjpeg = xtry; then
+  AC_CHECK_LIB([openjpeg], [opj_cio_open],
+               [enable_libopenjpeg="yes"],
+	       [enable_libopenjpeg="no"])
+  AC_CHECK_HEADERS([openjpeg.h],,
+		   [enable_libopenjpeg="no"])
+fi
+
+if test x$enable_libopenjpeg = xyes; then
+  LIBOPENJPEG_LIBS="-lopenjpeg"
+  AC_SUBST(LIBOPENJPEG_LIBS)
+  AC_DEFINE(ENABLE_LIBOPENJPEG)
+fi
+
+AM_CONDITIONAL(BUILD_LIBOPENJPEG, test x$enable_libopenjpeg = xyes)
+AH_TEMPLATE([ENABLE_LIBOPENJPEG],
+	    [Use libopenjpeg instead of builtin jpeg2000 decoder.])
+
+
+
 dnl Test for libjpeg
 AC_ARG_ENABLE(libjpeg,
 	      AC_HELP_STRING([--disable-libjpeg],
@@ -422,4 +454,5 @@ echo "    use GDK:          $enable_gdk"
 echo "  use gtk-doc:        $enable_gtk_doc"
 echo "  use libjpeg:        $enable_libjpeg"
 echo "  use zlib:           $enable_zlib"
+echo "  use libopenjpeg:    $enable_libopenjpeg"
 echo "  command line utils: $enable_utils"
diff --git a/poppler/JPEG2000Stream.cc b/poppler/JPEG2000Stream.cc
new file mode 100644
index 0000000..47908fb
--- /dev/null
+++ b/poppler/JPEG2000Stream.cc
@@ -0,0 +1,181 @@
+//========================================================================
+//
+// JPEG2000Stream.cc
+//
+// A JPX stream decoder using OpenJPEG
+//
+// Copyright 2008 Albert Astals Cid <aacid at kde.org>
+//
+// Licensed under GPLv2 or later
+//
+//========================================================================
+
+#include "JPEG2000Stream.h"
+
+JPXStream::JPXStream(Stream *strA) : FilterStream(strA)
+{
+  inited = gFalse;
+  image = NULL;
+  dinfo = NULL;
+}
+
+JPXStream::~JPXStream() {
+  delete str;
+  close();
+}
+
+void JPXStream::reset() {
+  counter = 0;
+}
+
+void JPXStream::close() {
+  if (image != NULL) {
+    opj_image_destroy(image);
+    image = NULL;
+  }
+  if (dinfo != NULL) {
+    opj_destroy_decompress(dinfo);
+    dinfo = NULL;
+  }
+}
+
+int JPXStream::getPos() {
+  return counter;
+}
+
+int JPXStream::getChar() {
+  int result = lookChar();
+  ++counter;
+  return result;
+}
+
+#define BUFFER_INCREASE 4096
+
+void JPXStream::init()
+{
+  int bufSize = BUFFER_INCREASE;
+  unsigned char *buf = (unsigned char*)gmallocn(bufSize, sizeof(unsigned char));
+  int index = 0;
+
+  str->reset();
+  int c = str->getChar();
+  while(c != EOF)
+  {
+    buf[index] = c;
+    ++index;
+    if (index >= bufSize)
+    {
+      bufSize += BUFFER_INCREASE;
+      buf = (unsigned char*)greallocn(buf, bufSize, sizeof(unsigned char));
+    }
+    c = str->getChar();
+  }
+
+  init2(buf, index, CODEC_JP2);
+
+  free(buf);
+
+  counter = 0;
+  inited = gTrue;
+}
+
+static void libopenjpeg_error_callback(const char *msg, void * /*client_data*/) {
+  error(-1, (char*)msg);
+}
+
+static void libopenjpeg_warning_callback(const char *msg, void * /*client_data*/) {
+  error(-1, (char*)msg);
+}
+
+void JPXStream::init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format)
+{
+  opj_cio_t *cio = NULL;
+
+  /* Use default decompression parameters */
+  opj_dparameters_t parameters;
+  opj_set_default_decoder_parameters(&parameters);
+
+  /* Configure the event manager to receive errors and warnings */
+  opj_event_mgr_t event_mgr;
+  memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
+  event_mgr.error_handler = libopenjpeg_error_callback;
+  event_mgr.warning_handler = libopenjpeg_warning_callback;
+
+  /* Get the decoder handle of the format */
+  dinfo = opj_create_decompress(format);
+  if (dinfo == NULL) goto error;
+
+  /* Catch events using our callbacks */
+  opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);
+
+  /* Setup the decoder decoding parameters */
+  opj_setup_decoder(dinfo, &parameters);
+
+  /* Open a byte stream */
+  cio = opj_cio_open((opj_common_ptr)dinfo, buf, bufLen);
+  if (cio == NULL) goto error;
+
+  /* Decode the stream and fill the image structure */
+  image = opj_decode(dinfo, cio);
+
+  /* Close the byte stream */
+  opj_cio_close(cio);
+
+  if (image == NULL) goto error;
+  else return;
+
+error:
+  if (format == CODEC_JP2) {
+    error(-1, "Did no succeed opening JPX Stream as JP2, trying as J2K.");
+    init2(buf, bufLen, CODEC_J2K);
+  } else if (format == CODEC_J2K) {
+    error(-1, "Did no succeed opening JPX Stream as J2K, trying as JPT.");
+    init2(buf, bufLen, CODEC_JPT);
+  } else {
+    error(-1, "Did no succeed opening JPX Stream.");
+  }
+}
+
+int JPXStream::lookChar() {
+  if (inited == gFalse) init();
+
+  if (!image) return EOF;
+
+  int w = image->comps[0].w;
+  int h = image->comps[0].h;
+
+  int y = (counter / image->numcomps) / w;
+  int x = (counter / image->numcomps) % w;
+  if (y >= h) return EOF;
+
+  int component = counter % image->numcomps;
+
+  int adjust = 0;
+  if (image->comps[component].prec > 8) {
+    adjust = image->comps[component].prec - 8;
+  }
+
+  int r = image->comps[component].data[y * w + x];
+  r += (image->comps[component].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
+
+  unsigned char rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2));
+
+  return rc;
+}
+
+GooString *JPXStream::getPSFilter(int psLevel, char *indent) {
+  return NULL;
+}
+
+GBool JPXStream::isBinary(GBool last) {
+  return str->isBinary(gTrue);
+}
+
+void JPXStream::getImageParams(int *bitsPerComponent, StreamColorSpaceMode *csMode) {
+  if (inited == gFalse) init();
+
+  *bitsPerComponent = 8;
+  if (image && image->numcomps == 3) *csMode = streamCSDeviceRGB;
+  else *csMode = streamCSDeviceGray;
+}
+
diff --git a/poppler/JPEG2000Stream.h b/poppler/JPEG2000Stream.h
new file mode 100644
index 0000000..ea32093
--- /dev/null
+++ b/poppler/JPEG2000Stream.h
@@ -0,0 +1,48 @@
+//========================================================================
+//
+// JPEG2000Stream.h
+//
+// A JPX stream decoder using OpenJPEG
+//
+// Copyright 2008 Albert Astals Cid <aacid at kde.org>
+//
+// Licensed under GPLv2 or later
+//
+//========================================================================
+
+
+#ifndef JPEG2000STREAM_H
+#define JPEG2000STREAM_H
+
+#include <openjpeg.h>
+
+#include "goo/gtypes.h"
+#include "Object.h"
+#include "Stream.h"
+
+class JPXStream: public FilterStream {
+public:
+
+  JPXStream(Stream *strA);
+  virtual ~JPXStream();
+  virtual StreamKind getKind() { return strJPX; }
+  virtual void reset();
+  virtual void close();
+  virtual int getPos();
+  virtual int getChar();
+  virtual int lookChar();
+  virtual GooString *getPSFilter(int psLevel, char *indent);
+  virtual GBool isBinary(GBool last = gTrue);
+  virtual void getImageParams(int *bitsPerComponent, StreamColorSpaceMode *csMode);
+
+private:
+  void init();
+  void init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format);
+
+  opj_image_t *image;
+  opj_dinfo_t *dinfo;
+  int counter;
+  GBool inited;
+};
+
+#endif
diff --git a/poppler/Makefile.am b/poppler/Makefile.am
index b1db1dc..a904e92 100644
--- a/poppler/Makefile.am
+++ b/poppler/Makefile.am
@@ -62,6 +62,24 @@ libjpeg_libs =					\
 
 endif
 
+if BUILD_LIBOPENJPEG
+
+libjpeg2000_sources =				\
+	JPEG2000Stream.h			\
+	JPEG2000Stream.cc
+
+libjpeg2000_libs =				\
+	$(LIBOPENJPEG_LIBS)
+
+else
+
+libjpeg2000_sources =				\
+	JPXStream.h			\
+	JPXStream.cc
+
+endif
+
+
 if BUILD_ZLIB
 
 zlib_sources =					\
@@ -111,6 +129,7 @@ libpoppler_la_LIBADD =				\
 	$(splash_libs)				\
 	$(libjpeg_libs)				\
 	$(zlib_libs)				\
+	$(libjpeg2000_libs)			\
 	$(abiword_libs)				\
 	$(FREETYPE_LIBS)			\
 	$(FONTCONFIG_LIBS)			\
@@ -146,7 +165,6 @@ poppler_include_HEADERS =	\
 	GlobalParams.h		\
 	JArithmeticDecoder.h	\
 	JBIG2Stream.h		\
-	JPXStream.h		\
 	Lexer.h			\
 	Link.h			\
 	Movie.h                 \
@@ -192,6 +210,7 @@ libpoppler_la_SOURCES =		\
 	$(arthur_sources)	\
 	$(libjpeg_sources)	\
 	$(zlib_sources)		\
+	$(libjpeg2000_sources)	\
 	$(abiword_sources)	\
 	Annot.cc		\
 	Array.cc 		\
@@ -213,7 +232,6 @@ libpoppler_la_SOURCES =		\
 	GlobalParams.cc		\
 	JArithmeticDecoder.cc	\
 	JBIG2Stream.cc		\
-	JPXStream.cc		\
 	Lexer.cc 		\
 	Link.cc 		\
 	Movie.cc                \
diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index b662edb..667a3e3 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -30,7 +30,6 @@
 #include "GfxState.h"
 #include "Stream.h"
 #include "JBIG2Stream.h"
-#include "JPXStream.h"
 #include "Stream-CCITT.h"
 
 #ifdef ENABLE_LIBJPEG
@@ -41,6 +40,12 @@
 #include "FlateStream.h"
 #endif
 
+#ifdef ENABLE_LIBOPENJPEG
+#include "JPEG2000Stream.h"
+#else
+#include "JPXStream.h"
+#endif
+
 #ifdef __DJGPP__
 static GBool setDJSYSFLAGS = gFalse;
 #endif


More information about the poppler mailing list