Commit 99d23610 authored by Albert Astals Cid's avatar Albert Astals Cid

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
parent e368838d
......@@ -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)
# - 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@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})
......@@ -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"
//========================================================================
//
// JPEG2000Stream.cc
//
// A JPX stream decoder using OpenJPEG
//
// Copyright 2008 Albert Astals Cid <aacid@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;
}
//========================================================================
//
// JPEG2000Stream.h
//
// A JPX stream decoder using OpenJPEG
//
// Copyright 2008 Albert Astals Cid <aacid@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
......@@ -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 \
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment