| OLD | NEW |
| 1 // Copyright 2011 Google Inc. All Rights Reserved. | 1 // Copyright 2011 Google Inc. All Rights Reserved. |
| 2 // | 2 // |
| 3 // Use of this source code is governed by a BSD-style license | 3 // Use of this source code is governed by a BSD-style license |
| 4 // that can be found in the COPYING file in the root of the source | 4 // that can be found in the COPYING file in the root of the source |
| 5 // tree. An additional intellectual property rights grant can be found | 5 // tree. An additional intellectual property rights grant can be found |
| 6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
| 7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
| 8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
| 9 // | 9 // |
| 10 // YUV to RGB upsampling functions. | 10 // YUV to RGB upsampling functions. |
| 11 // | 11 // |
| 12 // Author: somnath@google.com (Somnath Banerjee) | 12 // Author: somnath@google.com (Somnath Banerjee) |
| 13 | 13 |
| 14 #include "./dsp.h" | 14 #include "./dsp.h" |
| 15 #include "./yuv.h" | 15 #include "./yuv.h" |
| 16 | 16 |
| 17 #if defined(__cplusplus) || defined(c_plusplus) | 17 #include <assert.h> |
| 18 extern "C" { | |
| 19 #endif | |
| 20 | 18 |
| 21 //------------------------------------------------------------------------------ | 19 //------------------------------------------------------------------------------ |
| 22 // Fancy upsampler | 20 // Fancy upsampler |
| 23 | 21 |
| 24 #ifdef FANCY_UPSAMPLING | 22 #ifdef FANCY_UPSAMPLING |
| 25 | 23 |
| 26 // Fancy upsampling functions to convert YUV to RGB | 24 // Fancy upsampling functions to convert YUV to RGB |
| 27 WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST]; | 25 WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST]; |
| 28 | 26 |
| 29 // Given samples laid out in a square as: | 27 // Given samples laid out in a square as: |
| 30 // [a b] | 28 // [a b] |
| 31 // [c d] | 29 // [c d] |
| 32 // we interpolate u/v as: | 30 // we interpolate u/v as: |
| 33 // ([9*a + 3*b + 3*c + d 3*a + 9*b + 3*c + d] + [8 8]) / 16 | 31 // ([9*a + 3*b + 3*c + d 3*a + 9*b + 3*c + d] + [8 8]) / 16 |
| 34 // ([3*a + b + 9*c + 3*d a + 3*b + 3*c + 9*d] [8 8]) / 16 | 32 // ([3*a + b + 9*c + 3*d a + 3*b + 3*c + 9*d] [8 8]) / 16 |
| 35 | 33 |
| 36 // We process u and v together stashed into 32bit (16bit each). | 34 // We process u and v together stashed into 32bit (16bit each). |
| 37 #define LOAD_UV(u, v) ((u) | ((v) << 16)) | 35 #define LOAD_UV(u, v) ((u) | ((v) << 16)) |
| 38 | 36 |
| 39 #define UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \ | 37 #define UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \ |
| 40 static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ | 38 static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ |
| 41 const uint8_t* top_u, const uint8_t* top_v, \ | 39 const uint8_t* top_u, const uint8_t* top_v, \ |
| 42 const uint8_t* cur_u, const uint8_t* cur_v, \ | 40 const uint8_t* cur_u, const uint8_t* cur_v, \ |
| 43 uint8_t* top_dst, uint8_t* bottom_dst, int len) { \ | 41 uint8_t* top_dst, uint8_t* bottom_dst, int len) { \ |
| 44 int x; \ | 42 int x; \ |
| 45 const int last_pixel_pair = (len - 1) >> 1; \ | 43 const int last_pixel_pair = (len - 1) >> 1; \ |
| 46 uint32_t tl_uv = LOAD_UV(top_u[0], top_v[0]); /* top-left sample */ \ | 44 uint32_t tl_uv = LOAD_UV(top_u[0], top_v[0]); /* top-left sample */ \ |
| 47 uint32_t l_uv = LOAD_UV(cur_u[0], cur_v[0]); /* left-sample */ \ | 45 uint32_t l_uv = LOAD_UV(cur_u[0], cur_v[0]); /* left-sample */ \ |
| 48 if (top_y) { \ | 46 assert(top_y != NULL); \ |
| 47 { \ |
| 49 const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \ | 48 const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \ |
| 50 FUNC(top_y[0], uv0 & 0xff, (uv0 >> 16), top_dst); \ | 49 FUNC(top_y[0], uv0 & 0xff, (uv0 >> 16), top_dst); \ |
| 51 } \ | 50 } \ |
| 52 if (bottom_y) { \ | 51 if (bottom_y != NULL) { \ |
| 53 const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \ | 52 const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \ |
| 54 FUNC(bottom_y[0], uv0 & 0xff, (uv0 >> 16), bottom_dst); \ | 53 FUNC(bottom_y[0], uv0 & 0xff, (uv0 >> 16), bottom_dst); \ |
| 55 } \ | 54 } \ |
| 56 for (x = 1; x <= last_pixel_pair; ++x) { \ | 55 for (x = 1; x <= last_pixel_pair; ++x) { \ |
| 57 const uint32_t t_uv = LOAD_UV(top_u[x], top_v[x]); /* top sample */ \ | 56 const uint32_t t_uv = LOAD_UV(top_u[x], top_v[x]); /* top sample */ \ |
| 58 const uint32_t uv = LOAD_UV(cur_u[x], cur_v[x]); /* sample */ \ | 57 const uint32_t uv = LOAD_UV(cur_u[x], cur_v[x]); /* sample */ \ |
| 59 /* precompute invariant values associated with first and second diagonals*/\ | 58 /* precompute invariant values associated with first and second diagonals*/\ |
| 60 const uint32_t avg = tl_uv + t_uv + l_uv + uv + 0x00080008u; \ | 59 const uint32_t avg = tl_uv + t_uv + l_uv + uv + 0x00080008u; \ |
| 61 const uint32_t diag_12 = (avg + 2 * (t_uv + l_uv)) >> 3; \ | 60 const uint32_t diag_12 = (avg + 2 * (t_uv + l_uv)) >> 3; \ |
| 62 const uint32_t diag_03 = (avg + 2 * (tl_uv + uv)) >> 3; \ | 61 const uint32_t diag_03 = (avg + 2 * (tl_uv + uv)) >> 3; \ |
| 63 if (top_y) { \ | 62 { \ |
| 64 const uint32_t uv0 = (diag_12 + tl_uv) >> 1; \ | 63 const uint32_t uv0 = (diag_12 + tl_uv) >> 1; \ |
| 65 const uint32_t uv1 = (diag_03 + t_uv) >> 1; \ | 64 const uint32_t uv1 = (diag_03 + t_uv) >> 1; \ |
| 66 FUNC(top_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \ | 65 FUNC(top_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \ |
| 67 top_dst + (2 * x - 1) * XSTEP); \ | 66 top_dst + (2 * x - 1) * XSTEP); \ |
| 68 FUNC(top_y[2 * x - 0], uv1 & 0xff, (uv1 >> 16), \ | 67 FUNC(top_y[2 * x - 0], uv1 & 0xff, (uv1 >> 16), \ |
| 69 top_dst + (2 * x - 0) * XSTEP); \ | 68 top_dst + (2 * x - 0) * XSTEP); \ |
| 70 } \ | 69 } \ |
| 71 if (bottom_y) { \ | 70 if (bottom_y != NULL) { \ |
| 72 const uint32_t uv0 = (diag_03 + l_uv) >> 1; \ | 71 const uint32_t uv0 = (diag_03 + l_uv) >> 1; \ |
| 73 const uint32_t uv1 = (diag_12 + uv) >> 1; \ | 72 const uint32_t uv1 = (diag_12 + uv) >> 1; \ |
| 74 FUNC(bottom_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \ | 73 FUNC(bottom_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \ |
| 75 bottom_dst + (2 * x - 1) * XSTEP); \ | 74 bottom_dst + (2 * x - 1) * XSTEP); \ |
| 76 FUNC(bottom_y[2 * x + 0], uv1 & 0xff, (uv1 >> 16), \ | 75 FUNC(bottom_y[2 * x + 0], uv1 & 0xff, (uv1 >> 16), \ |
| 77 bottom_dst + (2 * x + 0) * XSTEP); \ | 76 bottom_dst + (2 * x + 0) * XSTEP); \ |
| 78 } \ | 77 } \ |
| 79 tl_uv = t_uv; \ | 78 tl_uv = t_uv; \ |
| 80 l_uv = uv; \ | 79 l_uv = uv; \ |
| 81 } \ | 80 } \ |
| 82 if (!(len & 1)) { \ | 81 if (!(len & 1)) { \ |
| 83 if (top_y) { \ | 82 { \ |
| 84 const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \ | 83 const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \ |
| 85 FUNC(top_y[len - 1], uv0 & 0xff, (uv0 >> 16), \ | 84 FUNC(top_y[len - 1], uv0 & 0xff, (uv0 >> 16), \ |
| 86 top_dst + (len - 1) * XSTEP); \ | 85 top_dst + (len - 1) * XSTEP); \ |
| 87 } \ | 86 } \ |
| 88 if (bottom_y) { \ | 87 if (bottom_y != NULL) { \ |
| 89 const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \ | 88 const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \ |
| 90 FUNC(bottom_y[len - 1], uv0 & 0xff, (uv0 >> 16), \ | 89 FUNC(bottom_y[len - 1], uv0 & 0xff, (uv0 >> 16), \ |
| 91 bottom_dst + (len - 1) * XSTEP); \ | 90 bottom_dst + (len - 1) * XSTEP); \ |
| 92 } \ | 91 } \ |
| 93 } \ | 92 } \ |
| 94 } | 93 } |
| 95 | 94 |
| 96 // All variants implemented. | 95 // All variants implemented. |
| 97 UPSAMPLE_FUNC(UpsampleRgbLinePair, VP8YuvToRgb, 3) | 96 UPSAMPLE_FUNC(UpsampleRgbLinePair, VP8YuvToRgb, 3) |
| 98 UPSAMPLE_FUNC(UpsampleBgrLinePair, VP8YuvToBgr, 3) | 97 UPSAMPLE_FUNC(UpsampleBgrLinePair, VP8YuvToBgr, 3) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 //------------------------------------------------------------------------------ | 160 //------------------------------------------------------------------------------ |
| 162 | 161 |
| 163 #if !defined(FANCY_UPSAMPLING) | 162 #if !defined(FANCY_UPSAMPLING) |
| 164 #define DUAL_SAMPLE_FUNC(FUNC_NAME, FUNC) \ | 163 #define DUAL_SAMPLE_FUNC(FUNC_NAME, FUNC) \ |
| 165 static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bot_y, \ | 164 static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bot_y, \ |
| 166 const uint8_t* top_u, const uint8_t* top_v, \ | 165 const uint8_t* top_u, const uint8_t* top_v, \ |
| 167 const uint8_t* bot_u, const uint8_t* bot_v, \ | 166 const uint8_t* bot_u, const uint8_t* bot_v, \ |
| 168 uint8_t* top_dst, uint8_t* bot_dst, int len) { \ | 167 uint8_t* top_dst, uint8_t* bot_dst, int len) { \ |
| 169 const int half_len = len >> 1; \ | 168 const int half_len = len >> 1; \ |
| 170 int x; \ | 169 int x; \ |
| 171 if (top_dst != NULL) { \ | 170 assert(top_dst != NULL); \ |
| 171 { \ |
| 172 for (x = 0; x < half_len; ++x) { \ | 172 for (x = 0; x < half_len; ++x) { \ |
| 173 FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x + 0); \ | 173 FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x + 0); \ |
| 174 FUNC(top_y[2 * x + 1], top_u[x], top_v[x], top_dst + 8 * x + 4); \ | 174 FUNC(top_y[2 * x + 1], top_u[x], top_v[x], top_dst + 8 * x + 4); \ |
| 175 } \ | 175 } \ |
| 176 if (len & 1) FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x); \ | 176 if (len & 1) FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x); \ |
| 177 } \ | 177 } \ |
| 178 if (bot_dst != NULL) { \ | 178 if (bot_dst != NULL) { \ |
| 179 for (x = 0; x < half_len; ++x) { \ | 179 for (x = 0; x < half_len; ++x) { \ |
| 180 FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x + 0); \ | 180 FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x + 0); \ |
| 181 FUNC(bot_y[2 * x + 1], bot_u[x], bot_v[x], bot_dst + 8 * x + 4); \ | 181 FUNC(bot_y[2 * x + 1], bot_u[x], bot_v[x], bot_dst + 8 * x + 4); \ |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 #endif | 357 #endif |
| 358 #if defined(WEBP_USE_NEON) | 358 #if defined(WEBP_USE_NEON) |
| 359 if (VP8GetCPUInfo(kNEON)) { | 359 if (VP8GetCPUInfo(kNEON)) { |
| 360 WebPInitPremultiplyNEON(); | 360 WebPInitPremultiplyNEON(); |
| 361 } | 361 } |
| 362 #endif | 362 #endif |
| 363 } | 363 } |
| 364 #endif // FANCY_UPSAMPLING | 364 #endif // FANCY_UPSAMPLING |
| 365 } | 365 } |
| 366 | 366 |
| 367 #if defined(__cplusplus) || defined(c_plusplus) | |
| 368 } // extern "C" | |
| 369 #endif | |
| OLD | NEW |