Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / quicktime / colormodels.c
blob8e39fd4f6d2e8fbdbd7ff407ba4ed1dd5db6e20b
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.
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
20 #include "colormodels.h"
21 #include <stdlib.h>
22 #include <string.h>
25 cmodel_yuv_t *yuv_table = 0;
27 // Compression coefficients straight out of jpeglib
28 #define R_TO_Y 0.29900
29 #define G_TO_Y 0.58700
30 #define B_TO_Y 0.11400
32 #define R_TO_U -0.16874
33 #define G_TO_U -0.33126
34 #define B_TO_U 0.50000
36 #define R_TO_V 0.50000
37 #define G_TO_V -0.41869
38 #define B_TO_V -0.08131
40 // Decompression coefficients straight out of jpeglib
41 #define V_TO_R 1.40200
42 #define V_TO_G -0.71414
44 #define U_TO_G -0.34414
45 #define U_TO_B 1.77200
52 void cmodel_init_yuv(cmodel_yuv_t *yuv_table)
54 int i;
56 /* compression */
57 for(i = 0; i < 0x100; i++)
59 yuv_table->rtoy_tab[i] = (int)(R_TO_Y * 0x10000 * i);
60 yuv_table->rtou_tab[i] = (int)(R_TO_U * 0x10000 * i);
61 yuv_table->rtov_tab[i] = (int)(R_TO_V * 0x10000 * i);
63 yuv_table->gtoy_tab[i] = (int)(G_TO_Y * 0x10000 * i);
64 yuv_table->gtou_tab[i] = (int)(G_TO_U * 0x10000 * i);
65 yuv_table->gtov_tab[i] = (int)(G_TO_V * 0x10000 * i);
67 yuv_table->btoy_tab[i] = (int)(B_TO_Y * 0x10000 * i);
68 yuv_table->btou_tab[i] = (int)(B_TO_U * 0x10000 * i) + 0x800000;
69 yuv_table->btov_tab[i] = (int)(B_TO_V * 0x10000 * i) + 0x800000;
72 /* compression */
73 for(i = 0; i < 0x10000; i++)
75 yuv_table->rtoy_tab16[i] = (int)(R_TO_Y * 0x100 * i);
76 yuv_table->rtou_tab16[i] = (int)(R_TO_U * 0x100 * i);
77 yuv_table->rtov_tab16[i] = (int)(R_TO_V * 0x100 * i);
79 yuv_table->gtoy_tab16[i] = (int)(G_TO_Y * 0x100 * i);
80 yuv_table->gtou_tab16[i] = (int)(G_TO_U * 0x100 * i);
81 yuv_table->gtov_tab16[i] = (int)(G_TO_V * 0x100 * i);
83 yuv_table->btoy_tab16[i] = (int)(B_TO_Y * 0x100 * i);
84 yuv_table->btou_tab16[i] = (int)(B_TO_U * 0x100 * i) + 0x800000;
85 yuv_table->btov_tab16[i] = (int)(B_TO_V * 0x100 * i) + 0x800000;
91 /* decompression */
92 yuv_table->vtor = &(yuv_table->vtor_tab[0x80]);
93 yuv_table->vtog = &(yuv_table->vtog_tab[0x80]);
94 yuv_table->utog = &(yuv_table->utog_tab[0x80]);
95 yuv_table->utob = &(yuv_table->utob_tab[0x80]);
96 yuv_table->vtor8 = &(yuv_table->vtor_tab8[0x80]);
97 yuv_table->vtog8 = &(yuv_table->vtog_tab8[0x80]);
98 yuv_table->utog8 = &(yuv_table->utog_tab8[0x80]);
99 yuv_table->utob8 = &(yuv_table->utob_tab8[0x80]);
100 for(i = -0x80; i < 0x80; i++)
102 yuv_table->vtor[i] = (int)(V_TO_R * 0x10000 * i);
103 yuv_table->vtog[i] = (int)(V_TO_G * 0x10000 * i);
105 yuv_table->utog[i] = (int)(U_TO_G * 0x10000 * i);
106 yuv_table->utob[i] = (int)(U_TO_B * 0x10000 * i);
108 yuv_table->vtor8[i] = (int)(V_TO_R * i);
109 yuv_table->vtog8[i] = (int)(V_TO_G * i);
111 yuv_table->utog8[i] = (int)(U_TO_G * i);
112 yuv_table->utob8[i] = (int)(U_TO_B * i);
116 /* decompression */
117 yuv_table->vtor_float = &(yuv_table->vtor_float_tab[0x80]);
118 yuv_table->vtog_float = &(yuv_table->vtog_float_tab[0x80]);
119 yuv_table->utog_float = &(yuv_table->utog_float_tab[0x80]);
120 yuv_table->utob_float = &(yuv_table->utob_float_tab[0x80]);
121 for(i = -0x80; i < 0x80; i++)
123 yuv_table->vtor_float[i] = V_TO_R * i / 0xff;
124 yuv_table->vtog_float[i] = V_TO_G * i / 0xff;
126 yuv_table->utog_float[i] = U_TO_G * i / 0xff;
127 yuv_table->utob_float[i] = U_TO_B * i / 0xff;
131 /* decompression */
132 yuv_table->vtor16 = &(yuv_table->vtor_tab16[0x8000]);
133 yuv_table->vtog16 = &(yuv_table->vtog_tab16[0x8000]);
134 yuv_table->utog16 = &(yuv_table->utog_tab16[0x8000]);
135 yuv_table->utob16 = &(yuv_table->utob_tab16[0x8000]);
136 for(i = -0x8000; i < 0x8000; i++)
138 yuv_table->vtor16[i] = (int)(V_TO_R * 0x100 * i);
139 yuv_table->vtog16[i] = (int)(V_TO_G * 0x100 * i);
141 yuv_table->utog16[i] = (int)(U_TO_G * 0x100 * i);
142 yuv_table->utob16[i] = (int)(U_TO_B * 0x100 * i);
146 /* decompression */
147 yuv_table->v16tor_float = &(yuv_table->v16tor_float_tab[0x8000]);
148 yuv_table->v16tog_float = &(yuv_table->v16tog_float_tab[0x8000]);
149 yuv_table->u16tog_float = &(yuv_table->u16tog_float_tab[0x8000]);
150 yuv_table->u16tob_float = &(yuv_table->u16tob_float_tab[0x8000]);
151 for(i = -0x8000; i < 0x8000; i++)
153 yuv_table->v16tor_float[i] = V_TO_R * i / 0xffff;
154 yuv_table->v16tog_float[i] = V_TO_G * i / 0xffff;
156 yuv_table->u16tog_float[i] = U_TO_G * i / 0xffff;
157 yuv_table->u16tob_float[i] = U_TO_B * i / 0xffff;
162 void cmodel_delete_yuv(cmodel_yuv_t *yuv_table)
166 int cmodel_is_planar(int colormodel)
168 switch(colormodel)
170 case BC_YUV420P: return 1; break;
171 case BC_YUV422P: return 1; break;
172 case BC_YUV444P: return 1; break;
173 case BC_YUV411P: return 1; break;
175 return 0;
178 int cmodel_components(int colormodel)
180 switch(colormodel)
182 case BC_A8: return 1; break;
183 case BC_A16: return 1; break;
184 case BC_A_FLOAT: return 1; break;
185 case BC_RGB888: return 3; break;
186 case BC_RGBA8888: return 4; break;
187 case BC_RGB161616: return 3; break;
188 case BC_RGBA16161616: return 4; break;
189 case BC_YUV888: return 3; break;
190 case BC_YUVA8888: return 4; break;
191 case BC_YUV161616: return 3; break;
192 case BC_YUVA16161616: return 4; break;
193 case BC_YUV101010: return 3; break;
194 case BC_RGB_FLOAT: return 3; break;
195 case BC_RGBA_FLOAT: return 4; break;
199 int cmodel_calculate_pixelsize(int colormodel)
201 switch(colormodel)
203 case BC_A8: return 1; break;
204 case BC_A16: return 2; break;
205 case BC_A_FLOAT: return 4; break;
206 case BC_TRANSPARENCY: return 1; break;
207 case BC_COMPRESSED: return 1; break;
208 case BC_RGB8: return 1; break;
209 case BC_RGB565: return 2; break;
210 case BC_BGR565: return 2; break;
211 case BC_BGR888: return 3; break;
212 case BC_BGR8888: return 4; break;
213 // Working bitmaps are packed to simplify processing
214 case BC_RGB888: return 3; break;
215 case BC_ARGB8888: return 4; break;
216 case BC_ABGR8888: return 4; break;
217 case BC_RGBA8888: return 4; break;
218 case BC_RGB161616: return 6; break;
219 case BC_RGBA16161616: return 8; break;
220 case BC_YUV888: return 3; break;
221 case BC_YUVA8888: return 4; break;
222 case BC_YUV161616: return 6; break;
223 case BC_YUVA16161616: return 8; break;
224 case BC_YUV101010: return 4; break;
225 case BC_VYU888: return 3; break;
226 case BC_UYVA8888: return 4; break;
227 case BC_RGB_FLOAT: return 12; break;
228 case BC_RGBA_FLOAT: return 16; break;
229 // Planar
230 case BC_YUV420P: return 1; break;
231 case BC_YUV422P: return 1; break;
232 case BC_YUV444P: return 1; break;
233 case BC_YUV422: return 2; break;
234 case BC_YUV411P: return 1; break;
235 case BC_YUV9P: return 1; break;
237 return 0;
240 int cmodel_calculate_max(int colormodel)
242 switch(colormodel)
244 // Working bitmaps are packed to simplify processing
245 case BC_A8: return 0xff; break;
246 case BC_A16: return 0xffff; break;
247 case BC_A_FLOAT: return 1; break;
248 case BC_RGB888: return 0xff; break;
249 case BC_RGBA8888: return 0xff; break;
250 case BC_RGB161616: return 0xffff; break;
251 case BC_RGBA16161616: return 0xffff; break;
252 case BC_YUV888: return 0xff; break;
253 case BC_YUVA8888: return 0xff; break;
254 case BC_YUV161616: return 0xffff; break;
255 case BC_YUVA16161616: return 0xffff; break;
256 case BC_RGB_FLOAT: return 1; break;
257 case BC_RGBA_FLOAT: return 1; break;
259 return 0;
262 int cmodel_calculate_datasize(int w, int h, int bytes_per_line, int color_model)
264 if(bytes_per_line < 0) bytes_per_line = w *
265 cmodel_calculate_pixelsize(color_model);
266 switch(color_model)
268 case BC_YUV420P:
269 case BC_YUV411P:
270 return w * h + w * h / 2 + 4;
271 break;
273 case BC_YUV422P:
274 return w * h * 2 + 4;
275 break;
277 case BC_YUV444P:
278 return w * h * 3 + 4;
279 break;
281 default:
282 return h * bytes_per_line + 4;
283 break;
285 return 0;
289 static void get_scale_tables(int **column_table,
290 int **row_table,
291 int in_x1,
292 int in_y1,
293 int in_x2,
294 int in_y2,
295 int out_x1,
296 int out_y1,
297 int out_x2,
298 int out_y2)
300 int y_out, i;
301 float w_in = in_x2 - in_x1;
302 float h_in = in_y2 - in_y1;
303 int w_out = out_x2 - out_x1;
304 int h_out = out_y2 - out_y1;
306 float hscale = w_in / w_out;
307 float vscale = h_in / h_out;
309 /* + 1 so we don't overflow when calculating in advance */
310 (*column_table) = malloc(sizeof(int) * (w_out + 1));
311 (*row_table) = malloc(sizeof(int) * h_out);
312 for(i = 0; i < w_out; i++)
314 (*column_table)[i] = (int)(hscale * i) + in_x1;
317 for(i = 0; i < h_out; i++)
319 (*row_table)[i] = (int)(vscale * i) + in_y1;
320 //printf("get_scale_tables %d %d\n", (*row_table)[i], i);
324 void cmodel_transfer(unsigned char **output_rows,
325 unsigned char **input_rows,
326 unsigned char *out_y_plane,
327 unsigned char *out_u_plane,
328 unsigned char *out_v_plane,
329 unsigned char *in_y_plane,
330 unsigned char *in_u_plane,
331 unsigned char *in_v_plane,
332 int in_x,
333 int in_y,
334 int in_w,
335 int in_h,
336 int out_x,
337 int out_y,
338 int out_w,
339 int out_h,
340 int in_colormodel,
341 int out_colormodel,
342 int bg_color,
343 int in_rowspan,
344 int out_rowspan)
346 int *column_table;
347 int *row_table;
348 int scale;
349 int bg_r, bg_g, bg_b;
350 int in_pixelsize = cmodel_calculate_pixelsize(in_colormodel);
351 int out_pixelsize = cmodel_calculate_pixelsize(out_colormodel);
353 bg_r = (bg_color & 0xff0000) >> 16;
354 bg_g = (bg_color & 0xff00) >> 8;
355 bg_b = (bg_color & 0xff);
357 // Initialize tables
358 if(yuv_table == 0)
360 yuv_table = calloc(1, sizeof(cmodel_yuv_t));
361 cmodel_init_yuv(yuv_table);
364 // Get scaling
365 scale = (out_w != in_w) || (in_x != 0);
366 get_scale_tables(&column_table, &row_table,
367 in_x, in_y, in_x + in_w, in_y + in_h,
368 out_x, out_y, out_x + out_w, out_y + out_h);
371 * printf("cmodel_transfer 1 %d %d %d,%d %d,%d %d,%d %d,%d\n",
372 * in_colormodel,
373 * out_colormodel,
374 * out_x,
375 * out_y,
376 * out_w,
377 * out_h,
378 * in_x,
379 * in_y,
380 * in_w,
381 * in_h);
385 #define PERMUTATION_VALUES \
386 output_rows, \
387 input_rows, \
388 out_y_plane, \
389 out_u_plane, \
390 out_v_plane, \
391 in_y_plane, \
392 in_u_plane, \
393 in_v_plane, \
394 in_x, \
395 in_y, \
396 in_w, \
397 in_h, \
398 out_x, \
399 out_y, \
400 out_w, \
401 out_h, \
402 in_colormodel, \
403 out_colormodel, \
404 bg_color, \
405 in_rowspan, \
406 out_rowspan, \
407 scale, \
408 out_pixelsize, \
409 in_pixelsize, \
410 row_table, \
411 column_table, \
412 bg_r, \
413 bg_g, \
414 bg_b
416 // Handle planar cmodels separately
417 switch(in_colormodel)
419 case BC_RGB_FLOAT:
420 case BC_RGBA_FLOAT:
421 cmodel_float(PERMUTATION_VALUES);
422 break;
424 case BC_YUV420P:
425 case BC_YUV422P:
426 cmodel_yuv420p(PERMUTATION_VALUES);
427 break;
429 case BC_YUV9P:
430 cmodel_yuv9p(PERMUTATION_VALUES);
431 break;
433 case BC_YUV444P:
434 cmodel_yuv444p(PERMUTATION_VALUES);
435 break;
437 case BC_YUV422:
438 cmodel_yuv422(PERMUTATION_VALUES);
439 break;
441 default:
442 cmodel_default(PERMUTATION_VALUES);
443 break;
447 * printf("cmodel_transfer 100 %d %d\n",
448 * in_colormodel,
449 * out_colormodel);
452 free(column_table);
453 free(row_table);
456 int cmodel_bc_to_x(int color_model)
458 switch(color_model)
460 case BC_YUV420P:
461 return FOURCC_YV12;
462 break;
463 case BC_YUV422:
464 return FOURCC_YUV2;
465 break;
467 return -1;
470 void cmodel_to_text(char *string, int cmodel)
472 switch(cmodel)
474 case BC_RGB888: strcpy(string, "RGB-8 Bit"); break;
475 case BC_RGBA8888: strcpy(string, "RGBA-8 Bit"); break;
476 case BC_RGB161616: strcpy(string, "RGB-16 Bit"); break;
477 case BC_RGBA16161616: strcpy(string, "RGBA-16 Bit"); break;
478 case BC_YUV888: strcpy(string, "YUV-8 Bit"); break;
479 case BC_YUVA8888: strcpy(string, "YUVA-8 Bit"); break;
480 case BC_YUV161616: strcpy(string, "YUV-16 Bit"); break;
481 case BC_YUVA16161616: strcpy(string, "YUVA-16 Bit"); break;
482 case BC_RGB_FLOAT: strcpy(string, "RGB-FLOAT"); break;
483 case BC_RGBA_FLOAT: strcpy(string, "RGBA-FLOAT"); break;
484 default: strcpy(string, "RGB-8 Bit"); break;
488 int cmodel_from_text(char *text)
490 if(!strcasecmp(text, "RGB-8 Bit")) return BC_RGB888;
491 if(!strcasecmp(text, "RGBA-8 Bit")) return BC_RGBA8888;
492 if(!strcasecmp(text, "RGB-16 Bit")) return BC_RGB161616;
493 if(!strcasecmp(text, "RGBA-16 Bit")) return BC_RGBA16161616;
494 if(!strcasecmp(text, "RGB-FLOAT")) return BC_RGB_FLOAT;
495 if(!strcasecmp(text, "RGBA-FLOAT")) return BC_RGBA_FLOAT;
496 if(!strcasecmp(text, "YUV-8 Bit")) return BC_YUV888;
497 if(!strcasecmp(text, "YUVA-8 Bit")) return BC_YUVA8888;
498 if(!strcasecmp(text, "YUV-16 Bit")) return BC_YUV161616;
499 if(!strcasecmp(text, "YUVA-16 Bit")) return BC_YUVA16161616;
500 return BC_RGB888;
503 int cmodel_is_yuv(int colormodel)
505 switch(colormodel)
507 case BC_YUV888:
508 case BC_YUVA8888:
509 case BC_YUV161616:
510 case BC_YUVA16161616:
511 case BC_YUV422:
512 case BC_YUV420P:
513 case BC_YUV422P:
514 case BC_YUV444P:
515 case BC_YUV411P:
516 return 1;
517 break;
519 default:
520 return 0;
521 break;
525 int cmodel_has_alpha(int colormodel)
527 switch(colormodel)
529 case BC_A8:
530 case BC_A16:
531 case BC_A_FLOAT:
532 case BC_RGBA8888:
533 case BC_RGBA16161616:
534 case BC_YUVA8888:
535 case BC_YUVA16161616:
536 case BC_RGBA_FLOAT:
537 return 1;
538 break;
540 default:
541 return 0;
542 break;