OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 The LibYuv Project Authors. All rights reserved. | 2 * Copyright 2011 The LibYuv Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 // Convert Q420 to I420. | 394 // Convert Q420 to I420. |
395 // Format is rows of YY/YUYV | 395 // Format is rows of YY/YUYV |
396 LIBYUV_API | 396 LIBYUV_API |
397 int Q420ToI420(const uint8* src_y, int src_stride_y, | 397 int Q420ToI420(const uint8* src_y, int src_stride_y, |
398 const uint8* src_yuy2, int src_stride_yuy2, | 398 const uint8* src_yuy2, int src_stride_yuy2, |
399 uint8* dst_y, int dst_stride_y, | 399 uint8* dst_y, int dst_stride_y, |
400 uint8* dst_u, int dst_stride_u, | 400 uint8* dst_u, int dst_stride_u, |
401 uint8* dst_v, int dst_stride_v, | 401 uint8* dst_v, int dst_stride_v, |
402 int width, int height) { | 402 int width, int height) { |
403 int y; | 403 int y; |
404 int halfheight = (height + 1) >> 1; | 404 int halfheight; |
405 void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; | 405 void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; |
406 void (*YUY2ToUV422Row)(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v, | 406 void (*YUY2ToUV422Row)(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v, |
407 int pix) = YUY2ToUV422Row_C; | 407 int pix) = YUY2ToUV422Row_C; |
408 void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int pix) = | 408 void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int pix) = |
409 YUY2ToYRow_C; | 409 YUY2ToYRow_C; |
410 if (!src_y || !src_yuy2 || | 410 if (!src_y || !src_yuy2 || |
411 !dst_y || !dst_u || !dst_v || | 411 !dst_y || !dst_u || !dst_v || |
412 width <= 0 || height == 0) { | 412 width <= 0 || height == 0) { |
413 return -1; | 413 return -1; |
414 } | 414 } |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 ARGBToYRow = ARGBToYRow_AVX2; | 704 ARGBToYRow = ARGBToYRow_AVX2; |
705 } | 705 } |
706 } | 706 } |
707 #endif | 707 #endif |
708 #if defined(HAS_ARGBTOYROW_NEON) | 708 #if defined(HAS_ARGBTOYROW_NEON) |
709 if (TestCpuFlag(kCpuHasNEON) && width >= 8) { | 709 if (TestCpuFlag(kCpuHasNEON) && width >= 8) { |
710 ARGBToYRow = ARGBToYRow_Any_NEON; | 710 ARGBToYRow = ARGBToYRow_Any_NEON; |
711 if (IS_ALIGNED(width, 8)) { | 711 if (IS_ALIGNED(width, 8)) { |
712 ARGBToYRow = ARGBToYRow_NEON; | 712 ARGBToYRow = ARGBToYRow_NEON; |
713 } | 713 } |
714 if (width >= 16) { | 714 } |
715 ARGBToUVRow = ARGBToUVRow_Any_NEON; | 715 #endif |
716 if (IS_ALIGNED(width, 16)) { | 716 #if defined(HAS_ARGBTOUVROW_NEON) |
717 ARGBToUVRow = ARGBToUVRow_NEON; | 717 if (TestCpuFlag(kCpuHasNEON) && width >= 16) { |
718 } | 718 ARGBToUVRow = ARGBToUVRow_Any_NEON; |
| 719 if (IS_ALIGNED(width, 16)) { |
| 720 ARGBToUVRow = ARGBToUVRow_NEON; |
719 } | 721 } |
720 } | 722 } |
721 #endif | 723 #endif |
722 | 724 |
723 for (y = 0; y < height - 1; y += 2) { | 725 for (y = 0; y < height - 1; y += 2) { |
724 ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width); | 726 ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width); |
725 ARGBToYRow(src_argb, dst_y, width); | 727 ARGBToYRow(src_argb, dst_y, width); |
726 ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width); | 728 ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width); |
727 src_argb += src_stride_argb * 2; | 729 src_argb += src_stride_argb * 2; |
728 dst_y += dst_stride_y * 2; | 730 dst_y += dst_stride_y * 2; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 uint8* dst_u, uint8* dst_v, int width) = RGB24ToUVRow_C; | 958 uint8* dst_u, uint8* dst_v, int width) = RGB24ToUVRow_C; |
957 void (*RGB24ToYRow)(const uint8* src_rgb24, uint8* dst_y, int pix) = | 959 void (*RGB24ToYRow)(const uint8* src_rgb24, uint8* dst_y, int pix) = |
958 RGB24ToYRow_C; | 960 RGB24ToYRow_C; |
959 #else | 961 #else |
960 void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = | 962 void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = |
961 RGB24ToARGBRow_C; | 963 RGB24ToARGBRow_C; |
962 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, | 964 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, |
963 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; | 965 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; |
964 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = | 966 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = |
965 ARGBToYRow_C; | 967 ARGBToYRow_C; |
966 // Allocate 2 rows of ARGB. | |
967 const int kRowSize = (width * 4 + 15) & ~15; | |
968 align_buffer_64(row, kRowSize * 2); | |
969 #endif | 968 #endif |
970 if (!src_rgb24 || !dst_y || !dst_u || !dst_v || | 969 if (!src_rgb24 || !dst_y || !dst_u || !dst_v || |
971 width <= 0 || height == 0) { | 970 width <= 0 || height == 0) { |
972 return -1; | 971 return -1; |
973 } | 972 } |
974 // Negative height means invert the image. | 973 // Negative height means invert the image. |
975 if (height < 0) { | 974 if (height < 0) { |
976 height = -height; | 975 height = -height; |
977 src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24; | 976 src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24; |
978 src_stride_rgb24 = -src_stride_rgb24; | 977 src_stride_rgb24 = -src_stride_rgb24; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 if (IS_ALIGNED(width, 16)) { | 1014 if (IS_ALIGNED(width, 16)) { |
1016 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; | 1015 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; |
1017 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { | 1016 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { |
1018 ARGBToYRow = ARGBToYRow_SSSE3; | 1017 ARGBToYRow = ARGBToYRow_SSSE3; |
1019 } | 1018 } |
1020 } | 1019 } |
1021 } | 1020 } |
1022 #endif // HAS_ARGBTOUVROW_SSSE3 | 1021 #endif // HAS_ARGBTOUVROW_SSSE3 |
1023 #endif // HAS_RGB24TOYROW_NEON | 1022 #endif // HAS_RGB24TOYROW_NEON |
1024 | 1023 |
1025 for (y = 0; y < height - 1; y += 2) { | 1024 { |
| 1025 #if !defined(HAS_RGB24TOYROW_NEON) |
| 1026 // Allocate 2 rows of ARGB. |
| 1027 const int kRowSize = (width * 4 + 15) & ~15; |
| 1028 align_buffer_64(row, kRowSize * 2); |
| 1029 #endif |
| 1030 |
| 1031 for (y = 0; y < height - 1; y += 2) { |
1026 #if defined(HAS_RGB24TOYROW_NEON) | 1032 #if defined(HAS_RGB24TOYROW_NEON) |
1027 RGB24ToUVRow(src_rgb24, src_stride_rgb24, dst_u, dst_v, width); | 1033 RGB24ToUVRow(src_rgb24, src_stride_rgb24, dst_u, dst_v, width); |
1028 RGB24ToYRow(src_rgb24, dst_y, width); | 1034 RGB24ToYRow(src_rgb24, dst_y, width); |
1029 RGB24ToYRow(src_rgb24 + src_stride_rgb24, dst_y + dst_stride_y, width); | 1035 RGB24ToYRow(src_rgb24 + src_stride_rgb24, dst_y + dst_stride_y, width); |
1030 #else | 1036 #else |
1031 RGB24ToARGBRow(src_rgb24, row, width); | 1037 RGB24ToARGBRow(src_rgb24, row, width); |
1032 RGB24ToARGBRow(src_rgb24 + src_stride_rgb24, row + kRowSize, width); | 1038 RGB24ToARGBRow(src_rgb24 + src_stride_rgb24, row + kRowSize, width); |
1033 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); | 1039 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); |
1034 ARGBToYRow(row, dst_y, width); | 1040 ARGBToYRow(row, dst_y, width); |
1035 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); | 1041 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); |
1036 #endif | 1042 #endif |
1037 src_rgb24 += src_stride_rgb24 * 2; | 1043 src_rgb24 += src_stride_rgb24 * 2; |
1038 dst_y += dst_stride_y * 2; | 1044 dst_y += dst_stride_y * 2; |
1039 dst_u += dst_stride_u; | 1045 dst_u += dst_stride_u; |
1040 dst_v += dst_stride_v; | 1046 dst_v += dst_stride_v; |
1041 } | 1047 } |
1042 if (height & 1) { | 1048 if (height & 1) { |
1043 #if defined(HAS_RGB24TOYROW_NEON) | 1049 #if defined(HAS_RGB24TOYROW_NEON) |
1044 RGB24ToUVRow(src_rgb24, 0, dst_u, dst_v, width); | 1050 RGB24ToUVRow(src_rgb24, 0, dst_u, dst_v, width); |
1045 RGB24ToYRow(src_rgb24, dst_y, width); | 1051 RGB24ToYRow(src_rgb24, dst_y, width); |
1046 #else | 1052 #else |
1047 RGB24ToARGBRow(src_rgb24, row, width); | 1053 RGB24ToARGBRow(src_rgb24, row, width); |
1048 ARGBToUVRow(row, 0, dst_u, dst_v, width); | 1054 ARGBToUVRow(row, 0, dst_u, dst_v, width); |
1049 ARGBToYRow(row, dst_y, width); | 1055 ARGBToYRow(row, dst_y, width); |
| 1056 #endif |
| 1057 } |
| 1058 #if !defined(HAS_RGB24TOYROW_NEON) |
| 1059 free_aligned_buffer_64(row); |
1050 #endif | 1060 #endif |
1051 } | 1061 } |
1052 #if !defined(HAS_RGB24TOYROW_NEON) | |
1053 free_aligned_buffer_64(row); | |
1054 #endif | |
1055 return 0; | 1062 return 0; |
1056 } | 1063 } |
1057 | 1064 |
1058 // Convert RAW to I420. | 1065 // Convert RAW to I420. |
1059 LIBYUV_API | 1066 LIBYUV_API |
1060 int RAWToI420(const uint8* src_raw, int src_stride_raw, | 1067 int RAWToI420(const uint8* src_raw, int src_stride_raw, |
1061 uint8* dst_y, int dst_stride_y, | 1068 uint8* dst_y, int dst_stride_y, |
1062 uint8* dst_u, int dst_stride_u, | 1069 uint8* dst_u, int dst_stride_u, |
1063 uint8* dst_v, int dst_stride_v, | 1070 uint8* dst_v, int dst_stride_v, |
1064 int width, int height) { | 1071 int width, int height) { |
1065 int y; | 1072 int y; |
1066 #if defined(HAS_RAWTOYROW_NEON) | 1073 #if defined(HAS_RAWTOYROW_NEON) |
1067 void (*RAWToUVRow)(const uint8* src_raw, int src_stride_raw, | 1074 void (*RAWToUVRow)(const uint8* src_raw, int src_stride_raw, |
1068 uint8* dst_u, uint8* dst_v, int width) = RAWToUVRow_C; | 1075 uint8* dst_u, uint8* dst_v, int width) = RAWToUVRow_C; |
1069 void (*RAWToYRow)(const uint8* src_raw, uint8* dst_y, int pix) = | 1076 void (*RAWToYRow)(const uint8* src_raw, uint8* dst_y, int pix) = |
1070 RAWToYRow_C; | 1077 RAWToYRow_C; |
1071 #else | 1078 #else |
1072 void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = | 1079 void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = |
1073 RAWToARGBRow_C; | 1080 RAWToARGBRow_C; |
1074 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, | 1081 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, |
1075 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; | 1082 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; |
1076 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = | 1083 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = |
1077 ARGBToYRow_C; | 1084 ARGBToYRow_C; |
1078 // Allocate 2 rows of ARGB. | |
1079 const int kRowSize = (width * 4 + 15) & ~15; | |
1080 align_buffer_64(row, kRowSize * 2); | |
1081 #endif | 1085 #endif |
1082 if (!src_raw || !dst_y || !dst_u || !dst_v || | 1086 if (!src_raw || !dst_y || !dst_u || !dst_v || |
1083 width <= 0 || height == 0) { | 1087 width <= 0 || height == 0) { |
1084 return -1; | 1088 return -1; |
1085 } | 1089 } |
1086 // Negative height means invert the image. | 1090 // Negative height means invert the image. |
1087 if (height < 0) { | 1091 if (height < 0) { |
1088 height = -height; | 1092 height = -height; |
1089 src_raw = src_raw + (height - 1) * src_stride_raw; | 1093 src_raw = src_raw + (height - 1) * src_stride_raw; |
1090 src_stride_raw = -src_stride_raw; | 1094 src_stride_raw = -src_stride_raw; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1127 if (IS_ALIGNED(width, 16)) { | 1131 if (IS_ALIGNED(width, 16)) { |
1128 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; | 1132 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; |
1129 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { | 1133 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { |
1130 ARGBToYRow = ARGBToYRow_SSSE3; | 1134 ARGBToYRow = ARGBToYRow_SSSE3; |
1131 } | 1135 } |
1132 } | 1136 } |
1133 } | 1137 } |
1134 #endif // HAS_ARGBTOUVROW_SSSE3 | 1138 #endif // HAS_ARGBTOUVROW_SSSE3 |
1135 #endif // HAS_RAWTOYROW_NEON | 1139 #endif // HAS_RAWTOYROW_NEON |
1136 | 1140 |
1137 for (y = 0; y < height - 1; y += 2) { | 1141 { |
1138 #if defined(HAS_RAWTOYROW_NEON) | 1142 // Allocate 2 rows of ARGB. |
1139 RAWToUVRow(src_raw, src_stride_raw, dst_u, dst_v, width); | 1143 const int kRowSize = (width * 4 + 15) & ~15; |
1140 RAWToYRow(src_raw, dst_y, width); | 1144 align_buffer_64(row, kRowSize * 2); |
1141 RAWToYRow(src_raw + src_stride_raw, dst_y + dst_stride_y, width); | 1145 |
1142 #else | 1146 for (y = 0; y < height - 1; y += 2) { |
1143 RAWToARGBRow(src_raw, row, width); | 1147 #if defined(HAS_RAWTOYROW_NEON) |
1144 RAWToARGBRow(src_raw + src_stride_raw, row + kRowSize, width); | 1148 RAWToUVRow(src_raw, src_stride_raw, dst_u, dst_v, width); |
1145 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); | 1149 RAWToYRow(src_raw, dst_y, width); |
1146 ARGBToYRow(row, dst_y, width); | 1150 RAWToYRow(src_raw + src_stride_raw, dst_y + dst_stride_y, width); |
1147 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); | 1151 #else |
1148 #endif | 1152 RAWToARGBRow(src_raw, row, width); |
1149 src_raw += src_stride_raw * 2; | 1153 RAWToARGBRow(src_raw + src_stride_raw, row + kRowSize, width); |
1150 dst_y += dst_stride_y * 2; | 1154 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); |
1151 dst_u += dst_stride_u; | 1155 ARGBToYRow(row, dst_y, width); |
1152 dst_v += dst_stride_v; | 1156 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); |
| 1157 #endif |
| 1158 src_raw += src_stride_raw * 2; |
| 1159 dst_y += dst_stride_y * 2; |
| 1160 dst_u += dst_stride_u; |
| 1161 dst_v += dst_stride_v; |
| 1162 } |
| 1163 if (height & 1) { |
| 1164 #if defined(HAS_RAWTOYROW_NEON) |
| 1165 RAWToUVRow(src_raw, 0, dst_u, dst_v, width); |
| 1166 RAWToYRow(src_raw, dst_y, width); |
| 1167 #else |
| 1168 RAWToARGBRow(src_raw, row, width); |
| 1169 ARGBToUVRow(row, 0, dst_u, dst_v, width); |
| 1170 ARGBToYRow(row, dst_y, width); |
| 1171 #endif |
| 1172 } |
| 1173 #if !defined(HAS_RAWTOYROW_NEON) |
| 1174 free_aligned_buffer_64(row); |
| 1175 #endif |
1153 } | 1176 } |
1154 if (height & 1) { | |
1155 #if defined(HAS_RAWTOYROW_NEON) | |
1156 RAWToUVRow(src_raw, 0, dst_u, dst_v, width); | |
1157 RAWToYRow(src_raw, dst_y, width); | |
1158 #else | |
1159 RAWToARGBRow(src_raw, row, width); | |
1160 ARGBToUVRow(row, 0, dst_u, dst_v, width); | |
1161 ARGBToYRow(row, dst_y, width); | |
1162 #endif | |
1163 } | |
1164 #if !defined(HAS_RAWTOYROW_NEON) | |
1165 free_aligned_buffer_64(row); | |
1166 #endif | |
1167 return 0; | 1177 return 0; |
1168 } | 1178 } |
1169 | 1179 |
1170 // Convert RGB565 to I420. | 1180 // Convert RGB565 to I420. |
1171 LIBYUV_API | 1181 LIBYUV_API |
1172 int RGB565ToI420(const uint8* src_rgb565, int src_stride_rgb565, | 1182 int RGB565ToI420(const uint8* src_rgb565, int src_stride_rgb565, |
1173 uint8* dst_y, int dst_stride_y, | 1183 uint8* dst_y, int dst_stride_y, |
1174 uint8* dst_u, int dst_stride_u, | 1184 uint8* dst_u, int dst_stride_u, |
1175 uint8* dst_v, int dst_stride_v, | 1185 uint8* dst_v, int dst_stride_v, |
1176 int width, int height) { | 1186 int width, int height) { |
1177 int y; | 1187 int y; |
1178 #if defined(HAS_RGB565TOYROW_NEON) | 1188 #if defined(HAS_RGB565TOYROW_NEON) |
1179 void (*RGB565ToUVRow)(const uint8* src_rgb565, int src_stride_rgb565, | 1189 void (*RGB565ToUVRow)(const uint8* src_rgb565, int src_stride_rgb565, |
1180 uint8* dst_u, uint8* dst_v, int width) = RGB565ToUVRow_C; | 1190 uint8* dst_u, uint8* dst_v, int width) = RGB565ToUVRow_C; |
1181 void (*RGB565ToYRow)(const uint8* src_rgb565, uint8* dst_y, int pix) = | 1191 void (*RGB565ToYRow)(const uint8* src_rgb565, uint8* dst_y, int pix) = |
1182 RGB565ToYRow_C; | 1192 RGB565ToYRow_C; |
1183 #else | 1193 #else |
1184 void (*RGB565ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = | 1194 void (*RGB565ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = |
1185 RGB565ToARGBRow_C; | 1195 RGB565ToARGBRow_C; |
1186 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, | 1196 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, |
1187 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; | 1197 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; |
1188 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = | 1198 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = |
1189 ARGBToYRow_C; | 1199 ARGBToYRow_C; |
1190 // Allocate 2 rows of ARGB. | |
1191 const int kRowSize = (width * 4 + 15) & ~15; | |
1192 align_buffer_64(row, kRowSize * 2); | |
1193 #endif | 1200 #endif |
1194 if (!src_rgb565 || !dst_y || !dst_u || !dst_v || | 1201 if (!src_rgb565 || !dst_y || !dst_u || !dst_v || |
1195 width <= 0 || height == 0) { | 1202 width <= 0 || height == 0) { |
1196 return -1; | 1203 return -1; |
1197 } | 1204 } |
1198 // Negative height means invert the image. | 1205 // Negative height means invert the image. |
1199 if (height < 0) { | 1206 if (height < 0) { |
1200 height = -height; | 1207 height = -height; |
1201 src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565; | 1208 src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565; |
1202 src_stride_rgb565 = -src_stride_rgb565; | 1209 src_stride_rgb565 = -src_stride_rgb565; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 if (IS_ALIGNED(width, 16)) { | 1246 if (IS_ALIGNED(width, 16)) { |
1240 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; | 1247 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; |
1241 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { | 1248 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { |
1242 ARGBToYRow = ARGBToYRow_SSSE3; | 1249 ARGBToYRow = ARGBToYRow_SSSE3; |
1243 } | 1250 } |
1244 } | 1251 } |
1245 } | 1252 } |
1246 #endif // HAS_ARGBTOUVROW_SSSE3 | 1253 #endif // HAS_ARGBTOUVROW_SSSE3 |
1247 #endif // HAS_RGB565TOYROW_NEON | 1254 #endif // HAS_RGB565TOYROW_NEON |
1248 | 1255 |
1249 for (y = 0; y < height - 1; y += 2) { | 1256 { |
| 1257 #if !defined(HAS_RGB565TOYROW_NEON) |
| 1258 // Allocate 2 rows of ARGB. |
| 1259 const int kRowSize = (width * 4 + 15) & ~15; |
| 1260 align_buffer_64(row, kRowSize * 2); |
| 1261 #endif |
| 1262 |
| 1263 for (y = 0; y < height - 1; y += 2) { |
1250 #if defined(HAS_RGB565TOYROW_NEON) | 1264 #if defined(HAS_RGB565TOYROW_NEON) |
1251 RGB565ToUVRow(src_rgb565, src_stride_rgb565, dst_u, dst_v, width); | 1265 RGB565ToUVRow(src_rgb565, src_stride_rgb565, dst_u, dst_v, width); |
1252 RGB565ToYRow(src_rgb565, dst_y, width); | 1266 RGB565ToYRow(src_rgb565, dst_y, width); |
1253 RGB565ToYRow(src_rgb565 + src_stride_rgb565, dst_y + dst_stride_y, width); | 1267 RGB565ToYRow(src_rgb565 + src_stride_rgb565, dst_y + dst_stride_y, width); |
1254 #else | 1268 #else |
1255 RGB565ToARGBRow(src_rgb565, row, width); | 1269 RGB565ToARGBRow(src_rgb565, row, width); |
1256 RGB565ToARGBRow(src_rgb565 + src_stride_rgb565, row + kRowSize, width); | 1270 RGB565ToARGBRow(src_rgb565 + src_stride_rgb565, row + kRowSize, width); |
1257 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); | 1271 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); |
1258 ARGBToYRow(row, dst_y, width); | 1272 ARGBToYRow(row, dst_y, width); |
1259 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); | 1273 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); |
1260 #endif | 1274 #endif |
1261 src_rgb565 += src_stride_rgb565 * 2; | 1275 src_rgb565 += src_stride_rgb565 * 2; |
1262 dst_y += dst_stride_y * 2; | 1276 dst_y += dst_stride_y * 2; |
1263 dst_u += dst_stride_u; | 1277 dst_u += dst_stride_u; |
1264 dst_v += dst_stride_v; | 1278 dst_v += dst_stride_v; |
1265 } | 1279 } |
1266 if (height & 1) { | 1280 if (height & 1) { |
1267 #if defined(HAS_RGB565TOYROW_NEON) | 1281 #if defined(HAS_RGB565TOYROW_NEON) |
1268 RGB565ToUVRow(src_rgb565, 0, dst_u, dst_v, width); | 1282 RGB565ToUVRow(src_rgb565, 0, dst_u, dst_v, width); |
1269 RGB565ToYRow(src_rgb565, dst_y, width); | 1283 RGB565ToYRow(src_rgb565, dst_y, width); |
1270 #else | 1284 #else |
1271 RGB565ToARGBRow(src_rgb565, row, width); | 1285 RGB565ToARGBRow(src_rgb565, row, width); |
1272 ARGBToUVRow(row, 0, dst_u, dst_v, width); | 1286 ARGBToUVRow(row, 0, dst_u, dst_v, width); |
1273 ARGBToYRow(row, dst_y, width); | 1287 ARGBToYRow(row, dst_y, width); |
| 1288 #endif |
| 1289 } |
| 1290 #if !defined(HAS_RGB565TOYROW_NEON) |
| 1291 free_aligned_buffer_64(row); |
1274 #endif | 1292 #endif |
1275 } | 1293 } |
1276 #if !defined(HAS_RGB565TOYROW_NEON) | |
1277 free_aligned_buffer_64(row); | |
1278 #endif | |
1279 return 0; | 1294 return 0; |
1280 } | 1295 } |
1281 | 1296 |
1282 // Convert ARGB1555 to I420. | 1297 // Convert ARGB1555 to I420. |
1283 LIBYUV_API | 1298 LIBYUV_API |
1284 int ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555, | 1299 int ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555, |
1285 uint8* dst_y, int dst_stride_y, | 1300 uint8* dst_y, int dst_stride_y, |
1286 uint8* dst_u, int dst_stride_u, | 1301 uint8* dst_u, int dst_stride_u, |
1287 uint8* dst_v, int dst_stride_v, | 1302 uint8* dst_v, int dst_stride_v, |
1288 int width, int height) { | 1303 int width, int height) { |
1289 int y; | 1304 int y; |
1290 #if defined(HAS_ARGB1555TOYROW_NEON) | 1305 #if defined(HAS_ARGB1555TOYROW_NEON) |
1291 void (*ARGB1555ToUVRow)(const uint8* src_argb1555, int src_stride_argb1555, | 1306 void (*ARGB1555ToUVRow)(const uint8* src_argb1555, int src_stride_argb1555, |
1292 uint8* dst_u, uint8* dst_v, int width) = ARGB1555ToUVRow_C; | 1307 uint8* dst_u, uint8* dst_v, int width) = ARGB1555ToUVRow_C; |
1293 void (*ARGB1555ToYRow)(const uint8* src_argb1555, uint8* dst_y, int pix) = | 1308 void (*ARGB1555ToYRow)(const uint8* src_argb1555, uint8* dst_y, int pix) = |
1294 ARGB1555ToYRow_C; | 1309 ARGB1555ToYRow_C; |
1295 #else | 1310 #else |
1296 void (*ARGB1555ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = | 1311 void (*ARGB1555ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = |
1297 ARGB1555ToARGBRow_C; | 1312 ARGB1555ToARGBRow_C; |
1298 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, | 1313 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, |
1299 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; | 1314 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; |
1300 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = | 1315 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = |
1301 ARGBToYRow_C; | 1316 ARGBToYRow_C; |
1302 // Allocate 2 rows of ARGB. | |
1303 const int kRowSize = (width * 4 + 15) & ~15; | |
1304 align_buffer_64(row, kRowSize * 2); | |
1305 #endif | 1317 #endif |
1306 if (!src_argb1555 || !dst_y || !dst_u || !dst_v || | 1318 if (!src_argb1555 || !dst_y || !dst_u || !dst_v || |
1307 width <= 0 || height == 0) { | 1319 width <= 0 || height == 0) { |
1308 return -1; | 1320 return -1; |
1309 } | 1321 } |
1310 // Negative height means invert the image. | 1322 // Negative height means invert the image. |
1311 if (height < 0) { | 1323 if (height < 0) { |
1312 height = -height; | 1324 height = -height; |
1313 src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555; | 1325 src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555; |
1314 src_stride_argb1555 = -src_stride_argb1555; | 1326 src_stride_argb1555 = -src_stride_argb1555; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1351 if (IS_ALIGNED(width, 16)) { | 1363 if (IS_ALIGNED(width, 16)) { |
1352 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; | 1364 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; |
1353 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { | 1365 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { |
1354 ARGBToYRow = ARGBToYRow_SSSE3; | 1366 ARGBToYRow = ARGBToYRow_SSSE3; |
1355 } | 1367 } |
1356 } | 1368 } |
1357 } | 1369 } |
1358 #endif // HAS_ARGBTOUVROW_SSSE3 | 1370 #endif // HAS_ARGBTOUVROW_SSSE3 |
1359 #endif // HAS_ARGB1555TOYROW_NEON | 1371 #endif // HAS_ARGB1555TOYROW_NEON |
1360 | 1372 |
1361 for (y = 0; y < height - 1; y += 2) { | 1373 { |
| 1374 #if !defined(HAS_ARGB1555TOYROW_NEON) |
| 1375 // Allocate 2 rows of ARGB. |
| 1376 const int kRowSize = (width * 4 + 15) & ~15; |
| 1377 align_buffer_64(row, kRowSize * 2); |
| 1378 #endif |
| 1379 for (y = 0; y < height - 1; y += 2) { |
1362 #if defined(HAS_ARGB1555TOYROW_NEON) | 1380 #if defined(HAS_ARGB1555TOYROW_NEON) |
1363 ARGB1555ToUVRow(src_argb1555, src_stride_argb1555, dst_u, dst_v, width); | 1381 ARGB1555ToUVRow(src_argb1555, src_stride_argb1555, dst_u, dst_v, width); |
1364 ARGB1555ToYRow(src_argb1555, dst_y, width); | 1382 ARGB1555ToYRow(src_argb1555, dst_y, width); |
1365 ARGB1555ToYRow(src_argb1555 + src_stride_argb1555, dst_y + dst_stride_y, | 1383 ARGB1555ToYRow(src_argb1555 + src_stride_argb1555, dst_y + dst_stride_y, |
1366 width); | 1384 width); |
1367 #else | 1385 #else |
1368 ARGB1555ToARGBRow(src_argb1555, row, width); | 1386 ARGB1555ToARGBRow(src_argb1555, row, width); |
1369 ARGB1555ToARGBRow(src_argb1555 + src_stride_argb1555, row + kRowSize, | 1387 ARGB1555ToARGBRow(src_argb1555 + src_stride_argb1555, row + kRowSize, |
1370 width); | 1388 width); |
1371 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); | 1389 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); |
1372 ARGBToYRow(row, dst_y, width); | 1390 ARGBToYRow(row, dst_y, width); |
1373 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); | 1391 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); |
1374 #endif | 1392 #endif |
1375 src_argb1555 += src_stride_argb1555 * 2; | 1393 src_argb1555 += src_stride_argb1555 * 2; |
1376 dst_y += dst_stride_y * 2; | 1394 dst_y += dst_stride_y * 2; |
1377 dst_u += dst_stride_u; | 1395 dst_u += dst_stride_u; |
1378 dst_v += dst_stride_v; | 1396 dst_v += dst_stride_v; |
1379 } | 1397 } |
1380 if (height & 1) { | 1398 if (height & 1) { |
1381 #if defined(HAS_ARGB1555TOYROW_NEON) | 1399 #if defined(HAS_ARGB1555TOYROW_NEON) |
1382 ARGB1555ToUVRow(src_argb1555, 0, dst_u, dst_v, width); | 1400 ARGB1555ToUVRow(src_argb1555, 0, dst_u, dst_v, width); |
1383 ARGB1555ToYRow(src_argb1555, dst_y, width); | 1401 ARGB1555ToYRow(src_argb1555, dst_y, width); |
1384 #else | 1402 #else |
1385 ARGB1555ToARGBRow(src_argb1555, row, width); | 1403 ARGB1555ToARGBRow(src_argb1555, row, width); |
1386 ARGBToUVRow(row, 0, dst_u, dst_v, width); | 1404 ARGBToUVRow(row, 0, dst_u, dst_v, width); |
1387 ARGBToYRow(row, dst_y, width); | 1405 ARGBToYRow(row, dst_y, width); |
1388 #endif | 1406 #endif |
1389 } | 1407 } |
1390 #if !defined(HAS_ARGB1555TOYROW_NEON) | 1408 #if !defined(HAS_ARGB1555TOYROW_NEON) |
1391 free_aligned_buffer_64(row); | 1409 free_aligned_buffer_64(row); |
1392 #endif | 1410 #endif |
| 1411 } |
1393 return 0; | 1412 return 0; |
1394 } | 1413 } |
1395 | 1414 |
1396 // Convert ARGB4444 to I420. | 1415 // Convert ARGB4444 to I420. |
1397 LIBYUV_API | 1416 LIBYUV_API |
1398 int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444, | 1417 int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444, |
1399 uint8* dst_y, int dst_stride_y, | 1418 uint8* dst_y, int dst_stride_y, |
1400 uint8* dst_u, int dst_stride_u, | 1419 uint8* dst_u, int dst_stride_u, |
1401 uint8* dst_v, int dst_stride_v, | 1420 uint8* dst_v, int dst_stride_v, |
1402 int width, int height) { | 1421 int width, int height) { |
1403 int y; | 1422 int y; |
1404 #if defined(HAS_ARGB4444TOYROW_NEON) | 1423 #if defined(HAS_ARGB4444TOYROW_NEON) |
1405 void (*ARGB4444ToUVRow)(const uint8* src_argb4444, int src_stride_argb4444, | 1424 void (*ARGB4444ToUVRow)(const uint8* src_argb4444, int src_stride_argb4444, |
1406 uint8* dst_u, uint8* dst_v, int width) = ARGB4444ToUVRow_C; | 1425 uint8* dst_u, uint8* dst_v, int width) = ARGB4444ToUVRow_C; |
1407 void (*ARGB4444ToYRow)(const uint8* src_argb4444, uint8* dst_y, int pix) = | 1426 void (*ARGB4444ToYRow)(const uint8* src_argb4444, uint8* dst_y, int pix) = |
1408 ARGB4444ToYRow_C; | 1427 ARGB4444ToYRow_C; |
1409 #else | 1428 #else |
1410 void (*ARGB4444ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = | 1429 void (*ARGB4444ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = |
1411 ARGB4444ToARGBRow_C; | 1430 ARGB4444ToARGBRow_C; |
1412 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, | 1431 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, |
1413 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; | 1432 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; |
1414 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = | 1433 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = |
1415 ARGBToYRow_C; | 1434 ARGBToYRow_C; |
1416 // Allocate 2 rows of ARGB. | |
1417 const int kRowSize = (width * 4 + 15) & ~15; | |
1418 align_buffer_64(row, kRowSize * 2); | |
1419 #endif | 1435 #endif |
1420 if (!src_argb4444 || !dst_y || !dst_u || !dst_v || | 1436 if (!src_argb4444 || !dst_y || !dst_u || !dst_v || |
1421 width <= 0 || height == 0) { | 1437 width <= 0 || height == 0) { |
1422 return -1; | 1438 return -1; |
1423 } | 1439 } |
1424 // Negative height means invert the image. | 1440 // Negative height means invert the image. |
1425 if (height < 0) { | 1441 if (height < 0) { |
1426 height = -height; | 1442 height = -height; |
1427 src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444; | 1443 src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444; |
1428 src_stride_argb4444 = -src_stride_argb4444; | 1444 src_stride_argb4444 = -src_stride_argb4444; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 if (IS_ALIGNED(width, 16)) { | 1481 if (IS_ALIGNED(width, 16)) { |
1466 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; | 1482 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; |
1467 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { | 1483 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { |
1468 ARGBToYRow = ARGBToYRow_SSSE3; | 1484 ARGBToYRow = ARGBToYRow_SSSE3; |
1469 } | 1485 } |
1470 } | 1486 } |
1471 } | 1487 } |
1472 #endif // HAS_ARGBTOUVROW_SSSE3 | 1488 #endif // HAS_ARGBTOUVROW_SSSE3 |
1473 #endif // HAS_ARGB4444TOYROW_NEON | 1489 #endif // HAS_ARGB4444TOYROW_NEON |
1474 | 1490 |
1475 for (y = 0; y < height - 1; y += 2) { | 1491 { |
| 1492 #if !defined(HAS_ARGB4444TOYROW_NEON) |
| 1493 // Allocate 2 rows of ARGB. |
| 1494 const int kRowSize = (width * 4 + 15) & ~15; |
| 1495 align_buffer_64(row, kRowSize * 2); |
| 1496 #endif |
| 1497 |
| 1498 for (y = 0; y < height - 1; y += 2) { |
1476 #if defined(HAS_ARGB4444TOYROW_NEON) | 1499 #if defined(HAS_ARGB4444TOYROW_NEON) |
1477 ARGB4444ToUVRow(src_argb4444, src_stride_argb4444, dst_u, dst_v, width); | 1500 ARGB4444ToUVRow(src_argb4444, src_stride_argb4444, dst_u, dst_v, width); |
1478 ARGB4444ToYRow(src_argb4444, dst_y, width); | 1501 ARGB4444ToYRow(src_argb4444, dst_y, width); |
1479 ARGB4444ToYRow(src_argb4444 + src_stride_argb4444, dst_y + dst_stride_y, | 1502 ARGB4444ToYRow(src_argb4444 + src_stride_argb4444, dst_y + dst_stride_y, |
1480 width); | 1503 width); |
1481 #else | 1504 #else |
1482 ARGB4444ToARGBRow(src_argb4444, row, width); | 1505 ARGB4444ToARGBRow(src_argb4444, row, width); |
1483 ARGB4444ToARGBRow(src_argb4444 + src_stride_argb4444, row + kRowSize, | 1506 ARGB4444ToARGBRow(src_argb4444 + src_stride_argb4444, row + kRowSize, |
1484 width); | 1507 width); |
1485 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); | 1508 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); |
1486 ARGBToYRow(row, dst_y, width); | 1509 ARGBToYRow(row, dst_y, width); |
1487 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); | 1510 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); |
1488 #endif | 1511 #endif |
1489 src_argb4444 += src_stride_argb4444 * 2; | 1512 src_argb4444 += src_stride_argb4444 * 2; |
1490 dst_y += dst_stride_y * 2; | 1513 dst_y += dst_stride_y * 2; |
1491 dst_u += dst_stride_u; | 1514 dst_u += dst_stride_u; |
1492 dst_v += dst_stride_v; | 1515 dst_v += dst_stride_v; |
1493 } | 1516 } |
1494 if (height & 1) { | 1517 if (height & 1) { |
1495 #if defined(HAS_ARGB4444TOYROW_NEON) | 1518 #if defined(HAS_ARGB4444TOYROW_NEON) |
1496 ARGB4444ToUVRow(src_argb4444, 0, dst_u, dst_v, width); | 1519 ARGB4444ToUVRow(src_argb4444, 0, dst_u, dst_v, width); |
1497 ARGB4444ToYRow(src_argb4444, dst_y, width); | 1520 ARGB4444ToYRow(src_argb4444, dst_y, width); |
1498 #else | 1521 #else |
1499 ARGB4444ToARGBRow(src_argb4444, row, width); | 1522 ARGB4444ToARGBRow(src_argb4444, row, width); |
1500 ARGBToUVRow(row, 0, dst_u, dst_v, width); | 1523 ARGBToUVRow(row, 0, dst_u, dst_v, width); |
1501 ARGBToYRow(row, dst_y, width); | 1524 ARGBToYRow(row, dst_y, width); |
| 1525 #endif |
| 1526 } |
| 1527 #if !defined(HAS_ARGB4444TOYROW_NEON) |
| 1528 free_aligned_buffer_64(row); |
1502 #endif | 1529 #endif |
1503 } | 1530 } |
1504 #if !defined(HAS_ARGB4444TOYROW_NEON) | |
1505 free_aligned_buffer_64(row); | |
1506 #endif | |
1507 return 0; | 1531 return 0; |
1508 } | 1532 } |
1509 | 1533 |
1510 #ifdef __cplusplus | 1534 #ifdef __cplusplus |
1511 } // extern "C" | 1535 } // extern "C" |
1512 } // namespace libyuv | 1536 } // namespace libyuv |
1513 #endif | 1537 #endif |
OLD | NEW |