initial commit
[goodguy/history.git] / cinelerra-5.0 / quicktime / colormodels.c
1 /*
2  * This library is free software; you can redistribute it and/or modify it
3  * under the terms of the GNU Lesser General Public License as published
4  * by the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  * 
7  * This library is distributed in the hope that it will be useful, but
8  * WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  * Lesser General Public License for more details.
11  * 
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 
15  * USA
16  */
17
18
19
20 #include "colormodels.h"
21 #include "cmodel_permutation.h"
22 #include <stdlib.h>
23 #include <string.h>
24
25
26 cmodel_yuv_t *yuv_table = 0;
27
28 // Compression coefficients straight out of jpeglib
29 #define R_TO_Y    0.29900
30 #define G_TO_Y    0.58700
31 #define B_TO_Y    0.11400
32
33 #define R_TO_U    -0.16874
34 #define G_TO_U    -0.33126
35 #define B_TO_U    0.50000
36
37 #define R_TO_V    0.50000
38 #define G_TO_V    -0.41869
39 #define B_TO_V    -0.08131
40
41 // Decompression coefficients straight out of jpeglib
42 #define V_TO_R    1.40200
43 #define V_TO_G    -0.71414
44
45 #define U_TO_G    -0.34414
46 #define U_TO_B    1.77200
47
48
49
50
51
52
53 void cmodel_init_yuv(cmodel_yuv_t *yuv_table)
54 {
55         int i;
56
57 /* compression */
58         for(i = 0; i < 0x100; i++)
59         {
60                 yuv_table->rtoy_tab[i] = (int)(R_TO_Y * 0x10000 * i);
61                 yuv_table->rtou_tab[i] = (int)(R_TO_U * 0x10000 * i);
62                 yuv_table->rtov_tab[i] = (int)(R_TO_V * 0x10000 * i);
63
64                 yuv_table->gtoy_tab[i] = (int)(G_TO_Y * 0x10000 * i);
65                 yuv_table->gtou_tab[i] = (int)(G_TO_U * 0x10000 * i);
66                 yuv_table->gtov_tab[i] = (int)(G_TO_V * 0x10000 * i);
67
68                 yuv_table->btoy_tab[i] = (int)(B_TO_Y * 0x10000 * i);
69                 yuv_table->btou_tab[i] = (int)(B_TO_U * 0x10000 * i) + 0x800000;
70                 yuv_table->btov_tab[i] = (int)(B_TO_V * 0x10000 * i) + 0x800000;
71         }
72
73 /* compression */
74         for(i = 0; i < 0x10000; i++)
75         {
76                 yuv_table->rtoy_tab16[i] = (int)(R_TO_Y * 0x100 * i);
77                 yuv_table->rtou_tab16[i] = (int)(R_TO_U * 0x100 * i);
78                 yuv_table->rtov_tab16[i] = (int)(R_TO_V * 0x100 * i);
79
80                 yuv_table->gtoy_tab16[i] = (int)(G_TO_Y * 0x100 * i);
81                 yuv_table->gtou_tab16[i] = (int)(G_TO_U * 0x100 * i);
82                 yuv_table->gtov_tab16[i] = (int)(G_TO_V * 0x100 * i);
83
84                 yuv_table->btoy_tab16[i] = (int)(B_TO_Y * 0x100 * i);
85                 yuv_table->btou_tab16[i] = (int)(B_TO_U * 0x100 * i) + 0x800000;
86                 yuv_table->btov_tab16[i] = (int)(B_TO_V * 0x100 * i) + 0x800000;
87         }
88
89
90
91
92 /* decompression */
93         yuv_table->vtor = &(yuv_table->vtor_tab[0x80]);
94         yuv_table->vtog = &(yuv_table->vtog_tab[0x80]);
95         yuv_table->utog = &(yuv_table->utog_tab[0x80]);
96         yuv_table->utob = &(yuv_table->utob_tab[0x80]);
97         yuv_table->vtor8 = &(yuv_table->vtor_tab8[0x80]);
98         yuv_table->vtog8 = &(yuv_table->vtog_tab8[0x80]);
99         yuv_table->utog8 = &(yuv_table->utog_tab8[0x80]);
100         yuv_table->utob8 = &(yuv_table->utob_tab8[0x80]);
101         for(i = -0x80; i < 0x80; i++)
102         {
103                 yuv_table->vtor[i] = (int)(V_TO_R * 0x10000 * i);
104                 yuv_table->vtog[i] = (int)(V_TO_G * 0x10000 * i);
105
106                 yuv_table->utog[i] = (int)(U_TO_G * 0x10000 * i);
107                 yuv_table->utob[i] = (int)(U_TO_B * 0x10000 * i);
108
109                 yuv_table->vtor8[i] = (int)(V_TO_R * i);
110                 yuv_table->vtog8[i] = (int)(V_TO_G * i);
111
112                 yuv_table->utog8[i] = (int)(U_TO_G * i);
113                 yuv_table->utob8[i] = (int)(U_TO_B * i);
114         }
115
116
117 /* decompression */
118         yuv_table->vtor_float = &(yuv_table->vtor_float_tab[0x80]);
119         yuv_table->vtog_float = &(yuv_table->vtog_float_tab[0x80]);
120         yuv_table->utog_float = &(yuv_table->utog_float_tab[0x80]);
121         yuv_table->utob_float = &(yuv_table->utob_float_tab[0x80]);
122         for(i = -0x80; i < 0x80; i++)
123         {
124                 yuv_table->vtor_float[i] = V_TO_R * i / 0xff;
125                 yuv_table->vtog_float[i] = V_TO_G * i / 0xff;
126
127                 yuv_table->utog_float[i] = U_TO_G * i / 0xff;
128                 yuv_table->utob_float[i] = U_TO_B * i / 0xff;
129         }
130
131
132 /* decompression */
133         yuv_table->vtor16 = &(yuv_table->vtor_tab16[0x8000]);
134         yuv_table->vtog16 = &(yuv_table->vtog_tab16[0x8000]);
135         yuv_table->utog16 = &(yuv_table->utog_tab16[0x8000]);
136         yuv_table->utob16 = &(yuv_table->utob_tab16[0x8000]);
137         for(i = -0x8000; i < 0x8000; i++)
138         {
139                 yuv_table->vtor16[i] = (int)(V_TO_R * 0x100 * i);
140                 yuv_table->vtog16[i] = (int)(V_TO_G * 0x100 * i);
141
142                 yuv_table->utog16[i] = (int)(U_TO_G * 0x100 * i);
143                 yuv_table->utob16[i] = (int)(U_TO_B * 0x100 * i);
144         }
145
146
147 /* decompression */
148         yuv_table->v16tor_float = &(yuv_table->v16tor_float_tab[0x8000]);
149         yuv_table->v16tog_float = &(yuv_table->v16tog_float_tab[0x8000]);
150         yuv_table->u16tog_float = &(yuv_table->u16tog_float_tab[0x8000]);
151         yuv_table->u16tob_float = &(yuv_table->u16tob_float_tab[0x8000]);
152         for(i = -0x8000; i < 0x8000; i++)
153         {
154                 yuv_table->v16tor_float[i] = V_TO_R * i / 0xffff;
155                 yuv_table->v16tog_float[i] = V_TO_G * i / 0xffff;
156
157                 yuv_table->u16tog_float[i] = U_TO_G * i / 0xffff;
158                 yuv_table->u16tob_float[i] = U_TO_B * i / 0xffff;
159         }
160 }
161
162
163 void cmodel_delete_yuv(cmodel_yuv_t *yuv_table)
164 {
165 }
166
167 int cmodel_is_planar(int colormodel)
168 {
169         switch(colormodel)
170         {
171                 case BC_YUV420P:      return 1; break;
172                 case BC_YUV422P:      return 1; break;
173                 case BC_YUV444P:      return 1; break;
174 //              case BC_YUV411P:      return 1; break;
175         }
176         return 0;
177 }
178
179 int cmodel_components(int colormodel)
180 {
181         switch(colormodel)
182         {
183                 case BC_A8:           return 1; break;
184                 case BC_A16:          return 1; break;
185                 case BC_A_FLOAT:      return 1; break;
186                 case BC_RGBA8888:     return 4; break;
187                 case BC_RGBA16161616: return 4; break;
188                 case BC_YUVA8888:     return 4; break;
189                 case BC_YUVA16161616: return 4; break;
190                 case BC_RGBA_FLOAT:   return 4; break;
191         }
192         return 3;
193 }
194
195 int cmodel_calculate_pixelsize(int colormodel)
196 {
197         switch(colormodel)
198         {
199                 case BC_A8:           return 1; break;
200                 case BC_A16:          return 2; break;
201                 case BC_A_FLOAT:      return 4; break;
202                 case BC_TRANSPARENCY: return 1; break;
203                 case BC_COMPRESSED:   return 1; break;
204                 case BC_RGB8:         return 1; break;
205                 case BC_RGB565:       return 2; break;
206                 case BC_BGR565:       return 2; break;
207                 case BC_BGR888:       return 3; break;
208                 case BC_BGR8888:      return 4; break;
209 // Working bitmaps are packed to simplify processing
210                 case BC_RGB888:       return 3; break;
211                 case BC_ARGB8888:     return 4; break;
212                 case BC_ABGR8888:     return 4; break;
213                 case BC_RGBA8888:     return 4; break;
214                 case BC_RGB161616:    return 6; break;
215                 case BC_RGBA16161616: return 8; break;
216                 case BC_YUV888:       return 3; break;
217                 case BC_YUVA8888:     return 4; break;
218                 case BC_YUV161616:    return 6; break;
219                 case BC_YUVA16161616: return 8; break;
220                 case BC_YUV101010:    return 4; break;
221                 case BC_VYU888:       return 3; break;
222                 case BC_UYVA8888:     return 4; break;
223                 case BC_RGB_FLOAT:    return 12; break;
224                 case BC_RGBA_FLOAT:   return 16; break;
225 // Planar
226                 case BC_YUV420P:      return 1; break;
227                 case BC_YUV422P:      return 1; break;
228                 case BC_YUV444P:      return 1; break;
229                 case BC_YUV422:       return 2; break;
230 //              case BC_YUV411P:      return 1; break;
231                 case BC_YUV9P:        return 1; break;
232         }
233         return 0;
234 }
235
236 int cmodel_calculate_max(int colormodel)
237 {
238         switch(colormodel)
239         {
240 // Working bitmaps are packed to simplify processing
241                 case BC_A8:           return 0xff; break;
242                 case BC_A16:          return 0xffff; break;
243                 case BC_A_FLOAT:      return 1; break;
244                 case BC_RGB888:       return 0xff; break;
245                 case BC_RGBA8888:     return 0xff; break;
246                 case BC_RGB161616:    return 0xffff; break;
247                 case BC_RGBA16161616: return 0xffff; break;
248                 case BC_YUV888:       return 0xff; break;
249                 case BC_YUVA8888:     return 0xff; break;
250                 case BC_YUV161616:    return 0xffff; break;
251                 case BC_YUVA16161616: return 0xffff; break;
252                 case BC_RGB_FLOAT:    return 1; break;
253                 case BC_RGBA_FLOAT:   return 1; break;
254         }
255         return 0;
256 }
257
258 int cmodel_calculate_datasize(int w, int h, int bytes_per_line, int color_model)
259 {
260         if(bytes_per_line < 0) bytes_per_line = w * 
261                 cmodel_calculate_pixelsize(color_model);
262         switch(color_model)
263         {
264                 case BC_YUV420P:
265 //              case BC_YUV411P:
266                         return w * h + w * h / 2 + 4;
267                         break;
268
269                 case BC_YUV422P:
270                         return w * h * 2 + 4;
271                         break;
272
273                 case BC_YUV444P:
274                         return w * h * 3 + 4;
275                         break;
276
277                 default:
278                         return h * bytes_per_line + 4;
279                         break;
280         }
281         return 0;
282 }
283
284
285 static void get_scale_tables(int **column_table, 
286         int **row_table, 
287         int in_x1, 
288         int in_y1, 
289         int in_x2, 
290         int in_y2,
291         int out_x1, 
292         int out_y1, 
293         int out_x2, 
294         int out_y2)
295 {
296         int i;
297         float w_in = in_x2 - in_x1;
298         float h_in = in_y2 - in_y1;
299         int w_out = out_x2 - out_x1;
300         int h_out = out_y2 - out_y1;
301
302         float hscale = w_in / w_out;
303         float vscale = h_in / h_out;
304
305 /* + 1 so we don't overflow when calculating in advance */
306         (*column_table) = malloc(sizeof(int) * (w_out + 1));
307         (*row_table) = malloc(sizeof(int) * h_out);
308         for(i = 0; i < w_out; i++)
309         {
310                 (*column_table)[i] = (int)(hscale * i) + in_x1;
311         }
312
313         for(i = 0; i < h_out; i++)
314         {
315                 (*row_table)[i] = (int)(vscale * i) + in_y1;
316 //printf("get_scale_tables %d %d\n", (*row_table)[i], i);
317         }
318 }
319
320
321 void cmodel_transfer(unsigned char **output_rows, 
322         unsigned char **input_rows,
323         unsigned char *out_y_plane,
324         unsigned char *out_u_plane,
325         unsigned char *out_v_plane,
326         unsigned char *in_y_plane,
327         unsigned char *in_u_plane,
328         unsigned char *in_v_plane,
329         int in_x, 
330         int in_y, 
331         int in_w, 
332         int in_h,
333         int out_x, 
334         int out_y, 
335         int out_w, 
336         int out_h,
337         int in_colormodel, 
338         int out_colormodel,
339         int bg_color,
340         int in_rowspan,
341         int out_rowspan)
342 {
343         int *column_table;
344         int *row_table;
345         int scale;
346         int bg_r, bg_g, bg_b;
347         int in_pixelsize = cmodel_calculate_pixelsize(in_colormodel);
348         int out_pixelsize = cmodel_calculate_pixelsize(out_colormodel);
349
350         bg_r = (bg_color & 0xff0000) >> 16;
351         bg_g = (bg_color & 0xff00) >> 8;
352         bg_b = (bg_color & 0xff);
353
354 // Initialize tables
355         if(yuv_table == 0)
356         {
357                 yuv_table = calloc(1, sizeof(cmodel_yuv_t));
358                 cmodel_init_yuv(yuv_table);
359         }
360
361 // Get scaling
362         scale = (out_w != in_w) || (in_x != 0);
363         get_scale_tables(&column_table, &row_table, 
364                 in_x, in_y, in_x + in_w, in_y + in_h,
365                 out_x, out_y, out_x + out_w, out_y + out_h);
366
367 /*
368  * printf("cmodel_transfer %d %d %d %d,%d %d,%d %d,%d %d,%d\n", 
369  * __LINE__,
370  * in_colormodel, 
371  * out_colormodel, 
372  * out_x, 
373  * out_y, 
374  * out_w, 
375  * out_h, 
376  * in_x, 
377  * in_y, 
378  * in_w, 
379  * in_h);
380  */
381
382
383 #define PERMUTATION_VALUES \
384         output_rows,  \
385         input_rows, \
386         out_y_plane, \
387         out_u_plane, \
388         out_v_plane, \
389         in_y_plane, \
390         in_u_plane, \
391         in_v_plane, \
392         in_x,  \
393         in_y,  \
394         in_w,  \
395         in_h, \
396         out_x,  \
397         out_y,  \
398         out_w,  \
399         out_h, \
400         in_colormodel,  \
401         out_colormodel, \
402         bg_color, \
403         in_rowspan, \
404         out_rowspan, \
405         scale, \
406         out_pixelsize, \
407         in_pixelsize, \
408         row_table, \
409         column_table, \
410         bg_r, \
411         bg_g, \
412         bg_b
413
414 // Handle planar cmodels separately
415         switch(in_colormodel)
416         {
417                 case BC_RGB_FLOAT:
418                 case BC_RGBA_FLOAT:
419                         cmodel_float(PERMUTATION_VALUES);
420                         break;
421
422                 case BC_YUV420P:
423                 case BC_YUV422P:
424                         cmodel_yuv420p(PERMUTATION_VALUES);
425                         break;
426
427                 case BC_YUV9P:
428                         cmodel_yuv9p(PERMUTATION_VALUES);
429                         break;
430
431                 case BC_YUV444P:
432                         cmodel_yuv444p(PERMUTATION_VALUES);
433                         break;
434
435                 case BC_YUV422:
436                         cmodel_yuv422(PERMUTATION_VALUES);
437                         break;
438
439                 default:
440                         cmodel_default(PERMUTATION_VALUES);
441                         break;
442         }
443
444 /*
445  * printf("cmodel_transfer 100 %d %d\n", 
446  * in_colormodel, 
447  * out_colormodel);
448  */
449
450         free(column_table);
451         free(row_table);
452 }
453
454 int cmodel_bc_to_x(int color_model)
455 {
456         switch(color_model)
457         {
458                 case BC_YUV420P:
459                         return FOURCC_YV12;
460                         break;
461                 case BC_YUV422:
462                         return FOURCC_YUV2;
463                         break;
464         }
465         return -1;
466 }
467
468 void cmodel_to_text(char *string, int cmodel)
469 {
470         switch(cmodel)
471         {
472                 case BC_RGB888:       strcpy(string, "RGB-8 Bit");   break;
473                 case BC_RGBA8888:     strcpy(string, "RGBA-8 Bit");  break;
474                 case BC_RGB161616:    strcpy(string, "RGB-16 Bit");  break;
475                 case BC_RGBA16161616: strcpy(string, "RGBA-16 Bit"); break;
476                 case BC_YUV888:       strcpy(string, "YUV-8 Bit");   break;
477                 case BC_YUVA8888:     strcpy(string, "YUVA-8 Bit");  break;
478                 case BC_YUV161616:    strcpy(string, "YUV-16 Bit");  break;
479                 case BC_YUVA16161616: strcpy(string, "YUVA-16 Bit"); break;
480                 case BC_RGB_FLOAT:    strcpy(string, "RGB-FLOAT");   break;
481                 case BC_RGBA_FLOAT:   strcpy(string, "RGBA-FLOAT");  break;
482                 default: strcpy(string, "RGB-8 Bit"); break;
483         }
484 }
485
486 int cmodel_from_text(const char *text)
487 {
488         if(!strcasecmp(text, "RGB-8 Bit"))   return BC_RGB888;
489         if(!strcasecmp(text, "RGBA-8 Bit"))  return BC_RGBA8888;
490         if(!strcasecmp(text, "RGB-16 Bit"))  return BC_RGB161616;
491         if(!strcasecmp(text, "RGBA-16 Bit")) return BC_RGBA16161616;
492         if(!strcasecmp(text, "RGB-FLOAT"))   return BC_RGB_FLOAT;
493         if(!strcasecmp(text, "RGBA-FLOAT"))  return BC_RGBA_FLOAT;
494         if(!strcasecmp(text, "YUV-8 Bit"))   return BC_YUV888;
495         if(!strcasecmp(text, "YUVA-8 Bit"))  return BC_YUVA8888;
496         if(!strcasecmp(text, "YUV-16 Bit"))  return BC_YUV161616;
497         if(!strcasecmp(text, "YUVA-16 Bit")) return BC_YUVA16161616;
498         return BC_RGB888;
499 }
500
501 int cmodel_has_alpha(int colormodel)
502 {
503         switch(colormodel)
504         {
505                 case BC_YUVA8888:
506                 case BC_RGBA8888:
507                 case BC_RGBA16161616:
508                 case BC_YUVA16161616:
509                 case BC_RGBA_FLOAT:
510                         return 1;
511         }
512         return 0;
513 }
514
515 int cmodel_is_float(int colormodel)
516 {
517         switch(colormodel)
518         {
519                 case BC_RGB_FLOAT:
520                 case BC_RGBA_FLOAT:
521                         return 1;
522         }
523         return 0;
524 }
525
526 int cmodel_is_yuv(int colormodel)
527 {
528         switch(colormodel)
529         {
530                 case BC_YUV888:
531                 case BC_YUVA8888:
532                 case BC_YUV161616:
533                 case BC_YUVA16161616:
534                 case BC_YUV422:
535                 case BC_YUV420P:
536                 case BC_YUV422P:
537                 case BC_YUV444P:
538 //              case BC_YUV411P:
539                         return 1;
540                         break;
541                 
542                 default:
543                         return 0;
544                         break;
545         }
546 }
547
548
549
550
551