Blame man/TIFFcolor.3tiff

Packit 994f1a
.\" $Id: TIFFcolor.3tiff,v 1.3 2006/03/23 14:54:02 dron Exp $
Packit 994f1a
.\"
Packit 994f1a
.\" Copyright (c) 2003, Andrey Kiselev <dron@ak4719.spb.edu>
Packit 994f1a
.\"
Packit 994f1a
.\" Permission to use, copy, modify, distribute, and sell this software and 
Packit 994f1a
.\" its documentation for any purpose is hereby granted without fee, provided
Packit 994f1a
.\" that (i) the above copyright notices and this permission notice appear in
Packit 994f1a
.\" all copies of the software and related documentation, and (ii) the names of
Packit 994f1a
.\" Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit 994f1a
.\" publicity relating to the software without the specific, prior written
Packit 994f1a
.\" permission of Sam Leffler and Silicon Graphics.
Packit 994f1a
.\" 
Packit 994f1a
.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit 994f1a
.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit 994f1a
.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit 994f1a
.\" 
Packit 994f1a
.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit 994f1a
.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit 994f1a
.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit 994f1a
.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit 994f1a
.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit 994f1a
.\" OF THIS SOFTWARE.
Packit 994f1a
.\"
Packit 994f1a
.if n .po 0
Packit 994f1a
.TH COLOR 3TIFF "December 21, 2003" "libtiff"
Packit 994f1a
.SH NAME
Packit 994f1a
TIFFYCbCrToRGBInit, TIFFYCbCrtoRGB, TIFFCIELabToRGBInit, TIFFCIELabToXYZ,
Packit 994f1a
TIFFXYZToRGB \- color conversion routines.
Packit 994f1a
.SH SYNOPSIS
Packit 994f1a
.B "#include <tiffio.h>"
Packit 994f1a
.sp
Packit 994f1a
.BI "int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *" ycbcr ", float *" luma ", float *"refBlackWhite" );"
Packit 994f1a
.br
Packit 994f1a
.BI "void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *" ycbcr ", uint32 " Y ", int32 " Cb ", int32 " Cr ", uint32 *" R ", uint32 *" G ", uint32 *" B " );"
Packit 994f1a
.sp
Packit 994f1a
.BI "int TIFFCIELabToRGBInit(TIFFCIELabToRGB *" cielab ", TIFFDisplay *" display ", float *" refWhite ");"
Packit 994f1a
.br
Packit 994f1a
.BI "void TIFFCIELabToXYZ(TIFFCIELabToRGB *" cielab ", uint32 " L ", int32 " a ", int32 " b ", float *" X ", float *" Y ", float *" Z ");"
Packit 994f1a
.br
Packit 994f1a
.BI "void TIFFXYZToRGB(TIFFCIELabToRGB *" cielab ", float " X ", float " Y ", float " Z" , uint32 *" R ", uint32 *" G ", uint32 *" B ");"
Packit 994f1a
.SH DESCRIPTION
Packit 994f1a
TIFF supports several color spaces for images stored in that format. There is
Packit 994f1a
usually a problem of application to handle the data properly and convert
Packit 994f1a
between different colorspaces for displaying and printing purposes. To
Packit 994f1a
simplify this task libtiff implements several color conversion routines
Packit 994f1a
itself. In particular, these routines used in
Packit 994f1a
.B TIFFRGBAImage(3TIFF)
Packit 994f1a
interface.
Packit 994f1a
.PP
Packit 994f1a
.B TIFFYCbCrToRGBInit()
Packit 994f1a
used to initialize
Packit 994f1a
.I YCbCr
Packit 994f1a
to
Packit 994f1a
.I RGB
Packit 994f1a
conversion state. Allocating and freeing of the
Packit 994f1a
.I ycbcr
Packit 994f1a
structure belongs to programmer.
Packit 994f1a
.I TIFFYCbCrToRGB
Packit 994f1a
defined in
Packit 994f1a
.B tiffio.h
Packit 994f1a
as
Packit 994f1a
.PP
Packit 994f1a
.RS
Packit 994f1a
.nf
Packit 994f1a
typedef struct {                /* YCbCr->RGB support */
Packit 994f1a
        TIFFRGBValue* clamptab; /* range clamping table */
Packit 994f1a
        int*	      Cr_r_tab;
Packit 994f1a
        int*	      Cb_b_tab;
Packit 994f1a
        int32*	      Cr_g_tab;
Packit 994f1a
        int32*	      Cb_g_tab;
Packit 994f1a
        int32*        Y_tab;
Packit 994f1a
} TIFFYCbCrToRGB;
Packit 994f1a
.fi
Packit 994f1a
.RE
Packit 994f1a
.PP
Packit 994f1a
.I luma
Packit 994f1a
is a float array of three values representing proportions of the red, green
Packit 994f1a
and blue in luminance, Y (see section 21 of the TIFF 6.0 specification, where
Packit 994f1a
the YCbCr images discussed).
Packit 994f1a
.I TIFFTAG_YCBCRCOEFFICIENTS
Packit 994f1a
holds that values in TIFF file.
Packit 994f1a
.I refBlackWhite
Packit 994f1a
is a float array of 6 values which specifies a pair of headroom and footroom
Packit 994f1a
image data values (codes) for each image component (see section 20 of the
Packit 994f1a
TIFF 6.0 specification where the colorinmetry fields discussed).
Packit 994f1a
.I TIFFTAG_REFERENCEBLACKWHITE
Packit 994f1a
is responsible for storing these values in TIFF file. Following code snippet
Packit 994f1a
should helps to understand the the technique:
Packit 994f1a
.PP
Packit 994f1a
.RS
Packit 994f1a
.nf
Packit 994f1a
float *luma, *refBlackWhite;
Packit 994f1a
uint16 hs, vs;
Packit 994f1a
Packit 994f1a
/* Initialize structures */
Packit 994f1a
ycbcr = (TIFFYCbCrToRGB*)
Packit 994f1a
	_TIFFmalloc(TIFFroundup(sizeof(TIFFYCbCrToRGB), sizeof(long))
Packit 994f1a
        	+ 4*256*sizeof(TIFFRGBValue)
Packit 994f1a
        	+ 2*256*sizeof(int)
Packit 994f1a
        	+ 3*256*sizeof(int32));
Packit 994f1a
if (ycbcr == NULL) {
Packit 994f1a
        TIFFError("YCbCr->RGB",
Packit 994f1a
		"No space for YCbCr->RGB conversion state");
Packit 994f1a
        exit(0);
Packit 994f1a
}
Packit 994f1a
Packit 994f1a
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
Packit 994f1a
TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite);
Packit 994f1a
if (TIFFYCbCrToRGBInit(ycbcr, luma, refBlackWhite) < 0)
Packit 994f1a
	exit(0);
Packit 994f1a
Packit 994f1a
/* Start conversion */
Packit 994f1a
uint32 r, g, b;
Packit 994f1a
uint32 Y;
Packit 994f1a
int32 Cb, Cr;
Packit 994f1a
Packit 994f1a
for each pixel in image
Packit 994f1a
	TIFFYCbCrtoRGB(img->ycbcr, Y, Cb, Cr, &r, &g, &b);
Packit 994f1a
Packit 994f1a
/* Free state structure */
Packit 994f1a
_TIFFfree(ycbcr);
Packit 994f1a
.fi
Packit 994f1a
.RE
Packit 994f1a
.PP
Packit 994f1a
Packit 994f1a
.PP
Packit 994f1a
.B TIFFCIELabToRGBInit()
Packit 994f1a
initializes the
Packit 994f1a
.I CIE L*a*b* 1976
Packit 994f1a
to
Packit 994f1a
.I RGB
Packit 994f1a
conversion state.
Packit 994f1a
.B TIFFCIELabToRGB
Packit 994f1a
defined as
Packit 994f1a
.PP
Packit 994f1a
.RS
Packit 994f1a
.nf
Packit 994f1a
#define CIELABTORGB_TABLE_RANGE 1500
Packit 994f1a
Packit 994f1a
typedef struct {		     /* CIE Lab 1976->RGB support */
Packit 994f1a
	int	range;		     /* Size of conversion table */
Packit 994f1a
	float	rstep, gstep, bstep;
Packit 994f1a
	float	X0, Y0, Z0;	     /* Reference white point */
Packit 994f1a
	TIFFDisplay display;
Packit 994f1a
	float	Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */
Packit 994f1a
	float	Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */
Packit 994f1a
	float	Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */
Packit 994f1a
} TIFFCIELabToRGB;
Packit 994f1a
.fi
Packit 994f1a
.RE
Packit 994f1a
.PP
Packit 994f1a
.I display
Packit 994f1a
is a display device description, declared as
Packit 994f1a
.PP
Packit 994f1a
.RS
Packit 994f1a
.nf
Packit 994f1a
typedef struct {
Packit 994f1a
	float d_mat[3][3]; /* XYZ -> luminance matrix */
Packit 994f1a
	float d_YCR;       /* Light o/p for reference white */
Packit 994f1a
	float d_YCG;
Packit 994f1a
	float d_YCB;
Packit 994f1a
	uint32 d_Vrwr;     /* Pixel values for ref. white */
Packit 994f1a
	uint32 d_Vrwg;
Packit 994f1a
	uint32 d_Vrwb;
Packit 994f1a
	float d_Y0R;       /* Residual light for black pixel */
Packit 994f1a
	float d_Y0G;
Packit 994f1a
	float d_Y0B;
Packit 994f1a
	float d_gammaR;    /* Gamma values for the three guns */
Packit 994f1a
	float d_gammaG;
Packit 994f1a
	float d_gammaB;
Packit 994f1a
} TIFFDisplay;
Packit 994f1a
.fi
Packit 994f1a
.RE
Packit 994f1a
.PP
Packit 994f1a
For example, the one can use sRGB device, which has the following parameters:
Packit 994f1a
.PP
Packit 994f1a
.RS
Packit 994f1a
.nf
Packit 994f1a
TIFFDisplay display_sRGB = {
Packit 994f1a
	{       /* XYZ -> luminance matrix */
Packit 994f1a
		{  3.2410F, -1.5374F, -0.4986F },
Packit 994f1a
		{  -0.9692F, 1.8760F, 0.0416F },
Packit 994f1a
		{  0.0556F, -0.2040F, 1.0570F }
Packit 994f1a
	},	
Packit 994f1a
	100.0F, 100.0F, 100.0F, /* Light o/p for reference white */
Packit 994f1a
	255, 255, 255,      /* Pixel values for ref. white */
Packit 994f1a
	1.0F, 1.0F, 1.0F,   /* Residual light o/p for black pixel */
Packit 994f1a
	2.4F, 2.4F, 2.4F,   /* Gamma values for the three guns */
Packit 994f1a
};
Packit 994f1a
.fi
Packit 994f1a
.RE
Packit 994f1a
.PP
Packit 994f1a
.I refWhite
Packit 994f1a
is a color temperature of the reference white. The
Packit 994f1a
.I TIFFTAG_WHITEPOINT
Packit 994f1a
contains the chromaticity of the white point of the image from where the
Packit 994f1a
reference white can be calculated using following formulae:
Packit 994f1a
.PP
Packit 994f1a
.RS
Packit 994f1a
refWhite_Y = 100.0
Packit 994f1a
.br
Packit 994f1a
refWhite_X = whitePoint_x / whitePoint_y * refWhite_Y
Packit 994f1a
.br
Packit 994f1a
refWhite_Z = (1.0 - whitePoint_x - whitePoint_y) / whitePoint_y * refWhite_X
Packit 994f1a
.br
Packit 994f1a
.RE
Packit 994f1a
.PP
Packit 994f1a
The conversion itself performed in two steps: at the first one we will convert
Packit 994f1a
.I CIE L*a*b* 1976
Packit 994f1a
to
Packit 994f1a
.I CIE XYZ
Packit 994f1a
using
Packit 994f1a
.B TIFFCIELabToXYZ()
Packit 994f1a
routine, and at the second step we will convert
Packit 994f1a
.I CIE XYZ
Packit 994f1a
to
Packit 994f1a
.I RGB
Packit 994f1a
using
Packit 994f1a
.B TIFFXYZToRGB().
Packit 994f1a
Look at the code sample below:
Packit 994f1a
.PP
Packit 994f1a
.RS
Packit 994f1a
.nf
Packit 994f1a
float   *whitePoint;
Packit 994f1a
float   refWhite[3];
Packit 994f1a
Packit 994f1a
/* Initialize structures */
Packit 994f1a
img->cielab = (TIFFCIELabToRGB *)
Packit 994f1a
	_TIFFmalloc(sizeof(TIFFCIELabToRGB));
Packit 994f1a
if (!cielab) {
Packit 994f1a
	TIFFError("CIE L*a*b*->RGB",
Packit 994f1a
		"No space for CIE L*a*b*->RGB conversion state.");
Packit 994f1a
	exit(0);
Packit 994f1a
}
Packit 994f1a
Packit 994f1a
TIFFGetFieldDefaulted(tif, TIFFTAG_WHITEPOINT, &whitePoint);
Packit 994f1a
refWhite[1] = 100.0F;
Packit 994f1a
refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
Packit 994f1a
refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
Packit 994f1a
	      / whitePoint[1] * refWhite[1];
Packit 994f1a
if (TIFFCIELabToRGBInit(cielab, &display_sRGB, refWhite) < 0) {
Packit 994f1a
	TIFFError("CIE L*a*b*->RGB",
Packit 994f1a
		"Failed to initialize CIE L*a*b*->RGB conversion state.");
Packit 994f1a
	_TIFFfree(cielab);
Packit 994f1a
	exit(0);
Packit 994f1a
}
Packit 994f1a
Packit 994f1a
/* Now we can start to convert */
Packit 994f1a
uint32 r, g, b;
Packit 994f1a
uint32 L;
Packit 994f1a
int32 a, b;
Packit 994f1a
float X, Y, Z;
Packit 994f1a
Packit 994f1a
for each pixel in image
Packit 994f1a
	TIFFCIELabToXYZ(cielab, L, a, b, &X, &Y, &Z);
Packit 994f1a
	TIFFXYZToRGB(cielab, X, Y, Z, &r, &g, &b);
Packit 994f1a
Packit 994f1a
/* Don't forget to free the state structure */
Packit 994f1a
_TIFFfree(cielab);
Packit 994f1a
.fi
Packit 994f1a
.RE
Packit 994f1a
.PP
Packit 994f1a
.SH "SEE ALSO"
Packit 994f1a
.BR TIFFRGBAImage (3TIFF)
Packit 994f1a
.BR libtiff (3TIFF),
Packit 994f1a
.PP
Packit 994f1a
Libtiff library home page:
Packit 994f1a
.BR http://www.remotesensing.org/libtiff/