/src/ffmpeg/libavcodec/pixlet.c
Line | Count | Source |
1 | | /* |
2 | | * Apple Pixlet decoder |
3 | | * Copyright (c) 2016 Paul B Mahol |
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 | | #include <stdint.h> |
23 | | |
24 | | #include "libavutil/intmath.h" |
25 | | #include "libavutil/mem.h" |
26 | | |
27 | | #include "avcodec.h" |
28 | | #include "bytestream.h" |
29 | | #include "codec_internal.h" |
30 | | #include "decode.h" |
31 | | #include "get_bits.h" |
32 | | #include "thread.h" |
33 | | #include "unary.h" |
34 | | |
35 | 307k | #define NB_LEVELS 4 |
36 | | |
37 | 27.7k | #define PIXLET_MAGIC 0xDEADBEEF |
38 | | |
39 | 58.5k | #define H 0 |
40 | 58.5k | #define V 1 |
41 | | |
42 | | typedef struct SubBand { |
43 | | unsigned width, height; |
44 | | unsigned size; |
45 | | unsigned x, y; |
46 | | } SubBand; |
47 | | |
48 | | typedef struct PixletContext { |
49 | | AVClass *class; |
50 | | |
51 | | GetByteContext gb; |
52 | | GetBitContext bc; |
53 | | |
54 | | int levels; |
55 | | int depth; |
56 | | int w, h; |
57 | | |
58 | | int16_t *filter[2]; |
59 | | int16_t *prediction; |
60 | | int64_t scaling[4][2][NB_LEVELS]; |
61 | | uint16_t lut[65536]; |
62 | | SubBand band[4][NB_LEVELS * 3 + 1]; |
63 | | } PixletContext; |
64 | | |
65 | | static av_cold int pixlet_init(AVCodecContext *avctx) |
66 | 2.16k | { |
67 | 2.16k | avctx->pix_fmt = AV_PIX_FMT_YUV420P16; |
68 | 2.16k | avctx->color_range = AVCOL_RANGE_JPEG; |
69 | 2.16k | return 0; |
70 | 2.16k | } |
71 | | |
72 | | static void free_buffers(AVCodecContext *avctx) |
73 | 5.97k | { |
74 | 5.97k | PixletContext *ctx = avctx->priv_data; |
75 | | |
76 | 5.97k | av_freep(&ctx->filter[0]); |
77 | 5.97k | av_freep(&ctx->filter[1]); |
78 | 5.97k | av_freep(&ctx->prediction); |
79 | 5.97k | } |
80 | | |
81 | | static av_cold int pixlet_close(AVCodecContext *avctx) |
82 | 2.16k | { |
83 | 2.16k | PixletContext *ctx = avctx->priv_data; |
84 | 2.16k | free_buffers(avctx); |
85 | 2.16k | ctx->w = 0; |
86 | 2.16k | ctx->h = 0; |
87 | 2.16k | return 0; |
88 | 2.16k | } |
89 | | |
90 | | static int init_decoder(AVCodecContext *avctx) |
91 | 3.81k | { |
92 | 3.81k | PixletContext *ctx = avctx->priv_data; |
93 | 3.81k | int i, plane; |
94 | | |
95 | 3.81k | ctx->filter[0] = av_malloc_array(ctx->h, sizeof(int16_t)); |
96 | 3.81k | ctx->filter[1] = av_malloc_array(FFMAX(ctx->h, ctx->w) + 16, sizeof(int16_t)); |
97 | 3.81k | ctx->prediction = av_malloc_array((ctx->w >> NB_LEVELS), sizeof(int16_t)); |
98 | 3.81k | if (!ctx->filter[0] || !ctx->filter[1] || !ctx->prediction) |
99 | 0 | return AVERROR(ENOMEM); |
100 | | |
101 | 15.2k | for (plane = 0; plane < 3; plane++) { |
102 | 11.4k | unsigned shift = plane > 0; |
103 | 11.4k | unsigned w = ctx->w >> shift; |
104 | 11.4k | unsigned h = ctx->h >> shift; |
105 | | |
106 | 11.4k | ctx->band[plane][0].width = w >> NB_LEVELS; |
107 | 11.4k | ctx->band[plane][0].height = h >> NB_LEVELS; |
108 | 11.4k | ctx->band[plane][0].size = (w >> NB_LEVELS) * (h >> NB_LEVELS); |
109 | | |
110 | 148k | for (i = 0; i < NB_LEVELS * 3; i++) { |
111 | 137k | unsigned scale = ctx->levels - (i / 3); |
112 | | |
113 | 137k | ctx->band[plane][i + 1].width = w >> scale; |
114 | 137k | ctx->band[plane][i + 1].height = h >> scale; |
115 | 137k | ctx->band[plane][i + 1].size = (w >> scale) * (h >> scale); |
116 | | |
117 | 137k | ctx->band[plane][i + 1].x = (w >> scale) * (((i + 1) % 3) != 2); |
118 | 137k | ctx->band[plane][i + 1].y = (h >> scale) * (((i + 1) % 3) != 1); |
119 | 137k | } |
120 | 11.4k | } |
121 | | |
122 | 3.81k | return 0; |
123 | 3.81k | } |
124 | | |
125 | | static int read_low_coeffs(AVCodecContext *avctx, int16_t *dst, int size, |
126 | | int width, ptrdiff_t stride) |
127 | 37.7k | { |
128 | 37.7k | PixletContext *ctx = avctx->priv_data; |
129 | 37.7k | GetBitContext *bc = &ctx->bc; |
130 | 37.7k | unsigned cnt1, nbits, k, j = 0, i = 0; |
131 | 37.7k | int64_t value, state = 3; |
132 | 37.7k | int rlen, escape, flag = 0; |
133 | | |
134 | 16.1M | while (i < size) { |
135 | 16.0M | nbits = FFMIN(ff_clz((state >> 8) + 3) ^ 0x1F, 14); |
136 | | |
137 | 16.0M | cnt1 = get_unary(bc, 0, 8); |
138 | 16.0M | if (cnt1 < 8) { |
139 | 15.9M | value = show_bits(bc, nbits); |
140 | 15.9M | if (value <= 1) { |
141 | 15.0M | skip_bits(bc, nbits - 1); |
142 | 15.0M | escape = ((1 << nbits) - 1) * cnt1; |
143 | 15.0M | } else { |
144 | 951k | skip_bits(bc, nbits); |
145 | 951k | escape = value + ((1 << nbits) - 1) * cnt1 - 1; |
146 | 951k | } |
147 | 15.9M | } else { |
148 | 67.6k | escape = get_bits(bc, 16); |
149 | 67.6k | } |
150 | | |
151 | 16.0M | value = -((escape + flag) & 1) | 1; |
152 | 16.0M | dst[j++] = value * ((escape + flag + 1) >> 1); |
153 | 16.0M | i++; |
154 | 16.0M | if (j == width) { |
155 | 1.19M | j = 0; |
156 | 1.19M | dst += stride; |
157 | 1.19M | } |
158 | 16.0M | state = 120 * (escape + flag) + state - (120 * state >> 8); |
159 | 16.0M | flag = 0; |
160 | | |
161 | 16.0M | if (state * 4ULL > 0xFF || i >= size) |
162 | 11.3M | continue; |
163 | | |
164 | 4.74M | nbits = ((state + 8) >> 5) + (state ? ff_clz(state) : 32) - 24; |
165 | 4.74M | escape = av_zero_extend(16383, nbits); |
166 | 4.74M | cnt1 = get_unary(bc, 0, 8); |
167 | 4.74M | if (cnt1 > 7) { |
168 | 1.46k | rlen = get_bits(bc, 16); |
169 | 4.74M | } else { |
170 | 4.74M | value = show_bits(bc, nbits); |
171 | 4.74M | if (value > 1) { |
172 | 102k | skip_bits(bc, nbits); |
173 | 102k | rlen = value + escape * cnt1 - 1; |
174 | 4.64M | } else { |
175 | 4.64M | skip_bits(bc, nbits - 1); |
176 | 4.64M | rlen = escape * cnt1; |
177 | 4.64M | } |
178 | 4.74M | } |
179 | | |
180 | 4.74M | if (rlen > size - i) |
181 | 1.58k | return AVERROR_INVALIDDATA; |
182 | 4.74M | i += rlen; |
183 | | |
184 | 12.0M | for (k = 0; k < rlen; k++) { |
185 | 7.26M | dst[j++] = 0; |
186 | 7.26M | if (j == width) { |
187 | 203k | j = 0; |
188 | 203k | dst += stride; |
189 | 203k | } |
190 | 7.26M | } |
191 | | |
192 | 4.74M | state = 0; |
193 | 4.74M | flag = rlen < 0xFFFF ? 1 : 0; |
194 | 4.74M | } |
195 | | |
196 | 36.1k | align_get_bits(bc); |
197 | 36.1k | return get_bits_count(bc) >> 3; |
198 | 37.7k | } |
199 | | |
200 | | static int read_high_coeffs(AVCodecContext *avctx, const uint8_t *src, int16_t *dst, |
201 | | int size, int c, int a, int d, |
202 | | int width, ptrdiff_t stride) |
203 | 23.3k | { |
204 | 23.3k | PixletContext *ctx = avctx->priv_data; |
205 | 23.3k | GetBitContext *bc = &ctx->bc; |
206 | 23.3k | unsigned cnt1, shbits, rlen, nbits, length, i = 0, j = 0, k; |
207 | 23.3k | int ret, escape, pfx, value, yflag, xflag, flag = 0; |
208 | 23.3k | int64_t state = 3, tmp; |
209 | | |
210 | 23.3k | ret = init_get_bits8(bc, src, bytestream2_get_bytes_left(&ctx->gb)); |
211 | 23.3k | if (ret < 0) |
212 | 0 | return ret; |
213 | | |
214 | 23.3k | if (a ^ (a >> 31)) { |
215 | 6.62k | nbits = 33 - ff_clz(a ^ (a >> 31)); |
216 | 6.62k | if (nbits > 16) |
217 | 956 | return AVERROR_INVALIDDATA; |
218 | 16.7k | } else { |
219 | 16.7k | nbits = 1; |
220 | 16.7k | } |
221 | | |
222 | 22.4k | length = 25 - nbits; |
223 | | |
224 | 4.65M | while (i < size) { |
225 | 4.63M | if (((state >> 8) + 3) & 0xFFFFFFF) |
226 | 4.63M | value = ff_clz((state >> 8) + 3) ^ 0x1F; |
227 | 351 | else |
228 | 351 | value = -1; |
229 | | |
230 | 4.63M | cnt1 = get_unary(bc, 0, length); |
231 | 4.63M | if (cnt1 >= length) { |
232 | 30.9k | cnt1 = get_bits(bc, nbits); |
233 | 4.60M | } else { |
234 | 4.60M | pfx = FFMIN(value, 14); |
235 | 4.60M | if (pfx < 1) |
236 | 372 | return AVERROR_INVALIDDATA; |
237 | 4.60M | cnt1 *= (1 << pfx) - 1; |
238 | 4.60M | shbits = show_bits(bc, pfx); |
239 | 4.60M | if (shbits <= 1) { |
240 | 2.96M | skip_bits(bc, pfx - 1); |
241 | 2.96M | } else { |
242 | 1.63M | skip_bits(bc, pfx); |
243 | 1.63M | cnt1 += shbits - 1; |
244 | 1.63M | } |
245 | 4.60M | } |
246 | | |
247 | 4.63M | xflag = flag + cnt1; |
248 | 4.63M | yflag = xflag; |
249 | | |
250 | 4.63M | if (flag + cnt1 == 0) { |
251 | 1.28M | value = 0; |
252 | 3.35M | } else { |
253 | 3.35M | xflag &= 1u; |
254 | 3.35M | tmp = (int64_t)c * ((yflag + 1) >> 1) + (c >> 1); |
255 | 3.35M | value = xflag + (tmp ^ -xflag); |
256 | 3.35M | } |
257 | | |
258 | 4.63M | i++; |
259 | 4.63M | dst[j++] = value; |
260 | 4.63M | if (j == width) { |
261 | 188k | j = 0; |
262 | 188k | dst += stride; |
263 | 188k | } |
264 | 4.63M | state += (int64_t)d * (uint64_t)yflag - ((int64_t)(d * (uint64_t)state) >> 8); |
265 | | |
266 | 4.63M | flag = 0; |
267 | | |
268 | 4.63M | if ((uint64_t)state > 0xFF / 4 || i >= size) |
269 | 3.12M | continue; |
270 | | |
271 | 1.50M | pfx = ((state + 8) >> 5) + (state ? ff_clz(state) : 32) - 24; |
272 | 1.50M | escape = av_zero_extend(16383, pfx); |
273 | 1.50M | cnt1 = get_unary(bc, 0, 8); |
274 | 1.50M | if (cnt1 < 8) { |
275 | 1.49M | if (pfx < 1 || pfx > 25) |
276 | 0 | return AVERROR_INVALIDDATA; |
277 | | |
278 | 1.49M | value = show_bits(bc, pfx); |
279 | 1.49M | if (value > 1) { |
280 | 39.0k | skip_bits(bc, pfx); |
281 | 39.0k | rlen = value + escape * cnt1 - 1; |
282 | 1.45M | } else { |
283 | 1.45M | skip_bits(bc, pfx - 1); |
284 | 1.45M | rlen = escape * cnt1; |
285 | 1.45M | } |
286 | 1.49M | } else { |
287 | 6.90k | if (get_bits1(bc)) |
288 | 1.70k | value = get_bits(bc, 16); |
289 | 5.20k | else |
290 | 5.20k | value = get_bits(bc, 8); |
291 | | |
292 | 6.90k | rlen = value + 8 * escape; |
293 | 6.90k | } |
294 | | |
295 | 1.50M | if (rlen > 0xFFFF || i + rlen > size) |
296 | 2.06k | return AVERROR_INVALIDDATA; |
297 | 1.50M | i += rlen; |
298 | | |
299 | 2.83M | for (k = 0; k < rlen; k++) { |
300 | 1.33M | dst[j++] = 0; |
301 | 1.33M | if (j == width) { |
302 | 31.6k | j = 0; |
303 | 31.6k | dst += stride; |
304 | 31.6k | } |
305 | 1.33M | } |
306 | | |
307 | 1.50M | state = 0; |
308 | 1.50M | flag = rlen < 0xFFFF ? 1 : 0; |
309 | 1.50M | } |
310 | | |
311 | 19.9k | align_get_bits(bc); |
312 | 19.9k | return get_bits_count(bc) >> 3; |
313 | 22.4k | } |
314 | | |
315 | | static int read_highpass(AVCodecContext *avctx, const uint8_t *ptr, |
316 | | int plane, AVFrame *frame) |
317 | 9.04k | { |
318 | 9.04k | PixletContext *ctx = avctx->priv_data; |
319 | 9.04k | ptrdiff_t stride = frame->linesize[plane] / 2; |
320 | 9.04k | int i, ret; |
321 | | |
322 | 29.0k | for (i = 0; i < ctx->levels * 3; i++) { |
323 | 27.7k | int32_t a = bytestream2_get_be32(&ctx->gb); |
324 | 27.7k | int32_t b = bytestream2_get_be32(&ctx->gb); |
325 | 27.7k | int32_t c = bytestream2_get_be32(&ctx->gb); |
326 | 27.7k | int32_t d = bytestream2_get_be32(&ctx->gb); |
327 | 27.7k | int16_t *dest = (int16_t *)frame->data[plane] + |
328 | 27.7k | ctx->band[plane][i + 1].x + |
329 | 27.7k | ctx->band[plane][i + 1].y * stride; |
330 | 27.7k | unsigned size = ctx->band[plane][i + 1].size; |
331 | 27.7k | uint32_t magic = bytestream2_get_be32(&ctx->gb); |
332 | | |
333 | 27.7k | if (magic != PIXLET_MAGIC) { |
334 | 4.14k | av_log(avctx, AV_LOG_ERROR, |
335 | 4.14k | "wrong magic number: 0x%08"PRIX32" for plane %d, band %d\n", |
336 | 4.14k | magic, plane, i); |
337 | 4.14k | return AVERROR_INVALIDDATA; |
338 | 4.14k | } |
339 | | |
340 | 23.5k | if (a == INT32_MIN) |
341 | 194 | return AVERROR_INVALIDDATA; |
342 | | |
343 | 23.3k | ret = read_high_coeffs(avctx, ptr + bytestream2_tell(&ctx->gb), dest, size, |
344 | 23.3k | c, (b >= FFABS(a)) ? b : a, d, |
345 | 23.3k | ctx->band[plane][i + 1].width, stride); |
346 | 23.3k | if (ret < 0) { |
347 | 3.39k | av_log(avctx, AV_LOG_ERROR, |
348 | 3.39k | "error in highpass coefficients for plane %d, band %d\n", |
349 | 3.39k | plane, i); |
350 | 3.39k | return ret; |
351 | 3.39k | } |
352 | 19.9k | bytestream2_skip(&ctx->gb, ret); |
353 | 19.9k | } |
354 | | |
355 | 1.31k | return 0; |
356 | 9.04k | } |
357 | | |
358 | | static void lowpass_prediction(int16_t *dst, int16_t *pred, |
359 | | int width, int height, ptrdiff_t stride) |
360 | 1.31k | { |
361 | 1.31k | int16_t val; |
362 | 1.31k | int i, j; |
363 | | |
364 | 1.31k | memset(pred, 0, width * sizeof(*pred)); |
365 | | |
366 | 3.95k | for (i = 0; i < height; i++) { |
367 | 2.63k | val = pred[0] + dst[0]; |
368 | 2.63k | dst[0] = pred[0] = val; |
369 | 5.27k | for (j = 1; j < width; j++) { |
370 | 2.63k | val = pred[j] + dst[j]; |
371 | 2.63k | dst[j] = pred[j] = val; |
372 | 2.63k | dst[j] += dst[j-1]; |
373 | 2.63k | } |
374 | 2.63k | dst += stride; |
375 | 2.63k | } |
376 | 1.31k | } |
377 | | |
378 | | static void filterfn(int16_t *dest, int16_t *tmp, unsigned size, int64_t scale) |
379 | 158k | { |
380 | 158k | int16_t *low, *high, *ll, *lh, *hl, *hh; |
381 | 158k | int hsize, i, j; |
382 | 158k | int64_t value; |
383 | | |
384 | 158k | hsize = size >> 1; |
385 | 158k | low = tmp + 4; |
386 | 158k | high = &low[hsize + 8]; |
387 | | |
388 | 158k | memcpy(low, dest, size); |
389 | 158k | memcpy(high, dest + hsize, size); |
390 | | |
391 | 158k | ll = &low[hsize]; |
392 | 158k | lh = &low[hsize]; |
393 | 158k | hl = &high[hsize]; |
394 | 158k | hh = hl; |
395 | 790k | for (i = 4, j = 2; i; i--, j++, ll--, hh++, lh++, hl--) { |
396 | 632k | low[i - 5] = low[j - 1]; |
397 | 632k | lh[0] = ll[-1]; |
398 | 632k | high[i - 5] = high[j - 2]; |
399 | 632k | hh[0] = hl[-2]; |
400 | 632k | } |
401 | | |
402 | 1.95M | for (i = 0; i < hsize; i++) { |
403 | 1.79M | value = (int64_t) low [i + 1] * -INT64_C(325392907) + |
404 | 1.79M | (int64_t) low [i + 0] * INT64_C(3687786320) + |
405 | 1.79M | (int64_t) low [i - 1] * -INT64_C(325392907) + |
406 | 1.79M | (int64_t) high[i + 0] * INT64_C(1518500249) + |
407 | 1.79M | (int64_t) high[i - 1] * INT64_C(1518500249); |
408 | 1.79M | dest[i * 2] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32); |
409 | 1.79M | } |
410 | | |
411 | 1.95M | for (i = 0; i < hsize; i++) { |
412 | 1.79M | value = (int64_t) low [i + 2] * -INT64_C(65078576) + |
413 | 1.79M | (int64_t) low [i + 1] * INT64_C(1583578880) + |
414 | 1.79M | (int64_t) low [i + 0] * INT64_C(1583578880) + |
415 | 1.79M | (int64_t) low [i - 1] * -INT64_C(65078576) + |
416 | 1.79M | (int64_t) high[i + 1] * INT64_C(303700064) + |
417 | 1.79M | (int64_t) high[i + 0] * -INT64_C(3644400640) + |
418 | 1.79M | (int64_t) high[i - 1] * INT64_C(303700064); |
419 | 1.79M | dest[i * 2 + 1] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32); |
420 | 1.79M | } |
421 | 158k | } |
422 | | |
423 | | static void reconstruction(AVCodecContext *avctx, int16_t *dest, |
424 | | unsigned width, unsigned height, ptrdiff_t stride, |
425 | | int64_t *scaling_h, int64_t *scaling_v) |
426 | 1.31k | { |
427 | 1.31k | PixletContext *ctx = avctx->priv_data; |
428 | 1.31k | unsigned scaled_width, scaled_height; |
429 | 1.31k | int16_t *ptr, *tmp; |
430 | 1.31k | int i, j, k; |
431 | | |
432 | 1.31k | scaled_width = width >> NB_LEVELS; |
433 | 1.31k | scaled_height = height >> NB_LEVELS; |
434 | 1.31k | tmp = ctx->filter[0]; |
435 | | |
436 | 6.59k | for (i = 0; i < NB_LEVELS; i++) { |
437 | 5.27k | int64_t scale_v = scaling_v[i]; |
438 | 5.27k | int64_t scale_h = scaling_h[i]; |
439 | 5.27k | scaled_width <<= 1; |
440 | 5.27k | scaled_height <<= 1; |
441 | | |
442 | 5.27k | ptr = dest; |
443 | 84.3k | for (j = 0; j < scaled_height; j++) { |
444 | 79.0k | filterfn(ptr, ctx->filter[1], scaled_width, scale_v); |
445 | 79.0k | ptr += stride; |
446 | 79.0k | } |
447 | | |
448 | 84.3k | for (j = 0; j < scaled_width; j++) { |
449 | 79.0k | ptr = dest + j; |
450 | 1.87M | for (k = 0; k < scaled_height; k++) { |
451 | 1.79M | tmp[k] = *ptr; |
452 | 1.79M | ptr += stride; |
453 | 1.79M | } |
454 | | |
455 | 79.0k | filterfn(tmp, ctx->filter[1], scaled_height, scale_h); |
456 | | |
457 | 79.0k | ptr = dest + j; |
458 | 1.87M | for (k = 0; k < scaled_height; k++) { |
459 | 1.79M | *ptr = tmp[k]; |
460 | 1.79M | ptr += stride; |
461 | 1.79M | } |
462 | 79.0k | } |
463 | 5.27k | } |
464 | 1.31k | } |
465 | | |
466 | | static void build_luma_lut(AVCodecContext *avctx, int depth) |
467 | 16.9k | { |
468 | 16.9k | PixletContext *ctx = avctx->priv_data; |
469 | 16.9k | int max = (1 << depth) - 1; |
470 | | |
471 | 16.9k | if (ctx->depth == depth) |
472 | 13.3k | return; |
473 | 3.60k | ctx->depth = depth; |
474 | | |
475 | 236M | for (int i = 0; i < FF_ARRAY_ELEMS(ctx->lut); i++) |
476 | 236M | ctx->lut[i] = ((int64_t)i * i * 65535LL) / max / max; |
477 | 3.60k | } |
478 | | |
479 | | static void postprocess_luma(AVCodecContext *avctx, AVFrame *frame, |
480 | | int w, int h, int depth) |
481 | 0 | { |
482 | 0 | PixletContext *ctx = avctx->priv_data; |
483 | 0 | uint16_t *dsty = (uint16_t *)frame->data[0]; |
484 | 0 | int16_t *srcy = (int16_t *)frame->data[0]; |
485 | 0 | ptrdiff_t stridey = frame->linesize[0] / 2; |
486 | 0 | uint16_t *lut = ctx->lut; |
487 | 0 | int i, j; |
488 | |
|
489 | 0 | for (j = 0; j < h; j++) { |
490 | 0 | for (i = 0; i < w; i++) { |
491 | 0 | if (srcy[i] <= 0) |
492 | 0 | dsty[i] = 0; |
493 | 0 | else if (srcy[i] > ((1 << depth) - 1)) |
494 | 0 | dsty[i] = 65535; |
495 | 0 | else |
496 | 0 | dsty[i] = lut[srcy[i]]; |
497 | 0 | } |
498 | 0 | dsty += stridey; |
499 | 0 | srcy += stridey; |
500 | 0 | } |
501 | 0 | } |
502 | | |
503 | | static void postprocess_chroma(AVFrame *frame, int w, int h, int depth) |
504 | 0 | { |
505 | 0 | uint16_t *dstu = (uint16_t *)frame->data[1]; |
506 | 0 | uint16_t *dstv = (uint16_t *)frame->data[2]; |
507 | 0 | int16_t *srcu = (int16_t *)frame->data[1]; |
508 | 0 | int16_t *srcv = (int16_t *)frame->data[2]; |
509 | 0 | ptrdiff_t strideu = frame->linesize[1] / 2; |
510 | 0 | ptrdiff_t stridev = frame->linesize[2] / 2; |
511 | 0 | const unsigned add = 1 << (depth - 1); |
512 | 0 | const unsigned shift = 16 - depth; |
513 | 0 | int i, j; |
514 | |
|
515 | 0 | for (j = 0; j < h; j++) { |
516 | 0 | for (i = 0; i < w; i++) { |
517 | 0 | dstu[i] = av_clip_uintp2_c(add + srcu[i], depth) << shift; |
518 | 0 | dstv[i] = av_clip_uintp2_c(add + srcv[i], depth) << shift; |
519 | 0 | } |
520 | 0 | dstu += strideu; |
521 | 0 | dstv += stridev; |
522 | 0 | srcu += strideu; |
523 | 0 | srcv += stridev; |
524 | 0 | } |
525 | 0 | } |
526 | | |
527 | | static int decode_plane(AVCodecContext *avctx, int plane, |
528 | | const AVPacket *avpkt, AVFrame *frame) |
529 | 17.0k | { |
530 | 17.0k | PixletContext *ctx = avctx->priv_data; |
531 | 17.0k | ptrdiff_t stride = frame->linesize[plane] / 2; |
532 | 17.0k | unsigned shift = plane > 0; |
533 | 17.0k | int16_t *dst; |
534 | 17.0k | int i, ret; |
535 | | |
536 | 74.3k | for (i = ctx->levels - 1; i >= 0; i--) { |
537 | 61.1k | int32_t h = sign_extend(bytestream2_get_be32(&ctx->gb), 32); |
538 | 61.1k | int32_t v = sign_extend(bytestream2_get_be32(&ctx->gb), 32); |
539 | | |
540 | 61.1k | if (!h || !v) |
541 | 3.91k | return AVERROR_INVALIDDATA; |
542 | | |
543 | 57.2k | ctx->scaling[plane][H][i] = (1000000ULL << 32) / h; |
544 | 57.2k | ctx->scaling[plane][V][i] = (1000000ULL << 32) / v; |
545 | 57.2k | } |
546 | | |
547 | 13.1k | bytestream2_skip(&ctx->gb, 4); |
548 | | |
549 | 13.1k | dst = (int16_t *)frame->data[plane]; |
550 | 13.1k | dst[0] = sign_extend(bytestream2_get_be16(&ctx->gb), 16); |
551 | | |
552 | 13.1k | ret = init_get_bits8(&ctx->bc, avpkt->data + bytestream2_tell(&ctx->gb), |
553 | 13.1k | bytestream2_get_bytes_left(&ctx->gb)); |
554 | 13.1k | if (ret < 0) |
555 | 0 | return ret; |
556 | | |
557 | 13.1k | ret = read_low_coeffs(avctx, dst + 1, ctx->band[plane][0].width - 1, |
558 | 13.1k | ctx->band[plane][0].width - 1, 0); |
559 | 13.1k | if (ret < 0) { |
560 | 512 | av_log(avctx, AV_LOG_ERROR, |
561 | 512 | "error in lowpass coefficients for plane %d, top row\n", plane); |
562 | 512 | return ret; |
563 | 512 | } |
564 | | |
565 | 12.6k | ret = read_low_coeffs(avctx, dst + stride, |
566 | 12.6k | ctx->band[plane][0].height - 1, 1, stride); |
567 | 12.6k | if (ret < 0) { |
568 | 713 | av_log(avctx, AV_LOG_ERROR, |
569 | 713 | "error in lowpass coefficients for plane %d, left column\n", |
570 | 713 | plane); |
571 | 713 | return ret; |
572 | 713 | } |
573 | | |
574 | 11.9k | ret = read_low_coeffs(avctx, dst + stride + 1, |
575 | 11.9k | (ctx->band[plane][0].width - 1) * (ctx->band[plane][0].height - 1), |
576 | 11.9k | ctx->band[plane][0].width - 1, stride); |
577 | 11.9k | if (ret < 0) { |
578 | 355 | av_log(avctx, AV_LOG_ERROR, |
579 | 355 | "error in lowpass coefficients for plane %d, rest\n", plane); |
580 | 355 | return ret; |
581 | 355 | } |
582 | | |
583 | 11.5k | bytestream2_skip(&ctx->gb, ret); |
584 | 11.5k | if (bytestream2_get_bytes_left(&ctx->gb) <= 0) { |
585 | 2.53k | av_log(avctx, AV_LOG_ERROR, "no bytes left\n"); |
586 | 2.53k | return AVERROR_INVALIDDATA; |
587 | 2.53k | } |
588 | | |
589 | 9.04k | ret = read_highpass(avctx, avpkt->data, plane, frame); |
590 | 9.04k | if (ret < 0) |
591 | 7.73k | return ret; |
592 | | |
593 | 1.31k | lowpass_prediction(dst, ctx->prediction, ctx->band[plane][0].width, |
594 | 1.31k | ctx->band[plane][0].height, stride); |
595 | | |
596 | 1.31k | reconstruction(avctx, (int16_t *)frame->data[plane], ctx->w >> shift, |
597 | 1.31k | ctx->h >> shift, stride, ctx->scaling[plane][H], |
598 | 1.31k | ctx->scaling[plane][V]); |
599 | | |
600 | 1.31k | return 0; |
601 | 9.04k | } |
602 | | |
603 | | static int pixlet_decode_frame(AVCodecContext *avctx, AVFrame *p, |
604 | | int *got_frame, AVPacket *avpkt) |
605 | 45.9k | { |
606 | 45.9k | PixletContext *ctx = avctx->priv_data; |
607 | 45.9k | int i, w, h, width, height, ret, version; |
608 | 45.9k | uint32_t pktsize, depth; |
609 | | |
610 | 45.9k | bytestream2_init(&ctx->gb, avpkt->data, avpkt->size); |
611 | | |
612 | 45.9k | pktsize = bytestream2_get_be32(&ctx->gb); |
613 | 45.9k | if (pktsize <= 44 + (NB_LEVELS * 8 + 6) * 3 || pktsize - 4 > bytestream2_get_bytes_left(&ctx->gb)) { |
614 | 26.9k | av_log(avctx, AV_LOG_ERROR, "Invalid packet size %"PRIu32"\n", pktsize); |
615 | 26.9k | return AVERROR_INVALIDDATA; |
616 | 26.9k | } |
617 | | |
618 | 19.0k | version = bytestream2_get_le32(&ctx->gb); |
619 | 19.0k | if (version != 1) |
620 | 18.7k | avpriv_request_sample(avctx, "Version %d", version); |
621 | | |
622 | 19.0k | bytestream2_skip(&ctx->gb, 4); |
623 | 19.0k | if (bytestream2_get_be32(&ctx->gb) != 1) |
624 | 703 | return AVERROR_INVALIDDATA; |
625 | 18.3k | bytestream2_skip(&ctx->gb, 4); |
626 | | |
627 | 18.3k | width = bytestream2_get_be32(&ctx->gb); |
628 | 18.3k | height = bytestream2_get_be32(&ctx->gb); |
629 | | |
630 | 18.3k | if ( width > INT_MAX - (1U << (NB_LEVELS + 1)) |
631 | 18.1k | || height > INT_MAX - (1U << (NB_LEVELS + 1))) |
632 | 411 | return AVERROR_INVALIDDATA; |
633 | | |
634 | 17.8k | w = FFALIGN(width, 1 << (NB_LEVELS + 1)); |
635 | 17.8k | h = FFALIGN(height, 1 << (NB_LEVELS + 1)); |
636 | | |
637 | 17.8k | ctx->levels = bytestream2_get_be32(&ctx->gb); |
638 | 17.8k | if (ctx->levels != NB_LEVELS) |
639 | 379 | return AVERROR_INVALIDDATA; |
640 | 17.5k | depth = bytestream2_get_be32(&ctx->gb); |
641 | 17.5k | if (depth < 8 || depth > 15) { |
642 | 569 | avpriv_request_sample(avctx, "Depth %d", depth); |
643 | 569 | return AVERROR_INVALIDDATA; |
644 | 569 | } |
645 | | |
646 | 16.9k | build_luma_lut(avctx, depth); |
647 | | |
648 | 16.9k | ret = ff_set_dimensions(avctx, w, h); |
649 | 16.9k | if (ret < 0) |
650 | 1.16k | return ret; |
651 | 15.7k | avctx->width = width; |
652 | 15.7k | avctx->height = height; |
653 | | |
654 | 15.7k | if (ctx->w != w || ctx->h != h) { |
655 | 3.81k | free_buffers(avctx); |
656 | 3.81k | ctx->w = w; |
657 | 3.81k | ctx->h = h; |
658 | | |
659 | 3.81k | ret = init_decoder(avctx); |
660 | 3.81k | if (ret < 0) { |
661 | 0 | free_buffers(avctx); |
662 | 0 | ctx->w = 0; |
663 | 0 | ctx->h = 0; |
664 | 0 | return ret; |
665 | 0 | } |
666 | 3.81k | } |
667 | | |
668 | 15.7k | bytestream2_skip(&ctx->gb, 8); |
669 | | |
670 | 15.7k | p->color_range = AVCOL_RANGE_JPEG; |
671 | | |
672 | 15.7k | ret = ff_thread_get_buffer(avctx, p, 0); |
673 | 15.7k | if (ret < 0) |
674 | 33 | return ret; |
675 | | |
676 | 17.0k | for (i = 0; i < 3; i++) { |
677 | 17.0k | ret = decode_plane(avctx, i, avpkt, p); |
678 | 17.0k | if (ret < 0) |
679 | 15.7k | return ret; |
680 | 1.31k | if (avctx->flags & AV_CODEC_FLAG_GRAY) |
681 | 0 | break; |
682 | 1.31k | } |
683 | | |
684 | 0 | postprocess_luma(avctx, p, ctx->w, ctx->h, ctx->depth); |
685 | 0 | postprocess_chroma(p, ctx->w >> 1, ctx->h >> 1, ctx->depth); |
686 | |
|
687 | 0 | *got_frame = 1; |
688 | |
|
689 | 0 | return pktsize; |
690 | 15.7k | } |
691 | | |
692 | | const FFCodec ff_pixlet_decoder = { |
693 | | .p.name = "pixlet", |
694 | | CODEC_LONG_NAME("Apple Pixlet"), |
695 | | .p.type = AVMEDIA_TYPE_VIDEO, |
696 | | .p.id = AV_CODEC_ID_PIXLET, |
697 | | .init = pixlet_init, |
698 | | .close = pixlet_close, |
699 | | FF_CODEC_DECODE_CB(pixlet_decode_frame), |
700 | | .priv_data_size = sizeof(PixletContext), |
701 | | .p.capabilities = AV_CODEC_CAP_DR1 | |
702 | | AV_CODEC_CAP_FRAME_THREADS, |
703 | | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, |
704 | | }; |