?? tif_jpeg.c
字號:
return (1);}/* * JPEG library source data manager. * These routines supply compressed data to libjpeg. */static voidstd_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 booleanstd_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 voidstd_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 voidstd_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 voidTIFFjpeg_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 voidtables_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 voidTIFFjpeg_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 intalloc_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 intJPEGSetupDecode(TIFF* tif){ JPEGState* sp = JState(tif); TIFFDirectory *td = &tif->tif_dir; JPEGInitializeLibJPEG( tif, 0, 1 ); 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) { TIFFErrorExt(tif->tif_clientdata, "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 intJPEGPreDecode(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 = TIFFOldScanlineSize(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) { TIFFWarningExt(tif->tif_clientdata, 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.image_width > segment_width || sp->cinfo.d.image_height > segment_height) { /* * This case could be dangerous, if the strip or tile size has * been reported as less than the amount of data jpeg will * return, some potential security issues arise. Catch this * case and error out. */ TIFFErrorExt(tif->tif_clientdata, module, "JPEG strip/tile size exceeds expected dimensions," " expected %dx%d, got %dx%d", segment_width, segment_height, sp->cinfo.d.image_width, sp->cinfo.d.image_height); return (0); } if (sp->cinfo.d.num_components != (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1)) { TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count"); return (0); }#ifdef JPEG_LIB_MK1 if (12 != td->td_bitspersample && 8 != td->td_bitspersample) { TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); return (0); } sp->cinfo.d.data_precision = td->td_bitspersample; sp->cinfo.d.bits_in_jsample = td->td_bitspersample;#else if (sp->cinfo.d.data_precision != td->td_bitspersample) { TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision"); return (0); }#endif 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) { TIFFWarningExt(tif->tif_clientdata, 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); /* * There are potential security issues here * for decoders that have already allocated * buffers based on the expected sampling * factors. Lets check the sampling factors * dont exceed what we were expecting. */ 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) { TIFFErrorExt(tif->tif_clientdata, module, "Cannot honour JPEG sampling factors" " that exceed those specified."); return (0); } /* * 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)) { TIFFWarningExt(tif->tif_clientdata, 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) { TIFFErrorExt(tif->tif_clientdata, 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) { TIFFErrorExt(tif->tif_clientdata, 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; /* XXX what about up-sampling? */ } 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 intJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s){ JPEGState *sp = JState(tif); tsize_t nrows; (void) s; nrows = cc / sp->bytesperline; if (cc % sp->bytesperline) TIFFWarningExt(tif->tif_clientdata, 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) { JSAMPROW line_work_buf = NULL; /* ** For 6B, only use temporary buffer for 12 bit imagery. ** For Mk1 always use it. */#if !defined(JPEG_LIB_MK1) if( sp->cinfo.d.data_precision == 12 )#endif { line_work_buf = (JSAMPROW) _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width * sp->cinfo.d.num_components ); } do { if( line_work_buf != NULL ) { /* ** In the MK1 case, we aways read into a 16bit buffer, and then ** pack down to 12bit or 8bit. In 6B case we only read into 16 ** bit buffer for 12bit data, which we need to repack. */ if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) return (0); if( sp->cinfo.d.data_precision == 12 ) { int value_pairs = (sp->cinfo.d.output_width * sp->cinfo.d.num_components) / 2; int iPair; for( iPair = 0; iPair < value_pairs; iPair++ ) { unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3; JSAMPLE *in_ptr = line_work_buf + iPair * 2; out_ptr[0] = (in_ptr[0] & 0xff0) >> 4; out_ptr[1] = ((in_ptr[0] & 0xf) << 4) | ((in_ptr[1] & 0xf00) >> 8); out_ptr[2] = ((in_ptr[1] & 0xff) >> 0); } } else if( sp->cinfo.d.data_precision == 8 ) { int value_count = (sp->cinfo.d.output_width * sp->cinfo.d.num_components); int iValue; for( iValue = 0; iValue < value_count; iValue++ ) { ((unsigned char *) buf)[iValue] = line_work_buf[iValue] & 0xff; } } } else { /* ** In the libjpeg6b 8bit case. We read directly into the ** TIFF buffer. */ 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); if( line_work_buf != NULL ) _TIFFfree( line_work_buf ); } /* 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 intJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s){ JPEGState *sp = JState(tif); tsize_t nrows; (void) s; /* 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;#ifdef JPEG_LIB_MK1 unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) * sp->cinfo.d.output_width * sp->cinfo.d.num_components);#endif do { jpeg_component_info *compptr; int ci, clumpoffset; /* Reload downsampled-data buffer if needed */ if (sp->scancount >= DCTSIZE) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -