On 2016-03-26 09:46:00 +0100, Vittorio Giovara wrote:
> Signed-off-by: Vittorio Giovara <[email protected]>
> ---
>  libavcodec/screenpresso.c | 48 
> ++++++++++++++++++++++++++++++++---------------
>  1 file changed, 33 insertions(+), 15 deletions(-)
> 
> diff --git a/libavcodec/screenpresso.c b/libavcodec/screenpresso.c
> index 88a927b..9635b60 100644
> --- a/libavcodec/screenpresso.c
> +++ b/libavcodec/screenpresso.c
> @@ -30,7 +30,7 @@
>   * rebuilt frame (not the reference), and since there is no coordinate system
>   * they contain exactly as many pixel as the keyframe.
>   *
> - * Supports: BGR24
> + * Supports: BGRA, BGR24, RGB555
>   */
>  
>  #include <stdint.h>
> @@ -79,10 +79,8 @@ static av_cold int screenpresso_init(AVCodecContext *avctx)
>      if (!ctx->current)
>          return AVERROR(ENOMEM);
>  
> -    avctx->pix_fmt = AV_PIX_FMT_BGR24;
> -
> -    /* Allocate maximum size possible, a full frame */
> -    ctx->inflated_size = avctx->width * avctx->height * 3;
> +    /* Allocate maximum size possible, a full RGBA frame */
> +    ctx->inflated_size = avctx->width * avctx->height * 4;
>      ctx->inflated_buf  = av_malloc(ctx->inflated_size);
>      if (!ctx->inflated_buf)
>          return AVERROR(ENOMEM);
> @@ -108,7 +106,7 @@ static int screenpresso_decode_frame(AVCodecContext 
> *avctx, void *data,
>      ScreenpressoContext *ctx = avctx->priv_data;
>      AVFrame *frame = data;
>      uLongf length = ctx->inflated_size;
> -    int keyframe;
> +    int keyframe, component_size;
>      int ret;
>  
>      /* Size check */
> @@ -118,13 +116,31 @@ static int screenpresso_decode_frame(AVCodecContext 
> *avctx, void *data,
>      }
>  
>      /* Basic sanity check, but not really harmful */
> -    if ((avpkt->data[0] != 0x73 && avpkt->data[0] != 0x72) ||
> -        avpkt->data[1] != 8) { // bpp probably
> -        av_log(avctx, AV_LOG_WARNING, "Unknown header 0x%02X%02X\n",
> -               avpkt->data[0], avpkt->data[1]);
> -    }
> +    if (avpkt->data[0] != 0x72 && avpkt->data[0] != 0x73)
> +        av_log(avctx, AV_LOG_WARNING, "Unknown header 0x%02X\n", 
> avpkt->data[0]);
> +
>      keyframe = (avpkt->data[0] == 0x73);
>  
> +    /* Pixel size */
> +    switch (avpkt->data[1]) {
> +    case 0x04:
> +        avctx->pix_fmt = AV_PIX_FMT_RGB555LE;
> +        component_size = 2;
> +        break;
> +    case 0x08:
> +        avctx->pix_fmt = AV_PIX_FMT_BGR24;
> +        component_size = 3;
> +        break;
> +    case 0x0C:
> +        avctx->pix_fmt = AV_PIX_FMT_BGRA;
> +        component_size = 4;
> +        break;
> +    default:
> +        av_log(avctx, AV_LOG_ERROR, "Invalid bits per pixel value 
> (0x%02X)\n",
> +               avpkt->data[1]);

it doesn't look like the whole byte is used to code the number of bytes 
per pixel. so a less specific error message and request sample would be 
better. component_size is ((data[1] >> 2) & 0x3) + 1.

> +        return AVERROR_UNKNOWN;
> +    }
> +
>      /* Inflate the frame after the 2 byte header */
>      ret = uncompress(ctx->inflated_buf, &length,
>                       avpkt->data + 2, avpkt->size - 2);
> @@ -142,13 +158,15 @@ static int screenpresso_decode_frame(AVCodecContext 
> *avctx, void *data,
>          av_image_copy_plane(ctx->current->data[0] +
>                              ctx->current->linesize[0] * (avctx->height - 1),
>                              -1 * ctx->current->linesize[0],
> -                            ctx->inflated_buf, avctx->width * 3,
> -                            avctx->width * 3, avctx->height);
> +                            ctx->inflated_buf,
> +                            FFALIGN(avctx->width * component_size, 4),
> +                            avctx->width * component_size, avctx->height);
>      /* Otherwise sum the delta on top of the current frame */
>      else
>          sum_delta_flipped(ctx->current->data[0], ctx->current->linesize[0],
> -                          ctx->inflated_buf, avctx->width * 3,
> -                          avctx->width * 3, avctx->height);
> +                          ctx->inflated_buf,
> +                          FFALIGN(avctx->width * component_size, 4),
> +                          avctx->width * component_size, avctx->height);
>  
>      /* Frame is ready to be output */
>      ret = av_frame_ref(frame, ctx->current);

otherwise ok

Janne
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to