00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "colormodels.h"
00021 #include <stdlib.h>
00022 #include <string.h>
00023
00024
00025 cmodel_yuv_t *yuv_table = 0;
00026
00027
00028 #define R_TO_Y 0.29900
00029 #define G_TO_Y 0.58700
00030 #define B_TO_Y 0.11400
00031
00032 #define R_TO_U -0.16874
00033 #define G_TO_U -0.33126
00034 #define B_TO_U 0.50000
00035
00036 #define R_TO_V 0.50000
00037 #define G_TO_V -0.41869
00038 #define B_TO_V -0.08131
00039
00040
00041 #define V_TO_R 1.40200
00042 #define V_TO_G -0.71414
00043
00044 #define U_TO_G -0.34414
00045 #define U_TO_B 1.77200
00046
00047
00048
00049
00050
00051
00052 void cmodel_init_yuv(cmodel_yuv_t *yuv_table)
00053 {
00054 int i;
00055
00056
00057 for(i = 0; i < 0x100; i++)
00058 {
00059 yuv_table->rtoy_tab[i] = (int)(R_TO_Y * 0x10000 * i);
00060 yuv_table->rtou_tab[i] = (int)(R_TO_U * 0x10000 * i);
00061 yuv_table->rtov_tab[i] = (int)(R_TO_V * 0x10000 * i);
00062
00063 yuv_table->gtoy_tab[i] = (int)(G_TO_Y * 0x10000 * i);
00064 yuv_table->gtou_tab[i] = (int)(G_TO_U * 0x10000 * i);
00065 yuv_table->gtov_tab[i] = (int)(G_TO_V * 0x10000 * i);
00066
00067 yuv_table->btoy_tab[i] = (int)(B_TO_Y * 0x10000 * i);
00068 yuv_table->btou_tab[i] = (int)(B_TO_U * 0x10000 * i) + 0x800000;
00069 yuv_table->btov_tab[i] = (int)(B_TO_V * 0x10000 * i) + 0x800000;
00070 }
00071
00072
00073 for(i = 0; i < 0x10000; i++)
00074 {
00075 yuv_table->rtoy_tab16[i] = (int)(R_TO_Y * 0x100 * i);
00076 yuv_table->rtou_tab16[i] = (int)(R_TO_U * 0x100 * i);
00077 yuv_table->rtov_tab16[i] = (int)(R_TO_V * 0x100 * i);
00078
00079 yuv_table->gtoy_tab16[i] = (int)(G_TO_Y * 0x100 * i);
00080 yuv_table->gtou_tab16[i] = (int)(G_TO_U * 0x100 * i);
00081 yuv_table->gtov_tab16[i] = (int)(G_TO_V * 0x100 * i);
00082
00083 yuv_table->btoy_tab16[i] = (int)(B_TO_Y * 0x100 * i);
00084 yuv_table->btou_tab16[i] = (int)(B_TO_U * 0x100 * i) + 0x800000;
00085 yuv_table->btov_tab16[i] = (int)(B_TO_V * 0x100 * i) + 0x800000;
00086 }
00087
00088
00089
00090
00091
00092 yuv_table->vtor = &(yuv_table->vtor_tab[0x80]);
00093 yuv_table->vtog = &(yuv_table->vtog_tab[0x80]);
00094 yuv_table->utog = &(yuv_table->utog_tab[0x80]);
00095 yuv_table->utob = &(yuv_table->utob_tab[0x80]);
00096 yuv_table->vtor8 = &(yuv_table->vtor_tab8[0x80]);
00097 yuv_table->vtog8 = &(yuv_table->vtog_tab8[0x80]);
00098 yuv_table->utog8 = &(yuv_table->utog_tab8[0x80]);
00099 yuv_table->utob8 = &(yuv_table->utob_tab8[0x80]);
00100 for(i = -0x80; i < 0x80; i++)
00101 {
00102 yuv_table->vtor[i] = (int)(V_TO_R * 0x10000 * i);
00103 yuv_table->vtog[i] = (int)(V_TO_G * 0x10000 * i);
00104
00105 yuv_table->utog[i] = (int)(U_TO_G * 0x10000 * i);
00106 yuv_table->utob[i] = (int)(U_TO_B * 0x10000 * i);
00107
00108 yuv_table->vtor8[i] = (int)(V_TO_R * i);
00109 yuv_table->vtog8[i] = (int)(V_TO_G * i);
00110
00111 yuv_table->utog8[i] = (int)(U_TO_G * i);
00112 yuv_table->utob8[i] = (int)(U_TO_B * i);
00113 }
00114
00115
00116
00117 yuv_table->vtor_float = &(yuv_table->vtor_float_tab[0x80]);
00118 yuv_table->vtog_float = &(yuv_table->vtog_float_tab[0x80]);
00119 yuv_table->utog_float = &(yuv_table->utog_float_tab[0x80]);
00120 yuv_table->utob_float = &(yuv_table->utob_float_tab[0x80]);
00121 for(i = -0x80; i < 0x80; i++)
00122 {
00123 yuv_table->vtor_float[i] = V_TO_R * i / 0xff;
00124 yuv_table->vtog_float[i] = V_TO_G * i / 0xff;
00125
00126 yuv_table->utog_float[i] = U_TO_G * i / 0xff;
00127 yuv_table->utob_float[i] = U_TO_B * i / 0xff;
00128 }
00129
00130
00131
00132 yuv_table->vtor16 = &(yuv_table->vtor_tab16[0x8000]);
00133 yuv_table->vtog16 = &(yuv_table->vtog_tab16[0x8000]);
00134 yuv_table->utog16 = &(yuv_table->utog_tab16[0x8000]);
00135 yuv_table->utob16 = &(yuv_table->utob_tab16[0x8000]);
00136 for(i = -0x8000; i < 0x8000; i++)
00137 {
00138 yuv_table->vtor16[i] = (int)(V_TO_R * 0x100 * i);
00139 yuv_table->vtog16[i] = (int)(V_TO_G * 0x100 * i);
00140
00141 yuv_table->utog16[i] = (int)(U_TO_G * 0x100 * i);
00142 yuv_table->utob16[i] = (int)(U_TO_B * 0x100 * i);
00143 }
00144
00145
00146
00147 yuv_table->v16tor_float = &(yuv_table->v16tor_float_tab[0x8000]);
00148 yuv_table->v16tog_float = &(yuv_table->v16tog_float_tab[0x8000]);
00149 yuv_table->u16tog_float = &(yuv_table->u16tog_float_tab[0x8000]);
00150 yuv_table->u16tob_float = &(yuv_table->u16tob_float_tab[0x8000]);
00151 for(i = -0x8000; i < 0x8000; i++)
00152 {
00153 yuv_table->v16tor_float[i] = V_TO_R * i / 0xffff;
00154 yuv_table->v16tog_float[i] = V_TO_G * i / 0xffff;
00155
00156 yuv_table->u16tog_float[i] = U_TO_G * i / 0xffff;
00157 yuv_table->u16tob_float[i] = U_TO_B * i / 0xffff;
00158 }
00159 }
00160
00161
00162 void cmodel_delete_yuv(cmodel_yuv_t *yuv_table)
00163 {
00164 }
00165
00166 int cmodel_is_planar(int colormodel)
00167 {
00168 switch(colormodel)
00169 {
00170 case BC_YUV420P: return 1; break;
00171 case BC_YUV422P: return 1; break;
00172 case BC_YUV444P: return 1; break;
00173 case BC_YUV411P: return 1; break;
00174 }
00175 return 0;
00176 }
00177
00178 int cmodel_components(int colormodel)
00179 {
00180 switch(colormodel)
00181 {
00182 case BC_A8: return 1; break;
00183 case BC_A16: return 1; break;
00184 case BC_A_FLOAT: return 1; break;
00185 case BC_RGB888: return 3; break;
00186 case BC_RGBA8888: return 4; break;
00187 case BC_RGB161616: return 3; break;
00188 case BC_RGBA16161616: return 4; break;
00189 case BC_YUV888: return 3; break;
00190 case BC_YUVA8888: return 4; break;
00191 case BC_YUV161616: return 3; break;
00192 case BC_YUVA16161616: return 4; break;
00193 case BC_YUV101010: return 3; break;
00194 case BC_RGB_FLOAT: return 3; break;
00195 case BC_RGBA_FLOAT: return 4; break;
00196 }
00197 }
00198
00199 int cmodel_calculate_pixelsize(int colormodel)
00200 {
00201 switch(colormodel)
00202 {
00203 case BC_A8: return 1; break;
00204 case BC_A16: return 2; break;
00205 case BC_A_FLOAT: return 4; break;
00206 case BC_TRANSPARENCY: return 1; break;
00207 case BC_COMPRESSED: return 1; break;
00208 case BC_RGB8: return 1; break;
00209 case BC_RGB565: return 2; break;
00210 case BC_BGR565: return 2; break;
00211 case BC_BGR888: return 3; break;
00212 case BC_BGR8888: return 4; break;
00213
00214 case BC_RGB888: return 3; break;
00215 case BC_ARGB8888: return 4; break;
00216 case BC_ABGR8888: return 4; break;
00217 case BC_RGBA8888: return 4; break;
00218 case BC_RGB161616: return 6; break;
00219 case BC_RGBA16161616: return 8; break;
00220 case BC_YUV888: return 3; break;
00221 case BC_YUVA8888: return 4; break;
00222 case BC_YUV161616: return 6; break;
00223 case BC_YUVA16161616: return 8; break;
00224 case BC_YUV101010: return 4; break;
00225 case BC_VYU888: return 3; break;
00226 case BC_UYVA8888: return 4; break;
00227 case BC_RGB_FLOAT: return 12; break;
00228 case BC_RGBA_FLOAT: return 16; break;
00229
00230 case BC_YUV420P: return 1; break;
00231 case BC_YUV422P: return 1; break;
00232 case BC_YUV444P: return 1; break;
00233 case BC_YUV422: return 2; break;
00234 case BC_YUV411P: return 1; break;
00235 case BC_YUV9P: return 1; break;
00236 }
00237 return 0;
00238 }
00239
00240 int cmodel_calculate_max(int colormodel)
00241 {
00242 switch(colormodel)
00243 {
00244
00245 case BC_A8: return 0xff; break;
00246 case BC_A16: return 0xffff; break;
00247 case BC_A_FLOAT: return 1; break;
00248 case BC_RGB888: return 0xff; break;
00249 case BC_RGBA8888: return 0xff; break;
00250 case BC_RGB161616: return 0xffff; break;
00251 case BC_RGBA16161616: return 0xffff; break;
00252 case BC_YUV888: return 0xff; break;
00253 case BC_YUVA8888: return 0xff; break;
00254 case BC_YUV161616: return 0xffff; break;
00255 case BC_YUVA16161616: return 0xffff; break;
00256 case BC_RGB_FLOAT: return 1; break;
00257 case BC_RGBA_FLOAT: return 1; break;
00258 }
00259 return 0;
00260 }
00261
00262 int cmodel_calculate_datasize(int w, int h, int bytes_per_line, int color_model)
00263 {
00264 if(bytes_per_line < 0) bytes_per_line = w *
00265 cmodel_calculate_pixelsize(color_model);
00266 switch(color_model)
00267 {
00268 case BC_YUV420P:
00269 case BC_YUV411P:
00270 return w * h + w * h / 2 + 4;
00271 break;
00272
00273 case BC_YUV422P:
00274 return w * h * 2 + 4;
00275 break;
00276
00277 case BC_YUV444P:
00278 return w * h * 3 + 4;
00279 break;
00280
00281 default:
00282 return h * bytes_per_line + 4;
00283 break;
00284 }
00285 return 0;
00286 }
00287
00288
00289 static void get_scale_tables(int **column_table,
00290 int **row_table,
00291 int in_x1,
00292 int in_y1,
00293 int in_x2,
00294 int in_y2,
00295 int out_x1,
00296 int out_y1,
00297 int out_x2,
00298 int out_y2)
00299 {
00300 int y_out, i;
00301 float w_in = in_x2 - in_x1;
00302 float h_in = in_y2 - in_y1;
00303 int w_out = out_x2 - out_x1;
00304 int h_out = out_y2 - out_y1;
00305
00306 float hscale = w_in / w_out;
00307 float vscale = h_in / h_out;
00308
00309
00310 (*column_table) = malloc(sizeof(int) * (w_out + 1));
00311 (*row_table) = malloc(sizeof(int) * h_out);
00312 for(i = 0; i < w_out; i++)
00313 {
00314 (*column_table)[i] = (int)(hscale * i) + in_x1;
00315 }
00316
00317 for(i = 0; i < h_out; i++)
00318 {
00319 (*row_table)[i] = (int)(vscale * i) + in_y1;
00320
00321 }
00322 }
00323
00324 void cmodel_transfer(unsigned char **output_rows,
00325 unsigned char **input_rows,
00326 unsigned char *out_y_plane,
00327 unsigned char *out_u_plane,
00328 unsigned char *out_v_plane,
00329 unsigned char *in_y_plane,
00330 unsigned char *in_u_plane,
00331 unsigned char *in_v_plane,
00332 int in_x,
00333 int in_y,
00334 int in_w,
00335 int in_h,
00336 int out_x,
00337 int out_y,
00338 int out_w,
00339 int out_h,
00340 int in_colormodel,
00341 int out_colormodel,
00342 int bg_color,
00343 int in_rowspan,
00344 int out_rowspan)
00345 {
00346 int *column_table;
00347 int *row_table;
00348 int scale;
00349 int bg_r, bg_g, bg_b;
00350 int in_pixelsize = cmodel_calculate_pixelsize(in_colormodel);
00351 int out_pixelsize = cmodel_calculate_pixelsize(out_colormodel);
00352
00353 bg_r = (bg_color & 0xff0000) >> 16;
00354 bg_g = (bg_color & 0xff00) >> 8;
00355 bg_b = (bg_color & 0xff);
00356
00357
00358 if(yuv_table == 0)
00359 {
00360 yuv_table = calloc(1, sizeof(cmodel_yuv_t));
00361 cmodel_init_yuv(yuv_table);
00362 }
00363
00364
00365 scale = (out_w != in_w) || (in_x != 0);
00366 get_scale_tables(&column_table, &row_table,
00367 in_x, in_y, in_x + in_w, in_y + in_h,
00368 out_x, out_y, out_x + out_w, out_y + out_h);
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 #define PERMUTATION_VALUES \
00386 output_rows, \
00387 input_rows, \
00388 out_y_plane, \
00389 out_u_plane, \
00390 out_v_plane, \
00391 in_y_plane, \
00392 in_u_plane, \
00393 in_v_plane, \
00394 in_x, \
00395 in_y, \
00396 in_w, \
00397 in_h, \
00398 out_x, \
00399 out_y, \
00400 out_w, \
00401 out_h, \
00402 in_colormodel, \
00403 out_colormodel, \
00404 bg_color, \
00405 in_rowspan, \
00406 out_rowspan, \
00407 scale, \
00408 out_pixelsize, \
00409 in_pixelsize, \
00410 row_table, \
00411 column_table, \
00412 bg_r, \
00413 bg_g, \
00414 bg_b
00415
00416
00417 switch(in_colormodel)
00418 {
00419 case BC_RGB_FLOAT:
00420 case BC_RGBA_FLOAT:
00421 cmodel_float(PERMUTATION_VALUES);
00422 break;
00423
00424 case BC_YUV420P:
00425 case BC_YUV422P:
00426 cmodel_yuv420p(PERMUTATION_VALUES);
00427 break;
00428
00429 case BC_YUV9P:
00430 cmodel_yuv9p(PERMUTATION_VALUES);
00431 break;
00432
00433 case BC_YUV444P:
00434 cmodel_yuv444p(PERMUTATION_VALUES);
00435 break;
00436
00437 case BC_YUV422:
00438 cmodel_yuv422(PERMUTATION_VALUES);
00439 break;
00440
00441 default:
00442 cmodel_default(PERMUTATION_VALUES);
00443 break;
00444 }
00445
00446
00447
00448
00449
00450
00451
00452 free(column_table);
00453 free(row_table);
00454 }
00455
00456 int cmodel_bc_to_x(int color_model)
00457 {
00458 switch(color_model)
00459 {
00460 case BC_YUV420P:
00461 return FOURCC_YV12;
00462 break;
00463 case BC_YUV422:
00464 return FOURCC_YUV2;
00465 break;
00466 }
00467 return -1;
00468 }
00469
00470 void cmodel_to_text(char *string, int cmodel)
00471 {
00472 switch(cmodel)
00473 {
00474 case BC_RGB888: strcpy(string, "RGB-8 Bit"); break;
00475 case BC_RGBA8888: strcpy(string, "RGBA-8 Bit"); break;
00476 case BC_RGB161616: strcpy(string, "RGB-16 Bit"); break;
00477 case BC_RGBA16161616: strcpy(string, "RGBA-16 Bit"); break;
00478 case BC_YUV888: strcpy(string, "YUV-8 Bit"); break;
00479 case BC_YUVA8888: strcpy(string, "YUVA-8 Bit"); break;
00480 case BC_YUV161616: strcpy(string, "YUV-16 Bit"); break;
00481 case BC_YUVA16161616: strcpy(string, "YUVA-16 Bit"); break;
00482 case BC_RGB_FLOAT: strcpy(string, "RGB-FLOAT"); break;
00483 case BC_RGBA_FLOAT: strcpy(string, "RGBA-FLOAT"); break;
00484 default: strcpy(string, "RGB-8 Bit"); break;
00485 }
00486 }
00487
00488 int cmodel_from_text(char *text)
00489 {
00490 if(!strcasecmp(text, "RGB-8 Bit")) return BC_RGB888;
00491 if(!strcasecmp(text, "RGBA-8 Bit")) return BC_RGBA8888;
00492 if(!strcasecmp(text, "RGB-16 Bit")) return BC_RGB161616;
00493 if(!strcasecmp(text, "RGBA-16 Bit")) return BC_RGBA16161616;
00494 if(!strcasecmp(text, "RGB-FLOAT")) return BC_RGB_FLOAT;
00495 if(!strcasecmp(text, "RGBA-FLOAT")) return BC_RGBA_FLOAT;
00496 if(!strcasecmp(text, "YUV-8 Bit")) return BC_YUV888;
00497 if(!strcasecmp(text, "YUVA-8 Bit")) return BC_YUVA8888;
00498 if(!strcasecmp(text, "YUV-16 Bit")) return BC_YUV161616;
00499 if(!strcasecmp(text, "YUVA-16 Bit")) return BC_YUVA16161616;
00500 return BC_RGB888;
00501 }
00502
00503 int cmodel_is_yuv(int colormodel)
00504 {
00505 switch(colormodel)
00506 {
00507 case BC_YUV888:
00508 case BC_YUVA8888:
00509 case BC_YUV161616:
00510 case BC_YUVA16161616:
00511 case BC_YUV422:
00512 case BC_YUV420P:
00513 case BC_YUV422P:
00514 case BC_YUV444P:
00515 case BC_YUV411P:
00516 return 1;
00517 break;
00518
00519 default:
00520 return 0;
00521 break;
00522 }
00523 }
00524
00525 int cmodel_has_alpha(int colormodel)
00526 {
00527 switch(colormodel)
00528 {
00529 case BC_A8:
00530 case BC_A16:
00531 case BC_A_FLOAT:
00532 case BC_RGBA8888:
00533 case BC_RGBA16161616:
00534 case BC_YUVA8888:
00535 case BC_YUVA16161616:
00536 case BC_RGBA_FLOAT:
00537 return 1;
00538 break;
00539
00540 default:
00541 return 0;
00542 break;
00543 }
00544 }
00545
00546
00547
00548