1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Apple ProRes compatible decoder
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * Copyright (c) 2010-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#include "config.h"
24cabdff1aSopenharmony_ci#include "libavutil/attributes.h"
25cabdff1aSopenharmony_ci#include "libavutil/common.h"
26cabdff1aSopenharmony_ci#include "idctdsp.h"
27cabdff1aSopenharmony_ci#include "proresdsp.h"
28cabdff1aSopenharmony_ci#include "simple_idct.h"
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_ci#define CLIP_MIN (1 << 2)                     ///< minimum value for clipping resulting pixels
31cabdff1aSopenharmony_ci#define CLIP_MAX_10 (1 << 10) - CLIP_MIN - 1  ///< maximum value for clipping resulting pixels
32cabdff1aSopenharmony_ci#define CLIP_MAX_12 (1 << 12) - CLIP_MIN - 1  ///< maximum value for clipping resulting pixels
33cabdff1aSopenharmony_ci
34cabdff1aSopenharmony_ci#define CLIP_10(x) (av_clip((x), CLIP_MIN, CLIP_MAX_10))
35cabdff1aSopenharmony_ci#define CLIP_12(x) (av_clip((x), CLIP_MIN, CLIP_MAX_12))
36cabdff1aSopenharmony_ci
37cabdff1aSopenharmony_ci/**
38cabdff1aSopenharmony_ci * Add bias value, clamp and output pixels of a slice
39cabdff1aSopenharmony_ci */
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_cistatic inline void put_pixel(uint16_t *dst, ptrdiff_t linesize, const int16_t *in, int bits_per_raw_sample) {
42cabdff1aSopenharmony_ci    int x, y, src_offset, dst_offset;
43cabdff1aSopenharmony_ci
44cabdff1aSopenharmony_ci    for (y = 0, dst_offset = 0; y < 8; y++, dst_offset += linesize) {
45cabdff1aSopenharmony_ci        for (x = 0; x < 8; x++) {
46cabdff1aSopenharmony_ci            src_offset = (y << 3) + x;
47cabdff1aSopenharmony_ci
48cabdff1aSopenharmony_ci            if (bits_per_raw_sample == 10) {
49cabdff1aSopenharmony_ci                dst[dst_offset + x] = CLIP_10(in[src_offset]);
50cabdff1aSopenharmony_ci            } else {//12b
51cabdff1aSopenharmony_ci                dst[dst_offset + x] = CLIP_12(in[src_offset]);
52cabdff1aSopenharmony_ci            }
53cabdff1aSopenharmony_ci        }
54cabdff1aSopenharmony_ci    }
55cabdff1aSopenharmony_ci}
56cabdff1aSopenharmony_ci
57cabdff1aSopenharmony_cistatic void put_pixels_10(uint16_t *dst, ptrdiff_t linesize, const int16_t *in)
58cabdff1aSopenharmony_ci{
59cabdff1aSopenharmony_ci    put_pixel(dst, linesize, in, 10);
60cabdff1aSopenharmony_ci}
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_cistatic void put_pixels_12(uint16_t *dst, ptrdiff_t linesize, const int16_t *in)
63cabdff1aSopenharmony_ci{
64cabdff1aSopenharmony_ci    put_pixel(dst, linesize, in, 12);
65cabdff1aSopenharmony_ci}
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_cistatic void prores_idct_put_10_c(uint16_t *out, ptrdiff_t linesize, int16_t *block, const int16_t *qmat)
68cabdff1aSopenharmony_ci{
69cabdff1aSopenharmony_ci    ff_prores_idct_10(block, qmat);
70cabdff1aSopenharmony_ci    put_pixels_10(out, linesize >> 1, block);
71cabdff1aSopenharmony_ci}
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_cistatic void prores_idct_put_12_c(uint16_t *out, ptrdiff_t linesize, int16_t *block, const int16_t *qmat)
74cabdff1aSopenharmony_ci{
75cabdff1aSopenharmony_ci    ff_prores_idct_12(block, qmat);
76cabdff1aSopenharmony_ci    put_pixels_12(out, linesize >> 1, block);
77cabdff1aSopenharmony_ci}
78cabdff1aSopenharmony_ci
79cabdff1aSopenharmony_ciav_cold int ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx)
80cabdff1aSopenharmony_ci{
81cabdff1aSopenharmony_ci    if (avctx->bits_per_raw_sample == 10) {
82cabdff1aSopenharmony_ci        dsp->idct_put = prores_idct_put_10_c;
83cabdff1aSopenharmony_ci        dsp->idct_permutation_type = FF_IDCT_PERM_NONE;
84cabdff1aSopenharmony_ci    } else if (avctx->bits_per_raw_sample == 12) {
85cabdff1aSopenharmony_ci        dsp->idct_put = prores_idct_put_12_c;
86cabdff1aSopenharmony_ci        dsp->idct_permutation_type = FF_IDCT_PERM_NONE;
87cabdff1aSopenharmony_ci    } else {
88cabdff1aSopenharmony_ci        return AVERROR_BUG;
89cabdff1aSopenharmony_ci    }
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_ci#if ARCH_X86
92cabdff1aSopenharmony_ci    ff_proresdsp_init_x86(dsp, avctx);
93cabdff1aSopenharmony_ci#endif
94cabdff1aSopenharmony_ci
95cabdff1aSopenharmony_ci    ff_init_scantable_permutation(dsp->idct_permutation,
96cabdff1aSopenharmony_ci                                  dsp->idct_permutation_type);
97cabdff1aSopenharmony_ci    return 0;
98cabdff1aSopenharmony_ci}
99