From db1ab60daca621f268025d0af7b249e64dd70b2e Mon Sep 17 00:00:00 2001 From: Frank Warmerdam Date: Sun, 21 Jun 2009 18:49:38 +0000 Subject: [PATCH] add support for 8/12bit jpeg dual mode builds --- ChangeLog | 5 +++ configure.ac | 32 +++++++++++++++++++ libtiff/Makefile.am | 1 + libtiff/tif_jpeg.c | 77 ++++++++++++++++++++++++++++++++++++++------- 4 files changed, 104 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index d1d6f60b..571ce08e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-06-21 Frank Warmerdam + + * configure.ac, libtiff/tif_jpeg.c, libtiff/tif_jpeg_12.c: add support + for dual mode 8/12 bit jpeg support. + 2009-06-03 Frank Warmerdam * libtiff/tif_write.c: do not override the planar configuration to be diff --git a/configure.ac b/configure.ac index 284bf7ff..4ae4aaa9 100644 --- a/configure.ac +++ b/configure.ac @@ -632,6 +632,37 @@ if test "$HAVE_JBIG" = "yes" ; then fi +dnl --------------------------------------------------------------------------- +dnl Should 8/12 bit jpeg mode be enabled? +dnl --------------------------------------------------------------------------- + +HAVE_JPEG12=no + +AC_ARG_ENABLE(jpeg12, + AS_HELP_STRING([--enable-jpeg12], + [enable libjpeg 8/12bit dual mode]),,) +AC_ARG_WITH(jpeg12-include-dir, + AS_HELP_STRING([--with-jpeg12-include-dir=DIR], + [location of libjpeg 12bit headers]),,) +AC_ARG_WITH(jpeg12-lib, + AS_HELP_STRING([--with-jpeg12-lib=LIBRARY], + [path to libjpeg 12bit library]),,) + +if test "x$enable_jpeg12" == "xyes" ; then + + if test "x$with_jpeg12_lib" != "x" ; then + LIBS="$with_jpeg12_lib $LIBS" + fi + + HAVE_JPEG12=yes + + AC_DEFINE(JPEG_DUAL_MODE_8_12,1,[8/12 bit libjpeg dual mode enabled]) + if test "x$with_jpeg12_include_dir" != "x" ; then + AC_DEFINE_UNQUOTED(LIBJPEG_12_PATH,"$with_jpeg12_include_dir/jpeglib.h",[12bit libjpeg primary include file with path]) + fi +fi + + dnl --------------------------------------------------------------------------- dnl Check for C++. dnl --------------------------------------------------------------------------- @@ -803,6 +834,7 @@ LOC_MSG([ ZLIB support: ${HAVE_ZLIB}]) LOC_MSG([ Pixar log-format algorithm: ${HAVE_PIXARLOG}]) LOC_MSG([ JPEG support: ${HAVE_JPEG}]) LOC_MSG([ Old JPEG support: ${HAVE_OJPEG}]) +LOC_MSG([ JPEG 8/12 bit dual mode: ${HAVE_JPEG12}]) LOC_MSG([ ISO JBIG support: ${HAVE_JBIG}]) LOC_MSG() LOC_MSG([ C++ support: ${HAVE_CXX}]) diff --git a/libtiff/Makefile.am b/libtiff/Makefile.am index 669c0e41..5f4f4b93 100644 --- a/libtiff/Makefile.am +++ b/libtiff/Makefile.am @@ -75,6 +75,7 @@ libtiff_la_SOURCES = \ tif_getimage.c \ tif_jbig.c \ tif_jpeg.c \ + tif_jpeg_12.c \ tif_luv.c \ tif_lzw.c \ tif_next.c \ diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c index 0db1483e..f1d571e2 100644 --- a/libtiff/tif_jpeg.c +++ b/libtiff/tif_jpeg.c @@ -1,4 +1,4 @@ -/* $Id: tif_jpeg.c,v 1.81 2009-05-03 14:29:36 fwarmerdam Exp $ */ +/* $Id: tif_jpeg.c,v 1.82 2009-06-21 18:49:38 fwarmerdam Exp $ */ /* * Copyright (c) 1994-1997 Sam Leffler @@ -46,6 +46,7 @@ int TIFFFillStrip(TIFF* tif, uint32 strip); int TIFFFillTile(TIFF* tif, uint32 tile); +int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ); /* We undefine FAR to avoid conflict with JPEG definition */ @@ -648,6 +649,7 @@ alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info, #define JPEG_MARKER_SOF3 0xC3 #define JPEG_MARKER_DHT 0xC4 #define JPEG_MARKER_SOI 0xD8 +#define JPEG_MARKER_SOS 0xDA #define JPEG_MARKER_DQT 0xDB #define JPEG_MARKER_DRI 0xDD #define JPEG_MARKER_APP0 0xE0 @@ -784,8 +786,10 @@ JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data) case JPEG_MARKER_APP0+14: case JPEG_MARKER_APP0+15: case JPEG_MARKER_DQT: + case JPEG_MARKER_SOS: case JPEG_MARKER_DHT: case JPEG_MARKER_DRI: + case JPEG_MARKER_SOF1: /* this type of marker has data, but it has no use to us and should be skipped */ { uint16 n; @@ -931,6 +935,11 @@ JPEGSetupDecode(TIFF* tif) JPEGState* sp = JState(tif); TIFFDirectory *td = &tif->tif_dir; +#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) + if( tif->tif_dir.td_bitspersample == 12 ) + return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 0 ); +#endif + JPEGInitializeLibJPEG( tif, TRUE ); assert(sp != NULL); @@ -1290,7 +1299,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; int samples_per_clump = sp->samplesperclump; -#ifdef JPEG_LIB_MK1 +#if defined(JPEG_LIB_MK1) || BITS_IN_JSAMPLE == 12 unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) * sp->cinfo.d.output_width * sp->cinfo.d.num_components); @@ -1321,7 +1330,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) for (ypos = 0; ypos < vsamp; ypos++) { JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; -#ifdef JPEG_LIB_MK1 +#if defined(JPEG_LIB_MK1) || BITS_IN_JSAMPLE == 12 JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset; #else JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset; @@ -1348,7 +1357,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) } } -#ifdef JPEG_LIB_MK1 +#if defined(JPEG_LIB_MK1) || BITS_IN_JSAMPLE == 12 { if (sp->cinfo.d.data_precision == 8) { @@ -1367,7 +1376,7 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) for( iPair = 0; iPair < value_pairs; iPair++ ) { unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3; - JSAMPLE *in_ptr = tmpbuf + iPair * 2; + JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2); out_ptr[0] = (in_ptr[0] & 0xff0) >> 4; out_ptr[1] = ((in_ptr[0] & 0xf) << 4) | ((in_ptr[1] & 0xf00) >> 8); @@ -1379,12 +1388,17 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) sp->scancount ++; tif->tif_row += sp->v_sampling; +/* buf += clumps_per_line*samples_per_clump; cc -= clumps_per_line*samples_per_clump; +*/ + buf += sp->bytesperline * sp->v_sampling; + cc -= sp->bytesperline * sp->v_sampling; + nrows -= sp->v_sampling; } while (nrows > 0); -#ifdef JPEG_LIB_MK1 +#if defined(JPEG_LIB_MK1) || BITS_IN_JSAMPLE == 12 _TIFFfree(tmpbuf); #endif @@ -1459,6 +1473,11 @@ JPEGSetupEncode(TIFF* tif) TIFFDirectory *td = &tif->tif_dir; static const char module[] = "JPEGSetupEncode"; +#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG) + if( tif->tif_dir.td_bitspersample == 12 ) + return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 1 ); +#endif + JPEGInitializeLibJPEG( tif, FALSE ); assert(sp != NULL); @@ -1715,6 +1734,8 @@ JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) JPEGState *sp = JState(tif); tmsize_t nrows; JSAMPROW bufptr[1]; + short *line16 = NULL; + int line16_count = 0; (void) s; assert(sp != NULL); @@ -1728,14 +1749,48 @@ JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength ) nrows = tif->tif_dir.td_imagelength - tif->tif_row; + if( sp->cinfo.c.data_precision == 12 ) + { + line16_count = (sp->bytesperline * 2) / 3; + line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count); + } + while (nrows-- > 0) { + + if( sp->cinfo.c.data_precision == 12 ) + { + + int value_pairs = line16_count / 2; + int iPair; + + bufptr[0] = (JSAMPROW) line16; + + for( iPair = 0; iPair < value_pairs; iPair++ ) + { + unsigned char *in_ptr = + ((unsigned char *) buf) + iPair * 3; + JSAMPLE *out_ptr = (JSAMPLE *) (line16 + iPair * 2); + + out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4); + out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2]; + } + } + else + { bufptr[0] = (JSAMPROW) buf; - if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) - return (0); - if (nrows > 0) - tif->tif_row++; - buf += sp->bytesperline; + } + if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) + return (0); + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; } + + if( sp->cinfo.c.data_precision == 12 ) + { + _TIFFfree( line16 ); + } + return (1); }