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