ffmpeg / libavcodec / lagarith.c @ d267b339
History  View  Annotate  Download (14.7 KB)
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 021101301 USA

20 
*/

21  
22 
/**

23 
* @file libavcodec/lagarith.c

24 
* Lagarith lossless decoder

25 
* @author Nathan Caldwell

26 
*/

27  
28 
#include "avcodec.h" 
29 
#include "get_bits.h" 
30 
#include "mathops.h" 
31 
#include "dsputil.h" 
32 
#include "lagarithrac.h" 
33  
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 nongrayscale 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 */ 
46 
}; 
47  
48 
typedef struct LagarithContext { 
49 
AVCodecContext *avctx; 
50 
AVFrame picture; 
51 
DSPContext dsp; 
52 
int zeros; /*!< number of consecutive zero bytes encountered */ 
53 
int zeros_rem; /*!< number of zero bytes remaining to output */ 
54 
} LagarithContext; 
55  
56 
/**

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

62 
* @see softfloat_mul

63 
*/

64 
static uint64_t softfloat_reciprocal(uint32_t denom)

65 
{ 
66 
int shift = av_log2(denom  1) + 1; 
67 
uint64_t ret = (1ULL << 52) / denom; 
68 
uint64_t err = (1ULL << 52)  ret * denom; 
69 
ret <<= shift; 
70 
err <<= shift; 
71 
err += denom / 2;

72 
return ret + err / denom;

73 
} 
74  
75 
/**

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

82 
*/

83 
static uint32_t softfloat_mul(uint32_t x, uint64_t mantissa)

84 
{ 
85 
uint64_t l = x * (mantissa & 0xffffffff);

86 
uint64_t h = x * (mantissa >> 32);

87 
h += l >> 32;

88 
l &= 0xffffffff;

89 
l += 1 << av_log2(h >> 21); 
90 
h += l >> 32;

91 
return h >> 20; 
92 
} 
93  
94 
static uint8_t lag_calc_zero_run(int8_t x)

95 
{ 
96 
return (x << 1) ^ (x >> 7); 
97 
} 
98  
99 
static int lag_decode_prob(GetBitContext *gb, uint32_t *value) 
100 
{ 
101 
static const uint8_t series[] = { 1, 2, 3, 5, 8, 13, 21 }; 
102 
int i;

103 
int bit = 0; 
104 
int bits = 0; 
105 
int prevbit = 0; 
106 
unsigned val;

107  
108 
for (i = 0; i < 7; i++) { 
109 
if (prevbit && bit)

110 
break;

111 
prevbit = bit; 
112 
bit = get_bits1(gb); 
113 
if (bit && !prevbit)

114 
bits += series[i]; 
115 
} 
116 
bits; 
117 
if (bits < 0  bits > 31) { 
118 
*value = 0;

119 
return 1; 
120 
} else if (bits == 0) { 
121 
*value = 0;

122 
return 0; 
123 
} 
124  
125 
val = get_bits_long(gb, bits); 
126 
val = 1 << bits;

127  
128 
*value = val  1;

129  
130 
return 0; 
131 
} 
132  
133 
static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb) 
134 
{ 
135 
int i, j, scale_factor;

136 
unsigned prob, cumulative_target;

137 
unsigned cumul_prob = 0; 
138 
unsigned scaled_cumul_prob = 0; 
139  
140 
rac>prob[0] = 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");

146 
return 1; 
147 
} 
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");

150 
return 1; 
151 
} 
152 
cumul_prob += rac>prob[i]; 
153 
if (!rac>prob[i]) {

154 
if (lag_decode_prob(gb, &prob)) {

155 
av_log(rac>avctx, AV_LOG_ERROR, "Invalid probability run encountered.\n");

156 
return 1; 
157 
} 
158 
if (prob > 257  i) 
159 
prob = 257  i;

160 
for (j = 0; j < prob; j++) 
161 
rac>prob[++i] = 0;

162 
} 
163 
} 
164  
165 
if (!cumul_prob) {

166 
av_log(rac>avctx, AV_LOG_ERROR, "All probabilities are 0!\n");

167 
return 1; 
168 
} 
169  
170 
/* Scale probabilities so cumulative probability is an even power of 2. */

171 
scale_factor = av_log2(cumul_prob); 
172  
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]; 
178 
} 
179  
180 
scale_factor++; 
181 
cumulative_target = 1 << scale_factor;

182  
183 
if (scaled_cumul_prob > cumulative_target) {

184 
av_log(rac>avctx, AV_LOG_ERROR, 
185 
"Scaled probabilities are larger than target!\n");

186 
return 1; 
187 
} 
188  
189 
scaled_cumul_prob = cumulative_target  scaled_cumul_prob; 
190  
191 
for (i = 1; scaled_cumul_prob; i = (i & 0x7f) + 1) { 
192 
if (rac>prob[i]) {

193 
rac>prob[i]++; 
194 
scaled_cumul_prob; 
195 
} 
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;

201 
* b &= 0xFF;

202 
* } else {

203 
* b++;

204 
* b &= 0x7f;

205 
* }

206 
*/

207 
} 
208 
} 
209  
210 
rac>scale = scale_factor; 
211  
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];

215  
216 
return 0; 
217 
} 
218  
219 
static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1, 
220 
uint8_t *diff, int w, int *left, 
221 
int *left_top)

222 
{ 
223 
/* This is almost identical to add_hfyu_median_prediction in dsputil.h.

224 
* However the &0xFF on the gradient predictor yealds incorrect output

225 
* for lagarith.

226 
*/

227 
int i;

228 
uint8_t l, lt; 
229  
230 
l = *left; 
231 
lt = *left_top; 
232  
233 
for (i = 0; i < w; i++) { 
234 
l = mid_pred(l, src1[i], l + src1[i]  lt) + diff[i]; 
235 
lt = src1[i]; 
236 
dst[i] = l; 
237 
} 
238  
239 
*left = l; 
240 
*left_top = lt; 
241 
} 
242  
243 
static void lag_pred_line(LagarithContext *l, uint8_t *buf, 
244 
int width, int stride, int line) 
245 
{ 
246 
int L, TL;

247  
248 
if (!line) {

249 
/* Left prediction only for first line */

250 
L = l>dsp.add_hfyu_left_prediction(buf + 1, buf + 1, 
251 
width  1, buf[0]); 
252 
return;

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 */

256 
TL = buf[stride]; 
257 
} else {

258 
/* Top left is 2 rows back, last pixel */

259 
TL = buf[width  (2 * stride)  1]; 
260 
} 
261 
/* Left pixel is actually prev_row[width] */

262 
L = buf[width  stride  1];

263  
264 
add_lag_median_prediction(buf, buf  stride, buf, 
265 
width, &L, &TL); 
266 
} 
267  
268 
static int lag_decode_line(LagarithContext *l, lag_rac *rac, 
269 
uint8_t *dst, int width, int stride, 
270 
int esc_count)

271 
{ 
272 
int i = 0; 
273 
int ret = 0; 
274  
275 
if (!esc_count)

276 
esc_count = 1;

277  
278 
/* Output any zeros remaining from the previous run */

279 
handle_zeros:

280 
if (l>zeros_rem) {

281 
int count = FFMIN(l>zeros_rem, width  i);

282 
memset(dst + i, 0, count);

283 
i += count; 
284 
l>zeros_rem = count; 
285 
} 
286  
287 
while (i < width) {

288 
dst[i] = lag_get_rac(rac); 
289 
ret++; 
290  
291 
if (dst[i])

292 
l>zeros = 0;

293 
else

294 
l>zeros++; 
295  
296 
i++; 
297 
if (l>zeros == esc_count) {

298 
int index = lag_get_rac(rac);

299 
ret++; 
300  
301 
l>zeros = 0;

302  
303 
l>zeros_rem = lag_calc_zero_run(index); 
304 
goto handle_zeros;

305 
} 
306 
} 
307 
return ret;

308 
} 
309  
310 
static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst, 
311 
const uint8_t *src, int width, 
312 
int esc_count)

313 
{ 
314 
int i = 0; 
315 
int count;

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);

321  
322 
output_zeros:

323 
if (l>zeros_rem) {

324 
count = FFMIN(l>zeros_rem, width  i); 
325 
memset(dst, 0, count);

326 
l>zeros_rem = count; 
327 
dst += count; 
328 
} 
329  
330 
while (dst < end) {

331 
i = 0;

332 
while (!zero_run && dst + i < end) {

333 
i++; 
334 
zero_run = 
335 
!(src[i]  (src[i + 1] & mask1)  (src[i + 2] & mask2)); 
336 
} 
337 
if (zero_run) {

338 
zero_run = 0;

339 
i += esc_count; 
340 
memcpy(dst, src, i); 
341 
dst += i; 
342 
l>zeros_rem = lag_calc_zero_run(src[i]); 
343  
344 
src += i + 1;

345 
goto output_zeros;

346 
} else {

347 
memcpy(dst, src, i); 
348 
src += i; 
349 
} 
350 
} 
351 
return start  src;

352 
} 
353  
354  
355  
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) 
359 
{ 
360 
int i = 0; 
361 
int read = 0; 
362 
uint32_t length; 
363 
uint32_t offset = 1;

364 
int esc_count = src[0]; 
365 
GetBitContext gb; 
366 
lag_rac rac; 
367  
368 
rac.avctx = l>avctx; 
369 
l>zeros = 0;

370  
371 
if (esc_count < 4) { 
372 
length = width * height; 
373 
if (esc_count && AV_RL32(src + 1) < length) { 
374 
length = AV_RL32(src + 1);

375 
offset += 4;

376 
} 
377  
378 
init_get_bits(&gb, src + offset, src_size * 8);

379  
380 
if (lag_read_prob_header(&rac, &gb) < 0) 
381 
return 1; 
382  
383 
lag_rac_init(&rac, &gb, length  stride); 
384  
385 
for (i = 0; i < height; i++) 
386 
read += lag_decode_line(l, &rac, dst + (i * stride), width, 
387 
stride, esc_count); 
388  
389 
if (read > length)

390 
av_log(l>avctx, AV_LOG_WARNING, 
391 
"Output more bytes than length (%d of %d)\n", read,

392 
length); 
393 
} else if (esc_count < 8) { 
394 
esc_count = 4;

395 
if (esc_count > 0) { 
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, 
399 
width, esc_count); 
400 
} else {

401 
/* Plane is stored uncompressed */

402 
for (i = 0; i < height; i++) { 
403 
memcpy(dst + (i * stride), src, width); 
404 
src += width; 
405 
} 
406 
} 
407 
} else if (esc_count == 0xff) { 
408 
/* Plane is a solid run of 0 bytes */

409 
for (i = 0; i < height; i++) 
410 
memset(dst + i * stride, 0, width);

411 
} else {

412 
av_log(l>avctx, AV_LOG_ERROR, 
413 
"Invalid zero run escape code! (%#x)\n", esc_count);

414 
return 1; 
415 
} 
416  
417 
for (i = 0; i < height; i++) { 
418 
lag_pred_line(l, dst, width, stride, i); 
419 
dst += stride; 
420 
} 
421  
422 
return 0; 
423 
} 
424  
425 
/**

426 
* Decode a frame.

427 
* @param avctx codec context

428 
* @param data output AVFrame

429 
* @param data_size size of output data or 0 if no picture is returned

430 
* @param avpkt input packet

431 
* @return number of consumed bytes on success or negative if decode fails

432 
*/

433 
static int lag_decode_frame(AVCodecContext *avctx, 
434 
void *data, int *data_size, AVPacket *avpkt) 
435 
{ 
436 
const uint8_t *buf = avpkt>data;

437 
int buf_size = avpkt>size;

438 
LagarithContext *l = avctx>priv_data; 
439 
AVFrame *const p = &l>picture;

440 
uint8_t frametype = 0;

441 
uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9; 
442  
443 
AVFrame *picture = data; 
444  
445 
if (p>data[0]) 
446 
avctx>release_buffer(avctx, p); 
447  
448 
p>reference = 0;

449 
p>key_frame = 1;

450  
451 
frametype = buf[0];

452  
453 
offset_gu = AV_RL32(buf + 1);

454 
offset_bv = AV_RL32(buf + 5);

455  
456 
switch (frametype) {

457 
case FRAME_ARITH_YV12:

458 
avctx>pix_fmt = PIX_FMT_YUV420P; 
459  
460 
if (avctx>get_buffer(avctx, p) < 0) { 
461 
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

462 
return 1; 
463 
} 
464  
465 
lag_decode_arith_plane(l, p>data[0], avctx>width, avctx>height,

466 
p>linesize[0], buf + offset_ry,

467 
buf_size); 
468 
lag_decode_arith_plane(l, p>data[2], avctx>width / 2, 
469 
avctx>height / 2, p>linesize[2], 
470 
buf + offset_gu, buf_size); 
471 
lag_decode_arith_plane(l, p>data[1], avctx>width / 2, 
472 
avctx>height / 2, p>linesize[1], 
473 
buf + offset_bv, buf_size); 
474 
break;

475 
default:

476 
av_log(avctx, AV_LOG_ERROR, 
477 
"Unsupported Lagarith frame type: %#x\n", frametype);

478 
return 1; 
479 
} 
480  
481 
*picture = *p; 
482 
*data_size = sizeof(AVFrame);

483  
484 
return buf_size;

485 
} 
486  
487 
static av_cold int lag_decode_init(AVCodecContext *avctx) 
488 
{ 
489 
LagarithContext *l = avctx>priv_data; 
490 
l>avctx = avctx; 
491  
492 
dsputil_init(&l>dsp, avctx); 
493  
494 
return 0; 
495 
} 
496  
497 
static av_cold int lag_decode_end(AVCodecContext *avctx) 
498 
{ 
499 
LagarithContext *l = avctx>priv_data; 
500  
501 
if (l>picture.data[0]) 
502 
avctx>release_buffer(avctx, &l>picture); 
503  
504 
return 0; 
505 
} 
506  
507 
AVCodec lagarith_decoder = { 
508 
"lagarith",

509 
CODEC_TYPE_VIDEO, 
510 
CODEC_ID_LAGARITH, 
511 
sizeof(LagarithContext),

512 
lag_decode_init, 
513 
NULL,

514 
lag_decode_end, 
515 
lag_decode_frame, 
516 
CODEC_CAP_DR1, 
517 
.long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),

518 
}; 