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 > 257 - i)
00162                 prob = 257 - 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 == 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         memset(dst, 0, count);
00373         l->zeros_rem -= count;
00374         dst += count;
00375     }
00376 
00377     while (dst < end) {
00378         i = 0;
00379         while (!zero_run && dst + i < end) {
00380             i++;
00381             if (i+2 >= src_end - src)
00382                 return AVERROR_INVALIDDATA;
00383             zero_run =
00384                 !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
00385         }
00386         if (zero_run) {
00387             zero_run = 0;
00388             i += esc_count;
00389             memcpy(dst, src, i);
00390             dst += i;
00391             l->zeros_rem = lag_calc_zero_run(src[i]);
00392 
00393             src += i + 1;
00394             goto output_zeros;
00395         } else {
00396             memcpy(dst, src, i);
00397             src += i;
00398             dst += i;
00399         }
00400     }
00401     return  src - src_start;
00402 }
00403 
00404 
00405 
00406 static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
00407                                   int width, int height, int stride,
00408                                   const uint8_t *src, int src_size)
00409 {
00410     int i = 0;
00411     int read = 0;
00412     uint32_t length;
00413     uint32_t offset = 1;
00414     int esc_count;
00415     GetBitContext gb;
00416     lag_rac rac;
00417     const uint8_t *src_end = src + src_size;
00418 
00419     rac.avctx = l->avctx;
00420     l->zeros = 0;
00421 
00422     if(src_size < 2)
00423         return AVERROR_INVALIDDATA;
00424 
00425     esc_count = src[0];
00426     if (esc_count < 4) {
00427         length = width * height;
00428         if(src_size < 5)
00429             return AVERROR_INVALIDDATA;
00430         if (esc_count && AV_RL32(src + 1) < length) {
00431             length = AV_RL32(src + 1);
00432             offset += 4;
00433         }
00434 
00435         init_get_bits(&gb, src + offset, src_size * 8);
00436 
00437         if (lag_read_prob_header(&rac, &gb) < 0)
00438             return -1;
00439 
00440         ff_lag_rac_init(&rac, &gb, length - stride);
00441 
00442         for (i = 0; i < height; i++)
00443             read += lag_decode_line(l, &rac, dst + (i * stride), width,
00444                                     stride, esc_count);
00445 
00446         if (read > length)
00447             av_log(l->avctx, AV_LOG_WARNING,
00448                    "Output more bytes than length (%d of %d)\n", read,
00449                    length);
00450     } else if (esc_count < 8) {
00451         esc_count -= 4;
00452         if (esc_count > 0) {
00453             
00454             for (i = 0; i < height; i++) {
00455                 int res = lag_decode_zero_run_line(l, dst + (i * stride), src,
00456                                                    src_end, width, esc_count);
00457                 if (res < 0)
00458                     return res;
00459                 src += res;
00460             }
00461         } else {
00462             if (src_size < width * height)
00463                 return AVERROR_INVALIDDATA; 
00464             
00465             for (i = 0; i < height; i++) {
00466                 memcpy(dst + (i * stride), src, width);
00467                 src += width;
00468             }
00469         }
00470     } else if (esc_count == 0xff) {
00471         
00472         for (i = 0; i < height; i++)
00473             memset(dst + i * stride, src[1], width);
00474         
00475 
00476 
00477         return 0;
00478     } else {
00479         av_log(l->avctx, AV_LOG_ERROR,
00480                "Invalid zero run escape code! (%#x)\n", esc_count);
00481         return -1;
00482     }
00483 
00484     if (l->avctx->pix_fmt != PIX_FMT_YUV422P) {
00485         for (i = 0; i < height; i++) {
00486             lag_pred_line(l, dst, width, stride, i);
00487             dst += stride;
00488         }
00489     } else {
00490         for (i = 0; i < height; i++) {
00491             lag_pred_line_yuy2(l, dst, width, stride, i,
00492                                width == l->avctx->width);
00493             dst += stride;
00494         }
00495     }
00496 
00497     return 0;
00498 }
00499 
00508 static int lag_decode_frame(AVCodecContext *avctx,
00509                             void *data, int *data_size, AVPacket *avpkt)
00510 {
00511     const uint8_t *buf = avpkt->data;
00512     unsigned int buf_size = avpkt->size;
00513     LagarithContext *l = avctx->priv_data;
00514     AVFrame *const p = &l->picture;
00515     uint8_t frametype = 0;
00516     uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
00517     uint32_t offs[4];
00518     uint8_t *srcs[4], *dst;
00519     int i, j, planes = 3;
00520 
00521     AVFrame *picture = data;
00522 
00523     if (p->data[0])
00524         ff_thread_release_buffer(avctx, p);
00525 
00526     p->reference = 0;
00527     p->key_frame = 1;
00528 
00529     frametype = buf[0];
00530 
00531     offset_gu = AV_RL32(buf + 1);
00532     offset_bv = AV_RL32(buf + 5);
00533 
00534     switch (frametype) {
00535     case FRAME_SOLID_RGBA:
00536         avctx->pix_fmt = PIX_FMT_RGB32;
00537 
00538         if (ff_thread_get_buffer(avctx, p) < 0) {
00539             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00540             return -1;
00541         }
00542 
00543         dst = p->data[0];
00544         for (j = 0; j < avctx->height; j++) {
00545             for (i = 0; i < avctx->width; i++)
00546                 AV_WN32(dst + i * 4, offset_gu);
00547             dst += p->linesize[0];
00548         }
00549         break;
00550     case FRAME_ARITH_RGBA:
00551         avctx->pix_fmt = PIX_FMT_RGB32;
00552         planes = 4;
00553         offset_ry += 4;
00554         offs[3] = AV_RL32(buf + 9);
00555     case FRAME_ARITH_RGB24:
00556     case FRAME_U_RGB24:
00557         if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
00558             avctx->pix_fmt = PIX_FMT_RGB24;
00559 
00560         if (ff_thread_get_buffer(avctx, p) < 0) {
00561             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00562             return -1;
00563         }
00564 
00565         offs[0] = offset_bv;
00566         offs[1] = offset_gu;
00567         offs[2] = offset_ry;
00568 
00569         if (!l->rgb_planes) {
00570             l->rgb_stride = FFALIGN(avctx->width, 16);
00571             l->rgb_planes = av_malloc(l->rgb_stride * avctx->height * planes + 16);
00572             if (!l->rgb_planes) {
00573                 av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n");
00574                 return AVERROR(ENOMEM);
00575             }
00576         }
00577         for (i = 0; i < planes; i++)
00578             srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride;
00579         for (i = 0; i < planes; i++)
00580             if (buf_size <= offs[i]) {
00581                 av_log(avctx, AV_LOG_ERROR,
00582                         "Invalid frame offsets\n");
00583                 return AVERROR_INVALIDDATA;
00584             }
00585 
00586         for (i = 0; i < planes; i++)
00587             lag_decode_arith_plane(l, srcs[i],
00588                                    avctx->width, avctx->height,
00589                                    -l->rgb_stride, buf + offs[i],
00590                                    buf_size - offs[i]);
00591         dst = p->data[0];
00592         for (i = 0; i < planes; i++)
00593             srcs[i] = l->rgb_planes + i * l->rgb_stride * avctx->height;
00594         for (j = 0; j < avctx->height; j++) {
00595             for (i = 0; i < avctx->width; i++) {
00596                 uint8_t r, g, b, a;
00597                 r = srcs[0][i];
00598                 g = srcs[1][i];
00599                 b = srcs[2][i];
00600                 r += g;
00601                 b += g;
00602                 if (frametype == FRAME_ARITH_RGBA) {
00603                     a = srcs[3][i];
00604                     AV_WN32(dst + i * 4, MKBETAG(a, r, g, b));
00605                 } else {
00606                     dst[i * 3 + 0] = r;
00607                     dst[i * 3 + 1] = g;
00608                     dst[i * 3 + 2] = b;
00609                 }
00610             }
00611             dst += p->linesize[0];
00612             for (i = 0; i < planes; i++)
00613                 srcs[i] += l->rgb_stride;
00614         }
00615         break;
00616     case FRAME_ARITH_YUY2:
00617         avctx->pix_fmt = PIX_FMT_YUV422P;
00618 
00619         if (ff_thread_get_buffer(avctx, p) < 0) {
00620             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00621             return -1;
00622         }
00623 
00624         if (offset_ry >= buf_size ||
00625             offset_gu >= buf_size ||
00626             offset_bv >= buf_size) {
00627             av_log(avctx, AV_LOG_ERROR,
00628                    "Invalid frame offsets\n");
00629             return AVERROR_INVALIDDATA;
00630         }
00631 
00632         lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
00633                                p->linesize[0], buf + offset_ry,
00634                                buf_size - offset_ry);
00635         lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
00636                                avctx->height, p->linesize[1],
00637                                buf + offset_gu, buf_size - offset_gu);
00638         lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
00639                                avctx->height, p->linesize[2],
00640                                buf + offset_bv, buf_size - offset_bv);
00641         break;
00642     case FRAME_ARITH_YV12:
00643         avctx->pix_fmt = PIX_FMT_YUV420P;
00644 
00645         if (ff_thread_get_buffer(avctx, p) < 0) {
00646             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00647             return -1;
00648         }
00649         if (buf_size <= offset_ry || buf_size <= offset_gu || buf_size <= offset_bv) {
00650             return AVERROR_INVALIDDATA;
00651         }
00652 
00653         if (offset_ry >= buf_size ||
00654             offset_gu >= buf_size ||
00655             offset_bv >= buf_size) {
00656             av_log(avctx, AV_LOG_ERROR,
00657                    "Invalid frame offsets\n");
00658             return AVERROR_INVALIDDATA;
00659         }
00660 
00661         lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
00662                                p->linesize[0], buf + offset_ry,
00663                                buf_size - offset_ry);
00664         lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
00665                                avctx->height / 2, p->linesize[2],
00666                                buf + offset_gu, buf_size - offset_gu);
00667         lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
00668                                avctx->height / 2, p->linesize[1],
00669                                buf + offset_bv, buf_size - offset_bv);
00670         break;
00671     default:
00672         av_log(avctx, AV_LOG_ERROR,
00673                "Unsupported Lagarith frame type: %#x\n", frametype);
00674         return -1;
00675     }
00676 
00677     *picture = *p;
00678     *data_size = sizeof(AVFrame);
00679 
00680     return buf_size;
00681 }
00682 
00683 static av_cold int lag_decode_init(AVCodecContext *avctx)
00684 {
00685     LagarithContext *l = avctx->priv_data;
00686     l->avctx = avctx;
00687 
00688     ff_dsputil_init(&l->dsp, avctx);
00689 
00690     return 0;
00691 }
00692 
00693 static av_cold int lag_decode_end(AVCodecContext *avctx)
00694 {
00695     LagarithContext *l = avctx->priv_data;
00696 
00697     if (l->picture.data[0])
00698         ff_thread_release_buffer(avctx, &l->picture);
00699     av_freep(&l->rgb_planes);
00700 
00701     return 0;
00702 }
00703 
00704 AVCodec ff_lagarith_decoder = {
00705     .name           = "lagarith",
00706     .type           = AVMEDIA_TYPE_VIDEO,
00707     .id             = AV_CODEC_ID_LAGARITH,
00708     .priv_data_size = sizeof(LagarithContext),
00709     .init           = lag_decode_init,
00710     .close          = lag_decode_end,
00711     .decode         = lag_decode_frame,
00712     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
00713     .long_name      = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
00714 };