2 * Zip Motion Blocks Video (ZMBV) decoder
3 * Copyright (c) 2006 Konstantin Shishkov
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * Zip Motion Blocks Video decoder
36 #define ZMBV_KEYFRAME 1
37 #define ZMBV_DELTAPAL 2
54 typedef struct ZmbvContext
{
55 AVCodecContext
*avctx
;
59 unsigned int decomp_size
;
72 int (*decode_intra
)(struct ZmbvContext
*c
);
73 int (*decode_xor
)(struct ZmbvContext
*c
);
77 * Decode XOR'ed frame - 8bpp version
80 static int zmbv_decode_xor_8(ZmbvContext
*c
)
82 uint8_t *src
= c
->decomp_buf
;
83 uint8_t *output
, *prev
;
86 int d
, dx
, dy
, bw2
, bh2
;
94 if(c
->flags
& ZMBV_DELTAPAL
){
95 for(i
= 0; i
< 768; i
++)
100 src
+= ((c
->bx
* c
->by
* 2 + 3) & ~3);
103 for(y
= 0; y
< c
->height
; y
+= c
->bh
) {
104 bh2
= ((c
->height
- y
) > c
->bh
) ? c
->bh
: (c
->height
- y
);
105 for(x
= 0; x
< c
->width
; x
+= c
->bw
) {
106 uint8_t *out
, *tprev
;
109 dx
= mvec
[block
] >> 1;
110 dy
= mvec
[block
+ 1] >> 1;
113 bw2
= ((c
->width
- x
) > c
->bw
) ? c
->bw
: (c
->width
- x
);
115 /* copy block - motion vectors out of bounds are used to zero blocks */
117 tprev
= prev
+ x
+ dx
+ dy
* c
->width
;
120 for(j
= 0; j
< bh2
; j
++){
121 if((my
+ j
< 0) || (my
+ j
>= c
->height
)) {
124 for(i
= 0; i
< bw2
; i
++){
125 if((mx
+ i
< 0) || (mx
+ i
>= c
->width
))
135 if(d
) { /* apply XOR'ed difference */
137 for(j
= 0; j
< bh2
; j
++){
138 for(i
= 0; i
< bw2
; i
++)
144 output
+= c
->width
* c
->bh
;
145 prev
+= c
->width
* c
->bh
;
147 if(src
- c
->decomp_buf
!= c
->decomp_len
)
148 av_log(c
->avctx
, AV_LOG_ERROR
, "Used %i of %i bytes\n", src
-c
->decomp_buf
, c
->decomp_len
);
153 * Decode XOR'ed frame - 15bpp and 16bpp version
156 static int zmbv_decode_xor_16(ZmbvContext
*c
)
158 uint8_t *src
= c
->decomp_buf
;
159 uint16_t *output
, *prev
;
162 int d
, dx
, dy
, bw2
, bh2
;
167 output
= (uint16_t*)c
->cur
;
168 prev
= (uint16_t*)c
->prev
;
171 src
+= ((c
->bx
* c
->by
* 2 + 3) & ~3);
174 for(y
= 0; y
< c
->height
; y
+= c
->bh
) {
175 bh2
= ((c
->height
- y
) > c
->bh
) ? c
->bh
: (c
->height
- y
);
176 for(x
= 0; x
< c
->width
; x
+= c
->bw
) {
177 uint16_t *out
, *tprev
;
180 dx
= mvec
[block
] >> 1;
181 dy
= mvec
[block
+ 1] >> 1;
184 bw2
= ((c
->width
- x
) > c
->bw
) ? c
->bw
: (c
->width
- x
);
186 /* copy block - motion vectors out of bounds are used to zero blocks */
188 tprev
= prev
+ x
+ dx
+ dy
* c
->width
;
191 for(j
= 0; j
< bh2
; j
++){
192 if((my
+ j
< 0) || (my
+ j
>= c
->height
)) {
193 memset(out
, 0, bw2
* 2);
195 for(i
= 0; i
< bw2
; i
++){
196 if((mx
+ i
< 0) || (mx
+ i
>= c
->width
))
206 if(d
) { /* apply XOR'ed difference */
208 for(j
= 0; j
< bh2
; j
++){
209 for(i
= 0; i
< bw2
; i
++) {
210 out
[i
] ^= *((uint16_t*)src
);
217 output
+= c
->width
* c
->bh
;
218 prev
+= c
->width
* c
->bh
;
220 if(src
- c
->decomp_buf
!= c
->decomp_len
)
221 av_log(c
->avctx
, AV_LOG_ERROR
, "Used %i of %i bytes\n", src
-c
->decomp_buf
, c
->decomp_len
);
225 #ifdef ZMBV_ENABLE_24BPP
227 * Decode XOR'ed frame - 24bpp version
230 static int zmbv_decode_xor_24(ZmbvContext
*c
)
232 uint8_t *src
= c
->decomp_buf
;
233 uint8_t *output
, *prev
;
236 int d
, dx
, dy
, bw2
, bh2
;
245 stride
= c
->width
* 3;
247 src
+= ((c
->bx
* c
->by
* 2 + 3) & ~3);
250 for(y
= 0; y
< c
->height
; y
+= c
->bh
) {
251 bh2
= ((c
->height
- y
) > c
->bh
) ? c
->bh
: (c
->height
- y
);
252 for(x
= 0; x
< c
->width
; x
+= c
->bw
) {
253 uint8_t *out
, *tprev
;
256 dx
= mvec
[block
] >> 1;
257 dy
= mvec
[block
+ 1] >> 1;
260 bw2
= ((c
->width
- x
) > c
->bw
) ? c
->bw
: (c
->width
- x
);
262 /* copy block - motion vectors out of bounds are used to zero blocks */
263 out
= output
+ x
* 3;
264 tprev
= prev
+ (x
+ dx
) * 3 + dy
* stride
;
267 for(j
= 0; j
< bh2
; j
++){
268 if((my
+ j
< 0) || (my
+ j
>= c
->height
)) {
269 memset(out
, 0, bw2
* 3);
271 for(i
= 0; i
< bw2
; i
++){
272 if((mx
+ i
< 0) || (mx
+ i
>= c
->width
)) {
277 out
[i
* 3 + 0] = tprev
[i
* 3 + 0];
278 out
[i
* 3 + 1] = tprev
[i
* 3 + 1];
279 out
[i
* 3 + 2] = tprev
[i
* 3 + 2];
287 if(d
) { /* apply XOR'ed difference */
288 out
= output
+ x
* 3;
289 for(j
= 0; j
< bh2
; j
++){
290 for(i
= 0; i
< bw2
; i
++) {
291 out
[i
* 3 + 0] ^= *src
++;
292 out
[i
* 3 + 1] ^= *src
++;
293 out
[i
* 3 + 2] ^= *src
++;
299 output
+= stride
* c
->bh
;
300 prev
+= stride
* c
->bh
;
302 if(src
- c
->decomp_buf
!= c
->decomp_len
)
303 av_log(c
->avctx
, AV_LOG_ERROR
, "Used %i of %i bytes\n", src
-c
->decomp_buf
, c
->decomp_len
);
306 #endif //ZMBV_ENABLE_24BPP
309 * Decode XOR'ed frame - 32bpp version
312 static int zmbv_decode_xor_32(ZmbvContext
*c
)
314 uint8_t *src
= c
->decomp_buf
;
315 uint32_t *output
, *prev
;
318 int d
, dx
, dy
, bw2
, bh2
;
323 output
= (uint32_t*)c
->cur
;
324 prev
= (uint32_t*)c
->prev
;
327 src
+= ((c
->bx
* c
->by
* 2 + 3) & ~3);
330 for(y
= 0; y
< c
->height
; y
+= c
->bh
) {
331 bh2
= ((c
->height
- y
) > c
->bh
) ? c
->bh
: (c
->height
- y
);
332 for(x
= 0; x
< c
->width
; x
+= c
->bw
) {
333 uint32_t *out
, *tprev
;
336 dx
= mvec
[block
] >> 1;
337 dy
= mvec
[block
+ 1] >> 1;
340 bw2
= ((c
->width
- x
) > c
->bw
) ? c
->bw
: (c
->width
- x
);
342 /* copy block - motion vectors out of bounds are used to zero blocks */
344 tprev
= prev
+ x
+ dx
+ dy
* c
->width
;
347 for(j
= 0; j
< bh2
; j
++){
348 if((my
+ j
< 0) || (my
+ j
>= c
->height
)) {
349 memset(out
, 0, bw2
* 4);
351 for(i
= 0; i
< bw2
; i
++){
352 if((mx
+ i
< 0) || (mx
+ i
>= c
->width
))
362 if(d
) { /* apply XOR'ed difference */
364 for(j
= 0; j
< bh2
; j
++){
365 for(i
= 0; i
< bw2
; i
++) {
366 out
[i
] ^= *((uint32_t*)src
);
373 output
+= c
->width
* c
->bh
;
374 prev
+= c
->width
* c
->bh
;
376 if(src
- c
->decomp_buf
!= c
->decomp_len
)
377 av_log(c
->avctx
, AV_LOG_ERROR
, "Used %i of %i bytes\n", src
-c
->decomp_buf
, c
->decomp_len
);
384 static int zmbv_decode_intra(ZmbvContext
*c
)
386 uint8_t *src
= c
->decomp_buf
;
388 /* make the palette available on the way out */
389 if (c
->fmt
== ZMBV_FMT_8BPP
) {
390 memcpy(c
->pal
, src
, 768);
394 memcpy(c
->cur
, src
, c
->width
* c
->height
* (c
->bpp
/ 8));
398 static int decode_frame(AVCodecContext
*avctx
, void *data
, int *data_size
, uint8_t *buf
, int buf_size
)
400 ZmbvContext
* const c
= (ZmbvContext
*)avctx
->priv_data
;
403 int zret
= Z_OK
; // Zlib return code
409 avctx
->release_buffer(avctx
, &c
->pic
);
411 c
->pic
.reference
= 1;
412 c
->pic
.buffer_hints
= FF_BUFFER_HINTS_VALID
;
413 if(avctx
->get_buffer(avctx
, &c
->pic
) < 0){
414 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
418 outptr
= c
->pic
.data
[0]; // Output image pointer
423 if(c
->flags
& ZMBV_KEYFRAME
) {
433 av_log(avctx
, AV_LOG_DEBUG
, "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",c
->flags
,hi_ver
,lo_ver
,c
->comp
,c
->fmt
,c
->bw
,c
->bh
);
434 if(hi_ver
!= 0 || lo_ver
!= 1) {
435 av_log(avctx
, AV_LOG_ERROR
, "Unsupported version %i.%i\n", hi_ver
, lo_ver
);
438 if(c
->bw
== 0 || c
->bh
== 0) {
439 av_log(avctx
, AV_LOG_ERROR
, "Unsupported block size %ix%i\n", c
->bw
, c
->bh
);
441 if(c
->comp
!= 0 && c
->comp
!= 1) {
442 av_log(avctx
, AV_LOG_ERROR
, "Unsupported compression type %i\n", c
->comp
);
449 c
->decode_intra
= zmbv_decode_intra
;
450 c
->decode_xor
= zmbv_decode_xor_8
;
455 c
->decode_intra
= zmbv_decode_intra
;
456 c
->decode_xor
= zmbv_decode_xor_16
;
458 #ifdef ZMBV_ENABLE_24BPP
461 c
->decode_intra
= zmbv_decode_intra
;
462 c
->decode_xor
= zmbv_decode_xor_24
;
464 #endif //ZMBV_ENABLE_24BPP
467 c
->decode_intra
= zmbv_decode_intra
;
468 c
->decode_xor
= zmbv_decode_xor_32
;
471 c
->decode_intra
= NULL
;
472 c
->decode_xor
= NULL
;
473 av_log(avctx
, AV_LOG_ERROR
, "Unsupported (for now) format %i\n", c
->fmt
);
477 zret
= inflateReset(&c
->zstream
);
479 av_log(avctx
, AV_LOG_ERROR
, "Inflate reset error: %d\n", zret
);
483 av_log(avctx
, AV_LOG_ERROR
, "BUG! Zlib support not compiled in frame decoder.\n");
485 #endif /* CONFIG_ZLIB */
486 c
->cur
= av_realloc(c
->cur
, avctx
->width
* avctx
->height
* (c
->bpp
/ 8));
487 c
->prev
= av_realloc(c
->prev
, avctx
->width
* avctx
->height
* (c
->bpp
/ 8));
488 c
->bx
= (c
->width
+ c
->bw
- 1) / c
->bw
;
489 c
->by
= (c
->height
+ c
->bh
- 1) / c
->bh
;
492 if(c
->decode_intra
== NULL
) {
493 av_log(avctx
, AV_LOG_ERROR
, "Error! Got no format or no keyframe!\n");
497 if(c
->comp
== 0) { //Uncompressed data
498 memcpy(c
->decomp_buf
, buf
, len
);
500 } else { // ZLIB-compressed data
502 c
->zstream
.total_in
= c
->zstream
.total_out
= 0;
503 c
->zstream
.next_in
= buf
;
504 c
->zstream
.avail_in
= len
;
505 c
->zstream
.next_out
= c
->decomp_buf
;
506 c
->zstream
.avail_out
= c
->decomp_size
;
507 inflate(&c
->zstream
, Z_FINISH
);
508 c
->decomp_len
= c
->zstream
.total_out
;
510 av_log(avctx
, AV_LOG_ERROR
, "BUG! Zlib support not compiled in frame decoder.\n");
514 if(c
->flags
& ZMBV_KEYFRAME
) {
515 c
->pic
.key_frame
= 1;
516 c
->pic
.pict_type
= FF_I_TYPE
;
519 c
->pic
.key_frame
= 0;
520 c
->pic
.pict_type
= FF_P_TYPE
;
529 out
= c
->pic
.data
[0];
533 for(j
= 0; j
< c
->height
; j
++) {
534 for(i
= 0; i
< c
->width
; i
++) {
535 out
[i
* 3 + 0] = c
->pal
[(*src
) * 3 + 0];
536 out
[i
* 3 + 1] = c
->pal
[(*src
) * 3 + 1];
537 out
[i
* 3 + 2] = c
->pal
[(*src
) * 3 + 2];
540 out
+= c
->pic
.linesize
[0];
544 for(j
= 0; j
< c
->height
; j
++) {
545 for(i
= 0; i
< c
->width
; i
++) {
546 uint16_t tmp
= LE_16(src
);
548 out
[i
* 3 + 0] = (tmp
& 0x7C00) >> 7;
549 out
[i
* 3 + 1] = (tmp
& 0x03E0) >> 2;
550 out
[i
* 3 + 2] = (tmp
& 0x001F) << 3;
552 out
+= c
->pic
.linesize
[0];
556 for(j
= 0; j
< c
->height
; j
++) {
557 for(i
= 0; i
< c
->width
; i
++) {
558 uint16_t tmp
= LE_16(src
);
560 out
[i
* 3 + 0] = (tmp
& 0xF800) >> 8;
561 out
[i
* 3 + 1] = (tmp
& 0x07E0) >> 3;
562 out
[i
* 3 + 2] = (tmp
& 0x001F) << 3;
564 out
+= c
->pic
.linesize
[0];
567 #ifdef ZMBV_ENABLE_24BPP
569 for(j
= 0; j
< c
->height
; j
++) {
570 memcpy(out
, src
, c
->width
* 3);
572 out
+= c
->pic
.linesize
[0];
575 #endif //ZMBV_ENABLE_24BPP
577 for(j
= 0; j
< c
->height
; j
++) {
578 for(i
= 0; i
< c
->width
; i
++) {
579 uint32_t tmp
= LE_32(src
);
581 out
[i
* 3 + 0] = tmp
>> 16;
582 out
[i
* 3 + 1] = tmp
>> 8;
583 out
[i
* 3 + 2] = tmp
>> 0;
585 out
+= c
->pic
.linesize
[0];
589 av_log(avctx
, AV_LOG_ERROR
, "Cannot handle format %i\n", c
->fmt
);
591 memcpy(c
->prev
, c
->cur
, c
->width
* c
->height
* (c
->bpp
/ 8));
593 *data_size
= sizeof(AVFrame
);
594 *(AVFrame
*)data
= c
->pic
;
596 /* always report that the buffer was completely consumed */
607 static int decode_init(AVCodecContext
*avctx
)
609 ZmbvContext
* const c
= (ZmbvContext
*)avctx
->priv_data
;
610 int zret
; // Zlib return code
613 avctx
->has_b_frames
= 0;
615 c
->pic
.data
[0] = NULL
;
616 c
->width
= avctx
->width
;
617 c
->height
= avctx
->height
;
619 if (avcodec_check_dimensions(avctx
, avctx
->height
, avctx
->width
) < 0) {
622 c
->bpp
= avctx
->bits_per_sample
;
625 // Needed if zlib unused or init aborted before inflateInit
626 memset(&(c
->zstream
), 0, sizeof(z_stream
));
628 av_log(avctx
, AV_LOG_ERROR
, "Zlib support not compiled.\n");
631 avctx
->pix_fmt
= PIX_FMT_RGB24
;
632 c
->decomp_size
= (avctx
->width
+ 255) * 4 * (avctx
->height
+ 64);
634 /* Allocate decompression buffer */
635 if (c
->decomp_size
) {
636 if ((c
->decomp_buf
= av_malloc(c
->decomp_size
)) == NULL
) {
637 av_log(avctx
, AV_LOG_ERROR
, "Can't allocate decompression buffer.\n");
643 c
->zstream
.zalloc
= Z_NULL
;
644 c
->zstream
.zfree
= Z_NULL
;
645 c
->zstream
.opaque
= Z_NULL
;
646 zret
= inflateInit(&(c
->zstream
));
648 av_log(avctx
, AV_LOG_ERROR
, "Inflate init error: %d\n", zret
);
660 * Uninit zmbv decoder
663 static int decode_end(AVCodecContext
*avctx
)
665 ZmbvContext
* const c
= (ZmbvContext
*)avctx
->priv_data
;
667 av_freep(&c
->decomp_buf
);
670 avctx
->release_buffer(avctx
, &c
->pic
);
672 inflateEnd(&(c
->zstream
));
682 AVCodec zmbv_decoder
= {