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