]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/libtiff/tif_color.c
   4  * Copyright (c) 1988-1997 Sam Leffler 
   5  * Copyright (c) 1991-1997 Silicon Graphics, Inc. 
   7  * Permission to use, copy, modify, distribute, and sell this software and  
   8  * its documentation for any purpose is hereby granted without fee, provided 
   9  * that (i) the above copyright notices and this permission notice appear in 
  10  * all copies of the software and related documentation, and (ii) the names of 
  11  * Sam Leffler and Silicon Graphics may not be used in any advertising or 
  12  * publicity relating to the software without the specific, prior written 
  13  * permission of Sam Leffler and Silicon Graphics. 
  15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  
  16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  
  17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   
  19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 
  20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 
  21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  
  23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  
  28  * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken 
  29  * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with 
  30  * the permission of John Cupitt, the VIPS author. 
  36  * Color space conversion routines. 
  43  * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ. 
  46 TIFFCIELabToXYZ(TIFFCIELabToRGB 
*cielab
, uint32 l
, int32 a
, int32 b
, 
  47                 float *X
, float *Y
, float *Z
) 
  49         float L 
= (float)l 
* 100.0F 
/ 255.0F
; 
  53                 *Y 
= (L 
* cielab
->Y0
) / 903.292F
; 
  54                 cby 
= 7.787F 
* (*Y 
/ cielab
->Y0
) + 16.0F 
/ 116.0F
; 
  56                 cby 
= (L 
+ 16.0F
) / 116.0F
; 
  57                 *Y 
= cielab
->Y0 
* cby 
* cby 
* cby
; 
  60         tmp 
= (float)a 
/ 500.0F 
+ cby
; 
  62                 *X 
= cielab
->X0 
* (tmp 
- 0.13793F
) / 7.787F
; 
  64                 *X 
= cielab
->X0 
* tmp 
* tmp 
* tmp
; 
  66         tmp 
= cby 
- (float)b 
/ 200.0F
; 
  68                 *Z 
= cielab
->Z0 
* (tmp 
- 0.13793F
) / 7.787F
; 
  70                 *Z 
= cielab
->Z0 
* tmp 
* tmp 
* tmp
; 
  73 #define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5))) 
  75  * Convert color value from the XYZ space to RGB. 
  78 TIFFXYZToRGB(TIFFCIELabToRGB 
*cielab
, float X
, float Y
, float Z
, 
  79              uint32 
*r
, uint32 
*g
, uint32 
*b
) 
  83         float *matrix 
= &cielab
->display
.d_mat
[0][0]; 
  85         /* Multiply through the matrix to get luminosity values. */ 
  86         Yr 
=  matrix
[0] * X 
+ matrix
[1] * Y 
+ matrix
[2] * Z
; 
  87         Yg 
=  matrix
[3] * X 
+ matrix
[4] * Y 
+ matrix
[5] * Z
; 
  88         Yb 
=  matrix
[6] * X 
+ matrix
[7] * Y 
+ matrix
[8] * Z
; 
  91         Yr 
= TIFFmax(Yr
, cielab
->display
.d_Y0R
); 
  92         Yg 
= TIFFmax(Yg
, cielab
->display
.d_Y0G
); 
  93         Yb 
= TIFFmax(Yb
, cielab
->display
.d_Y0B
); 
  95         /* Avoid overflow in case of wrong input values */ 
  96         Yr 
= TIFFmin(Yr
, cielab
->display
.d_YCR
); 
  97         Yg 
= TIFFmin(Yg
, cielab
->display
.d_YCG
); 
  98         Yb 
= TIFFmin(Yb
, cielab
->display
.d_YCB
); 
 100         /* Turn luminosity to colour value. */ 
 101         i 
= (int)((Yr 
- cielab
->display
.d_Y0R
) / cielab
->rstep
); 
 102         i 
= TIFFmin(cielab
->range
, i
); 
 103         *r 
= RINT(cielab
->Yr2r
[i
]); 
 105         i 
= (int)((Yg 
- cielab
->display
.d_Y0G
) / cielab
->gstep
); 
 106         i 
= TIFFmin(cielab
->range
, i
); 
 107         *g 
= RINT(cielab
->Yg2g
[i
]); 
 109         i 
= (int)((Yb 
- cielab
->display
.d_Y0B
) / cielab
->bstep
); 
 110         i 
= TIFFmin(cielab
->range
, i
); 
 111         *b 
= RINT(cielab
->Yb2b
[i
]); 
 114         *r 
= TIFFmin(*r
, cielab
->display
.d_Vrwr
); 
 115         *g 
= TIFFmin(*g
, cielab
->display
.d_Vrwg
); 
 116         *b 
= TIFFmin(*b
, cielab
->display
.d_Vrwb
); 
 121  * Allocate conversion state structures and make look_up tables for 
 122  * the Yr,Yb,Yg <=> r,g,b conversions. 
 125 TIFFCIELabToRGBInit(TIFFCIELabToRGB
* cielab
, 
 126                     TIFFDisplay 
*display
, float *refWhite
) 
 131         cielab
->range 
= CIELABTORGB_TABLE_RANGE
; 
 133         _TIFFmemcpy(&cielab
->display
, display
, sizeof(TIFFDisplay
)); 
 136         gamma 
= 1.0 / cielab
->display
.d_gammaR 
; 
 138                 (cielab
->display
.d_YCR 
- cielab
->display
.d_Y0R
) / cielab
->range
; 
 139         for(i 
= 0; i 
<= cielab
->range
; i
++) { 
 140                 cielab
->Yr2r
[i
] = cielab
->display
.d_Vrwr
 
 141                     * ((float)pow((double)i 
/ cielab
->range
, gamma
)); 
 145         gamma 
= 1.0 / cielab
->display
.d_gammaG 
; 
 147             (cielab
->display
.d_YCR 
- cielab
->display
.d_Y0R
) / cielab
->range
; 
 148         for(i 
= 0; i 
<= cielab
->range
; i
++) { 
 149                 cielab
->Yg2g
[i
] = cielab
->display
.d_Vrwg
 
 150                     * ((float)pow((double)i 
/ cielab
->range
, gamma
)); 
 154         gamma 
= 1.0 / cielab
->display
.d_gammaB 
; 
 156             (cielab
->display
.d_YCR 
- cielab
->display
.d_Y0R
) / cielab
->range
; 
 157         for(i 
= 0; i 
<= cielab
->range
; i
++) { 
 158                 cielab
->Yb2b
[i
] = cielab
->display
.d_Vrwb
 
 159                     * ((float)pow((double)i 
/ cielab
->range
, gamma
)); 
 162         /* Init reference white point */ 
 163         cielab
->X0 
= refWhite
[0]; 
 164         cielab
->Y0 
= refWhite
[1]; 
 165         cielab
->Z0 
= refWhite
[2]; 
 171  * Convert color value from the YCbCr space to CIE XYZ. 
 172  * The colorspace conversion algorithm comes from the IJG v5a code; 
 173  * see below for more information on how it works. 
 176 #define FIX(x)                  ((int32)((x) * (1L<<SHIFT) + 0.5)) 
 177 #define ONE_HALF                ((int32)(1<<(SHIFT-1))) 
 178 #define Code2V(c, RB, RW, CR)   ((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)) ? ((RW)-(RB)) : 1)) 
 179 #define CLAMP(f,min,max)        ((f)<(min)?(min):(f)>(max)?(max):(f)) 
 180 #define HICLAMP(f,max)          ((f)>(max)?(max):(f)) 
 183 TIFFYCbCrtoRGB(TIFFYCbCrToRGB 
*ycbcr
, uint32 Y
, int32 Cb
, int32 Cr
, 
 184                uint32 
*r
, uint32 
*g
, uint32 
*b
) 
 186         /* XXX: Only 8-bit YCbCr input supported for now */ 
 187         Y 
= HICLAMP(Y
, 255), Cb 
= CLAMP(Cb
, 0, 255), Cr 
= CLAMP(Cr
, 0, 255); 
 189         *r 
= ycbcr
->clamptab
[ycbcr
->Y_tab
[Y
] + ycbcr
->Cr_r_tab
[Cr
]]; 
 190         *g 
= ycbcr
->clamptab
[ycbcr
->Y_tab
[Y
] 
 191             + (int)((ycbcr
->Cb_g_tab
[Cb
] + ycbcr
->Cr_g_tab
[Cr
]) >> SHIFT
)]; 
 192         *b 
= ycbcr
->clamptab
[ycbcr
->Y_tab
[Y
] + ycbcr
->Cb_b_tab
[Cb
]]; 
 196  * Initialize the YCbCr->RGB conversion tables.  The conversion 
 197  * is done according to the 6.0 spec: 
 199  *    R = Y + Cr*(2 - 2*LumaRed) 
 200  *    B = Y + Cb*(2 - 2*LumaBlue) 
 202  *        - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen 
 203  *        - LumaRed*Cr*(2-2*LumaRed)/LumaGreen 
 205  * To avoid floating point arithmetic the fractional constants that 
 206  * come out of the equations are represented as fixed point values 
 207  * in the range 0...2^16.  We also eliminate multiplications by 
 208  * pre-calculating possible values indexed by Cb and Cr (this code 
 209  * assumes conversion is being done for 8-bit samples). 
 212 TIFFYCbCrToRGBInit(TIFFYCbCrToRGB
* ycbcr
, float *luma
, float *refBlackWhite
) 
 214     TIFFRGBValue
* clamptab
; 
 217 #define LumaRed     luma[0] 
 218 #define LumaGreen   luma[1] 
 219 #define LumaBlue    luma[2] 
 221     clamptab 
= (TIFFRGBValue
*)( 
 222         (tidata_t
) ycbcr
+TIFFroundup(sizeof (TIFFYCbCrToRGB
), sizeof (long))); 
 223     _TIFFmemset(clamptab
, 0, 256);              /* v < 0 => 0 */ 
 224     ycbcr
->clamptab 
= (clamptab 
+= 256); 
 225     for (i 
= 0; i 
< 256; i
++) 
 226         clamptab
[i
] = (TIFFRGBValue
) i
; 
 227     _TIFFmemset(clamptab
+256, 255, 2*256);      /* v > 255 => 255 */ 
 228     ycbcr
->Cr_r_tab 
= (int*) (clamptab 
+ 3*256); 
 229     ycbcr
->Cb_b_tab 
= ycbcr
->Cr_r_tab 
+ 256; 
 230     ycbcr
->Cr_g_tab 
= (int32
*) (ycbcr
->Cb_b_tab 
+ 256); 
 231     ycbcr
->Cb_g_tab 
= ycbcr
->Cr_g_tab 
+ 256; 
 232     ycbcr
->Y_tab 
= ycbcr
->Cb_g_tab 
+ 256; 
 234     { float f1 
= 2-2*LumaRed
;           int32 D1 
= FIX(f1
); 
 235       float f2 
= LumaRed
*f1
/LumaGreen
;  int32 D2 
= -FIX(f2
); 
 236       float f3 
= 2-2*LumaBlue
;          int32 D3 
= FIX(f3
); 
 237       float f4 
= LumaBlue
*f3
/LumaGreen
; int32 D4 
= -FIX(f4
); 
 245        * i is the actual input pixel value in the range 0..255 
 246        * Cb and Cr values are in the range -128..127 (actually 
 247        * they are in a range defined by the ReferenceBlackWhite 
 248        * tag) so there is some range shifting to do here when 
 249        * constructing tables indexed by the raw pixel data. 
 251       for (i 
= 0, x 
= -128; i 
< 256; i
++, x
++) { 
 252             int32 Cr 
= (int32
)Code2V(x
, refBlackWhite
[4] - 128.0F
, 
 253                             refBlackWhite
[5] - 128.0F
, 127); 
 254             int32 Cb 
= (int32
)Code2V(x
, refBlackWhite
[2] - 128.0F
, 
 255                             refBlackWhite
[3] - 128.0F
, 127); 
 257             ycbcr
->Cr_r_tab
[i
] = (int32
)((D1
*Cr 
+ ONE_HALF
)>>SHIFT
); 
 258             ycbcr
->Cb_b_tab
[i
] = (int32
)((D3
*Cb 
+ ONE_HALF
)>>SHIFT
); 
 259             ycbcr
->Cr_g_tab
[i
] = D2
*Cr
; 
 260             ycbcr
->Cb_g_tab
[i
] = D4
*Cb 
+ ONE_HALF
; 
 262                     (int32
)Code2V(x 
+ 128, refBlackWhite
[0], refBlackWhite
[1], 255); 
 275 /* vim: set ts=8 sts=8 sw=8 noet: */