1 /*
2 * Lagarith lossless decoder
3 * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
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 /**
23 * @file
24 * Lagarith lossless decoder
25 * @author Nathan Caldwell
26 */
27
28 #include <inttypes.h>
29
36
44 FRAME_OLD_ARITH_RGB = 7,
/**< obsolete arithmetic coded RGB (no longer encoded by upstream since version 1.1.0) */
49 };
50
54 int zeros;
/**< number of consecutive zero bytes encountered */
55 int zeros_rem;
/**< number of zero bytes remaining to output */
60
61 /**
62 * Compute the 52-bit mantissa of 1/(double)denom.
63 * This crazy format uses floats in an entropy coder and we have to match x86
64 * rounding exactly, thus ordinary floats aren't portable enough.
65 * @param denom denominator
66 * @return 52-bit mantissa
67 * @see softfloat_mul
68 */
70 {
72 uint64_t ret = (1ULL << 52) / denom;
73 uint64_t err = (1ULL << 52) - ret * denom;
76 err += denom / 2;
77 return ret + err / denom;
78 }
79
80 /**
81 * (uint32_t)(x*f), where f has the given mantissa, and exponent 0
82 * Used in combination with softfloat_reciprocal computes x/(double)denom.
83 * @param x 32-bit integer factor
84 * @param mantissa mantissa of f with exponent 0
85 * @return 32-bit integer value (x*f)
86 * @see softfloat_reciprocal
87 */
89 {
90 uint64_t l = x * (mantissa & 0xffffffff);
91 uint64_t
h = x * (mantissa >> 32);
92 h += l >> 32;
93 l &= 0xffffffff;
94 l += 1LL << av_log2(h >> 21);
95 h += l >> 32;
96 return h >> 20;
97 }
98
100 {
101 return (x * 2) ^ (x >> 7);
102 }
103
105 {
106 static const uint8_t series[] = { 1, 2, 3, 5, 8, 13, 21 };
107 int i;
108 int bit = 0;
109 int bits = 0;
110 int prevbit = 0;
112
113 for (i = 0; i < 7; i++) {
114 if (prevbit && bit)
115 break;
116 prevbit = bit;
118 if (bit && !prevbit)
119 bits += series[i];
120 }
121 bits--;
122 if (bits < 0 || bits > 31) {
123 *value = 0;
124 return -1;
125 } else if (bits == 0) {
126 *value = 0;
127 return 0;
128 }
129
132
133 *value = val - 1;
134
135 return 0;
136 }
137
139 {
140 int i, j, scale_factor;
141 unsigned prob, cumulative_target;
142 unsigned cumul_prob = 0;
143 unsigned scaled_cumul_prob = 0;
144
146 rac->
prob[257] = UINT_MAX;
147 /* Read probabilities from bitstream */
148 for (i = 1; i < 257; i++) {
151 return -1;
152 }
153 if ((uint64_t)cumul_prob + rac->
prob[i] > UINT_MAX) {
155 return -1;
156 }
157 cumul_prob += rac->
prob[i];
161 return -1;
162 }
163 if (prob > 256 - i)
164 prob = 256 - i;
165 for (j = 0; j < prob; j++)
167 }
168 }
169
170 if (!cumul_prob) {
172 return -1;
173 }
174
175 /* Scale probabilities so cumulative probability is an even power of 2. */
176 scale_factor =
av_log2(cumul_prob);
177
178 if (cumul_prob & (cumul_prob - 1)) {
180 for (i = 1; i <= 128; i++) {
182 scaled_cumul_prob += rac->
prob[i];
183 }
184 if (scaled_cumul_prob <= 0) {
187 }
188 for (; i < 257; i++) {
190 scaled_cumul_prob += rac->
prob[i];
191 }
192
193 scale_factor++;
194 if (scale_factor >= 32
U)
196 cumulative_target = 1
U << scale_factor;
197
198 if (scaled_cumul_prob > cumulative_target) {
200 "Scaled probabilities are larger than target!\n");
201 return -1;
202 }
203
204 scaled_cumul_prob = cumulative_target - scaled_cumul_prob;
205
206 for (i = 1; scaled_cumul_prob; i = (i & 0x7f) + 1) {
209 scaled_cumul_prob--;
210 }
211 /* Comment from reference source:
212 * if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way
213 * // since the compression change is negligible and fixing it
214 * // breaks backwards compatibility
215 * b =- (signed int)b;
216 * b &= 0xFF;
217 * } else {
218 * b++;
219 * b &= 0x7f;
220 * }
221 */
222 }
223 }
224
225 rac->
scale = scale_factor;
226
227 /* Fill probability array with cumulative probability for each symbol. */
228 for (i = 1; i < 257; i++)
230
231 return 0;
232 }
233
236 int *left_top)
237 {
238 /* This is almost identical to add_hfyu_median_pred in huffyuvdsp.h.
239 * However the &0xFF on the gradient predictor yields incorrect output
240 * for lagarith.
241 */
242 int i;
244
245 l = *left;
246 lt = *left_top;
247
248 for (i = 0; i <
w; i++) {
249 l =
mid_pred(l, src1[i], l + src1[i] - lt) + diff[i];
250 lt = src1[i];
251 dst[i] = l;
252 }
253
254 *left = l;
255 *left_top = lt;
256 }
257
260 {
262
263 if (!line) {
264 /* Left prediction only for first line */
266 } else {
267 /* Left pixel is actually prev_row[width] */
268 L = buf[width - stride - 1];
269
270 if (line == 1) {
271 /* Second line, left predict first pixel, the rest of the line is median predicted
272 * NOTE: In the case of RGB this pixel is top predicted */
274 } else {
275 /* Top left is 2 rows back, last pixel */
276 TL = buf[width - (2 *
stride) - 1];
277 }
278
280 width, &L, &TL);
281 }
282 }
283
286 int is_luma)
287 {
289
290 if (!line) {
291 L= buf[0];
292 if (is_luma)
293 buf[0] = 0;
295 if (is_luma)
297 return;
298 }
299 if (line == 1) {
300 const int HEAD = is_luma ? 4 : 2;
301 int i;
302
303 L = buf[width - stride - 1];
304 TL = buf[HEAD - stride - 1];
305 for (i = 0; i < HEAD; i++) {
306 L += buf[i];
308 }
309 for (; i <
width; i++) {
310 L =
mid_pred(L & 0xFF, buf[i - stride], (L + buf[i - stride] - TL) & 0xFF) + buf[i];
313 }
314 } else {
315 TL = buf[width - (2 *
stride) - 1];
316 L = buf[width - stride - 1];
318 }
319 }
320
323 int esc_count)
324 {
325 int i = 0;
326 int ret = 0;
327
328 if (!esc_count)
329 esc_count = -1;
330
331 /* Output any zeros remaining from the previous run */
332 handle_zeros:
335 memset(dst + i, 0, count);
338 }
339
340 while (i < width) {
342 ret++;
343
344 if (dst[i])
346 else
348
349 i++;
350 if (l->
zeros == esc_count) {
352 ret++;
353
355
357 goto handle_zeros;
358 }
359 }
360 return ret;
361 }
362
365 int width,
int esc_count)
366 {
367 int i = 0;
371 uint8_t mask1 = -(esc_count < 2);
372 uint8_t mask2 = -(esc_count < 3);
374
376
377 memset(dst, 0, width);
378
379 output_zeros:
382 if (end - dst < count) {
385 }
386
387 memset(dst, 0, count);
390 }
391
392 while (dst < end) {
393 i = 0;
394 while (!zero_run && dst + i < end) {
395 i++;
396 if (i+2 >= src_end - src)
398 zero_run =
399 !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
400 }
401 if (zero_run) {
402 zero_run = 0;
403 i += esc_count;
404 memcpy(dst, src, i);
405 dst += i;
407
408 src += i + 1;
409 goto output_zeros;
410 } else {
411 memcpy(dst, src, i);
412 src += i;
413 dst += i;
414 }
415 }
416 return src - src_start;
417 }
418
419
420
424 {
425 int i = 0;
426 int read = 0;
429 int esc_count;
432 const uint8_t *src_end = src + src_size;
433 int ret;
434
437
438 if(src_size < 2)
440
441 esc_count = src[0];
442 if (esc_count < 4) {
444 if(src_size < 5)
446 if (esc_count &&
AV_RL32(src + 1) < length) {
448 offset += 4;
449 }
450
451 if ((ret =
init_get_bits8(&gb, src + offset, src_size - offset)) < 0)
452 return ret;
453
455 return -1;
456
458 for (i = 0; i <
height; i++) {
462 stride, esc_count);
463 }
464
465 if (read > length)
467 "Output more bytes than length (%d of %"PRIu32")\n", read,
468 length);
469 } else if (esc_count < 8) {
470 esc_count -= 4;
471 src ++;
472 src_size --;
473 if (esc_count > 0) {
474 /* Zero run coding only, no range coding. */
475 for (i = 0; i <
height; i++) {
477 src_end, width, esc_count);
478 if (res < 0)
479 return res;
480 src += res;
481 }
482 } else {
483 if (src_size < width * height)
485 /* Plane is stored uncompressed */
486 for (i = 0; i <
height; i++) {
487 memcpy(dst + (i * stride), src, width);
489 }
490 }
491 } else if (esc_count == 0xff) {
492 /* Plane is a solid run of given value */
493 for (i = 0; i <
height; i++)
494 memset(dst + i * stride, src[1], width);
495 /* Do not apply prediction.
496 Note: memset to 0 above, setting first value to src[1]
497 and applying prediction gives the same result. */
498 return 0;
499 } else {
501 "Invalid zero run escape code! (%#x)\n", esc_count);
502 return -1;
503 }
504
506 for (i = 0; i <
height; i++) {
509 }
510 } else {
511 for (i = 0; i <
height; i++) {
515 }
516 }
517
518 return 0;
519 }
520
521 /**
522 * Decode a frame.
523 * @param avctx codec context
524 * @param data output AVFrame
525 * @param data_size size of output data or 0 if no picture is returned
526 * @param avpkt input packet
527 * @return number of consumed bytes on success or negative if decode fails
528 */
531 {
533 unsigned int buf_size = avpkt->
size;
538 uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
539 uint32_t offs[4];
542 int ret;
543
545
546 frametype = buf[0];
547
550
551 switch (frametype) {
558 } else {
560 planes = 4;
561 }
562
564 return ret;
565
568 for (j = 0; j < avctx->
height; j++) {
569 for (i = 0; i < avctx->
width; i++)
570 AV_WN32(dst + i * 4, offset_gu);
572 }
573 } else {
574 for (j = 0; j < avctx->
height; j++) {
575 memset(dst, buf[1], avctx->
width * planes);
577 }
578 }
579 break;
583 } else {
585 offset_gu |= 0xFF
U << 24;
586 }
587
589 return ret;
590
592 for (j = 0; j < avctx->
height; j++) {
593 for (i = 0; i < avctx->
width; i++)
595 AV_WB24(dst + i * 3, offset_gu);
596 } else {
597 AV_WN32(dst + i * 4, offset_gu);
598 }
600 }
601 break;
604 planes = 4;
605 offset_ry += 4;
611
613 return ret;
614
615 offs[0] = offset_bv;
616 offs[1] = offset_gu;
617 offs[2] = offset_ry;
618
625 }
626 for (i = 0; i <
planes; i++)
628 for (i = 0; i <
planes; i++)
629 if (buf_size <= offs[i]) {
631 "Invalid frame offsets\n");
633 }
634
635 for (i = 0; i <
planes; i++)
639 buf_size - offs[i]);
641 for (i = 0; i <
planes; i++)
644 for (i = 0; i < avctx->
width; i++) {
646 r = srcs[0][i];
647 g = srcs[1][i];
648 b = srcs[2][i];
652 a = srcs[3][i];
654 } else {
658 }
659 }
661 for (i = 0; i <
planes; i++)
663 }
664 break;
667
669 return ret;
670
671 if (offset_ry >= buf_size ||
672 offset_gu >= buf_size ||
673 offset_bv >= buf_size) {
675 "Invalid frame offsets\n");
677 }
678
681 buf_size - offset_ry);
684 buf + offset_gu, buf_size - offset_gu);
687 buf + offset_bv, buf_size - offset_bv);
688 break;
691
693 return ret;
694 if (buf_size <= offset_ry || buf_size <= offset_gu || buf_size <= offset_bv) {
696 }
697
698 if (offset_ry >= buf_size ||
699 offset_gu >= buf_size ||
700 offset_bv >= buf_size) {
702 "Invalid frame offsets\n");
704 }
705
708 buf_size - offset_ry);
711 buf + offset_gu, buf_size - offset_gu);
714 buf + offset_bv, buf_size - offset_bv);
715 break;
716 default:
718 "Unsupported Lagarith frame type: %#"PRIx8"\n", frametype);
720 }
721
722 *got_frame = 1;
723
724 return buf_size;
725 }
726
728 {
731
733
734 return 0;
735 }
736
737 #if HAVE_THREADS
739 {
742
743 return 0;
744 }
745 #endif
746
748 {
750
752
753 return 0;
754 }
755
767 };
static uint8_t lag_get_rac(lag_rac *l)
Decode a single byte from the compressed plane described by *l.
const char const char void * val
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static int shift(int a, int b)
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
void ff_lag_rac_init(lag_rac *l, GetBitContext *gb, int length)
#define AV_LOG_WARNING
Something somehow does not look correct.
static int init_thread_copy(AVCodecContext *avctx)
packed RGB 8:8:8, 24bpp, RGBRGB...
static av_cold int init(AVCodecContext *avctx)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, int width, int height, int stride, const uint8_t *src, int src_size)
int zeros
number of consecutive zero bytes encountered
AVCodec ff_lagarith_decoder
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst, const uint8_t *src, const uint8_t *src_end, int width, int esc_count)
solid grayscale color frame
static av_cold int end(AVCodecContext *avctx)
static void lag_pred_line(LagarithContext *l, uint8_t *buf, int width, int stride, int line)
Multithreading support functions.
int zeros_rem
number of zero bytes remaining to output
unsigned scale
Number of bits of precision in range.
bitstream reader API header.
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
const char * name
Name of the codec implementation.
static const uint8_t offset[127][2]
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
static av_cold int lag_decode_init(AVCodecContext *avctx)
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
#define ONLY_IF_THREADS_ENABLED(x)
Define a function with only the non-default version specified.
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
static uint64_t softfloat_reciprocal(uint32_t denom)
Compute the 52-bit mantissa of 1/(double)denom.
obsolete arithmetic coded RGB (no longer encoded by upstream since version 1.1.0) ...
int width
picture width / height.
GLsizei GLboolean const GLfloat * value
static int lag_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Decode a frame.
static int lag_decode_prob(GetBitContext *gb, uint32_t *value)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
static int lag_decode_line(LagarithContext *l, lag_rac *rac, uint8_t *dst, int width, int stride, int esc_count)
Libavcodec external API header.
uint32_t prob[258]
Table of cumulative probability for each symbol.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
static uint32_t softfloat_mul(uint32_t x, uint64_t mantissa)
(uint32_t)(x*f), where f has the given mantissa, and exponent 0 Used in combination with softfloat_re...
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
main external API structure.
void ff_llviddsp_init(LLVidDSPContext *c)
static unsigned int get_bits1(GetBitContext *s)
static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb)
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
GLint GLenum GLboolean GLsizei stride
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
static av_cold int lag_decode_end(AVCodecContext *avctx)
static const struct @272 planes[]
solid non-grayscale color frame
#define MKBETAG(a, b, c, d)
static uint8_t lag_calc_zero_run(int8_t x)
static av_always_inline int diff(const uint32_t a, const uint32_t b)
int(* add_left_pred)(uint8_t *dst, const uint8_t *src, ptrdiff_t w, int left)
static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf, int width, int stride, int line, int is_luma)
int key_frame
1 -> keyframe, 0-> not
reduced resolution YV12 frame
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
This structure stores compressed data.
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
void(* add_median_pred)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, ptrdiff_t w, int *left, int *left_top)
#define AV_PIX_FMT_0RGB32