1 /*
2 * Westwood Studios VQA Video Decoder
3 * Copyright (c) 2003 Mike Melanson <melanson@pcisys.net>
4 * Copyright (c) 2021 Pekka Väänänen <pekka.vaananen@iki.fi>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file
25 * VQA Video Decoder
26 * @author Mike Melanson (melanson@pcisys.net)
27 * @see http://wiki.multimedia.cx/index.php?title=VQA
28 *
29 * The VQA video decoder outputs PAL8 or RGB555 colorspace data, depending
30 * on the type of data in the file.
31 *
32 * This decoder needs the 42-byte VQHD header from the beginning
33 * of the VQA file passed through the extradata field. The VQHD header
34 * is laid out as:
35 *
36 * bytes 0-3 chunk fourcc: 'VQHD'
37 * bytes 4-7 chunk size in big-endian format, should be 0x0000002A
38 * bytes 8-49 VQHD chunk data
39 *
40 * Bytes 8-49 are what this decoder expects to see.
41 *
42 * Briefly, VQA is a vector quantized animation format that operates in a
43 * VGA palettized colorspace. It operates on pixel vectors (blocks)
44 * of either 4x2 or 4x4 in size. Compressed VQA chunks can contain vector
45 * codebooks, palette information, and code maps for rendering vectors onto
46 * frames. Any of these components can also be compressed with a run-length
47 * encoding (RLE) algorithm commonly referred to as "format80".
48 *
49 * VQA takes a novel approach to rate control. Each group of n frames
50 * (usually, n = 8) relies on a different vector codebook. Rather than
51 * transporting an entire codebook every 8th frame, the new codebook is
52 * broken up into 8 pieces and sent along with the compressed video chunks
53 * for each of the 8 frames preceding the 8 frames which require the
54 * codebook. A full codebook is also sent on the very first frame of a
55 * file. This is an interesting technique, although it makes random file
56 * seeking difficult despite the fact that the frames are all intracoded.
57 *
58 * V1,2 VQA uses 12-bit codebook indexes. If the 12-bit indexes were
59 * packed into bytes and then RLE compressed, bytewise, the results would
60 * be poor. That is why the coding method divides each index into 2 parts,
61 * the top 4 bits and the bottom 8 bits, then RL encodes the 4-bit pieces
62 * together and the 8-bit pieces together. If most of the vectors are
63 * clustered into one group of 256 vectors, most of the 4-bit index pieces
64 * should be the same.
65 *
66 * VQA3 introduces a 15-bit high color codebook, delta coding, replaces
67 * the above "split byte" scheme with RLE compression, and extends the
68 * "format80" compression with relative references. In VQA3 the whole
69 * codebook is always updated as a whole without splitting it into pieces.
70 */
71
72 #include <stdio.h>
73 #include <string.h>
74
81
82 #define PALETTE_COUNT 256
83 #define VQA_HEADER_SIZE 0x2A
84
85 /* allocate the maximum vector space, regardless of the file version:
86 * (0xFF00 codebook vectors + 0x100 solid pixel vectors) * (4x4 pixels/block) */
87 #define MAX_CODEBOOK_VECTORS 0xFF00
88 #define SOLID_PIXEL_VECTORS 0x100
89 #define MAX_VECTORS (MAX_CODEBOOK_VECTORS + SOLID_PIXEL_VECTORS)
90 #define MAX_CODEBOOK_SIZE (MAX_VECTORS * 4 * 4 * sizeof(uint16_t))
91
92 #define CBF0_TAG MKBETAG('C', 'B', 'F', '0')
93 #define CBFZ_TAG MKBETAG('C', 'B', 'F', 'Z')
94 #define CBP0_TAG MKBETAG('C', 'B', 'P', '0')
95 #define CBPZ_TAG MKBETAG('C', 'B', 'P', 'Z')
96 #define CPL0_TAG MKBETAG('C', 'P', 'L', '0')
97 #define CPLZ_TAG MKBETAG('C', 'P', 'L', 'Z')
98 #define VPTZ_TAG MKBETAG('V', 'P', 'T', 'Z')
99 #define VPTR_TAG MKBETAG('V', 'P', 'T', 'R')
100 #define VPRZ_TAG MKBETAG('V', 'P', 'R', 'Z')
101
106
108
114
115 unsigned char *
codebook;
/* the current codebook */
119
122
123 /* number of frames to go before replacing codebook */
127
129 {
131 int i, j, codebook_index,
ret;
132 int colors;
133
135
136 /* make sure the extradata made it */
140 }
141
142 /* load up the VQA parameters from the header */
143 s->vqa_version =
s->avctx->extradata[0];
144
145 if (
s->vqa_version < 1 ||
s->vqa_version > 3) {
148 }
149
150 s->width =
AV_RL16(&
s->avctx->extradata[6]);
151 s->height =
AV_RL16(&
s->avctx->extradata[8]);
153 s->width=
s->height= 0;
155 }
156 s->vector_width =
s->avctx->extradata[10];
157 s->vector_height =
s->avctx->extradata[11];
158 s->partial_count =
s->partial_countdown =
s->avctx->extradata[13];
159
160 colors = (
s->avctx->extradata[14] << 8) |
s->avctx->extradata[15];
161
164 } else {
166 }
167
168 /* the vector dimensions have to meet very stringent requirements */
169 if ((
s->vector_width != 4) ||
170 ((
s->vector_height != 2) && (
s->vector_height != 4))) {
171 /* return without further initialization */
173 }
174
175 if (
s->width %
s->vector_width ||
s->height %
s->vector_height) {
178 }
179
183
184 /* allocate codebooks */
189 s->next_codebook_buffer =
av_malloc(
s->codebook_size);
190 if (!
s->next_codebook_buffer)
192
193 /* allocate decode buffer */
194 s->decode_buffer_size = (
s->width /
s->vector_width) *
195 (
s->height /
s->vector_height) * 2;
197 if (!
s->decode_buffer)
199
200 /* initialize the solid-color vectors */
201 if (
s->vector_height == 4) {
202 codebook_index = 0xFF00 * 16;
203 for (
i = 0;
i < 256;
i++)
204 for (j = 0; j < 16; j++)
205 s->codebook[codebook_index++] =
i;
206 } else {
207 codebook_index = 0xF00 * 8;
208 for (
i = 0;
i < 256;
i++)
209 for (j = 0; j < 8; j++)
210 s->codebook[codebook_index++] =
i;
211 }
212 s->next_codebook_buffer_index = 0;
213
214 return 0;
215 }
216
217 #define CHECK_COUNT() \
218 if (dest_index + count > dest_size) { \
219 av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: next op would overflow dest_index\n"); \
220 av_log(s->avctx, AV_LOG_ERROR, "current dest_index = %d, count = %d, dest_size = %d\n", \
221 dest_index, count, dest_size); \
222 return AVERROR_INVALIDDATA; \
223 }
224
225 #define CHECK_COPY(idx) \
226 if (idx < 0 || idx + count > dest_size) { \
227 av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: next op would overflow dest_index\n"); \
228 av_log(s->avctx, AV_LOG_ERROR, "current src_pos = %d, count = %d, dest_size = %d\n", \
229 src_pos, count, dest_size); \
230 return AVERROR_INVALIDDATA; \
231 }
232
233
235 unsigned char *dest,
int dest_size,
int check_size) {
236
237 int dest_index = 0;
238 int count, opcode, start;
239 int src_pos;
243
246 src_size);
248 }
249
250 /* the "new" scheme makes references relative to destination pointer */
251 if (bytestream2_peek_byte(&
s->gb) == 0x00) {
253 bytestream2_get_byte(&
s->gb);
254 ff_tlog(
s->avctx,
"found new format stream ");
255 }
256
259 opcode = bytestream2_get_byte(&
s->gb);
260 ff_tlog(
s->avctx,
"opcode %02X: ", opcode);
261
262 /* 0x80 means that frame is finished */
263 if (opcode == 0x80)
264 break;
265
266 if (dest_index >= dest_size) {
267 av_log(
s->avctx,
AV_LOG_ERROR,
"decode_format80 problem: dest_index (%d) exceeded dest_size (%d)\n",
268 dest_index, dest_size);
270 }
271
272 if (opcode == 0xFF) {
273
274 count = bytestream2_get_le16(&
s->gb);
275 src_pos = bytestream2_get_le16(&
s->gb);
277 src_pos = dest_index - src_pos;
278 ff_tlog(
s->avctx,
"(1) copy %X bytes from pos %X\n", count, src_pos);
281 for (
i = 0;
i < count;
i++)
282 dest[dest_index +
i] = dest[src_pos +
i];
283 dest_index += count;
284
285 } else if (opcode == 0xFE) {
286
287 count = bytestream2_get_le16(&
s->gb);
288 color = bytestream2_get_byte(&
s->gb);
289 ff_tlog(
s->avctx,
"(2) set %X bytes to %02X\n", count,
color);
291 memset(&dest[dest_index],
color, count);
292 dest_index += count;
293
294 } else if ((opcode & 0xC0) == 0xC0) {
295
296 count = (opcode & 0x3F) + 3;
297 src_pos = bytestream2_get_le16(&
s->gb);
299 src_pos = dest_index - src_pos;
300 ff_tlog(
s->avctx,
"(3) copy %X bytes from pos %X\n", count, src_pos);
303 for (
i = 0;
i < count;
i++)
304 dest[dest_index +
i] = dest[src_pos +
i];
305 dest_index += count;
306
307 } else if (opcode > 0x80) {
308
309 count = opcode & 0x3F;
310 ff_tlog(
s->avctx,
"(4) copy %X bytes from source to dest\n", count);
313 dest_index += count;
314
315 } else {
316
317 count = ((opcode & 0x70) >> 4) + 3;
318 src_pos = bytestream2_get_byte(&
s->gb) | ((opcode & 0x0F) << 8);
319 ff_tlog(
s->avctx,
"(5) copy %X bytes from relpos %X\n", count, src_pos);
322 for (
i = 0;
i < count;
i++)
323 dest[dest_index +
i] = dest[dest_index - src_pos +
i];
324 dest_index += count;
325 }
326 }
327
328 /* validate that the entire destination buffer was filled; this is
329 * important for decoding frame maps since each vector needs to have a
330 * codebook entry; it is not important for compressed codebooks because
331 * not every entry needs to be filled */
333 if (dest_index < dest_size) {
334 av_log(
s->avctx,
AV_LOG_ERROR,
"decode_format80 problem: decode finished with dest_index (%d) < dest_size (%d)\n",
335 dest_index, dest_size);
336 memset(dest + dest_index, 0, dest_size - dest_index);
337 }
338
339 return 0; // let's display what we decoded anyway
340 }
341
343 {
344 unsigned int chunk_type;
345 unsigned int chunk_size;
346 int byte_skip;
347 unsigned int index = 0;
349 unsigned char r,
g,
b;
350 int index_shift;
351 int res;
352
353 int cbf0_chunk = -1;
354 int cbfz_chunk = -1;
355 int cbp0_chunk = -1;
356 int cbpz_chunk = -1;
357 int cpl0_chunk = -1;
358 int cplz_chunk = -1;
359 int vptz_chunk = -1;
360
361 int x, y;
362 int lines = 0;
363 int pixel_ptr;
364 int vector_index = 0;
365 int lobyte = 0;
366 int hibyte = 0;
367 int lobytes = 0;
368 int hibytes =
s->decode_buffer_size / 2;
369
370 /* first, traverse through the frame and find the subchunks */
372
373 chunk_type = bytestream2_get_be32u(&
s->gb);
375 chunk_size = bytestream2_get_be32u(&
s->gb);
376
377 switch (chunk_type) {
378
381 break;
382
385 break;
386
389 break;
390
393 break;
394
397 break;
398
401 break;
402
405 break;
406
407 default:
410 break;
411 }
412
413 byte_skip = chunk_size & 0x01;
415 }
416
417 /* next, deal with the palette */
418 if ((cpl0_chunk != -1) && (cplz_chunk != -1)) {
419
420 /* a chunk should not have both chunk types */
423 }
424
425 /* decompress the palette chunk */
426 if (cplz_chunk != -1) {
427
428 /* yet to be handled */
429
430 }
431
432 /* convert the RGB palette into the machine's endian format */
433 if (cpl0_chunk != -1) {
434
436 chunk_size = bytestream2_get_be32(&
s->gb);
437 /* sanity check the palette size */
440 chunk_size / 3);
442 }
443 for (
i = 0;
i < chunk_size / 3;
i++) {
444 /* scale by 4 to transform 6-bit palette -> 8-bit */
445 r = bytestream2_get_byteu(&
s->gb) * 4;
446 g = bytestream2_get_byteu(&
s->gb) * 4;
447 b = bytestream2_get_byteu(&
s->gb) * 4;
448 s->palette[
i] = 0xFF
U << 24 |
r << 16 |
g << 8 |
b;
449 s->palette[
i] |=
s->palette[
i] >> 6 & 0x30303;
450 }
451 }
452
453 /* next, look for a full codebook */
454 if ((cbf0_chunk != -1) && (cbfz_chunk != -1)) {
455
456 /* a chunk should not have both chunk types */
459 }
460
461 /* decompress the full codebook chunk */
462 if (cbfz_chunk != -1) {
463
465 chunk_size = bytestream2_get_be32(&
s->gb);
467 s->codebook_size, 0)) < 0)
468 return res;
469 }
470
471 /* copy a full codebook */
472 if (cbf0_chunk != -1) {
473
475 chunk_size = bytestream2_get_be32(&
s->gb);
476 /* sanity check the full codebook size */
479 chunk_size);
481 }
482
484 }
485
486 /* decode the frame */
487 if (vptz_chunk == -1) {
488
489 /* something is wrong if there is no VPTZ chunk */
492 }
493
495 chunk_size = bytestream2_get_be32(&
s->gb);
497 s->decode_buffer,
s->decode_buffer_size, 1)) < 0)
498 return res;
499
500 /* render the final PAL8 frame */
501 if (
s->vector_height == 4)
502 index_shift = 4;
503 else
504 index_shift = 3;
505 for (y = 0; y <
s->height; y +=
s->vector_height) {
506 for (x = 0; x <
s->width; x += 4, lobytes++, hibytes++) {
507 pixel_ptr = y *
frame->linesize[0] + x;
508
509 /* get the vector index, the method for which varies according to
510 * VQA file version */
511 switch (
s->vqa_version) {
512
513 case 1:
514 lobyte =
s->decode_buffer[lobytes * 2];
515 hibyte =
s->decode_buffer[(lobytes * 2) + 1];
516 vector_index = ((hibyte << 8) | lobyte) >> 3;
517 vector_index <<= index_shift;
518 lines =
s->vector_height;
519 /* uniform color fill - a quick hack */
520 if (hibyte == 0xFF) {
521 while (lines--) {
522 frame->data[0][pixel_ptr + 0] = 255 - lobyte;
523 frame->data[0][pixel_ptr + 1] = 255 - lobyte;
524 frame->data[0][pixel_ptr + 2] = 255 - lobyte;
525 frame->data[0][pixel_ptr + 3] = 255 - lobyte;
526 pixel_ptr +=
frame->linesize[0];
527 }
528 lines=0;
529 }
530 break;
531
532 case 2:
533 lobyte =
s->decode_buffer[lobytes];
534 hibyte =
s->decode_buffer[hibytes];
535 vector_index = (hibyte << 8) | lobyte;
536 vector_index <<= index_shift;
537 lines =
s->vector_height;
538 break;
539
540 case 3:
543 }
544
545 while (lines--) {
546 frame->data[0][pixel_ptr + 0] =
s->codebook[vector_index++];
547 frame->data[0][pixel_ptr + 1] =
s->codebook[vector_index++];
548 frame->data[0][pixel_ptr + 2] =
s->codebook[vector_index++];
549 frame->data[0][pixel_ptr + 3] =
s->codebook[vector_index++];
550 pixel_ptr +=
frame->linesize[0];
551 }
552 }
553 }
554
555 /* handle partial codebook */
556 if ((cbp0_chunk != -1) && (cbpz_chunk != -1)) {
557 /* a chunk should not have both chunk types */
560 }
561
562 if (cbp0_chunk != -1) {
563
565 chunk_size = bytestream2_get_be32(&
s->gb);
566
569 chunk_size);
571 }
572
573 /* accumulate partial codebook */
575 chunk_size))
577 s->next_codebook_buffer_index += chunk_size;
578
579 s->partial_countdown--;
580 if (
s->partial_countdown <= 0) {
581
582 /* time to replace codebook */
583 memcpy(
s->codebook,
s->next_codebook_buffer,
584 s->next_codebook_buffer_index);
585
586 /* reset accounting */
587 s->next_codebook_buffer_index = 0;
588 s->partial_countdown =
s->partial_count;
589 }
590 }
591
592 if (cbpz_chunk != -1) {
593
595 chunk_size = bytestream2_get_be32(&
s->gb);
596
599 chunk_size);
601 }
602
603 /* accumulate partial codebook */
605 chunk_size))
607 s->next_codebook_buffer_index += chunk_size;
608
609 s->partial_countdown--;
610 if (
s->partial_countdown <= 0) {
612 /* decompress codebook */
614 s->codebook,
s->codebook_size, 0);
615
616 /* reset accounting */
617 s->next_codebook_buffer_index = 0;
618 s->partial_countdown =
s->partial_count;
619 if (res < 0)
620 return res;
621 }
622 }
623
624 return 0;
625 }
626
628 {
629 unsigned int chunk_type;
630 unsigned int chunk_size;
631 unsigned int index = 0;
632 int res;
633
634 int cbf0_chunk = -1;
635 int cbfz_chunk = -1;
636 int vptr_chunk = -1;
637 int vprz_chunk = -1;
638
640
642 chunk_type = bytestream2_get_be32u(&
s->gb);
644 chunk_size = bytestream2_get_be32u(&
s->gb);
645
646 switch (chunk_type) {
649 break;
652 break;
655 break;
658 break;
659 default:
662 break;
663 }
664
666 }
667
668 /* next, look for a full codebook */
669 if ((cbf0_chunk != -1) && (cbfz_chunk != -1)) {
670 /* a chunk should not have both chunk types */
673 }
674
675 /* decompress the full codebook chunk */
676 if (cbfz_chunk != -1) {
678 chunk_size = bytestream2_get_be32(&
s->gb);
680 s->codebook_size, 0)) < 0)
681 return res;
682 }
683
684 /* copy a full codebook */
685 if (cbf0_chunk != -1) {
687 chunk_size = bytestream2_get_be32(&
s->gb);
688 /* sanity check the full codebook size */
691 chunk_size);
693 }
694
696 }
697
698 /* decode the frame */
699
700 if (vptr_chunk != -1) {
701 /* copy uncompressed tile data */
703 chunk_size = bytestream2_get_be32(&
s->gb);
704 if (chunk_size >
s->decode_buffer_size) {
707 }
709 } else if (vprz_chunk != -1) {
710 /* decompress the tile data */
712
713 chunk_size = bytestream2_get_be32(&
s->gb);
714 if ((res =
decode_format80(
s, chunk_size,
s->decode_buffer,
s->decode_buffer_size, 0)) < 0)
715 return res;
716 } else {
719 }
720
721 /* now uncompress the per-row RLE of the decode buffer and draw the blocks in framebuffer */
722
724
725 for (
int y_pos = 0; y_pos <
s->height; y_pos +=
s->vector_height) {
726 int x_pos = 0;
727
728 while (x_pos < s->
width) {
729 int vector_index = 0;
730 int count = 0;
733
736
737 code = bytestream2_get_le16(&gb_stream);
738
741
744 continue;
745 }
else if (
type < 3) {
746 vector_index =
code & 0xff;
747 count = ((
code & 0x1f00) >> 7) + 1 +
type;
748 }
else if (
type < 5) {
750 count = 1;
751 }
else if (
type < 7) {
753 count = bytestream2_get_byte(&gb_stream);
754 } else {
757 }
758
759 if (count < 0 || count > (
s->width - x_pos) /
s->vector_width) {
762 }
763
764 while (count-- && x_pos < s->
width) {
765 const int bytes_per_vector = 4 *
s->vector_height *
sizeof(uint16_t);
766 unsigned char *
src =
s->codebook + vector_index * bytes_per_vector;
767 unsigned char *
dst =
s->frame->data[0] + y_pos *
s->frame->linesize[0]
768 + sizeof(uint16_t) * x_pos;
769
772
773 for (
int y = 0; y <
s->vector_height; y++) {
774 int size = 4 *
sizeof(uint16_t);
776 dst +=
s->frame->linesize[0];
778 }
779
780 /* we might want to read the next block index from stream */
781 if ((
type == 2) && count > 0) {
782 vector_index = bytestream2_get_byte(&gb_stream);
783 }
784
785 x_pos += 4;
786 }
787
788 if (count > 0) {
791 }
792 }
793 }
794
795 return 0;
796 }
797
800 {
802 int res;
803
805 return res;
806
808
811 return res;
812
813 /* make the palette available on the way out */
817 return res;
818 } else {
821 }
822
824 return res;
825
826 *got_frame = 1;
827
828 /* report that the buffer was completely consumed */
830 }
831
833 {
835
840
841 return 0;
842 }
843
845 { "max_pixels", "640*480" },
847 };
848
850 .
p.
name =
"vqavideo",
851 CODEC_LONG_NAME(
"Westwood Studios VQA (Vector Quantized Animation) video"),
861 };