~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/blenkernel/intern/colortools.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 * $Id: colortools.c 30325 2010-07-14 14:11:03Z jwilkins $
3
 
 *
 
1
/*
4
2
 * ***** BEGIN GPL LICENSE BLOCK *****
5
3
 *
6
4
 * This program is free software; you can redistribute it and/or
27
25
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
28
26
 */
29
27
 
 
28
/** \file blender/blenkernel/intern/colortools.c
 
29
 *  \ingroup bke
 
30
 */
 
31
 
 
32
 
30
33
#include <string.h>
31
34
#include <math.h>
32
35
#include <stdlib.h>
33
36
#include <float.h>
34
37
 
35
 
#ifdef WITH_LCMS
36
 
#include <lcms.h>
37
 
#endif
38
 
 
39
38
#include "MEM_guardedalloc.h"
40
39
 
41
40
#include "DNA_color_types.h"
42
41
#include "DNA_curve_types.h"
43
42
 
 
43
#include "BLI_blenlib.h"
 
44
#include "BLI_math.h"
 
45
#include "BLI_utildefines.h"
 
46
 
44
47
#include "BKE_colortools.h"
45
48
#include "BKE_curve.h"
46
 
#include "BKE_ipo.h"
47
 
#include "BKE_utildefines.h"
 
49
#include "BKE_fcurve.h"
48
50
 
49
 
#include "BLI_blenlib.h"
50
 
#include "BLI_math.h"
51
51
 
52
52
#include "IMB_imbuf.h"
53
53
#include "IMB_imbuf_types.h"
54
54
 
55
 
 
56
 
void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w)
57
 
{
58
 
        int x, y;
59
 
        float *rf= rectf;
60
 
        float srgb[3];
61
 
        unsigned char *rc= rectc;
62
 
        
63
 
        for(y=y1; y<y2; y++) {
64
 
                for(x=x1; x<x2; x++, rf+=4, rc+=4) {
65
 
                        srgb[0]= linearrgb_to_srgb(rf[0]);
66
 
                        srgb[1]= linearrgb_to_srgb(rf[1]);
67
 
                        srgb[2]= linearrgb_to_srgb(rf[2]);
68
 
 
69
 
                        rc[0]= FTOCHAR(srgb[0]);
70
 
                        rc[1]= FTOCHAR(srgb[1]);
71
 
                        rc[2]= FTOCHAR(srgb[2]);
72
 
                        rc[3]= FTOCHAR(rf[3]);
73
 
                }
74
 
        }
75
 
}
76
 
 
77
 
void floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w)
78
 
{
79
 
        int x, y;
80
 
        float *rf= rectf;
81
 
        unsigned char *rc= rectc;
82
 
        
83
 
        for(y=y1; y<y2; y++) {
84
 
                for(x=x1; x<x2; x++, rf+=4, rc+=4) {
85
 
                        rc[0]= FTOCHAR(rf[0]);
86
 
                        rc[1]= FTOCHAR(rf[1]);
87
 
                        rc[2]= FTOCHAR(rf[2]);
88
 
                        rc[3]= FTOCHAR(rf[3]);
89
 
                }
90
 
        }
91
 
}
92
 
 
93
 
 
94
55
/* ********************************* color curve ********************* */
95
56
 
96
57
/* ***************** operations on full struct ************* */
103
64
        
104
65
        cumap= MEM_callocN(sizeof(CurveMapping), "new curvemap");
105
66
        cumap->flag= CUMA_DO_CLIP;
106
 
        if(tot==4) cumap->cur= 3;               /* rhms, hack for 'col' curve? */
 
67
        if (tot==4) cumap->cur= 3;              /* rhms, hack for 'col' curve? */
107
68
        
108
69
        clipminx = MIN2(minx, maxx);
109
70
        clipminy = MIN2(miny, maxy);
116
77
        cumap->white[0]= cumap->white[1]= cumap->white[2]= 1.0f;
117
78
        cumap->bwmul[0]= cumap->bwmul[1]= cumap->bwmul[2]= 1.0f;
118
79
        
119
 
        for(a=0; a<tot; a++) {
 
80
        for (a=0; a<tot; a++) {
120
81
                cumap->cm[a].flag= CUMA_EXTEND_EXTRAPOLATE;
121
82
                cumap->cm[a].totpoint= 2;
122
83
                cumap->cm[a].curve= MEM_callocN(2*sizeof(CurveMapPoint), "curve points");
136
97
{
137
98
        int a;
138
99
        
139
 
        if(cumap) {
140
 
                for(a=0; a<CM_TOT; a++) {
141
 
                        if(cumap->cm[a].curve) MEM_freeN(cumap->cm[a].curve);
142
 
                        if(cumap->cm[a].table) MEM_freeN(cumap->cm[a].table);
143
 
                        if(cumap->cm[a].premultable) MEM_freeN(cumap->cm[a].premultable);
 
100
        if (cumap) {
 
101
                for (a=0; a<CM_TOT; a++) {
 
102
                        if (cumap->cm[a].curve) MEM_freeN(cumap->cm[a].curve);
 
103
                        if (cumap->cm[a].table) MEM_freeN(cumap->cm[a].table);
 
104
                        if (cumap->cm[a].premultable) MEM_freeN(cumap->cm[a].premultable);
144
105
                }
145
106
                MEM_freeN(cumap);
146
107
        }
150
111
{
151
112
        int a;
152
113
        
153
 
        if(cumap) {
 
114
        if (cumap) {
154
115
                CurveMapping *cumapn= MEM_dupallocN(cumap);
155
 
                for(a=0; a<CM_TOT; a++) {
156
 
                        if(cumap->cm[a].curve) 
 
116
                for (a=0; a<CM_TOT; a++) {
 
117
                        if (cumap->cm[a].curve) 
157
118
                                cumapn->cm[a].curve= MEM_dupallocN(cumap->cm[a].curve);
158
 
                        if(cumap->cm[a].table) 
 
119
                        if (cumap->cm[a].table) 
159
120
                                cumapn->cm[a].table= MEM_dupallocN(cumap->cm[a].table);
160
 
                        if(cumap->cm[a].premultable) 
 
121
                        if (cumap->cm[a].premultable) 
161
122
                                cumapn->cm[a].premultable= MEM_dupallocN(cumap->cm[a].premultable);
162
123
                }
163
124
                return cumapn;
165
126
        return NULL;
166
127
}
167
128
 
168
 
void curvemapping_set_black_white(CurveMapping *cumap, float *black, float *white)
 
129
void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], const float white[3])
169
130
{
170
131
        int a;
171
132
        
172
 
        if(white)
173
 
                VECCOPY(cumap->white, white);
174
 
        if(black)
175
 
                VECCOPY(cumap->black, black);
 
133
        if (white)
 
134
                copy_v3_v3(cumap->white, white);
 
135
        if (black)
 
136
                copy_v3_v3(cumap->black, black);
176
137
        
177
 
        for(a=0; a<3; a++) {
178
 
                if(cumap->white[a]==cumap->black[a])
 
138
        for (a=0; a<3; a++) {
 
139
                if (cumap->white[a]==cumap->black[a])
179
140
                        cumap->bwmul[a]= 0.0f;
180
141
                else
181
142
                        cumap->bwmul[a]= 1.0f/(cumap->white[a] - cumap->black[a]);
193
154
        
194
155
        /* well, lets keep the two outer points! */
195
156
        cmp[0]= cuma->curve[0];
196
 
        for(a=1, b=1; a<cuma->totpoint-1; a++) {
197
 
                if(!(cuma->curve[a].flag & flag)) {
 
157
        for (a=1, b=1; a<cuma->totpoint-1; a++) {
 
158
                if (!(cuma->curve[a].flag & flag)) {
198
159
                        cmp[b]= cuma->curve[a];
199
160
                        b++;
200
161
                }
214
175
                
215
176
        /* insert fragments of the old one and the new point to the new curve */
216
177
        cuma->totpoint++;
217
 
        for(a=0, b=0; a<cuma->totpoint; a++) {
218
 
                if((x < cuma->curve[a].x) && !foundloc) {
 
178
        for (a=0, b=0; a<cuma->totpoint; a++) {
 
179
                if ((x < cuma->curve[a].x) && !foundloc) {
219
180
                        cmp[a].x= x;
220
181
                        cmp[a].y= y;
221
182
                        cmp[a].flag= CUMA_SELECT;
236
197
        cuma->curve= cmp;
237
198
}
238
199
 
239
 
void curvemap_reset(CurveMap *cuma, rctf *clipr, int preset)
 
200
void curvemap_reset(CurveMap *cuma, rctf *clipr, int preset, int slope)
240
201
{
241
 
        if(cuma->curve)
 
202
        if (cuma->curve)
242
203
                MEM_freeN(cuma->curve);
243
204
 
244
205
        switch(preset) {
320
281
                        break;
321
282
        }
322
283
 
323
 
        if(cuma->table) {
 
284
        /* mirror curve in x direction to have positive slope
 
285
         * rather than default negative slope */
 
286
        if (slope == CURVEMAP_SLOPE_POSITIVE) {
 
287
                int i, last=cuma->totpoint-1;
 
288
                CurveMapPoint *newpoints= MEM_dupallocN(cuma->curve);
 
289
                
 
290
                for (i=0; i<cuma->totpoint; i++) {
 
291
                        newpoints[i].y = cuma->curve[last-i].y;
 
292
                }
 
293
                
 
294
                MEM_freeN(cuma->curve);
 
295
                cuma->curve = newpoints;
 
296
        }
 
297
        
 
298
        if (cuma->table) {
324
299
                MEM_freeN(cuma->table);
325
300
                cuma->table= NULL;
326
301
        }
331
306
{
332
307
        int a;
333
308
        
334
 
        for(a=0; a<cuma->totpoint; a++) {
335
 
                if(cuma->curve[a].flag & CUMA_SELECT) {
336
 
                        if(type) cuma->curve[a].flag |= CUMA_VECTOR;
 
309
        for (a=0; a<cuma->totpoint; a++) {
 
310
                if (cuma->curve[a].flag & CUMA_SELECT) {
 
311
                        if (type) cuma->curve[a].flag |= CUMA_VECTOR;
337
312
                        else cuma->curve[a].flag &= ~CUMA_VECTOR;
338
313
                }
339
314
        }
342
317
/* *********************** Making the tables and display ************** */
343
318
 
344
319
/* reduced copy of garbled calchandleNurb() code in curve.c */
345
 
static void calchandle_curvemap(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
 
320
static void calchandle_curvemap(BezTriple *bezt, BezTriple *prev, BezTriple *next, int UNUSED(mode))
346
321
{
347
322
        float *p1,*p2,*p3,pt[3];
348
 
        float dx1,dy1, dx,dy, vx,vy, len,len1,len2;
349
 
        
350
 
        if(bezt->h1==0 && bezt->h2==0) return;
 
323
        float len,len_a, len_b;
 
324
        float dvec_a[2], dvec_b[2];
 
325
 
 
326
        if (bezt->h1==0 && bezt->h2==0) {
 
327
                return;
 
328
        }
351
329
        
352
330
        p2= bezt->vec[1];
353
331
        
354
 
        if(prev==NULL) {
 
332
        if (prev==NULL) {
355
333
                p3= next->vec[1];
356
 
                pt[0]= 2*p2[0]- p3[0];
357
 
                pt[1]= 2*p2[1]- p3[1];
 
334
                pt[0]= 2.0f*p2[0] - p3[0];
 
335
                pt[1]= 2.0f*p2[1] - p3[1];
358
336
                p1= pt;
359
337
        }
360
 
        else p1= prev->vec[1];
 
338
        else {
 
339
                p1= prev->vec[1];
 
340
        }
361
341
        
362
 
        if(next==NULL) {
 
342
        if (next==NULL) {
363
343
                p1= prev->vec[1];
364
 
                pt[0]= 2*p2[0]- p1[0];
365
 
                pt[1]= 2*p2[1]- p1[1];
 
344
                pt[0]= 2.0f*p2[0] - p1[0];
 
345
                pt[1]= 2.0f*p2[1] - p1[1];
366
346
                p3= pt;
367
347
        }
368
 
        else p3= next->vec[1];
369
 
        
370
 
        dx= p2[0]- p1[0];
371
 
        dy= p2[1]- p1[1];
372
 
 
373
 
        len1= (float)sqrt(dx*dx+dy*dy);
374
 
        
375
 
        dx1= p3[0]- p2[0];
376
 
        dy1= p3[1]- p2[1];
377
 
 
378
 
        len2= (float)sqrt(dx1*dx1+dy1*dy1);
379
 
        
380
 
        if(len1==0.0f) len1=1.0f;
381
 
        if(len2==0.0f) len2=1.0f;
382
 
        
383
 
        if(bezt->h1==HD_AUTO || bezt->h2==HD_AUTO) {    /* auto */
384
 
                vx= dx1/len2 + dx/len1;
385
 
                vy= dy1/len2 + dy/len1;
386
 
                
387
 
                len= 2.5614f*(float)sqrt(vx*vx + vy*vy);
388
 
                if(len!=0.0f) {
 
348
        else {
 
349
                p3= next->vec[1];
 
350
        }
 
351
 
 
352
        sub_v2_v2v2(dvec_a, p2, p1);
 
353
        sub_v2_v2v2(dvec_b, p3, p2);
 
354
 
 
355
        len_a= len_v2(dvec_a);
 
356
        len_b= len_v2(dvec_b);
 
357
 
 
358
        if (len_a==0.0f) len_a=1.0f;
 
359
        if (len_b==0.0f) len_b=1.0f;
 
360
 
 
361
        if (bezt->h1==HD_AUTO || bezt->h2==HD_AUTO) { /* auto */
 
362
                float tvec[2];
 
363
                tvec[0]= dvec_b[0]/len_b + dvec_a[0]/len_a;
 
364
                tvec[1]= dvec_b[1]/len_b + dvec_a[1]/len_a;
 
365
 
 
366
                len= len_v2(tvec) * 2.5614f;
 
367
                if (len!=0.0f) {
389
368
                        
390
 
                        if(bezt->h1==HD_AUTO) {
391
 
                                len1/=len;
392
 
                                *(p2-3)= *p2-vx*len1;
393
 
                                *(p2-2)= *(p2+1)-vy*len1;
 
369
                        if (bezt->h1==HD_AUTO) {
 
370
                                len_a/=len;
 
371
                                madd_v2_v2v2fl(p2-3, p2, tvec, -len_a);
394
372
                        }
395
 
                        if(bezt->h2==HD_AUTO) {
396
 
                                len2/=len;
397
 
                                *(p2+3)= *p2+vx*len2;
398
 
                                *(p2+4)= *(p2+1)+vy*len2;
 
373
                        if (bezt->h2==HD_AUTO) {
 
374
                                len_b/=len;
 
375
                                madd_v2_v2v2fl(p2+3, p2, tvec,  len_b);
399
376
                        }
400
377
                }
401
378
        }
402
379
 
403
 
        if(bezt->h1==HD_VECT) { /* vector */
404
 
                dx/=3.0; 
405
 
                dy/=3.0; 
406
 
                *(p2-3)= *p2-dx;
407
 
                *(p2-2)= *(p2+1)-dy;
 
380
        if (bezt->h1==HD_VECT) {        /* vector */
 
381
                madd_v2_v2v2fl(p2-3, p2, dvec_a, -1.0f/3.0f);
408
382
        }
409
 
        if(bezt->h2==HD_VECT) {
410
 
                dx1/=3.0; 
411
 
                dy1/=3.0; 
412
 
                *(p2+3)= *p2+dx1;
413
 
                *(p2+4)= *(p2+1)+dy1;
 
383
        if (bezt->h2==HD_VECT) {
 
384
                madd_v2_v2v2fl(p2+3, p2, dvec_b,  1.0f/3.0f);
414
385
        }
415
386
}
416
387
 
417
388
/* in X, out Y. 
418
 
   X is presumed to be outside first or last */
419
 
static float curvemap_calc_extend(CurveMap *cuma, float x, float *first, float *last)
 
389
 * X is presumed to be outside first or last */
 
390
static float curvemap_calc_extend(CurveMap *cuma, float x, const float first[2], const float last[2])
420
391
{
421
 
        if(x <= first[0]) {
422
 
                if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0) {
 
392
        if (x <= first[0]) {
 
393
                if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0) {
423
394
                        /* no extrapolate */
424
395
                        return first[1];
425
396
                }
426
397
                else {
427
 
                        if(cuma->ext_in[0]==0.0f)
 
398
                        if (cuma->ext_in[0]==0.0f)
428
399
                                return first[1] + cuma->ext_in[1]*10000.0f;
429
400
                        else
430
401
                                return first[1] + cuma->ext_in[1]*(x - first[0])/cuma->ext_in[0];
431
402
                }
432
403
        }
433
 
        else if(x >= last[0]) {
434
 
                if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0) {
 
404
        else if (x >= last[0]) {
 
405
                if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0) {
435
406
                        /* no extrapolate */
436
407
                        return last[1];
437
408
                }
438
409
                else {
439
 
                        if(cuma->ext_out[0]==0.0f)
 
410
                        if (cuma->ext_out[0]==0.0f)
440
411
                                return last[1] - cuma->ext_out[1]*10000.0f;
441
412
                        else
442
413
                                return last[1] + cuma->ext_out[1]*(x - last[0])/cuma->ext_out[0];
453
424
        float *fp, *allpoints, *lastpoint, curf, range;
454
425
        int a, totpoint;
455
426
        
456
 
        if(cuma->curve==NULL) return;
 
427
        if (cuma->curve==NULL) return;
457
428
        
458
429
        /* default rect also is table range */
459
430
        cuma->mintable= clipr->xmin;
462
433
        /* hrmf... we now rely on blender ipo beziers, these are more advanced */
463
434
        bezt= MEM_callocN(cuma->totpoint*sizeof(BezTriple), "beztarr");
464
435
        
465
 
        for(a=0; a<cuma->totpoint; a++) {
 
436
        for (a=0; a<cuma->totpoint; a++) {
466
437
                cuma->mintable= MIN2(cuma->mintable, cmp[a].x);
467
438
                cuma->maxtable= MAX2(cuma->maxtable, cmp[a].x);
468
439
                bezt[a].vec[1][0]= cmp[a].x;
469
440
                bezt[a].vec[1][1]= cmp[a].y;
470
 
                if(cmp[a].flag & CUMA_VECTOR)
 
441
                if (cmp[a].flag & CUMA_VECTOR)
471
442
                        bezt[a].h1= bezt[a].h2= HD_VECT;
472
443
                else
473
444
                        bezt[a].h1= bezt[a].h2= HD_AUTO;
474
445
        }
475
446
        
476
 
        for(a=0; a<cuma->totpoint; a++) {
477
 
                if(a==0)
 
447
        for (a=0; a<cuma->totpoint; a++) {
 
448
                if (a==0)
478
449
                        calchandle_curvemap(bezt, NULL, bezt+1, 0);
479
 
                else if(a==cuma->totpoint-1)
 
450
                else if (a==cuma->totpoint-1)
480
451
                        calchandle_curvemap(bezt+a, bezt+a-1, NULL, 0);
481
452
                else
482
453
                        calchandle_curvemap(bezt+a, bezt+a-1, bezt+a+1, 0);
483
454
        }
484
455
        
485
456
        /* first and last handle need correction, instead of pointing to center of next/prev, 
486
 
                we let it point to the closest handle */
487
 
        if(cuma->totpoint>2) {
 
457
         * we let it point to the closest handle */
 
458
        if (cuma->totpoint>2) {
488
459
                float hlen, nlen, vec[3];
489
460
                
490
 
                if(bezt[0].h2==HD_AUTO) {
 
461
                if (bezt[0].h2==HD_AUTO) {
491
462
                        
492
463
                        hlen= len_v3v3(bezt[0].vec[1], bezt[0].vec[2]); /* original handle length */
493
464
                        /* clip handle point */
494
 
                        VECCOPY(vec, bezt[1].vec[0]);
495
 
                        if(vec[0] < bezt[0].vec[1][0])
 
465
                        copy_v3_v3(vec, bezt[1].vec[0]);
 
466
                        if (vec[0] < bezt[0].vec[1][0])
496
467
                                vec[0]= bezt[0].vec[1][0];
497
468
                        
498
469
                        sub_v3_v3(vec, bezt[0].vec[1]);
499
470
                        nlen= len_v3(vec);
500
 
                        if(nlen>FLT_EPSILON) {
 
471
                        if (nlen>FLT_EPSILON) {
501
472
                                mul_v3_fl(vec, hlen/nlen);
502
473
                                add_v3_v3v3(bezt[0].vec[2], vec, bezt[0].vec[1]);
503
474
                                sub_v3_v3v3(bezt[0].vec[0], bezt[0].vec[1], vec);
504
475
                        }
505
476
                }
506
477
                a= cuma->totpoint-1;
507
 
                if(bezt[a].h2==HD_AUTO) {
 
478
                if (bezt[a].h2==HD_AUTO) {
508
479
                        
509
480
                        hlen= len_v3v3(bezt[a].vec[1], bezt[a].vec[0]); /* original handle length */
510
481
                        /* clip handle point */
511
 
                        VECCOPY(vec, bezt[a-1].vec[2]);
512
 
                        if(vec[0] > bezt[a].vec[1][0])
 
482
                        copy_v3_v3(vec, bezt[a-1].vec[2]);
 
483
                        if (vec[0] > bezt[a].vec[1][0])
513
484
                                vec[0]= bezt[a].vec[1][0];
514
485
                        
515
486
                        sub_v3_v3(vec, bezt[a].vec[1]);
516
487
                        nlen= len_v3(vec);
517
 
                        if(nlen>FLT_EPSILON) {
 
488
                        if (nlen>FLT_EPSILON) {
518
489
                                mul_v3_fl(vec, hlen/nlen);
519
490
                                add_v3_v3v3(bezt[a].vec[0], vec, bezt[a].vec[1]);
520
491
                                sub_v3_v3v3(bezt[a].vec[2], bezt[a].vec[1], vec);
522
493
                }
523
494
        }       
524
495
        /* make the bezier curve */
525
 
        if(cuma->table)
 
496
        if (cuma->table)
526
497
                MEM_freeN(cuma->table);
527
498
        totpoint= (cuma->totpoint-1)*CM_RESOL;
528
499
        fp= allpoints= MEM_callocN(totpoint*2*sizeof(float), "table");
529
500
        
530
 
        for(a=0; a<cuma->totpoint-1; a++, fp += 2*CM_RESOL) {
 
501
        for (a=0; a<cuma->totpoint-1; a++, fp += 2*CM_RESOL) {
531
502
                correct_bezpart(bezt[a].vec[1], bezt[a].vec[2], bezt[a+1].vec[0], bezt[a+1].vec[1]);
532
503
                forward_diff_bezier(bezt[a].vec[1][0], bezt[a].vec[2][0], bezt[a+1].vec[0][0], bezt[a+1].vec[1][0], fp, CM_RESOL-1, 2*sizeof(float));   
533
504
                forward_diff_bezier(bezt[a].vec[1][1], bezt[a].vec[2][1], bezt[a+1].vec[0][1], bezt[a+1].vec[1][1], fp+1, CM_RESOL-1, 2*sizeof(float));
558
529
        lastpoint= allpoints + 2*(totpoint-1);
559
530
        cmp= MEM_callocN((CM_TABLE+1)*sizeof(CurveMapPoint), "dist table");
560
531
        
561
 
        for(a=0; a<=CM_TABLE; a++) {
 
532
        for (a=0; a<=CM_TABLE; a++) {
562
533
                curf= cuma->mintable + range*(float)a;
563
534
                cmp[a].x= curf;
564
535
                
565
536
                /* get the first x coordinate larger than curf */
566
 
                while(curf >= fp[0] && fp!=lastpoint) {
 
537
                while (curf >= fp[0] && fp!=lastpoint) {
567
538
                        fp+=2;
568
539
                }
569
 
                if(fp==allpoints || (curf >= fp[0] && fp==lastpoint))
 
540
                if (fp==allpoints || (curf >= fp[0] && fp==lastpoint))
570
541
                        cmp[a].y= curvemap_calc_extend(cuma, curf, allpoints, lastpoint);
571
542
                else {
572
543
                        float fac1= fp[0] - fp[-2];
573
544
                        float fac2= fp[0] - curf;
574
 
                        if(fac1 > FLT_EPSILON)
 
545
                        if (fac1 > FLT_EPSILON)
575
546
                                fac1= fac2/fac1;
576
547
                        else
577
548
                                fac1= 0.0f;
589
560
{
590
561
        int a;
591
562
        
592
 
        if(restore) {
593
 
                if(cumap->flag & CUMA_PREMULLED) {
594
 
                        for(a=0; a<3; a++) {
 
563
        if (restore) {
 
564
                if (cumap->flag & CUMA_PREMULLED) {
 
565
                        for (a=0; a<3; a++) {
595
566
                                MEM_freeN(cumap->cm[a].table);
596
567
                                cumap->cm[a].table= cumap->cm[a].premultable;
597
568
                                cumap->cm[a].premultable= NULL;
601
572
                }
602
573
        }
603
574
        else {
604
 
                if((cumap->flag & CUMA_PREMULLED)==0) {
 
575
                if ((cumap->flag & CUMA_PREMULLED)==0) {
605
576
                        /* verify and copy */
606
 
                        for(a=0; a<3; a++) {
607
 
                                if(cumap->cm[a].table==NULL)
 
577
                        for (a=0; a<3; a++) {
 
578
                                if (cumap->cm[a].table==NULL)
608
579
                                        curvemap_make_table(cumap->cm+a, &cumap->clipr);
609
580
                                cumap->cm[a].premultable= cumap->cm[a].table;
610
581
                                cumap->cm[a].table= MEM_mallocN((CM_TABLE+1)*sizeof(CurveMapPoint), "premul table");
611
582
                                memcpy(cumap->cm[a].table, cumap->cm[a].premultable, (CM_TABLE+1)*sizeof(CurveMapPoint));
612
583
                        }
613
584
                        
614
 
                        if(cumap->cm[3].table==NULL)
 
585
                        if (cumap->cm[3].table==NULL)
615
586
                                curvemap_make_table(cumap->cm+3, &cumap->clipr);
616
587
                
617
588
                        /* premul */
618
 
                        for(a=0; a<3; a++) {
 
589
                        for (a=0; a<3; a++) {
619
590
                                int b;
620
 
                                for(b=0; b<=CM_TABLE; b++) {
 
591
                                for (b=0; b<=CM_TABLE; b++) {
621
592
                                        cumap->cm[a].table[b].y= curvemap_evaluateF(cumap->cm+3, cumap->cm[a].table[b].y);
622
593
                                }
623
594
                        }
631
602
{
632
603
        const struct CurveMapPoint *x1=a1, *x2=a2;
633
604
        
634
 
        if( x1->x > x2->x ) return 1;
635
 
        else if( x1->x < x2->x) return -1;
 
605
        if ( x1->x > x2->x ) return 1;
 
606
        else if ( x1->x < x2->x) return -1;
636
607
        return 0;
637
608
}
638
609
 
651
622
        cumap->changed_timestamp++;
652
623
 
653
624
        /* clamp with clip */
654
 
        if(cumap->flag & CUMA_DO_CLIP) {
655
 
                for(a=0; a<cuma->totpoint; a++) {
656
 
                        if(cmp[a].flag & CUMA_SELECT) {
657
 
                                if(cmp[a].x < clipr->xmin)
 
625
        if (cumap->flag & CUMA_DO_CLIP) {
 
626
                for (a=0; a<cuma->totpoint; a++) {
 
627
                        if (cmp[a].flag & CUMA_SELECT) {
 
628
                                if (cmp[a].x < clipr->xmin)
658
629
                                        dx= MIN2(dx, cmp[a].x - clipr->xmin);
659
 
                                else if(cmp[a].x > clipr->xmax)
 
630
                                else if (cmp[a].x > clipr->xmax)
660
631
                                        dx= MAX2(dx, cmp[a].x - clipr->xmax);
661
 
                                if(cmp[a].y < clipr->ymin)
 
632
                                if (cmp[a].y < clipr->ymin)
662
633
                                        dy= MIN2(dy, cmp[a].y - clipr->ymin);
663
 
                                else if(cmp[a].y > clipr->ymax)
 
634
                                else if (cmp[a].y > clipr->ymax)
664
635
                                        dy= MAX2(dy, cmp[a].y - clipr->ymax);
665
636
                        }
666
637
                }
667
 
                for(a=0; a<cuma->totpoint; a++) {
668
 
                        if(cmp[a].flag & CUMA_SELECT) {
 
638
                for (a=0; a<cuma->totpoint; a++) {
 
639
                        if (cmp[a].flag & CUMA_SELECT) {
669
640
                                cmp[a].x -= dx;
670
641
                                cmp[a].y -= dy;
671
642
                        }
676
647
        qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints);
677
648
        
678
649
        /* remove doubles, threshold set on 1% of default range */
679
 
        if(rem_doubles && cuma->totpoint>2) {
680
 
                for(a=0; a<cuma->totpoint-1; a++) {
 
650
        if (rem_doubles && cuma->totpoint>2) {
 
651
                for (a=0; a<cuma->totpoint-1; a++) {
681
652
                        dx= cmp[a].x - cmp[a+1].x;
682
653
                        dy= cmp[a].y - cmp[a+1].y;
683
 
                        if( sqrt(dx*dx + dy*dy) < thresh ) {
684
 
                                if(a==0) {
 
654
                        if ( sqrtf(dx*dx + dy*dy) < thresh ) {
 
655
                                if (a==0) {
685
656
                                        cmp[a+1].flag|= 2;
686
 
                                        if(cmp[a+1].flag & CUMA_SELECT)
 
657
                                        if (cmp[a+1].flag & CUMA_SELECT)
687
658
                                                cmp[a].flag |= CUMA_SELECT;
688
659
                                }
689
660
                                else {
690
661
                                        cmp[a].flag|= 2;
691
 
                                        if(cmp[a].flag & CUMA_SELECT)
 
662
                                        if (cmp[a].flag & CUMA_SELECT)
692
663
                                                cmp[a+1].flag |= CUMA_SELECT;
693
664
                                }
694
665
                                break;  /* we assume 1 deletion per edit is ok */
695
666
                        }
696
667
                }
697
 
                if(a != cuma->totpoint-1)
 
668
                if (a != cuma->totpoint-1)
698
669
                        curvemap_remove(cuma, 2);
699
670
        }       
700
671
        curvemap_make_table(cuma, clipr);
711
682
        i= (int)fi;
712
683
        
713
684
        /* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */
714
 
        if(fi<0.0f || fi>CM_TABLE)
 
685
        if (fi<0.0f || fi>CM_TABLE)
715
686
                return curvemap_calc_extend(cuma, value, &cuma->table[0].x, &cuma->table[CM_TABLE].x);
716
687
        else {
717
 
                if(i<0) return cuma->table[0].y;
718
 
                if(i>=CM_TABLE) return cuma->table[CM_TABLE].y;
 
688
                if (i<0) return cuma->table[0].y;
 
689
                if (i>=CM_TABLE) return cuma->table[CM_TABLE].y;
719
690
                
720
691
                fi= fi-(float)i;
721
692
                return (1.0f-fi)*cuma->table[i].y + (fi)*cuma->table[i+1].y; 
728
699
        CurveMap *cuma= cumap->cm+cur;
729
700
        
730
701
        /* allocate or bail out */
731
 
        if(cuma->table==NULL) {
 
702
        if (cuma->table==NULL) {
732
703
                curvemap_make_table(cuma, &cumap->clipr);
733
 
                if(cuma->table==NULL)
 
704
                if (cuma->table==NULL)
734
705
                        return 1.0f-value;
735
706
        }
736
707
        return curvemap_evaluateF(cuma, value);
737
708
}
738
709
 
739
710
/* vector case */
740
 
void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *vecin)
 
711
void curvemapping_evaluate3F(CurveMapping *cumap, float vecout[3], const float vecin[3])
741
712
{
742
713
        vecout[0]= curvemapping_evaluateF(cumap, 0, vecin[0]);
743
714
        vecout[1]= curvemapping_evaluateF(cumap, 1, vecin[1]);
745
716
}
746
717
 
747
718
/* RGB case, no black/white points, no premult */
748
 
void curvemapping_evaluateRGBF(CurveMapping *cumap, float *vecout, const float *vecin)
 
719
void curvemapping_evaluateRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3])
749
720
{
750
721
        vecout[0]= curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, vecin[0]));
751
722
        vecout[1]= curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, vecin[1]));
754
725
 
755
726
 
756
727
/* RGB with black/white points and premult. tables are checked */
757
 
void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const float *vecin)
 
728
void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3])
758
729
{
759
730
        float fac;
760
731
        
768
739
        vecout[2]= curvemap_evaluateF(cumap->cm+2, fac);
769
740
}
770
741
 
771
 
void colorcorrection_do_ibuf(ImBuf *ibuf, const char *profile)
772
 
{
773
 
        if (ibuf->crect == NULL)
774
 
        {
775
 
#ifdef WITH_LCMS
776
 
                cmsHPROFILE imageProfile, proofingProfile;
777
 
                cmsHTRANSFORM hTransform;
778
 
                
779
 
                ibuf->crect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(int), "imbuf crect");
780
 
 
781
 
                imageProfile  = cmsCreate_sRGBProfile();
782
 
                proofingProfile = cmsOpenProfileFromFile(profile, "r");
783
 
                
784
 
                cmsErrorAction(LCMS_ERROR_SHOW);
785
 
        
786
 
                hTransform = cmsCreateProofingTransform(imageProfile, TYPE_RGBA_8, imageProfile, TYPE_RGBA_8, 
787
 
                                                                                          proofingProfile,
788
 
                                                                                          INTENT_ABSOLUTE_COLORIMETRIC,
789
 
                                                                                          INTENT_ABSOLUTE_COLORIMETRIC,
790
 
                                                                                          cmsFLAGS_SOFTPROOFING);
791
 
        
792
 
                cmsDoTransform(hTransform, ibuf->rect, ibuf->crect, ibuf->x * ibuf->y);
793
 
        
794
 
                cmsDeleteTransform(hTransform);
795
 
                cmsCloseProfile(imageProfile);
796
 
                cmsCloseProfile(proofingProfile);
797
 
#else
798
 
                ibuf->crect = ibuf->rect;
799
 
#endif
800
 
        }
801
 
}
802
742
 
803
743
/* only used for image editor curves */
804
744
void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)
810
750
        int stride= 4;
811
751
        float *pix_out;
812
752
        
813
 
        if(ibuf==NULL)
 
753
        if (ibuf==NULL)
814
754
                return;
815
 
        if(ibuf->rect_float==NULL)
 
755
        if (ibuf->rect_float==NULL)
816
756
                IMB_float_from_rect(ibuf);
817
 
        else if(ibuf->rect==NULL)
 
757
        else if (ibuf->rect==NULL)
818
758
                imb_addrectImBuf(ibuf);
819
759
        
820
760
        if (!ibuf->rect || !ibuf->rect_float)
829
769
        pix_in= ibuf->rect_float;
830
770
        pix_out= tmpbuf->rect_float;
831
771
 
832
 
        if(ibuf->channels)
 
772
        if (ibuf->channels)
833
773
                stride= ibuf->channels;
834
774
        
835
 
        for(pixel= ibuf->x*ibuf->y; pixel>0; pixel--, pix_in+=stride, pix_out+=4) {
836
 
                if(stride<3) {
 
775
        for (pixel= ibuf->x*ibuf->y; pixel>0; pixel--, pix_in+=stride, pix_out+=stride) {
 
776
                if (stride<3) {
837
777
                        col[0]= curvemap_evaluateF(cumap->cm, *pix_in);
838
778
                        
839
779
                        pix_out[1]= pix_out[2]= pix_out[3]= pix_out[0]= col[0];
843
783
                        pix_out[0]= col[0];
844
784
                        pix_out[1]= col[1];
845
785
                        pix_out[2]= col[2];
846
 
                        if(stride>3)
 
786
                        if (stride>3)
847
787
                                pix_out[3]= pix_in[3];
848
788
                        else
849
789
                                pix_out[3]= 1.f;
861
801
{
862
802
        int a;
863
803
        
864
 
        if(cumap->black[0]!=0.0f) return 1;
865
 
        if(cumap->black[1]!=0.0f) return 1;
866
 
        if(cumap->black[2]!=0.0f) return 1;
867
 
        if(cumap->white[0]!=1.0f) return 1;
868
 
        if(cumap->white[1]!=1.0f) return 1;
869
 
        if(cumap->white[2]!=1.0f) return 1;
 
804
        if (cumap->black[0]!=0.0f) return 1;
 
805
        if (cumap->black[1]!=0.0f) return 1;
 
806
        if (cumap->black[2]!=0.0f) return 1;
 
807
        if (cumap->white[0]!=1.0f) return 1;
 
808
        if (cumap->white[1]!=1.0f) return 1;
 
809
        if (cumap->white[2]!=1.0f) return 1;
870
810
        
871
 
        for(a=0; a<CM_TOT; a++) {
872
 
                if(cumap->cm[a].curve) {
873
 
                        if(cumap->cm[a].totpoint!=2)  return 1;
 
811
        for (a=0; a<CM_TOT; a++) {
 
812
                if (cumap->cm[a].curve) {
 
813
                        if (cumap->cm[a].totpoint!=2)  return 1;
874
814
                        
875
 
                        if(cumap->cm[a].curve[0].x != 0.0f) return 1;
876
 
                        if(cumap->cm[a].curve[0].y != 0.0f) return 1;
877
 
                        if(cumap->cm[a].curve[1].x != 1.0f) return 1;
878
 
                        if(cumap->cm[a].curve[1].y != 1.0f) return 1;
 
815
                        if (cumap->cm[a].curve[0].x != 0.0f) return 1;
 
816
                        if (cumap->cm[a].curve[0].y != 0.0f) return 1;
 
817
                        if (cumap->cm[a].curve[1].x != 1.0f) return 1;
 
818
                        if (cumap->cm[a].curve[1].y != 1.0f) return 1;
879
819
                }
880
820
        }
881
821
        return 0;
885
825
{
886
826
        int a;
887
827
        
888
 
        if(cumap==NULL) return;
 
828
        if (cumap==NULL) return;
889
829
        
890
 
        for(a=0; a<CM_TOT; a++) {
891
 
                if(cumap->cm[a].table==NULL)
 
830
        for (a=0; a<CM_TOT; a++) {
 
831
                if (cumap->cm[a].table==NULL)
892
832
                        curvemap_make_table(cumap->cm+a, &cumap->clipr);
893
833
        }
894
834
}
901
841
        *array = MEM_callocN(sizeof(float)*(*size)*4, "CurveMapping");
902
842
        curvemapping_initialize(cumap);
903
843
 
904
 
        for(a=0; a<*size; a++) {
905
 
                if(cumap->cm[0].table)
 
844
        for (a=0; a<*size; a++) {
 
845
                if (cumap->cm[0].table)
906
846
                        (*array)[a*4+0]= cumap->cm[0].table[a].y;
907
 
                if(cumap->cm[1].table)
 
847
                if (cumap->cm[1].table)
908
848
                        (*array)[a*4+1]= cumap->cm[1].table[a].y;
909
 
                if(cumap->cm[2].table)
 
849
                if (cumap->cm[2].table)
910
850
                        (*array)[a*4+2]= cumap->cm[2].table[a].y;
911
 
                if(cumap->cm[3].table)
 
851
                if (cumap->cm[3].table)
912
852
                        (*array)[a*4+3]= cumap->cm[3].table[a].y;
913
853
        }
914
854
}
919
859
 
920
860
DO_INLINE int get_bin_float(float f)
921
861
{
922
 
        int bin= (int)(f*255);
 
862
        int bin= (int)((f*255.0f) + 0.5f);      /* 0.5 to prevent quantisation differences */
923
863
 
924
864
        /* note: clamp integer instead of float to avoid problems with NaN */
925
865
        CLAMP(bin, 0, 255);
926
 
        
927
 
        //return (int) (((f + 0.25) / 1.5) * 255);
928
 
        
 
866
 
929
867
        return bin;
930
868
}
931
869
 
932
 
DO_INLINE void save_sample_line(Scopes *scopes, const int idx, const float fx, float *rgb, float *ycc)
 
870
DO_INLINE void save_sample_line(Scopes *scopes, const int idx, const float fx, const float rgb[3], const float ycc[3])
933
871
{
934
872
        float yuv[3];
935
873
 
967
905
 
968
906
void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
969
907
{
970
 
        int x, y, c, n, nl;
 
908
        int x, y, c;
 
909
        unsigned int n, nl;
971
910
        double div, divl;
972
911
        float *rf=NULL;
973
912
        unsigned char *rc=NULL;
975
914
        int savedlines, saveline;
976
915
        float rgb[3], ycc[3], luma;
977
916
        int ycc_mode=-1;
 
917
        const short is_float = (ibuf->rect_float != NULL);
 
918
 
 
919
        if (ibuf->rect==NULL && ibuf->rect_float==NULL) return;
978
920
 
979
921
        if (scopes->ok == 1 ) return;
980
922
 
982
924
 
983
925
        /* hmmmm */
984
926
        if (!(ELEM(ibuf->channels, 3, 4))) return;
 
927
 
985
928
        scopes->hist.channels = 3;
986
929
        scopes->hist.x_resolution = 256;
987
930
 
1008
951
        bin_lum = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
1009
952
 
1010
953
        /* convert to number of lines with logarithmic scale */
1011
 
        scopes->sample_lines = (scopes->accuracy*0.01) * (scopes->accuracy*0.01) * ibuf->y;
 
954
        scopes->sample_lines = (scopes->accuracy*0.01f) * (scopes->accuracy*0.01f) * ibuf->y;
1012
955
        
1013
956
        if (scopes->sample_full)
1014
957
                scopes->sample_lines = ibuf->y;
1036
979
        scopes->waveform_3= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3");
1037
980
        scopes->vecscope= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel");
1038
981
        
1039
 
        if (ibuf->rect_float)
 
982
        if (is_float)
1040
983
                rf = ibuf->rect_float;
1041
 
        else if (ibuf->rect)
 
984
        else
1042
985
                rc = (unsigned char *)ibuf->rect;
1043
986
 
1044
987
        for (y = 0; y < ibuf->y; y++) {
1045
988
                if (savedlines<scopes->sample_lines && y>=((savedlines)*ibuf->y)/(scopes->sample_lines+1)) {
1046
 
                        saveline=1;
1047
 
                } else saveline=0;
 
989
                        saveline = 1;
 
990
                }
 
991
                else {
 
992
                        saveline = 0;
 
993
                }
1048
994
                for (x = 0; x < ibuf->x; x++) {
1049
995
 
1050
 
                        if (ibuf->rect_float) {
 
996
                        if (is_float) {
1051
997
                                if (use_color_management)
1052
998
                                        linearrgb_to_srgb_v3_v3(rgb, rf);
1053
999
                                else
1054
1000
                                        copy_v3_v3(rgb, rf);
1055
1001
                        }
1056
 
                        else if (ibuf->rect) {
 
1002
                        else {
1057
1003
                                for (c=0; c<3; c++)
1058
1004
                                        rgb[c] = rc[c] * INV_255;
1059
1005
                        }
1060
1006
 
1061
1007
                        /* we still need luma for histogram */
1062
 
                        luma = 0.299*rgb[0] + 0.587*rgb[1] + 0.114 * rgb[2];
 
1008
                        luma = rgb_to_luma(rgb);
1063
1009
 
1064
1010
                        /* check for min max */
1065
 
                        if(ycc_mode == -1 ) {
 
1011
                        if (ycc_mode == -1 ) {
1066
1012
                                for (c=0; c<3; c++) {
1067
1013
                                        if (rgb[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgb[c];
1068
1014
                                        if (rgb[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgb[c];
1083
1029
                        bin_lum[ get_bin_float(luma) ] += 1;
1084
1030
 
1085
1031
                        /* save sample if needed */
1086
 
                        if(saveline) {
 
1032
                        if (saveline) {
1087
1033
                                const float fx = (float)x / (float)ibuf->x;
1088
1034
                                const int idx = 2*(ibuf->x*savedlines+x);
1089
1035
                                save_sample_line(scopes, idx, fx, rgb, ycc);
1109
1055
                if (bin_lum[x] > nl)
1110
1056
                        nl = bin_lum[x];
1111
1057
        }
1112
 
        div = 1.f/(double)n;
1113
 
        divl = 1.f/(double)nl;
 
1058
        div = 1.0/(double)n;
 
1059
        divl = 1.0/(double)nl;
1114
1060
        for (x=0; x<256; x++) {
1115
1061
                scopes->hist.data_r[x] = bin_r[x] * div;
1116
1062
                scopes->hist.data_g[x] = bin_g[x] * div;