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"
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
)
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;
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;
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
);
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;
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
);
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
)
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;
178 int cmodel_components(int 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
)
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;
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;
240 int cmodel_calculate_max(int 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;
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
);
270 return w
* h
+ w
* h
/ 2 + 4;
274 return w
* h
* 2 + 4;
278 return w
* h
* 3 + 4;
282 return h
* bytes_per_line
+ 4;
289 static void get_scale_tables(int **column_table
,
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
,
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);
360 yuv_table
= calloc(1, sizeof(cmodel_yuv_t
));
361 cmodel_init_yuv(yuv_table
);
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",
385 #define PERMUTATION_VALUES \
416 // Handle planar cmodels separately
417 switch(in_colormodel
)
421 cmodel_float(PERMUTATION_VALUES
);
426 cmodel_yuv420p(PERMUTATION_VALUES
);
430 cmodel_yuv9p(PERMUTATION_VALUES
);
434 cmodel_yuv444p(PERMUTATION_VALUES
);
438 cmodel_yuv422(PERMUTATION_VALUES
);
442 cmodel_default(PERMUTATION_VALUES
);
447 * printf("cmodel_transfer 100 %d %d\n",
456 int cmodel_bc_to_x(int color_model
)
470 void cmodel_to_text(char *string
, int 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
;
503 int cmodel_is_yuv(int colormodel
)
510 case BC_YUVA16161616
:
525 int cmodel_has_alpha(int colormodel
)
533 case BC_RGBA16161616
:
535 case BC_YUVA16161616
: