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

📄 tif_luv.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1997 Greg Ward Larson * Copyright (c) 1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and  * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any * advertising or publicity relating to the software without the specific, * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics. *  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   *  * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  * OF THIS SOFTWARE. */#include "tiffiop.h"#ifdef LOGLUV_SUPPORT/* * TIFF Library. * LogLuv compression support for high dynamic range images. * * Contributed by Greg Larson. * * LogLuv image support uses the TIFF library to store 16 or 10-bit * log luminance values with 8 bits each of u and v or a 14-bit index. * * The codec can take as input and produce as output 32-bit IEEE float values  * as well as 16-bit integer values.  A 16-bit luminance is interpreted * as a sign bit followed by a 15-bit integer that is converted * to and from a linear magnitude using the transformation: * *	L = 2^( (Le+.5)/256 - 64 )		# real from 15-bit * *	Le = floor( 256*(log2(L) + 64) )	# 15-bit from real * * The actual conversion to world luminance units in candelas per sq. meter * requires an additional multiplier, which is stored in the TIFFTAG_STONITS. * This value is usually set such that a reasonable exposure comes from * clamping decoded luminances above 1 to 1 in the displayed image. * * The 16-bit values for u and v may be converted to real values by dividing * each by 32768.  (This allows for negative values, which aren't useful as * far as we know, but are left in case of future improvements in human * color vision.) * * Conversion from (u,v), which is actually the CIE (u',v') system for * you color scientists, is accomplished by the following transformation: * *	u = 4*x / (-2*x + 12*y + 3) *	v = 9*y / (-2*x + 12*y + 3) * *	x = 9*u / (6*u - 16*v + 12) *	y = 4*v / (6*u - 16*v + 12) * * This process is greatly simplified by passing 32-bit IEEE floats * for each of three CIE XYZ coordinates.  The codec then takes care * of conversion to and from LogLuv, though the application is still * responsible for interpreting the TIFFTAG_STONITS calibration factor. * * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white * point of (x,y)=(1/3,1/3).  However, most color systems assume some other * white point, such as D65, and an absolute color conversion to XYZ then * to another color space with a different white point may introduce an * unwanted color cast to the image.  It is often desirable, therefore, to * perform a white point conversion that maps the input white to [1 1 1] * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT * tag value.  A decoder that demands absolute color calibration may use * this white point tag to get back the original colors, but usually it * will be ignored and the new white point will be used instead that * matches the output color space. * * Pixel information is compressed into one of two basic encodings, depending * on the setting of the compression tag, which is one of COMPRESSION_SGILOG * or COMPRESSION_SGILOG24.  For COMPRESSION_SGILOG, greyscale data is * stored as: * *	 1       15 *	|-+---------------| * * COMPRESSION_SGILOG color data is stored as: * *	 1       15           8        8 *	|-+---------------|--------+--------| *	 S       Le           ue       ve * * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as: * *	     10           14 *	|----------|--------------| *	     Le'          Ce * * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is * encoded as an index for optimal color resolution.  The 10 log bits are * defined by the following conversions: * *	L = 2^((Le'+.5)/64 - 12)		# real from 10-bit * *	Le' = floor( 64*(log2(L) + 12) )	# 10-bit from real * * The 10 bits of the smaller format may be converted into the 15 bits of * the larger format by multiplying by 4 and adding 13314.  Obviously, * a smaller range of magnitudes is covered (about 5 orders of magnitude * instead of 38), and the lack of a sign bit means that negative luminances * are not allowed.  (Well, they aren't allowed in the real world, either, * but they are useful for certain types of image processing.) * * The desired user format is controlled by the setting the internal * pseudo tag TIFFTAG_SGILOGDATAFMT to one of: *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float XYZ values *  SGILOGDATAFMT_16BIT	      = 16-bit integer encodings of logL, u and v * Raw data i/o is also possible using: *  SGILOGDATAFMT_RAW         = 32-bit unsigned integer with encoded pixel * In addition, the following decoding is provided for ease of display: *  SGILOGDATAFMT_8BIT        = 8-bit default RGB gamma-corrected values * * For grayscale images, we provide the following data formats: *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float Y values *  SGILOGDATAFMT_16BIT       = 16-bit integer w/ encoded luminance *  SGILOGDATAFMT_8BIT        = 8-bit gray monitor values * * Note that the COMPRESSION_SGILOG applies a simple run-length encoding * scheme by separating the logL, u and v bytes for each row and applying * a PackBits type of compression.  Since the 24-bit encoding is not * adaptive, the 32-bit color format takes less space in many cases. * * Further control is provided over the conversion from higher-resolution * formats to final encoded values through the pseudo tag * TIFFTAG_SGILOGENCODE: *  SGILOGENCODE_NODITHER     = do not dither encoded values *  SGILOGENCODE_RANDITHER    = apply random dithering during encoding * * The default value of this tag is SGILOGENCODE_NODITHER for * COMPRESSION_SGILOG to maximize run-length encoding and * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn * quantization errors into noise. */#include <stdio.h>#include <assert.h>#include <stdlib.h>#include <math.h>/* * State block for each open TIFF * file using LogLuv compression/decompression. */typedef	struct logLuvState LogLuvState;struct logLuvState {	int			user_datafmt;	/* user data format */	int			encode_meth;	/* encoding method */	int			pixel_size;	/* bytes per pixel */	tidata_t*		tbuf;		/* translation buffer */	int			tbuflen;	/* buffer length */	void (*tfunc)(LogLuvState*, tidata_t, int);	TIFFVSetMethod		vgetparent;	/* super-class method */	TIFFVSetMethod		vsetparent;	/* super-class method */};#define	DecoderState(tif)	((LogLuvState*) (tif)->tif_data)#define	EncoderState(tif)	((LogLuvState*) (tif)->tif_data)#define N(a)   (sizeof(a)/sizeof(a[0]))#define SGILOGDATAFMT_UNKNOWN	-1#define MINRUN		4	/* minimum run length *//* * Decode a string of 16-bit gray pixels. */static intLogL16Decode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s){	LogLuvState* sp = DecoderState(tif);	int shft, i, npixels;	u_char* bp;	int16* tp;	int16 b;	int cc, rc;	assert(s == 0);	assert(sp != NULL);	npixels = occ / sp->pixel_size;	if (sp->user_datafmt == SGILOGDATAFMT_16BIT)		tp = (int16*) op;	else {		assert(sp->tbuflen >= npixels);		tp = (int16*) sp->tbuf;	}	_TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0]));	bp = (u_char*) tif->tif_rawcp;	cc = tif->tif_rawcc;					/* get each byte string */	for (shft = 2*8; (shft -= 8) >= 0; ) {		for (i = 0; i < npixels && cc > 0; )			if (*bp >= 128) {		/* run */				rc = *bp++ + (2-128);				b = (int16)*bp++ << shft;				cc -= 2;				while (rc--)					tp[i++] |= b;			} else {			/* non-run */				rc = *bp++;		/* nul is noop */				while (--cc && rc--)					tp[i++] |= (int16)*bp++ << shft;			}		if (i != npixels) {			TIFFError(tif->tif_name,		"LogL16Decode: Not enough data at row %d (short %d pixels)",			    tif->tif_row, npixels - i);			tif->tif_rawcp = (tidata_t) bp;			tif->tif_rawcc = cc;			return (0);		}	}	(*sp->tfunc)(sp, op, npixels);	tif->tif_rawcp = (tidata_t) bp;	tif->tif_rawcc = cc;	return (1);}/* * Decode a string of 24-bit pixels. */static intLogLuvDecode24(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s){	LogLuvState* sp = DecoderState(tif);	int cc, i, npixels;	u_char* bp;	uint32* tp;	assert(s == 0);	assert(sp != NULL);	npixels = occ / sp->pixel_size;	if (sp->user_datafmt == SGILOGDATAFMT_RAW)		tp = (uint32 *)op;	else {		assert(sp->tbuflen >= npixels);		tp = (uint32 *) sp->tbuf;	}					/* copy to array of uint32 */	bp = (u_char*) tif->tif_rawcp;	cc = tif->tif_rawcc;	for (i = 0; i < npixels && cc > 0; i++) {		tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];		bp += 3;		cc -= 3;	}	tif->tif_rawcp = (tidata_t) bp;	tif->tif_rawcc = cc;	if (i != npixels) {		TIFFError(tif->tif_name,	    "LogLuvDecode24: Not enough data at row %d (short %d pixels)",		    tif->tif_row, npixels - i);		return (0);	}	(*sp->tfunc)(sp, op, npixels);	return (1);}/* * Decode a string of 32-bit pixels. */static intLogLuvDecode32(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s){	LogLuvState* sp;	int shft, i, npixels;	u_char* bp;	uint32* tp;	uint32 b;	int cc, rc;	assert(s == 0);	sp = DecoderState(tif);	assert(sp != NULL);	npixels = occ / sp->pixel_size;	if (sp->user_datafmt == SGILOGDATAFMT_RAW)		tp = (uint32*) op;	else {		assert(sp->tbuflen >= npixels);		tp = (uint32*) sp->tbuf;	}	_TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0]));	bp = (u_char*) tif->tif_rawcp;	cc = tif->tif_rawcc;					/* get each byte string */	for (shft = 4*8; (shft -= 8) >= 0; ) {		for (i = 0; i < npixels && cc > 0; )			if (*bp >= 128) {		/* run */				rc = *bp++ + (2-128);				b = (uint32)*bp++ << shft;				cc -= 2;				while (rc--)					tp[i++] |= b;			} else {			/* non-run */				rc = *bp++;		/* nul is noop */				while (--cc && rc--)					tp[i++] |= (uint32)*bp++ << shft;			}		if (i != npixels) {			TIFFError(tif->tif_name,		"LogLuvDecode32: Not enough data at row %d (short %d pixels)",			    tif->tif_row, npixels - i);			tif->tif_rawcp = (tidata_t) bp;			tif->tif_rawcc = cc;			return (0);		}	}	(*sp->tfunc)(sp, op, npixels);	tif->tif_rawcp = (tidata_t) bp;	tif->tif_rawcc = cc;	return (1);}/* * Decode a strip of pixels.  We break it into rows to * maintain synchrony with the encode algorithm, which * is row by row. */static intLogLuvDecodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s){	tsize_t rowlen = TIFFScanlineSize(tif);	assert(cc%rowlen == 0);	while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))		bp += rowlen, cc -= rowlen;	return (cc == 0);}/* * Decode a tile of pixels.  We break it into rows to * maintain synchrony with the encode algorithm, which * is row by row. */static intLogLuvDecodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s){	tsize_t rowlen = TIFFTileRowSize(tif);	assert(cc%rowlen == 0);	while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))		bp += rowlen, cc -= rowlen;	return (cc == 0);}/* * Encode a row of 16-bit pixels. */static intLogL16Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s){	LogLuvState* sp = EncoderState(tif);	int shft, i, j, npixels;	tidata_t op;	int16* tp;	int16 b;	int occ, rc=0, mask, beg;	assert(s == 0);	assert(sp != NULL);	npixels = cc / sp->pixel_size;	if (sp->user_datafmt == SGILOGDATAFMT_16BIT)		tp = (int16*) bp;	else {		tp = (int16*) sp->tbuf;		assert(sp->tbuflen >= npixels);		(*sp->tfunc)(sp, bp, npixels);	}					/* compress each byte string */	op = tif->tif_rawcp;	occ = tif->tif_rawdatasize - tif->tif_rawcc;	for (shft = 2*8; (shft -= 8) >= 0; )		for (i = 0; i < npixels; i += rc) {			if (occ < 4) {				tif->tif_rawcp = op;				tif->tif_rawcc = tif->tif_rawdatasize - occ;				if (!TIFFFlushData1(tif))					return (-1);				op = tif->tif_rawcp;				occ = tif->tif_rawdatasize - tif->tif_rawcc;			}			mask = 0xff << shft;		/* find next run */			for (beg = i; beg < npixels; beg += rc) {				b = tp[beg] & mask;				rc = 1;				while (rc < 127+2 && beg+rc < npixels &&						(tp[beg+rc] & mask) == b)					rc++;				if (rc >= MINRUN)					break;		/* long enough */			}			if (beg-i > 1 && beg-i < MINRUN) {				b = tp[i] & mask;	/* check short run */				j = i+1;				while ((tp[j++] & mask) == b)					if (j == beg) {						*op++ = 128-2+j-i;						*op++ = b >> shft;						occ -= 2;						i = beg;						break;					}			}			while (i < beg) {		/* write out non-run */				if ((j = beg-i) > 127) j = 127;				if (occ < j+3) {					tif->tif_rawcp = op;					tif->tif_rawcc = tif->tif_rawdatasize - occ;					if (!TIFFFlushData1(tif))						return (-1);					op = tif->tif_rawcp;					occ = tif->tif_rawdatasize - tif->tif_rawcc;				}				*op++ = j; occ--;				while (j--) {					*op++ = tp[i++] >> shft & 0xff;					occ--;				}			}			if (rc >= MINRUN) {		/* write out run */				*op++ = 128-2+rc;				*op++ = tp[beg] >> shft & 0xff;				occ -= 2;			} else				rc = 0;		}	tif->tif_rawcp = op;	tif->tif_rawcc = tif->tif_rawdatasize - occ;	return (0);}/* * Encode a row of 24-bit pixels. */static intLogLuvEncode24(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s){	LogLuvState* sp = EncoderState(tif);	int i, npixels, occ;	tidata_t op;	uint32* tp;	assert(s == 0);	assert(sp != NULL);	npixels = cc / sp->pixel_size;	if (sp->user_datafmt == SGILOGDATAFMT_RAW)		tp = (uint32*) bp;	else {		tp = (uint32*) sp->tbuf;		assert(sp->tbuflen >= npixels);		(*sp->tfunc)(sp, bp, npixels);	}					/* write out encoded pixels */	op = tif->tif_rawcp;	occ = tif->tif_rawdatasize - tif->tif_rawcc;	for (i = npixels; i--; ) {		if (occ < 3) {			tif->tif_rawcp = op;			tif->tif_rawcc = tif->tif_rawdatasize - occ;			if (!TIFFFlushData1(tif))				return (-1);			op = tif->tif_rawcp;			occ = tif->tif_rawdatasize - tif->tif_rawcc;		}		*op++ = (tidataval_t)(*tp >> 16);		*op++ = (tidataval_t)(*tp >> 8 & 0xff);		*op++ = (tidataval_t)(*tp++ & 0xff);		occ -= 3;	}	tif->tif_rawcp = op;	tif->tif_rawcc = tif->tif_rawdatasize - occ;	return (0);}/* * Encode a row of 32-bit pixels. */static intLogLuvEncode32(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s){	LogLuvState* sp = EncoderState(tif);	int shft, i, j, npixels;	tidata_t op;	uint32* tp;	uint32 b;	int occ, rc=0, mask, beg;	assert(s == 0);	assert(sp != NULL);	npixels = cc / sp->pixel_size;	if (sp->user_datafmt == SGILOGDATAFMT_RAW)		tp = (uint32*) bp;	else {		tp = (uint32*) sp->tbuf;		assert(sp->tbuflen >= npixels);		(*sp->tfunc)(sp, bp, npixels);	}					/* compress each byte string */	op = tif->tif_rawcp;	occ = tif->tif_rawdatasize - tif->tif_rawcc;

⌨️ 快捷键说明

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