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

📄 tif_pixarlog.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 3 页
字号:
	} else {	    REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)	    n -= stride;	    while (n > 0) {		REPEAT(stride,		    wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)		n -= stride;	    }	}    }}/* * State block for each open TIFF * file using PixarLog compression/decompression. */typedef	struct {	TIFFPredictorState	predict;	z_stream		stream;	uint16			*tbuf; 	uint16			stride;	int			state;	int			user_datafmt;	int			quality;#define PLSTATE_INIT 1	TIFFVSetMethod		vgetparent;	/* super-class method */	TIFFVSetMethod		vsetparent;	/* super-class method */	float *ToLinearF;	uint16 *ToLinear16;	unsigned char *ToLinear8;	uint16  *FromLT2;	uint16  *From14; /* Really for 16-bit data, but we shift down 2 */	uint16  *From8;	} PixarLogState;static intPixarLogMakeTables(PixarLogState *sp){/* *    We make several tables here to convert between various external *    representations (float, 16-bit, and 8-bit) and the internal *    11-bit companded representation.  The 11-bit representation has two *    distinct regions.  A linear bottom end up through .018316 in steps *    of about .000073, and a region of constant ratio up to about 25. *    These floating point numbers are stored in the main table ToLinearF.  *    All other tables are derived from this one.  The tables (and the *    ratios) are continuous at the internal seam. */    int  nlin, lt2size;    int  i, j;    double  b, c, linstep, max;    double  k, v, dv, r, lr2, r2;    float *ToLinearF;    uint16 *ToLinear16;    unsigned char *ToLinear8;    uint16  *FromLT2;    uint16  *From14; /* Really for 16-bit data, but we shift down 2 */    uint16  *From8;    c = log(RATIO);	    nlin = 1./c;	/* nlin must be an integer */    c = 1./nlin;    b = exp(-c*ONE);	/* multiplicative scale factor [b*exp(c*ONE) = 1] */    linstep = b*c*exp(1.);    LogK1 = 1./c;	/* if (v >= 2)  token = k1*log(v*k2) */    LogK2 = 1./b;    lt2size = (2./linstep)+1;    FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16));    From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16));    From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16));    ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float));    ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16));    ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char));    if (FromLT2 == NULL || From14  == NULL || From8   == NULL ||	 ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) {	if (FromLT2) _TIFFfree(FromLT2);	if (From14) _TIFFfree(From14);	if (From8) _TIFFfree(From8);	if (ToLinearF) _TIFFfree(ToLinearF);	if (ToLinear16) _TIFFfree(ToLinear16);	if (ToLinear8) _TIFFfree(ToLinear8);	sp->FromLT2 = NULL;	sp->From14 = NULL;	sp->From8 = NULL;	sp->ToLinearF = NULL;	sp->ToLinear16 = NULL;	sp->ToLinear8 = NULL;	return 0;    }    j = 0;    for (i = 0; i < nlin; i++)  {	v = i * linstep;	ToLinearF[j++] = v;    }    for (i = nlin; i < TSIZE; i++)	ToLinearF[j++] = b*exp(c*i);    ToLinearF[2048] = ToLinearF[2047];    for (i = 0; i < TSIZEP1; i++)  {	v = ToLinearF[i]*65535.0 + 0.5;	ToLinear16[i] = (v > 65535.0) ? 65535 : v;	v = ToLinearF[i]*255.0  + 0.5;	ToLinear8[i]  = (v > 255.0) ? 255 : v;    }    j = 0;    for (i = 0; i < lt2size; i++)  {	if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])	    j++;	FromLT2[i] = j;    }    /*     * Since we lose info anyway on 16-bit data, we set up a 14-bit     * table and shift 16-bit values down two bits on input.     * saves a little table space.     */    j = 0;    for (i = 0; i < 16384; i++)  {	while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])	    j++;	From14[i] = j;    }    j = 0;    for (i = 0; i < 256; i++)  {	while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])	    j++;	From8[i] = j;    }    Fltsize = lt2size/2;    sp->ToLinearF = ToLinearF;    sp->ToLinear16 = ToLinear16;    sp->ToLinear8 = ToLinear8;    sp->FromLT2 = FromLT2;    sp->From14 = From14;    sp->From8 = From8;    return 1;}#define	DecoderState(tif)	((PixarLogState*) (tif)->tif_data)#define	EncoderState(tif)	((PixarLogState*) (tif)->tif_data)static	int PixarLogEncode(TIFF*, tidata_t, tsize_t, tsample_t);static	int PixarLogDecode(TIFF*, tidata_t, tsize_t, tsample_t);#define N(a)   (sizeof(a)/sizeof(a[0]))#define PIXARLOGDATAFMT_UNKNOWN	-1static intPixarLogGuessDataFmt(TIFFDirectory *td){	int guess = PIXARLOGDATAFMT_UNKNOWN;	int format = td->td_sampleformat;	/* If the user didn't tell us his datafmt,	 * take our best guess from the bitspersample.	 */	switch (td->td_bitspersample) {	 case 32:		if (format == SAMPLEFORMAT_IEEEFP)			guess = PIXARLOGDATAFMT_FLOAT;		break;	 case 16:		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)			guess = PIXARLOGDATAFMT_16BIT;		break;	 case 12:		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)			guess = PIXARLOGDATAFMT_12BITPICIO;		break;	 case 11:		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)			guess = PIXARLOGDATAFMT_11BITLOG;		break;	 case 8:		if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)			guess = PIXARLOGDATAFMT_8BIT;		break;	}	return guess;}static intPixarLogSetupDecode(TIFF* tif){	TIFFDirectory *td = &tif->tif_dir;	PixarLogState* sp = DecoderState(tif);	static const char module[] = "PixarLogSetupDecode";	assert(sp != NULL);	/* Make sure no byte swapping happens on the data	 * after decompression. */	tif->tif_postdecode = _TIFFNoPostDecode;	/* for some reason, we can't do this in TIFFInitPixarLog */	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?	    td->td_samplesperpixel : 1);	sp->tbuf = (uint16 *) _TIFFmalloc(sp->stride * 		td->td_imagewidth * td->td_rowsperstrip * sizeof(uint16));	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)		sp->user_datafmt = PixarLogGuessDataFmt(td);	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {		TIFFError(module, 			"PixarLog compression can't handle bits depth/data format combination (depth: %d)", 			td->td_bitspersample);		return (0);	}	if (inflateInit(&sp->stream) != Z_OK) {		TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg);		return (0);	} else {		sp->state |= PLSTATE_INIT;		return (1);	}}/* * Setup state for decoding a strip. */static intPixarLogPreDecode(TIFF* tif, tsample_t s){	TIFFDirectory *td = &tif->tif_dir;	PixarLogState* sp = DecoderState(tif);	(void) s;	assert(sp != NULL);	sp->stream.next_in = tif->tif_rawdata;	sp->stream.avail_in = tif->tif_rawcc;	return (inflateReset(&sp->stream) == Z_OK);}static intPixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s){	TIFFDirectory *td = &tif->tif_dir;	PixarLogState* sp = DecoderState(tif);	static const char module[] = "PixarLogDecode";	int i, nsamples, llen;	uint16 *up;	switch (sp->user_datafmt) {	case PIXARLOGDATAFMT_FLOAT:		nsamples = occ / sizeof(float);	/* XXX float == 32 bits */		break;	case PIXARLOGDATAFMT_16BIT:	case PIXARLOGDATAFMT_12BITPICIO:	case PIXARLOGDATAFMT_11BITLOG:		nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */		break;	case PIXARLOGDATAFMT_8BIT:	case PIXARLOGDATAFMT_8BITABGR:		nsamples = occ;		break;	default:		TIFFError(tif->tif_name,			"%d bit input not supported in PixarLog",			td->td_bitspersample);		return 0;	}	llen = sp->stride * td->td_imagewidth;	(void) s;	assert(sp != NULL);	sp->stream.next_out = (unsigned char *) sp->tbuf;	sp->stream.avail_out = nsamples * sizeof(uint16);	do {		int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);		if (state == Z_STREAM_END) {			break;			/* XXX */		}		if (state == Z_DATA_ERROR) {			TIFFError(module,			    "%s: Decoding error at scanline %d, %s",			    tif->tif_name, tif->tif_row, sp->stream.msg);			if (inflateSync(&sp->stream) != Z_OK)				return (0);			continue;		}		if (state != Z_OK) {			TIFFError(module, "%s: zlib error: %s",			    tif->tif_name, sp->stream.msg);			return (0);		}	} while (sp->stream.avail_out > 0);	/* hopefully, we got all the bytes we needed */	if (sp->stream.avail_out != 0) {		TIFFError(module,		    "%s: Not enough data at scanline %d (short %d bytes)",		    tif->tif_name, tif->tif_row, sp->stream.avail_out);		return (0);	}	up = sp->tbuf;	/* Swap bytes in the data if from a different endian machine. */	if (tif->tif_flags & TIFF_SWAB)		TIFFSwabArrayOfShort(up, nsamples);	for (i = 0; i < nsamples; i += llen, up += llen) {		switch (sp->user_datafmt)  {		case PIXARLOGDATAFMT_FLOAT:			horizontalAccumulateF(up, llen, sp->stride,					(float *)op, sp->ToLinearF);			op += llen * sizeof(float);			break;		case PIXARLOGDATAFMT_16BIT:			horizontalAccumulate16(up, llen, sp->stride,					(uint16 *)op, sp->ToLinear16);			op += llen * sizeof(uint16);			break;		case PIXARLOGDATAFMT_12BITPICIO:			horizontalAccumulate12(up, llen, sp->stride,					(int16 *)op, sp->ToLinearF);			op += llen * sizeof(int16);			break;		case PIXARLOGDATAFMT_11BITLOG:			horizontalAccumulate11(up, llen, sp->stride,					(uint16 *)op);			op += llen * sizeof(uint16);			break;		case PIXARLOGDATAFMT_8BIT:			horizontalAccumulate8(up, llen, sp->stride,					(unsigned char *)op, sp->ToLinear8);			op += llen * sizeof(unsigned char);			break;		case PIXARLOGDATAFMT_8BITABGR:			horizontalAccumulate8abgr(up, llen, sp->stride,					(unsigned char *)op, sp->ToLinear8);			op += llen * sizeof(unsigned char);			break;		default:			TIFFError(tif->tif_name,				  "PixarLogDecode: unsupported bits/sample: %d", 				  td->td_bitspersample);			return (0);		}	}	return (1);}static intPixarLogSetupEncode(TIFF* tif){	TIFFDirectory *td = &tif->tif_dir;	PixarLogState* sp = EncoderState(tif);	static const char module[] = "PixarLogSetupEncode";	assert(sp != NULL);	/* for some reason, we can't do this in TIFFInitPixarLog */	sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?	    td->td_samplesperpixel : 1);	sp->tbuf = (uint16 *) _TIFFmalloc(sp->stride * 		td->td_imagewidth * td->td_rowsperstrip * sizeof(uint16));	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)		sp->user_datafmt = PixarLogGuessDataFmt(td);	if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {		TIFFError(module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample);		return (0);	}	if (deflateInit(&sp->stream, sp->quality) != Z_OK) {		TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg);		return (0);	} else {		sp->state |= PLSTATE_INIT;		return (1);	}}/* * Reset encoding state at the start of a strip. */static intPixarLogPreEncode(TIFF* tif, tsample_t s){	TIFFDirectory *td = &tif->tif_dir;	PixarLogState *sp = EncoderState(tif);	(void) s;	assert(sp != NULL);	sp->stream.next_out = tif->tif_rawdata;	sp->stream.avail_out = tif->tif_rawdatasize;	return (deflateReset(&sp->stream) == Z_OK);}static voidhorizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2){    register int  r1, g1, b1, a1, r2, g2, b2, a2, mask;    register float  fltsize = Fltsize;#define  CLAMP(v) ( (v<(float)0.)   ? 0				\		  : (v<(float)2.)   ? FromLT2[(int)(v*fltsize)]	\		  : (v>(float)24.2) ? 2047			\		  : LogK1*log(v*LogK2) + 0.5 )    mask = CODE_MASK;    if (n >= stride) {	if (stride == 3) {	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);	    b2 = wp[2] = CLAMP(ip[2]);	    n -= 3;	    while (n > 0) {		n -= 3;		wp += 3;		ip += 3;		r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;		g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;		b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;	    }	} else if (stride == 4) {	    r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);	    b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);

⌨️ 快捷键说明

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