summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/hapdec.c7
-rw-r--r--libavcodec/snappy.c24
-rw-r--r--libavcodec/snappy.h19
3 files changed, 37 insertions, 13 deletions
diff --git a/libavcodec/hapdec.c b/libavcodec/hapdec.c
index a4880cd3e7..0398efe6ca 100644
--- a/libavcodec/hapdec.c
+++ b/libavcodec/hapdec.c
@@ -108,8 +108,13 @@ static int setup_texture(AVCodecContext *avctx, size_t length)
compressorstr = "none";
break;
case HAP_COMP_SNAPPY:
+ snappy_size = ff_snappy_peek_uncompressed_length(gbc);
+ ret = av_reallocp(&ctx->snappied, snappy_size);
+ if (ret < 0) {
+ return ret;
+ }
/* Uncompress the frame */
- ret = ff_snappy_uncompress(gbc, &ctx->snappied, &snappy_size);
+ ret = ff_snappy_uncompress(gbc, ctx->snappied, &snappy_size);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Snappy uncompress error\n");
return ret;
diff --git a/libavcodec/snappy.c b/libavcodec/snappy.c
index 13ef1ec137..df6c6b386a 100644
--- a/libavcodec/snappy.c
+++ b/libavcodec/snappy.c
@@ -128,7 +128,17 @@ static int64_t decode_len(GetByteContext *gb)
return len;
}
-int ff_snappy_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
+int64_t ff_snappy_peek_uncompressed_length(GetByteContext *gb)
+{
+ int pos = bytestream2_get_bytes_left(gb);
+ int64_t len = decode_len(gb);
+
+ bytestream2_seek(gb, -pos, SEEK_END);
+
+ return len;
+}
+
+int ff_snappy_uncompress(GetByteContext *gb, uint8_t *buf, int64_t *size)
{
int64_t len = decode_len(gb);
int ret = 0;
@@ -137,11 +147,11 @@ int ff_snappy_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
if (len < 0)
return len;
- if ((ret = av_reallocp(buf, len)) < 0)
- return AVERROR(ENOMEM);
+ if (len > *size)
+ return AVERROR_BUG;
*size = len;
- p = *buf;
+ p = buf;
while (bytestream2_get_bytes_left(gb) > 0) {
uint8_t s = bytestream2_get_byte(gb);
@@ -152,13 +162,13 @@ int ff_snappy_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
ret = snappy_literal(gb, p, len, val);
break;
case SNAPPY_COPY_1:
- ret = snappy_copy1(gb, *buf, p, len, val);
+ ret = snappy_copy1(gb, buf, p, len, val);
break;
case SNAPPY_COPY_2:
- ret = snappy_copy2(gb, *buf, p, len, val);
+ ret = snappy_copy2(gb, buf, p, len, val);
break;
case SNAPPY_COPY_4:
- ret = snappy_copy4(gb, *buf, p, len, val);
+ ret = snappy_copy4(gb, buf, p, len, val);
break;
}
diff --git a/libavcodec/snappy.h b/libavcodec/snappy.h
index 96666a814d..8d365c0f8e 100644
--- a/libavcodec/snappy.h
+++ b/libavcodec/snappy.h
@@ -38,14 +38,23 @@
#include "bytestream.h"
/**
- * Decompress an input buffer using Snappy algorithm. Caller is
- * responsible of freeing the memory allocated in buf.
+ * Get the uncompressed length of an input buffer compressed using the Snappy
+ * algorithm. The GetByteContext is not advanced.
*
* @param gb input GetByteContext.
- * @param buf output buffer pointer.
- * @param size output buffer size.
+ * @return A positive length on success, AVERROR otherwise.
+ */
+ int64_t ff_snappy_peek_uncompressed_length(GetByteContext *gb);
+
+/**
+ * Decompress an input buffer using Snappy algorithm.
+ *
+ * @param gb input GetByteContext.
+ * @param buf input buffer pointer.
+ * @param size input/output on input, the size of buffer, on output, the size
+ * of the uncompressed data.
* @return 0 if success, AVERROR otherwise.
*/
-int ff_snappy_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size);
+int ff_snappy_uncompress(GetByteContext *gb, uint8_t *buf, int64_t *size);
#endif /* AVCODEC_SNAPPY_H */