📄 tif_jpeg.c
字号:
sp->dest.free_in_buffer = (size_t) sp->jpegtables_length;}static booleantables_empty_output_buffer(j_compress_ptr cinfo){ JPEGState* sp = (JPEGState*) cinfo; void* newbuf; /* the entire buffer has been filled; enlarge it by 1000 bytes */ newbuf = _TIFFrealloc((tdata_t) sp->jpegtables, (tsize_t) (sp->jpegtables_length + 1000)); 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 voidtables_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 intTIFFjpeg_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 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 ); 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 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 = 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; /* 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; 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 intJPEGDecodeRaw(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; /* Reload downsampled-data buffer if needed */ if (sp->scancount >= DCTSIZE) { int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -