Coverage Report

Created: 2023-09-25 06:56

/src/FreeRDP/libfreerdp/codec/rfx_sse2.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * RemoteFX Codec Library - SSE2 Optimizations
4
 *
5
 * Copyright 2011 Stephen Erisman
6
 * Copyright 2011 Norbert Federa <norbert.federa@thincast.com>
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
#include <freerdp/config.h>
22
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <winpr/sysinfo.h>
27
28
#include <xmmintrin.h>
29
#include <emmintrin.h>
30
31
#include "rfx_types.h"
32
#include "rfx_sse2.h"
33
34
#ifdef _MSC_VER
35
#define __attribute__(...)
36
#endif
37
38
0
#define CACHE_LINE_BYTES 64
39
40
#ifndef __clang__
41
#define ATTRIBUTES __gnu_inline__, __always_inline__, __artificial__
42
#else
43
#define ATTRIBUTES __gnu_inline__, __always_inline__
44
#endif
45
46
#define _mm_between_epi16(_val, _min, _max)                    \
47
  do                                                         \
48
  {                                                          \
49
    _val = _mm_min_epi16(_max, _mm_max_epi16(_val, _min)); \
50
  } while (0)
51
52
static __inline void __attribute__((ATTRIBUTES)) _mm_prefetch_buffer(char* buffer, int num_bytes)
53
0
{
54
0
  __m128i* buf = (__m128i*)buffer;
55
0
  unsigned int i;
56
57
0
  for (i = 0; i < (num_bytes / sizeof(__m128i)); i += (CACHE_LINE_BYTES / sizeof(__m128i)))
58
0
  {
59
0
    _mm_prefetch((char*)(&buf[i]), _MM_HINT_NTA);
60
0
  }
61
0
}
62
63
/* rfx_decode_ycbcr_to_rgb_sse2 code now resides in the primitives library. */
64
/* rfx_encode_rgb_to_ycbcr_sse2 code now resides in the primitives library. */
65
66
static __inline void __attribute__((ATTRIBUTES))
67
rfx_quantization_decode_block_sse2(INT16* buffer, const int buffer_size, const UINT32 factor)
68
0
{
69
0
  __m128i a;
70
0
  __m128i* ptr = (__m128i*)buffer;
71
0
  __m128i* buf_end = (__m128i*)(buffer + buffer_size);
72
73
0
  if (factor == 0)
74
0
    return;
75
76
0
  do
77
0
  {
78
0
    a = _mm_load_si128(ptr);
79
0
    a = _mm_slli_epi16(a, factor);
80
0
    _mm_store_si128(ptr, a);
81
0
    ptr++;
82
0
  } while (ptr < buf_end);
83
0
}
84
85
static void rfx_quantization_decode_sse2(INT16* WINPR_RESTRICT buffer,
86
                                         const UINT32* WINPR_RESTRICT quantVals)
87
0
{
88
0
  WINPR_ASSERT(buffer);
89
0
  WINPR_ASSERT(quantVals);
90
91
0
  _mm_prefetch_buffer((char*)buffer, 4096 * sizeof(INT16));
92
0
  rfx_quantization_decode_block_sse2(&buffer[0], 1024, quantVals[8] - 1);    /* HL1 */
93
0
  rfx_quantization_decode_block_sse2(&buffer[1024], 1024, quantVals[7] - 1); /* LH1 */
94
0
  rfx_quantization_decode_block_sse2(&buffer[2048], 1024, quantVals[9] - 1); /* HH1 */
95
0
  rfx_quantization_decode_block_sse2(&buffer[3072], 256, quantVals[5] - 1);  /* HL2 */
96
0
  rfx_quantization_decode_block_sse2(&buffer[3328], 256, quantVals[4] - 1);  /* LH2 */
97
0
  rfx_quantization_decode_block_sse2(&buffer[3584], 256, quantVals[6] - 1);  /* HH2 */
98
0
  rfx_quantization_decode_block_sse2(&buffer[3840], 64, quantVals[2] - 1);   /* HL3 */
99
0
  rfx_quantization_decode_block_sse2(&buffer[3904], 64, quantVals[1] - 1);   /* LH3 */
100
0
  rfx_quantization_decode_block_sse2(&buffer[3968], 64, quantVals[3] - 1);   /* HH3 */
101
0
  rfx_quantization_decode_block_sse2(&buffer[4032], 64, quantVals[0] - 1);   /* LL3 */
102
0
}
103
104
static __inline void __attribute__((ATTRIBUTES))
105
rfx_quantization_encode_block_sse2(INT16* buffer, const int buffer_size, const UINT32 factor)
106
0
{
107
0
  __m128i a;
108
0
  __m128i* ptr = (__m128i*)buffer;
109
0
  __m128i* buf_end = (__m128i*)(buffer + buffer_size);
110
0
  __m128i half;
111
112
0
  if (factor == 0)
113
0
    return;
114
115
0
  half = _mm_set1_epi16(1 << (factor - 1));
116
117
0
  do
118
0
  {
119
0
    a = _mm_load_si128(ptr);
120
0
    a = _mm_add_epi16(a, half);
121
0
    a = _mm_srai_epi16(a, factor);
122
0
    _mm_store_si128(ptr, a);
123
0
    ptr++;
124
0
  } while (ptr < buf_end);
125
0
}
126
127
static void rfx_quantization_encode_sse2(INT16* WINPR_RESTRICT buffer,
128
                                         const UINT32* WINPR_RESTRICT quantization_values)
129
0
{
130
0
  WINPR_ASSERT(buffer);
131
0
  WINPR_ASSERT(quantization_values);
132
133
0
  _mm_prefetch_buffer((char*)buffer, 4096 * sizeof(INT16));
134
0
  rfx_quantization_encode_block_sse2(buffer, 1024, quantization_values[8] - 6);        /* HL1 */
135
0
  rfx_quantization_encode_block_sse2(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
136
0
  rfx_quantization_encode_block_sse2(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
137
0
  rfx_quantization_encode_block_sse2(buffer + 3072, 256, quantization_values[5] - 6);  /* HL2 */
138
0
  rfx_quantization_encode_block_sse2(buffer + 3328, 256, quantization_values[4] - 6);  /* LH2 */
139
0
  rfx_quantization_encode_block_sse2(buffer + 3584, 256, quantization_values[6] - 6);  /* HH2 */
140
0
  rfx_quantization_encode_block_sse2(buffer + 3840, 64, quantization_values[2] - 6);   /* HL3 */
141
0
  rfx_quantization_encode_block_sse2(buffer + 3904, 64, quantization_values[1] - 6);   /* LH3 */
142
0
  rfx_quantization_encode_block_sse2(buffer + 3968, 64, quantization_values[3] - 6);   /* HH3 */
143
0
  rfx_quantization_encode_block_sse2(buffer + 4032, 64, quantization_values[0] - 6);   /* LL3 */
144
0
  rfx_quantization_encode_block_sse2(buffer, 4096, 5);
145
0
}
146
147
static __inline void __attribute__((ATTRIBUTES))
148
rfx_dwt_2d_decode_block_horiz_sse2(INT16* l, INT16* h, INT16* dst, int subband_width)
149
0
{
150
0
  int y, n;
151
0
  INT16* l_ptr = l;
152
0
  INT16* h_ptr = h;
153
0
  INT16* dst_ptr = dst;
154
0
  int first;
155
0
  int last;
156
0
  __m128i l_n;
157
0
  __m128i h_n;
158
0
  __m128i h_n_m;
159
0
  __m128i tmp_n;
160
0
  __m128i dst_n;
161
0
  __m128i dst_n_p;
162
0
  __m128i dst1;
163
0
  __m128i dst2;
164
165
0
  for (y = 0; y < subband_width; y++)
166
0
  {
167
    /* Even coefficients */
168
0
    for (n = 0; n < subband_width; n += 8)
169
0
    {
170
      /* dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); */
171
0
      l_n = _mm_load_si128((__m128i*)l_ptr);
172
0
      h_n = _mm_load_si128((__m128i*)h_ptr);
173
0
      h_n_m = _mm_loadu_si128((__m128i*)(h_ptr - 1));
174
175
0
      if (n == 0)
176
0
      {
177
0
        first = _mm_extract_epi16(h_n_m, 1);
178
0
        h_n_m = _mm_insert_epi16(h_n_m, first, 0);
179
0
      }
180
181
0
      tmp_n = _mm_add_epi16(h_n, h_n_m);
182
0
      tmp_n = _mm_add_epi16(tmp_n, _mm_set1_epi16(1));
183
0
      tmp_n = _mm_srai_epi16(tmp_n, 1);
184
0
      dst_n = _mm_sub_epi16(l_n, tmp_n);
185
0
      _mm_store_si128((__m128i*)l_ptr, dst_n);
186
0
      l_ptr += 8;
187
0
      h_ptr += 8;
188
0
    }
189
190
0
    l_ptr -= subband_width;
191
0
    h_ptr -= subband_width;
192
193
    /* Odd coefficients */
194
0
    for (n = 0; n < subband_width; n += 8)
195
0
    {
196
      /* dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); */
197
0
      h_n = _mm_load_si128((__m128i*)h_ptr);
198
0
      h_n = _mm_slli_epi16(h_n, 1);
199
0
      dst_n = _mm_load_si128((__m128i*)(l_ptr));
200
0
      dst_n_p = _mm_loadu_si128((__m128i*)(l_ptr + 1));
201
202
0
      if (n == subband_width - 8)
203
0
      {
204
0
        last = _mm_extract_epi16(dst_n_p, 6);
205
0
        dst_n_p = _mm_insert_epi16(dst_n_p, last, 7);
206
0
      }
207
208
0
      tmp_n = _mm_add_epi16(dst_n_p, dst_n);
209
0
      tmp_n = _mm_srai_epi16(tmp_n, 1);
210
0
      tmp_n = _mm_add_epi16(tmp_n, h_n);
211
0
      dst1 = _mm_unpacklo_epi16(dst_n, tmp_n);
212
0
      dst2 = _mm_unpackhi_epi16(dst_n, tmp_n);
213
0
      _mm_store_si128((__m128i*)dst_ptr, dst1);
214
0
      _mm_store_si128((__m128i*)(dst_ptr + 8), dst2);
215
0
      l_ptr += 8;
216
0
      h_ptr += 8;
217
0
      dst_ptr += 16;
218
0
    }
219
0
  }
220
0
}
221
222
static __inline void __attribute__((ATTRIBUTES))
223
rfx_dwt_2d_decode_block_vert_sse2(INT16* l, INT16* h, INT16* dst, int subband_width)
224
0
{
225
0
  int x, n;
226
0
  INT16* l_ptr = l;
227
0
  INT16* h_ptr = h;
228
0
  INT16* dst_ptr = dst;
229
0
  __m128i l_n;
230
0
  __m128i h_n;
231
0
  __m128i tmp_n;
232
0
  __m128i h_n_m;
233
0
  __m128i dst_n;
234
0
  __m128i dst_n_m;
235
0
  __m128i dst_n_p;
236
0
  int total_width = subband_width + subband_width;
237
238
  /* Even coefficients */
239
0
  for (n = 0; n < subband_width; n++)
240
0
  {
241
0
    for (x = 0; x < total_width; x += 8)
242
0
    {
243
      /* dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); */
244
0
      l_n = _mm_load_si128((__m128i*)l_ptr);
245
0
      h_n = _mm_load_si128((__m128i*)h_ptr);
246
0
      tmp_n = _mm_add_epi16(h_n, _mm_set1_epi16(1));
247
248
0
      if (n == 0)
249
0
        tmp_n = _mm_add_epi16(tmp_n, h_n);
250
0
      else
251
0
      {
252
0
        h_n_m = _mm_loadu_si128((__m128i*)(h_ptr - total_width));
253
0
        tmp_n = _mm_add_epi16(tmp_n, h_n_m);
254
0
      }
255
256
0
      tmp_n = _mm_srai_epi16(tmp_n, 1);
257
0
      dst_n = _mm_sub_epi16(l_n, tmp_n);
258
0
      _mm_store_si128((__m128i*)dst_ptr, dst_n);
259
0
      l_ptr += 8;
260
0
      h_ptr += 8;
261
0
      dst_ptr += 8;
262
0
    }
263
264
0
    dst_ptr += total_width;
265
0
  }
266
267
0
  h_ptr = h;
268
0
  dst_ptr = dst + total_width;
269
270
  /* Odd coefficients */
271
0
  for (n = 0; n < subband_width; n++)
272
0
  {
273
0
    for (x = 0; x < total_width; x += 8)
274
0
    {
275
      /* dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); */
276
0
      h_n = _mm_load_si128((__m128i*)h_ptr);
277
0
      dst_n_m = _mm_load_si128((__m128i*)(dst_ptr - total_width));
278
0
      h_n = _mm_slli_epi16(h_n, 1);
279
0
      tmp_n = dst_n_m;
280
281
0
      if (n == subband_width - 1)
282
0
        tmp_n = _mm_add_epi16(tmp_n, dst_n_m);
283
0
      else
284
0
      {
285
0
        dst_n_p = _mm_loadu_si128((__m128i*)(dst_ptr + total_width));
286
0
        tmp_n = _mm_add_epi16(tmp_n, dst_n_p);
287
0
      }
288
289
0
      tmp_n = _mm_srai_epi16(tmp_n, 1);
290
0
      dst_n = _mm_add_epi16(tmp_n, h_n);
291
0
      _mm_store_si128((__m128i*)dst_ptr, dst_n);
292
0
      h_ptr += 8;
293
0
      dst_ptr += 8;
294
0
    }
295
296
0
    dst_ptr += total_width;
297
0
  }
298
0
}
299
300
static __inline void __attribute__((ATTRIBUTES))
301
rfx_dwt_2d_decode_block_sse2(INT16* buffer, INT16* idwt, int subband_width)
302
0
{
303
0
  INT16 *hl, *lh, *hh, *ll;
304
0
  INT16 *l_dst, *h_dst;
305
0
  _mm_prefetch_buffer((char*)idwt, subband_width * 4 * sizeof(INT16));
306
  /* Inverse DWT in horizontal direction, results in 2 sub-bands in L, H order in tmp buffer idwt.
307
   */
308
  /* The 4 sub-bands are stored in HL(0), LH(1), HH(2), LL(3) order. */
309
  /* The lower part L uses LL(3) and HL(0). */
310
  /* The higher part H uses LH(1) and HH(2). */
311
0
  ll = buffer + subband_width * subband_width * 3;
312
0
  hl = buffer;
313
0
  l_dst = idwt;
314
0
  rfx_dwt_2d_decode_block_horiz_sse2(ll, hl, l_dst, subband_width);
315
0
  lh = buffer + subband_width * subband_width;
316
0
  hh = buffer + subband_width * subband_width * 2;
317
0
  h_dst = idwt + subband_width * subband_width * 2;
318
0
  rfx_dwt_2d_decode_block_horiz_sse2(lh, hh, h_dst, subband_width);
319
  /* Inverse DWT in vertical direction, results are stored in original buffer. */
320
0
  rfx_dwt_2d_decode_block_vert_sse2(l_dst, h_dst, buffer, subband_width);
321
0
}
322
323
static void rfx_dwt_2d_decode_sse2(INT16* WINPR_RESTRICT buffer, INT16* WINPR_RESTRICT dwt_buffer)
324
0
{
325
0
  WINPR_ASSERT(buffer);
326
0
  WINPR_ASSERT(dwt_buffer);
327
328
0
  _mm_prefetch_buffer((char*)buffer, 4096 * sizeof(INT16));
329
0
  rfx_dwt_2d_decode_block_sse2(&buffer[3840], dwt_buffer, 8);
330
0
  rfx_dwt_2d_decode_block_sse2(&buffer[3072], dwt_buffer, 16);
331
0
  rfx_dwt_2d_decode_block_sse2(&buffer[0], dwt_buffer, 32);
332
0
}
333
334
static __inline void __attribute__((ATTRIBUTES))
335
rfx_dwt_2d_encode_block_vert_sse2(INT16* src, INT16* l, INT16* h, int subband_width)
336
0
{
337
0
  int total_width;
338
0
  int x;
339
0
  int n;
340
0
  __m128i src_2n;
341
0
  __m128i src_2n_1;
342
0
  __m128i src_2n_2;
343
0
  __m128i h_n;
344
0
  __m128i h_n_m;
345
0
  __m128i l_n;
346
0
  total_width = subband_width << 1;
347
348
0
  for (n = 0; n < subband_width; n++)
349
0
  {
350
0
    for (x = 0; x < total_width; x += 8)
351
0
    {
352
0
      src_2n = _mm_load_si128((__m128i*)src);
353
0
      src_2n_1 = _mm_load_si128((__m128i*)(src + total_width));
354
355
0
      if (n < subband_width - 1)
356
0
        src_2n_2 = _mm_load_si128((__m128i*)(src + 2 * total_width));
357
0
      else
358
0
        src_2n_2 = src_2n;
359
360
      /* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */
361
0
      h_n = _mm_add_epi16(src_2n, src_2n_2);
362
0
      h_n = _mm_srai_epi16(h_n, 1);
363
0
      h_n = _mm_sub_epi16(src_2n_1, h_n);
364
0
      h_n = _mm_srai_epi16(h_n, 1);
365
0
      _mm_store_si128((__m128i*)h, h_n);
366
367
0
      if (n == 0)
368
0
        h_n_m = h_n;
369
0
      else
370
0
        h_n_m = _mm_load_si128((__m128i*)(h - total_width));
371
372
      /* l[n] = src[2n] + ((h[n - 1] + h[n]) >> 1) */
373
0
      l_n = _mm_add_epi16(h_n_m, h_n);
374
0
      l_n = _mm_srai_epi16(l_n, 1);
375
0
      l_n = _mm_add_epi16(l_n, src_2n);
376
0
      _mm_store_si128((__m128i*)l, l_n);
377
0
      src += 8;
378
0
      l += 8;
379
0
      h += 8;
380
0
    }
381
382
0
    src += total_width;
383
0
  }
384
0
}
385
386
static __inline void __attribute__((ATTRIBUTES))
387
rfx_dwt_2d_encode_block_horiz_sse2(INT16* src, INT16* l, INT16* h, int subband_width)
388
0
{
389
0
  int y;
390
0
  int n;
391
0
  int first;
392
0
  __m128i src_2n;
393
0
  __m128i src_2n_1;
394
0
  __m128i src_2n_2;
395
0
  __m128i h_n;
396
0
  __m128i h_n_m;
397
0
  __m128i l_n;
398
399
0
  for (y = 0; y < subband_width; y++)
400
0
  {
401
0
    for (n = 0; n < subband_width; n += 8)
402
0
    {
403
      /* The following 3 Set operations consumes more than half of the total DWT processing
404
       * time! */
405
0
      src_2n =
406
0
          _mm_set_epi16(src[14], src[12], src[10], src[8], src[6], src[4], src[2], src[0]);
407
0
      src_2n_1 =
408
0
          _mm_set_epi16(src[15], src[13], src[11], src[9], src[7], src[5], src[3], src[1]);
409
0
      src_2n_2 = _mm_set_epi16(n == subband_width - 8 ? src[14] : src[16], src[14], src[12],
410
0
                               src[10], src[8], src[6], src[4], src[2]);
411
      /* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */
412
0
      h_n = _mm_add_epi16(src_2n, src_2n_2);
413
0
      h_n = _mm_srai_epi16(h_n, 1);
414
0
      h_n = _mm_sub_epi16(src_2n_1, h_n);
415
0
      h_n = _mm_srai_epi16(h_n, 1);
416
0
      _mm_store_si128((__m128i*)h, h_n);
417
0
      h_n_m = _mm_loadu_si128((__m128i*)(h - 1));
418
419
0
      if (n == 0)
420
0
      {
421
0
        first = _mm_extract_epi16(h_n_m, 1);
422
0
        h_n_m = _mm_insert_epi16(h_n_m, first, 0);
423
0
      }
424
425
      /* l[n] = src[2n] + ((h[n - 1] + h[n]) >> 1) */
426
0
      l_n = _mm_add_epi16(h_n_m, h_n);
427
0
      l_n = _mm_srai_epi16(l_n, 1);
428
0
      l_n = _mm_add_epi16(l_n, src_2n);
429
0
      _mm_store_si128((__m128i*)l, l_n);
430
0
      src += 16;
431
0
      l += 8;
432
0
      h += 8;
433
0
    }
434
0
  }
435
0
}
436
437
static __inline void __attribute__((ATTRIBUTES))
438
rfx_dwt_2d_encode_block_sse2(INT16* buffer, INT16* dwt, int subband_width)
439
0
{
440
0
  INT16 *hl, *lh, *hh, *ll;
441
0
  INT16 *l_src, *h_src;
442
0
  _mm_prefetch_buffer((char*)dwt, subband_width * 4 * sizeof(INT16));
443
  /* DWT in vertical direction, results in 2 sub-bands in L, H order in tmp buffer dwt. */
444
0
  l_src = dwt;
445
0
  h_src = dwt + subband_width * subband_width * 2;
446
0
  rfx_dwt_2d_encode_block_vert_sse2(buffer, l_src, h_src, subband_width);
447
  /* DWT in horizontal direction, results in 4 sub-bands in HL(0), LH(1), HH(2), LL(3) order,
448
   * stored in original buffer. */
449
  /* The lower part L generates LL(3) and HL(0). */
450
  /* The higher part H generates LH(1) and HH(2). */
451
0
  ll = buffer + subband_width * subband_width * 3;
452
0
  hl = buffer;
453
0
  lh = buffer + subband_width * subband_width;
454
0
  hh = buffer + subband_width * subband_width * 2;
455
0
  rfx_dwt_2d_encode_block_horiz_sse2(l_src, ll, hl, subband_width);
456
0
  rfx_dwt_2d_encode_block_horiz_sse2(h_src, lh, hh, subband_width);
457
0
}
458
459
static void rfx_dwt_2d_encode_sse2(INT16* WINPR_RESTRICT buffer, INT16* WINPR_RESTRICT dwt_buffer)
460
0
{
461
0
  WINPR_ASSERT(buffer);
462
0
  WINPR_ASSERT(dwt_buffer);
463
464
0
  _mm_prefetch_buffer((char*)buffer, 4096 * sizeof(INT16));
465
0
  rfx_dwt_2d_encode_block_sse2(buffer, dwt_buffer, 32);
466
0
  rfx_dwt_2d_encode_block_sse2(buffer + 3072, dwt_buffer, 16);
467
0
  rfx_dwt_2d_encode_block_sse2(buffer + 3840, dwt_buffer, 8);
468
0
}
469
470
void rfx_init_sse2(RFX_CONTEXT* context)
471
0
{
472
0
  if (!IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE))
473
0
    return;
474
475
0
  PROFILER_RENAME(context->priv->prof_rfx_quantization_decode, "rfx_quantization_decode_sse2")
476
0
  PROFILER_RENAME(context->priv->prof_rfx_quantization_encode, "rfx_quantization_encode_sse2")
477
0
  PROFILER_RENAME(context->priv->prof_rfx_dwt_2d_decode, "rfx_dwt_2d_decode_sse2")
478
0
  PROFILER_RENAME(context->priv->prof_rfx_dwt_2d_encode, "rfx_dwt_2d_encode_sse2")
479
0
  context->quantization_decode = rfx_quantization_decode_sse2;
480
0
  context->quantization_encode = rfx_quantization_encode_sse2;
481
0
  context->dwt_2d_decode = rfx_dwt_2d_decode_sse2;
482
0
  context->dwt_2d_encode = rfx_dwt_2d_encode_sse2;
483
0
}