3 * Copyright (c) 2016 Paul B Mahol
5 * This file is part of Libav.
7 * Libav 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.
12 * Libav 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "libavutil/imgutils.h"
25 #include "libavutil/intmath.h"
26 #include "libavutil/opt.h"
29 #include "bitstream.h"
30 #include "bytestream.h"
37 #define PIXLET_MAGIC 0xDEADBEEF
42 typedef struct SubBand
{
48 typedef struct PixletContext
{
60 int64_t scaling
[4][2][NB_LEVELS
];
61 SubBand band
[4][NB_LEVELS
* 3 + 1];
64 static av_cold
int pixlet_init(AVCodecContext
*avctx
)
66 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P16
;
67 avctx
->color_range
= AVCOL_RANGE_JPEG
;
71 static av_cold
int pixlet_close(AVCodecContext
*avctx
)
73 PixletContext
*ctx
= avctx
->priv_data
;
75 av_freep(&ctx
->filter
[0]);
76 av_freep(&ctx
->filter
[1]);
77 av_freep(&ctx
->prediction
);
82 static int init_decoder(AVCodecContext
*avctx
)
84 PixletContext
*ctx
= avctx
->priv_data
;
87 ctx
->filter
[0] = av_malloc_array(ctx
->h
, sizeof(int16_t));
88 ctx
->filter
[1] = av_malloc_array(FFMAX(ctx
->h
, ctx
->w
) + 16, sizeof(int16_t));
89 ctx
->prediction
= av_malloc_array((ctx
->w
>> NB_LEVELS
), sizeof(int16_t));
90 if (!ctx
->filter
[0] || !ctx
->filter
[1] || !ctx
->prediction
)
91 return AVERROR(ENOMEM
);
93 for (plane
= 0; plane
< 3; plane
++) {
94 unsigned shift
= plane
> 0;
95 size_t w
= ctx
->w
>> shift
;
96 size_t h
= ctx
->h
>> shift
;
98 ctx
->band
[plane
][0].width
= w
>> NB_LEVELS
;
99 ctx
->band
[plane
][0].height
= h
>> NB_LEVELS
;
100 ctx
->band
[plane
][0].size
= (w
>> NB_LEVELS
) * (h
>> NB_LEVELS
);
102 for (i
= 0; i
< NB_LEVELS
* 3; i
++) {
103 unsigned scale
= ctx
->levels
- (i
/ 3);
105 ctx
->band
[plane
][i
+ 1].width
= w
>> scale
;
106 ctx
->band
[plane
][i
+ 1].height
= h
>> scale
;
107 ctx
->band
[plane
][i
+ 1].size
= (w
>> scale
) * (h
>> scale
);
109 ctx
->band
[plane
][i
+ 1].x
= (w
>> scale
) * (((i
+ 1) % 3) != 2);
110 ctx
->band
[plane
][i
+ 1].y
= (h
>> scale
) * (((i
+ 1) % 3) != 1);
117 static int read_low_coeffs(AVCodecContext
*avctx
, int16_t *dst
, size_t size
,
118 size_t width
, ptrdiff_t stride
)
120 PixletContext
*ctx
= avctx
->priv_data
;
121 BitstreamContext
*bc
= &ctx
->bc
;
122 unsigned cnt1
, nbits
, k
, j
= 0, i
= 0;
123 int64_t value
, state
= 3;
124 int rlen
, escape
, flag
= 0;
127 nbits
= FFMIN(ff_clz((state
>> 8) + 3) ^ 0x1F, 14);
129 cnt1
= get_unary(bc
, 0, 8);
131 value
= bitstream_read(bc
, nbits
);
133 bitstream_unget(bc
, value
& 1, 1);
136 escape
= value
+ ((1 << nbits
) - 1) * cnt1
- 1;
138 escape
= bitstream_read(bc
, 16);
141 value
= -((escape
+ flag
) & 1) | 1;
142 dst
[j
++] = value
* ((escape
+ flag
+ 1) >> 1);
148 state
= 120 * (escape
+ flag
) + state
- (120 * state
>> 8);
151 if (state
* 4 > 0xFF || i
>= size
)
154 nbits
= ((state
+ 8) >> 5) + (state
? ff_clz(state
) : 32) - 24;
155 escape
= av_mod_uintp2(16383, nbits
);
156 cnt1
= get_unary(bc
, 0, 8);
158 rlen
= bitstream_read(bc
, 16);
160 value
= bitstream_read(bc
, nbits
);
162 bitstream_unget(bc
, value
& 1, 1);
165 rlen
= value
+ escape
* cnt1
- 1;
169 return AVERROR_INVALIDDATA
;
172 for (k
= 0; k
< rlen
; k
++) {
181 flag
= rlen
< 0xFFFF ? 1 : 0;
185 return bitstream_tell(bc
) >> 3;
188 static int read_high_coeffs(AVCodecContext
*avctx
, uint8_t *src
, int16_t *dst
,
189 int size
, int64_t c
, int a
, int64_t d
,
190 int width
, ptrdiff_t stride
)
192 PixletContext
*ctx
= avctx
->priv_data
;
193 BitstreamContext
*bc
= &ctx
->bc
;
194 unsigned cnt1
, shbits
, rlen
, nbits
, length
, i
= 0, j
= 0, k
;
195 int ret
, escape
, pfx
, cthulu
, yflag
, xflag
, flag
= 0;
196 int64_t state
= 3, value
, tmp
;
198 ret
= bitstream_init8(bc
, src
, bytestream2_get_bytes_left(&ctx
->gb
));
202 cthulu
= (a
>= 0) + (a
^ (a
>> 31)) - (a
>> 31);
204 nbits
= 33 - ff_clz(cthulu
- 1);
206 return AVERROR_INVALIDDATA
;
214 if (state
>> 8 != -3)
215 value
= ff_clz((state
>> 8) + 3) ^ 0x1F;
219 cnt1
= get_unary(bc
, 0, length
);
220 if (cnt1
>= length
) {
221 cnt1
= bitstream_read(bc
, nbits
);
223 pfx
= 14 + (((value
- 14) >> 32) & (value
- 14));
224 cnt1
*= (1 << pfx
) - 1;
226 shbits
= bitstream_read(bc
, pfx
);
228 bitstream_unget(bc
, shbits
& 1, 1);
237 if (flag
+ cnt1
== 0) {
241 tmp
= c
* ((yflag
+ 1) >> 1) + (c
>> 1);
242 value
= xflag
+ (tmp
^ -xflag
);
251 state
+= d
* yflag
- (d
* state
>> 8);
255 if (state
* 4 > 0xFF || i
>= size
)
258 pfx
= ((state
+ 8) >> 5) + (state
? ff_clz(state
) : 32) - 24;
259 escape
= av_mod_uintp2(16383, pfx
);
260 cnt1
= get_unary(bc
, 0, 8);
262 if (pfx
< 1 || pfx
> 25)
263 return AVERROR_INVALIDDATA
;
265 value
= bitstream_read(bc
, pfx
);
267 bitstream_unget(bc
, value
& 1, 1);
270 rlen
= value
+ escape
* cnt1
- 1;
272 if (bitstream_read_bit(bc
))
273 value
= bitstream_read(bc
, 16);
275 value
= bitstream_read(bc
, 8);
277 rlen
= value
+ 8 * escape
;
280 if (rlen
> 0xFFFF || i
+ rlen
> size
)
281 return AVERROR_INVALIDDATA
;
284 for (k
= 0; k
< rlen
; k
++) {
293 flag
= rlen
< 0xFFFF ? 1 : 0;
297 return bitstream_tell(bc
) >> 3;
300 static int read_highpass(AVCodecContext
*avctx
, uint8_t *ptr
,
301 int plane
, AVFrame
*frame
)
303 PixletContext
*ctx
= avctx
->priv_data
;
304 ptrdiff_t stride
= frame
->linesize
[plane
] / 2;
307 for (i
= 0; i
< ctx
->levels
* 3; i
++) {
308 int32_t a
= bytestream2_get_be32(&ctx
->gb
);
309 int32_t b
= bytestream2_get_be32(&ctx
->gb
);
310 int32_t c
= bytestream2_get_be32(&ctx
->gb
);
311 int32_t d
= bytestream2_get_be32(&ctx
->gb
);
312 int16_t *dest
= (int16_t *)frame
->data
[plane
] +
313 ctx
->band
[plane
][i
+ 1].x
+
314 ctx
->band
[plane
][i
+ 1].y
* stride
;
315 size_t size
= ctx
->band
[plane
][i
+ 1].size
;
316 uint32_t magic
= bytestream2_get_be32(&ctx
->gb
);
318 if (magic
!= PIXLET_MAGIC
) {
319 av_log(avctx
, AV_LOG_ERROR
,
320 "wrong magic number: 0x%"PRIX32
" for plane %d, band %d\n",
322 return AVERROR_INVALIDDATA
;
325 ret
= read_high_coeffs(avctx
, ptr
+ bytestream2_tell(&ctx
->gb
), dest
,
326 size
, c
, (b
>= FFABS(a
)) ? b
: a
, d
,
327 ctx
->band
[plane
][i
+ 1].width
, stride
);
329 av_log(avctx
, AV_LOG_ERROR
,
330 "error in highpass coefficients for plane %d, band %d\n",
334 bytestream2_skip(&ctx
->gb
, ret
);
340 static void line_add_sat_s16(int16_t *dst
, const int16_t *src
, size_t len
)
343 for (i
= 0; i
< len
; i
++) {
344 int val
= dst
[i
] + src
[i
];
345 dst
[i
] = av_clip_int16(val
);
349 static void lowpass_prediction(int16_t *dst
, int16_t *pred
,
350 size_t width
, size_t height
, ptrdiff_t stride
)
354 memset(pred
, 0, width
* sizeof(*pred
));
356 for (i
= 0; i
< height
; i
++) {
357 line_add_sat_s16(pred
, dst
, width
);
359 for (j
= 1; j
< width
; j
++)
360 dst
[j
] = pred
[j
] + dst
[j
- 1];
365 static void filterfn(int16_t *dest
, int16_t *tmp
, size_t size
, int64_t scale
)
367 int16_t *low
, *high
, *ll
, *lh
, *hl
, *hh
;
373 high
= &low
[hsize
+ 8];
375 memcpy(low
, dest
, size
);
376 memcpy(high
, dest
+ hsize
, size
);
382 for (i
= 4, j
= 2; i
; i
--, j
++, ll
--, hh
++, lh
++, hl
--) {
383 low
[i
- 5] = low
[j
- 1];
385 high
[i
- 5] = high
[j
- 2];
389 for (i
= 0; i
< hsize
; i
++) {
390 value
= (int64_t) low
[i
+ 1] * -INT64_C(325392907) +
391 (int64_t) low
[i
+ 0] * INT64_C(3687786320) +
392 (int64_t) low
[i
- 1] * -INT64_C(325392907) +
393 (int64_t) high
[i
+ 0] * INT64_C(1518500249) +
394 (int64_t) high
[i
- 1] * INT64_C(1518500249);
395 dest
[i
* 2] = av_clip_int16(((value
>> 32) * scale
) >> 32);
398 for (i
= 0; i
< hsize
; i
++) {
399 value
= (int64_t) low
[i
+ 2] * -INT64_C(65078576) +
400 (int64_t) low
[i
+ 1] * INT64_C(1583578880) +
401 (int64_t) low
[i
+ 0] * INT64_C(1583578880) +
402 (int64_t) low
[i
- 1] * -INT64_C(65078576) +
403 (int64_t) high
[i
+ 1] * INT64_C(303700064) +
404 (int64_t) high
[i
+ 0] * -INT64_C(3644400640) +
405 (int64_t) high
[i
- 1] * INT64_C(303700064);
406 dest
[i
* 2 + 1] = av_clip_int16(((value
>> 32) * scale
) >> 32);
410 static void reconstruction(AVCodecContext
*avctx
, int16_t *dest
,
411 size_t width
, size_t height
, ptrdiff_t stride
,
412 int64_t *scaling_h
, int64_t *scaling_v
)
414 PixletContext
*ctx
= avctx
->priv_data
;
415 unsigned scaled_width
, scaled_height
;
419 scaled_width
= width
>> NB_LEVELS
;
420 scaled_height
= height
>> NB_LEVELS
;
421 tmp
= ctx
->filter
[0];
423 for (i
= 0; i
< NB_LEVELS
; i
++) {
424 int64_t scale_v
= scaling_v
[i
];
425 int64_t scale_h
= scaling_h
[i
];
430 for (j
= 0; j
< scaled_height
; j
++) {
431 filterfn(ptr
, ctx
->filter
[1], scaled_width
, scale_v
);
435 for (j
= 0; j
< scaled_width
; j
++) {
437 for (k
= 0; k
< scaled_height
; k
++) {
442 filterfn(tmp
, ctx
->filter
[1], scaled_height
, scale_h
);
445 for (k
= 0; k
< scaled_height
; k
++) {
453 static void postprocess_luma(AVFrame
*frame
, size_t w
, size_t h
, int depth
)
455 uint16_t *dsty
= (uint16_t *)frame
->data
[0];
456 int16_t *srcy
= (int16_t *)frame
->data
[0];
457 ptrdiff_t stridey
= frame
->linesize
[0] / 2;
460 for (j
= 0; j
< h
; j
++) {
461 for (i
= 0; i
< w
; i
++) {
464 else if (srcy
[i
] > ((1 << depth
) - 1))
467 dsty
[i
] = ((int64_t) srcy
[i
] * srcy
[i
] * 65535) /
468 ((1 << depth
) - 1) / ((1 << depth
) - 1);
475 static void postprocess_chroma(AVFrame
*frame
, int w
, int h
, int depth
)
477 uint16_t *dstu
= (uint16_t *)frame
->data
[1];
478 uint16_t *dstv
= (uint16_t *)frame
->data
[2];
479 int16_t *srcu
= (int16_t *)frame
->data
[1];
480 int16_t *srcv
= (int16_t *)frame
->data
[2];
481 ptrdiff_t strideu
= frame
->linesize
[1] / 2;
482 ptrdiff_t stridev
= frame
->linesize
[2] / 2;
483 const unsigned add
= 1 << (depth
- 1);
484 const unsigned shift
= 16 - depth
;
487 for (j
= 0; j
< h
; j
++) {
488 for (i
= 0; i
< w
; i
++) {
489 dstu
[i
] = av_clip_uintp2_c(add
+ srcu
[i
], depth
) << shift
;
490 dstv
[i
] = av_clip_uintp2_c(add
+ srcv
[i
], depth
) << shift
;
499 static int decode_plane(AVCodecContext
*avctx
, int plane
,
500 AVPacket
*avpkt
, AVFrame
*frame
)
502 PixletContext
*ctx
= avctx
->priv_data
;
503 ptrdiff_t stride
= frame
->linesize
[plane
] / 2;
504 unsigned shift
= plane
> 0;
508 for (i
= ctx
->levels
- 1; i
>= 0; i
--) {
509 int32_t h
= sign_extend(bytestream2_get_be32(&ctx
->gb
), 32);
510 int32_t v
= sign_extend(bytestream2_get_be32(&ctx
->gb
), 32);
513 return AVERROR_INVALIDDATA
;
515 ctx
->scaling
[plane
][H
][i
] = (1000000ULL << 32) / h
;
516 ctx
->scaling
[plane
][V
][i
] = (1000000ULL << 32) / v
;
519 bytestream2_skip(&ctx
->gb
, 4);
521 dst
= (int16_t *)frame
->data
[plane
];
522 dst
[0] = sign_extend(bytestream2_get_be16(&ctx
->gb
), 16);
524 ret
= bitstream_init8(&ctx
->bc
, avpkt
->data
+ bytestream2_tell(&ctx
->gb
),
525 bytestream2_get_bytes_left(&ctx
->gb
));
529 ret
= read_low_coeffs(avctx
, dst
+ 1, ctx
->band
[plane
][0].width
- 1,
530 ctx
->band
[plane
][0].width
- 1, 0);
532 av_log(avctx
, AV_LOG_ERROR
,
533 "error in lowpass coefficients for plane %d, top row\n", plane
);
537 ret
= read_low_coeffs(avctx
, dst
+ stride
,
538 ctx
->band
[plane
][0].height
- 1, 1, stride
);
540 av_log(avctx
, AV_LOG_ERROR
,
541 "error in lowpass coefficients for plane %d, left column\n",
546 ret
= read_low_coeffs(avctx
, dst
+ stride
+ 1,
547 (ctx
->band
[plane
][0].width
- 1) * (ctx
->band
[plane
][0].height
- 1),
548 ctx
->band
[plane
][0].width
- 1, stride
);
550 av_log(avctx
, AV_LOG_ERROR
,
551 "error in lowpass coefficients for plane %d, rest\n", plane
);
555 bytestream2_skip(&ctx
->gb
, ret
);
556 if (bytestream2_get_bytes_left(&ctx
->gb
) <= 0) {
557 av_log(avctx
, AV_LOG_ERROR
, "no bytes left\n");
558 return AVERROR_INVALIDDATA
;
561 ret
= read_highpass(avctx
, avpkt
->data
, plane
, frame
);
565 lowpass_prediction(dst
, ctx
->prediction
, ctx
->band
[plane
][0].width
,
566 ctx
->band
[plane
][0].height
, stride
);
568 reconstruction(avctx
, (int16_t *)frame
->data
[plane
], ctx
->w
>> shift
,
569 ctx
->h
>> shift
, stride
, ctx
->scaling
[plane
][H
],
570 ctx
->scaling
[plane
][V
]);
575 static int pixlet_decode_frame(AVCodecContext
*avctx
, void *data
,
576 int *got_frame
, AVPacket
*avpkt
)
578 PixletContext
*ctx
= avctx
->priv_data
;
579 int i
, w
, h
, width
, height
, ret
, version
;
581 ThreadFrame frame
= { .f
= data
};
584 bytestream2_init(&ctx
->gb
, avpkt
->data
, avpkt
->size
);
586 pktsize
= bytestream2_get_be32(&ctx
->gb
);
587 if (pktsize
<= 44 || pktsize
- 4 > bytestream2_get_bytes_left(&ctx
->gb
)) {
588 av_log(avctx
, AV_LOG_ERROR
, "Invalid packet size %"PRIu32
".\n", pktsize
);
589 return AVERROR_INVALIDDATA
;
592 version
= bytestream2_get_le32(&ctx
->gb
);
594 avpriv_request_sample(avctx
, "Version %d", version
);
596 bytestream2_skip(&ctx
->gb
, 4);
597 if (bytestream2_get_be32(&ctx
->gb
) != 1)
598 return AVERROR_INVALIDDATA
;
599 bytestream2_skip(&ctx
->gb
, 4);
601 width
= bytestream2_get_be32(&ctx
->gb
);
602 height
= bytestream2_get_be32(&ctx
->gb
);
604 w
= FFALIGN(width
, 1 << (NB_LEVELS
+ 1));
605 h
= FFALIGN(height
, 1 << (NB_LEVELS
+ 1));
607 ctx
->levels
= bytestream2_get_be32(&ctx
->gb
);
608 if (ctx
->levels
!= NB_LEVELS
)
609 return AVERROR_INVALIDDATA
;
610 ctx
->depth
= bytestream2_get_be32(&ctx
->gb
);
611 if (ctx
->depth
< 8 || ctx
->depth
> 15) {
612 avpriv_request_sample(avctx
, "Depth %d", ctx
->depth
);
613 return AVERROR_INVALIDDATA
;
616 ret
= ff_set_dimensions(avctx
, w
, h
);
619 avctx
->width
= width
;
620 avctx
->height
= height
;
622 /* reinit should dimensions change */
623 if (ctx
->w
!= w
|| ctx
->h
!= h
) {
628 ret
= init_decoder(avctx
);
637 bytestream2_skip(&ctx
->gb
, 8);
639 ret
= ff_thread_get_buffer(avctx
, &frame
, 0);
643 for (i
= 0; i
< 3; i
++) {
644 ret
= decode_plane(avctx
, i
, avpkt
, frame
.f
);
647 if (avctx
->flags
& AV_CODEC_FLAG_GRAY
)
651 postprocess_luma(frame
.f
, ctx
->w
, ctx
->h
, ctx
->depth
);
652 postprocess_chroma(frame
.f
, ctx
->w
>> 1, ctx
->h
>> 1, ctx
->depth
);
654 p
->pict_type
= AV_PICTURE_TYPE_I
;
655 p
->color_range
= AVCOL_RANGE_JPEG
;
664 static int pixlet_init_thread_copy(AVCodecContext
*avctx
)
666 PixletContext
*ctx
= avctx
->priv_data
;
668 ctx
->filter
[0] = NULL
;
669 ctx
->filter
[1] = NULL
;
670 ctx
->prediction
= NULL
;
676 #endif /* HAVE_THREADS */
678 AVCodec ff_pixlet_decoder
= {
680 .long_name
= NULL_IF_CONFIG_SMALL("Apple Pixlet"),
681 .type
= AVMEDIA_TYPE_VIDEO
,
682 .id
= AV_CODEC_ID_PIXLET
,
684 .init_thread_copy
= ONLY_IF_THREADS_ENABLED(pixlet_init_thread_copy
),
685 .close
= pixlet_close
,
686 .decode
= pixlet_decode_frame
,
687 .priv_data_size
= sizeof(PixletContext
),
688 .capabilities
= AV_CODEC_CAP_DR1
|
689 AV_CODEC_CAP_FRAME_THREADS
,
690 .caps_internal
= FF_CODEC_CAP_INIT_THREADSAFE
|
691 FF_CODEC_CAP_INIT_CLEANUP
,