summaryrefslogtreecommitdiff
path: root/src/libffmpeg/libavcodec/lcl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libffmpeg/libavcodec/lcl.c')
-rw-r--r--src/libffmpeg/libavcodec/lcl.c82
1 files changed, 56 insertions, 26 deletions
diff --git a/src/libffmpeg/libavcodec/lcl.c b/src/libffmpeg/libavcodec/lcl.c
index 9a8591a89..a15a10769 100644
--- a/src/libffmpeg/libavcodec/lcl.c
+++ b/src/libffmpeg/libavcodec/lcl.c
@@ -41,6 +41,7 @@
#include <stdlib.h>
#include "common.h"
+#include "bitstream.h"
#include "avcodec.h"
#ifdef CONFIG_ZLIB
@@ -144,14 +145,15 @@ static inline unsigned char get_r (unsigned char yq, signed char rq)
-static int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr)
+static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize)
{
unsigned char *destptr_bak = destptr;
+ unsigned char *destptr_end = destptr + destsize;
unsigned char mask = 0;
unsigned char maskbit = 0;
unsigned int ofs, cnt;
- while (srclen > 0) {
+ while ((srclen > 0) && (destptr < destptr_end)) {
if (maskbit == 0) {
mask = *(srcptr++);
maskbit = 8;
@@ -159,6 +161,8 @@ static int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destp
continue;
}
if ((mask & (1 << (--maskbit))) == 0) {
+ if (destptr + 4 > destptr_end)
+ break;
*(int*)destptr = *(int*)srcptr;
srclen -= 4;
destptr += 4;
@@ -171,6 +175,9 @@ static int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destp
ofs &= 0x7ff;
srclen -= 2;
cnt *= 4;
+ if (destptr + cnt > destptr_end) {
+ cnt = destptr_end - destptr;
+ }
for (; cnt > 0; cnt--) {
*(destptr) = *(destptr - ofs);
destptr++;
@@ -193,7 +200,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
{
LclContext * const c = (LclContext *)avctx->priv_data;
unsigned char *encoded = (unsigned char *)buf;
- int pixel_ptr;
+ unsigned int pixel_ptr;
int row, col;
unsigned char *outptr;
unsigned int width = avctx->width; // Real image width
@@ -205,11 +212,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
#ifdef CONFIG_ZLIB
int zret; // Zlib return code
#endif
- int len = buf_size;
-
- /* no supplementary picture */
- if (buf_size == 0)
- return 0;
+ unsigned int len = buf_size;
if(c->pic.data[0])
avctx->release_buffer(avctx, &c->pic);
@@ -231,24 +234,29 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
if (c->flags & FLAG_MULTITHREAD) {
mthread_inlen = *((unsigned int*)encoded);
mthread_outlen = *((unsigned int*)(encoded+4));
- mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf);
+ if (mthread_outlen > c->decomp_size) // this should not happen
+ mthread_outlen = c->decomp_size;
+ mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size);
if (mthread_outlen != mszh_dlen) {
av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
mthread_outlen, mszh_dlen);
+ return -1;
}
mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen,
- c->decomp_buf + mthread_outlen);
- if ((c->decomp_size - mthread_outlen) != mszh_dlen) {
+ c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen);
+ if (mthread_outlen != mszh_dlen) {
av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
- c->decomp_size - mthread_outlen, mszh_dlen);
+ mthread_outlen, mszh_dlen);
+ return -1;
}
encoded = c->decomp_buf;
len = c->decomp_size;
} else {
- mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf);
+ mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size);
if (c->decomp_size != mszh_dlen) {
av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
c->decomp_size, mszh_dlen);
+ return -1;
}
encoded = c->decomp_buf;
len = mszh_dlen;
@@ -277,10 +285,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
if (c->flags & FLAG_MULTITHREAD) {
mthread_inlen = *((unsigned int*)encoded);
mthread_outlen = *((unsigned int*)(encoded+4));
+ if (mthread_outlen > c->decomp_size)
+ mthread_outlen = c->decomp_size;
c->zstream.next_in = encoded + 8;
c->zstream.avail_in = mthread_inlen;
c->zstream.next_out = c->decomp_buf;
- c->zstream.avail_out = mthread_outlen;
+ c->zstream.avail_out = c->decomp_size;
zret = inflate(&(c->zstream), Z_FINISH);
if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret);
@@ -289,6 +299,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
if (mthread_outlen != (unsigned int)(c->zstream.total_out)) {
av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n",
mthread_outlen, c->zstream.total_out);
+ return -1;
}
zret = inflateReset(&(c->zstream));
if (zret != Z_OK) {
@@ -298,15 +309,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
c->zstream.next_in = encoded + 8 + mthread_inlen;
c->zstream.avail_in = len - mthread_inlen;
c->zstream.next_out = c->decomp_buf + mthread_outlen;
- c->zstream.avail_out = mthread_outlen;
+ c->zstream.avail_out = c->decomp_size - mthread_outlen;
zret = inflate(&(c->zstream), Z_FINISH);
if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret);
return -1;
}
- if ((c->decomp_size - mthread_outlen) != (unsigned int)(c->zstream.total_out)) {
+ if (mthread_outlen != (unsigned int)(c->zstream.total_out)) {
av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n",
- c->decomp_size - mthread_outlen, c->zstream.total_out);
+ mthread_outlen, c->zstream.total_out);
+ return -1;
}
} else {
c->zstream.next_in = encoded;
@@ -321,6 +333,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
if (c->decomp_size != (unsigned int)(c->zstream.total_out)) {
av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
c->decomp_size, c->zstream.total_out);
+ return -1;
}
}
encoded = c->decomp_buf;
@@ -567,13 +580,20 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret);
return -1;
}
- c->zstream.next_in = p->data[0];
- c->zstream.avail_in = c->decomp_size;
c->zstream.next_out = c->comp_buf;
c->zstream.avail_out = c->max_comp_size;
+ for(i = avctx->height - 1; i >= 0; i--) {
+ c->zstream.next_in = p->data[0]+p->linesize[0]*i;
+ c->zstream.avail_in = avctx->width*3;
+ zret = deflate(&(c->zstream), Z_NO_FLUSH);
+ if (zret != Z_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
+ return -1;
+ }
+ }
zret = deflate(&(c->zstream), Z_FINISH);
- if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
+ if (zret != Z_STREAM_END) {
av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
return -1;
}
@@ -596,7 +616,9 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
static int decode_init(AVCodecContext *avctx)
{
LclContext * const c = (LclContext *)avctx->priv_data;
- int basesize = avctx->width * avctx->height;
+ unsigned int basesize = avctx->width * avctx->height;
+ unsigned int max_basesize = ((avctx->width + 3) & ~3) * ((avctx->height + 3) & ~3);
+ unsigned int max_decomp_size;
int zret; // Zlib return code
c->avctx = avctx;
@@ -614,6 +636,10 @@ static int decode_init(AVCodecContext *avctx)
return 1;
}
+ if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
+ return 1;
+ }
+
/* Check codec type */
if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) ||
((avctx->codec_id == CODEC_ID_ZLIB) && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) {
@@ -624,26 +650,32 @@ static int decode_init(AVCodecContext *avctx)
switch (c->imgtype = *((char *)avctx->extradata + 4)) {
case IMGTYPE_YUV111:
c->decomp_size = basesize * 3;
+ max_decomp_size = max_basesize * 3;
av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n");
break;
case IMGTYPE_YUV422:
c->decomp_size = basesize * 2;
+ max_decomp_size = max_basesize * 2;
av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n");
break;
case IMGTYPE_RGB24:
c->decomp_size = basesize * 3;
+ max_decomp_size = max_basesize * 3;
av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n");
break;
case IMGTYPE_YUV411:
c->decomp_size = basesize / 2 * 3;
+ max_decomp_size = max_basesize / 2 * 3;
av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n");
break;
case IMGTYPE_YUV211:
c->decomp_size = basesize * 2;
+ max_decomp_size = max_basesize * 2;
av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n");
break;
case IMGTYPE_YUV420:
c->decomp_size = basesize / 2 * 3;
+ max_decomp_size = max_basesize / 2 * 3;
av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n");
break;
default:
@@ -698,9 +730,8 @@ static int decode_init(AVCodecContext *avctx)
}
/* Allocate decompression buffer */
- /* 4*8 max overflow space for mszh decomp algorithm */
if (c->decomp_size) {
- if ((c->decomp_buf = av_malloc(c->decomp_size+4*8)) == NULL) {
+ if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) {
av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
return 1;
}
@@ -785,7 +816,7 @@ static int encode_init(AVCodecContext *avctx)
((uint8_t*)avctx->extradata)[4]= c->imgtype;
((uint8_t*)avctx->extradata)[5]= c->compression;
((uint8_t*)avctx->extradata)[6]= c->flags;
- ((uint8_t*)avctx->extradata)[7]= 0;
+ ((uint8_t*)avctx->extradata)[7]= CODEC_ZLIB;
c->avctx->extradata_size= 8;
c->zstream.zalloc = Z_NULL;
@@ -843,7 +874,7 @@ static int encode_end(AVCodecContext *avctx)
LclContext *c = avctx->priv_data;
av_freep(&avctx->extradata);
- av_freep(c->comp_buf);
+ av_freep(&c->comp_buf);
#ifdef CONFIG_ZLIB
deflateEnd(&(c->zstream));
#endif
@@ -886,7 +917,6 @@ AVCodec zlib_encoder = {
encode_init,
encode_frame,
encode_end,
-// .options = lcl_options,
};
#endif //CONFIG_ENCODERS