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