| AWARE [SYSTEMS] | Imaging expertise for the Delphi developer | |||||||
![]() |
TIFF and LibTiff Mailing List Archive | |||||||
LibTiff Mailing List
TIFF and LibTiff Mailing List Archive Contact
The TIFF Mailing List Homepage |
2004.06.23 10:31 "Tiff JpegCompression 12-bit", by Albert AdellHi 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
libraries),
* 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,
op##params)
#define CALLJPEG12(sp, fail, op,params) CALLJPEGX(sp, fail,
op##12##params)
#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,
((op##params),1))
#define CALLVJPEG12(sp, op, params) CALLJPEGX(sp, 0,
((op##12##params),1))
#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
(http://bugzilla.remotesensing.org/show_bug.cgi?id=451).
it can not read, neither write directly this file format. A possible
solution:
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.
TiffLib::tiff_tile.c::TIFFTileRowSize
..
//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;
..
TiffLib::tiff_tile.c::TIFFVTileSize
...
//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);
...
TiffLib::tiff_strip.c::TIFFScanlineSize
...
//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;
...
TiffLib::tiff_strip.c::TIFFRasterScanlineSize
...
//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;
...
TiffLib::tiff_strip.c::TIFFVStripSize
...
//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
TiffLib::tiff_jpeg.c::JPEGPreEncode
...
//if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
// sp->cinfo.c.optimize_coding = FALSE;
//else
// sp->cinfo.c.optimize_coding = TRUE;
if ((sp->jpegtablesmode & JPEGTABLESMODE_HUFF) &&
sp->tif->tif_dir.td_bitspersample == 8)
sp->cinfo.c.optimize_coding = FALSE;
else
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 http://www.icc.es
|
|||||||