1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5)
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * Copyright (c) 2009-2011 Maxim Poliakovski
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * This file is part of FFmpeg.
7cabdff1aSopenharmony_ci *
8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
12cabdff1aSopenharmony_ci *
13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16cabdff1aSopenharmony_ci * Lesser General Public License for more details.
17cabdff1aSopenharmony_ci *
18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21cabdff1aSopenharmony_ci */
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci/**
24cabdff1aSopenharmony_ci * @file
25cabdff1aSopenharmony_ci * DSP functions (inverse transforms, motion compensation, wavelet recompositions)
26cabdff1aSopenharmony_ci * for Indeo Video Interactive codecs.
27cabdff1aSopenharmony_ci */
28cabdff1aSopenharmony_ci
29cabdff1aSopenharmony_ci#include <string.h>
30cabdff1aSopenharmony_ci#include "libavutil/common.h"
31cabdff1aSopenharmony_ci#include "ivi.h"
32cabdff1aSopenharmony_ci#include "ivi_dsp.h"
33cabdff1aSopenharmony_ci
34cabdff1aSopenharmony_civoid ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
35cabdff1aSopenharmony_ci                        const ptrdiff_t dst_pitch)
36cabdff1aSopenharmony_ci{
37cabdff1aSopenharmony_ci    int             x, y, indx;
38cabdff1aSopenharmony_ci    int32_t         p0, p1, p2, p3, tmp0, tmp1, tmp2;
39cabdff1aSopenharmony_ci    int32_t         b0_1, b0_2, b1_1, b1_2, b1_3, b2_1, b2_2, b2_3, b2_4, b2_5, b2_6;
40cabdff1aSopenharmony_ci    int32_t         b3_1, b3_2, b3_3, b3_4, b3_5, b3_6, b3_7, b3_8, b3_9;
41cabdff1aSopenharmony_ci    ptrdiff_t       pitch, back_pitch;
42cabdff1aSopenharmony_ci    const short     *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
43cabdff1aSopenharmony_ci    const int       num_bands = 4;
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_ci    /* all bands should have the same pitch */
46cabdff1aSopenharmony_ci    pitch = plane->bands[0].pitch;
47cabdff1aSopenharmony_ci
48cabdff1aSopenharmony_ci    /* pixels at the position "y-1" will be set to pixels at the "y" for the 1st iteration */
49cabdff1aSopenharmony_ci    back_pitch = 0;
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci    /* get pointers to the wavelet bands */
52cabdff1aSopenharmony_ci    b0_ptr = plane->bands[0].buf;
53cabdff1aSopenharmony_ci    b1_ptr = plane->bands[1].buf;
54cabdff1aSopenharmony_ci    b2_ptr = plane->bands[2].buf;
55cabdff1aSopenharmony_ci    b3_ptr = plane->bands[3].buf;
56cabdff1aSopenharmony_ci
57cabdff1aSopenharmony_ci    for (y = 0; y < plane->height; y += 2) {
58cabdff1aSopenharmony_ci
59cabdff1aSopenharmony_ci        if (y+2 >= plane->height)
60cabdff1aSopenharmony_ci            pitch= 0;
61cabdff1aSopenharmony_ci        /* load storage variables with values */
62cabdff1aSopenharmony_ci        if (num_bands > 0) {
63cabdff1aSopenharmony_ci            b0_1 = b0_ptr[0];
64cabdff1aSopenharmony_ci            b0_2 = b0_ptr[pitch];
65cabdff1aSopenharmony_ci        }
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_ci        if (num_bands > 1) {
68cabdff1aSopenharmony_ci            b1_1 = b1_ptr[back_pitch];
69cabdff1aSopenharmony_ci            b1_2 = b1_ptr[0];
70cabdff1aSopenharmony_ci            b1_3 = b1_1 - b1_2*6 + b1_ptr[pitch];
71cabdff1aSopenharmony_ci        }
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_ci        if (num_bands > 2) {
74cabdff1aSopenharmony_ci            b2_2 = b2_ptr[0];     // b2[x,  y  ]
75cabdff1aSopenharmony_ci            b2_3 = b2_2;          // b2[x+1,y  ] = b2[x,y]
76cabdff1aSopenharmony_ci            b2_5 = b2_ptr[pitch]; // b2[x  ,y+1]
77cabdff1aSopenharmony_ci            b2_6 = b2_5;          // b2[x+1,y+1] = b2[x,y+1]
78cabdff1aSopenharmony_ci        }
79cabdff1aSopenharmony_ci
80cabdff1aSopenharmony_ci        if (num_bands > 3) {
81cabdff1aSopenharmony_ci            b3_2 = b3_ptr[back_pitch]; // b3[x  ,y-1]
82cabdff1aSopenharmony_ci            b3_3 = b3_2;               // b3[x+1,y-1] = b3[x  ,y-1]
83cabdff1aSopenharmony_ci            b3_5 = b3_ptr[0];          // b3[x  ,y  ]
84cabdff1aSopenharmony_ci            b3_6 = b3_5;               // b3[x+1,y  ] = b3[x  ,y  ]
85cabdff1aSopenharmony_ci            b3_8 = b3_2 - b3_5*6 + b3_ptr[pitch];
86cabdff1aSopenharmony_ci            b3_9 = b3_8;
87cabdff1aSopenharmony_ci        }
88cabdff1aSopenharmony_ci
89cabdff1aSopenharmony_ci        for (x = 0, indx = 0; x < plane->width; x+=2, indx++) {
90cabdff1aSopenharmony_ci            if (x+2 >= plane->width) {
91cabdff1aSopenharmony_ci                b0_ptr --;
92cabdff1aSopenharmony_ci                b1_ptr --;
93cabdff1aSopenharmony_ci                b2_ptr --;
94cabdff1aSopenharmony_ci                b3_ptr --;
95cabdff1aSopenharmony_ci            }
96cabdff1aSopenharmony_ci
97cabdff1aSopenharmony_ci            /* some values calculated in the previous iterations can */
98cabdff1aSopenharmony_ci            /* be reused in the next ones, so do appropriate copying */
99cabdff1aSopenharmony_ci            b2_1 = b2_2; // b2[x-1,y  ] = b2[x,  y  ]
100cabdff1aSopenharmony_ci            b2_2 = b2_3; // b2[x  ,y  ] = b2[x+1,y  ]
101cabdff1aSopenharmony_ci            b2_4 = b2_5; // b2[x-1,y+1] = b2[x  ,y+1]
102cabdff1aSopenharmony_ci            b2_5 = b2_6; // b2[x  ,y+1] = b2[x+1,y+1]
103cabdff1aSopenharmony_ci            b3_1 = b3_2; // b3[x-1,y-1] = b3[x  ,y-1]
104cabdff1aSopenharmony_ci            b3_2 = b3_3; // b3[x  ,y-1] = b3[x+1,y-1]
105cabdff1aSopenharmony_ci            b3_4 = b3_5; // b3[x-1,y  ] = b3[x  ,y  ]
106cabdff1aSopenharmony_ci            b3_5 = b3_6; // b3[x  ,y  ] = b3[x+1,y  ]
107cabdff1aSopenharmony_ci            b3_7 = b3_8; // vert_HPF(x-1)
108cabdff1aSopenharmony_ci            b3_8 = b3_9; // vert_HPF(x  )
109cabdff1aSopenharmony_ci
110cabdff1aSopenharmony_ci            p0 = p1 = p2 = p3 = 0;
111cabdff1aSopenharmony_ci
112cabdff1aSopenharmony_ci            /* process the LL-band by applying LPF both vertically and horizontally */
113cabdff1aSopenharmony_ci            if (num_bands > 0) {
114cabdff1aSopenharmony_ci                tmp0 = b0_1;
115cabdff1aSopenharmony_ci                tmp2 = b0_2;
116cabdff1aSopenharmony_ci                b0_1 = b0_ptr[indx+1];
117cabdff1aSopenharmony_ci                b0_2 = b0_ptr[pitch+indx+1];
118cabdff1aSopenharmony_ci                tmp1 = tmp0 + b0_1;
119cabdff1aSopenharmony_ci
120cabdff1aSopenharmony_ci                p0 =  tmp0 * 16;
121cabdff1aSopenharmony_ci                p1 =  tmp1 * 8;
122cabdff1aSopenharmony_ci                p2 = (tmp0 + tmp2) * 8;
123cabdff1aSopenharmony_ci                p3 = (tmp1 + tmp2 + b0_2) * 4;
124cabdff1aSopenharmony_ci            }
125cabdff1aSopenharmony_ci
126cabdff1aSopenharmony_ci            /* process the HL-band by applying HPF vertically and LPF horizontally */
127cabdff1aSopenharmony_ci            if (num_bands > 1) {
128cabdff1aSopenharmony_ci                tmp0 = b1_2;
129cabdff1aSopenharmony_ci                tmp1 = b1_1;
130cabdff1aSopenharmony_ci                b1_2 = b1_ptr[indx+1];
131cabdff1aSopenharmony_ci                b1_1 = b1_ptr[back_pitch+indx+1];
132cabdff1aSopenharmony_ci
133cabdff1aSopenharmony_ci                tmp2 = tmp1 - tmp0*6 + b1_3;
134cabdff1aSopenharmony_ci                b1_3 = b1_1 - b1_2*6 + b1_ptr[pitch+indx+1];
135cabdff1aSopenharmony_ci
136cabdff1aSopenharmony_ci                p0 += (tmp0 + tmp1) * 8;
137cabdff1aSopenharmony_ci                p1 += (tmp0 + tmp1 + b1_1 + b1_2) * 4;
138cabdff1aSopenharmony_ci                p2 +=  tmp2 * 4;
139cabdff1aSopenharmony_ci                p3 += (tmp2 + b1_3) * 2;
140cabdff1aSopenharmony_ci            }
141cabdff1aSopenharmony_ci
142cabdff1aSopenharmony_ci            /* process the LH-band by applying LPF vertically and HPF horizontally */
143cabdff1aSopenharmony_ci            if (num_bands > 2) {
144cabdff1aSopenharmony_ci                b2_3 = b2_ptr[indx+1];
145cabdff1aSopenharmony_ci                b2_6 = b2_ptr[pitch+indx+1];
146cabdff1aSopenharmony_ci
147cabdff1aSopenharmony_ci                tmp0 = b2_1 + b2_2;
148cabdff1aSopenharmony_ci                tmp1 = b2_1 - b2_2*6 + b2_3;
149cabdff1aSopenharmony_ci
150cabdff1aSopenharmony_ci                p0 += tmp0 * 8;
151cabdff1aSopenharmony_ci                p1 += tmp1 * 4;
152cabdff1aSopenharmony_ci                p2 += (tmp0 + b2_4 + b2_5) * 4;
153cabdff1aSopenharmony_ci                p3 += (tmp1 + b2_4 - b2_5*6 + b2_6) * 2;
154cabdff1aSopenharmony_ci            }
155cabdff1aSopenharmony_ci
156cabdff1aSopenharmony_ci            /* process the HH-band by applying HPF both vertically and horizontally */
157cabdff1aSopenharmony_ci            if (num_bands > 3) {
158cabdff1aSopenharmony_ci                b3_6 = b3_ptr[indx+1];            // b3[x+1,y  ]
159cabdff1aSopenharmony_ci                b3_3 = b3_ptr[back_pitch+indx+1]; // b3[x+1,y-1]
160cabdff1aSopenharmony_ci
161cabdff1aSopenharmony_ci                tmp0 = b3_1 + b3_4;
162cabdff1aSopenharmony_ci                tmp1 = b3_2 + b3_5;
163cabdff1aSopenharmony_ci                tmp2 = b3_3 + b3_6;
164cabdff1aSopenharmony_ci
165cabdff1aSopenharmony_ci                b3_9 = b3_3 - b3_6*6 + b3_ptr[pitch+indx+1];
166cabdff1aSopenharmony_ci
167cabdff1aSopenharmony_ci                p0 += (tmp0 + tmp1) * 4;
168cabdff1aSopenharmony_ci                p1 += (tmp0 - tmp1*6 + tmp2) * 2;
169cabdff1aSopenharmony_ci                p2 += (b3_7 + b3_8) * 2;
170cabdff1aSopenharmony_ci                p3 +=  b3_7 - b3_8*6 + b3_9;
171cabdff1aSopenharmony_ci            }
172cabdff1aSopenharmony_ci
173cabdff1aSopenharmony_ci            /* output four pixels */
174cabdff1aSopenharmony_ci            dst[x]             = av_clip_uint8((p0 >> 6) + 128);
175cabdff1aSopenharmony_ci            dst[x+1]           = av_clip_uint8((p1 >> 6) + 128);
176cabdff1aSopenharmony_ci            dst[dst_pitch+x]   = av_clip_uint8((p2 >> 6) + 128);
177cabdff1aSopenharmony_ci            dst[dst_pitch+x+1] = av_clip_uint8((p3 >> 6) + 128);
178cabdff1aSopenharmony_ci        }// for x
179cabdff1aSopenharmony_ci
180cabdff1aSopenharmony_ci        dst += dst_pitch << 1;
181cabdff1aSopenharmony_ci
182cabdff1aSopenharmony_ci        back_pitch = -pitch;
183cabdff1aSopenharmony_ci
184cabdff1aSopenharmony_ci        b0_ptr += pitch + 1;
185cabdff1aSopenharmony_ci        b1_ptr += pitch + 1;
186cabdff1aSopenharmony_ci        b2_ptr += pitch + 1;
187cabdff1aSopenharmony_ci        b3_ptr += pitch + 1;
188cabdff1aSopenharmony_ci    }
189cabdff1aSopenharmony_ci}
190cabdff1aSopenharmony_ci
191cabdff1aSopenharmony_civoid ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
192cabdff1aSopenharmony_ci                           const ptrdiff_t dst_pitch)
193cabdff1aSopenharmony_ci{
194cabdff1aSopenharmony_ci    int             x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3;
195cabdff1aSopenharmony_ci    const short     *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
196cabdff1aSopenharmony_ci    ptrdiff_t       pitch;
197cabdff1aSopenharmony_ci
198cabdff1aSopenharmony_ci    /* all bands should have the same pitch */
199cabdff1aSopenharmony_ci    pitch = plane->bands[0].pitch;
200cabdff1aSopenharmony_ci
201cabdff1aSopenharmony_ci    /* get pointers to the wavelet bands */
202cabdff1aSopenharmony_ci    b0_ptr = plane->bands[0].buf;
203cabdff1aSopenharmony_ci    b1_ptr = plane->bands[1].buf;
204cabdff1aSopenharmony_ci    b2_ptr = plane->bands[2].buf;
205cabdff1aSopenharmony_ci    b3_ptr = plane->bands[3].buf;
206cabdff1aSopenharmony_ci
207cabdff1aSopenharmony_ci    for (y = 0; y < plane->height; y += 2) {
208cabdff1aSopenharmony_ci        for (x = 0, indx = 0; x < plane->width; x += 2, indx++) {
209cabdff1aSopenharmony_ci            /* load coefficients */
210cabdff1aSopenharmony_ci            b0 = b0_ptr[indx]; //should be: b0 = (num_bands > 0) ? b0_ptr[indx] : 0;
211cabdff1aSopenharmony_ci            b1 = b1_ptr[indx]; //should be: b1 = (num_bands > 1) ? b1_ptr[indx] : 0;
212cabdff1aSopenharmony_ci            b2 = b2_ptr[indx]; //should be: b2 = (num_bands > 2) ? b2_ptr[indx] : 0;
213cabdff1aSopenharmony_ci            b3 = b3_ptr[indx]; //should be: b3 = (num_bands > 3) ? b3_ptr[indx] : 0;
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_ci            /* haar wavelet recomposition */
216cabdff1aSopenharmony_ci            p0 = (b0 + b1 + b2 + b3 + 2) >> 2;
217cabdff1aSopenharmony_ci            p1 = (b0 + b1 - b2 - b3 + 2) >> 2;
218cabdff1aSopenharmony_ci            p2 = (b0 - b1 + b2 - b3 + 2) >> 2;
219cabdff1aSopenharmony_ci            p3 = (b0 - b1 - b2 + b3 + 2) >> 2;
220cabdff1aSopenharmony_ci
221cabdff1aSopenharmony_ci            /* bias, convert and output four pixels */
222cabdff1aSopenharmony_ci            dst[x]                 = av_clip_uint8(p0 + 128);
223cabdff1aSopenharmony_ci            dst[x + 1]             = av_clip_uint8(p1 + 128);
224cabdff1aSopenharmony_ci            dst[dst_pitch + x]     = av_clip_uint8(p2 + 128);
225cabdff1aSopenharmony_ci            dst[dst_pitch + x + 1] = av_clip_uint8(p3 + 128);
226cabdff1aSopenharmony_ci        }// for x
227cabdff1aSopenharmony_ci
228cabdff1aSopenharmony_ci        dst += dst_pitch << 1;
229cabdff1aSopenharmony_ci
230cabdff1aSopenharmony_ci        b0_ptr += pitch;
231cabdff1aSopenharmony_ci        b1_ptr += pitch;
232cabdff1aSopenharmony_ci        b2_ptr += pitch;
233cabdff1aSopenharmony_ci        b3_ptr += pitch;
234cabdff1aSopenharmony_ci    }// for y
235cabdff1aSopenharmony_ci}
236cabdff1aSopenharmony_ci
237cabdff1aSopenharmony_ci/** butterfly operation for the inverse Haar transform */
238cabdff1aSopenharmony_ci#define IVI_HAAR_BFLY(s1, s2, o1, o2, t) \
239cabdff1aSopenharmony_ci    t  = ((s1) - (s2)) >> 1;\
240cabdff1aSopenharmony_ci    o1 = ((s1) + (s2)) >> 1;\
241cabdff1aSopenharmony_ci    o2 = (t);\
242cabdff1aSopenharmony_ci
243cabdff1aSopenharmony_ci/** inverse 8-point Haar transform */
244cabdff1aSopenharmony_ci#define INV_HAAR8(s1, s5, s3, s7, s2, s4, s6, s8,\
245cabdff1aSopenharmony_ci                  d1, d2, d3, d4, d5, d6, d7, d8,\
246cabdff1aSopenharmony_ci                  t0, t1, t2, t3, t4, t5, t6, t7, t8) {\
247cabdff1aSopenharmony_ci    t1 = (s1) * 2; t5 = (s5) * 2;\
248cabdff1aSopenharmony_ci    IVI_HAAR_BFLY(t1, t5, t1, t5, t0); IVI_HAAR_BFLY(t1, s3, t1, t3, t0);\
249cabdff1aSopenharmony_ci    IVI_HAAR_BFLY(t5, s7, t5, t7, t0); IVI_HAAR_BFLY(t1, s2, t1, t2, t0);\
250cabdff1aSopenharmony_ci    IVI_HAAR_BFLY(t3, s4, t3, t4, t0); IVI_HAAR_BFLY(t5, s6, t5, t6, t0);\
251cabdff1aSopenharmony_ci    IVI_HAAR_BFLY(t7, s8, t7, t8, t0);\
252cabdff1aSopenharmony_ci    d1 = COMPENSATE(t1);\
253cabdff1aSopenharmony_ci    d2 = COMPENSATE(t2);\
254cabdff1aSopenharmony_ci    d3 = COMPENSATE(t3);\
255cabdff1aSopenharmony_ci    d4 = COMPENSATE(t4);\
256cabdff1aSopenharmony_ci    d5 = COMPENSATE(t5);\
257cabdff1aSopenharmony_ci    d6 = COMPENSATE(t6);\
258cabdff1aSopenharmony_ci    d7 = COMPENSATE(t7);\
259cabdff1aSopenharmony_ci    d8 = COMPENSATE(t8); }
260cabdff1aSopenharmony_ci
261cabdff1aSopenharmony_ci/** inverse 4-point Haar transform */
262cabdff1aSopenharmony_ci#define INV_HAAR4(s1, s3, s5, s7, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\
263cabdff1aSopenharmony_ci    IVI_HAAR_BFLY(s1, s3, t0, t1, t4);\
264cabdff1aSopenharmony_ci    IVI_HAAR_BFLY(t0, s5, t2, t3, t4);\
265cabdff1aSopenharmony_ci    d1 = COMPENSATE(t2);\
266cabdff1aSopenharmony_ci    d2 = COMPENSATE(t3);\
267cabdff1aSopenharmony_ci    IVI_HAAR_BFLY(t1, s7, t2, t3, t4);\
268cabdff1aSopenharmony_ci    d3 = COMPENSATE(t2);\
269cabdff1aSopenharmony_ci    d4 = COMPENSATE(t3); }
270cabdff1aSopenharmony_ci
271cabdff1aSopenharmony_civoid ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch,
272cabdff1aSopenharmony_ci                             const uint8_t *flags)
273cabdff1aSopenharmony_ci{
274cabdff1aSopenharmony_ci    int     i, shift, sp1, sp2, sp3, sp4;
275cabdff1aSopenharmony_ci    const int32_t *src;
276cabdff1aSopenharmony_ci    int32_t *dst;
277cabdff1aSopenharmony_ci    int     tmp[64];
278cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
279cabdff1aSopenharmony_ci
280cabdff1aSopenharmony_ci    /* apply the InvHaar8 to all columns */
281cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
282cabdff1aSopenharmony_ci    src = in;
283cabdff1aSopenharmony_ci    dst = tmp;
284cabdff1aSopenharmony_ci    for (i = 0; i < 8; i++) {
285cabdff1aSopenharmony_ci        if (flags[i]) {
286cabdff1aSopenharmony_ci            /* pre-scaling */
287cabdff1aSopenharmony_ci            shift = !(i & 4);
288cabdff1aSopenharmony_ci            sp1 = src[ 0] * (1 << shift);
289cabdff1aSopenharmony_ci            sp2 = src[ 8] * (1 << shift);
290cabdff1aSopenharmony_ci            sp3 = src[16] * (1 << shift);
291cabdff1aSopenharmony_ci            sp4 = src[24] * (1 << shift);
292cabdff1aSopenharmony_ci            INV_HAAR8(    sp1,     sp2,     sp3,     sp4,
293cabdff1aSopenharmony_ci                      src[32], src[40], src[48], src[56],
294cabdff1aSopenharmony_ci                      dst[ 0], dst[ 8], dst[16], dst[24],
295cabdff1aSopenharmony_ci                      dst[32], dst[40], dst[48], dst[56],
296cabdff1aSopenharmony_ci                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
297cabdff1aSopenharmony_ci        } else
298cabdff1aSopenharmony_ci            dst[ 0] = dst[ 8] = dst[16] = dst[24] =
299cabdff1aSopenharmony_ci            dst[32] = dst[40] = dst[48] = dst[56] = 0;
300cabdff1aSopenharmony_ci
301cabdff1aSopenharmony_ci        src++;
302cabdff1aSopenharmony_ci        dst++;
303cabdff1aSopenharmony_ci    }
304cabdff1aSopenharmony_ci#undef  COMPENSATE
305cabdff1aSopenharmony_ci
306cabdff1aSopenharmony_ci    /* apply the InvHaar8 to all rows */
307cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
308cabdff1aSopenharmony_ci    src = tmp;
309cabdff1aSopenharmony_ci    for (i = 0; i < 8; i++) {
310cabdff1aSopenharmony_ci        if (   !src[0] && !src[1] && !src[2] && !src[3]
311cabdff1aSopenharmony_ci            && !src[4] && !src[5] && !src[6] && !src[7]) {
312cabdff1aSopenharmony_ci            memset(out, 0, 8 * sizeof(out[0]));
313cabdff1aSopenharmony_ci        } else {
314cabdff1aSopenharmony_ci            INV_HAAR8(src[0], src[1], src[2], src[3],
315cabdff1aSopenharmony_ci                      src[4], src[5], src[6], src[7],
316cabdff1aSopenharmony_ci                      out[0], out[1], out[2], out[3],
317cabdff1aSopenharmony_ci                      out[4], out[5], out[6], out[7],
318cabdff1aSopenharmony_ci                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
319cabdff1aSopenharmony_ci        }
320cabdff1aSopenharmony_ci        src += 8;
321cabdff1aSopenharmony_ci        out += pitch;
322cabdff1aSopenharmony_ci    }
323cabdff1aSopenharmony_ci#undef  COMPENSATE
324cabdff1aSopenharmony_ci}
325cabdff1aSopenharmony_ci
326cabdff1aSopenharmony_civoid ff_ivi_row_haar8(const int32_t *in, int16_t *out, ptrdiff_t pitch,
327cabdff1aSopenharmony_ci                      const uint8_t *flags)
328cabdff1aSopenharmony_ci{
329cabdff1aSopenharmony_ci    int     i;
330cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
331cabdff1aSopenharmony_ci
332cabdff1aSopenharmony_ci    /* apply the InvHaar8 to all rows */
333cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
334cabdff1aSopenharmony_ci    for (i = 0; i < 8; i++) {
335cabdff1aSopenharmony_ci        if (   !in[0] && !in[1] && !in[2] && !in[3]
336cabdff1aSopenharmony_ci            && !in[4] && !in[5] && !in[6] && !in[7]) {
337cabdff1aSopenharmony_ci            memset(out, 0, 8 * sizeof(out[0]));
338cabdff1aSopenharmony_ci        } else {
339cabdff1aSopenharmony_ci            INV_HAAR8(in[0],  in[1],  in[2],  in[3],
340cabdff1aSopenharmony_ci                      in[4],  in[5],  in[6],  in[7],
341cabdff1aSopenharmony_ci                      out[0], out[1], out[2], out[3],
342cabdff1aSopenharmony_ci                      out[4], out[5], out[6], out[7],
343cabdff1aSopenharmony_ci                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
344cabdff1aSopenharmony_ci        }
345cabdff1aSopenharmony_ci        in  += 8;
346cabdff1aSopenharmony_ci        out += pitch;
347cabdff1aSopenharmony_ci    }
348cabdff1aSopenharmony_ci#undef  COMPENSATE
349cabdff1aSopenharmony_ci}
350cabdff1aSopenharmony_ci
351cabdff1aSopenharmony_civoid ff_ivi_col_haar8(const int32_t *in, int16_t *out, ptrdiff_t pitch,
352cabdff1aSopenharmony_ci                      const uint8_t *flags)
353cabdff1aSopenharmony_ci{
354cabdff1aSopenharmony_ci    int     i;
355cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
356cabdff1aSopenharmony_ci
357cabdff1aSopenharmony_ci    /* apply the InvHaar8 to all columns */
358cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
359cabdff1aSopenharmony_ci    for (i = 0; i < 8; i++) {
360cabdff1aSopenharmony_ci        if (flags[i]) {
361cabdff1aSopenharmony_ci            INV_HAAR8(in[ 0], in[ 8], in[16], in[24],
362cabdff1aSopenharmony_ci                      in[32], in[40], in[48], in[56],
363cabdff1aSopenharmony_ci                      out[0 * pitch], out[1 * pitch],
364cabdff1aSopenharmony_ci                      out[2 * pitch], out[3 * pitch],
365cabdff1aSopenharmony_ci                      out[4 * pitch], out[5 * pitch],
366cabdff1aSopenharmony_ci                      out[6 * pitch], out[7 * pitch],
367cabdff1aSopenharmony_ci                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
368cabdff1aSopenharmony_ci        } else
369cabdff1aSopenharmony_ci            out[0 * pitch] = out[1 * pitch] =
370cabdff1aSopenharmony_ci            out[2 * pitch] = out[3 * pitch] =
371cabdff1aSopenharmony_ci            out[4 * pitch] = out[5 * pitch] =
372cabdff1aSopenharmony_ci            out[6 * pitch] = out[7 * pitch] = 0;
373cabdff1aSopenharmony_ci
374cabdff1aSopenharmony_ci        in++;
375cabdff1aSopenharmony_ci        out++;
376cabdff1aSopenharmony_ci    }
377cabdff1aSopenharmony_ci#undef  COMPENSATE
378cabdff1aSopenharmony_ci}
379cabdff1aSopenharmony_ci
380cabdff1aSopenharmony_civoid ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, ptrdiff_t pitch,
381cabdff1aSopenharmony_ci                             const uint8_t *flags)
382cabdff1aSopenharmony_ci{
383cabdff1aSopenharmony_ci    int     i, shift, sp1, sp2;
384cabdff1aSopenharmony_ci    const int32_t *src;
385cabdff1aSopenharmony_ci    int32_t *dst;
386cabdff1aSopenharmony_ci    int     tmp[16];
387cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4;
388cabdff1aSopenharmony_ci
389cabdff1aSopenharmony_ci    /* apply the InvHaar4 to all columns */
390cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
391cabdff1aSopenharmony_ci    src = in;
392cabdff1aSopenharmony_ci    dst = tmp;
393cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
394cabdff1aSopenharmony_ci        if (flags[i]) {
395cabdff1aSopenharmony_ci            /* pre-scaling */
396cabdff1aSopenharmony_ci            shift = !(i & 2);
397cabdff1aSopenharmony_ci            sp1 = src[0] * (1 << shift);
398cabdff1aSopenharmony_ci            sp2 = src[4] * (1 << shift);
399cabdff1aSopenharmony_ci            INV_HAAR4(   sp1,    sp2, src[8], src[12],
400cabdff1aSopenharmony_ci                      dst[0], dst[4], dst[8], dst[12],
401cabdff1aSopenharmony_ci                      t0, t1, t2, t3, t4);
402cabdff1aSopenharmony_ci        } else
403cabdff1aSopenharmony_ci            dst[0] = dst[4] = dst[8] = dst[12] = 0;
404cabdff1aSopenharmony_ci
405cabdff1aSopenharmony_ci        src++;
406cabdff1aSopenharmony_ci        dst++;
407cabdff1aSopenharmony_ci    }
408cabdff1aSopenharmony_ci#undef  COMPENSATE
409cabdff1aSopenharmony_ci
410cabdff1aSopenharmony_ci    /* apply the InvHaar8 to all rows */
411cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
412cabdff1aSopenharmony_ci    src = tmp;
413cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
414cabdff1aSopenharmony_ci        if (!src[0] && !src[1] && !src[2] && !src[3]) {
415cabdff1aSopenharmony_ci            memset(out, 0, 4 * sizeof(out[0]));
416cabdff1aSopenharmony_ci        } else {
417cabdff1aSopenharmony_ci            INV_HAAR4(src[0], src[1], src[2], src[3],
418cabdff1aSopenharmony_ci                      out[0], out[1], out[2], out[3],
419cabdff1aSopenharmony_ci                      t0, t1, t2, t3, t4);
420cabdff1aSopenharmony_ci        }
421cabdff1aSopenharmony_ci        src += 4;
422cabdff1aSopenharmony_ci        out += pitch;
423cabdff1aSopenharmony_ci    }
424cabdff1aSopenharmony_ci#undef  COMPENSATE
425cabdff1aSopenharmony_ci}
426cabdff1aSopenharmony_ci
427cabdff1aSopenharmony_civoid ff_ivi_row_haar4(const int32_t *in, int16_t *out, ptrdiff_t pitch,
428cabdff1aSopenharmony_ci                      const uint8_t *flags)
429cabdff1aSopenharmony_ci{
430cabdff1aSopenharmony_ci    int     i;
431cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4;
432cabdff1aSopenharmony_ci
433cabdff1aSopenharmony_ci    /* apply the InvHaar4 to all rows */
434cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
435cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
436cabdff1aSopenharmony_ci        if (!in[0] && !in[1] && !in[2] && !in[3]) {
437cabdff1aSopenharmony_ci            memset(out, 0, 4 * sizeof(out[0]));
438cabdff1aSopenharmony_ci        } else {
439cabdff1aSopenharmony_ci            INV_HAAR4(in[0], in[1], in[2], in[3],
440cabdff1aSopenharmony_ci                      out[0], out[1], out[2], out[3],
441cabdff1aSopenharmony_ci                      t0, t1, t2, t3, t4);
442cabdff1aSopenharmony_ci        }
443cabdff1aSopenharmony_ci        in  += 4;
444cabdff1aSopenharmony_ci        out += pitch;
445cabdff1aSopenharmony_ci    }
446cabdff1aSopenharmony_ci#undef  COMPENSATE
447cabdff1aSopenharmony_ci}
448cabdff1aSopenharmony_ci
449cabdff1aSopenharmony_civoid ff_ivi_col_haar4(const int32_t *in, int16_t *out, ptrdiff_t pitch,
450cabdff1aSopenharmony_ci                      const uint8_t *flags)
451cabdff1aSopenharmony_ci{
452cabdff1aSopenharmony_ci    int     i;
453cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4;
454cabdff1aSopenharmony_ci
455cabdff1aSopenharmony_ci    /* apply the InvHaar8 to all columns */
456cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
457cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
458cabdff1aSopenharmony_ci        if (flags[i]) {
459cabdff1aSopenharmony_ci            INV_HAAR4(in[0], in[4], in[8], in[12],
460cabdff1aSopenharmony_ci                      out[0 * pitch], out[1 * pitch],
461cabdff1aSopenharmony_ci                      out[2 * pitch], out[3 * pitch],
462cabdff1aSopenharmony_ci                      t0, t1, t2, t3, t4);
463cabdff1aSopenharmony_ci        } else
464cabdff1aSopenharmony_ci            out[0 * pitch] = out[1 * pitch] =
465cabdff1aSopenharmony_ci            out[2 * pitch] = out[3 * pitch] = 0;
466cabdff1aSopenharmony_ci
467cabdff1aSopenharmony_ci        in++;
468cabdff1aSopenharmony_ci        out++;
469cabdff1aSopenharmony_ci    }
470cabdff1aSopenharmony_ci#undef  COMPENSATE
471cabdff1aSopenharmony_ci}
472cabdff1aSopenharmony_ci
473cabdff1aSopenharmony_civoid ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, ptrdiff_t pitch,
474cabdff1aSopenharmony_ci                       int blk_size)
475cabdff1aSopenharmony_ci{
476cabdff1aSopenharmony_ci    int     x, y;
477cabdff1aSopenharmony_ci    int16_t dc_coeff;
478cabdff1aSopenharmony_ci
479cabdff1aSopenharmony_ci    dc_coeff = (*in + 0) >> 3;
480cabdff1aSopenharmony_ci
481cabdff1aSopenharmony_ci    for (y = 0; y < blk_size; out += pitch, y++) {
482cabdff1aSopenharmony_ci        for (x = 0; x < blk_size; x++)
483cabdff1aSopenharmony_ci            out[x] = dc_coeff;
484cabdff1aSopenharmony_ci    }
485cabdff1aSopenharmony_ci}
486cabdff1aSopenharmony_ci
487cabdff1aSopenharmony_ci/** butterfly operation for the inverse slant transform */
488cabdff1aSopenharmony_ci#define IVI_SLANT_BFLY(s1, s2, o1, o2, t) \
489cabdff1aSopenharmony_ci    t  = (s1) - (s2);\
490cabdff1aSopenharmony_ci    o1 = (s1) + (s2);\
491cabdff1aSopenharmony_ci    o2 = (t);\
492cabdff1aSopenharmony_ci
493cabdff1aSopenharmony_ci/** This is a reflection a,b = 1/2, 5/4 for the inverse slant transform */
494cabdff1aSopenharmony_ci#define IVI_IREFLECT(s1, s2, o1, o2, t) \
495cabdff1aSopenharmony_ci    t  = (((s1) + (s2)*2 + 2) >> 2) + (s1);\
496cabdff1aSopenharmony_ci    o2 = (((s1)*2 - (s2) + 2) >> 2) - (s2);\
497cabdff1aSopenharmony_ci    o1 = (t);\
498cabdff1aSopenharmony_ci
499cabdff1aSopenharmony_ci/** This is a reflection a,b = 1/2, 7/8 for the inverse slant transform */
500cabdff1aSopenharmony_ci#define IVI_SLANT_PART4(s1, s2, o1, o2, t) \
501cabdff1aSopenharmony_ci    t  = (s2) + (((s1)*4  - (s2) + 4) >> 3);\
502cabdff1aSopenharmony_ci    o2 = (s1) + ((-(s1) - (s2)*4 + 4) >> 3);\
503cabdff1aSopenharmony_ci    o1 = (t);\
504cabdff1aSopenharmony_ci
505cabdff1aSopenharmony_ci/** inverse slant8 transform */
506cabdff1aSopenharmony_ci#define IVI_INV_SLANT8(s1, s4, s8, s5, s2, s6, s3, s7,\
507cabdff1aSopenharmony_ci                       d1, d2, d3, d4, d5, d6, d7, d8,\
508cabdff1aSopenharmony_ci                       t0, t1, t2, t3, t4, t5, t6, t7, t8) {\
509cabdff1aSopenharmony_ci    IVI_SLANT_PART4(s4, s5, t4, t5, t0);\
510cabdff1aSopenharmony_ci\
511cabdff1aSopenharmony_ci    IVI_SLANT_BFLY(s1, t5, t1, t5, t0); IVI_SLANT_BFLY(s2, s6, t2, t6, t0);\
512cabdff1aSopenharmony_ci    IVI_SLANT_BFLY(s7, s3, t7, t3, t0); IVI_SLANT_BFLY(t4, s8, t4, t8, t0);\
513cabdff1aSopenharmony_ci\
514cabdff1aSopenharmony_ci    IVI_SLANT_BFLY(t1, t2, t1, t2, t0); IVI_IREFLECT  (t4, t3, t4, t3, t0);\
515cabdff1aSopenharmony_ci    IVI_SLANT_BFLY(t5, t6, t5, t6, t0); IVI_IREFLECT  (t8, t7, t8, t7, t0);\
516cabdff1aSopenharmony_ci    IVI_SLANT_BFLY(t1, t4, t1, t4, t0); IVI_SLANT_BFLY(t2, t3, t2, t3, t0);\
517cabdff1aSopenharmony_ci    IVI_SLANT_BFLY(t5, t8, t5, t8, t0); IVI_SLANT_BFLY(t6, t7, t6, t7, t0);\
518cabdff1aSopenharmony_ci    d1 = COMPENSATE(t1);\
519cabdff1aSopenharmony_ci    d2 = COMPENSATE(t2);\
520cabdff1aSopenharmony_ci    d3 = COMPENSATE(t3);\
521cabdff1aSopenharmony_ci    d4 = COMPENSATE(t4);\
522cabdff1aSopenharmony_ci    d5 = COMPENSATE(t5);\
523cabdff1aSopenharmony_ci    d6 = COMPENSATE(t6);\
524cabdff1aSopenharmony_ci    d7 = COMPENSATE(t7);\
525cabdff1aSopenharmony_ci    d8 = COMPENSATE(t8);}
526cabdff1aSopenharmony_ci
527cabdff1aSopenharmony_ci/** inverse slant4 transform */
528cabdff1aSopenharmony_ci#define IVI_INV_SLANT4(s1, s4, s2, s3, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\
529cabdff1aSopenharmony_ci    IVI_SLANT_BFLY(s1, s2, t1, t2, t0); IVI_IREFLECT  (s4, s3, t4, t3, t0);\
530cabdff1aSopenharmony_ci\
531cabdff1aSopenharmony_ci    IVI_SLANT_BFLY(t1, t4, t1, t4, t0); IVI_SLANT_BFLY(t2, t3, t2, t3, t0);\
532cabdff1aSopenharmony_ci    d1 = COMPENSATE(t1);\
533cabdff1aSopenharmony_ci    d2 = COMPENSATE(t2);\
534cabdff1aSopenharmony_ci    d3 = COMPENSATE(t3);\
535cabdff1aSopenharmony_ci    d4 = COMPENSATE(t4);}
536cabdff1aSopenharmony_ci
537cabdff1aSopenharmony_civoid ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags)
538cabdff1aSopenharmony_ci{
539cabdff1aSopenharmony_ci    int     i;
540cabdff1aSopenharmony_ci    const int32_t *src;
541cabdff1aSopenharmony_ci    int32_t *dst;
542cabdff1aSopenharmony_ci    int     tmp[64];
543cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
544cabdff1aSopenharmony_ci
545cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
546cabdff1aSopenharmony_ci    src = in;
547cabdff1aSopenharmony_ci    dst = tmp;
548cabdff1aSopenharmony_ci    for (i = 0; i < 8; i++) {
549cabdff1aSopenharmony_ci        if (flags[i]) {
550cabdff1aSopenharmony_ci            IVI_INV_SLANT8(src[0], src[8], src[16], src[24], src[32], src[40], src[48], src[56],
551cabdff1aSopenharmony_ci                           dst[0], dst[8], dst[16], dst[24], dst[32], dst[40], dst[48], dst[56],
552cabdff1aSopenharmony_ci                           t0, t1, t2, t3, t4, t5, t6, t7, t8);
553cabdff1aSopenharmony_ci        } else
554cabdff1aSopenharmony_ci            dst[0] = dst[8] = dst[16] = dst[24] = dst[32] = dst[40] = dst[48] = dst[56] = 0;
555cabdff1aSopenharmony_ci
556cabdff1aSopenharmony_ci        src++;
557cabdff1aSopenharmony_ci        dst++;
558cabdff1aSopenharmony_ci    }
559cabdff1aSopenharmony_ci#undef COMPENSATE
560cabdff1aSopenharmony_ci
561cabdff1aSopenharmony_ci#define COMPENSATE(x) (((x) + 1)>>1)
562cabdff1aSopenharmony_ci    src = tmp;
563cabdff1aSopenharmony_ci    for (i = 0; i < 8; i++) {
564cabdff1aSopenharmony_ci        if (!src[0] && !src[1] && !src[2] && !src[3] && !src[4] && !src[5] && !src[6] && !src[7]) {
565cabdff1aSopenharmony_ci            memset(out, 0, 8*sizeof(out[0]));
566cabdff1aSopenharmony_ci        } else {
567cabdff1aSopenharmony_ci            IVI_INV_SLANT8(src[0], src[1], src[2], src[3], src[4], src[5], src[6], src[7],
568cabdff1aSopenharmony_ci                           out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
569cabdff1aSopenharmony_ci                           t0, t1, t2, t3, t4, t5, t6, t7, t8);
570cabdff1aSopenharmony_ci        }
571cabdff1aSopenharmony_ci        src += 8;
572cabdff1aSopenharmony_ci        out += pitch;
573cabdff1aSopenharmony_ci    }
574cabdff1aSopenharmony_ci#undef COMPENSATE
575cabdff1aSopenharmony_ci}
576cabdff1aSopenharmony_ci
577cabdff1aSopenharmony_civoid ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags)
578cabdff1aSopenharmony_ci{
579cabdff1aSopenharmony_ci    int     i;
580cabdff1aSopenharmony_ci    const int32_t *src;
581cabdff1aSopenharmony_ci    int32_t *dst;
582cabdff1aSopenharmony_ci    int     tmp[16];
583cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4;
584cabdff1aSopenharmony_ci
585cabdff1aSopenharmony_ci#define COMPENSATE(x) (x)
586cabdff1aSopenharmony_ci    src = in;
587cabdff1aSopenharmony_ci    dst = tmp;
588cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
589cabdff1aSopenharmony_ci        if (flags[i]) {
590cabdff1aSopenharmony_ci            IVI_INV_SLANT4(src[0], src[4], src[8], src[12],
591cabdff1aSopenharmony_ci                           dst[0], dst[4], dst[8], dst[12],
592cabdff1aSopenharmony_ci                           t0, t1, t2, t3, t4);
593cabdff1aSopenharmony_ci        } else
594cabdff1aSopenharmony_ci            dst[0] = dst[4] = dst[8] = dst[12] = 0;
595cabdff1aSopenharmony_ci
596cabdff1aSopenharmony_ci        src++;
597cabdff1aSopenharmony_ci        dst++;
598cabdff1aSopenharmony_ci    }
599cabdff1aSopenharmony_ci#undef COMPENSATE
600cabdff1aSopenharmony_ci
601cabdff1aSopenharmony_ci#define COMPENSATE(x) (((x) + 1)>>1)
602cabdff1aSopenharmony_ci    src = tmp;
603cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
604cabdff1aSopenharmony_ci        if (!src[0] && !src[1] && !src[2] && !src[3]) {
605cabdff1aSopenharmony_ci            out[0] = out[1] = out[2] = out[3] = 0;
606cabdff1aSopenharmony_ci        } else {
607cabdff1aSopenharmony_ci            IVI_INV_SLANT4(src[0], src[1], src[2], src[3],
608cabdff1aSopenharmony_ci                           out[0], out[1], out[2], out[3],
609cabdff1aSopenharmony_ci                           t0, t1, t2, t3, t4);
610cabdff1aSopenharmony_ci        }
611cabdff1aSopenharmony_ci        src += 4;
612cabdff1aSopenharmony_ci        out += pitch;
613cabdff1aSopenharmony_ci    }
614cabdff1aSopenharmony_ci#undef COMPENSATE
615cabdff1aSopenharmony_ci}
616cabdff1aSopenharmony_ci
617cabdff1aSopenharmony_civoid ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size)
618cabdff1aSopenharmony_ci{
619cabdff1aSopenharmony_ci    int     x, y;
620cabdff1aSopenharmony_ci    int16_t dc_coeff;
621cabdff1aSopenharmony_ci
622cabdff1aSopenharmony_ci    dc_coeff = (*in + 1) >> 1;
623cabdff1aSopenharmony_ci
624cabdff1aSopenharmony_ci    for (y = 0; y < blk_size; out += pitch, y++) {
625cabdff1aSopenharmony_ci        for (x = 0; x < blk_size; x++)
626cabdff1aSopenharmony_ci            out[x] = dc_coeff;
627cabdff1aSopenharmony_ci    }
628cabdff1aSopenharmony_ci}
629cabdff1aSopenharmony_ci
630cabdff1aSopenharmony_civoid ff_ivi_row_slant8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags)
631cabdff1aSopenharmony_ci{
632cabdff1aSopenharmony_ci    int     i;
633cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
634cabdff1aSopenharmony_ci
635cabdff1aSopenharmony_ci#define COMPENSATE(x) (((x) + 1)>>1)
636cabdff1aSopenharmony_ci    for (i = 0; i < 8; i++) {
637cabdff1aSopenharmony_ci        if (!in[0] && !in[1] && !in[2] && !in[3] && !in[4] && !in[5] && !in[6] && !in[7]) {
638cabdff1aSopenharmony_ci            memset(out, 0, 8*sizeof(out[0]));
639cabdff1aSopenharmony_ci        } else {
640cabdff1aSopenharmony_ci            IVI_INV_SLANT8( in[0],  in[1],  in[2],  in[3],  in[4],  in[5],  in[6],  in[7],
641cabdff1aSopenharmony_ci                           out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
642cabdff1aSopenharmony_ci                           t0, t1, t2, t3, t4, t5, t6, t7, t8);
643cabdff1aSopenharmony_ci        }
644cabdff1aSopenharmony_ci        in += 8;
645cabdff1aSopenharmony_ci        out += pitch;
646cabdff1aSopenharmony_ci    }
647cabdff1aSopenharmony_ci#undef COMPENSATE
648cabdff1aSopenharmony_ci}
649cabdff1aSopenharmony_ci
650cabdff1aSopenharmony_civoid ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size)
651cabdff1aSopenharmony_ci{
652cabdff1aSopenharmony_ci    int     x, y;
653cabdff1aSopenharmony_ci    int16_t dc_coeff;
654cabdff1aSopenharmony_ci
655cabdff1aSopenharmony_ci    dc_coeff = (*in + 1) >> 1;
656cabdff1aSopenharmony_ci
657cabdff1aSopenharmony_ci    for (x = 0; x < blk_size; x++)
658cabdff1aSopenharmony_ci        out[x] = dc_coeff;
659cabdff1aSopenharmony_ci
660cabdff1aSopenharmony_ci    out += pitch;
661cabdff1aSopenharmony_ci
662cabdff1aSopenharmony_ci    for (y = 1; y < blk_size; out += pitch, y++) {
663cabdff1aSopenharmony_ci        for (x = 0; x < blk_size; x++)
664cabdff1aSopenharmony_ci            out[x] = 0;
665cabdff1aSopenharmony_ci    }
666cabdff1aSopenharmony_ci}
667cabdff1aSopenharmony_ci
668cabdff1aSopenharmony_civoid ff_ivi_col_slant8(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags)
669cabdff1aSopenharmony_ci{
670cabdff1aSopenharmony_ci    int     i, row2, row4, row8;
671cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
672cabdff1aSopenharmony_ci
673cabdff1aSopenharmony_ci    row2 = pitch << 1;
674cabdff1aSopenharmony_ci    row4 = pitch << 2;
675cabdff1aSopenharmony_ci    row8 = pitch << 3;
676cabdff1aSopenharmony_ci
677cabdff1aSopenharmony_ci#define COMPENSATE(x) (((x) + 1)>>1)
678cabdff1aSopenharmony_ci    for (i = 0; i < 8; i++) {
679cabdff1aSopenharmony_ci        if (flags[i]) {
680cabdff1aSopenharmony_ci            IVI_INV_SLANT8(in[0], in[8], in[16], in[24], in[32], in[40], in[48], in[56],
681cabdff1aSopenharmony_ci                           out[0], out[pitch], out[row2], out[row2 + pitch], out[row4],
682cabdff1aSopenharmony_ci                           out[row4 + pitch],  out[row4 + row2], out[row8 - pitch],
683cabdff1aSopenharmony_ci                           t0, t1, t2, t3, t4, t5, t6, t7, t8);
684cabdff1aSopenharmony_ci        } else {
685cabdff1aSopenharmony_ci            out[0] = out[pitch] = out[row2] = out[row2 + pitch] = out[row4] =
686cabdff1aSopenharmony_ci            out[row4 + pitch] =  out[row4 + row2] = out[row8 - pitch] = 0;
687cabdff1aSopenharmony_ci        }
688cabdff1aSopenharmony_ci
689cabdff1aSopenharmony_ci        in++;
690cabdff1aSopenharmony_ci        out++;
691cabdff1aSopenharmony_ci    }
692cabdff1aSopenharmony_ci#undef COMPENSATE
693cabdff1aSopenharmony_ci}
694cabdff1aSopenharmony_ci
695cabdff1aSopenharmony_civoid ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, ptrdiff_t pitch, int blk_size)
696cabdff1aSopenharmony_ci{
697cabdff1aSopenharmony_ci    int     x, y;
698cabdff1aSopenharmony_ci    int16_t dc_coeff;
699cabdff1aSopenharmony_ci
700cabdff1aSopenharmony_ci    dc_coeff = (*in + 1) >> 1;
701cabdff1aSopenharmony_ci
702cabdff1aSopenharmony_ci    for (y = 0; y < blk_size; out += pitch, y++) {
703cabdff1aSopenharmony_ci        out[0] = dc_coeff;
704cabdff1aSopenharmony_ci        for (x = 1; x < blk_size; x++)
705cabdff1aSopenharmony_ci            out[x] = 0;
706cabdff1aSopenharmony_ci    }
707cabdff1aSopenharmony_ci}
708cabdff1aSopenharmony_ci
709cabdff1aSopenharmony_civoid ff_ivi_row_slant4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags)
710cabdff1aSopenharmony_ci{
711cabdff1aSopenharmony_ci    int     i;
712cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4;
713cabdff1aSopenharmony_ci
714cabdff1aSopenharmony_ci#define COMPENSATE(x) (((x) + 1)>>1)
715cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
716cabdff1aSopenharmony_ci        if (!in[0] && !in[1] && !in[2] && !in[3]) {
717cabdff1aSopenharmony_ci            memset(out, 0, 4*sizeof(out[0]));
718cabdff1aSopenharmony_ci        } else {
719cabdff1aSopenharmony_ci            IVI_INV_SLANT4( in[0],  in[1],  in[2],  in[3],
720cabdff1aSopenharmony_ci                           out[0], out[1], out[2], out[3],
721cabdff1aSopenharmony_ci                           t0, t1, t2, t3, t4);
722cabdff1aSopenharmony_ci        }
723cabdff1aSopenharmony_ci        in  += 4;
724cabdff1aSopenharmony_ci        out += pitch;
725cabdff1aSopenharmony_ci    }
726cabdff1aSopenharmony_ci#undef COMPENSATE
727cabdff1aSopenharmony_ci}
728cabdff1aSopenharmony_ci
729cabdff1aSopenharmony_civoid ff_ivi_col_slant4(const int32_t *in, int16_t *out, ptrdiff_t pitch, const uint8_t *flags)
730cabdff1aSopenharmony_ci{
731cabdff1aSopenharmony_ci    int     i, row2;
732cabdff1aSopenharmony_ci    int     t0, t1, t2, t3, t4;
733cabdff1aSopenharmony_ci
734cabdff1aSopenharmony_ci    row2 = pitch << 1;
735cabdff1aSopenharmony_ci
736cabdff1aSopenharmony_ci#define COMPENSATE(x) (((x) + 1)>>1)
737cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
738cabdff1aSopenharmony_ci        if (flags[i]) {
739cabdff1aSopenharmony_ci            IVI_INV_SLANT4(in[0], in[4], in[8], in[12],
740cabdff1aSopenharmony_ci                           out[0], out[pitch], out[row2], out[row2 + pitch],
741cabdff1aSopenharmony_ci                           t0, t1, t2, t3, t4);
742cabdff1aSopenharmony_ci        } else {
743cabdff1aSopenharmony_ci            out[0] = out[pitch] = out[row2] = out[row2 + pitch] = 0;
744cabdff1aSopenharmony_ci        }
745cabdff1aSopenharmony_ci
746cabdff1aSopenharmony_ci        in++;
747cabdff1aSopenharmony_ci        out++;
748cabdff1aSopenharmony_ci    }
749cabdff1aSopenharmony_ci#undef COMPENSATE
750cabdff1aSopenharmony_ci}
751cabdff1aSopenharmony_ci
752cabdff1aSopenharmony_civoid ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch,
753cabdff1aSopenharmony_ci                           const uint8_t *flags)
754cabdff1aSopenharmony_ci{
755cabdff1aSopenharmony_ci    int     x, y;
756cabdff1aSopenharmony_ci
757cabdff1aSopenharmony_ci    for (y = 0; y < 8; out += pitch, in += 8, y++)
758cabdff1aSopenharmony_ci        for (x = 0; x < 8; x++)
759cabdff1aSopenharmony_ci            out[x] = in[x];
760cabdff1aSopenharmony_ci}
761cabdff1aSopenharmony_ci
762cabdff1aSopenharmony_civoid ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, ptrdiff_t pitch,
763cabdff1aSopenharmony_ci                             int blk_size)
764cabdff1aSopenharmony_ci{
765cabdff1aSopenharmony_ci    int     y;
766cabdff1aSopenharmony_ci
767cabdff1aSopenharmony_ci    out[0] = in[0];
768cabdff1aSopenharmony_ci    memset(out + 1, 0, 7*sizeof(out[0]));
769cabdff1aSopenharmony_ci    out += pitch;
770cabdff1aSopenharmony_ci
771cabdff1aSopenharmony_ci    for (y = 1; y < 8; out += pitch, y++)
772cabdff1aSopenharmony_ci        memset(out, 0, 8*sizeof(out[0]));
773cabdff1aSopenharmony_ci}
774cabdff1aSopenharmony_ci
775cabdff1aSopenharmony_ci#define IVI_MC_TEMPLATE(size, suffix, OP) \
776cabdff1aSopenharmony_cistatic void ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, \
777cabdff1aSopenharmony_ci                                                 ptrdiff_t dpitch, \
778cabdff1aSopenharmony_ci                                                 const int16_t *ref_buf, \
779cabdff1aSopenharmony_ci                                                 ptrdiff_t pitch, int mc_type) \
780cabdff1aSopenharmony_ci{ \
781cabdff1aSopenharmony_ci    int     i, j; \
782cabdff1aSopenharmony_ci    const int16_t *wptr; \
783cabdff1aSopenharmony_ci\
784cabdff1aSopenharmony_ci    switch (mc_type) { \
785cabdff1aSopenharmony_ci    case 0: /* fullpel (no interpolation) */ \
786cabdff1aSopenharmony_ci        for (i = 0; i < size; i++, buf += dpitch, ref_buf += pitch) { \
787cabdff1aSopenharmony_ci            for (j = 0; j < size; j++) {\
788cabdff1aSopenharmony_ci                OP(buf[j], ref_buf[j]); \
789cabdff1aSopenharmony_ci            } \
790cabdff1aSopenharmony_ci        } \
791cabdff1aSopenharmony_ci        break; \
792cabdff1aSopenharmony_ci    case 1: /* horizontal halfpel interpolation */ \
793cabdff1aSopenharmony_ci        for (i = 0; i < size; i++, buf += dpitch, ref_buf += pitch) \
794cabdff1aSopenharmony_ci            for (j = 0; j < size; j++) \
795cabdff1aSopenharmony_ci                OP(buf[j], (ref_buf[j] + ref_buf[j+1]) >> 1); \
796cabdff1aSopenharmony_ci        break; \
797cabdff1aSopenharmony_ci    case 2: /* vertical halfpel interpolation */ \
798cabdff1aSopenharmony_ci        wptr = ref_buf + pitch; \
799cabdff1aSopenharmony_ci        for (i = 0; i < size; i++, buf += dpitch, wptr += pitch, ref_buf += pitch) \
800cabdff1aSopenharmony_ci            for (j = 0; j < size; j++) \
801cabdff1aSopenharmony_ci                OP(buf[j], (ref_buf[j] + wptr[j]) >> 1); \
802cabdff1aSopenharmony_ci        break; \
803cabdff1aSopenharmony_ci    case 3: /* vertical and horizontal halfpel interpolation */ \
804cabdff1aSopenharmony_ci        wptr = ref_buf + pitch; \
805cabdff1aSopenharmony_ci        for (i = 0; i < size; i++, buf += dpitch, wptr += pitch, ref_buf += pitch) \
806cabdff1aSopenharmony_ci            for (j = 0; j < size; j++) \
807cabdff1aSopenharmony_ci                OP(buf[j], (ref_buf[j] + ref_buf[j+1] + wptr[j] + wptr[j+1]) >> 2); \
808cabdff1aSopenharmony_ci        break; \
809cabdff1aSopenharmony_ci    } \
810cabdff1aSopenharmony_ci} \
811cabdff1aSopenharmony_ci\
812cabdff1aSopenharmony_civoid ff_ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, const int16_t *ref_buf, \
813cabdff1aSopenharmony_ci                                             ptrdiff_t pitch, int mc_type) \
814cabdff1aSopenharmony_ci{ \
815cabdff1aSopenharmony_ci    ivi_mc_ ## size ##x## size ## suffix(buf, pitch, ref_buf, pitch, mc_type); \
816cabdff1aSopenharmony_ci} \
817cabdff1aSopenharmony_ci
818cabdff1aSopenharmony_ci#define IVI_MC_AVG_TEMPLATE(size, suffix, OP) \
819cabdff1aSopenharmony_civoid ff_ivi_mc_avg_ ## size ##x## size ## suffix(int16_t *buf, \
820cabdff1aSopenharmony_ci                                                 const int16_t *ref_buf, \
821cabdff1aSopenharmony_ci                                                 const int16_t *ref_buf2, \
822cabdff1aSopenharmony_ci                                                 ptrdiff_t pitch, \
823cabdff1aSopenharmony_ci                                                 int mc_type, int mc_type2) \
824cabdff1aSopenharmony_ci{ \
825cabdff1aSopenharmony_ci    int16_t tmp[size * size]; \
826cabdff1aSopenharmony_ci    int i, j; \
827cabdff1aSopenharmony_ci\
828cabdff1aSopenharmony_ci    ivi_mc_ ## size ##x## size ## _no_delta(tmp, size, ref_buf, pitch, mc_type); \
829cabdff1aSopenharmony_ci    ivi_mc_ ## size ##x## size ## _delta(tmp, size, ref_buf2, pitch, mc_type2); \
830cabdff1aSopenharmony_ci    for (i = 0; i < size; i++, buf += pitch) { \
831cabdff1aSopenharmony_ci        for (j = 0; j < size; j++) {\
832cabdff1aSopenharmony_ci            OP(buf[j], tmp[i * size + j] >> 1); \
833cabdff1aSopenharmony_ci        } \
834cabdff1aSopenharmony_ci    } \
835cabdff1aSopenharmony_ci} \
836cabdff1aSopenharmony_ci
837cabdff1aSopenharmony_ci#define OP_PUT(a, b)  (a) = (b)
838cabdff1aSopenharmony_ci#define OP_ADD(a, b)  (a) += (b)
839cabdff1aSopenharmony_ci
840cabdff1aSopenharmony_ciIVI_MC_TEMPLATE(8, _no_delta, OP_PUT)
841cabdff1aSopenharmony_ciIVI_MC_TEMPLATE(8, _delta,    OP_ADD)
842cabdff1aSopenharmony_ciIVI_MC_TEMPLATE(4, _no_delta, OP_PUT)
843cabdff1aSopenharmony_ciIVI_MC_TEMPLATE(4, _delta,    OP_ADD)
844cabdff1aSopenharmony_ciIVI_MC_AVG_TEMPLATE(8, _no_delta, OP_PUT)
845cabdff1aSopenharmony_ciIVI_MC_AVG_TEMPLATE(8, _delta,    OP_ADD)
846cabdff1aSopenharmony_ciIVI_MC_AVG_TEMPLATE(4, _no_delta, OP_PUT)
847cabdff1aSopenharmony_ciIVI_MC_AVG_TEMPLATE(4, _delta,    OP_ADD)
848