Mercurial > libavcodec.hg
comparison imgconvert.c @ 1202:8b49a7ee4e4e libavcodec
YUV formats/gray formats are correctly defined - added format loss information - preliminary JPEG YUV formats support
| author | bellard |
|---|---|
| date | Sun, 20 Apr 2003 16:18:44 +0000 |
| parents | 6b566c5d02e4 |
| children | 80c73b9b0ba2 |
comparison
equal
deleted
inserted
replaced
| 1201:e0fc95a6eb4e | 1202:8b49a7ee4e4e |
|---|---|
| 32 | 32 |
| 33 #ifdef HAVE_MMX | 33 #ifdef HAVE_MMX |
| 34 #include "i386/mmx.h" | 34 #include "i386/mmx.h" |
| 35 #endif | 35 #endif |
| 36 | 36 |
| 37 #define FF_COLOR_RGB 0 /* RGB color space */ | |
| 38 #define FF_COLOR_GRAY 1 /* gray color space */ | |
| 39 #define FF_COLOR_YUV 2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ | |
| 40 #define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ | |
| 41 | |
| 37 typedef struct PixFmtInfo { | 42 typedef struct PixFmtInfo { |
| 38 const char *name; | 43 const char *name; |
| 39 uint8_t nb_components; /* number of components in AVPicture array */ | 44 uint8_t nb_components; /* number of components in AVPicture array */ |
| 40 uint8_t is_yuv : 1; /* true if YUV instead of RGB color space */ | 45 uint8_t color_type; /* color type (see FF_COLOR_xxx constants) */ |
| 41 uint8_t is_packed : 1; /* true if multiple components in same word */ | 46 uint8_t is_packed : 1; /* true if multiple components in same word */ |
| 42 uint8_t is_paletted : 1; /* true if paletted */ | 47 uint8_t is_paletted : 1; /* true if paletted */ |
| 43 uint8_t is_alpha : 1; /* true if alpha can be specified */ | 48 uint8_t is_alpha : 1; /* true if alpha can be specified */ |
| 44 uint8_t is_gray : 1; /* true if gray or monochrome format */ | |
| 45 uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */ | 49 uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */ |
| 46 uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */ | 50 uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */ |
| 51 uint8_t depth; /* bit depth of the color components */ | |
| 47 } PixFmtInfo; | 52 } PixFmtInfo; |
| 48 | 53 |
| 49 /* this table gives more information about formats */ | 54 /* this table gives more information about formats */ |
| 50 static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { | 55 static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { |
| 51 /* YUV formats */ | 56 /* YUV formats */ |
| 52 [PIX_FMT_YUV420P] = { | 57 [PIX_FMT_YUV420P] = { |
| 53 .name = "yuv420p", | 58 .name = "yuv420p", |
| 54 .nb_components = 3, .is_yuv = 1, | 59 .nb_components = 3, |
| 60 .color_type = FF_COLOR_YUV, | |
| 61 .depth = 8, | |
| 55 .x_chroma_shift = 1, .y_chroma_shift = 1, | 62 .x_chroma_shift = 1, .y_chroma_shift = 1, |
| 56 }, | 63 }, |
| 57 [PIX_FMT_YUV422P] = { | 64 [PIX_FMT_YUV422P] = { |
| 58 .name = "yuv422p", | 65 .name = "yuv422p", |
| 59 .nb_components = 3, .is_yuv = 1, | 66 .nb_components = 3, |
| 67 .color_type = FF_COLOR_YUV, | |
| 68 .depth = 8, | |
| 60 .x_chroma_shift = 1, .y_chroma_shift = 0, | 69 .x_chroma_shift = 1, .y_chroma_shift = 0, |
| 61 }, | 70 }, |
| 62 [PIX_FMT_YUV444P] = { | 71 [PIX_FMT_YUV444P] = { |
| 63 .name = "yuv444p", | 72 .name = "yuv444p", |
| 64 .nb_components = 3, .is_yuv = 1, | 73 .nb_components = 3, |
| 74 .color_type = FF_COLOR_YUV, | |
| 75 .depth = 8, | |
| 65 .x_chroma_shift = 0, .y_chroma_shift = 0, | 76 .x_chroma_shift = 0, .y_chroma_shift = 0, |
| 66 }, | 77 }, |
| 67 [PIX_FMT_YUV422] = { | 78 [PIX_FMT_YUV422] = { |
| 68 .name = "yuv422", | 79 .name = "yuv422", |
| 69 .nb_components = 1, .is_yuv = 1, .is_packed = 1, | 80 .nb_components = 1, .is_packed = 1, |
| 81 .color_type = FF_COLOR_YUV, | |
| 82 .depth = 8, | |
| 70 .x_chroma_shift = 1, .y_chroma_shift = 0, | 83 .x_chroma_shift = 1, .y_chroma_shift = 0, |
| 71 }, | 84 }, |
| 72 [PIX_FMT_YUV410P] = { | 85 [PIX_FMT_YUV410P] = { |
| 73 .name = "yuv410p", | 86 .name = "yuv410p", |
| 74 .nb_components = 3, .is_yuv = 1, | 87 .nb_components = 3, |
| 88 .color_type = FF_COLOR_YUV, | |
| 89 .depth = 8, | |
| 75 .x_chroma_shift = 2, .y_chroma_shift = 2, | 90 .x_chroma_shift = 2, .y_chroma_shift = 2, |
| 76 }, | 91 }, |
| 77 [PIX_FMT_YUV411P] = { | 92 [PIX_FMT_YUV411P] = { |
| 78 .name = "yuv411p", | 93 .name = "yuv411p", |
| 79 .nb_components = 3, .is_yuv = 1, | 94 .nb_components = 3, |
| 95 .color_type = FF_COLOR_YUV, | |
| 96 .depth = 8, | |
| 80 .x_chroma_shift = 2, .y_chroma_shift = 0, | 97 .x_chroma_shift = 2, .y_chroma_shift = 0, |
| 98 }, | |
| 99 | |
| 100 /* JPEG YUV */ | |
| 101 [PIX_FMT_YUVJ420P] = { | |
| 102 .name = "yuvj420p", | |
| 103 .nb_components = 3, | |
| 104 .color_type = FF_COLOR_YUV_JPEG, | |
| 105 .depth = 8, | |
| 106 .x_chroma_shift = 1, .y_chroma_shift = 1, | |
| 107 }, | |
| 108 [PIX_FMT_YUVJ422P] = { | |
| 109 .name = "yuvj422p", | |
| 110 .nb_components = 3, | |
| 111 .color_type = FF_COLOR_YUV_JPEG, | |
| 112 .depth = 8, | |
| 113 .x_chroma_shift = 1, .y_chroma_shift = 0, | |
| 114 }, | |
| 115 [PIX_FMT_YUVJ444P] = { | |
| 116 .name = "yuvj444p", | |
| 117 .nb_components = 3, | |
| 118 .color_type = FF_COLOR_YUV_JPEG, | |
| 119 .depth = 8, | |
| 120 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 81 }, | 121 }, |
| 82 | 122 |
| 83 /* RGB formats */ | 123 /* RGB formats */ |
| 84 [PIX_FMT_RGB24] = { | 124 [PIX_FMT_RGB24] = { |
| 85 .name = "rgb24", | 125 .name = "rgb24", |
| 86 .nb_components = 1, .is_packed = 1, | 126 .nb_components = 1, .is_packed = 1, |
| 127 .color_type = FF_COLOR_RGB, | |
| 128 .depth = 8, | |
| 87 }, | 129 }, |
| 88 [PIX_FMT_BGR24] = { | 130 [PIX_FMT_BGR24] = { |
| 89 .name = "bgr24", | 131 .name = "bgr24", |
| 90 .nb_components = 1, .is_packed = 1, | 132 .nb_components = 1, .is_packed = 1, |
| 133 .color_type = FF_COLOR_RGB, | |
| 134 .depth = 8, | |
| 91 }, | 135 }, |
| 92 [PIX_FMT_RGBA32] = { | 136 [PIX_FMT_RGBA32] = { |
| 93 .name = "rgba32", | 137 .name = "rgba32", |
| 94 .nb_components = 1, .is_packed = 1, .is_alpha = 1, | 138 .nb_components = 1, .is_packed = 1, .is_alpha = 1, |
| 139 .color_type = FF_COLOR_RGB, | |
| 140 .depth = 8, | |
| 95 }, | 141 }, |
| 96 [PIX_FMT_RGB565] = { | 142 [PIX_FMT_RGB565] = { |
| 97 .name = "rgb565", | 143 .name = "rgb565", |
| 98 .nb_components = 1, .is_packed = 1, | 144 .nb_components = 1, .is_packed = 1, |
| 145 .color_type = FF_COLOR_RGB, | |
| 146 .depth = 5, | |
| 99 }, | 147 }, |
| 100 [PIX_FMT_RGB555] = { | 148 [PIX_FMT_RGB555] = { |
| 101 .name = "rgb555", | 149 .name = "rgb555", |
| 102 .nb_components = 1, .is_packed = 1, .is_alpha = 1, | 150 .nb_components = 1, .is_packed = 1, .is_alpha = 1, |
| 151 .color_type = FF_COLOR_RGB, | |
| 152 .depth = 5, | |
| 103 }, | 153 }, |
| 104 | 154 |
| 105 /* gray / mono formats */ | 155 /* gray / mono formats */ |
| 106 [PIX_FMT_GRAY8] = { | 156 [PIX_FMT_GRAY8] = { |
| 107 .name = "gray", | 157 .name = "gray", |
| 108 .nb_components = 1, .is_gray = 1, | 158 .nb_components = 1, |
| 159 .color_type = FF_COLOR_GRAY, | |
| 160 .depth = 8, | |
| 109 }, | 161 }, |
| 110 [PIX_FMT_MONOWHITE] = { | 162 [PIX_FMT_MONOWHITE] = { |
| 111 .name = "monow", | 163 .name = "monow", |
| 112 .nb_components = 1, .is_packed = 1, .is_gray = 1, | 164 .nb_components = 1, |
| 165 .color_type = FF_COLOR_GRAY, | |
| 166 .depth = 1, | |
| 113 }, | 167 }, |
| 114 [PIX_FMT_MONOBLACK] = { | 168 [PIX_FMT_MONOBLACK] = { |
| 115 .name = "monob", | 169 .name = "monob", |
| 116 .nb_components = 1, .is_packed = 1, .is_gray = 1, | 170 .nb_components = 1, |
| 171 .color_type = FF_COLOR_GRAY, | |
| 172 .depth = 1, | |
| 117 }, | 173 }, |
| 118 | 174 |
| 119 /* paletted formats */ | 175 /* paletted formats */ |
| 120 [PIX_FMT_PAL8] = { | 176 [PIX_FMT_PAL8] = { |
| 121 .name = "pal8", | 177 .name = "pal8", |
| 122 .nb_components = 1, .is_packed = 1, .is_alpha = 1, .is_paletted = 1, | 178 .nb_components = 1, .is_packed = 1, .is_alpha = 1, .is_paletted = 1, |
| 179 .color_type = FF_COLOR_RGB, | |
| 180 .depth = 8, | |
| 123 }, | 181 }, |
| 124 }; | 182 }; |
| 125 | 183 |
| 126 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift) | 184 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift) |
| 127 { | 185 { |
| 128 if (pix_fmt_info[pix_fmt].is_yuv) { | 186 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift; |
| 129 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift; | 187 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift; |
| 130 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift; | |
| 131 } else { | |
| 132 *h_shift=0; | |
| 133 *v_shift=0; | |
| 134 } | |
| 135 } | 188 } |
| 136 | 189 |
| 137 const char *avcodec_get_pix_fmt_name(int pix_fmt) | 190 const char *avcodec_get_pix_fmt_name(int pix_fmt) |
| 138 { | 191 { |
| 139 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) | 192 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) |
| 222 { | 275 { |
| 223 AVPicture dummy_pict; | 276 AVPicture dummy_pict; |
| 224 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); | 277 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); |
| 225 } | 278 } |
| 226 | 279 |
| 280 /** | |
| 281 * compute the loss when converting from a pixel format to another | |
| 282 */ | |
| 283 int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, | |
| 284 int has_alpha) | |
| 285 { | |
| 286 const PixFmtInfo *pf, *ps; | |
| 287 int loss; | |
| 288 | |
| 289 ps = &pix_fmt_info[src_pix_fmt]; | |
| 290 pf = &pix_fmt_info[dst_pix_fmt]; | |
| 291 | |
| 292 /* compute loss */ | |
| 293 loss = 0; | |
| 294 pf = &pix_fmt_info[dst_pix_fmt]; | |
| 295 if (pf->depth < ps->depth) | |
| 296 loss |= FF_LOSS_DEPTH; | |
| 297 if (pf->x_chroma_shift >= ps->x_chroma_shift || | |
| 298 pf->y_chroma_shift >= ps->y_chroma_shift) | |
| 299 loss |= FF_LOSS_RESOLUTION; | |
| 300 switch(pf->color_type) { | |
| 301 case FF_COLOR_RGB: | |
| 302 if (ps->color_type != FF_COLOR_RGB && | |
| 303 ps->color_type != FF_COLOR_GRAY) | |
| 304 loss |= FF_LOSS_COLORSPACE; | |
| 305 break; | |
| 306 case FF_COLOR_GRAY: | |
| 307 if (ps->color_type != FF_COLOR_GRAY) | |
| 308 loss |= FF_LOSS_COLORSPACE; | |
| 309 break; | |
| 310 case FF_COLOR_YUV: | |
| 311 if (ps->color_type != FF_COLOR_YUV) | |
| 312 loss |= FF_LOSS_COLORSPACE; | |
| 313 break; | |
| 314 case FF_COLOR_YUV_JPEG: | |
| 315 if (ps->color_type != FF_COLOR_YUV_JPEG && | |
| 316 ps->color_type != FF_COLOR_YUV) | |
| 317 loss |= FF_LOSS_COLORSPACE; | |
| 318 break; | |
| 319 default: | |
| 320 /* fail safe test */ | |
| 321 if (ps->color_type != pf->color_type) | |
| 322 loss |= FF_LOSS_COLORSPACE; | |
| 323 break; | |
| 324 } | |
| 325 if (pf->color_type == FF_COLOR_GRAY && | |
| 326 ps->color_type != FF_COLOR_GRAY) | |
| 327 loss |= FF_LOSS_CHROMA; | |
| 328 if (!pf->is_alpha && (ps->is_alpha && has_alpha)) | |
| 329 loss |= FF_LOSS_ALPHA; | |
| 330 if (pf->is_paletted && (!ps->is_paletted && ps->color_type != FF_COLOR_GRAY)) | |
| 331 loss |= FF_LOSS_COLORQUANT; | |
| 332 return loss; | |
| 333 } | |
| 334 | |
| 335 static int avg_bits_per_pixel(int pix_fmt) | |
| 336 { | |
| 337 int bits; | |
| 338 const PixFmtInfo *pf; | |
| 339 | |
| 340 pf = &pix_fmt_info[pix_fmt]; | |
| 341 if (pf->is_packed) { | |
| 342 switch(pix_fmt) { | |
| 343 case PIX_FMT_RGB24: | |
| 344 case PIX_FMT_BGR24: | |
| 345 bits = 24; | |
| 346 break; | |
| 347 case PIX_FMT_RGBA32: | |
| 348 bits = 32; | |
| 349 break; | |
| 350 case PIX_FMT_RGB565: | |
| 351 case PIX_FMT_RGB555: | |
| 352 bits = 16; | |
| 353 break; | |
| 354 case PIX_FMT_PAL8: | |
| 355 bits = 8; | |
| 356 break; | |
| 357 default: | |
| 358 bits = 32; | |
| 359 break; | |
| 360 } | |
| 361 } else { | |
| 362 bits = pf->depth; | |
| 363 bits += (2 * pf->depth >> | |
| 364 (pf->x_chroma_shift + pf->x_chroma_shift)); | |
| 365 } | |
| 366 return bits; | |
| 367 } | |
| 368 | |
| 369 static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, | |
| 370 int src_pix_fmt, | |
| 371 int has_alpha, | |
| 372 int loss_mask) | |
| 373 { | |
| 374 int dist, i, loss, min_dist, dst_pix_fmt; | |
| 375 | |
| 376 /* find exact color match with smallest size */ | |
| 377 dst_pix_fmt = -1; | |
| 378 min_dist = 0x7fffffff; | |
| 379 for(i = 0;i < PIX_FMT_NB; i++) { | |
| 380 if (pix_fmt_mask & (1 << i)) { | |
| 381 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask; | |
| 382 if (loss == 0) { | |
| 383 dist = avg_bits_per_pixel(i); | |
| 384 if (dist < min_dist) { | |
| 385 min_dist = dist; | |
| 386 dst_pix_fmt = i; | |
| 387 } | |
| 388 } | |
| 389 } | |
| 390 } | |
| 391 return dst_pix_fmt; | |
| 392 } | |
| 393 | |
| 394 /** | |
| 395 * find best pixel format to convert to. Return -1 if none found | |
| 396 */ | |
| 397 int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, | |
| 398 int has_alpha, int *loss_ptr) | |
| 399 { | |
| 400 int dst_pix_fmt, loss_mask, i; | |
| 401 static const int loss_mask_order[] = { | |
| 402 ~0, /* no loss first */ | |
| 403 ~FF_LOSS_ALPHA, | |
| 404 ~FF_LOSS_RESOLUTION, | |
| 405 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION), | |
| 406 ~FF_LOSS_COLORQUANT, | |
| 407 ~FF_LOSS_DEPTH, | |
| 408 0, | |
| 409 }; | |
| 410 | |
| 411 /* try with successive loss */ | |
| 412 i = 0; | |
| 413 for(;;) { | |
| 414 loss_mask = loss_mask_order[i++]; | |
| 415 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, | |
| 416 has_alpha, loss_mask); | |
| 417 if (dst_pix_fmt >= 0) | |
| 418 goto found; | |
| 419 if (loss_mask == 0) | |
| 420 break; | |
| 421 } | |
| 422 return -1; | |
| 423 found: | |
| 424 if (loss_ptr) | |
| 425 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); | |
| 426 return dst_pix_fmt; | |
| 427 } | |
| 428 | |
| 227 | 429 |
| 228 /* XXX: totally non optimized */ | 430 /* XXX: totally non optimized */ |
| 229 | 431 |
| 230 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src, | 432 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src, |
| 231 int width, int height) | 433 int width, int height) |
| 261 | 463 |
| 262 #define SCALEBITS 8 | 464 #define SCALEBITS 8 |
| 263 #define ONE_HALF (1 << (SCALEBITS - 1)) | 465 #define ONE_HALF (1 << (SCALEBITS - 1)) |
| 264 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5)) | 466 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5)) |
| 265 | 467 |
| 468 #define SCALE_BITS 10 | |
| 469 | |
| 470 #define C_Y (76309 >> (16 - SCALE_BITS)) | |
| 471 #define C_RV (117504 >> (16 - SCALE_BITS)) | |
| 472 #define C_BU (138453 >> (16 - SCALE_BITS)) | |
| 473 #define C_GU (13954 >> (16 - SCALE_BITS)) | |
| 474 #define C_GV (34903 >> (16 - SCALE_BITS)) | |
| 475 | |
| 476 #define YUV_TO_RGB2(r, g, b, y1)\ | |
| 477 {\ | |
| 478 y = (y1 - 16) * C_Y;\ | |
| 479 r = cm[(y + r_add) >> SCALE_BITS];\ | |
| 480 g = cm[(y + g_add) >> SCALE_BITS];\ | |
| 481 b = cm[(y + b_add) >> SCALE_BITS];\ | |
| 482 } | |
| 483 | |
| 484 /* XXX: use a table ? */ | |
| 485 #define CCIR_TO_GRAY(y)\ | |
| 486 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS] | |
| 487 | |
| 488 #define GRAY_TO_CCIR(y)\ | |
| 489 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) | |
| 490 | |
| 491 #define RGB_TO_Y(r, g, b) \ | |
| 492 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \ | |
| 493 FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS) | |
| 494 | |
| 495 #define RGB4_TO_U(r1, g1, b1)\ | |
| 496 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ | |
| 497 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) | |
| 498 | |
| 499 #define RGB4_TO_V(r1, g1, b1)\ | |
| 500 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ | |
| 501 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) | |
| 502 | |
| 503 #define RGB_TO_Y_CCIR(r, g, b) \ | |
| 504 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ | |
| 505 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) | |
| 506 | |
| 507 #define RGB4_TO_U_CCIR(r1, g1, b1)\ | |
| 508 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ | |
| 509 FIX(0.50000*224.0/255.0) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) | |
| 510 | |
| 511 #define RGB4_TO_V_CCIR(r1, g1, b1)\ | |
| 512 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ | |
| 513 FIX(0.08131*224.0/255.0) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) | |
| 514 | |
| 515 /* convert from CCIR luma (16 <= Y <= 235) to full scale gray (0 <= Y <= 255) */ | |
| 516 static void luma_ccir_to_gray(uint8_t *dst, int dst_wrap, | |
| 517 uint8_t *src, int src_wrap, | |
| 518 int width, int height) | |
| 519 { | |
| 520 int n; | |
| 521 const uint8_t *s; | |
| 522 uint8_t *d; | |
| 523 uint8_t *cm = cropTbl + MAX_NEG_CROP; | |
| 524 | |
| 525 for(;height > 0; height--) { | |
| 526 s = src; | |
| 527 d = dst; | |
| 528 n = width; | |
| 529 while (n >= 4) { | |
| 530 d[0] = CCIR_TO_GRAY(s[0]); | |
| 531 d[1] = CCIR_TO_GRAY(s[1]); | |
| 532 d[2] = CCIR_TO_GRAY(s[2]); | |
| 533 d[3] = CCIR_TO_GRAY(s[3]); | |
| 534 d += 4; | |
| 535 s += 4; | |
| 536 n -= 4; | |
| 537 } | |
| 538 while (n > 0) { | |
| 539 d[0] = CCIR_TO_GRAY(s[0]); | |
| 540 d++; | |
| 541 s++; | |
| 542 n--; | |
| 543 } | |
| 544 dst += dst_wrap; | |
| 545 src += src_wrap; | |
| 546 } | |
| 547 } | |
| 548 | |
| 549 /* convert from full scale gray (0 <= Y <= 255) to CCIR luma (16 <= Y <= 235) */ | |
| 550 static void gray_to_luma_ccir(uint8_t *dst, int dst_wrap, | |
| 551 uint8_t *src, int src_wrap, | |
| 552 int width, int height) | |
| 553 { | |
| 554 int n; | |
| 555 const uint8_t *s; | |
| 556 uint8_t *d; | |
| 557 | |
| 558 for(;height > 0; height--) { | |
| 559 s = src; | |
| 560 d = dst; | |
| 561 n = width; | |
| 562 while (n >= 4) { | |
| 563 d[0] = GRAY_TO_CCIR(s[0]); | |
| 564 d[1] = GRAY_TO_CCIR(s[1]); | |
| 565 d[2] = GRAY_TO_CCIR(s[2]); | |
| 566 d[3] = GRAY_TO_CCIR(s[3]); | |
| 567 d += 4; | |
| 568 s += 4; | |
| 569 n -= 4; | |
| 570 } | |
| 571 while (n > 0) { | |
| 572 d[0] = GRAY_TO_CCIR(s[0]); | |
| 573 d++; | |
| 574 s++; | |
| 575 n--; | |
| 576 } | |
| 577 dst += dst_wrap; | |
| 578 src += src_wrap; | |
| 579 } | |
| 580 } | |
| 581 | |
| 266 /* XXX: use generic filter ? */ | 582 /* XXX: use generic filter ? */ |
| 267 /* 1x2 -> 1x1 */ | 583 /* 1x2 -> 1x1 */ |
| 268 static void shrink2(uint8_t *dst, int dst_wrap, | 584 static void shrink2(uint8_t *dst, int dst_wrap, |
| 269 uint8_t *src, int src_wrap, | 585 uint8_t *src, int src_wrap, |
| 270 int width, int height) | 586 int width, int height) |
| 390 for(;height > 0; height--) { | 706 for(;height > 0; height--) { |
| 391 memcpy(dst, src, width); | 707 memcpy(dst, src, width); |
| 392 dst += dst_wrap; | 708 dst += dst_wrap; |
| 393 src += src_wrap; | 709 src += src_wrap; |
| 394 } | 710 } |
| 395 } | |
| 396 | |
| 397 #define SCALE_BITS 10 | |
| 398 | |
| 399 #define C_Y (76309 >> (16 - SCALE_BITS)) | |
| 400 #define C_RV (117504 >> (16 - SCALE_BITS)) | |
| 401 #define C_BU (138453 >> (16 - SCALE_BITS)) | |
| 402 #define C_GU (13954 >> (16 - SCALE_BITS)) | |
| 403 #define C_GV (34903 >> (16 - SCALE_BITS)) | |
| 404 | |
| 405 #define YUV_TO_RGB2(r, g, b, y1)\ | |
| 406 {\ | |
| 407 y = (y1 - 16) * C_Y;\ | |
| 408 r = cm[(y + r_add) >> SCALE_BITS];\ | |
| 409 g = cm[(y + g_add) >> SCALE_BITS];\ | |
| 410 b = cm[(y + b_add) >> SCALE_BITS];\ | |
| 411 } | 711 } |
| 412 | 712 |
| 413 /* XXX: no chroma interpolating is done */ | 713 /* XXX: no chroma interpolating is done */ |
| 414 #define RGB_FUNCTIONS(rgb_name) \ | 714 #define RGB_FUNCTIONS(rgb_name) \ |
| 415 \ | 715 \ |
| 605 for(x=0;x<width;x+=2) { \ | 905 for(x=0;x<width;x+=2) { \ |
| 606 RGB_IN(r, g, b, p); \ | 906 RGB_IN(r, g, b, p); \ |
| 607 r1 = r; \ | 907 r1 = r; \ |
| 608 g1 = g; \ | 908 g1 = g; \ |
| 609 b1 = b; \ | 909 b1 = b; \ |
| 610 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 910 lum[0] = RGB_TO_Y_CCIR(r, g, b); \ |
| 611 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | 911 \ |
| 612 RGB_IN(r, g, b, p + BPP); \ | 912 RGB_IN(r, g, b, p + BPP); \ |
| 613 r1 += r; \ | 913 r1 += r; \ |
| 614 g1 += g; \ | 914 g1 += g; \ |
| 615 b1 += b; \ | 915 b1 += b; \ |
| 616 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 916 lum[1] = RGB_TO_Y_CCIR(r, g, b); \ |
| 617 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | |
| 618 p += wrap3; \ | 917 p += wrap3; \ |
| 619 lum += wrap; \ | 918 lum += wrap; \ |
| 620 \ | 919 \ |
| 621 RGB_IN(r, g, b, p); \ | 920 RGB_IN(r, g, b, p); \ |
| 622 r1 += r; \ | 921 r1 += r; \ |
| 623 g1 += g; \ | 922 g1 += g; \ |
| 624 b1 += b; \ | 923 b1 += b; \ |
| 625 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 924 lum[0] = RGB_TO_Y_CCIR(r, g, b); \ |
| 626 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | 925 \ |
| 627 \ | |
| 628 RGB_IN(r, g, b, p + BPP); \ | 926 RGB_IN(r, g, b, p + BPP); \ |
| 629 r1 += r; \ | 927 r1 += r; \ |
| 630 g1 += g; \ | 928 g1 += g; \ |
| 631 b1 += b; \ | 929 b1 += b; \ |
| 632 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 930 lum[1] = RGB_TO_Y_CCIR(r, g, b); \ |
| 633 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | 931 \ |
| 634 \ | 932 cb[0] = RGB4_TO_U_CCIR(r1, g1, b1); \ |
| 635 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ | 933 cr[0] = RGB4_TO_V_CCIR(r1, g1, b1); \ |
| 636 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> \ | |
| 637 (SCALEBITS + 2)) + 128; \ | |
| 638 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ | |
| 639 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> \ | |
| 640 (SCALEBITS + 2)) + 128; \ | |
| 641 \ | 934 \ |
| 642 cb++; \ | 935 cb++; \ |
| 643 cr++; \ | 936 cr++; \ |
| 644 p += -wrap3 + 2 * BPP; \ | 937 p += -wrap3 + 2 * BPP; \ |
| 645 lum += -wrap + 2; \ | 938 lum += -wrap + 2; \ |
| 666 dst_wrap = dst->linesize[0] - width; \ | 959 dst_wrap = dst->linesize[0] - width; \ |
| 667 \ | 960 \ |
| 668 for(y=0;y<height;y++) { \ | 961 for(y=0;y<height;y++) { \ |
| 669 for(x=0;x<width;x++) { \ | 962 for(x=0;x<width;x++) { \ |
| 670 RGB_IN(r, g, b, p); \ | 963 RGB_IN(r, g, b, p); \ |
| 671 q[0] = (FIX(0.29900) * r + FIX(0.58700) * g + \ | 964 q[0] = RGB_TO_Y(r, g, b); \ |
| 672 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; \ | |
| 673 q++; \ | 965 q++; \ |
| 674 p += BPP; \ | 966 p += BPP; \ |
| 675 } \ | 967 } \ |
| 676 p += src_wrap; \ | 968 p += src_wrap; \ |
| 677 q += dst_wrap; \ | 969 q += dst_wrap; \ |
| 1315 /* same format: just copy */ | 1607 /* same format: just copy */ |
| 1316 for(i = 0; i < dst_pix->nb_components; i++) { | 1608 for(i = 0; i < dst_pix->nb_components; i++) { |
| 1317 int w, h; | 1609 int w, h; |
| 1318 w = dst_width; | 1610 w = dst_width; |
| 1319 h = dst_height; | 1611 h = dst_height; |
| 1320 if (dst_pix->is_yuv && (i == 1 || i == 2)) { | 1612 if ((dst_pix->color_type == FF_COLOR_YUV || |
| 1613 dst_pix->color_type == FF_COLOR_YUV_JPEG) && | |
| 1614 (i == 1 || i == 2)) { | |
| 1321 w >>= dst_pix->x_chroma_shift; | 1615 w >>= dst_pix->x_chroma_shift; |
| 1322 h >>= dst_pix->y_chroma_shift; | 1616 h >>= dst_pix->y_chroma_shift; |
| 1323 } | 1617 } |
| 1324 img_copy(dst->data[i], dst->linesize[i], | 1618 img_copy(dst->data[i], dst->linesize[i], |
| 1325 src->data[i], src->linesize[i], | 1619 src->data[i], src->linesize[i], |
| 1334 ce->convert(dst, src, dst_width, dst_height); | 1628 ce->convert(dst, src, dst_width, dst_height); |
| 1335 return 0; | 1629 return 0; |
| 1336 } | 1630 } |
| 1337 | 1631 |
| 1338 /* gray to YUV */ | 1632 /* gray to YUV */ |
| 1339 if (dst_pix->is_yuv && src_pix_fmt == PIX_FMT_GRAY8) { | 1633 if ((dst_pix->color_type == FF_COLOR_YUV || |
| 1634 dst_pix->color_type == FF_COLOR_YUV_JPEG) && | |
| 1635 src_pix_fmt == PIX_FMT_GRAY8) { | |
| 1340 int w, h, y; | 1636 int w, h, y; |
| 1341 uint8_t *d; | 1637 uint8_t *d; |
| 1342 | 1638 |
| 1343 img_copy(dst->data[0], dst->linesize[0], | 1639 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) { |
| 1344 src->data[0], src->linesize[0], | 1640 img_copy(dst->data[0], dst->linesize[0], |
| 1345 dst_width, dst_height); | 1641 src->data[0], src->linesize[0], |
| 1642 dst_width, dst_height); | |
| 1643 } else { | |
| 1644 gray_to_luma_ccir(dst->data[0], dst->linesize[0], | |
| 1645 src->data[0], src->linesize[0], | |
| 1646 dst_width, dst_height); | |
| 1647 } | |
| 1346 /* fill U and V with 128 */ | 1648 /* fill U and V with 128 */ |
| 1347 w = dst_width; | 1649 w = dst_width; |
| 1348 h = dst_height; | 1650 h = dst_height; |
| 1349 w >>= dst_pix->x_chroma_shift; | 1651 w >>= dst_pix->x_chroma_shift; |
| 1350 h >>= dst_pix->y_chroma_shift; | 1652 h >>= dst_pix->y_chroma_shift; |
| 1357 } | 1659 } |
| 1358 return 0; | 1660 return 0; |
| 1359 } | 1661 } |
| 1360 | 1662 |
| 1361 /* YUV to gray */ | 1663 /* YUV to gray */ |
| 1362 if (src_pix->is_yuv && dst_pix_fmt == PIX_FMT_GRAY8) { | 1664 if ((src_pix->color_type == FF_COLOR_YUV || |
| 1363 img_copy(dst->data[0], dst->linesize[0], | 1665 src_pix->color_type == FF_COLOR_YUV_JPEG) && |
| 1364 src->data[0], src->linesize[0], | 1666 dst_pix_fmt == PIX_FMT_GRAY8) { |
| 1365 dst_width, dst_height); | 1667 if (src_pix->color_type == FF_COLOR_YUV_JPEG) { |
| 1668 img_copy(dst->data[0], dst->linesize[0], | |
| 1669 src->data[0], src->linesize[0], | |
| 1670 dst_width, dst_height); | |
| 1671 } else { | |
| 1672 luma_ccir_to_gray(dst->data[0], dst->linesize[0], | |
| 1673 src->data[0], src->linesize[0], | |
| 1674 dst_width, dst_height); | |
| 1675 } | |
| 1366 return 0; | 1676 return 0; |
| 1367 } | 1677 } |
| 1368 | 1678 |
| 1369 /* YUV to YUV */ | 1679 /* YUV to YUV */ |
| 1370 if (dst_pix->is_yuv && src_pix->is_yuv) { | 1680 if (dst_pix->color_type == FF_COLOR_YUV && |
| 1681 dst_pix->color_type == src_pix->color_type) { | |
| 1371 int x_shift, y_shift, w, h; | 1682 int x_shift, y_shift, w, h; |
| 1372 void (*resize_func)(uint8_t *dst, int dst_wrap, | 1683 void (*resize_func)(uint8_t *dst, int dst_wrap, |
| 1373 uint8_t *src, int src_wrap, | 1684 uint8_t *src, int src_wrap, |
| 1374 int width, int height); | 1685 int width, int height); |
| 1375 | 1686 |
