summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2011-12-03 21:48:34 +0000
committerRafaël Carré <rafael.carre@gmail.com>2011-12-03 21:48:34 +0000
commit1414e837430eef49822233a8bb1fa6587335d859 (patch)
treed0f22cda924745ebdfc1c117807fed7455e34897
parent2c523acf3f4cebd79f272a5b77313057f62ad807 (diff)
downloadrockbox-1414e837430eef49822233a8bb1fa6587335d859.tar.gz
rockbox-1414e837430eef49822233a8bb1fa6587335d859.zip
lcd_blit_yuv: move to lcd-16bit-common.c
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31129 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/lcd-16bit-common.c204
-rw-r--r--firmware/drivers/lcd-16bit.c204
2 files changed, 204 insertions, 204 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c
index 47f5968228..89d6dce966 100644
--- a/firmware/drivers/lcd-16bit-common.c
+++ b/firmware/drivers/lcd-16bit-common.c
@@ -589,3 +589,207 @@ void ICODE_ATTR lcd_bmp(const struct bitmap *bmp, int x, int y)
589{ 589{
590 lcd_bmp_part(bmp, 0, 0, x, y, bmp->width, bmp->height); 590 lcd_bmp_part(bmp, 0, 0, x, y, bmp->width, bmp->height);
591} 591}
592
593/**
594 * |R| |1.000000 -0.000001 1.402000| |Y'|
595 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
596 * |B| |1.000000 1.772000 0.000000| |Pr|
597 * Scaled, normalized, rounded and tweaked to yield RGB 565:
598 * |R| |74 0 101| |Y' - 16| >> 9
599 * |G| = |74 -24 -51| |Cb - 128| >> 8
600 * |B| |74 128 0| |Cr - 128| >> 9
601 */
602#define YFAC (74)
603#define RVFAC (101)
604#define GUFAC (-24)
605#define GVFAC (-51)
606#define BUFAC (128)
607
608static inline int clamp(int val, int min, int max)
609{
610 if (val < min)
611 val = min;
612 else if (val > max)
613 val = max;
614 return val;
615}
616
617__attribute__((weak)) void lcd_yuv_set_options(unsigned options)
618{
619 (void)options;
620}
621
622/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
623 in the core */
624
625__attribute__((weak)) void lcd_blit_yuv(unsigned char * const src[3],
626 int src_x, int src_y, int stride,
627 int x, int y, int width, int height)
628{
629 const unsigned char *ysrc, *usrc, *vsrc;
630 int linecounter;
631 fb_data *dst, *row_end;
632 long z;
633
634 /* width and height must be >= 2 and an even number */
635 width &= ~1;
636 linecounter = height >> 1;
637
638#if LCD_WIDTH >= LCD_HEIGHT
639 dst = &lcd_framebuffer[y][x];
640 row_end = dst + width;
641#else
642 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
643 row_end = dst + LCD_WIDTH * width;
644#endif
645
646 z = stride * src_y;
647 ysrc = src[0] + z + src_x;
648 usrc = src[1] + (z >> 2) + (src_x >> 1);
649 vsrc = src[2] + (usrc - src[1]);
650
651 /* stride => amount to jump from end of last row to start of next */
652 stride -= width;
653
654 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
655
656 do
657 {
658 do
659 {
660 int y, cb, cr, rv, guv, bu, r, g, b;
661
662 y = YFAC*(*ysrc++ - 16);
663 cb = *usrc++ - 128;
664 cr = *vsrc++ - 128;
665
666 rv = RVFAC*cr;
667 guv = GUFAC*cb + GVFAC*cr;
668 bu = BUFAC*cb;
669
670 r = y + rv;
671 g = y + guv;
672 b = y + bu;
673
674 if ((unsigned)(r | g | b) > 64*256-1)
675 {
676 r = clamp(r, 0, 64*256-1);
677 g = clamp(g, 0, 64*256-1);
678 b = clamp(b, 0, 64*256-1);
679 }
680
681 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
682
683#if LCD_WIDTH >= LCD_HEIGHT
684 dst++;
685#else
686 dst += LCD_WIDTH;
687#endif
688
689 y = YFAC*(*ysrc++ - 16);
690 r = y + rv;
691 g = y + guv;
692 b = y + bu;
693
694 if ((unsigned)(r | g | b) > 64*256-1)
695 {
696 r = clamp(r, 0, 64*256-1);
697 g = clamp(g, 0, 64*256-1);
698 b = clamp(b, 0, 64*256-1);
699 }
700
701 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
702
703#if LCD_WIDTH >= LCD_HEIGHT
704 dst++;
705#else
706 dst += LCD_WIDTH;
707#endif
708 }
709 while (dst < row_end);
710
711 ysrc += stride;
712 usrc -= width >> 1;
713 vsrc -= width >> 1;
714
715#if LCD_WIDTH >= LCD_HEIGHT
716 row_end += LCD_WIDTH;
717 dst += LCD_WIDTH - width;
718#else
719 row_end -= 1;
720 dst -= LCD_WIDTH*width + 1;
721#endif
722
723 do
724 {
725 int y, cb, cr, rv, guv, bu, r, g, b;
726
727 y = YFAC*(*ysrc++ - 16);
728 cb = *usrc++ - 128;
729 cr = *vsrc++ - 128;
730
731 rv = RVFAC*cr;
732 guv = GUFAC*cb + GVFAC*cr;
733 bu = BUFAC*cb;
734
735 r = y + rv;
736 g = y + guv;
737 b = y + bu;
738
739 if ((unsigned)(r | g | b) > 64*256-1)
740 {
741 r = clamp(r, 0, 64*256-1);
742 g = clamp(g, 0, 64*256-1);
743 b = clamp(b, 0, 64*256-1);
744 }
745
746 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
747
748#if LCD_WIDTH >= LCD_HEIGHT
749 dst++;
750#else
751 dst += LCD_WIDTH;
752#endif
753
754 y = YFAC*(*ysrc++ - 16);
755 r = y + rv;
756 g = y + guv;
757 b = y + bu;
758
759 if ((unsigned)(r | g | b) > 64*256-1)
760 {
761 r = clamp(r, 0, 64*256-1);
762 g = clamp(g, 0, 64*256-1);
763 b = clamp(b, 0, 64*256-1);
764 }
765
766 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
767
768#if LCD_WIDTH >= LCD_HEIGHT
769 dst++;
770#else
771 dst += LCD_WIDTH;
772#endif
773 }
774 while (dst < row_end);
775
776 ysrc += stride;
777 usrc += stride >> 1;
778 vsrc += stride >> 1;
779
780#if LCD_WIDTH >= LCD_HEIGHT
781 row_end += LCD_WIDTH;
782 dst += LCD_WIDTH - width;
783#else
784 row_end -= 1;
785 dst -= LCD_WIDTH*width + 1;
786#endif
787 }
788 while (--linecounter > 0);
789
790#if LCD_WIDTH >= LCD_HEIGHT
791 lcd_update_rect(x, y, width, height);
792#else
793 lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
794#endif
795}
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 300dbba9ac..844db296c6 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -913,210 +913,6 @@ void lcd_bitmap_transparent(const fb_data *src, int x, int y,
913 lcd_bitmap_transparent_part(src, 0, 0, width, x, y, width, height); 913 lcd_bitmap_transparent_part(src, 0, 0, width, x, y, width, height);
914} 914}
915 915
916/**
917 * |R| |1.000000 -0.000001 1.402000| |Y'|
918 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
919 * |B| |1.000000 1.772000 0.000000| |Pr|
920 * Scaled, normalized, rounded and tweaked to yield RGB 565:
921 * |R| |74 0 101| |Y' - 16| >> 9
922 * |G| = |74 -24 -51| |Cb - 128| >> 8
923 * |B| |74 128 0| |Cr - 128| >> 9
924 */
925#define YFAC (74)
926#define RVFAC (101)
927#define GUFAC (-24)
928#define GVFAC (-51)
929#define BUFAC (128)
930
931static inline int clamp(int val, int min, int max)
932{
933 if (val < min)
934 val = min;
935 else if (val > max)
936 val = max;
937 return val;
938}
939
940__attribute__((weak)) void lcd_yuv_set_options(unsigned options)
941{
942 (void)options;
943}
944
945/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
946 in the core */
947
948__attribute__((weak)) void lcd_blit_yuv(unsigned char * const src[3],
949 int src_x, int src_y, int stride,
950 int x, int y, int width, int height)
951{
952 const unsigned char *ysrc, *usrc, *vsrc;
953 int linecounter;
954 fb_data *dst, *row_end;
955 long z;
956
957 /* width and height must be >= 2 and an even number */
958 width &= ~1;
959 linecounter = height >> 1;
960
961#if LCD_WIDTH >= LCD_HEIGHT
962 dst = &lcd_framebuffer[y][x];
963 row_end = dst + width;
964#else
965 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
966 row_end = dst + LCD_WIDTH * width;
967#endif
968
969 z = stride * src_y;
970 ysrc = src[0] + z + src_x;
971 usrc = src[1] + (z >> 2) + (src_x >> 1);
972 vsrc = src[2] + (usrc - src[1]);
973
974 /* stride => amount to jump from end of last row to start of next */
975 stride -= width;
976
977 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
978
979 do
980 {
981 do
982 {
983 int y, cb, cr, rv, guv, bu, r, g, b;
984
985 y = YFAC*(*ysrc++ - 16);
986 cb = *usrc++ - 128;
987 cr = *vsrc++ - 128;
988
989 rv = RVFAC*cr;
990 guv = GUFAC*cb + GVFAC*cr;
991 bu = BUFAC*cb;
992
993 r = y + rv;
994 g = y + guv;
995 b = y + bu;
996
997 if ((unsigned)(r | g | b) > 64*256-1)
998 {
999 r = clamp(r, 0, 64*256-1);
1000 g = clamp(g, 0, 64*256-1);
1001 b = clamp(b, 0, 64*256-1);
1002 }
1003
1004 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
1005
1006#if LCD_WIDTH >= LCD_HEIGHT
1007 dst++;
1008#else
1009 dst += LCD_WIDTH;
1010#endif
1011
1012 y = YFAC*(*ysrc++ - 16);
1013 r = y + rv;
1014 g = y + guv;
1015 b = y + bu;
1016
1017 if ((unsigned)(r | g | b) > 64*256-1)
1018 {
1019 r = clamp(r, 0, 64*256-1);
1020 g = clamp(g, 0, 64*256-1);
1021 b = clamp(b, 0, 64*256-1);
1022 }
1023
1024 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
1025
1026#if LCD_WIDTH >= LCD_HEIGHT
1027 dst++;
1028#else
1029 dst += LCD_WIDTH;
1030#endif
1031 }
1032 while (dst < row_end);
1033
1034 ysrc += stride;
1035 usrc -= width >> 1;
1036 vsrc -= width >> 1;
1037
1038#if LCD_WIDTH >= LCD_HEIGHT
1039 row_end += LCD_WIDTH;
1040 dst += LCD_WIDTH - width;
1041#else
1042 row_end -= 1;
1043 dst -= LCD_WIDTH*width + 1;
1044#endif
1045
1046 do
1047 {
1048 int y, cb, cr, rv, guv, bu, r, g, b;
1049
1050 y = YFAC*(*ysrc++ - 16);
1051 cb = *usrc++ - 128;
1052 cr = *vsrc++ - 128;
1053
1054 rv = RVFAC*cr;
1055 guv = GUFAC*cb + GVFAC*cr;
1056 bu = BUFAC*cb;
1057
1058 r = y + rv;
1059 g = y + guv;
1060 b = y + bu;
1061
1062 if ((unsigned)(r | g | b) > 64*256-1)
1063 {
1064 r = clamp(r, 0, 64*256-1);
1065 g = clamp(g, 0, 64*256-1);
1066 b = clamp(b, 0, 64*256-1);
1067 }
1068
1069 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
1070
1071#if LCD_WIDTH >= LCD_HEIGHT
1072 dst++;
1073#else
1074 dst += LCD_WIDTH;
1075#endif
1076
1077 y = YFAC*(*ysrc++ - 16);
1078 r = y + rv;
1079 g = y + guv;
1080 b = y + bu;
1081
1082 if ((unsigned)(r | g | b) > 64*256-1)
1083 {
1084 r = clamp(r, 0, 64*256-1);
1085 g = clamp(g, 0, 64*256-1);
1086 b = clamp(b, 0, 64*256-1);
1087 }
1088
1089 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
1090
1091#if LCD_WIDTH >= LCD_HEIGHT
1092 dst++;
1093#else
1094 dst += LCD_WIDTH;
1095#endif
1096 }
1097 while (dst < row_end);
1098
1099 ysrc += stride;
1100 usrc += stride >> 1;
1101 vsrc += stride >> 1;
1102
1103#if LCD_WIDTH >= LCD_HEIGHT
1104 row_end += LCD_WIDTH;
1105 dst += LCD_WIDTH - width;
1106#else
1107 row_end -= 1;
1108 dst -= LCD_WIDTH*width + 1;
1109#endif
1110 }
1111 while (--linecounter > 0);
1112
1113#if LCD_WIDTH >= LCD_HEIGHT
1114 lcd_update_rect(x, y, width, height);
1115#else
1116 lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
1117#endif
1118}
1119
1120#define ROW_INC LCD_WIDTH 916#define ROW_INC LCD_WIDTH
1121#define COL_INC 1 917#define COL_INC 1
1122 918