~ubuntu-branches/ubuntu/utopic/blender/utopic-proposed

« back to all changes in this revision

Viewing changes to source/blender/blenlib/intern/math_color.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-04-28 12:11:12 UTC
  • mto: (14.1.6 experimental) (1.5.1)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: package-import@ubuntu.com-20120428121112-2zi0vp8b6vejda8i
Tags: upstream-2.63
ImportĀ upstreamĀ versionĀ 2.63

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *
18
18
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19
19
 * All rights reserved.
20
 
 
 
20
 *
21
21
 * The Original Code is: some of this file.
22
22
 *
23
23
 * ***** END GPL LICENSE BLOCK *****
41
41
        int i;
42
42
        float f, p, q, t;
43
43
 
44
 
        if(s==0.0f) {
 
44
        if (s == 0.0f) {
45
45
                *r = v;
46
46
                *g = v;
47
47
                *b = v;
48
48
        }
49
49
        else {
50
 
                h= (h - floorf(h))*6.0f;
 
50
                h = (h - floorf(h)) * 6.0f;
51
51
 
52
52
                i = (int)floorf(h);
53
53
                f = h - i;
54
 
                p = v*(1.0f-s);
55
 
                q = v*(1.0f-(s*f));
56
 
                t = v*(1.0f-(s*(1.0f-f)));
57
 
                
 
54
                p = v * (1.0f - s);
 
55
                q = v * (1.0f - (s * f));
 
56
                t = v * (1.0f - (s * (1.0f - f)));
 
57
 
58
58
                switch (i) {
59
 
                case 0 :
60
 
                        *r = v;
61
 
                        *g = t;
62
 
                        *b = p;
63
 
                        break;
64
 
                case 1 :
65
 
                        *r = q;
66
 
                        *g = v;
67
 
                        *b = p;
68
 
                        break;
69
 
                case 2 :
70
 
                        *r = p;
71
 
                        *g = v;
72
 
                        *b = t;
73
 
                        break;
74
 
                case 3 :
75
 
                        *r = p;
76
 
                        *g = q;
77
 
                        *b = v;
78
 
                        break;
79
 
                case 4 :
80
 
                        *r = t;
81
 
                        *g = p;
82
 
                        *b = v;
83
 
                        break;
84
 
                case 5 :
85
 
                        *r = v;
86
 
                        *g = p;
87
 
                        *b = q;
88
 
                        break;
 
59
                        case 0:
 
60
                                *r = v;
 
61
                                *g = t;
 
62
                                *b = p;
 
63
                                break;
 
64
                        case 1:
 
65
                                *r = q;
 
66
                                *g = v;
 
67
                                *b = p;
 
68
                                break;
 
69
                        case 2:
 
70
                                *r = p;
 
71
                                *g = v;
 
72
                                *b = t;
 
73
                                break;
 
74
                        case 3:
 
75
                                *r = p;
 
76
                                *g = q;
 
77
                                *b = v;
 
78
                                break;
 
79
                        case 4:
 
80
                                *r = t;
 
81
                                *g = p;
 
82
                                *b = v;
 
83
                                break;
 
84
                        case 5:
 
85
                                *r = v;
 
86
                                *g = p;
 
87
                                *b = q;
 
88
                                break;
89
89
                }
90
90
        }
91
91
}
93
93
void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv)
94
94
{
95
95
        float y, u, v;
96
 
        y= 0.299f*r + 0.587f*g + 0.114f*b;
97
 
        u=-0.147f*r - 0.289f*g + 0.436f*b;
98
 
        v= 0.615f*r - 0.515f*g - 0.100f*b;
99
 
        
100
 
        *ly=y;
101
 
        *lu=u;
102
 
        *lv=v;
 
96
        y = 0.299f * r + 0.587f * g + 0.114f * b;
 
97
        u = -0.147f * r - 0.289f * g + 0.436f * b;
 
98
        v = 0.615f * r - 0.515f * g - 0.100f * b;
 
99
 
 
100
        *ly = y;
 
101
        *lu = u;
 
102
        *lv = v;
103
103
}
104
104
 
105
105
void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb)
106
106
{
107
107
        float r, g, b;
108
 
        r=y+1.140f*v;
109
 
        g=y-0.394f*u - 0.581f*v;
110
 
        b=y+2.032f*u;
111
 
        
112
 
        *lr=r;
113
 
        *lg=g;
114
 
        *lb=b;
 
108
        r = y + 1.140f * v;
 
109
        g = y - 0.394f * u - 0.581f * v;
 
110
        b = y + 2.032f * u;
 
111
 
 
112
        *lr = r;
 
113
        *lg = g;
 
114
        *lb = b;
115
115
}
116
116
 
117
 
/* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f */
118
 
/* Output YCC have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */
 
117
/* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f
 
118
 *
 
119
 * Output YCC have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */
119
120
void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr, int colorspace)
120
121
{
121
 
        float sr,sg, sb;
 
122
        float sr, sg, sb;
122
123
        float y = 128.f, cr = 128.f, cb = 128.f;
123
 
        
124
 
        sr=255.0f*r;
125
 
        sg=255.0f*g;
126
 
        sb=255.0f*b;
127
 
        
 
124
 
 
125
        sr = 255.0f * r;
 
126
        sg = 255.0f * g;
 
127
        sb = 255.0f * b;
 
128
 
128
129
        switch (colorspace) {
129
 
        case BLI_YCC_ITU_BT601 :
130
 
                y=(0.257f*sr)+(0.504f*sg)+(0.098f*sb)+16.0f;
131
 
                cb=(-0.148f*sr)-(0.291f*sg)+(0.439f*sb)+128.0f;
132
 
                cr=(0.439f*sr)-(0.368f*sg)-(0.071f*sb)+128.0f;
133
 
                break;
134
 
        case BLI_YCC_ITU_BT709 :
135
 
                y=(0.183f*sr)+(0.614f*sg)+(0.062f*sb)+16.0f;
136
 
                cb=(-0.101f*sr)-(0.338f*sg)+(0.439f*sb)+128.0f;
137
 
                cr=(0.439f*sr)-(0.399f*sg)-(0.040f*sb)+128.0f;
138
 
                break;
139
 
        case BLI_YCC_JFIF_0_255 :
140
 
                y=(0.299f*sr)+(0.587f*sg)+(0.114f*sb);
141
 
                cb=(-0.16874f*sr)-(0.33126f*sg)+(0.5f*sb)+128.0f;
142
 
                cr=(0.5f*sr)-(0.41869f*sg)-(0.08131f*sb)+128.0f;
143
 
                break;
144
 
        default:
145
 
                assert(!"invalid colorspace");
 
130
                case BLI_YCC_ITU_BT601:
 
131
                        y = (0.257f * sr) + (0.504f * sg) + (0.098f * sb) + 16.0f;
 
132
                        cb = (-0.148f * sr) - (0.291f * sg) + (0.439f * sb) + 128.0f;
 
133
                        cr = (0.439f * sr) - (0.368f * sg) - (0.071f * sb) + 128.0f;
 
134
                        break;
 
135
                case BLI_YCC_ITU_BT709:
 
136
                        y = (0.183f * sr) + (0.614f * sg) + (0.062f * sb) + 16.0f;
 
137
                        cb = (-0.101f * sr) - (0.338f * sg) + (0.439f * sb) + 128.0f;
 
138
                        cr = (0.439f * sr) - (0.399f * sg) - (0.040f * sb) + 128.0f;
 
139
                        break;
 
140
                case BLI_YCC_JFIF_0_255:
 
141
                        y = (0.299f * sr) + (0.587f * sg) + (0.114f * sb);
 
142
                        cb = (-0.16874f * sr) - (0.33126f * sg) + (0.5f * sb) + 128.0f;
 
143
                        cr = (0.5f * sr) - (0.41869f * sg) - (0.08131f * sb) + 128.0f;
 
144
                        break;
 
145
                default:
 
146
                        assert(!"invalid colorspace");
146
147
        }
147
 
        
148
 
        *ly=y;
149
 
        *lcb=cb;
150
 
        *lcr=cr;
 
148
 
 
149
        *ly = y;
 
150
        *lcb = cb;
 
151
        *lcr = cr;
151
152
}
152
153
 
153
154
 
154
155
/* YCC input have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */
155
156
/* RGB outputs are in the range 0 - 1.0f */
 
157
 
156
158
/* FIXME comment above must be wrong because BLI_YCC_ITU_BT601 y 16.0 cr 16.0 -> r -0.7009 */
157
159
void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, int colorspace)
158
160
{
159
161
        float r = 128.f, g = 128.f, b = 128.f;
160
 
        
 
162
 
161
163
        switch (colorspace) {
162
 
        case BLI_YCC_ITU_BT601 :
163
 
                r=1.164f*(y-16.0f)+1.596f*(cr-128.0f);
164
 
                g=1.164f*(y-16.0f)-0.813f*(cr-128.0f)-0.392f*(cb-128.0f);
165
 
                b=1.164f*(y-16.0f)+2.017f*(cb-128.0f);
166
 
                break;
167
 
        case BLI_YCC_ITU_BT709 :
168
 
                r=1.164f*(y-16.0f)+1.793f*(cr-128.0f);
169
 
                g=1.164f*(y-16.0f)-0.534f*(cr-128.0f)-0.213f*(cb-128.0f);
170
 
                b=1.164f*(y-16.0f)+2.115f*(cb-128.0f);
171
 
                break;
172
 
        case BLI_YCC_JFIF_0_255 :
173
 
                r=y+1.402f*cr - 179.456f;
174
 
                g=y-0.34414f*cb - 0.71414f*cr + 135.45984f;
175
 
                b=y+1.772f*cb - 226.816f;
176
 
                break;
177
 
        default:
178
 
                assert(!"invalid colorspace");
 
164
                case BLI_YCC_ITU_BT601:
 
165
                        r = 1.164f * (y - 16.0f) + 1.596f * (cr - 128.0f);
 
166
                        g = 1.164f * (y - 16.0f) - 0.813f * (cr - 128.0f) - 0.392f * (cb - 128.0f);
 
167
                        b = 1.164f * (y - 16.0f) + 2.017f * (cb - 128.0f);
 
168
                        break;
 
169
                case BLI_YCC_ITU_BT709:
 
170
                        r = 1.164f * (y - 16.0f) + 1.793f * (cr - 128.0f);
 
171
                        g = 1.164f * (y - 16.0f) - 0.534f * (cr - 128.0f) - 0.213f * (cb - 128.0f);
 
172
                        b = 1.164f * (y - 16.0f) + 2.115f * (cb - 128.0f);
 
173
                        break;
 
174
                case BLI_YCC_JFIF_0_255:
 
175
                        r = y + 1.402f * cr - 179.456f;
 
176
                        g = y - 0.34414f * cb - 0.71414f * cr + 135.45984f;
 
177
                        b = y + 1.772f * cb - 226.816f;
 
178
                        break;
 
179
                default:
 
180
                        assert(!"invalid colorspace");
179
181
        }
180
 
        *lr=r/255.0f;
181
 
        *lg=g/255.0f;
182
 
        *lb=b/255.0f;
 
182
        *lr = r / 255.0f;
 
183
        *lg = g / 255.0f;
 
184
        *lb = b / 255.0f;
183
185
}
184
186
 
185
187
void hex_to_rgb(char *hexcol, float *r, float *g, float *b)
188
190
 
189
191
        if (hexcol[0] == '#') hexcol++;
190
192
 
191
 
        if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi)==3) {
 
193
        if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi) == 3) {
192
194
                *r = ri / 255.0f;
193
195
                *g = gi / 255.0f;
194
196
                *b = bi / 255.0f;
198
200
        }
199
201
        else {
200
202
                /* avoid using un-initialized vars */
201
 
                *r= *g= *b= 0.0f;
 
203
                *r = *g = *b = 0.0f;
202
204
        }
203
205
}
204
206
 
210
212
 
211
213
        cmax = r;
212
214
        cmin = r;
213
 
        cmax = (g>cmax ? g:cmax);
214
 
        cmin = (g<cmin ? g:cmin);
215
 
        cmax = (b>cmax ? b:cmax);
216
 
        cmin = (b<cmin ? b:cmin);
 
215
        cmax = (g > cmax ? g : cmax);
 
216
        cmin = (g < cmin ? g : cmin);
 
217
        cmax = (b > cmax ? b : cmax);
 
218
        cmin = (b < cmin ? b : cmin);
217
219
 
218
 
        v = cmax;               /* value */
 
220
        v = cmax; /* value */
219
221
        if (cmax != 0.0f)
220
 
                s = (cmax - cmin)/cmax;
 
222
                s = (cmax - cmin) / cmax;
221
223
        else {
222
224
                s = 0.0f;
223
225
        }
224
226
        if (s == 0.0f)
225
227
                h = -1.0f;
226
228
        else {
227
 
                cdelta = cmax-cmin;
228
 
                rc = (cmax-r)/cdelta;
229
 
                gc = (cmax-g)/cdelta;
230
 
                bc = (cmax-b)/cdelta;
231
 
                if (r==cmax)
232
 
                        h = bc-gc;
233
 
                else
234
 
                        if (g==cmax)
235
 
                                h = 2.0f+rc-bc;
236
 
                        else
237
 
                                h = 4.0f+gc-rc;
238
 
                h = h*60.0f;
 
229
                cdelta = cmax - cmin;
 
230
                rc = (cmax - r) / cdelta;
 
231
                gc = (cmax - g) / cdelta;
 
232
                bc = (cmax - b) / cdelta;
 
233
 
 
234
                if (r == cmax) {
 
235
                        h = bc - gc;
 
236
                }
 
237
                else if (g == cmax) {
 
238
                        h = 2.0f + rc - bc;
 
239
                }
 
240
                else {
 
241
                        h = 4.0f + gc - rc;
 
242
                }
 
243
 
 
244
                h = h * 60.0f;
239
245
                if (h < 0.0f)
240
246
                        h += 360.0f;
241
247
        }
242
 
        
 
248
 
243
249
        *ls = s;
244
250
        *lh = h / 360.0f;
245
 
        if(*lh < 0.0f) *lh= 0.0f;
 
251
        if (*lh < 0.0f) *lh = 0.0f;
246
252
        *lv = v;
247
253
}
248
254
 
249
255
void rgb_to_hsv_compat(float r, float g, float b, float *lh, float *ls, float *lv)
250
256
{
251
 
        float orig_h= *lh;
252
 
        float orig_s= *ls;
 
257
        float orig_h = *lh;
 
258
        float orig_s = *ls;
253
259
 
254
260
        rgb_to_hsv(r, g, b, lh, ls, lv);
255
261
 
256
 
        if(*lv <= 0.0f) {
257
 
                *lh= orig_h;
258
 
                *ls= orig_s;
 
262
        if (*lv <= 0.0f) {
 
263
                *lh = orig_h;
 
264
                *ls = orig_s;
259
265
        }
260
266
        else if (*ls <= 0.0f) {
261
 
                *lh= orig_h;
 
267
                *lh = orig_h;
262
268
        }
263
269
 
264
 
        if(*lh==0.0f && orig_h >= 1.0f) {
265
 
                *lh= 1.0f;
 
270
        if (*lh == 0.0f && orig_h >= 1.0f) {
 
271
                *lh = 1.0f;
266
272
        }
267
273
}
268
274
 
270
276
 
271
277
void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b, int colorspace)
272
278
{
273
 
        switch (colorspace) { 
274
 
        case BLI_XYZ_SMPTE:
275
 
                *r = (3.50570f   * xc) + (-1.73964f      * yc) + (-0.544011f * zc);
276
 
                *g = (-1.06906f  * xc) + (1.97781f       * yc) + (0.0351720f * zc);
277
 
                *b = (0.0563117f * xc) + (-0.196994f * yc) + (1.05005f   * zc);
278
 
                break;
279
 
        case BLI_XYZ_REC709_SRGB:
280
 
                *r = (3.240476f  * xc) + (-1.537150f * yc) + (-0.498535f * zc);
281
 
                *g = (-0.969256f * xc) + (1.875992f  * yc) + (0.041556f  * zc);
282
 
                *b = (0.055648f  * xc) + (-0.204043f * yc) + (1.057311f  * zc);
283
 
                break;
284
 
        case BLI_XYZ_CIE:
285
 
                *r = (2.28783848734076f * xc) + (-0.833367677835217f    * yc) + (-0.454470795871421f    * zc);
286
 
                *g = (-0.511651380743862f * xc) + (1.42275837632178f * yc) + (0.0888930017552939f * zc);
287
 
                *b = (0.00572040983140966f      * xc) + (-0.0159068485104036f   * yc) + (1.0101864083734f       * zc);
288
 
                break;
 
279
        switch (colorspace) {
 
280
                case BLI_XYZ_SMPTE:
 
281
                        *r = (3.50570f * xc) + (-1.73964f * yc) + (-0.544011f * zc);
 
282
                        *g = (-1.06906f * xc) + (1.97781f * yc) + (0.0351720f * zc);
 
283
                        *b = (0.0563117f * xc) + (-0.196994f * yc) + (1.05005f * zc);
 
284
                        break;
 
285
                case BLI_XYZ_REC709_SRGB:
 
286
                        *r = (3.240476f * xc) + (-1.537150f * yc) + (-0.498535f * zc);
 
287
                        *g = (-0.969256f * xc) + (1.875992f * yc) + (0.041556f * zc);
 
288
                        *b = (0.055648f * xc) + (-0.204043f * yc) + (1.057311f * zc);
 
289
                        break;
 
290
                case BLI_XYZ_CIE:
 
291
                        *r = (2.28783848734076f * xc) + (-0.833367677835217f * yc) + (-0.454470795871421f * zc);
 
292
                        *g = (-0.511651380743862f * xc) + (1.42275837632178f * yc) + (0.0888930017552939f * zc);
 
293
                        *b = (0.00572040983140966f * xc) + (-0.0159068485104036f * yc) + (1.0101864083734f * zc);
 
294
                        break;
289
295
        }
290
296
}
291
297
 
292
298
/* we define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so.
293
 
   for that reason it is sensitive for endianness... with this function it works correctly
294
 
*/
 
299
 * for that reason it is sensitive for endianness... with this function it works correctly
 
300
 */
295
301
 
296
302
unsigned int hsv_to_cpack(float h, float s, float v)
297
303
{
298
304
        short r, g, b;
299
305
        float rf, gf, bf;
300
306
        unsigned int col;
301
 
        
 
307
 
302
308
        hsv_to_rgb(h, s, v, &rf, &gf, &bf);
303
 
        
304
 
        r= (short)(rf*255.0f);
305
 
        g= (short)(gf*255.0f);
306
 
        b= (short)(bf*255.0f);
307
 
        
308
 
        col= ( r + (g*256) + (b*256*256) );
 
309
 
 
310
        r = (short) (rf * 255.0f);
 
311
        g = (short) (gf * 255.0f);
 
312
        b = (short) (bf * 255.0f);
 
313
 
 
314
        col = (r + (g * 256) + (b * 256 * 256));
309
315
        return col;
310
316
}
311
317
 
312
 
 
313
318
unsigned int rgb_to_cpack(float r, float g, float b)
314
319
{
315
320
        int ir, ig, ib;
316
 
        
317
 
        ir= (int)floor(255.0f*r);
318
 
        if(ir<0) ir= 0; else if(ir>255) ir= 255;
319
 
        ig= (int)floor(255.0f*g);
320
 
        if(ig<0) ig= 0; else if(ig>255) ig= 255;
321
 
        ib= (int)floor(255.0f*b);
322
 
        if(ib<0) ib= 0; else if(ib>255) ib= 255;
323
 
        
324
 
        return (ir+ (ig*256) + (ib*256*256));
 
321
 
 
322
        ir = (int)floor(255.0f * r);
 
323
        if (ir < 0) ir = 0;
 
324
        else if (ir > 255) ir = 255;
 
325
        ig = (int)floor(255.0f * g);
 
326
        if (ig < 0) ig = 0;
 
327
        else if (ig > 255) ig = 255;
 
328
        ib = (int)floor(255.0f * b);
 
329
        if (ib < 0) ib = 0;
 
330
        else if (ib > 255) ib = 255;
 
331
 
 
332
        return (ir + (ig * 256) + (ib * 256 * 256));
325
333
}
326
334
 
327
335
void cpack_to_rgb(unsigned int col, float *r, float *g, float *b)
328
336
{
329
 
        
330
 
        *r= (float)((col)&0xFF);
 
337
 
 
338
        *r = (float)((col) & 0xFF);
331
339
        *r /= 255.0f;
332
340
 
333
 
        *g= (float)(((col)>>8)&0xFF);
 
341
        *g = (float)(((col) >> 8) & 0xFF);
334
342
        *g /= 255.0f;
335
343
 
336
 
        *b= (float)(((col)>>16)&0xFF);
 
344
        *b = (float)(((col) >> 16) & 0xFF);
337
345
        *b /= 255.0f;
338
346
}
339
347
 
340
348
void rgb_uchar_to_float(float col_r[3], const unsigned char col_ub[3])
341
349
{
342
 
        col_r[0]= ((float)col_ub[0]) / 255.0f;
343
 
        col_r[1]= ((float)col_ub[1]) / 255.0f;
344
 
        col_r[2]= ((float)col_ub[2]) / 255.0f;
 
350
        col_r[0] = ((float)col_ub[0]) / 255.0f;
 
351
        col_r[1] = ((float)col_ub[1]) / 255.0f;
 
352
        col_r[2] = ((float)col_ub[2]) / 255.0f;
345
353
}
346
354
 
347
355
void rgba_uchar_to_float(float col_r[4], const unsigned char col_ub[4])
348
356
{
349
 
        col_r[0]= ((float)col_ub[0]) / 255.0f;
350
 
        col_r[1]= ((float)col_ub[1]) / 255.0f;
351
 
        col_r[2]= ((float)col_ub[2]) / 255.0f;
352
 
        col_r[3]= ((float)col_ub[3]) / 255.0f;
 
357
        col_r[0] = ((float)col_ub[0]) / 255.0f;
 
358
        col_r[1] = ((float)col_ub[1]) / 255.0f;
 
359
        col_r[2] = ((float)col_ub[2]) / 255.0f;
 
360
        col_r[3] = ((float)col_ub[3]) / 255.0f;
353
361
}
354
362
 
355
363
void rgb_float_to_uchar(unsigned char col_r[3], const float col_f[3])
373
381
float rec709_to_linearrgb(float c)
374
382
{
375
383
        if (c < 0.081f)
376
 
                return (c < 0.0f)? 0.0f: c * (1.0f/4.5f);
 
384
                return (c < 0.0f) ? 0.0f : c * (1.0f / 4.5f);
377
385
        else
378
 
                return powf((c + 0.099f)*(1.0f/1.099f), (1.0f/0.45f));
 
386
                return powf((c + 0.099f) * (1.0f / 1.099f), (1.0f / 0.45f));
379
387
}
380
388
 
381
389
float linearrgb_to_rec709(float c)
382
390
{
383
391
        if (c < 0.018f)
384
 
                return (c < 0.0f)? 0.0f: c * 4.5f;
 
392
                return (c < 0.0f) ? 0.0f : c * 4.5f;
385
393
        else
386
394
                return 1.099f * powf(c, 0.45f) - 0.099f;
387
395
}
389
397
float srgb_to_linearrgb(float c)
390
398
{
391
399
        if (c < 0.04045f)
392
 
                return (c < 0.0f)? 0.0f: c * (1.0f/12.92f);
 
400
                return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
393
401
        else
394
 
                return powf((c + 0.055f)*(1.0f/1.055f), 2.4f);
 
402
                return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
395
403
}
396
404
 
397
405
float linearrgb_to_srgb(float c)
398
406
{
399
407
        if (c < 0.0031308f)
400
 
                return (c < 0.0f)? 0.0f: c * 12.92f;
 
408
                return (c < 0.0f) ? 0.0f : c * 12.92f;
401
409
        else
402
 
                return  1.055f * powf(c, 1.0f/2.4f) - 0.055f;
 
410
                return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
403
411
}
404
412
 
405
413
void minmax_rgb(short c[])
406
414
{
407
 
        if(c[0]>255) c[0]=255;
408
 
        else if(c[0]<0) c[0]=0;
409
 
        if(c[1]>255) c[1]=255;
410
 
        else if(c[1]<0) c[1]=0;
411
 
        if(c[2]>255) c[2]=255;
412
 
        else if(c[2]<0) c[2]=0;
 
415
        if (c[0] > 255) c[0] = 255;
 
416
        else if (c[0] < 0) c[0] = 0;
 
417
        if (c[1] > 255) c[1] = 255;
 
418
        else if (c[1] < 0) c[1] = 0;
 
419
        if (c[2] > 255) c[2] = 255;
 
420
        else if (c[2] < 0) c[2] = 0;
413
421
}
414
422
 
415
423
/*If the requested RGB shade contains a negative weight for
416
 
  one of the primaries, it lies outside the color gamut 
417
 
  accessible from the given triple of primaries.  Desaturate
418
 
  it by adding white, equal quantities of R, G, and B, enough
419
 
  to make RGB all positive.  The function returns 1 if the
420
 
  components were modified, zero otherwise.*/
 
424
 * one of the primaries, it lies outside the color gamut
 
425
 * accessible from the given triple of primaries.  Desaturate
 
426
 * it by adding white, equal quantities of R, G, and B, enough
 
427
 * to make RGB all positive.  The function returns 1 if the
 
428
 * components were modified, zero otherwise.*/
421
429
int constrain_rgb(float *r, float *g, float *b)
422
430
{
423
431
        float w;
432
440
        /* Add just enough white to make r, g, b all positive. */
433
441
 
434
442
        if (w > 0) {
435
 
                *r += w;  *g += w; *b += w;
436
 
                return 1;                     /* Color modified to fit RGB gamut */
 
443
                *r += w;
 
444
                *g += w;
 
445
                *b += w;
 
446
                return 1; /* Color modified to fit RGB gamut */
437
447
        }
438
448
 
439
 
        return 0;                         /* Color within RGB gamut */
 
449
        return 0; /* Color within RGB gamut */
440
450
}
441
451
 
442
452
float rgb_to_grayscale(const float rgb[3])
443
453
{
444
 
        return 0.3f*rgb[0] + 0.58f*rgb[1] + 0.12f*rgb[2];
 
454
        return 0.3f * rgb[0] + 0.58f * rgb[1] + 0.12f * rgb[2];
445
455
}
446
456
 
447
457
unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3])
448
458
{
449
 
        return (76*(unsigned short)rgb[0] + 148*(unsigned short)rgb[1] + 31*(unsigned short)rgb[2]) / 255;
 
459
        return (76 * (unsigned short) rgb[0] + 148 * (unsigned short) rgb[1] + 31 * (unsigned short) rgb[2]) / 255;
450
460
}
451
461
 
452
462
float rgb_to_luma(const float rgb[3])
453
463
{
454
 
        return 0.299f*rgb[0] + 0.587f*rgb[1] + 0.114f*rgb[2];
 
464
        return 0.299f * rgb[0] + 0.587f * rgb[1] + 0.114f * rgb[2];
455
465
}
456
466
 
457
467
unsigned char rgb_to_luma_byte(const unsigned char rgb[3])
458
468
{
459
 
        return (76*(unsigned short)rgb[0] + 150*(unsigned short)rgb[1] + 29*(unsigned short)rgb[2]) / 255;
 
469
        return (76 * (unsigned short) rgb[0] + 150 * (unsigned short) rgb[1] + 29 * (unsigned short) rgb[2]) / 255;
460
470
}
461
471
 
462
472
/* ********************************* lift/gamma/gain / ASC-CDL conversion ********************************* */
464
474
void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power)
465
475
{
466
476
        int c;
467
 
        for(c=0; c<3; c++) {
468
 
                offset[c]= lift[c]*gain[c];
469
 
                slope[c]=  gain[c]*(1.0f-lift[c]);
470
 
                if(gamma[c] == 0)
471
 
                        power[c]= FLT_MAX;
 
477
        for (c = 0; c < 3; c++) {
 
478
                offset[c] = lift[c] * gain[c];
 
479
                slope[c] = gain[c] * (1.0f - lift[c]);
 
480
                if (gamma[c] == 0)
 
481
                        power[c] = FLT_MAX;
472
482
                else
473
 
                        power[c]= 1.0f/gamma[c];
 
483
                        power[c] = 1.0f / gamma[c];
474
484
        }
475
485
}
476
486
 
480
490
void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset)
481
491
{
482
492
        float hsv[3];
483
 
        
484
 
        rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
485
 
        
486
 
        hsv[0]+= hue_offset;
487
 
        if(hsv[0] > 1.0f)               hsv[0] -= 1.0f;
488
 
        else if(hsv[0] < 0.0f)  hsv[0] += 1.0f;
489
 
        
490
 
        hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
 
493
 
 
494
        rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
 
495
 
 
496
        hsv[0] += hue_offset;
 
497
        if (hsv[0] > 1.0f) hsv[0] -= 1.0f;
 
498
        else if (hsv[0] < 0.0f) hsv[0] += 1.0f;
 
499
 
 
500
        hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
491
501
}
492
502
 
493
503
/* Applies an hue offset to a byte rgb color */
494
504
void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset)
495
505
{
496
506
        float rgb_float[3];
497
 
        
 
507
 
498
508
        rgb_uchar_to_float(rgb_float, rgb);
499
509
        rgb_float_set_hue_float_offset(rgb_float, hue_offset);
500
510
        rgb_float_to_uchar(rgb, rgb_float);
527
537
 
528
538
static float index_to_float(const unsigned short i)
529
539
{
 
540
 
530
541
        union {
531
542
                float f;
532
543
                unsigned short us[2];
533
544
        } tmp;
534
545
 
535
546
        /* positive and negative zeros, and all gradual underflow, turn into zero: */
536
 
        if (i<0x80 || (i >= 0x8000 && i < 0x8080)) return 0;
 
547
        if (i < 0x80 || (i >= 0x8000 && i < 0x8080)) return 0;
537
548
        /* All NaN's and infinity turn into the largest possible legal float: */
538
 
        if (i>=0x7f80 && i<0x8000) return FLT_MAX;
539
 
        if (i>=0xff80) return -FLT_MAX;
 
549
        if (i >= 0x7f80 && i < 0x8000) return FLT_MAX;
 
550
        if (i >= 0xff80) return -FLT_MAX;
540
551
 
541
552
#ifdef __BIG_ENDIAN__
542
553
        tmp.us[0] = i;
551
562
 
552
563
void BLI_init_srgb_conversion(void)
553
564
{
554
 
        static int initialized= 0;
 
565
        static int initialized = 0;
555
566
        int i, b;
556
567
 
557
568
        if (initialized) return;
559
570
 
560
571
        /* Fill in the lookup table to convert floats to bytes: */
561
572
        for (i = 0; i < 0x10000; i++) {
562
 
                float f = linearrgb_to_srgb(index_to_float(i))*255.0f;
 
573
                float f = linearrgb_to_srgb(index_to_float(i)) * 255.0f;
563
574
                if (f <= 0) BLI_color_to_srgb_table[i] = 0;
564
 
                else if (f < 255) BLI_color_to_srgb_table[i] = (unsigned short)(f*0x100+0.5f);
 
575
                else if (f < 255) BLI_color_to_srgb_table[i] = (unsigned short) (f * 0x100 + 0.5f);
565
576
                else BLI_color_to_srgb_table[i] = 0xff00;
566
577
        }
567
578
 
568
579
        /* Fill in the lookup table to convert bytes to float: */
569
580
        for (b = 0; b <= 255; b++) {
570
 
                float f = srgb_to_linearrgb(((float)b)*(1.0f/255.0f));
 
581
                float f = srgb_to_linearrgb(((float)b) * (1.0f / 255.0f));
571
582
                BLI_color_from_srgb_table[b] = f;
572
583
                i = hipart(f);
573
584
                /* replace entries so byte->float->byte does not change the data: */
574
 
                BLI_color_to_srgb_table[i] = b*0x100;
 
585
                BLI_color_to_srgb_table[i] = b * 0x100;
575
586
        }
576
587
}
577