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

📄 tif_luv.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 3 页
字号:
static voidLuv32toXYZ(LogLuvState* sp, tidata_t op, int n){	uint32* luv = (uint32*) sp->tbuf;	float* xyz = (float*) op;	while (n-- > 0) {		LogLuv32toXYZ(*luv++, xyz);		xyz += 3;	}}static voidLuv32toLuv48(LogLuvState* sp, tidata_t op, int n){	uint32* luv = (uint32*) sp->tbuf;	int16* luv3 = (int16*) op;	while (n-- > 0) {		double u, v;		*luv3++ = (int16)(*luv >> 16);		u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5);		v = 1./UVSCALE * ((*luv & 0xff) + .5);		*luv3++ = (int16)(u * (1L<<15));		*luv3++ = (int16)(v * (1L<<15));		luv++;	}}static voidLuv32toRGB(LogLuvState* sp, tidata_t op, int n){	uint32* luv = (uint32*) sp->tbuf;	uint8* rgb = (uint8*) op;	while (n-- > 0) {		float xyz[3];		LogLuv32toXYZ(*luv++, xyz);		XYZtoRGB24(xyz, rgb);		rgb += 3;	}}static voidLuv32fromXYZ(LogLuvState* sp, tidata_t op, int n){	uint32* luv = (uint32*) sp->tbuf;	float* xyz = (float*) op;	while (n-- > 0) {		*luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth);		xyz += 3;	}}static voidLuv32fromLuv48(LogLuvState* sp, tidata_t op, int n){	uint32* luv = (uint32*) sp->tbuf;	int16* luv3 = (int16*) op;	if (sp->encode_meth == SGILOGENCODE_NODITHER) {		while (n-- > 0) {			*luv++ = (uint32)luv3[0] << 16 |				(luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) |				(luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff);			luv3 += 3;		}		return;	}	while (n-- > 0) {		*luv++ = (uint32)luv3[0] << 16 |	(itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |		(itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);		luv3 += 3;	}}static void_logLuvNop(LogLuvState* sp, tidata_t op, int n){	(void) sp; (void) op; (void) n;}static intLogL16GuessDataFmt(TIFFDirectory *td){#define	PACK(s,b,f)	(((b)<<6)|((s)<<3)|(f))	switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) {	case PACK(1, 32, SAMPLEFORMAT_IEEEFP):		return (SGILOGDATAFMT_FLOAT);	case PACK(1, 16, SAMPLEFORMAT_VOID):	case PACK(1, 16, SAMPLEFORMAT_INT):	case PACK(1, 16, SAMPLEFORMAT_UINT):		return (SGILOGDATAFMT_16BIT);	case PACK(1,  8, SAMPLEFORMAT_VOID):	case PACK(1,  8, SAMPLEFORMAT_UINT):		return (SGILOGDATAFMT_8BIT);	}#undef PACK	return (SGILOGDATAFMT_UNKNOWN);}static intLogL16InitState(TIFF* tif){	TIFFDirectory *td = &tif->tif_dir;	LogLuvState* sp = DecoderState(tif);	static const char module[] = "LogL16InitState";	assert(sp != NULL);	assert(td->td_photometric == PHOTOMETRIC_LOGL);	/* for some reason, we can't do this in TIFFInitLogL16 */	if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)		sp->user_datafmt = LogL16GuessDataFmt(td);	switch (sp->user_datafmt) {	case SGILOGDATAFMT_FLOAT:		sp->pixel_size = sizeof (float);		break;	case SGILOGDATAFMT_16BIT:		sp->pixel_size = sizeof (int16);		break;	case SGILOGDATAFMT_8BIT:		sp->pixel_size = sizeof (uint8);		break;	default:		TIFFError(tif->tif_name,		    "No support for converting user data format to LogL");		return (0);	}	sp->tbuflen = td->td_imagewidth * td->td_rowsperstrip;	sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (int16));	if (sp->tbuf == NULL) {		TIFFError(module, "%s: No space for SGILog translation buffer",		    tif->tif_name);		return (0);	}	return (1);}static intLogLuvGuessDataFmt(TIFFDirectory *td){	int guess;	/*	 * If the user didn't tell us their datafmt,	 * take our best guess from the bitspersample.	 */#define	PACK(a,b)	(((a)<<3)|(b))	switch (PACK(td->td_bitspersample, td->td_sampleformat)) {	case PACK(32, SAMPLEFORMAT_IEEEFP):		guess = SGILOGDATAFMT_FLOAT;		break;	case PACK(32, SAMPLEFORMAT_VOID):	case PACK(32, SAMPLEFORMAT_UINT):	case PACK(32, SAMPLEFORMAT_INT):		guess = SGILOGDATAFMT_RAW;		break;	case PACK(16, SAMPLEFORMAT_VOID):	case PACK(16, SAMPLEFORMAT_INT):	case PACK(16, SAMPLEFORMAT_UINT):		guess = SGILOGDATAFMT_16BIT;		break;	case PACK( 8, SAMPLEFORMAT_VOID):	case PACK( 8, SAMPLEFORMAT_UINT):		guess = SGILOGDATAFMT_8BIT;		break;	default:		guess = SGILOGDATAFMT_UNKNOWN;		break;#undef PACK	}	/*	 * Double-check samples per pixel.	 */	switch (td->td_samplesperpixel) {	case 1:		if (guess != SGILOGDATAFMT_RAW)			guess = SGILOGDATAFMT_UNKNOWN;		break;	case 3:		if (guess == SGILOGDATAFMT_RAW)			guess = SGILOGDATAFMT_UNKNOWN;		break;	default:		guess = SGILOGDATAFMT_UNKNOWN;		break;	}	return (guess);}static intLogLuvInitState(TIFF* tif){	TIFFDirectory* td = &tif->tif_dir;	LogLuvState* sp = DecoderState(tif);	static const char module[] = "LogLuvInitState";	assert(sp != NULL);	assert(td->td_photometric == PHOTOMETRIC_LOGLUV);	/* for some reason, we can't do this in TIFFInitLogLuv */	if (td->td_planarconfig != PLANARCONFIG_CONTIG) {		TIFFError(module,		    "SGILog compression cannot handle non-contiguous data");		return (0);	}	if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)		sp->user_datafmt = LogLuvGuessDataFmt(td);	switch (sp->user_datafmt) {	case SGILOGDATAFMT_FLOAT:		sp->pixel_size = 3*sizeof (float);		break;	case SGILOGDATAFMT_16BIT:		sp->pixel_size = 3*sizeof (int16);		break;	case SGILOGDATAFMT_RAW:		sp->pixel_size = sizeof (uint32);		break;	case SGILOGDATAFMT_8BIT:		sp->pixel_size = 3*sizeof (uint8);		break;	default:		TIFFError(tif->tif_name,		    "No support for converting user data format to LogLuv");		return (0);	}	sp->tbuflen = td->td_imagewidth * td->td_rowsperstrip;	sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (uint32));	if (sp->tbuf == NULL) {		TIFFError(module, "%s: No space for SGILog translation buffer",		    tif->tif_name);		return (0);	}	return (1);}static intLogLuvSetupDecode(TIFF* tif){	LogLuvState* sp = DecoderState(tif);	TIFFDirectory* td = &tif->tif_dir;	tif->tif_postdecode = _TIFFNoPostDecode;	switch (td->td_photometric) {	case PHOTOMETRIC_LOGLUV:		if (!LogLuvInitState(tif))			break;		if (td->td_compression == COMPRESSION_SGILOG24) {			tif->tif_decoderow = LogLuvDecode24;			switch (sp->user_datafmt) {			case SGILOGDATAFMT_FLOAT:				sp->tfunc = Luv24toXYZ;				break;			case SGILOGDATAFMT_16BIT:				sp->tfunc = Luv24toLuv48;				break;			case SGILOGDATAFMT_8BIT:				sp->tfunc = Luv24toRGB;				break;			}		} else {			tif->tif_decoderow = LogLuvDecode32;			switch (sp->user_datafmt) {			case SGILOGDATAFMT_FLOAT:				sp->tfunc = Luv32toXYZ;				break;			case SGILOGDATAFMT_16BIT:				sp->tfunc = Luv32toLuv48;				break;			case SGILOGDATAFMT_8BIT:				sp->tfunc = Luv32toRGB;				break;			}		}		return (1);	case PHOTOMETRIC_LOGL:		if (!LogL16InitState(tif))			break;		tif->tif_decoderow = LogL16Decode;		switch (sp->user_datafmt) {		case SGILOGDATAFMT_FLOAT:			sp->tfunc = L16toY;			break;		case SGILOGDATAFMT_8BIT:			sp->tfunc = L16toGry;			break;		}		return (1);	default:		TIFFError(tif->tif_name,    "Inappropriate photometric interpretation %d for SGILog compression; %s",		    td->td_photometric, "must be either LogLUV or LogL");		break;	}	return (0);}static intLogLuvSetupEncode(TIFF* tif){	LogLuvState* sp = EncoderState(tif);	TIFFDirectory* td = &tif->tif_dir;	switch (td->td_photometric) {	case PHOTOMETRIC_LOGLUV:		if (!LogLuvInitState(tif))			break;		if (td->td_compression == COMPRESSION_SGILOG24) {			tif->tif_encoderow = LogLuvEncode24;			switch (sp->user_datafmt) {			case SGILOGDATAFMT_FLOAT:				sp->tfunc = Luv24fromXYZ;				break;			case SGILOGDATAFMT_16BIT:				sp->tfunc = Luv24fromLuv48;				break;			case SGILOGDATAFMT_RAW:				break;			default:				goto notsupported;			}		} else {			tif->tif_encoderow = LogLuvEncode32;			switch (sp->user_datafmt) {			case SGILOGDATAFMT_FLOAT:				sp->tfunc = Luv32fromXYZ;				break;			case SGILOGDATAFMT_16BIT:				sp->tfunc = Luv32fromLuv48;				break;			case SGILOGDATAFMT_RAW:				break;			default:				goto notsupported;			}		}		break;	case PHOTOMETRIC_LOGL:		if (!LogL16InitState(tif))			break;		tif->tif_encoderow = LogL16Encode;		switch (sp->user_datafmt) {		case SGILOGDATAFMT_FLOAT:			sp->tfunc = L16fromY;			break;		case SGILOGDATAFMT_16BIT:			break;		default:			goto notsupported;		}		break;	default:		TIFFError(tif->tif_name,    "Inappropriate photometric interpretation %d for SGILog compression; %s",    		    td->td_photometric, "must be either LogLUV or LogL");		break;	}	return (1);notsupported:	TIFFError(tif->tif_name,	    "SGILog compression supported only for %s, or raw data",	    td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv");	return (0);}static voidLogLuvClose(TIFF* tif){	TIFFDirectory *td = &tif->tif_dir;	/*	 * For consistency, we always want to write out the same	 * bitspersample and sampleformat for our TIFF file,	 * regardless of the data format being used by the application.	 * Since this routine is called after tags have been set but	 * before they have been recorded in the file, we reset them here.	 */	td->td_samplesperpixel =	    (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;	td->td_bitspersample = 16;	td->td_sampleformat = SAMPLEFORMAT_INT;}static voidLogLuvCleanup(TIFF* tif){	LogLuvState* sp = (LogLuvState *)tif->tif_data;	if (sp) {		if (sp->tbuf)			_TIFFfree(sp->tbuf);		_TIFFfree(sp);		tif->tif_data = NULL;	}}static intLogLuvVSetField(TIFF* tif, ttag_t tag, va_list ap){	LogLuvState* sp = DecoderState(tif);	int bps, fmt;	switch (tag) {	case TIFFTAG_SGILOGDATAFMT:		sp->user_datafmt = va_arg(ap, int);		/*		 * Tweak the TIFF header so that the rest of libtiff knows what		 * size of data will be passed between app and library, and		 * assume that the app knows what it is doing and is not		 * confused by these header manipulations...		 */		switch (sp->user_datafmt) {		case SGILOGDATAFMT_FLOAT:			bps = 32, fmt = SAMPLEFORMAT_IEEEFP;			break;		case SGILOGDATAFMT_16BIT:			bps = 16, fmt = SAMPLEFORMAT_INT;			break;		case SGILOGDATAFMT_RAW:			bps = 32, fmt = SAMPLEFORMAT_UINT;			TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);			break;		case SGILOGDATAFMT_8BIT:			bps = 8, fmt = SAMPLEFORMAT_UINT;			break;		default:			TIFFError(tif->tif_name,			    "Unknown data format %d for LogLuv compression",			    sp->user_datafmt);			return (0);		}		TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);		TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt);		/*		 * Must recalculate sizes should bits/sample change.		 */		tif->tif_tilesize = TIFFTileSize(tif);		tif->tif_scanlinesize = TIFFScanlineSize(tif);		return (1);	case TIFFTAG_SGILOGENCODE:		sp->encode_meth = va_arg(ap, int);		if (sp->encode_meth != SGILOGENCODE_NODITHER &&				sp->encode_meth != SGILOGENCODE_RANDITHER) {			TIFFError(tif->tif_name,				"Unknown encoding %d for LogLuv compression",				sp->encode_meth);			return (0);		}		return (1);	default:		return (*sp->vsetparent)(tif, tag, ap);	}}static intLogLuvVGetField(TIFF* tif, ttag_t tag, va_list ap){	LogLuvState *sp = (LogLuvState *)tif->tif_data;	switch (tag) {	case TIFFTAG_SGILOGDATAFMT:		*va_arg(ap, int*) = sp->user_datafmt;		return (1);	default:		return (*sp->vgetparent)(tif, tag, ap);	}}static const TIFFFieldInfo LogLuvFieldInfo[] = {    { TIFFTAG_SGILOGDATAFMT,	  0, 0,	TIFF_SHORT,	FIELD_PSEUDO,      TRUE,	FALSE,	"SGILogDataFmt"},    { TIFFTAG_SGILOGENCODE,	  0, 0, TIFF_SHORT,	FIELD_PSEUDO,      TRUE,	FALSE,	"SGILogEncode"}};intTIFFInitSGILog(TIFF* tif, int scheme){	static const char module[] = "TIFFInitSGILog";	LogLuvState* sp;	assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG);	/*	 * Allocate state block so tag methods have storage to record values.	 */	tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LogLuvState));	if (tif->tif_data == NULL)		goto bad;	sp = (LogLuvState*) tif->tif_data;	_TIFFmemset((tdata_t)sp, 0, sizeof (*sp));	sp->user_datafmt = SGILOGDATAFMT_UNKNOWN;	sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ?				SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER;	sp->tfunc = _logLuvNop;	/*	 * Install codec methods.	 * NB: tif_decoderow & tif_encoderow are filled	 *     in at setup time.	 */	tif->tif_setupdecode = LogLuvSetupDecode;	tif->tif_decodestrip = LogLuvDecodeStrip;	tif->tif_decodetile = LogLuvDecodeTile;	tif->tif_setupencode = LogLuvSetupEncode;	tif->tif_encodestrip = LogLuvEncodeStrip;	tif->tif_encodetile = LogLuvEncodeTile;	tif->tif_close = LogLuvClose;	tif->tif_cleanup = LogLuvCleanup;	/* override SetField so we can handle our private pseudo-tag */	_TIFFMergeFieldInfo(tif, LogLuvFieldInfo, N(LogLuvFieldInfo));	sp->vgetparent = tif->tif_vgetfield;	tif->tif_vgetfield = LogLuvVGetField;   /* hook for codec tags */	sp->vsetparent = tif->tif_vsetfield;	tif->tif_vsetfield = LogLuvVSetField;   /* hook for codec tags */	return (1);bad:	TIFFError(module, "%s: No space for LogLuv state block", tif->tif_name);	return (0);}#endif /* LOGLUV_SUPPORT */

⌨️ 快捷键说明

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