LCOV - code coverage report
Current view: top level - libavcodec - dxtory.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 33 311 10.6 %
Date: 2017-12-16 01:21:47 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 :         av_log(avctx, AV_LOG_VERBOSE,
     309             :                "Not enough slice data available, "
     310             :                "cropping the frame by %d pixels\n",
     311           0 :                 avctx->height - line);
     312           0 :         avctx->height = line;
     313             :     }
     314             : 
     315           0 :     return 0;
     316             : }
     317             : 
     318             : av_always_inline
     319           0 : static int dx2_decode_slice_5x5(GetBitContext *gb, AVFrame *frame,
     320             :                                 int line, int left, uint8_t lru[3][8],
     321             :                                 int is_565)
     322             : {
     323             :     int x, y;
     324             :     int r, g, b;
     325           0 :     int width    = frame->width;
     326           0 :     int stride   = frame->linesize[0];
     327           0 :     uint8_t *dst = frame->data[0] + stride * line;
     328             : 
     329           0 :     for (y = 0; y < left && get_bits_left(gb) > 16; y++) {
     330           0 :         for (x = 0; x < width; x++) {
     331           0 :             b = decode_sym_565(gb, lru[0], 5);
     332           0 :             g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5);
     333           0 :             r = decode_sym_565(gb, lru[2], 5);
     334           0 :             dst[x * 3 + 0] = (r << 3) | (r >> 2);
     335           0 :             dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2);
     336           0 :             dst[x * 3 + 2] = (b << 3) | (b >> 2);
     337             :         }
     338             : 
     339           0 :         dst += stride;
     340             :     }
     341             : 
     342           0 :     return y;
     343             : }
     344             : 
     345           0 : static void setup_lru_555(uint8_t lru[3][8])
     346             : {
     347           0 :     memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
     348           0 :     memcpy(lru[1], def_lru_555, 8 * sizeof(*def_lru));
     349           0 :     memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
     350           0 : }
     351             : 
     352           0 : static void setup_lru_565(uint8_t lru[3][8])
     353             : {
     354           0 :     memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
     355           0 :     memcpy(lru[1], def_lru_565, 8 * sizeof(*def_lru));
     356           0 :     memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
     357           0 : }
     358             : 
     359           0 : static int dx2_decode_slice_555(GetBitContext *gb, AVFrame *frame,
     360             :                                 int line, int left, uint8_t lru[3][8])
     361             : {
     362           0 :     return dx2_decode_slice_5x5(gb, frame, line, left, lru, 0);
     363             : }
     364             : 
     365           0 : static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame,
     366             :                                 int line, int left, uint8_t lru[3][8])
     367             : {
     368           0 :     return dx2_decode_slice_5x5(gb, frame, line, left, lru, 1);
     369             : }
     370             : 
     371           0 : static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
     372             :                                 const uint8_t *src, int src_size, int is_565)
     373             : {
     374           0 :     enum AVPixelFormat fmt = AV_PIX_FMT_RGB24;
     375           0 :     if (is_565)
     376           0 :         return dxtory_decode_v2(avctx, pic, src, src_size,
     377             :                                 dx2_decode_slice_565,
     378             :                                 setup_lru_565,
     379             :                                 fmt);
     380             :     else
     381           0 :         return dxtory_decode_v2(avctx, pic, src, src_size,
     382             :                                 dx2_decode_slice_555,
     383             :                                 setup_lru_555,
     384             :                                 fmt);
     385             : }
     386             : 
     387           0 : static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame,
     388             :                                 int line, int left, uint8_t lru[3][8])
     389             : {
     390             :     int x, y;
     391           0 :     int width    = frame->width;
     392           0 :     int stride   = frame->linesize[0];
     393           0 :     uint8_t *dst = frame->data[0] + stride * line;
     394             : 
     395           0 :     for (y = 0; y < left && get_bits_left(gb) > 16; y++) {
     396           0 :         for (x = 0; x < width; x++) {
     397           0 :             dst[x * 3 + 0] = decode_sym(gb, lru[0]);
     398           0 :             dst[x * 3 + 1] = decode_sym(gb, lru[1]);
     399           0 :             dst[x * 3 + 2] = decode_sym(gb, lru[2]);
     400             :         }
     401             : 
     402           0 :         dst += stride;
     403             :     }
     404             : 
     405           0 :     return y;
     406             : }
     407             : 
     408           0 : static void default_setup_lru(uint8_t lru[3][8])
     409             : {
     410             :     int i;
     411             : 
     412           0 :     for (i = 0; i < 3; i++)
     413           0 :         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
     414           0 : }
     415             : 
     416           0 : static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
     417             :                                 const uint8_t *src, int src_size)
     418             : {
     419           0 :     return dxtory_decode_v2(avctx, pic, src, src_size,
     420             :                             dx2_decode_slice_rgb,
     421             :                             default_setup_lru,
     422             :                             AV_PIX_FMT_BGR24);
     423             : }
     424             : 
     425           0 : static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame,
     426             :                                 int line, int left,
     427             :                                 uint8_t lru[3][8])
     428             : {
     429             :     int x, y, i, j;
     430           0 :     int width   = frame->width;
     431             : 
     432           0 :     int ystride = frame->linesize[0];
     433           0 :     int ustride = frame->linesize[1];
     434           0 :     int vstride = frame->linesize[2];
     435             : 
     436           0 :     uint8_t *Y  = frame->data[0] + ystride * line;
     437           0 :     uint8_t *U  = frame->data[1] + (ustride >> 2) * line;
     438           0 :     uint8_t *V  = frame->data[2] + (vstride >> 2) * line;
     439             : 
     440           0 :     for (y = 0; y < left - 3 && get_bits_left(gb) > 16; y += 4) {
     441           0 :         for (x = 0; x < width; x += 4) {
     442           0 :             for (j = 0; j < 4; j++)
     443           0 :                 for (i = 0; i < 4; i++)
     444           0 :                     Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
     445           0 :             U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
     446           0 :             V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
     447             :         }
     448             : 
     449           0 :         Y += ystride << 2;
     450           0 :         U += ustride;
     451           0 :         V += vstride;
     452             :     }
     453             : 
     454           0 :     return y;
     455             : }
     456             : 
     457             : 
     458           0 : static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
     459             :                                 const uint8_t *src, int src_size)
     460             : {
     461           0 :     return dxtory_decode_v2(avctx, pic, src, src_size,
     462             :                             dx2_decode_slice_410,
     463             :                             default_setup_lru,
     464             :                             AV_PIX_FMT_YUV410P);
     465             : }
     466             : 
     467           0 : static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame,
     468             :                                 int line, int left,
     469             :                                 uint8_t lru[3][8])
     470             : {
     471             :     int x, y;
     472             : 
     473           0 :     int width    = frame->width;
     474             : 
     475           0 :     int ystride = frame->linesize[0];
     476           0 :     int ustride = frame->linesize[1];
     477           0 :     int vstride = frame->linesize[2];
     478             : 
     479           0 :     uint8_t *Y  = frame->data[0] + ystride * line;
     480           0 :     uint8_t *U  = frame->data[1] + (ustride >> 1) * line;
     481           0 :     uint8_t *V  = frame->data[2] + (vstride >> 1) * line;
     482             : 
     483             : 
     484           0 :     for (y = 0; y < left - 1 && get_bits_left(gb) > 16; y += 2) {
     485           0 :         for (x = 0; x < width; x += 2) {
     486           0 :             Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
     487           0 :             Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
     488           0 :             Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
     489           0 :             Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
     490           0 :             U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
     491           0 :             V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
     492             :         }
     493             : 
     494           0 :         Y += ystride << 1;
     495           0 :         U += ustride;
     496           0 :         V += vstride;
     497             :     }
     498             : 
     499           0 :     return y;
     500             : }
     501             : 
     502           0 : static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
     503             :                                 const uint8_t *src, int src_size)
     504             : {
     505           0 :     return dxtory_decode_v2(avctx, pic, src, src_size,
     506             :                             dx2_decode_slice_420,
     507             :                             default_setup_lru,
     508             :                             AV_PIX_FMT_YUV420P);
     509             : }
     510             : 
     511           0 : static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame,
     512             :                                 int line, int left,
     513             :                                 uint8_t lru[3][8])
     514             : {
     515             :     int x, y;
     516             : 
     517           0 :     int width   = frame->width;
     518             : 
     519           0 :     int ystride = frame->linesize[0];
     520           0 :     int ustride = frame->linesize[1];
     521           0 :     int vstride = frame->linesize[2];
     522             : 
     523           0 :     uint8_t *Y  = frame->data[0] + ystride * line;
     524           0 :     uint8_t *U  = frame->data[1] + ustride * line;
     525           0 :     uint8_t *V  = frame->data[2] + vstride * line;
     526             : 
     527           0 :     for (y = 0; y < left && get_bits_left(gb) > 16; y++) {
     528           0 :         for (x = 0; x < width; x++) {
     529           0 :             Y[x] = decode_sym(gb, lru[0]);
     530           0 :             U[x] = decode_sym(gb, lru[1]) ^ 0x80;
     531           0 :             V[x] = decode_sym(gb, lru[2]) ^ 0x80;
     532             :         }
     533             : 
     534           0 :         Y += ystride;
     535           0 :         U += ustride;
     536           0 :         V += vstride;
     537             :     }
     538             : 
     539           0 :     return y;
     540             : }
     541             : 
     542           0 : static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
     543             :                                 const uint8_t *src, int src_size)
     544             : {
     545           0 :     return dxtory_decode_v2(avctx, pic, src, src_size,
     546             :                             dx2_decode_slice_444,
     547             :                             default_setup_lru,
     548             :                             AV_PIX_FMT_YUV444P);
     549             : }
     550             : 
     551           2 : static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     552             :                         AVPacket *avpkt)
     553             : {
     554           2 :     AVFrame *pic = data;
     555           2 :     const uint8_t *src = avpkt->data;
     556             :     int ret;
     557             : 
     558           2 :     if (avpkt->size < 16) {
     559           0 :         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
     560           0 :         return AVERROR_INVALIDDATA;
     561             :     }
     562             : 
     563           2 :     switch (AV_RB32(src)) {
     564           0 :     case 0x01000001:
     565           0 :         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
     566             :                                    AV_PIX_FMT_BGR24, 3);
     567           0 :         break;
     568           0 :     case 0x01000009:
     569           0 :         ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16);
     570           0 :         break;
     571           2 :     case 0x02000001:
     572           2 :         ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16);
     573           2 :         break;
     574           0 :     case 0x02000009:
     575           0 :         ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16);
     576           0 :         break;
     577           0 :     case 0x03000001:
     578           0 :         ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16);
     579           0 :         break;
     580           0 :     case 0x03000009:
     581           0 :         ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16);
     582           0 :         break;
     583           0 :     case 0x04000001:
     584           0 :         ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16);
     585           0 :         break;
     586           0 :     case 0x04000009:
     587           0 :         ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16);
     588           0 :         break;
     589           0 :     case 0x17000001:
     590           0 :         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
     591             :                                    AV_PIX_FMT_RGB565LE, 2);
     592           0 :         break;
     593           0 :     case 0x17000009:
     594           0 :         ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1);
     595           0 :         break;
     596           0 :     case 0x18000001:
     597             :     case 0x19000001:
     598           0 :         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
     599             :                                    AV_PIX_FMT_RGB555LE, 2);
     600           0 :         break;
     601           0 :     case 0x18000009:
     602             :     case 0x19000009:
     603           0 :         ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0);
     604           0 :         break;
     605           0 :     default:
     606           0 :         avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src));
     607           0 :         return AVERROR_PATCHWELCOME;
     608             :     }
     609             : 
     610           2 :     if (ret)
     611           0 :         return ret;
     612             : 
     613           2 :     pic->pict_type = AV_PICTURE_TYPE_I;
     614           2 :     pic->key_frame = 1;
     615           2 :     *got_frame = 1;
     616             : 
     617           2 :     return avpkt->size;
     618             : }
     619             : 
     620             : AVCodec ff_dxtory_decoder = {
     621             :     .name           = "dxtory",
     622             :     .long_name      = NULL_IF_CONFIG_SMALL("Dxtory"),
     623             :     .type           = AVMEDIA_TYPE_VIDEO,
     624             :     .id             = AV_CODEC_ID_DXTORY,
     625             :     .decode         = decode_frame,
     626             :     .capabilities   = AV_CODEC_CAP_DR1,
     627             : };

Generated by: LCOV version 1.13