Remove lag_decode_init
[FFMpeg-mirror/lagarith.git] / libavcodec / lagarith.c
blob5db517dce398f1d5b6cbaadf2d8d7daf6e14ee9f
1 /*
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
22 /**
23 * @file libavcodec/lagarith.c
24 * Lagarith lossless decoder
25 * @author Nathan Caldwell
29 #include "avcodec.h"
30 #include "get_bits.h"
31 #include "mathops.h"
32 #include "lagarith.h"
33 #include "lagarithrac.h"
35 typedef struct LagarithContext {
36 AVCodecContext *avctx;
37 AVFrame picture;
38 int zeros; /*!< number of consecutave zero bytes encountered */
39 int zeros_rem; /*!< number of zero bytes remaining to output */
40 } LagarithContext;
42 static void lag_memset(uint8_t *s, uint8_t c, size_t n, int step)
44 int i;
45 if (step == 1) {
46 memset(s, c, n);
47 return;
50 for (i = 0; i < n * step; i += step)
51 s[i] = c;
54 static uint8_t *lag_memcpy(uint8_t *dest, const uint8_t *src, size_t n,
55 int step)
57 int i, j;
58 if (step == 1)
59 return memcpy(dest, src, n);
61 for (i = j = 0; i < n ; i++) {
62 dest[j] = src[i];
63 j += step;
65 return dest;
68 static uint8_t lag_calc_zero_run(int8_t x)
70 return (x << 1) ^ (x >> 7);
73 static uint32_t lag_decode_prob(GetBitContext *gb)
75 static const uint8_t series[] = { 1, 2, 3, 5, 8, 13, 21, 34 };
76 int i = 0;
77 int bit = 0;
78 int bits = 0;
79 int prevbit = 0;
80 unsigned value = 1;
82 for (i = 0; i < 7; i++) {
83 if (prevbit && bit)
84 break;
85 prevbit = bit;
86 bit = get_bits1(gb);
87 if (bit && !prevbit)
88 bits += series[i];
90 bits--;
91 if (bits <= 0)
92 return 0;
93 if (bits > 31) {
94 /* This is most likely an error, just use the first 32 bits */
95 bits = 31;
98 value = get_bits_long(gb, bits);
99 value |= 1 << bits;
101 return value - 1;
104 static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb)
106 int i, j;
107 int prob = 0;
108 int scale_factor = 0;
109 unsigned cumul_prob = 0;
110 unsigned cumulative_target = 1;
111 unsigned scaled_cumul_prob = 0;
113 rac->prob[0] = 0;
114 rac->prob[257] = UINT_MAX;
115 /* Read probabilities from bitstream */
116 for (i = 1; i < 257; i++) {
117 rac->prob[i] = lag_decode_prob(gb);
118 cumul_prob += rac->prob[i];
119 if (!rac->prob[i]) {
120 prob = lag_decode_prob(gb);
121 if (i + prob >= 258)
122 prob = 257 - i;
123 for (j = 0; j < prob; j++)
124 rac->prob[++i] = 0;
128 if (!cumul_prob) {
129 av_log(rac->avctx, AV_LOG_ERROR, "All probabilities are 0!\n");
130 return -1;
133 /* Scale probabilities so cumulative probability is an even power of 2. */
134 scale_factor = av_log2(cumul_prob);
136 if (cumul_prob & (cumul_prob - 1)) {
137 scale_factor++;
138 for (i = 1; i < 257; i++) {
139 rac->prob[i] =
140 ((uint64_t) rac->prob[i] << scale_factor) / cumul_prob;
141 scaled_cumul_prob += rac->prob[i];
144 cumulative_target = 1 << scale_factor;
146 if (scaled_cumul_prob > cumulative_target) {
147 av_log(rac->avctx, AV_LOG_ERROR,
148 "Scaled probabilities are larger than target!\n");
149 return -1;
152 scaled_cumul_prob = cumulative_target - scaled_cumul_prob;
154 for (i = 1; scaled_cumul_prob; i = (i & 0x7f) + 1) {
155 if (rac->prob[i]) {
156 rac->prob[i]++;
157 scaled_cumul_prob--;
159 /* Comment from reference source:
160 * if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way
161 * // since the compression change is negligable and fixing it
162 * // breaks backwards compatibilty
163 * b =- (signed int)b;
164 * b &= 0xFF;
165 * } else {
166 * b++;
167 * b &= 0x7f;
173 rac->scale = scale_factor;
175 /* Fill probability array with cumulative probability for each symbol. */
176 for (i = 1; i < 257; i++)
177 rac->prob[i] += rac->prob[i - 1];
179 return 0;
182 static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1,
183 uint8_t *diff, int w, int *left,
184 int *left_top)
186 /* This is almost identical to add_hfyu_median_prediction in dsputil.h.
187 * However the &0xFF on the gradient predictor yealds incorrect output
188 * for lagarith.
190 int i;
191 uint8_t l, lt;
193 l = *left;
194 lt = *left_top;
196 for (i = 0; i < w; i++) {
197 l = mid_pred(l, src1[i], l + src1[i] - lt) + diff[i];
198 lt = src1[i];
199 dst[i] = l;
202 *left = l;
203 *left_top = lt;
206 static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w,
207 int acc)
209 int i;
211 for (i = 0; i < w - 1; i++) {
212 acc += src[i];
213 dst[i] = acc;
214 i++;
215 acc += src[i];
216 dst[i] = acc;
219 for (; i < w; i++) {
220 acc += src[i];
221 dst[i] = acc;
224 return acc;
227 static void lag_pred_line(LagarithContext *l, uint8_t *buf,
228 int width, int stride, int step, int line)
230 int i = 0;
231 int L, TL;
232 int width_scaled = width * step;
234 if (!line) {
235 /* Left prediction only for first line */
236 L = add_left_prediction(buf + step, buf + step, width - step,
237 buf[0]);
238 return;
239 } else if (line == 1) {
240 /* Second line, left predict first pixel, the rest of the line is median predicted */
241 /* FIXME: In the case of RGB this pixel is top predicted */
242 TL = buf[-stride];
243 L = add_left_prediction(buf, buf, 1,
244 buf[width_scaled - stride - step]);
245 i += step;
246 } else {
247 /* Left pixel is actually prev_row[width] */
248 L = buf[width_scaled - stride - step];
249 /* Top left is 2 rows back, last pixel */
250 TL = buf[width_scaled - (2 * stride) - step];
253 if (i < width_scaled)
254 add_lag_median_prediction(buf + i, buf - stride + i, buf + i,
255 width_scaled - i, &L, &TL);
258 static int lag_decode_line(LagarithContext *l, lag_rac *rac,
259 uint8_t *dst, int width, int stride,
260 int step, int esc_count)
262 int i = 0;
263 int ret = 0;
265 /* Output any zeros remaining from the previous run */
266 if (l->zeros_rem) {
267 int count = FFMIN(l->zeros_rem, width);
268 lag_memset(dst + i * step, 0, count, step);
269 i += count;
270 l->zeros_rem -= count;
273 while (i < width) {
275 dst[i * step] = lag_get_rac(rac);
276 ret++;
278 if (dst[i * step])
279 l->zeros = 0;
280 else
281 l->zeros++;
283 i++;
284 if (esc_count && (l->zeros == esc_count)) {
285 int count;
286 int index = lag_get_rac(rac);
287 ret++;
289 l->zeros = 0;
291 l->zeros_rem =
292 count = lag_calc_zero_run(index);
294 if (i + count > width)
295 count = width - i;
296 if (!count)
297 continue;
299 lag_memset(dst + i * step, 0, count, step);
301 i += count;
302 l->zeros_rem -= count;
305 return ret;
308 static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst,
309 const uint8_t *src, int width,
310 int step, int esc_count)
312 int i = 0;
313 int count;
314 uint8_t zero_run = 1;
315 const uint8_t *start = src;
316 uint8_t mask1 = -(esc_count < 2);
317 uint8_t mask2 = -(esc_count < 3);
318 uint8_t *end = dst + (width - 2) * step;
320 if (l->zeros_rem) {
321 count = FFMIN(l->zeros_rem, width);
322 lag_memset(dst, 0, count, step);
323 l->zeros_rem -= count;
324 dst += count;
327 while (dst < end) {
328 i = 0;
329 while (!zero_run && dst + i * step < end) {
330 i++;
331 zero_run =
332 (src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
334 if (!zero_run) {
335 i += esc_count;
336 lag_memcpy(dst, src, i, step);
337 dst += i;
338 l->zeros_rem =
339 count = lag_calc_zero_run(src[i]);
341 if (dst + l->zeros_rem * step > end)
342 count = (end - dst) / step;
344 lag_memset(dst, 0, count, step);
345 dst += count;
346 src += i + 1;
347 l->zeros_rem -= count;
348 } else {
349 lag_memcpy(dst, src, i, step);
350 src += i;
353 return start - src;
358 static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
359 int width, int height, int stride,
360 int step, const uint8_t *src,
361 int src_size)
363 int i = 0;
364 int read = 0;
365 uint32_t length;
366 uint32_t offset = 1;
367 int esc_count = src[0];
368 GetBitContext gb;
369 lag_rac rac;
371 rac.avctx = l->avctx;
373 if (esc_count < 4) {
374 length = width * height;
375 if (esc_count && AV_RL32(src + 1) < length) {
376 length = AV_RL32(src + 1);
377 offset += 4;
380 init_get_bits(&gb, src + offset, src_size * 8);
382 if (lag_read_prob_header(&rac, &gb) < 0)
383 return -1;
385 lag_rac_init(&rac, &gb, length - stride);
387 for (i = 0; i < height; i++)
388 read +=
389 lag_decode_line(l, &rac, dst + (i * stride), width,
390 stride, step, esc_count);
392 if (read > length)
393 av_log(l->avctx, AV_LOG_WARNING,
394 "Output more bytes than length (%d of %d)\n", read,
395 length);
396 } else if (esc_count < 8) {
397 esc_count -= 4;
398 if (esc_count > 0) {
399 /* Zero run coding only, no range coding. */
400 for (i = 0; i < height; i++)
401 src +=
402 lag_decode_zero_run_line(l, dst + (i * stride),
403 src, width, step, esc_count);
404 } else {
405 /* Plane is stored uncompressed */
406 for (i = 0; i < height; i++) {
407 lag_memcpy(dst + (i * stride), src, width, step);
408 src += width;
411 } else if (esc_count == 0xff) {
412 /* Plane is a solid run of 0 bytes */
413 for(i = 0; i < height; i++)
414 lag_memset(dst + i * stride, 0, width, step);
415 } else {
416 av_log(l->avctx, AV_LOG_ERROR,
417 "Invalid zero run escape code! (%#x)\n", esc_count);
418 return -1;
421 for (i = 0; i < height; i++) {
422 lag_pred_line(l, dst, width, stride, step, i);
423 dst += stride;
426 return 0;
430 * Decode a frame.
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;
449 if (!l->avctx)
450 l->avctx = avctx;
452 if (p->data[0])
453 avctx->release_buffer(avctx, p);
455 p->reference = 0;
456 p->key_frame = 1;
458 frametype = buf[0];
460 offset_gu = AV_RL32(buf + 1);
461 offset_bv = AV_RL32(buf + 5);
463 switch (frametype) {
464 case FRAME_ARITH_YV12:
465 avctx->pix_fmt = PIX_FMT_YUV420P;
467 if (avctx->get_buffer(avctx, p) < 0) {
468 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
469 return -1;
472 lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
473 p->linesize[0], 1, buf + offset_ry,
474 buf_size);
475 lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
476 avctx->height / 2, p->linesize[2], 1,
477 buf + offset_gu, buf_size);
478 lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
479 avctx->height / 2, p->linesize[1], 1,
480 buf + offset_bv, buf_size);
481 break;
482 default:
483 av_log(avctx, AV_LOG_ERROR,
484 "Unsupported Lagarith frame type: %#x\n", frametype);
485 return -1;
488 *picture = *p;
489 *data_size = sizeof(AVFrame);
491 return buf_size;
494 AVCodec lagarith_decoder = {
495 "lagarith",
496 CODEC_TYPE_VIDEO,
497 CODEC_ID_LAGARITH,
498 sizeof(LagarithContext),
499 NULL,
500 NULL,
501 NULL,
502 lag_decode_frame,
503 CODEC_CAP_DR1,
504 .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),