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