Coverage Report

Created: 2026-09-01 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/common/ihevc_itrans.c
Line
Count
Source
1
/******************************************************************************
2
*
3
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4
*
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at:
8
*
9
* http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
16
*
17
******************************************************************************/
18
/**
19
 *******************************************************************************
20
 * @file
21
 *  ihevc_itrans.c
22
 *
23
 * @brief
24
 *  Contains function definitions for single stage  inverse transform
25
 *
26
 * @author
27
 *  100470
28
 *
29
 * @par List of Functions:
30
 *  - ihevc_itrans_4x4_ttype1()
31
 *  - ihevc_itrans_4x4()
32
 *  - ihevc_itrans_8x8()
33
 *  - ihevc_itrans_16x16()
34
 *  - ihevc_itrans_32x32()
35
 *
36
 * @remarks
37
 *  None
38
 *
39
 *******************************************************************************
40
 */
41
#include <stdio.h>
42
#include <string.h>
43
#include "ihevc_typedefs.h"
44
#include "ihevc_macros.h"
45
#include "ihevc_platform_macros.h"
46
#include "ihevc_defs.h"
47
#include "ihevc_trans_tables.h"
48
#include "ihevc_trans_macros.h"
49
50
#define NON_OPTIMIZED 1
51
52
/**
53
 *******************************************************************************
54
 *
55
 * @brief
56
 *  This function performs Single stage  Inverse transform type 1 (DST) for
57
 * 4x4 input block
58
 *
59
 * @par Description:
60
 *  Performs single stage 4x4 inverse transform type 1  by utilizing the
61
 * symmetry of transformation matrix  and reducing number of multiplications
62
 * wherever  possible but keeping the number of operations
63
 * (addition,multiplication and shift)same
64
 *
65
 * @param[in] pi2_src
66
 *  Input 4x4 coefficients
67
 *
68
 * @param[out] pi2_dst
69
 *  Output 4x4 block
70
 *
71
 * @param[in] src_strd
72
 *  Input stride
73
 *
74
 * @param[in] dst_strd
75
 *  Output Stride
76
 *
77
 * @param[in] i4_shift
78
 *  Output shift
79
 *
80
 * @param[in] zero_cols
81
 *  Zero columns in pi2_src
82
 *
83
 * @returns  Void
84
 *
85
 * @remarks
86
 *  None
87
 *
88
 *******************************************************************************
89
 */
90
91
92
void ihevc_itrans_4x4_ttype1(WORD16 *pi2_src,
93
                             WORD16 *pi2_dst,
94
                             WORD32 src_strd,
95
                             WORD32 dst_strd,
96
                             WORD32 i4_shift,
97
                             WORD32 zero_cols)
98
0
{
99
0
    WORD32 i, c[4];
100
0
    WORD32 add;
101
102
0
    add = 1 << (i4_shift - 1);
103
104
0
    for(i = 0; i < TRANS_SIZE_4; i++)
105
0
    {
106
        /* Checking for Zero Cols */
107
0
        if((zero_cols & 1) == 1)
108
0
        {
109
0
            memset(pi2_dst, 0, TRANS_SIZE_4 * sizeof(WORD16));
110
0
        }
111
0
        else
112
0
        {
113
            // Intermediate Variables
114
0
            c[0] = pi2_src[0] + pi2_src[2 * src_strd];
115
0
            c[1] = pi2_src[2 * src_strd] + pi2_src[3 * src_strd];
116
0
            c[2] = pi2_src[0] - pi2_src[3 * src_strd];
117
0
            c[3] = 74 * pi2_src[src_strd];
118
119
0
            pi2_dst[0] =
120
0
                            CLIP_S16((29 * c[0] + 55 * c[1] + c[3] + add) >> i4_shift);
121
0
            pi2_dst[1] =
122
0
                            CLIP_S16((55 * c[2] - 29 * c[1] + c[3] + add) >> i4_shift);
123
0
            pi2_dst[2] =
124
0
                            CLIP_S16((74 * (pi2_src[0] - pi2_src[2 * src_strd] + pi2_src[3 * src_strd]) + add) >> i4_shift);
125
0
            pi2_dst[3] =
126
0
                            CLIP_S16((55 * c[0] + 29 * c[2] - c[3] + add) >> i4_shift);
127
0
        }
128
0
        pi2_src++;
129
0
        pi2_dst += dst_strd;
130
0
        zero_cols = zero_cols >> 1;
131
0
    }
132
0
}
133
134
135
/**
136
 *******************************************************************************
137
 *
138
 * @brief
139
 *  This function performs Single stage  Inverse transform for 4x4 input
140
 * block
141
 *
142
 * @par Description:
143
 *  Performs single stage 4x4 inverse transform by utilizing  the symmetry of
144
 * transformation matrix and reducing number  of multiplications wherever
145
 * possible but keeping the  number of operations(addition,multiplication and
146
 * shift)  same
147
 *
148
 * @param[in] pi2_src
149
 *  Input 4x4 coefficients
150
 *
151
 * @param[out] pi2_dst
152
 *  Output 4x4 block
153
 *
154
 * @param[in] src_strd
155
 *  Input stride
156
 *
157
 * @param[in] dst_strd
158
 *  Output Stride
159
 *
160
 * @param[in] i4_shift
161
 *  Output shift
162
 *
163
 * @param[in] zero_cols
164
 *  Zero columns in pi2_src
165
 *
166
 * @returns  Void
167
 *
168
 * @remarks
169
 *  None
170
 *
171
 *******************************************************************************
172
 */
173
174
#if NON_OPTIMIZED
175
void ihevc_itrans_4x4(WORD16 *pi2_src,
176
                      WORD16 *pi2_dst,
177
                      WORD32 src_strd,
178
                      WORD32 dst_strd,
179
                      WORD32 i4_shift,
180
                      WORD32 zero_cols)
181
0
{
182
0
    WORD32 j;
183
0
    WORD32 e[2], o[2];
184
0
    WORD32 add;
185
186
0
    add = 1 << (i4_shift - 1);
187
188
0
    for(j = 0; j < TRANS_SIZE_4; j++)
189
0
    {
190
        /* Checking for Zero Cols */
191
0
        if((zero_cols & 1) == 1)
192
0
        {
193
0
            memset(pi2_dst, 0, TRANS_SIZE_4 * sizeof(WORD16));
194
0
        }
195
0
        else
196
0
        {
197
198
            /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
199
0
            o[0] = g_ai2_ihevc_trans_4[1][0] * pi2_src[src_strd]
200
0
                            + g_ai2_ihevc_trans_4[3][0] * pi2_src[3 * src_strd];
201
0
            o[1] = g_ai2_ihevc_trans_4[1][1] * pi2_src[src_strd]
202
0
                            + g_ai2_ihevc_trans_4[3][1] * pi2_src[3 * src_strd];
203
0
            e[0] = g_ai2_ihevc_trans_4[0][0] * pi2_src[0]
204
0
                            + g_ai2_ihevc_trans_4[2][0] * pi2_src[2 * src_strd];
205
0
            e[1] = g_ai2_ihevc_trans_4[0][1] * pi2_src[0]
206
0
                            + g_ai2_ihevc_trans_4[2][1] * pi2_src[2 * src_strd];
207
208
0
            pi2_dst[0] =
209
0
                            CLIP_S16(((e[0] + o[0] + add) >> i4_shift));
210
0
            pi2_dst[1] =
211
0
                            CLIP_S16(((e[1] + o[1] + add) >> i4_shift));
212
0
            pi2_dst[2] =
213
0
                            CLIP_S16(((e[1] - o[1] + add) >> i4_shift));
214
0
            pi2_dst[3] =
215
0
                            CLIP_S16(((e[0] - o[0] + add) >> i4_shift));
216
217
0
        }
218
0
        pi2_src++;
219
0
        pi2_dst += dst_strd;
220
0
        zero_cols = zero_cols >> 1;
221
0
    }
222
0
}
223
#else
224
void ihevc_itrans_4x4(WORD16 *pi2_src,
225
                      WORD16 *pi2_dst,
226
                      WORD32 src_strd,
227
                      WORD32 dst_strd,
228
                      WORD32 i4_shift,
229
                      WORD32 zero_cols)
230
{
231
    WORD32 j;
232
    WORD32 e[2], o[2];
233
    WORD32 add;
234
235
    add = 1 << (i4_shift - 1);
236
237
    /***************************************************************************/
238
    /* Transform Matrix 4x4                                                    */
239
    /*      0   1   2   3                                                      */
240
    /* 0 { 64, 64, 64, 64},                                                    */
241
    /* 1 { 83, 36,-36,-83},                                                    */
242
    /* 2 { 64,-64,-64, 64},                                                    */
243
    /* 3 { 36,-83, 83,-36}                                                     */
244
    /***************************************************************************/
245
246
    for(j = 0; j < TRANS_SIZE_4; j++)
247
    {
248
        WORD32 temp;
249
250
        /* Checking for Zero Cols */
251
        if((zero_cols & 1) == 1)
252
        {
253
            memset(pi2_dst, 0, TRANS_SIZE_4 * sizeof(WORD16));
254
        }
255
        else
256
        {
257
            /* Common operation in o[0] and o[1] */
258
            temp = (pi2_src[src_strd] + pi2_src[3 * src_strd]) * 36;
259
260
            o[0] = temp + 47 * pi2_src[src_strd];
261
            o[1] = temp - 119 * pi2_src[3 * src_strd];
262
            e[0] = (pi2_src[0] + pi2_src[2 * src_strd]) << 6;
263
            e[1] = (pi2_src[0] - pi2_src[2 * src_strd]) << 6;
264
265
            pi2_dst[0] =
266
                            CLIP_S16(((e[0] + o[0] + add) >> i4_shift));
267
            pi2_dst[1] =
268
                            CLIP_S16(((e[1] + o[1] + add) >> i4_shift));
269
            pi2_dst[2] =
270
                            CLIP_S16(((e[1] - o[1] + add) >> i4_shift));
271
            pi2_dst[3] =
272
                            CLIP_S16(((e[0] - o[0] + add) >> i4_shift));
273
        }
274
        pi2_src++;
275
        pi2_dst += dst_strd;
276
        zero_cols = zero_cols >> 1;
277
    }
278
}
279
#endif
280
281
/**
282
 *******************************************************************************
283
 *
284
 * @brief
285
 *  This function performs Single stage  Inverse transform for 8x8 input
286
 * block
287
 *
288
 * @par Description:
289
 *  Performs single stage 8x8 inverse transform by utilizing  the symmetry of
290
 * transformation matrix and reducing number  of multiplications wherever
291
 * possible but keeping the  number of operations(addition,multiplication and
292
 * shift)  same
293
 *
294
 * @param[in] pi2_src
295
 *  Input 8x8 coefficients
296
 *
297
 * @param[out] pi2_dst
298
 *  Output 8x8 block
299
 *
300
 * @param[in] src_strd
301
 *  Input stride
302
 *
303
 * @param[in] dst_strd
304
 *  Output Stride
305
 *
306
 * @param[in] i4_shift
307
 *  Output shift
308
 *
309
 * @param[in] zero_cols
310
 *  Zero columns in pi2_src
311
 *
312
 * @returns  Void
313
 *
314
 * @remarks
315
 *  None
316
 *
317
 *******************************************************************************
318
 */
319
320
#if NON_OPTIMIZED
321
void ihevc_itrans_8x8(WORD16 *pi2_src,
322
                      WORD16 *pi2_dst,
323
                      WORD32 src_strd,
324
                      WORD32 dst_strd,
325
                      WORD32 i4_shift,
326
                      WORD32 zero_cols)
327
0
{
328
0
    WORD32 j, k;
329
0
    WORD32 e[4], o[4];
330
0
    WORD32 ee[2], eo[2];
331
0
    WORD32 add;
332
333
0
    add = 1 << (i4_shift - 1);
334
335
0
    for(j = 0; j < TRANS_SIZE_8; j++)
336
0
    {
337
        /* Checking for Zero Cols */
338
0
        if((zero_cols & 1) == 1)
339
0
        {
340
0
            memset(pi2_dst, 0, TRANS_SIZE_8 * sizeof(WORD16));
341
0
        }
342
0
        else
343
0
        {
344
            /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
345
0
            for(k = 0; k < 4; k++)
346
0
            {
347
0
                o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_src[src_strd]
348
0
                                + g_ai2_ihevc_trans_8[3][k]
349
0
                                                * pi2_src[3 * src_strd]
350
0
                                + g_ai2_ihevc_trans_8[5][k]
351
0
                                                * pi2_src[5 * src_strd]
352
0
                                + g_ai2_ihevc_trans_8[7][k]
353
0
                                                * pi2_src[7 * src_strd];
354
0
            }
355
356
0
            eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_src[2 * src_strd]
357
0
                            + g_ai2_ihevc_trans_8[6][0] * pi2_src[6 * src_strd];
358
0
            eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_src[2 * src_strd]
359
0
                            + g_ai2_ihevc_trans_8[6][1] * pi2_src[6 * src_strd];
360
0
            ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_src[0]
361
0
                            + g_ai2_ihevc_trans_8[4][0] * pi2_src[4 * src_strd];
362
0
            ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_src[0]
363
0
                            + g_ai2_ihevc_trans_8[4][1] * pi2_src[4 * src_strd];
364
365
            /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
366
0
            e[0] = ee[0] + eo[0];
367
0
            e[3] = ee[0] - eo[0];
368
0
            e[1] = ee[1] + eo[1];
369
0
            e[2] = ee[1] - eo[1];
370
0
            for(k = 0; k < 4; k++)
371
0
            {
372
0
                pi2_dst[k] =
373
0
                                CLIP_S16(((e[k] + o[k] + add) >> i4_shift));
374
0
                pi2_dst[k + 4] =
375
0
                                CLIP_S16(((e[3 - k] - o[3 - k] + add) >> i4_shift));
376
0
            }
377
0
        }
378
0
        pi2_src++;
379
0
        pi2_dst += dst_strd;
380
0
        zero_cols = zero_cols >> 1;
381
0
    }
382
0
}
383
384
#else
385
void ihevc_itrans_8x8(WORD16 *pi2_src,
386
                      WORD16 *pi2_dst,
387
                      WORD32 src_strd,
388
                      WORD32 dst_strd,
389
                      WORD32 i4_shift,
390
                      WORD32 zero_cols)
391
{
392
    /* Transform Matrix 8x8                          */
393
    /*              0    1    2   3   4   5   6   7  */
394
    /*     0 -      64   64   64  64  64  64  64  64 */
395
    /*     1 -      89   75   50  18 -18 -50 -75 -89 */
396
    /*     2 -      83   36  -36 -83 -83 -36  36  83 */
397
    /*     3 -      75  -18  -89 -50  50  89  18 -75 */
398
    /*     4 -      64  -64  -64  64  64 -64 -64  64 */
399
    /*     5 -      50  -89   18  75 -75 -18  89 -50 */
400
    /*     6 -      36  -83   83 -36 -36  83 -83  36 */
401
    /*     7 -      18  -50   75 -89  89 -75  50 -18 */
402
403
    /* 0th and 4th row will have no multiplications */
404
    /* 2nd and 6th row has only two coefff multiplies */
405
    /* 1st, 3rd, 5th and 7th rows have o mirror symmetry */
406
    WORD32 j, k;
407
    WORD32 temp1, temp2;
408
    WORD32 e[4], o[4];
409
    WORD32 ee[2], eo[2];
410
    WORD32 add;
411
412
    add = 1 << (i4_shift - 1);
413
414
    for(j = 0; j < TRANS_SIZE_8; j++)
415
    {
416
        /* Checking for Zero Cols */
417
        if((zero_cols & 1) == 1)
418
        {
419
            memset(pi2_dst, 0, TRANS_SIZE_8 * sizeof(WORD16));
420
        }
421
        else
422
        {
423
424
            /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
425
            /*
426
             o[0] = 89 *pi2_src[8] +  75 *pi2_src[3*8] +  50 *pi2_src[5*8] +  18 *pi2_src[7*8];
427
             o[1] = 75 *pi2_src[8] + -18 *pi2_src[3*8] + -89 *pi2_src[5*8] + -50 *pi2_src[7*8];
428
             o[2] = 50 *pi2_src[8] + -89 *pi2_src[3*8] +  18 *pi2_src[5*8] +  75 *pi2_src[7*8];
429
             o[3] = 18 *pi2_src[8] + -50 *pi2_src[3*8] +  75 *pi2_src[5*8] + -89 *pi2_src[7*8];
430
             */
431
432
            /* Optimization: 4 mul + 2 add  ---> 3 mul + 3 add */
433
            /*
434
             temp1 = (pi2_src[8  ] + pi2_src[3*8]) * 75;
435
             temp2 = (pi2_src[5*8] + pi2_src[7*8]) * 50;
436
437
             o[0] = temp1 + 14 * pi2_src[8  ] + temp2 - 32 * pi2_src[7*8];
438
             o[1] = temp1 - 93 * pi2_src[3*8] - temp2 - 39 * pi2_src[5*8];
439
             */
440
441
            temp1 = (pi2_src[src_strd] + pi2_src[3 * src_strd]) * 75;
442
            temp2 = (pi2_src[5 * src_strd] + pi2_src[7 * src_strd]) * 50;
443
444
            o[0] = temp1 + 14 * pi2_src[src_strd] + temp2
445
                            - (pi2_src[7 * src_strd] << 5);
446
            o[1] = temp1 - 93 * pi2_src[3 * src_strd] - temp2
447
                            - 39 * pi2_src[5 * src_strd];
448
449
            /* Optimization: 4 mul + 2 add  ---> 3 mul + 3 add */
450
            /*
451
             temp1 = (pi2_src[8  ] - pi2_src[3*8]) * 50;
452
             temp2 = (pi2_src[5*8] + pi2_src[7*8]) * 75;
453
454
             o[2] = temp1 - 39 * pi2_src[3*8] + temp2 -  57 * pi2_src[5*8];
455
             o[3] = temp1 - 32 * pi2_src[8  ] + temp2 - 164 * pi2_src[7*8];
456
             */
457
458
            temp1 = (pi2_src[src_strd] - pi2_src[3 * src_strd]) * 50;
459
            temp2 = (pi2_src[5 * src_strd] + pi2_src[7 * src_strd]) * 75;
460
461
            o[2] = temp1 - 39 * pi2_src[3 * src_strd] + temp2
462
                            - 57 * pi2_src[5 * src_strd];
463
            o[3] = temp1 - (pi2_src[src_strd] << 5) + temp2
464
                            - 164 * pi2_src[7 * src_strd];
465
466
            /*
467
             eo[0] = 83 *pi2_src[ 2*8 ] +  36 *pi2_src[ 6*8 ];
468
             eo[1] = 36 *pi2_src[ 2*8 ] + -83 *pi2_src[ 6*8 ];
469
             ee[0] = 64 *pi2_src[ 0   ] +  64 *pi2_src[ 4*8 ];
470
             ee[1] = 64 *pi2_src[ 0   ] + -64 *pi2_src[ 4*8 ];
471
             */
472
473
            /* Optimization: 4 mul + 2 add  ---> 3 mul + 3 add */
474
            temp1 = (pi2_src[2 * src_strd] + pi2_src[6 * src_strd]) * 36;
475
            eo[0] = temp1 + 47 * pi2_src[2 * src_strd];
476
            eo[1] = temp1 - 119 * pi2_src[6 * src_strd];
477
478
            /* Optimization: 4 mul + 2 add  ---> 2 i4_shift + 2 add */
479
            ee[0] = (pi2_src[0] + pi2_src[4 * src_strd]) << 6;
480
            ee[1] = (pi2_src[0] - pi2_src[4 * src_strd]) << 6;
481
482
            e[0] = ee[0] + eo[0];
483
            e[3] = ee[0] - eo[0];
484
            e[1] = ee[1] + eo[1];
485
            e[2] = ee[1] - eo[1];
486
487
            for(k = 0; k < 4; k++)
488
            {
489
                pi2_dst[k] =
490
                                CLIP_S16(((e[k] + o[k] + add) >> i4_shift));
491
                pi2_dst[k + 4] =
492
                                CLIP_S16(((e[3 - k] - o[3 - k] + add) >> i4_shift));
493
            }
494
        }
495
        pi2_src++;
496
        pi2_dst += dst_strd;
497
        zero_cols = zero_cols >> 1;
498
    }
499
500
}
501
#endif
502
503
504
/**
505
 *******************************************************************************
506
 *
507
 * @brief
508
 *  This function performs Single stage  Inverse transform for 16x16 input
509
 * block
510
 *
511
 * @par Description:
512
 *  Performs single stage 16x16 inverse transform by  utilizing the symmetry
513
 * of transformation matrix  and reducing number of multiplications wherever
514
 * possible  but keeping the number of operations  (addition,multiplication
515
 * and shift) same
516
 *
517
 * @param[in] pi2_src
518
 *  Input 16x16 coefficients
519
 *
520
 * @param[out] pi2_dst
521
 *  Output 16x16 block
522
 *
523
 * @param[in] src_strd
524
 *  Input stride
525
 *
526
 * @param[in] dst_strd
527
 *  Output Stride
528
 *
529
 * @param[in] i4_shift
530
 *  Output shift
531
 *
532
 * @param[in] zero_cols
533
 *  Zero columns in pi2_src
534
 *
535
 * @returns  Void
536
 *
537
 * @remarks
538
 *  None
539
 *
540
 *******************************************************************************
541
 */
542
543
#if NON_OPTIMIZED
544
void ihevc_itrans_16x16(WORD16 *pi2_src,
545
                        WORD16 *pi2_dst,
546
                        WORD32 src_strd,
547
                        WORD32 dst_strd,
548
                        WORD32 i4_shift,
549
                        WORD32 zero_cols)
550
0
{
551
0
    WORD32 j, k;
552
0
    WORD32 e[8], o[8];
553
0
    WORD32 ee[4], eo[4];
554
0
    WORD32 eee[2], eeo[2];
555
0
    WORD32 add;
556
557
0
    add = 1 << (i4_shift - 1);
558
559
0
    for(j = 0; j < TRANS_SIZE_16; j++)
560
0
    {
561
        /* Checking for Zero Cols */
562
0
        if((zero_cols & 1) == 1)
563
0
        {
564
0
            memset(pi2_dst, 0, TRANS_SIZE_16 * sizeof(WORD16));
565
0
        }
566
0
        else
567
0
        {
568
            /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
569
0
            for(k = 0; k < 8; k++)
570
0
            {
571
0
                o[k] = g_ai2_ihevc_trans_16[1][k] * pi2_src[src_strd]
572
0
                                + g_ai2_ihevc_trans_16[3][k]
573
0
                                                * pi2_src[3 * src_strd]
574
0
                                + g_ai2_ihevc_trans_16[5][k]
575
0
                                                * pi2_src[5 * src_strd]
576
0
                                + g_ai2_ihevc_trans_16[7][k]
577
0
                                                * pi2_src[7 * src_strd]
578
0
                                + g_ai2_ihevc_trans_16[9][k]
579
0
                                                * pi2_src[9 * src_strd]
580
0
                                + g_ai2_ihevc_trans_16[11][k]
581
0
                                                * pi2_src[11 * src_strd]
582
0
                                + g_ai2_ihevc_trans_16[13][k]
583
0
                                                * pi2_src[13 * src_strd]
584
0
                                + g_ai2_ihevc_trans_16[15][k]
585
0
                                                * pi2_src[15 * src_strd];
586
0
            }
587
0
            for(k = 0; k < 4; k++)
588
0
            {
589
0
                eo[k] = g_ai2_ihevc_trans_16[2][k] * pi2_src[2 * src_strd]
590
0
                                + g_ai2_ihevc_trans_16[6][k]
591
0
                                                * pi2_src[6 * src_strd]
592
0
                                + g_ai2_ihevc_trans_16[10][k]
593
0
                                                * pi2_src[10 * src_strd]
594
0
                                + g_ai2_ihevc_trans_16[14][k]
595
0
                                                * pi2_src[14 * src_strd];
596
0
            }
597
0
            eeo[0] = g_ai2_ihevc_trans_16[4][0] * pi2_src[4 * src_strd]
598
0
                            + g_ai2_ihevc_trans_16[12][0]
599
0
                                            * pi2_src[12 * src_strd];
600
0
            eee[0] =
601
0
                            g_ai2_ihevc_trans_16[0][0] * pi2_src[0]
602
0
                                            + g_ai2_ihevc_trans_16[8][0]
603
0
                                                            * pi2_src[8
604
0
                                                                            * src_strd];
605
0
            eeo[1] = g_ai2_ihevc_trans_16[4][1] * pi2_src[4 * src_strd]
606
0
                            + g_ai2_ihevc_trans_16[12][1]
607
0
                                            * pi2_src[12 * src_strd];
608
0
            eee[1] =
609
0
                            g_ai2_ihevc_trans_16[0][1] * pi2_src[0]
610
0
                                            + g_ai2_ihevc_trans_16[8][1]
611
0
                                                            * pi2_src[8
612
0
                                                                            * src_strd];
613
614
            /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
615
0
            for(k = 0; k < 2; k++)
616
0
            {
617
0
                ee[k] = eee[k] + eeo[k];
618
0
                ee[k + 2] = eee[1 - k] - eeo[1 - k];
619
0
            }
620
0
            for(k = 0; k < 4; k++)
621
0
            {
622
0
                e[k] = ee[k] + eo[k];
623
0
                e[k + 4] = ee[3 - k] - eo[3 - k];
624
0
            }
625
0
            for(k = 0; k < 8; k++)
626
0
            {
627
0
                pi2_dst[k] =
628
0
                                CLIP_S16(((e[k] + o[k] + add) >> i4_shift));
629
0
                pi2_dst[k + 8] =
630
0
                                CLIP_S16(((e[7 - k] - o[7 - k] + add) >> i4_shift));
631
0
            }
632
0
        }
633
0
        pi2_src++;
634
0
        pi2_dst += dst_strd;
635
0
        zero_cols = zero_cols >> 1;
636
0
    }
637
0
}
638
#else
639
void ihevc_itrans_16x16(WORD16 *pi2_src,
640
                        WORD16 *pi2_dst,
641
                        WORD32 src_strd,
642
                        WORD32 dst_strd,
643
                        WORD32 i4_shift,
644
                        WORD32 zero_cols)
645
{
646
    WORD32 j, k;
647
    WORD32 e[8], o[8];
648
    WORD32 ee[4], eo[4];
649
    WORD32 eee[2], eeo[2];
650
    WORD32 add;
651
    WORD32 temp1, temp2;
652
653
    add = 1 << (i4_shift - 1);
654
    /***************************************************************************/
655
    /* Transform Matrix 16x16                                                  */
656
    /*       0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15     */
657
    /* 0  { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},   */
658
    /* 1  { 90, 87, 80, 70, 57, 43, 25,  9, -9,-25,-43,-57,-70,-80,-87,-90},   */
659
    /* 2  { 89, 75, 50, 18,-18,-50,-75,-89,-89,-75,-50,-18, 18, 50, 75, 89},   */
660
    /* 3  { 87, 57,  9,-43,-80,-90,-70,-25, 25, 70, 90, 80, 43, -9,-57,-87},   */
661
    /* 4  { 83, 36,-36,-83,-83,-36, 36, 83, 83, 36,-36,-83,-83,-36, 36, 83},   */
662
    /* 5  { 80,  9,-70,-87,-25, 57, 90, 43,-43,-90,-57, 25, 87, 70, -9,-80},   */
663
    /* 6  { 75,-18,-89,-50, 50, 89, 18,-75,-75, 18, 89, 50,-50,-89,-18, 75},   */
664
    /* 7  { 70,-43,-87,  9, 90, 25,-80,-57, 57, 80,-25,-90, -9, 87, 43,-70},   */
665
    /* 8  { 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64, 64,-64,-64, 64},   */
666
    /* 9  { 57,-80,-25, 90, -9,-87, 43, 70,-70,-43, 87,  9,-90, 25, 80,-57},   */
667
    /* 10 { 50,-89, 18, 75,-75,-18, 89,-50,-50, 89,-18,-75, 75, 18,-89, 50},   */
668
    /* 11 { 43,-90, 57, 25,-87, 70,  9,-80, 80, -9,-70, 87,-25,-57, 90,-43},   */
669
    /* 12 { 36,-83, 83,-36,-36, 83,-83, 36, 36,-83, 83,-36,-36, 83,-83, 36},   */
670
    /* 13 { 25,-70, 90,-80, 43,  9,-57, 87,-87, 57, -9,-43, 80,-90, 70,-25},   */
671
    /* 14 { 18,-50, 75,-89, 89,-75, 50,-18,-18, 50,-75, 89,-89, 75,-50, 18},   */
672
    /* 15 {  9,-25, 43,-57, 70,-80, 87,-90, 90,-87, 80,-70, 57,-43, 25, -9}    */
673
    /***************************************************************************/
674
675
    for(j = 0; j < TRANS_SIZE_16; j++)
676
    {
677
        /* Checking for Zero Cols */
678
        if((zero_cols & 1) == 1)
679
        {
680
            memset(pi2_dst, 0, TRANS_SIZE_16 * sizeof(WORD16));
681
        }
682
        else
683
        {
684
            /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
685
            {
686
                /*
687
                 o[k] = g_ai2_ihevc_trans_16[ 1][k]*pi2_src[ src_strd   ] + g_ai2_ihevc_trans_16[ 3][k]*pi2_src[ 3*src_strd   ] + g_ai2_ihevc_trans_16[ 5][k]*pi2_src[ 5*src_strd   ] + g_ai2_ihevc_trans_16[ 7][k]*pi2_src[ 7*src_strd   ] +
688
                 g_ai2_ihevc_trans_16[ 9][k]*pi2_src[ 9*src_strd   ] + g_ai2_ihevc_trans_16[11][k]*pi2_src[11*src_strd   ] + g_ai2_ihevc_trans_16[13][k]*pi2_src[13*src_strd   ] + g_ai2_ihevc_trans_16[15][k]*pi2_src[15*src_strd   ];
689
                 */
690
691
                o[0] = 90 * pi2_src[src_strd] + 87 * pi2_src[3 * src_strd]
692
                                + 80 * pi2_src[5 * src_strd]
693
                                + 70 * pi2_src[7 * src_strd]
694
                                + 57 * pi2_src[9 * src_strd]
695
                                + 43 * pi2_src[11 * src_strd]
696
                                + 25 * pi2_src[13 * src_strd]
697
                                + 9 * pi2_src[15 * src_strd];
698
699
                o[1] = 87 * pi2_src[src_strd] + 57 * pi2_src[3 * src_strd]
700
                                + 9 * pi2_src[5 * src_strd]
701
                                + -43 * pi2_src[7 * src_strd]
702
                                + -80 * pi2_src[9 * src_strd]
703
                                + -90 * pi2_src[11 * src_strd]
704
                                + -70 * pi2_src[13 * src_strd]
705
                                + -25 * pi2_src[15 * src_strd];
706
707
                o[2] = 80 * pi2_src[src_strd] + 9 * pi2_src[3 * src_strd]
708
                                + -70 * pi2_src[5 * src_strd]
709
                                + -87 * pi2_src[7 * src_strd]
710
                                + -25 * pi2_src[9 * src_strd]
711
                                + 57 * pi2_src[11 * src_strd]
712
                                + 90 * pi2_src[13 * src_strd]
713
                                + 43 * pi2_src[15 * src_strd];
714
715
                o[3] = 70 * pi2_src[src_strd] + -43 * pi2_src[3 * src_strd]
716
                                + -87 * pi2_src[5 * src_strd]
717
                                + 9 * pi2_src[7 * src_strd]
718
                                + 90 * pi2_src[9 * src_strd]
719
                                + 25 * pi2_src[11 * src_strd]
720
                                + -80 * pi2_src[13 * src_strd]
721
                                + -57 * pi2_src[15 * src_strd];
722
723
                o[4] = 57 * pi2_src[src_strd] + -80 * pi2_src[3 * src_strd]
724
                                + -25 * pi2_src[5 * src_strd]
725
                                + 90 * pi2_src[7 * src_strd]
726
                                + -9 * pi2_src[9 * src_strd]
727
                                + -87 * pi2_src[11 * src_strd]
728
                                + 43 * pi2_src[13 * src_strd]
729
                                + 70 * pi2_src[15 * src_strd];
730
731
                o[5] = 43 * pi2_src[src_strd] + -90 * pi2_src[3 * src_strd]
732
                                + 57 * pi2_src[5 * src_strd]
733
                                + 25 * pi2_src[7 * src_strd]
734
                                + -87 * pi2_src[9 * src_strd]
735
                                + 70 * pi2_src[11 * src_strd]
736
                                + 9 * pi2_src[13 * src_strd]
737
                                + -80 * pi2_src[15 * src_strd];
738
739
                o[6] = 25 * pi2_src[src_strd] + -70 * pi2_src[3 * src_strd]
740
                                + 90 * pi2_src[5 * src_strd]
741
                                + -80 * pi2_src[7 * src_strd]
742
                                + 43 * pi2_src[9 * src_strd]
743
                                + 9 * pi2_src[11 * src_strd]
744
                                + -57 * pi2_src[13 * src_strd]
745
                                + 87 * pi2_src[15 * src_strd];
746
747
                o[7] = 9 * pi2_src[src_strd] + -25 * pi2_src[3 * src_strd]
748
                                + 43 * pi2_src[5 * src_strd]
749
                                + -57 * pi2_src[7 * src_strd]
750
                                + 70 * pi2_src[9 * src_strd]
751
                                + -80 * pi2_src[11 * src_strd]
752
                                + 87 * pi2_src[13 * src_strd]
753
                                + -90 * pi2_src[15 * src_strd];
754
            }
755
            {
756
                temp1 = (pi2_src[2 * src_strd] + pi2_src[6 * src_strd]) * 75;
757
                temp2 = (pi2_src[10 * src_strd] + pi2_src[14 * src_strd]) * 50;
758
                eo[0] = temp1 + 14 * pi2_src[2 * src_strd] + temp2
759
                                - (pi2_src[14 * src_strd] << 5);
760
                eo[1] = temp1 - 93 * pi2_src[6 * src_strd] - temp2
761
                                - 39 * pi2_src[10 * src_strd];
762
763
                temp1 = (pi2_src[2 * src_strd] - pi2_src[6 * src_strd]) * 50;
764
                temp2 = (pi2_src[10 * src_strd] + pi2_src[14 * src_strd]) * 75;
765
                eo[2] = temp1 - 39 * pi2_src[6 * src_strd] + temp2
766
                                - 57 * pi2_src[10 * src_strd];
767
                eo[3] = temp1 - (pi2_src[2 * src_strd] << 5) + temp2
768
                                - 164 * pi2_src[14 * src_strd];
769
            }
770
771
            temp1 = (pi2_src[4 * src_strd] + pi2_src[12 * src_strd]) * 36;
772
            eeo[0] = temp1 + 47 * pi2_src[4 * src_strd];
773
            eeo[1] = temp1 - 119 * pi2_src[12 * src_strd];
774
775
            eee[0] = (pi2_src[0] + pi2_src[8 * src_strd]) << 6;
776
            eee[1] = (pi2_src[0] - pi2_src[8 * src_strd]) << 6;
777
778
            /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
779
            for(k = 0; k < 2; k++)
780
            {
781
                ee[k] = eee[k] + eeo[k];
782
                ee[k + 2] = eee[1 - k] - eeo[1 - k];
783
            }
784
            for(k = 0; k < 4; k++)
785
            {
786
                e[k] = ee[k] + eo[k];
787
                e[k + 4] = ee[3 - k] - eo[3 - k];
788
            }
789
            for(k = 0; k < 8; k++)
790
            {
791
                pi2_dst[k] =
792
                                CLIP_S16(((e[k] + o[k] + add) >> i4_shift));
793
                pi2_dst[k + 8] =
794
                                CLIP_S16(((e[7 - k] - o[7 - k] + add) >> i4_shift));
795
            }
796
        }
797
        pi2_src++;
798
        pi2_dst += dst_strd;
799
        zero_cols = zero_cols >> 1;
800
    }
801
}
802
#endif
803
804
/**
805
 *******************************************************************************
806
 *
807
 * @brief
808
 *  This function performs Single stage  Inverse transform for 32x32 input
809
 * block
810
 *
811
 * @par Description:
812
 *  Performs single stage 32x32 inverse transform by  utilizing the symmetry
813
 * of transformation matrix and  reducing number of multiplications wherever
814
 * possible  but keeping the number of operations  (addition,multiplication
815
 * and shift) same
816
 *
817
 * @param[in] pi2_src
818
 *  Input 32x32 coefficients
819
 *
820
 * @param[out] pi2_dst
821
 *  Output 32x32 block
822
 *
823
 * @param[in] src_strd
824
 *  Input stride
825
 *
826
 * @param[in] dst_strd
827
 *  Output Stride
828
 *
829
 * @param[in] i4_shift
830
 *  Output shift
831
 *
832
 * @param[in] zero_cols
833
 *  Zero columns in pi2_src
834
 *
835
 * @returns  Void
836
 *
837
 * @remarks
838
 *  None
839
 *
840
 *******************************************************************************
841
 */
842
843
844
void ihevc_itrans_32x32(WORD16 *pi2_src,
845
                        WORD16 *pi2_dst,
846
                        WORD32 src_strd,
847
                        WORD32 dst_strd,
848
                        WORD32 i4_shift,
849
                        WORD32 zero_cols)
850
0
{
851
0
    WORD32 j, k;
852
0
    WORD32 e[16], o[16];
853
0
    WORD32 ee[8], eo[8];
854
0
    WORD32 eee[4], eeo[4];
855
0
    WORD32 eeee[2], eeeo[2];
856
0
    WORD32 add;
857
858
0
    add = 1 << (i4_shift - 1);
859
860
0
    for(j = 0; j < TRANS_SIZE_32; j++)
861
0
    {
862
        /* Checking for Zero Cols */
863
0
        if((zero_cols & 1) == 1)
864
0
        {
865
0
            memset(pi2_dst, 0, TRANS_SIZE_32 * sizeof(WORD16));
866
0
        }
867
0
        else
868
0
        {
869
            /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
870
0
            for(k = 0; k < 16; k++)
871
0
            {
872
0
                o[k] = g_ai2_ihevc_trans_32[1][k] * pi2_src[src_strd]
873
0
                                + g_ai2_ihevc_trans_32[3][k]
874
0
                                                * pi2_src[3 * src_strd]
875
0
                                + g_ai2_ihevc_trans_32[5][k]
876
0
                                                * pi2_src[5 * src_strd]
877
0
                                + g_ai2_ihevc_trans_32[7][k]
878
0
                                                * pi2_src[7 * src_strd]
879
0
                                + g_ai2_ihevc_trans_32[9][k]
880
0
                                                * pi2_src[9 * src_strd]
881
0
                                + g_ai2_ihevc_trans_32[11][k]
882
0
                                                * pi2_src[11 * src_strd]
883
0
                                + g_ai2_ihevc_trans_32[13][k]
884
0
                                                * pi2_src[13 * src_strd]
885
0
                                + g_ai2_ihevc_trans_32[15][k]
886
0
                                                * pi2_src[15 * src_strd]
887
0
                                + g_ai2_ihevc_trans_32[17][k]
888
0
                                                * pi2_src[17 * src_strd]
889
0
                                + g_ai2_ihevc_trans_32[19][k]
890
0
                                                * pi2_src[19 * src_strd]
891
0
                                + g_ai2_ihevc_trans_32[21][k]
892
0
                                                * pi2_src[21 * src_strd]
893
0
                                + g_ai2_ihevc_trans_32[23][k]
894
0
                                                * pi2_src[23 * src_strd]
895
0
                                + g_ai2_ihevc_trans_32[25][k]
896
0
                                                * pi2_src[25 * src_strd]
897
0
                                + g_ai2_ihevc_trans_32[27][k]
898
0
                                                * pi2_src[27 * src_strd]
899
0
                                + g_ai2_ihevc_trans_32[29][k]
900
0
                                                * pi2_src[29 * src_strd]
901
0
                                + g_ai2_ihevc_trans_32[31][k]
902
0
                                                * pi2_src[31 * src_strd];
903
0
            }
904
0
            for(k = 0; k < 8; k++)
905
0
            {
906
0
                eo[k] = g_ai2_ihevc_trans_32[2][k] * pi2_src[2 * src_strd]
907
0
                                + g_ai2_ihevc_trans_32[6][k]
908
0
                                                * pi2_src[6 * src_strd]
909
0
                                + g_ai2_ihevc_trans_32[10][k]
910
0
                                                * pi2_src[10 * src_strd]
911
0
                                + g_ai2_ihevc_trans_32[14][k]
912
0
                                                * pi2_src[14 * src_strd]
913
0
                                + g_ai2_ihevc_trans_32[18][k]
914
0
                                                * pi2_src[18 * src_strd]
915
0
                                + g_ai2_ihevc_trans_32[22][k]
916
0
                                                * pi2_src[22 * src_strd]
917
0
                                + g_ai2_ihevc_trans_32[26][k]
918
0
                                                * pi2_src[26 * src_strd]
919
0
                                + g_ai2_ihevc_trans_32[30][k]
920
0
                                                * pi2_src[30 * src_strd];
921
0
            }
922
0
            for(k = 0; k < 4; k++)
923
0
            {
924
0
                eeo[k] = g_ai2_ihevc_trans_32[4][k] * pi2_src[4 * src_strd]
925
0
                                + g_ai2_ihevc_trans_32[12][k]
926
0
                                                * pi2_src[12 * src_strd]
927
0
                                + g_ai2_ihevc_trans_32[20][k]
928
0
                                                * pi2_src[20 * src_strd]
929
0
                                + g_ai2_ihevc_trans_32[28][k]
930
0
                                                * pi2_src[28 * src_strd];
931
0
            }
932
0
            eeeo[0] = g_ai2_ihevc_trans_32[8][0] * pi2_src[8 * src_strd]
933
0
                            + g_ai2_ihevc_trans_32[24][0]
934
0
                                            * pi2_src[24 * src_strd];
935
0
            eeeo[1] = g_ai2_ihevc_trans_32[8][1] * pi2_src[8 * src_strd]
936
0
                            + g_ai2_ihevc_trans_32[24][1]
937
0
                                            * pi2_src[24 * src_strd];
938
0
            eeee[0] = g_ai2_ihevc_trans_32[0][0] * pi2_src[0]
939
0
                            + g_ai2_ihevc_trans_32[16][0]
940
0
                                            * pi2_src[16 * src_strd];
941
0
            eeee[1] = g_ai2_ihevc_trans_32[0][1] * pi2_src[0]
942
0
                            + g_ai2_ihevc_trans_32[16][1]
943
0
                                            * pi2_src[16 * src_strd];
944
945
            /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
946
0
            eee[0] = eeee[0] + eeeo[0];
947
0
            eee[3] = eeee[0] - eeeo[0];
948
0
            eee[1] = eeee[1] + eeeo[1];
949
0
            eee[2] = eeee[1] - eeeo[1];
950
0
            for(k = 0; k < 4; k++)
951
0
            {
952
0
                ee[k] = eee[k] + eeo[k];
953
0
                ee[k + 4] = eee[3 - k] - eeo[3 - k];
954
0
            }
955
0
            for(k = 0; k < 8; k++)
956
0
            {
957
0
                e[k] = ee[k] + eo[k];
958
0
                e[k + 8] = ee[7 - k] - eo[7 - k];
959
0
            }
960
0
            for(k = 0; k < 16; k++)
961
0
            {
962
0
                pi2_dst[k] =
963
0
                                CLIP_S16(((e[k] + o[k] + add) >> i4_shift));
964
0
                pi2_dst[k + 16] =
965
0
                                CLIP_S16(((e[15 - k] - o[15 - k] + add) >> i4_shift));
966
0
            }
967
0
        }
968
0
        pi2_src++;
969
0
        pi2_dst += dst_strd;
970
0
        zero_cols = zero_cols >> 1;
971
0
    }
972
0
}
973