1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "config.h"
20#include "libavutil/attributes.h"
21#include "libavutil/common.h"
22#include "avcodec.h"
23#include "dct.h"
24#include "faanidct.h"
25#include "idctdsp.h"
26#include "simple_idct.h"
27
28av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st,
29                               const uint8_t *src_scantable)
30{
31    int i, end;
32
33    st->scantable = src_scantable;
34
35    for (i = 0; i < 64; i++) {
36        int j = src_scantable[i];
37        st->permutated[i] = permutation[j];
38    }
39
40    end = -1;
41    for (i = 0; i < 64; i++) {
42        int j = st->permutated[i];
43        if (j > end)
44            end = j;
45        st->raster_end[i] = end;
46    }
47}
48
49av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation,
50                                           int idct_permutation_type)
51{
52    int i;
53
54    if (ARCH_X86)
55        if (ff_init_scantable_permutation_x86(idct_permutation,
56                                              idct_permutation_type))
57            return;
58
59    switch (idct_permutation_type) {
60    case FF_NO_IDCT_PERM:
61        for (i = 0; i < 64; i++)
62            idct_permutation[i] = i;
63        break;
64    case FF_LIBMPEG2_IDCT_PERM:
65        for (i = 0; i < 64; i++)
66            idct_permutation[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
67        break;
68    case FF_TRANSPOSE_IDCT_PERM:
69        for (i = 0; i < 64; i++)
70            idct_permutation[i] = ((i & 7) << 3) | (i >> 3);
71        break;
72    case FF_PARTTRANS_IDCT_PERM:
73        for (i = 0; i < 64; i++)
74            idct_permutation[i] = (i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3);
75        break;
76    default:
77        av_log(NULL, AV_LOG_ERROR,
78               "Internal error, IDCT permutation not set\n");
79    }
80}
81
82static void put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
83                                 int line_size)
84{
85    int i;
86
87    /* read the pixels */
88    for (i = 0; i < 8; i++) {
89        pixels[0] = av_clip_uint8(block[0]);
90        pixels[1] = av_clip_uint8(block[1]);
91        pixels[2] = av_clip_uint8(block[2]);
92        pixels[3] = av_clip_uint8(block[3]);
93        pixels[4] = av_clip_uint8(block[4]);
94        pixels[5] = av_clip_uint8(block[5]);
95        pixels[6] = av_clip_uint8(block[6]);
96        pixels[7] = av_clip_uint8(block[7]);
97
98        pixels += line_size;
99        block  += 8;
100    }
101}
102
103static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
104                                 int line_size)
105{
106    int i;
107
108    /* read the pixels */
109    for(i=0;i<4;i++) {
110        pixels[0] = av_clip_uint8(block[0]);
111        pixels[1] = av_clip_uint8(block[1]);
112        pixels[2] = av_clip_uint8(block[2]);
113        pixels[3] = av_clip_uint8(block[3]);
114
115        pixels += line_size;
116        block += 8;
117    }
118}
119
120static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
121                                 int line_size)
122{
123    int i;
124
125    /* read the pixels */
126    for(i=0;i<2;i++) {
127        pixels[0] = av_clip_uint8(block[0]);
128        pixels[1] = av_clip_uint8(block[1]);
129
130        pixels += line_size;
131        block += 8;
132    }
133}
134
135static void put_signed_pixels_clamped_c(const int16_t *block,
136                                        uint8_t *av_restrict pixels,
137                                        int line_size)
138{
139    int i, j;
140
141    for (i = 0; i < 8; i++) {
142        for (j = 0; j < 8; j++) {
143            if (*block < -128)
144                *pixels = 0;
145            else if (*block > 127)
146                *pixels = 255;
147            else
148                *pixels = (uint8_t) (*block + 128);
149            block++;
150            pixels++;
151        }
152        pixels += (line_size - 8);
153    }
154}
155
156static void add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
157                                 int line_size)
158{
159    int i;
160
161    /* read the pixels */
162    for (i = 0; i < 8; i++) {
163        pixels[0] = av_clip_uint8(pixels[0] + block[0]);
164        pixels[1] = av_clip_uint8(pixels[1] + block[1]);
165        pixels[2] = av_clip_uint8(pixels[2] + block[2]);
166        pixels[3] = av_clip_uint8(pixels[3] + block[3]);
167        pixels[4] = av_clip_uint8(pixels[4] + block[4]);
168        pixels[5] = av_clip_uint8(pixels[5] + block[5]);
169        pixels[6] = av_clip_uint8(pixels[6] + block[6]);
170        pixels[7] = av_clip_uint8(pixels[7] + block[7]);
171        pixels   += line_size;
172        block    += 8;
173    }
174}
175
176static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
177                          int line_size)
178{
179    int i;
180
181    /* read the pixels */
182    for(i=0;i<4;i++) {
183        pixels[0] = av_clip_uint8(pixels[0] + block[0]);
184        pixels[1] = av_clip_uint8(pixels[1] + block[1]);
185        pixels[2] = av_clip_uint8(pixels[2] + block[2]);
186        pixels[3] = av_clip_uint8(pixels[3] + block[3]);
187        pixels += line_size;
188        block += 8;
189    }
190}
191
192static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
193                          int line_size)
194{
195    int i;
196
197    /* read the pixels */
198    for(i=0;i<2;i++) {
199        pixels[0] = av_clip_uint8(pixels[0] + block[0]);
200        pixels[1] = av_clip_uint8(pixels[1] + block[1]);
201        pixels += line_size;
202        block += 8;
203    }
204}
205
206static void jref_idct_put(uint8_t *dest, int line_size, int16_t *block)
207{
208    ff_j_rev_dct(block);
209    put_pixels_clamped_c(block, dest, line_size);
210}
211
212static void jref_idct_add(uint8_t *dest, int line_size, int16_t *block)
213{
214    ff_j_rev_dct(block);
215    add_pixels_clamped_c(block, dest, line_size);
216}
217static void ff_jref_idct4_put(uint8_t *dest, int line_size, int16_t *block)
218{
219    ff_j_rev_dct4 (block);
220    put_pixels_clamped4_c(block, dest, line_size);
221}
222static void ff_jref_idct4_add(uint8_t *dest, int line_size, int16_t *block)
223{
224    ff_j_rev_dct4 (block);
225    add_pixels_clamped4_c(block, dest, line_size);
226}
227
228static void ff_jref_idct2_put(uint8_t *dest, int line_size, int16_t *block)
229{
230    ff_j_rev_dct2 (block);
231    put_pixels_clamped2_c(block, dest, line_size);
232}
233static void ff_jref_idct2_add(uint8_t *dest, int line_size, int16_t *block)
234{
235    ff_j_rev_dct2 (block);
236    add_pixels_clamped2_c(block, dest, line_size);
237}
238
239static void ff_jref_idct1_put(uint8_t *dest, int line_size, int16_t *block)
240{
241    dest[0] = av_clip_uint8((block[0] + 4)>>3);
242}
243static void ff_jref_idct1_add(uint8_t *dest, int line_size, int16_t *block)
244{
245    dest[0] = av_clip_uint8(dest[0] + ((block[0] + 4)>>3));
246}
247
248av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
249{
250    const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8;
251
252    if (avctx->lowres==1) {
253        c->idct_put              = ff_jref_idct4_put;
254        c->idct_add              = ff_jref_idct4_add;
255        c->idct                  = ff_j_rev_dct4;
256        c->idct_permutation_type = FF_NO_IDCT_PERM;
257    } else if (avctx->lowres==2) {
258        c->idct_put              =  ff_jref_idct2_put;
259        c->idct_add              =  ff_jref_idct2_add;
260        c->idct                  =  ff_j_rev_dct2;
261        c->idct_permutation_type = FF_NO_IDCT_PERM;
262    } else if (avctx->lowres==3) {
263        c->idct_put              =  ff_jref_idct1_put;
264        c->idct_add              =  ff_jref_idct1_add;
265        c->idct                  =  ff_j_rev_dct1;
266        c->idct_permutation_type = FF_NO_IDCT_PERM;
267    } else {
268        if (avctx->bits_per_raw_sample == 10) {
269            c->idct_put              = ff_simple_idct_put_10;
270            c->idct_add              = ff_simple_idct_add_10;
271            c->idct                  = ff_simple_idct_10;
272            c->idct_permutation_type = FF_NO_IDCT_PERM;
273        } else if (avctx->bits_per_raw_sample == 12) {
274            c->idct_put              = ff_simple_idct_put_12;
275            c->idct_add              = ff_simple_idct_add_12;
276            c->idct                  = ff_simple_idct_12;
277            c->idct_permutation_type = FF_NO_IDCT_PERM;
278        } else {
279        if (avctx->idct_algo == FF_IDCT_INT) {
280            c->idct_put              = jref_idct_put;
281            c->idct_add              = jref_idct_add;
282            c->idct                  = ff_j_rev_dct;
283            c->idct_permutation_type = FF_LIBMPEG2_IDCT_PERM;
284        } else if (avctx->idct_algo == FF_IDCT_FAAN) {
285            c->idct_put              = ff_faanidct_put;
286            c->idct_add              = ff_faanidct_add;
287            c->idct                  = ff_faanidct;
288            c->idct_permutation_type = FF_NO_IDCT_PERM;
289        } else { // accurate/default
290            c->idct_put              = ff_simple_idct_put_8;
291            c->idct_add              = ff_simple_idct_add_8;
292            c->idct                  = ff_simple_idct_8;
293            c->idct_permutation_type = FF_NO_IDCT_PERM;
294        }
295        }
296    }
297
298    c->put_pixels_clamped        = put_pixels_clamped_c;
299    c->put_signed_pixels_clamped = put_signed_pixels_clamped_c;
300    c->add_pixels_clamped        = add_pixels_clamped_c;
301
302    if (ARCH_ALPHA)
303        ff_idctdsp_init_alpha(c, avctx, high_bit_depth);
304    if (ARCH_ARM)
305        ff_idctdsp_init_arm(c, avctx, high_bit_depth);
306    if (ARCH_PPC)
307        ff_idctdsp_init_ppc(c, avctx, high_bit_depth);
308    if (ARCH_X86)
309        ff_idctdsp_init_x86(c, avctx, high_bit_depth);
310
311    ff_init_scantable_permutation(c->idct_permutation,
312                                  c->idct_permutation_type);
313}
314