~ubuntu-branches/ubuntu/karmic/tiff/karmic-security

« back to all changes in this revision

Viewing changes to libtiff/tif_color.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2004-10-14 07:57:59 UTC
  • Revision ID: james.westby@ubuntu.com-20041014075759-a77e7zuaetya8cp0
Tags: upstream-3.6.1
ImportĀ upstreamĀ versionĀ 3.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Header: /cvsroot/osrs/libtiff/libtiff/tif_color.c,v 1.7 2003/12/24 22:02:04 dron Exp $ */
 
2
 
 
3
/*
 
4
 * Copyright (c) 1988-1997 Sam Leffler
 
5
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 
6
 *
 
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.
 
14
 * 
 
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.  
 
18
 * 
 
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 
 
24
 * OF THIS SOFTWARE.
 
25
 */
 
26
 
 
27
/*
 
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.
 
31
 */
 
32
 
 
33
/*
 
34
 * TIFF Library.
 
35
 *
 
36
 * Color space conversion routines.
 
37
 */
 
38
 
 
39
#include "tiffiop.h"
 
40
#include <math.h>
 
41
 
 
42
/*
 
43
 * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
 
44
 */
 
45
void
 
46
TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b,
 
47
                float *X, float *Y, float *Z)
 
48
{
 
49
        float L = (float)l * 100.0F / 255.0F;
 
50
        float cby, tmp;
 
51
 
 
52
        if( L < 8.856F ) {
 
53
                *Y = (L * cielab->Y0) / 903.292F;
 
54
                cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
 
55
        } else {
 
56
                cby = (L + 16.0F) / 116.0F;
 
57
                *Y = cielab->Y0 * cby * cby * cby;
 
58
        }
 
59
 
 
60
        tmp = (float)a / 500.0F + cby;
 
61
        if( tmp < 0.2069F )
 
62
                *X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
 
63
        else    
 
64
                *X = cielab->X0 * tmp * tmp * tmp;
 
65
 
 
66
        tmp = cby - (float)b / 200.0F;
 
67
        if( tmp < 0.2069F )
 
68
                *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
 
69
        else    
 
70
                *Z = cielab->Z0 * tmp * tmp * tmp;
 
71
}
 
72
 
 
73
#define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5)))
 
74
/*
 
75
 * Convert color value from the XYZ space to RGB.
 
76
 */
 
77
void
 
78
TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
 
79
             uint32 *r, uint32 *g, uint32 *b)
 
80
{
 
81
        int i;
 
82
        float Yr, Yg, Yb;
 
83
        float *matrix = &cielab->display.d_mat[0][0];
 
84
 
 
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;
 
89
 
 
90
        /* Clip input */
 
91
        Yr = TIFFmax( Yr, cielab->display.d_Y0R );
 
92
        Yg = TIFFmax( Yg, cielab->display.d_Y0G );
 
93
        Yb = TIFFmax( Yb, cielab->display.d_Y0B );
 
94
 
 
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]);
 
99
 
 
100
        i = TIFFmin(cielab->range,
 
101
                    (int)((Yg - cielab->display.d_Y0G) / cielab->gstep));
 
102
        *g = RINT(cielab->Yg2g[i]);
 
103
 
 
104
        i = TIFFmin(cielab->range,
 
105
                    (int)((Yb - cielab->display.d_Y0B) / cielab->bstep));
 
106
        *b = RINT(cielab->Yb2b[i]);
 
107
 
 
108
        /* Clip output. */
 
109
        *r = TIFFmin( *r, cielab->display.d_Vrwr );
 
110
        *g = TIFFmin( *g, cielab->display.d_Vrwg );
 
111
        *b = TIFFmin( *b, cielab->display.d_Vrwb );
 
112
}
 
113
#undef RINT
 
114
 
 
115
/* 
 
116
 * Allocate conversion state structures and make look_up tables for
 
117
 * the Yr,Yb,Yg <=> r,g,b conversions.
 
118
 */
 
119
int
 
120
TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab,
 
121
                    TIFFDisplay *display, float *refWhite)
 
122
{
 
123
        int i;
 
124
        float gamma;
 
125
 
 
126
        cielab->range = CIELABTORGB_TABLE_RANGE;
 
127
 
 
128
        _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
 
129
 
 
130
        /* Red */
 
131
        gamma = 1.0F / cielab->display.d_gammaR ;
 
132
        cielab->rstep =
 
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));
 
137
        }
 
138
 
 
139
        /* Green */
 
140
        gamma = 1.0F / cielab->display.d_gammaG ;
 
141
        cielab->gstep =
 
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));
 
146
        }
 
147
 
 
148
        /* Blue */
 
149
        gamma = 1.0F / cielab->display.d_gammaB ;
 
150
        cielab->bstep =
 
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));
 
155
        }
 
156
 
 
157
        /* Init reference white point */
 
158
        cielab->X0 = refWhite[0];
 
159
        cielab->Y0 = refWhite[1];
 
160
        cielab->Z0 = refWhite[2];
 
161
 
 
162
        return 0;
 
163
}
 
164
 
 
165
/* 
 
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.
 
169
 */
 
170
#define SHIFT                   16
 
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))
 
175
 
 
176
void
 
177
TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
 
178
               uint32 *r, uint32 *g, uint32 *b)
 
179
{
 
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);
 
182
 
 
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]];
 
187
}
 
188
 
 
189
/*
 
190
 * Initialize the YCbCr->RGB conversion tables.  The conversion
 
191
 * is done according to the 6.0 spec:
 
192
 *
 
193
 *    R = Y + Cr*(2 - 2*LumaRed)
 
194
 *    B = Y + Cb*(2 - 2*LumaBlue)
 
195
 *    G =   Y
 
196
 *        - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
 
197
 *        - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
 
198
 *
 
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).
 
204
 */
 
205
int
 
206
TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
 
207
{
 
208
    TIFFRGBValue* clamptab;
 
209
    int i;
 
210
    
 
211
#define LumaRed     luma[0]
 
212
#define LumaGreen   luma[1]
 
213
#define LumaBlue    luma[2]
 
214
 
 
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;
 
227
 
 
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);
 
232
      int x;
 
233
 
 
234
#undef LumaBlue
 
235
#undef LumaGreen
 
236
#undef LumaRed
 
237
      
 
238
      /*
 
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.
 
244
       */
 
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);
 
250
 
 
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;
 
255
            ycbcr->Y_tab[i] =
 
256
                    (int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255);
 
257
      }
 
258
    }
 
259
 
 
260
    return 0;
 
261
}
 
262
#undef  CLAMP
 
263
#undef  Code2V
 
264
#undef  SHIFT
 
265
#undef  ONE_HALF
 
266
#undef  FIX
 
267
 
 
268