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_iquant_recon.c
22 *
23 * @brief
24 *  Contains function definitions for inverse  quantization and
25 * reconstruction
26 *
27 * @author
28 *  100470
29 *
30 * @par List of Functions:
31 *  - ihevc_iquant_recon_4x4_ttype1()
32 *  - ihevc_iquant_recon_4x4()
33 *  - ihevc_iquant_recon_8x8()
34 *  - ihevc_iquant_recon_16x16()
35 *  - ihevc_iquant_recon_32x32()
36 *
37 * @remarks
38 *  None
39 *
40 *******************************************************************************
41 */
42#include <stdio.h>
43#include <string.h>
44#include "ihevc_typedefs.h"
45#include "ihevc_macros.h"
46#include "ihevc_platform_macros.h"
47#include "ihevc_defs.h"
48#include "ihevc_trans_tables.h"
49#include "ihevc_iquant_recon.h"
50#include "ihevc_func_selector.h"
51#include "ihevc_trans_macros.h"
52
53/* All the functions here are replicated from ihevc_iquant_itrans_recon.c and modified to */
54/* include reconstruction */
55
56/**
57 *******************************************************************************
58 *
59 * @brief
60 *  This function performs inverse quantization type 1 and  reconstruction
61 * for 4x4 input block
62 *
63 * @par Description:
64 *  This function performs inverse quantization and  reconstruction for 4x4
65 * input block
66 *
67 * @param[in] pi2_src
68 *  Input 4x4 coefficients
69 *
70 * @param[in] pu1_pred
71 *  Prediction 4x4 block
72 *
73 * @param[in] pi2_dequant_coeff
74 *  Dequant Coeffs
75 *
76 * @param[out] pu1_dst
77 *  Output 4x4 block
78 *
79 * @param[in] qp_div
80 *  Quantization parameter / 6
81 *
82 * @param[in] qp_rem
83 *  Quantization parameter % 6
84 *
85 * @param[in] src_strd
86 *  Input stride
87 *
88 * @param[in] pred_strd
89 *  Prediction stride
90 *
91 * @param[in] dst_strd
92 *  Output Stride
93 *
94 * @param[in] zero_cols
95 *  Zero columns in pi2_src
96 *
97 * @returns  Void
98 *
99 * @remarks
100 *  None
101 *
102 *******************************************************************************
103 */
104
105void ihevc_iquant_recon_4x4_ttype1(WORD16 *pi2_src,
106                                   UWORD8 *pu1_pred,
107                                   WORD16 *pi2_dequant_coeff,
108                                   UWORD8 *pu1_dst,
109                                   WORD32 qp_div, /* qpscaled / 6 */
110                                   WORD32 qp_rem, /* qpscaled % 6 */
111                                   WORD32 src_strd,
112                                   WORD32 pred_strd,
113                                   WORD32 dst_strd,
114                                   WORD32 zero_cols)
115{
116
117    {
118        /* Inverse Quant and recon */
119        {
120            WORD32 i, j;
121            WORD32 shift_iq;
122            WORD32 trans_size;
123            /* Inverse Quantization constants */
124            {
125                WORD32 log2_trans_size, bit_depth;
126
127                log2_trans_size = 2;
128                bit_depth = 8 + 0;
129                shift_iq = bit_depth + log2_trans_size - 5;
130            }
131
132            trans_size = TRANS_SIZE_4;
133
134            for(i = 0; i < trans_size; i++)
135            {
136                /* Checking for Zero Cols */
137                if((zero_cols & 1) == 1)
138                {
139                    for(j = 0; j < trans_size; j++)
140                        pu1_dst[j * dst_strd] = pu1_pred[j * pred_strd];
141                }
142                else
143                {
144                    for(j = 0; j < trans_size; j++)
145                    {
146                        WORD32 iquant_out;
147                        IQUANT_4x4(iquant_out,
148                                   pi2_src[j * src_strd],
149                                   pi2_dequant_coeff[j * trans_size] * g_ihevc_iquant_scales[qp_rem],
150                                   shift_iq, qp_div);
151
152                        iquant_out = (iquant_out + 16) >> 5;
153                        pu1_dst[j * dst_strd] =
154                                        CLIP_U8(iquant_out + pu1_pred[j * pred_strd]);
155                    }
156                }
157                pi2_src++;
158                pi2_dequant_coeff++;
159                pu1_pred++;
160                pu1_dst++;
161
162                zero_cols = zero_cols >> 1;
163            }
164        }
165    }
166}
167
168/**
169 *******************************************************************************
170 *
171 * @brief
172 *  This function performs inverse quantization and  reconstruction for 4x4
173 * input block
174 *
175 * @par Description:
176 *  This function performs inverse quantization and  reconstruction for 4x4
177 * input block
178 *
179 * @param[in] pi2_src
180 *  Input 4x4 coefficients
181 *
182 * @param[in] pu1_pred
183 *  Prediction 4x4 block
184 *
185 * @param[in] pi2_dequant_coeff
186 *  Dequant Coeffs
187 *
188 * @param[out] pu1_dst
189 *  Output 4x4 block
190 *
191 * @param[in] qp_div
192 *  Quantization parameter / 6
193 *
194 * @param[in] qp_rem
195 *  Quantization parameter % 6
196 *
197 * @param[in] src_strd
198 *  Input stride
199 *
200 * @param[in] pred_strd
201 *  Prediction stride
202 *
203 * @param[in] dst_strd
204 *  Output Stride
205 *
206 * @param[in] zero_cols
207 *  Zero columns in pi2_src
208 *
209 * @returns  Void
210 *
211 * @remarks
212 *  None
213 *
214 *******************************************************************************
215 */
216
217void ihevc_iquant_recon_4x4(WORD16 *pi2_src,
218                            UWORD8 *pu1_pred,
219                            WORD16 *pi2_dequant_coeff,
220                            UWORD8 *pu1_dst,
221                            WORD32 qp_div, /* qpscaled / 6 */
222                            WORD32 qp_rem, /* qpscaled % 6 */
223                            WORD32 src_strd,
224                            WORD32 pred_strd,
225                            WORD32 dst_strd,
226                            WORD32 zero_cols)
227{
228
229    {
230        /* Inverse Quant and recon */
231        {
232            WORD32 i, j;
233            WORD32 shift_iq;
234            WORD32 trans_size;
235            /* Inverse Quantization constants */
236            {
237                WORD32 log2_trans_size, bit_depth;
238
239                log2_trans_size = 2;
240                bit_depth = 8 + 0;
241                shift_iq = bit_depth + log2_trans_size - 5;
242            }
243
244            trans_size = TRANS_SIZE_4;
245
246            for(i = 0; i < trans_size; i++)
247            {
248                /* Checking for Zero Cols */
249                if((zero_cols & 1) == 1)
250                {
251                    for(j = 0; j < trans_size; j++)
252                        pu1_dst[j * dst_strd] = pu1_pred[j * pred_strd];
253                }
254                else
255                {
256                    for(j = 0; j < trans_size; j++)
257                    {
258                        WORD32 iquant_out;
259                        IQUANT_4x4(iquant_out,
260                                   pi2_src[j * src_strd],
261                                   pi2_dequant_coeff[j * trans_size] * g_ihevc_iquant_scales[qp_rem],
262                                   shift_iq, qp_div);
263                        iquant_out = (iquant_out + 16) >> 5;
264                        pu1_dst[j * dst_strd] =
265                                        CLIP_U8(iquant_out + pu1_pred[j * pred_strd]);
266                    }
267                }
268                pi2_src++;
269                pi2_dequant_coeff++;
270                pu1_pred++;
271                pu1_dst++;
272
273                zero_cols = zero_cols >> 1;
274            }
275        }
276    }
277}
278
279/**
280 *******************************************************************************
281 *
282 * @brief
283 *  This function performs inverse quantization and  reconstruction for 8x8
284 * input block
285 *
286 * @par Description:
287 *  This function performs inverse quantization and  reconstruction for 8x8
288 * input block
289 *
290 * @param[in] pi2_src
291 *  Input 8x8 coefficients
292 *
293 * @param[in] pu1_pred
294 *  Prediction 8x8 block
295 *
296 * @param[in] pi2_dequant_coeff
297 *  Dequant Coeffs
298 *
299 * @param[out] pu1_dst
300 *  Output 8x8 block
301 *
302 * @param[in] qp_div
303 *  Quantization parameter / 6
304 *
305 * @param[in] qp_rem
306 *  Quantization parameter % 6
307 *
308 * @param[in] src_strd
309 *  Input stride
310 *
311 * @param[in] pred_strd
312 *  Prediction stride
313 *
314 * @param[in] dst_strd
315 *  Output Stride
316 *
317 * @param[in] zero_cols
318 *  Zero columns in pi2_src
319 *
320 * @returns  Void
321 *
322 * @remarks
323 *  None
324 *
325 *******************************************************************************
326 */
327
328void ihevc_iquant_recon_8x8(WORD16 *pi2_src,
329                            UWORD8 *pu1_pred,
330                            WORD16 *pi2_dequant_coeff,
331                            UWORD8 *pu1_dst,
332                            WORD32 qp_div, /* qpscaled / 6 */
333                            WORD32 qp_rem, /* qpscaled % 6 */
334                            WORD32 src_strd,
335                            WORD32 pred_strd,
336                            WORD32 dst_strd,
337                            WORD32 zero_cols)
338{
339
340    {
341        /* Inverse Quant and recon */
342        {
343            WORD32 i, j;
344            WORD32 shift_iq;
345            WORD32 trans_size;
346            /* Inverse Quantization constants */
347            {
348                WORD32 log2_trans_size, bit_depth;
349
350                log2_trans_size = 3;
351                bit_depth = 8 + 0;
352                shift_iq = bit_depth + log2_trans_size - 5;
353            }
354
355            trans_size = TRANS_SIZE_8;
356
357            for(i = 0; i < trans_size; i++)
358            {
359                /* Checking for Zero Cols */
360                if((zero_cols & 1) == 1)
361                {
362                    for(j = 0; j < trans_size; j++)
363                        pu1_dst[j * dst_strd] = pu1_pred[j * pred_strd];
364                }
365                else
366                {
367                    for(j = 0; j < trans_size; j++)
368                    {
369                        WORD32 iquant_out;
370                        IQUANT(iquant_out,
371                               pi2_src[j * src_strd],
372                               pi2_dequant_coeff[j * trans_size] * g_ihevc_iquant_scales[qp_rem],
373                               shift_iq, qp_div);
374                        iquant_out = (iquant_out + 16) >> 5;
375                        pu1_dst[j * dst_strd] =
376                                        CLIP_U8(iquant_out + pu1_pred[j * pred_strd]);
377                    }
378                }
379                pi2_src++;
380                pi2_dequant_coeff++;
381                pu1_pred++;
382                pu1_dst++;
383
384                zero_cols = zero_cols >> 1;
385            }
386        }
387    }
388}
389
390/**
391 *******************************************************************************
392 *
393 * @brief
394 *  This function performs inverse quantization and  reconstruction for 16x16
395 * input block
396 *
397 * @par Description:
398 *  This function performs inverse quantization and  reconstruction for 16x16
399 * input block
400 *
401 * @param[in] pi2_src
402 *  Input 16x16 coefficients
403 *
404 * @param[in] pu1_pred
405 *  Prediction 16x16 block
406 *
407 * @param[in] pi2_dequant_coeff
408 *  Dequant Coeffs
409 *
410 * @param[out] pu1_dst
411 *  Output 16x16 block
412 *
413 * @param[in] qp_div
414 *  Quantization parameter / 6
415 *
416 * @param[in] qp_rem
417 *  Quantization parameter % 6
418 *
419 * @param[in] src_strd
420 *  Input stride
421 *
422 * @param[in] pred_strd
423 *  Prediction stride
424 *
425 * @param[in] dst_strd
426 *  Output Stride
427 *
428 * @param[in] zero_cols
429 *  Zero columns in pi2_src
430 *
431 * @returns  Void
432 *
433 * @remarks
434 *  None
435 *
436 *******************************************************************************
437 */
438
439void ihevc_iquant_recon_16x16(WORD16 *pi2_src,
440                              UWORD8 *pu1_pred,
441                              WORD16 *pi2_dequant_coeff,
442                              UWORD8 *pu1_dst,
443                              WORD32 qp_div, /* qpscaled / 6 */
444                              WORD32 qp_rem, /* qpscaled % 6 */
445                              WORD32 src_strd,
446                              WORD32 pred_strd,
447                              WORD32 dst_strd,
448                              WORD32 zero_cols)
449
450{
451
452    {
453        /* Inverse Quant and recon */
454        {
455            WORD32 i, j;
456            WORD32 shift_iq;
457            WORD32 trans_size;
458            /* Inverse Quantization constants */
459            {
460                WORD32 log2_trans_size, bit_depth;
461
462                log2_trans_size = 4;
463                bit_depth = 8 + 0;
464                shift_iq = bit_depth + log2_trans_size - 5;
465            }
466
467            trans_size = TRANS_SIZE_16;
468
469            for(i = 0; i < trans_size; i++)
470            {
471                /* Checking for Zero Cols */
472                if((zero_cols & 1) == 1)
473                {
474                    for(j = 0; j < trans_size; j++)
475                        pu1_dst[j * dst_strd] = pu1_pred[j * pred_strd];
476                }
477                else
478                {
479                    for(j = 0; j < trans_size; j++)
480                    {
481                        WORD32 iquant_out;
482                        IQUANT(iquant_out,
483                               pi2_src[j * src_strd],
484                               pi2_dequant_coeff[j * trans_size] * g_ihevc_iquant_scales[qp_rem],
485                               shift_iq, qp_div);
486                        iquant_out = (iquant_out + 16) >> 5;
487                        pu1_dst[j * dst_strd] =
488                                        CLIP_U8(iquant_out + pu1_pred[j * pred_strd]);
489                    }
490                }
491                pi2_src++;
492                pi2_dequant_coeff++;
493                pu1_pred++;
494                pu1_dst++;
495
496                zero_cols = zero_cols >> 1;
497            }
498        }
499    }
500}
501
502/**
503 *******************************************************************************
504 *
505 * @brief
506 *  This function performs inverse quantization and  reconstruction for 32x32
507 * input block
508 *
509 * @par Description:
510 *  This function performs inverse quantization and  reconstruction for 32x32
511 * input block
512 *
513 * @param[in] pi2_src
514 *  Input 32x32 coefficients
515 *
516 * @param[in] pu1_pred
517 *  Prediction 32x32 block
518 *
519 * @param[in] pi2_dequant_coeff
520 *  Dequant Coeffs
521 *
522 * @param[out] pu1_dst
523 *  Output 32x32 block
524 *
525 * @param[in] qp_div
526 *  Quantization parameter / 6
527 *
528 * @param[in] qp_rem
529 *  Quantization parameter % 6
530 *
531 * @param[in] src_strd
532 *  Input stride
533 *
534 * @param[in] pred_strd
535 *  Prediction stride
536 *
537 * @param[in] dst_strd
538 *  Output Stride
539 *
540 * @param[in] zero_cols
541 *  Zero columns in pi2_src
542 *
543 * @returns  Void
544 *
545 * @remarks
546 *  None
547 *
548 *******************************************************************************
549 */
550
551void ihevc_iquant_recon_32x32(WORD16 *pi2_src,
552                              UWORD8 *pu1_pred,
553                              WORD16 *pi2_dequant_coeff,
554                              UWORD8 *pu1_dst,
555                              WORD32 qp_div, /* qpscaled / 6 */
556                              WORD32 qp_rem, /* qpscaled % 6 */
557                              WORD32 src_strd,
558                              WORD32 pred_strd,
559                              WORD32 dst_strd,
560                              WORD32 zero_cols)
561{
562
563    {
564        /* Inverse Quant and recon */
565        {
566            WORD32 i, j;
567            WORD32 shift_iq;
568            WORD32 trans_size;
569            /* Inverse Quantization constants */
570            {
571                WORD32 log2_trans_size, bit_depth;
572
573                log2_trans_size = 5;
574                bit_depth = 8 + 0;
575                shift_iq = bit_depth + log2_trans_size - 5;
576            }
577
578            trans_size = TRANS_SIZE_32;
579
580            for(i = 0; i < trans_size; i++)
581            {
582                /* Checking for Zero Cols */
583                if((zero_cols & 1) == 1)
584                {
585                    for(j = 0; j < trans_size; j++)
586                        pu1_dst[j * dst_strd] = pu1_pred[j * pred_strd];
587                }
588                else
589                {
590                    for(j = 0; j < trans_size; j++)
591                    {
592                        WORD32 iquant_out;
593                        IQUANT(iquant_out,
594                               pi2_src[j * src_strd],
595                               pi2_dequant_coeff[j * trans_size] * g_ihevc_iquant_scales[qp_rem],
596                               shift_iq, qp_div);
597                        iquant_out = (iquant_out + 16) >> 5;
598                        pu1_dst[j * dst_strd] =
599                                        CLIP_U8(iquant_out + pu1_pred[j * pred_strd]);
600                    }
601                }
602                pi2_src++;
603                pi2_dequant_coeff++;
604                pu1_pred++;
605                pu1_dst++;
606
607                zero_cols = zero_cols >> 1;
608            }
609        }
610    }
611}
612
613