X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fpixlet.c;h=5361bc42bfde2c11f79804cb0c8db6acc94a17ca;hb=a247ac640df3da573cd661065bf53f37863e2b46;hp=03a2cdacc8ba1b9e8102c2ff695847e7ec26ccb3;hpb=29929fc8e2449d2db8bd144b2badc8d1e6347412;p=ffmpeg diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c index 03a2cdacc8b..5361bc42bfd 100644 --- a/libavcodec/pixlet.c +++ b/libavcodec/pixlet.c @@ -58,6 +58,7 @@ typedef struct PixletContext { int16_t *filter[2]; int16_t *prediction; int64_t scaling[4][2][NB_LEVELS]; + uint16_t lut[65536]; SubBand band[4][NB_LEVELS * 3 + 1]; } PixletContext; @@ -221,7 +222,7 @@ static int read_high_coeffs(AVCodecContext *avctx, uint8_t *src, int16_t *dst, length = 25 - nbits; while (i < size) { - if (state >> 8 != -3) + if (((state >> 8) + 3) & 0xFFFFFFF) value = ff_clz((state >> 8) + 3) ^ 0x1F; else value = -1; @@ -462,11 +463,27 @@ static void reconstruction(AVCodecContext *avctx, int16_t *dest, } } -static void postprocess_luma(AVFrame *frame, int w, int h, int depth) +static void build_luma_lut(AVCodecContext *avctx, int depth) { + PixletContext *ctx = avctx->priv_data; + int max = (1 << depth) - 1; + + if (ctx->depth == depth) + return; + ctx->depth = depth; + + for (int i = 0; i < FF_ARRAY_ELEMS(ctx->lut); i++) + ctx->lut[i] = ((int64_t)i * i * 65535LL) / max / max; +} + +static void postprocess_luma(AVCodecContext *avctx, AVFrame *frame, + int w, int h, int depth) +{ + PixletContext *ctx = avctx->priv_data; uint16_t *dsty = (uint16_t *)frame->data[0]; int16_t *srcy = (int16_t *)frame->data[0]; ptrdiff_t stridey = frame->linesize[0] / 2; + uint16_t *lut = ctx->lut; int i, j; for (j = 0; j < h; j++) { @@ -476,8 +493,7 @@ static void postprocess_luma(AVFrame *frame, int w, int h, int depth) else if (srcy[i] > ((1 << depth) - 1)) dsty[i] = 65535; else - dsty[i] = ((int64_t) srcy[i] * srcy[i] * 65535) / - ((1 << depth) - 1) / ((1 << depth) - 1); + dsty[i] = lut[srcy[i]]; } dsty += stridey; srcy += stridey; @@ -509,7 +525,7 @@ static void postprocess_chroma(AVFrame *frame, int w, int h, int depth) } static int decode_plane(AVCodecContext *avctx, int plane, - AVPacket *avpkt, AVFrame *frame) + const AVPacket *avpkt, AVFrame *frame) { PixletContext *ctx = avctx->priv_data; ptrdiff_t stride = frame->linesize[plane] / 2; @@ -591,7 +607,7 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data, int i, w, h, width, height, ret, version; AVFrame *p = data; ThreadFrame frame = { .f = data }; - uint32_t pktsize; + uint32_t pktsize, depth; bytestream2_init(&ctx->gb, avpkt->data, avpkt->size); @@ -623,12 +639,14 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data, ctx->levels = bytestream2_get_be32(&ctx->gb); if (ctx->levels != NB_LEVELS) return AVERROR_INVALIDDATA; - ctx->depth = bytestream2_get_be32(&ctx->gb); - if (ctx->depth < 8 || ctx->depth > 15) { - avpriv_request_sample(avctx, "Depth %d", ctx->depth); + depth = bytestream2_get_be32(&ctx->gb); + if (depth < 8 || depth > 15) { + avpriv_request_sample(avctx, "Depth %d", depth); return AVERROR_INVALIDDATA; } + build_luma_lut(avctx, depth); + ret = ff_set_dimensions(avctx, w, h); if (ret < 0) return ret; @@ -667,7 +685,7 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data, break; } - postprocess_luma(frame.f, ctx->w, ctx->h, ctx->depth); + postprocess_luma(avctx, frame.f, ctx->w, ctx->h, ctx->depth); postprocess_chroma(frame.f, ctx->w >> 1, ctx->h >> 1, ctx->depth); *got_frame = 1; @@ -675,28 +693,12 @@ static int pixlet_decode_frame(AVCodecContext *avctx, void *data, return pktsize; } -#if HAVE_THREADS -static int pixlet_init_thread_copy(AVCodecContext *avctx) -{ - PixletContext *ctx = avctx->priv_data; - - ctx->filter[0] = NULL; - ctx->filter[1] = NULL; - ctx->prediction = NULL; - ctx->w = 0; - ctx->h = 0; - - return 0; -} -#endif /* HAVE_THREADS */ - -AVCodec ff_pixlet_decoder = { +const AVCodec ff_pixlet_decoder = { .name = "pixlet", .long_name = NULL_IF_CONFIG_SMALL("Apple Pixlet"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PIXLET, .init = pixlet_init, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(pixlet_init_thread_copy), .close = pixlet_close, .decode = pixlet_decode_frame, .priv_data_size = sizeof(PixletContext),