Commit 17ee24af authored by Tom Butterworth's avatar Tom Butterworth Committed by Michael Niedermayer

avcodec/snappy: refactor so ff_snappy_uncompress uses an existing buffer

Some uses of Snappy require uncompressing to positions within an existing buffer. Also adds a function to get the uncompressed length of Snappy data.
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent c4dfb76f
...@@ -107,8 +107,13 @@ static int setup_texture(AVCodecContext *avctx, size_t length) ...@@ -107,8 +107,13 @@ static int setup_texture(AVCodecContext *avctx, size_t length)
compressorstr = "none"; compressorstr = "none";
break; break;
case HAP_COMP_SNAPPY: 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 */ /* Uncompress the frame */
ret = ff_snappy_uncompress(gbc, &ctx->snappied, &snappy_size); ret = ff_snappy_uncompress(gbc, ctx->snappied, &snappy_size);
if (ret < 0) { if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Snappy uncompress error\n"); av_log(avctx, AV_LOG_ERROR, "Snappy uncompress error\n");
return ret; return ret;
......
...@@ -128,7 +128,17 @@ static int64_t decode_len(GetByteContext *gb) ...@@ -128,7 +128,17 @@ static int64_t decode_len(GetByteContext *gb)
return len; 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); int64_t len = decode_len(gb);
int ret = 0; int ret = 0;
...@@ -137,11 +147,11 @@ int ff_snappy_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size) ...@@ -137,11 +147,11 @@ int ff_snappy_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
if (len < 0) if (len < 0)
return len; return len;
if ((ret = av_reallocp(buf, len)) < 0) if (len > *size)
return AVERROR(ENOMEM); return AVERROR_BUFFER_TOO_SMALL;
*size = len; *size = len;
p = *buf; p = buf;
while (bytestream2_get_bytes_left(gb) > 0) { while (bytestream2_get_bytes_left(gb) > 0) {
uint8_t s = bytestream2_get_byte(gb); uint8_t s = bytestream2_get_byte(gb);
...@@ -152,13 +162,13 @@ int ff_snappy_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size) ...@@ -152,13 +162,13 @@ int ff_snappy_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
ret = snappy_literal(gb, p, len, val); ret = snappy_literal(gb, p, len, val);
break; break;
case SNAPPY_COPY_1: case SNAPPY_COPY_1:
ret = snappy_copy1(gb, *buf, p, len, val); ret = snappy_copy1(gb, buf, p, len, val);
break; break;
case SNAPPY_COPY_2: case SNAPPY_COPY_2:
ret = snappy_copy2(gb, *buf, p, len, val); ret = snappy_copy2(gb, buf, p, len, val);
break; break;
case SNAPPY_COPY_4: case SNAPPY_COPY_4:
ret = snappy_copy4(gb, *buf, p, len, val); ret = snappy_copy4(gb, buf, p, len, val);
break; break;
} }
......
...@@ -38,14 +38,23 @@ ...@@ -38,14 +38,23 @@
#include "bytestream.h" #include "bytestream.h"
/** /**
* Decompress an input buffer using Snappy algorithm. Caller is * Get the uncompressed length of an input buffer compressed using the Snappy
* responsible of freeing the memory allocated in buf. * algorithm. The GetByteContext is not advanced.
* *
* @param gb input GetByteContext. * @param gb input GetByteContext.
* @param buf output buffer pointer. * @return A positive length on success, AVERROR otherwise.
* @param size output buffer size. */
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. * @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 */ #endif /* AVCODEC_SNAPPY_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment