comparison imgconvert.c @ 1203:80c73b9b0ba2 libavcodec

accurate YUV to RGB and RGB to YUV conversions - added comments
author bellard
date Mon, 21 Apr 2003 12:12:58 +0000
parents 8b49a7ee4e4e
children e55580ae9969
comparison
equal deleted inserted replaced
1202:8b49a7ee4e4e 1203:80c73b9b0ba2
20 /** 20 /**
21 * @file imgconvert.c 21 * @file imgconvert.c
22 * Misc image convertion routines. 22 * Misc image convertion routines.
23 */ 23 */
24 24
25 /* TODO:
26 * - write 'ffimg' program to test all the image related stuff
27 * - move all api to slice based system
28 * - integrate deinterlacing, postprocessing and scaling in the conversion process
29 */
25 30
26 #include "avcodec.h" 31 #include "avcodec.h"
27 #include "dsputil.h" 32 #include "dsputil.h"
28 33
29 #ifdef USE_FASTMEMCPY 34 #ifdef USE_FASTMEMCPY
208 case PIX_FMT_YUV420P: 213 case PIX_FMT_YUV420P:
209 case PIX_FMT_YUV422P: 214 case PIX_FMT_YUV422P:
210 case PIX_FMT_YUV444P: 215 case PIX_FMT_YUV444P:
211 case PIX_FMT_YUV410P: 216 case PIX_FMT_YUV410P:
212 case PIX_FMT_YUV411P: 217 case PIX_FMT_YUV411P:
218 case PIX_FMT_YUVJ420P:
219 case PIX_FMT_YUVJ422P:
220 case PIX_FMT_YUVJ444P:
213 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift; 221 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
214 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; 222 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
215 size2 = w2 * h2; 223 size2 = w2 * h2;
216 picture->data[0] = ptr; 224 picture->data[0] = ptr;
217 picture->data[1] = picture->data[0] + size; 225 picture->data[1] = picture->data[0] + size;
430 /* XXX: totally non optimized */ 438 /* XXX: totally non optimized */
431 439
432 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src, 440 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src,
433 int width, int height) 441 int width, int height)
434 { 442 {
435 uint8_t *lum, *cb, *cr; 443 const uint8_t *p, *p1;
436 int x, y; 444 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
437 const uint8_t *p; 445 int x;
438 446
439 lum = dst->data[0]; 447 p1 = src->data[0];
440 cb = dst->data[1]; 448 lum1 = dst->data[0];
441 cr = dst->data[2]; 449 cb1 = dst->data[0];
442 p = src->data[0]; 450 cr1 = dst->data[0];
443 451
444 for(y=0;y<height;y+=2) { 452 for(;height >= 2; height -= 2) {
453 p = p1;
454 lum = lum1;
455 cb = cb1;
456 cr = cr1;
445 for(x=0;x<width;x+=2) { 457 for(x=0;x<width;x+=2) {
446 lum[0] = p[0]; 458 lum[0] = p[0];
447 cb[0] = p[1]; 459 cb[0] = p[1];
448 lum[1] = p[2]; 460 lum[1] = p[2];
449 cr[0] = p[3]; 461 cr[0] = p[3];
450 p += 4; 462 p += 4;
451 lum += 2; 463 lum += 2;
452 cb++; 464 cb++;
453 cr++; 465 cr++;
454 } 466 }
467 p1 += src->linesize[0];
468 lum1 += dst->linesize[0];
469 p = p1;
470 lum = lum1;
455 for(x=0;x<width;x+=2) { 471 for(x=0;x<width;x+=2) {
456 lum[0] = p[0]; 472 lum[0] = p[0];
457 lum[1] = p[2]; 473 lum[1] = p[2];
458 p += 4; 474 p += 4;
459 lum += 2; 475 lum += 2;
460 } 476 }
461 } 477 p1 += src->linesize[0];
462 } 478 lum1 += dst->linesize[0];
463 479 cb1 += dst->linesize[1];
464 #define SCALEBITS 8 480 cr1 += dst->linesize[2];
481 }
482 }
483
484 static void yuv422_to_yuv422p(AVPicture *dst, AVPicture *src,
485 int width, int height)
486 {
487 const uint8_t *p, *p1;
488 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
489 int w;
490
491 p1 = src->data[0];
492 lum1 = dst->data[0];
493 cb1 = dst->data[0];
494 cr1 = dst->data[0];
495 for(;height >= 2; height -= 2) {
496 p = p1;
497 lum = lum1;
498 cb = cb1;
499 cr = cr1;
500 for(w = width; w >= 2; w -= 2) {
501 lum[0] = p[0];
502 cb[0] = p[1];
503 lum[1] = p[2];
504 cr[0] = p[3];
505 p += 4;
506 lum += 2;
507 cb++;
508 cr++;
509 }
510 p1 += src->linesize[0];
511 lum1 += dst->linesize[0];
512 cb1 += dst->linesize[1];
513 cr1 += dst->linesize[2];
514 }
515 }
516
517 static void yuv422p_to_yuv422(AVPicture *dst, AVPicture *src,
518 int width, int height)
519 {
520 uint8_t *p, *p1;
521 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
522 int w;
523
524 p1 = dst->data[0];
525 lum1 = src->data[0];
526 cb1 = src->data[0];
527 cr1 = src->data[0];
528 for(;height >= 2; height -= 2) {
529 p = p1;
530 lum = lum1;
531 cb = cb1;
532 cr = cr1;
533 for(w = width; w >= 2; w -= 2) {
534 p[0] = lum[0];
535 p[1] = cb[0];
536 p[2] = lum[1];
537 p[3] = cr[0];
538 p += 4;
539 lum += 2;
540 cb++;
541 cr++;
542 }
543 p1 += src->linesize[0];
544 lum1 += dst->linesize[0];
545 cb1 += dst->linesize[1];
546 cr1 += dst->linesize[2];
547 }
548 }
549
550 #define SCALEBITS 10
465 #define ONE_HALF (1 << (SCALEBITS - 1)) 551 #define ONE_HALF (1 << (SCALEBITS - 1))
466 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5)) 552 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
467 553
468 #define SCALE_BITS 10 554 #define YUV_TO_RGB1_CCIR(cb1, cr1)\
469 555 {\
470 #define C_Y (76309 >> (16 - SCALE_BITS)) 556 cb = (cb1) - 128;\
471 #define C_RV (117504 >> (16 - SCALE_BITS)) 557 cr = (cr1) - 128;\
472 #define C_BU (138453 >> (16 - SCALE_BITS)) 558 r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
473 #define C_GU (13954 >> (16 - SCALE_BITS)) 559 g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
474 #define C_GV (34903 >> (16 - SCALE_BITS)) 560 ONE_HALF;\
561 b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
562 }
563
564 #define YUV_TO_RGB2_CCIR(r, g, b, y1)\
565 {\
566 y = ((y1) - 16) * FIX(255.0/219.0);\
567 r = cm[(y + r_add) >> SCALEBITS];\
568 g = cm[(y + g_add) >> SCALEBITS];\
569 b = cm[(y + b_add) >> SCALEBITS];\
570 }
571
572 #define YUV_TO_RGB1(cb1, cr1)\
573 {\
574 cb = (cb1) - 128;\
575 cr = (cr1) - 128;\
576 r_add = FIX(1.40200) * cr + ONE_HALF;\
577 g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
578 b_add = FIX(1.77200) * cb + ONE_HALF;\
579 }
475 580
476 #define YUV_TO_RGB2(r, g, b, y1)\ 581 #define YUV_TO_RGB2(r, g, b, y1)\
477 {\ 582 {\
478 y = (y1 - 16) * C_Y;\ 583 y = (y1) << SCALEBITS;\
479 r = cm[(y + r_add) >> SCALE_BITS];\ 584 r = cm[(y + r_add) >> SCALEBITS];\
480 g = cm[(y + g_add) >> SCALE_BITS];\ 585 g = cm[(y + g_add) >> SCALEBITS];\
481 b = cm[(y + b_add) >> SCALE_BITS];\ 586 b = cm[(y + b_add) >> SCALEBITS];\
482 } 587 }
483 588
484 /* XXX: use a table ? */ 589 #define Y_CCIR_TO_JPEG(y)\
485 #define CCIR_TO_GRAY(y)\
486 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS] 590 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
487 591
488 #define GRAY_TO_CCIR(y)\ 592 #define Y_JPEG_TO_CCIR(y)\
489 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) 593 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
594
595 #define C_CCIR_TO_JPEG(y)\
596 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
597
598 /* NOTE: the clamp is really necessary! */
599 #define C_JPEG_TO_CCIR(y)\
600 ({\
601 int __y;\
602 __y = ((((y) - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);\
603 if (__y < 16)\
604 __y = 16;\
605 __y;\
606 })
490 607
491 #define RGB_TO_Y(r, g, b) \ 608 #define RGB_TO_Y(r, g, b) \
492 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \ 609 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
493 FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS) 610 FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
494 611
495 #define RGB4_TO_U(r1, g1, b1)\ 612 #define RGB_TO_U(r1, g1, b1, shift)\
496 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ 613 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \
497 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) 614 FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
498 615
499 #define RGB4_TO_V(r1, g1, b1)\ 616 #define RGB_TO_V(r1, g1, b1, shift)\
500 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ 617 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \
501 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128) 618 FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
502 619
503 #define RGB_TO_Y_CCIR(r, g, b) \ 620 #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) + \ 621 ((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) 622 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
506 623
507 #define RGB4_TO_U_CCIR(r1, g1, b1)\ 624 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
508 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ 625 (((- 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) 626 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
510 627
511 #define RGB4_TO_V_CCIR(r1, g1, b1)\ 628 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
512 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ 629 (((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) 630 FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
514 631
515 /* convert from CCIR luma (16 <= Y <= 235) to full scale gray (0 <= Y <= 255) */ 632 static uint8_t y_ccir_to_jpeg[256];
516 static void luma_ccir_to_gray(uint8_t *dst, int dst_wrap, 633 static uint8_t y_jpeg_to_ccir[256];
517 uint8_t *src, int src_wrap, 634 static uint8_t c_ccir_to_jpeg[256];
518 int width, int height) 635 static uint8_t c_jpeg_to_ccir[256];
636
637 /* init various conversion tables */
638 static void img_convert_init(void)
639 {
640 int i;
641 uint8_t *cm = cropTbl + MAX_NEG_CROP;
642
643 for(i = 0;i < 256; i++) {
644 y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
645 y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
646 c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
647 c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
648 }
649 }
650
651 /* apply to each pixel the given table */
652 static void img_apply_table(uint8_t *dst, int dst_wrap,
653 const uint8_t *src, int src_wrap,
654 int width, int height, const uint8_t *table1)
519 { 655 {
520 int n; 656 int n;
521 const uint8_t *s; 657 const uint8_t *s;
522 uint8_t *d; 658 uint8_t *d;
523 uint8_t *cm = cropTbl + MAX_NEG_CROP; 659 const uint8_t *table;
524 660
661 table = table1;
525 for(;height > 0; height--) { 662 for(;height > 0; height--) {
526 s = src; 663 s = src;
527 d = dst; 664 d = dst;
528 n = width; 665 n = width;
529 while (n >= 4) { 666 while (n >= 4) {
530 d[0] = CCIR_TO_GRAY(s[0]); 667 d[0] = table[s[0]];
531 d[1] = CCIR_TO_GRAY(s[1]); 668 d[1] = table[s[1]];
532 d[2] = CCIR_TO_GRAY(s[2]); 669 d[2] = table[s[2]];
533 d[3] = CCIR_TO_GRAY(s[3]); 670 d[3] = table[s[3]];
534 d += 4; 671 d += 4;
535 s += 4; 672 s += 4;
536 n -= 4; 673 n -= 4;
537 } 674 }
538 while (n > 0) { 675 while (n > 0) {
539 d[0] = CCIR_TO_GRAY(s[0]); 676 d[0] = table[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++; 677 d++;
574 s++; 678 s++;
575 n--; 679 n--;
576 } 680 }
577 dst += dst_wrap; 681 dst += dst_wrap;
729 for(;height >= 2; height -= 2) { \ 833 for(;height >= 2; height -= 2) { \
730 d1 = d; \ 834 d1 = d; \
731 d2 = d + dst->linesize[0]; \ 835 d2 = d + dst->linesize[0]; \
732 y2_ptr = y1_ptr + src->linesize[0]; \ 836 y2_ptr = y1_ptr + src->linesize[0]; \
733 for(w = width; w >= 2; w -= 2) { \ 837 for(w = width; w >= 2; w -= 2) { \
734 cb = cb_ptr[0] - 128; \ 838 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); \
735 cr = cr_ptr[0] - 128; \
736 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); \
737 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); \
738 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); \
739 \
740 /* output 4 pixels */ \ 839 /* output 4 pixels */ \
741 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \ 840 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); \
742 RGB_OUT(d1, r, g, b); \ 841 RGB_OUT(d1, r, g, b); \
743 \ 842 \
744 YUV_TO_RGB2(r, g, b, y1_ptr[1]); \ 843 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]); \
745 RGB_OUT(d1 + BPP, r, g, b); \ 844 RGB_OUT(d1 + BPP, r, g, b); \
746 \ 845 \
747 YUV_TO_RGB2(r, g, b, y2_ptr[0]); \ 846 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]); \
748 RGB_OUT(d2, r, g, b); \ 847 RGB_OUT(d2, r, g, b); \
749 \ 848 \
750 YUV_TO_RGB2(r, g, b, y2_ptr[1]); \ 849 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[1]); \
751 RGB_OUT(d2 + BPP, r, g, b); \ 850 RGB_OUT(d2 + BPP, r, g, b); \
752 \ 851 \
753 d1 += 2 * BPP; \ 852 d1 += 2 * BPP; \
754 d2 += 2 * BPP; \ 853 d2 += 2 * BPP; \
755 \ 854 \
758 cb_ptr++; \ 857 cb_ptr++; \
759 cr_ptr++; \ 858 cr_ptr++; \
760 } \ 859 } \
761 /* handle odd width */ \ 860 /* handle odd width */ \
762 if (w) { \ 861 if (w) { \
763 cb = cb_ptr[0] - 128; \ 862 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); \
764 cr = cr_ptr[0] - 128; \ 863 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); \
765 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); \
766 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); \
767 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); \
768 \
769 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \
770 RGB_OUT(d1, r, g, b); \ 864 RGB_OUT(d1, r, g, b); \
771 \ 865 \
772 YUV_TO_RGB2(r, g, b, y2_ptr[0]); \ 866 YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]); \
773 RGB_OUT(d2, r, g, b); \ 867 RGB_OUT(d2, r, g, b); \
774 d1 += BPP; \ 868 d1 += BPP; \
775 d2 += BPP; \ 869 d2 += BPP; \
776 y1_ptr++; \ 870 y1_ptr++; \
777 y2_ptr++; \ 871 y2_ptr++; \
785 } \ 879 } \
786 /* handle odd height */ \ 880 /* handle odd height */ \
787 if (height) { \ 881 if (height) { \
788 d1 = d; \ 882 d1 = d; \
789 for(w = width; w >= 2; w -= 2) { \ 883 for(w = width; w >= 2; w -= 2) { \
790 cb = cb_ptr[0] - 128; \ 884 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); \
791 cr = cr_ptr[0] - 128; \
792 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); \
793 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); \
794 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); \
795 \
796 /* output 2 pixels */ \ 885 /* output 2 pixels */ \
797 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \ 886 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); \
798 RGB_OUT(d1, r, g, b); \ 887 RGB_OUT(d1, r, g, b); \
799 \ 888 \
800 YUV_TO_RGB2(r, g, b, y1_ptr[1]); \ 889 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]); \
801 RGB_OUT(d1 + BPP, r, g, b); \ 890 RGB_OUT(d1 + BPP, r, g, b); \
802 \ 891 \
803 d1 += 2 * BPP; \ 892 d1 += 2 * BPP; \
804 \ 893 \
805 y1_ptr += 2; \ 894 y1_ptr += 2; \
806 cb_ptr++; \ 895 cb_ptr++; \
807 cr_ptr++; \ 896 cr_ptr++; \
808 } \ 897 } \
809 /* handle width */ \ 898 /* handle width */ \
810 if (w) { \ 899 if (w) { \
811 cb = cb_ptr[0] - 128; \ 900 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); \
812 cr = cr_ptr[0] - 128; \
813 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); \
814 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); \
815 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); \
816 \
817 /* output 2 pixels */ \ 901 /* output 2 pixels */ \
818 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \ 902 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); \
819 RGB_OUT(d1, r, g, b); \ 903 RGB_OUT(d1, r, g, b); \
820 d1 += BPP; \ 904 d1 += BPP; \
821 \ 905 \
822 y1_ptr++; \ 906 y1_ptr++; \
823 cb_ptr++; \ 907 cb_ptr++; \
824 cr_ptr++; \ 908 cr_ptr++; \
825 } \ 909 } \
826 } \ 910 } \
827 } \ 911 } \
828 \ 912 \
829 /* XXX: no chroma interpolating is done */ \ 913 static void yuvj420p_to_ ## rgb_name (AVPicture *dst, AVPicture *src, \
830 static void yuv422p_to_ ## rgb_name (AVPicture *dst, AVPicture *src, \ 914 int width, int height) \
831 int width, int height) \
832 { \ 915 { \
833 uint8_t *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1; \ 916 uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2; \
834 int w, y, cb, cr, r_add, g_add, b_add, width2; \ 917 int w, y, cb, cr, r_add, g_add, b_add, width2; \
835 uint8_t *cm = cropTbl + MAX_NEG_CROP; \ 918 uint8_t *cm = cropTbl + MAX_NEG_CROP; \
836 unsigned int r, g, b; \ 919 unsigned int r, g, b; \
837 \ 920 \
838 d = dst->data[0]; \ 921 d = dst->data[0]; \
839 y1_ptr = src->data[0]; \ 922 y1_ptr = src->data[0]; \
840 cb_ptr = src->data[1]; \ 923 cb_ptr = src->data[1]; \
841 cr_ptr = src->data[2]; \ 924 cr_ptr = src->data[2]; \
842 width2 = (width + 1) >> 1; \ 925 width2 = (width + 1) >> 1; \
843 for(;height > 0; height --) { \ 926 for(;height >= 2; height -= 2) { \
927 d1 = d; \
928 d2 = d + dst->linesize[0]; \
929 y2_ptr = y1_ptr + src->linesize[0]; \
930 for(w = width; w >= 2; w -= 2) { \
931 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]); \
932 /* output 4 pixels */ \
933 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \
934 RGB_OUT(d1, r, g, b); \
935 \
936 YUV_TO_RGB2(r, g, b, y1_ptr[1]); \
937 RGB_OUT(d1 + BPP, r, g, b); \
938 \
939 YUV_TO_RGB2(r, g, b, y2_ptr[0]); \
940 RGB_OUT(d2, r, g, b); \
941 \
942 YUV_TO_RGB2(r, g, b, y2_ptr[1]); \
943 RGB_OUT(d2 + BPP, r, g, b); \
944 \
945 d1 += 2 * BPP; \
946 d2 += 2 * BPP; \
947 \
948 y1_ptr += 2; \
949 y2_ptr += 2; \
950 cb_ptr++; \
951 cr_ptr++; \
952 } \
953 /* handle odd width */ \
954 if (w) { \
955 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]); \
956 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \
957 RGB_OUT(d1, r, g, b); \
958 \
959 YUV_TO_RGB2(r, g, b, y2_ptr[0]); \
960 RGB_OUT(d2, r, g, b); \
961 d1 += BPP; \
962 d2 += BPP; \
963 y1_ptr++; \
964 y2_ptr++; \
965 cb_ptr++; \
966 cr_ptr++; \
967 } \
968 d += 2 * dst->linesize[0]; \
969 y1_ptr += 2 * src->linesize[0] - width; \
970 cb_ptr += src->linesize[1] - width2; \
971 cr_ptr += src->linesize[2] - width2; \
972 } \
973 /* handle odd height */ \
974 if (height) { \
844 d1 = d; \ 975 d1 = d; \
845 for(w = width; w >= 2; w -= 2) { \ 976 for(w = width; w >= 2; w -= 2) { \
846 cb = cb_ptr[0] - 128; \ 977 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]); \
847 cr = cr_ptr[0] - 128; \
848 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); \
849 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); \
850 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); \
851 \
852 /* output 2 pixels */ \ 978 /* output 2 pixels */ \
853 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \ 979 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \
854 RGB_OUT(d1, r, g, b); \ 980 RGB_OUT(d1, r, g, b); \
855 \ 981 \
856 YUV_TO_RGB2(r, g, b, y1_ptr[1]); \ 982 YUV_TO_RGB2(r, g, b, y1_ptr[1]); \
857 RGB_OUT(d1 + BPP, r, g, b); \ 983 RGB_OUT(d1 + BPP, r, g, b); \
858 \ 984 \
859 d1 += 2 * BPP; \ 985 d1 += 2 * BPP; \
860 \ 986 \
861 y1_ptr += 2; \ 987 y1_ptr += 2; \
862 cb_ptr++; \ 988 cb_ptr++; \
863 cr_ptr++; \ 989 cr_ptr++; \
864 } \ 990 } \
865 /* handle width */ \ 991 /* handle width */ \
866 if (w) { \ 992 if (w) { \
867 cb = cb_ptr[0] - 128; \ 993 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]); \
868 cr = cr_ptr[0] - 128; \
869 r_add = C_RV * cr + (1 << (SCALE_BITS - 1)); \
870 g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1)); \
871 b_add = C_BU * cb + (1 << (SCALE_BITS - 1)); \
872 \
873 /* output 2 pixels */ \ 994 /* output 2 pixels */ \
874 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \ 995 YUV_TO_RGB2(r, g, b, y1_ptr[0]); \
875 RGB_OUT(d1, r, g, b); \ 996 RGB_OUT(d1, r, g, b); \
876 d1 += BPP; \ 997 d1 += BPP; \
877 \ 998 \
878 y1_ptr++; \ 999 y1_ptr++; \
879 cb_ptr++; \ 1000 cb_ptr++; \
880 cr_ptr++; \ 1001 cr_ptr++; \
881 } \ 1002 } \
882 d += dst->linesize[0]; \
883 y1_ptr += src->linesize[0] - width; \
884 cb_ptr += src->linesize[1] - width2; \
885 cr_ptr += src->linesize[2] - width2; \
886 } \ 1003 } \
887 } \ 1004 } \
888 \ 1005 \
889 static void rgb_name ## _to_yuv420p(AVPicture *dst, AVPicture *src, \ 1006 static void rgb_name ## _to_yuv420p(AVPicture *dst, AVPicture *src, \
890 int width, int height) \ 1007 int width, int height) \
891 { \ 1008 { \
892 int wrap, wrap3, x, y; \ 1009 int wrap, wrap3, width2; \
893 int r, g, b, r1, g1, b1; \ 1010 int r, g, b, r1, g1, b1, w; \
894 uint8_t *lum, *cb, *cr; \ 1011 uint8_t *lum, *cb, *cr; \
895 const uint8_t *p; \ 1012 const uint8_t *p; \
896 \ 1013 \
897 lum = dst->data[0]; \ 1014 lum = dst->data[0]; \
898 cb = dst->data[1]; \ 1015 cb = dst->data[1]; \
899 cr = dst->data[2]; \ 1016 cr = dst->data[2]; \
900 \ 1017 \
1018 width2 = (width + 1) >> 1; \
901 wrap = dst->linesize[0]; \ 1019 wrap = dst->linesize[0]; \
902 wrap3 = src->linesize[0]; \ 1020 wrap3 = src->linesize[0]; \
903 p = src->data[0]; \ 1021 p = src->data[0]; \
904 for(y=0;y<height;y+=2) { \ 1022 for(;height>=2;height -= 2) { \
905 for(x=0;x<width;x+=2) { \ 1023 for(w = width; w >= 2; w -= 2) { \
906 RGB_IN(r, g, b, p); \ 1024 RGB_IN(r, g, b, p); \
907 r1 = r; \ 1025 r1 = r; \
908 g1 = g; \ 1026 g1 = g; \
909 b1 = b; \ 1027 b1 = b; \
910 lum[0] = RGB_TO_Y_CCIR(r, g, b); \ 1028 lum[0] = RGB_TO_Y_CCIR(r, g, b); \
927 r1 += r; \ 1045 r1 += r; \
928 g1 += g; \ 1046 g1 += g; \
929 b1 += b; \ 1047 b1 += b; \
930 lum[1] = RGB_TO_Y_CCIR(r, g, b); \ 1048 lum[1] = RGB_TO_Y_CCIR(r, g, b); \
931 \ 1049 \
932 cb[0] = RGB4_TO_U_CCIR(r1, g1, b1); \ 1050 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 2); \
933 cr[0] = RGB4_TO_V_CCIR(r1, g1, b1); \ 1051 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 2); \
934 \ 1052 \
935 cb++; \ 1053 cb++; \
936 cr++; \ 1054 cr++; \
937 p += -wrap3 + 2 * BPP; \ 1055 p += -wrap3 + 2 * BPP; \
938 lum += -wrap + 2; \ 1056 lum += -wrap + 2; \
939 } \ 1057 } \
1058 if (w) { \
1059 RGB_IN(r, g, b, p); \
1060 r1 = r; \
1061 g1 = g; \
1062 b1 = b; \
1063 lum[0] = RGB_TO_Y_CCIR(r, g, b); \
1064 p += wrap3; \
1065 lum += wrap; \
1066 RGB_IN(r, g, b, p); \
1067 r1 += r; \
1068 g1 += g; \
1069 b1 += b; \
1070 lum[0] = RGB_TO_Y_CCIR(r, g, b); \
1071 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1); \
1072 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1); \
1073 cb++; \
1074 cr++; \
1075 p += -wrap3 + BPP; \
1076 lum += -wrap + 1; \
1077 } \
940 p += wrap3 + (wrap3 - width * BPP); \ 1078 p += wrap3 + (wrap3 - width * BPP); \
941 lum += wrap + (wrap - width); \ 1079 lum += wrap + (wrap - width); \
942 cb += dst->linesize[1] - width / 2; \ 1080 cb += dst->linesize[1] - width2; \
943 cr += dst->linesize[2] - width / 2; \ 1081 cr += dst->linesize[2] - width2; \
1082 } \
1083 /* handle odd height */ \
1084 if (height) { \
1085 for(w = width; w >= 2; w -= 2) { \
1086 RGB_IN(r, g, b, p); \
1087 r1 = r; \
1088 g1 = g; \
1089 b1 = b; \
1090 lum[0] = RGB_TO_Y_CCIR(r, g, b); \
1091 \
1092 RGB_IN(r, g, b, p + BPP); \
1093 r1 += r; \
1094 g1 += g; \
1095 b1 += b; \
1096 lum[1] = RGB_TO_Y_CCIR(r, g, b); \
1097 cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1); \
1098 cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1); \
1099 cb++; \
1100 cr++; \
1101 p += 2 * BPP;\
1102 lum += 2;\
1103 } \
1104 if (w) { \
1105 RGB_IN(r, g, b, p); \
1106 lum[0] = RGB_TO_Y_CCIR(r, g, b); \
1107 cb[0] = RGB_TO_U_CCIR(r, g, b, 0); \
1108 cr[0] = RGB_TO_V_CCIR(r, g, b, 0); \
1109 } \
944 } \ 1110 } \
945 } \ 1111 } \
946 \ 1112 \
947 static void rgb_name ## _to_gray(AVPicture *dst, AVPicture *src, \ 1113 static void rgb_name ## _to_gray(AVPicture *dst, AVPicture *src, \
948 int width, int height) \ 1114 int width, int height) \
1123 } 1289 }
1124 1290
1125 #define BPP 3 1291 #define BPP 3
1126 1292
1127 RGB_FUNCTIONS(rgb24) 1293 RGB_FUNCTIONS(rgb24)
1294
1295 static void yuv444p_to_rgb24(AVPicture *dst, AVPicture *src,
1296 int width, int height)
1297 {
1298 uint8_t *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1;
1299 int w, y, cb, cr, r_add, g_add, b_add;
1300 uint8_t *cm = cropTbl + MAX_NEG_CROP;
1301 unsigned int r, g, b;
1302
1303 d = dst->data[0];
1304 y1_ptr = src->data[0];
1305 cb_ptr = src->data[1];
1306 cr_ptr = src->data[2];
1307 for(;height > 0; height --) {
1308 d1 = d;
1309 for(w = width; w > 0; w--) {
1310 YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
1311
1312 YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
1313 RGB_OUT(d1, r, g, b);
1314 d1 += BPP;
1315
1316 y1_ptr++;
1317 cb_ptr++;
1318 cr_ptr++;
1319 }
1320 d += dst->linesize[0];
1321 y1_ptr += src->linesize[0] - width;
1322 cb_ptr += src->linesize[1] - width;
1323 cr_ptr += src->linesize[2] - width;
1324 }
1325 }
1326
1327 static void yuvj444p_to_rgb24(AVPicture *dst, AVPicture *src,
1328 int width, int height)
1329 {
1330 uint8_t *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1;
1331 int w, y, cb, cr, r_add, g_add, b_add;
1332 uint8_t *cm = cropTbl + MAX_NEG_CROP;
1333 unsigned int r, g, b;
1334
1335 d = dst->data[0];
1336 y1_ptr = src->data[0];
1337 cb_ptr = src->data[1];
1338 cr_ptr = src->data[2];
1339 for(;height > 0; height --) {
1340 d1 = d;
1341 for(w = width; w > 0; w--) {
1342 YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
1343
1344 YUV_TO_RGB2(r, g, b, y1_ptr[0]);
1345 RGB_OUT(d1, r, g, b);
1346 d1 += BPP;
1347
1348 y1_ptr++;
1349 cb_ptr++;
1350 cr_ptr++;
1351 }
1352 d += dst->linesize[0];
1353 y1_ptr += src->linesize[0] - width;
1354 cb_ptr += src->linesize[1] - width;
1355 cr_ptr += src->linesize[2] - width;
1356 }
1357 }
1358
1359 static void rgb24_to_yuv444p(AVPicture *dst, AVPicture *src,
1360 int width, int height)
1361 {
1362 int src_wrap, x, y;
1363 int r, g, b;
1364 uint8_t *lum, *cb, *cr;
1365 const uint8_t *p;
1366
1367 lum = dst->data[0];
1368 cb = dst->data[1];
1369 cr = dst->data[2];
1370
1371 src_wrap = src->linesize[0] - width * BPP;
1372 p = src->data[0];
1373 for(y=0;y<height;y++) {
1374 for(x=0;x<width;x++) {
1375 RGB_IN(r, g, b, p);
1376 lum[0] = RGB_TO_Y_CCIR(r, g, b);
1377 cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
1378 cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
1379 cb++;
1380 cr++;
1381 lum++;
1382 }
1383 p += src_wrap;
1384 lum += dst->linesize[0] - width;
1385 cb += dst->linesize[1] - width;
1386 cr += dst->linesize[2] - width;
1387 }
1388 }
1389
1390 static void rgb24_to_yuvj420p(AVPicture *dst, AVPicture *src,
1391 int width, int height)
1392 {
1393 int wrap, wrap3, width2;
1394 int r, g, b, r1, g1, b1, w;
1395 uint8_t *lum, *cb, *cr;
1396 const uint8_t *p;
1397
1398 lum = dst->data[0];
1399 cb = dst->data[1];
1400 cr = dst->data[2];
1401
1402 width2 = (width + 1) >> 1;
1403 wrap = dst->linesize[0];
1404 wrap3 = src->linesize[0];
1405 p = src->data[0];
1406 for(;height>=2;height -= 2) {
1407 for(w = width; w >= 2; w -= 2) {
1408 RGB_IN(r, g, b, p);
1409 r1 = r;
1410 g1 = g;
1411 b1 = b;
1412 lum[0] = RGB_TO_Y(r, g, b);
1413
1414 RGB_IN(r, g, b, p + BPP);
1415 r1 += r;
1416 g1 += g;
1417 b1 += b;
1418 lum[1] = RGB_TO_Y(r, g, b);
1419 p += wrap3;
1420 lum += wrap;
1421
1422 RGB_IN(r, g, b, p);
1423 r1 += r;
1424 g1 += g;
1425 b1 += b;
1426 lum[0] = RGB_TO_Y(r, g, b);
1427
1428 RGB_IN(r, g, b, p + BPP);
1429 r1 += r;
1430 g1 += g;
1431 b1 += b;
1432 lum[1] = RGB_TO_Y(r, g, b);
1433
1434 cb[0] = RGB_TO_U(r1, g1, b1, 2);
1435 cr[0] = RGB_TO_V(r1, g1, b1, 2);
1436
1437 cb++;
1438 cr++;
1439 p += -wrap3 + 2 * BPP;
1440 lum += -wrap + 2;
1441 }
1442 if (w) {
1443 RGB_IN(r, g, b, p);
1444 r1 = r;
1445 g1 = g;
1446 b1 = b;
1447 lum[0] = RGB_TO_Y(r, g, b);
1448 p += wrap3;
1449 lum += wrap;
1450 RGB_IN(r, g, b, p);
1451 r1 += r;
1452 g1 += g;
1453 b1 += b;
1454 lum[0] = RGB_TO_Y(r, g, b);
1455 cb[0] = RGB_TO_U(r1, g1, b1, 1);
1456 cr[0] = RGB_TO_V(r1, g1, b1, 1);
1457 cb++;
1458 cr++;
1459 p += -wrap3 + BPP;
1460 lum += -wrap + 1;
1461 }
1462 p += wrap3 + (wrap3 - width * BPP);
1463 lum += wrap + (wrap - width);
1464 cb += dst->linesize[1] - width2;
1465 cr += dst->linesize[2] - width2;
1466 }
1467 /* handle odd height */
1468 if (height) {
1469 for(w = width; w >= 2; w -= 2) {
1470 RGB_IN(r, g, b, p);
1471 r1 = r;
1472 g1 = g;
1473 b1 = b;
1474 lum[0] = RGB_TO_Y(r, g, b);
1475
1476 RGB_IN(r, g, b, p + BPP);
1477 r1 += r;
1478 g1 += g;
1479 b1 += b;
1480 lum[1] = RGB_TO_Y(r, g, b);
1481 cb[0] = RGB_TO_U(r1, g1, b1, 1);
1482 cr[0] = RGB_TO_V(r1, g1, b1, 1);
1483 cb++;
1484 cr++;
1485 p += 2 * BPP;
1486 lum += 2;
1487 }
1488 if (w) {
1489 RGB_IN(r, g, b, p);
1490 lum[0] = RGB_TO_Y(r, g, b);
1491 cb[0] = RGB_TO_U(r, g, b, 0);
1492 cr[0] = RGB_TO_V(r, g, b, 0);
1493 }
1494 }
1495 }
1496
1497 static void rgb24_to_yuvj444p(AVPicture *dst, AVPicture *src,
1498 int width, int height)
1499 {
1500 int src_wrap, x, y;
1501 int r, g, b;
1502 uint8_t *lum, *cb, *cr;
1503 const uint8_t *p;
1504
1505 lum = dst->data[0];
1506 cb = dst->data[1];
1507 cr = dst->data[2];
1508
1509 src_wrap = src->linesize[0] - width * BPP;
1510 p = src->data[0];
1511 for(y=0;y<height;y++) {
1512 for(x=0;x<width;x++) {
1513 RGB_IN(r, g, b, p);
1514 lum[0] = RGB_TO_Y(r, g, b);
1515 cb[0] = RGB_TO_U(r, g, b, 0);
1516 cr[0] = RGB_TO_V(r, g, b, 0);
1517 cb++;
1518 cr++;
1519 lum++;
1520 }
1521 p += src_wrap;
1522 lum += dst->linesize[0] - width;
1523 cb += dst->linesize[1] - width;
1524 cr += dst->linesize[2] - width;
1525 }
1526 }
1128 1527
1129 #undef RGB_IN 1528 #undef RGB_IN
1130 #undef RGB_OUT 1529 #undef RGB_OUT
1131 #undef BPP 1530 #undef BPP
1132 1531
1406 1805
1407 typedef struct ConvertEntry { 1806 typedef struct ConvertEntry {
1408 void (*convert)(AVPicture *dst, AVPicture *src, int width, int height); 1807 void (*convert)(AVPicture *dst, AVPicture *src, int width, int height);
1409 } ConvertEntry; 1808 } ConvertEntry;
1410 1809
1411 /* add each new convertion function in this table */ 1810 /* Add each new convertion function in this table. In order to be able
1412 /* constraints; 1811 to convert from any format to any format, the following constraints
1413 - all non YUV modes must convert at least to and from PIX_FMT_RGB24 1812 must be satisfied:
1813
1814 - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1815
1816 - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1817
1818 - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
1819
1820 - all PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1821 PIX_FMT_RGB24.
1822
1823 - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1414 */ 1824 */
1415 static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = { 1825 static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1416 [PIX_FMT_YUV420P] = { 1826 [PIX_FMT_YUV420P] = {
1417 [PIX_FMT_RGB555] = { 1827 [PIX_FMT_RGB555] = {
1418 .convert = yuv420p_to_rgb555 1828 .convert = yuv420p_to_rgb555
1428 }, 1838 },
1429 [PIX_FMT_RGBA32] = { 1839 [PIX_FMT_RGBA32] = {
1430 .convert = yuv420p_to_rgba32 1840 .convert = yuv420p_to_rgba32
1431 }, 1841 },
1432 }, 1842 },
1433 [PIX_FMT_YUV422P] = { 1843 [PIX_FMT_YUV422P] = {
1844 [PIX_FMT_YUV422] = {
1845 .convert = yuv422p_to_yuv422,
1846 },
1847 },
1848 [PIX_FMT_YUV444P] = {
1849 [PIX_FMT_RGB24] = {
1850 .convert = yuv444p_to_rgb24
1851 },
1852 },
1853 [PIX_FMT_YUVJ420P] = {
1434 [PIX_FMT_RGB555] = { 1854 [PIX_FMT_RGB555] = {
1435 .convert = yuv422p_to_rgb555 1855 .convert = yuvj420p_to_rgb555
1436 }, 1856 },
1437 [PIX_FMT_RGB565] = { 1857 [PIX_FMT_RGB565] = {
1438 .convert = yuv422p_to_rgb565 1858 .convert = yuvj420p_to_rgb565
1439 }, 1859 },
1440 [PIX_FMT_BGR24] = { 1860 [PIX_FMT_BGR24] = {
1441 .convert = yuv422p_to_bgr24 1861 .convert = yuvj420p_to_bgr24
1442 }, 1862 },
1443 [PIX_FMT_RGB24] = { 1863 [PIX_FMT_RGB24] = {
1444 .convert = yuv422p_to_rgb24 1864 .convert = yuvj420p_to_rgb24
1445 }, 1865 },
1446 [PIX_FMT_RGBA32] = { 1866 [PIX_FMT_RGBA32] = {
1447 .convert = yuv422p_to_rgba32 1867 .convert = yuvj420p_to_rgba32
1868 },
1869 },
1870 [PIX_FMT_YUVJ444P] = {
1871 [PIX_FMT_RGB24] = {
1872 .convert = yuvj444p_to_rgb24
1448 }, 1873 },
1449 }, 1874 },
1450 [PIX_FMT_YUV422] = { 1875 [PIX_FMT_YUV422] = {
1451 [PIX_FMT_YUV420P] = { 1876 [PIX_FMT_YUV420P] = {
1452 .convert = yuv422_to_yuv420p, 1877 .convert = yuv422_to_yuv420p,
1453 }, 1878 },
1879 [PIX_FMT_YUV422P] = {
1880 .convert = yuv422_to_yuv422p,
1881 },
1454 }, 1882 },
1455 1883
1456 [PIX_FMT_RGB24] = { 1884 [PIX_FMT_RGB24] = {
1457 [PIX_FMT_YUV420P] = { 1885 [PIX_FMT_YUV420P] = {
1458 .convert = rgb24_to_yuv420p 1886 .convert = rgb24_to_yuv420p
1466 [PIX_FMT_GRAY8] = { 1894 [PIX_FMT_GRAY8] = {
1467 .convert = rgb24_to_gray 1895 .convert = rgb24_to_gray
1468 }, 1896 },
1469 [PIX_FMT_PAL8] = { 1897 [PIX_FMT_PAL8] = {
1470 .convert = rgb24_to_pal8 1898 .convert = rgb24_to_pal8
1899 },
1900 [PIX_FMT_YUV444P] = {
1901 .convert = rgb24_to_yuv444p
1902 },
1903 [PIX_FMT_YUVJ420P] = {
1904 .convert = rgb24_to_yuvj420p
1905 },
1906 [PIX_FMT_YUVJ444P] = {
1907 .convert = rgb24_to_yuvj444p
1471 }, 1908 },
1472 }, 1909 },
1473 [PIX_FMT_RGBA32] = { 1910 [PIX_FMT_RGBA32] = {
1474 [PIX_FMT_YUV420P] = { 1911 [PIX_FMT_YUV420P] = {
1475 .convert = rgba32_to_yuv420p 1912 .convert = rgba32_to_yuv420p
1579 static void avpicture_free(AVPicture *picture) 2016 static void avpicture_free(AVPicture *picture)
1580 { 2017 {
1581 av_free(picture->data[0]); 2018 av_free(picture->data[0]);
1582 } 2019 }
1583 2020
2021 /* return true if yuv planar */
2022 static inline int is_yuv_planar(PixFmtInfo *ps)
2023 {
2024 return (ps->color_type == FF_COLOR_YUV ||
2025 ps->color_type == FF_COLOR_YUV_JPEG) && !ps->is_packed;
2026 }
2027
1584 /* XXX: always use linesize. Return -1 if not supported */ 2028 /* XXX: always use linesize. Return -1 if not supported */
1585 int img_convert(AVPicture *dst, int dst_pix_fmt, 2029 int img_convert(AVPicture *dst, int dst_pix_fmt,
1586 AVPicture *src, int src_pix_fmt, 2030 AVPicture *src, int src_pix_fmt,
1587 int src_width, int src_height) 2031 int src_width, int src_height)
1588 { 2032 {
2033 static int inited;
1589 int i, ret, dst_width, dst_height, int_pix_fmt; 2034 int i, ret, dst_width, dst_height, int_pix_fmt;
1590 PixFmtInfo *src_pix, *dst_pix; 2035 PixFmtInfo *src_pix, *dst_pix;
1591 ConvertEntry *ce; 2036 ConvertEntry *ce;
1592 AVPicture tmp1, *tmp = &tmp1; 2037 AVPicture tmp1, *tmp = &tmp1;
1593 2038
1594 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB || 2039 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
1595 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB) 2040 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
1596 return -1; 2041 return -1;
1597 if (src_width <= 0 || src_height <= 0) 2042 if (src_width <= 0 || src_height <= 0)
1598 return 0; 2043 return 0;
2044
2045 if (!inited) {
2046 inited = 1;
2047 img_convert_init();
2048 }
1599 2049
1600 dst_width = src_width; 2050 dst_width = src_width;
1601 dst_height = src_height; 2051 dst_height = src_height;
1602 2052
1603 dst_pix = &pix_fmt_info[dst_pix_fmt]; 2053 dst_pix = &pix_fmt_info[dst_pix_fmt];
1607 /* same format: just copy */ 2057 /* same format: just copy */
1608 for(i = 0; i < dst_pix->nb_components; i++) { 2058 for(i = 0; i < dst_pix->nb_components; i++) {
1609 int w, h; 2059 int w, h;
1610 w = dst_width; 2060 w = dst_width;
1611 h = dst_height; 2061 h = dst_height;
1612 if ((dst_pix->color_type == FF_COLOR_YUV || 2062 if (is_yuv_planar(dst_pix) && (i == 1 || i == 2)) {
1613 dst_pix->color_type == FF_COLOR_YUV_JPEG) &&
1614 (i == 1 || i == 2)) {
1615 w >>= dst_pix->x_chroma_shift; 2063 w >>= dst_pix->x_chroma_shift;
1616 h >>= dst_pix->y_chroma_shift; 2064 h >>= dst_pix->y_chroma_shift;
1617 } 2065 }
1618 img_copy(dst->data[i], dst->linesize[i], 2066 img_copy(dst->data[i], dst->linesize[i],
1619 src->data[i], src->linesize[i], 2067 src->data[i], src->linesize[i],
1628 ce->convert(dst, src, dst_width, dst_height); 2076 ce->convert(dst, src, dst_width, dst_height);
1629 return 0; 2077 return 0;
1630 } 2078 }
1631 2079
1632 /* gray to YUV */ 2080 /* gray to YUV */
1633 if ((dst_pix->color_type == FF_COLOR_YUV || 2081 if (is_yuv_planar(dst_pix) &&
1634 dst_pix->color_type == FF_COLOR_YUV_JPEG) &&
1635 src_pix_fmt == PIX_FMT_GRAY8) { 2082 src_pix_fmt == PIX_FMT_GRAY8) {
1636 int w, h, y; 2083 int w, h, y;
1637 uint8_t *d; 2084 uint8_t *d;
1638 2085
1639 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) { 2086 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
1640 img_copy(dst->data[0], dst->linesize[0], 2087 img_copy(dst->data[0], dst->linesize[0],
1641 src->data[0], src->linesize[0], 2088 src->data[0], src->linesize[0],
1642 dst_width, dst_height); 2089 dst_width, dst_height);
1643 } else { 2090 } else {
1644 gray_to_luma_ccir(dst->data[0], dst->linesize[0], 2091 img_apply_table(dst->data[0], dst->linesize[0],
1645 src->data[0], src->linesize[0], 2092 src->data[0], src->linesize[0],
1646 dst_width, dst_height); 2093 dst_width, dst_height,
2094 y_jpeg_to_ccir);
1647 } 2095 }
1648 /* fill U and V with 128 */ 2096 /* fill U and V with 128 */
1649 w = dst_width; 2097 w = dst_width;
1650 h = dst_height; 2098 h = dst_height;
1651 w >>= dst_pix->x_chroma_shift; 2099 w >>= dst_pix->x_chroma_shift;
1659 } 2107 }
1660 return 0; 2108 return 0;
1661 } 2109 }
1662 2110
1663 /* YUV to gray */ 2111 /* YUV to gray */
1664 if ((src_pix->color_type == FF_COLOR_YUV || 2112 if (is_yuv_planar(src_pix) &&
1665 src_pix->color_type == FF_COLOR_YUV_JPEG) &&
1666 dst_pix_fmt == PIX_FMT_GRAY8) { 2113 dst_pix_fmt == PIX_FMT_GRAY8) {
1667 if (src_pix->color_type == FF_COLOR_YUV_JPEG) { 2114 if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
1668 img_copy(dst->data[0], dst->linesize[0], 2115 img_copy(dst->data[0], dst->linesize[0],
1669 src->data[0], src->linesize[0], 2116 src->data[0], src->linesize[0],
1670 dst_width, dst_height); 2117 dst_width, dst_height);
1671 } else { 2118 } else {
1672 luma_ccir_to_gray(dst->data[0], dst->linesize[0], 2119 img_apply_table(dst->data[0], dst->linesize[0],
1673 src->data[0], src->linesize[0], 2120 src->data[0], src->linesize[0],
1674 dst_width, dst_height); 2121 dst_width, dst_height,
2122 y_ccir_to_jpeg);
1675 } 2123 }
1676 return 0; 2124 return 0;
1677 } 2125 }
1678 2126
1679 /* YUV to YUV */ 2127 /* YUV to YUV planar */
1680 if (dst_pix->color_type == FF_COLOR_YUV && 2128 if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
1681 dst_pix->color_type == src_pix->color_type) {
1682 int x_shift, y_shift, w, h; 2129 int x_shift, y_shift, w, h;
1683 void (*resize_func)(uint8_t *dst, int dst_wrap, 2130 void (*resize_func)(uint8_t *dst, int dst_wrap,
1684 uint8_t *src, int src_wrap, 2131 uint8_t *src, int src_wrap,
1685 int width, int height); 2132 int width, int height);
1686 2133
1696 else 2143 else
1697 h >>= src_pix->y_chroma_shift; 2144 h >>= src_pix->y_chroma_shift;
1698 2145
1699 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift); 2146 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
1700 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift); 2147 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2148
1701 if (x_shift == 0 && y_shift == 0) { 2149 if (x_shift == 0 && y_shift == 0) {
1702 resize_func = img_copy; /* should never happen */ 2150 resize_func = img_copy;
1703 } else if (x_shift == 0 && y_shift == 1) { 2151 } else if (x_shift == 0 && y_shift == 1) {
1704 resize_func = shrink2; 2152 resize_func = shrink2;
1705 } else if (x_shift == 1 && y_shift == 1) { 2153 } else if (x_shift == 1 && y_shift == 1) {
1706 resize_func = shrink22; 2154 resize_func = shrink22;
1707 } else if (x_shift == -1 && y_shift == -1) { 2155 } else if (x_shift == -1 && y_shift == -1) {
1719 2167
1720 for(i = 1;i <= 2; i++) 2168 for(i = 1;i <= 2; i++)
1721 resize_func(dst->data[i], dst->linesize[i], 2169 resize_func(dst->data[i], dst->linesize[i],
1722 src->data[i], src->linesize[i], 2170 src->data[i], src->linesize[i],
1723 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift); 2171 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
1724 return 0; 2172 /* if yuv color space conversion is needed, we do it here on
2173 the destination image */
2174 if (dst_pix->color_type != src_pix->color_type) {
2175 const uint8_t *y_table, *c_table;
2176 if (dst_pix->color_type == FF_COLOR_YUV) {
2177 y_table = y_jpeg_to_ccir;
2178 c_table = c_jpeg_to_ccir;
2179 } else {
2180 y_table = y_ccir_to_jpeg;
2181 c_table = c_ccir_to_jpeg;
2182 }
2183 img_apply_table(dst->data[0], dst->linesize[0],
2184 dst->data[0], dst->linesize[0],
2185 dst_width, dst_height,
2186 y_table);
2187
2188 for(i = 1;i <= 2; i++)
2189 img_apply_table(dst->data[i], dst->linesize[i],
2190 dst->data[i], dst->linesize[i],
2191 dst_width>>dst_pix->x_chroma_shift,
2192 dst_height>>dst_pix->y_chroma_shift,
2193 c_table);
2194 }
2195 return 0;
1725 } 2196 }
1726 2197
1727 /* try to use an intermediate format */ 2198 /* try to use an intermediate format */
1728 if (src_pix_fmt == PIX_FMT_MONOWHITE || 2199 if (src_pix_fmt == PIX_FMT_YUV422 ||
1729 src_pix_fmt == PIX_FMT_MONOBLACK || 2200 dst_pix_fmt == PIX_FMT_YUV422) {
1730 dst_pix_fmt == PIX_FMT_MONOWHITE || 2201 /* specific case: convert to YUV422P first */
1731 dst_pix_fmt == PIX_FMT_MONOBLACK) { 2202 int_pix_fmt = PIX_FMT_YUV422P;
2203 } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2204 src_pix_fmt != PIX_FMT_GRAY8) ||
2205 (dst_pix->color_type == FF_COLOR_GRAY &&
2206 dst_pix_fmt != PIX_FMT_GRAY8)) {
2207 /* gray8 is the normalized format */
1732 int_pix_fmt = PIX_FMT_GRAY8; 2208 int_pix_fmt = PIX_FMT_GRAY8;
2209 } else if ((is_yuv_planar(src_pix) &&
2210 src_pix_fmt != PIX_FMT_YUV444P &&
2211 src_pix_fmt != PIX_FMT_YUVJ444P)) {
2212 /* yuv444 is the normalized format */
2213 if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2214 int_pix_fmt = PIX_FMT_YUVJ444P;
2215 else
2216 int_pix_fmt = PIX_FMT_YUV444P;
2217 } else if ((is_yuv_planar(dst_pix) &&
2218 dst_pix_fmt != PIX_FMT_YUV444P &&
2219 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2220 /* yuv444 is the normalized format */
2221 if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2222 int_pix_fmt = PIX_FMT_YUVJ444P;
2223 else
2224 int_pix_fmt = PIX_FMT_YUV444P;
1733 } else { 2225 } else {
1734 int_pix_fmt = PIX_FMT_RGB24; 2226 /* the two formats are rgb or gray8 or yuv[j]444p */
2227 if (src_pix->is_alpha && dst_pix->is_alpha)
2228 int_pix_fmt = PIX_FMT_RGBA32;
2229 else
2230 int_pix_fmt = PIX_FMT_RGB24;
1735 } 2231 }
1736 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0) 2232 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
1737 return -1; 2233 return -1;
1738 ret = -1; 2234 ret = -1;
1739 if (img_convert(tmp, int_pix_fmt, 2235 if (img_convert(tmp, int_pix_fmt,