LCOV - code coverage report
Current view: top level - libavcodec - tscc2.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 153 192 79.7 %
Date: 2017-12-18 06:23:41 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :  * TechSmith Screen Codec 2 (aka Dora) decoder
       3             :  * Copyright (c) 2012 Konstantin Shishkov
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /**
      23             :  * @file
      24             :  * TechSmith Screen Codec 2 decoder
      25             :  */
      26             : 
      27             : #include <inttypes.h>
      28             : 
      29             : #define BITSTREAM_READER_LE
      30             : #include "avcodec.h"
      31             : #include "bytestream.h"
      32             : #include "get_bits.h"
      33             : #include "internal.h"
      34             : #include "mathops.h"
      35             : #include "tscc2data.h"
      36             : 
      37             : typedef struct TSCC2Context {
      38             :     AVCodecContext *avctx;
      39             :     AVFrame       *pic;
      40             :     int            mb_width, mb_height;
      41             :     uint8_t        *slice_quants;
      42             :     int            quant[2];
      43             :     int            q[2][3];
      44             :     GetBitContext  gb;
      45             : 
      46             :     VLC            dc_vlc, nc_vlc[NUM_VLC_SETS], ac_vlc[NUM_VLC_SETS];
      47             :     int            block[16];
      48             : } TSCC2Context;
      49             : 
      50           4 : static av_cold void free_vlcs(TSCC2Context *c)
      51             : {
      52             :     int i;
      53             : 
      54           4 :     ff_free_vlc(&c->dc_vlc);
      55          56 :     for (i = 0; i < NUM_VLC_SETS; i++) {
      56          52 :         ff_free_vlc(c->nc_vlc + i);
      57          52 :         ff_free_vlc(c->ac_vlc + i);
      58             :     }
      59           4 : }
      60             : 
      61           4 : static av_cold int init_vlcs(TSCC2Context *c)
      62             : {
      63             :     int i, ret;
      64             : 
      65           4 :     ret = ff_init_vlc_sparse(&c->dc_vlc, 9, DC_VLC_COUNT,
      66             :                              tscc2_dc_vlc_bits,  1, 1,
      67             :                              tscc2_dc_vlc_codes, 2, 2,
      68             :                              tscc2_dc_vlc_syms,  2, 2, INIT_VLC_LE);
      69           4 :     if (ret)
      70           0 :         return ret;
      71             : 
      72          56 :     for (i = 0; i < NUM_VLC_SETS; i++) {
      73          52 :         ret = ff_init_vlc_sparse(c->nc_vlc + i, 9, 16,
      74          52 :                                  tscc2_nc_vlc_bits[i],  1, 1,
      75          52 :                                  tscc2_nc_vlc_codes[i], 2, 2,
      76             :                                  tscc2_nc_vlc_syms,     1, 1, INIT_VLC_LE);
      77          52 :         if (ret) {
      78           0 :             free_vlcs(c);
      79           0 :             return ret;
      80             :         }
      81          52 :         ret = ff_init_vlc_sparse(c->ac_vlc + i, 9, tscc2_ac_vlc_sizes[i],
      82          52 :                                  tscc2_ac_vlc_bits[i],  1, 1,
      83          52 :                                  tscc2_ac_vlc_codes[i], 2, 2,
      84          52 :                                  tscc2_ac_vlc_syms[i],  2, 2, INIT_VLC_LE);
      85          52 :         if (ret) {
      86           0 :             free_vlcs(c);
      87           0 :             return ret;
      88             :         }
      89             :     }
      90             : 
      91           4 :     return 0;
      92             : }
      93             : 
      94             : #define DEQUANT(val, q) (((q) * (val) + 0x80) >> 8)
      95             : #define DCT1D(d0, d1, d2, d3, s0, s1, s2, s3, OP) \
      96             :     OP(d0, 5 * ((s0) + (s1) + (s2)) + 2 * (s3));  \
      97             :     OP(d1, 5 * ((s0) - (s2) - (s3)) + 2 * (s1));  \
      98             :     OP(d2, 5 * ((s0) - (s2) + (s3)) - 2 * (s1));  \
      99             :     OP(d3, 5 * ((s0) - (s1) + (s2)) - 2 * (s3));  \
     100             : 
     101             : #define COL_OP(a, b)  a = (b)
     102             : #define ROW_OP(a, b)  a = ((b) + 0x20) >> 6
     103             : 
     104      441488 : static void tscc2_idct4_put(int *in, int q[3], uint8_t *dst, int stride)
     105             : {
     106             :     int i;
     107             :     int tblk[4 * 4];
     108             :     int t0, t1, t2, t3;
     109             : 
     110     2207440 :     for (i = 0; i < 4; i++) {
     111     1765952 :         t0 = DEQUANT(q[0 + (i & 1)], in[0 * 4 + i]);
     112     1765952 :         t1 = DEQUANT(q[1 + (i & 1)], in[1 * 4 + i]);
     113     1765952 :         t2 = DEQUANT(q[0 + (i & 1)], in[2 * 4 + i]);
     114     1765952 :         t3 = DEQUANT(q[1 + (i & 1)], in[3 * 4 + i]);
     115     1765952 :         DCT1D(tblk[0 * 4 + i], tblk[1 * 4 + i],
     116             :               tblk[2 * 4 + i], tblk[3 * 4 + i],
     117             :               t0, t1, t2, t3, COL_OP);
     118             :     }
     119     2207440 :     for (i = 0; i < 4; i++) {
     120     1765952 :         DCT1D(dst[0], dst[1], dst[2], dst[3],
     121             :               tblk[i * 4 + 0], tblk[i * 4 + 1],
     122             :               tblk[i * 4 + 2], tblk[i * 4 + 3], ROW_OP);
     123     1765952 :         dst += stride;
     124             :     }
     125      441488 : }
     126             : 
     127       66141 : static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set,
     128             :                            uint8_t *dst, int stride, int plane)
     129             : {
     130       66141 :     GetBitContext *gb = &c->gb;
     131             :     int prev_dc, dc, nc, ac, bpos, val;
     132             :     int i, j, k, l;
     133             : 
     134       66141 :     if (get_bits1(gb)) {
     135       10955 :         if (get_bits1(gb)) {
     136       10954 :             val = get_bits(gb, 8);
     137       98586 :             for (i = 0; i < 8; i++, dst += stride)
     138       87632 :                 memset(dst, val, 16);
     139             :         } else {
     140           1 :             if (get_bits_left(gb) < 16 * 8 * 8)
     141           0 :                 return AVERROR_INVALIDDATA;
     142           9 :             for (i = 0; i < 8; i++) {
     143         136 :                 for (j = 0; j < 16; j++)
     144         128 :                     dst[j] = get_bits(gb, 8);
     145           8 :                 dst += stride;
     146             :             }
     147             :         }
     148       10955 :         return 0;
     149             :     }
     150             : 
     151       55186 :     prev_dc = 0;
     152      165558 :     for (j = 0; j < 2; j++) {
     153      551860 :         for (k = 0; k < 4; k++) {
     154      441488 :             if (!(j | k)) {
     155       55186 :                 dc = get_bits(gb, 8);
     156             :             } else {
     157      386302 :                 dc = get_vlc2(gb, c->dc_vlc.table, 9, 2);
     158      386302 :                 if (dc == -1)
     159           0 :                     return AVERROR_INVALIDDATA;
     160      386302 :                 if (dc == 0x100)
     161       22622 :                     dc = get_bits(gb, 8);
     162             :             }
     163      441488 :             dc          = (dc + prev_dc) & 0xFF;
     164      441488 :             prev_dc     = dc;
     165      441488 :             c->block[0] = dc;
     166             : 
     167      441488 :             nc = get_vlc2(gb, c->nc_vlc[vlc_set].table, 9, 1);
     168      441488 :             if (nc == -1)
     169           0 :                 return AVERROR_INVALIDDATA;
     170             : 
     171      441488 :             bpos = 1;
     172      441488 :             memset(c->block + 1, 0, 15 * sizeof(*c->block));
     173     2082935 :             for (l = 0; l < nc; l++) {
     174     1641447 :                 ac = get_vlc2(gb, c->ac_vlc[vlc_set].table, 9, 2);
     175     1641447 :                 if (ac == -1)
     176           0 :                     return AVERROR_INVALIDDATA;
     177     1641447 :                 if (ac == 0x1000)
     178       48321 :                     ac = get_bits(gb, 12);
     179     1641447 :                 bpos += ac & 0xF;
     180     1641447 :                 if (bpos >= 16)
     181           0 :                     return AVERROR_INVALIDDATA;
     182     1641447 :                 val = sign_extend(ac >> 4, 8);
     183     1641447 :                 c->block[ff_zigzag_scan[bpos++]] = val;
     184             :             }
     185      441488 :             tscc2_idct4_put(c->block, q, dst + k * 4, stride);
     186             :         }
     187      110372 :         dst += 4 * stride;
     188             :     }
     189       55186 :     return 0;
     190             : }
     191             : 
     192        1084 : static int tscc2_decode_slice(TSCC2Context *c, int mb_y,
     193             :                               const uint8_t *buf, int buf_size)
     194             : {
     195             :     int i, mb_x, q, ret;
     196             :     int off;
     197             : 
     198        1084 :     if ((ret = init_get_bits8(&c->gb, buf, buf_size)) < 0)
     199           0 :         return ret;
     200             : 
     201       34860 :     for (mb_x = 0; mb_x < c->mb_width; mb_x++) {
     202       33776 :         q = c->slice_quants[mb_x + c->mb_width * mb_y];
     203             : 
     204       33776 :         if (q == 0 || q == 3) // skip block
     205       11729 :             continue;
     206       88188 :         for (i = 0; i < 3; i++) {
     207       66141 :             off = mb_x * 16 + mb_y * 8 * c->pic->linesize[i];
     208      132282 :             ret = tscc2_decode_mb(c, c->q[q - 1], c->quant[q - 1] - 2,
     209      132282 :                                   c->pic->data[i] + off, c->pic->linesize[i], i);
     210       66141 :             if (ret)
     211           0 :                 return ret;
     212             :         }
     213             :     }
     214             : 
     215        1084 :     return 0;
     216             : }
     217             : 
     218          48 : static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
     219             :                               int *got_frame, AVPacket *avpkt)
     220             : {
     221          48 :     const uint8_t *buf = avpkt->data;
     222          48 :     int buf_size = avpkt->size;
     223          48 :     TSCC2Context *c = avctx->priv_data;
     224             :     GetByteContext gb;
     225             :     uint32_t frame_type, size;
     226          48 :     int i, val, len, pos = 0;
     227          48 :     int num_mb = c->mb_width * c->mb_height;
     228             :     int ret;
     229             : 
     230          48 :     bytestream2_init(&gb, buf, buf_size);
     231          48 :     frame_type = bytestream2_get_byte(&gb);
     232          48 :     if (frame_type > 1) {
     233           0 :         av_log(avctx, AV_LOG_ERROR, "Incorrect frame type %"PRIu32"\n",
     234             :                frame_type);
     235           0 :         return AVERROR_INVALIDDATA;
     236             :     }
     237             : 
     238          48 :     if (frame_type == 0) {
     239             :         // Skip duplicate frames
     240          17 :         return buf_size;
     241             :     }
     242             : 
     243          31 :     if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) {
     244           0 :         return ret;
     245             :     }
     246             : 
     247          31 :     if (bytestream2_get_bytes_left(&gb) < 4) {
     248           0 :         av_log(avctx, AV_LOG_ERROR, "Frame is too short\n");
     249           0 :         return AVERROR_INVALIDDATA;
     250             :     }
     251             : 
     252          31 :     c->quant[0] = bytestream2_get_byte(&gb);
     253          31 :     c->quant[1] = bytestream2_get_byte(&gb);
     254          62 :     if (c->quant[0] < 2 || c->quant[0] > NUM_VLC_SETS + 1 ||
     255          62 :         c->quant[1] < 2 || c->quant[1] > NUM_VLC_SETS + 1) {
     256           0 :         av_log(avctx, AV_LOG_ERROR, "Invalid quantisers %d / %d\n",
     257             :                c->quant[0], c->quant[1]);
     258           0 :         return AVERROR_INVALIDDATA;
     259             :     }
     260             : 
     261         124 :     for (i = 0; i < 3; i++) {
     262          93 :         c->q[0][i] = tscc2_quants[c->quant[0] - 2][i];
     263          93 :         c->q[1][i] = tscc2_quants[c->quant[1] - 2][i];
     264             :     }
     265             : 
     266          31 :     bytestream2_skip(&gb, 1);
     267             : 
     268          31 :     size = bytestream2_get_le32(&gb);
     269          31 :     if (size > bytestream2_get_bytes_left(&gb)) {
     270           0 :         av_log(avctx, AV_LOG_ERROR, "Slice properties chunk is too large\n");
     271           0 :         return AVERROR_INVALIDDATA;
     272             :     }
     273             : 
     274        3319 :     for (i = 0; i < size; i++) {
     275        3288 :         val   = bytestream2_get_byte(&gb);
     276        3288 :         len   = val & 0x3F;
     277        3288 :         val >>= 6;
     278        3288 :         if (pos + len > num_mb) {
     279           0 :             av_log(avctx, AV_LOG_ERROR, "Too many slice properties\n");
     280           0 :             return AVERROR_INVALIDDATA;
     281             :         }
     282        3288 :         memset(c->slice_quants + pos, val, len);
     283        3288 :         pos += len;
     284             :     }
     285          31 :     if (pos < num_mb) {
     286           0 :         av_log(avctx, AV_LOG_ERROR, "Too few slice properties (%d / %d)\n",
     287             :                pos, num_mb);
     288           0 :         return AVERROR_INVALIDDATA;
     289             :     }
     290             : 
     291        1115 :     for (i = 0; i < c->mb_height; i++) {
     292        1085 :         size = bytestream2_peek_byte(&gb);
     293        1085 :         if (size & 1) {
     294         103 :             size = bytestream2_get_byte(&gb) - 1;
     295             :         } else {
     296         982 :             size = bytestream2_get_le32(&gb) >> 1;
     297             :         }
     298        1085 :         if (!size) {
     299         103 :             int skip_row = 1, j, off = i * c->mb_width;
     300        5871 :             for (j = 0; j < c->mb_width; j++) {
     301       11536 :                 if (c->slice_quants[off + j] == 1 ||
     302        5768 :                     c->slice_quants[off + j] == 2) {
     303           0 :                     skip_row = 0;
     304           0 :                     break;
     305             :                 }
     306             :             }
     307         103 :             if (!skip_row) {
     308           0 :                 av_log(avctx, AV_LOG_ERROR, "Non-skip row with zero size\n");
     309           0 :                 return AVERROR_INVALIDDATA;
     310             :             }
     311             :         }
     312        1085 :         if (bytestream2_get_bytes_left(&gb) < size) {
     313           1 :             av_log(avctx, AV_LOG_ERROR, "Invalid slice size (%"PRIu32"/%u)\n",
     314             :                    size, bytestream2_get_bytes_left(&gb));
     315           1 :             return AVERROR_INVALIDDATA;
     316             :         }
     317        1084 :         ret = tscc2_decode_slice(c, i, buf + bytestream2_tell(&gb), size);
     318        1084 :         if (ret) {
     319           0 :             av_log(avctx, AV_LOG_ERROR, "Error decoding slice %d\n", i);
     320           0 :             return ret;
     321             :         }
     322        1084 :         bytestream2_skip(&gb, size);
     323             :     }
     324             : 
     325          30 :     *got_frame      = 1;
     326          30 :     if ((ret = av_frame_ref(data, c->pic)) < 0)
     327           0 :         return ret;
     328             : 
     329             :     /* always report that the buffer was completely consumed */
     330          30 :     return buf_size;
     331             : }
     332             : 
     333           4 : static av_cold int tscc2_decode_end(AVCodecContext *avctx)
     334             : {
     335           4 :     TSCC2Context * const c = avctx->priv_data;
     336             : 
     337           4 :     av_frame_free(&c->pic);
     338           4 :     av_freep(&c->slice_quants);
     339           4 :     free_vlcs(c);
     340             : 
     341           4 :     return 0;
     342             : }
     343             : 
     344           4 : static av_cold int tscc2_decode_init(AVCodecContext *avctx)
     345             : {
     346           4 :     TSCC2Context * const c = avctx->priv_data;
     347             :     int ret;
     348             : 
     349           4 :     c->avctx = avctx;
     350             : 
     351           4 :     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
     352             : 
     353           4 :     if ((ret = init_vlcs(c)) < 0) {
     354           0 :         av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n");
     355           0 :         return ret;
     356             :     }
     357             : 
     358           4 :     c->mb_width     = FFALIGN(avctx->width,  16) >> 4;
     359           4 :     c->mb_height    = FFALIGN(avctx->height,  8) >> 3;
     360           4 :     c->slice_quants = av_malloc(c->mb_width * c->mb_height);
     361           4 :     if (!c->slice_quants) {
     362           0 :         av_log(avctx, AV_LOG_ERROR, "Cannot allocate slice information\n");
     363           0 :         free_vlcs(c);
     364           0 :         return AVERROR(ENOMEM);
     365             :     }
     366             : 
     367           4 :     c->pic = av_frame_alloc();
     368           4 :     if (!c->pic) {
     369           0 :         tscc2_decode_end(avctx);
     370           0 :         return AVERROR(ENOMEM);
     371             :     }
     372             : 
     373           4 :     return 0;
     374             : }
     375             : 
     376             : AVCodec ff_tscc2_decoder = {
     377             :     .name           = "tscc2",
     378             :     .long_name      = NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"),
     379             :     .type           = AVMEDIA_TYPE_VIDEO,
     380             :     .id             = AV_CODEC_ID_TSCC2,
     381             :     .priv_data_size = sizeof(TSCC2Context),
     382             :     .init           = tscc2_decode_init,
     383             :     .close          = tscc2_decode_end,
     384             :     .decode         = tscc2_decode_frame,
     385             :     .capabilities   = AV_CODEC_CAP_DR1,
     386             : };

Generated by: LCOV version 1.13