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
35 typedef struct LagarithContext
{
36 AVCodecContext
*avctx
;
38 int zeros
; /*!< Number of consecutave zero bytes encountered. */
39 int zeros_rem
; /*!< Number of zero bytes remaining to output. */
42 static av_cold
int lag_decode_init(AVCodecContext
*avctx
)
44 LagarithContext
*l
= avctx
->priv_data
;
51 static void lag_memset(uint8_t *s
, uint8_t c
, size_t n
, int step
)
59 for (i
= 0; i
< n
* step
; i
+= step
)
63 static uint8_t *lag_memcpy(uint8_t *dest
, const uint8_t *src
, size_t n
,
68 return memcpy(dest
, src
, n
);
70 for (i
= 0; i
< n
* step
; i
+= step
)
75 static inline int lag_predict(uint8_t *src
, int stride
, int step
)
79 int TL
= src
[-stride
- step
];
81 return mid_pred(T
, L
, L
+ T
- TL
);
84 static uint8_t lag_calc_zero_run(int8_t x
)
88 if (x
> 255) return ~x
;
91 return (x
<< 1) ^ (x
>> 7);
94 static uint32_t lag_decode_prob(GetBitContext
*gb
)
96 static const uint8_t series
[] = { 1, 2, 3, 5, 8, 13, 21, 34 };
103 for (i
= 0; !(prevbit
&& bit
); i
++) {
113 /* This is most likely an error, just use the final 32 bits */
114 skip_bits_long(gb
, bits
- 31);
118 value
= get_bits_long(gb
, bits
);
124 static int lag_read_prob_header(lag_rac
*rac
, GetBitContext
*gb
)
128 double scale_factor
= 0;
129 unsigned cumul_prob
= 0;
130 unsigned cumulative_target
= 1;
131 unsigned scaled_cumul_prob
= 0;
134 /* Read probabilities from bitstream */
135 for (i
= 1; i
< 257; i
++) {
136 rac
->prob
[i
] = lag_decode_prob(gb
);
137 cumul_prob
+= rac
->prob
[i
];
139 prob
= lag_decode_prob(gb
);
142 for (j
= 0; j
< prob
; j
++)
147 /* Scale probabilities so cumulative probability is an even power of 2. */
148 cumulative_target
= 2 << av_log2(cumul_prob
-1);
150 scale_factor
= cumulative_target
/ (double) cumul_prob
;
152 for (i
= 1; i
< 257; i
++) {
153 rac
->prob
[i
] = (unsigned) (rac
->prob
[i
] * scale_factor
);
154 scaled_cumul_prob
+= rac
->prob
[i
];
157 scaled_cumul_prob
= cumulative_target
- scaled_cumul_prob
;
159 if (scaled_cumul_prob
> INT_MAX
) {
160 av_log(rac
->avctx
, AV_LOG_ERROR
,
161 "Scaled cumulative probability is larger than target!");
165 for (i
= 1; scaled_cumul_prob
; i
= (i
& 0x7f) + 1) {
170 /* Comment from reference source:
171 * if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way
172 * // since the compression change is negligable and fixing it
173 * // breaks backwards compatibilty
174 * b =- (signed int)b;
183 rac
->scale
= cumulative_target
? av_log2(cumulative_target
) : 0;
185 /* Fill probability array with cumulative probability for each symbol. */
186 for (i
= 1; i
< 257; i
++)
187 rac
->prob
[i
] += rac
->prob
[i
- 1];
192 static void lag_pred_line(LagarithContext
*l
, uint8_t *buf
,
193 int width
, int stride
, int step
, int mode
)
196 int width_scaled
= width
* step
;
199 /* Left prediction only for first line */
200 for (i
= step
; i
< width_scaled
; i
+= step
)
201 buf
[i
] += buf
[i
- step
];
202 } else if (mode
== 1) {
203 /* Second line, left predict first pixel, the rest of the line is median predicted */
204 /* FIXME: In the case of RGB this pixel is top predicted */
205 buf
[i
] += buf
[width_scaled
- stride
- step
];
208 /* Special case for first pixel in a row */
209 int T
= buf
[-stride
];
210 /* Left pixel is actually prev_row[width] */
211 int L
= buf
[width_scaled
- stride
- step
];
212 /* Top left is 2 rows back, last pixel */
213 int TL
= buf
[width_scaled
- (2 * stride
) - step
];
215 buf
[i
] += mid_pred(T
, L
, L
+ T
- TL
);
219 while (i
< width_scaled
) {
220 buf
[i
] += lag_predict(buf
+ i
, stride
, step
);
225 static int lag_decode_line(LagarithContext
*l
, lag_rac
*rac
,
226 uint8_t *dst
, int width
, int stride
,
227 int step
, int esc_count
)
232 /* Output any zeros remaining from the previous run */
234 int count
= FFMIN(l
->zeros_rem
, width
);
235 lag_memset(dst
+ i
* step
, 0, count
, step
);
237 l
->zeros_rem
-= count
;
242 dst
[i
* step
] = lag_get_rac(rac
);
251 if (esc_count
&& (l
->zeros
== esc_count
)) {
253 int index
= lag_get_rac(rac
);
259 count
= lag_calc_zero_run(index
);
261 if (i
+ count
> width
)
266 lag_memset(dst
+ i
* step
, 0, count
, step
);
269 l
->zeros_rem
-= count
;
275 static int lag_decode_zero_run_line(LagarithContext
*l
, uint8_t *dst
,
276 const uint8_t *src
, int width
,
277 int step
, int esc_count
)
281 uint8_t zero_run
= 1;
282 const uint8_t *start
= src
;
283 uint8_t mask1
= -(esc_count
< 2);
284 uint8_t mask2
= -(esc_count
< 3);
285 uint8_t *end
= dst
+ (width
- 2) * step
;
288 count
= l
->zeros_rem
;
291 lag_memset(dst
, 0, count
, step
);
292 l
->zeros_rem
-= count
;
298 while (!zero_run
&& dst
+ i
* step
< end
) {
301 (src
[i
] | (src
[i
+ 1] & mask1
) | (src
[i
+ 2] & mask2
));
305 lag_memcpy(dst
, src
, i
, step
);
308 count
= lag_calc_zero_run(src
[i
]);
310 if (dst
+ l
->zeros_rem
* step
> end
)
311 count
= (end
- dst
) / step
;
313 lag_memset(dst
, 0, count
, step
);
316 l
->zeros_rem
-= count
;
318 lag_memcpy(dst
, src
, i
, step
);
327 static int lag_decode_arith_plane(LagarithContext
*l
, uint8_t *dst
,
328 int width
, int height
, int stride
,
329 int step
, const uint8_t *src
,
336 int esc_count
= src
[0];
342 length
= AV_RL32(src
+ 1);
343 if (length
< width
* height
)
346 length
= width
* height
;
348 length
= width
* height
;
350 init_get_bits(&gb
, src
+ offset
, src_size
* 8);
352 if (lag_read_prob_header(&rac
, &gb
) < 0)
355 lag_rac_init(&rac
, &gb
, length
- stride
);
357 for (i
= 0; i
< height
; i
++)
359 lag_decode_line(l
, &rac
, dst
+ (i
* stride
), width
,
360 stride
, step
, esc_count
);
363 av_log(l
->avctx
, AV_LOG_WARNING
,
364 "Read more bytes than length (%d of %d)\n", read
,
366 } else if (esc_count
< 8) {
369 /* Zero run coding only, no range coding. */
370 for (i
= 0; i
< height
; i
++)
372 lag_decode_zero_run_line(l
, dst
+ (i
* stride
),
373 src
, width
, step
, esc_count
);
375 /* Plane is stored uncompressed */
376 for (i
= 0; i
< height
; i
++) {
377 lag_memcpy(dst
+ (i
* stride
), src
, width
, step
);
381 } else if (esc_count
== 0xff) {
382 /* Plane is a solid run of 0 bytes */
383 memset(dst
, 0, stride
* height
);
385 av_log(l
->avctx
, AV_LOG_ERROR
,
386 "Invalid zero run escape code! (%#x)", esc_count
);
390 for (i
= 0; i
< height
; i
++) {
391 lag_pred_line(l
, dst
, width
, stride
, step
, i
);
400 * @param avctx codec context
401 * @param data output AVFrame
402 * @param data_size size of output data or 0 if no picture is returned
403 * @param avpkt input packet
404 * @return number of consumed bytes on success or negative if decode fails
406 static int lag_decode_frame(AVCodecContext
*avctx
,
407 void *data
, int *data_size
, AVPacket
*avpkt
)
409 const uint8_t *buf
= avpkt
->data
;
410 int buf_size
= avpkt
->size
;
411 LagarithContext
*l
= avctx
->priv_data
;
412 AVFrame
*const p
= &l
->picture
;
413 uint8_t frametype
= 0;
414 uint32_t offset_gu
= 0, offset_bv
= 0, offset_ry
= 9;
416 AVFrame
*picture
= data
;
419 avctx
->release_buffer(avctx
, p
);
426 offset_gu
= AV_RL32(buf
+ 1);
427 offset_bv
= AV_RL32(buf
+ 5);
430 case FRAME_ARITH_YV12
:
431 avctx
->pix_fmt
= PIX_FMT_YUV420P
;
433 if (avctx
->get_buffer(avctx
, p
) < 0) {
434 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
438 lag_decode_arith_plane(l
, p
->data
[0], avctx
->width
, avctx
->height
,
439 p
->linesize
[0], 1, buf
+ offset_ry
,
441 lag_decode_arith_plane(l
, p
->data
[2], avctx
->width
/ 2,
442 avctx
->height
/ 2, p
->linesize
[2], 1,
443 buf
+ offset_gu
, buf_size
);
444 lag_decode_arith_plane(l
, p
->data
[1], avctx
->width
/ 2,
445 avctx
->height
/ 2, p
->linesize
[1], 1,
446 buf
+ offset_bv
, buf_size
);
449 av_log(avctx
, AV_LOG_ERROR
,
450 "Unsupported Lagarith frame type: %#x\n", frametype
);
454 *picture
= *(AVFrame
*) & l
->picture
;
455 *data_size
= sizeof(AVPicture
);
460 AVCodec lagarith_decoder
= {
464 sizeof(LagarithContext
),
470 .long_name
= NULL_IF_CONFIG_SMALL("Lagarith"),