[PATCH] Simplify vqa_decode_chunk part I
Adam Iglewski
adam.iglewski
Sat May 9 11:42:25 CEST 2009
---
libavcodec/vqavideo.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 119 insertions(+), 0 deletions(-)
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index 9646d67..e991cdd 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -121,6 +121,7 @@ typedef struct VqaContext {
int codebook_size;
unsigned char *next_codebook_buffer; /* accumulator for next codebook */
int next_codebook_buffer_index;
+ int is_codebook;
unsigned char *decode_buffer;
int decode_buffer_size;
@@ -188,6 +189,7 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
s->codebook[codebook_index++] = i;
}
s->next_codebook_buffer_index = 0;
+ s->is_codebook = 0;
/* allocate decode buffer */
s->decode_buffer_size = (s->width / s->vector_width) *
@@ -345,6 +347,123 @@ static void vqa_decode_hc_video_frame(VqaContext *s,const unsigned char *src,uns
}
}
+static void vqa_decode_pal8_video_frame(VqaContext *s,const unsigned char *src,unsigned int src_size)
+{
+ int x, y;
+ int lines;
+ int vector_index;
+ int index_shift;
+
+ unsigned char *pixels, *frame_end;
+ const unsigned char *mid_src = src + (src_size>>1);
+ unsigned int *codebook = (unsigned int *)s->codebook;
+
+ frame_end = s->frame.data[0] + s->height * s->frame.linesize[0] + s->width;
+
+ if (s->vector_height == 4)
+ index_shift = 4;
+ else
+ index_shift = 3;
+
+ for (y = 0; y < s->frame.linesize[0] * s->height;
+ y += s->frame.linesize[0] * s->vector_height) {
+
+ for (x = y; x < y + s->width; x += 4) {
+ pixels = s->frame.data[0] + x;
+ lines = s->vector_height;
+
+ /* get the vector index, the method for which varies according to
+ * VQA file version */
+ switch (s->vqa_version) {
+
+ case 1:
+/* still need sample media for this case (only one game, "Legend of
+ * Kyrandia III : Malcolm's Revenge", is known to use this version) */
+
+ vector_index = bytestream_get_le16(&src);
+
+ /* uniform color fill - a quick hack */
+ if((vector_index & 0xff00) == 0xff00) {
+ while(lines--) {
+ memset(pixels,255-(vector_index & 0x00ff),4);
+ pixels += s->frame.linesize[0];
+ }
+ continue;
+ }
+ vector_index >>= 3;
+ break;
+
+ case 2:
+ vector_index = (*mid_src++ << 8) | *src++;
+ break;
+ }
+
+ codebook = (unsigned int *) (s->codebook + (vector_index << index_shift));
+ while (lines--) {
+ *(unsigned int *) pixels = *codebook++;
+ pixels += s->frame.linesize[0];
+ }
+ }
+ }
+}
+
+static const unsigned char* vqa_get_chunk(unsigned int chunk_type, const unsigned char *buff,
+ unsigned int buff_size,unsigned int *chunk_size)
+{
+ const unsigned char *buff_end = buff + buff_size;
+ unsigned int curr_chunk_type;
+ unsigned int curr_chunk_size;
+
+ while(buff + CHUNK_PREAMBLE_SIZE < buff_end)
+ {
+ curr_chunk_type = bytestream_get_be32(&buff);
+ curr_chunk_size = bytestream_get_be32(&buff);
+ if(chunk_type == curr_chunk_type)
+ {
+ if(curr_chunk_size + buff > buff_end) {
+ av_log(NULL, AV_LOG_ERROR, " VQA video: problem: chunk exceeded packet size\n");
+ return 0;
+ }
+ *chunk_size = curr_chunk_size;
+ return buff;
+ }
+ buff += curr_chunk_size + (curr_chunk_size & 0x01);
+ }
+
+ return 0;
+}
+
+static void vqa_join_partial_codebook(VqaContext *s,unsigned int chunk_type,const unsigned char *chunk,
+ unsigned int chunk_size)
+{
+ if (s->next_codebook_buffer_index + chunk_size > MAX_CODEBOOK_SIZE) {
+ av_log(s->avctx, AV_LOG_ERROR, " problem: partial codebook bigger than max allowed size\n");
+ return;
+ }
+ /* accumulate partial codebook */
+ memcpy(&s->next_codebook_buffer[s->next_codebook_buffer_index],
+ chunk, chunk_size);
+ s->next_codebook_buffer_index += chunk_size;
+
+ s->partial_countdown--;
+ if (!s->partial_countdown) {
+
+ /* time to replace codebook */
+ if (chunk_type == CBP0_TAG)
+ memcpy(s->codebook, s->next_codebook_buffer,
+ s->next_codebook_buffer_index);
+ else
+ decode_format80(s->next_codebook_buffer,
+ s->next_codebook_buffer_index,
+ s->codebook, s->codebook_size, 0);
+
+ /* reset accounting */
+ s->next_codebook_buffer_index = 0;
+ s->partial_countdown = s->partial_count;
+ s->is_codebook = 1;
+ }
+}
+
static void vqa_decode_chunk(VqaContext *s)
{
unsigned int chunk_type;
--
1.6.0.4
--------------000406070301060204010203
Content-Type: text/x-diff;
name="0007-Simplify-vqa_decode_chunk-part-II.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="0007-Simplify-vqa_decode_chunk-part-II.patch"
More information about the ffmpeg-devel
mailing list