LCOV - code coverage report
Current view: top level - libavcodec - dxtory.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 33 309 10.7 %
Date: 2018-05-20 11:54:08 Functions: 2 25 8.0 %

          Line data    Source code
       1             : /*
       2             :  * Dxtory decoder
       3             :  *
       4             :  * Copyright (c) 2011 Konstantin Shishkov
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #include <inttypes.h>
      24             : 
      25             : #include "libavutil/common.h"
      26             : #include "libavutil/intreadwrite.h"
      27             : 
      28             : #define BITSTREAM_READER_LE
      29             : #include "avcodec.h"
      30             : #include "bytestream.h"
      31             : #include "get_bits.h"
      32             : #include "internal.h"
      33             : #include "unary.h"
      34             : 
      35           0 : static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
      36             :                                 const uint8_t *src, int src_size,
      37             :                                 int id, int bpp)
      38             : {
      39             :     int h;
      40             :     uint8_t *dst;
      41             :     int ret;
      42             : 
      43           0 :     if (src_size < avctx->width * avctx->height * (int64_t)bpp) {
      44           0 :         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
      45           0 :         return AVERROR_INVALIDDATA;
      46             :     }
      47             : 
      48           0 :     avctx->pix_fmt = id;
      49           0 :     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
      50           0 :         return ret;
      51             : 
      52           0 :     dst = pic->data[0];
      53           0 :     for (h = 0; h < avctx->height; h++) {
      54           0 :         memcpy(dst, src, avctx->width * bpp);
      55           0 :         src += avctx->width * bpp;
      56           0 :         dst += pic->linesize[0];
      57             :     }
      58             : 
      59           0 :     return 0;
      60             : }
      61             : 
      62           0 : static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
      63             :                                 const uint8_t *src, int src_size)
      64             : {
      65             :     int h, w;
      66             :     uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
      67             :     int ret;
      68             : 
      69           0 :     if (src_size < FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) * 9LL / 8) {
      70           0 :         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
      71           0 :         return AVERROR_INVALIDDATA;
      72             :     }
      73             : 
      74           0 :     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
      75           0 :     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
      76           0 :         return ret;
      77             : 
      78           0 :     Y1 = pic->data[0];
      79           0 :     Y2 = pic->data[0] + pic->linesize[0];
      80           0 :     Y3 = pic->data[0] + pic->linesize[0] * 2;
      81           0 :     Y4 = pic->data[0] + pic->linesize[0] * 3;
      82           0 :     U  = pic->data[1];
      83           0 :     V  = pic->data[2];
      84           0 :     for (h = 0; h < avctx->height; h += 4) {
      85           0 :         for (w = 0; w < avctx->width; w += 4) {
      86           0 :             AV_COPY32U(Y1 + w, src);
      87           0 :             AV_COPY32U(Y2 + w, src + 4);
      88           0 :             AV_COPY32U(Y3 + w, src + 8);
      89           0 :             AV_COPY32U(Y4 + w, src + 12);
      90           0 :             U[w >> 2] = src[16] + 0x80;
      91           0 :             V[w >> 2] = src[17] + 0x80;
      92           0 :             src += 18;
      93             :         }
      94           0 :         Y1 += pic->linesize[0] << 2;
      95           0 :         Y2 += pic->linesize[0] << 2;
      96           0 :         Y3 += pic->linesize[0] << 2;
      97           0 :         Y4 += pic->linesize[0] << 2;
      98           0 :         U  += pic->linesize[1];
      99           0 :         V  += pic->linesize[2];
     100             :     }
     101             : 
     102           0 :     return 0;
     103             : }
     104             : 
     105           2 : static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
     106             :                                 const uint8_t *src, int src_size)
     107             : {
     108             :     int h, w;
     109             :     uint8_t *Y1, *Y2, *U, *V;
     110             :     int ret;
     111             : 
     112           2 :     if (src_size < FFALIGN(avctx->width, 2) * FFALIGN(avctx->height, 2) * 3LL / 2) {
     113           0 :         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
     114           0 :         return AVERROR_INVALIDDATA;
     115             :     }
     116             : 
     117           2 :     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     118           2 :     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
     119           0 :         return ret;
     120             : 
     121           2 :     Y1 = pic->data[0];
     122           2 :     Y2 = pic->data[0] + pic->linesize[0];
     123           2 :     U  = pic->data[1];
     124           2 :     V  = pic->data[2];
     125         722 :     for (h = 0; h < avctx->height; h += 2) {
     126      461520 :         for (w = 0; w < avctx->width; w += 2) {
     127      460800 :             AV_COPY16(Y1 + w, src);
     128      460800 :             AV_COPY16(Y2 + w, src + 2);
     129      460800 :             U[w >> 1] = src[4] + 0x80;
     130      460800 :             V[w >> 1] = src[5] + 0x80;
     131      460800 :             src += 6;
     132             :         }
     133         720 :         Y1 += pic->linesize[0] << 1;
     134         720 :         Y2 += pic->linesize[0] << 1;
     135         720 :         U  += pic->linesize[1];
     136         720 :         V  += pic->linesize[2];
     137             :     }
     138             : 
     139           2 :     return 0;
     140             : }
     141             : 
     142           0 : static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
     143             :                                 const uint8_t *src, int src_size)
     144             : {
     145             :     int h, w;
     146             :     uint8_t *Y, *U, *V;
     147             :     int ret;
     148             : 
     149           0 :     if (src_size < avctx->width * avctx->height * 3LL) {
     150           0 :         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
     151           0 :         return AVERROR_INVALIDDATA;
     152             :     }
     153             : 
     154           0 :     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
     155           0 :     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
     156           0 :         return ret;
     157             : 
     158           0 :     Y = pic->data[0];
     159           0 :     U = pic->data[1];
     160           0 :     V = pic->data[2];
     161           0 :     for (h = 0; h < avctx->height; h++) {
     162           0 :         for (w = 0; w < avctx->width; w++) {
     163           0 :             Y[w] = *src++;
     164           0 :             U[w] = *src++ ^ 0x80;
     165           0 :             V[w] = *src++ ^ 0x80;
     166             :         }
     167           0 :         Y += pic->linesize[0];
     168           0 :         U += pic->linesize[1];
     169           0 :         V += pic->linesize[2];
     170             :     }
     171             : 
     172           0 :     return 0;
     173             : }
     174             : 
     175             : static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
     176             : static const uint8_t def_lru_555[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F };
     177             : static const uint8_t def_lru_565[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F };
     178             : 
     179           0 : static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
     180             : {
     181             :     uint8_t c, val;
     182             : 
     183           0 :     c = get_unary(gb, 0, 8);
     184           0 :     if (!c) {
     185           0 :         val = get_bits(gb, 8);
     186           0 :         memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
     187             :     } else {
     188           0 :         val = lru[c - 1];
     189           0 :         memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
     190             :     }
     191           0 :     lru[0] = val;
     192             : 
     193           0 :     return val;
     194             : }
     195             : 
     196           0 : static int check_slice_size(AVCodecContext *avctx,
     197             :                             const uint8_t *src, int src_size,
     198             :                             int slice_size, int off)
     199             : {
     200             :     int cur_slice_size;
     201             : 
     202           0 :     if (slice_size > src_size - off) {
     203           0 :         av_log(avctx, AV_LOG_ERROR,
     204             :                "invalid slice size %d (only %d bytes left)\n",
     205             :                slice_size, src_size - off);
     206           0 :         return AVERROR_INVALIDDATA;
     207             :     }
     208           0 :     if (slice_size <= 16) {
     209           0 :         av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n",
     210             :                slice_size);
     211           0 :         return AVERROR_INVALIDDATA;
     212             :     }
     213             : 
     214           0 :     cur_slice_size = AV_RL32(src + off);
     215           0 :     if (cur_slice_size != slice_size - 16) {
     216           0 :         av_log(avctx, AV_LOG_ERROR,
     217             :                "Slice sizes mismatch: got %d instead of %d\n",
     218             :                cur_slice_size, slice_size - 16);
     219             :     }
     220             : 
     221           0 :     return 0;
     222             : }
     223             : 
     224           0 : static int load_buffer(AVCodecContext *avctx,
     225             :                        const uint8_t *src, int src_size,
     226             :                        GetByteContext *gb,
     227             :                        int *nslices, int *off)
     228             : {
     229           0 :     bytestream2_init(gb, src, src_size);
     230           0 :     *nslices = bytestream2_get_le16(gb);
     231           0 :     *off = FFALIGN(*nslices * 4 + 2, 16);
     232           0 :     if (src_size < *off) {
     233           0 :         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
     234           0 :         return AVERROR_INVALIDDATA;
     235             :     }
     236             : 
     237           0 :     if (!*nslices) {
     238           0 :         avpriv_request_sample(avctx, "%d slices for %dx%d", *nslices,
     239             :                               avctx->width, avctx->height);
     240           0 :         return AVERROR_PATCHWELCOME;
     241             :     }
     242             : 
     243           0 :     return 0;
     244             : }
     245             : 
     246           0 : static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8],
     247             :                                      int bits)
     248             : {
     249             :     uint8_t c, val;
     250             : 
     251           0 :     c = get_unary(gb, 0, bits);
     252           0 :     if (!c) {
     253           0 :         val = get_bits(gb, bits);
     254           0 :         memmove(lru + 1, lru, sizeof(*lru) * (6 - 1));
     255             :     } else {
     256           0 :         val = lru[c - 1];
     257           0 :         memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
     258             :     }
     259           0 :     lru[0] = val;
     260             : 
     261           0 :     return val;
     262             : }
     263             : 
     264             : typedef int (*decode_slice_func)(GetBitContext *gb, AVFrame *frame,
     265             :                                  int line, int height, uint8_t lru[3][8]);
     266             : 
     267             : typedef void (*setup_lru_func)(uint8_t lru[3][8]);
     268             : 
     269           0 : static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
     270             :                             const uint8_t *src, int src_size,
     271             :                             decode_slice_func decode_slice,
     272             :                             setup_lru_func setup_lru,
     273             :                             enum AVPixelFormat fmt)
     274             : {
     275             :     GetByteContext gb;
     276             :     GetBitContext  gb2;
     277           0 :     int nslices, slice, line = 0;
     278             :     uint32_t off, slice_size;
     279             :     uint8_t lru[3][8];
     280             :     int ret;
     281             : 
     282           0 :     ret = load_buffer(avctx, src, src_size, &gb, &nslices, &off);
     283           0 :     if (ret < 0)
     284           0 :         return ret;
     285             : 
     286           0 :     avctx->pix_fmt = fmt;
     287           0 :     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
     288           0 :         return ret;
     289             : 
     290           0 :     for (slice = 0; slice < nslices; slice++) {
     291           0 :         slice_size = bytestream2_get_le32(&gb);
     292             : 
     293           0 :         setup_lru(lru);
     294             : 
     295           0 :         ret = check_slice_size(avctx, src, src_size, slice_size, off);
     296           0 :         if (ret < 0)
     297           0 :             return ret;
     298             : 
     299           0 :         if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
     300           0 :             return ret;
     301             : 
     302           0 :         line += decode_slice(&gb2, pic, line, avctx->height - line, lru);
     303             : 
     304           0 :         off += slice_size;
     305             :     }
     306             : 
     307           0 :     if (avctx->height - line) {
     308           0 :         avpriv_request_sample(avctx, "Not enough slice data available");
     309             :     }
     310             : 
     311           0 :     return 0;
     312             : }
     313             : 
     314             : av_always_inline
     315           0 : static int dx2_decode_slice_5x5(GetBitContext *gb, AVFrame *frame,
     316             :                                 int line, int left, uint8_t lru[3][8],
     317             :                                 int is_565)
     318             : {
     319             :     int x, y;
     320             :     int r, g, b;
     321           0 :     int width    = frame->width;
     322           0 :     int stride   = frame->linesize[0];
     323           0 :     uint8_t *dst = frame->data[0] + stride * line;
     324             : 
     325           0 :     for (y = 0; y < left && get_bits_left(gb) > 6 * width; y++) {
     326           0 :         for (x = 0; x < width; x++) {
     327           0 :             b = decode_sym_565(gb, lru[0], 5);
     328           0 :             g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5);
     329           0 :             r = decode_sym_565(gb, lru[2], 5);
     330           0 :             dst[x * 3 + 0] = (r << 3) | (r >> 2);
     331           0 :             dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2);
     332           0 :             dst[x * 3 + 2] = (b << 3) | (b >> 2);
     333             :         }
     334             : 
     335           0 :         dst += stride;
     336             :     }
     337             : 
     338           0 :     return y;
     339             : }
     340             : 
     341           0 : static void setup_lru_555(uint8_t lru[3][8])
     342             : {
     343           0 :     memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
     344           0 :     memcpy(lru[1], def_lru_555, 8 * sizeof(*def_lru));
     345           0 :     memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
     346           0 : }
     347             : 
     348           0 : static void setup_lru_565(uint8_t lru[3][8])
     349             : {
     350           0 :     memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
     351           0 :     memcpy(lru[1], def_lru_565, 8 * sizeof(*def_lru));
     352           0 :     memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
     353           0 : }
     354             : 
     355           0 : static int dx2_decode_slice_555(GetBitContext *gb, AVFrame *frame,
     356             :                                 int line, int left, uint8_t lru[3][8])
     357             : {
     358           0 :     return dx2_decode_slice_5x5(gb, frame, line, left, lru, 0);
     359             : }
     360             : 
     361           0 : static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame,
     362             :                                 int line, int left, uint8_t lru[3][8])
     363             : {
     364           0 :     return dx2_decode_slice_5x5(gb, frame, line, left, lru, 1);
     365             : }
     366             : 
     367           0 : static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
     368             :                                 const uint8_t *src, int src_size, int is_565)
     369             : {
     370           0 :     enum AVPixelFormat fmt = AV_PIX_FMT_RGB24;
     371           0 :     if (is_565)
     372           0 :         return dxtory_decode_v2(avctx, pic, src, src_size,
     373             :                                 dx2_decode_slice_565,
     374             :                                 setup_lru_565,
     375             :                                 fmt);
     376             :     else
     377           0 :         return dxtory_decode_v2(avctx, pic, src, src_size,
     378             :                                 dx2_decode_slice_555,
     379             :                                 setup_lru_555,
     380             :                                 fmt);
     381             : }
     382             : 
     383           0 : static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame,
     384             :                                 int line, int left, uint8_t lru[3][8])
     385             : {
     386             :     int x, y;
     387           0 :     int width    = frame->width;
     388           0 :     int stride   = frame->linesize[0];
     389           0 :     uint8_t *dst = frame->data[0] + stride * line;
     390             : 
     391           0 :     for (y = 0; y < left && get_bits_left(gb) > 6 * width; y++) {
     392           0 :         for (x = 0; x < width; x++) {
     393           0 :             dst[x * 3 + 0] = decode_sym(gb, lru[0]);
     394           0 :             dst[x * 3 + 1] = decode_sym(gb, lru[1]);
     395           0 :             dst[x * 3 + 2] = decode_sym(gb, lru[2]);
     396             :         }
     397             : 
     398           0 :         dst += stride;
     399             :     }
     400             : 
     401           0 :     return y;
     402             : }
     403             : 
     404           0 : static void default_setup_lru(uint8_t lru[3][8])
     405             : {
     406             :     int i;
     407             : 
     408           0 :     for (i = 0; i < 3; i++)
     409           0 :         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
     410           0 : }
     411             : 
     412           0 : static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
     413             :                                 const uint8_t *src, int src_size)
     414             : {
     415           0 :     return dxtory_decode_v2(avctx, pic, src, src_size,
     416             :                             dx2_decode_slice_rgb,
     417             :                             default_setup_lru,
     418             :                             AV_PIX_FMT_BGR24);
     419             : }
     420             : 
     421           0 : static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame,
     422             :                                 int line, int left,
     423             :                                 uint8_t lru[3][8])
     424             : {
     425             :     int x, y, i, j;
     426           0 :     int width   = frame->width;
     427             : 
     428           0 :     int ystride = frame->linesize[0];
     429           0 :     int ustride = frame->linesize[1];
     430           0 :     int vstride = frame->linesize[2];
     431             : 
     432           0 :     uint8_t *Y  = frame->data[0] + ystride * line;
     433           0 :     uint8_t *U  = frame->data[1] + (ustride >> 2) * line;
     434           0 :     uint8_t *V  = frame->data[2] + (vstride >> 2) * line;
     435             : 
     436           0 :     for (y = 0; y < left - 3 && get_bits_left(gb) > 9 * width; y += 4) {
     437           0 :         for (x = 0; x < width; x += 4) {
     438           0 :             for (j = 0; j < 4; j++)
     439           0 :                 for (i = 0; i < 4; i++)
     440           0 :                     Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
     441           0 :             U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
     442           0 :             V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
     443             :         }
     444             : 
     445           0 :         Y += ystride << 2;
     446           0 :         U += ustride;
     447           0 :         V += vstride;
     448             :     }
     449             : 
     450           0 :     return y;
     451             : }
     452             : 
     453             : 
     454           0 : static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
     455             :                                 const uint8_t *src, int src_size)
     456             : {
     457           0 :     return dxtory_decode_v2(avctx, pic, src, src_size,
     458             :                             dx2_decode_slice_410,
     459             :                             default_setup_lru,
     460             :                             AV_PIX_FMT_YUV410P);
     461             : }
     462             : 
     463           0 : static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame,
     464             :                                 int line, int left,
     465             :                                 uint8_t lru[3][8])
     466             : {
     467             :     int x, y;
     468             : 
     469           0 :     int width    = frame->width;
     470             : 
     471           0 :     int ystride = frame->linesize[0];
     472           0 :     int ustride = frame->linesize[1];
     473           0 :     int vstride = frame->linesize[2];
     474             : 
     475           0 :     uint8_t *Y  = frame->data[0] + ystride * line;
     476           0 :     uint8_t *U  = frame->data[1] + (ustride >> 1) * line;
     477           0 :     uint8_t *V  = frame->data[2] + (vstride >> 1) * line;
     478             : 
     479             : 
     480           0 :     for (y = 0; y < left - 1 && get_bits_left(gb) > 6 * width; y += 2) {
     481           0 :         for (x = 0; x < width; x += 2) {
     482           0 :             Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
     483           0 :             Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
     484           0 :             Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
     485           0 :             Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
     486           0 :             U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
     487           0 :             V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
     488             :         }
     489             : 
     490           0 :         Y += ystride << 1;
     491           0 :         U += ustride;
     492           0 :         V += vstride;
     493             :     }
     494             : 
     495           0 :     return y;
     496             : }
     497             : 
     498           0 : static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
     499             :                                 const uint8_t *src, int src_size)
     500             : {
     501           0 :     return dxtory_decode_v2(avctx, pic, src, src_size,
     502             :                             dx2_decode_slice_420,
     503             :                             default_setup_lru,
     504             :                             AV_PIX_FMT_YUV420P);
     505             : }
     506             : 
     507           0 : static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame,
     508             :                                 int line, int left,
     509             :                                 uint8_t lru[3][8])
     510             : {
     511             :     int x, y;
     512             : 
     513           0 :     int width   = frame->width;
     514             : 
     515           0 :     int ystride = frame->linesize[0];
     516           0 :     int ustride = frame->linesize[1];
     517           0 :     int vstride = frame->linesize[2];
     518             : 
     519           0 :     uint8_t *Y  = frame->data[0] + ystride * line;
     520           0 :     uint8_t *U  = frame->data[1] + ustride * line;
     521           0 :     uint8_t *V  = frame->data[2] + vstride * line;
     522             : 
     523           0 :     for (y = 0; y < left && get_bits_left(gb) > 6 * width; y++) {
     524           0 :         for (x = 0; x < width; x++) {
     525           0 :             Y[x] = decode_sym(gb, lru[0]);
     526           0 :             U[x] = decode_sym(gb, lru[1]) ^ 0x80;
     527           0 :             V[x] = decode_sym(gb, lru[2]) ^ 0x80;
     528             :         }
     529             : 
     530           0 :         Y += ystride;
     531           0 :         U += ustride;
     532           0 :         V += vstride;
     533             :     }
     534             : 
     535           0 :     return y;
     536             : }
     537             : 
     538           0 : static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
     539             :                                 const uint8_t *src, int src_size)
     540             : {
     541           0 :     return dxtory_decode_v2(avctx, pic, src, src_size,
     542             :                             dx2_decode_slice_444,
     543             :                             default_setup_lru,
     544             :                             AV_PIX_FMT_YUV444P);
     545             : }
     546             : 
     547           2 : static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     548             :                         AVPacket *avpkt)
     549             : {
     550           2 :     AVFrame *pic = data;
     551           2 :     const uint8_t *src = avpkt->data;
     552             :     int ret;
     553             : 
     554           2 :     if (avpkt->size < 16) {
     555           0 :         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
     556           0 :         return AVERROR_INVALIDDATA;
     557             :     }
     558             : 
     559           2 :     switch (AV_RB32(src)) {
     560           0 :     case 0x01000001:
     561           0 :         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
     562             :                                    AV_PIX_FMT_BGR24, 3);
     563           0 :         break;
     564           0 :     case 0x01000009:
     565           0 :         ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16);
     566           0 :         break;
     567           2 :     case 0x02000001:
     568           2 :         ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16);
     569           2 :         break;
     570           0 :     case 0x02000009:
     571           0 :         ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16);
     572           0 :         break;
     573           0 :     case 0x03000001:
     574           0 :         ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16);
     575           0 :         break;
     576           0 :     case 0x03000009:
     577           0 :         ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16);
     578           0 :         break;
     579           0 :     case 0x04000001:
     580           0 :         ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16);
     581           0 :         break;
     582           0 :     case 0x04000009:
     583           0 :         ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16);
     584           0 :         break;
     585           0 :     case 0x17000001:
     586           0 :         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
     587             :                                    AV_PIX_FMT_RGB565LE, 2);
     588           0 :         break;
     589           0 :     case 0x17000009:
     590           0 :         ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1);
     591           0 :         break;
     592           0 :     case 0x18000001:
     593             :     case 0x19000001:
     594           0 :         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
     595             :                                    AV_PIX_FMT_RGB555LE, 2);
     596           0 :         break;
     597           0 :     case 0x18000009:
     598             :     case 0x19000009:
     599           0 :         ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0);
     600           0 :         break;
     601           0 :     default:
     602           0 :         avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src));
     603           0 :         return AVERROR_PATCHWELCOME;
     604             :     }
     605             : 
     606           2 :     if (ret)
     607           0 :         return ret;
     608             : 
     609           2 :     pic->pict_type = AV_PICTURE_TYPE_I;
     610           2 :     pic->key_frame = 1;
     611           2 :     *got_frame = 1;
     612             : 
     613           2 :     return avpkt->size;
     614             : }
     615             : 
     616             : AVCodec ff_dxtory_decoder = {
     617             :     .name           = "dxtory",
     618             :     .long_name      = NULL_IF_CONFIG_SMALL("Dxtory"),
     619             :     .type           = AVMEDIA_TYPE_VIDEO,
     620             :     .id             = AV_CODEC_ID_DXTORY,
     621             :     .decode         = decode_frame,
     622             :     .capabilities   = AV_CODEC_CAP_DR1,
     623             : };

Generated by: LCOV version 1.13