comparison imgconvert.c @ 993:895d3b01c6f4 libavcodec

added missing formats in all functions - added monoblack, monowhite and gray8 support for most conversions
author bellard
date Sat, 11 Jan 2003 04:54:38 +0000
parents fe9083c56733
children 48349e11c9b2
comparison
equal deleted inserted replaced
992:b9ca09e5c9ad 993:895d3b01c6f4
127 return "???"; 127 return "???";
128 else 128 else
129 return pix_fmt_info[pix_fmt].name; 129 return pix_fmt_info[pix_fmt].name;
130 } 130 }
131 131
132 /* Picture field are filled with 'ptr' addresses. Also return size */
133 int avpicture_fill(AVPicture *picture, UINT8 *ptr,
134 int pix_fmt, int width, int height)
135 {
136 int size;
137
138 size = width * height;
139 switch(pix_fmt) {
140 case PIX_FMT_YUV420P:
141 picture->data[0] = ptr;
142 picture->data[1] = picture->data[0] + size;
143 picture->data[2] = picture->data[1] + size / 4;
144 picture->linesize[0] = width;
145 picture->linesize[1] = width / 2;
146 picture->linesize[2] = width / 2;
147 return (size * 3) / 2;
148 case PIX_FMT_RGB24:
149 case PIX_FMT_BGR24:
150 picture->data[0] = ptr;
151 picture->data[1] = NULL;
152 picture->data[2] = NULL;
153 picture->linesize[0] = width * 3;
154 return size * 3;
155 case PIX_FMT_YUV422P:
156 picture->data[0] = ptr;
157 picture->data[1] = picture->data[0] + size;
158 picture->data[2] = picture->data[1] + size / 2;
159 picture->linesize[0] = width;
160 picture->linesize[1] = width / 2;
161 picture->linesize[2] = width / 2;
162 return (size * 2);
163 case PIX_FMT_YUV444P:
164 picture->data[0] = ptr;
165 picture->data[1] = picture->data[0] + size;
166 picture->data[2] = picture->data[1] + size;
167 picture->linesize[0] = width;
168 picture->linesize[1] = width;
169 picture->linesize[2] = width;
170 return size * 3;
171 case PIX_FMT_RGBA32:
172 picture->data[0] = ptr;
173 picture->data[1] = NULL;
174 picture->data[2] = NULL;
175 picture->linesize[0] = width * 4;
176 return size * 4;
177 case PIX_FMT_YUV410P:
178 picture->data[0] = ptr;
179 picture->data[1] = picture->data[0] + size;
180 picture->data[2] = picture->data[1] + size / 16;
181 picture->linesize[0] = width;
182 picture->linesize[1] = width / 4;
183 picture->linesize[2] = width / 4;
184 return size + (size / 8);
185 case PIX_FMT_YUV411P:
186 picture->data[0] = ptr;
187 picture->data[1] = picture->data[0] + size;
188 picture->data[2] = picture->data[1] + size / 4;
189 picture->linesize[0] = width;
190 picture->linesize[1] = width / 4;
191 picture->linesize[2] = width / 4;
192 return size + (size / 2);
193 case PIX_FMT_RGB555:
194 case PIX_FMT_RGB565:
195 case PIX_FMT_YUV422:
196 picture->data[0] = ptr;
197 picture->data[1] = NULL;
198 picture->data[2] = NULL;
199 picture->linesize[0] = width * 2;
200 return size * 2;
201 case PIX_FMT_GRAY8:
202 picture->data[0] = ptr;
203 picture->data[1] = NULL;
204 picture->data[2] = NULL;
205 picture->linesize[0] = width;
206 return size;
207 case PIX_FMT_MONOWHITE:
208 case PIX_FMT_MONOBLACK:
209 picture->data[0] = ptr;
210 picture->data[1] = NULL;
211 picture->data[2] = NULL;
212 picture->linesize[0] = (width + 7) >> 3;
213 return picture->linesize[0] * height;
214 default:
215 picture->data[0] = NULL;
216 picture->data[1] = NULL;
217 picture->data[2] = NULL;
218 return -1;
219 }
220 }
221
222 int avpicture_get_size(int pix_fmt, int width, int height)
223 {
224 AVPicture dummy_pict;
225 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
226 }
227
228
132 /* XXX: totally non optimized */ 229 /* XXX: totally non optimized */
133 230
134 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src, 231 static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src,
135 int width, int height) 232 int width, int height)
136 { 233 {
718 p += src_wrap; 815 p += src_wrap;
719 q += dst_wrap; 816 q += dst_wrap;
720 } 817 }
721 } 818 }
722 819
723 static void monowhite_to_rgb24(AVPicture *dst, AVPicture *src, 820 static void mono_to_gray(AVPicture *dst, AVPicture *src,
724 int width, int height) 821 int width, int height, int xor_mask)
725 { 822 {
726 const unsigned char *p; 823 const unsigned char *p;
727 unsigned char *q; 824 unsigned char *q;
728 int v, dst_wrap, src_wrap; 825 int v, dst_wrap, src_wrap;
729 int y, w; 826 int y, w;
730 827
731 p = src->data[0]; 828 p = src->data[0];
732 src_wrap = src->linesize[0] - ((width + 7) >> 3); 829 src_wrap = src->linesize[0] - ((width + 7) >> 3);
733 830
734 q = dst->data[0]; 831 q = dst->data[0];
735 dst_wrap = dst->linesize[0] - 3 * width; 832 dst_wrap = dst->linesize[0] - width;
736
737 for(y=0;y<height;y++) { 833 for(y=0;y<height;y++) {
738 w = width; 834 w = width;
739 while (w >= 8) { 835 while (w >= 8) {
740 v = *p++ ^ 0xff; 836 v = *p++ ^ xor_mask;
741 q[0] = q[1] = q[2] = -(v >> 7); q += 3; 837 q[0] = -(v >> 7);
742 q[0] = q[1] = q[2] = -((v >> 6) & 1); q += 3; 838 q[1] = -((v >> 6) & 1);
743 q[0] = q[1] = q[2] = -((v >> 5) & 1); q += 3; 839 q[2] = -((v >> 5) & 1);
744 q[0] = q[1] = q[2] = -((v >> 4) & 1); q += 3; 840 q[3] = -((v >> 4) & 1);
745 q[0] = q[1] = q[2] = -((v >> 3) & 1); q += 3; 841 q[4] = -((v >> 3) & 1);
746 q[0] = q[1] = q[2] = -((v >> 2) & 1); q += 3; 842 q[5] = -((v >> 2) & 1);
747 q[0] = q[1] = q[2] = -((v >> 1) & 1); q += 3; 843 q[6] = -((v >> 1) & 1);
748 q[0] = q[1] = q[2] = -((v >> 0) & 1); q += 3; 844 q[7] = -((v >> 0) & 1);
749 w -= 8; 845 w -= 8;
846 q += 8;
750 } 847 }
751 if (w > 0) { 848 if (w > 0) {
752 v = *p++ ^ 0xff; 849 v = *p++ ^ xor_mask;
753 do { 850 do {
754 q[0] = q[1] = q[2] = -((v >> 7) & 1); q += 3; 851 q[0] = -((v >> 7) & 1);
852 q++;
755 v <<= 1; 853 v <<= 1;
756 } while (--w); 854 } while (--w);
757 } 855 }
758 p += src_wrap; 856 p += src_wrap;
759 q += dst_wrap; 857 q += dst_wrap;
760 } 858 }
761 } 859 }
762 860
763 static void monoblack_to_rgb24(AVPicture *dst, AVPicture *src, 861 static void monowhite_to_gray(AVPicture *dst, AVPicture *src,
764 int width, int height) 862 int width, int height)
765 { 863 {
766 const unsigned char *p; 864 mono_to_gray(dst, src, width, height, 0xff);
767 unsigned char *q; 865 }
768 int v, dst_wrap, src_wrap; 866
769 int y, w; 867 static void monoblack_to_gray(AVPicture *dst, AVPicture *src,
770 868 int width, int height)
771 p = src->data[0]; 869 {
772 src_wrap = src->linesize[0] - ((width + 7) >> 3); 870 mono_to_gray(dst, src, width, height, 0x00);
773 871 }
774 q = dst->data[0]; 872
775 dst_wrap = dst->linesize[0] - 3 * width; 873 static void gray_to_mono(AVPicture *dst, AVPicture *src,
874 int width, int height, int xor_mask)
875 {
876 int n;
877 const UINT8 *s;
878 UINT8 *d;
879 int j, b, v, n1, src_wrap, dst_wrap, y;
880
881 s = src->data[0];
882 src_wrap = src->linesize[0] - width;
883
884 d = dst->data[0];
885 dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
886 printf("%d %d\n", width, height);
776 887
777 for(y=0;y<height;y++) { 888 for(y=0;y<height;y++) {
778 w = width; 889 n = width;
779 while (w >= 8) { 890 while (n >= 8) {
780 v = *p++; 891 v = 0;
781 q[0] = q[1] = q[2] = -(v >> 7); q += 3; 892 for(j=0;j<8;j++) {
782 q[0] = q[1] = q[2] = -((v >> 6) & 1); q += 3; 893 b = s[0];
783 q[0] = q[1] = q[2] = -((v >> 5) & 1); q += 3; 894 s++;
784 q[0] = q[1] = q[2] = -((v >> 4) & 1); q += 3; 895 v = (v << 1) | (b >> 7);
785 q[0] = q[1] = q[2] = -((v >> 3) & 1); q += 3; 896 }
786 q[0] = q[1] = q[2] = -((v >> 2) & 1); q += 3; 897 d[0] = v ^ xor_mask;
787 q[0] = q[1] = q[2] = -((v >> 1) & 1); q += 3; 898 d++;
788 q[0] = q[1] = q[2] = -((v >> 0) & 1); q += 3; 899 n -= 8;
789 w -= 8; 900 }
790 } 901 if (n > 0) {
791 if (w > 0) { 902 n1 = n;
792 v = *p++; 903 v = 0;
793 do { 904 while (n > 0) {
794 q[0] = q[1] = q[2] = -((v >> 7) & 1); q += 3; 905 b = s[0];
795 v <<= 1; 906 s++;
796 } while (--w); 907 v = (v << 1) | (b >> 7);
797 } 908 n--;
798 p += src_wrap; 909 }
799 q += dst_wrap; 910 d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
800 } 911 d++;
912 }
913 s += src_wrap;
914 d += dst_wrap;
915 }
916 }
917
918 static void gray_to_monowhite(AVPicture *dst, AVPicture *src,
919 int width, int height)
920 {
921 gray_to_mono(dst, src, width, height, 0xff);
922 }
923
924 static void gray_to_monoblack(AVPicture *dst, AVPicture *src,
925 int width, int height)
926 {
927 gray_to_mono(dst, src, width, height, 0x00);
801 } 928 }
802 929
803 typedef struct ConvertEntry { 930 typedef struct ConvertEntry {
804 void (*convert)(AVPicture *dst, AVPicture *src, int width, int height); 931 void (*convert)(AVPicture *dst, AVPicture *src, int width, int height);
805 } ConvertEntry; 932 } ConvertEntry;
885 }, 1012 },
886 [PIX_FMT_GRAY8] = { 1013 [PIX_FMT_GRAY8] = {
887 [PIX_FMT_RGB24] = { 1014 [PIX_FMT_RGB24] = {
888 convert: gray_to_rgb24 1015 convert: gray_to_rgb24
889 }, 1016 },
1017 [PIX_FMT_MONOWHITE] = {
1018 convert: gray_to_monowhite
1019 },
1020 [PIX_FMT_MONOBLACK] = {
1021 convert: gray_to_monoblack
1022 },
890 }, 1023 },
891 [PIX_FMT_MONOWHITE] = { 1024 [PIX_FMT_MONOWHITE] = {
892 [PIX_FMT_RGB24] = { 1025 [PIX_FMT_GRAY8] = {
893 convert: monowhite_to_rgb24 1026 convert: monowhite_to_gray
894 }, 1027 },
895 }, 1028 },
896 [PIX_FMT_MONOBLACK] = { 1029 [PIX_FMT_MONOBLACK] = {
897 [PIX_FMT_RGB24] = { 1030 [PIX_FMT_GRAY8] = {
898 convert: monoblack_to_rgb24 1031 convert: monoblack_to_gray
899 }, 1032 },
900 }, 1033 },
901 }; 1034 };
902 1035
903 static int avpicture_alloc(AVPicture *picture, 1036 static int avpicture_alloc(AVPicture *picture,
927 /* XXX: always use linesize. Return -1 if not supported */ 1060 /* XXX: always use linesize. Return -1 if not supported */
928 int img_convert(AVPicture *dst, int dst_pix_fmt, 1061 int img_convert(AVPicture *dst, int dst_pix_fmt,
929 AVPicture *src, int src_pix_fmt, 1062 AVPicture *src, int src_pix_fmt,
930 int src_width, int src_height) 1063 int src_width, int src_height)
931 { 1064 {
932 int i, ret, dst_width, dst_height; 1065 int i, ret, dst_width, dst_height, int_pix_fmt;
933 PixFmtInfo *src_pix, *dst_pix; 1066 PixFmtInfo *src_pix, *dst_pix;
934 ConvertEntry *ce; 1067 ConvertEntry *ce;
935 AVPicture tmp1, *tmp = &tmp1; 1068 AVPicture tmp1, *tmp = &tmp1;
936 1069
937 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB || 1070 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
944 dst_height = src_height; 1077 dst_height = src_height;
945 1078
946 dst_pix = &pix_fmt_info[dst_pix_fmt]; 1079 dst_pix = &pix_fmt_info[dst_pix_fmt];
947 src_pix = &pix_fmt_info[src_pix_fmt]; 1080 src_pix = &pix_fmt_info[src_pix_fmt];
948 if (src_pix_fmt == dst_pix_fmt) { 1081 if (src_pix_fmt == dst_pix_fmt) {
1082 /* XXX: incorrect */
949 /* same format: just copy */ 1083 /* same format: just copy */
950 for(i = 0; i < dst_pix->nb_components; i++) { 1084 for(i = 0; i < dst_pix->nb_components; i++) {
951 int w, h; 1085 int w, h;
952 w = dst_width; 1086 w = dst_width;
953 h = dst_height; 1087 h = dst_height;
967 /* specific convertion routine */ 1101 /* specific convertion routine */
968 ce->convert(dst, src, dst_width, dst_height); 1102 ce->convert(dst, src, dst_width, dst_height);
969 return 0; 1103 return 0;
970 } 1104 }
971 1105
972 /* if both format are not YUV, try to use RGB24 as common
973 format */
974 if (!dst_pix->is_yuv && !src_pix->is_yuv) {
975 if (avpicture_alloc(tmp, PIX_FMT_RGB24, dst_width, dst_height) < 0)
976 return -1;
977 ret = -1;
978 if (img_convert(tmp, PIX_FMT_RGB24,
979 src, src_pix_fmt, src_width, src_height) < 0)
980 goto fail1;
981 if (img_convert(dst, dst_pix_fmt,
982 tmp, PIX_FMT_RGB24, dst_width, dst_height) < 0)
983 goto fail1;
984 ret = 0;
985 fail1:
986 avpicture_free(tmp);
987 return ret;
988 }
989
990 /* gray to YUV */ 1106 /* gray to YUV */
991 if (dst_pix->is_yuv && src_pix_fmt == PIX_FMT_GRAY8) { 1107 if (dst_pix->is_yuv && src_pix_fmt == PIX_FMT_GRAY8) {
992 int w, h, y; 1108 int w, h, y;
993 uint8_t *d; 1109 uint8_t *d;
994 1110
1000 h = dst_height; 1116 h = dst_height;
1001 w >>= dst_pix->x_chroma_shift; 1117 w >>= dst_pix->x_chroma_shift;
1002 h >>= dst_pix->y_chroma_shift; 1118 h >>= dst_pix->y_chroma_shift;
1003 for(i = 1; i <= 2; i++) { 1119 for(i = 1; i <= 2; i++) {
1004 d = dst->data[i]; 1120 d = dst->data[i];
1005 for(y = 0; y<h; y++) { 1121 for(y = 0; y< h; y++) {
1006 memset(d, 128, 0); 1122 memset(d, 128, w);
1007 d += dst->linesize[i]; 1123 d += dst->linesize[i];
1008 } 1124 }
1009 } 1125 }
1010 return 0; 1126 return 0;
1011 } 1127 }
1061 resize_func(dst->data[1], dst->linesize[1], 1177 resize_func(dst->data[1], dst->linesize[1],
1062 src->data[1], src->linesize[1], 1178 src->data[1], src->linesize[1],
1063 w, h); 1179 w, h);
1064 } 1180 }
1065 1181
1066 /* cannot convert yet */ 1182 /* try to use an intermediate format */
1067 1183 if (src_pix_fmt == PIX_FMT_MONOWHITE ||
1068 return -1; 1184 src_pix_fmt == PIX_FMT_MONOBLACK ||
1185 dst_pix_fmt == PIX_FMT_MONOWHITE ||
1186 dst_pix_fmt == PIX_FMT_MONOBLACK) {
1187 int_pix_fmt = PIX_FMT_GRAY8;
1188 } else {
1189 int_pix_fmt = PIX_FMT_RGB24;
1190 }
1191 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
1192 return -1;
1193 ret = -1;
1194 if (img_convert(tmp, int_pix_fmt,
1195 src, src_pix_fmt, src_width, src_height) < 0)
1196 goto fail1;
1197 if (img_convert(dst, dst_pix_fmt,
1198 tmp, int_pix_fmt, dst_width, dst_height) < 0)
1199 goto fail1;
1200 ret = 0;
1201 fail1:
1202 avpicture_free(tmp);
1203 return ret;
1069 } 1204 }
1070 1205
1071 1206
1072 #ifdef HAVE_MMX 1207 #ifdef HAVE_MMX
1073 #define DEINT_INPLACE_LINE_LUM \ 1208 #define DEINT_INPLACE_LINE_LUM \