Merge remote-tracking branch 'qatar/master'
[ffmpeg.git] / libavcodec / txd.c
index ca07b6c..344187d 100644 (file)
@@ -25,6 +25,7 @@
 #include "libavutil/imgutils.h"
 #include "bytestream.h"
 #include "avcodec.h"
+#include "bytestream.h"
 #include "s3tc.h"
 
 typedef struct TXDContext {
@@ -42,28 +43,26 @@ static av_cold int txd_init(AVCodecContext *avctx) {
 
 static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                             AVPacket *avpkt) {
-    const uint8_t *buf = avpkt->data;
-    const uint8_t *buf_end = avpkt->data + avpkt->size;
     TXDContext * const s = avctx->priv_data;
+    GetByteContext gb;
     AVFrame *picture = data;
     AVFrame * const p = &s->picture;
-    unsigned int version, w, h, d3d_format, depth, stride, mipmap_count, flags;
+    unsigned int version, w, h, d3d_format, depth, stride, flags;
+    unsigned int av_unused mipmap_count;
     unsigned int y, v;
     uint8_t *ptr;
-    const uint8_t *cur = buf;
-    const uint32_t *palette = (const uint32_t *)(cur + 88);
     uint32_t *pal;
 
-    if (buf_end - cur < 92)
-        return AVERROR_INVALIDDATA;
-    version         = AV_RL32(cur);
-    d3d_format      = AV_RL32(cur+76);
-    w               = AV_RL16(cur+80);
-    h               = AV_RL16(cur+82);
-    depth           = AV_RL8 (cur+84);
-    mipmap_count    = AV_RL8 (cur+85);
-    flags           = AV_RL8 (cur+87);
-    cur            += 92;
+    bytestream2_init(&gb, avpkt->data, avpkt->size);
+    version         = bytestream2_get_le32(&gb);
+    bytestream2_skip(&gb, 72);
+    d3d_format      = bytestream2_get_le32(&gb);
+    w               = bytestream2_get_le16(&gb);
+    h               = bytestream2_get_le16(&gb);
+    depth           = bytestream2_get_byte(&gb);
+    mipmap_count    = bytestream2_get_byte(&gb);
+    bytestream2_skip(&gb, 1);
+    flags           = bytestream2_get_byte(&gb);
 
     if (version < 8 || version > 9) {
         av_log(avctx, AV_LOG_ERROR, "texture data version %i is unsupported\n",
@@ -73,12 +72,9 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 
     if (depth == 8) {
         avctx->pix_fmt = PIX_FMT_PAL8;
-        if (buf_end - cur < 1024)
-            return AVERROR_INVALIDDATA;
-        cur += 1024;
-    } else if (depth == 16 || depth == 32)
+    } else if (depth == 16 || depth == 32) {
         avctx->pix_fmt = PIX_FMT_RGB32;
-    else {
+    else {
         av_log(avctx, AV_LOG_ERROR, "depth of %i is unsupported\n", depth);
         return -1;
     }
@@ -102,31 +98,32 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 
     if (depth == 8) {
         pal = (uint32_t *) p->data[1];
-        for (y=0; y<256; y++) {
-            v = AV_RB32(palette+y);
-            pal[y] = (v>>8) + (v<<24);
+        for (y = 0; y < 256; y++) {
+            v = bytestream2_get_be32(&gb);
+            pal[y] = (v >> 8) + (v << 24);
         }
-        if (buf_end - cur < w * h)
+        if (bytestream2_get_bytes_left(&gb) < w * h)
             return AVERROR_INVALIDDATA;
+        bytestream2_skip(&gb, 4);
         for (y=0; y<h; y++) {
-            memcpy(ptr, cur, w);
+            bytestream2_get_buffer(&gb, ptr, w);
             ptr += stride;
-            cur += w;
         }
     } else if (depth == 16) {
+        bytestream2_skip(&gb, 4);
         switch (d3d_format) {
         case 0:
             if (!(flags & 1))
                 goto unsupported;
         case FF_S3TC_DXT1:
-            if (buf_end - cur < (w/4) * (h/4) * 8)
+            if (bytestream2_get_bytes_left(&gb) < (w/4) * (h/4) * 8)
                 return AVERROR_INVALIDDATA;
-            ff_decode_dxt1(cur, ptr, w, h, stride);
+            ff_decode_dxt1(&gb, ptr, w, h, stride);
             break;
         case FF_S3TC_DXT3:
-            if (buf_end - cur < (w/4) * (h/4) * 16)
+            if (bytestream2_get_bytes_left(&gb) < (w/4) * (h/4) * 16)
                 return AVERROR_INVALIDDATA;
-            ff_decode_dxt3(cur, ptr, w, h, stride);
+            ff_decode_dxt3(&gb, ptr, w, h, stride);
             break;
         default:
             goto unsupported;
@@ -135,12 +132,11 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
         switch (d3d_format) {
         case 0x15:
         case 0x16:
-            if (buf_end - cur < h * w * 4)
+            if (bytestream2_get_bytes_left(&gb) < h * w * 4)
                 return AVERROR_INVALIDDATA;
             for (y=0; y<h; y++) {
-                memcpy(ptr, cur, w*4);
+                bytestream2_get_buffer(&gb, ptr, w * 4);
                 ptr += stride;
-                cur += w*4;
             }
             break;
         default:
@@ -148,17 +144,10 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
         }
     }
 
-    for (; mipmap_count > 1 && buf_end - cur >= 4; mipmap_count--) {
-        uint32_t length = bytestream_get_le32(&cur);
-        if (buf_end - cur < length)
-            break;
-        cur += length;
-    }
-
     *picture   = s->picture;
     *data_size = sizeof(AVPicture);
 
-    return cur - buf;
+    return avpkt->size;
 
 unsupported:
     av_log(avctx, AV_LOG_ERROR, "unsupported d3d format (%08x)\n", d3d_format);
@@ -183,5 +172,5 @@ AVCodec ff_txd_decoder = {
     .close          = txd_end,
     .decode         = txd_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"),
+    .long_name      = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"),
 };