Merge commit 'def97856de6021965db86c25a732d78689bd6bb0'
[ffmpeg.git] / libavcodec / brenderpix.c
index a4b4c87..0556858 100644 (file)
@@ -2,20 +2,20 @@
  * BRender PIX (.pix) image decoder
  * Copyright (c) 2012 Aleksi Nurmi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -134,7 +134,7 @@ static int pix_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 {
     AVFrame *frame = data;
 
-    int ret, i, j;
+    int ret, i;
     GetByteContext gb;
 
     unsigned int bytes_pp;
@@ -142,6 +142,7 @@ static int pix_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     unsigned int chunk_type;
     unsigned int data_len;
     unsigned int bytes_per_scanline;
+    unsigned int bytes_left;
     PixHeader hdr;
 
     bytestream2_init(&gb, avpkt->data, avpkt->size);
@@ -168,7 +169,7 @@ static int pix_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     ret = pix_decode_header(&hdr, &gb);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Invalid header length.\n");
-        return AVERROR_INVALIDDATA;
+        return ret;
     }
     switch (hdr.format) {
     case 3:
@@ -187,7 +188,10 @@ static int pix_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         avctx->pix_fmt = AV_PIX_FMT_RGB24;
         bytes_pp = 3;
         break;
-    case 7: // XRGB
+    case 7:
+        avctx->pix_fmt = AV_PIX_FMT_0RGB;
+        bytes_pp = 4;
+        break;
     case 8: // ARGB
         avctx->pix_fmt = AV_PIX_FMT_ARGB;
         bytes_pp = 4;
@@ -219,22 +223,21 @@ static int pix_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         ret = pix_decode_header(&palhdr, &gb);
         if (ret < 0) {
             av_log(avctx, AV_LOG_ERROR, "Invalid palette header length.\n");
-            return AVERROR_INVALIDDATA;
+            return ret;
         }
         if (palhdr.format != 7)
             avpriv_request_sample(avctx, "Palette not in RGB format");
 
         chunk_type = bytestream2_get_be32(&gb);
         data_len = bytestream2_get_be32(&gb);
-        if (chunk_type != IMAGE_DATA_CHUNK ||
-            bytestream2_get_bytes_left(&gb) < data_len) {
+        bytestream2_skip(&gb, 8);
+        if (chunk_type != IMAGE_DATA_CHUNK || data_len != 1032 ||
+            bytestream2_get_bytes_left(&gb) < 1032) {
             av_log(avctx, AV_LOG_ERROR, "Invalid palette data.\n");
             return AVERROR_INVALIDDATA;
         }
-
         // palette data is surrounded by 8 null bytes (both top and bottom)
-        bytestream2_skip(&gb, 8);
-        // convert to machine endian format (ARGB)
+        // convert 0RGB to machine endian format (ARGB32)
         for (i = 0; i < 256; ++i)
             *pal_out++ = (0xFFU << 24) | bytestream2_get_be32u(&gb);
         bytestream2_skip(&gb, 8);
@@ -259,9 +262,10 @@ static int pix_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     // read the image data to the buffer
     bytes_per_scanline = bytes_pp * hdr.width;
-    if (chunk_type != IMAGE_DATA_CHUNK ||
-        data_len < bytes_per_scanline * hdr.height ||
-        bytestream2_get_bytes_left(&gb) < data_len) {
+    bytes_left = bytestream2_get_bytes_left(&gb);
+
+    if (chunk_type != IMAGE_DATA_CHUNK || data_len != bytes_left ||
+        bytes_left / bytes_per_scanline < hdr.height) {
         av_log(avctx, AV_LOG_ERROR, "Invalid image data.\n");
         return AVERROR_INVALIDDATA;
     }
@@ -271,12 +275,6 @@ static int pix_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         bytes_per_scanline,
                         bytes_per_scanline, hdr.height);
 
-    // make alpha opaque for XRGB
-    if (hdr.format == 7)
-        for (j = 0; j < frame->height; j++)
-            for (i = 0; i < frame->linesize[0]; i += 4)
-                frame->data[0][j * frame->linesize[0] + i] = 0xFF;
-
     frame->pict_type = AV_PICTURE_TYPE_I;
     frame->key_frame = 1;
     *got_frame = 1;