| OLD | NEW |
| 1 // Copyright 2016 Google Inc. All Rights Reserved. | 1 // Copyright 2016 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 // SSE2 code common to several files. | 10 // SSE2 code common to several files. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 *out0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1); | 93 *out0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1); |
| 94 *out1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1); | 94 *out1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1); |
| 95 *out2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3); | 95 *out2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3); |
| 96 *out3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3); | 96 *out3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3); |
| 97 // a00 a10 a20 a30 b00 b10 b20 b30 | 97 // a00 a10 a20 a30 b00 b10 b20 b30 |
| 98 // a01 a11 a21 a31 b01 b11 b21 b31 | 98 // a01 a11 a21 a31 b01 b11 b21 b31 |
| 99 // a02 a12 a22 a32 b02 b12 b22 b32 | 99 // a02 a12 a22 a32 b02 b12 b22 b32 |
| 100 // a03 a13 a23 a33 b03 b13 b23 b33 | 100 // a03 a13 a23 a33 b03 b13 b23 b33 |
| 101 } | 101 } |
| 102 | 102 |
| 103 //------------------------------------------------------------------------------ |
| 104 // Channel mixing. |
| 105 |
| 106 // Function used several times in VP8PlanarTo24b. |
| 107 // It samples the in buffer as follows: one every two unsigned char is stored |
| 108 // at the beginning of the buffer, while the other half is stored at the end. |
| 109 #define VP8PlanarTo24bHelper(IN, OUT) \ |
| 110 do { \ |
| 111 const __m128i v_mask = _mm_set1_epi16(0x00ff); \ |
| 112 /* Take one every two upper 8b values.*/ \ |
| 113 (OUT##0) = _mm_packus_epi16(_mm_and_si128((IN##0), v_mask), \ |
| 114 _mm_and_si128((IN##1), v_mask)); \ |
| 115 (OUT##1) = _mm_packus_epi16(_mm_and_si128((IN##2), v_mask), \ |
| 116 _mm_and_si128((IN##3), v_mask)); \ |
| 117 (OUT##2) = _mm_packus_epi16(_mm_and_si128((IN##4), v_mask), \ |
| 118 _mm_and_si128((IN##5), v_mask)); \ |
| 119 /* Take one every two lower 8b values.*/ \ |
| 120 (OUT##3) = _mm_packus_epi16(_mm_srli_epi16((IN##0), 8), \ |
| 121 _mm_srli_epi16((IN##1), 8)); \ |
| 122 (OUT##4) = _mm_packus_epi16(_mm_srli_epi16((IN##2), 8), \ |
| 123 _mm_srli_epi16((IN##3), 8)); \ |
| 124 (OUT##5) = _mm_packus_epi16(_mm_srli_epi16((IN##4), 8), \ |
| 125 _mm_srli_epi16((IN##5), 8)); \ |
| 126 } while (0) |
| 127 |
| 128 // Pack the planar buffers |
| 129 // rrrr... rrrr... gggg... gggg... bbbb... bbbb.... |
| 130 // triplet by triplet in the output buffer rgb as rgbrgbrgbrgb ... |
| 131 static WEBP_INLINE void VP8PlanarTo24b(__m128i* const in0, __m128i* const in1, |
| 132 __m128i* const in2, __m128i* const in3, |
| 133 __m128i* const in4, __m128i* const in5) { |
| 134 // The input is 6 registers of sixteen 8b but for the sake of explanation, |
| 135 // let's take 6 registers of four 8b values. |
| 136 // To pack, we will keep taking one every two 8b integer and move it |
| 137 // around as follows: |
| 138 // Input: |
| 139 // r0r1r2r3 | r4r5r6r7 | g0g1g2g3 | g4g5g6g7 | b0b1b2b3 | b4b5b6b7 |
| 140 // Split the 6 registers in two sets of 3 registers: the first set as the even |
| 141 // 8b bytes, the second the odd ones: |
| 142 // r0r2r4r6 | g0g2g4g6 | b0b2b4b6 | r1r3r5r7 | g1g3g5g7 | b1b3b5b7 |
| 143 // Repeat the same permutations twice more: |
| 144 // r0r4g0g4 | b0b4r1r5 | g1g5b1b5 | r2r6g2g6 | b2b6r3r7 | g3g7b3b7 |
| 145 // r0g0b0r1 | g1b1r2g2 | b2r3g3b3 | r4g4b4r5 | g5b5r6g6 | b6r7g7b7 |
| 146 __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; |
| 147 VP8PlanarTo24bHelper(*in, tmp); |
| 148 VP8PlanarTo24bHelper(tmp, *in); |
| 149 VP8PlanarTo24bHelper(*in, tmp); |
| 150 // We need to do it two more times than the example as we have sixteen bytes. |
| 151 { |
| 152 __m128i out0, out1, out2, out3, out4, out5; |
| 153 VP8PlanarTo24bHelper(tmp, out); |
| 154 VP8PlanarTo24bHelper(out, *in); |
| 155 } |
| 156 } |
| 157 |
| 158 #undef VP8PlanarTo24bHelper |
| 159 |
| 160 // Convert four packed four-channel buffers like argbargbargbargb... into the |
| 161 // split channels aaaaa ... rrrr ... gggg .... bbbbb ...... |
| 162 static WEBP_INLINE void VP8L32bToPlanar(__m128i* const in0, |
| 163 __m128i* const in1, |
| 164 __m128i* const in2, |
| 165 __m128i* const in3) { |
| 166 // Column-wise transpose. |
| 167 const __m128i A0 = _mm_unpacklo_epi8(*in0, *in1); |
| 168 const __m128i A1 = _mm_unpackhi_epi8(*in0, *in1); |
| 169 const __m128i A2 = _mm_unpacklo_epi8(*in2, *in3); |
| 170 const __m128i A3 = _mm_unpackhi_epi8(*in2, *in3); |
| 171 const __m128i B0 = _mm_unpacklo_epi8(A0, A1); |
| 172 const __m128i B1 = _mm_unpackhi_epi8(A0, A1); |
| 173 const __m128i B2 = _mm_unpacklo_epi8(A2, A3); |
| 174 const __m128i B3 = _mm_unpackhi_epi8(A2, A3); |
| 175 // C0 = g7 g6 ... g1 g0 | b7 b6 ... b1 b0 |
| 176 // C1 = a7 a6 ... a1 a0 | r7 r6 ... r1 r0 |
| 177 const __m128i C0 = _mm_unpacklo_epi8(B0, B1); |
| 178 const __m128i C1 = _mm_unpackhi_epi8(B0, B1); |
| 179 const __m128i C2 = _mm_unpacklo_epi8(B2, B3); |
| 180 const __m128i C3 = _mm_unpackhi_epi8(B2, B3); |
| 181 // Gather the channels. |
| 182 *in0 = _mm_unpackhi_epi64(C1, C3); |
| 183 *in1 = _mm_unpacklo_epi64(C1, C3); |
| 184 *in2 = _mm_unpackhi_epi64(C0, C2); |
| 185 *in3 = _mm_unpacklo_epi64(C0, C2); |
| 186 } |
| 187 |
| 103 #endif // WEBP_USE_SSE2 | 188 #endif // WEBP_USE_SSE2 |
| 104 | 189 |
| 105 #ifdef __cplusplus | 190 #ifdef __cplusplus |
| 106 } // extern "C" | 191 } // extern "C" |
| 107 #endif | 192 #endif |
| 108 | 193 |
| 109 #endif // WEBP_DSP_COMMON_SSE2_H_ | 194 #endif // WEBP_DSP_COMMON_SSE2_H_ |
| OLD | NEW |