Libav 0.7.1
|
00001 /* 00002 * Lagarith lossless decoder 00003 * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com> 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 /* Read probabilities from bitstream */ 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 /* Scale probabilities so cumulative probability is an even power of 2. */ 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 /* Comment from reference source: 00197 * if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way 00198 * // since the compression change is negligable and fixing it 00199 * // breaks backwards compatibilty 00200 * b =- (signed int)b; 00201 * b &= 0xFF; 00202 * } else { 00203 * b++; 00204 * b &= 0x7f; 00205 * } 00206 */ 00207 } 00208 } 00209 00210 rac->scale = scale_factor; 00211 00212 /* Fill probability array with cumulative probability for each symbol. */ 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 /* This is almost identical to add_hfyu_median_prediction in dsputil.h. 00224 * However the &0xFF on the gradient predictor yealds incorrect output 00225 * for lagarith. 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 /* Left prediction only for first line */ 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 /* Second line, left predict first pixel, the rest of the line is median predicted */ 00255 /* FIXME: In the case of RGB this pixel is top predicted */ 00256 TL = buf[-stride]; 00257 } else { 00258 /* Top left is 2 rows back, last pixel */ 00259 TL = buf[width - (2 * stride) - 1]; 00260 } 00261 /* Left pixel is actually prev_row[width] */ 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 /* Output any zeros remaining from the previous run */ 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 /* Zero run coding only, no range coding. */ 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 /* Plane is stored uncompressed */ 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 /* Plane is a solid run of given value */ 00409 for (i = 0; i < height; i++) 00410 memset(dst + i * stride, src[1], width); 00411 /* Do not apply prediction. 00412 Note: memset to 0 above, setting first value to src[1] 00413 and applying prediction gives the same result. */ 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 };