Some uses of Snappy require uncompressing to positions within an existing buffer. Also adds a function to get the uncompressed length of Snappy data.tags/n2.8
| @@ -108,8 +108,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) | |||||
| 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) | |||||
| if (len < 0) | if (len < 0) | ||||
| return len; | return len; | ||||
| if ((ret = av_reallocp(buf, len)) < 0) | |||||
| return AVERROR(ENOMEM); | |||||
| if (len > *size) | |||||
| return AVERROR_BUG; | |||||
| *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) | |||||
| 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 @@ | |||||
| #include "bytestream.h" | #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 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. | * @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 */ | ||||