LCOV - code coverage report
Current view: top level - libavcodec - truemotion1.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 264 355 74.4 %
Date: 2017-12-17 04:34:43 Functions: 13 16 81.2 %

          Line data    Source code
       1             : /*
       2             :  * Duck TrueMotion 1.0 Decoder
       3             :  * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
       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             :  * Duck TrueMotion v1 Video Decoder by
      25             :  * Alex Beregszaszi and
      26             :  * Mike Melanson (melanson@pcisys.net)
      27             :  *
      28             :  * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and
      29             :  * outputs RGB555 (or RGB565) data. 24-bit TM1 data is not supported yet.
      30             :  */
      31             : 
      32             : #include <stdio.h>
      33             : #include <stdlib.h>
      34             : #include <string.h>
      35             : 
      36             : #include "avcodec.h"
      37             : #include "internal.h"
      38             : #include "libavutil/imgutils.h"
      39             : #include "libavutil/internal.h"
      40             : #include "libavutil/intreadwrite.h"
      41             : #include "libavutil/mem.h"
      42             : 
      43             : #include "truemotion1data.h"
      44             : 
      45             : typedef struct TrueMotion1Context {
      46             :     AVCodecContext *avctx;
      47             :     AVFrame *frame;
      48             : 
      49             :     const uint8_t *buf;
      50             :     int size;
      51             : 
      52             :     const uint8_t *mb_change_bits;
      53             :     int mb_change_bits_row_size;
      54             :     const uint8_t *index_stream;
      55             :     int index_stream_size;
      56             : 
      57             :     int flags;
      58             :     int x, y, w, h;
      59             : 
      60             :     uint32_t y_predictor_table[1024];
      61             :     uint32_t c_predictor_table[1024];
      62             :     uint32_t fat_y_predictor_table[1024];
      63             :     uint32_t fat_c_predictor_table[1024];
      64             : 
      65             :     int compression;
      66             :     int block_type;
      67             :     int block_width;
      68             :     int block_height;
      69             : 
      70             :     int16_t ydt[8];
      71             :     int16_t cdt[8];
      72             :     int16_t fat_ydt[8];
      73             :     int16_t fat_cdt[8];
      74             : 
      75             :     int last_deltaset, last_vectable;
      76             : 
      77             :     unsigned int *vert_pred;
      78             :     int vert_pred_size;
      79             : 
      80             : } TrueMotion1Context;
      81             : 
      82             : #define FLAG_SPRITE         32
      83             : #define FLAG_KEYFRAME       16
      84             : #define FLAG_INTERFRAME      8
      85             : #define FLAG_INTERPOLATED    4
      86             : 
      87             : struct frame_header {
      88             :     uint8_t header_size;
      89             :     uint8_t compression;
      90             :     uint8_t deltaset;
      91             :     uint8_t vectable;
      92             :     uint16_t ysize;
      93             :     uint16_t xsize;
      94             :     uint16_t checksum;
      95             :     uint8_t version;
      96             :     uint8_t header_type;
      97             :     uint8_t flags;
      98             :     uint8_t control;
      99             :     uint16_t xoffset;
     100             :     uint16_t yoffset;
     101             :     uint16_t width;
     102             :     uint16_t height;
     103             : };
     104             : 
     105             : #define ALGO_NOP        0
     106             : #define ALGO_RGB16V     1
     107             : #define ALGO_RGB16H     2
     108             : #define ALGO_RGB24H     3
     109             : 
     110             : /* these are the various block sizes that can occupy a 4x4 block */
     111             : #define BLOCK_2x2  0
     112             : #define BLOCK_2x4  1
     113             : #define BLOCK_4x2  2
     114             : #define BLOCK_4x4  3
     115             : 
     116             : typedef struct comp_types {
     117             :     int algorithm;
     118             :     int block_width; // vres
     119             :     int block_height; // hres
     120             :     int block_type;
     121             : } comp_types;
     122             : 
     123             : /* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */
     124             : static const comp_types compression_types[17] = {
     125             :     { ALGO_NOP,    0, 0, 0 },
     126             : 
     127             :     { ALGO_RGB16V, 4, 4, BLOCK_4x4 },
     128             :     { ALGO_RGB16H, 4, 4, BLOCK_4x4 },
     129             :     { ALGO_RGB16V, 4, 2, BLOCK_4x2 },
     130             :     { ALGO_RGB16H, 4, 2, BLOCK_4x2 },
     131             : 
     132             :     { ALGO_RGB16V, 2, 4, BLOCK_2x4 },
     133             :     { ALGO_RGB16H, 2, 4, BLOCK_2x4 },
     134             :     { ALGO_RGB16V, 2, 2, BLOCK_2x2 },
     135             :     { ALGO_RGB16H, 2, 2, BLOCK_2x2 },
     136             : 
     137             :     { ALGO_NOP,    4, 4, BLOCK_4x4 },
     138             :     { ALGO_RGB24H, 4, 4, BLOCK_4x4 },
     139             :     { ALGO_NOP,    4, 2, BLOCK_4x2 },
     140             :     { ALGO_RGB24H, 4, 2, BLOCK_4x2 },
     141             : 
     142             :     { ALGO_NOP,    2, 4, BLOCK_2x4 },
     143             :     { ALGO_RGB24H, 2, 4, BLOCK_2x4 },
     144             :     { ALGO_NOP,    2, 2, BLOCK_2x2 },
     145             :     { ALGO_RGB24H, 2, 2, BLOCK_2x2 }
     146             : };
     147             : 
     148           4 : static void select_delta_tables(TrueMotion1Context *s, int delta_table_index)
     149             : {
     150             :     int i;
     151             : 
     152           4 :     if (delta_table_index > 3)
     153           0 :         return;
     154             : 
     155           4 :     memcpy(s->ydt, ydts[delta_table_index], 8 * sizeof(int16_t));
     156           4 :     memcpy(s->cdt, cdts[delta_table_index], 8 * sizeof(int16_t));
     157           4 :     memcpy(s->fat_ydt, fat_ydts[delta_table_index], 8 * sizeof(int16_t));
     158           4 :     memcpy(s->fat_cdt, fat_cdts[delta_table_index], 8 * sizeof(int16_t));
     159             : 
     160             :     /* Y skinny deltas need to be halved for some reason; maybe the
     161             :      * skinny Y deltas should be modified */
     162          36 :     for (i = 0; i < 8; i++)
     163             :     {
     164             :         /* drop the lsb before dividing by 2-- net effect: round down
     165             :          * when dividing a negative number (e.g., -3/2 = -2, not -1) */
     166          32 :         s->ydt[i] &= 0xFFFE;
     167          32 :         s->ydt[i] /= 2;
     168             :     }
     169             : }
     170             : 
     171             : #if HAVE_BIGENDIAN
     172             : static int make_ydt15_entry(int p2, int p1, int16_t *ydt)
     173             : #else
     174        1104 : static int make_ydt15_entry(int p1, int p2, int16_t *ydt)
     175             : #endif
     176             : {
     177             :     int lo, hi;
     178             : 
     179        1104 :     lo = ydt[p1];
     180        1104 :     lo += (lo * 32) + (lo * 1024);
     181        1104 :     hi = ydt[p2];
     182        1104 :     hi += (hi * 32) + (hi * 1024);
     183        1104 :     return (lo + (hi * (1U << 16))) * 2;
     184             : }
     185             : 
     186        1104 : static int make_cdt15_entry(int p1, int p2, int16_t *cdt)
     187             : {
     188             :     int r, b, lo;
     189             : 
     190        1104 :     b = cdt[p2];
     191        1104 :     r = cdt[p1] * 1024;
     192        1104 :     lo = b + r;
     193        1104 :     return (lo + (lo * (1U << 16))) * 2;
     194             : }
     195             : 
     196             : #if HAVE_BIGENDIAN
     197             : static int make_ydt16_entry(int p2, int p1, int16_t *ydt)
     198             : #else
     199           0 : static int make_ydt16_entry(int p1, int p2, int16_t *ydt)
     200             : #endif
     201             : {
     202             :     int lo, hi;
     203             : 
     204           0 :     lo = ydt[p1];
     205           0 :     lo += (lo << 6) + (lo << 11);
     206           0 :     hi = ydt[p2];
     207           0 :     hi += (hi << 6) + (hi << 11);
     208           0 :     return (lo + (hi << 16)) << 1;
     209             : }
     210             : 
     211           0 : static int make_cdt16_entry(int p1, int p2, int16_t *cdt)
     212             : {
     213             :     int r, b, lo;
     214             : 
     215           0 :     b = cdt[p2];
     216           0 :     r = cdt[p1] << 11;
     217           0 :     lo = b + r;
     218           0 :     return (lo + (lo * (1 << 16))) * 2;
     219             : }
     220             : 
     221        2048 : static int make_ydt24_entry(int p1, int p2, int16_t *ydt)
     222             : {
     223             :     int lo, hi;
     224             : 
     225        2048 :     lo = ydt[p1];
     226        2048 :     hi = ydt[p2];
     227        2048 :     return (lo + (hi * (1 << 8)) + (hi * (1 << 16))) * 2;
     228             : }
     229             : 
     230        2048 : static int make_cdt24_entry(int p1, int p2, int16_t *cdt)
     231             : {
     232             :     int r, b;
     233             : 
     234        2048 :     b = cdt[p2];
     235        2048 :     r = cdt[p1] * (1 << 16);
     236        2048 :     return (b+r) * 2;
     237             : }
     238             : 
     239           2 : static void gen_vector_table15(TrueMotion1Context *s, const uint8_t *sel_vector_table)
     240             : {
     241             :     int len, i, j;
     242             :     unsigned char delta_pair;
     243             : 
     244         514 :     for (i = 0; i < 1024; i += 4)
     245             :     {
     246         512 :         len = *sel_vector_table++ / 2;
     247        1616 :         for (j = 0; j < len; j++)
     248             :         {
     249        1104 :             delta_pair = *sel_vector_table++;
     250        1104 :             s->y_predictor_table[i+j] = 0xfffffffe &
     251        1104 :                 make_ydt15_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
     252        1104 :             s->c_predictor_table[i+j] = 0xfffffffe &
     253        1104 :                 make_cdt15_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
     254             :         }
     255         512 :         s->y_predictor_table[i+(j-1)] |= 1;
     256         512 :         s->c_predictor_table[i+(j-1)] |= 1;
     257             :     }
     258           2 : }
     259             : 
     260           0 : static void gen_vector_table16(TrueMotion1Context *s, const uint8_t *sel_vector_table)
     261             : {
     262             :     int len, i, j;
     263             :     unsigned char delta_pair;
     264             : 
     265           0 :     for (i = 0; i < 1024; i += 4)
     266             :     {
     267           0 :         len = *sel_vector_table++ / 2;
     268           0 :         for (j = 0; j < len; j++)
     269             :         {
     270           0 :             delta_pair = *sel_vector_table++;
     271           0 :             s->y_predictor_table[i+j] = 0xfffffffe &
     272           0 :                 make_ydt16_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
     273           0 :             s->c_predictor_table[i+j] = 0xfffffffe &
     274           0 :                 make_cdt16_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
     275             :         }
     276           0 :         s->y_predictor_table[i+(j-1)] |= 1;
     277           0 :         s->c_predictor_table[i+(j-1)] |= 1;
     278             :     }
     279           0 : }
     280             : 
     281           2 : static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table)
     282             : {
     283             :     int len, i, j;
     284             :     unsigned char delta_pair;
     285             : 
     286         514 :     for (i = 0; i < 1024; i += 4)
     287             :     {
     288         512 :         len = *sel_vector_table++ / 2;
     289        1536 :         for (j = 0; j < len; j++)
     290             :         {
     291        1024 :             delta_pair = *sel_vector_table++;
     292        1024 :             s->y_predictor_table[i+j] = 0xfffffffe &
     293        1024 :                 make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
     294        1024 :             s->c_predictor_table[i+j] = 0xfffffffe &
     295        1024 :                 make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
     296        1024 :             s->fat_y_predictor_table[i+j] = 0xfffffffe &
     297        1024 :                 make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_ydt);
     298        1024 :             s->fat_c_predictor_table[i+j] = 0xfffffffe &
     299        1024 :                 make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_cdt);
     300             :         }
     301         512 :         s->y_predictor_table[i+(j-1)] |= 1;
     302         512 :         s->c_predictor_table[i+(j-1)] |= 1;
     303         512 :         s->fat_y_predictor_table[i+(j-1)] |= 1;
     304         512 :         s->fat_c_predictor_table[i+(j-1)] |= 1;
     305             :     }
     306           2 : }
     307             : 
     308             : /* Returns the number of bytes consumed from the bytestream. Returns -1 if
     309             :  * there was an error while decoding the header */
     310         123 : static int truemotion1_decode_header(TrueMotion1Context *s)
     311             : {
     312             :     int i, ret;
     313         123 :     int width_shift = 0;
     314             :     int new_pix_fmt;
     315             :     struct frame_header header;
     316         123 :     uint8_t header_buffer[128] = { 0 };  /* logical maximum size of the header */
     317             :     const uint8_t *sel_vector_table;
     318             : 
     319         123 :     header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
     320         123 :     if (s->buf[0] < 0x10)
     321             :     {
     322           0 :         av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]);
     323           0 :         return AVERROR_INVALIDDATA;
     324             :     }
     325             : 
     326         123 :     if (header.header_size + 1 > s->size) {
     327           0 :         av_log(s->avctx, AV_LOG_ERROR, "Input packet too small.\n");
     328           0 :         return AVERROR_INVALIDDATA;
     329             :     }
     330             : 
     331             :     /* unscramble the header bytes with a XOR operation */
     332        1816 :     for (i = 1; i < header.header_size; i++)
     333        1693 :         header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1];
     334             : 
     335         123 :     header.compression = header_buffer[0];
     336         123 :     header.deltaset = header_buffer[1];
     337         123 :     header.vectable = header_buffer[2];
     338         123 :     header.ysize = AV_RL16(&header_buffer[3]);
     339         123 :     header.xsize = AV_RL16(&header_buffer[5]);
     340         123 :     header.checksum = AV_RL16(&header_buffer[7]);
     341         123 :     header.version = header_buffer[9];
     342         123 :     header.header_type = header_buffer[10];
     343         123 :     header.flags = header_buffer[11];
     344         123 :     header.control = header_buffer[12];
     345             : 
     346             :     /* Version 2 */
     347         123 :     if (header.version >= 2)
     348             :     {
     349         123 :         if (header.header_type > 3)
     350             :         {
     351           0 :             av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type);
     352           0 :             return AVERROR_INVALIDDATA;
     353         123 :         } else if ((header.header_type == 2) || (header.header_type == 3)) {
     354         123 :             s->flags = header.flags;
     355         246 :             if (!(s->flags & FLAG_INTERFRAME))
     356           0 :                 s->flags |= FLAG_KEYFRAME;
     357             :         } else
     358           0 :             s->flags = FLAG_KEYFRAME;
     359             :     } else /* Version 1 */
     360           0 :         s->flags = FLAG_KEYFRAME;
     361             : 
     362         123 :     if (s->flags & FLAG_SPRITE) {
     363           0 :         avpriv_request_sample(s->avctx, "Frame with sprite");
     364             :         /* FIXME header.width, height, xoffset and yoffset aren't initialized */
     365           0 :         return AVERROR_PATCHWELCOME;
     366             :     } else {
     367         123 :         s->w = header.xsize;
     368         123 :         s->h = header.ysize;
     369         123 :         if (header.header_type < 2) {
     370           0 :             if ((s->w < 213) && (s->h >= 176))
     371             :             {
     372           0 :                 s->flags |= FLAG_INTERPOLATED;
     373           0 :                 avpriv_request_sample(s->avctx, "Interpolated frame");
     374             :             }
     375             :         }
     376             :     }
     377             : 
     378         123 :     if (header.compression >= 17) {
     379           0 :         av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression);
     380           0 :         return AVERROR_INVALIDDATA;
     381             :     }
     382             : 
     383         244 :     if ((header.deltaset != s->last_deltaset) ||
     384         121 :         (header.vectable != s->last_vectable))
     385           4 :         select_delta_tables(s, header.deltaset);
     386             : 
     387         123 :     if ((header.compression & 1) && header.header_type)
     388           0 :         sel_vector_table = pc_tbl2;
     389             :     else {
     390         123 :         if (header.vectable > 0 && header.vectable < 4)
     391         123 :             sel_vector_table = tables[header.vectable - 1];
     392             :         else {
     393           0 :             av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable);
     394           0 :             return AVERROR_INVALIDDATA;
     395             :         }
     396             :     }
     397             : 
     398         123 :     if (compression_types[header.compression].algorithm == ALGO_RGB24H) {
     399          17 :         new_pix_fmt = AV_PIX_FMT_0RGB32;
     400          17 :         width_shift = 1;
     401             :     } else
     402         106 :         new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well
     403             : 
     404         123 :     s->w >>= width_shift;
     405         123 :     if (s->w & 1) {
     406           0 :         avpriv_request_sample(s->avctx, "Frame with odd width");
     407           0 :         return AVERROR_PATCHWELCOME;
     408             :     }
     409             : 
     410         245 :     if (s->w != s->avctx->width || s->h != s->avctx->height ||
     411         122 :         new_pix_fmt != s->avctx->pix_fmt) {
     412           2 :         av_frame_unref(s->frame);
     413           2 :         s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
     414           2 :         s->avctx->pix_fmt = new_pix_fmt;
     415             : 
     416           2 :         if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
     417           0 :             return ret;
     418             : 
     419           2 :         ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);
     420             : 
     421           2 :         av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
     422           2 :         if (!s->vert_pred)
     423           0 :             return AVERROR(ENOMEM);
     424             :     }
     425             : 
     426             :     /* There is 1 change bit per 4 pixels, so each change byte represents
     427             :      * 32 pixels; divide width by 4 to obtain the number of change bits and
     428             :      * then round up to the nearest byte. */
     429         123 :     s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3;
     430             : 
     431         123 :     if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable))
     432             :     {
     433           4 :         if (compression_types[header.compression].algorithm == ALGO_RGB24H)
     434           2 :             gen_vector_table24(s, sel_vector_table);
     435             :         else
     436           2 :         if (s->avctx->pix_fmt == AV_PIX_FMT_RGB555)
     437           2 :             gen_vector_table15(s, sel_vector_table);
     438             :         else
     439           0 :             gen_vector_table16(s, sel_vector_table);
     440             :     }
     441             : 
     442             :     /* set up pointers to the other key data chunks */
     443         123 :     s->mb_change_bits = s->buf + header.header_size;
     444         123 :     if (s->flags & FLAG_KEYFRAME) {
     445             :         /* no change bits specified for a keyframe; only index bytes */
     446          25 :         s->index_stream = s->mb_change_bits;
     447             :     } else {
     448             :         /* one change bit per 4x4 block */
     449         196 :         s->index_stream = s->mb_change_bits +
     450          98 :             (s->mb_change_bits_row_size * (s->avctx->height >> 2));
     451             :     }
     452         123 :     s->index_stream_size = s->size - (s->index_stream - s->buf);
     453             : 
     454         123 :     s->last_deltaset = header.deltaset;
     455         123 :     s->last_vectable = header.vectable;
     456         123 :     s->compression = header.compression;
     457         123 :     s->block_width = compression_types[header.compression].block_width;
     458         123 :     s->block_height = compression_types[header.compression].block_height;
     459         123 :     s->block_type = compression_types[header.compression].block_type;
     460             : 
     461         123 :     if (s->avctx->debug & FF_DEBUG_PICT_INFO)
     462           0 :         av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
     463             :             s->last_deltaset, s->last_vectable, s->compression, s->block_width,
     464             :             s->block_height, s->block_type,
     465           0 :             s->flags & FLAG_KEYFRAME ? " KEY" : "",
     466           0 :             s->flags & FLAG_INTERFRAME ? " INTER" : "",
     467           0 :             s->flags & FLAG_SPRITE ? " SPRITE" : "",
     468           0 :             s->flags & FLAG_INTERPOLATED ? " INTERPOL" : "");
     469             : 
     470         123 :     return header.header_size;
     471             : }
     472             : 
     473           4 : static av_cold int truemotion1_decode_init(AVCodecContext *avctx)
     474             : {
     475           4 :     TrueMotion1Context *s = avctx->priv_data;
     476             : 
     477           4 :     s->avctx = avctx;
     478             : 
     479             :     // FIXME: it may change ?
     480             : //    if (avctx->bits_per_sample == 24)
     481             : //        avctx->pix_fmt = AV_PIX_FMT_RGB24;
     482             : //    else
     483             : //        avctx->pix_fmt = AV_PIX_FMT_RGB555;
     484             : 
     485           4 :     s->frame = av_frame_alloc();
     486           4 :     if (!s->frame)
     487           0 :         return AVERROR(ENOMEM);
     488             : 
     489             :     /* there is a vertical predictor for each pixel in a line; each vertical
     490             :      * predictor is 0 to start with */
     491           4 :     av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
     492           4 :     if (!s->vert_pred) {
     493           0 :         av_frame_free(&s->frame);
     494           0 :         return AVERROR(ENOMEM);
     495             :     }
     496             : 
     497           4 :     return 0;
     498             : }
     499             : 
     500             : /*
     501             : Block decoding order:
     502             : 
     503             : dxi: Y-Y
     504             : dxic: Y-C-Y
     505             : dxic2: Y-C-Y-C
     506             : 
     507             : hres,vres,i,i%vres (0 < i < 4)
     508             : 2x2 0: 0 dxic2
     509             : 2x2 1: 1 dxi
     510             : 2x2 2: 0 dxic2
     511             : 2x2 3: 1 dxi
     512             : 2x4 0: 0 dxic2
     513             : 2x4 1: 1 dxi
     514             : 2x4 2: 2 dxi
     515             : 2x4 3: 3 dxi
     516             : 4x2 0: 0 dxic
     517             : 4x2 1: 1 dxi
     518             : 4x2 2: 0 dxic
     519             : 4x2 3: 1 dxi
     520             : 4x4 0: 0 dxic
     521             : 4x4 1: 1 dxi
     522             : 4x4 2: 2 dxi
     523             : 4x4 3: 3 dxi
     524             : */
     525             : 
     526             : #define GET_NEXT_INDEX() \
     527             : {\
     528             :     if (index_stream_index >= s->index_stream_size) { \
     529             :         av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
     530             :         return; \
     531             :     } \
     532             :     index = s->index_stream[index_stream_index++] * 4; \
     533             : }
     534             : 
     535             : #define INC_INDEX                                                   \
     536             : do {                                                                \
     537             :     if (index >= 1023) {                                            \
     538             :         av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n");   \
     539             :         return;                                                     \
     540             :     }                                                               \
     541             :     index++;                                                        \
     542             : } while (0)
     543             : 
     544             : #define APPLY_C_PREDICTOR() \
     545             :     predictor_pair = s->c_predictor_table[index]; \
     546             :     horiz_pred += (predictor_pair >> 1); \
     547             :     if (predictor_pair & 1) { \
     548             :         GET_NEXT_INDEX() \
     549             :         if (!index) { \
     550             :             GET_NEXT_INDEX() \
     551             :             predictor_pair = s->c_predictor_table[index]; \
     552             :             horiz_pred += ((predictor_pair >> 1) * 5); \
     553             :             if (predictor_pair & 1) \
     554             :                 GET_NEXT_INDEX() \
     555             :             else \
     556             :                 INC_INDEX; \
     557             :         } \
     558             :     } else \
     559             :         INC_INDEX;
     560             : 
     561             : #define APPLY_C_PREDICTOR_24() \
     562             :     predictor_pair = s->c_predictor_table[index]; \
     563             :     horiz_pred += (predictor_pair >> 1); \
     564             :     if (predictor_pair & 1) { \
     565             :         GET_NEXT_INDEX() \
     566             :         if (!index) { \
     567             :             GET_NEXT_INDEX() \
     568             :             predictor_pair = s->fat_c_predictor_table[index]; \
     569             :             horiz_pred += (predictor_pair >> 1); \
     570             :             if (predictor_pair & 1) \
     571             :                 GET_NEXT_INDEX() \
     572             :             else \
     573             :                 INC_INDEX; \
     574             :         } \
     575             :     } else \
     576             :         INC_INDEX;
     577             : 
     578             : 
     579             : #define APPLY_Y_PREDICTOR() \
     580             :     predictor_pair = s->y_predictor_table[index]; \
     581             :     horiz_pred += (predictor_pair >> 1); \
     582             :     if (predictor_pair & 1) { \
     583             :         GET_NEXT_INDEX() \
     584             :         if (!index) { \
     585             :             GET_NEXT_INDEX() \
     586             :             predictor_pair = s->y_predictor_table[index]; \
     587             :             horiz_pred += ((predictor_pair >> 1) * 5); \
     588             :             if (predictor_pair & 1) \
     589             :                 GET_NEXT_INDEX() \
     590             :             else \
     591             :                 INC_INDEX; \
     592             :         } \
     593             :     } else \
     594             :         INC_INDEX;
     595             : 
     596             : #define APPLY_Y_PREDICTOR_24() \
     597             :     predictor_pair = s->y_predictor_table[index]; \
     598             :     horiz_pred += (predictor_pair >> 1); \
     599             :     if (predictor_pair & 1) { \
     600             :         GET_NEXT_INDEX() \
     601             :         if (!index) { \
     602             :             GET_NEXT_INDEX() \
     603             :             predictor_pair = s->fat_y_predictor_table[index]; \
     604             :             horiz_pred += (predictor_pair >> 1); \
     605             :             if (predictor_pair & 1) \
     606             :                 GET_NEXT_INDEX() \
     607             :             else \
     608             :                 INC_INDEX; \
     609             :         } \
     610             :     } else \
     611             :         INC_INDEX;
     612             : 
     613             : #define OUTPUT_PIXEL_PAIR() \
     614             :     *current_pixel_pair = *vert_pred + horiz_pred; \
     615             :     *vert_pred++ = *current_pixel_pair++;
     616             : 
     617          97 : static void truemotion1_decode_16bit(TrueMotion1Context *s)
     618             : {
     619             :     int y;
     620             :     int pixels_left;  /* remaining pixels on this line */
     621             :     unsigned int predictor_pair;
     622             :     unsigned int horiz_pred;
     623             :     unsigned int *vert_pred;
     624             :     unsigned int *current_pixel_pair;
     625          97 :     unsigned char *current_line = s->frame->data[0];
     626          97 :     int keyframe = s->flags & FLAG_KEYFRAME;
     627             : 
     628             :     /* these variables are for managing the stream of macroblock change bits */
     629          97 :     const unsigned char *mb_change_bits = s->mb_change_bits;
     630             :     unsigned char mb_change_byte;
     631             :     unsigned char mb_change_byte_mask;
     632             :     int mb_change_index;
     633             : 
     634             :     /* these variables are for managing the main index stream */
     635          97 :     int index_stream_index = 0;  /* yes, the index into the index stream */
     636             :     int index;
     637             : 
     638             :     /* clean out the line buffer */
     639          97 :     memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
     640             : 
     641          97 :     GET_NEXT_INDEX();
     642             : 
     643       16393 :     for (y = 0; y < s->avctx->height; y++) {
     644             : 
     645             :         /* re-init variables for the next line iteration */
     646       16296 :         horiz_pred = 0;
     647       16296 :         current_pixel_pair = (unsigned int *)current_line;
     648       16296 :         vert_pred = s->vert_pred;
     649       16296 :         mb_change_index = 0;
     650       16296 :         if (!keyframe)
     651       12600 :             mb_change_byte = mb_change_bits[mb_change_index++];
     652       16296 :         mb_change_byte_mask = 0x01;
     653       16296 :         pixels_left = s->avctx->width;
     654             : 
     655     1336272 :         while (pixels_left > 0) {
     656             : 
     657     1303680 :             if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
     658             : 
     659      706460 :                 switch (y & 3) {
     660      176615 :                 case 0:
     661             :                     /* if macroblock width is 2, apply C-Y-C-Y; else
     662             :                      * apply C-Y-Y */
     663      176615 :                     if (s->block_width == 2) {
     664           0 :                         APPLY_C_PREDICTOR();
     665           0 :                         APPLY_Y_PREDICTOR();
     666           0 :                         OUTPUT_PIXEL_PAIR();
     667           0 :                         APPLY_C_PREDICTOR();
     668           0 :                         APPLY_Y_PREDICTOR();
     669           0 :                         OUTPUT_PIXEL_PAIR();
     670             :                     } else {
     671      176615 :                         APPLY_C_PREDICTOR();
     672      176615 :                         APPLY_Y_PREDICTOR();
     673      176615 :                         OUTPUT_PIXEL_PAIR();
     674      176615 :                         APPLY_Y_PREDICTOR();
     675      176615 :                         OUTPUT_PIXEL_PAIR();
     676             :                     }
     677      176615 :                     break;
     678             : 
     679      353230 :                 case 1:
     680             :                 case 3:
     681             :                     /* always apply 2 Y predictors on these iterations */
     682      353230 :                     APPLY_Y_PREDICTOR();
     683      353230 :                     OUTPUT_PIXEL_PAIR();
     684      353230 :                     APPLY_Y_PREDICTOR();
     685      353230 :                     OUTPUT_PIXEL_PAIR();
     686      353230 :                     break;
     687             : 
     688      176615 :                 case 2:
     689             :                     /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
     690             :                      * depending on the macroblock type */
     691      176615 :                     if (s->block_type == BLOCK_2x2) {
     692           0 :                         APPLY_C_PREDICTOR();
     693           0 :                         APPLY_Y_PREDICTOR();
     694           0 :                         OUTPUT_PIXEL_PAIR();
     695           0 :                         APPLY_C_PREDICTOR();
     696           0 :                         APPLY_Y_PREDICTOR();
     697           0 :                         OUTPUT_PIXEL_PAIR();
     698      176615 :                     } else if (s->block_type == BLOCK_4x2) {
     699           0 :                         APPLY_C_PREDICTOR();
     700           0 :                         APPLY_Y_PREDICTOR();
     701           0 :                         OUTPUT_PIXEL_PAIR();
     702           0 :                         APPLY_Y_PREDICTOR();
     703           0 :                         OUTPUT_PIXEL_PAIR();
     704             :                     } else {
     705      176615 :                         APPLY_Y_PREDICTOR();
     706      176615 :                         OUTPUT_PIXEL_PAIR();
     707      176615 :                         APPLY_Y_PREDICTOR();
     708      176615 :                         OUTPUT_PIXEL_PAIR();
     709             :                     }
     710      176615 :                     break;
     711             :                 }
     712             : 
     713      706460 :             } else {
     714             : 
     715             :                 /* skip (copy) four pixels, but reassign the horizontal
     716             :                  * predictor */
     717      597220 :                 *vert_pred++ = *current_pixel_pair++;
     718      597220 :                 horiz_pred = *current_pixel_pair - *vert_pred;
     719      597220 :                 *vert_pred++ = *current_pixel_pair++;
     720             : 
     721             :             }
     722             : 
     723     1303680 :             if (!keyframe) {
     724     1008000 :                 mb_change_byte_mask <<= 1;
     725             : 
     726             :                 /* next byte */
     727     1008000 :                 if (!mb_change_byte_mask) {
     728      126000 :                     mb_change_byte = mb_change_bits[mb_change_index++];
     729      126000 :                     mb_change_byte_mask = 0x01;
     730             :                 }
     731             :             }
     732             : 
     733     1303680 :             pixels_left -= 4;
     734             :         }
     735             : 
     736             :         /* next change row */
     737       16296 :         if (((y + 1) & 3) == 0)
     738        4074 :             mb_change_bits += s->mb_change_bits_row_size;
     739             : 
     740       16296 :         current_line += s->frame->linesize[0];
     741             :     }
     742             : }
     743             : 
     744          17 : static void truemotion1_decode_24bit(TrueMotion1Context *s)
     745             : {
     746             :     int y;
     747             :     int pixels_left;  /* remaining pixels on this line */
     748             :     unsigned int predictor_pair;
     749             :     unsigned int horiz_pred;
     750             :     unsigned int *vert_pred;
     751             :     unsigned int *current_pixel_pair;
     752          17 :     unsigned char *current_line = s->frame->data[0];
     753          17 :     int keyframe = s->flags & FLAG_KEYFRAME;
     754             : 
     755             :     /* these variables are for managing the stream of macroblock change bits */
     756          17 :     const unsigned char *mb_change_bits = s->mb_change_bits;
     757             :     unsigned char mb_change_byte;
     758             :     unsigned char mb_change_byte_mask;
     759             :     int mb_change_index;
     760             : 
     761             :     /* these variables are for managing the main index stream */
     762          17 :     int index_stream_index = 0;  /* yes, the index into the index stream */
     763             :     int index;
     764             : 
     765             :     /* clean out the line buffer */
     766          17 :     memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
     767             : 
     768          17 :     GET_NEXT_INDEX();
     769             : 
     770        2707 :     for (y = 0; y < s->avctx->height; y++) {
     771             : 
     772             :         /* re-init variables for the next line iteration */
     773        2691 :         horiz_pred = 0;
     774        2691 :         current_pixel_pair = (unsigned int *)current_line;
     775        2691 :         vert_pred = s->vert_pred;
     776        2691 :         mb_change_index = 0;
     777        2691 :         mb_change_byte = mb_change_bits[mb_change_index++];
     778        2691 :         mb_change_byte_mask = 0x01;
     779        2691 :         pixels_left = s->avctx->width;
     780             : 
     781      199086 :         while (pixels_left > 0) {
     782             : 
     783      193705 :             if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
     784             : 
     785      153710 :                 switch (y & 3) {
     786       38453 :                 case 0:
     787             :                     /* if macroblock width is 2, apply C-Y-C-Y; else
     788             :                      * apply C-Y-Y */
     789       38453 :                     if (s->block_width == 2) {
     790       38453 :                         APPLY_C_PREDICTOR_24();
     791       38453 :                         APPLY_Y_PREDICTOR_24();
     792       38453 :                         OUTPUT_PIXEL_PAIR();
     793       38453 :                         APPLY_C_PREDICTOR_24();
     794       38453 :                         APPLY_Y_PREDICTOR_24();
     795       38453 :                         OUTPUT_PIXEL_PAIR();
     796             :                     } else {
     797           0 :                         APPLY_C_PREDICTOR_24();
     798           0 :                         APPLY_Y_PREDICTOR_24();
     799           0 :                         OUTPUT_PIXEL_PAIR();
     800           0 :                         APPLY_Y_PREDICTOR_24();
     801           0 :                         OUTPUT_PIXEL_PAIR();
     802             :                     }
     803       38453 :                     break;
     804             : 
     805       76846 :                 case 1:
     806             :                 case 3:
     807             :                     /* always apply 2 Y predictors on these iterations */
     808       76846 :                     APPLY_Y_PREDICTOR_24();
     809       76846 :                     OUTPUT_PIXEL_PAIR();
     810       76846 :                     APPLY_Y_PREDICTOR_24();
     811       76846 :                     OUTPUT_PIXEL_PAIR();
     812       76846 :                     break;
     813             : 
     814       38411 :                 case 2:
     815             :                     /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
     816             :                      * depending on the macroblock type */
     817       38411 :                     if (s->block_type == BLOCK_2x2) {
     818       38411 :                         APPLY_C_PREDICTOR_24();
     819       38411 :                         APPLY_Y_PREDICTOR_24();
     820       38411 :                         OUTPUT_PIXEL_PAIR();
     821       38411 :                         APPLY_C_PREDICTOR_24();
     822       38411 :                         APPLY_Y_PREDICTOR_24();
     823       38410 :                         OUTPUT_PIXEL_PAIR();
     824           0 :                     } else if (s->block_type == BLOCK_4x2) {
     825           0 :                         APPLY_C_PREDICTOR_24();
     826           0 :                         APPLY_Y_PREDICTOR_24();
     827           0 :                         OUTPUT_PIXEL_PAIR();
     828           0 :                         APPLY_Y_PREDICTOR_24();
     829           0 :                         OUTPUT_PIXEL_PAIR();
     830             :                     } else {
     831           0 :                         APPLY_Y_PREDICTOR_24();
     832           0 :                         OUTPUT_PIXEL_PAIR();
     833           0 :                         APPLY_Y_PREDICTOR_24();
     834           0 :                         OUTPUT_PIXEL_PAIR();
     835             :                     }
     836       38410 :                     break;
     837             :                 }
     838             : 
     839      153709 :             } else {
     840             : 
     841             :                 /* skip (copy) four pixels, but reassign the horizontal
     842             :                  * predictor */
     843       39995 :                 *vert_pred++ = *current_pixel_pair++;
     844       39995 :                 horiz_pred = *current_pixel_pair - *vert_pred;
     845       39995 :                 *vert_pred++ = *current_pixel_pair++;
     846             : 
     847             :             }
     848             : 
     849      193704 :             if (!keyframe) {
     850      159144 :                 mb_change_byte_mask <<= 1;
     851             : 
     852             :                 /* next byte */
     853      159144 :                 if (!mb_change_byte_mask) {
     854       19893 :                     mb_change_byte = mb_change_bits[mb_change_index++];
     855       19893 :                     mb_change_byte_mask = 0x01;
     856             :                 }
     857             :             }
     858             : 
     859      193704 :             pixels_left -= 2;
     860             :         }
     861             : 
     862             :         /* next change row */
     863        2690 :         if (((y + 1) & 3) == 0)
     864         672 :             mb_change_bits += s->mb_change_bits_row_size;
     865             : 
     866        2690 :         current_line += s->frame->linesize[0];
     867             :     }
     868             : }
     869             : 
     870             : 
     871         123 : static int truemotion1_decode_frame(AVCodecContext *avctx,
     872             :                                     void *data, int *got_frame,
     873             :                                     AVPacket *avpkt)
     874             : {
     875         123 :     const uint8_t *buf = avpkt->data;
     876         123 :     int ret, buf_size = avpkt->size;
     877         123 :     TrueMotion1Context *s = avctx->priv_data;
     878             : 
     879         123 :     s->buf = buf;
     880         123 :     s->size = buf_size;
     881             : 
     882         123 :     if ((ret = truemotion1_decode_header(s)) < 0)
     883           0 :         return ret;
     884             : 
     885         123 :     if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
     886           0 :         return ret;
     887             : 
     888         123 :     if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
     889          17 :         truemotion1_decode_24bit(s);
     890         106 :     } else if (compression_types[s->compression].algorithm != ALGO_NOP) {
     891          97 :         truemotion1_decode_16bit(s);
     892             :     }
     893             : 
     894         123 :     if ((ret = av_frame_ref(data, s->frame)) < 0)
     895           0 :         return ret;
     896             : 
     897         123 :     *got_frame      = 1;
     898             : 
     899             :     /* report that the buffer was completely consumed */
     900         123 :     return buf_size;
     901             : }
     902             : 
     903           4 : static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
     904             : {
     905           4 :     TrueMotion1Context *s = avctx->priv_data;
     906             : 
     907           4 :     av_frame_free(&s->frame);
     908           4 :     av_freep(&s->vert_pred);
     909             : 
     910           4 :     return 0;
     911             : }
     912             : 
     913             : AVCodec ff_truemotion1_decoder = {
     914             :     .name           = "truemotion1",
     915             :     .long_name      = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),
     916             :     .type           = AVMEDIA_TYPE_VIDEO,
     917             :     .id             = AV_CODEC_ID_TRUEMOTION1,
     918             :     .priv_data_size = sizeof(TrueMotion1Context),
     919             :     .init           = truemotion1_decode_init,
     920             :     .close          = truemotion1_decode_end,
     921             :     .decode         = truemotion1_decode_frame,
     922             :     .capabilities   = AV_CODEC_CAP_DR1,
     923             : };

Generated by: LCOV version 1.13