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 memset(dst, 0, count);
00326 l->zeros_rem -= count;
00327 dst += count;
00328 }
00329
00330 while (dst < end) {
00331 i = 0;
00332 while (!zero_run && dst + i < end) {
00333 i++;
00334 zero_run =
00335 !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
00336 }
00337 if (zero_run) {
00338 zero_run = 0;
00339 i += esc_count;
00340 memcpy(dst, src, i);
00341 dst += i;
00342 l->zeros_rem = lag_calc_zero_run(src[i]);
00343
00344 src += i + 1;
00345 goto output_zeros;
00346 } else {
00347 memcpy(dst, src, i);
00348 src += i;
00349 }
00350 }
00351 return start - src;
00352 }
00353
00354
00355
00356 static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
00357 int width, int height, int stride,
00358 const uint8_t *src, int src_size)
00359 {
00360 int i = 0;
00361 int read = 0;
00362 uint32_t length;
00363 uint32_t offset = 1;
00364 int esc_count = src[0];
00365 GetBitContext gb;
00366 lag_rac rac;
00367
00368 rac.avctx = l->avctx;
00369 l->zeros = 0;
00370
00371 if (esc_count < 4) {
00372 length = width * height;
00373 if (esc_count && AV_RL32(src + 1) < length) {
00374 length = AV_RL32(src + 1);
00375 offset += 4;
00376 }
00377
00378 init_get_bits(&gb, src + offset, src_size * 8);
00379
00380 if (lag_read_prob_header(&rac, &gb) < 0)
00381 return -1;
00382
00383 lag_rac_init(&rac, &gb, length - stride);
00384
00385 for (i = 0; i < height; i++)
00386 read += lag_decode_line(l, &rac, dst + (i * stride), width,
00387 stride, esc_count);
00388
00389 if (read > length)
00390 av_log(l->avctx, AV_LOG_WARNING,
00391 "Output more bytes than length (%d of %d)\n", read,
00392 length);
00393 } else if (esc_count < 8) {
00394 esc_count -= 4;
00395 if (esc_count > 0) {
00396
00397 for (i = 0; i < height; i++)
00398 src += lag_decode_zero_run_line(l, dst + (i * stride), src,
00399 width, esc_count);
00400 } else {
00401
00402 for (i = 0; i < height; i++) {
00403 memcpy(dst + (i * stride), src, width);
00404 src += width;
00405 }
00406 }
00407 } else if (esc_count == 0xff) {
00408
00409 for (i = 0; i < height; i++)
00410 memset(dst + i * stride, src[1], width);
00411
00412
00413
00414 return 0;
00415 } else {
00416 av_log(l->avctx, AV_LOG_ERROR,
00417 "Invalid zero run escape code! (%#x)\n", esc_count);
00418 return -1;
00419 }
00420
00421 for (i = 0; i < height; i++) {
00422 lag_pred_line(l, dst, width, stride, i);
00423 dst += stride;
00424 }
00425
00426 return 0;
00427 }
00428
00437 static int lag_decode_frame(AVCodecContext *avctx,
00438 void *data, int *data_size, AVPacket *avpkt)
00439 {
00440 const uint8_t *buf = avpkt->data;
00441 int buf_size = avpkt->size;
00442 LagarithContext *l = avctx->priv_data;
00443 AVFrame *const p = &l->picture;
00444 uint8_t frametype = 0;
00445 uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
00446
00447 AVFrame *picture = data;
00448
00449 if (p->data[0])
00450 avctx->release_buffer(avctx, p);
00451
00452 p->reference = 0;
00453 p->key_frame = 1;
00454
00455 frametype = buf[0];
00456
00457 offset_gu = AV_RL32(buf + 1);
00458 offset_bv = AV_RL32(buf + 5);
00459
00460 switch (frametype) {
00461 case FRAME_ARITH_YV12:
00462 avctx->pix_fmt = PIX_FMT_YUV420P;
00463
00464 if (avctx->get_buffer(avctx, p) < 0) {
00465 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00466 return -1;
00467 }
00468
00469 lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
00470 p->linesize[0], buf + offset_ry,
00471 buf_size);
00472 lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
00473 avctx->height / 2, p->linesize[2],
00474 buf + offset_gu, buf_size);
00475 lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
00476 avctx->height / 2, p->linesize[1],
00477 buf + offset_bv, buf_size);
00478 break;
00479 default:
00480 av_log(avctx, AV_LOG_ERROR,
00481 "Unsupported Lagarith frame type: %#x\n", frametype);
00482 return -1;
00483 }
00484
00485 *picture = *p;
00486 *data_size = sizeof(AVFrame);
00487
00488 return buf_size;
00489 }
00490
00491 static av_cold int lag_decode_init(AVCodecContext *avctx)
00492 {
00493 LagarithContext *l = avctx->priv_data;
00494 l->avctx = avctx;
00495
00496 dsputil_init(&l->dsp, avctx);
00497
00498 return 0;
00499 }
00500
00501 static av_cold int lag_decode_end(AVCodecContext *avctx)
00502 {
00503 LagarithContext *l = avctx->priv_data;
00504
00505 if (l->picture.data[0])
00506 avctx->release_buffer(avctx, &l->picture);
00507
00508 return 0;
00509 }
00510
00511 AVCodec ff_lagarith_decoder = {
00512 "lagarith",
00513 AVMEDIA_TYPE_VIDEO,
00514 CODEC_ID_LAGARITH,
00515 sizeof(LagarithContext),
00516 lag_decode_init,
00517 NULL,
00518 lag_decode_end,
00519 lag_decode_frame,
00520 CODEC_CAP_DR1,
00521 .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
00522 };