LCOV - code coverage report
Current view: top level - libavcodec - interplayvideo.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 458 649 70.6 %
Date: 2017-12-16 01:21:47 Functions: 28 36 77.8 %

          Line data    Source code
       1             : /*
       2             :  * Interplay MVE Video Decoder
       3             :  * Copyright (C) 2003 The FFmpeg project
       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             :  * Interplay MVE Video Decoder by Mike Melanson (melanson@pcisys.net)
      25             :  * For more information about the Interplay MVE format, visit:
      26             :  *   http://www.pcisys.net/~melanson/codecs/interplay-mve.txt
      27             :  * This code is written in such a way that the identifiers match up
      28             :  * with the encoding descriptions in the document.
      29             :  *
      30             :  * This decoder presently only supports a PAL8 output colorspace.
      31             :  *
      32             :  * An Interplay video frame consists of 2 parts: The decoding map and
      33             :  * the video data. A demuxer must load these 2 parts together in a single
      34             :  * buffer before sending it through the stream to this decoder.
      35             :  */
      36             : 
      37             : #include <stdio.h>
      38             : #include <stdlib.h>
      39             : #include <string.h>
      40             : 
      41             : #include "libavutil/intreadwrite.h"
      42             : 
      43             : #define BITSTREAM_READER_LE
      44             : #include "avcodec.h"
      45             : #include "bytestream.h"
      46             : #include "get_bits.h"
      47             : #include "hpeldsp.h"
      48             : #include "internal.h"
      49             : 
      50             : #define PALETTE_COUNT 256
      51             : 
      52             : typedef struct IpvideoContext {
      53             : 
      54             :     AVCodecContext *avctx;
      55             :     HpelDSPContext hdsp;
      56             :     AVFrame *second_last_frame;
      57             :     AVFrame *last_frame;
      58             : 
      59             :     /* For format 0x10 */
      60             :     AVFrame *cur_decode_frame;
      61             :     AVFrame *prev_decode_frame;
      62             : 
      63             :     const unsigned char *decoding_map;
      64             :     int decoding_map_size;
      65             :     const unsigned char *skip_map;
      66             :     int skip_map_size;
      67             : 
      68             :     int is_16bpp;
      69             :     GetByteContext stream_ptr, mv_ptr;
      70             :     unsigned char *pixel_ptr;
      71             :     int line_inc;
      72             :     int stride;
      73             :     int upper_motion_limit_offset;
      74             : 
      75             :     uint32_t pal[256];
      76             : } IpvideoContext;
      77             : 
      78      341521 : static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y)
      79             : {
      80      341521 :     int current_offset = s->pixel_ptr - dst->data[0];
      81      683042 :     int motion_offset = current_offset + delta_y * dst->linesize[0]
      82      341521 :                        + delta_x * (1 + s->is_16bpp);
      83      341521 :     if (motion_offset < 0) {
      84           0 :         av_log(s->avctx, AV_LOG_ERROR, "motion offset < 0 (%d)\n", motion_offset);
      85           0 :         return AVERROR_INVALIDDATA;
      86      341521 :     } else if (motion_offset > s->upper_motion_limit_offset) {
      87           0 :         av_log(s->avctx, AV_LOG_ERROR, "motion offset above limit (%d >= %d)\n",
      88             :             motion_offset, s->upper_motion_limit_offset);
      89           0 :         return AVERROR_INVALIDDATA;
      90             :     }
      91      341521 :     if (!src->data[0]) {
      92           0 :         av_log(s->avctx, AV_LOG_ERROR, "Invalid decode type, corrupted header?\n");
      93           0 :         return AVERROR(EINVAL);
      94             :     }
      95      683042 :     s->hdsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
      96      341521 :                                             dst->linesize[0], 8);
      97      341521 :     return 0;
      98             : }
      99             : 
     100       34551 : static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s, AVFrame *frame)
     101             : {
     102       34551 :     return copy_from(s, s->last_frame, frame, 0, 0);
     103             : }
     104             : 
     105      280419 : static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s, AVFrame *frame)
     106             : {
     107      280419 :     return copy_from(s, s->second_last_frame, frame, 0, 0);
     108             : }
     109             : 
     110        1282 : static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s, AVFrame *frame)
     111             : {
     112             :     unsigned char B;
     113             :     int x, y;
     114             : 
     115             :     /* copy block from 2 frames ago using a motion vector; need 1 more byte */
     116        1282 :     if (!s->is_16bpp) {
     117         579 :         B = bytestream2_get_byte(&s->stream_ptr);
     118             :     } else {
     119         703 :         B = bytestream2_get_byte(&s->mv_ptr);
     120             :     }
     121             : 
     122        1282 :     if (B < 56) {
     123         491 :         x = 8 + (B % 7);
     124         491 :         y = B / 7;
     125             :     } else {
     126         791 :         x = -14 + ((B - 56) % 29);
     127         791 :         y =   8 + ((B - 56) / 29);
     128             :     }
     129             : 
     130             :     ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
     131        1282 :     return copy_from(s, s->second_last_frame, frame, x, y);
     132             : }
     133             : 
     134        3043 : static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s, AVFrame *frame)
     135             : {
     136             :     unsigned char B;
     137             :     int x, y;
     138             : 
     139             :     /* copy 8x8 block from current frame from an up/left block */
     140             : 
     141             :     /* need 1 more byte for motion */
     142        3043 :     if (!s->is_16bpp) {
     143         387 :         B = bytestream2_get_byte(&s->stream_ptr);
     144             :     } else {
     145        2656 :         B = bytestream2_get_byte(&s->mv_ptr);
     146             :     }
     147             : 
     148        3043 :     if (B < 56) {
     149        1630 :         x = -(8 + (B % 7));
     150        1630 :         y = -(B / 7);
     151             :     } else {
     152        1413 :         x = -(-14 + ((B - 56) % 29));
     153        1413 :         y = -(  8 + ((B - 56) / 29));
     154             :     }
     155             : 
     156             :     ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
     157        3043 :     return copy_from(s, frame, frame, x, y);
     158             : }
     159             : 
     160       18863 : static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s, AVFrame *frame)
     161             : {
     162             :     int x, y;
     163             :     unsigned char B, BL, BH;
     164             : 
     165             :     /* copy a block from the previous frame; need 1 more byte */
     166       18863 :     if (!s->is_16bpp) {
     167        6043 :         B = bytestream2_get_byte(&s->stream_ptr);
     168             :     } else {
     169       12820 :         B = bytestream2_get_byte(&s->mv_ptr);
     170             :     }
     171             : 
     172       18863 :     BL = B & 0x0F;
     173       18863 :     BH = (B >> 4) & 0x0F;
     174       18863 :     x = -8 + BL;
     175       18863 :     y = -8 + BH;
     176             : 
     177             :     ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
     178       18863 :     return copy_from(s, s->last_frame, frame, x, y);
     179             : }
     180             : 
     181        3363 : static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s, AVFrame *frame)
     182             : {
     183             :     signed char x, y;
     184             : 
     185             :     /* copy a block from the previous frame using an expanded range;
     186             :      * need 2 more bytes */
     187        3363 :     x = bytestream2_get_byte(&s->stream_ptr);
     188        3363 :     y = bytestream2_get_byte(&s->stream_ptr);
     189             : 
     190             :     ff_tlog(s->avctx, "motion bytes = %d, %d\n", x, y);
     191        3363 :     return copy_from(s, s->last_frame, frame, x, y);
     192             : }
     193             : 
     194           0 : static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s, AVFrame *frame)
     195             : {
     196             :     /* mystery opcode? skip multiple blocks? */
     197           0 :     av_log(s->avctx, AV_LOG_ERROR, "Help! Mystery opcode 0x6 seen\n");
     198             : 
     199             :     /* report success */
     200           0 :     return 0;
     201             : }
     202             : 
     203         815 : static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s, AVFrame *frame)
     204             : {
     205             :     int x, y;
     206             :     unsigned char P[2];
     207             :     unsigned int flags;
     208             : 
     209         815 :     if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) {
     210           0 :         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x7\n");
     211           0 :         return AVERROR_INVALIDDATA;
     212             :     }
     213             : 
     214             :     /* 2-color encoding */
     215         815 :     P[0] = bytestream2_get_byte(&s->stream_ptr);
     216         815 :     P[1] = bytestream2_get_byte(&s->stream_ptr);
     217             : 
     218         815 :     if (P[0] <= P[1]) {
     219             : 
     220             :         /* need 8 more bytes from the stream */
     221        6471 :         for (y = 0; y < 8; y++) {
     222        5752 :             flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
     223       51768 :             for (; flags != 1; flags >>= 1)
     224       46016 :                 *s->pixel_ptr++ = P[flags & 1];
     225        5752 :             s->pixel_ptr += s->line_inc;
     226             :         }
     227             : 
     228             :     } else {
     229             : 
     230             :         /* need 2 more bytes from the stream */
     231          96 :         flags = bytestream2_get_le16(&s->stream_ptr);
     232         480 :         for (y = 0; y < 8; y += 2) {
     233        1920 :             for (x = 0; x < 8; x += 2, flags >>= 1) {
     234        3072 :                 s->pixel_ptr[x                ] =
     235        4608 :                 s->pixel_ptr[x + 1            ] =
     236        4608 :                 s->pixel_ptr[x +     s->stride] =
     237        3072 :                 s->pixel_ptr[x + 1 + s->stride] = P[flags & 1];
     238             :             }
     239         384 :             s->pixel_ptr += s->stride * 2;
     240             :         }
     241             :     }
     242             : 
     243             :     /* report success */
     244         815 :     return 0;
     245             : }
     246             : 
     247        1013 : static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s, AVFrame *frame)
     248             : {
     249             :     int x, y;
     250             :     unsigned char P[4];
     251        1013 :     unsigned int flags = 0;
     252             : 
     253        1013 :     if (bytestream2_get_bytes_left(&s->stream_ptr) < 12) {
     254           0 :         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x8\n");
     255           0 :         return AVERROR_INVALIDDATA;
     256             :     }
     257             : 
     258             :     /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
     259             :      * either top and bottom or left and right halves */
     260        1013 :     P[0] = bytestream2_get_byte(&s->stream_ptr);
     261        1013 :     P[1] = bytestream2_get_byte(&s->stream_ptr);
     262             : 
     263        1013 :     if (P[0] <= P[1]) {
     264        5627 :         for (y = 0; y < 16; y++) {
     265             :             // new values for each 4x4 block
     266        5296 :             if (!(y & 3)) {
     267        1324 :                 if (y) {
     268         993 :                     P[0]  = bytestream2_get_byte(&s->stream_ptr);
     269         993 :                     P[1]  = bytestream2_get_byte(&s->stream_ptr);
     270             :                 }
     271        1324 :                 flags = bytestream2_get_le16(&s->stream_ptr);
     272             :             }
     273             : 
     274       26480 :             for (x = 0; x < 4; x++, flags >>= 1)
     275       21184 :                 *s->pixel_ptr++ = P[flags & 1];
     276        5296 :             s->pixel_ptr += s->stride - 4;
     277             :             // switch to right half
     278        5296 :             if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
     279             :         }
     280             : 
     281             :     } else {
     282         682 :         flags = bytestream2_get_le32(&s->stream_ptr);
     283         682 :         P[2] = bytestream2_get_byte(&s->stream_ptr);
     284         682 :         P[3] = bytestream2_get_byte(&s->stream_ptr);
     285             : 
     286         682 :         if (P[2] <= P[3]) {
     287             : 
     288             :             /* vertical split; left & right halves are 2-color encoded */
     289             : 
     290        6919 :             for (y = 0; y < 16; y++) {
     291       32560 :                 for (x = 0; x < 4; x++, flags >>= 1)
     292       26048 :                     *s->pixel_ptr++ = P[flags & 1];
     293        6512 :                 s->pixel_ptr += s->stride - 4;
     294             :                 // switch to right half
     295        6512 :                 if (y == 7) {
     296         407 :                     s->pixel_ptr -= 8 * s->stride - 4;
     297         407 :                     P[0]  = P[2];
     298         407 :                     P[1]  = P[3];
     299         407 :                     flags = bytestream2_get_le32(&s->stream_ptr);
     300             :                 }
     301             :             }
     302             : 
     303             :         } else {
     304             : 
     305             :             /* horizontal split; top & bottom halves are 2-color encoded */
     306             : 
     307        2475 :             for (y = 0; y < 8; y++) {
     308        2200 :                 if (y == 4) {
     309         275 :                     P[0]  = P[2];
     310         275 :                     P[1]  = P[3];
     311         275 :                     flags = bytestream2_get_le32(&s->stream_ptr);
     312             :                 }
     313             : 
     314       19800 :                 for (x = 0; x < 8; x++, flags >>= 1)
     315       17600 :                     *s->pixel_ptr++ = P[flags & 1];
     316        2200 :                 s->pixel_ptr += s->line_inc;
     317             :             }
     318             :         }
     319             :     }
     320             : 
     321             :     /* report success */
     322        1013 :     return 0;
     323             : }
     324             : 
     325        2412 : static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s, AVFrame *frame)
     326             : {
     327             :     int x, y;
     328             :     unsigned char P[4];
     329             : 
     330        2412 :     if (bytestream2_get_bytes_left(&s->stream_ptr) < 8) {
     331           0 :         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x9\n");
     332           0 :         return AVERROR_INVALIDDATA;
     333             :     }
     334             : 
     335             :     /* 4-color encoding */
     336        2412 :     bytestream2_get_buffer(&s->stream_ptr, P, 4);
     337             : 
     338        2412 :     if (P[0] <= P[1]) {
     339        2053 :         if (P[2] <= P[3]) {
     340             : 
     341             :             /* 1 of 4 colors for each pixel, need 16 more bytes */
     342       16515 :             for (y = 0; y < 8; y++) {
     343             :                 /* get the next set of 8 2-bit flags */
     344       14680 :                 int flags = bytestream2_get_le16(&s->stream_ptr);
     345      132120 :                 for (x = 0; x < 8; x++, flags >>= 2)
     346      117440 :                     *s->pixel_ptr++ = P[flags & 0x03];
     347       14680 :                 s->pixel_ptr += s->line_inc;
     348             :             }
     349             : 
     350             :         } else {
     351             :             uint32_t flags;
     352             : 
     353             :             /* 1 of 4 colors for each 2x2 block, need 4 more bytes */
     354         218 :             flags = bytestream2_get_le32(&s->stream_ptr);
     355             : 
     356        1090 :             for (y = 0; y < 8; y += 2) {
     357        4360 :                 for (x = 0; x < 8; x += 2, flags >>= 2) {
     358        6976 :                     s->pixel_ptr[x                ] =
     359       10464 :                     s->pixel_ptr[x + 1            ] =
     360       10464 :                     s->pixel_ptr[x +     s->stride] =
     361        6976 :                     s->pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
     362             :                 }
     363         872 :                 s->pixel_ptr += s->stride * 2;
     364             :             }
     365             : 
     366             :         }
     367             :     } else {
     368             :         uint64_t flags;
     369             : 
     370             :         /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */
     371         359 :         flags = bytestream2_get_le64(&s->stream_ptr);
     372         359 :         if (P[2] <= P[3]) {
     373        1755 :             for (y = 0; y < 8; y++) {
     374        7800 :                 for (x = 0; x < 8; x += 2, flags >>= 2) {
     375       12480 :                     s->pixel_ptr[x    ] =
     376       12480 :                     s->pixel_ptr[x + 1] = P[flags & 0x03];
     377             :                 }
     378        1560 :                 s->pixel_ptr += s->stride;
     379             :             }
     380             :         } else {
     381         820 :             for (y = 0; y < 8; y += 2) {
     382        5904 :                 for (x = 0; x < 8; x++, flags >>= 2) {
     383       10496 :                     s->pixel_ptr[x            ] =
     384       10496 :                     s->pixel_ptr[x + s->stride] = P[flags & 0x03];
     385             :                 }
     386         656 :                 s->pixel_ptr += s->stride * 2;
     387             :             }
     388             :         }
     389             :     }
     390             : 
     391             :     /* report success */
     392        2412 :     return 0;
     393             : }
     394             : 
     395        5451 : static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s, AVFrame *frame)
     396             : {
     397             :     int x, y;
     398             :     unsigned char P[8];
     399        5451 :     int flags = 0;
     400             : 
     401        5451 :     if (bytestream2_get_bytes_left(&s->stream_ptr) < 16) {
     402           0 :         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xA\n");
     403           0 :         return AVERROR_INVALIDDATA;
     404             :     }
     405             : 
     406        5451 :     bytestream2_get_buffer(&s->stream_ptr, P, 4);
     407             : 
     408             :     /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
     409             :      * either top and bottom or left and right halves */
     410        5451 :     if (P[0] <= P[1]) {
     411             : 
     412             :         /* 4-color encoding for each quadrant; need 32 bytes */
     413       32419 :         for (y = 0; y < 16; y++) {
     414             :             // new values for each 4x4 block
     415       30512 :             if (!(y & 3)) {
     416        7628 :                 if (y) bytestream2_get_buffer(&s->stream_ptr, P, 4);
     417        7628 :                 flags = bytestream2_get_le32(&s->stream_ptr);
     418             :             }
     419             : 
     420      152560 :             for (x = 0; x < 4; x++, flags >>= 2)
     421      122048 :                 *s->pixel_ptr++ = P[flags & 0x03];
     422             : 
     423       30512 :             s->pixel_ptr += s->stride - 4;
     424             :             // switch to right half
     425       30512 :             if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
     426             :         }
     427             : 
     428             :     } else {
     429             :         // vertical split?
     430             :         int vert;
     431        3544 :         uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
     432             : 
     433        3544 :         bytestream2_get_buffer(&s->stream_ptr, P + 4, 4);
     434        3544 :         vert = P[4] <= P[5];
     435             : 
     436             :         /* 4-color encoding for either left and right or top and bottom
     437             :          * halves */
     438             : 
     439       60248 :         for (y = 0; y < 16; y++) {
     440      283520 :             for (x = 0; x < 4; x++, flags >>= 2)
     441      226816 :                 *s->pixel_ptr++ = P[flags & 0x03];
     442             : 
     443       56704 :             if (vert) {
     444       30576 :                 s->pixel_ptr += s->stride - 4;
     445             :                 // switch to right half
     446       30576 :                 if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
     447       26128 :             } else if (y & 1) s->pixel_ptr += s->line_inc;
     448             : 
     449             :             // load values for second half
     450       56704 :             if (y == 7) {
     451        3544 :                 memcpy(P, P + 4, 4);
     452        3544 :                 flags = bytestream2_get_le64(&s->stream_ptr);
     453             :             }
     454             :         }
     455             :     }
     456             : 
     457             :     /* report success */
     458        5451 :     return 0;
     459             : }
     460             : 
     461       21074 : static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s, AVFrame *frame)
     462             : {
     463             :     int y;
     464             : 
     465             :     /* 64-color encoding (each pixel in block is a different color) */
     466      189666 :     for (y = 0; y < 8; y++) {
     467      168592 :         bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
     468      168592 :         s->pixel_ptr  += s->stride;
     469             :     }
     470             : 
     471             :     /* report success */
     472       21074 :     return 0;
     473             : }
     474             : 
     475         135 : static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s, AVFrame *frame)
     476             : {
     477             :     int x, y;
     478             : 
     479             :     /* 16-color block encoding: each 2x2 block is a different color */
     480         675 :     for (y = 0; y < 8; y += 2) {
     481        2700 :         for (x = 0; x < 8; x += 2) {
     482        4320 :             s->pixel_ptr[x                ] =
     483        6480 :             s->pixel_ptr[x + 1            ] =
     484        6480 :             s->pixel_ptr[x +     s->stride] =
     485        4320 :             s->pixel_ptr[x + 1 + s->stride] = bytestream2_get_byte(&s->stream_ptr);
     486             :         }
     487         540 :         s->pixel_ptr += s->stride * 2;
     488             :     }
     489             : 
     490             :     /* report success */
     491         135 :     return 0;
     492             : }
     493             : 
     494          49 : static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s, AVFrame *frame)
     495             : {
     496             :     int y;
     497             :     unsigned char P[2];
     498             : 
     499          49 :     if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) {
     500           0 :         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xD\n");
     501           0 :         return AVERROR_INVALIDDATA;
     502             :     }
     503             : 
     504             :     /* 4-color block encoding: each 4x4 block is a different color */
     505         441 :     for (y = 0; y < 8; y++) {
     506         392 :         if (!(y & 3)) {
     507          98 :             P[0] = bytestream2_get_byte(&s->stream_ptr);
     508          98 :             P[1] = bytestream2_get_byte(&s->stream_ptr);
     509             :         }
     510         392 :         memset(s->pixel_ptr,     P[0], 4);
     511         392 :         memset(s->pixel_ptr + 4, P[1], 4);
     512         392 :         s->pixel_ptr += s->stride;
     513             :     }
     514             : 
     515             :     /* report success */
     516          49 :     return 0;
     517             : }
     518             : 
     519        1696 : static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s, AVFrame *frame)
     520             : {
     521             :     int y;
     522             :     unsigned char pix;
     523             : 
     524             :     /* 1-color encoding: the whole block is 1 solid color */
     525        1696 :     pix = bytestream2_get_byte(&s->stream_ptr);
     526             : 
     527       15264 :     for (y = 0; y < 8; y++) {
     528       13568 :         memset(s->pixel_ptr, pix, 8);
     529       13568 :         s->pixel_ptr += s->stride;
     530             :     }
     531             : 
     532             :     /* report success */
     533        1696 :     return 0;
     534             : }
     535             : 
     536          27 : static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s, AVFrame *frame)
     537             : {
     538             :     int x, y;
     539             :     unsigned char sample[2];
     540             : 
     541             :     /* dithered encoding */
     542          27 :     sample[0] = bytestream2_get_byte(&s->stream_ptr);
     543          27 :     sample[1] = bytestream2_get_byte(&s->stream_ptr);
     544             : 
     545         243 :     for (y = 0; y < 8; y++) {
     546        1080 :         for (x = 0; x < 8; x += 2) {
     547         864 :             *s->pixel_ptr++ = sample[  y & 1 ];
     548         864 :             *s->pixel_ptr++ = sample[!(y & 1)];
     549             :         }
     550         216 :         s->pixel_ptr += s->line_inc;
     551             :     }
     552             : 
     553             :     /* report success */
     554          27 :     return 0;
     555             : }
     556             : 
     557           0 : static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s, AVFrame *frame)
     558             : {
     559             :     signed char x, y;
     560             : 
     561             :     /* copy a block from the second last frame using an expanded range */
     562           0 :     x = bytestream2_get_byte(&s->stream_ptr);
     563           0 :     y = bytestream2_get_byte(&s->stream_ptr);
     564             : 
     565             :     ff_tlog(s->avctx, "motion bytes = %d, %d\n", x, y);
     566           0 :     return copy_from(s, s->second_last_frame, frame, x, y);
     567             : }
     568             : 
     569        2197 : static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s, AVFrame *frame)
     570             : {
     571             :     int x, y;
     572             :     uint16_t P[2];
     573             :     unsigned int flags;
     574        2197 :     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
     575             : 
     576             :     /* 2-color encoding */
     577        2197 :     P[0] = bytestream2_get_le16(&s->stream_ptr);
     578        2197 :     P[1] = bytestream2_get_le16(&s->stream_ptr);
     579             : 
     580        2197 :     if (!(P[0] & 0x8000)) {
     581             : 
     582       14823 :         for (y = 0; y < 8; y++) {
     583       13176 :             flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
     584      118584 :             for (; flags != 1; flags >>= 1)
     585      105408 :                 *pixel_ptr++ = P[flags & 1];
     586       13176 :             pixel_ptr += s->line_inc;
     587             :         }
     588             : 
     589             :     } else {
     590             : 
     591         550 :         flags = bytestream2_get_le16(&s->stream_ptr);
     592        2750 :         for (y = 0; y < 8; y += 2) {
     593       11000 :             for (x = 0; x < 8; x += 2, flags >>= 1) {
     594       17600 :                 pixel_ptr[x                ] =
     595       26400 :                 pixel_ptr[x + 1            ] =
     596       26400 :                 pixel_ptr[x +     s->stride] =
     597       17600 :                 pixel_ptr[x + 1 + s->stride] = P[flags & 1];
     598             :             }
     599        2200 :             pixel_ptr += s->stride * 2;
     600             :         }
     601             :     }
     602             : 
     603        2197 :     return 0;
     604             : }
     605             : 
     606        1478 : static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s, AVFrame *frame)
     607             : {
     608             :     int x, y;
     609             :     uint16_t P[4];
     610        1478 :     unsigned int flags = 0;
     611        1478 :     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
     612             : 
     613             :     /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
     614             :      * either top and bottom or left and right halves */
     615        1478 :     P[0] = bytestream2_get_le16(&s->stream_ptr);
     616        1478 :     P[1] = bytestream2_get_le16(&s->stream_ptr);
     617             : 
     618        1478 :     if (!(P[0] & 0x8000)) {
     619             : 
     620        4522 :         for (y = 0; y < 16; y++) {
     621             :             // new values for each 4x4 block
     622        4256 :             if (!(y & 3)) {
     623        1064 :                 if (y) {
     624         798 :                     P[0] = bytestream2_get_le16(&s->stream_ptr);
     625         798 :                     P[1] = bytestream2_get_le16(&s->stream_ptr);
     626             :                 }
     627        1064 :                 flags = bytestream2_get_le16(&s->stream_ptr);
     628             :             }
     629             : 
     630       21280 :             for (x = 0; x < 4; x++, flags >>= 1)
     631       17024 :                 *pixel_ptr++ = P[flags & 1];
     632        4256 :             pixel_ptr += s->stride - 4;
     633             :             // switch to right half
     634        4256 :             if (y == 7) pixel_ptr -= 8 * s->stride - 4;
     635             :         }
     636             : 
     637             :     } else {
     638             : 
     639        1212 :         flags = bytestream2_get_le32(&s->stream_ptr);
     640        1212 :         P[2]  = bytestream2_get_le16(&s->stream_ptr);
     641        1212 :         P[3]  = bytestream2_get_le16(&s->stream_ptr);
     642             : 
     643        1212 :         if (!(P[2] & 0x8000)) {
     644             : 
     645             :             /* vertical split; left & right halves are 2-color encoded */
     646             : 
     647        6834 :             for (y = 0; y < 16; y++) {
     648       32160 :                 for (x = 0; x < 4; x++, flags >>= 1)
     649       25728 :                     *pixel_ptr++ = P[flags & 1];
     650        6432 :                 pixel_ptr += s->stride - 4;
     651             :                 // switch to right half
     652        6432 :                 if (y == 7) {
     653         402 :                     pixel_ptr -= 8 * s->stride - 4;
     654         402 :                     P[0]  = P[2];
     655         402 :                     P[1]  = P[3];
     656         402 :                     flags = bytestream2_get_le32(&s->stream_ptr);
     657             :                 }
     658             :             }
     659             : 
     660             :         } else {
     661             : 
     662             :             /* horizontal split; top & bottom halves are 2-color encoded */
     663             : 
     664        7290 :             for (y = 0; y < 8; y++) {
     665        6480 :                 if (y == 4) {
     666         810 :                     P[0]  = P[2];
     667         810 :                     P[1]  = P[3];
     668         810 :                     flags = bytestream2_get_le32(&s->stream_ptr);
     669             :                 }
     670             : 
     671       58320 :                 for (x = 0; x < 8; x++, flags >>= 1)
     672       51840 :                     *pixel_ptr++ = P[flags & 1];
     673        6480 :                 pixel_ptr += s->line_inc;
     674             :             }
     675             :         }
     676             :     }
     677             : 
     678             :     /* report success */
     679        1478 :     return 0;
     680             : }
     681             : 
     682        6526 : static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s, AVFrame *frame)
     683             : {
     684             :     int x, y;
     685             :     uint16_t P[4];
     686        6526 :     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
     687             : 
     688             :     /* 4-color encoding */
     689       32630 :     for (x = 0; x < 4; x++)
     690       26104 :         P[x] = bytestream2_get_le16(&s->stream_ptr);
     691             : 
     692        6526 :     if (!(P[0] & 0x8000)) {
     693        2987 :         if (!(P[2] & 0x8000)) {
     694             : 
     695             :             /* 1 of 4 colors for each pixel */
     696       25947 :             for (y = 0; y < 8; y++) {
     697             :                 /* get the next set of 8 2-bit flags */
     698       23064 :                 int flags = bytestream2_get_le16(&s->stream_ptr);
     699      207576 :                 for (x = 0; x < 8; x++, flags >>= 2)
     700      184512 :                     *pixel_ptr++ = P[flags & 0x03];
     701       23064 :                 pixel_ptr += s->line_inc;
     702             :             }
     703             : 
     704             :         } else {
     705             :             uint32_t flags;
     706             : 
     707             :             /* 1 of 4 colors for each 2x2 block */
     708         104 :             flags = bytestream2_get_le32(&s->stream_ptr);
     709             : 
     710         520 :             for (y = 0; y < 8; y += 2) {
     711        2080 :                 for (x = 0; x < 8; x += 2, flags >>= 2) {
     712        3328 :                     pixel_ptr[x                ] =
     713        4992 :                     pixel_ptr[x + 1            ] =
     714        4992 :                     pixel_ptr[x +     s->stride] =
     715        3328 :                     pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
     716             :                 }
     717         416 :                 pixel_ptr += s->stride * 2;
     718             :             }
     719             : 
     720             :         }
     721             :     } else {
     722             :         uint64_t flags;
     723             : 
     724             :         /* 1 of 4 colors for each 2x1 or 1x2 block */
     725        3539 :         flags = bytestream2_get_le64(&s->stream_ptr);
     726        3539 :         if (!(P[2] & 0x8000)) {
     727       25371 :             for (y = 0; y < 8; y++) {
     728      112760 :                 for (x = 0; x < 8; x += 2, flags >>= 2) {
     729      180416 :                     pixel_ptr[x    ] =
     730      180416 :                     pixel_ptr[x + 1] = P[flags & 0x03];
     731             :                 }
     732       22552 :                 pixel_ptr += s->stride;
     733             :             }
     734             :         } else {
     735        3600 :             for (y = 0; y < 8; y += 2) {
     736       25920 :                 for (x = 0; x < 8; x++, flags >>= 2) {
     737       46080 :                     pixel_ptr[x            ] =
     738       46080 :                     pixel_ptr[x + s->stride] = P[flags & 0x03];
     739             :                 }
     740        2880 :                 pixel_ptr += s->stride * 2;
     741             :             }
     742             :         }
     743             :     }
     744             : 
     745             :     /* report success */
     746        6526 :     return 0;
     747             : }
     748             : 
     749        7914 : static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s, AVFrame *frame)
     750             : {
     751             :     int x, y;
     752             :     uint16_t P[8];
     753        7914 :     int flags = 0;
     754        7914 :     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
     755             : 
     756       39570 :     for (x = 0; x < 4; x++)
     757       31656 :         P[x] = bytestream2_get_le16(&s->stream_ptr);
     758             : 
     759             :     /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
     760             :      * either top and bottom or left and right halves */
     761        7914 :     if (!(P[0] & 0x8000)) {
     762             : 
     763             :         /* 4-color encoding for each quadrant */
     764       52530 :         for (y = 0; y < 16; y++) {
     765             :             // new values for each 4x4 block
     766       49440 :             if (!(y & 3)) {
     767       12360 :                 if (y)
     768       46350 :                     for (x = 0; x < 4; x++)
     769       37080 :                         P[x] = bytestream2_get_le16(&s->stream_ptr);
     770       12360 :                 flags = bytestream2_get_le32(&s->stream_ptr);
     771             :             }
     772             : 
     773      247200 :             for (x = 0; x < 4; x++, flags >>= 2)
     774      197760 :                 *pixel_ptr++ = P[flags & 0x03];
     775             : 
     776       49440 :             pixel_ptr += s->stride - 4;
     777             :             // switch to right half
     778       49440 :             if (y == 7) pixel_ptr -= 8 * s->stride - 4;
     779             :         }
     780             : 
     781             :     } else {
     782             :         // vertical split?
     783             :         int vert;
     784        4824 :         uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
     785             : 
     786       24120 :         for (x = 4; x < 8; x++)
     787       19296 :             P[x] = bytestream2_get_le16(&s->stream_ptr);
     788        4824 :         vert = !(P[4] & 0x8000);
     789             : 
     790             :         /* 4-color encoding for either left and right or top and bottom
     791             :          * halves */
     792             : 
     793       82008 :         for (y = 0; y < 16; y++) {
     794      385920 :             for (x = 0; x < 4; x++, flags >>= 2)
     795      308736 :                 *pixel_ptr++ = P[flags & 0x03];
     796             : 
     797       77184 :             if (vert) {
     798       26000 :                 pixel_ptr += s->stride - 4;
     799             :                 // switch to right half
     800       26000 :                 if (y == 7) pixel_ptr -= 8 * s->stride - 4;
     801       51184 :             } else if (y & 1) pixel_ptr += s->line_inc;
     802             : 
     803             :             // load values for second half
     804       77184 :             if (y == 7) {
     805        4824 :                 memcpy(P, P + 4, 8);
     806        4824 :                 flags = bytestream2_get_le64(&s->stream_ptr);
     807             :             }
     808             :         }
     809             :     }
     810             : 
     811             :     /* report success */
     812        7914 :     return 0;
     813             : }
     814             : 
     815        1690 : static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s, AVFrame *frame)
     816             : {
     817             :     int x, y;
     818        1690 :     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
     819             : 
     820             :     /* 64-color encoding (each pixel in block is a different color) */
     821       15210 :     for (y = 0; y < 8; y++) {
     822      121680 :         for (x = 0; x < 8; x++)
     823      108160 :             pixel_ptr[x] = bytestream2_get_le16(&s->stream_ptr);
     824       13520 :         pixel_ptr  += s->stride;
     825             :     }
     826             : 
     827             :     /* report success */
     828        1690 :     return 0;
     829             : }
     830             : 
     831           8 : static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s, AVFrame *frame)
     832             : {
     833             :     int x, y;
     834           8 :     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
     835             : 
     836             :     /* 16-color block encoding: each 2x2 block is a different color */
     837          40 :     for (y = 0; y < 8; y += 2) {
     838         160 :         for (x = 0; x < 8; x += 2) {
     839         256 :             pixel_ptr[x                ] =
     840         384 :             pixel_ptr[x + 1            ] =
     841         384 :             pixel_ptr[x +     s->stride] =
     842         256 :             pixel_ptr[x + 1 + s->stride] = bytestream2_get_le16(&s->stream_ptr);
     843             :         }
     844          32 :         pixel_ptr += s->stride * 2;
     845             :     }
     846             : 
     847             :     /* report success */
     848           8 :     return 0;
     849             : }
     850             : 
     851          38 : static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s, AVFrame *frame)
     852             : {
     853             :     int x, y;
     854             :     uint16_t P[2];
     855          38 :     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
     856             : 
     857             :     /* 4-color block encoding: each 4x4 block is a different color */
     858         342 :     for (y = 0; y < 8; y++) {
     859         304 :         if (!(y & 3)) {
     860          76 :             P[0] = bytestream2_get_le16(&s->stream_ptr);
     861          76 :             P[1] = bytestream2_get_le16(&s->stream_ptr);
     862             :         }
     863        2736 :         for (x = 0; x < 8; x++)
     864        2432 :             pixel_ptr[x] = P[x >> 2];
     865         304 :         pixel_ptr += s->stride;
     866             :     }
     867             : 
     868             :     /* report success */
     869          38 :     return 0;
     870             : }
     871             : 
     872        3556 : static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s, AVFrame *frame)
     873             : {
     874             :     int x, y;
     875             :     uint16_t pix;
     876        3556 :     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
     877             : 
     878             :     /* 1-color encoding: the whole block is 1 solid color */
     879        3556 :     pix = bytestream2_get_le16(&s->stream_ptr);
     880             : 
     881       32004 :     for (y = 0; y < 8; y++) {
     882      256032 :         for (x = 0; x < 8; x++)
     883      227584 :             pixel_ptr[x] = pix;
     884       28448 :         pixel_ptr += s->stride;
     885             :     }
     886             : 
     887             :     /* report success */
     888        3556 :     return 0;
     889             : }
     890             : 
     891             : static int (* const ipvideo_decode_block[])(IpvideoContext *s, AVFrame *frame) = {
     892             :     ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1,
     893             :     ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3,
     894             :     ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5,
     895             :     ipvideo_decode_block_opcode_0x6, ipvideo_decode_block_opcode_0x7,
     896             :     ipvideo_decode_block_opcode_0x8, ipvideo_decode_block_opcode_0x9,
     897             :     ipvideo_decode_block_opcode_0xA, ipvideo_decode_block_opcode_0xB,
     898             :     ipvideo_decode_block_opcode_0xC, ipvideo_decode_block_opcode_0xD,
     899             :     ipvideo_decode_block_opcode_0xE, ipvideo_decode_block_opcode_0xF,
     900             : };
     901             : 
     902             : static int (* const ipvideo_decode_block16[])(IpvideoContext *s, AVFrame *frame) = {
     903             :     ipvideo_decode_block_opcode_0x0,    ipvideo_decode_block_opcode_0x1,
     904             :     ipvideo_decode_block_opcode_0x2,    ipvideo_decode_block_opcode_0x3,
     905             :     ipvideo_decode_block_opcode_0x4,    ipvideo_decode_block_opcode_0x5,
     906             :     ipvideo_decode_block_opcode_0x6_16, ipvideo_decode_block_opcode_0x7_16,
     907             :     ipvideo_decode_block_opcode_0x8_16, ipvideo_decode_block_opcode_0x9_16,
     908             :     ipvideo_decode_block_opcode_0xA_16, ipvideo_decode_block_opcode_0xB_16,
     909             :     ipvideo_decode_block_opcode_0xC_16, ipvideo_decode_block_opcode_0xD_16,
     910             :     ipvideo_decode_block_opcode_0xE_16, ipvideo_decode_block_opcode_0x1,
     911             : };
     912             : 
     913           0 : static void ipvideo_format_06_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
     914             : {
     915             :     int line;
     916             : 
     917           0 :     if (!opcode) {
     918           0 :         for (line = 0; line < 8; ++line) {
     919           0 :             bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
     920           0 :             s->pixel_ptr += s->stride;
     921             :         }
     922             :     } else {
     923             :         /* Don't try to copy second_last_frame data on the first frames */
     924           0 :         if (s->avctx->frame_number > 2)
     925           0 :             copy_from(s, s->second_last_frame, frame, 0, 0);
     926             :     }
     927           0 : }
     928             : 
     929           0 : static void ipvideo_format_06_secondpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
     930             : {
     931             :     int off_x, off_y;
     932             : 
     933           0 :     if (opcode < 0) {
     934           0 :         off_x = ((uint16_t)opcode - 0xC000) % frame->linesize[0];
     935           0 :         off_y = ((uint16_t)opcode - 0xC000) / frame->linesize[0];
     936           0 :         copy_from(s, s->last_frame, frame, off_x, off_y);
     937           0 :     } else if (opcode > 0) {
     938           0 :         off_x = ((uint16_t)opcode - 0x4000) % frame->linesize[0];
     939           0 :         off_y = ((uint16_t)opcode - 0x4000) / frame->linesize[0];
     940           0 :         copy_from(s, frame, frame, off_x, off_y);
     941             :     }
     942           0 : }
     943             : 
     944             : static void (* const ipvideo_format_06_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op) = {
     945             :     ipvideo_format_06_firstpass, ipvideo_format_06_secondpass,
     946             : };
     947             : 
     948           0 : static void ipvideo_decode_format_06_opcodes(IpvideoContext *s, AVFrame *frame)
     949             : {
     950             :     int pass, x, y;
     951             :     int16_t opcode;
     952             :     GetByteContext decoding_map_ptr;
     953             : 
     954             :     /* this is PAL8, so make the palette available */
     955           0 :     memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
     956           0 :     s->stride = frame->linesize[0];
     957             : 
     958           0 :     s->line_inc = s->stride - 8;
     959           0 :     s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
     960           0 :                                   + (s->avctx->width - 8) * (1 + s->is_16bpp);
     961             : 
     962           0 :     bytestream2_init(&decoding_map_ptr, s->decoding_map, s->decoding_map_size);
     963             : 
     964           0 :     for (pass = 0; pass < 2; ++pass) {
     965           0 :         bytestream2_seek(&decoding_map_ptr, 0, SEEK_SET);
     966           0 :         for (y = 0; y < s->avctx->height; y += 8) {
     967           0 :             for (x = 0; x < s->avctx->width; x += 8) {
     968           0 :                 opcode = bytestream2_get_le16(&decoding_map_ptr);
     969             : 
     970             :                 ff_tlog(s->avctx,
     971             :                         "  block @ (%3d, %3d): opcode 0x%X, data ptr offset %d\n",
     972             :                         x, y, opcode, bytestream2_tell(&s->stream_ptr));
     973             : 
     974           0 :                 s->pixel_ptr = frame->data[0] + x + y * frame->linesize[0];
     975           0 :                 ipvideo_format_06_passes[pass](s, frame, opcode);
     976             :             }
     977             :         }
     978             :     }
     979             : 
     980           0 :     if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
     981           0 :         av_log(s->avctx, AV_LOG_DEBUG,
     982             :                "decode finished with %d bytes left over\n",
     983             :                bytestream2_get_bytes_left(&s->stream_ptr));
     984             :     }
     985           0 : }
     986             : 
     987           0 : static void ipvideo_format_10_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
     988             : {
     989             :     int line;
     990             : 
     991           0 :     if (!opcode) {
     992           0 :         for (line = 0; line < 8; ++line) {
     993           0 :             bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
     994           0 :             s->pixel_ptr += s->stride;
     995             :         }
     996             :     }
     997           0 : }
     998             : 
     999           0 : static void ipvideo_format_10_secondpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
    1000             : {
    1001             :     int off_x, off_y;
    1002             : 
    1003           0 :     if (opcode < 0) {
    1004           0 :         off_x = ((uint16_t)opcode - 0xC000) % s->cur_decode_frame->linesize[0];
    1005           0 :         off_y = ((uint16_t)opcode - 0xC000) / s->cur_decode_frame->linesize[0];
    1006           0 :         copy_from(s, s->prev_decode_frame, s->cur_decode_frame, off_x, off_y);
    1007           0 :     } else if (opcode > 0) {
    1008           0 :         off_x = ((uint16_t)opcode - 0x4000) % s->cur_decode_frame->linesize[0];
    1009           0 :         off_y = ((uint16_t)opcode - 0x4000) / s->cur_decode_frame->linesize[0];
    1010           0 :         copy_from(s, s->cur_decode_frame, s->cur_decode_frame, off_x, off_y);
    1011             :     }
    1012           0 : }
    1013             : 
    1014             : static void (* const ipvideo_format_10_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op) = {
    1015             :     ipvideo_format_10_firstpass, ipvideo_format_10_secondpass,
    1016             : };
    1017             : 
    1018           0 : static void ipvideo_decode_format_10_opcodes(IpvideoContext *s, AVFrame *frame)
    1019             : {
    1020             :     int pass, x, y, changed_block;
    1021             :     int16_t opcode, skip;
    1022             :     GetByteContext decoding_map_ptr;
    1023             :     GetByteContext skip_map_ptr;
    1024             : 
    1025           0 :     bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
    1026             : 
    1027             :     /* this is PAL8, so make the palette available */
    1028           0 :     memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
    1029           0 :     s->stride = frame->linesize[0];
    1030             : 
    1031           0 :     s->line_inc = s->stride - 8;
    1032           0 :     s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
    1033           0 :                                   + (s->avctx->width - 8) * (1 + s->is_16bpp);
    1034             : 
    1035           0 :     bytestream2_init(&decoding_map_ptr, s->decoding_map, s->decoding_map_size);
    1036           0 :     bytestream2_init(&skip_map_ptr, s->skip_map, s->skip_map_size);
    1037             : 
    1038           0 :     for (pass = 0; pass < 2; ++pass) {
    1039           0 :         bytestream2_seek(&decoding_map_ptr, 0, SEEK_SET);
    1040           0 :         bytestream2_seek(&skip_map_ptr, 0, SEEK_SET);
    1041           0 :         skip = bytestream2_get_le16(&skip_map_ptr);
    1042             : 
    1043           0 :         for (y = 0; y < s->avctx->height; y += 8) {
    1044           0 :             for (x = 0; x < s->avctx->width; x += 8) {
    1045           0 :                 s->pixel_ptr = s->cur_decode_frame->data[0] + x + y * s->cur_decode_frame->linesize[0];
    1046             : 
    1047           0 :                 while (skip <= 0)  {
    1048           0 :                     if (skip != -0x8000 && skip) {
    1049           0 :                         opcode = bytestream2_get_le16(&decoding_map_ptr);
    1050           0 :                         ipvideo_format_10_passes[pass](s, frame, opcode);
    1051           0 :                         break;
    1052             :                     }
    1053           0 :                     if (bytestream2_get_bytes_left(&skip_map_ptr) < 2)
    1054           0 :                         return;
    1055           0 :                     skip = bytestream2_get_le16(&skip_map_ptr);
    1056             :                 }
    1057           0 :                 skip *= 2;
    1058             :             }
    1059             :         }
    1060             :     }
    1061             : 
    1062           0 :     bytestream2_seek(&skip_map_ptr, 0, SEEK_SET);
    1063           0 :     skip = bytestream2_get_le16(&skip_map_ptr);
    1064           0 :     for (y = 0; y < s->avctx->height; y += 8) {
    1065           0 :         for (x = 0; x < s->avctx->width; x += 8) {
    1066           0 :             changed_block = 0;
    1067           0 :             s->pixel_ptr = frame->data[0] + x + y*frame->linesize[0];
    1068             : 
    1069           0 :             while (skip <= 0)  {
    1070           0 :                 if (skip != -0x8000 && skip) {
    1071           0 :                     changed_block = 1;
    1072           0 :                     break;
    1073             :                 }
    1074           0 :                 if (bytestream2_get_bytes_left(&skip_map_ptr) < 2)
    1075           0 :                     return;
    1076           0 :                 skip = bytestream2_get_le16(&skip_map_ptr);
    1077             :             }
    1078             : 
    1079           0 :             if (changed_block) {
    1080           0 :                 copy_from(s, s->cur_decode_frame, frame, 0, 0);
    1081             :             } else {
    1082             :                 /* Don't try to copy last_frame data on the first frame */
    1083           0 :                 if (s->avctx->frame_number)
    1084           0 :                     copy_from(s, s->last_frame, frame, 0, 0);
    1085             :             }
    1086           0 :             skip *= 2;
    1087             :         }
    1088             :     }
    1089             : 
    1090           0 :     FFSWAP(AVFrame*, s->prev_decode_frame, s->cur_decode_frame);
    1091             : 
    1092           0 :     if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
    1093           0 :         av_log(s->avctx, AV_LOG_DEBUG,
    1094             :                "decode finished with %d bytes left over\n",
    1095             :                bytestream2_get_bytes_left(&s->stream_ptr));
    1096             :     }
    1097             : }
    1098             : 
    1099         160 : static void ipvideo_decode_format_11_opcodes(IpvideoContext *s, AVFrame *frame)
    1100             : {
    1101             :     int x, y;
    1102             :     unsigned char opcode;
    1103             :     int ret;
    1104             :     GetBitContext gb;
    1105             : 
    1106         160 :     bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
    1107         160 :     if (!s->is_16bpp) {
    1108             :         /* this is PAL8, so make the palette available */
    1109         110 :         memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
    1110             : 
    1111         110 :         s->stride = frame->linesize[0];
    1112             :     } else {
    1113          50 :         s->stride = frame->linesize[0] >> 1;
    1114          50 :         s->mv_ptr = s->stream_ptr;
    1115          50 :         bytestream2_skip(&s->mv_ptr, bytestream2_get_le16(&s->stream_ptr));
    1116             :     }
    1117         160 :     s->line_inc = s->stride - 8;
    1118         320 :     s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
    1119         160 :                                   + (s->avctx->width - 8) * (1 + s->is_16bpp);
    1120             : 
    1121         160 :     init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8);
    1122        6560 :     for (y = 0; y < s->avctx->height; y += 8) {
    1123      404000 :         for (x = 0; x < s->avctx->width; x += 8) {
    1124      397600 :             if (get_bits_left(&gb) < 4)
    1125           0 :                 return;
    1126      397600 :             opcode = get_bits(&gb, 4);
    1127             : 
    1128             :             ff_tlog(s->avctx,
    1129             :                     "  block @ (%3d, %3d): encoding 0x%X, data ptr offset %d\n",
    1130             :                     x, y, opcode, bytestream2_tell(&s->stream_ptr));
    1131             : 
    1132      397600 :             if (!s->is_16bpp) {
    1133      475200 :                 s->pixel_ptr = frame->data[0] + x
    1134      237600 :                               + y*frame->linesize[0];
    1135      237600 :                 ret = ipvideo_decode_block[opcode](s, frame);
    1136             :             } else {
    1137      320000 :                 s->pixel_ptr = frame->data[0] + x*2
    1138      160000 :                               + y*frame->linesize[0];
    1139      160000 :                 ret = ipvideo_decode_block16[opcode](s, frame);
    1140             :             }
    1141      397600 :             if (ret != 0) {
    1142           0 :                 av_log(s->avctx, AV_LOG_ERROR, "decode problem on frame %d, @ block (%d, %d)\n",
    1143           0 :                        s->avctx->frame_number, x, y);
    1144           0 :                 return;
    1145             :             }
    1146             :         }
    1147             :     }
    1148         160 :     if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
    1149          48 :         av_log(s->avctx, AV_LOG_DEBUG,
    1150             :                "decode finished with %d bytes left over\n",
    1151             :                bytestream2_get_bytes_left(&s->stream_ptr));
    1152             :     }
    1153             : }
    1154             : 
    1155           5 : static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
    1156             : {
    1157           5 :     IpvideoContext *s = avctx->priv_data;
    1158             :     int ret;
    1159             : 
    1160           5 :     s->avctx = avctx;
    1161             : 
    1162           5 :     s->is_16bpp = avctx->bits_per_coded_sample == 16;
    1163           5 :     avctx->pix_fmt = s->is_16bpp ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_PAL8;
    1164             : 
    1165           5 :     ff_hpeldsp_init(&s->hdsp, avctx->flags);
    1166             : 
    1167           5 :     s->last_frame        = av_frame_alloc();
    1168           5 :     s->second_last_frame = av_frame_alloc();
    1169           5 :     s->cur_decode_frame  = av_frame_alloc();
    1170           5 :     s->prev_decode_frame = av_frame_alloc();
    1171          10 :     if (!s->last_frame || !s->second_last_frame ||
    1172          10 :         !s->cur_decode_frame || !s->prev_decode_frame) {
    1173           0 :         ret = AVERROR(ENOMEM);
    1174           0 :         goto error;
    1175             :     }
    1176             : 
    1177           5 :     s->cur_decode_frame->width   = avctx->width;
    1178           5 :     s->prev_decode_frame->width  = avctx->width;
    1179           5 :     s->cur_decode_frame->height  = avctx->height;
    1180           5 :     s->prev_decode_frame->height = avctx->height;
    1181           5 :     s->cur_decode_frame->format  = avctx->pix_fmt;
    1182           5 :     s->prev_decode_frame->format = avctx->pix_fmt;
    1183             : 
    1184           5 :     ret = ff_get_buffer(avctx, s->cur_decode_frame, 0);
    1185           5 :     if (ret < 0)
    1186           0 :         goto error;
    1187             : 
    1188           5 :     ret = ff_get_buffer(avctx, s->prev_decode_frame, 0);
    1189           5 :     if (ret < 0)
    1190           0 :         goto error;
    1191             : 
    1192           5 :     return 0;
    1193           0 : error:
    1194           0 :     av_frame_free(&s->last_frame);
    1195           0 :     av_frame_free(&s->second_last_frame);
    1196           0 :     av_frame_free(&s->cur_decode_frame);
    1197           0 :     av_frame_free(&s->prev_decode_frame);
    1198           0 :     return ret;
    1199             : }
    1200             : 
    1201         160 : static int ipvideo_decode_frame(AVCodecContext *avctx,
    1202             :                                 void *data, int *got_frame,
    1203             :                                 AVPacket *avpkt)
    1204             : {
    1205         160 :     const uint8_t *buf = avpkt->data;
    1206         160 :     int buf_size = avpkt->size;
    1207         160 :     IpvideoContext *s = avctx->priv_data;
    1208         160 :     AVFrame *frame = data;
    1209             :     int ret;
    1210             :     int send_buffer;
    1211             :     int frame_format;
    1212             :     int video_data_size;
    1213             : 
    1214         160 :     if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {
    1215           2 :         av_frame_unref(s->last_frame);
    1216           2 :         av_frame_unref(s->second_last_frame);
    1217           2 :         av_frame_unref(s->cur_decode_frame);
    1218           2 :         av_frame_unref(s->prev_decode_frame);
    1219             :     }
    1220             : 
    1221         160 :     if (!s->cur_decode_frame->data[0]) {
    1222           2 :         ret = ff_get_buffer(avctx, s->cur_decode_frame, 0);
    1223           2 :         if (ret < 0)
    1224           0 :             return ret;
    1225             : 
    1226           2 :         ret = ff_get_buffer(avctx, s->prev_decode_frame, 0);
    1227           2 :         if (ret < 0) {
    1228           0 :             av_frame_unref(s->cur_decode_frame);
    1229           0 :             return ret;
    1230             :         }
    1231             :     }
    1232             : 
    1233         160 :     if (buf_size < 8)
    1234           0 :         return AVERROR_INVALIDDATA;
    1235             : 
    1236         160 :     frame_format         = AV_RL8(buf);
    1237         160 :     send_buffer          = AV_RL8(buf + 1);
    1238         160 :     video_data_size      = AV_RL16(buf + 2);
    1239         160 :     s->decoding_map_size = AV_RL16(buf + 4);
    1240         160 :     s->skip_map_size     = AV_RL16(buf + 6);
    1241             : 
    1242         160 :     switch(frame_format) {
    1243           0 :         case 0x06:
    1244           0 :             if (s->decoding_map_size) {
    1245           0 :                 av_log(avctx, AV_LOG_ERROR, "Decoding map for format 0x06\n");
    1246           0 :                 return AVERROR_INVALIDDATA;
    1247             :             }
    1248             : 
    1249           0 :             if (s->skip_map_size) {
    1250           0 :                 av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x06\n");
    1251           0 :                 return AVERROR_INVALIDDATA;
    1252             :             }
    1253             : 
    1254           0 :             if (s->is_16bpp) {
    1255           0 :                 av_log(avctx, AV_LOG_ERROR, "Video format 0x06 does not support 16bpp movies\n");
    1256           0 :                 return AVERROR_INVALIDDATA;
    1257             :             }
    1258             : 
    1259             :             /* Decoding map for 0x06 frame format is at the top of pixeldata */
    1260           0 :             s->decoding_map_size = ((s->avctx->width / 8) * (s->avctx->height / 8)) * 2;
    1261           0 :             s->decoding_map = buf + 8 + 14; /* 14 bits of op data */
    1262           0 :             video_data_size -= s->decoding_map_size + 14;
    1263           0 :             if (video_data_size <= 0)
    1264           0 :                 return AVERROR_INVALIDDATA;
    1265             : 
    1266           0 :             if (buf_size < 8 + s->decoding_map_size + 14 + video_data_size)
    1267           0 :                 return AVERROR_INVALIDDATA;
    1268             : 
    1269           0 :             bytestream2_init(&s->stream_ptr, buf + 8 + s->decoding_map_size + 14, video_data_size);
    1270             : 
    1271           0 :             break;
    1272             : 
    1273           0 :         case 0x10:
    1274           0 :             if (! s->decoding_map_size) {
    1275           0 :                 av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x10\n");
    1276           0 :                 return AVERROR_INVALIDDATA;
    1277             :             }
    1278             : 
    1279           0 :             if (! s->skip_map_size) {
    1280           0 :                 av_log(avctx, AV_LOG_ERROR, "Empty skip map for format 0x10\n");
    1281           0 :                 return AVERROR_INVALIDDATA;
    1282             :             }
    1283             : 
    1284           0 :             if (s->is_16bpp) {
    1285           0 :                 av_log(avctx, AV_LOG_ERROR, "Video format 0x10 does not support 16bpp movies\n");
    1286           0 :                 return AVERROR_INVALIDDATA;
    1287             :             }
    1288             : 
    1289           0 :             if (buf_size < 8 + video_data_size + s->decoding_map_size + s->skip_map_size)
    1290           0 :                 return AVERROR_INVALIDDATA;
    1291             : 
    1292           0 :             bytestream2_init(&s->stream_ptr, buf + 8, video_data_size);
    1293           0 :             s->decoding_map = buf + 8 + video_data_size;
    1294           0 :             s->skip_map = buf + 8 + video_data_size + s->decoding_map_size;
    1295             : 
    1296           0 :             break;
    1297             : 
    1298         160 :         case 0x11:
    1299         160 :             if (! s->decoding_map_size) {
    1300           0 :                 av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x11\n");
    1301           0 :                 return AVERROR_INVALIDDATA;
    1302             :             }
    1303             : 
    1304         160 :             if (s->skip_map_size) {
    1305           0 :                 av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x11\n");
    1306           0 :                 return AVERROR_INVALIDDATA;
    1307             :             }
    1308             : 
    1309         160 :             if (buf_size < 8 + video_data_size + s->decoding_map_size)
    1310           0 :                 return AVERROR_INVALIDDATA;
    1311             : 
    1312         160 :             bytestream2_init(&s->stream_ptr, buf + 8, video_data_size);
    1313         160 :             s->decoding_map = buf + 8 + video_data_size;
    1314             : 
    1315         160 :             break;
    1316             : 
    1317           0 :         default:
    1318           0 :             av_log(avctx, AV_LOG_ERROR, "Frame type 0x%02X unsupported\n", frame_format);
    1319             :     }
    1320             : 
    1321             :     /* ensure we can't overread the packet */
    1322         160 :     if (buf_size < 8 + s->decoding_map_size + video_data_size + s->skip_map_size) {
    1323           0 :         av_log(avctx, AV_LOG_ERROR, "Invalid IP packet size\n");
    1324           0 :         return AVERROR_INVALIDDATA;
    1325             :     }
    1326             : 
    1327         160 :     if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
    1328           0 :         return ret;
    1329             : 
    1330         160 :     if (!s->is_16bpp) {
    1331             :         int size;
    1332         110 :         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size);
    1333         110 :         if (pal && size == AVPALETTE_SIZE) {
    1334           1 :             frame->palette_has_changed = 1;
    1335           1 :             memcpy(s->pal, pal, AVPALETTE_SIZE);
    1336         109 :         } else if (pal) {
    1337           0 :             av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
    1338             :         }
    1339             :     }
    1340             : 
    1341         160 :     switch(frame_format) {
    1342           0 :         case 0x06:
    1343           0 :             ipvideo_decode_format_06_opcodes(s, frame);
    1344           0 :             break;
    1345           0 :         case 0x10:
    1346           0 :             ipvideo_decode_format_10_opcodes(s, frame);
    1347           0 :             break;
    1348         160 :         case 0x11:
    1349         160 :             ipvideo_decode_format_11_opcodes(s, frame);
    1350         160 :             break;
    1351             :     }
    1352             : 
    1353         160 :     *got_frame = send_buffer;
    1354             : 
    1355             :     /* shuffle frames */
    1356         160 :     av_frame_unref(s->second_last_frame);
    1357         160 :     FFSWAP(AVFrame*, s->second_last_frame, s->last_frame);
    1358         160 :     if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
    1359           0 :         return ret;
    1360             : 
    1361             :     /* report that the buffer was completely consumed */
    1362         160 :     return buf_size;
    1363             : }
    1364             : 
    1365           5 : static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
    1366             : {
    1367           5 :     IpvideoContext *s = avctx->priv_data;
    1368             : 
    1369           5 :     av_frame_free(&s->last_frame);
    1370           5 :     av_frame_free(&s->second_last_frame);
    1371           5 :     av_frame_free(&s->cur_decode_frame);
    1372           5 :     av_frame_free(&s->prev_decode_frame);
    1373             : 
    1374           5 :     return 0;
    1375             : }
    1376             : 
    1377             : AVCodec ff_interplay_video_decoder = {
    1378             :     .name           = "interplayvideo",
    1379             :     .long_name      = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
    1380             :     .type           = AVMEDIA_TYPE_VIDEO,
    1381             :     .id             = AV_CODEC_ID_INTERPLAY_VIDEO,
    1382             :     .priv_data_size = sizeof(IpvideoContext),
    1383             :     .init           = ipvideo_decode_init,
    1384             :     .close          = ipvideo_decode_end,
    1385             :     .decode         = ipvideo_decode_frame,
    1386             :     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE,
    1387             : };

Generated by: LCOV version 1.13