LCOV - code coverage report
Current view: top level - libavcodec - ylc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 214 0.0 %
Date: 2017-12-16 01:21:47 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /*
       2             :  * YUY2 Lossless Codec
       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 <stdio.h>
      22             : #include <stdlib.h>
      23             : #include <string.h>
      24             : 
      25             : #include "libavutil/imgutils.h"
      26             : #include "libavutil/internal.h"
      27             : #include "libavutil/intreadwrite.h"
      28             : #include "libavutil/mem.h"
      29             : #include "avcodec.h"
      30             : #include "bswapdsp.h"
      31             : #include "get_bits.h"
      32             : #include "huffyuvdsp.h"
      33             : #include "internal.h"
      34             : #include "thread.h"
      35             : #include "unary.h"
      36             : 
      37             : typedef struct YLCContext {
      38             :     VLC vlc[4];
      39             :     uint32_t table[1024];
      40             :     uint8_t *table_bits;
      41             :     uint8_t *bitstream_bits;
      42             :     int table_bits_size;
      43             :     int bitstream_bits_size;
      44             :     BswapDSPContext bdsp;
      45             : } YLCContext;
      46             : 
      47           0 : static av_cold int decode_init(AVCodecContext *avctx)
      48             : {
      49           0 :     YLCContext *s = avctx->priv_data;
      50             : 
      51           0 :     avctx->pix_fmt = AV_PIX_FMT_YUYV422;
      52           0 :     ff_bswapdsp_init(&s->bdsp);
      53             : 
      54           0 :     return 0;
      55             : }
      56             : 
      57             : typedef struct Node {
      58             :     int16_t  sym;
      59             :     int16_t  n0;
      60             :     uint32_t count;
      61             :     int16_t  l, r;
      62             : } Node;
      63             : 
      64           0 : static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat,
      65             :                            Node *nodes, int node,
      66             :                            uint32_t pfx, int pl, int *pos)
      67             : {
      68             :     int s;
      69             : 
      70           0 :     s = nodes[node].sym;
      71           0 :     if (s != -1) {
      72           0 :         bits[*pos] = (~pfx) & ((1ULL << FFMAX(pl, 1)) - 1);
      73           0 :         lens[*pos] = FFMAX(pl, 1);
      74           0 :         xlat[*pos] = s + (pl == 0);
      75           0 :         (*pos)++;
      76             :     } else {
      77           0 :         pfx <<= 1;
      78           0 :         pl++;
      79           0 :         get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl,
      80             :                        pos);
      81           0 :         pfx |= 1;
      82           0 :         get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl,
      83             :                        pos);
      84             :     }
      85           0 : }
      86             : 
      87           0 : static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table)
      88             : {
      89             :     Node nodes[512];
      90             :     uint32_t bits[256];
      91             :     int16_t lens[256];
      92             :     uint8_t xlat[256];
      93           0 :     int cur_node, i, j, pos = 0;
      94             : 
      95           0 :     ff_free_vlc(vlc);
      96             : 
      97           0 :     for (i = 0; i < 256; i++) {
      98           0 :         nodes[i].count = table[i];
      99           0 :         nodes[i].sym   = i;
     100           0 :         nodes[i].n0    = -2;
     101           0 :         nodes[i].l     = i;
     102           0 :         nodes[i].r     = i;
     103             :     }
     104             : 
     105           0 :     cur_node = 256;
     106           0 :     j = 0;
     107             :     do {
     108           0 :         for (i = 0; ; i++) {
     109           0 :             int new_node = j;
     110           0 :             int first_node = cur_node;
     111           0 :             int second_node = cur_node;
     112             :             unsigned nd, st;
     113             : 
     114           0 :             nodes[cur_node].count = -1;
     115             : 
     116             :             do {
     117           0 :                 int val = nodes[new_node].count;
     118           0 :                 if (val && (val < nodes[first_node].count)) {
     119           0 :                     if (val >= nodes[second_node].count) {
     120           0 :                         first_node = new_node;
     121             :                     } else {
     122           0 :                         first_node = second_node;
     123           0 :                         second_node = new_node;
     124             :                     }
     125             :                 }
     126           0 :                 new_node += 1;
     127           0 :             } while (new_node != cur_node);
     128             : 
     129           0 :             if (first_node == cur_node)
     130           0 :                 break;
     131             : 
     132           0 :             nd = nodes[second_node].count;
     133           0 :             st = nodes[first_node].count;
     134           0 :             nodes[second_node].count = 0;
     135           0 :             nodes[first_node].count  = 0;
     136           0 :             if (nd >= UINT32_MAX - st) {
     137           0 :                 av_log(avctx, AV_LOG_ERROR, "count overflow\n");
     138           0 :                 return AVERROR_INVALIDDATA;
     139             :             }
     140           0 :             nodes[cur_node].count = nd + st;
     141           0 :             nodes[cur_node].sym = -1;
     142           0 :             nodes[cur_node].n0 = cur_node;
     143           0 :             nodes[cur_node].l = first_node;
     144           0 :             nodes[cur_node].r = second_node;
     145           0 :             cur_node++;
     146             :         }
     147           0 :         j++;
     148           0 :     } while (cur_node - 256 == j);
     149             : 
     150           0 :     get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
     151             : 
     152           0 :     return ff_init_vlc_sparse(vlc, 10, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
     153             : }
     154             : 
     155             : static const uint8_t table_y1[] = {
     156             :     0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
     157             :     0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
     158             :     0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
     159             :     0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
     160             :     0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
     161             :     0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
     162             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     163             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     164             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     165             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     166             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     167             :     0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     168             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     169             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     170             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     171             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     172             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
     173             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     174             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     175             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     176             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     177             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     178             :     0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
     179             :     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
     180             :     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
     181             :     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
     182             :     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
     183             :     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
     184             :     0x02, 0x00,
     185             : };
     186             : 
     187             : static const uint8_t table_u[] = {
     188             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     189             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
     190             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     191             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
     192             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     193             :     0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
     194             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     195             :     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
     196             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     197             :     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
     198             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     199             :     0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     200             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     201             :     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     202             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     203             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     204             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,
     205             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     206             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
     207             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     208             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
     209             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     210             :     0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
     211             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     212             :     0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
     213             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     214             :     0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     215             :     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     216             :     0x01, 0x00,
     217             : };
     218             : 
     219             : static const uint8_t table_y2[] = {
     220             :     0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
     221             :     0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC,
     222             :     0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE,
     223             :     0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC,
     224             :     0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF,
     225             :     0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD,
     226             :     0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
     227             :     0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE,
     228             :     0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
     229             :     0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
     230             :     0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
     231             :     0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
     232             :     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
     233             :     0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00,
     234             :     0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
     235             :     0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
     236             :     0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF,
     237             :     0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
     238             :     0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF,
     239             :     0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
     240             :     0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF,
     241             :     0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
     242             :     0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01,
     243             :     0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
     244             :     0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01,
     245             :     0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04,
     246             :     0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
     247             :     0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04,
     248             :     0x04, 0x00,
     249             : };
     250             : 
     251             : static const uint8_t table_v[] = {
     252             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     253             :     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
     254             :     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
     255             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     256             :     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
     257             :     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
     258             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     259             :     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
     260             :     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
     261             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     262             :     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
     263             :     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
     264             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     265             :     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
     266             :     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
     267             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     268             :     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
     269             :     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
     270             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     271             :     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
     272             :     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
     273             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     274             :     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
     275             :     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
     276             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     277             :     0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
     278             :     0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
     279             :     0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
     280             :     0x01, 0x00,
     281             : };
     282             : 
     283           0 : static int decode_frame(AVCodecContext *avctx,
     284             :                         void *data, int *got_frame,
     285             :                         AVPacket *avpkt)
     286             : {
     287           0 :     int TL[4] = { 128, 128, 128, 128 };
     288           0 :     int L[4]  = { 128, 128, 128, 128 };
     289           0 :     YLCContext *s = avctx->priv_data;
     290           0 :     ThreadFrame frame = { .f = data };
     291           0 :     const uint8_t *buf = avpkt->data;
     292             :     int ret, x, y, toffset, boffset;
     293           0 :     AVFrame * const p = data;
     294             :     GetBitContext gb;
     295             :     uint8_t *dst;
     296             : 
     297           0 :     if (avpkt->size <= 16)
     298           0 :         return AVERROR_INVALIDDATA;
     299             : 
     300           0 :     if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
     301           0 :         AV_RL32(buf + 4) != 0)
     302           0 :         return AVERROR_INVALIDDATA;
     303             : 
     304           0 :     toffset = AV_RL32(buf + 8);
     305           0 :     if (toffset < 16 || toffset >= avpkt->size)
     306           0 :         return AVERROR_INVALIDDATA;
     307             : 
     308           0 :     boffset = AV_RL32(buf + 12);
     309           0 :     if (toffset >= boffset || boffset >= avpkt->size)
     310           0 :         return AVERROR_INVALIDDATA;
     311             : 
     312           0 :     if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
     313           0 :         return ret;
     314             : 
     315           0 :     av_fast_malloc(&s->table_bits, &s->table_bits_size,
     316           0 :                    boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE);
     317           0 :     if (!s->table_bits)
     318           0 :         return AVERROR(ENOMEM);
     319             : 
     320           0 :     memcpy(s->table_bits, avpkt->data + toffset, boffset - toffset);
     321           0 :     memset(s->table_bits + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
     322           0 :     s->bdsp.bswap_buf((uint32_t *) s->table_bits,
     323           0 :                       (uint32_t *) s->table_bits,
     324           0 :                       (boffset - toffset + 3) >> 2);
     325           0 :     if ((ret = init_get_bits8(&gb, s->table_bits, boffset - toffset)) < 0)
     326           0 :         return ret;
     327             : 
     328           0 :     for (x = 0; x < 1024; x++) {
     329           0 :         unsigned len = get_unary(&gb, 1, 31);
     330           0 :         uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
     331             : 
     332           0 :         s->table[x] = val;
     333             :     }
     334             : 
     335           0 :     ret = build_vlc(avctx, &s->vlc[0], &s->table[0  ]);
     336           0 :     if (ret < 0)
     337           0 :         return ret;
     338           0 :     ret = build_vlc(avctx, &s->vlc[1], &s->table[256]);
     339           0 :     if (ret < 0)
     340           0 :         return ret;
     341           0 :     ret = build_vlc(avctx, &s->vlc[2], &s->table[512]);
     342           0 :     if (ret < 0)
     343           0 :         return ret;
     344           0 :     ret = build_vlc(avctx, &s->vlc[3], &s->table[768]);
     345           0 :     if (ret < 0)
     346           0 :         return ret;
     347             : 
     348           0 :     av_fast_malloc(&s->bitstream_bits, &s->bitstream_bits_size,
     349           0 :                    avpkt->size - boffset + AV_INPUT_BUFFER_PADDING_SIZE);
     350           0 :     if (!s->bitstream_bits)
     351           0 :         return AVERROR(ENOMEM);
     352             : 
     353           0 :     memcpy(s->bitstream_bits, avpkt->data + boffset, avpkt->size - boffset);
     354           0 :     memset(s->bitstream_bits + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
     355           0 :     s->bdsp.bswap_buf((uint32_t *) s->bitstream_bits,
     356           0 :                       (uint32_t *) s->bitstream_bits,
     357           0 :                       (avpkt->size - boffset) >> 2);
     358           0 :     if ((ret = init_get_bits8(&gb, s->bitstream_bits, avpkt->size - boffset)) < 0)
     359           0 :         return ret;
     360             : 
     361           0 :     dst = p->data[0];
     362           0 :     for (y = 0; y < avctx->height; y++) {
     363           0 :         memset(dst, 0, avctx->width * 2);
     364           0 :         dst += p->linesize[0];
     365             :     }
     366             : 
     367           0 :     dst = p->data[0];
     368           0 :     for (y = 0; y < avctx->height; y++) {
     369           0 :         for (x = 0; x < avctx->width * 2 && y < avctx->height;) {
     370           0 :             if (get_bits_left(&gb) <= 0)
     371           0 :                 return AVERROR_INVALIDDATA;
     372             : 
     373           0 :             if (get_bits1(&gb)) {
     374           0 :                 int val = get_vlc2(&gb, s->vlc[0].table, s->vlc[0].bits, 3);
     375           0 :                 if (val < 0) {
     376           0 :                     return AVERROR_INVALIDDATA;
     377           0 :                 } else if (val < 0xE1) {
     378           0 :                     dst[x    ] = table_y1[val];
     379           0 :                     dst[x + 1] = table_u[val];
     380           0 :                     dst[x + 2] = table_y2[val];
     381           0 :                     dst[x + 3] = table_v[val];
     382           0 :                     x += 4;
     383             :                 } else {
     384           0 :                     int incr = (val - 0xDF) * 4;
     385           0 :                     if (x + incr >= avctx->width * 2) {
     386           0 :                         int iy = ((x + incr) / (avctx->width * 2));
     387           0 :                         x  = (x + incr) % (avctx->width * 2);
     388           0 :                         y += iy;
     389           0 :                         dst += iy * p->linesize[0];
     390             :                     } else {
     391           0 :                         x += incr;
     392             :                     }
     393             :                 }
     394             :             } else {
     395             :                 int y1, y2, u, v;
     396             : 
     397           0 :                 y1 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
     398           0 :                 u  = get_vlc2(&gb, s->vlc[2].table, s->vlc[2].bits, 3);
     399           0 :                 y2 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
     400           0 :                 v  = get_vlc2(&gb, s->vlc[3].table, s->vlc[3].bits, 3);
     401           0 :                 if (y1 < 0 || y2 < 0 || u < 0 || v < 0)
     402           0 :                     return AVERROR_INVALIDDATA;
     403           0 :                 dst[x    ] = y1;
     404           0 :                 dst[x + 1] = u;
     405           0 :                 dst[x + 2] = y1 + y2;
     406           0 :                 dst[x + 3] = v;
     407           0 :                 x += 4;
     408             :             }
     409             :         }
     410           0 :         dst += p->linesize[0];
     411             :     }
     412             : 
     413           0 :     dst = p->data[0];
     414           0 :     for (x = 0; x < avctx->width * 2; x += 4) {
     415           0 :         dst[x    ] =        dst[x    ] + L[0];
     416           0 :         dst[x + 2] = L[0] = dst[x + 2] + L[0];
     417           0 :         L[1] = dst[x + 1] + L[1];
     418           0 :         dst[x + 1] = L[1];
     419           0 :         L[2] = dst[x + 3] + L[2];
     420           0 :         dst[x + 3] = L[2];
     421             :     }
     422           0 :     dst += p->linesize[0];
     423             : 
     424           0 :     for (y = 1; y < avctx->height; y++) {
     425           0 :         x = 0;
     426           0 :         dst[x    ] =        dst[x    ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
     427           0 :         dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
     428           0 :         TL[0] = dst[x + 2 - p->linesize[0]];
     429           0 :         L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
     430           0 :         dst[x + 1] = L[1];
     431           0 :         TL[1] = dst[x + 1 - p->linesize[0]];
     432           0 :         L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
     433           0 :         dst[x + 3] = L[2];
     434           0 :         TL[2] = dst[x + 3 - p->linesize[0]];
     435           0 :         for (x = 4; x < avctx->width * 2; x += 4) {
     436           0 :             dst[x    ] =        dst[x    ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
     437           0 :             dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
     438           0 :             TL[0] = dst[x + 2 - p->linesize[0]];
     439           0 :             L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
     440           0 :             dst[x + 1] = L[1];
     441           0 :             TL[1] = dst[x + 1 - p->linesize[0]];
     442           0 :             L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
     443           0 :             dst[x + 3] = L[2];
     444           0 :             TL[2] = dst[x + 3 - p->linesize[0]];
     445             :         }
     446           0 :         dst += p->linesize[0];
     447             :     }
     448             : 
     449           0 :     p->pict_type = AV_PICTURE_TYPE_I;
     450           0 :     p->key_frame = 1;
     451           0 :     *got_frame   = 1;
     452             : 
     453           0 :     return avpkt->size;
     454             : }
     455             : 
     456             : #if HAVE_THREADS
     457           0 : static int init_thread_copy(AVCodecContext *avctx)
     458             : {
     459           0 :     YLCContext *s = avctx->priv_data;
     460             : 
     461           0 :     memset(&s->vlc[0], 0, sizeof(VLC));
     462           0 :     memset(&s->vlc[1], 0, sizeof(VLC));
     463           0 :     memset(&s->vlc[2], 0, sizeof(VLC));
     464           0 :     memset(&s->vlc[3], 0, sizeof(VLC));
     465           0 :     s->table_bits = NULL;
     466           0 :     s->table_bits_size = 0;
     467           0 :     s->bitstream_bits = NULL;
     468           0 :     s->bitstream_bits_size = 0;
     469             : 
     470           0 :     return 0;
     471             : }
     472             : #endif
     473             : 
     474           0 : static av_cold int decode_end(AVCodecContext *avctx)
     475             : {
     476           0 :     YLCContext *s = avctx->priv_data;
     477             : 
     478           0 :     ff_free_vlc(&s->vlc[0]);
     479           0 :     ff_free_vlc(&s->vlc[1]);
     480           0 :     ff_free_vlc(&s->vlc[2]);
     481           0 :     ff_free_vlc(&s->vlc[3]);
     482           0 :     av_freep(&s->table_bits);
     483           0 :     s->table_bits_size = 0;
     484           0 :     av_freep(&s->bitstream_bits);
     485           0 :     s->bitstream_bits_size = 0;
     486             : 
     487           0 :     return 0;
     488             : }
     489             : 
     490             : AVCodec ff_ylc_decoder = {
     491             :     .name           = "ylc",
     492             :     .long_name      = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
     493             :     .type           = AVMEDIA_TYPE_VIDEO,
     494             :     .id             = AV_CODEC_ID_YLC,
     495             :     .priv_data_size = sizeof(YLCContext),
     496             :     .init           = decode_init,
     497             :     .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
     498             :     .close          = decode_end,
     499             :     .decode         = decode_frame,
     500             :     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     501             :     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     502             : };

Generated by: LCOV version 1.13