⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tif_jpeg.c

📁 这是VCF框架的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
{	(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;	/* Cb,Cr both have sampling factors 1 */	/* so downsampled width of Cb is # of clumps per line */	sp->bytesperline = sizeof(JSAMPLE) * samples_per_clump *		comp_info[1].downsampled_width;	return (1);}/* * JPEG Decoding. */static intJPEGSetupDecode(TIFF* tif){	JPEGState* sp = JState(tif);	TIFFDirectory *td = &tif->tif_dir;	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.	 */	if (isTiled(tif)) {		segment_width = td->td_tilewidth;		segment_height = td->td_tilelength;		sp->bytesperline = TIFFTileRowSize(tif);	} else {		segment_width = td->td_imagewidth;		segment_height = td->td_imagelength - tif->tif_row;		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) {		TIFFError(module, "Improper JPEG strip/tile size");		return (0);	}	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) {			TIFFError(module, "Improper JPEG sampling factors");			return (0);		}		/* 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. */static intJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s){	JPEGState *sp = JState(tif);	tsize_t nrows;	JSAMPROW bufptr[1];	(void) s;	assert(sp != NULL);	/* data is expected to be read in multiples of a scanline */	nrows = cc / sp->bytesperline;	if (cc % sp->bytesperline)		TIFFWarning(tif->tif_name, "fractional scanline not read");	while (nrows-- > 0) {		bufptr[0] = (JSAMPROW) buf;		if (TIFFjpeg_read_scanlines(sp, bufptr, 1) != 1)			return (0);		if (nrows > 0)			tif->tif_row++;		buf += sp->bytesperline;	}	/* Close down the decompressor if we've finished the strip or tile. */	if (sp->cinfo.d.output_scanline == sp->cinfo.d.output_height) {		if (TIFFjpeg_finish_decompress(sp) != TRUE)			return (0);	}	return (1);}/* * Decode a chunk of pixels. * Returned data is downsampled per sampling factors. */static intJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s){	JPEGState *sp = JState(tif);	JSAMPLE* inptr;	JSAMPLE* outptr;	tsize_t nrows;	JDIMENSION clumps_per_line, nclump;	int clumpoffset, ci, xpos, ypos;	jpeg_component_info* compptr;	int samples_per_clump = sp->samplesperclump;	(void) s;	assert(sp != NULL);	/* data is expected to be read in multiples of a scanline */	nrows = cc / sp->bytesperline;	if (cc % sp->bytesperline)		TIFFWarning(tif->tif_name, "fractional scanline not read");	/* Cb,Cr both have sampling factors 1, so this is correct */	clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;	while (nrows-- > 0) {		/* Reload downsampled-data buffer if needed */		if (sp->scancount >= DCTSIZE) {			int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE;			if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n)				return (0);			sp->scancount = 0;		}		/*		 * Fastest way to unseparate the data is to make one pass		 * over the scanline for each row of each component.		 */		clumpoffset = 0;		/* first sample in clump */		for (ci = 0, compptr = sp->cinfo.d.comp_info;		     ci < sp->cinfo.d.num_components;		     ci++, compptr++) {		    int hsamp = compptr->h_samp_factor;		    int vsamp = compptr->v_samp_factor;		    for (ypos = 0; ypos < vsamp; ypos++) {			inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];			outptr = ((JSAMPLE*) buf) + clumpoffset;			if (hsamp == 1) {			    /* fast path for at least Cb and Cr */			    for (nclump = clumps_per_line; nclump-- > 0; ) {				outptr[0] = *inptr++;				outptr += samples_per_clump;			    }			} else {			    /* general case */			    for (nclump = clumps_per_line; nclump-- > 0; ) {				for (xpos = 0; xpos < hsamp; xpos++)				    outptr[xpos] = *inptr++;				outptr += samples_per_clump;			    }			}			clumpoffset += hsamp;		    }		}		sp->scancount++;		if (nrows > 0)			tif->tif_row++;		buf += sp->bytesperline;	}        /* Close down the decompressor if done. */        if (sp->cinfo.d.output_scanline >= sp->cinfo.d.output_height) {            if (TIFFjpeg_finish_decompress(sp) != TRUE)                return (0);        }	return (1);}/* * JPEG Encoding. */static voidunsuppress_quant_table (JPEGState* sp, int tblno){	JQUANT_TBL* qtbl;	if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)		qtbl->sent_table = FALSE;}static voidunsuppress_huff_table (JPEGState* sp, int tblno){	JHUFF_TBL* htbl;	if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)		htbl->sent_table = FALSE;	if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)		htbl->sent_table = FALSE;}static intprepare_JPEGTables(TIFF* tif){	JPEGState* sp = JState(tif);	/* Initialize quant tables for current quality setting */	if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))		return (0);	/* Mark only the tables we want for output */	/* NB: chrominance tables are currently used only with YCbCr */	if (!TIFFjpeg_suppress_tables(sp, TRUE))		return (0);	if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {		unsuppress_quant_table(sp, 0);		if (sp->photometric == PHOTOMETRIC_YCBCR)			unsuppress_quant_table(sp, 1);	}	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) {		unsuppress_huff_table(sp, 0);		if (sp->photometric == PHOTOMETRIC_YCBCR)			unsuppress_huff_table(sp, 1);	}	/* Direct libjpeg output into jpegtables */	if (!TIFFjpeg_tables_dest(sp, tif))		return (0);	/* Emit tables-only datastream */	if (!TIFFjpeg_write_tables(sp))		return (0);	return (1);}static intJPEGSetupEncode(TIFF* tif){	JPEGState* sp = JState(tif);	TIFFDirectory *td = &tif->tif_dir;	static const char module[] = "JPEGSetupEncode";	assert(sp != NULL);	assert(!sp->cinfo.comm.is_decompressor);	/*	 * Initialize all JPEG parameters to default values.	 * Note that jpeg_set_defaults needs legal values for	 * in_color_space and input_components.	 */	sp->cinfo.c.in_color_space = JCS_UNKNOWN;	sp->cinfo.c.input_components = 1;	if (!TIFFjpeg_set_defaults(sp))		return (0);	/* Set per-file parameters */	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];		/*		 * A ReferenceBlackWhite field *must* be present since the		 * default value is inappropriate for YCbCr.  Fill in the		 * proper value if application didn't set it.		 */#ifdef COLORIMETRY_SUPPORT		if (!TIFFFieldSet(tif, FIELD_REFBLACKWHITE)) {			float refbw[6];			long top = 1L << td->td_bitspersample;			refbw[0] = 0;			refbw[1] = (float)(top-1L);			refbw[2] = (float)(top>>1);			refbw[3] = refbw[1];			refbw[4] = refbw[2];			refbw[5] = refbw[1];			TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw);		}#endif		break;	case PHOTOMETRIC_PALETTE:		/* disallowed by Tech Note */	case PHOTOMETRIC_MASK:		TIFFError(module,			  "PhotometricInterpretation %d not allowed for JPEG",			  (int) sp->photometric);		return (0);	default:		/* TIFF 6.0 forbids subsampling of all other color spaces */		sp->h_sampling = 1;		sp->v_sampling = 1;		break;	}		/* Verify miscellaneous parameters */	/*	 * This would need work if libtiff ever supports different	 * depths for different components, or if libjpeg ever supports	 * run-time selection of depth.  Neither is imminent.	 */	if (td->td_bitspersample != BITS_IN_JSAMPLE) {		TIFFError(module, "BitsPerSample %d not allowed for JPEG",			  (int) td->td_bitspersample);		return (0);	}	sp->cinfo.c.data_precision = td->td_bitspersample;	if (isTiled(tif)) {		if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) {			TIFFError(module,				  "JPEG tile height must be multiple of %d",				  sp->v_sampling * DCTSIZE);			return (0);		}		if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) {			TIFFError(module,				  "JPEG tile width must be multiple of %d",				  sp->h_sampling * DCTSIZE);			return (0);		}	} else {		if (td->td_rowsperstrip < td->td_imagelength &&		    (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -