Mercurial > libavcodec.hg
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, |