LCOV - code coverage report
Current view: top level - libavcodec - hqx.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 199 292 68.2 %
Date: 2017-12-16 13:57:32 Functions: 10 12 83.3 %

          Line data    Source code
       1             : /*
       2             :  * Canopus HQX decoder
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <inttypes.h>
      22             : 
      23             : #include "libavutil/imgutils.h"
      24             : #include "libavutil/intreadwrite.h"
      25             : 
      26             : #include "avcodec.h"
      27             : #include "canopus.h"
      28             : #include "get_bits.h"
      29             : #include "internal.h"
      30             : #include "thread.h"
      31             : 
      32             : #include "hqx.h"
      33             : #include "hqxdsp.h"
      34             : 
      35             : /* HQX has four modes - 422, 444, 422alpha and 444alpha - all 12-bit */
      36             : enum HQXFormat {
      37             :     HQX_422 = 0,
      38             :     HQX_444,
      39             :     HQX_422A,
      40             :     HQX_444A,
      41             : };
      42             : 
      43             : #define HQX_HEADER_SIZE 59
      44             : 
      45             : /* macroblock selects a group of 4 possible quants and
      46             :  * a block can use any of those four quantisers
      47             :  * one column is powers of 2, the other one is powers of 2 * 3,
      48             :  * then there is the special one, powers of 2 * 5 */
      49             : static const int hqx_quants[16][4] = {
      50             :     {  0x1,   0x2,   0x4,   0x8 }, {  0x1,  0x3,   0x6,   0xC },
      51             :     {  0x2,   0x4,   0x8,  0x10 }, {  0x3,  0x6,   0xC,  0x18 },
      52             :     {  0x4,   0x8,  0x10,  0x20 }, {  0x6,  0xC,  0x18,  0x30 },
      53             :     {  0x8,  0x10,  0x20,  0x40 },
      54             :                       { 0xA, 0x14, 0x28, 0x50 },
      55             :                                    {  0xC, 0x18,  0x30,  0x60 },
      56             :     { 0x10,  0x20,  0x40,  0x80 }, { 0x18, 0x30,  0x60,  0xC0 },
      57             :     { 0x20,  0x40,  0x80, 0x100 }, { 0x30, 0x60,  0xC0, 0x180 },
      58             :     { 0x40,  0x80, 0x100, 0x200 }, { 0x60, 0xC0, 0x180, 0x300 },
      59             :     { 0x80, 0x100, 0x200, 0x400 }
      60             : };
      61             : 
      62             : static const uint8_t hqx_quant_luma[64] = {
      63             :     16,  16,  16,  19,  19,  19,  42,  44,
      64             :     16,  16,  19,  19,  19,  38,  43,  45,
      65             :     16,  19,  19,  19,  40,  41,  45,  48,
      66             :     19,  19,  19,  40,  41,  42,  46,  49,
      67             :     19,  19,  40,  41,  42,  43,  48, 101,
      68             :     19,  38,  41,  42,  43,  44,  98, 104,
      69             :     42,  43,  45,  46,  48,  98, 109, 116,
      70             :     44,  45,  48,  49, 101, 104, 116, 123,
      71             : };
      72             : 
      73             : static const uint8_t hqx_quant_chroma[64] = {
      74             :     16,  16,  19,  25,  26,  26,  42,  44,
      75             :     16,  19,  25,  25,  26,  38,  43,  91,
      76             :     19,  25,  26,  27,  40,  41,  91,  96,
      77             :     25,  25,  27,  40,  41,  84,  93, 197,
      78             :     26,  26,  40,  41,  84,  86, 191, 203,
      79             :     26,  38,  41,  84,  86, 177, 197, 209,
      80             :     42,  43,  91,  93, 191, 197, 219, 232,
      81             :     44,  91,  96, 197, 203, 209, 232, 246,
      82             : };
      83             : 
      84      110880 : static inline void put_blocks(HQXContext *ctx, int plane,
      85             :                               int x, int y, int ilace,
      86             :                               int16_t *block0, int16_t *block1,
      87             :                               const uint8_t *quant)
      88             : {
      89      110880 :     int fields = ilace ? 2 : 1;
      90      110880 :     int lsize = ctx->pic->linesize[plane];
      91      110880 :     uint8_t *p = ctx->pic->data[plane] + x * 2;
      92             : 
      93      221760 :     ctx->hqxdsp.idct_put((uint16_t *)(p + y * lsize),
      94      110880 :                          lsize * fields, block0, quant);
      95      221760 :     ctx->hqxdsp.idct_put((uint16_t *)(p + (y + (ilace ? 1 : 8)) * lsize),
      96      110880 :                          lsize * fields, block1, quant);
      97      110880 : }
      98             : 
      99     2674300 : static inline void hqx_get_ac(GetBitContext *gb, const HQXAC *ac,
     100             :                               int *run, int *lev)
     101             : {
     102             :     int val;
     103             : 
     104     2674300 :     val = show_bits(gb, ac->lut_bits);
     105     2674300 :     if (ac->lut[val].bits == -1) {
     106      108610 :         GetBitContext gb2 = *gb;
     107      108610 :         skip_bits(&gb2, ac->lut_bits);
     108      108610 :         val = ac->lut[val].lev + show_bits(&gb2, ac->extra_bits);
     109             :     }
     110     2674300 :     *run = ac->lut[val].run;
     111     2674300 :     *lev = ac->lut[val].lev;
     112     2674300 :     skip_bits(gb, ac->lut[val].bits);
     113     2674300 : }
     114             : 
     115      144104 : static int decode_block(GetBitContext *gb, VLC *vlc,
     116             :                         const int *quants, int dcb,
     117             :                         int16_t block[64], int *last_dc)
     118             : {
     119             :     int q, dc;
     120             :     int ac_idx;
     121      144104 :     int run, lev, pos = 1;
     122             : 
     123      144104 :     memset(block, 0, 64 * sizeof(*block));
     124      144104 :     dc = get_vlc2(gb, vlc->table, HQX_DC_VLC_BITS, 2);
     125      144104 :     if (dc < 0)
     126           0 :         return AVERROR_INVALIDDATA;
     127      144104 :     *last_dc += dc;
     128             : 
     129      144104 :     block[0] = sign_extend(*last_dc << (12 - dcb), 12);
     130             : 
     131      144104 :     q = quants[get_bits(gb, 2)];
     132      144104 :     if (q >= 128)
     133           0 :         ac_idx = HQX_AC_Q128;
     134      144104 :     else if (q >= 64)
     135           0 :         ac_idx = HQX_AC_Q64;
     136      144104 :     else if (q >= 32)
     137           0 :         ac_idx = HQX_AC_Q32;
     138      144104 :     else if (q >= 16)
     139           0 :         ac_idx = HQX_AC_Q16;
     140      144104 :     else if (q >= 8)
     141          14 :         ac_idx = HQX_AC_Q8;
     142             :     else
     143      144090 :         ac_idx = HQX_AC_Q0;
     144             : 
     145             :     do {
     146     2674300 :         hqx_get_ac(gb, &ff_hqx_ac[ac_idx], &run, &lev);
     147     2674300 :         pos += run;
     148     2674300 :         if (pos >= 64)
     149      140780 :             break;
     150     2533520 :         block[ff_zigzag_direct[pos++]] = lev * q;
     151     2533520 :     } while (pos < 64);
     152             : 
     153      144104 :     return 0;
     154             : }
     155             : 
     156        3240 : static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y)
     157             : {
     158        3240 :     HQXSlice *slice = &ctx->slice[slice_no];
     159        3240 :     GetBitContext *gb = &slice->gb;
     160             :     const int *quants;
     161             :     int flag;
     162             :     int last_dc;
     163             :     int i, ret;
     164             : 
     165        3240 :     if (ctx->interlaced)
     166        3240 :         flag = get_bits1(gb);
     167             :     else
     168           0 :         flag = 0;
     169             : 
     170        3240 :     quants = hqx_quants[get_bits(gb, 4)];
     171             : 
     172       29160 :     for (i = 0; i < 8; i++) {
     173       25920 :         int vlc_index = ctx->dcb - 9;
     174       25920 :         if (i == 0 || i == 4 || i == 6)
     175        9720 :             last_dc = 0;
     176       25920 :         ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
     177       25920 :                            ctx->dcb, slice->block[i], &last_dc);
     178       25920 :         if (ret < 0)
     179           0 :             return ret;
     180             :     }
     181             : 
     182        3240 :     put_blocks(ctx, 0, x,      y, flag, slice->block[0], slice->block[2], hqx_quant_luma);
     183        3240 :     put_blocks(ctx, 0, x + 8,  y, flag, slice->block[1], slice->block[3], hqx_quant_luma);
     184        3240 :     put_blocks(ctx, 2, x >> 1, y, flag, slice->block[4], slice->block[5], hqx_quant_chroma);
     185        3240 :     put_blocks(ctx, 1, x >> 1, y, flag, slice->block[6], slice->block[7], hqx_quant_chroma);
     186             : 
     187        3240 :     return 0;
     188             : }
     189             : 
     190       16320 : static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
     191             : {
     192       16320 :     HQXSlice *slice = &ctx->slice[slice_no];
     193       16320 :     GetBitContext *gb = &slice->gb;
     194             :     const int *quants;
     195       16320 :     int flag = 0;
     196             :     int last_dc;
     197             :     int i, ret;
     198             :     int cbp;
     199             : 
     200       16320 :     cbp = get_vlc2(gb, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1);
     201             : 
     202      212160 :     for (i = 0; i < 12; i++)
     203      195840 :         memset(slice->block[i], 0, sizeof(**slice->block) * 64);
     204      212160 :     for (i = 0; i < 12; i++)
     205      195840 :         slice->block[i][0] = -0x800;
     206       16320 :     if (cbp) {
     207        9986 :         if (ctx->interlaced)
     208        9986 :             flag = get_bits1(gb);
     209             : 
     210        9986 :         quants = hqx_quants[get_bits(gb, 4)];
     211             : 
     212        9986 :         cbp |= cbp << 4; // alpha CBP
     213        9986 :         if (cbp & 0x3)   // chroma CBP - top
     214        9896 :             cbp |= 0x500;
     215        9986 :         if (cbp & 0xC)   // chroma CBP - bottom
     216        9878 :             cbp |= 0xA00;
     217      129818 :         for (i = 0; i < 12; i++) {
     218      119832 :             if (i == 0 || i == 4 || i == 8 || i == 10)
     219       39944 :                 last_dc = 0;
     220      119832 :             if (cbp & (1 << i)) {
     221      118184 :                 int vlc_index = ctx->dcb - 9;
     222      118184 :                 ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
     223      118184 :                                    ctx->dcb, slice->block[i], &last_dc);
     224      118184 :                 if (ret < 0)
     225           0 :                     return ret;
     226             :             }
     227             :         }
     228             :     }
     229             : 
     230       16320 :     put_blocks(ctx, 3, x,      y, flag, slice->block[ 0], slice->block[ 2], hqx_quant_luma);
     231       16320 :     put_blocks(ctx, 3, x + 8,  y, flag, slice->block[ 1], slice->block[ 3], hqx_quant_luma);
     232       16320 :     put_blocks(ctx, 0, x,      y, flag, slice->block[ 4], slice->block[ 6], hqx_quant_luma);
     233       16320 :     put_blocks(ctx, 0, x + 8,  y, flag, slice->block[ 5], slice->block[ 7], hqx_quant_luma);
     234       16320 :     put_blocks(ctx, 2, x >> 1, y, flag, slice->block[ 8], slice->block[ 9], hqx_quant_chroma);
     235       16320 :     put_blocks(ctx, 1, x >> 1, y, flag, slice->block[10], slice->block[11], hqx_quant_chroma);
     236             : 
     237       16320 :     return 0;
     238             : }
     239             : 
     240           0 : static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y)
     241             : {
     242           0 :     HQXSlice *slice = &ctx->slice[slice_no];
     243           0 :     GetBitContext *gb = &slice->gb;
     244             :     const int *quants;
     245             :     int flag;
     246             :     int last_dc;
     247             :     int i, ret;
     248             : 
     249           0 :     if (ctx->interlaced)
     250           0 :         flag = get_bits1(gb);
     251             :     else
     252           0 :         flag = 0;
     253             : 
     254           0 :     quants = hqx_quants[get_bits(gb, 4)];
     255             : 
     256           0 :     for (i = 0; i < 12; i++) {
     257           0 :         int vlc_index = ctx->dcb - 9;
     258           0 :         if (i == 0 || i == 4 || i == 8)
     259           0 :             last_dc = 0;
     260           0 :         ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
     261           0 :                            ctx->dcb, slice->block[i], &last_dc);
     262           0 :         if (ret < 0)
     263           0 :             return ret;
     264             :     }
     265             : 
     266           0 :     put_blocks(ctx, 0, x,     y, flag, slice->block[0], slice->block[ 2], hqx_quant_luma);
     267           0 :     put_blocks(ctx, 0, x + 8, y, flag, slice->block[1], slice->block[ 3], hqx_quant_luma);
     268           0 :     put_blocks(ctx, 2, x,     y, flag, slice->block[4], slice->block[ 6], hqx_quant_chroma);
     269           0 :     put_blocks(ctx, 2, x + 8, y, flag, slice->block[5], slice->block[ 7], hqx_quant_chroma);
     270           0 :     put_blocks(ctx, 1, x,     y, flag, slice->block[8], slice->block[10], hqx_quant_chroma);
     271           0 :     put_blocks(ctx, 1, x + 8, y, flag, slice->block[9], slice->block[11], hqx_quant_chroma);
     272             : 
     273           0 :     return 0;
     274             : }
     275             : 
     276           0 : static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
     277             : {
     278           0 :     HQXSlice *slice = &ctx->slice[slice_no];
     279           0 :     GetBitContext *gb = &slice->gb;
     280             :     const int *quants;
     281           0 :     int flag = 0;
     282             :     int last_dc;
     283             :     int i, ret;
     284             :     int cbp;
     285             : 
     286           0 :     cbp = get_vlc2(gb, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1);
     287             : 
     288           0 :     for (i = 0; i < 16; i++)
     289           0 :         memset(slice->block[i], 0, sizeof(**slice->block) * 64);
     290           0 :     for (i = 0; i < 16; i++)
     291           0 :         slice->block[i][0] = -0x800;
     292           0 :     if (cbp) {
     293           0 :         if (ctx->interlaced)
     294           0 :             flag = get_bits1(gb);
     295             : 
     296           0 :         quants = hqx_quants[get_bits(gb, 4)];
     297             : 
     298           0 :         cbp |= cbp << 4; // alpha CBP
     299           0 :         cbp |= cbp << 8; // chroma CBP
     300           0 :         for (i = 0; i < 16; i++) {
     301           0 :             if (i == 0 || i == 4 || i == 8 || i == 12)
     302           0 :                 last_dc = 0;
     303           0 :             if (cbp & (1 << i)) {
     304           0 :                 int vlc_index = ctx->dcb - 9;
     305           0 :                 ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
     306           0 :                                    ctx->dcb, slice->block[i], &last_dc);
     307           0 :                 if (ret < 0)
     308           0 :                     return ret;
     309             :             }
     310             :         }
     311             :     }
     312             : 
     313           0 :     put_blocks(ctx, 3, x,     y, flag, slice->block[ 0], slice->block[ 2], hqx_quant_luma);
     314           0 :     put_blocks(ctx, 3, x + 8, y, flag, slice->block[ 1], slice->block[ 3], hqx_quant_luma);
     315           0 :     put_blocks(ctx, 0, x,     y, flag, slice->block[ 4], slice->block[ 6], hqx_quant_luma);
     316           0 :     put_blocks(ctx, 0, x + 8, y, flag, slice->block[ 5], slice->block[ 7], hqx_quant_luma);
     317           0 :     put_blocks(ctx, 2, x,     y, flag, slice->block[ 8], slice->block[10], hqx_quant_chroma);
     318           0 :     put_blocks(ctx, 2, x + 8, y, flag, slice->block[ 9], slice->block[11], hqx_quant_chroma);
     319           0 :     put_blocks(ctx, 1, x,     y, flag, slice->block[12], slice->block[14], hqx_quant_chroma);
     320           0 :     put_blocks(ctx, 1, x + 8, y, flag, slice->block[13], slice->block[15], hqx_quant_chroma);
     321             : 
     322           0 :     return 0;
     323             : }
     324             : 
     325             : static const int shuffle_16[16] = {
     326             :     0, 5, 11, 14, 2, 7, 9, 13, 1, 4, 10, 15, 3, 6, 8, 12
     327             : };
     328             : 
     329          64 : static int decode_slice(HQXContext *ctx, int slice_no)
     330             : {
     331          64 :     int mb_w = (ctx->width  + 15) >> 4;
     332          64 :     int mb_h = (ctx->height + 15) >> 4;
     333          64 :     int grp_w = (mb_w + 4) / 5;
     334          64 :     int grp_h = (mb_h + 4) / 5;
     335          64 :     int grp_h_edge = grp_w * (mb_w / grp_w);
     336          64 :     int grp_v_edge = grp_h * (mb_h / grp_h);
     337          64 :     int grp_v_rest = mb_w - grp_h_edge;
     338          64 :     int grp_h_rest = mb_h - grp_v_edge;
     339          64 :     int num_mbs = mb_w * mb_h;
     340          64 :     int num_tiles = (num_mbs + 479) / 480;
     341          64 :     int std_tile_blocks = num_mbs / (16 * num_tiles);
     342          64 :     int g_tile = slice_no * num_tiles;
     343             :     int blk_addr, loc_addr, mb_x, mb_y, pos, loc_row, i;
     344             :     int tile_blocks, tile_limit, tile_no;
     345             : 
     346         736 :     for (tile_no = 0; tile_no < num_tiles; tile_no++, g_tile++) {
     347         672 :         tile_blocks = std_tile_blocks;
     348         672 :         tile_limit = -1;
     349         672 :         if (g_tile < num_mbs - std_tile_blocks * 16 * num_tiles) {
     350          40 :             tile_limit = num_mbs / (16 * num_tiles);
     351          40 :             tile_blocks++;
     352             :         }
     353       20232 :         for (i = 0; i < tile_blocks; i++) {
     354       19560 :             if (i == tile_limit)
     355          40 :                 blk_addr = g_tile + 16 * num_tiles * i;
     356             :             else
     357       39040 :                 blk_addr = tile_no + 16 * num_tiles * i +
     358       19520 :                            num_tiles * shuffle_16[(i + slice_no) & 0xF];
     359       19560 :             loc_row  = grp_h * (blk_addr / (grp_h * mb_w));
     360       19560 :             loc_addr =          blk_addr % (grp_h * mb_w);
     361       19560 :             if (loc_row >= grp_v_edge) {
     362        3240 :                 mb_x = grp_w * (loc_addr / (grp_h_rest * grp_w));
     363        3240 :                 pos  =          loc_addr % (grp_h_rest * grp_w);
     364             :             } else {
     365       16320 :                 mb_x = grp_w * (loc_addr / (grp_h * grp_w));
     366       16320 :                 pos  =          loc_addr % (grp_h * grp_w);
     367             :             }
     368       19560 :             if (mb_x >= grp_h_edge) {
     369           0 :                 mb_x +=            pos % grp_v_rest;
     370           0 :                 mb_y  = loc_row + (pos / grp_v_rest);
     371             :             } else {
     372       19560 :                 mb_x +=            pos % grp_w;
     373       19560 :                 mb_y  = loc_row + (pos / grp_w);
     374             :             }
     375       19560 :             ctx->decode_func(ctx, slice_no, mb_x * 16, mb_y * 16);
     376             :         }
     377             :     }
     378             : 
     379          64 :     return 0;
     380             : }
     381             : 
     382          64 : static int decode_slice_thread(AVCodecContext *avctx, void *arg,
     383             :                                int slice_no, int threadnr)
     384             : {
     385          64 :     HQXContext *ctx = avctx->priv_data;
     386          64 :     uint32_t *slice_off = ctx->slice_off;
     387             :     int ret;
     388             : 
     389         128 :     if (slice_off[slice_no] < HQX_HEADER_SIZE ||
     390         128 :         slice_off[slice_no] >= slice_off[slice_no + 1] ||
     391          64 :         slice_off[slice_no + 1] > ctx->data_size) {
     392           0 :         av_log(avctx, AV_LOG_ERROR, "Invalid slice size %d.\n", ctx->data_size);
     393           0 :         return AVERROR_INVALIDDATA;
     394             :     }
     395             : 
     396         128 :     ret = init_get_bits8(&ctx->slice[slice_no].gb,
     397          64 :                          ctx->src + slice_off[slice_no],
     398          64 :                          slice_off[slice_no + 1] - slice_off[slice_no]);
     399          64 :     if (ret < 0)
     400           0 :         return ret;
     401             : 
     402          64 :     return decode_slice(ctx, slice_no);
     403             : }
     404             : 
     405           4 : static int hqx_decode_frame(AVCodecContext *avctx, void *data,
     406             :                             int *got_picture_ptr, AVPacket *avpkt)
     407             : {
     408           4 :     HQXContext *ctx = avctx->priv_data;
     409           4 :     ThreadFrame frame = { .f = data };
     410           4 :     uint8_t *src = avpkt->data;
     411             :     uint32_t info_tag;
     412             :     int data_start;
     413             :     int i, ret;
     414             : 
     415           4 :     if (avpkt->size < 4 + 4) {
     416           0 :         av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size);
     417           0 :         return AVERROR_INVALIDDATA;
     418             :     }
     419             : 
     420           4 :     info_tag    = AV_RL32(src);
     421           4 :     if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
     422           4 :         uint32_t info_offset = AV_RL32(src + 4);
     423           4 :         if (info_offset > INT_MAX || info_offset + 8 > avpkt->size) {
     424           0 :             av_log(avctx, AV_LOG_ERROR,
     425             :                    "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
     426             :                    info_offset);
     427           0 :             return AVERROR_INVALIDDATA;
     428             :         }
     429           4 :         ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
     430             : 
     431           4 :         info_offset += 8;
     432           4 :         src         += info_offset;
     433             :     }
     434             : 
     435           4 :     data_start     = src - avpkt->data;
     436           4 :     ctx->data_size = avpkt->size - data_start;
     437           4 :     ctx->src       = src;
     438           4 :     ctx->pic       = data;
     439             : 
     440           4 :     if (ctx->data_size < HQX_HEADER_SIZE) {
     441           0 :         av_log(avctx, AV_LOG_ERROR, "Frame too small.\n");
     442           0 :         return AVERROR_INVALIDDATA;
     443             :     }
     444             : 
     445           4 :     if (src[0] != 'H' || src[1] != 'Q') {
     446           0 :         av_log(avctx, AV_LOG_ERROR, "Not an HQX frame.\n");
     447           0 :         return AVERROR_INVALIDDATA;
     448             :     }
     449           4 :     ctx->interlaced = !(src[2] & 0x80);
     450           4 :     ctx->format     = src[2] & 7;
     451           4 :     ctx->dcb        = (src[3] & 3) + 8;
     452           4 :     ctx->width      = AV_RB16(src + 4);
     453           4 :     ctx->height     = AV_RB16(src + 6);
     454          72 :     for (i = 0; i < 17; i++)
     455          68 :         ctx->slice_off[i] = AV_RB24(src + 8 + i * 3);
     456             : 
     457           4 :     if (ctx->dcb == 8) {
     458           0 :         av_log(avctx, AV_LOG_ERROR, "Invalid DC precision %d.\n", ctx->dcb);
     459           0 :         return AVERROR_INVALIDDATA;
     460             :     }
     461           4 :     ret = av_image_check_size(ctx->width, ctx->height, 0, avctx);
     462           4 :     if (ret < 0) {
     463           0 :         av_log(avctx, AV_LOG_ERROR, "Invalid stored dimensions %dx%d.\n",
     464             :                ctx->width, ctx->height);
     465           0 :         return AVERROR_INVALIDDATA;
     466             :     }
     467             : 
     468           4 :     avctx->coded_width         = FFALIGN(ctx->width,  16);
     469           4 :     avctx->coded_height        = FFALIGN(ctx->height, 16);
     470           4 :     avctx->width               = ctx->width;
     471           4 :     avctx->height              = ctx->height;
     472           4 :     avctx->bits_per_raw_sample = 10;
     473             : 
     474           4 :     switch (ctx->format) {
     475           2 :     case HQX_422:
     476           2 :         avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
     477           2 :         ctx->decode_func = hqx_decode_422;
     478           2 :         break;
     479           0 :     case HQX_444:
     480           0 :         avctx->pix_fmt = AV_PIX_FMT_YUV444P16;
     481           0 :         ctx->decode_func = hqx_decode_444;
     482           0 :         break;
     483           2 :     case HQX_422A:
     484           2 :         avctx->pix_fmt = AV_PIX_FMT_YUVA422P16;
     485           2 :         ctx->decode_func = hqx_decode_422a;
     486           2 :         break;
     487           0 :     case HQX_444A:
     488           0 :         avctx->pix_fmt = AV_PIX_FMT_YUVA444P16;
     489           0 :         ctx->decode_func = hqx_decode_444a;
     490           0 :         break;
     491           0 :     default:
     492           0 :         av_log(avctx, AV_LOG_ERROR, "Invalid format: %d.\n", ctx->format);
     493           0 :         return AVERROR_INVALIDDATA;
     494             :     }
     495             : 
     496           4 :     ret = ff_thread_get_buffer(avctx, &frame, 0);
     497           4 :     if (ret < 0)
     498           0 :         return ret;
     499             : 
     500           4 :     avctx->execute2(avctx, decode_slice_thread, NULL, NULL, 16);
     501             : 
     502           4 :     ctx->pic->key_frame = 1;
     503           4 :     ctx->pic->pict_type = AV_PICTURE_TYPE_I;
     504             : 
     505           4 :     *got_picture_ptr = 1;
     506             : 
     507           4 :     return avpkt->size;
     508             : }
     509             : 
     510           4 : static av_cold int hqx_decode_close(AVCodecContext *avctx)
     511             : {
     512             :     int i;
     513           4 :     HQXContext *ctx = avctx->priv_data;
     514             : 
     515           4 :     if (avctx->internal->is_copy)
     516           0 :         return 0;
     517             : 
     518           4 :     ff_free_vlc(&ctx->cbp_vlc);
     519          16 :     for (i = 0; i < 3; i++) {
     520          12 :         ff_free_vlc(&ctx->dc_vlc[i]);
     521             :     }
     522             : 
     523           4 :     return 0;
     524             : }
     525             : 
     526           4 : static av_cold int hqx_decode_init(AVCodecContext *avctx)
     527             : {
     528           4 :     HQXContext *ctx = avctx->priv_data;
     529             : 
     530           4 :     ff_hqxdsp_init(&ctx->hqxdsp);
     531             : 
     532           4 :     return ff_hqx_init_vlcs(ctx);
     533             : }
     534             : 
     535             : AVCodec ff_hqx_decoder = {
     536             :     .name           = "hqx",
     537             :     .long_name      = NULL_IF_CONFIG_SMALL("Canopus HQX"),
     538             :     .type           = AVMEDIA_TYPE_VIDEO,
     539             :     .id             = AV_CODEC_ID_HQX,
     540             :     .priv_data_size = sizeof(HQXContext),
     541             :     .init           = hqx_decode_init,
     542             :     .decode         = hqx_decode_frame,
     543             :     .close          = hqx_decode_close,
     544             :     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
     545             :                       AV_CODEC_CAP_FRAME_THREADS,
     546             :     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
     547             :                       FF_CODEC_CAP_INIT_CLEANUP,
     548             : };

Generated by: LCOV version 1.13