annotate ffmpeg/libavcodec/zmbv.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Zip Motion Blocks Video (ZMBV) decoder
yading@10 3 * Copyright (c) 2006 Konstantin Shishkov
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * Zip Motion Blocks Video decoder
yading@10 25 */
yading@10 26
yading@10 27 #include <stdio.h>
yading@10 28 #include <stdlib.h>
yading@10 29
yading@10 30 #include "libavutil/common.h"
yading@10 31 #include "libavutil/intreadwrite.h"
yading@10 32 #include "avcodec.h"
yading@10 33 #include "internal.h"
yading@10 34
yading@10 35 #include <zlib.h>
yading@10 36
yading@10 37 #define ZMBV_KEYFRAME 1
yading@10 38 #define ZMBV_DELTAPAL 2
yading@10 39
yading@10 40 enum ZmbvFormat {
yading@10 41 ZMBV_FMT_NONE = 0,
yading@10 42 ZMBV_FMT_1BPP = 1,
yading@10 43 ZMBV_FMT_2BPP = 2,
yading@10 44 ZMBV_FMT_4BPP = 3,
yading@10 45 ZMBV_FMT_8BPP = 4,
yading@10 46 ZMBV_FMT_15BPP = 5,
yading@10 47 ZMBV_FMT_16BPP = 6,
yading@10 48 ZMBV_FMT_24BPP = 7,
yading@10 49 ZMBV_FMT_32BPP = 8
yading@10 50 };
yading@10 51
yading@10 52 /*
yading@10 53 * Decoder context
yading@10 54 */
yading@10 55 typedef struct ZmbvContext {
yading@10 56 AVCodecContext *avctx;
yading@10 57
yading@10 58 int bpp;
yading@10 59 unsigned int decomp_size;
yading@10 60 uint8_t* decomp_buf;
yading@10 61 uint8_t pal[768];
yading@10 62 uint8_t *prev, *cur;
yading@10 63 int width, height;
yading@10 64 int fmt;
yading@10 65 int comp;
yading@10 66 int flags;
yading@10 67 int stride;
yading@10 68 int bw, bh, bx, by;
yading@10 69 int decomp_len;
yading@10 70 z_stream zstream;
yading@10 71 int (*decode_intra)(struct ZmbvContext *c);
yading@10 72 int (*decode_xor)(struct ZmbvContext *c);
yading@10 73 } ZmbvContext;
yading@10 74
yading@10 75 /**
yading@10 76 * Decode XOR'ed frame - 8bpp version
yading@10 77 */
yading@10 78
yading@10 79 static int zmbv_decode_xor_8(ZmbvContext *c)
yading@10 80 {
yading@10 81 uint8_t *src = c->decomp_buf;
yading@10 82 uint8_t *output, *prev;
yading@10 83 int8_t *mvec;
yading@10 84 int x, y;
yading@10 85 int d, dx, dy, bw2, bh2;
yading@10 86 int block;
yading@10 87 int i, j;
yading@10 88 int mx, my;
yading@10 89
yading@10 90 output = c->cur;
yading@10 91 prev = c->prev;
yading@10 92
yading@10 93 if (c->flags & ZMBV_DELTAPAL) {
yading@10 94 for (i = 0; i < 768; i++)
yading@10 95 c->pal[i] ^= *src++;
yading@10 96 }
yading@10 97
yading@10 98 mvec = (int8_t*)src;
yading@10 99 src += ((c->bx * c->by * 2 + 3) & ~3);
yading@10 100
yading@10 101 block = 0;
yading@10 102 for (y = 0; y < c->height; y += c->bh) {
yading@10 103 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
yading@10 104 for (x = 0; x < c->width; x += c->bw) {
yading@10 105 uint8_t *out, *tprev;
yading@10 106
yading@10 107 d = mvec[block] & 1;
yading@10 108 dx = mvec[block] >> 1;
yading@10 109 dy = mvec[block + 1] >> 1;
yading@10 110 block += 2;
yading@10 111
yading@10 112 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
yading@10 113
yading@10 114 /* copy block - motion vectors out of bounds are used to zero blocks */
yading@10 115 out = output + x;
yading@10 116 tprev = prev + x + dx + dy * c->width;
yading@10 117 mx = x + dx;
yading@10 118 my = y + dy;
yading@10 119 for (j = 0; j < bh2; j++) {
yading@10 120 if (my + j < 0 || my + j >= c->height) {
yading@10 121 memset(out, 0, bw2);
yading@10 122 } else {
yading@10 123 for (i = 0; i < bw2; i++) {
yading@10 124 if (mx + i < 0 || mx + i >= c->width)
yading@10 125 out[i] = 0;
yading@10 126 else
yading@10 127 out[i] = tprev[i];
yading@10 128 }
yading@10 129 }
yading@10 130 out += c->width;
yading@10 131 tprev += c->width;
yading@10 132 }
yading@10 133
yading@10 134 if (d) { /* apply XOR'ed difference */
yading@10 135 out = output + x;
yading@10 136 for (j = 0; j < bh2; j++) {
yading@10 137 for (i = 0; i < bw2; i++)
yading@10 138 out[i] ^= *src++;
yading@10 139 out += c->width;
yading@10 140 }
yading@10 141 }
yading@10 142 }
yading@10 143 output += c->width * c->bh;
yading@10 144 prev += c->width * c->bh;
yading@10 145 }
yading@10 146 if (src - c->decomp_buf != c->decomp_len)
yading@10 147 av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n",
yading@10 148 src-c->decomp_buf, c->decomp_len);
yading@10 149 return 0;
yading@10 150 }
yading@10 151
yading@10 152 /**
yading@10 153 * Decode XOR'ed frame - 15bpp and 16bpp version
yading@10 154 */
yading@10 155
yading@10 156 static int zmbv_decode_xor_16(ZmbvContext *c)
yading@10 157 {
yading@10 158 uint8_t *src = c->decomp_buf;
yading@10 159 uint16_t *output, *prev;
yading@10 160 int8_t *mvec;
yading@10 161 int x, y;
yading@10 162 int d, dx, dy, bw2, bh2;
yading@10 163 int block;
yading@10 164 int i, j;
yading@10 165 int mx, my;
yading@10 166
yading@10 167 output = (uint16_t*)c->cur;
yading@10 168 prev = (uint16_t*)c->prev;
yading@10 169
yading@10 170 mvec = (int8_t*)src;
yading@10 171 src += ((c->bx * c->by * 2 + 3) & ~3);
yading@10 172
yading@10 173 block = 0;
yading@10 174 for (y = 0; y < c->height; y += c->bh) {
yading@10 175 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
yading@10 176 for (x = 0; x < c->width; x += c->bw) {
yading@10 177 uint16_t *out, *tprev;
yading@10 178
yading@10 179 d = mvec[block] & 1;
yading@10 180 dx = mvec[block] >> 1;
yading@10 181 dy = mvec[block + 1] >> 1;
yading@10 182 block += 2;
yading@10 183
yading@10 184 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
yading@10 185
yading@10 186 /* copy block - motion vectors out of bounds are used to zero blocks */
yading@10 187 out = output + x;
yading@10 188 tprev = prev + x + dx + dy * c->width;
yading@10 189 mx = x + dx;
yading@10 190 my = y + dy;
yading@10 191 for (j = 0; j < bh2; j++) {
yading@10 192 if (my + j < 0 || my + j >= c->height) {
yading@10 193 memset(out, 0, bw2 * 2);
yading@10 194 } else {
yading@10 195 for (i = 0; i < bw2; i++) {
yading@10 196 if (mx + i < 0 || mx + i >= c->width)
yading@10 197 out[i] = 0;
yading@10 198 else
yading@10 199 out[i] = tprev[i];
yading@10 200 }
yading@10 201 }
yading@10 202 out += c->width;
yading@10 203 tprev += c->width;
yading@10 204 }
yading@10 205
yading@10 206 if (d) { /* apply XOR'ed difference */
yading@10 207 out = output + x;
yading@10 208 for (j = 0; j < bh2; j++){
yading@10 209 for (i = 0; i < bw2; i++) {
yading@10 210 out[i] ^= *((uint16_t*)src);
yading@10 211 src += 2;
yading@10 212 }
yading@10 213 out += c->width;
yading@10 214 }
yading@10 215 }
yading@10 216 }
yading@10 217 output += c->width * c->bh;
yading@10 218 prev += c->width * c->bh;
yading@10 219 }
yading@10 220 if (src - c->decomp_buf != c->decomp_len)
yading@10 221 av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n",
yading@10 222 src-c->decomp_buf, c->decomp_len);
yading@10 223 return 0;
yading@10 224 }
yading@10 225
yading@10 226 #ifdef ZMBV_ENABLE_24BPP
yading@10 227 /**
yading@10 228 * Decode XOR'ed frame - 24bpp version
yading@10 229 */
yading@10 230
yading@10 231 static int zmbv_decode_xor_24(ZmbvContext *c)
yading@10 232 {
yading@10 233 uint8_t *src = c->decomp_buf;
yading@10 234 uint8_t *output, *prev;
yading@10 235 int8_t *mvec;
yading@10 236 int x, y;
yading@10 237 int d, dx, dy, bw2, bh2;
yading@10 238 int block;
yading@10 239 int i, j;
yading@10 240 int mx, my;
yading@10 241 int stride;
yading@10 242
yading@10 243 output = c->cur;
yading@10 244 prev = c->prev;
yading@10 245
yading@10 246 stride = c->width * 3;
yading@10 247 mvec = (int8_t*)src;
yading@10 248 src += ((c->bx * c->by * 2 + 3) & ~3);
yading@10 249
yading@10 250 block = 0;
yading@10 251 for (y = 0; y < c->height; y += c->bh) {
yading@10 252 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
yading@10 253 for (x = 0; x < c->width; x += c->bw) {
yading@10 254 uint8_t *out, *tprev;
yading@10 255
yading@10 256 d = mvec[block] & 1;
yading@10 257 dx = mvec[block] >> 1;
yading@10 258 dy = mvec[block + 1] >> 1;
yading@10 259 block += 2;
yading@10 260
yading@10 261 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
yading@10 262
yading@10 263 /* copy block - motion vectors out of bounds are used to zero blocks */
yading@10 264 out = output + x * 3;
yading@10 265 tprev = prev + (x + dx) * 3 + dy * stride;
yading@10 266 mx = x + dx;
yading@10 267 my = y + dy;
yading@10 268 for (j = 0; j < bh2; j++) {
yading@10 269 if (my + j < 0 || my + j >= c->height) {
yading@10 270 memset(out, 0, bw2 * 3);
yading@10 271 } else {
yading@10 272 for (i = 0; i < bw2; i++){
yading@10 273 if (mx + i < 0 || mx + i >= c->width) {
yading@10 274 out[i * 3 + 0] = 0;
yading@10 275 out[i * 3 + 1] = 0;
yading@10 276 out[i * 3 + 2] = 0;
yading@10 277 } else {
yading@10 278 out[i * 3 + 0] = tprev[i * 3 + 0];
yading@10 279 out[i * 3 + 1] = tprev[i * 3 + 1];
yading@10 280 out[i * 3 + 2] = tprev[i * 3 + 2];
yading@10 281 }
yading@10 282 }
yading@10 283 }
yading@10 284 out += stride;
yading@10 285 tprev += stride;
yading@10 286 }
yading@10 287
yading@10 288 if (d) { /* apply XOR'ed difference */
yading@10 289 out = output + x * 3;
yading@10 290 for (j = 0; j < bh2; j++) {
yading@10 291 for (i = 0; i < bw2; i++) {
yading@10 292 out[i * 3 + 0] ^= *src++;
yading@10 293 out[i * 3 + 1] ^= *src++;
yading@10 294 out[i * 3 + 2] ^= *src++;
yading@10 295 }
yading@10 296 out += stride;
yading@10 297 }
yading@10 298 }
yading@10 299 }
yading@10 300 output += stride * c->bh;
yading@10 301 prev += stride * c->bh;
yading@10 302 }
yading@10 303 if (src - c->decomp_buf != c->decomp_len)
yading@10 304 av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n",
yading@10 305 src-c->decomp_buf, c->decomp_len);
yading@10 306 return 0;
yading@10 307 }
yading@10 308 #endif //ZMBV_ENABLE_24BPP
yading@10 309
yading@10 310 /**
yading@10 311 * Decode XOR'ed frame - 32bpp version
yading@10 312 */
yading@10 313
yading@10 314 static int zmbv_decode_xor_32(ZmbvContext *c)
yading@10 315 {
yading@10 316 uint8_t *src = c->decomp_buf;
yading@10 317 uint32_t *output, *prev;
yading@10 318 int8_t *mvec;
yading@10 319 int x, y;
yading@10 320 int d, dx, dy, bw2, bh2;
yading@10 321 int block;
yading@10 322 int i, j;
yading@10 323 int mx, my;
yading@10 324
yading@10 325 output = (uint32_t*)c->cur;
yading@10 326 prev = (uint32_t*)c->prev;
yading@10 327
yading@10 328 mvec = (int8_t*)src;
yading@10 329 src += ((c->bx * c->by * 2 + 3) & ~3);
yading@10 330
yading@10 331 block = 0;
yading@10 332 for (y = 0; y < c->height; y += c->bh) {
yading@10 333 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
yading@10 334 for (x = 0; x < c->width; x += c->bw) {
yading@10 335 uint32_t *out, *tprev;
yading@10 336
yading@10 337 d = mvec[block] & 1;
yading@10 338 dx = mvec[block] >> 1;
yading@10 339 dy = mvec[block + 1] >> 1;
yading@10 340 block += 2;
yading@10 341
yading@10 342 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
yading@10 343
yading@10 344 /* copy block - motion vectors out of bounds are used to zero blocks */
yading@10 345 out = output + x;
yading@10 346 tprev = prev + x + dx + dy * c->width;
yading@10 347 mx = x + dx;
yading@10 348 my = y + dy;
yading@10 349 for (j = 0; j < bh2; j++) {
yading@10 350 if (my + j < 0 || my + j >= c->height) {
yading@10 351 memset(out, 0, bw2 * 4);
yading@10 352 } else {
yading@10 353 for (i = 0; i < bw2; i++){
yading@10 354 if (mx + i < 0 || mx + i >= c->width)
yading@10 355 out[i] = 0;
yading@10 356 else
yading@10 357 out[i] = tprev[i];
yading@10 358 }
yading@10 359 }
yading@10 360 out += c->width;
yading@10 361 tprev += c->width;
yading@10 362 }
yading@10 363
yading@10 364 if (d) { /* apply XOR'ed difference */
yading@10 365 out = output + x;
yading@10 366 for (j = 0; j < bh2; j++){
yading@10 367 for (i = 0; i < bw2; i++) {
yading@10 368 out[i] ^= *((uint32_t *) src);
yading@10 369 src += 4;
yading@10 370 }
yading@10 371 out += c->width;
yading@10 372 }
yading@10 373 }
yading@10 374 }
yading@10 375 output += c->width * c->bh;
yading@10 376 prev += c->width * c->bh;
yading@10 377 }
yading@10 378 if (src - c->decomp_buf != c->decomp_len)
yading@10 379 av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n",
yading@10 380 src-c->decomp_buf, c->decomp_len);
yading@10 381 return 0;
yading@10 382 }
yading@10 383
yading@10 384 /**
yading@10 385 * Decode intraframe
yading@10 386 */
yading@10 387 static int zmbv_decode_intra(ZmbvContext *c)
yading@10 388 {
yading@10 389 uint8_t *src = c->decomp_buf;
yading@10 390
yading@10 391 /* make the palette available on the way out */
yading@10 392 if (c->fmt == ZMBV_FMT_8BPP) {
yading@10 393 memcpy(c->pal, src, 768);
yading@10 394 src += 768;
yading@10 395 }
yading@10 396
yading@10 397 memcpy(c->cur, src, c->width * c->height * (c->bpp / 8));
yading@10 398 return 0;
yading@10 399 }
yading@10 400
yading@10 401 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
yading@10 402 {
yading@10 403 AVFrame *frame = data;
yading@10 404 const uint8_t *buf = avpkt->data;
yading@10 405 int buf_size = avpkt->size;
yading@10 406 ZmbvContext * const c = avctx->priv_data;
yading@10 407 int zret = Z_OK; // Zlib return code
yading@10 408 int len = buf_size;
yading@10 409 int hi_ver, lo_ver, ret;
yading@10 410
yading@10 411 /* parse header */
yading@10 412 c->flags = buf[0];
yading@10 413 buf++; len--;
yading@10 414 if (c->flags & ZMBV_KEYFRAME) {
yading@10 415 void *decode_intra = NULL;
yading@10 416 c->decode_intra= NULL;
yading@10 417 hi_ver = buf[0];
yading@10 418 lo_ver = buf[1];
yading@10 419 c->comp = buf[2];
yading@10 420 c->fmt = buf[3];
yading@10 421 c->bw = buf[4];
yading@10 422 c->bh = buf[5];
yading@10 423 c->decode_intra = NULL;
yading@10 424 c->decode_xor = NULL;
yading@10 425
yading@10 426 buf += 6;
yading@10 427 len -= 6;
yading@10 428 av_log(avctx, AV_LOG_DEBUG,
yading@10 429 "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",
yading@10 430 c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh);
yading@10 431 if (hi_ver != 0 || lo_ver != 1) {
yading@10 432 avpriv_request_sample(avctx, "Version %i.%i", hi_ver, lo_ver);
yading@10 433 return AVERROR_PATCHWELCOME;
yading@10 434 }
yading@10 435 if (c->bw == 0 || c->bh == 0) {
yading@10 436 avpriv_request_sample(avctx, "Block size %ix%i", c->bw, c->bh);
yading@10 437 return AVERROR_PATCHWELCOME;
yading@10 438 }
yading@10 439 if (c->comp != 0 && c->comp != 1) {
yading@10 440 avpriv_request_sample(avctx, "Compression type %i", c->comp);
yading@10 441 return AVERROR_PATCHWELCOME;
yading@10 442 }
yading@10 443
yading@10 444 switch (c->fmt) {
yading@10 445 case ZMBV_FMT_8BPP:
yading@10 446 c->bpp = 8;
yading@10 447 decode_intra = zmbv_decode_intra;
yading@10 448 c->decode_xor = zmbv_decode_xor_8;
yading@10 449 avctx->pix_fmt = AV_PIX_FMT_PAL8;
yading@10 450 c->stride = c->width;
yading@10 451 break;
yading@10 452 case ZMBV_FMT_15BPP:
yading@10 453 case ZMBV_FMT_16BPP:
yading@10 454 c->bpp = 16;
yading@10 455 decode_intra = zmbv_decode_intra;
yading@10 456 c->decode_xor = zmbv_decode_xor_16;
yading@10 457 if (c->fmt == ZMBV_FMT_15BPP)
yading@10 458 avctx->pix_fmt = AV_PIX_FMT_RGB555LE;
yading@10 459 else
yading@10 460 avctx->pix_fmt = AV_PIX_FMT_RGB565LE;
yading@10 461 c->stride = c->width * 2;
yading@10 462 break;
yading@10 463 #ifdef ZMBV_ENABLE_24BPP
yading@10 464 case ZMBV_FMT_24BPP:
yading@10 465 c->bpp = 24;
yading@10 466 decode_intra = zmbv_decode_intra;
yading@10 467 c->decode_xor = zmbv_decode_xor_24;
yading@10 468 avctx->pix_fmt = AV_PIX_FMT_RGB24;
yading@10 469 c->stride = c->width * 3;
yading@10 470 break;
yading@10 471 #endif //ZMBV_ENABLE_24BPP
yading@10 472 case ZMBV_FMT_32BPP:
yading@10 473 c->bpp = 32;
yading@10 474 decode_intra = zmbv_decode_intra;
yading@10 475 c->decode_xor = zmbv_decode_xor_32;
yading@10 476 avctx->pix_fmt = AV_PIX_FMT_BGR0;
yading@10 477 c->stride = c->width * 4;
yading@10 478 break;
yading@10 479 default:
yading@10 480 c->decode_xor = NULL;
yading@10 481 avpriv_request_sample(avctx, "Format %i", c->fmt);
yading@10 482 return AVERROR_PATCHWELCOME;
yading@10 483 }
yading@10 484
yading@10 485 zret = inflateReset(&c->zstream);
yading@10 486 if (zret != Z_OK) {
yading@10 487 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
yading@10 488 return AVERROR_UNKNOWN;
yading@10 489 }
yading@10 490
yading@10 491 c->cur = av_realloc_f(c->cur, avctx->width * avctx->height, (c->bpp / 8));
yading@10 492 c->prev = av_realloc_f(c->prev, avctx->width * avctx->height, (c->bpp / 8));
yading@10 493 c->bx = (c->width + c->bw - 1) / c->bw;
yading@10 494 c->by = (c->height+ c->bh - 1) / c->bh;
yading@10 495 if (!c->cur || !c->prev)
yading@10 496 return -1;
yading@10 497 memset(c->cur, 0, avctx->width * avctx->height * (c->bpp / 8));
yading@10 498 memset(c->prev, 0, avctx->width * avctx->height * (c->bpp / 8));
yading@10 499 c->decode_intra= decode_intra;
yading@10 500 }
yading@10 501
yading@10 502 if (c->decode_intra == NULL) {
yading@10 503 av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n");
yading@10 504 return AVERROR_INVALIDDATA;
yading@10 505 }
yading@10 506
yading@10 507 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
yading@10 508 return ret;
yading@10 509
yading@10 510 if (c->comp == 0) { //Uncompressed data
yading@10 511 if (c->decomp_size < len) {
yading@10 512 av_log(avctx, AV_LOG_ERROR, "decomp buffer too small\n");
yading@10 513 return AVERROR_INVALIDDATA;
yading@10 514 }
yading@10 515 memcpy(c->decomp_buf, buf, len);
yading@10 516 } else { // ZLIB-compressed data
yading@10 517 c->zstream.total_in = c->zstream.total_out = 0;
yading@10 518 c->zstream.next_in = (uint8_t*)buf;
yading@10 519 c->zstream.avail_in = len;
yading@10 520 c->zstream.next_out = c->decomp_buf;
yading@10 521 c->zstream.avail_out = c->decomp_size;
yading@10 522 zret = inflate(&c->zstream, Z_SYNC_FLUSH);
yading@10 523 if (zret != Z_OK && zret != Z_STREAM_END) {
yading@10 524 av_log(avctx, AV_LOG_ERROR, "inflate error %d\n", zret);
yading@10 525 return AVERROR_INVALIDDATA;
yading@10 526 }
yading@10 527 c->decomp_len = c->zstream.total_out;
yading@10 528 }
yading@10 529 if (c->flags & ZMBV_KEYFRAME) {
yading@10 530 frame->key_frame = 1;
yading@10 531 frame->pict_type = AV_PICTURE_TYPE_I;
yading@10 532 c->decode_intra(c);
yading@10 533 } else {
yading@10 534 frame->key_frame = 0;
yading@10 535 frame->pict_type = AV_PICTURE_TYPE_P;
yading@10 536 if (c->decomp_len)
yading@10 537 c->decode_xor(c);
yading@10 538 }
yading@10 539
yading@10 540 /* update frames */
yading@10 541 {
yading@10 542 uint8_t *out, *src;
yading@10 543 int j;
yading@10 544
yading@10 545 out = frame->data[0];
yading@10 546 src = c->cur;
yading@10 547 switch (c->fmt) {
yading@10 548 case ZMBV_FMT_8BPP:
yading@10 549 for (j = 0; j < 256; j++)
yading@10 550 AV_WN32(&frame->data[1][j * 4], 0xFFU << 24 | AV_RB24(&c->pal[j * 3]));
yading@10 551 case ZMBV_FMT_15BPP:
yading@10 552 case ZMBV_FMT_16BPP:
yading@10 553 #ifdef ZMBV_ENABLE_24BPP
yading@10 554 case ZMBV_FMT_24BPP:
yading@10 555 #endif
yading@10 556 case ZMBV_FMT_32BPP:
yading@10 557 for (j = 0; j < c->height; j++) {
yading@10 558 memcpy(out, src, c->stride);
yading@10 559 src += c->stride;
yading@10 560 out += frame->linesize[0];
yading@10 561 }
yading@10 562 break;
yading@10 563 default:
yading@10 564 av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt);
yading@10 565 }
yading@10 566 FFSWAP(uint8_t *, c->cur, c->prev);
yading@10 567 }
yading@10 568 *got_frame = 1;
yading@10 569
yading@10 570 /* always report that the buffer was completely consumed */
yading@10 571 return buf_size;
yading@10 572 }
yading@10 573
yading@10 574 static av_cold int decode_init(AVCodecContext *avctx)
yading@10 575 {
yading@10 576 ZmbvContext * const c = avctx->priv_data;
yading@10 577 int zret; // Zlib return code
yading@10 578
yading@10 579 c->avctx = avctx;
yading@10 580
yading@10 581 c->width = avctx->width;
yading@10 582 c->height = avctx->height;
yading@10 583
yading@10 584 c->bpp = avctx->bits_per_coded_sample;
yading@10 585
yading@10 586 // Needed if zlib unused or init aborted before inflateInit
yading@10 587 memset(&c->zstream, 0, sizeof(z_stream));
yading@10 588
yading@10 589 c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64);
yading@10 590
yading@10 591 /* Allocate decompression buffer */
yading@10 592 if (c->decomp_size) {
yading@10 593 if ((c->decomp_buf = av_mallocz(c->decomp_size)) == NULL) {
yading@10 594 av_log(avctx, AV_LOG_ERROR,
yading@10 595 "Can't allocate decompression buffer.\n");
yading@10 596 return AVERROR(ENOMEM);
yading@10 597 }
yading@10 598 }
yading@10 599
yading@10 600 c->zstream.zalloc = Z_NULL;
yading@10 601 c->zstream.zfree = Z_NULL;
yading@10 602 c->zstream.opaque = Z_NULL;
yading@10 603 zret = inflateInit(&c->zstream);
yading@10 604 if (zret != Z_OK) {
yading@10 605 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
yading@10 606 return AVERROR_UNKNOWN;
yading@10 607 }
yading@10 608
yading@10 609 return 0;
yading@10 610 }
yading@10 611
yading@10 612 static av_cold int decode_end(AVCodecContext *avctx)
yading@10 613 {
yading@10 614 ZmbvContext * const c = avctx->priv_data;
yading@10 615
yading@10 616 av_freep(&c->decomp_buf);
yading@10 617
yading@10 618 inflateEnd(&c->zstream);
yading@10 619 av_freep(&c->cur);
yading@10 620 av_freep(&c->prev);
yading@10 621
yading@10 622 return 0;
yading@10 623 }
yading@10 624
yading@10 625 AVCodec ff_zmbv_decoder = {
yading@10 626 .name = "zmbv",
yading@10 627 .type = AVMEDIA_TYPE_VIDEO,
yading@10 628 .id = AV_CODEC_ID_ZMBV,
yading@10 629 .priv_data_size = sizeof(ZmbvContext),
yading@10 630 .init = decode_init,
yading@10 631 .close = decode_end,
yading@10 632 .decode = decode_frame,
yading@10 633 .capabilities = CODEC_CAP_DR1,
yading@10 634 .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"),
yading@10 635 };