---
libavcodec/dxa.c | 257
++++++++++++++++++++++++++++--------------------------
1 files changed, 135 insertions(+), 122 deletions(-)
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index 97b912a..73e0b47 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -29,6 +29,7 @@
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
+#include "bytestream.h"
#include <zlib.h>
@@ -39,41 +40,57 @@ typedef struct DxaDecContext {
AVCodecContext *avctx;
AVFrame pic, prev;
- int dsize;
+ unsigned long decomp_size;
+ int allocated_decomp_size;
uint8_t *decomp_buf;
uint32_t pal[256];
+ GetByteContext g;
} DxaDecContext;
static const int shift1[6] = { 0, 8, 8, 8, 4, 4 };
static const int shift2[6] = { 0, 0, 8, 4, 0, 4 };
-static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t*
dst, uint8_t *src, uint8_t *ref)
-{
- uint8_t *code, *data, *mv, *msk, *tmp, *tmp2;
+static int decode_13 (DxaDecContext *c, uint8_t *dst, uint8_t *ref)
+ {
+ GetByteContext data, mv, msk;
+ int mv_offset, msk_offset;
+ uint8_t tmp3;
+ uint8_t t[4];
+ uint8_t *tmp, *tmp2;
int i, j, k;
int type, x, y, d, d2;
int stride = c->pic.linesize[0];
uint32_t mask;
- code = src + 12;
- data = code + ((avctx->width * avctx->height) >> 4);
- mv = data + AV_RB32(src + 0);
- msk = mv + AV_RB32(src + 4);
+ mv_offset = bytestream2_get_be32 (&c->g);
+ msk_offset = bytestream2_get_be32 (&c->g);
+ bytestream2_skip (&c->g, 4);
+ data = c->g;
+ bytestream2_skip (&data, (c->avctx->width * c->avctx->height) >> 4);
+ mv = data;
+ bytestream2_skip (&mv, mv_offset);
+ msk = mv;
+ bytestream2_skip (&msk, msk_offset);
- for(j = 0; j < avctx->height; j += 4){
- for(i = 0; i < avctx->width; i += 4){
+ for (j = 0; j < c->avctx->height; j += 4) {
+ for (i = 0; i < c->avctx->width; i += 4) {
tmp = dst + i;
tmp2 = ref + i;
- type = *code++;
- switch(type){
+ type = bytestream2_get_byte (&c->g);
+ switch (type) {
case 4: // motion compensation
- x = (*mv) >> 4; if(x & 8) x = 8 - x;
- y = (*mv++) & 0xF; if(y & 8) y = 8 - y;
+ tmp3 = bytestream2_get_byte (&mv);
+ x = tmp3 >> 4;
+ if (x & 8)
+ x = 8 - x;
+ y = tmp3 & 0xF;
+ if (y & 8)
+ y = 8 - y;
tmp2 += x + y*stride;
case 0: // skip
case 5: // skip in method 12
- for(y = 0; y < 4; y++){
- memcpy(tmp, tmp2, 4);
+ for (y = 0; y < 4; y++) {
+ memcpy (tmp, tmp2, 4);
tmp += stride;
tmp2 += stride;
}
@@ -85,17 +102,16 @@ static int decode_13(AVCodecContext *avctx,
DxaDecContext *c, uint8_t* dst, uint
case 13:
case 14:
case 15:
- if(type == 1){
- mask = AV_RB16(msk);
- msk += 2;
- }else{
+ if (type == 1)
+ mask = bytestream2_get_be16 (&msk);
+ else {
+ tmp3 = bytestream2_get_byte (&msk);
type -= 10;
- mask = ((msk[0] & 0xF0) << shift1[type]) | ((msk[0] &
0xF) << shift2[type]);
- msk++;
+ mask = ((tmp3 & 0xF0) << shift1[type]) | ((tmp3 & 0xF)
<< shift2[type]);
}
- for(y = 0; y < 4; y++){
- for(x = 0; x < 4; x++){
- tmp[x] = (mask & 0x8000) ? *data++ : tmp2[x];
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ tmp[x] = (mask & 0x8000) ? bytestream2_get_byte
(&data) : tmp2[x];
mask <<= 1;
}
tmp += stride;
@@ -103,29 +119,33 @@ static int decode_13(AVCodecContext *avctx,
DxaDecContext *c, uint8_t* dst, uint
}
break;
case 2: // fill block
- for(y = 0; y < 4; y++){
- memset(tmp, data[0], 4);
+ tmp3 = bytestream2_get_byte (&data);
+ for (y = 0; y < 4; y++) {
+ memset (tmp, tmp3, 4);
tmp += stride;
}
- data++;
break;
case 3: // raw block
- for(y = 0; y < 4; y++){
- memcpy(tmp, data, 4);
- data += 4;
+ for (y = 0; y < 4; y++) {
+ bytestream2_get_buffer (&data, tmp, 4);
tmp += stride;
}
break;
case 8: // subblocks - method 13 only
- mask = *msk++;
- for(k = 0; k < 4; k++){
+ mask = bytestream2_get_byte (&msk);
+ for (k = 0; k < 4; k++) {
d = ((k & 1) << 1) + ((k & 2) * stride);
d2 = ((k & 1) << 1) + ((k & 2) * stride);
tmp2 = ref + i + d2;
- switch(mask & 0xC0){
+ switch (mask & 0xC0) {
case 0x80: // motion compensation
- x = (*mv) >> 4; if(x & 8) x = 8 - x;
- y = (*mv++) & 0xF; if(y & 8) y = 8 - y;
+ tmp3 = bytestream2_get_byte (&mv);
+ x = tmp3 >> 4;
+ if (x & 8)
+ x = 8 - x;
+ y = tmp3 & 0xF;
+ if (y & 8)
+ y = 8 - y;
tmp2 += x + y*stride;
case 0x00: // skip
tmp[d + 0 ] = tmp2[0];
@@ -134,51 +154,47 @@ static int decode_13(AVCodecContext *avctx,
DxaDecContext *c, uint8_t* dst, uint
tmp[d + 1 + stride] = tmp2[1 + stride];
break;
case 0x40: // fill
- tmp[d + 0 ] = data[0];
- tmp[d + 1 ] = data[0];
- tmp[d + 0 + stride] = data[0];
- tmp[d + 1 + stride] = data[0];
- data++;
+ tmp3 = bytestream2_get_byte (&data);
+ tmp[d + 0 ] = tmp3;
+ tmp[d + 1 ] = tmp3;
+ tmp[d + 0 + stride] = tmp3;
+ tmp[d + 1 + stride] = tmp3;
break;
case 0xC0: // raw
- tmp[d + 0 ] = *data++;
- tmp[d + 1 ] = *data++;
- tmp[d + 0 + stride] = *data++;
- tmp[d + 1 + stride] = *data++;
+ tmp[d ] = bytestream2_get_be16 (&data);
+ tmp[d + stride] = bytestream2_get_be16 (&data);
break;
}
mask <<= 2;
}
break;
case 32: // vector quantization - 2 colors
- mask = AV_RB16(msk);
- msk += 2;
- for(y = 0; y < 4; y++){
- for(x = 0; x < 4; x++){
- tmp[x] = data[mask & 1];
+ mask = bytestream2_get_be16 (&msk);
+ bytestream2_get_buffer (&data, t, 2);
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ tmp[x] = t[mask & 1];
mask >>= 1;
}
tmp += stride;
tmp2 += stride;
}
- data += 2;
break;
case 33: // vector quantization - 3 or 4 colors
case 34:
- mask = AV_RB32(msk);
- msk += 4;
- for(y = 0; y < 4; y++){
- for(x = 0; x < 4; x++){
- tmp[x] = data[mask & 3];
+ mask = bytestream2_get_be32 (&msk);
+ bytestream2_get_buffer (&data, t, 4);
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ tmp[x] = t[mask & 3];
mask >>= 2;
}
tmp += stride;
tmp2 += stride;
}
- data += type - 30;
break;
default:
- av_log(avctx, AV_LOG_ERROR, "Unknown opcode %d\n", type);
+ av_log (c->avctx, AV_LOG_ERROR, "Unknown opcode %d\n",
type);
return -1;
}
}
@@ -188,63 +204,62 @@ static int decode_13(AVCodecContext *avctx,
DxaDecContext *c, uint8_t* dst, uint
return 0;
}
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
+static int decode_frame (AVCodecContext *avctx,
+ void *data, int *data_size, AVPacket *avpkt)
+ {
DxaDecContext * const c = avctx->priv_data;
- uint8_t *outptr, *srcptr, *tmpptr;
- unsigned long dsize;
+ uint8_t *outptr, *tmpptr;
int i, j, compr;
int stride;
- int orig_buf_size = buf_size;
int pc = 0;
- /* make the palette available on the way out */
- if(buf[0]=='C' && buf[1]=='M' && buf[2]=='A' && buf[3]=='P'){
- int r, g, b;
+ bytestream2_init (&c->g, avpkt->data, avpkt->size);
- buf += 4;
- for(i = 0; i < 256; i++){
- r = *buf++;
- g = *buf++;
- b = *buf++;
- c->pal[i] = (r << 16) | (g << 8) | b;
- }
+ /* make the palette available on the way out */
+ if (bytestream2_peek_le32 (&c->g) == MKTAG ('C', 'M', 'A', 'P')) {
+ bytestream2_skip (&c->g, 4);
+ for (i = 0; i < 256; i++)
+ c->pal[i] = bytestream2_get_be24 (&c->g);
pc = 1;
- buf_size -= 768+4;
}
- if(avctx->get_buffer(avctx, &c->pic) < 0){
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ if (avctx->get_buffer (avctx, &c->pic) < 0) {
+ av_log (avctx, AV_LOG_ERROR, "get_buffer () failed\n");
return -1;
}
- memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
+ memcpy (c->pic.data[1], c->pal, AVPALETTE_SIZE);
c->pic.palette_has_changed = pc;
outptr = c->pic.data[0];
- srcptr = c->decomp_buf;
tmpptr = c->prev.data[0];
stride = c->pic.linesize[0];
- if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L')
+ if (bytestream2_get_le32 (&c->g) == MKTAG ('N', 'U', 'L', 'L')) {
compr = -1;
- else
- compr = buf[4];
+ }
+ else {
+ compr = bytestream2_get_byte (&c->g);
+ bytestream2_skip (&c->g, 4);
+ }
- dsize = c->dsize;
- if((compr != 4 && compr != -1) && uncompress(c->decomp_buf, &dsize,
buf + 9, buf_size - 9) != Z_OK){
- av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n");
- return -1;
+ if ((compr != 4 && compr != -1)) {
+ c->decomp_size = c->allocated_decomp_size;
+ if (uncompress (c->decomp_buf, &c->decomp_size,
+ avpkt->data + bytestream2_tell (&c->g),
+ bytestream2_get_bytes_left (&c->g)) != Z_OK) {
+ av_log (avctx, AV_LOG_ERROR, "Uncompress failed!\n");
+ return -1;
+ }
}
- switch(compr){
+ bytestream2_init (&c->g, c->decomp_buf, c->decomp_size);
+ switch (compr) {
case -1:
c->pic.key_frame = 0;
c->pic.pict_type = AV_PICTURE_TYPE_P;
- if(c->prev.data[0])
- memcpy(c->pic.data[0], c->prev.data[0], c->pic.linesize[0] *
avctx->height);
- else{ // Should happen only when first frame is 'NULL'
- memset(c->pic.data[0], 0, c->pic.linesize[0] * avctx->height);
+ if (c->prev.data[0])
+ memcpy (c->pic.data[0], c->prev.data[0], c->pic.linesize[0] *
avctx->height);
+ else { // Should happen only when first frame is 'NULL'
+ memset (c->pic.data[0], 0, c->pic.linesize[0] * avctx->height);
c->pic.key_frame = 1;
c->pic.pict_type = AV_PICTURE_TYPE_I;
}
@@ -253,66 +268,65 @@ static int decode_frame(AVCodecContext *avctx, void
*data, int *data_size, AVPac
case 3:
case 4:
case 5:
- c->pic.key_frame = !(compr & 1);
+ c->pic.key_frame = ! (compr & 1);
c->pic.pict_type = (compr & 1) ? AV_PICTURE_TYPE_P :
AV_PICTURE_TYPE_I;
- for(j = 0; j < avctx->height; j++){
- if(compr & 1){
- for(i = 0; i < avctx->width; i++)
- outptr[i] = srcptr[i] ^ tmpptr[i];
+ for (j = 0; j < avctx->height; j++) {
+ if (compr & 1) {
+ for (i = 0; i < avctx->width; i++)
+ outptr[i] = bytestream2_get_byte (&c->g) ^ tmpptr[i];
tmpptr += stride;
}else
- memcpy(outptr, srcptr, avctx->width);
+ bytestream2_get_buffer (&c->g, outptr, avctx->width);
outptr += stride;
- srcptr += avctx->width;
}
break;
case 12: // ScummVM coding
case 13:
c->pic.key_frame = 0;
c->pic.pict_type = AV_PICTURE_TYPE_P;
- decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]);
+ decode_13 (c, c->pic.data[0], c->prev.data[0]);
break;
default:
- av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type
%d\n", buf[4]);
+ av_log (avctx, AV_LOG_ERROR, "Unknown/unsupported compression type
%d\n", compr);
return -1;
}
- FFSWAP(AVFrame, c->pic, c->prev);
- if(c->pic.data[0])
- avctx->release_buffer(avctx, &c->pic);
+ FFSWAP (AVFrame, c->pic, c->prev);
+ if (c->pic.data[0])
+ avctx->release_buffer (avctx, &c->pic);
- *data_size = sizeof(AVFrame);
- *(AVFrame*)data = c->prev;
+ *data_size = sizeof (AVFrame);
+ * (AVFrame*)data = c->prev;
/* always report that the buffer was completely consumed */
- return orig_buf_size;
+ return avpkt->size;
}
-static av_cold int decode_init(AVCodecContext *avctx)
-{
+static av_cold int decode_init (AVCodecContext *avctx)
+ {
DxaDecContext * const c = avctx->priv_data;
c->avctx = avctx;
avctx->pix_fmt = PIX_FMT_PAL8;
- c->dsize = avctx->width * avctx->height * 2;
- if((c->decomp_buf = av_malloc(c->dsize)) == NULL) {
- av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression
buffer.\n");
+ c->allocated_decomp_size = avctx->width * avctx->height * 2;
+ if ((c->decomp_buf = av_malloc (c->allocated_decomp_size)) == NULL) {
+ av_log (avctx, AV_LOG_ERROR, "Can't allocate decompression
buffer.\n");
return -1;
}
return 0;
}
-static av_cold int decode_end(AVCodecContext *avctx)
-{
+static av_cold int decode_end (AVCodecContext *avctx)
+ {
DxaDecContext * const c = avctx->priv_data;
- av_freep(&c->decomp_buf);
- if(c->prev.data[0])
- avctx->release_buffer(avctx, &c->prev);
- if(c->pic.data[0])
- avctx->release_buffer(avctx, &c->pic);
+ av_freep (&c->decomp_buf);
+ if (c->prev.data[0])
+ avctx->release_buffer (avctx, &c->prev);
+ if (c->pic.data[0])
+ avctx->release_buffer (avctx, &c->pic);
return 0;
}
@@ -321,11 +335,10 @@ AVCodec ff_dxa_decoder = {
.name = "dxa",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_DXA,
- .priv_data_size = sizeof(DxaDecContext),
+ .priv_data_size = sizeof (DxaDecContext),
.init = decode_init,
.close = decode_end,
.decode = decode_frame,
.capabilities = CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"),
+ .long_name = NULL_IF_CONFIG_SMALL ("Feeble Files/ScummVM DXA"),
};
-
--
1.7.5.4
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel