LCOV - code coverage report
Current view: top level - libavcodec - zmbv.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 241 282 85.5 %
Date: 2017-12-14 08:27:08 Functions: 7 7 100.0 %

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

Generated by: LCOV version 1.13