?? tif_jpeg.c
字號:
if (newbuf == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length;
sp->dest.free_in_buffer = (size_t) 1000;
sp->jpegtables = newbuf;
sp->jpegtables_length += 1000;
return (TRUE);
}
static void
tables_term_destination(j_compress_ptr cinfo)
{
JPEGState* sp = (JPEGState*) cinfo;
/* set tables length to number of bytes actually emitted */
sp->jpegtables_length -= sp->dest.free_in_buffer;
}
static int
TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif)
{
(void) tif;
/*
* Allocate a working buffer for building tables.
* Initial size is 1000 bytes, which is usually adequate.
*/
if (sp->jpegtables)
_TIFFfree(sp->jpegtables);
sp->jpegtables_length = 1000;
sp->jpegtables = (void*) _TIFFmalloc((tsize_t) sp->jpegtables_length);
if (sp->jpegtables == NULL) {
sp->jpegtables_length = 0;
TIFFError("TIFFjpeg_tables_dest", "No space for JPEGTables");
return (0);
}
sp->cinfo.c.dest = &sp->dest;
sp->dest.init_destination = tables_init_destination;
sp->dest.empty_output_buffer = tables_empty_output_buffer;
sp->dest.term_destination = tables_term_destination;
return (1);
}
/*
* JPEG library source data manager.
* These routines supply compressed data to libjpeg.
*/
static void
std_init_source(j_decompress_ptr cinfo)
{
JPEGState* sp = (JPEGState*) cinfo;
TIFF* tif = sp->tif;
sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata;
sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
}
static boolean
std_fill_input_buffer(j_decompress_ptr cinfo)
{
JPEGState* sp = (JPEGState* ) cinfo;
static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI };
/*
* Should never get here since entire strip/tile is
* read into memory before the decompressor is called,
* and thus was supplied by init_source.
*/
WARNMS(cinfo, JWRN_JPEG_EOF);
/* insert a fake EOI marker */
sp->src.next_input_byte = dummy_EOI;
sp->src.bytes_in_buffer = 2;
return (TRUE);
}
static void
std_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
JPEGState* sp = (JPEGState*) cinfo;
if (num_bytes > 0) {
if (num_bytes > (long) sp->src.bytes_in_buffer) {
/* oops, buffer overrun */
(void) std_fill_input_buffer(cinfo);
} else {
sp->src.next_input_byte += (size_t) num_bytes;
sp->src.bytes_in_buffer -= (size_t) num_bytes;
}
}
}
static void
std_term_source(j_decompress_ptr cinfo)
{
/* No work necessary here */
/* Or must we update tif->tif_rawcp, tif->tif_rawcc ??? */
/* (if so, need empty tables_term_source!) */
(void) cinfo;
}
static void
TIFFjpeg_data_src(JPEGState* sp, TIFF* tif)
{
(void) tif;
sp->cinfo.d.src = &sp->src;
sp->src.init_source = std_init_source;
sp->src.fill_input_buffer = std_fill_input_buffer;
sp->src.skip_input_data = std_skip_input_data;
sp->src.resync_to_restart = jpeg_resync_to_restart;
sp->src.term_source = std_term_source;
sp->src.bytes_in_buffer = 0; /* for safety */
sp->src.next_input_byte = NULL;
}
/*
* Alternate source manager for reading from JPEGTables.
* We can share all the code except for the init routine.
*/
static void
tables_init_source(j_decompress_ptr cinfo)
{
JPEGState* sp = (JPEGState*) cinfo;
sp->src.next_input_byte = (const JOCTET*) sp->jpegtables;
sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length;
}
static void
TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif)
{
TIFFjpeg_data_src(sp, tif);
sp->src.init_source = tables_init_source;
}
/*
* Allocate downsampled-data buffers needed for downsampled I/O.
* We use values computed in jpeg_start_compress or jpeg_start_decompress.
* We use libjpeg's allocator so that buffers will be released automatically
* when done with strip/tile.
* This is also a handy place to compute samplesperclump, bytesperline.
*/
static int
alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info,
int num_components)
{
JPEGState* sp = JState(tif);
int ci;
jpeg_component_info* compptr;
JSAMPARRAY buf;
int samples_per_clump = 0;
for (ci = 0, compptr = comp_info; ci < num_components;
ci++, compptr++) {
samples_per_clump += compptr->h_samp_factor *
compptr->v_samp_factor;
buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE,
compptr->width_in_blocks * DCTSIZE,
(JDIMENSION) (compptr->v_samp_factor*DCTSIZE));
if (buf == NULL)
return (0);
sp->ds_buffer[ci] = buf;
}
sp->samplesperclump = samples_per_clump;
return (1);
}
/*
* JPEG Decoding.
*/
static int
JPEGSetupDecode(TIFF* tif)
{
JPEGState* sp = JState(tif);
TIFFDirectory *td = &tif->tif_dir;
JPEGInitializeLibJPEG( tif );
assert(sp != NULL);
assert(sp->cinfo.comm.is_decompressor);
/* Read JPEGTables if it is present */
if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) {
TIFFjpeg_tables_src(sp, tif);
if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) {
TIFFError("JPEGSetupDecode", "Bogus JPEGTables field");
return (0);
}
}
/* Grab parameters that are same for all strips/tiles */
sp->photometric = td->td_photometric;
switch (sp->photometric) {
case PHOTOMETRIC_YCBCR:
sp->h_sampling = td->td_ycbcrsubsampling[0];
sp->v_sampling = td->td_ycbcrsubsampling[1];
break;
default:
/* TIFF 6.0 forbids subsampling of all other color spaces */
sp->h_sampling = 1;
sp->v_sampling = 1;
break;
}
/* Set up for reading normal data */
TIFFjpeg_data_src(sp, tif);
tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
return (1);
}
/*
* Set up for decoding a strip or tile.
*/
static int
JPEGPreDecode(TIFF* tif, tsample_t s)
{
JPEGState *sp = JState(tif);
TIFFDirectory *td = &tif->tif_dir;
static const char module[] = "JPEGPreDecode";
uint32 segment_width, segment_height;
int downsampled_output;
int ci;
assert(sp != NULL);
assert(sp->cinfo.comm.is_decompressor);
/*
* Reset decoder state from any previous strip/tile,
* in case application didn't read the whole strip.
*/
if (!TIFFjpeg_abort(sp))
return (0);
/*
* Read the header for this strip/tile.
*/
if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK)
return (0);
/*
* Check image parameters and set decompression parameters.
*/
segment_width = td->td_imagewidth;
segment_height = td->td_imagelength - tif->tif_row;
if (isTiled(tif)) {
segment_width = td->td_tilewidth;
segment_height = td->td_tilelength;
sp->bytesperline = TIFFTileRowSize(tif);
} else {
if (segment_height > td->td_rowsperstrip)
segment_height = td->td_rowsperstrip;
sp->bytesperline = TIFFScanlineSize(tif);
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
/*
* For PC 2, scale down the expected strip/tile size
* to match a downsampled component
*/
segment_width = TIFFhowmany(segment_width, sp->h_sampling);
segment_height = TIFFhowmany(segment_height, sp->v_sampling);
}
if (sp->cinfo.d.image_width != segment_width ||
sp->cinfo.d.image_height != segment_height) {
TIFFWarning(module,
"Improper JPEG strip/tile size, expected %dx%d, got %dx%d",
segment_width,
segment_height,
sp->cinfo.d.image_width,
sp->cinfo.d.image_height);
}
if (sp->cinfo.d.num_components !=
(td->td_planarconfig == PLANARCONFIG_CONTIG ?
td->td_samplesperpixel : 1)) {
TIFFError(module, "Improper JPEG component count");
return (0);
}
if (sp->cinfo.d.data_precision != td->td_bitspersample) {
TIFFError(module, "Improper JPEG data precision");
return (0);
}
if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
/* Component 0 should have expected sampling factors */
if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) {
TIFFWarning(module,
"Improper JPEG sampling factors %d,%d\n"
"Apparently should be %d,%d.",
sp->cinfo.d.comp_info[0].h_samp_factor,
sp->cinfo.d.comp_info[0].v_samp_factor,
sp->h_sampling, sp->v_sampling);
/*
* XXX: Files written by the Intergraph software
* has different sampling factors stored in the
* TIFF tags and in the JPEG structures. We will
* try to deduce Intergraph files by the presense
* of the tag 33918.
*/
if (!_TIFFFindFieldInfo(tif, 33918, TIFF_ANY)) {
TIFFWarning(module,
"Decompressor will try reading with "
"sampling %d,%d.",
sp->cinfo.d.comp_info[0].h_samp_factor,
sp->cinfo.d.comp_info[0].v_samp_factor);
sp->h_sampling = (uint16)
sp->cinfo.d.comp_info[0].h_samp_factor;
sp->v_sampling = (uint16)
sp->cinfo.d.comp_info[0].v_samp_factor;
}
}
/* Rest should have sampling factors 1,1 */
for (ci = 1; ci < sp->cinfo.d.num_components; ci++) {
if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 ||
sp->cinfo.d.comp_info[ci].v_samp_factor != 1) {
TIFFError(module, "Improper JPEG sampling factors");
return (0);
}
}
} else {
/* PC 2's single component should have sampling factors 1,1 */
if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 ||
sp->cinfo.d.comp_info[0].v_samp_factor != 1) {
TIFFError(module, "Improper JPEG sampling factors");
return (0);
}
}
downsampled_output = FALSE;
if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
sp->photometric == PHOTOMETRIC_YCBCR &&
sp->jpegcolormode == JPEGCOLORMODE_RGB) {
/* Convert YCbCr to RGB */
sp->cinfo.d.jpeg_color_space = JCS_YCbCr;
sp->cinfo.d.out_color_space = JCS_RGB;
} else {
/* Suppress colorspace handling */
sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN;
sp->cinfo.d.out_color_space = JCS_UNKNOWN;
if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
(sp->h_sampling != 1 || sp->v_sampling != 1))
downsampled_output = TRUE;
}
if (downsampled_output) {
/* Need to use raw-data interface to libjpeg */
sp->cinfo.d.raw_data_out = TRUE;
tif->tif_decoderow = JPEGDecodeRaw;
tif->tif_decodestrip = JPEGDecodeRaw;
tif->tif_decodetile = JPEGDecodeRaw;
} else {
/* Use normal interface to libjpeg */
sp->cinfo.d.raw_data_out = FALSE;
tif->tif_decoderow = JPEGDecode;
tif->tif_decodestrip = JPEGDecode;
tif->tif_decodetile = JPEGDecode;
}
/* Start JPEG decompressor */
if (!TIFFjpeg_start_decompress(sp))
return (0);
/* Allocate downsampled-data buffers if needed */
if (downsampled_output) {
if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
sp->cinfo.d.num_components))
return (0);
sp->scancount = DCTSIZE; /* mark buffer empty */
}
return (1);
}
/*
* Decode a chunk of pixels.
* "Standard" case: returned data is not downsampled.
*/
/*ARGSUSED*/ static int
JPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
{
JPEGState *sp = JState(tif);
tsize_t nrows;
nrows = cc / sp->bytesperline;
if (cc % sp->bytesperline)
TIFFWarning(tif->tif_name, "fractional scanline not read");
if( nrows > (int) sp->cinfo.d.image_height )
nrows = sp->cinfo.d.image_height;
/* data is expected to be read in multiples of a scanline */
if (nrows)
{
do {
JSAMPROW bufptr = (JSAMPROW)buf;
if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
return (0);
++tif->tif_row;
buf += sp->bytesperline;
cc -= sp->bytesperline;
} while (--nrows > 0);
}
/* Close down the decompressor if we've finished the strip or tile. */
return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
|| TIFFjpeg_finish_decompress(sp);
}
/*
* Decode a chunk of pixels.
* Returned data is downsampled per sampling factors.
*/
/*ARGSUSED*/ static int
JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
{
JPEGState *sp = JState(tif);
tsize_t nrows;
/* data is expected to be read in multiples of a scanline */
if ( (nrows = sp->cinfo.d.image_height) ) {
/* Cb,Cr both have sampling factors 1, so this is correct */
JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;
int samples_per_clump = sp->samplesperclump;
do {
jpeg_component_info *compptr;
int ci, clumpoffset;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -