AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
June 2004

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date


The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems

Valid HTML 4.01!

2004.06.23 10:31 "Tiff JpegCompression 12-bit", by Albert Adell

Hi all,

During some weeks I have been trying  to read and to write TIFF 8-bits and
12-bits (true 16) Tiled JpegCompressed Files by using LibTiff 3.6.1 and IJG
JpegLib v6b. At least for the 12 bits images that I have, and some other
that I found by Internet I reached a possible solution. I hope this can help
to someone that could be at the same trouble.

- Read/Write 8-bits TIFF Files with JPEG compression is direct, thanks to
the TIFF-JPEG tiff_jpeg.c interface.

- Generate TIFF 8-12 bits JPEG compression files by giving simultaneous
support was not possible at the beginning, due to the fact that the JPEG
library supports both, but NOT at once. It can be worked around by:
  * generation 2 libraries, each of one with its corresponding settings,
changing #defines at compilation time, that able that one or other option
could be chosen, also is necessary to change all the identification's calls
and the filenames by adding _12 at the name (so now we have two split
  * communicating both options at the tiff_jpeg.c file, basically by
modifying the CALLJPEG y CALLVJPEG macros,
  * adding the *.h files at both versions and
  * reviewing the consistency with the supported compressions.
For example:

TiffLib::tiff_jpeg.c::JPEGSetupEncode(TIFF* tif)
        //#define CALLJPEG(sp, fail, op)        (SETJMP((sp)->exit_jmpbuf) ?
(fail) : (op))
        //#define CALLVJPEG(sp, op)             CALLJPEG(sp, 0, ((op),1))

        #define CALLJPEGX(sp, fail, op)         (SETJMP((sp)->exit_jmpbuf) ?
(fail) : (op))

        #define CALLJPEG8(sp, fail, op, params) CALLJPEGX(sp, fail,
        #define CALLJPEG12(sp, fail, op,params) CALLJPEGX(sp, fail,
        #define CALLJPEG(sp, fail, op, params)
(sp->tif->tif_dir.td_bitspersample==12 ? CALLJPEG12(sp, fail, op, params) :
CALLJPEG8(sp, fail, op, params))

        #define CALLVJPEG8(sp, op, params)      CALLJPEGX(sp, 0,
        #define CALLVJPEG12(sp, op, params)     CALLJPEGX(sp, 0,
        #define CALLVJPEG(sp, op, params)
(sp->tif->tif_dir.td_bitspersample==12 ? CALLVJPEG12(sp, op, params) :
CALLVJPEG8(sp, op, params))

TiffLib::tiff_jpeg.c::JPEGSetupEncode(TIFF* tif)
        //if (td->td_bitspersample != BITS_IN_JSAMPLE) {
        if (td->td_bitspersample != 8 && td->td_bitspersample != 12) {

- Apart from the previous point, the 12-bits compression is not correctly
supported by LibTiff. There is a recognized bug at
it can not read, neither write directly this file format. A possible

Reading: could be done by modifying the TIFF library, where the computation
of the number of tiles and strips (in bytes)  of the is done. The problem
was that the size returned in bytes was incorrectly computed, without taking
on count that the data were packed in 16 bits, not in 12. For that the
number in bytes was fewer that the real one.

        //rowsize = td->td_bitspersample * td->td_tilewidth;
        bitspersample = (td->td_bitspersample<=8 ||
td->td_bitspersample%8==0) ? td->td_bitspersample : (td->td_bitspersample/8
+ 1)*8;
        rowsize = bitspersample * td->td_tilewidth;
        //tsize_t rowsize = TIFFhowmany(w*td->td_bitspersample, 8);
        tsize_t bitspersample = (td->td_bitspersample<=8 ||
td->td_bitspersample%8==0) ? td->td_bitspersample : (td->td_bitspersample/8
+ 1)*8;
        tsize_t rowsize = TIFFhowmany(w*bitspersample, 8);
        //scanline = td->td_bitspersample * td->td_imagewidth;
        bitspersample = (td->td_bitspersample<=8 ||
td->td_bitspersample%8==0) ? td->td_bitspersample : (td->td_bitspersample/8
+ 1)*8;
        scanline = bitspersample * td->td_imagewidth;
        //scanline = td->td_bitspersample * td->td_imagewidth;
        bitspersample = (td->td_bitspersample<=8 ||
td->td_bitspersample%8==0) ? td->td_bitspersample : (td->td_bitspersample/8
+ 1)*8;
        scanline = bitspersample * td->td_imagewidth;
        //scanline = TIFFhowmany(w*td->td_bitspersample, 8);
        bitspersample = (td->td_bitspersample<=8 ||
td->td_bitspersample%8==0) ? td->td_bitspersample : (td->td_bitspersample/8
+ 1)*8;
        scanline = TIFFhowmany(w*bitspersample, 8);

Writing: The problem was when creating the Huffman tables at the IJG JpegLib
library, causing a  "Missing Huffman code table entry" error due to the fact
that the file tiff_jpeg.c did not set up correctly the above mentioned
library at the 12-bits case. This can be solved by modifying the
JPEGPreEncode call

        //if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
        //      sp->cinfo.c.optimize_coding = FALSE;
        //      sp->cinfo.c.optimize_coding = TRUE;
        if ((sp->jpegtablesmode & JPEGTABLESMODE_HUFF) &&
sp->tif->tif_dir.td_bitspersample == 8)
                sp->cinfo.c.optimize_coding = FALSE;
                sp->cinfo.c.optimize_coding = TRUE;

Greetings to you all. Saludos a todos.

Albert Adell


Albert Adell Fernández              Desenvolupament Fotogrametria Digital
Institut Cartografic de Catalunya   Passeig Santa Madrona 45-51         
E-08004 Barcelona                   www