soc-2008-mxcurioni: foundations for Freestyle as a render layer - new UI buttons...
[blender.git] / source / blender / src / seqscopes.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Author: Peter Schlaile < peter [at] schlaile [dot] de >
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  *
24  */
25
26 #include "BSE_seqscopes.h"
27 #include "IMB_imbuf_types.h"
28 #include "IMB_imbuf.h"
29 #include "BKE_utildefines.h"
30 #include <math.h>
31 #include <string.h>
32
33 static void rgb_to_yuv(float rgb[3], float yuv[3]) {
34         yuv[0]= 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
35         yuv[1]= 0.492*(rgb[2] - yuv[0]);
36         yuv[2]= 0.877*(rgb[0] - yuv[0]);
37
38         /* Normalize */
39         yuv[1]*= 255.0/(122*2.0);
40         yuv[1]+= 0.5;
41
42         yuv[2]*= 255.0/(157*2.0);
43         yuv[2]+= 0.5;
44 }
45
46 static void scope_put_pixel(unsigned char* table, unsigned char * pos)
47 {
48         char newval = table[*pos];
49         pos[0] = pos[1] = pos[2] = newval;
50         pos[3] = 255;
51 }
52
53 static void scope_put_pixel_single(unsigned char* table, unsigned char * pos,
54                                    int col)
55 {
56         char newval = table[pos[col]];
57         pos[col] = newval;
58         pos[3] = 255;
59 }
60
61 static void wform_put_line(int w,
62                            unsigned char * last_pos, unsigned char * new_pos)
63 {
64         if (last_pos > new_pos) {
65                 unsigned char* temp = new_pos;
66                 new_pos = last_pos;
67                 last_pos = temp;
68         }
69
70         while (last_pos < new_pos) {
71                 if (last_pos[0] == 0) {
72                         last_pos[0] = last_pos[1] = last_pos[2] = 32;
73                         last_pos[3] = 255;
74                 }
75                 last_pos += 4*w;
76         }
77 }
78
79 static void wform_put_line_single(
80         int w, unsigned char * last_pos, unsigned char * new_pos, int col)
81 {
82         if (last_pos > new_pos) {
83                 unsigned char* temp = new_pos;
84                 new_pos = last_pos;
85                 last_pos = temp;
86         }
87
88         while (last_pos < new_pos) {
89                 if (last_pos[col] == 0) {
90                         last_pos[col] = 32;
91                         last_pos[3] = 255;
92                 }
93                 last_pos += 4*w;
94         }
95 }
96
97 static void wform_put_border(unsigned char * tgt, int w, int h)
98 {
99         int x, y;
100
101         for (x = 0; x < w; x++) {
102                 unsigned char * p = tgt + 4 * x;
103                 p[1] = p[3] = 255.0;
104                 p[4 * w + 1] = p[4 * w + 3] = 255.0;
105                 p = tgt + 4 * (w * (h - 1) + x);
106                 p[1] = p[3] = 255.0;
107                 p[-4 * w + 1] = p[-4 * w + 3] = 255.0;
108         }
109
110         for (y = 0; y < h; y++) {
111                 unsigned char * p = tgt + 4 * w * y;
112                 p[1] = p[3] = 255.0;
113                 p[4 + 1] = p[4 + 3] = 255.0;
114                 p = tgt + 4 * (w * y + w - 1);
115                 p[1] = p[3] = 255.0;
116                 p[-4 + 1] = p[-4 + 3] = 255.0;
117         }
118 }
119
120 static void wform_put_gridrow(unsigned char * tgt, float perc, int w, int h)
121 {
122         int i;
123
124         tgt += (int) (perc/100.0 * h) * w * 4;
125
126         for (i = 0; i < w*2; i++) {
127                 tgt[0] = 255;
128
129                 tgt += 4;
130         }
131 }
132
133 static void wform_put_grid(unsigned char * tgt, int w, int h)
134 {
135         wform_put_gridrow(tgt, 90.0, w, h);
136         wform_put_gridrow(tgt, 70.0, w, h);
137         wform_put_gridrow(tgt, 10.0, w, h);
138 }
139
140 static struct ImBuf *make_waveform_view_from_ibuf_byte(struct ImBuf * ibuf)
141 {
142         struct ImBuf * rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect, 0);
143         int x,y;
144         unsigned char* src = (unsigned char*) ibuf->rect;
145         unsigned char* tgt = (unsigned char*) rval->rect;
146         int w = ibuf->x + 3;
147         int h = 515;
148         float waveform_gamma = 0.2;
149         unsigned char wtable[256];
150
151         wform_put_grid(tgt, w, h);
152
153         for (x = 0; x < 256; x++) {
154                 wtable[x] = (unsigned char) (pow(((float) x + 1)/256, 
155                                                  waveform_gamma)*255);
156         }
157
158         for (y = 0; y < ibuf->y; y++) {
159                 unsigned char * last_p = 0;
160
161                 for (x = 0; x < ibuf->x; x++) {
162                         unsigned char * rgb = src + 4 * (ibuf->x * y + x);
163                         float v = 1.0 * 
164                                 (  0.299*rgb[0] 
165                                  + 0.587*rgb[1] 
166                                  + 0.114*rgb[2]) / 255.0;
167                         unsigned char * p = tgt;
168                         p += 4 * (w * ((int) (v * (h - 3)) + 1) + x + 1);
169
170                         scope_put_pixel(wtable, p);
171                         p += 4 * w;
172                         scope_put_pixel(wtable, p);
173
174                         if (last_p != 0) {
175                                 wform_put_line(w, last_p, p);
176                         }
177                         last_p = p;
178                 }
179         }
180
181         wform_put_border(tgt, w, h);
182         
183         return rval;
184 }
185
186 static struct ImBuf *make_waveform_view_from_ibuf_float(struct ImBuf * ibuf)
187 {
188         struct ImBuf * rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect, 0);
189         int x,y;
190         float* src = ibuf->rect_float;
191         unsigned char* tgt = (unsigned char*) rval->rect;
192         int w = ibuf->x + 3;
193         int h = 515;
194         float waveform_gamma = 0.2;
195         unsigned char wtable[256];
196
197         wform_put_grid(tgt, w, h);
198
199         for (x = 0; x < 256; x++) {
200                 wtable[x] = (unsigned char) (pow(((float) x + 1)/256, 
201                                                  waveform_gamma)*255);
202         }
203
204         for (y = 0; y < ibuf->y; y++) {
205                 unsigned char * last_p = 0;
206
207                 for (x = 0; x < ibuf->x; x++) {
208                         float * rgb = src + 4 * (ibuf->x * y + x);
209                         float v = 1.0 * 
210                                 (  0.299*rgb[0] 
211                                  + 0.587*rgb[1] 
212                                  + 0.114*rgb[2]);
213                         unsigned char * p = tgt;
214
215                         CLAMP(v, 0.0, 1.0);
216
217                         p += 4 * (w * ((int) (v * (h - 3)) + 1) + x + 1);
218
219                         scope_put_pixel(wtable, p);
220                         p += 4 * w;
221                         scope_put_pixel(wtable, p);
222
223                         if (last_p != 0) {
224                                 wform_put_line(w, last_p, p);
225                         }
226                         last_p = p;
227                 }
228         }
229
230         wform_put_border(tgt, w, h);
231         
232         return rval;
233 }
234
235 struct ImBuf *make_waveform_view_from_ibuf(struct ImBuf * ibuf)
236 {
237         if (ibuf->rect_float) {
238                 return make_waveform_view_from_ibuf_float(ibuf);
239         } else {
240                 return make_waveform_view_from_ibuf_byte(ibuf);
241         }
242 }
243
244
245 static struct ImBuf *make_sep_waveform_view_from_ibuf_byte(struct ImBuf * ibuf)
246 {
247         struct ImBuf * rval = IMB_allocImBuf(
248                 ibuf->x + 3, 515, 32, IB_rect, 0);
249         int x,y;
250         unsigned char* src = (unsigned char*) ibuf->rect;
251         unsigned char* tgt = (unsigned char*) rval->rect;
252         int w = ibuf->x + 3;
253         int sw = ibuf->x/3;
254         int h = 515;
255         float waveform_gamma = 0.2;
256         unsigned char wtable[256];
257
258         wform_put_grid(tgt, w, h);
259
260         for (x = 0; x < 256; x++) {
261                 wtable[x] = (unsigned char) (pow(((float) x + 1)/256, 
262                                                  waveform_gamma)*255);
263         }
264
265         for (y = 0; y < ibuf->y; y++) {
266                 unsigned char * last_p[3] = {0,0,0};
267
268                 for (x = 0; x < ibuf->x; x++) {
269                         int c;
270                         unsigned char * rgb = src + 4 * (ibuf->x * y + x);
271                         for (c = 0; c < 3; c++) {
272                                 unsigned char * p = tgt;
273                                 p += 4 * (w * ((rgb[c] * (h - 3))/255 + 1) 
274                                           + c * sw + x/3 + 1);
275
276                                 scope_put_pixel_single(wtable, p, c);
277                                 p += 4 * w;
278                                 scope_put_pixel_single(wtable, p, c);
279
280                                 if (last_p[c] != 0) {
281                                         wform_put_line_single(
282                                                 w, last_p[c], p, c);
283                                 }
284                                 last_p[c] = p;
285                         }
286                 }
287         }
288
289         wform_put_border(tgt, w, h);
290         
291         return rval;
292 }
293
294 static struct ImBuf *make_sep_waveform_view_from_ibuf_float(
295         struct ImBuf * ibuf)
296 {
297         struct ImBuf * rval = IMB_allocImBuf(
298                 ibuf->x + 3, 515, 32, IB_rect, 0);
299         int x,y;
300         float* src = ibuf->rect_float;
301         unsigned char* tgt = (unsigned char*) rval->rect;
302         int w = ibuf->x + 3;
303         int sw = ibuf->x/3;
304         int h = 515;
305         float waveform_gamma = 0.2;
306         unsigned char wtable[256];
307
308         wform_put_grid(tgt, w, h);
309
310         for (x = 0; x < 256; x++) {
311                 wtable[x] = (unsigned char) (pow(((float) x + 1)/256, 
312                                                  waveform_gamma)*255);
313         }
314
315         for (y = 0; y < ibuf->y; y++) {
316                 unsigned char * last_p[3] = {0, 0, 0};
317
318                 for (x = 0; x < ibuf->x; x++) {
319                         int c;
320                         float * rgb = src + 4 * (ibuf->x * y + x);
321                         for (c = 0; c < 3; c++) {
322                                 unsigned char * p = tgt;
323                                 float v = rgb[c];
324
325                                 CLAMP(v, 0.0, 1.0);
326
327                                 p += 4 * (w * ((int) (v * (h - 3)) + 1)
328                                           + c * sw + x/3 + 1);
329
330                                 scope_put_pixel_single(wtable, p, c);
331                                 p += 4 * w;
332                                 scope_put_pixel_single(wtable, p, c);
333
334                                 if (last_p[c] != 0) {
335                                         wform_put_line_single(
336                                                 w, last_p[c], p, c);
337                                 }
338                                 last_p[c] = p;
339                         }
340                 }
341         }
342
343         wform_put_border(tgt, w, h);
344         
345         return rval;
346 }
347
348 struct ImBuf *make_sep_waveform_view_from_ibuf(struct ImBuf * ibuf)
349 {
350         if (ibuf->rect_float) {
351                 return make_sep_waveform_view_from_ibuf_float(ibuf);
352         } else {
353                 return make_sep_waveform_view_from_ibuf_byte(ibuf);
354         }
355 }
356
357 static void draw_zebra_byte(struct ImBuf * src,struct ImBuf * ibuf, float perc)
358 {
359         unsigned int limit = 255 * perc / 100.0;
360         unsigned char * p = (unsigned char*) src->rect;
361         unsigned char * o = (unsigned char*) ibuf->rect;
362         int x;
363         int y;
364
365         for (y = 0; y < ibuf->y; y++) {
366                 for (x = 0; x < ibuf->x; x++) {
367                         unsigned char r = *p++;
368                         unsigned char g = *p++;
369                         unsigned char b = *p++;
370                         unsigned char a = *p++;
371
372                         if (r >= limit || g >= limit || b >= limit) {
373                                 if (((x + y) & 0x08) != 0) {
374                                         r = 255 - r;
375                                         g = 255 - g;
376                                         b = 255 - b;
377                                 }
378                         }
379                         *o++ = r;
380                         *o++ = g;
381                         *o++ = b;
382                         *o++ = a;
383                 }
384         }
385 }
386
387 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.99f*val))
388
389 static void draw_zebra_float(struct ImBuf * src,struct ImBuf * ibuf,float perc)
390 {
391         float limit = perc / 100.0;
392         float * p = src->rect_float;
393         unsigned char * o = (unsigned char*) ibuf->rect;
394         int x;
395         int y;
396
397         for (y = 0; y < ibuf->y; y++) {
398                 for (x = 0; x < ibuf->x; x++) {
399                         float r = *p++;
400                         float g = *p++;
401                         float b = *p++;
402                         float a = *p++;
403
404                         if (r >= limit || g >= limit || b >= limit) {
405                                 if (((x + y) & 0x08) != 0) {
406                                         r = -r;
407                                         g = -g;
408                                         b = -b;
409                                 }
410                         }
411
412                         *o++ = FTOCHAR(r);
413                         *o++ = FTOCHAR(g);
414                         *o++ = FTOCHAR(b);
415                         *o++ = FTOCHAR(a);
416                 }
417         }
418 }
419
420 struct ImBuf * make_zebra_view_from_ibuf(struct ImBuf * src, float perc)
421 {
422         struct ImBuf * ibuf = IMB_allocImBuf(src->x, src->y, 32, IB_rect, 0);
423
424         if (src->rect_float) {
425                 draw_zebra_float(src, ibuf, perc);
426         } else {
427                 draw_zebra_byte(src, ibuf, perc);
428         }
429         return ibuf;
430 }
431
432 static void draw_histogram_marker(struct ImBuf * ibuf, int x)
433 {
434         unsigned char * p = (unsigned char*) ibuf->rect;
435         int barh = ibuf->y * 0.1;
436         int i;
437
438         p += 4 * (x + ibuf->x * (ibuf->y - barh + 1));
439
440         for (i = 0; i < barh-1; i++) {
441                 p[0] = p[1] = p[2] = 255;
442                 p += ibuf->x * 4;
443         }
444 }
445
446 static void draw_histogram_bar(struct ImBuf * ibuf, int x,float val, int col)
447 {
448         unsigned char * p = (unsigned char*) ibuf->rect;
449         int barh = ibuf->y * val * 0.9;
450         int i;
451
452         p += 4 * (x + ibuf->x);
453
454         for (i = 0; i < barh; i++) {
455                 p[col] = 255;
456                 p += ibuf->x * 4;
457         }
458 }
459
460 static struct ImBuf *make_histogram_view_from_ibuf_byte(
461         struct ImBuf * ibuf)
462 {
463         struct ImBuf * rval = IMB_allocImBuf(515, 128, 32, IB_rect, 0);
464         int n,c,x,y;
465         unsigned char* src = (unsigned char*) ibuf->rect;
466
467         unsigned int bins[3][256];
468
469         memset(bins, 0, 3 * 256* sizeof(unsigned int));
470
471         for (y = 0; y < ibuf->y; y++) {
472                 for (x = 0; x < ibuf->x; x++) {
473                         bins[0][*src++]++;
474                         bins[1][*src++]++;
475                         bins[2][*src++]++;
476                         src++;
477                 }
478         }
479
480         n = 0;
481         for (c = 0; c < 3; c++) {
482                 for (x = 0; x < 256; x++) {
483                         if (bins[c][x] > n) {
484                                 n = bins[c][x];
485                         }
486                 }
487         }
488
489         for (c = 0; c < 3; c++) {
490                 for (x = 0; x < 256; x++) {
491                         draw_histogram_bar(rval, x*2+1, 
492                                            ((float) bins[c][x])/n, c);
493                         draw_histogram_bar(rval, x*2+2, 
494                                            ((float) bins[c][x])/n, c);
495                 }
496         }
497
498         wform_put_border((unsigned char*) rval->rect, rval->x, rval->y);
499         
500         return rval;
501 }
502
503 static int get_bin_float(float f)
504 {
505         if (f < -0.25) {
506                 f = -0.25;
507         } else if (f > 1.25) {
508                 f = 1.25;
509         }
510
511         return (int) (((f + 0.25) / 1.5) * 512);
512 }
513
514 static struct ImBuf *make_histogram_view_from_ibuf_float(
515         struct ImBuf * ibuf)
516 {
517         struct ImBuf * rval = IMB_allocImBuf(515, 128, 32, IB_rect, 0);
518         int n,c,x,y;
519         float* src = ibuf->rect_float;
520
521         unsigned int bins[3][512];
522
523         memset(bins, 0, 3 * 256* sizeof(unsigned int));
524
525         for (y = 0; y < ibuf->y; y++) {
526                 for (x = 0; x < ibuf->x; x++) {
527                         bins[0][get_bin_float(*src++)]++;
528                         bins[1][get_bin_float(*src++)]++;
529                         bins[2][get_bin_float(*src++)]++;
530                         src++;
531                 }
532         }
533
534         draw_histogram_marker(rval, get_bin_float(0.0));
535         draw_histogram_marker(rval, get_bin_float(1.0));
536
537         n = 0;
538         for (c = 0; c < 3; c++) {
539                 for (x = 0; x < 512; x++) {
540                         if (bins[c][x] > n) {
541                                 n = bins[c][x];
542                         }
543                 }
544         }
545         for (c = 0; c < 3; c++) {
546                 for (x = 0; x < 512; x++) {
547                         draw_histogram_bar(rval, x+1, (float) bins[c][x]/n, c);
548                 }
549         }
550
551         wform_put_border((unsigned char*) rval->rect, rval->x, rval->y);
552         
553         return rval;
554 }
555
556 struct ImBuf *make_histogram_view_from_ibuf(struct ImBuf * ibuf)
557 {
558         if (ibuf->rect_float) {
559                 return make_histogram_view_from_ibuf_float(ibuf);
560         } else {
561                 return make_histogram_view_from_ibuf_byte(ibuf);
562         }
563 }
564
565 static void vectorscope_put_cross(unsigned char r, unsigned char g, 
566                                   unsigned char b, 
567                                   char * tgt, int w, int h, int size)
568 {
569         float rgb[3], yuv[3];
570         char * p;
571         int x = 0;
572         int y = 0;
573
574         rgb[0]= (float)r/255.0;
575         rgb[1]= (float)g/255.0;
576         rgb[2]= (float)b/255.0;
577         rgb_to_yuv(rgb, yuv);
578                         
579         p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) 
580                        + (int) ((yuv[1] * (w - 3) + 1)));
581
582         if (r == 0 && g == 0 && b == 0) {
583                 r = 255;
584         }
585
586         for (y = -size; y <= size; y++) {
587                 for (x = -size; x <= size; x++) {
588                         char * q = p + 4 * (y * w + x);
589                         q[0] = r; q[1] = g; q[2] = b; q[3] = 255;
590                 }
591         }
592 }
593
594 static struct ImBuf *make_vectorscope_view_from_ibuf_byte(struct ImBuf * ibuf)
595 {
596         struct ImBuf * rval = IMB_allocImBuf(515, 515, 32, IB_rect, 0);
597         int x,y;
598         char* src = (char*) ibuf->rect;
599         char* tgt = (char*) rval->rect;
600         float rgb[3], yuv[3];
601         int w = 515;
602         int h = 515;
603         float scope_gamma = 0.2;
604         unsigned char wtable[256];
605
606         for (x = 0; x < 256; x++) {
607                 wtable[x] = (unsigned char) (pow(((float) x + 1)/256, 
608                                                  scope_gamma)*255);
609         }
610
611         for (x = 0; x <= 255; x++) {
612                 vectorscope_put_cross(255   ,     0,255 - x, tgt, w, h, 1);
613                 vectorscope_put_cross(255   ,     x,      0, tgt, w, h, 1);
614                 vectorscope_put_cross(255- x,   255,      0, tgt, w, h, 1);
615                 vectorscope_put_cross(0,        255,      x, tgt, w, h, 1);
616                 vectorscope_put_cross(0,    255 - x,    255, tgt, w, h, 1);
617                 vectorscope_put_cross(x,          0,    255, tgt, w, h, 1);
618         }
619
620         for (y = 0; y < ibuf->y; y++) {
621                 for (x = 0; x < ibuf->x; x++) {
622                         char * src1 = src + 4 * (ibuf->x * y + x);
623                         char * p;
624                         
625                         rgb[0]= (float)src1[0]/255.0;
626                         rgb[1]= (float)src1[1]/255.0;
627                         rgb[2]= (float)src1[2]/255.0;
628                         rgb_to_yuv(rgb, yuv);
629                         
630                         p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) 
631                                        + (int) ((yuv[1] * (w - 3) + 1)));
632                         scope_put_pixel(wtable, (unsigned char*)p);
633                 }
634         }
635
636         vectorscope_put_cross(0, 0, 0, tgt, w, h, 3);
637
638         return rval;
639 }
640
641 static struct ImBuf *make_vectorscope_view_from_ibuf_float(struct ImBuf * ibuf)
642 {
643         struct ImBuf * rval = IMB_allocImBuf(515, 515, 32, IB_rect, 0);
644         int x,y;
645         float* src = ibuf->rect_float;
646         char* tgt = (char*) rval->rect;
647         float rgb[3], yuv[3];
648         int w = 515;
649         int h = 515;
650         float scope_gamma = 0.2;
651         unsigned char wtable[256];
652
653         for (x = 0; x < 256; x++) {
654                 wtable[x] = (unsigned char) (pow(((float) x + 1)/256, 
655                                                  scope_gamma)*255);
656         }
657
658         for (x = 0; x <= 255; x++) {
659                 vectorscope_put_cross(255   ,     0,255 - x, tgt, w, h, 1);
660                 vectorscope_put_cross(255   ,     x,      0, tgt, w, h, 1);
661                 vectorscope_put_cross(255- x,   255,      0, tgt, w, h, 1);
662                 vectorscope_put_cross(0,        255,      x, tgt, w, h, 1);
663                 vectorscope_put_cross(0,    255 - x,    255, tgt, w, h, 1);
664                 vectorscope_put_cross(x,          0,    255, tgt, w, h, 1);
665         }
666
667         for (y = 0; y < ibuf->y; y++) {
668                 for (x = 0; x < ibuf->x; x++) {
669                         float * src1 = src + 4 * (ibuf->x * y + x);
670                         char * p;
671                         
672                         memcpy(rgb, src1, 3 * sizeof(float));
673
674                         CLAMP(rgb[0], 0.0, 1.0);
675                         CLAMP(rgb[1], 0.0, 1.0);
676                         CLAMP(rgb[2], 0.0, 1.0);
677
678                         rgb_to_yuv(rgb, yuv);
679                         
680                         p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) 
681                                        + (int) ((yuv[1] * (w - 3) + 1)));
682                         scope_put_pixel(wtable, (unsigned char*)p);
683                 }
684         }
685
686         vectorscope_put_cross(0, 0, 0, tgt, w, h, 3);
687
688         return rval;
689 }
690
691 struct ImBuf *make_vectorscope_view_from_ibuf(struct ImBuf * ibuf)
692 {
693         if (ibuf->rect_float) {
694                 return make_vectorscope_view_from_ibuf_float(ibuf);
695         } else {
696                 return make_vectorscope_view_from_ibuf_byte(ibuf);
697         }
698 }