LCOV - code coverage report
Current view: top level - libavcodec - escape124.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 143 165 86.7 %
Date: 2017-12-16 13:57:32 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Escape 124 Video Decoder
       3             :  * Copyright (C) 2008 Eli Friedman (eli.friedman@gmail.com)
       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             : #define BITSTREAM_READER_LE
      23             : #include "avcodec.h"
      24             : #include "get_bits.h"
      25             : #include "internal.h"
      26             : 
      27             : typedef union MacroBlock {
      28             :     uint16_t pixels[4];
      29             :     uint32_t pixels32[2];
      30             : } MacroBlock;
      31             : 
      32             : typedef union SuperBlock {
      33             :     uint16_t pixels[64];
      34             :     uint32_t pixels32[32];
      35             : } SuperBlock;
      36             : 
      37             : typedef struct CodeBook {
      38             :     unsigned depth;
      39             :     unsigned size;
      40             :     MacroBlock* blocks;
      41             : } CodeBook;
      42             : 
      43             : typedef struct Escape124Context {
      44             :     AVFrame *frame;
      45             : 
      46             :     unsigned num_superblocks;
      47             : 
      48             :     CodeBook codebooks[3];
      49             : } Escape124Context;
      50             : 
      51             : /**
      52             :  * Initialize the decoder
      53             :  * @param avctx decoder context
      54             :  * @return 0 success, negative on error
      55             :  */
      56           2 : static av_cold int escape124_decode_init(AVCodecContext *avctx)
      57             : {
      58           2 :     Escape124Context *s = avctx->priv_data;
      59             : 
      60           2 :     avctx->pix_fmt = AV_PIX_FMT_RGB555;
      61             : 
      62           4 :     s->num_superblocks = ((unsigned)avctx->width / 8) *
      63           2 :                          ((unsigned)avctx->height / 8);
      64             : 
      65           2 :     s->frame = av_frame_alloc();
      66           2 :     if (!s->frame)
      67           0 :         return AVERROR(ENOMEM);
      68             : 
      69           2 :     return 0;
      70             : }
      71             : 
      72           2 : static av_cold int escape124_decode_close(AVCodecContext *avctx)
      73             : {
      74             :     unsigned i;
      75           2 :     Escape124Context *s = avctx->priv_data;
      76             : 
      77           8 :     for (i = 0; i < 3; i++)
      78           6 :         av_freep(&s->codebooks[i].blocks);
      79             : 
      80           2 :     av_frame_free(&s->frame);
      81             : 
      82           2 :     return 0;
      83             : }
      84             : 
      85          12 : static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth,
      86             :                                  unsigned size)
      87             : {
      88             :     unsigned i, j;
      89          12 :     CodeBook cb = { 0 };
      90             : 
      91          12 :     if (size >= INT_MAX / 34 || get_bits_left(gb) < size * 34)
      92           0 :         return cb;
      93             : 
      94          12 :     if (size >= INT_MAX / sizeof(MacroBlock))
      95           0 :         return cb;
      96          12 :     cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1);
      97          12 :     if (!cb.blocks)
      98           0 :         return cb;
      99             : 
     100          12 :     cb.depth = depth;
     101          12 :     cb.size = size;
     102       21255 :     for (i = 0; i < size; i++) {
     103       21243 :         unsigned mask_bits = get_bits(gb, 4);
     104       21243 :         unsigned color0 = get_bits(gb, 15);
     105       21243 :         unsigned color1 = get_bits(gb, 15);
     106             : 
     107      106215 :         for (j = 0; j < 4; j++) {
     108       84972 :             if (mask_bits & (1 << j))
     109       40481 :                 cb.blocks[i].pixels[j] = color1;
     110             :             else
     111       44491 :                 cb.blocks[i].pixels[j] = color0;
     112             :         }
     113             :     }
     114          12 :     return cb;
     115             : }
     116             : 
     117       69095 : static unsigned decode_skip_count(GetBitContext* gb)
     118             : {
     119             :     unsigned value;
     120             :     // This function reads a maximum of 23 bits,
     121             :     // which is within the padding space
     122       69095 :     if (get_bits_left(gb) < 1)
     123           0 :         return -1;
     124       69095 :     value = get_bits1(gb);
     125       69095 :     if (!value)
     126       59778 :         return value;
     127             : 
     128        9317 :     value += get_bits(gb, 3);
     129        9317 :     if (value != (1 + ((1 << 3) - 1)))
     130        8204 :         return value;
     131             : 
     132        1113 :     value += get_bits(gb, 7);
     133        1113 :     if (value != (1 + ((1 << 3) - 1)) + ((1 << 7) - 1))
     134        1086 :         return value;
     135             : 
     136          27 :     return value + get_bits(gb, 12);
     137             : }
     138             : 
     139      339543 : static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb,
     140             :                                     int* codebook_index, int superblock_index)
     141             : {
     142             :     // This function reads a maximum of 22 bits; the callers
     143             :     // guard this function appropriately
     144             :     unsigned block_index, depth;
     145      339543 :     int value = get_bits1(gb);
     146      339543 :     if (value) {
     147             :         static const int8_t transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} };
     148      131966 :         value = get_bits1(gb);
     149      131966 :         *codebook_index = transitions[*codebook_index][value];
     150             :     }
     151             : 
     152      339543 :     depth = s->codebooks[*codebook_index].depth;
     153             : 
     154             :     // depth = 0 means that this shouldn't read any bits;
     155             :     // in theory, this is the same as get_bits(gb, 0), but
     156             :     // that doesn't actually work.
     157      339543 :     block_index = get_bitsz(gb, depth);
     158             : 
     159      339543 :     if (*codebook_index == 1) {
     160       33088 :         block_index += superblock_index << s->codebooks[1].depth;
     161             :     }
     162             : 
     163             :     // This condition can occur with invalid bitstreams and
     164             :     // *codebook_index == 2
     165      339543 :     if (block_index >= s->codebooks[*codebook_index].size)
     166           0 :         return (MacroBlock) { { 0 } };
     167             : 
     168      339543 :     return s->codebooks[*codebook_index].blocks[block_index];
     169             : }
     170             : 
     171      492736 : static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) {
     172             :    // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2
     173      492736 :    uint32_t *dst = sb->pixels32 + index + (index & -4);
     174             : 
     175             :    // This technically violates C99 aliasing rules, but it should be safe.
     176      492736 :    dst[0] = mb.pixels32[0];
     177      492736 :    dst[4] = mb.pixels32[1];
     178      492736 : }
     179             : 
     180      189026 : static void copy_superblock(uint16_t* dest, unsigned dest_stride,
     181             :                             uint16_t* src, unsigned src_stride)
     182             : {
     183             :     unsigned y;
     184      189026 :     if (src)
     185     1690434 :         for (y = 0; y < 8; y++)
     186     1502608 :             memcpy(dest + y * dest_stride, src + y * src_stride,
     187             :                    sizeof(uint16_t) * 8);
     188             :     else
     189       10800 :         for (y = 0; y < 8; y++)
     190        9600 :             memset(dest + y * dest_stride, 0, sizeof(uint16_t) * 8);
     191      189026 : }
     192             : 
     193             : static const uint16_t mask_matrix[] = {0x1,   0x2,   0x10,   0x20,
     194             :                                        0x4,   0x8,   0x40,   0x80,
     195             :                                        0x100, 0x200, 0x1000, 0x2000,
     196             :                                        0x400, 0x800, 0x4000, 0x8000};
     197             : 
     198         100 : static int escape124_decode_frame(AVCodecContext *avctx,
     199             :                                   void *data, int *got_frame,
     200             :                                   AVPacket *avpkt)
     201             : {
     202         100 :     int buf_size = avpkt->size;
     203         100 :     Escape124Context *s = avctx->priv_data;
     204         100 :     AVFrame *frame = data;
     205             : 
     206             :     GetBitContext gb;
     207             :     unsigned frame_flags, frame_size;
     208             :     unsigned i;
     209             : 
     210         100 :     unsigned superblock_index, cb_index = 1,
     211         100 :              superblock_col_index = 0,
     212         100 :              superblocks_per_row = avctx->width / 8, skip = -1;
     213             : 
     214             :     uint16_t* old_frame_data, *new_frame_data;
     215             :     unsigned old_stride, new_stride;
     216             : 
     217             :     int ret;
     218             : 
     219         100 :     if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
     220           0 :         return ret;
     221             : 
     222             :     // This call also guards the potential depth reads for the
     223             :     // codebook unpacking.
     224         100 :     if (get_bits_left(&gb) < 64)
     225           0 :         return -1;
     226             : 
     227         100 :     frame_flags = get_bits_long(&gb, 32);
     228         100 :     frame_size  = get_bits_long(&gb, 32);
     229             : 
     230             :     // Leave last frame unchanged
     231             :     // FIXME: Is this necessary?  I haven't seen it in any real samples
     232         100 :     if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) {
     233           0 :         if (!s->frame->data[0])
     234           0 :             return AVERROR_INVALIDDATA;
     235             : 
     236           0 :         av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n");
     237             : 
     238           0 :         *got_frame = 1;
     239           0 :         if ((ret = av_frame_ref(frame, s->frame)) < 0)
     240           0 :             return ret;
     241             : 
     242           0 :         return frame_size;
     243             :     }
     244             : 
     245         400 :     for (i = 0; i < 3; i++) {
     246         300 :         if (frame_flags & (1 << (17 + i))) {
     247             :             unsigned cb_depth, cb_size;
     248          12 :             if (i == 2) {
     249             :                 // This codebook can be cut off at places other than
     250             :                 // powers of 2, leaving some of the entries undefined.
     251           4 :                 cb_size = get_bits_long(&gb, 20);
     252           4 :                 if (!cb_size) {
     253           0 :                     av_log(avctx, AV_LOG_ERROR, "Invalid codebook size 0.\n");
     254           0 :                     return AVERROR_INVALIDDATA;
     255             :                 }
     256           4 :                 cb_depth = av_log2(cb_size - 1) + 1;
     257             :             } else {
     258           8 :                 cb_depth = get_bits(&gb, 4);
     259           8 :                 if (i == 0) {
     260             :                     // This is the most basic codebook: pow(2,depth) entries
     261             :                     // for a depth-length key
     262           4 :                     cb_size = 1 << cb_depth;
     263             :                 } else {
     264             :                     // This codebook varies per superblock
     265             :                     // FIXME: I don't think this handles integer overflow
     266             :                     // properly
     267           4 :                     cb_size = s->num_superblocks << cb_depth;
     268             :                 }
     269             :             }
     270          12 :             if (s->num_superblocks >= INT_MAX >> cb_depth) {
     271           0 :                 av_log(avctx, AV_LOG_ERROR, "Depth or num_superblocks are too large\n");
     272           0 :                 return AVERROR_INVALIDDATA;
     273             :             }
     274             : 
     275          12 :             av_freep(&s->codebooks[i].blocks);
     276          12 :             s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size);
     277          12 :             if (!s->codebooks[i].blocks)
     278           0 :                 return -1;
     279             :         }
     280             :     }
     281             : 
     282         100 :     if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
     283           0 :         return ret;
     284             : 
     285         100 :     new_frame_data = (uint16_t*)frame->data[0];
     286         100 :     new_stride = frame->linesize[0] / 2;
     287         100 :     old_frame_data = (uint16_t*)s->frame->data[0];
     288         100 :     old_stride = s->frame->linesize[0] / 2;
     289             : 
     290      120200 :     for (superblock_index = 0; superblock_index < s->num_superblocks;
     291      120000 :          superblock_index++) {
     292             :         MacroBlock mb;
     293             :         SuperBlock sb;
     294      120000 :         unsigned multi_mask = 0;
     295             : 
     296      120000 :         if (skip == -1) {
     297             :             // Note that this call will make us skip the rest of the blocks
     298             :             // if the frame prematurely ends
     299       69095 :             skip = decode_skip_count(&gb);
     300             :         }
     301             : 
     302      120000 :         if (skip) {
     303       50974 :             copy_superblock(new_frame_data, new_stride,
     304             :                             old_frame_data, old_stride);
     305             :         } else {
     306       69026 :             copy_superblock(sb.pixels, 8,
     307             :                             old_frame_data, old_stride);
     308             : 
     309      169956 :             while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) {
     310             :                 unsigned mask;
     311       31904 :                 mb = decode_macroblock(s, &gb, &cb_index, superblock_index);
     312       31904 :                 mask = get_bits(&gb, 16);
     313       31904 :                 multi_mask |= mask;
     314      542368 :                 for (i = 0; i < 16; i++) {
     315      510464 :                     if (mask & mask_matrix[i]) {
     316      185097 :                         insert_mb_into_sb(&sb, mb, i);
     317             :                     }
     318             :                 }
     319             :             }
     320             : 
     321       69026 :             if (!get_bits1(&gb)) {
     322       29605 :                 unsigned inv_mask = get_bits(&gb, 4);
     323      148025 :                 for (i = 0; i < 4; i++) {
     324      118420 :                     if (inv_mask & (1 << i)) {
     325       45362 :                         multi_mask ^= 0xF << i*4;
     326             :                     } else {
     327       73058 :                         multi_mask ^= get_bits(&gb, 4) << i*4;
     328             :                     }
     329             :                 }
     330             : 
     331      503285 :                 for (i = 0; i < 16; i++) {
     332      473680 :                     if (multi_mask & mask_matrix[i]) {
     333      251422 :                         mb = decode_macroblock(s, &gb, &cb_index,
     334             :                                                superblock_index);
     335      251422 :                         insert_mb_into_sb(&sb, mb, i);
     336             :                     }
     337             :                 }
     338       39421 :             } else if (frame_flags & (1 << 16)) {
     339      135059 :                 while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) {
     340       56217 :                     mb = decode_macroblock(s, &gb, &cb_index, superblock_index);
     341       56217 :                     insert_mb_into_sb(&sb, mb, get_bits(&gb, 4));
     342             :                 }
     343             :             }
     344             : 
     345       69026 :             copy_superblock(new_frame_data, new_stride, sb.pixels, 8);
     346             :         }
     347             : 
     348      120000 :         superblock_col_index++;
     349      120000 :         new_frame_data += 8;
     350      120000 :         if (old_frame_data)
     351      118800 :             old_frame_data += 8;
     352      120000 :         if (superblock_col_index == superblocks_per_row) {
     353        3000 :             new_frame_data += new_stride * 8 - superblocks_per_row * 8;
     354        3000 :             if (old_frame_data)
     355        2970 :                 old_frame_data += old_stride * 8 - superblocks_per_row * 8;
     356        3000 :             superblock_col_index = 0;
     357             :         }
     358      120000 :         skip--;
     359             :     }
     360             : 
     361         100 :     av_log(avctx, AV_LOG_DEBUG,
     362             :            "Escape sizes: %i, %i, %i\n",
     363         100 :            frame_size, buf_size, get_bits_count(&gb) / 8);
     364             : 
     365         100 :     av_frame_unref(s->frame);
     366         100 :     if ((ret = av_frame_ref(s->frame, frame)) < 0)
     367           0 :         return ret;
     368             : 
     369         100 :     *got_frame = 1;
     370             : 
     371         100 :     return frame_size;
     372             : }
     373             : 
     374             : 
     375             : AVCodec ff_escape124_decoder = {
     376             :     .name           = "escape124",
     377             :     .long_name      = NULL_IF_CONFIG_SMALL("Escape 124"),
     378             :     .type           = AVMEDIA_TYPE_VIDEO,
     379             :     .id             = AV_CODEC_ID_ESCAPE124,
     380             :     .priv_data_size = sizeof(Escape124Context),
     381             :     .init           = escape124_decode_init,
     382             :     .close          = escape124_decode_close,
     383             :     .decode         = escape124_decode_frame,
     384             :     .capabilities   = AV_CODEC_CAP_DR1,
     385             : };

Generated by: LCOV version 1.13