| 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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 src_argb += 8; | 192 src_argb += 8; |
| 193 } | 193 } |
| 194 if (width & 1) { | 194 if (width & 1) { |
| 195 uint8 b0 = src_argb[0] >> 3; | 195 uint8 b0 = src_argb[0] >> 3; |
| 196 uint8 g0 = src_argb[1] >> 2; | 196 uint8 g0 = src_argb[1] >> 2; |
| 197 uint8 r0 = src_argb[2] >> 3; | 197 uint8 r0 = src_argb[2] >> 3; |
| 198 *(uint16*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); | 198 *(uint16*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); |
| 199 } | 199 } |
| 200 } | 200 } |
| 201 | 201 |
| 202 // dither4 is a row of 4 values from 4x4 dither matrix. |
| 203 // The 4x4 matrix contains values to increase RGB. When converting to |
| 204 // fewer bits (565) this provides an ordered dither. |
| 205 // The order in the 4x4 matrix in first byte is upper left. |
| 206 // The 4 values are passed as an int, then referenced as an array, so |
| 207 // endian will not affect order of the original matrix. But the dither4 |
| 208 // will containing the first pixel in the lower byte for little endian |
| 209 // or the upper byte for big endian. |
| 202 void ARGBToRGB565DitherRow_C(const uint8* src_argb, uint8* dst_rgb, | 210 void ARGBToRGB565DitherRow_C(const uint8* src_argb, uint8* dst_rgb, |
| 203 const uint8* dither8x8, int width) { | 211 const uint32 dither4, int width) { |
| 204 int x; | 212 int x; |
| 205 for (x = 0; x < width - 1; x += 2) { | 213 for (x = 0; x < width - 1; x += 2) { |
| 206 int dither0 = dither8x8[x & 7] - 128; | 214 int dither0 = ((const unsigned char*)(&dither4))[x & 3]; |
| 207 int dither1 = dither8x8[(x & 7) + 1] - 128; | 215 int dither1 = ((const unsigned char*)(&dither4))[(x + 1) & 3]; |
| 208 uint8 b0 = Clamp(src_argb[0] + dither0) >> 3; | 216 uint8 b0 = clamp255(src_argb[0] + dither0) >> 3; |
| 209 uint8 g0 = Clamp(src_argb[1] + dither0) >> 2; | 217 uint8 g0 = clamp255(src_argb[1] + dither0) >> 2; |
| 210 uint8 r0 = Clamp(src_argb[2] + dither0) >> 3; | 218 uint8 r0 = clamp255(src_argb[2] + dither0) >> 3; |
| 211 uint8 b1 = Clamp(src_argb[4] + dither1) >> 3; | 219 uint8 b1 = clamp255(src_argb[4] + dither1) >> 3; |
| 212 uint8 g1 = Clamp(src_argb[5] + dither1) >> 2; | 220 uint8 g1 = clamp255(src_argb[5] + dither1) >> 2; |
| 213 uint8 r1 = Clamp(src_argb[6] + dither1) >> 3; | 221 uint8 r1 = clamp255(src_argb[6] + dither1) >> 3; |
| 214 WRITEWORD(dst_rgb, b0 | (g0 << 5) | (r0 << 11) | | 222 WRITEWORD(dst_rgb, b0 | (g0 << 5) | (r0 << 11) | |
| 215 (b1 << 16) | (g1 << 21) | (r1 << 27)); | 223 (b1 << 16) | (g1 << 21) | (r1 << 27)); |
| 216 dst_rgb += 4; | 224 dst_rgb += 4; |
| 217 src_argb += 8; | 225 src_argb += 8; |
| 218 } | 226 } |
| 219 if (width & 1) { | 227 if (width & 1) { |
| 220 int dither0 = dither8x8[(width - 1) & 7] - 128; | 228 int dither0 = ((const unsigned char*)(&dither4))[(width - 1) & 3]; |
| 221 uint8 b0 = Clamp(src_argb[0] + dither0) >> 3; | 229 uint8 b0 = clamp255(src_argb[0] + dither0) >> 3; |
| 222 uint8 g0 = Clamp(src_argb[1] + dither0) >> 2; | 230 uint8 g0 = clamp255(src_argb[1] + dither0) >> 2; |
| 223 uint8 r0 = Clamp(src_argb[2] + dither0) >> 3; | 231 uint8 r0 = clamp255(src_argb[2] + dither0) >> 3; |
| 224 *(uint16*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); | 232 *(uint16*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); |
| 225 } | 233 } |
| 226 } | 234 } |
| 227 | 235 |
| 228 void ARGBToARGB1555Row_C(const uint8* src_argb, uint8* dst_rgb, int width) { | 236 void ARGBToARGB1555Row_C(const uint8* src_argb, uint8* dst_rgb, int width) { |
| 229 int x; | 237 int x; |
| 230 for (x = 0; x < width - 1; x += 2) { | 238 for (x = 0; x < width - 1; x += 2) { |
| 231 uint8 b0 = src_argb[0] >> 3; | 239 uint8 b0 = src_argb[0] >> 3; |
| 232 uint8 g0 = src_argb[1] >> 3; | 240 uint8 g0 = src_argb[1] >> 3; |
| 233 uint8 r0 = src_argb[2] >> 3; | 241 uint8 r0 = src_argb[2] >> 3; |
| (...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 int b = src_sobely[i]; | 975 int b = src_sobely[i]; |
| 968 int g = clamp255(r + b); | 976 int g = clamp255(r + b); |
| 969 dst_argb[0] = (uint8)(b); | 977 dst_argb[0] = (uint8)(b); |
| 970 dst_argb[1] = (uint8)(g); | 978 dst_argb[1] = (uint8)(g); |
| 971 dst_argb[2] = (uint8)(r); | 979 dst_argb[2] = (uint8)(r); |
| 972 dst_argb[3] = (uint8)(255u); | 980 dst_argb[3] = (uint8)(255u); |
| 973 dst_argb += 4; | 981 dst_argb += 4; |
| 974 } | 982 } |
| 975 } | 983 } |
| 976 | 984 |
| 977 void I400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) { | 985 void J400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) { |
| 978 // Copy a Y to RGB. | 986 // Copy a Y to RGB. |
| 979 int x; | 987 int x; |
| 980 for (x = 0; x < width; ++x) { | 988 for (x = 0; x < width; ++x) { |
| 981 uint8 y = src_y[0]; | 989 uint8 y = src_y[0]; |
| 982 dst_argb[2] = dst_argb[1] = dst_argb[0] = y; | 990 dst_argb[2] = dst_argb[1] = dst_argb[0] = y; |
| 983 dst_argb[3] = 255u; | 991 dst_argb[3] = 255u; |
| 984 dst_argb += 4; | 992 dst_argb += 4; |
| 985 ++src_y; | 993 ++src_y; |
| 986 } | 994 } |
| 987 } | 995 } |
| 988 | 996 |
| 989 // YUV to RGB conversion constants. | 997 // BT.601 YUV to RGB reference |
| 998 // R = (Y - 16) * 1.164 - V * -1.596 |
| 999 // G = (Y - 16) * 1.164 - U * 0.391 - V * 0.813 |
| 1000 // B = (Y - 16) * 1.164 - U * -2.018 |
| 1001 |
| 990 // Y contribution to R,G,B. Scale and bias. | 1002 // Y contribution to R,G,B. Scale and bias. |
| 991 // TODO(fbarchard): Consider moving constants into a common header. | 1003 // TODO(fbarchard): Consider moving constants into a common header. |
| 992 #define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */ | 1004 #define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */ |
| 993 #define YGB 1160 /* 1.164 * 64 * 16 - adjusted for even error distribution */ | 1005 #define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */ |
| 994 | 1006 |
| 995 // U and V contributions to R,G,B. | 1007 // U and V contributions to R,G,B. |
| 996 #define UB -128 /* -min(128, round(2.018 * 64)) */ | 1008 #define UB -128 /* max(-128, round(-2.018 * 64)) */ |
| 997 #define UG 25 /* -round(-0.391 * 64) */ | 1009 #define UG 25 /* round(0.391 * 64) */ |
| 998 #define VG 52 /* -round(-0.813 * 64) */ | 1010 #define VG 52 /* round(0.813 * 64) */ |
| 999 #define VR -102 /* -round(1.596 * 64) */ | 1011 #define VR -102 /* round(-1.596 * 64) */ |
| 1000 | 1012 |
| 1001 // Bias values to subtract 16 from Y and 128 from U and V. | 1013 // Bias values to subtract 16 from Y and 128 from U and V. |
| 1002 #define BB (UB * 128 - YGB) | 1014 #define BB (UB * 128 + YGB) |
| 1003 #define BG (UG * 128 + VG * 128 - YGB) | 1015 #define BG (UG * 128 + VG * 128 + YGB) |
| 1004 #define BR (VR * 128 - YGB) | 1016 #define BR (VR * 128 + YGB) |
| 1005 | 1017 |
| 1006 // C reference code that mimics the YUV assembly. | 1018 // C reference code that mimics the YUV assembly. |
| 1007 static __inline void YuvPixel(uint8 y, uint8 u, uint8 v, | 1019 static __inline void YuvPixel(uint8 y, uint8 u, uint8 v, |
| 1008 uint8* b, uint8* g, uint8* r) { | 1020 uint8* b, uint8* g, uint8* r) { |
| 1009 uint32 y1 = (uint32)(y * 0x0101 * YG) >> 16; | 1021 uint32 y1 = (uint32)(y * 0x0101 * YG) >> 16; |
| 1010 *b = Clamp((int32)(BB - ( u * UB) + y1) >> 6); | 1022 *b = Clamp((int32)(-(u * UB) + y1 + BB) >> 6); |
| 1011 *g = Clamp((int32)(BG - (v * VG + u * UG) + y1) >> 6); | 1023 *g = Clamp((int32)(-(v * VG + u * UG) + y1 + BG) >> 6); |
| 1012 *r = Clamp((int32)(BR - (v * VR ) + y1) >> 6); | 1024 *r = Clamp((int32)(-(v * VR)+ y1 + BR) >> 6); |
| 1013 } | 1025 } |
| 1014 | 1026 |
| 1015 // C reference code that mimics the YUV assembly. | 1027 // C reference code that mimics the YUV assembly. |
| 1016 static __inline void YPixel(uint8 y, uint8* b, uint8* g, uint8* r) { | 1028 static __inline void YPixel(uint8 y, uint8* b, uint8* g, uint8* r) { |
| 1017 uint32 y1 = (uint32)(y * 0x0101 * YG) >> 16; | 1029 uint32 y1 = (uint32)(y * 0x0101 * YG) >> 16; |
| 1018 *b = Clamp((int32)(y1 - YGB) >> 6); | 1030 *b = Clamp((int32)(y1 + YGB) >> 6); |
| 1019 *g = Clamp((int32)(y1 - YGB) >> 6); | 1031 *g = Clamp((int32)(y1 + YGB) >> 6); |
| 1020 *r = Clamp((int32)(y1 - YGB) >> 6); | 1032 *r = Clamp((int32)(y1 + YGB) >> 6); |
| 1021 } | 1033 } |
| 1022 | 1034 |
| 1023 #undef YG | 1035 #undef YG |
| 1024 #undef YGB | 1036 #undef YGB |
| 1025 #undef UB | 1037 #undef UB |
| 1026 #undef UG | 1038 #undef UG |
| 1027 #undef VG | 1039 #undef VG |
| 1028 #undef VR | 1040 #undef VR |
| 1029 #undef BB | 1041 #undef BB |
| 1030 #undef BG | 1042 #undef BG |
| 1031 #undef BR | 1043 #undef BR |
| 1032 | 1044 |
| 1045 // JPEG YUV to RGB reference |
| 1046 // * R = Y - V * -1.40200 |
| 1047 // * G = Y - U * 0.34414 - V * 0.71414 |
| 1048 // * B = Y - U * -1.77200 |
| 1049 |
| 1050 // Y contribution to R,G,B. Scale and bias. |
| 1051 // TODO(fbarchard): Consider moving constants into a common header. |
| 1052 #define YGJ 16320 /* round(1.000 * 64 * 256 * 256 / 257) */ |
| 1053 #define YGBJ 32 /* 64 / 2 */ |
| 1054 |
| 1055 // U and V contributions to R,G,B. |
| 1056 #define UBJ -113 /* round(-1.77200 * 64) */ |
| 1057 #define UGJ 22 /* round(0.34414 * 64) */ |
| 1058 #define VGJ 46 /* round(0.71414 * 64) */ |
| 1059 #define VRJ -90 /* round(-1.40200 * 64) */ |
| 1060 |
| 1061 // Bias values to subtract 16 from Y and 128 from U and V. |
| 1062 #define BBJ (UBJ * 128 + YGBJ) |
| 1063 #define BGJ (UGJ * 128 + VGJ * 128 + YGBJ) |
| 1064 #define BRJ (VRJ * 128 + YGBJ) |
| 1065 |
| 1066 // C reference code that mimics the YUV assembly. |
| 1067 static __inline void YuvJPixel(uint8 y, uint8 u, uint8 v, |
| 1068 uint8* b, uint8* g, uint8* r) { |
| 1069 uint32 y1 = (uint32)(y * 0x0101 * YGJ) >> 16; |
| 1070 *b = Clamp((int32)(-(u * UBJ) + y1 + BBJ) >> 6); |
| 1071 *g = Clamp((int32)(-(v * VGJ + u * UGJ) + y1 + BGJ) >> 6); |
| 1072 *r = Clamp((int32)(-(v * VRJ) + y1 + BRJ) >> 6); |
| 1073 } |
| 1074 |
| 1075 #undef YGJ |
| 1076 #undef YGBJ |
| 1077 #undef UBJ |
| 1078 #undef UGJ |
| 1079 #undef VGJ |
| 1080 #undef VRJ |
| 1081 #undef BBJ |
| 1082 #undef BGJ |
| 1083 #undef BRJ |
| 1084 |
| 1033 #if !defined(LIBYUV_DISABLE_NEON) && \ | 1085 #if !defined(LIBYUV_DISABLE_NEON) && \ |
| 1034 (defined(__ARM_NEON__) || defined(__aarch64__) || defined(LIBYUV_NEON)) | 1086 (defined(__ARM_NEON__) || defined(__aarch64__) || defined(LIBYUV_NEON)) |
| 1035 // C mimic assembly. | 1087 // C mimic assembly. |
| 1036 // TODO(fbarchard): Remove subsampling from Neon. | 1088 // TODO(fbarchard): Remove subsampling from Neon. |
| 1037 void I444ToARGBRow_C(const uint8* src_y, | 1089 void I444ToARGBRow_C(const uint8* src_y, |
| 1038 const uint8* src_u, | 1090 const uint8* src_u, |
| 1039 const uint8* src_v, | 1091 const uint8* src_v, |
| 1040 uint8* rgb_buf, | 1092 uint8* rgb_buf, |
| 1041 int width) { | 1093 int width) { |
| 1042 int x; | 1094 int x; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 src_v += 1; | 1147 src_v += 1; |
| 1096 rgb_buf += 8; // Advance 2 pixels. | 1148 rgb_buf += 8; // Advance 2 pixels. |
| 1097 } | 1149 } |
| 1098 if (width & 1) { | 1150 if (width & 1) { |
| 1099 YuvPixel(src_y[0], src_u[0], src_v[0], | 1151 YuvPixel(src_y[0], src_u[0], src_v[0], |
| 1100 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); | 1152 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); |
| 1101 rgb_buf[3] = 255; | 1153 rgb_buf[3] = 255; |
| 1102 } | 1154 } |
| 1103 } | 1155 } |
| 1104 | 1156 |
| 1105 // C reference code that mimics the YUV assembly. | |
| 1106 // * R = Y + 1.40200 * Cr | |
| 1107 // * G = Y - 0.34414 * Cb - 0.71414 * Cr | |
| 1108 // * B = Y + 1.77200 * Cb | |
| 1109 | |
| 1110 #define YGJ 64 /* (int8)round(1.000 * 64) */ | |
| 1111 | |
| 1112 #define UBJ 113 /* (int8)round(1.772 * 64) */ | |
| 1113 #define UGJ -22 /* (int8)round(-0.34414 * 64) */ | |
| 1114 #define URJ 0 | |
| 1115 | |
| 1116 #define VBJ 0 | |
| 1117 #define VGJ -46 /* (int8)round(-0.71414 * 64) */ | |
| 1118 #define VRJ 90 /* (int8)round(1.402 * 64) */ | |
| 1119 | |
| 1120 // Bias | |
| 1121 #define BBJ (UBJ * 128 + VBJ * 128) | |
| 1122 #define BGJ (UGJ * 128 + VGJ * 128) | |
| 1123 #define BRJ (URJ * 128 + VRJ * 128) | |
| 1124 | |
| 1125 static __inline void YuvJPixel(uint8 y, uint8 u, uint8 v, | |
| 1126 uint8* b, uint8* g, uint8* r) { | |
| 1127 uint32 y1 = (uint32)(y * YGJ); | |
| 1128 *b = Clamp((int32)(u * UBJ + v * VBJ + y1 - BBJ) >> 6); | |
| 1129 *g = Clamp((int32)(u * UGJ + v * VGJ + y1 - BGJ) >> 6); | |
| 1130 *r = Clamp((int32)(u * URJ + v * VRJ + y1 - BRJ) >> 6); | |
| 1131 } | |
| 1132 | |
| 1133 void J422ToARGBRow_C(const uint8* src_y, | 1157 void J422ToARGBRow_C(const uint8* src_y, |
| 1134 const uint8* src_u, | 1158 const uint8* src_u, |
| 1135 const uint8* src_v, | 1159 const uint8* src_v, |
| 1136 uint8* rgb_buf, | 1160 uint8* rgb_buf, |
| 1137 int width) { | 1161 int width) { |
| 1138 int x; | 1162 int x; |
| 1139 for (x = 0; x < width - 1; x += 2) { | 1163 for (x = 0; x < width - 1; x += 2) { |
| 1140 YuvJPixel(src_y[0], src_u[0], src_v[0], | 1164 YuvJPixel(src_y[0], src_u[0], src_v[0], |
| 1141 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); | 1165 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); |
| 1142 rgb_buf[3] = 255; | 1166 rgb_buf[3] = 255; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 rgb_buf += 8; // Advance 2 pixels. | 1371 rgb_buf += 8; // Advance 2 pixels. |
| 1348 } | 1372 } |
| 1349 if (width & 1) { | 1373 if (width & 1) { |
| 1350 YuvPixel(src_y[0], src_u[0], src_v[0], | 1374 YuvPixel(src_y[0], src_u[0], src_v[0], |
| 1351 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); | 1375 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); |
| 1352 rgb_buf[3] = 255; | 1376 rgb_buf[3] = 255; |
| 1353 } | 1377 } |
| 1354 } | 1378 } |
| 1355 | 1379 |
| 1356 void NV12ToARGBRow_C(const uint8* src_y, | 1380 void NV12ToARGBRow_C(const uint8* src_y, |
| 1357 const uint8* usrc_v, | 1381 const uint8* src_uv, |
| 1358 uint8* rgb_buf, | 1382 uint8* rgb_buf, |
| 1359 int width) { | 1383 int width) { |
| 1360 int x; | 1384 int x; |
| 1361 for (x = 0; x < width - 1; x += 2) { | 1385 for (x = 0; x < width - 1; x += 2) { |
| 1362 YuvPixel(src_y[0], usrc_v[0], usrc_v[1], | 1386 YuvPixel(src_y[0], src_uv[0], src_uv[1], |
| 1363 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); | 1387 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); |
| 1364 rgb_buf[3] = 255; | 1388 rgb_buf[3] = 255; |
| 1365 YuvPixel(src_y[1], usrc_v[0], usrc_v[1], | 1389 YuvPixel(src_y[1], src_uv[0], src_uv[1], |
| 1366 rgb_buf + 4, rgb_buf + 5, rgb_buf + 6); | 1390 rgb_buf + 4, rgb_buf + 5, rgb_buf + 6); |
| 1367 rgb_buf[7] = 255; | 1391 rgb_buf[7] = 255; |
| 1368 src_y += 2; | 1392 src_y += 2; |
| 1369 usrc_v += 2; | 1393 src_uv += 2; |
| 1370 rgb_buf += 8; // Advance 2 pixels. | 1394 rgb_buf += 8; // Advance 2 pixels. |
| 1371 } | 1395 } |
| 1372 if (width & 1) { | 1396 if (width & 1) { |
| 1373 YuvPixel(src_y[0], usrc_v[0], usrc_v[1], | 1397 YuvPixel(src_y[0], src_uv[0], src_uv[1], |
| 1374 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); | 1398 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); |
| 1375 rgb_buf[3] = 255; | 1399 rgb_buf[3] = 255; |
| 1376 } | 1400 } |
| 1377 } | 1401 } |
| 1378 | 1402 |
| 1379 void NV21ToARGBRow_C(const uint8* src_y, | 1403 void NV21ToARGBRow_C(const uint8* src_y, |
| 1380 const uint8* src_vu, | 1404 const uint8* src_vu, |
| 1381 uint8* rgb_buf, | 1405 uint8* rgb_buf, |
| 1382 int width) { | 1406 int width) { |
| 1383 int x; | 1407 int x; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1395 rgb_buf += 8; // Advance 2 pixels. | 1419 rgb_buf += 8; // Advance 2 pixels. |
| 1396 } | 1420 } |
| 1397 if (width & 1) { | 1421 if (width & 1) { |
| 1398 YuvPixel(src_y[0], src_vu[1], src_vu[0], | 1422 YuvPixel(src_y[0], src_vu[1], src_vu[0], |
| 1399 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); | 1423 rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); |
| 1400 rgb_buf[3] = 255; | 1424 rgb_buf[3] = 255; |
| 1401 } | 1425 } |
| 1402 } | 1426 } |
| 1403 | 1427 |
| 1404 void NV12ToRGB565Row_C(const uint8* src_y, | 1428 void NV12ToRGB565Row_C(const uint8* src_y, |
| 1405 const uint8* usrc_v, | 1429 const uint8* src_uv, |
| 1406 uint8* dst_rgb565, | 1430 uint8* dst_rgb565, |
| 1407 int width) { | 1431 int width) { |
| 1408 uint8 b0; | 1432 uint8 b0; |
| 1409 uint8 g0; | 1433 uint8 g0; |
| 1410 uint8 r0; | 1434 uint8 r0; |
| 1411 uint8 b1; | 1435 uint8 b1; |
| 1412 uint8 g1; | 1436 uint8 g1; |
| 1413 uint8 r1; | 1437 uint8 r1; |
| 1414 int x; | 1438 int x; |
| 1415 for (x = 0; x < width - 1; x += 2) { | 1439 for (x = 0; x < width - 1; x += 2) { |
| 1416 YuvPixel(src_y[0], usrc_v[0], usrc_v[1], &b0, &g0, &r0); | 1440 YuvPixel(src_y[0], src_uv[0], src_uv[1], &b0, &g0, &r0); |
| 1417 YuvPixel(src_y[1], usrc_v[0], usrc_v[1], &b1, &g1, &r1); | 1441 YuvPixel(src_y[1], src_uv[0], src_uv[1], &b1, &g1, &r1); |
| 1418 b0 = b0 >> 3; | 1442 b0 = b0 >> 3; |
| 1419 g0 = g0 >> 2; | 1443 g0 = g0 >> 2; |
| 1420 r0 = r0 >> 3; | 1444 r0 = r0 >> 3; |
| 1421 b1 = b1 >> 3; | 1445 b1 = b1 >> 3; |
| 1422 g1 = g1 >> 2; | 1446 g1 = g1 >> 2; |
| 1423 r1 = r1 >> 3; | 1447 r1 = r1 >> 3; |
| 1424 *(uint32*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11) | | 1448 *(uint32*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11) | |
| 1425 (b1 << 16) | (g1 << 21) | (r1 << 27); | 1449 (b1 << 16) | (g1 << 21) | (r1 << 27); |
| 1426 src_y += 2; | 1450 src_y += 2; |
| 1427 usrc_v += 2; | 1451 src_uv += 2; |
| 1428 dst_rgb565 += 4; // Advance 2 pixels. | 1452 dst_rgb565 += 4; // Advance 2 pixels. |
| 1429 } | 1453 } |
| 1430 if (width & 1) { | 1454 if (width & 1) { |
| 1431 YuvPixel(src_y[0], usrc_v[0], usrc_v[1], &b0, &g0, &r0); | 1455 YuvPixel(src_y[0], src_uv[0], src_uv[1], &b0, &g0, &r0); |
| 1432 b0 = b0 >> 3; | 1456 b0 = b0 >> 3; |
| 1433 g0 = g0 >> 2; | 1457 g0 = g0 >> 2; |
| 1434 r0 = r0 >> 3; | 1458 r0 = r0 >> 3; |
| 1435 *(uint16*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11); | 1459 *(uint16*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11); |
| 1436 } | 1460 } |
| 1437 } | 1461 } |
| 1438 | 1462 |
| 1439 void NV21ToRGB565Row_C(const uint8* src_y, | 1463 void NV21ToRGB565Row_C(const uint8* src_y, |
| 1440 const uint8* vsrc_u, | 1464 const uint8* vsrc_u, |
| 1441 uint8* dst_rgb565, | 1465 uint8* dst_rgb565, |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1581 src_v += 1; | 1605 src_v += 1; |
| 1582 rgb_buf += 8; // Advance 2 pixels. | 1606 rgb_buf += 8; // Advance 2 pixels. |
| 1583 } | 1607 } |
| 1584 if (width & 1) { | 1608 if (width & 1) { |
| 1585 YuvPixel(src_y[0], src_u[0], src_v[0], | 1609 YuvPixel(src_y[0], src_u[0], src_v[0], |
| 1586 rgb_buf + 1, rgb_buf + 2, rgb_buf + 3); | 1610 rgb_buf + 1, rgb_buf + 2, rgb_buf + 3); |
| 1587 rgb_buf[0] = 255; | 1611 rgb_buf[0] = 255; |
| 1588 } | 1612 } |
| 1589 } | 1613 } |
| 1590 | 1614 |
| 1591 void YToARGBRow_C(const uint8* src_y, uint8* rgb_buf, int width) { | 1615 void I400ToARGBRow_C(const uint8* src_y, uint8* rgb_buf, int width) { |
| 1592 int x; | 1616 int x; |
| 1593 for (x = 0; x < width - 1; x += 2) { | 1617 for (x = 0; x < width - 1; x += 2) { |
| 1594 YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); | 1618 YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); |
| 1595 rgb_buf[3] = 255; | 1619 rgb_buf[3] = 255; |
| 1596 YPixel(src_y[1], rgb_buf + 4, rgb_buf + 5, rgb_buf + 6); | 1620 YPixel(src_y[1], rgb_buf + 4, rgb_buf + 5, rgb_buf + 6); |
| 1597 rgb_buf[7] = 255; | 1621 rgb_buf[7] = 255; |
| 1598 src_y += 2; | 1622 src_y += 2; |
| 1599 rgb_buf += 8; // Advance 2 pixels. | 1623 rgb_buf += 8; // Advance 2 pixels. |
| 1600 } | 1624 } |
| 1601 if (width & 1) { | 1625 if (width & 1) { |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2055 dst_ptr[1] = (src_ptr[1] * y0_fraction + src_ptr1[1] * y1_fraction) >> 8; | 2079 dst_ptr[1] = (src_ptr[1] * y0_fraction + src_ptr1[1] * y1_fraction) >> 8; |
| 2056 src_ptr += 2; | 2080 src_ptr += 2; |
| 2057 src_ptr1 += 2; | 2081 src_ptr1 += 2; |
| 2058 dst_ptr += 2; | 2082 dst_ptr += 2; |
| 2059 } | 2083 } |
| 2060 if (width & 1) { | 2084 if (width & 1) { |
| 2061 dst_ptr[0] = (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8; | 2085 dst_ptr[0] = (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8; |
| 2062 } | 2086 } |
| 2063 } | 2087 } |
| 2064 | 2088 |
| 2065 // Select G channel from ARGB. e.g. GGGGGGGG | |
| 2066 void ARGBToBayerGGRow_C(const uint8* src_argb, | |
| 2067 uint8* dst_bayer, uint32 selector, int pix) { | |
| 2068 // Copy a row of G. | |
| 2069 int x; | |
| 2070 for (x = 0; x < pix - 1; x += 2) { | |
| 2071 dst_bayer[0] = src_argb[1]; | |
| 2072 dst_bayer[1] = src_argb[5]; | |
| 2073 src_argb += 8; | |
| 2074 dst_bayer += 2; | |
| 2075 } | |
| 2076 if (pix & 1) { | |
| 2077 dst_bayer[0] = src_argb[1]; | |
| 2078 } | |
| 2079 } | |
| 2080 | |
| 2081 // Use first 4 shuffler values to reorder ARGB channels. | 2089 // Use first 4 shuffler values to reorder ARGB channels. |
| 2082 void ARGBShuffleRow_C(const uint8* src_argb, uint8* dst_argb, | 2090 void ARGBShuffleRow_C(const uint8* src_argb, uint8* dst_argb, |
| 2083 const uint8* shuffler, int pix) { | 2091 const uint8* shuffler, int pix) { |
| 2084 int index0 = shuffler[0]; | 2092 int index0 = shuffler[0]; |
| 2085 int index1 = shuffler[1]; | 2093 int index1 = shuffler[1]; |
| 2086 int index2 = shuffler[2]; | 2094 int index2 = shuffler[2]; |
| 2087 int index3 = shuffler[3]; | 2095 int index3 = shuffler[3]; |
| 2088 // Shuffle a row of ARGB. | 2096 // Shuffle a row of ARGB. |
| 2089 int x; | 2097 int x; |
| 2090 for (x = 0; x < pix; ++x) { | 2098 for (x = 0; x < pix; ++x) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2113 dst_frame[2] = src_y[1]; | 2121 dst_frame[2] = src_y[1]; |
| 2114 dst_frame[3] = src_v[0]; | 2122 dst_frame[3] = src_v[0]; |
| 2115 dst_frame += 4; | 2123 dst_frame += 4; |
| 2116 src_y += 2; | 2124 src_y += 2; |
| 2117 src_u += 1; | 2125 src_u += 1; |
| 2118 src_v += 1; | 2126 src_v += 1; |
| 2119 } | 2127 } |
| 2120 if (width & 1) { | 2128 if (width & 1) { |
| 2121 dst_frame[0] = src_y[0]; | 2129 dst_frame[0] = src_y[0]; |
| 2122 dst_frame[1] = src_u[0]; | 2130 dst_frame[1] = src_u[0]; |
| 2123 dst_frame[2] = src_y[0]; // duplicate last y | 2131 dst_frame[2] = 0; |
| 2124 dst_frame[3] = src_v[0]; | 2132 dst_frame[3] = src_v[0]; |
| 2125 } | 2133 } |
| 2126 } | 2134 } |
| 2127 | 2135 |
| 2128 void I422ToUYVYRow_C(const uint8* src_y, | 2136 void I422ToUYVYRow_C(const uint8* src_y, |
| 2129 const uint8* src_u, | 2137 const uint8* src_u, |
| 2130 const uint8* src_v, | 2138 const uint8* src_v, |
| 2131 uint8* dst_frame, int width) { | 2139 uint8* dst_frame, int width) { |
| 2132 int x; | 2140 int x; |
| 2133 for (x = 0; x < width - 1; x += 2) { | 2141 for (x = 0; x < width - 1; x += 2) { |
| 2134 dst_frame[0] = src_u[0]; | 2142 dst_frame[0] = src_u[0]; |
| 2135 dst_frame[1] = src_y[0]; | 2143 dst_frame[1] = src_y[0]; |
| 2136 dst_frame[2] = src_v[0]; | 2144 dst_frame[2] = src_v[0]; |
| 2137 dst_frame[3] = src_y[1]; | 2145 dst_frame[3] = src_y[1]; |
| 2138 dst_frame += 4; | 2146 dst_frame += 4; |
| 2139 src_y += 2; | 2147 src_y += 2; |
| 2140 src_u += 1; | 2148 src_u += 1; |
| 2141 src_v += 1; | 2149 src_v += 1; |
| 2142 } | 2150 } |
| 2143 if (width & 1) { | 2151 if (width & 1) { |
| 2144 dst_frame[0] = src_u[0]; | 2152 dst_frame[0] = src_u[0]; |
| 2145 dst_frame[1] = src_y[0]; | 2153 dst_frame[1] = src_y[0]; |
| 2146 dst_frame[2] = src_v[0]; | 2154 dst_frame[2] = src_v[0]; |
| 2147 dst_frame[3] = src_y[0]; // duplicate last y | 2155 dst_frame[3] = 0; |
| 2148 } | 2156 } |
| 2149 } | 2157 } |
| 2150 | 2158 |
| 2151 // Maximum temporary width for wrappers to process at a time, in pixels. | 2159 // Maximum temporary width for wrappers to process at a time, in pixels. |
| 2152 #define MAXTWIDTH 2048 | 2160 #define MAXTWIDTH 2048 |
| 2153 | 2161 |
| 2154 #if !defined(_MSC_VER) && defined(HAS_I422TORGB565ROW_SSSE3) | 2162 #if !(defined(_MSC_VER) && !defined(__clang__)) && \ |
| 2163 defined(HAS_I422TORGB565ROW_SSSE3) |
| 2155 // row_win.cc has asm version, but GCC uses 2 step wrapper. | 2164 // row_win.cc has asm version, but GCC uses 2 step wrapper. |
| 2156 void I422ToRGB565Row_SSSE3(const uint8* src_y, | 2165 void I422ToRGB565Row_SSSE3(const uint8* src_y, |
| 2157 const uint8* src_u, | 2166 const uint8* src_u, |
| 2158 const uint8* src_v, | 2167 const uint8* src_v, |
| 2159 uint8* dst_rgb565, | 2168 uint8* dst_rgb565, |
| 2160 int width) { | 2169 int width) { |
| 2161 SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); | 2170 SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]); |
| 2162 while (width > 0) { | 2171 while (width > 0) { |
| 2163 int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; | 2172 int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; |
| 2164 I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, twidth); | 2173 I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, twidth); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2339 ARGBToARGB4444Row_AVX2(row, dst_argb4444, twidth); | 2348 ARGBToARGB4444Row_AVX2(row, dst_argb4444, twidth); |
| 2340 src_y += twidth; | 2349 src_y += twidth; |
| 2341 src_u += twidth / 2; | 2350 src_u += twidth / 2; |
| 2342 src_v += twidth / 2; | 2351 src_v += twidth / 2; |
| 2343 dst_argb4444 += twidth * 2; | 2352 dst_argb4444 += twidth * 2; |
| 2344 width -= twidth; | 2353 width -= twidth; |
| 2345 } | 2354 } |
| 2346 } | 2355 } |
| 2347 #endif | 2356 #endif |
| 2348 | 2357 |
| 2358 #if defined(HAS_I422TORGB24ROW_AVX2) |
| 2359 void I422ToRGB24Row_AVX2(const uint8* src_y, |
| 2360 const uint8* src_u, |
| 2361 const uint8* src_v, |
| 2362 uint8* dst_rgb24, |
| 2363 int width) { |
| 2364 // Row buffer for intermediate ARGB pixels. |
| 2365 SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]); |
| 2366 while (width > 0) { |
| 2367 int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; |
| 2368 I422ToARGBRow_AVX2(src_y, src_u, src_v, row, twidth); |
| 2369 // TODO(fbarchard): ARGBToRGB24Row_AVX2 |
| 2370 ARGBToRGB24Row_SSSE3(row, dst_rgb24, twidth); |
| 2371 src_y += twidth; |
| 2372 src_u += twidth / 2; |
| 2373 src_v += twidth / 2; |
| 2374 dst_rgb24 += twidth * 3; |
| 2375 width -= twidth; |
| 2376 } |
| 2377 } |
| 2378 #endif |
| 2379 |
| 2380 #if defined(HAS_I422TORAWROW_AVX2) |
| 2381 void I422ToRAWRow_AVX2(const uint8* src_y, |
| 2382 const uint8* src_u, |
| 2383 const uint8* src_v, |
| 2384 uint8* dst_raw, |
| 2385 int width) { |
| 2386 // Row buffer for intermediate ARGB pixels. |
| 2387 SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]); |
| 2388 while (width > 0) { |
| 2389 int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; |
| 2390 I422ToARGBRow_AVX2(src_y, src_u, src_v, row, twidth); |
| 2391 // TODO(fbarchard): ARGBToRAWRow_AVX2 |
| 2392 ARGBToRAWRow_SSSE3(row, dst_raw, twidth); |
| 2393 src_y += twidth; |
| 2394 src_u += twidth / 2; |
| 2395 src_v += twidth / 2; |
| 2396 dst_raw += twidth * 3; |
| 2397 width -= twidth; |
| 2398 } |
| 2399 } |
| 2400 #endif |
| 2401 |
| 2349 #if defined(HAS_NV12TORGB565ROW_AVX2) | 2402 #if defined(HAS_NV12TORGB565ROW_AVX2) |
| 2350 void NV12ToRGB565Row_AVX2(const uint8* src_y, const uint8* src_uv, | 2403 void NV12ToRGB565Row_AVX2(const uint8* src_y, const uint8* src_uv, |
| 2351 uint8* dst_rgb565, int width) { | 2404 uint8* dst_rgb565, int width) { |
| 2352 // Row buffer for intermediate ARGB pixels. | 2405 // Row buffer for intermediate ARGB pixels. |
| 2353 SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]); | 2406 SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]); |
| 2354 while (width > 0) { | 2407 while (width > 0) { |
| 2355 int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; | 2408 int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; |
| 2356 NV12ToARGBRow_AVX2(src_y, src_uv, row, twidth); | 2409 NV12ToARGBRow_AVX2(src_y, src_uv, row, twidth); |
| 2357 ARGBToRGB565Row_AVX2(row, dst_rgb565, twidth); | 2410 ARGBToRGB565Row_AVX2(row, dst_rgb565, twidth); |
| 2358 src_y += twidth; | 2411 src_y += twidth; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2514 } | 2567 } |
| 2515 if (width & 1) { | 2568 if (width & 1) { |
| 2516 dst[3] = src[0]; | 2569 dst[3] = src[0]; |
| 2517 } | 2570 } |
| 2518 } | 2571 } |
| 2519 | 2572 |
| 2520 #ifdef __cplusplus | 2573 #ifdef __cplusplus |
| 2521 } // extern "C" | 2574 } // extern "C" |
| 2522 } // namespace libyuv | 2575 } // namespace libyuv |
| 2523 #endif | 2576 #endif |
| OLD | NEW |