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