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.
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
20 #include "colormodels.h"
21 #include "cmodel_permutation.h"
26 cmodel_yuv_t *yuv_table = 0;
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
33 #define R_TO_U -0.16874
34 #define G_TO_U -0.33126
35 #define B_TO_U 0.50000
37 #define R_TO_V 0.50000
38 #define G_TO_V -0.41869
39 #define B_TO_V -0.08131
41 // Decompression coefficients straight out of jpeglib
42 #define V_TO_R 1.40200
43 #define V_TO_G -0.71414
45 #define U_TO_G -0.34414
46 #define U_TO_B 1.77200
53 void cmodel_init_yuv(cmodel_yuv_t *yuv_table)
58 for(i = 0; i < 0x100; i++)
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);
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);
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;
74 for(i = 0; i < 0x10000; i++)
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);
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);
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;
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++)
103 yuv_table->vtor[i] = (int)(V_TO_R * 0x10000 * i);
104 yuv_table->vtog[i] = (int)(V_TO_G * 0x10000 * i);
106 yuv_table->utog[i] = (int)(U_TO_G * 0x10000 * i);
107 yuv_table->utob[i] = (int)(U_TO_B * 0x10000 * i);
109 yuv_table->vtor8[i] = (int)(V_TO_R * i);
110 yuv_table->vtog8[i] = (int)(V_TO_G * i);
112 yuv_table->utog8[i] = (int)(U_TO_G * i);
113 yuv_table->utob8[i] = (int)(U_TO_B * i);
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++)
124 yuv_table->vtor_float[i] = V_TO_R * i / 0xff;
125 yuv_table->vtog_float[i] = V_TO_G * i / 0xff;
127 yuv_table->utog_float[i] = U_TO_G * i / 0xff;
128 yuv_table->utob_float[i] = U_TO_B * i / 0xff;
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++)
139 yuv_table->vtor16[i] = (int)(V_TO_R * 0x100 * i);
140 yuv_table->vtog16[i] = (int)(V_TO_G * 0x100 * i);
142 yuv_table->utog16[i] = (int)(U_TO_G * 0x100 * i);
143 yuv_table->utob16[i] = (int)(U_TO_B * 0x100 * i);
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++)
154 yuv_table->v16tor_float[i] = V_TO_R * i / 0xffff;
155 yuv_table->v16tog_float[i] = V_TO_G * i / 0xffff;
157 yuv_table->u16tog_float[i] = U_TO_G * i / 0xffff;
158 yuv_table->u16tob_float[i] = U_TO_B * i / 0xffff;
163 void cmodel_delete_yuv(cmodel_yuv_t *yuv_table)
167 int cmodel_is_planar(int colormodel)
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;
179 int cmodel_components(int colormodel)
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;
195 int cmodel_calculate_pixelsize(int colormodel)
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;
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;
236 int cmodel_calculate_max(int colormodel)
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;
258 int cmodel_calculate_datasize(int w, int h, int bytes_per_line, int color_model)
260 if(bytes_per_line < 0) bytes_per_line = w *
261 cmodel_calculate_pixelsize(color_model);
266 return w * h + w * h / 2 + 4;
270 return w * h * 2 + 4;
274 return w * h * 3 + 4;
278 return h * bytes_per_line + 4;
285 static void get_scale_tables(int **column_table,
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;
302 float hscale = w_in / w_out;
303 float vscale = h_in / h_out;
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++)
310 (*column_table)[i] = (int)(hscale * i) + in_x1;
313 for(i = 0; i < h_out; i++)
315 (*row_table)[i] = (int)(vscale * i) + in_y1;
316 //printf("get_scale_tables %d %d\n", (*row_table)[i], i);
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,
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);
350 bg_r = (bg_color & 0xff0000) >> 16;
351 bg_g = (bg_color & 0xff00) >> 8;
352 bg_b = (bg_color & 0xff);
357 yuv_table = calloc(1, sizeof(cmodel_yuv_t));
358 cmodel_init_yuv(yuv_table);
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);
368 * printf("cmodel_transfer %d %d %d %d,%d %d,%d %d,%d %d,%d\n",
383 #define PERMUTATION_VALUES \
414 // Handle planar cmodels separately
415 switch(in_colormodel)
419 cmodel_float(PERMUTATION_VALUES);
424 cmodel_yuv420p(PERMUTATION_VALUES);
428 cmodel_yuv9p(PERMUTATION_VALUES);
432 cmodel_yuv444p(PERMUTATION_VALUES);
436 cmodel_yuv422(PERMUTATION_VALUES);
440 cmodel_default(PERMUTATION_VALUES);
445 * printf("cmodel_transfer 100 %d %d\n",
454 int cmodel_bc_to_x(int color_model)
468 void cmodel_to_text(char *string, int cmodel)
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;
486 int cmodel_from_text(const char *text)
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;
501 int cmodel_has_alpha(int colormodel)
507 case BC_RGBA16161616:
508 case BC_YUVA16161616:
515 int cmodel_is_float(int colormodel)
526 int cmodel_is_yuv(int colormodel)
533 case BC_YUVA16161616: