X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2F8bps.c;h=3fd15e05eb42bdda4662dce1bc526a72a66c311d;hb=b11acd57326db6c2cc1475dd0bea2a06fbc85aa2;hp=ea428da628bc2ece3f3c9cde1455d540a1f11921;hpb=594d4d5df3c70404168701dd5c90b7e6e5587793;p=ffmpeg diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c index ea428da628b..3fd15e05eb4 100644 --- a/libavcodec/8bps.c +++ b/libavcodec/8bps.c @@ -44,12 +44,8 @@ static const enum AVPixelFormat pixfmt_rgb24[] = { AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE }; -/* - * Decoder context - */ typedef struct EightBpsContext { AVCodecContext *avctx; - AVFrame pic; unsigned char planes; unsigned char planemap[4]; @@ -57,15 +53,10 @@ typedef struct EightBpsContext { uint32_t pal[256]; } EightBpsContext; - -/* - * - * Decode a frame - * - */ static int decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) + int *got_frame, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; EightBpsContext * const c = avctx->priv_data; @@ -73,22 +64,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, unsigned char *pixptr, *pixptr_end; unsigned int height = avctx->height; // Real image height unsigned int dlen, p, row; - const unsigned char *lp, *dp; + const unsigned char *lp, *dp, *ep; unsigned char count; unsigned int px_inc; unsigned int planes = c->planes; unsigned char *planemap = c->planemap; + int ret; - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - c->pic.reference = 0; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; - if (ff_get_buffer(avctx, &c->pic) < 0){ + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } + ep = encoded + buf_size; + /* Set data pointer after line lengths */ dp = encoded + planes * (height << 1); @@ -104,27 +93,29 @@ static int decode_frame(AVCodecContext *avctx, void *data, /* Decode a plane */ for (row = 0; row < height; row++) { - pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p]; - pixptr_end = pixptr + c->pic.linesize[0]; + pixptr = frame->data[0] + row * frame->linesize[0] + planemap[p]; + pixptr_end = pixptr + frame->linesize[0]; + if (ep - lp < row * 2 + 2) + return AVERROR_INVALIDDATA; dlen = av_be2ne16(*(const unsigned short *)(lp + row * 2)); /* Decode a row of this plane */ while (dlen > 0) { - if (dp + 1 >= buf + buf_size) - return -1; + if (ep - dp <= 1) + return AVERROR_INVALIDDATA; if ((count = *dp++) <= 127) { count++; dlen -= count + 1; - if (pixptr + count * px_inc > pixptr_end) + if (pixptr_end - pixptr < count * px_inc) break; - if (dp + count > buf + buf_size) - return -1; + if (ep - dp < count) + return AVERROR_INVALIDDATA; while (count--) { *pixptr = *dp++; pixptr += px_inc; } } else { count = 257 - count; - if (pixptr + count * px_inc > pixptr_end) + if (pixptr_end - pixptr < count * px_inc) break; while (count--) { *pixptr = *dp; @@ -142,32 +133,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, AV_PKT_DATA_PALETTE, NULL); if (pal) { - c->pic.palette_has_changed = 1; + frame->palette_has_changed = 1; memcpy(c->pal, pal, AVPALETTE_SIZE); } - memcpy (c->pic.data[1], c->pal, AVPALETTE_SIZE); + memcpy (frame->data[1], c->pal, AVPALETTE_SIZE); } - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; + *got_frame = 1; /* always report that the buffer was completely consumed */ return buf_size; } - -/* - * - * Init 8BPS decoder - * - */ static av_cold int decode_init(AVCodecContext *avctx) { EightBpsContext * const c = avctx->priv_data; c->avctx = avctx; - c->pic.data[0] = NULL; switch (avctx->bits_per_coded_sample) { case 8: @@ -176,7 +159,7 @@ static av_cold int decode_init(AVCodecContext *avctx) c->planemap[0] = 0; // 1st plane is palette indexes break; case 24: - avctx->pix_fmt = avctx->get_format(avctx, pixfmt_rgb24); + avctx->pix_fmt = ff_get_format(avctx, pixfmt_rgb24); c->planes = 3; c->planemap[0] = 2; // 1st plane is red c->planemap[1] = 1; // 2nd plane is green @@ -185,55 +168,30 @@ static av_cold int decode_init(AVCodecContext *avctx) case 32: avctx->pix_fmt = AV_PIX_FMT_RGB32; c->planes = 4; -#if HAVE_BIGENDIAN - c->planemap[0] = 1; // 1st plane is red - c->planemap[1] = 2; // 2nd plane is green - c->planemap[2] = 3; // 3rd plane is blue - c->planemap[3] = 0; // 4th plane is alpha??? -#else - c->planemap[0] = 2; // 1st plane is red - c->planemap[1] = 1; // 2nd plane is green - c->planemap[2] = 0; // 3rd plane is blue - c->planemap[3] = 3; // 4th plane is alpha??? -#endif + /* handle planemap setup later for decoding rgb24 data as rbg32 */ break; default: av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n", avctx->bits_per_coded_sample); - return -1; + return AVERROR_INVALIDDATA; } + if (avctx->pix_fmt == AV_PIX_FMT_RGB32) { + c->planemap[0] = HAVE_BIGENDIAN ? 1 : 2; // 1st plane is red + c->planemap[1] = HAVE_BIGENDIAN ? 2 : 1; // 2nd plane is green + c->planemap[2] = HAVE_BIGENDIAN ? 3 : 0; // 3rd plane is blue + c->planemap[3] = HAVE_BIGENDIAN ? 0 : 3; // 4th plane is alpha??? + } return 0; } - - - -/* - * - * Uninit 8BPS decoder - * - */ -static av_cold int decode_end(AVCodecContext *avctx) -{ - EightBpsContext * const c = avctx->priv_data; - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - - - AVCodec ff_eightbps_decoder = { .name = "8bps", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_8BPS, .priv_data_size = sizeof(EightBpsContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"), };