exr: rle decompression
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
26d7232722
commit
f7e26cca89
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "bytestream.h"
|
#include "bytestream.h"
|
||||||
|
#include "mathops.h"
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
|
|
||||||
enum ExrCompr {
|
enum ExrCompr {
|
||||||
@ -183,6 +184,42 @@ static void reorder_pixels(uint8_t *src, uint8_t *dst, int size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rle_uncompress(const uint8_t *src, int ssize, uint8_t *dst, int dsize)
|
||||||
|
{
|
||||||
|
int8_t *d = (int8_t *)dst;
|
||||||
|
int8_t *s = (int8_t *)src;
|
||||||
|
int8_t *dend = d + dsize;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
while (ssize > 0) {
|
||||||
|
count = *s++;
|
||||||
|
|
||||||
|
if (count < 0) {
|
||||||
|
count = -count;
|
||||||
|
|
||||||
|
if ((dsize -= count ) < 0 ||
|
||||||
|
(ssize -= count + 1) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
*d++ = *s++;
|
||||||
|
} else {
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if ((dsize -= count) < 0 ||
|
||||||
|
(ssize -= 2 ) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
*d++ = *s;
|
||||||
|
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dend != d;
|
||||||
|
}
|
||||||
|
|
||||||
static int decode_frame(AVCodecContext *avctx,
|
static int decode_frame(AVCodecContext *avctx,
|
||||||
void *data,
|
void *data,
|
||||||
int *data_size,
|
int *data_size,
|
||||||
@ -366,10 +403,10 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
s->compr = *buf;
|
s->compr = *buf;
|
||||||
switch (s->compr) {
|
switch (s->compr) {
|
||||||
case EXR_RAW:
|
case EXR_RAW:
|
||||||
|
case EXR_RLE:
|
||||||
case EXR_ZIP1:
|
case EXR_ZIP1:
|
||||||
case EXR_ZIP16:
|
case EXR_ZIP16:
|
||||||
break;
|
break;
|
||||||
case EXR_RLE:
|
|
||||||
case EXR_PIZ:
|
case EXR_PIZ:
|
||||||
case EXR_B44:
|
case EXR_B44:
|
||||||
default:
|
default:
|
||||||
@ -431,6 +468,7 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
|
|
||||||
switch (s->compr) {
|
switch (s->compr) {
|
||||||
case EXR_RAW:
|
case EXR_RAW:
|
||||||
|
case EXR_RLE:
|
||||||
case EXR_ZIP1:
|
case EXR_ZIP1:
|
||||||
scan_lines_per_block = 1;
|
scan_lines_per_block = 1;
|
||||||
break;
|
break;
|
||||||
@ -508,7 +546,14 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n");
|
av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n");
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
|
} else if (s->compr == EXR_RLE && data_size < uncompressed_size) {
|
||||||
|
if (rle_uncompress(avpkt->data + line_offset, data_size, s->tmp, uncompressed_size)) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "error during rle decompression\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->compr != EXR_RAW && data_size < uncompressed_size) {
|
||||||
predictor(s->tmp, uncompressed_size);
|
predictor(s->tmp, uncompressed_size);
|
||||||
reorder_pixels(s->tmp, s->uncompressed_data, uncompressed_size);
|
reorder_pixels(s->tmp, s->uncompressed_data, uncompressed_size);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user