2 * FFV1 decoder template
4 * Copyright (c) 2003-2016 Michael Niedermayer <michaelni@gmx.at>
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "ffv1_template.c"
25 static av_always_inline
int
26 RENAME(decode_line
)(FFV1Context
*f
, FFV1SliceContext
*sc
,
28 int w
, TYPE
*sample
[2], int plane_index
, int bits
,
31 PlaneContext
*const p
= &sc
->plane
[plane_index
];
32 RangeCoder
*const c
= &sc
->c
;
33 const int16_t (*quant_table
)[256] = f
->quant_tables
[p
->quant_table_index
];
37 int run_index
= sc
->run_index
;
39 if (is_input_end(c
, gb
, ac
))
40 return AVERROR_INVALIDDATA
;
42 if (sc
->slice_coding_mode
== 1) {
44 for (x
= 0; x
< w
; x
++) {
46 for (i
=0; i
<bits
; i
++) {
48 v
+= v
+ get_rac(c
, &state
);
55 for (x
= 0; x
< w
; x
++) {
56 int diff
, context
, sign
;
59 if (is_input_end(c
, gb
, ac
))
60 return AVERROR_INVALIDDATA
;
63 context
= RENAME(get_context
)(quant_table
,
64 sample
[1] + x
, sample
[0] + x
, sample
[1] + x
);
71 av_assert2(context
< p
->context_count
);
73 if (ac
!= AC_GOLOMB_RICE
) {
74 diff
= get_symbol_inline(c
, p
->state
[context
], 1);
76 if (context
== 0 && run_mode
== 0)
80 if (run_count
== 0 && run_mode
== 1) {
82 run_count
= 1 << ff_log2_run
[run_index
];
83 if (x
+ run_count
<= w
)
86 if (ff_log2_run
[run_index
])
87 run_count
= get_bits(gb
, ff_log2_run
[run_index
]);
95 if (sample
[1][x
- 1] == sample
[0][x
- 1]) {
96 while (run_count
> 1 && w
-x
> 1) {
97 sample
[1][x
] = sample
[0][x
];
102 while (run_count
> 1 && w
-x
> 1) {
103 sample
[1][x
] = RENAME(predict
)(sample
[1] + x
, sample
[0] + x
);
112 diff
= get_vlc_symbol(gb
, &p
->vlc_state
[context
],
119 diff
= get_vlc_symbol(gb
, &p
->vlc_state
[context
], bits
);
121 ff_dlog(f
->avctx
, "count:%d index:%d, mode:%d, x:%d pos:%d\n",
122 run_count
, run_index
, run_mode
, x
, get_bits_count(gb
));
126 diff
= -(unsigned)diff
;
128 sample
[1][x
] = av_zero_extend(RENAME(predict
)(sample
[1] + x
, sample
[0] + x
) + (SUINT
)diff
, bits
);
130 sc
->run_index
= run_index
;
134 static int RENAME(decode_rgb_frame
)(FFV1Context
*f
, FFV1SliceContext
*sc
,
136 uint8_t *src
[4], int w
, int h
, int stride
[4])
140 int lbd
= f
->avctx
->bits_per_raw_sample
<= 8;
141 int bits
= f
->avctx
->bits_per_raw_sample
> 0 ? f
->avctx
->bits_per_raw_sample
: 8;
142 int offset
= 1 << bits
;
143 int transparency
= f
->transparency
;
146 if (sc
->slice_coding_mode
== 1)
149 for (x
= 0; x
< 4; x
++) {
150 sample
[x
][0] = RENAME(sc
->sample_buffer
) + x
* 2 * (w
+ 6) + 3;
151 sample
[x
][1] = RENAME(sc
->sample_buffer
) + (x
* 2 + 1) * (w
+ 6) + 3;
156 memset(RENAME(sc
->sample_buffer
), 0, 8 * (w
+ 6) * sizeof(*RENAME(sc
->sample_buffer
)));
158 for (y
= 0; y
< h
; y
++) {
159 for (p
= 0; p
< 3 + transparency
; p
++) {
161 TYPE
*temp
= sample
[p
][0]; // FIXME: try a normal buffer
163 sample
[p
][0] = sample
[p
][1];
166 sample
[p
][1][-1]= sample
[p
][0][0 ];
167 sample
[p
][0][ w
]= sample
[p
][0][w
-1];
168 if (lbd
&& sc
->slice_coding_mode
== 0)
169 ret
= RENAME(decode_line
)(f
, sc
, gb
, w
, sample
[p
], (p
+ 1)/2, 9, ac
);
171 ret
= RENAME(decode_line
)(f
, sc
, gb
, w
, sample
[p
], (p
+ 1)/2, bits
+ (sc
->slice_coding_mode
!= 1), ac
);
175 for (x
= 0; x
< w
; x
++) {
176 int g
= sample
[0][1][x
];
177 int b
= sample
[1][1][x
];
178 int r
= sample
[2][1][x
];
179 int a
= sample
[3][1][x
];
181 if (sc
->slice_coding_mode
!= 1) {
184 g
-= (b
* sc
->slice_rct_by_coef
+ r
* sc
->slice_rct_ry_coef
) >> 2;
190 *((uint32_t*)(src
[0] + x
*4 + stride
[0]*y
)) = b
+ ((unsigned)g
<<8) + ((unsigned)r
<<16) + ((unsigned)a
<<24);
191 else if (sizeof(TYPE
) == 4 || transparency
) {
192 *((uint16_t*)(src
[0] + x
*2 + stride
[0]*y
)) = g
;
193 *((uint16_t*)(src
[1] + x
*2 + stride
[1]*y
)) = b
;
194 *((uint16_t*)(src
[2] + x
*2 + stride
[2]*y
)) = r
;
196 *((uint16_t*)(src
[3] + x
*2 + stride
[3]*y
)) = a
;
198 *((uint16_t*)(src
[0] + x
*2 + stride
[0]*y
)) = b
;
199 *((uint16_t*)(src
[1] + x
*2 + stride
[1]*y
)) = g
;
200 *((uint16_t*)(src
[2] + x
*2 + stride
[2]*y
)) = r
;