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
17 #include "colormodels.h"
21 cmodel_yuv_t
*yuv_table
= 0;
23 // Compression coefficients straight out of jpeglib
24 #define R_TO_Y 0.29900
25 #define G_TO_Y 0.58700
26 #define B_TO_Y 0.11400
28 #define R_TO_U -0.16874
29 #define G_TO_U -0.33126
30 #define B_TO_U 0.50000
32 #define R_TO_V 0.50000
33 #define G_TO_V -0.41869
34 #define B_TO_V -0.08131
36 // Decompression coefficients straight out of jpeglib
37 #define V_TO_R 1.40200
38 #define V_TO_G -0.71414
40 #define U_TO_G -0.34414
41 #define U_TO_B 1.77200
48 void cmodel_init_yuv(cmodel_yuv_t
*yuv_table
)
53 for(i
= 0; i
< 0x100; i
++)
55 yuv_table
->rtoy_tab
[i
] = (int)(R_TO_Y
* 0x10000 * i
);
56 yuv_table
->rtou_tab
[i
] = (int)(R_TO_U
* 0x10000 * i
);
57 yuv_table
->rtov_tab
[i
] = (int)(R_TO_V
* 0x10000 * i
);
59 yuv_table
->gtoy_tab
[i
] = (int)(G_TO_Y
* 0x10000 * i
);
60 yuv_table
->gtou_tab
[i
] = (int)(G_TO_U
* 0x10000 * i
);
61 yuv_table
->gtov_tab
[i
] = (int)(G_TO_V
* 0x10000 * i
);
63 yuv_table
->btoy_tab
[i
] = (int)(B_TO_Y
* 0x10000 * i
);
64 yuv_table
->btou_tab
[i
] = (int)(B_TO_U
* 0x10000 * i
) + 0x800000;
65 yuv_table
->btov_tab
[i
] = (int)(B_TO_V
* 0x10000 * i
) + 0x800000;
69 for(i
= 0; i
< 0x10000; i
++)
71 yuv_table
->rtoy_tab16
[i
] = (int)(R_TO_Y
* 0x100 * i
);
72 yuv_table
->rtou_tab16
[i
] = (int)(R_TO_U
* 0x100 * i
);
73 yuv_table
->rtov_tab16
[i
] = (int)(R_TO_V
* 0x100 * i
);
75 yuv_table
->gtoy_tab16
[i
] = (int)(G_TO_Y
* 0x100 * i
);
76 yuv_table
->gtou_tab16
[i
] = (int)(G_TO_U
* 0x100 * i
);
77 yuv_table
->gtov_tab16
[i
] = (int)(G_TO_V
* 0x100 * i
);
79 yuv_table
->btoy_tab16
[i
] = (int)(B_TO_Y
* 0x100 * i
);
80 yuv_table
->btou_tab16
[i
] = (int)(B_TO_U
* 0x100 * i
) + 0x800000;
81 yuv_table
->btov_tab16
[i
] = (int)(B_TO_V
* 0x100 * i
) + 0x800000;
88 yuv_table
->vtor
= &(yuv_table
->vtor_tab
[0x80]);
89 yuv_table
->vtog
= &(yuv_table
->vtog_tab
[0x80]);
90 yuv_table
->utog
= &(yuv_table
->utog_tab
[0x80]);
91 yuv_table
->utob
= &(yuv_table
->utob_tab
[0x80]);
92 yuv_table
->vtor8
= &(yuv_table
->vtor_tab8
[0x80]);
93 yuv_table
->vtog8
= &(yuv_table
->vtog_tab8
[0x80]);
94 yuv_table
->utog8
= &(yuv_table
->utog_tab8
[0x80]);
95 yuv_table
->utob8
= &(yuv_table
->utob_tab8
[0x80]);
96 for(i
= -0x80; i
< 0x80; i
++)
98 yuv_table
->vtor
[i
] = (int)(V_TO_R
* 0x10000 * i
);
99 yuv_table
->vtog
[i
] = (int)(V_TO_G
* 0x10000 * i
);
101 yuv_table
->utog
[i
] = (int)(U_TO_G
* 0x10000 * i
);
102 yuv_table
->utob
[i
] = (int)(U_TO_B
* 0x10000 * i
);
104 yuv_table
->vtor8
[i
] = (int)(V_TO_R
* i
);
105 yuv_table
->vtog8
[i
] = (int)(V_TO_G
* i
);
107 yuv_table
->utog8
[i
] = (int)(U_TO_G
* i
);
108 yuv_table
->utob8
[i
] = (int)(U_TO_B
* i
);
113 yuv_table
->vtor_float
= &(yuv_table
->vtor_float_tab
[0x80]);
114 yuv_table
->vtog_float
= &(yuv_table
->vtog_float_tab
[0x80]);
115 yuv_table
->utog_float
= &(yuv_table
->utog_float_tab
[0x80]);
116 yuv_table
->utob_float
= &(yuv_table
->utob_float_tab
[0x80]);
117 for(i
= -0x80; i
< 0x80; i
++)
119 yuv_table
->vtor_float
[i
] = V_TO_R
* i
/ 0xff;
120 yuv_table
->vtog_float
[i
] = V_TO_G
* i
/ 0xff;
122 yuv_table
->utog_float
[i
] = U_TO_G
* i
/ 0xff;
123 yuv_table
->utob_float
[i
] = U_TO_B
* i
/ 0xff;
128 yuv_table
->vtor16
= &(yuv_table
->vtor_tab16
[0x8000]);
129 yuv_table
->vtog16
= &(yuv_table
->vtog_tab16
[0x8000]);
130 yuv_table
->utog16
= &(yuv_table
->utog_tab16
[0x8000]);
131 yuv_table
->utob16
= &(yuv_table
->utob_tab16
[0x8000]);
132 for(i
= -0x8000; i
< 0x8000; i
++)
134 yuv_table
->vtor16
[i
] = (int)(V_TO_R
* 0x100 * i
);
135 yuv_table
->vtog16
[i
] = (int)(V_TO_G
* 0x100 * i
);
137 yuv_table
->utog16
[i
] = (int)(U_TO_G
* 0x100 * i
);
138 yuv_table
->utob16
[i
] = (int)(U_TO_B
* 0x100 * i
);
143 yuv_table
->v16tor_float
= &(yuv_table
->v16tor_float_tab
[0x8000]);
144 yuv_table
->v16tog_float
= &(yuv_table
->v16tog_float_tab
[0x8000]);
145 yuv_table
->u16tog_float
= &(yuv_table
->u16tog_float_tab
[0x8000]);
146 yuv_table
->u16tob_float
= &(yuv_table
->u16tob_float_tab
[0x8000]);
147 for(i
= -0x8000; i
< 0x8000; i
++)
149 yuv_table
->v16tor_float
[i
] = V_TO_R
* i
/ 0xffff;
150 yuv_table
->v16tog_float
[i
] = V_TO_G
* i
/ 0xffff;
152 yuv_table
->u16tog_float
[i
] = U_TO_G
* i
/ 0xffff;
153 yuv_table
->u16tob_float
[i
] = U_TO_B
* i
/ 0xffff;
158 void cmodel_delete_yuv(cmodel_yuv_t
*yuv_table
)
162 int cmodel_is_planar(int colormodel
)
166 case BC_YUV420P
: return 1; break;
167 case BC_YUV422P
: return 1; break;
168 case BC_YUV444P
: return 1; break;
169 case BC_YUV411P
: return 1; break;
174 int cmodel_components(int colormodel
)
178 case BC_A8
: return 1; break;
179 case BC_A16
: return 1; break;
180 case BC_A_FLOAT
: return 1; break;
181 case BC_RGB888
: return 3; break;
182 case BC_RGBA8888
: return 4; break;
183 case BC_RGB161616
: return 3; break;
184 case BC_RGBA16161616
: return 4; break;
185 case BC_YUV888
: return 3; break;
186 case BC_YUVA8888
: return 4; break;
187 case BC_YUV161616
: return 3; break;
188 case BC_YUVA16161616
: return 4; break;
189 case BC_YUV101010
: return 3; break;
190 case BC_RGB_FLOAT
: return 3; break;
191 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);
320 void cmodel_transfer(unsigned char **output_rows
,
321 unsigned char **input_rows
,
322 unsigned char *out_y_plane
,
323 unsigned char *out_u_plane
,
324 unsigned char *out_v_plane
,
325 unsigned char *in_y_plane
,
326 unsigned char *in_u_plane
,
327 unsigned char *in_v_plane
,
345 int bg_r
, bg_g
, bg_b
;
346 int in_pixelsize
= cmodel_calculate_pixelsize(in_colormodel
);
347 int out_pixelsize
= cmodel_calculate_pixelsize(out_colormodel
);
349 bg_r
= (bg_color
& 0xff0000) >> 16;
350 bg_g
= (bg_color
& 0xff00) >> 8;
351 bg_b
= (bg_color
& 0xff);
356 yuv_table
= calloc(1, sizeof(cmodel_yuv_t
));
357 cmodel_init_yuv(yuv_table
);
361 scale
= (out_w
!= in_w
) || (in_x
!= 0);
362 get_scale_tables(&column_table
, &row_table
,
363 in_x
, in_y
, in_x
+ in_w
, in_y
+ in_h
,
364 out_x
, out_y
, out_x
+ out_w
, out_y
+ out_h
);
367 * printf("cmodel_transfer 1 %d %d %d,%d %d,%d %d,%d %d,%d\n",
379 // printf("in: %i, out: %i\n", in_colormodel, out_colormodel);
382 #define PERMUTATION_VALUES \
413 // Handle planar cmodels separately
414 switch(in_colormodel
)
418 cmodel_float(PERMUTATION_VALUES
);
423 cmodel_yuv420p(PERMUTATION_VALUES
);
427 cmodel_yuv9p(PERMUTATION_VALUES
);
431 cmodel_yuv444p(PERMUTATION_VALUES
);
435 cmodel_yuv422(PERMUTATION_VALUES
);
439 cmodel_default(PERMUTATION_VALUES
);
444 * printf("cmodel_transfer 100 %d %d\n",
453 int cmodel_bc_to_x(int color_model
)
467 void cmodel_to_text(char *string
, int cmodel
)
471 case BC_RGB888
: strcpy(string
, "RGB-8 Bit"); break;
472 case BC_RGBA8888
: strcpy(string
, "RGBA-8 Bit"); break;
473 case BC_RGB161616
: strcpy(string
, "RGB-16 Bit"); break;
474 case BC_RGBA16161616
: strcpy(string
, "RGBA-16 Bit"); break;
475 case BC_YUV888
: strcpy(string
, "YUV-8 Bit"); break;
476 case BC_YUVA8888
: strcpy(string
, "YUVA-8 Bit"); break;
477 case BC_YUV161616
: strcpy(string
, "YUV-16 Bit"); break;
478 case BC_YUVA16161616
: strcpy(string
, "YUVA-16 Bit"); break;
479 case BC_RGB_FLOAT
: strcpy(string
, "RGB-FLOAT"); break;
480 case BC_RGBA_FLOAT
: strcpy(string
, "RGBA-FLOAT"); break;
481 default: strcpy(string
, "RGB-8 Bit"); break;
485 int cmodel_from_text(char *text
)
487 if(!strcasecmp(text
, "RGB-8 Bit")) return BC_RGB888
;
488 if(!strcasecmp(text
, "RGBA-8 Bit")) return BC_RGBA8888
;
489 if(!strcasecmp(text
, "RGB-16 Bit")) return BC_RGB161616
;
490 if(!strcasecmp(text
, "RGBA-16 Bit")) return BC_RGBA16161616
;
491 if(!strcasecmp(text
, "RGB-FLOAT")) return BC_RGB_FLOAT
;
492 if(!strcasecmp(text
, "RGBA-FLOAT")) return BC_RGBA_FLOAT
;
493 if(!strcasecmp(text
, "YUV-8 Bit")) return BC_YUV888
;
494 if(!strcasecmp(text
, "YUVA-8 Bit")) return BC_YUVA8888
;
495 if(!strcasecmp(text
, "YUV-16 Bit")) return BC_YUV161616
;
496 if(!strcasecmp(text
, "YUVA-16 Bit")) return BC_YUVA16161616
;
500 int cmodel_is_yuv(int colormodel
)
507 case BC_YUVA16161616
: