Coverage Report

Created: 2026-09-14 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/common/ihevc_itrans_recon_8x8.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_recon_8x8.c
22
 *
23
 * @brief
24
 *  Contains function definitions for inverse transform  and reconstruction 8x8
25
 *
26
 *
27
 * @author
28
 *  100470
29
 *
30
 * @par List of Functions:
31
 *  - ihevc_itrans_recon_8x8()
32
 *
33
 * @remarks
34
 *  None
35
 *
36
 *******************************************************************************
37
 */
38
#include <stdio.h>
39
#include <string.h>
40
#include "ihevc_typedefs.h"
41
#include "ihevc_macros.h"
42
#include "ihevc_platform_macros.h"
43
#include "ihevc_defs.h"
44
#include "ihevc_trans_tables.h"
45
#include "ihevc_itrans_recon.h"
46
#include "ihevc_trans_macros.h"
47
48
/**
49
 *******************************************************************************
50
 *
51
 * @brief
52
 *  This function performs Inverse transform  and reconstruction for 8x8
53
 * input block
54
 *
55
 * @par Description:
56
 *  Performs inverse transform and adds the prediction  data and clips output
57
 * to 8 bit
58
 *
59
 * @param[in] pi2_src
60
 *  Input 8x8 coefficients
61
 *
62
 * @param[in] pi2_tmp
63
 *  Temporary 8x8 buffer for storing inverse
64
 *
65
 *  transform
66
 *  1st stage output
67
 *
68
 * @param[in] pu1_pred
69
 *  Prediction 8x8 block
70
 *
71
 * @param[out] pu1_dst
72
 *  Output 8x8 block
73
 *
74
 * @param[in] src_strd
75
 *  Input stride
76
 *
77
 * @param[in] pred_strd
78
 *  Prediction stride
79
 *
80
 * @param[in] dst_strd
81
 *  Output Stride
82
 *
83
 * @param[in] shift
84
 *  Output shift
85
 *
86
 * @param[in] zero_cols
87
 *  Zero columns in pi2_src
88
 *
89
 * @returns  Void
90
 *
91
 * @remarks
92
 *  None
93
 *
94
 *******************************************************************************
95
 */
96
97
void ihevc_itrans_recon_8x8(WORD16 *pi2_src,
98
                            WORD16 *pi2_tmp,
99
                            UWORD8 *pu1_pred,
100
                            UWORD8 *pu1_dst,
101
                            WORD32 src_strd,
102
                            WORD32 pred_strd,
103
                            WORD32 dst_strd,
104
                            WORD32 zero_cols,
105
                            WORD32 zero_rows)
106
202k
{
107
202k
    WORD32 j, k;
108
202k
    WORD32 e[4], o[4];
109
202k
    WORD32 ee[2], eo[2];
110
202k
    WORD32 add;
111
202k
    WORD32 shift;
112
202k
    WORD16 *pi2_tmp_orig;
113
202k
    WORD32 trans_size;
114
202k
    WORD32 zero_rows_2nd_stage = zero_cols;
115
202k
    WORD32 row_limit_2nd_stage;
116
117
202k
    trans_size = TRANS_SIZE_8;
118
119
202k
    pi2_tmp_orig = pi2_tmp;
120
121
202k
    if((zero_cols & 0xF0) == 0xF0)
122
33.2k
        row_limit_2nd_stage = 4;
123
168k
    else
124
168k
        row_limit_2nd_stage = TRANS_SIZE_8;
125
126
127
202k
    if((zero_rows & 0xF0) == 0xF0) /* First 4 rows of input are non-zero */
128
19.0k
    {
129
        /************************************************************************************************/
130
        /**********************************START - IT_RECON_8x8******************************************/
131
        /************************************************************************************************/
132
133
        /* Inverse Transform 1st stage */
134
19.0k
        shift = IT_SHIFT_STAGE_1;
135
19.0k
        add = 1 << (shift - 1);
136
137
130k
        for(j = 0; j < row_limit_2nd_stage; j++)
138
111k
        {
139
            /* Checking for Zero Cols */
140
111k
            if((zero_cols & 1) == 1)
141
788
            {
142
788
                memset(pi2_tmp, 0, trans_size * sizeof(WORD16));
143
788
            }
144
111k
            else
145
111k
            {
146
                /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
147
555k
                for(k = 0; k < 4; k++)
148
444k
                {
149
444k
                    o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_src[src_strd]
150
444k
                                    + g_ai2_ihevc_trans_8[3][k]
151
444k
                                                    * pi2_src[3 * src_strd];
152
444k
                }
153
111k
                eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_src[2 * src_strd];
154
111k
                eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_src[2 * src_strd];
155
111k
                ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_src[0];
156
111k
                ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_src[0];
157
158
                /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
159
111k
                e[0] = ee[0] + eo[0];
160
111k
                e[3] = ee[0] - eo[0];
161
111k
                e[1] = ee[1] + eo[1];
162
111k
                e[2] = ee[1] - eo[1];
163
555k
                for(k = 0; k < 4; k++)
164
444k
                {
165
444k
                    pi2_tmp[k] =
166
444k
                                    CLIP_S16(((e[k] + o[k] + add) >> shift));
167
444k
                    pi2_tmp[k + 4] =
168
444k
                                    CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift));
169
444k
                }
170
111k
            }
171
111k
            pi2_src++;
172
111k
            pi2_tmp += trans_size;
173
111k
            zero_cols = zero_cols >> 1;
174
111k
        }
175
176
19.0k
        pi2_tmp = pi2_tmp_orig;
177
178
        /* Inverse Transform 2nd stage */
179
19.0k
        shift = IT_SHIFT_STAGE_2;
180
19.0k
        add = 1 << (shift - 1);
181
19.0k
        if((zero_rows_2nd_stage & 0xF0) == 0xF0) /* First 4 rows of output of 1st stage are non-zero */
182
10.1k
        {
183
91.6k
            for(j = 0; j < trans_size; j++)
184
81.5k
            {
185
                /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
186
407k
                for(k = 0; k < 4; k++)
187
326k
                {
188
326k
                    o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_tmp[trans_size]
189
326k
                                    + g_ai2_ihevc_trans_8[3][k] * pi2_tmp[3 * trans_size];
190
326k
                }
191
81.5k
                eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_tmp[2 * trans_size];
192
81.5k
                eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_tmp[2 * trans_size];
193
81.5k
                ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_tmp[0];
194
81.5k
                ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_tmp[0];
195
196
                /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
197
81.5k
                e[0] = ee[0] + eo[0];
198
81.5k
                e[3] = ee[0] - eo[0];
199
81.5k
                e[1] = ee[1] + eo[1];
200
81.5k
                e[2] = ee[1] - eo[1];
201
407k
                for(k = 0; k < 4; k++)
202
326k
                {
203
326k
                    WORD32 itrans_out;
204
326k
                    itrans_out =
205
326k
                                    CLIP_S16(((e[k] + o[k] + add) >> shift));
206
326k
                    pu1_dst[k] = CLIP_U8((itrans_out + pu1_pred[k]));
207
326k
                    itrans_out =
208
326k
                                    CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift));
209
326k
                    pu1_dst[k + 4] = CLIP_U8((itrans_out + pu1_pred[k + 4]));
210
326k
                }
211
81.5k
                pi2_tmp++;
212
81.5k
                pu1_pred += pred_strd;
213
81.5k
                pu1_dst += dst_strd;
214
81.5k
            }
215
10.1k
        }
216
8.88k
        else /* All rows of output of 1st stage are non-zero */
217
8.88k
        {
218
79.9k
            for(j = 0; j < trans_size; j++)
219
71.0k
            {
220
                /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
221
355k
                for(k = 0; k < 4; k++)
222
284k
                {
223
284k
                    o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_tmp[trans_size]
224
284k
                                    + g_ai2_ihevc_trans_8[3][k]
225
284k
                                                    * pi2_tmp[3 * trans_size]
226
284k
                                    + g_ai2_ihevc_trans_8[5][k]
227
284k
                                                    * pi2_tmp[5 * trans_size]
228
284k
                                    + g_ai2_ihevc_trans_8[7][k]
229
284k
                                                    * pi2_tmp[7 * trans_size];
230
284k
                }
231
232
71.0k
                eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_tmp[2 * trans_size]
233
71.0k
                                + g_ai2_ihevc_trans_8[6][0] * pi2_tmp[6 * trans_size];
234
71.0k
                eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_tmp[2 * trans_size]
235
71.0k
                                + g_ai2_ihevc_trans_8[6][1] * pi2_tmp[6 * trans_size];
236
71.0k
                ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_tmp[0]
237
71.0k
                                + g_ai2_ihevc_trans_8[4][0] * pi2_tmp[4 * trans_size];
238
71.0k
                ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_tmp[0]
239
71.0k
                                + g_ai2_ihevc_trans_8[4][1] * pi2_tmp[4 * trans_size];
240
241
                /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
242
71.0k
                e[0] = ee[0] + eo[0];
243
71.0k
                e[3] = ee[0] - eo[0];
244
71.0k
                e[1] = ee[1] + eo[1];
245
71.0k
                e[2] = ee[1] - eo[1];
246
355k
                for(k = 0; k < 4; k++)
247
284k
                {
248
284k
                    WORD32 itrans_out;
249
284k
                    itrans_out =
250
284k
                                    CLIP_S16(((e[k] + o[k] + add) >> shift));
251
284k
                    pu1_dst[k] = CLIP_U8((itrans_out + pu1_pred[k]));
252
284k
                    itrans_out =
253
284k
                                    CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift));
254
284k
                    pu1_dst[k + 4] = CLIP_U8((itrans_out + pu1_pred[k + 4]));
255
284k
                }
256
71.0k
                pi2_tmp++;
257
71.0k
                pu1_pred += pred_strd;
258
71.0k
                pu1_dst += dst_strd;
259
71.0k
            }
260
8.88k
        }
261
        /************************************************************************************************/
262
        /************************************END - IT_RECON_8x8******************************************/
263
        /************************************************************************************************/
264
19.0k
    }
265
183k
    else /* All rows of input are non-zero */
266
183k
    {
267
        /************************************************************************************************/
268
        /**********************************START - IT_RECON_8x8******************************************/
269
        /************************************************************************************************/
270
271
        /* Inverse Transform 1st stage */
272
183k
        shift = IT_SHIFT_STAGE_1;
273
183k
        add = 1 << (shift - 1);
274
275
1.55M
        for(j = 0; j < row_limit_2nd_stage; j++)
276
1.37M
        {
277
            /* Checking for Zero Cols */
278
1.37M
            if((zero_cols & 1) == 1)
279
920
            {
280
920
                memset(pi2_tmp, 0, trans_size * sizeof(WORD16));
281
920
            }
282
1.37M
            else
283
1.37M
            {
284
                /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
285
6.86M
                for(k = 0; k < 4; k++)
286
5.48M
                {
287
5.48M
                    o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_src[src_strd]
288
5.48M
                                    + g_ai2_ihevc_trans_8[3][k]
289
5.48M
                                                    * pi2_src[3 * src_strd]
290
5.48M
                                    + g_ai2_ihevc_trans_8[5][k]
291
5.48M
                                                    * pi2_src[5 * src_strd]
292
5.48M
                                    + g_ai2_ihevc_trans_8[7][k]
293
5.48M
                                                    * pi2_src[7 * src_strd];
294
5.48M
                }
295
296
1.37M
                eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_src[2 * src_strd]
297
1.37M
                                + g_ai2_ihevc_trans_8[6][0] * pi2_src[6 * src_strd];
298
1.37M
                eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_src[2 * src_strd]
299
1.37M
                                + g_ai2_ihevc_trans_8[6][1] * pi2_src[6 * src_strd];
300
1.37M
                ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_src[0]
301
1.37M
                                + g_ai2_ihevc_trans_8[4][0] * pi2_src[4 * src_strd];
302
1.37M
                ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_src[0]
303
1.37M
                                + g_ai2_ihevc_trans_8[4][1] * pi2_src[4 * src_strd];
304
305
                /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
306
1.37M
                e[0] = ee[0] + eo[0];
307
1.37M
                e[3] = ee[0] - eo[0];
308
1.37M
                e[1] = ee[1] + eo[1];
309
1.37M
                e[2] = ee[1] - eo[1];
310
6.86M
                for(k = 0; k < 4; k++)
311
5.48M
                {
312
5.48M
                    pi2_tmp[k] =
313
5.48M
                                    CLIP_S16(((e[k] + o[k] + add) >> shift));
314
5.48M
                    pi2_tmp[k + 4] =
315
5.48M
                                    CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift));
316
5.48M
                }
317
1.37M
            }
318
1.37M
            pi2_src++;
319
1.37M
            pi2_tmp += trans_size;
320
1.37M
            zero_cols = zero_cols >> 1;
321
1.37M
        }
322
323
183k
        pi2_tmp = pi2_tmp_orig;
324
325
        /* Inverse Transform 2nd stage */
326
183k
        shift = IT_SHIFT_STAGE_2;
327
183k
        add = 1 << (shift - 1);
328
183k
        if((zero_rows_2nd_stage & 0xF0) == 0xF0) /* First 4 rows of output of 1st stage are non-zero */
329
23.0k
        {
330
207k
            for(j = 0; j < trans_size; j++)
331
184k
            {
332
                /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
333
923k
                for(k = 0; k < 4; k++)
334
738k
                {
335
738k
                    o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_tmp[trans_size]
336
738k
                                    + g_ai2_ihevc_trans_8[3][k] * pi2_tmp[3 * trans_size];
337
738k
                }
338
184k
                eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_tmp[2 * trans_size];
339
184k
                eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_tmp[2 * trans_size];
340
184k
                ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_tmp[0];
341
184k
                ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_tmp[0];
342
343
                /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
344
184k
                e[0] = ee[0] + eo[0];
345
184k
                e[3] = ee[0] - eo[0];
346
184k
                e[1] = ee[1] + eo[1];
347
184k
                e[2] = ee[1] - eo[1];
348
923k
                for(k = 0; k < 4; k++)
349
738k
                {
350
738k
                    WORD32 itrans_out;
351
738k
                    itrans_out =
352
738k
                                    CLIP_S16(((e[k] + o[k] + add) >> shift));
353
738k
                    pu1_dst[k] = CLIP_U8((itrans_out + pu1_pred[k]));
354
738k
                    itrans_out =
355
738k
                                    CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift));
356
738k
                    pu1_dst[k + 4] = CLIP_U8((itrans_out + pu1_pred[k + 4]));
357
738k
                }
358
184k
                pi2_tmp++;
359
184k
                pu1_pred += pred_strd;
360
184k
                pu1_dst += dst_strd;
361
184k
            }
362
23.0k
        }
363
160k
        else /* All rows of output of 1st stage are non-zero */
364
160k
        {
365
1.44M
            for(j = 0; j < trans_size; j++)
366
1.28M
            {
367
                /* Utilizing symmetry properties to the maximum to minimize the number of multiplications */
368
6.40M
                for(k = 0; k < 4; k++)
369
5.12M
                {
370
5.12M
                    o[k] = g_ai2_ihevc_trans_8[1][k] * pi2_tmp[trans_size]
371
5.12M
                                    + g_ai2_ihevc_trans_8[3][k]
372
5.12M
                                                    * pi2_tmp[3 * trans_size]
373
5.12M
                                    + g_ai2_ihevc_trans_8[5][k]
374
5.12M
                                                    * pi2_tmp[5 * trans_size]
375
5.12M
                                    + g_ai2_ihevc_trans_8[7][k]
376
5.12M
                                                    * pi2_tmp[7 * trans_size];
377
5.12M
                }
378
379
1.28M
                eo[0] = g_ai2_ihevc_trans_8[2][0] * pi2_tmp[2 * trans_size]
380
1.28M
                                + g_ai2_ihevc_trans_8[6][0] * pi2_tmp[6 * trans_size];
381
1.28M
                eo[1] = g_ai2_ihevc_trans_8[2][1] * pi2_tmp[2 * trans_size]
382
1.28M
                                + g_ai2_ihevc_trans_8[6][1] * pi2_tmp[6 * trans_size];
383
1.28M
                ee[0] = g_ai2_ihevc_trans_8[0][0] * pi2_tmp[0]
384
1.28M
                                + g_ai2_ihevc_trans_8[4][0] * pi2_tmp[4 * trans_size];
385
1.28M
                ee[1] = g_ai2_ihevc_trans_8[0][1] * pi2_tmp[0]
386
1.28M
                                + g_ai2_ihevc_trans_8[4][1] * pi2_tmp[4 * trans_size];
387
388
                /* Combining e and o terms at each hierarchy levels to calculate the final spatial domain vector */
389
1.28M
                e[0] = ee[0] + eo[0];
390
1.28M
                e[3] = ee[0] - eo[0];
391
1.28M
                e[1] = ee[1] + eo[1];
392
1.28M
                e[2] = ee[1] - eo[1];
393
6.40M
                for(k = 0; k < 4; k++)
394
5.12M
                {
395
5.12M
                    WORD32 itrans_out;
396
5.12M
                    itrans_out =
397
5.12M
                                    CLIP_S16(((e[k] + o[k] + add) >> shift));
398
5.12M
                    pu1_dst[k] = CLIP_U8((itrans_out + pu1_pred[k]));
399
5.12M
                    itrans_out =
400
5.12M
                                    CLIP_S16(((e[3 - k] - o[3 - k] + add) >> shift));
401
5.12M
                    pu1_dst[k + 4] = CLIP_U8((itrans_out + pu1_pred[k + 4]));
402
5.12M
                }
403
1.28M
                pi2_tmp++;
404
1.28M
                pu1_pred += pred_strd;
405
1.28M
                pu1_dst += dst_strd;
406
1.28M
            }
407
160k
        }
408
        /************************************************************************************************/
409
        /************************************END - IT_RECON_8x8******************************************/
410
        /************************************************************************************************/
411
183k
    }
412
202k
}
413