00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "avcodec.h"
00029 #include "get_bits.h"
00030 #include "mathops.h"
00031 #include "dsputil.h"
00032 #include "lagarithrac.h"
00033 #include "thread.h"
00034
00035 enum LagarithFrameType {
00036 FRAME_RAW = 1,
00037 FRAME_U_RGB24 = 2,
00038 FRAME_ARITH_YUY2 = 3,
00039 FRAME_ARITH_RGB24 = 4,
00040 FRAME_SOLID_GRAY = 5,
00041 FRAME_SOLID_COLOR = 6,
00042 FRAME_OLD_ARITH_RGB = 7,
00043 FRAME_ARITH_RGBA = 8,
00044 FRAME_SOLID_RGBA = 9,
00045 FRAME_ARITH_YV12 = 10,
00046 FRAME_REDUCED_RES = 11,
00047 };
00048
00049 typedef struct LagarithContext {
00050 AVCodecContext *avctx;
00051 AVFrame picture;
00052 DSPContext dsp;
00053 int zeros;
00054 int zeros_rem;
00055 uint8_t *rgb_planes;
00056 int rgb_stride;
00057 } LagarithContext;
00058
00067 static uint64_t softfloat_reciprocal(uint32_t denom)
00068 {
00069 int shift = av_log2(denom - 1) + 1;
00070 uint64_t ret = (1ULL << 52) / denom;
00071 uint64_t err = (1ULL << 52) - ret * denom;
00072 ret <<= shift;
00073 err <<= shift;
00074 err += denom / 2;
00075 return ret + err / denom;
00076 }
00077
00086 static uint32_t softfloat_mul(uint32_t x, uint64_t mantissa)
00087 {
00088 uint64_t l = x * (mantissa & 0xffffffff);
00089 uint64_t h = x * (mantissa >> 32);
00090 h += l >> 32;
00091 l &= 0xffffffff;
00092 l += 1 << av_log2(h >> 21);
00093 h += l >> 32;
00094 return h >> 20;
00095 }
00096
00097 static uint8_t lag_calc_zero_run(int8_t x)
00098 {
00099 return (x << 1) ^ (x >> 7);
00100 }
00101
00102 static int lag_decode_prob(GetBitContext *gb, uint32_t *value)
00103 {
00104 static const uint8_t series[] = { 1, 2, 3, 5, 8, 13, 21 };
00105 int i;
00106 int bit = 0;
00107 int bits = 0;
00108 int prevbit = 0;
00109 unsigned val;
00110
00111 for (i = 0; i < 7; i++) {
00112 if (prevbit && bit)
00113 break;
00114 prevbit = bit;
00115 bit = get_bits1(gb);
00116 if (bit && !prevbit)
00117 bits += series[i];
00118 }
00119 bits--;
00120 if (bits < 0 || bits > 31) {
00121 *value = 0;
00122 return -1;
00123 } else if (bits == 0) {
00124 *value = 0;
00125 return 0;
00126 }
00127
00128 val = get_bits_long(gb, bits);
00129 val |= 1 << bits;
00130
00131 *value = val - 1;
00132
00133 return 0;
00134 }
00135
00136 static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb)
00137 {
00138 int i, j, scale_factor;
00139 unsigned prob, cumulative_target;
00140 unsigned cumul_prob = 0;
00141 unsigned scaled_cumul_prob = 0;
00142
00143 rac->prob[0] = 0;
00144 rac->prob[257] = UINT_MAX;
00145
00146 for (i = 1; i < 257; i++) {
00147 if (lag_decode_prob(gb, &rac->prob[i]) < 0) {
00148 av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability encountered.\n");
00149 return -1;
00150 }
00151 if ((uint64_t)cumul_prob + rac->prob[i] > UINT_MAX) {
00152 av_log(rac->avctx, AV_LOG_ERROR, "Integer overflow encountered in cumulative probability calculation.\n");
00153 return -1;
00154 }
00155 cumul_prob += rac->prob[i];
00156 if (!rac->prob[i]) {
00157 if (lag_decode_prob(gb, &prob)) {
00158 av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability run encountered.\n");
00159 return -1;
00160 }
00161 if (prob > 256 - i)
00162 prob = 256 - i;
00163 for (j = 0; j < prob; j++)
00164 rac->prob[++i] = 0;
00165 }
00166 }
00167
00168 if (!cumul_prob) {
00169 av_log(rac->avctx, AV_LOG_ERROR, "All probabilities are 0!\n");
00170 return -1;
00171 }
00172
00173
00174 scale_factor = av_log2(cumul_prob);
00175
00176 if (cumul_prob & (cumul_prob - 1)) {
00177 uint64_t mul = softfloat_reciprocal(cumul_prob);
00178 for (i = 1; i < 257; i++) {
00179 rac->prob[i] = softfloat_mul(rac->prob[i], mul);
00180 scaled_cumul_prob += rac->prob[i];
00181 }
00182
00183 scale_factor++;
00184 cumulative_target = 1 << scale_factor;
00185
00186 if (scaled_cumul_prob > cumulative_target) {
00187 av_log(rac->avctx, AV_LOG_ERROR,
00188 "Scaled probabilities are larger than target!\n");
00189 return -1;
00190 }
00191
00192 scaled_cumul_prob = cumulative_target - scaled_cumul_prob;
00193
00194 for (i = 1; scaled_cumul_prob; i = (i & 0x7f) + 1) {
00195 if (rac->prob[i]) {
00196 rac->prob[i]++;
00197 scaled_cumul_prob--;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 }
00211 }
00212
00213 rac->scale = scale_factor;
00214
00215
00216 for (i = 1; i < 257; i++)
00217 rac->prob[i] += rac->prob[i - 1];
00218
00219 return 0;
00220 }
00221
00222 static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1,
00223 uint8_t *diff, int w, int *left,
00224 int *left_top)
00225 {
00226
00227
00228
00229
00230 int i;
00231 uint8_t l, lt;
00232
00233 l = *left;
00234 lt = *left_top;
00235
00236 for (i = 0; i < w; i++) {
00237 l = mid_pred(l, src1[i], l + src1[i] - lt) + diff[i];
00238 lt = src1[i];
00239 dst[i] = l;
00240 }
00241
00242 *left = l;
00243 *left_top = lt;
00244 }
00245
00246 static void lag_pred_line(LagarithContext *l, uint8_t *buf,
00247 int width, int stride, int line)
00248 {
00249 int L, TL;
00250
00251 if (!line) {
00252
00253 L = l->dsp.add_hfyu_left_prediction(buf, buf,
00254 width, 0);
00255 } else {
00256
00257 L = buf[width - stride - 1];
00258
00259 if (line == 1) {
00260
00261
00262 TL = l->avctx->pix_fmt == AV_PIX_FMT_YUV420P ? buf[-stride] : L;
00263 } else {
00264
00265 TL = buf[width - (2 * stride) - 1];
00266 }
00267
00268 add_lag_median_prediction(buf, buf - stride, buf,
00269 width, &L, &TL);
00270 }
00271 }
00272
00273 static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf,
00274 int width, int stride, int line,
00275 int is_luma)
00276 {
00277 int L, TL;
00278
00279 if (!line) {
00280 L= buf[0];
00281 if (is_luma)
00282 buf[0] = 0;
00283 l->dsp.add_hfyu_left_prediction(buf, buf, width, 0);
00284 if (is_luma)
00285 buf[0] = L;
00286 return;
00287 }
00288 if (line == 1) {
00289 const int HEAD = is_luma ? 4 : 2;
00290 int i;
00291
00292 L = buf[width - stride - 1];
00293 TL = buf[HEAD - stride - 1];
00294 for (i = 0; i < HEAD; i++) {
00295 L += buf[i];
00296 buf[i] = L;
00297 }
00298 for (; i<width; i++) {
00299 L = mid_pred(L&0xFF, buf[i-stride], (L + buf[i-stride] - TL)&0xFF) + buf[i];
00300 TL = buf[i-stride];
00301 buf[i]= L;
00302 }
00303 } else {
00304 TL = buf[width - (2 * stride) - 1];
00305 L = buf[width - stride - 1];
00306 l->dsp.add_hfyu_median_prediction(buf, buf - stride, buf, width,
00307 &L, &TL);
00308 }
00309 }
00310
00311 static int lag_decode_line(LagarithContext *l, lag_rac *rac,
00312 uint8_t *dst, int width, int stride,
00313 int esc_count)
00314 {
00315 int i = 0;
00316 int ret = 0;
00317
00318 if (!esc_count)
00319 esc_count = -1;
00320
00321
00322 handle_zeros:
00323 if (l->zeros_rem) {
00324 int count = FFMIN(l->zeros_rem, width - i);
00325 memset(dst + i, 0, count);
00326 i += count;
00327 l->zeros_rem -= count;
00328 }
00329
00330 while (i < width) {
00331 dst[i] = lag_get_rac(rac);
00332 ret++;
00333
00334 if (dst[i])
00335 l->zeros = 0;
00336 else
00337 l->zeros++;
00338
00339 i++;
00340 if (l->zeros == esc_count) {
00341 int index = lag_get_rac(rac);
00342 ret++;
00343
00344 l->zeros = 0;
00345
00346 l->zeros_rem = lag_calc_zero_run(index);
00347 goto handle_zeros;
00348 }
00349 }
00350 return ret;
00351 }
00352
00353 static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst,
00354 const uint8_t *src, const uint8_t *src_end,
00355 int width, int esc_count)
00356 {
00357 int i = 0;
00358 int count;
00359 uint8_t zero_run = 0;
00360 const uint8_t *src_start = src;
00361 uint8_t mask1 = -(esc_count < 2);
00362 uint8_t mask2 = -(esc_count < 3);
00363 uint8_t *end = dst + (width - 2);
00364
00365 output_zeros:
00366 if (l->zeros_rem) {
00367 count = FFMIN(l->zeros_rem, width - i);
00368 if (end - dst < count) {
00369 av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n");
00370 return AVERROR_INVALIDDATA;
00371 }
00372
00373 memset(dst, 0, count);
00374 l->zeros_rem -= count;
00375 dst += count;
00376 }
00377
00378 while (dst < end) {
00379 i = 0;
00380 while (!zero_run && dst + i < end) {
00381 i++;
00382 if (i+2 >= src_end - src)
00383 return AVERROR_INVALIDDATA;
00384 zero_run =
00385 !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
00386 }
00387 if (zero_run) {
00388 zero_run = 0;
00389 i += esc_count;
00390 memcpy(dst, src, i);
00391 dst += i;
00392 l->zeros_rem = lag_calc_zero_run(src[i]);
00393
00394 src += i + 1;
00395 goto output_zeros;
00396 } else {
00397 memcpy(dst, src, i);
00398 src += i;
00399 dst += i;
00400 }
00401 }
00402 return src - src_start;
00403 }
00404
00405
00406
00407 static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
00408 int width, int height, int stride,
00409 const uint8_t *src, int src_size)
00410 {
00411 int i = 0;
00412 int read = 0;
00413 uint32_t length;
00414 uint32_t offset = 1;
00415 int esc_count;
00416 GetBitContext gb;
00417 lag_rac rac;
00418 const uint8_t *src_end = src + src_size;
00419
00420 rac.avctx = l->avctx;
00421 l->zeros = 0;
00422
00423 if(src_size < 2)
00424 return AVERROR_INVALIDDATA;
00425
00426 esc_count = src[0];
00427 if (esc_count < 4) {
00428 length = width * height;
00429 if(src_size < 5)
00430 return AVERROR_INVALIDDATA;
00431 if (esc_count && AV_RL32(src + 1) < length) {
00432 length = AV_RL32(src + 1);
00433 offset += 4;
00434 }
00435
00436 init_get_bits(&gb, src + offset, src_size * 8);
00437
00438 if (lag_read_prob_header(&rac, &gb) < 0)
00439 return -1;
00440
00441 ff_lag_rac_init(&rac, &gb, length - stride);
00442
00443 for (i = 0; i < height; i++)
00444 read += lag_decode_line(l, &rac, dst + (i * stride), width,
00445 stride, esc_count);
00446
00447 if (read > length)
00448 av_log(l->avctx, AV_LOG_WARNING,
00449 "Output more bytes than length (%d of %d)\n", read,
00450 length);
00451 } else if (esc_count < 8) {
00452 esc_count -= 4;
00453 if (esc_count > 0) {
00454
00455 for (i = 0; i < height; i++) {
00456 int res = lag_decode_zero_run_line(l, dst + (i * stride), src,
00457 src_end, width, esc_count);
00458 if (res < 0)
00459 return res;
00460 src += res;
00461 }
00462 } else {
00463 if (src_size < width * height)
00464 return AVERROR_INVALIDDATA;
00465
00466 for (i = 0; i < height; i++) {
00467 memcpy(dst + (i * stride), src, width);
00468 src += width;
00469 }
00470 }
00471 } else if (esc_count == 0xff) {
00472
00473 for (i = 0; i < height; i++)
00474 memset(dst + i * stride, src[1], width);
00475
00476
00477
00478 return 0;
00479 } else {
00480 av_log(l->avctx, AV_LOG_ERROR,
00481 "Invalid zero run escape code! (%#x)\n", esc_count);
00482 return -1;
00483 }
00484
00485 if (l->avctx->pix_fmt != AV_PIX_FMT_YUV422P) {
00486 for (i = 0; i < height; i++) {
00487 lag_pred_line(l, dst, width, stride, i);
00488 dst += stride;
00489 }
00490 } else {
00491 for (i = 0; i < height; i++) {
00492 lag_pred_line_yuy2(l, dst, width, stride, i,
00493 width == l->avctx->width);
00494 dst += stride;
00495 }
00496 }
00497
00498 return 0;
00499 }
00500
00509 static int lag_decode_frame(AVCodecContext *avctx,
00510 void *data, int *got_frame, AVPacket *avpkt)
00511 {
00512 const uint8_t *buf = avpkt->data;
00513 unsigned int buf_size = avpkt->size;
00514 LagarithContext *l = avctx->priv_data;
00515 AVFrame *const p = &l->picture;
00516 uint8_t frametype = 0;
00517 uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
00518 uint32_t offs[4];
00519 uint8_t *srcs[4], *dst;
00520 int i, j, planes = 3;
00521
00522 AVFrame *picture = data;
00523
00524 if (p->data[0])
00525 ff_thread_release_buffer(avctx, p);
00526
00527 p->reference = 0;
00528 p->key_frame = 1;
00529
00530 frametype = buf[0];
00531
00532 offset_gu = AV_RL32(buf + 1);
00533 offset_bv = AV_RL32(buf + 5);
00534
00535 switch (frametype) {
00536 case FRAME_SOLID_RGBA:
00537 avctx->pix_fmt = AV_PIX_FMT_RGB32;
00538
00539 if (ff_thread_get_buffer(avctx, p) < 0) {
00540 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00541 return -1;
00542 }
00543
00544 dst = p->data[0];
00545 for (j = 0; j < avctx->height; j++) {
00546 for (i = 0; i < avctx->width; i++)
00547 AV_WN32(dst + i * 4, offset_gu);
00548 dst += p->linesize[0];
00549 }
00550 break;
00551 case FRAME_ARITH_RGBA:
00552 avctx->pix_fmt = AV_PIX_FMT_RGB32;
00553 planes = 4;
00554 offset_ry += 4;
00555 offs[3] = AV_RL32(buf + 9);
00556 case FRAME_ARITH_RGB24:
00557 case FRAME_U_RGB24:
00558 if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
00559 avctx->pix_fmt = AV_PIX_FMT_RGB24;
00560
00561 if (ff_thread_get_buffer(avctx, p) < 0) {
00562 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00563 return -1;
00564 }
00565
00566 offs[0] = offset_bv;
00567 offs[1] = offset_gu;
00568 offs[2] = offset_ry;
00569
00570 if (!l->rgb_planes) {
00571 l->rgb_stride = FFALIGN(avctx->width, 16);
00572 l->rgb_planes = av_malloc(l->rgb_stride * avctx->height * 4 + 16);
00573 if (!l->rgb_planes) {
00574 av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n");
00575 return AVERROR(ENOMEM);
00576 }
00577 }
00578 for (i = 0; i < planes; i++)
00579 srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride;
00580 for (i = 0; i < planes; i++)
00581 if (buf_size <= offs[i]) {
00582 av_log(avctx, AV_LOG_ERROR,
00583 "Invalid frame offsets\n");
00584 return AVERROR_INVALIDDATA;
00585 }
00586
00587 for (i = 0; i < planes; i++)
00588 lag_decode_arith_plane(l, srcs[i],
00589 avctx->width, avctx->height,
00590 -l->rgb_stride, buf + offs[i],
00591 buf_size - offs[i]);
00592 dst = p->data[0];
00593 for (i = 0; i < planes; i++)
00594 srcs[i] = l->rgb_planes + i * l->rgb_stride * avctx->height;
00595 for (j = 0; j < avctx->height; j++) {
00596 for (i = 0; i < avctx->width; i++) {
00597 uint8_t r, g, b, a;
00598 r = srcs[0][i];
00599 g = srcs[1][i];
00600 b = srcs[2][i];
00601 r += g;
00602 b += g;
00603 if (frametype == FRAME_ARITH_RGBA) {
00604 a = srcs[3][i];
00605 AV_WN32(dst + i * 4, MKBETAG(a, r, g, b));
00606 } else {
00607 dst[i * 3 + 0] = r;
00608 dst[i * 3 + 1] = g;
00609 dst[i * 3 + 2] = b;
00610 }
00611 }
00612 dst += p->linesize[0];
00613 for (i = 0; i < planes; i++)
00614 srcs[i] += l->rgb_stride;
00615 }
00616 break;
00617 case FRAME_ARITH_YUY2:
00618 avctx->pix_fmt = AV_PIX_FMT_YUV422P;
00619
00620 if (ff_thread_get_buffer(avctx, p) < 0) {
00621 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00622 return -1;
00623 }
00624
00625 if (offset_ry >= buf_size ||
00626 offset_gu >= buf_size ||
00627 offset_bv >= buf_size) {
00628 av_log(avctx, AV_LOG_ERROR,
00629 "Invalid frame offsets\n");
00630 return AVERROR_INVALIDDATA;
00631 }
00632
00633 lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
00634 p->linesize[0], buf + offset_ry,
00635 buf_size - offset_ry);
00636 lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
00637 avctx->height, p->linesize[1],
00638 buf + offset_gu, buf_size - offset_gu);
00639 lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
00640 avctx->height, p->linesize[2],
00641 buf + offset_bv, buf_size - offset_bv);
00642 break;
00643 case FRAME_ARITH_YV12:
00644 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
00645
00646 if (ff_thread_get_buffer(avctx, p) < 0) {
00647 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00648 return -1;
00649 }
00650 if (buf_size <= offset_ry || buf_size <= offset_gu || buf_size <= offset_bv) {
00651 return AVERROR_INVALIDDATA;
00652 }
00653
00654 if (offset_ry >= buf_size ||
00655 offset_gu >= buf_size ||
00656 offset_bv >= buf_size) {
00657 av_log(avctx, AV_LOG_ERROR,
00658 "Invalid frame offsets\n");
00659 return AVERROR_INVALIDDATA;
00660 }
00661
00662 lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
00663 p->linesize[0], buf + offset_ry,
00664 buf_size - offset_ry);
00665 lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
00666 avctx->height / 2, p->linesize[2],
00667 buf + offset_gu, buf_size - offset_gu);
00668 lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
00669 avctx->height / 2, p->linesize[1],
00670 buf + offset_bv, buf_size - offset_bv);
00671 break;
00672 default:
00673 av_log(avctx, AV_LOG_ERROR,
00674 "Unsupported Lagarith frame type: %#x\n", frametype);
00675 return -1;
00676 }
00677
00678 *picture = *p;
00679 *got_frame = 1;
00680
00681 return buf_size;
00682 }
00683
00684 static av_cold int lag_decode_init(AVCodecContext *avctx)
00685 {
00686 LagarithContext *l = avctx->priv_data;
00687 l->avctx = avctx;
00688
00689 ff_dsputil_init(&l->dsp, avctx);
00690
00691 return 0;
00692 }
00693
00694 static av_cold int lag_decode_end(AVCodecContext *avctx)
00695 {
00696 LagarithContext *l = avctx->priv_data;
00697
00698 if (l->picture.data[0])
00699 ff_thread_release_buffer(avctx, &l->picture);
00700 av_freep(&l->rgb_planes);
00701
00702 return 0;
00703 }
00704
00705 AVCodec ff_lagarith_decoder = {
00706 .name = "lagarith",
00707 .type = AVMEDIA_TYPE_VIDEO,
00708 .id = AV_CODEC_ID_LAGARITH,
00709 .priv_data_size = sizeof(LagarithContext),
00710 .init = lag_decode_init,
00711 .close = lag_decode_end,
00712 .decode = lag_decode_frame,
00713 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
00714 .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
00715 };