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

📄 tif_jpeg.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 4 页
字号:
            /* 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];#ifdef JPEG_LIB_MK1                    JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;#else                    JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;#endif                    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;                }            }#ifdef JPEG_LIB_MK1            {                if (sp->cinfo.d.data_precision == 8)                {                    int i=0;                    int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components;                    for (i=0; i<len; i++)                    {                        ((unsigned char*)buf)[i] = tmpbuf[i] & 0xff;                    }                }                else                {         // 12-bit                    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 = tmpbuf + 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);                    }                }            }#endif            ++sp->scancount;            ++tif->tif_row;            buf += sp->bytesperline;            cc -= sp->bytesperline;        } while (--nrows > 0);  #ifdef JPEG_LIB_MK1        _TIFFfree(tmpbuf);#endif    }    /* 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);        JPEGInitializeLibJPEG( tif, 0, 0 );	/* 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";        JPEGInitializeLibJPEG( tif, 1, 0 );	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.		 */		{			float *ref;			if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE,					  &ref)) {				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);			}		}		break;	case PHOTOMETRIC_PALETTE:		/* disallowed by Tech Note */	case PHOTOMETRIC_MASK:		TIFFErrorExt(tif->tif_clientdata, 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.	 */#ifdef JPEG_LIB_MK1        /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */	if (td->td_bitspersample != 8 && td->td_bitspersample != 12) #else	if (td->td_bitspersample != BITS_IN_JSAMPLE ) #endif        {		TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %d not allowed for JPEG",			  (int) td->td_bitspersample);		return (0);	}	sp->cinfo.c.data_precision = td->td_bitspersample;#ifdef JPEG_LIB_MK1        sp->cinfo.c.bits_in_jsample = td->td_bitspersample;#endif	if (isTiled(tif)) {		if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) {			TIFFErrorExt(tif->tif_clientdata, module,				  "JPEG tile height must be multiple of %d",				  sp->v_sampling * DCTSIZE);			return (0);		}		if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) {			TIFFErrorExt(tif->tif_clientdata, 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) {			TIFFErrorExt(tif->tif_clientdata, module,				  "RowsPerStrip must be multiple of %d for JPEG",				  sp->v_sampling * DCTSIZE);			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) {		TIFFErrorExt(tif->tif_clientdata, 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)		TIFFWarningExt(tif->tif_clientdata, 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)		TIFFWarningExt(tif->tif_clientdata, 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;			    }			}

⌨️ 快捷键说明

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