]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/tiff.c
prores: Error out only on surely incomplete ac_coeffs
[ffmpeg] / libavcodec / tiff.c
index a2fae325906040b962b654ccf0a57998076edd79..735eafe7215184fc3ba04fa286259530ab3caa8d 100644 (file)
@@ -111,8 +111,68 @@ static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src,
     *len = zstream.total_out;
     return zret == Z_STREAM_END ? Z_OK : zret;
 }
+
+static int tiff_unpack_zlib(TiffContext *s, uint8_t *dst, int stride,
+                            const uint8_t *src, int size,
+                            int width, int lines)
+{
+    uint8_t *zbuf;
+    unsigned long outlen;
+    int ret, line;
+    outlen = width * lines;
+    zbuf   = av_malloc(outlen);
+    if (!zbuf)
+        return AVERROR(ENOMEM);
+    ret = tiff_uncompress(zbuf, &outlen, src, size);
+    if (ret != Z_OK) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Uncompressing failed (%lu of %lu) with error %d\n", outlen,
+               (unsigned long)width * lines, ret);
+        av_free(zbuf);
+        return AVERROR_UNKNOWN;
+    }
+    src = zbuf;
+    for (line = 0; line < lines; line++) {
+        memcpy(dst, src, width);
+        dst += stride;
+        src += width;
+    }
+    av_free(zbuf);
+    return 0;
+}
 #endif
 
+
+static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride,
+                           const uint8_t *src, int size, int lines)
+{
+    int i, ret = 0;
+    uint8_t *src2 = av_malloc((unsigned)size +
+                              FF_INPUT_BUFFER_PADDING_SIZE);
+
+    if (!src2) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Error allocating temporary buffer\n");
+        return AVERROR(ENOMEM);
+    }
+    if (s->fax_opts & 2) {
+        avpriv_request_sample(s->avctx, "Uncompressed fax mode");
+        av_free(src2);
+        return AVERROR_PATCHWELCOME;
+    }
+    if (!s->fill_order) {
+        memcpy(src2, src, size);
+    } else {
+        for (i = 0; i < size; i++)
+            src2[i] = ff_reverse[src[i]];
+    }
+    memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+    ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride,
+                          s->compr, s->fax_opts);
+    av_free(src2);
+    return ret;
+}
+
 static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
                              const uint8_t *src, int size, int lines)
 {
@@ -123,33 +183,16 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
     if (size <= 0)
         return AVERROR_INVALIDDATA;
 
-#if CONFIG_ZLIB
     if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
-        uint8_t *zbuf;
-        unsigned long outlen;
-        int ret;
-        outlen = width * lines;
-        zbuf   = av_malloc(outlen);
-        if (!zbuf)
-            return AVERROR(ENOMEM);
-        ret = tiff_uncompress(zbuf, &outlen, src, size);
-        if (ret != Z_OK) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Uncompressing failed (%lu of %lu) with error %d\n", outlen,
-                   (unsigned long)width * lines, ret);
-            av_free(zbuf);
-            return AVERROR_UNKNOWN;
-        }
-        src = zbuf;
-        for (line = 0; line < lines; line++) {
-            memcpy(dst, src, width);
-            dst += stride;
-            src += width;
-        }
-        av_free(zbuf);
-        return 0;
-    }
+#if CONFIG_ZLIB
+        return tiff_unpack_zlib(s, dst, stride, src, size, width, lines);
+#else
+        av_log(s->avctx, AV_LOG_ERROR,
+               "zlib support not enabled, "
+               "deflate compression not supported\n");
+        return AVERROR(ENOSYS);
 #endif
+    }
     if (s->compr == TIFF_LZW) {
         if ((ret = ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF)) < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
@@ -159,38 +202,7 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
     if (s->compr == TIFF_CCITT_RLE ||
         s->compr == TIFF_G3        ||
         s->compr == TIFF_G4) {
-        int i, ret = 0;
-        uint8_t *src2 = av_malloc((unsigned)size +
-                                  FF_INPUT_BUFFER_PADDING_SIZE);
-
-        if (!src2) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Error allocating temporary buffer\n");
-            return AVERROR(ENOMEM);
-        }
-        if (s->fax_opts & 2) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Uncompressed fax mode is not supported (yet)\n");
-            av_free(src2);
-            return AVERROR_INVALIDDATA;
-        }
-        if (!s->fill_order) {
-            memcpy(src2, src, size);
-        } else {
-            for (i = 0; i < size; i++)
-                src2[i] = ff_reverse[src[i]];
-        }
-        memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-        switch (s->compr) {
-        case TIFF_CCITT_RLE:
-        case TIFF_G3:
-        case TIFF_G4:
-            ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride,
-                                  s->compr, s->fax_opts);
-            break;
-        }
-        av_free(src2);
-        return ret;
+        return tiff_unpack_fax(s, dst, stride, src, size, lines);
     }
     for (line = 0; line < lines; line++) {
         if (src - ssrc > size) {
@@ -212,10 +224,13 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
             break;
         case TIFF_PACKBITS:
             for (pixels = 0; pixels < width;) {
+                if (ssrc + size - src < 2)
+                    return AVERROR_INVALIDDATA;
                 code = (int8_t) *src++;
                 if (code >= 0) {
                     code++;
-                    if (pixels + code > width) {
+                    if (pixels + code > width ||
+                        ssrc + size - src < code) {
                         av_log(s->avctx, AV_LOG_ERROR,
                                "Copy went out of bounds\n");
                         return AVERROR_INVALIDDATA;
@@ -424,8 +439,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
 #endif
         case TIFF_JPEG:
         case TIFF_NEWJPEG:
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "JPEG compression is not supported\n");
+            avpriv_report_missing_feature(s->avctx, "JPEG compression");
             return AVERROR_PATCHWELCOME;
         default:
             av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n",
@@ -522,7 +536,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
         break;
     case TIFF_PLANAR:
         if (value == 2) {
-            av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");
+            avpriv_report_missing_feature(s->avctx, "Planar format");
             return AVERROR_PATCHWELCOME;
         }
         break;
@@ -535,8 +549,12 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
             s->fax_opts = value;
         break;
     default:
-        av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n",
-               tag, tag);
+        if (s->avctx->err_recognition & AV_EF_EXPLODE) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Unknown or unsupported tag %d/0X%0X\n",
+                   tag, tag);
+            return AVERROR_INVALIDDATA;
+        }
     }
     return 0;
 }
@@ -627,9 +645,12 @@ static int decode_frame(AVCodecContext *avctx,
             av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
             return AVERROR_INVALIDDATA;
         }
-        if (tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize,
-                              FFMIN(s->rps, s->height - i)) < 0)
+        if ((ret = tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize,
+                                     FFMIN(s->rps, s->height - i))) < 0) {
+            if (avctx->err_recognition & AV_EF_EXPLODE)
+                return ret;
             break;
+        }
         dst += s->rps * stride;
     }
     if (s->predictor == 2) {