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 } LagarithContext;
00055
00064 static uint64_t softfloat_reciprocal(uint32_t denom)
00065 {
00066 int shift = av_log2(denom - 1) + 1;
00067 uint64_t ret = (1ULL << 52) / denom;
00068 uint64_t err = (1ULL << 52) - ret * denom;
00069 ret <<= shift;
00070 err <<= shift;
00071 err += denom / 2;
00072 return ret + err / denom;
00073 }
00074
00083 static uint32_t softfloat_mul(uint32_t x, uint64_t mantissa)
00084 {
00085 uint64_t l = x * (mantissa & 0xffffffff);
00086 uint64_t h = x * (mantissa >> 32);
00087 h += l >> 32;
00088 l &= 0xffffffff;
00089 l += 1 << av_log2(h >> 21);
00090 h += l >> 32;
00091 return h >> 20;
00092 }
00093
00094 static uint8_t lag_calc_zero_run(int8_t x)
00095 {
00096 return (x << 1) ^ (x >> 7);
00097 }
00098
00099 static int lag_decode_prob(GetBitContext *gb, uint32_t *value)
00100 {
00101 static const uint8_t series[] = { 1, 2, 3, 5, 8, 13, 21 };
00102 int i;
00103 int bit = 0;
00104 int bits = 0;
00105 int prevbit = 0;
00106 unsigned val;
00107
00108 for (i = 0; i < 7; i++) {
00109 if (prevbit && bit)
00110 break;
00111 prevbit = bit;
00112 bit = get_bits1(gb);
00113 if (bit && !prevbit)
00114 bits += series[i];
00115 }
00116 bits--;
00117 if (bits < 0 || bits > 31) {
00118 *value = 0;
00119 return -1;
00120 } else if (bits == 0) {
00121 *value = 0;
00122 return 0;
00123 }
00124
00125 val = get_bits_long(gb, bits);
00126 val |= 1 << bits;
00127
00128 *value = val - 1;
00129
00130 return 0;
00131 }
00132
00133 static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb)
00134 {
00135 int i, j, scale_factor;
00136 unsigned prob, cumulative_target;
00137 unsigned cumul_prob = 0;
00138 unsigned scaled_cumul_prob = 0;
00139
00140 rac->prob[0] = 0;
00141 rac->prob[257] = UINT_MAX;
00142
00143 for (i = 1; i < 257; i++) {
00144 if (lag_decode_prob(gb, &rac->prob[i]) < 0) {
00145 av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability encountered.\n");
00146 return -1;
00147 }
00148 if ((uint64_t)cumul_prob + rac->prob[i] > UINT_MAX) {
00149 av_log(rac->avctx, AV_LOG_ERROR, "Integer overflow encountered in cumulative probability calculation.\n");
00150 return -1;
00151 }
00152 cumul_prob += rac->prob[i];
00153 if (!rac->prob[i]) {
00154 if (lag_decode_prob(gb, &prob)) {
00155 av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability run encountered.\n");
00156 return -1;
00157 }
00158 if (prob > 257 - i)
00159 prob = 257 - i;
00160 for (j = 0; j < prob; j++)
00161 rac->prob[++i] = 0;
00162 }
00163 }
00164
00165 if (!cumul_prob) {
00166 av_log(rac->avctx, AV_LOG_ERROR, "All probabilities are 0!\n");
00167 return -1;
00168 }
00169
00170
00171 scale_factor = av_log2(cumul_prob);
00172
00173 if (cumul_prob & (cumul_prob - 1)) {
00174 uint64_t mul = softfloat_reciprocal(cumul_prob);
00175 for (i = 1; i < 257; i++) {
00176 rac->prob[i] = softfloat_mul(rac->prob[i], mul);
00177 scaled_cumul_prob += rac->prob[i];
00178 }
00179
00180 scale_factor++;
00181 cumulative_target = 1 << scale_factor;
00182
00183 if (scaled_cumul_prob > cumulative_target) {
00184 av_log(rac->avctx, AV_LOG_ERROR,
00185 "Scaled probabilities are larger than target!\n");
00186 return -1;
00187 }
00188
00189 scaled_cumul_prob = cumulative_target - scaled_cumul_prob;
00190
00191 for (i = 1; scaled_cumul_prob; i = (i & 0x7f) + 1) {
00192 if (rac->prob[i]) {
00193 rac->prob[i]++;
00194 scaled_cumul_prob--;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 }
00208 }
00209
00210 rac->scale = scale_factor;
00211
00212
00213 for (i = 1; i < 257; i++)
00214 rac->prob[i] += rac->prob[i - 1];
00215
00216 return 0;
00217 }
00218
00219 static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1,
00220 uint8_t *diff, int w, int *left,
00221 int *left_top)
00222 {
00223
00224
00225
00226
00227 int i;
00228 uint8_t l, lt;
00229
00230 l = *left;
00231 lt = *left_top;
00232
00233 for (i = 0; i < w; i++) {
00234 l = mid_pred(l, src1[i], l + src1[i] - lt) + diff[i];
00235 lt = src1[i];
00236 dst[i] = l;
00237 }
00238
00239 *left = l;
00240 *left_top = lt;
00241 }
00242
00243 static void lag_pred_line(LagarithContext *l, uint8_t *buf,
00244 int width, int stride, int line)
00245 {
00246 int L, TL;
00247
00248 if (!line) {
00249
00250 L = l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1,
00251 width - 1, buf[0]);
00252 return;
00253 } else if (line == 1) {
00254
00255
00256 TL = buf[-stride];
00257 } else {
00258
00259 TL = buf[width - (2 * stride) - 1];
00260 }
00261
00262 L = buf[width - stride - 1];
00263
00264 add_lag_median_prediction(buf, buf - stride, buf,
00265 width, &L, &TL);
00266 }
00267
00268 static int lag_decode_line(LagarithContext *l, lag_rac *rac,
00269 uint8_t *dst, int width, int stride,
00270 int esc_count)
00271 {
00272 int i = 0;
00273 int ret = 0;
00274
00275 if (!esc_count)
00276 esc_count = -1;
00277
00278
00279 handle_zeros:
00280 if (l->zeros_rem) {
00281 int count = FFMIN(l->zeros_rem, width - i);
00282 memset(dst + i, 0, count);
00283 i += count;
00284 l->zeros_rem -= count;
00285 }
00286
00287 while (i < width) {
00288 dst[i] = lag_get_rac(rac);
00289 ret++;
00290
00291 if (dst[i])
00292 l->zeros = 0;
00293 else
00294 l->zeros++;
00295
00296 i++;
00297 if (l->zeros == esc_count) {
00298 int index = lag_get_rac(rac);
00299 ret++;
00300
00301 l->zeros = 0;
00302
00303 l->zeros_rem = lag_calc_zero_run(index);
00304 goto handle_zeros;
00305 }
00306 }
00307 return ret;
00308 }
00309
00310 static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst,
00311 const uint8_t *src, int width,
00312 int esc_count)
00313 {
00314 int i = 0;
00315 int count;
00316 uint8_t zero_run = 0;
00317 const uint8_t *start = src;
00318 uint8_t mask1 = -(esc_count < 2);
00319 uint8_t mask2 = -(esc_count < 3);
00320 uint8_t *end = dst + (width - 2);
00321
00322 output_zeros:
00323 if (l->zeros_rem) {
00324 count = FFMIN(l->zeros_rem, width - i);
00325 if (end - dst < count) {
00326 av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n");
00327 return AVERROR_INVALIDDATA;
00328 }
00329
00330 memset(dst, 0, count);
00331 l->zeros_rem -= count;
00332 dst += count;
00333 }
00334
00335 while (dst < end) {
00336 i = 0;
00337 while (!zero_run && dst + i < end) {
00338 i++;
00339 zero_run =
00340 !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
00341 }
00342 if (zero_run) {
00343 zero_run = 0;
00344 i += esc_count;
00345 memcpy(dst, src, i);
00346 dst += i;
00347 l->zeros_rem = lag_calc_zero_run(src[i]);
00348
00349 src += i + 1;
00350 goto output_zeros;
00351 } else {
00352 memcpy(dst, src, i);
00353 src += i;
00354 }
00355 }
00356 return start - src;
00357 }
00358
00359
00360
00361 static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
00362 int width, int height, int stride,
00363 const uint8_t *src, int src_size)
00364 {
00365 int i = 0;
00366 int read = 0;
00367 uint32_t length;
00368 uint32_t offset = 1;
00369 int esc_count = src[0];
00370 GetBitContext gb;
00371 lag_rac rac;
00372
00373 rac.avctx = l->avctx;
00374 l->zeros = 0;
00375
00376 if (esc_count < 4) {
00377 length = width * height;
00378 if (esc_count && AV_RL32(src + 1) < length) {
00379 length = AV_RL32(src + 1);
00380 offset += 4;
00381 }
00382
00383 init_get_bits(&gb, src + offset, src_size * 8);
00384
00385 if (lag_read_prob_header(&rac, &gb) < 0)
00386 return -1;
00387
00388 lag_rac_init(&rac, &gb, length - stride);
00389
00390 for (i = 0; i < height; i++)
00391 read += lag_decode_line(l, &rac, dst + (i * stride), width,
00392 stride, esc_count);
00393
00394 if (read > length)
00395 av_log(l->avctx, AV_LOG_WARNING,
00396 "Output more bytes than length (%d of %d)\n", read,
00397 length);
00398 } else if (esc_count < 8) {
00399 esc_count -= 4;
00400 if (esc_count > 0) {
00401
00402 for (i = 0; i < height; i++)
00403 src += lag_decode_zero_run_line(l, dst + (i * stride), src,
00404 width, esc_count);
00405 } else {
00406
00407 for (i = 0; i < height; i++) {
00408 memcpy(dst + (i * stride), src, width);
00409 src += width;
00410 }
00411 }
00412 } else if (esc_count == 0xff) {
00413
00414 for (i = 0; i < height; i++)
00415 memset(dst + i * stride, src[1], width);
00416
00417
00418
00419 return 0;
00420 } else {
00421 av_log(l->avctx, AV_LOG_ERROR,
00422 "Invalid zero run escape code! (%#x)\n", esc_count);
00423 return -1;
00424 }
00425
00426 for (i = 0; i < height; i++) {
00427 lag_pred_line(l, dst, width, stride, i);
00428 dst += stride;
00429 }
00430
00431 return 0;
00432 }
00433
00442 static int lag_decode_frame(AVCodecContext *avctx,
00443 void *data, int *data_size, AVPacket *avpkt)
00444 {
00445 const uint8_t *buf = avpkt->data;
00446 int buf_size = avpkt->size;
00447 LagarithContext *l = avctx->priv_data;
00448 AVFrame *const p = &l->picture;
00449 uint8_t frametype = 0;
00450 uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
00451
00452 AVFrame *picture = data;
00453
00454 if (p->data[0])
00455 avctx->release_buffer(avctx, p);
00456
00457 p->reference = 0;
00458 p->key_frame = 1;
00459
00460 frametype = buf[0];
00461
00462 offset_gu = AV_RL32(buf + 1);
00463 offset_bv = AV_RL32(buf + 5);
00464
00465 switch (frametype) {
00466 case FRAME_ARITH_YV12:
00467 avctx->pix_fmt = PIX_FMT_YUV420P;
00468
00469 if (avctx->get_buffer(avctx, p) < 0) {
00470 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00471 return -1;
00472 }
00473
00474 lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
00475 p->linesize[0], buf + offset_ry,
00476 buf_size);
00477 lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
00478 avctx->height / 2, p->linesize[2],
00479 buf + offset_gu, buf_size);
00480 lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
00481 avctx->height / 2, p->linesize[1],
00482 buf + offset_bv, buf_size);
00483 break;
00484 default:
00485 av_log(avctx, AV_LOG_ERROR,
00486 "Unsupported Lagarith frame type: %#x\n", frametype);
00487 return -1;
00488 }
00489
00490 *picture = *p;
00491 *data_size = sizeof(AVFrame);
00492
00493 return buf_size;
00494 }
00495
00496 static av_cold int lag_decode_init(AVCodecContext *avctx)
00497 {
00498 LagarithContext *l = avctx->priv_data;
00499 l->avctx = avctx;
00500
00501 dsputil_init(&l->dsp, avctx);
00502
00503 return 0;
00504 }
00505
00506 static av_cold int lag_decode_end(AVCodecContext *avctx)
00507 {
00508 LagarithContext *l = avctx->priv_data;
00509
00510 if (l->picture.data[0])
00511 avctx->release_buffer(avctx, &l->picture);
00512
00513 return 0;
00514 }
00515
00516 AVCodec ff_lagarith_decoder = {
00517 "lagarith",
00518 AVMEDIA_TYPE_VIDEO,
00519 CODEC_ID_LAGARITH,
00520 sizeof(LagarithContext),
00521 lag_decode_init,
00522 NULL,
00523 lag_decode_end,
00524 lag_decode_frame,
00525 CODEC_CAP_DR1,
00526 .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
00527 };