| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Panasonic RW2 raw image decoder | ||
| 3 | * Copyright (c) 2026 Lynne <dev@lynne.ee> | ||
| 4 | * | ||
| 5 | * This file is part of FFmpeg. | ||
| 6 | * | ||
| 7 | * FFmpeg is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with FFmpeg; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | /** | ||
| 23 | * @file | ||
| 24 | * Panasonic RW2 decoder, RawFormat 8 only (S1II, S5II, GH6). | ||
| 25 | * Bit-exact with LibRaw's pana8.cpp, quirks included. | ||
| 26 | * | ||
| 27 | * Input is the whole file as one packet. | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include "libavutil/internal.h" | ||
| 31 | #include "libavutil/buffer.h" | ||
| 32 | #include "libavutil/mem.h" | ||
| 33 | #include "libavutil/raw_color_params.h" | ||
| 34 | #include "libavutil/reverse.h" | ||
| 35 | |||
| 36 | #define BITSTREAM_READER_LE | ||
| 37 | #define CACHED_BITSTREAM_READER 1 | ||
| 38 | #include "avcodec.h" | ||
| 39 | #include "bytestream.h" | ||
| 40 | #include "codec_internal.h" | ||
| 41 | #include "decode.h" | ||
| 42 | #include "exif.h" | ||
| 43 | #include "exif_internal.h" | ||
| 44 | #include "get_bits.h" | ||
| 45 | #include "hwaccel_internal.h" | ||
| 46 | #include "thread.h" | ||
| 47 | #include "tiff_common.h" | ||
| 48 | |||
| 49 | #include "rw2.h" | ||
| 50 | |||
| 51 | #define RW2_VLC_BITS 11 | ||
| 52 | #define RW2_JOINT_BITS 16 /* longest code with its magnitude folded in */ | ||
| 53 | #define RW2_SYM_DELTA 0x2000 /* joint symbols: delta + RW2_SYM_DELTA */ | ||
| 54 | #define RW2_SYM_ESC 0x4000 /* other categories: RW2_SYM_ESC + category */ | ||
| 55 | |||
| 56 | ✗ | static av_always_inline int get_delta(const RW2DecContext *s, | |
| 57 | GetBitContext *bc, int *delta) | ||
| 58 | { | ||
| 59 | ✗ | int sym = get_vlc2(bc, s->vlc.table, RW2_VLC_BITS, 2); | |
| 60 | ✗ | if (sym < RW2_SYM_ESC) { | |
| 61 | ✗ | if (sym < 0) | |
| 62 | ✗ | return AVERROR_INVALIDDATA; | |
| 63 | ✗ | *delta = sym - RW2_SYM_DELTA; | |
| 64 | ✗ | return 0; | |
| 65 | } | ||
| 66 | |||
| 67 | /* Escapes read k - shift magnitude bits, MSB-first, the sign leading */ | ||
| 68 | ✗ | int k = sym - RW2_SYM_ESC; | |
| 69 | ✗ | int shift = s->h.c.code_shift[k], extra = k - shift; | |
| 70 | ✗ | int d = 0; | |
| 71 | ✗ | if (extra > 0) { | |
| 72 | ✗ | unsigned v = get_bits(bc, extra); | |
| 73 | ✗ | unsigned m = (ff_reverse[v & 0xFF] << 8 | ff_reverse[v >> 8]) >> (16 - extra); | |
| 74 | ✗ | d = (m << shift) & 0xFFFF; | |
| 75 | ✗ | if (!(v & 1)) | |
| 76 | ✗ | d += !shift - (1 << k); | |
| 77 | ✗ | } else if (k && !show_bits(bc, 1)) { | |
| 78 | /* No magnitude, but LibRaw still tests the next bit for the sign */ | ||
| 79 | ✗ | d = !shift - (1 << k); | |
| 80 | } | ||
| 81 | |||
| 82 | ✗ | *delta = d + (shift ? 1 << (shift - 1) : 0); | |
| 83 | ✗ | return 0; | |
| 84 | } | ||
| 85 | |||
| 86 | ✗ | static int gamma_curve(const RW2Coding *c, uint32_t v) | |
| 87 | { | ||
| 88 | ✗ | int seg = 0; | |
| 89 | ✗ | while (seg < 5 && v >= c->gamma_point[seg + 1]) | |
| 90 | ✗ | seg++; | |
| 91 | |||
| 92 | /* LibRaw only keeps the second half of each 0x3A pair, which makes the | ||
| 93 | * output offset of every segment 0 */ | ||
| 94 | ✗ | uint32_t sh = c->gamma_shift[seg]; | |
| 95 | ✗ | uint32_t r = v - c->gamma_point[seg]; | |
| 96 | ✗ | if ((sh & 0x1F) == 31) | |
| 97 | ✗ | r = seg == 5 ? 0xFFFF : 0; | |
| 98 | ✗ | else if (sh & 0x10) | |
| 99 | ✗ | r <<= sh & 0xF; | |
| 100 | ✗ | else if ((sh & 0x1F) == 15) | |
| 101 | ✗ | r = 0; | |
| 102 | ✗ | else if (sh & 0x1F) | |
| 103 | ✗ | r = (r + (1 << ((sh & 0x1F) - 1))) >> (sh & 0x1F); | |
| 104 | |||
| 105 | ✗ | return FFMIN(r, c->datamax); | |
| 106 | } | ||
| 107 | |||
| 108 | ✗ | static int build_tables(RW2DecContext *s) | |
| 109 | { | ||
| 110 | ✗ | const RW2Coding *c = &s->h.c; | |
| 111 | ✗ | int nb = 0; | |
| 112 | |||
| 113 | /* A code per magnitude where both fit and nothing is shifted, the rest escape */ | ||
| 114 | ✗ | for (int k = 0; k < 17; k++) { | |
| 115 | ✗ | int len = c->code_len[k], code = c->code_val[k]; | |
| 116 | ✗ | if (!len) | |
| 117 | ✗ | continue; | |
| 118 | ✗ | if (c->code_shift[k] || k >= RW2_JOINT_CATS || len + k > RW2_JOINT_BITS) { | |
| 119 | ✗ | s->codes[nb++] = (RW2Code){ len, code, RW2_SYM_ESC + k }; | |
| 120 | ✗ | continue; | |
| 121 | } | ||
| 122 | ✗ | for (int m = 0; m < (1 << k); m++) { | |
| 123 | ✗ | int d = k && !(m >> (k - 1)) ? m + 1 - (1 << k) : m; | |
| 124 | ✗ | s->codes[nb++] = (RW2Code){ len + k, code << k | m, RW2_SYM_DELTA + d }; | |
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | ✗ | ff_vlc_free(&s->vlc); | |
| 129 | ✗ | int ret = ff_vlc_init_sparse(&s->vlc, RW2_VLC_BITS, nb, | |
| 130 | ✗ | &s->codes[0].len, sizeof(*s->codes), 1, | |
| 131 | ✗ | &s->codes[0].code, sizeof(*s->codes), 2, | |
| 132 | ✗ | &s->codes[0].sym, sizeof(*s->codes), 2, | |
| 133 | VLC_INIT_OUTPUT_LE); | ||
| 134 | ✗ | if (ret < 0) | |
| 135 | ✗ | return ret; | |
| 136 | |||
| 137 | /* The gamma LUT, an identity on every file seen so far */ | ||
| 138 | ✗ | s->use_gamma = 0; | |
| 139 | ✗ | for (int i = 0; i <= c->datamax; i++) { | |
| 140 | ✗ | s->gamma[i] = gamma_curve(c, i); | |
| 141 | ✗ | s->use_gamma |= s->gamma[i] != i; | |
| 142 | } | ||
| 143 | |||
| 144 | ✗ | return 0; | |
| 145 | } | ||
| 146 | |||
| 147 | ✗ | static int decode_stripe(AVCodecContext *avctx, void *tdata, | |
| 148 | int jobnr, int threadnr) | ||
| 149 | { | ||
| 150 | ✗ | RW2DecContext *s = avctx->priv_data; | |
| 151 | ✗ | AVFrame *frame = tdata; | |
| 152 | ✗ | const RW2Stripe *st = &s->h.stripes[jobnr]; | |
| 153 | ✗ | const ptrdiff_t stride = frame->linesize[0]; | |
| 154 | ✗ | const uint16_t *gamma = s->use_gamma ? s->gamma : NULL; | |
| 155 | ✗ | const int datamax = s->h.c.datamax; | |
| 156 | int line_base[4], cur[4]; | ||
| 157 | GetBitContext bc; | ||
| 158 | int ret; | ||
| 159 | |||
| 160 | ✗ | ret = init_get_bits(&bc, s->payload + st->offset, st->size_bits); | |
| 161 | ✗ | if (ret < 0) | |
| 162 | ✗ | return ret; | |
| 163 | |||
| 164 | ✗ | for (int i = 0; i < 4; i++) | |
| 165 | ✗ | line_base[i] = s->h.c.initial[i]; | |
| 166 | |||
| 167 | ✗ | for (int y = 0; y < st->height; y += 2) { | |
| 168 | ✗ | uint16_t *dst0 = (uint16_t *)(frame->data[0] + y*stride) + st->left; | |
| 169 | ✗ | uint16_t *dst1 = (uint16_t *)((uint8_t *)dst0 + stride); | |
| 170 | |||
| 171 | /* Each sample predicts from the same position in the previous 2x2 */ | ||
| 172 | ✗ | memcpy(cur, line_base, sizeof(cur)); | |
| 173 | ✗ | for (int x = 0; x < st->width; x += 2) { | |
| 174 | /* Coding order: top-left, bottom-left, top-right, bottom-right */ | ||
| 175 | static const uint8_t slot[4] = { 0, 2, 1, 3 }; | ||
| 176 | ✗ | for (int i = 0; i < 4; i++) { | |
| 177 | ✗ | int delta, j = slot[i]; | |
| 178 | ✗ | if ((ret = get_delta(s, &bc, &delta)) < 0) | |
| 179 | ✗ | return ret; | |
| 180 | ✗ | cur[j] = av_clip(cur[j] + delta, 0, datamax); | |
| 181 | } | ||
| 182 | |||
| 183 | ✗ | if (gamma) { | |
| 184 | ✗ | dst0[x] = gamma[cur[0]]; dst0[x + 1] = gamma[cur[1]]; | |
| 185 | ✗ | dst1[x] = gamma[cur[2]]; dst1[x + 1] = gamma[cur[3]]; | |
| 186 | } else { | ||
| 187 | ✗ | dst0[x] = cur[0]; dst0[x + 1] = cur[1]; | |
| 188 | ✗ | dst1[x] = cur[2]; dst1[x + 1] = cur[3]; | |
| 189 | } | ||
| 190 | |||
| 191 | ✗ | if (!x) | |
| 192 | ✗ | memcpy(line_base, cur, sizeof(line_base)); | |
| 193 | } | ||
| 194 | |||
| 195 | ✗ | if (get_bits_left(&bc) < 0) | |
| 196 | ✗ | return AVERROR_INVALIDDATA; | |
| 197 | } | ||
| 198 | |||
| 199 | ✗ | return 0; | |
| 200 | } | ||
| 201 | |||
| 202 | ✗ | static int read_array_count(GetByteContext *gb, unsigned type, unsigned count, | |
| 203 | unsigned expected, int max) | ||
| 204 | { | ||
| 205 | int n; | ||
| 206 | ✗ | if (type != AV_TIFF_UNDEFINED || count != expected) | |
| 207 | ✗ | return 0; | |
| 208 | ✗ | n = bytestream2_get_le16(gb); | |
| 209 | ✗ | return FFMIN(n, max); | |
| 210 | } | ||
| 211 | |||
| 212 | /* Tag layouts and clamps follow LibRaw */ | ||
| 213 | ✗ | static int parse_header(RW2Header *h, const uint8_t *data, int size) | |
| 214 | { | ||
| 215 | ✗ | RW2Coding *c = &h->c; | |
| 216 | GetByteContext gb; | ||
| 217 | |||
| 218 | ✗ | memset(h, 0, sizeof(*h)); | |
| 219 | |||
| 220 | ✗ | bytestream2_init(&gb, data, size); | |
| 221 | ✗ | if (bytestream2_get_le32(&gb) != MKTAG('I', 'I', 'U', '\0')) | |
| 222 | ✗ | return AVERROR_INVALIDDATA; | |
| 223 | ✗ | int64_t ifd0 = bytestream2_get_le32(&gb); | |
| 224 | ✗ | if (ifd0 < 8 || ifd0 + 2 > size) | |
| 225 | ✗ | return AVERROR_INVALIDDATA; | |
| 226 | ✗ | bytestream2_seek(&gb, ifd0, SEEK_SET); | |
| 227 | |||
| 228 | ✗ | int nb_entries = bytestream2_get_le16(&gb); | |
| 229 | ✗ | if (nb_entries > RW2_MAX_IFD0_ENTRIES || bytestream2_get_bytes_left(&gb) < nb_entries*12) | |
| 230 | ✗ | return AVERROR_INVALIDDATA; | |
| 231 | |||
| 232 | ✗ | int64_t ifd_end = ifd0 + 2 + 12*(int64_t)nb_entries + 4; | |
| 233 | ✗ | h->exif_off = ifd0; | |
| 234 | ✗ | h->exif_end = size; | |
| 235 | |||
| 236 | ✗ | for (int i = 0; i < nb_entries; i++) { | |
| 237 | unsigned tag, type, count, n, v; | ||
| 238 | int next; | ||
| 239 | |||
| 240 | ✗ | if (ff_tread_tag(&gb, 1, &tag, &type, &count, &next) < 0) | |
| 241 | ✗ | goto next; | |
| 242 | |||
| 243 | /* Keep the standard tags verbatim for EXIF in this same walk, leaving | ||
| 244 | * out the Panasonic-private ones and the orientation that is exported | ||
| 245 | * as a display matrix; the previews mark where the metadata ends */ | ||
| 246 | ✗ | const uint8_t *rec = data + ifd0 + 2 + 12*i; | |
| 247 | ✗ | if ((tag == 0x2E || tag == 0x111 || tag == 0x127) && AV_RL32(rec + 8) >= ifd_end) | |
| 248 | ✗ | h->exif_end = FFMIN(h->exif_end, (int64_t)AV_RL32(rec + 8)); | |
| 249 | ✗ | if (tag >= 0x100 && tag != 0x111 && tag != 0x112 && tag != 0x117 && | |
| 250 | ✗ | !(tag >= 0x118 && tag <= 0x127)) { | |
| 251 | ✗ | memcpy(h->exif + h->exif_count*12, rec, 12); | |
| 252 | ✗ | h->exif_count++; | |
| 253 | } | ||
| 254 | |||
| 255 | ✗ | switch (tag) { | |
| 256 | ✗ | case 0x02: h->raw_width = ff_tget(&gb, type, 1); break; | |
| 257 | ✗ | case 0x03: h->raw_height = ff_tget(&gb, type, 1); break; | |
| 258 | ✗ | case 0x04: case 0x05: case 0x06: case 0x07: | |
| 259 | ✗ | h->border[tag - 0x04] = ff_tget(&gb, type, 1); | |
| 260 | ✗ | break; | |
| 261 | ✗ | case 0x09: h->cfa = ff_tget(&gb, type, 1); break; | |
| 262 | ✗ | case 0x0A: h->bpp = ff_tget(&gb, type, 1); break; | |
| 263 | ✗ | case 0x0E: case 0x0F: case 0x10: | |
| 264 | ✗ | h->linearity[tag - 0x0E] = ff_tget(&gb, type, 1); | |
| 265 | ✗ | break; | |
| 266 | ✗ | case 0x1C: case 0x1D: case 0x1E: | |
| 267 | ✗ | h->black[tag - 0x1C] = ff_tget(&gb, type, 1); | |
| 268 | ✗ | break; | |
| 269 | ✗ | case 0x24: case 0x25: case 0x26: | |
| 270 | ✗ | h->wb[tag - 0x24] = ff_tget(&gb, type, 1); | |
| 271 | ✗ | break; | |
| 272 | ✗ | case 0x2D: h->raw_format = ff_tget(&gb, type, 1); break; | |
| 273 | ✗ | case 0x39: | |
| 274 | ✗ | n = read_array_count(&gb, type, count, 26, 6); | |
| 275 | ✗ | for (int j = 0; j < n; j++) | |
| 276 | ✗ | c->gamma_shift[j] = bytestream2_get_le32(&gb); | |
| 277 | ✗ | break; | |
| 278 | ✗ | case 0x3A: | |
| 279 | ✗ | n = read_array_count(&gb, type, count, 26, 6); | |
| 280 | ✗ | for (int j = 0; j < n; j++) { | |
| 281 | ✗ | bytestream2_skip(&gb, 2); | |
| 282 | ✗ | c->gamma_point[j] = bytestream2_get_le16(&gb); | |
| 283 | } | ||
| 284 | ✗ | break; | |
| 285 | ✗ | case 0x3B: c->datamax = ff_tget(&gb, type, 1) & 0xFFFF; break; | |
| 286 | ✗ | case 0x3C: case 0x3D: case 0x3E: case 0x3F: | |
| 287 | ✗ | c->initial[tag - 0x3C] = ff_tget(&gb, type, 1) & 0xFFFF; | |
| 288 | ✗ | break; | |
| 289 | ✗ | case 0x40: | |
| 290 | ✗ | n = read_array_count(&gb, type, count, 70, 17); | |
| 291 | ✗ | for (int k = 0; k < n; k++) { | |
| 292 | ✗ | v = bytestream2_get_le16(&gb); | |
| 293 | ✗ | int len = FFMIN(v, 16); | |
| 294 | ✗ | v = bytestream2_get_le16(&gb); | |
| 295 | ✗ | int code = FFMIN(v, 0xFFF) & ((1 << len) - 1); | |
| 296 | |||
| 297 | /* LibRaw takes the first match, drop the codes it never reaches */ | ||
| 298 | ✗ | for (int j = 0; j < k && len; j++) | |
| 299 | ✗ | if (c->code_len[j] && c->code_len[j] <= len && | |
| 300 | ✗ | code >> (len - c->code_len[j]) == c->code_val[j]) | |
| 301 | ✗ | len = 0; | |
| 302 | ✗ | c->code_len[k] = len; | |
| 303 | ✗ | c->code_val[k] = code; | |
| 304 | } | ||
| 305 | ✗ | break; | |
| 306 | ✗ | case 0x41: | |
| 307 | ✗ | n = read_array_count(&gb, type, count, 36, 17); | |
| 308 | ✗ | for (int j = 0; j < n; j++) { | |
| 309 | ✗ | v = bytestream2_get_le16(&gb); | |
| 310 | ✗ | c->code_shift[j] = FFMIN(v, 64) & 0x1F; | |
| 311 | } | ||
| 312 | ✗ | break; | |
| 313 | ✗ | case 0x42: | |
| 314 | ✗ | v = ff_tget(&gb, type, 1); | |
| 315 | ✗ | h->nb_stripes = FFMIN(v, RW2_MAX_STRIPES); | |
| 316 | ✗ | break; | |
| 317 | ✗ | case 0x44: case 0x45: case 0x46: | |
| 318 | ✗ | n = read_array_count(&gb, type, count, 50, RW2_MAX_STRIPES); | |
| 319 | ✗ | for (int j = 0; j < n; j++) { | |
| 320 | ✗ | v = bytestream2_get_le32(&gb); | |
| 321 | ✗ | if (tag == 0x44) | |
| 322 | ✗ | h->stripes[j].offset = v; | |
| 323 | ✗ | else if (tag == 0x45) | |
| 324 | ✗ | h->stripes[j].left = v; | |
| 325 | else | ||
| 326 | ✗ | h->stripes[j].size_bits = v; | |
| 327 | } | ||
| 328 | ✗ | break; | |
| 329 | ✗ | case 0x47: case 0x48: | |
| 330 | ✗ | n = read_array_count(&gb, type, count, 26, RW2_MAX_STRIPES); | |
| 331 | ✗ | for (int j = 0; j < n; j++) { | |
| 332 | ✗ | v = bytestream2_get_le16(&gb); | |
| 333 | ✗ | if (tag == 0x47) | |
| 334 | ✗ | h->stripes[j].width = v; | |
| 335 | else | ||
| 336 | ✗ | h->stripes[j].height = v; | |
| 337 | } | ||
| 338 | ✗ | break; | |
| 339 | ✗ | case 0x112: h->orientation = ff_tget(&gb, type, 1); break; | |
| 340 | } | ||
| 341 | |||
| 342 | ✗ | next: | |
| 343 | ✗ | bytestream2_seek(&gb, next, SEEK_SET); | |
| 344 | } | ||
| 345 | |||
| 346 | ✗ | return 0; | |
| 347 | } | ||
| 348 | |||
| 349 | ✗ | static int check_stripes(AVCodecContext *avctx, const RW2Header *h, | |
| 350 | int payload_size) | ||
| 351 | { | ||
| 352 | ✗ | uint32_t left = 0; | |
| 353 | |||
| 354 | ✗ | if (h->nb_stripes < 1) | |
| 355 | ✗ | return AVERROR_INVALIDDATA; | |
| 356 | |||
| 357 | /* Stripes must tile the image exactly */ | ||
| 358 | ✗ | for (int i = 0; i < h->nb_stripes; i++) { | |
| 359 | ✗ | const RW2Stripe *st = &h->stripes[i]; | |
| 360 | ✗ | if (st->left != left || st->height != h->raw_height || | |
| 361 | ✗ | !st->width || (st->width & 1) || st->width > h->raw_width - left || | |
| 362 | ✗ | !st->size_bits || st->size_bits > INT_MAX - 7 || | |
| 363 | ✗ | st->offset > payload_size || | |
| 364 | ✗ | (st->size_bits + 7) >> 3 > payload_size - st->offset) { | |
| 365 | ✗ | av_log(avctx, AV_LOG_ERROR, "Invalid stripe %d\n", i); | |
| 366 | ✗ | return AVERROR_INVALIDDATA; | |
| 367 | } | ||
| 368 | ✗ | left += st->width; | |
| 369 | } | ||
| 370 | |||
| 371 | ✗ | if (left != h->raw_width) | |
| 372 | ✗ | return AVERROR_INVALIDDATA; | |
| 373 | |||
| 374 | ✗ | return 0; | |
| 375 | } | ||
| 376 | |||
| 377 | ✗ | static enum AVPixelFormat get_pixel_format(AVCodecContext *avctx, | |
| 378 | enum AVPixelFormat pix_fmt) | ||
| 379 | { | ||
| 380 | ✗ | enum AVPixelFormat pix_fmts[] = { | |
| 381 | pix_fmt, | ||
| 382 | AV_PIX_FMT_NONE, | ||
| 383 | }; | ||
| 384 | |||
| 385 | ✗ | return ff_get_format(avctx, pix_fmts); | |
| 386 | } | ||
| 387 | |||
| 388 | /* The TIFF and EXIF tags of the file. Panasonic's own tags, below 0x100 and | ||
| 389 | * at 0x118 - 0x127, hold the raw parameters exported as side data and the | ||
| 390 | * previews; the strips point into the file. */ | ||
| 391 | ✗ | static int export_exif(AVCodecContext *avctx, AVFrame *frame, | |
| 392 | const uint8_t *data, int size) | ||
| 393 | { | ||
| 394 | ✗ | const RW2Header *h = &((RW2DecContext *)avctx->priv_data)->h; | |
| 395 | ✗ | int64_t off = h->exif_off, keep = FFMIN(h->exif_end, size); | |
| 396 | |||
| 397 | ✗ | if (!h->exif_count || off + 2 + (int64_t)h->exif_count*12 + 4 > keep) | |
| 398 | ✗ | return 0; | |
| 399 | |||
| 400 | /* The metadata precedes the embedded previews, so attach it whole, pointing | ||
| 401 | * IFD0 at the standard tags gathered during the header walk */ | ||
| 402 | ✗ | uint8_t *buf = av_memdup(data, keep); | |
| 403 | ✗ | if (!buf) | |
| 404 | ✗ | return AVERROR(ENOMEM); | |
| 405 | |||
| 406 | ✗ | AV_WL16(buf + 2, 42); /* "IIU\0" -> TIFF */ | |
| 407 | ✗ | AV_WL16(buf + off, h->exif_count); | |
| 408 | ✗ | memcpy(buf + off + 2, h->exif, h->exif_count * 12); | |
| 409 | ✗ | AV_WL32(buf + off + 2 + h->exif_count*12, 0); /* no next IFD */ | |
| 410 | |||
| 411 | ✗ | AVBufferRef *bref = av_buffer_create(buf, keep, NULL, NULL, 0); | |
| 412 | ✗ | if (!bref) { | |
| 413 | ✗ | av_free(buf); | |
| 414 | ✗ | return AVERROR(ENOMEM); | |
| 415 | } | ||
| 416 | |||
| 417 | ✗ | return ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_EXIF, &bref); | |
| 418 | } | ||
| 419 | |||
| 420 | ✗ | static int export_metadata(AVCodecContext *avctx, AVFrame *frame, | |
| 421 | const uint8_t *hdr, int hdr_size) | ||
| 422 | { | ||
| 423 | ✗ | RW2DecContext *s = avctx->priv_data; | |
| 424 | ✗ | const RW2Header *h = &s->h; | |
| 425 | int ret; | ||
| 426 | |||
| 427 | /* Even crops keep the CFA phase */ | ||
| 428 | ✗ | if (h->border[0] >= 0 && h->border[1] >= 0 && | |
| 429 | ✗ | h->border[0] < h->border[2] && h->border[2] <= h->raw_height && | |
| 430 | ✗ | h->border[1] < h->border[3] && h->border[3] <= h->raw_width) { | |
| 431 | ✗ | frame->crop_top = h->border[0] & ~1; | |
| 432 | ✗ | frame->crop_left = h->border[1] & ~1; | |
| 433 | ✗ | frame->crop_bottom = (h->raw_height - h->border[2]) & ~1; | |
| 434 | ✗ | frame->crop_right = (h->raw_width - h->border[3]) & ~1; | |
| 435 | } | ||
| 436 | |||
| 437 | ✗ | if (h->orientation > 1 && h->orientation <= 8) { | |
| 438 | AVFrameSideData *sd; | ||
| 439 | ✗ | ret = ff_frame_new_side_data(avctx, frame, AV_FRAME_DATA_DISPLAYMATRIX, | |
| 440 | sizeof(int32_t) * 9, &sd); | ||
| 441 | ✗ | if (ret < 0) | |
| 442 | ✗ | return ret; | |
| 443 | ✗ | if (sd) | |
| 444 | ✗ | av_exif_orientation_to_matrix((int32_t *)sd->data, h->orientation); | |
| 445 | } | ||
| 446 | |||
| 447 | /* Per-channel black levels are not representable, use green's */ | ||
| 448 | ✗ | int white = FFMAX3(h->linearity[0], h->linearity[1], h->linearity[2]); | |
| 449 | ✗ | if (!white) | |
| 450 | ✗ | white = (1 << h->bpp) - 1; | |
| 451 | |||
| 452 | ✗ | AVRawColorParams *rcp = av_raw_color_params_create_side_data(frame); | |
| 453 | ✗ | if (!rcp) | |
| 454 | ✗ | return AVERROR(ENOMEM); | |
| 455 | ✗ | rcp->black_level = av_make_q(h->black[1], 65535); | |
| 456 | ✗ | rcp->white_level = av_make_q(white, 65535); | |
| 457 | |||
| 458 | ✗ | if (h->wb[1]) { | |
| 459 | ✗ | rcp->type = AV_RAW_COLOR_PARAMS_RW2; | |
| 460 | ✗ | rcp->codec.rw2.wb_red = av_make_q(h->wb[0], h->wb[1]); | |
| 461 | ✗ | rcp->codec.rw2.wb_blue = av_make_q(h->wb[2], h->wb[1]); | |
| 462 | } | ||
| 463 | |||
| 464 | ✗ | return export_exif(avctx, frame, hdr, hdr_size); | |
| 465 | } | ||
| 466 | |||
| 467 | ✗ | static int decode_frame(AVCodecContext *avctx, AVFrame *frame, | |
| 468 | int *got_frame, AVPacket *avpkt) | ||
| 469 | { | ||
| 470 | ✗ | RW2DecContext *s = avctx->priv_data; | |
| 471 | ✗ | RW2Header *h = &s->h; | |
| 472 | int ret; | ||
| 473 | |||
| 474 | static const enum AVPixelFormat cfa_fmts[] = { | ||
| 475 | AV_PIX_FMT_BAYER_RGGB16, AV_PIX_FMT_BAYER_GRBG16, | ||
| 476 | AV_PIX_FMT_BAYER_GBRG16, AV_PIX_FMT_BAYER_BGGR16, | ||
| 477 | }; | ||
| 478 | |||
| 479 | ✗ | ret = parse_header(h, avpkt->data, avpkt->size); | |
| 480 | ✗ | if (ret < 0) | |
| 481 | ✗ | return ret; | |
| 482 | |||
| 483 | ✗ | if (h->raw_format != 8) { | |
| 484 | ✗ | if (!h->raw_format) | |
| 485 | ✗ | return AVERROR_INVALIDDATA; | |
| 486 | ✗ | avpriv_request_sample(avctx, "RawFormat %d", h->raw_format); | |
| 487 | ✗ | return AVERROR_PATCHWELCOME; | |
| 488 | } | ||
| 489 | |||
| 490 | ✗ | if (h->cfa < 1 || h->cfa > 4 || h->bpp < 8 || h->bpp > 16 || | |
| 491 | ✗ | (h->raw_width & 1) || (h->raw_height & 1)) | |
| 492 | ✗ | return AVERROR_INVALIDDATA; | |
| 493 | |||
| 494 | ✗ | ret = ff_set_dimensions(avctx, h->raw_width, h->raw_height); | |
| 495 | ✗ | if (ret < 0) | |
| 496 | ✗ | return ret; | |
| 497 | |||
| 498 | ✗ | s->payload = avpkt->data; | |
| 499 | |||
| 500 | ✗ | ret = check_stripes(avctx, h, avpkt->size); | |
| 501 | ✗ | if (ret < 0) | |
| 502 | ✗ | return ret; | |
| 503 | |||
| 504 | ✗ | if (cfa_fmts[h->cfa - 1] != s->pix_fmt) { | |
| 505 | ✗ | s->pix_fmt = cfa_fmts[h->cfa - 1]; | |
| 506 | ✗ | ret = get_pixel_format(avctx, s->pix_fmt); | |
| 507 | ✗ | if (ret < 0) | |
| 508 | ✗ | return ret; | |
| 509 | ✗ | avctx->pix_fmt = ret; | |
| 510 | } | ||
| 511 | ✗ | avctx->bits_per_raw_sample = h->bpp; | |
| 512 | |||
| 513 | ✗ | if (avctx->skip_frame >= AVDISCARD_ALL) | |
| 514 | ✗ | return avpkt->size; | |
| 515 | |||
| 516 | ✗ | ret = ff_thread_get_buffer(avctx, frame, 0); | |
| 517 | ✗ | if (ret < 0) | |
| 518 | ✗ | return ret; | |
| 519 | |||
| 520 | ✗ | s->frame = frame; | |
| 521 | |||
| 522 | ✗ | ret = ff_hwaccel_frame_priv_alloc(avctx, &s->hwaccel_picture_private); | |
| 523 | ✗ | if (ret < 0) | |
| 524 | ✗ | return ret; | |
| 525 | |||
| 526 | ✗ | ff_thread_finish_setup(avctx); | |
| 527 | |||
| 528 | ✗ | if (avctx->hwaccel) { | |
| 529 | ✗ | const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel); | |
| 530 | |||
| 531 | ✗ | ret = hwaccel->start_frame(avctx, avpkt->buf, avpkt->data, avpkt->size); | |
| 532 | ✗ | if (ret < 0) | |
| 533 | ✗ | return ret; | |
| 534 | |||
| 535 | ✗ | for (int i = 0; i < h->nb_stripes; i++) { | |
| 536 | ✗ | const RW2Stripe *st = &h->stripes[i]; | |
| 537 | ✗ | ret = hwaccel->decode_slice(avctx, s->payload + st->offset, | |
| 538 | ✗ | (st->size_bits + 7) >> 3); | |
| 539 | ✗ | if (ret < 0) | |
| 540 | ✗ | return ret; | |
| 541 | } | ||
| 542 | |||
| 543 | ✗ | ret = hwaccel->end_frame(avctx); | |
| 544 | ✗ | if (ret < 0) | |
| 545 | ✗ | return ret; | |
| 546 | |||
| 547 | ✗ | av_refstruct_unref(&s->hwaccel_picture_private); | |
| 548 | } else { | ||
| 549 | int rets[RW2_MAX_STRIPES]; | ||
| 550 | |||
| 551 | ✗ | ret = build_tables(s); | |
| 552 | ✗ | if (ret < 0) | |
| 553 | ✗ | return ret; | |
| 554 | |||
| 555 | ✗ | avctx->execute2(avctx, decode_stripe, frame, rets, h->nb_stripes); | |
| 556 | ✗ | for (int i = 0; i < h->nb_stripes; i++) { | |
| 557 | ✗ | if (rets[i] < 0) { | |
| 558 | ✗ | av_log(avctx, AV_LOG_ERROR, "Error decoding stripe %d\n", i); | |
| 559 | ✗ | return rets[i]; | |
| 560 | } | ||
| 561 | } | ||
| 562 | } | ||
| 563 | |||
| 564 | ✗ | frame->pict_type = AV_PICTURE_TYPE_I; | |
| 565 | ✗ | frame->flags |= AV_FRAME_FLAG_KEY; | |
| 566 | |||
| 567 | ✗ | ret = export_metadata(avctx, frame, avpkt->data, avpkt->size); | |
| 568 | ✗ | if (ret < 0) | |
| 569 | ✗ | return ret; | |
| 570 | |||
| 571 | ✗ | *got_frame = 1; | |
| 572 | |||
| 573 | ✗ | return avpkt->size; | |
| 574 | } | ||
| 575 | |||
| 576 | #if HAVE_THREADS | ||
| 577 | ✗ | static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) | |
| 578 | { | ||
| 579 | ✗ | RW2DecContext *ssrc = src->priv_data; | |
| 580 | ✗ | RW2DecContext *sdst = dst->priv_data; | |
| 581 | |||
| 582 | ✗ | sdst->pix_fmt = ssrc->pix_fmt; | |
| 583 | |||
| 584 | ✗ | return 0; | |
| 585 | } | ||
| 586 | #endif | ||
| 587 | |||
| 588 | ✗ | static av_cold int decode_init(AVCodecContext *avctx) | |
| 589 | { | ||
| 590 | ✗ | RW2DecContext *s = avctx->priv_data; | |
| 591 | |||
| 592 | ✗ | avctx->color_trc = AVCOL_TRC_LINEAR; | |
| 593 | ✗ | avctx->color_primaries = AVCOL_PRI_UNSPECIFIED; | |
| 594 | ✗ | avctx->colorspace = AVCOL_SPC_UNSPECIFIED; | |
| 595 | |||
| 596 | ✗ | s->pix_fmt = AV_PIX_FMT_NONE; | |
| 597 | |||
| 598 | ✗ | return 0; | |
| 599 | } | ||
| 600 | |||
| 601 | ✗ | static av_cold int decode_end(AVCodecContext *avctx) | |
| 602 | { | ||
| 603 | ✗ | RW2DecContext *s = avctx->priv_data; | |
| 604 | ✗ | av_refstruct_unref(&s->hwaccel_picture_private); | |
| 605 | ✗ | ff_vlc_free(&s->vlc); | |
| 606 | ✗ | return 0; | |
| 607 | } | ||
| 608 | |||
| 609 | const FFCodec ff_rw2_decoder = { | ||
| 610 | .p.name = "rw2", | ||
| 611 | CODEC_LONG_NAME("Panasonic RW2"), | ||
| 612 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
| 613 | .p.id = AV_CODEC_ID_RW2, | ||
| 614 | .priv_data_size = sizeof(RW2DecContext), | ||
| 615 | .init = decode_init, | ||
| 616 | .close = decode_end, | ||
| 617 | FF_CODEC_DECODE_CB(decode_frame), | ||
| 618 | UPDATE_THREAD_CONTEXT(update_thread_context), | ||
| 619 | .p.capabilities = AV_CODEC_CAP_DR1 | | ||
| 620 | AV_CODEC_CAP_FRAME_THREADS | | ||
| 621 | AV_CODEC_CAP_SLICE_THREADS, | ||
| 622 | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | ||
| 623 | FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | ||
| 624 | }; | ||
| 625 |