1bf61bd23d72c9e58fb9e8a8b9363d28d6f4fe34
2 * Lagarith lossless decoder
3 * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
5 * This file is part of FFmpeg.
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.
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.
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
23 * @file libavcodec/lagarith.c
24 * Lagarith lossless decoder
25 * @author Nathan Caldwell
32 #include "lagarithrac.h"
34 enum LagarithFrameType
{
35 FRAME_RAW
= 1, /*!< uncompressed */
36 FRAME_U_RGB24
= 2, /*!< unaligned RGB24 */
37 FRAME_ARITH_YUY2
= 3, /*!< arithmetic coded YUY2 */
38 FRAME_ARITH_RGB24
= 4, /*!< arithmetic coded RGB24 */
39 FRAME_SOLID_GRAY
= 5, /*!< solid grayscale color frame */
40 FRAME_SOLID_COLOR
= 6, /*!< solid non-grayscale color frame */
41 FRAME_OLD_ARITH_RGB
= 7, /*!< obsolete arithmetic coded RGB (no longer encoded by upstream since version 1.1.0) */
42 FRAME_ARITH_RGBA
= 8, /*!< arithmetic coded RGBA */
43 FRAME_SOLID_RGBA
= 9, /*!< solid RGBA color frame */
44 FRAME_ARITH_YV12
= 10, /*!< arithmetic coded YV12 */
45 FRAME_REDUCED_RES
= 11, /*!< reduced resolution YV12 frame */
48 typedef struct LagarithContext
{
49 AVCodecContext
*avctx
;
52 int zeros
; /*!< number of consecutive zero bytes encountered */
53 int zeros_rem
; /*!< number of zero bytes remaining to output */
57 * Compute the 52bit mantissa of 1/(double)denom.
58 * This crazy format uses floats in an entropy coder and we have to match x86
59 * rounding exactly, thus ordinary floats aren't portable enough.
60 * @param denom denominator
61 * @return 52bit mantissa
64 static uint64_t softfloat_reciprocal(uint32_t denom
)
66 int shift
= av_log2(denom
- 1) + 1;
67 uint64_t ret
= (1ULL << 52) / denom
;
68 uint64_t err
= (1ULL << 52) - ret
* denom
;
72 return ret
+ err
/ denom
;
76 * (uint32_t)(x*f), where f has the given mantissa, and exponent 0
77 * Used in combination with softfloat_reciprocal computes x/(double)denom.
78 * @param x 32bit integer factor
79 * @param mantissa mantissa of f with exponent 0
80 * @return 32bit integer value (x*f)
81 * @see softfloat_reciprocal
83 static uint32_t softfloat_mul(uint32_t x
, uint64_t mantissa
)
85 uint64_t l
= x
* (mantissa
& 0xffffffff);
86 uint64_t h
= x
* (mantissa
>> 32);
89 l
+= 1 << av_log2(h
>> 21);
94 static uint8_t lag_calc_zero_run(int8_t x
)
96 return (x
<< 1) ^ (x
>> 7);
99 static int lag_decode_prob(GetBitContext
*gb
, uint32_t *value
)
101 static const uint8_t series
[] = { 1, 2, 3, 5, 8, 13, 21 };
108 for (i
= 0; i
< 7; i
++) {
117 if (bits
< 0 || bits
> 31) {
120 } else if (bits
== 0) {
125 val
= get_bits_long(gb
, bits
);
133 static int lag_read_prob_header(lag_rac
*rac
, GetBitContext
*gb
)
135 int i
, j
, scale_factor
;
136 unsigned prob
, cumulative_target
;
137 unsigned cumul_prob
= 0;
138 unsigned scaled_cumul_prob
= 0;
141 rac
->prob
[257] = UINT_MAX
;
142 /* Read probabilities from bitstream */
143 for (i
= 1; i
< 257; i
++) {
144 if (lag_decode_prob(gb
, &rac
->prob
[i
]) < 0) {
145 av_log(rac
->avctx
, AV_LOG_ERROR
, "Invalid probability encountered.\n");
148 if ((uint64_t)cumul_prob
+ rac
->prob
[i
] > UINT_MAX
) {
149 av_log(rac
->avctx
, AV_LOG_ERROR
, "Integer overflow encountered in cumulative probability calculation.\n");
152 cumul_prob
+= rac
->prob
[i
];
154 if (lag_decode_prob(gb
, &prob
)) {
155 av_log(rac
->avctx
, AV_LOG_ERROR
, "Invalid probability run encountered.\n");
160 for (j
= 0; j
< prob
; j
++)
166 av_log(rac
->avctx
, AV_LOG_ERROR
, "All probabilities are 0!\n");
170 /* Scale probabilities so cumulative probability is an even power of 2. */
171 scale_factor
= av_log2(cumul_prob
);
173 if (cumul_prob
& (cumul_prob
- 1)) {
174 uint64_t mul
= softfloat_reciprocal(cumul_prob
);
175 for (i
= 1; i
< 257; i
++) {
176 rac
->prob
[i
] = softfloat_mul(rac
->prob
[i
], mul
);
177 scaled_cumul_prob
+= rac
->prob
[i
];
181 cumulative_target
= 1 << scale_factor
;
183 if (scaled_cumul_prob
> cumulative_target
) {
184 av_log(rac
->avctx
, AV_LOG_ERROR
,
185 "Scaled probabilities are larger than target!\n");
189 scaled_cumul_prob
= cumulative_target
- scaled_cumul_prob
;
191 for (i
= 1; scaled_cumul_prob
; i
= (i
& 0x7f) + 1) {
196 /* Comment from reference source:
197 * if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way
198 * // since the compression change is negligable and fixing it
199 * // breaks backwards compatibilty
200 * b =- (signed int)b;
210 rac
->scale
= scale_factor
;
212 /* Fill probability array with cumulative probability for each symbol. */
213 for (i
= 1; i
< 257; i
++)
214 rac
->prob
[i
] += rac
->prob
[i
- 1];
219 static void add_lag_median_prediction(uint8_t *dst
, uint8_t *src1
,
220 uint8_t *diff
, int w
, int *left
,
223 /* This is almost identical to add_hfyu_median_prediction in dsputil.h.
224 * However the &0xFF on the gradient predictor yealds incorrect output
233 for (i
= 0; i
< w
; i
++) {
234 l
= mid_pred(l
, src1
[i
], l
+ src1
[i
] - lt
) + diff
[i
];
243 static void lag_pred_line(LagarithContext
*l
, uint8_t *buf
,
244 int width
, int stride
, int line
)
249 /* Left prediction only for first line */
250 L
= l
->dsp
.add_hfyu_left_prediction(buf
+ 1, buf
+ 1,
253 } else if (line
== 1) {
254 /* Second line, left predict first pixel, the rest of the line is median predicted */
255 /* FIXME: In the case of RGB this pixel is top predicted */
258 /* Top left is 2 rows back, last pixel */
259 TL
= buf
[width
- (2 * stride
) - 1];
261 /* Left pixel is actually prev_row[width] */
262 L
= buf
[width
- stride
- 1];
264 add_lag_median_prediction(buf
, buf
- stride
, buf
,
268 static int lag_decode_line(LagarithContext
*l
, lag_rac
*rac
,
269 uint8_t *dst
, int width
, int stride
,
278 /* Output any zeros remaining from the previous run */
281 int count
= FFMIN(l
->zeros_rem
, width
- i
);
282 memset(dst
+ i
, 0, count
);
284 l
->zeros_rem
-= count
;
288 dst
[i
] = lag_get_rac(rac
);
297 if (l
->zeros
== esc_count
) {
298 int index
= lag_get_rac(rac
);
303 l
->zeros_rem
= lag_calc_zero_run(index
);
310 static int lag_decode_zero_run_line(LagarithContext
*l
, uint8_t *dst
,
311 const uint8_t *src
, int width
,
316 uint8_t zero_run
= 0;
317 const uint8_t *start
= src
;
318 uint8_t mask1
= -(esc_count
< 2);
319 uint8_t mask2
= -(esc_count
< 3);
320 uint8_t *end
= dst
+ (width
- 2);
324 count
= FFMIN(l
->zeros_rem
, width
- i
);
325 memset(dst
, 0, count
);
326 l
->zeros_rem
-= count
;
332 while (!zero_run
&& dst
+ i
< end
) {
335 !(src
[i
] | (src
[i
+ 1] & mask1
) | (src
[i
+ 2] & mask2
));
342 l
->zeros_rem
= lag_calc_zero_run(src
[i
]);
356 static int lag_decode_arith_plane(LagarithContext
*l
, uint8_t *dst
,
357 int width
, int height
, int stride
,
358 const uint8_t *src
, int src_size
)
364 int esc_count
= src
[0];
368 rac
.avctx
= l
->avctx
;
372 length
= width
* height
;
373 if (esc_count
&& AV_RL32(src
+ 1) < length
) {
374 length
= AV_RL32(src
+ 1);
378 init_get_bits(&gb
, src
+ offset
, src_size
* 8);
380 if (lag_read_prob_header(&rac
, &gb
) < 0)
383 lag_rac_init(&rac
, &gb
, length
- stride
);
385 for (i
= 0; i
< height
; i
++)
386 read
+= lag_decode_line(l
, &rac
, dst
+ (i
* stride
), width
,
390 av_log(l
->avctx
, AV_LOG_WARNING
,
391 "Output more bytes than length (%d of %d)\n", read
,
393 } else if (esc_count
< 8) {
396 /* Zero run coding only, no range coding. */
397 for (i
= 0; i
< height
; i
++)
398 src
+= lag_decode_zero_run_line(l
, dst
+ (i
* stride
), src
,
401 /* Plane is stored uncompressed */
402 for (i
= 0; i
< height
; i
++) {
403 memcpy(dst
+ (i
* stride
), src
, width
);
407 } else if (esc_count
== 0xff) {
408 /* Plane is a solid run of given value */
409 for (i
= 0; i
< height
; i
++)
410 memset(dst
+ i
* stride
, src
[1], width
);
411 /* Do not apply prediction.
412 Note: memset to 0 above, setting first value to src[1]
413 and applying prediction gives the same result. */
416 av_log(l
->avctx
, AV_LOG_ERROR
,
417 "Invalid zero run escape code! (%#x)\n", esc_count
);
421 for (i
= 0; i
< height
; i
++) {
422 lag_pred_line(l
, dst
, width
, stride
, i
);
431 * @param avctx codec context
432 * @param data output AVFrame
433 * @param data_size size of output data or 0 if no picture is returned
434 * @param avpkt input packet
435 * @return number of consumed bytes on success or negative if decode fails
437 static int lag_decode_frame(AVCodecContext
*avctx
,
438 void *data
, int *data_size
, AVPacket
*avpkt
)
440 const uint8_t *buf
= avpkt
->data
;
441 int buf_size
= avpkt
->size
;
442 LagarithContext
*l
= avctx
->priv_data
;
443 AVFrame
*const p
= &l
->picture
;
444 uint8_t frametype
= 0;
445 uint32_t offset_gu
= 0, offset_bv
= 0, offset_ry
= 9;
447 AVFrame
*picture
= data
;
450 avctx
->release_buffer(avctx
, p
);
457 offset_gu
= AV_RL32(buf
+ 1);
458 offset_bv
= AV_RL32(buf
+ 5);
461 case FRAME_ARITH_YV12
:
462 avctx
->pix_fmt
= PIX_FMT_YUV420P
;
464 if (avctx
->get_buffer(avctx
, p
) < 0) {
465 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
469 lag_decode_arith_plane(l
, p
->data
[0], avctx
->width
, avctx
->height
,
470 p
->linesize
[0], buf
+ offset_ry
,
472 lag_decode_arith_plane(l
, p
->data
[2], avctx
->width
/ 2,
473 avctx
->height
/ 2, p
->linesize
[2],
474 buf
+ offset_gu
, buf_size
);
475 lag_decode_arith_plane(l
, p
->data
[1], avctx
->width
/ 2,
476 avctx
->height
/ 2, p
->linesize
[1],
477 buf
+ offset_bv
, buf_size
);
480 av_log(avctx
, AV_LOG_ERROR
,
481 "Unsupported Lagarith frame type: %#x\n", frametype
);
486 *data_size
= sizeof(AVFrame
);
491 static av_cold
int lag_decode_init(AVCodecContext
*avctx
)
493 LagarithContext
*l
= avctx
->priv_data
;
496 dsputil_init(&l
->dsp
, avctx
);
501 static av_cold
int lag_decode_end(AVCodecContext
*avctx
)
503 LagarithContext
*l
= avctx
->priv_data
;
505 if (l
->picture
.data
[0])
506 avctx
->release_buffer(avctx
, &l
->picture
);
511 AVCodec lagarith_decoder
= {
515 sizeof(LagarithContext
),
521 .long_name
= NULL_IF_CONFIG_SMALL("Lagarith lossless"),