]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/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         /* Turn luminosity to colour value. */ 
  96         i 
= TIFFmin(cielab
->range
, 
  97                     (int)((Yr 
- cielab
->display
.d_Y0R
) / cielab
->rstep
)); 
  98         *r 
= RINT(cielab
->Yr2r
[i
]); 
 100         i 
= TIFFmin(cielab
->range
, 
 101                     (int)((Yg 
- cielab
->display
.d_Y0G
) / cielab
->gstep
)); 
 102         *g 
= RINT(cielab
->Yg2g
[i
]); 
 104         i 
= TIFFmin(cielab
->range
, 
 105                     (int)((Yb 
- cielab
->display
.d_Y0B
) / cielab
->bstep
)); 
 106         *b 
= RINT(cielab
->Yb2b
[i
]); 
 109         *r 
= TIFFmin( *r
, cielab
->display
.d_Vrwr 
); 
 110         *g 
= TIFFmin( *g
, cielab
->display
.d_Vrwg 
); 
 111         *b 
= TIFFmin( *b
, cielab
->display
.d_Vrwb 
); 
 116  * Allocate conversion state structures and make look_up tables for 
 117  * the Yr,Yb,Yg <=> r,g,b conversions. 
 120 TIFFCIELabToRGBInit(TIFFCIELabToRGB
* cielab
, 
 121                     TIFFDisplay 
*display
, float *refWhite
) 
 126         cielab
->range 
= CIELABTORGB_TABLE_RANGE
; 
 128         _TIFFmemcpy(&cielab
->display
, display
, sizeof(TIFFDisplay
)); 
 131         gamma 
= 1.0F 
/ cielab
->display
.d_gammaR 
; 
 133                 (cielab
->display
.d_YCR 
- cielab
->display
.d_Y0R
) / cielab
->range
; 
 134         for(i 
= 0; i 
<= cielab
->range
; i
++) { 
 135                 cielab
->Yr2r
[i
] = cielab
->display
.d_Vrwr
 
 136                     * ((float)pow((double)i 
/ cielab
->range
, gamma
)); 
 140         gamma 
= 1.0F 
/ cielab
->display
.d_gammaG 
; 
 142             (cielab
->display
.d_YCR 
- cielab
->display
.d_Y0R
) / cielab
->range
; 
 143         for(i 
= 0; i 
<= cielab
->range
; i
++) { 
 144                 cielab
->Yg2g
[i
] = cielab
->display
.d_Vrwg
 
 145                     * ((float)pow((double)i 
/ cielab
->range
, gamma
)); 
 149         gamma 
= 1.0F 
/ cielab
->display
.d_gammaB 
; 
 151             (cielab
->display
.d_YCR 
- cielab
->display
.d_Y0R
) / cielab
->range
; 
 152         for(i 
= 0; i 
<= cielab
->range
; i
++) { 
 153                 cielab
->Yb2b
[i
] = cielab
->display
.d_Vrwb
 
 154                     * ((float)pow((double)i 
/ cielab
->range
, gamma
)); 
 157         /* Init reference white point */ 
 158         cielab
->X0 
= refWhite
[0]; 
 159         cielab
->Y0 
= refWhite
[1]; 
 160         cielab
->Z0 
= refWhite
[2]; 
 166  * Convert color value from the YCbCr space to CIE XYZ. 
 167  * The colorspace conversion algorithm comes from the IJG v5a code; 
 168  * see below for more information on how it works. 
 171 #define FIX(x)                  ((int32)((x) * (1L<<SHIFT) + 0.5)) 
 172 #define ONE_HALF                ((int32)(1<<(SHIFT-1))) 
 173 #define Code2V(c, RB, RW, CR)   ((((c)-(int32)(RB))*(float)(CR))/(float)((RW)-(RB))) 
 174 #define CLAMP(f,min,max)        ((f)<(min)?(min):(f)>(max)?(max):(f)) 
 177 TIFFYCbCrtoRGB(TIFFYCbCrToRGB 
*ycbcr
, uint32 Y
, int32 Cb
, int32 Cr
, 
 178                uint32 
*r
, uint32 
*g
, uint32 
*b
) 
 180         /* XXX: Only 8-bit YCbCr input supported for now */ 
 181         Y 
= CLAMP(Y
, 0, 255), Cb 
= CLAMP(Cb
, 0, 255), Cr 
= CLAMP(Cr
, 0, 255); 
 183         *r 
= ycbcr
->clamptab
[ycbcr
->Y_tab
[Y
] + ycbcr
->Cr_r_tab
[Cr
]]; 
 184         *g 
= ycbcr
->clamptab
[ycbcr
->Y_tab
[Y
] 
 185             + (int)((ycbcr
->Cb_g_tab
[Cb
] + ycbcr
->Cr_g_tab
[Cr
]) >> SHIFT
)]; 
 186         *b 
= ycbcr
->clamptab
[ycbcr
->Y_tab
[Y
] + ycbcr
->Cb_b_tab
[Cb
]]; 
 190  * Initialize the YCbCr->RGB conversion tables.  The conversion 
 191  * is done according to the 6.0 spec: 
 193  *    R = Y + Cr*(2 - 2*LumaRed) 
 194  *    B = Y + Cb*(2 - 2*LumaBlue) 
 196  *        - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen 
 197  *        - LumaRed*Cr*(2-2*LumaRed)/LumaGreen 
 199  * To avoid floating point arithmetic the fractional constants that 
 200  * come out of the equations are represented as fixed point values 
 201  * in the range 0...2^16.  We also eliminate multiplications by 
 202  * pre-calculating possible values indexed by Cb and Cr (this code 
 203  * assumes conversion is being done for 8-bit samples). 
 206 TIFFYCbCrToRGBInit(TIFFYCbCrToRGB
* ycbcr
, float *luma
, float *refBlackWhite
) 
 208     TIFFRGBValue
* clamptab
; 
 211 #define LumaRed     luma[0] 
 212 #define LumaGreen   luma[1] 
 213 #define LumaBlue    luma[2] 
 215     clamptab 
= (TIFFRGBValue
*)( 
 216         (tidata_t
) ycbcr
+TIFFroundup(sizeof (TIFFYCbCrToRGB
), sizeof (long))); 
 217     _TIFFmemset(clamptab
, 0, 256);              /* v < 0 => 0 */ 
 218     ycbcr
->clamptab 
= (clamptab 
+= 256); 
 219     for (i 
= 0; i 
< 256; i
++) 
 220         clamptab
[i
] = (TIFFRGBValue
) i
; 
 221     _TIFFmemset(clamptab
+256, 255, 2*256);      /* v > 255 => 255 */ 
 222     ycbcr
->Cr_r_tab 
= (int*) (clamptab 
+ 3*256); 
 223     ycbcr
->Cb_b_tab 
= ycbcr
->Cr_r_tab 
+ 256; 
 224     ycbcr
->Cr_g_tab 
= (int32
*) (ycbcr
->Cb_b_tab 
+ 256); 
 225     ycbcr
->Cb_g_tab 
= ycbcr
->Cr_g_tab 
+ 256; 
 226     ycbcr
->Y_tab 
= ycbcr
->Cb_g_tab 
+ 256; 
 228     { float f1 
= 2-2*LumaRed
;           int32 D1 
= FIX(f1
); 
 229       float f2 
= LumaRed
*f1
/LumaGreen
;  int32 D2 
= -FIX(f2
); 
 230       float f3 
= 2-2*LumaBlue
;          int32 D3 
= FIX(f3
); 
 231       float f4 
= LumaBlue
*f3
/LumaGreen
; int32 D4 
= -FIX(f4
); 
 239        * i is the actual input pixel value in the range 0..255 
 240        * Cb and Cr values are in the range -128..127 (actually 
 241        * they are in a range defined by the ReferenceBlackWhite 
 242        * tag) so there is some range shifting to do here when 
 243        * constructing tables indexed by the raw pixel data. 
 245       for (i 
= 0, x 
= -128; i 
< 256; i
++, x
++) { 
 246             int32 Cr 
= (int32
)Code2V(x
, refBlackWhite
[4] - 128.0F
, 
 247                             refBlackWhite
[5] - 128.0F
, 127); 
 248             int32 Cb 
= (int32
)Code2V(x
, refBlackWhite
[2] - 128.0F
, 
 249                             refBlackWhite
[3] - 128.0F
, 127); 
 251             ycbcr
->Cr_r_tab
[i
] = (int32
)((D1
*Cr 
+ ONE_HALF
)>>SHIFT
); 
 252             ycbcr
->Cb_b_tab
[i
] = (int32
)((D3
*Cb 
+ ONE_HALF
)>>SHIFT
); 
 253             ycbcr
->Cr_g_tab
[i
] = D2
*Cr
; 
 254             ycbcr
->Cb_g_tab
[i
] = D4
*Cb 
+ ONE_HALF
; 
 256                     (int32
)Code2V(x 
+ 128, refBlackWhite
[0], refBlackWhite
[1], 255);