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

📄 tif_jpeg.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* 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;	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)) {		if (segment_height > td->td_tilelength)			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) {		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. *//*ARGSUSED*/ static intJPEGDecode(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)		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;				if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n)					!= n)					return (0);				sp->scancount = 0;			}			/*			 * Fastest way to unseparate 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;			    int ypos;			    for (ypos = 0; ypos < vsamp; ypos++) {				JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];				JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;				JDIMENSION nclump;				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 {					int xpos;				    /* 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;			++tif->tif_row;			buf += sp->bytesperline;			cc -= sp->bytesperline;		} while (--nrows > 0);	}        /* Close down the decompressor if done. */        return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height       	    || TIFFjpeg_finish_decompress(sp);}/* * 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) {			TIFFError(module,				  "RowsPerStrip must be multiple of %d for JPEG",				  sp->v_sampling * DCTSIZE);

⌨️ 快捷键说明

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