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

📄 tif_jpeg.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 3 页
字号:
			return (0);		}	}	/* Create a JPEGTables field if appropriate */	if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) {		if (!prepare_JPEGTables(tif))			return (0);		/* Mark the field present */		/* Can't use TIFFSetField since BEENWRITING is already set! */		TIFFSetFieldBit(tif, FIELD_JPEGTABLES);		tif->tif_flags |= TIFF_DIRTYDIRECT;	} else {		/* We do not support application-supplied JPEGTables, */		/* so mark the field not present */		TIFFClrFieldBit(tif, FIELD_JPEGTABLES);	}	/* Direct libjpeg output to libtiff's output buffer */	TIFFjpeg_data_dest(sp, tif);	return (1);}/* * Set encoding state at the start of a strip or tile. */static intJPEGPreEncode(TIFF* tif, tsample_t s){	JPEGState *sp = JState(tif);	TIFFDirectory *td = &tif->tif_dir;	static const char module[] = "JPEGPreEncode";	uint32 segment_width, segment_height;	int downsampled_input;	assert(sp != NULL);	assert(!sp->cinfo.comm.is_decompressor);	/*	 * Set encoding parameters for this strip/tile.	 */	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 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 (segment_width > 65535 || segment_height > 65535) {		TIFFError(module, "Strip/tile too large for JPEG");		return (0);	}	sp->cinfo.c.image_width = segment_width;	sp->cinfo.c.image_height = segment_height;	downsampled_input = FALSE;	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {		sp->cinfo.c.input_components = td->td_samplesperpixel;		if (sp->photometric == PHOTOMETRIC_YCBCR) {			if (sp->jpegcolormode == JPEGCOLORMODE_RGB) {				sp->cinfo.c.in_color_space = JCS_RGB;			} else {				sp->cinfo.c.in_color_space = JCS_YCbCr;				if (sp->h_sampling != 1 || sp->v_sampling != 1)					downsampled_input = TRUE;			}			if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr))				return (0);			/*			 * Set Y sampling factors;			 * we assume jpeg_set_colorspace() set the rest to 1			 */			sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;			sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;		} else {			sp->cinfo.c.in_color_space = JCS_UNKNOWN;			if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))				return (0);			/* jpeg_set_colorspace set all sampling factors to 1 */		}	} else {		sp->cinfo.c.input_components = 1;		sp->cinfo.c.in_color_space = JCS_UNKNOWN;		if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))			return (0);		sp->cinfo.c.comp_info[0].component_id = s;		/* jpeg_set_colorspace() set sampling factors to 1 */		if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) {			sp->cinfo.c.comp_info[0].quant_tbl_no = 1;			sp->cinfo.c.comp_info[0].dc_tbl_no = 1;			sp->cinfo.c.comp_info[0].ac_tbl_no = 1;		}	}	/* ensure libjpeg won't write any extraneous markers */	sp->cinfo.c.write_JFIF_header = FALSE;	sp->cinfo.c.write_Adobe_marker = FALSE;	/* set up table handling correctly */	if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) {		if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))			return (0);		unsuppress_quant_table(sp, 0);		unsuppress_quant_table(sp, 1);	}	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)		sp->cinfo.c.optimize_coding = FALSE;	else		sp->cinfo.c.optimize_coding = TRUE;	if (downsampled_input) {		/* Need to use raw-data interface to libjpeg */		sp->cinfo.c.raw_data_in = TRUE;		tif->tif_encoderow = JPEGEncodeRaw;		tif->tif_encodestrip = JPEGEncodeRaw;		tif->tif_encodetile = JPEGEncodeRaw;	} else {		/* Use normal interface to libjpeg */		sp->cinfo.c.raw_data_in = FALSE;		tif->tif_encoderow = JPEGEncode;		tif->tif_encodestrip = JPEGEncode;		tif->tif_encodetile = JPEGEncode;	}	/* Start JPEG compressor */	if (!TIFFjpeg_start_compress(sp, FALSE))		return (0);	/* Allocate downsampled-data buffers if needed */	if (downsampled_input) {		if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,					       sp->cinfo.c.num_components))			return (0);	}	sp->scancount = 0;	return (1);}/* * Encode a chunk of pixels. * "Standard" case: incoming data is not downsampled. */static intJPEGEncode(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 supplied in multiples of a scanline */	nrows = cc / sp->bytesperline;	if (cc % sp->bytesperline)		TIFFWarning(tif->tif_name, "fractional scanline discarded");	while (nrows-- > 0) {		bufptr[0] = (JSAMPROW) buf;		if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)			return (0);		if (nrows > 0)			tif->tif_row++;		buf += sp->bytesperline;	}	return (1);}/* * Encode a chunk of pixels. * Incoming data is expected to be downsampled per sampling factors. */static intJPEGEncodeRaw(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 supplied in multiples of a scanline */	nrows = cc / sp->bytesperline;	if (cc % sp->bytesperline)		TIFFWarning(tif->tif_name, "fractional scanline discarded");	/* Cb,Cr both have sampling factors 1, so this is correct */	clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width;	while (nrows-- > 0) {		/*		 * Fastest way to separate 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.c.comp_info;		     ci < sp->cinfo.c.num_components;		     ci++, compptr++) {		    int hsamp = compptr->h_samp_factor;		    int vsamp = compptr->v_samp_factor;		    int padding = (int) (compptr->width_in_blocks * DCTSIZE -					 clumps_per_line * hsamp);		    for (ypos = 0; ypos < vsamp; ypos++) {			inptr = ((JSAMPLE*) buf) + clumpoffset;			outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];			if (hsamp == 1) {			    /* fast path for at least Cb and Cr */			    for (nclump = clumps_per_line; nclump-- > 0; ) {				*outptr++ = inptr[0];				inptr += samples_per_clump;			    }			} else {			    /* general case */			    for (nclump = clumps_per_line; nclump-- > 0; ) {				for (xpos = 0; xpos < hsamp; xpos++)				    *outptr++ = inptr[xpos];				inptr += samples_per_clump;			    }			}			/* pad each scanline as needed */			for (xpos = 0; xpos < padding; xpos++) {			    *outptr = outptr[-1];			    outptr++;			}			clumpoffset += hsamp;		    }		}		sp->scancount++;		if (sp->scancount >= DCTSIZE) {			int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;			if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)				return (0);			sp->scancount = 0;		}		if (nrows > 0)			tif->tif_row++;		buf += sp->bytesperline;	}	return (1);}/* * Finish up at the end of a strip or tile. */static intJPEGPostEncode(TIFF* tif){	JPEGState *sp = JState(tif);	if (sp->scancount > 0) {		/*		 * Need to emit a partial bufferload of downsampled data.		 * Pad the data vertically.		 */		int ci, ypos, n;		jpeg_component_info* compptr;		for (ci = 0, compptr = sp->cinfo.c.comp_info;		     ci < sp->cinfo.c.num_components;		     ci++, compptr++) {			int vsamp = compptr->v_samp_factor;			tsize_t row_width = compptr->width_in_blocks * DCTSIZE				* sizeof(JSAMPLE);			for (ypos = sp->scancount * vsamp;			     ypos < DCTSIZE * vsamp; ypos++) {				_TIFFmemcpy((tdata_t)sp->ds_buffer[ci][ypos],					    (tdata_t)sp->ds_buffer[ci][ypos-1],					    row_width);			}		}		n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;		if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)			return (0);	}	return (TIFFjpeg_finish_compress(JState(tif)));}static voidJPEGCleanup(TIFF* tif){	if (tif->tif_data) {		JPEGState *sp = JState(tif);		TIFFjpeg_destroy(sp);		/* release libjpeg resources */		if (sp->jpegtables)		/* tag value */			_TIFFfree(sp->jpegtables);		_TIFFfree(tif->tif_data);	/* release local state */		tif->tif_data = NULL;	}}static intJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap){	JPEGState* sp = JState(tif);	TIFFDirectory* td = &tif->tif_dir;	uint32 v32;	switch (tag) {	case TIFFTAG_JPEGTABLES:		v32 = va_arg(ap, uint32);		if (v32 == 0) {			/* XXX */			return (0);		}		_TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*),		    (long) v32);		sp->jpegtables_length = v32;		TIFFSetFieldBit(tif, FIELD_JPEGTABLES);		break;	case TIFFTAG_JPEGQUALITY:		sp->jpegquality = va_arg(ap, int);		return (1);			/* pseudo tag */	case TIFFTAG_JPEGCOLORMODE:		sp->jpegcolormode = va_arg(ap, int);		/*		 * Mark whether returned data is up-sampled or not		 * so TIFFStripSize and TIFFTileSize return values		 * that reflect the true amount of data.		 */		tif->tif_flags &= ~TIFF_UPSAMPLED;		if (td->td_planarconfig == PLANARCONFIG_CONTIG) {		    if (td->td_photometric == PHOTOMETRIC_YCBCR &&		      sp->jpegcolormode == JPEGCOLORMODE_RGB) {			tif->tif_flags |= TIFF_UPSAMPLED;		    } else {			if (td->td_ycbcrsubsampling[0] != 1 ||			    td->td_ycbcrsubsampling[1] != 1)			    ; /* XXX what about up-sampling? */		    }		}		/*		 * Must recalculate cached tile size		 * in case sampling state changed.		 */		tif->tif_tilesize = TIFFTileSize(tif);		return (1);			/* pseudo tag */	case TIFFTAG_JPEGTABLESMODE:		sp->jpegtablesmode = va_arg(ap, int);		return (1);			/* pseudo tag */	default:		return (*sp->vsetparent)(tif, tag, ap);	}	tif->tif_flags |= TIFF_DIRTYDIRECT;	return (1);}static intJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap){	JPEGState* sp = JState(tif);	switch (tag) {	case TIFFTAG_JPEGTABLES:		/* u_short is bogus --- should be uint32 ??? */		/* TIFFWriteNormalTag needs fixed  XXX */		*va_arg(ap, u_short*) = (u_short) sp->jpegtables_length;		*va_arg(ap, void**) = sp->jpegtables;		break;	case TIFFTAG_JPEGQUALITY:		*va_arg(ap, int*) = sp->jpegquality;		break;	case TIFFTAG_JPEGCOLORMODE:		*va_arg(ap, int*) = sp->jpegcolormode;		break;	case TIFFTAG_JPEGTABLESMODE:		*va_arg(ap, int*) = sp->jpegtablesmode;		break;	default:		return (*sp->vgetparent)(tif, tag, ap);	}	return (1);}static voidJPEGPrintDir(TIFF* tif, FILE* fd, long flags){	JPEGState* sp = JState(tif);	(void) flags;	if (TIFFFieldSet(tif,FIELD_JPEGTABLES))		fprintf(fd, "  JPEG Tables: (%lu bytes)\n",			(u_long) sp->jpegtables_length);}static uint32JPEGDefaultStripSize(TIFF* tif, uint32 s){	JPEGState* sp = JState(tif);	TIFFDirectory *td = &tif->tif_dir;	s = (*sp->defsparent)(tif, s);	if (s < td->td_imagelength)		s = TIFFroundup(s, td->td_ycbcrsubsampling[1] * DCTSIZE);	return (s);}static voidJPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th){	JPEGState* sp = JState(tif);	TIFFDirectory *td = &tif->tif_dir;	(*sp->deftparent)(tif, tw, th);	*tw = TIFFroundup(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE);	*th = TIFFroundup(*th, td->td_ycbcrsubsampling[1] * DCTSIZE);}intTIFFInitJPEG(TIFF* tif, int scheme){	JPEGState* sp;	assert(scheme == COMPRESSION_JPEG);	/*	 * Allocate state block so tag methods have storage to record values.	 */	tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (JPEGState));	if (tif->tif_data == NULL) {		TIFFError("TIFFInitJPEG", "No space for JPEG state block");		return (0);	}	sp = JState(tif);	sp->tif = tif;				/* back link */	/*	 * Merge codec-specific tag information and	 * override parent get/set field methods.	 */	_TIFFMergeFieldInfo(tif, jpegFieldInfo, N(jpegFieldInfo));	sp->vgetparent = tif->tif_vgetfield;	tif->tif_vgetfield = JPEGVGetField;	/* hook for codec tags */	sp->vsetparent = tif->tif_vsetfield;	tif->tif_vsetfield = JPEGVSetField;	/* hook for codec tags */	tif->tif_printdir = JPEGPrintDir;	/* hook for codec tags */	/* Default values for codec-specific fields */	sp->jpegtables = NULL;	sp->jpegtables_length = 0;	sp->jpegquality = 75;			/* Default IJG quality */	sp->jpegcolormode = JPEGCOLORMODE_RAW;	sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF;	/*	 * Install codec methods.	 */	tif->tif_setupdecode = JPEGSetupDecode;	tif->tif_predecode = JPEGPreDecode;	tif->tif_decoderow = JPEGDecode;	tif->tif_decodestrip = JPEGDecode;	tif->tif_decodetile = JPEGDecode;	tif->tif_setupencode = JPEGSetupEncode;	tif->tif_preencode = JPEGPreEncode;	tif->tif_postencode = JPEGPostEncode;	tif->tif_encoderow = JPEGEncode;	tif->tif_encodestrip = JPEGEncode;	tif->tif_encodetile = JPEGEncode;	tif->tif_cleanup = JPEGCleanup;	sp->defsparent = tif->tif_defstripsize;	tif->tif_defstripsize = JPEGDefaultStripSize;	sp->deftparent = tif->tif_deftilesize;	tif->tif_deftilesize = JPEGDefaultTileSize;	tif->tif_flags |= TIFF_NOBITREV;	/* no bit reversal, please */	/*	 * Initialize libjpeg.	 */	if (tif->tif_mode == O_RDONLY) {		if (!TIFFjpeg_create_decompress(sp))			return (0);	} else {		if (!TIFFjpeg_create_compress(sp))			return (0);	}	return (1);}#endif /* JPEG_SUPPORT */

⌨️ 快捷键说明

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