GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* |
||
2 |
* Copyright (c) 2015-2016 Kieran Kunhya <kieran@kunhya.com> |
||
3 |
* |
||
4 |
* This file is part of FFmpeg. |
||
5 |
* |
||
6 |
* FFmpeg is free software; you can redistribute it and/or |
||
7 |
* modify it under the terms of the GNU Lesser General Public |
||
8 |
* License as published by the Free Software Foundation; either |
||
9 |
* version 2.1 of the License, or (at your option) any later version. |
||
10 |
* |
||
11 |
* FFmpeg is distributed in the hope that it will be useful, |
||
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
14 |
* Lesser General Public License for more details. |
||
15 |
* |
||
16 |
* You should have received a copy of the GNU Lesser General Public |
||
17 |
* License along with FFmpeg; if not, write to the Free Software |
||
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||
19 |
*/ |
||
20 |
|||
21 |
/** |
||
22 |
* @file |
||
23 |
* Cineform HD video decoder |
||
24 |
*/ |
||
25 |
|||
26 |
#include "libavutil/attributes.h" |
||
27 |
#include "libavutil/buffer.h" |
||
28 |
#include "libavutil/common.h" |
||
29 |
#include "libavutil/imgutils.h" |
||
30 |
#include "libavutil/intreadwrite.h" |
||
31 |
#include "libavutil/opt.h" |
||
32 |
|||
33 |
#include "avcodec.h" |
||
34 |
#include "bytestream.h" |
||
35 |
#include "get_bits.h" |
||
36 |
#include "internal.h" |
||
37 |
#include "thread.h" |
||
38 |
#include "cfhd.h" |
||
39 |
|||
40 |
#define ALPHA_COMPAND_DC_OFFSET 256 |
||
41 |
#define ALPHA_COMPAND_GAIN 9400 |
||
42 |
|||
43 |
6 |
static av_cold int cfhd_init(AVCodecContext *avctx) |
|
44 |
{ |
||
45 |
6 |
CFHDContext *s = avctx->priv_data; |
|
46 |
|||
47 |
6 |
s->avctx = avctx; |
|
48 |
|||
49 |
✓✓ | 390 |
for (int i = 0; i < 64; i++) { |
50 |
384 |
int val = i; |
|
51 |
|||
52 |
✓✓ | 384 |
if (val >= 40) { |
53 |
✓✓ | 144 |
if (val >= 54) { |
54 |
60 |
val -= 54; |
|
55 |
60 |
val <<= 2; |
|
56 |
60 |
val += 54; |
|
57 |
} |
||
58 |
|||
59 |
144 |
val -= 40; |
|
60 |
144 |
val <<= 2; |
|
61 |
144 |
val += 40; |
|
62 |
} |
||
63 |
|||
64 |
384 |
s->lut[0][i] = val; |
|
65 |
} |
||
66 |
|||
67 |
✓✓ | 1542 |
for (int i = 0; i < 256; i++) |
68 |
1536 |
s->lut[1][i] = i + ((768LL * i * i * i) / (256 * 256 * 256)); |
|
69 |
|||
70 |
6 |
return ff_cfhd_init_vlcs(s); |
|
71 |
} |
||
72 |
|||
73 |
99 |
static void init_plane_defaults(CFHDContext *s) |
|
74 |
{ |
||
75 |
99 |
s->subband_num = 0; |
|
76 |
99 |
s->level = 0; |
|
77 |
99 |
s->subband_num_actual = 0; |
|
78 |
99 |
} |
|
79 |
|||
80 |
33 |
static void init_peak_table_defaults(CFHDContext *s) |
|
81 |
{ |
||
82 |
33 |
s->peak.level = 0; |
|
83 |
33 |
s->peak.offset = 0; |
|
84 |
33 |
memset(&s->peak.base, 0, sizeof(s->peak.base)); |
|
85 |
33 |
} |
|
86 |
|||
87 |
33 |
static void init_frame_defaults(CFHDContext *s) |
|
88 |
{ |
||
89 |
33 |
s->coded_width = 0; |
|
90 |
33 |
s->coded_height = 0; |
|
91 |
33 |
s->coded_format = AV_PIX_FMT_YUV422P10; |
|
92 |
33 |
s->cropped_height = 0; |
|
93 |
33 |
s->bpc = 10; |
|
94 |
33 |
s->channel_cnt = 3; |
|
95 |
33 |
s->subband_cnt = SUBBAND_COUNT; |
|
96 |
33 |
s->channel_num = 0; |
|
97 |
33 |
s->lowpass_precision = 16; |
|
98 |
33 |
s->quantisation = 1; |
|
99 |
33 |
s->codebook = 0; |
|
100 |
33 |
s->difference_coding = 0; |
|
101 |
33 |
s->frame_type = 0; |
|
102 |
33 |
s->sample_type = 0; |
|
103 |
✓✗ | 33 |
if (s->transform_type != 2) |
104 |
33 |
s->transform_type = -1; |
|
105 |
33 |
init_plane_defaults(s); |
|
106 |
33 |
init_peak_table_defaults(s); |
|
107 |
33 |
} |
|
108 |
|||
109 |
3522977 |
static inline int dequant_and_decompand(CFHDContext *s, int level, int quantisation, int codebook) |
|
110 |
{ |
||
111 |
✓✗✓✗ |
3522977 |
if (codebook == 0 || codebook == 1) { |
112 |
✓✓ | 3522977 |
return s->lut[codebook][abs(level)] * FFSIGN(level) * quantisation; |
113 |
} else |
||
114 |
return level * quantisation; |
||
115 |
} |
||
116 |
|||
117 |
static inline void difference_coding(int16_t *band, int width, int height) |
||
118 |
{ |
||
119 |
|||
120 |
int i,j; |
||
121 |
for (i = 0; i < height; i++) { |
||
122 |
for (j = 1; j < width; j++) { |
||
123 |
band[j] += band[j-1]; |
||
124 |
} |
||
125 |
band += width; |
||
126 |
} |
||
127 |
} |
||
128 |
|||
129 |
static inline void peak_table(int16_t *band, Peak *peak, int length) |
||
130 |
{ |
||
131 |
int i; |
||
132 |
for (i = 0; i < length; i++) |
||
133 |
if (abs(band[i]) > peak->level) |
||
134 |
band[i] = bytestream2_get_le16(&peak->base); |
||
135 |
} |
||
136 |
|||
137 |
static inline void process_alpha(int16_t *alpha, int width) |
||
138 |
{ |
||
139 |
int i, channel; |
||
140 |
for (i = 0; i < width; i++) { |
||
141 |
channel = alpha[i]; |
||
142 |
channel -= ALPHA_COMPAND_DC_OFFSET; |
||
143 |
channel <<= 3; |
||
144 |
channel *= ALPHA_COMPAND_GAIN; |
||
145 |
channel >>= 16; |
||
146 |
channel = av_clip_uintp2(channel, 12); |
||
147 |
alpha[i] = channel; |
||
148 |
} |
||
149 |
} |
||
150 |
|||
151 |
static inline void process_bayer(AVFrame *frame, int bpc) |
||
152 |
{ |
||
153 |
const int linesize = frame->linesize[0]; |
||
154 |
uint16_t *r = (uint16_t *)frame->data[0]; |
||
155 |
uint16_t *g1 = (uint16_t *)(frame->data[0] + 2); |
||
156 |
uint16_t *g2 = (uint16_t *)(frame->data[0] + frame->linesize[0]); |
||
157 |
uint16_t *b = (uint16_t *)(frame->data[0] + frame->linesize[0] + 2); |
||
158 |
const int mid = 1 << (bpc - 1); |
||
159 |
const int factor = 1 << (16 - bpc); |
||
160 |
|||
161 |
for (int y = 0; y < frame->height >> 1; y++) { |
||
162 |
for (int x = 0; x < frame->width; x += 2) { |
||
163 |
int R, G1, G2, B; |
||
164 |
int g, rg, bg, gd; |
||
165 |
|||
166 |
g = r[x]; |
||
167 |
rg = g1[x]; |
||
168 |
bg = g2[x]; |
||
169 |
gd = b[x]; |
||
170 |
gd -= mid; |
||
171 |
|||
172 |
R = (rg - mid) * 2 + g; |
||
173 |
G1 = g + gd; |
||
174 |
G2 = g - gd; |
||
175 |
B = (bg - mid) * 2 + g; |
||
176 |
|||
177 |
R = av_clip_uintp2(R * factor, 16); |
||
178 |
G1 = av_clip_uintp2(G1 * factor, 16); |
||
179 |
G2 = av_clip_uintp2(G2 * factor, 16); |
||
180 |
B = av_clip_uintp2(B * factor, 16); |
||
181 |
|||
182 |
r[x] = R; |
||
183 |
g1[x] = G1; |
||
184 |
g2[x] = G2; |
||
185 |
b[x] = B; |
||
186 |
} |
||
187 |
|||
188 |
r += linesize; |
||
189 |
g1 += linesize; |
||
190 |
g2 += linesize; |
||
191 |
b += linesize; |
||
192 |
} |
||
193 |
} |
||
194 |
|||
195 |
static inline void interlaced_vertical_filter(int16_t *output, int16_t *low, int16_t *high, |
||
196 |
int width, int linesize, int plane) |
||
197 |
{ |
||
198 |
int i; |
||
199 |
int16_t even, odd; |
||
200 |
for (i = 0; i < width; i++) { |
||
201 |
even = (low[i] - high[i])/2; |
||
202 |
odd = (low[i] + high[i])/2; |
||
203 |
output[i] = av_clip_uintp2(even, 10); |
||
204 |
output[i + linesize] = av_clip_uintp2(odd, 10); |
||
205 |
} |
||
206 |
} |
||
207 |
|||
208 |
static inline void inverse_temporal_filter(int16_t *low, int16_t *high, int width) |
||
209 |
{ |
||
210 |
for (int i = 0; i < width; i++) { |
||
211 |
int even = (low[i] - high[i]) / 2; |
||
212 |
int odd = (low[i] + high[i]) / 2; |
||
213 |
|||
214 |
low[i] = even; |
||
215 |
high[i] = odd; |
||
216 |
} |
||
217 |
} |
||
218 |
|||
219 |
12 |
static void free_buffers(CFHDContext *s) |
|
220 |
{ |
||
221 |
int i, j; |
||
222 |
|||
223 |
✓✓ | 60 |
for (i = 0; i < FF_ARRAY_ELEMS(s->plane); i++) { |
224 |
48 |
Plane *p = &s->plane[i]; |
|
225 |
48 |
av_freep(&s->plane[i].idwt_buf); |
|
226 |
48 |
av_freep(&s->plane[i].idwt_tmp); |
|
227 |
48 |
s->plane[i].idwt_size = 0; |
|
228 |
|||
229 |
✓✓ | 864 |
for (j = 0; j < SUBBAND_COUNT_3D; j++) |
230 |
816 |
s->plane[i].subband[j] = NULL; |
|
231 |
|||
232 |
✓✓ | 528 |
for (j = 0; j < 10; j++) |
233 |
480 |
s->plane[i].l_h[j] = NULL; |
|
234 |
|||
235 |
✓✓ | 336 |
for (j = 0; j < DWT_LEVELS_3D; j++) |
236 |
288 |
p->band[j][0].read_ok = |
|
237 |
288 |
p->band[j][1].read_ok = |
|
238 |
288 |
p->band[j][2].read_ok = |
|
239 |
288 |
p->band[j][3].read_ok = 0; |
|
240 |
} |
||
241 |
12 |
s->a_height = 0; |
|
242 |
12 |
s->a_width = 0; |
|
243 |
12 |
s->a_transform_type = INT_MIN; |
|
244 |
12 |
} |
|
245 |
|||
246 |
6 |
static int alloc_buffers(AVCodecContext *avctx) |
|
247 |
{ |
||
248 |
6 |
CFHDContext *s = avctx->priv_data; |
|
249 |
6 |
int i, j, ret, planes, bayer = 0; |
|
250 |
int chroma_x_shift, chroma_y_shift; |
||
251 |
unsigned k; |
||
252 |
|||
253 |
✗✓ | 6 |
if ((ret = ff_set_dimensions(avctx, s->coded_width, s->coded_height)) < 0) |
254 |
return ret; |
||
255 |
6 |
avctx->pix_fmt = s->coded_format; |
|
256 |
|||
257 |
6 |
ff_cfhddsp_init(&s->dsp, s->bpc, avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16); |
|
258 |
|||
259 |
✗✓ | 6 |
if ((ret = av_pix_fmt_get_chroma_sub_sample(s->coded_format, |
260 |
&chroma_x_shift, |
||
261 |
&chroma_y_shift)) < 0) |
||
262 |
return ret; |
||
263 |
6 |
planes = av_pix_fmt_count_planes(s->coded_format); |
|
264 |
✗✓ | 6 |
if (s->coded_format == AV_PIX_FMT_BAYER_RGGB16) { |
265 |
planes = 4; |
||
266 |
chroma_x_shift = 1; |
||
267 |
chroma_y_shift = 1; |
||
268 |
bayer = 1; |
||
269 |
} |
||
270 |
|||
271 |
✓✓ | 24 |
for (i = 0; i < planes; i++) { |
272 |
int w8, h8, w4, h4, w2, h2; |
||
273 |
✓✓✗✓ |
18 |
int width = (i || bayer) ? s->coded_width >> chroma_x_shift : s->coded_width; |
274 |
✓✓✗✓ |
18 |
int height = (i || bayer) ? s->coded_height >> chroma_y_shift : s->coded_height; |
275 |
18 |
ptrdiff_t stride = (FFALIGN(width / 8, 8) + 64) * 8; |
|
276 |
|||
277 |
✗✓✗✗ |
18 |
if (chroma_y_shift && !bayer) |
278 |
height = FFALIGN(height / 8, 2) * 8; |
||
279 |
18 |
s->plane[i].width = width; |
|
280 |
18 |
s->plane[i].height = height; |
|
281 |
18 |
s->plane[i].stride = stride; |
|
282 |
|||
283 |
18 |
w8 = FFALIGN(s->plane[i].width / 8, 8) + 64; |
|
284 |
18 |
h8 = FFALIGN(height, 8) / 8; |
|
285 |
18 |
w4 = w8 * 2; |
|
286 |
18 |
h4 = h8 * 2; |
|
287 |
18 |
w2 = w4 * 2; |
|
288 |
18 |
h2 = h4 * 2; |
|
289 |
|||
290 |
✓✗ | 18 |
if (s->transform_type == 0) { |
291 |
18 |
s->plane[i].idwt_size = FFALIGN(height, 8) * stride; |
|
292 |
18 |
s->plane[i].idwt_buf = |
|
293 |
18 |
av_mallocz_array(s->plane[i].idwt_size, sizeof(*s->plane[i].idwt_buf)); |
|
294 |
18 |
s->plane[i].idwt_tmp = |
|
295 |
18 |
av_malloc_array(s->plane[i].idwt_size, sizeof(*s->plane[i].idwt_tmp)); |
|
296 |
} else { |
||
297 |
s->plane[i].idwt_size = FFALIGN(height, 8) * stride * 2; |
||
298 |
s->plane[i].idwt_buf = |
||
299 |
av_mallocz_array(s->plane[i].idwt_size, sizeof(*s->plane[i].idwt_buf)); |
||
300 |
s->plane[i].idwt_tmp = |
||
301 |
av_malloc_array(s->plane[i].idwt_size, sizeof(*s->plane[i].idwt_tmp)); |
||
302 |
} |
||
303 |
|||
304 |
✓✗✗✓ |
18 |
if (!s->plane[i].idwt_buf || !s->plane[i].idwt_tmp) |
305 |
return AVERROR(ENOMEM); |
||
306 |
|||
307 |
18 |
s->plane[i].subband[0] = s->plane[i].idwt_buf; |
|
308 |
18 |
s->plane[i].subband[1] = s->plane[i].idwt_buf + 2 * w8 * h8; |
|
309 |
18 |
s->plane[i].subband[2] = s->plane[i].idwt_buf + 1 * w8 * h8; |
|
310 |
18 |
s->plane[i].subband[3] = s->plane[i].idwt_buf + 3 * w8 * h8; |
|
311 |
18 |
s->plane[i].subband[4] = s->plane[i].idwt_buf + 2 * w4 * h4; |
|
312 |
18 |
s->plane[i].subband[5] = s->plane[i].idwt_buf + 1 * w4 * h4; |
|
313 |
18 |
s->plane[i].subband[6] = s->plane[i].idwt_buf + 3 * w4 * h4; |
|
314 |
✓✗ | 18 |
if (s->transform_type == 0) { |
315 |
18 |
s->plane[i].subband[7] = s->plane[i].idwt_buf + 2 * w2 * h2; |
|
316 |
18 |
s->plane[i].subband[8] = s->plane[i].idwt_buf + 1 * w2 * h2; |
|
317 |
18 |
s->plane[i].subband[9] = s->plane[i].idwt_buf + 3 * w2 * h2; |
|
318 |
} else { |
||
319 |
int16_t *frame2 = |
||
320 |
s->plane[i].subband[7] = s->plane[i].idwt_buf + 4 * w2 * h2; |
||
321 |
s->plane[i].subband[8] = frame2 + 2 * w4 * h4; |
||
322 |
s->plane[i].subband[9] = frame2 + 1 * w4 * h4; |
||
323 |
s->plane[i].subband[10] = frame2 + 3 * w4 * h4; |
||
324 |
s->plane[i].subband[11] = frame2 + 2 * w2 * h2; |
||
325 |
s->plane[i].subband[12] = frame2 + 1 * w2 * h2; |
||
326 |
s->plane[i].subband[13] = frame2 + 3 * w2 * h2; |
||
327 |
s->plane[i].subband[14] = s->plane[i].idwt_buf + 2 * w2 * h2; |
||
328 |
s->plane[i].subband[15] = s->plane[i].idwt_buf + 1 * w2 * h2; |
||
329 |
s->plane[i].subband[16] = s->plane[i].idwt_buf + 3 * w2 * h2; |
||
330 |
} |
||
331 |
|||
332 |
✓✗ | 18 |
if (s->transform_type == 0) { |
333 |
✓✓ | 72 |
for (j = 0; j < DWT_LEVELS; j++) { |
334 |
✓✓ | 270 |
for (k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { |
335 |
216 |
s->plane[i].band[j][k].a_width = w8 << j; |
|
336 |
216 |
s->plane[i].band[j][k].a_height = h8 << j; |
|
337 |
} |
||
338 |
} |
||
339 |
} else { |
||
340 |
for (j = 0; j < DWT_LEVELS_3D; j++) { |
||
341 |
int t = j < 1 ? 0 : (j < 3 ? 1 : 2); |
||
342 |
|||
343 |
for (k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { |
||
344 |
s->plane[i].band[j][k].a_width = w8 << t; |
||
345 |
s->plane[i].band[j][k].a_height = h8 << t; |
||
346 |
} |
||
347 |
} |
||
348 |
} |
||
349 |
|||
350 |
/* ll2 and ll1 commented out because they are done in-place */ |
||
351 |
18 |
s->plane[i].l_h[0] = s->plane[i].idwt_tmp; |
|
352 |
18 |
s->plane[i].l_h[1] = s->plane[i].idwt_tmp + 2 * w8 * h8; |
|
353 |
// s->plane[i].l_h[2] = ll2; |
||
354 |
18 |
s->plane[i].l_h[3] = s->plane[i].idwt_tmp; |
|
355 |
18 |
s->plane[i].l_h[4] = s->plane[i].idwt_tmp + 2 * w4 * h4; |
|
356 |
// s->plane[i].l_h[5] = ll1; |
||
357 |
18 |
s->plane[i].l_h[6] = s->plane[i].idwt_tmp; |
|
358 |
18 |
s->plane[i].l_h[7] = s->plane[i].idwt_tmp + 2 * w2 * h2; |
|
359 |
✗✓ | 18 |
if (s->transform_type != 0) { |
360 |
int16_t *frame2 = s->plane[i].idwt_tmp + 4 * w2 * h2; |
||
361 |
|||
362 |
s->plane[i].l_h[8] = frame2; |
||
363 |
s->plane[i].l_h[9] = frame2 + 2 * w2 * h2; |
||
364 |
} |
||
365 |
} |
||
366 |
|||
367 |
6 |
s->a_transform_type = s->transform_type; |
|
368 |
6 |
s->a_height = s->coded_height; |
|
369 |
6 |
s->a_width = s->coded_width; |
|
370 |
6 |
s->a_format = s->coded_format; |
|
371 |
|||
372 |
6 |
return 0; |
|
373 |
} |
||
374 |
|||
375 |
33 |
static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, |
|
376 |
AVPacket *avpkt) |
||
377 |
{ |
||
378 |
33 |
CFHDContext *s = avctx->priv_data; |
|
379 |
33 |
CFHDDSPContext *dsp = &s->dsp; |
|
380 |
GetByteContext gb; |
||
381 |
33 |
ThreadFrame frame = { .f = data }; |
|
382 |
33 |
AVFrame *pic = data; |
|
383 |
33 |
int ret = 0, i, j, plane, got_buffer = 0; |
|
384 |
int16_t *coeff_data; |
||
385 |
|||
386 |
33 |
init_frame_defaults(s); |
|
387 |
33 |
s->planes = av_pix_fmt_count_planes(s->coded_format); |
|
388 |
|||
389 |
33 |
bytestream2_init(&gb, avpkt->data, avpkt->size); |
|
390 |
|||
391 |
✓✓ | 17226 |
while (bytestream2_get_bytes_left(&gb) >= 4) { |
392 |
/* Bit weird but implement the tag parsing as the spec says */ |
||
393 |
17193 |
uint16_t tagu = bytestream2_get_be16(&gb); |
|
394 |
17193 |
int16_t tag = (int16_t)tagu; |
|
395 |
17193 |
int8_t tag8 = (int8_t)(tagu >> 8); |
|
396 |
17193 |
uint16_t abstag = abs(tag); |
|
397 |
17193 |
int8_t abs_tag8 = abs(tag8); |
|
398 |
17193 |
uint16_t data = bytestream2_get_be16(&gb); |
|
399 |
✗✓✗✗ |
17193 |
if (abs_tag8 >= 0x60 && abs_tag8 <= 0x6f) { |
400 |
av_log(avctx, AV_LOG_DEBUG, "large len %x\n", ((tagu & 0xff) << 16) | data); |
||
401 |
✓✓ | 17193 |
} else if (tag == SampleFlags) { |
402 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Progressive? %"PRIu16"\n", data); |
|
403 |
33 |
s->progressive = data & 0x0001; |
|
404 |
✗✓ | 17160 |
} else if (tag == FrameType) { |
405 |
s->frame_type = data; |
||
406 |
av_log(avctx, AV_LOG_DEBUG, "Frame type %"PRIu16"\n", data); |
||
407 |
✗✓ | 17160 |
} else if (abstag == VersionMajor) { |
408 |
av_log(avctx, AV_LOG_DEBUG, "Version major %"PRIu16"\n", data); |
||
409 |
✗✓ | 17160 |
} else if (abstag == VersionMinor) { |
410 |
av_log(avctx, AV_LOG_DEBUG, "Version minor %"PRIu16"\n", data); |
||
411 |
✗✓ | 17160 |
} else if (abstag == VersionRevision) { |
412 |
av_log(avctx, AV_LOG_DEBUG, "Version revision %"PRIu16"\n", data); |
||
413 |
✗✓ | 17160 |
} else if (abstag == VersionEdit) { |
414 |
av_log(avctx, AV_LOG_DEBUG, "Version edit %"PRIu16"\n", data); |
||
415 |
✓✓ | 17160 |
} else if (abstag == Version) { |
416 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Version %"PRIu16"\n", data); |
|
417 |
✓✓ | 17127 |
} else if (tag == ImageWidth) { |
418 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Width %"PRIu16"\n", data); |
|
419 |
33 |
s->coded_width = data; |
|
420 |
✓✓ | 17094 |
} else if (tag == ImageHeight) { |
421 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Height %"PRIu16"\n", data); |
|
422 |
33 |
s->coded_height = data; |
|
423 |
✓✓ | 17061 |
} else if (tag == ChannelCount) { |
424 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Channel Count: %"PRIu16"\n", data); |
|
425 |
33 |
s->channel_cnt = data; |
|
426 |
✗✓ | 33 |
if (data > 4) { |
427 |
av_log(avctx, AV_LOG_ERROR, "Channel Count of %"PRIu16" is unsupported\n", data); |
||
428 |
ret = AVERROR_PATCHWELCOME; |
||
429 |
goto end; |
||
430 |
} |
||
431 |
✓✓ | 17028 |
} else if (tag == SubbandCount) { |
432 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Subband Count: %"PRIu16"\n", data); |
|
433 |
✗✓✗✗ |
33 |
if (data != SUBBAND_COUNT && data != SUBBAND_COUNT_3D) { |
434 |
av_log(avctx, AV_LOG_ERROR, "Subband Count of %"PRIu16" is unsupported\n", data); |
||
435 |
ret = AVERROR_PATCHWELCOME; |
||
436 |
goto end; |
||
437 |
} |
||
438 |
✓✓ | 16995 |
} else if (tag == ChannelNumber) { |
439 |
66 |
s->channel_num = data; |
|
440 |
66 |
av_log(avctx, AV_LOG_DEBUG, "Channel number %"PRIu16"\n", data); |
|
441 |
✗✓ | 66 |
if (s->channel_num >= s->planes) { |
442 |
av_log(avctx, AV_LOG_ERROR, "Invalid channel number\n"); |
||
443 |
ret = AVERROR(EINVAL); |
||
444 |
goto end; |
||
445 |
} |
||
446 |
66 |
init_plane_defaults(s); |
|
447 |
✓✓ | 16929 |
} else if (tag == SubbandNumber) { |
448 |
✓✓✓✓ ✗✓✗✗ |
891 |
if (s->subband_num != 0 && data == 1 && (s->transform_type == 0 || s->transform_type == 2)) // hack |
449 |
198 |
s->level++; |
|
450 |
891 |
av_log(avctx, AV_LOG_DEBUG, "Subband number %"PRIu16"\n", data); |
|
451 |
891 |
s->subband_num = data; |
|
452 |
✓✗✓✗ |
891 |
if ((s->transform_type == 0 && s->level >= DWT_LEVELS) || |
453 |
✗✓✗✗ |
891 |
(s->transform_type == 2 && s->level >= DWT_LEVELS_3D)) { |
454 |
av_log(avctx, AV_LOG_ERROR, "Invalid level\n"); |
||
455 |
ret = AVERROR(EINVAL); |
||
456 |
goto end; |
||
457 |
} |
||
458 |
✗✓ | 891 |
if (s->subband_num > 3) { |
459 |
av_log(avctx, AV_LOG_ERROR, "Invalid subband number\n"); |
||
460 |
ret = AVERROR(EINVAL); |
||
461 |
goto end; |
||
462 |
} |
||
463 |
✓✓ | 16038 |
} else if (tag == SubbandBand) { |
464 |
891 |
av_log(avctx, AV_LOG_DEBUG, "Subband number actual %"PRIu16"\n", data); |
|
465 |
✓✗✓✗ |
891 |
if ((s->transform_type == 0 && data >= SUBBAND_COUNT) || |
466 |
✗✓✗✗ ✗✗ |
891 |
(s->transform_type == 2 && data >= SUBBAND_COUNT_3D && data != 255)) { |
467 |
av_log(avctx, AV_LOG_ERROR, "Invalid subband number actual\n"); |
||
468 |
ret = AVERROR(EINVAL); |
||
469 |
goto end; |
||
470 |
} |
||
471 |
✗✓✗✗ |
891 |
if (s->transform_type == 0 || s->transform_type == 2) |
472 |
891 |
s->subband_num_actual = data; |
|
473 |
else |
||
474 |
av_log(avctx, AV_LOG_WARNING, "Ignoring subband num actual %"PRIu16"\n", data); |
||
475 |
✓✓ | 15147 |
} else if (tag == LowpassPrecision) |
476 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Lowpass precision bits: %"PRIu16"\n", data); |
|
477 |
✓✓ | 15048 |
else if (tag == Quantization) { |
478 |
891 |
s->quantisation = data; |
|
479 |
891 |
av_log(avctx, AV_LOG_DEBUG, "Quantisation: %"PRIu16"\n", data); |
|
480 |
✓✓ | 14157 |
} else if (tag == PrescaleTable) { |
481 |
✓✓ | 99 |
for (i = 0; i < 8; i++) |
482 |
88 |
s->prescale_table[i] = (data >> (14 - i * 2)) & 0x3; |
|
483 |
11 |
av_log(avctx, AV_LOG_DEBUG, "Prescale table: %x\n", data); |
|
484 |
✓✓ | 14146 |
} else if (tag == BandEncoding) { |
485 |
✓✗✗✓ |
891 |
if (!data || data > 5) { |
486 |
av_log(avctx, AV_LOG_ERROR, "Invalid band encoding\n"); |
||
487 |
ret = AVERROR(EINVAL); |
||
488 |
goto end; |
||
489 |
} |
||
490 |
891 |
s->band_encoding = data; |
|
491 |
891 |
av_log(avctx, AV_LOG_DEBUG, "Encode Method for Subband %d : %x\n", s->subband_num_actual, data); |
|
492 |
✓✓ | 13255 |
} else if (tag == LowpassWidth) { |
493 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Lowpass width %"PRIu16"\n", data); |
|
494 |
99 |
s->plane[s->channel_num].band[0][0].width = data; |
|
495 |
99 |
s->plane[s->channel_num].band[0][0].stride = data; |
|
496 |
✓✓ | 13156 |
} else if (tag == LowpassHeight) { |
497 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Lowpass height %"PRIu16"\n", data); |
|
498 |
99 |
s->plane[s->channel_num].band[0][0].height = data; |
|
499 |
✓✓ | 13057 |
} else if (tag == SampleType) { |
500 |
99 |
s->sample_type = data; |
|
501 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Sample type? %"PRIu16"\n", data); |
|
502 |
✓✓ | 12958 |
} else if (tag == TransformType) { |
503 |
✗✓ | 33 |
if (data > 2) { |
504 |
av_log(avctx, AV_LOG_ERROR, "Invalid transform type\n"); |
||
505 |
ret = AVERROR(EINVAL); |
||
506 |
goto end; |
||
507 |
✗✓ | 33 |
} else if (data == 1) { |
508 |
av_log(avctx, AV_LOG_ERROR, "unsupported transform type\n"); |
||
509 |
ret = AVERROR_PATCHWELCOME; |
||
510 |
goto end; |
||
511 |
} |
||
512 |
✓✗ | 33 |
if (s->transform_type == -1) { |
513 |
33 |
s->transform_type = data; |
|
514 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Transform type %"PRIu16"\n", data); |
|
515 |
} else { |
||
516 |
av_log(avctx, AV_LOG_DEBUG, "Ignoring additional transform type %"PRIu16"\n", data); |
||
517 |
} |
||
518 |
✓✓✓✗ |
12925 |
} else if (abstag >= 0x4000 && abstag <= 0x40ff) { |
519 |
✗✓ | 66 |
if (abstag == 0x4001) |
520 |
s->peak.level = 0; |
||
521 |
✓✗ | 66 |
av_log(avctx, AV_LOG_DEBUG, "Small chunk length %d %s\n", data * 4, tag < 0 ? "optional" : "required"); |
522 |
66 |
bytestream2_skipu(&gb, data * 4); |
|
523 |
✗✓ | 12859 |
} else if (tag == FrameIndex) { |
524 |
av_log(avctx, AV_LOG_DEBUG, "Frame index %"PRIu16"\n", data); |
||
525 |
s->frame_index = data; |
||
526 |
✓✓ | 12859 |
} else if (tag == SampleIndexTable) { |
527 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Sample index table - skipping %i values\n", data); |
|
528 |
✗✓ | 33 |
if (data > bytestream2_get_bytes_left(&gb) / 4) { |
529 |
av_log(avctx, AV_LOG_ERROR, "too many values (%d)\n", data); |
||
530 |
ret = AVERROR_INVALIDDATA; |
||
531 |
goto end; |
||
532 |
} |
||
533 |
✓✓ | 132 |
for (i = 0; i < data; i++) { |
534 |
99 |
uint32_t offset = bytestream2_get_be32(&gb); |
|
535 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Offset = %"PRIu32"\n", offset); |
|
536 |
} |
||
537 |
✓✓ | 12826 |
} else if (tag == HighpassWidth) { |
538 |
297 |
av_log(avctx, AV_LOG_DEBUG, "Highpass width %i channel %i level %i subband %i\n", data, s->channel_num, s->level, s->subband_num); |
|
539 |
✗✓ | 297 |
if (data < 3) { |
540 |
av_log(avctx, AV_LOG_ERROR, "Invalid highpass width\n"); |
||
541 |
ret = AVERROR(EINVAL); |
||
542 |
goto end; |
||
543 |
} |
||
544 |
297 |
s->plane[s->channel_num].band[s->level][s->subband_num].width = data; |
|
545 |
297 |
s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8); |
|
546 |
✓✓ | 12529 |
} else if (tag == HighpassHeight) { |
547 |
297 |
av_log(avctx, AV_LOG_DEBUG, "Highpass height %i\n", data); |
|
548 |
✗✓ | 297 |
if (data < 3) { |
549 |
av_log(avctx, AV_LOG_ERROR, "Invalid highpass height\n"); |
||
550 |
ret = AVERROR(EINVAL); |
||
551 |
goto end; |
||
552 |
} |
||
553 |
297 |
s->plane[s->channel_num].band[s->level][s->subband_num].height = data; |
|
554 |
✓✓ | 12232 |
} else if (tag == BandWidth) { |
555 |
891 |
av_log(avctx, AV_LOG_DEBUG, "Highpass width2 %i\n", data); |
|
556 |
✗✓ | 891 |
if (data < 3) { |
557 |
av_log(avctx, AV_LOG_ERROR, "Invalid highpass width2\n"); |
||
558 |
ret = AVERROR(EINVAL); |
||
559 |
goto end; |
||
560 |
} |
||
561 |
891 |
s->plane[s->channel_num].band[s->level][s->subband_num].width = data; |
|
562 |
891 |
s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8); |
|
563 |
✓✓ | 11341 |
} else if (tag == BandHeight) { |
564 |
891 |
av_log(avctx, AV_LOG_DEBUG, "Highpass height2 %i\n", data); |
|
565 |
✗✓ | 891 |
if (data < 3) { |
566 |
av_log(avctx, AV_LOG_ERROR, "Invalid highpass height2\n"); |
||
567 |
ret = AVERROR(EINVAL); |
||
568 |
goto end; |
||
569 |
} |
||
570 |
891 |
s->plane[s->channel_num].band[s->level][s->subband_num].height = data; |
|
571 |
✗✓ | 10450 |
} else if (tag == InputFormat) { |
572 |
av_log(avctx, AV_LOG_DEBUG, "Input format %i\n", data); |
||
573 |
if (s->coded_format == AV_PIX_FMT_NONE || |
||
574 |
s->coded_format == AV_PIX_FMT_YUV422P10) { |
||
575 |
if (data >= 100 && data <= 105) { |
||
576 |
s->coded_format = AV_PIX_FMT_BAYER_RGGB16; |
||
577 |
} else if (data >= 122 && data <= 128) { |
||
578 |
s->coded_format = AV_PIX_FMT_GBRP12; |
||
579 |
} else if (data == 30) { |
||
580 |
s->coded_format = AV_PIX_FMT_GBRAP12; |
||
581 |
} else { |
||
582 |
s->coded_format = AV_PIX_FMT_YUV422P10; |
||
583 |
} |
||
584 |
s->planes = s->coded_format == AV_PIX_FMT_BAYER_RGGB16 ? 4 : av_pix_fmt_count_planes(s->coded_format); |
||
585 |
} |
||
586 |
✓✓ | 10450 |
} else if (tag == BandCodingFlags) { |
587 |
891 |
s->codebook = data & 0xf; |
|
588 |
891 |
s->difference_coding = (data >> 4) & 1; |
|
589 |
891 |
av_log(avctx, AV_LOG_DEBUG, "Other codebook? %i\n", s->codebook); |
|
590 |
✓✓ | 9559 |
} else if (tag == Precision) { |
591 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Precision %i\n", data); |
|
592 |
✓✓✗✓ |
33 |
if (!(data == 10 || data == 12)) { |
593 |
av_log(avctx, AV_LOG_ERROR, "Invalid bits per channel\n"); |
||
594 |
ret = AVERROR(EINVAL); |
||
595 |
goto end; |
||
596 |
} |
||
597 |
33 |
avctx->bits_per_raw_sample = s->bpc = data; |
|
598 |
✓✓ | 9526 |
} else if (tag == EncodedFormat) { |
599 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Sample format? %i\n", data); |
|
600 |
✓✓ | 33 |
if (data == 1) { |
601 |
22 |
s->coded_format = AV_PIX_FMT_YUV422P10; |
|
602 |
✗✓ | 11 |
} else if (data == 2) { |
603 |
s->coded_format = AV_PIX_FMT_BAYER_RGGB16; |
||
604 |
✓✗ | 11 |
} else if (data == 3) { |
605 |
11 |
s->coded_format = AV_PIX_FMT_GBRP12; |
|
606 |
} else if (data == 4) { |
||
607 |
s->coded_format = AV_PIX_FMT_GBRAP12; |
||
608 |
} else { |
||
609 |
avpriv_report_missing_feature(avctx, "Sample format of %"PRIu16, data); |
||
610 |
ret = AVERROR_PATCHWELCOME; |
||
611 |
goto end; |
||
612 |
} |
||
613 |
✓✗ | 33 |
s->planes = data == 2 ? 4 : av_pix_fmt_count_planes(s->coded_format); |
614 |
✓✓ | 9493 |
} else if (tag == -DisplayHeight) { |
615 |
33 |
av_log(avctx, AV_LOG_DEBUG, "Cropped height %"PRIu16"\n", data); |
|
616 |
33 |
s->cropped_height = data; |
|
617 |
✗✓ | 9460 |
} else if (tag == -PeakOffsetLow) { |
618 |
s->peak.offset &= ~0xffff; |
||
619 |
s->peak.offset |= (data & 0xffff); |
||
620 |
s->peak.base = gb; |
||
621 |
s->peak.level = 0; |
||
622 |
✗✓ | 9460 |
} else if (tag == -PeakOffsetHigh) { |
623 |
s->peak.offset &= 0xffff; |
||
624 |
s->peak.offset |= (data & 0xffffU)<<16; |
||
625 |
s->peak.base = gb; |
||
626 |
s->peak.level = 0; |
||
627 |
✗✓✗✗ |
9460 |
} else if (tag == -PeakLevel && s->peak.offset) { |
628 |
s->peak.level = data; |
||
629 |
if (s->peak.offset < 4 - bytestream2_tell(&s->peak.base) || |
||
630 |
s->peak.offset > 4 + bytestream2_get_bytes_left(&s->peak.base) |
||
631 |
) { |
||
632 |
ret = AVERROR_INVALIDDATA; |
||
633 |
goto end; |
||
634 |
} |
||
635 |
bytestream2_seek(&s->peak.base, s->peak.offset - 4, SEEK_CUR); |
||
636 |
} else |
||
637 |
9460 |
av_log(avctx, AV_LOG_DEBUG, "Unknown tag %i data %x\n", tag, data); |
|
638 |
|||
639 |
✓✓✓✓ |
17193 |
if (tag == BitstreamMarker && data == 0xf0f && |
640 |
✓✓ | 99 |
s->coded_format != AV_PIX_FMT_NONE) { |
641 |
33 |
int lowpass_height = s->plane[s->channel_num].band[0][0].height; |
|
642 |
33 |
int lowpass_width = s->plane[s->channel_num].band[0][0].width; |
|
643 |
✗✓ | 33 |
int factor = s->coded_format == AV_PIX_FMT_BAYER_RGGB16 ? 2 : 1; |
644 |
|||
645 |
✓✗ | 33 |
if (s->coded_width) { |
646 |
33 |
s->coded_width *= factor; |
|
647 |
} |
||
648 |
|||
649 |
✓✗ | 33 |
if (s->coded_height) { |
650 |
33 |
s->coded_height *= factor; |
|
651 |
} |
||
652 |
|||
653 |
✓✓✗✓ |
33 |
if (!s->a_width && !s->coded_width) { |
654 |
s->coded_width = lowpass_width * factor * 8; |
||
655 |
} |
||
656 |
|||
657 |
✓✓✗✓ |
33 |
if (!s->a_height && !s->coded_height) { |
658 |
s->coded_height = lowpass_height * factor * 8; |
||
659 |
} |
||
660 |
|||
661 |
✓✓✗✓ |
33 |
if (s->a_width && !s->coded_width) |
662 |
s->coded_width = s->a_width; |
||
663 |
✓✓✗✓ |
33 |
if (s->a_height && !s->coded_height) |
664 |
s->coded_height = s->a_height; |
||
665 |
|||
666 |
✓✓✓✗ |
33 |
if (s->a_width != s->coded_width || s->a_height != s->coded_height || |
667 |
✓✗ | 27 |
s->a_format != s->coded_format || |
668 |
✗✓ | 27 |
s->transform_type != s->a_transform_type) { |
669 |
6 |
free_buffers(s); |
|
670 |
✗✓ | 6 |
if ((ret = alloc_buffers(avctx)) < 0) { |
671 |
free_buffers(s); |
||
672 |
return ret; |
||
673 |
} |
||
674 |
} |
||
675 |
33 |
ret = ff_set_dimensions(avctx, s->coded_width, s->coded_height); |
|
676 |
✗✓ | 33 |
if (ret < 0) |
677 |
return ret; |
||
678 |
✓✗ | 33 |
if (s->cropped_height) { |
679 |
33 |
unsigned height = s->cropped_height << (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16); |
|
680 |
✗✓ | 33 |
if (avctx->height < height) |
681 |
return AVERROR_INVALIDDATA; |
||
682 |
33 |
avctx->height = height; |
|
683 |
} |
||
684 |
33 |
frame.f->width = |
|
685 |
33 |
frame.f->height = 0; |
|
686 |
|||
687 |
✗✓ | 33 |
if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) |
688 |
return ret; |
||
689 |
|||
690 |
33 |
s->coded_width = 0; |
|
691 |
33 |
s->coded_height = 0; |
|
692 |
33 |
s->coded_format = AV_PIX_FMT_NONE; |
|
693 |
33 |
got_buffer = 1; |
|
694 |
✗✓✗✗ ✗✗✗✗ |
17160 |
} else if (tag == FrameIndex && data == 1 && s->sample_type == 1 && s->frame_type == 2) { |
695 |
frame.f->width = |
||
696 |
frame.f->height = 0; |
||
697 |
|||
698 |
if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) |
||
699 |
return ret; |
||
700 |
s->coded_width = 0; |
||
701 |
s->coded_height = 0; |
||
702 |
s->coded_format = AV_PIX_FMT_NONE; |
||
703 |
got_buffer = 1; |
||
704 |
} |
||
705 |
|||
706 |
✗✓ | 17193 |
if (s->subband_num_actual == 255) |
707 |
goto finish; |
||
708 |
17193 |
coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual]; |
|
709 |
|||
710 |
/* Lowpass coefficients */ |
||
711 |
✓✓✓✓ |
17193 |
if (tag == BitstreamMarker && data == 0xf0f) { |
712 |
int lowpass_height, lowpass_width, lowpass_a_height, lowpass_a_width; |
||
713 |
|||
714 |
✓✗✗✓ |
99 |
if (!s->a_width || !s->a_height) { |
715 |
ret = AVERROR_INVALIDDATA; |
||
716 |
goto end; |
||
717 |
} |
||
718 |
|||
719 |
99 |
lowpass_height = s->plane[s->channel_num].band[0][0].height; |
|
720 |
99 |
lowpass_width = s->plane[s->channel_num].band[0][0].width; |
|
721 |
99 |
lowpass_a_height = s->plane[s->channel_num].band[0][0].a_height; |
|
722 |
99 |
lowpass_a_width = s->plane[s->channel_num].band[0][0].a_width; |
|
723 |
|||
724 |
✓✗✗✓ |
99 |
if (lowpass_width < 3 || |
725 |
lowpass_width > lowpass_a_width) { |
||
726 |
av_log(avctx, AV_LOG_ERROR, "Invalid lowpass width\n"); |
||
727 |
ret = AVERROR(EINVAL); |
||
728 |
goto end; |
||
729 |
} |
||
730 |
|||
731 |
✓✗✗✓ |
99 |
if (lowpass_height < 3 || |
732 |
lowpass_height > lowpass_a_height) { |
||
733 |
av_log(avctx, AV_LOG_ERROR, "Invalid lowpass height\n"); |
||
734 |
ret = AVERROR(EINVAL); |
||
735 |
goto end; |
||
736 |
} |
||
737 |
|||
738 |
✗✓ | 99 |
if (!got_buffer) { |
739 |
av_log(avctx, AV_LOG_ERROR, "No end of header tag found\n"); |
||
740 |
ret = AVERROR(EINVAL); |
||
741 |
goto end; |
||
742 |
} |
||
743 |
|||
744 |
✓✗✓✗ |
99 |
if (lowpass_height > lowpass_a_height || lowpass_width > lowpass_a_width || |
745 |
✗✓ | 99 |
lowpass_width * lowpass_height * sizeof(int16_t) > bytestream2_get_bytes_left(&gb)) { |
746 |
av_log(avctx, AV_LOG_ERROR, "Too many lowpass coefficients\n"); |
||
747 |
ret = AVERROR(EINVAL); |
||
748 |
goto end; |
||
749 |
} |
||
750 |
|||
751 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Start of lowpass coeffs component %d height:%d, width:%d\n", s->channel_num, lowpass_height, lowpass_width); |
|
752 |
✓✓ | 5082 |
for (i = 0; i < lowpass_height; i++) { |
753 |
✓✓ | 344267 |
for (j = 0; j < lowpass_width; j++) |
754 |
339284 |
coeff_data[j] = bytestream2_get_be16u(&gb); |
|
755 |
|||
756 |
4983 |
coeff_data += lowpass_width; |
|
757 |
} |
||
758 |
|||
759 |
/* Align to mod-4 position to continue reading tags */ |
||
760 |
99 |
bytestream2_seek(&gb, bytestream2_tell(&gb) & 3, SEEK_CUR); |
|
761 |
|||
762 |
/* Copy last line of coefficients if odd height */ |
||
763 |
✓✓ | 99 |
if (lowpass_height & 1) { |
764 |
33 |
memcpy(&coeff_data[lowpass_height * lowpass_width], |
|
765 |
33 |
&coeff_data[(lowpass_height - 1) * lowpass_width], |
|
766 |
lowpass_width * sizeof(*coeff_data)); |
||
767 |
} |
||
768 |
|||
769 |
99 |
s->plane[s->channel_num].band[0][0].read_ok = 1; |
|
770 |
|||
771 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Lowpass coefficients %d\n", lowpass_width * lowpass_height); |
|
772 |
} |
||
773 |
|||
774 |
✗✓ | 17193 |
av_assert0(s->subband_num_actual != 255); |
775 |
✓✓✗✓ |
17193 |
if (tag == BandHeader || tag == BandSecondPass) { |
776 |
int highpass_height, highpass_width, highpass_a_width, highpass_a_height, highpass_stride, a_expected; |
||
777 |
int expected; |
||
778 |
int level, run, coeff; |
||
779 |
891 |
int count = 0, bytes; |
|
780 |
|||
781 |
✓✗✗✓ |
891 |
if (!s->a_width || !s->a_height) { |
782 |
ret = AVERROR_INVALIDDATA; |
||
783 |
goto end; |
||
784 |
} |
||
785 |
|||
786 |
891 |
highpass_height = s->plane[s->channel_num].band[s->level][s->subband_num].height; |
|
787 |
891 |
highpass_width = s->plane[s->channel_num].band[s->level][s->subband_num].width; |
|
788 |
891 |
highpass_a_width = s->plane[s->channel_num].band[s->level][s->subband_num].a_width; |
|
789 |
891 |
highpass_a_height = s->plane[s->channel_num].band[s->level][s->subband_num].a_height; |
|
790 |
891 |
highpass_stride = s->plane[s->channel_num].band[s->level][s->subband_num].stride; |
|
791 |
891 |
a_expected = highpass_a_height * highpass_a_width; |
|
792 |
|||
793 |
✗✓ | 891 |
if (!got_buffer) { |
794 |
av_log(avctx, AV_LOG_ERROR, "No end of header tag found\n"); |
||
795 |
ret = AVERROR(EINVAL); |
||
796 |
goto end; |
||
797 |
} |
||
798 |
|||
799 |
✓✗✓✗ ✗✓ |
891 |
if (highpass_height > highpass_a_height || highpass_width > highpass_a_width || a_expected < highpass_height * (uint64_t)highpass_stride) { |
800 |
av_log(avctx, AV_LOG_ERROR, "Too many highpass coefficients\n"); |
||
801 |
ret = AVERROR(EINVAL); |
||
802 |
goto end; |
||
803 |
} |
||
804 |
891 |
expected = highpass_height * highpass_stride; |
|
805 |
|||
806 |
891 |
av_log(avctx, AV_LOG_DEBUG, "Start subband coeffs plane %i level %i codebook %i expected %i\n", s->channel_num, s->level, s->codebook, expected); |
|
807 |
|||
808 |
891 |
ret = init_get_bits8(&s->gb, gb.buffer, bytestream2_get_bytes_left(&gb)); |
|
809 |
✗✓ | 891 |
if (ret < 0) |
810 |
goto end; |
||
811 |
{ |
||
812 |
891 |
OPEN_READER(re, &s->gb); |
|
813 |
|||
814 |
891 |
const int lossless = s->band_encoding == 5; |
|
815 |
|||
816 |
✗✓✗✗ ✗✗ |
891 |
if (s->codebook == 0 && s->transform_type == 2 && s->subband_num_actual == 7) |
817 |
s->codebook = 1; |
||
818 |
✗✓ | 891 |
if (!s->codebook) { |
819 |
while (1) { |
||
820 |
UPDATE_CACHE(re, &s->gb); |
||
821 |
GET_RL_VLC(level, run, re, &s->gb, s->table_9_rl_vlc, |
||
822 |
VLC_BITS, 3, 1); |
||
823 |
|||
824 |
/* escape */ |
||
825 |
if (level == 64) |
||
826 |
break; |
||
827 |
|||
828 |
count += run; |
||
829 |
|||
830 |
if (count > expected) |
||
831 |
break; |
||
832 |
|||
833 |
if (!lossless) |
||
834 |
coeff = dequant_and_decompand(s, level, s->quantisation, 0); |
||
835 |
else |
||
836 |
coeff = level; |
||
837 |
if (tag == BandSecondPass) { |
||
838 |
const uint16_t q = s->quantisation; |
||
839 |
|||
840 |
for (i = 0; i < run; i++) { |
||
841 |
*coeff_data |= coeff * 256; |
||
842 |
*coeff_data++ *= q; |
||
843 |
} |
||
844 |
} else { |
||
845 |
for (i = 0; i < run; i++) |
||
846 |
*coeff_data++ = coeff; |
||
847 |
} |
||
848 |
} |
||
849 |
} else { |
||
850 |
while (1) { |
||
851 |
3523868 |
UPDATE_CACHE(re, &s->gb); |
|
852 |
✓✓✓✓ |
3523868 |
GET_RL_VLC(level, run, re, &s->gb, s->table_18_rl_vlc, |
853 |
VLC_BITS, 3, 1); |
||
854 |
|||
855 |
/* escape */ |
||
856 |
✓✓✓✗ |
3523868 |
if (level == 255 && run == 2) |
857 |
891 |
break; |
|
858 |
|||
859 |
3522977 |
count += run; |
|
860 |
|||
861 |
✗✓ | 3522977 |
if (count > expected) |
862 |
break; |
||
863 |
|||
864 |
✓✗ | 3522977 |
if (!lossless) |
865 |
3522977 |
coeff = dequant_and_decompand(s, level, s->quantisation, s->codebook); |
|
866 |
else |
||
867 |
coeff = level; |
||
868 |
✗✓ | 3522977 |
if (tag == BandSecondPass) { |
869 |
const uint16_t q = s->quantisation; |
||
870 |
|||
871 |
for (i = 0; i < run; i++) { |
||
872 |
*coeff_data |= coeff * 256; |
||
873 |
*coeff_data++ *= q; |
||
874 |
} |
||
875 |
} else { |
||
876 |
✓✓ | 25184705 |
for (i = 0; i < run; i++) |
877 |
21661728 |
*coeff_data++ = coeff; |
|
878 |
} |
||
879 |
} |
||
880 |
} |
||
881 |
891 |
CLOSE_READER(re, &s->gb); |
|
882 |
} |
||
883 |
|||
884 |
✗✓ | 891 |
if (count > expected) { |
885 |
av_log(avctx, AV_LOG_ERROR, "Escape codeword not found, probably corrupt data\n"); |
||
886 |
ret = AVERROR(EINVAL); |
||
887 |
goto end; |
||
888 |
} |
||
889 |
✗✓ | 891 |
if (s->peak.level) |
890 |
peak_table(coeff_data - count, &s->peak, count); |
||
891 |
✗✓ | 891 |
if (s->difference_coding) |
892 |
difference_coding(s->plane[s->channel_num].subband[s->subband_num_actual], highpass_width, highpass_height); |
||
893 |
|||
894 |
891 |
bytes = FFALIGN(AV_CEIL_RSHIFT(get_bits_count(&s->gb), 3), 4); |
|
895 |
✗✓ | 891 |
if (bytes > bytestream2_get_bytes_left(&gb)) { |
896 |
av_log(avctx, AV_LOG_ERROR, "Bitstream overread error\n"); |
||
897 |
ret = AVERROR(EINVAL); |
||
898 |
goto end; |
||
899 |
} else |
||
900 |
891 |
bytestream2_seek(&gb, bytes, SEEK_CUR); |
|
901 |
|||
902 |
891 |
av_log(avctx, AV_LOG_DEBUG, "End subband coeffs %i extra %i\n", count, count - expected); |
|
903 |
891 |
s->plane[s->channel_num].band[s->level][s->subband_num].read_ok = 1; |
|
904 |
891 |
finish: |
|
905 |
✓✗ | 891 |
if (s->subband_num_actual != 255) |
906 |
891 |
s->codebook = 0; |
|
907 |
} |
||
908 |
} |
||
909 |
|||
910 |
33 |
s->planes = av_pix_fmt_count_planes(avctx->pix_fmt); |
|
911 |
✗✓ | 33 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { |
912 |
s->progressive = 1; |
||
913 |
s->planes = 4; |
||
914 |
} |
||
915 |
|||
916 |
33 |
ff_thread_finish_setup(avctx); |
|
917 |
|||
918 |
✓✗✓✗ ✓✗ |
33 |
if (!s->a_width || !s->a_height || s->a_format == AV_PIX_FMT_NONE || |
919 |
✓✗ | 33 |
s->a_transform_type == INT_MIN || |
920 |
✓✗✓✗ ✗✓ |
33 |
s->coded_width || s->coded_height || s->coded_format != AV_PIX_FMT_NONE) { |
921 |
av_log(avctx, AV_LOG_ERROR, "Invalid dimensions\n"); |
||
922 |
ret = AVERROR(EINVAL); |
||
923 |
goto end; |
||
924 |
} |
||
925 |
|||
926 |
✗✓ | 33 |
if (!got_buffer) { |
927 |
av_log(avctx, AV_LOG_ERROR, "No end of header tag found\n"); |
||
928 |
ret = AVERROR(EINVAL); |
||
929 |
goto end; |
||
930 |
} |
||
931 |
|||
932 |
✓✓ | 132 |
for (plane = 0; plane < s->planes; plane++) { |
933 |
int o, level; |
||
934 |
|||
935 |
✓✗✓✓ |
396 |
for (level = 0; level < (s->transform_type == 0 ? DWT_LEVELS : DWT_LEVELS_3D) ; level++) { |
936 |
✗✓ | 297 |
if (s->transform_type == 2) |
937 |
if (level == 2 || level == 5) |
||
938 |
continue; |
||
939 |
✓✓ | 1287 |
for (o = !!level; o < 4 ; o++) { |
940 |
✗✓ | 990 |
if (!s->plane[plane].band[level][o].read_ok) { |
941 |
ret = AVERROR_INVALIDDATA; |
||
942 |
goto end; |
||
943 |
} |
||
944 |
} |
||
945 |
} |
||
946 |
} |
||
947 |
|||
948 |
✓✗✓✗ |
33 |
if (s->transform_type == 0 && s->sample_type != 1) { |
949 |
✓✓✓✗ |
132 |
for (plane = 0; plane < s->planes && !ret; plane++) { |
950 |
/* level 1 */ |
||
951 |
99 |
int lowpass_height = s->plane[plane].band[0][0].height; |
|
952 |
99 |
int output_stride = s->plane[plane].band[0][0].a_width; |
|
953 |
99 |
int lowpass_width = s->plane[plane].band[0][0].width; |
|
954 |
99 |
int highpass_stride = s->plane[plane].band[0][1].stride; |
|
955 |
✓✓✓✓ |
99 |
int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane; |
956 |
ptrdiff_t dst_linesize; |
||
957 |
int16_t *low, *high, *output, *dst; |
||
958 |
|||
959 |
✗✓ | 99 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { |
960 |
act_plane = 0; |
||
961 |
dst_linesize = pic->linesize[act_plane]; |
||
962 |
} else { |
||
963 |
99 |
dst_linesize = pic->linesize[act_plane] / 2; |
|
964 |
} |
||
965 |
|||
966 |
✓✗✓✗ ✓✗ |
99 |
if (lowpass_height > s->plane[plane].band[0][0].a_height || lowpass_width > s->plane[plane].band[0][0].a_width || |
967 |
✓✗✓✗ |
99 |
!highpass_stride || s->plane[plane].band[0][1].width > s->plane[plane].band[0][1].a_width || |
968 |
✗✓ | 99 |
lowpass_width < 3 || lowpass_height < 3) { |
969 |
av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); |
||
970 |
ret = AVERROR(EINVAL); |
||
971 |
goto end; |
||
972 |
} |
||
973 |
|||
974 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Decoding level 1 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); |
|
975 |
|||
976 |
99 |
low = s->plane[plane].subband[0]; |
|
977 |
99 |
high = s->plane[plane].subband[2]; |
|
978 |
99 |
output = s->plane[plane].l_h[0]; |
|
979 |
99 |
dsp->vert_filter(output, output_stride, low, lowpass_width, high, highpass_stride, lowpass_width, lowpass_height); |
|
980 |
|||
981 |
99 |
low = s->plane[plane].subband[1]; |
|
982 |
99 |
high = s->plane[plane].subband[3]; |
|
983 |
99 |
output = s->plane[plane].l_h[1]; |
|
984 |
|||
985 |
99 |
dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
|
986 |
|||
987 |
99 |
low = s->plane[plane].l_h[0]; |
|
988 |
99 |
high = s->plane[plane].l_h[1]; |
|
989 |
99 |
output = s->plane[plane].subband[0]; |
|
990 |
99 |
dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); |
|
991 |
✓✓ | 99 |
if (s->bpc == 12) { |
992 |
33 |
output = s->plane[plane].subband[0]; |
|
993 |
✓✓ | 3993 |
for (i = 0; i < lowpass_height * 2; i++) { |
994 |
✓✓ | 716760 |
for (j = 0; j < lowpass_width * 2; j++) |
995 |
712800 |
output[j] *= 4; |
|
996 |
|||
997 |
3960 |
output += output_stride * 2; |
|
998 |
} |
||
999 |
} |
||
1000 |
|||
1001 |
/* level 2 */ |
||
1002 |
99 |
lowpass_height = s->plane[plane].band[1][1].height; |
|
1003 |
99 |
output_stride = s->plane[plane].band[1][1].a_width; |
|
1004 |
99 |
lowpass_width = s->plane[plane].band[1][1].width; |
|
1005 |
99 |
highpass_stride = s->plane[plane].band[1][1].stride; |
|
1006 |
|||
1007 |
✓✗✓✗ ✓✗ |
99 |
if (lowpass_height > s->plane[plane].band[1][1].a_height || lowpass_width > s->plane[plane].band[1][1].a_width || |
1008 |
✓✗✓✗ |
99 |
!highpass_stride || s->plane[plane].band[1][1].width > s->plane[plane].band[1][1].a_width || |
1009 |
✗✓ | 99 |
lowpass_width < 3 || lowpass_height < 3) { |
1010 |
av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); |
||
1011 |
ret = AVERROR(EINVAL); |
||
1012 |
goto end; |
||
1013 |
} |
||
1014 |
|||
1015 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Level 2 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); |
|
1016 |
|||
1017 |
99 |
low = s->plane[plane].subband[0]; |
|
1018 |
99 |
high = s->plane[plane].subband[5]; |
|
1019 |
99 |
output = s->plane[plane].l_h[3]; |
|
1020 |
99 |
dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); |
|
1021 |
|||
1022 |
99 |
low = s->plane[plane].subband[4]; |
|
1023 |
99 |
high = s->plane[plane].subband[6]; |
|
1024 |
99 |
output = s->plane[plane].l_h[4]; |
|
1025 |
99 |
dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
|
1026 |
|||
1027 |
99 |
low = s->plane[plane].l_h[3]; |
|
1028 |
99 |
high = s->plane[plane].l_h[4]; |
|
1029 |
99 |
output = s->plane[plane].subband[0]; |
|
1030 |
99 |
dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); |
|
1031 |
|||
1032 |
99 |
output = s->plane[plane].subband[0]; |
|
1033 |
✓✓ | 20031 |
for (i = 0; i < lowpass_height * 2; i++) { |
1034 |
✓✓ | 5448476 |
for (j = 0; j < lowpass_width * 2; j++) |
1035 |
5428544 |
output[j] *= 4; |
|
1036 |
|||
1037 |
19932 |
output += output_stride * 2; |
|
1038 |
} |
||
1039 |
|||
1040 |
/* level 3 */ |
||
1041 |
99 |
lowpass_height = s->plane[plane].band[2][1].height; |
|
1042 |
99 |
output_stride = s->plane[plane].band[2][1].a_width; |
|
1043 |
99 |
lowpass_width = s->plane[plane].band[2][1].width; |
|
1044 |
99 |
highpass_stride = s->plane[plane].band[2][1].stride; |
|
1045 |
|||
1046 |
✓✗✓✗ ✓✗ |
99 |
if (lowpass_height > s->plane[plane].band[2][1].a_height || lowpass_width > s->plane[plane].band[2][1].a_width || |
1047 |
✓✗✓✗ |
99 |
!highpass_stride || s->plane[plane].band[2][1].width > s->plane[plane].band[2][1].a_width || |
1048 |
✓✗✗✓ |
99 |
lowpass_height < 3 || lowpass_width < 3 || lowpass_width * 2 > s->plane[plane].width) { |
1049 |
av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); |
||
1050 |
ret = AVERROR(EINVAL); |
||
1051 |
goto end; |
||
1052 |
} |
||
1053 |
|||
1054 |
99 |
av_log(avctx, AV_LOG_DEBUG, "Level 3 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); |
|
1055 |
✓✗ | 99 |
if (s->progressive) { |
1056 |
99 |
low = s->plane[plane].subband[0]; |
|
1057 |
99 |
high = s->plane[plane].subband[8]; |
|
1058 |
99 |
output = s->plane[plane].l_h[6]; |
|
1059 |
99 |
dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); |
|
1060 |
|||
1061 |
99 |
low = s->plane[plane].subband[7]; |
|
1062 |
99 |
high = s->plane[plane].subband[9]; |
|
1063 |
99 |
output = s->plane[plane].l_h[7]; |
|
1064 |
99 |
dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
|
1065 |
|||
1066 |
99 |
dst = (int16_t *)pic->data[act_plane]; |
|
1067 |
✗✓ | 99 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { |
1068 |
if (plane & 1) |
||
1069 |
dst++; |
||
1070 |
if (plane > 1) |
||
1071 |
dst += pic->linesize[act_plane] >> 1; |
||
1072 |
} |
||
1073 |
99 |
low = s->plane[plane].l_h[6]; |
|
1074 |
99 |
high = s->plane[plane].l_h[7]; |
|
1075 |
|||
1076 |
✗✓ | 99 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16 && |
1077 |
(lowpass_height * 2 > avctx->coded_height / 2 || |
||
1078 |
lowpass_width * 2 > avctx->coded_width / 2 ) |
||
1079 |
) { |
||
1080 |
ret = AVERROR_INVALIDDATA; |
||
1081 |
goto end; |
||
1082 |
} |
||
1083 |
|||
1084 |
✓✓ | 39963 |
for (i = 0; i < s->plane[act_plane].height; i++) { |
1085 |
39864 |
dsp->horiz_filter_clip(dst, low, high, lowpass_width, s->bpc); |
|
1086 |
✗✓✗✗ |
39864 |
if (avctx->pix_fmt == AV_PIX_FMT_GBRAP12 && act_plane == 3) |
1087 |
process_alpha(dst, lowpass_width * 2); |
||
1088 |
39864 |
low += output_stride; |
|
1089 |
39864 |
high += output_stride; |
|
1090 |
39864 |
dst += dst_linesize; |
|
1091 |
} |
||
1092 |
} else { |
||
1093 |
av_log(avctx, AV_LOG_DEBUG, "interlaced frame ? %d", pic->interlaced_frame); |
||
1094 |
pic->interlaced_frame = 1; |
||
1095 |
low = s->plane[plane].subband[0]; |
||
1096 |
high = s->plane[plane].subband[7]; |
||
1097 |
output = s->plane[plane].l_h[6]; |
||
1098 |
dsp->horiz_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1099 |
|||
1100 |
low = s->plane[plane].subband[8]; |
||
1101 |
high = s->plane[plane].subband[9]; |
||
1102 |
output = s->plane[plane].l_h[7]; |
||
1103 |
dsp->horiz_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1104 |
|||
1105 |
dst = (int16_t *)pic->data[act_plane]; |
||
1106 |
low = s->plane[plane].l_h[6]; |
||
1107 |
high = s->plane[plane].l_h[7]; |
||
1108 |
for (i = 0; i < s->plane[act_plane].height / 2; i++) { |
||
1109 |
interlaced_vertical_filter(dst, low, high, lowpass_width * 2, pic->linesize[act_plane]/2, act_plane); |
||
1110 |
low += output_stride * 2; |
||
1111 |
high += output_stride * 2; |
||
1112 |
dst += pic->linesize[act_plane]; |
||
1113 |
} |
||
1114 |
} |
||
1115 |
} |
||
1116 |
} else if (s->transform_type == 2 && (avctx->internal->is_copy || s->frame_index == 1 || s->sample_type != 1)) { |
||
1117 |
for (plane = 0; plane < s->planes && !ret; plane++) { |
||
1118 |
int lowpass_height = s->plane[plane].band[0][0].height; |
||
1119 |
int output_stride = s->plane[plane].band[0][0].a_width; |
||
1120 |
int lowpass_width = s->plane[plane].band[0][0].width; |
||
1121 |
int highpass_stride = s->plane[plane].band[0][1].stride; |
||
1122 |
int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane; |
||
1123 |
int16_t *low, *high, *output, *dst; |
||
1124 |
ptrdiff_t dst_linesize; |
||
1125 |
|||
1126 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { |
||
1127 |
act_plane = 0; |
||
1128 |
dst_linesize = pic->linesize[act_plane]; |
||
1129 |
} else { |
||
1130 |
dst_linesize = pic->linesize[act_plane] / 2; |
||
1131 |
} |
||
1132 |
|||
1133 |
if (lowpass_height > s->plane[plane].band[0][0].a_height || lowpass_width > s->plane[plane].band[0][0].a_width || |
||
1134 |
!highpass_stride || s->plane[plane].band[0][1].width > s->plane[plane].band[0][1].a_width || |
||
1135 |
lowpass_width < 3 || lowpass_height < 3) { |
||
1136 |
av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); |
||
1137 |
ret = AVERROR(EINVAL); |
||
1138 |
goto end; |
||
1139 |
} |
||
1140 |
|||
1141 |
av_log(avctx, AV_LOG_DEBUG, "Decoding level 1 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); |
||
1142 |
|||
1143 |
low = s->plane[plane].subband[0]; |
||
1144 |
high = s->plane[plane].subband[2]; |
||
1145 |
output = s->plane[plane].l_h[0]; |
||
1146 |
dsp->vert_filter(output, output_stride, low, lowpass_width, high, highpass_stride, lowpass_width, lowpass_height); |
||
1147 |
|||
1148 |
low = s->plane[plane].subband[1]; |
||
1149 |
high = s->plane[plane].subband[3]; |
||
1150 |
output = s->plane[plane].l_h[1]; |
||
1151 |
dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1152 |
|||
1153 |
low = s->plane[plane].l_h[0]; |
||
1154 |
high = s->plane[plane].l_h[1]; |
||
1155 |
output = s->plane[plane].l_h[7]; |
||
1156 |
dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); |
||
1157 |
if (s->bpc == 12) { |
||
1158 |
output = s->plane[plane].l_h[7]; |
||
1159 |
for (i = 0; i < lowpass_height * 2; i++) { |
||
1160 |
for (j = 0; j < lowpass_width * 2; j++) |
||
1161 |
output[j] *= 4; |
||
1162 |
|||
1163 |
output += output_stride * 2; |
||
1164 |
} |
||
1165 |
} |
||
1166 |
|||
1167 |
lowpass_height = s->plane[plane].band[1][1].height; |
||
1168 |
output_stride = s->plane[plane].band[1][1].a_width; |
||
1169 |
lowpass_width = s->plane[plane].band[1][1].width; |
||
1170 |
highpass_stride = s->plane[plane].band[1][1].stride; |
||
1171 |
|||
1172 |
if (lowpass_height > s->plane[plane].band[1][1].a_height || lowpass_width > s->plane[plane].band[1][1].a_width || |
||
1173 |
!highpass_stride || s->plane[plane].band[1][1].width > s->plane[plane].band[1][1].a_width || |
||
1174 |
lowpass_width < 3 || lowpass_height < 3) { |
||
1175 |
av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); |
||
1176 |
ret = AVERROR(EINVAL); |
||
1177 |
goto end; |
||
1178 |
} |
||
1179 |
|||
1180 |
av_log(avctx, AV_LOG_DEBUG, "Level 2 lowpass plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); |
||
1181 |
|||
1182 |
low = s->plane[plane].l_h[7]; |
||
1183 |
high = s->plane[plane].subband[5]; |
||
1184 |
output = s->plane[plane].l_h[3]; |
||
1185 |
dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1186 |
|||
1187 |
low = s->plane[plane].subband[4]; |
||
1188 |
high = s->plane[plane].subband[6]; |
||
1189 |
output = s->plane[plane].l_h[4]; |
||
1190 |
dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1191 |
|||
1192 |
low = s->plane[plane].l_h[3]; |
||
1193 |
high = s->plane[plane].l_h[4]; |
||
1194 |
output = s->plane[plane].l_h[7]; |
||
1195 |
dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); |
||
1196 |
|||
1197 |
output = s->plane[plane].l_h[7]; |
||
1198 |
for (i = 0; i < lowpass_height * 2; i++) { |
||
1199 |
for (j = 0; j < lowpass_width * 2; j++) |
||
1200 |
output[j] *= 4; |
||
1201 |
output += output_stride * 2; |
||
1202 |
} |
||
1203 |
|||
1204 |
low = s->plane[plane].subband[7]; |
||
1205 |
high = s->plane[plane].subband[9]; |
||
1206 |
output = s->plane[plane].l_h[3]; |
||
1207 |
dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1208 |
|||
1209 |
low = s->plane[plane].subband[8]; |
||
1210 |
high = s->plane[plane].subband[10]; |
||
1211 |
output = s->plane[plane].l_h[4]; |
||
1212 |
dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1213 |
|||
1214 |
low = s->plane[plane].l_h[3]; |
||
1215 |
high = s->plane[plane].l_h[4]; |
||
1216 |
output = s->plane[plane].l_h[9]; |
||
1217 |
dsp->horiz_filter(output, output_stride, low, output_stride, high, output_stride, lowpass_width, lowpass_height * 2); |
||
1218 |
|||
1219 |
lowpass_height = s->plane[plane].band[4][1].height; |
||
1220 |
output_stride = s->plane[plane].band[4][1].a_width; |
||
1221 |
lowpass_width = s->plane[plane].band[4][1].width; |
||
1222 |
highpass_stride = s->plane[plane].band[4][1].stride; |
||
1223 |
av_log(avctx, AV_LOG_DEBUG, "temporal level %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride); |
||
1224 |
|||
1225 |
if (lowpass_height > s->plane[plane].band[4][1].a_height || lowpass_width > s->plane[plane].band[4][1].a_width || |
||
1226 |
!highpass_stride || s->plane[plane].band[4][1].width > s->plane[plane].band[4][1].a_width || |
||
1227 |
lowpass_width < 3 || lowpass_height < 3) { |
||
1228 |
av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); |
||
1229 |
ret = AVERROR(EINVAL); |
||
1230 |
goto end; |
||
1231 |
} |
||
1232 |
|||
1233 |
low = s->plane[plane].l_h[7]; |
||
1234 |
high = s->plane[plane].l_h[9]; |
||
1235 |
output = s->plane[plane].l_h[7]; |
||
1236 |
for (i = 0; i < lowpass_height; i++) { |
||
1237 |
inverse_temporal_filter(low, high, lowpass_width); |
||
1238 |
low += output_stride; |
||
1239 |
high += output_stride; |
||
1240 |
} |
||
1241 |
if (s->progressive) { |
||
1242 |
low = s->plane[plane].l_h[7]; |
||
1243 |
high = s->plane[plane].subband[15]; |
||
1244 |
output = s->plane[plane].l_h[6]; |
||
1245 |
dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1246 |
|||
1247 |
low = s->plane[plane].subband[14]; |
||
1248 |
high = s->plane[plane].subband[16]; |
||
1249 |
output = s->plane[plane].l_h[7]; |
||
1250 |
dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1251 |
|||
1252 |
low = s->plane[plane].l_h[9]; |
||
1253 |
high = s->plane[plane].subband[12]; |
||
1254 |
output = s->plane[plane].l_h[8]; |
||
1255 |
dsp->vert_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1256 |
|||
1257 |
low = s->plane[plane].subband[11]; |
||
1258 |
high = s->plane[plane].subband[13]; |
||
1259 |
output = s->plane[plane].l_h[9]; |
||
1260 |
dsp->vert_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1261 |
|||
1262 |
if (s->sample_type == 1) |
||
1263 |
continue; |
||
1264 |
|||
1265 |
dst = (int16_t *)pic->data[act_plane]; |
||
1266 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { |
||
1267 |
if (plane & 1) |
||
1268 |
dst++; |
||
1269 |
if (plane > 1) |
||
1270 |
dst += pic->linesize[act_plane] >> 1; |
||
1271 |
} |
||
1272 |
|||
1273 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16 && |
||
1274 |
(lowpass_height * 2 > avctx->coded_height / 2 || |
||
1275 |
lowpass_width * 2 > avctx->coded_width / 2 ) |
||
1276 |
) { |
||
1277 |
ret = AVERROR_INVALIDDATA; |
||
1278 |
goto end; |
||
1279 |
} |
||
1280 |
|||
1281 |
low = s->plane[plane].l_h[6]; |
||
1282 |
high = s->plane[plane].l_h[7]; |
||
1283 |
for (i = 0; i < s->plane[act_plane].height; i++) { |
||
1284 |
dsp->horiz_filter_clip(dst, low, high, lowpass_width, s->bpc); |
||
1285 |
low += output_stride; |
||
1286 |
high += output_stride; |
||
1287 |
dst += dst_linesize; |
||
1288 |
} |
||
1289 |
} else { |
||
1290 |
pic->interlaced_frame = 1; |
||
1291 |
low = s->plane[plane].l_h[7]; |
||
1292 |
high = s->plane[plane].subband[14]; |
||
1293 |
output = s->plane[plane].l_h[6]; |
||
1294 |
dsp->horiz_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1295 |
|||
1296 |
low = s->plane[plane].subband[15]; |
||
1297 |
high = s->plane[plane].subband[16]; |
||
1298 |
output = s->plane[plane].l_h[7]; |
||
1299 |
dsp->horiz_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1300 |
|||
1301 |
low = s->plane[plane].l_h[9]; |
||
1302 |
high = s->plane[plane].subband[11]; |
||
1303 |
output = s->plane[plane].l_h[8]; |
||
1304 |
dsp->horiz_filter(output, output_stride, low, output_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1305 |
|||
1306 |
low = s->plane[plane].subband[12]; |
||
1307 |
high = s->plane[plane].subband[13]; |
||
1308 |
output = s->plane[plane].l_h[9]; |
||
1309 |
dsp->horiz_filter(output, output_stride, low, highpass_stride, high, highpass_stride, lowpass_width, lowpass_height); |
||
1310 |
|||
1311 |
if (s->sample_type == 1) |
||
1312 |
continue; |
||
1313 |
|||
1314 |
dst = (int16_t *)pic->data[act_plane]; |
||
1315 |
low = s->plane[plane].l_h[6]; |
||
1316 |
high = s->plane[plane].l_h[7]; |
||
1317 |
for (i = 0; i < s->plane[act_plane].height / 2; i++) { |
||
1318 |
interlaced_vertical_filter(dst, low, high, lowpass_width * 2, pic->linesize[act_plane]/2, act_plane); |
||
1319 |
low += output_stride * 2; |
||
1320 |
high += output_stride * 2; |
||
1321 |
dst += pic->linesize[act_plane]; |
||
1322 |
} |
||
1323 |
} |
||
1324 |
} |
||
1325 |
} |
||
1326 |
|||
1327 |
✗✓✗✗ |
33 |
if (s->transform_type == 2 && s->sample_type == 1) { |
1328 |
int16_t *low, *high, *dst; |
||
1329 |
int output_stride, lowpass_height, lowpass_width; |
||
1330 |
ptrdiff_t dst_linesize; |
||
1331 |
|||
1332 |
for (plane = 0; plane < s->planes; plane++) { |
||
1333 |
int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane; |
||
1334 |
|||
1335 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { |
||
1336 |
act_plane = 0; |
||
1337 |
dst_linesize = pic->linesize[act_plane]; |
||
1338 |
} else { |
||
1339 |
dst_linesize = pic->linesize[act_plane] / 2; |
||
1340 |
} |
||
1341 |
|||
1342 |
lowpass_height = s->plane[plane].band[4][1].height; |
||
1343 |
output_stride = s->plane[plane].band[4][1].a_width; |
||
1344 |
lowpass_width = s->plane[plane].band[4][1].width; |
||
1345 |
|||
1346 |
if (lowpass_height > s->plane[plane].band[4][1].a_height || lowpass_width > s->plane[plane].band[4][1].a_width || |
||
1347 |
s->plane[plane].band[4][1].width > s->plane[plane].band[4][1].a_width || |
||
1348 |
lowpass_width < 3 || lowpass_height < 3) { |
||
1349 |
av_log(avctx, AV_LOG_ERROR, "Invalid plane dimensions\n"); |
||
1350 |
ret = AVERROR(EINVAL); |
||
1351 |
goto end; |
||
1352 |
} |
||
1353 |
|||
1354 |
if (s->progressive) { |
||
1355 |
dst = (int16_t *)pic->data[act_plane]; |
||
1356 |
low = s->plane[plane].l_h[8]; |
||
1357 |
high = s->plane[plane].l_h[9]; |
||
1358 |
|||
1359 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) { |
||
1360 |
if (plane & 1) |
||
1361 |
dst++; |
||
1362 |
if (plane > 1) |
||
1363 |
dst += pic->linesize[act_plane] >> 1; |
||
1364 |
} |
||
1365 |
|||
1366 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16 && |
||
1367 |
(lowpass_height * 2 > avctx->coded_height / 2 || |
||
1368 |
lowpass_width * 2 > avctx->coded_width / 2 ) |
||
1369 |
) { |
||
1370 |
ret = AVERROR_INVALIDDATA; |
||
1371 |
goto end; |
||
1372 |
} |
||
1373 |
|||
1374 |
for (i = 0; i < s->plane[act_plane].height; i++) { |
||
1375 |
dsp->horiz_filter_clip(dst, low, high, lowpass_width, s->bpc); |
||
1376 |
low += output_stride; |
||
1377 |
high += output_stride; |
||
1378 |
dst += dst_linesize; |
||
1379 |
} |
||
1380 |
} else { |
||
1381 |
dst = (int16_t *)pic->data[act_plane]; |
||
1382 |
low = s->plane[plane].l_h[8]; |
||
1383 |
high = s->plane[plane].l_h[9]; |
||
1384 |
for (i = 0; i < s->plane[act_plane].height / 2; i++) { |
||
1385 |
interlaced_vertical_filter(dst, low, high, lowpass_width * 2, pic->linesize[act_plane]/2, act_plane); |
||
1386 |
low += output_stride * 2; |
||
1387 |
high += output_stride * 2; |
||
1388 |
dst += pic->linesize[act_plane]; |
||
1389 |
} |
||
1390 |
} |
||
1391 |
} |
||
1392 |
} |
||
1393 |
|||
1394 |
✓✗ | 33 |
if (avctx->pix_fmt == AV_PIX_FMT_BAYER_RGGB16) |
1395 |
process_bayer(pic, s->bpc); |
||
1396 |
33 |
end: |
|
1397 |
✗✓ | 33 |
if (ret < 0) |
1398 |
return ret; |
||
1399 |
|||
1400 |
33 |
*got_frame = 1; |
|
1401 |
33 |
return avpkt->size; |
|
1402 |
} |
||
1403 |
|||
1404 |
6 |
static av_cold int cfhd_close(AVCodecContext *avctx) |
|
1405 |
{ |
||
1406 |
6 |
CFHDContext *s = avctx->priv_data; |
|
1407 |
|||
1408 |
6 |
free_buffers(s); |
|
1409 |
|||
1410 |
6 |
ff_free_vlc(&s->vlc_9); |
|
1411 |
6 |
ff_free_vlc(&s->vlc_18); |
|
1412 |
|||
1413 |
6 |
return 0; |
|
1414 |
} |
||
1415 |
|||
1416 |
#if HAVE_THREADS |
||
1417 |
static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) |
||
1418 |
{ |
||
1419 |
CFHDContext *psrc = src->priv_data; |
||
1420 |
CFHDContext *pdst = dst->priv_data; |
||
1421 |
int ret; |
||
1422 |
|||
1423 |
if (dst == src || psrc->transform_type == 0) |
||
1424 |
return 0; |
||
1425 |
|||
1426 |
if (pdst->plane[0].idwt_size != psrc->plane[0].idwt_size || |
||
1427 |
pdst->a_format != psrc->a_format || |
||
1428 |
pdst->a_width != psrc->a_width || |
||
1429 |
pdst->a_height != psrc->a_height || |
||
1430 |
pdst->a_transform_type != psrc->a_transform_type) |
||
1431 |
free_buffers(pdst); |
||
1432 |
|||
1433 |
pdst->a_format = psrc->a_format; |
||
1434 |
pdst->a_width = psrc->a_width; |
||
1435 |
pdst->a_height = psrc->a_height; |
||
1436 |
pdst->a_transform_type = psrc->a_transform_type; |
||
1437 |
pdst->transform_type = psrc->transform_type; |
||
1438 |
pdst->progressive = psrc->progressive; |
||
1439 |
pdst->planes = psrc->planes; |
||
1440 |
|||
1441 |
if (!pdst->plane[0].idwt_buf) { |
||
1442 |
pdst->coded_width = pdst->a_width; |
||
1443 |
pdst->coded_height = pdst->a_height; |
||
1444 |
pdst->coded_format = pdst->a_format; |
||
1445 |
pdst->transform_type = pdst->a_transform_type; |
||
1446 |
ret = alloc_buffers(dst); |
||
1447 |
if (ret < 0) |
||
1448 |
return ret; |
||
1449 |
} |
||
1450 |
|||
1451 |
for (int plane = 0; plane < pdst->planes; plane++) { |
||
1452 |
memcpy(pdst->plane[plane].band, psrc->plane[plane].band, sizeof(pdst->plane[plane].band)); |
||
1453 |
memcpy(pdst->plane[plane].idwt_buf, psrc->plane[plane].idwt_buf, |
||
1454 |
pdst->plane[plane].idwt_size * sizeof(int16_t)); |
||
1455 |
} |
||
1456 |
|||
1457 |
return 0; |
||
1458 |
} |
||
1459 |
#endif |
||
1460 |
|||
1461 |
AVCodec ff_cfhd_decoder = { |
||
1462 |
.name = "cfhd", |
||
1463 |
.long_name = NULL_IF_CONFIG_SMALL("GoPro CineForm HD"), |
||
1464 |
.type = AVMEDIA_TYPE_VIDEO, |
||
1465 |
.id = AV_CODEC_ID_CFHD, |
||
1466 |
.priv_data_size = sizeof(CFHDContext), |
||
1467 |
.init = cfhd_init, |
||
1468 |
.close = cfhd_close, |
||
1469 |
.decode = cfhd_decode, |
||
1470 |
.update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), |
||
1471 |
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, |
||
1472 |
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, |
||
1473 |
}; |
Generated by: GCOVR (Version 4.2) |