Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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. #define BITSTREAM_READER_LE
  26. #include "avcodec.h"
  27. #include "bytestream.h"
  28. #include "get_bits.h"
  29. #include "internal.h"
  30. #include "unary.h"
  31. #include "libavutil/common.h"
  32. #include "libavutil/intreadwrite.h"
  33.  
  34. static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
  35.                                 const uint8_t *src, int src_size,
  36.                                 int id, int bpp)
  37. {
  38.     int h;
  39.     uint8_t *dst;
  40.     int ret;
  41.  
  42.     if (src_size < avctx->width * avctx->height * (int64_t)bpp) {
  43.         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  44.         return AVERROR_INVALIDDATA;
  45.     }
  46.  
  47.     avctx->pix_fmt = id;
  48.     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  49.         return ret;
  50.  
  51.     dst = pic->data[0];
  52.     for (h = 0; h < avctx->height; h++) {
  53.         memcpy(dst, src, avctx->width * bpp);
  54.         src += avctx->width * bpp;
  55.         dst += pic->linesize[0];
  56.     }
  57.  
  58.     return 0;
  59. }
  60.  
  61. static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
  62.                                 const uint8_t *src, int src_size)
  63. {
  64.     int h, w;
  65.     uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
  66.     int ret;
  67.  
  68.     if (src_size < FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) * 9LL / 8) {
  69.         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  70.         return AVERROR_INVALIDDATA;
  71.     }
  72.  
  73.     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
  74.     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  75.         return ret;
  76.  
  77.     Y1 = pic->data[0];
  78.     Y2 = pic->data[0] + pic->linesize[0];
  79.     Y3 = pic->data[0] + pic->linesize[0] * 2;
  80.     Y4 = pic->data[0] + pic->linesize[0] * 3;
  81.     U  = pic->data[1];
  82.     V  = pic->data[2];
  83.     for (h = 0; h < avctx->height; h += 4) {
  84.         for (w = 0; w < avctx->width; w += 4) {
  85.             AV_COPY32U(Y1 + w, src);
  86.             AV_COPY32U(Y2 + w, src + 4);
  87.             AV_COPY32U(Y3 + w, src + 8);
  88.             AV_COPY32U(Y4 + w, src + 12);
  89.             U[w >> 2] = src[16] + 0x80;
  90.             V[w >> 2] = src[17] + 0x80;
  91.             src += 18;
  92.         }
  93.         Y1 += pic->linesize[0] << 2;
  94.         Y2 += pic->linesize[0] << 2;
  95.         Y3 += pic->linesize[0] << 2;
  96.         Y4 += pic->linesize[0] << 2;
  97.         U  += pic->linesize[1];
  98.         V  += pic->linesize[2];
  99.     }
  100.  
  101.     return 0;
  102. }
  103.  
  104. static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
  105.                                 const uint8_t *src, int src_size)
  106. {
  107.     int h, w;
  108.     uint8_t *Y1, *Y2, *U, *V;
  109.     int ret;
  110.  
  111.     if (src_size < FFALIGN(avctx->width, 2) * FFALIGN(avctx->height, 2) * 3LL / 2) {
  112.         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  113.         return AVERROR_INVALIDDATA;
  114.     }
  115.  
  116.     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  117.     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  118.         return ret;
  119.  
  120.     Y1 = pic->data[0];
  121.     Y2 = pic->data[0] + pic->linesize[0];
  122.     U  = pic->data[1];
  123.     V  = pic->data[2];
  124.     for (h = 0; h < avctx->height; h += 2) {
  125.         for (w = 0; w < avctx->width; w += 2) {
  126.             AV_COPY16(Y1 + w, src);
  127.             AV_COPY16(Y2 + w, src + 2);
  128.             U[w >> 1] = src[4] + 0x80;
  129.             V[w >> 1] = src[5] + 0x80;
  130.             src += 6;
  131.         }
  132.         Y1 += pic->linesize[0] << 1;
  133.         Y2 += pic->linesize[0] << 1;
  134.         U  += pic->linesize[1];
  135.         V  += pic->linesize[2];
  136.     }
  137.  
  138.     return 0;
  139. }
  140.  
  141. static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
  142.                                 const uint8_t *src, int src_size)
  143. {
  144.     int h, w;
  145.     uint8_t *Y, *U, *V;
  146.     int ret;
  147.  
  148.     if (src_size < avctx->width * avctx->height * 3LL) {
  149.         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  150.         return AVERROR_INVALIDDATA;
  151.     }
  152.  
  153.     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
  154.     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  155.         return ret;
  156.  
  157.     Y = pic->data[0];
  158.     U = pic->data[1];
  159.     V = pic->data[2];
  160.     for (h = 0; h < avctx->height; h++) {
  161.         for (w = 0; w < avctx->width; w++) {
  162.             Y[w] = *src++;
  163.             U[w] = *src++ ^ 0x80;
  164.             V[w] = *src++ ^ 0x80;
  165.         }
  166.         Y += pic->linesize[0];
  167.         U += pic->linesize[1];
  168.         V += pic->linesize[2];
  169.     }
  170.  
  171.     return 0;
  172. }
  173.  
  174. static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
  175. static const uint8_t def_lru_555[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F };
  176. static const uint8_t def_lru_565[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F };
  177.  
  178. static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
  179. {
  180.     uint8_t c, val;
  181.  
  182.     c = get_unary(gb, 0, 8);
  183.     if (!c) {
  184.         val = get_bits(gb, 8);
  185.         memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
  186.     } else {
  187.         val = lru[c - 1];
  188.         memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
  189.     }
  190.     lru[0] = val;
  191.  
  192.     return val;
  193. }
  194.  
  195. static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8],
  196.                                      int bits)
  197. {
  198.     uint8_t c, val;
  199.  
  200.     c = get_unary(gb, 0, bits);
  201.     if (!c) {
  202.         val = get_bits(gb, bits);
  203.         memmove(lru + 1, lru, sizeof(*lru) * (6 - 1));
  204.     } else {
  205.         val = lru[c - 1];
  206.         memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
  207.     }
  208.     lru[0] = val;
  209.  
  210.     return val;
  211. }
  212.  
  213. static int dx2_decode_slice_565(GetBitContext *gb, int width, int height,
  214.                                 uint8_t *dst, int stride, int is_565)
  215. {
  216.     int x, y;
  217.     int r, g, b;
  218.     uint8_t lru[3][8];
  219.  
  220.     memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
  221.     memcpy(lru[1], is_565 ? def_lru_565 : def_lru_555, 8 * sizeof(*def_lru));
  222.     memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
  223.  
  224.     for (y = 0; y < height; y++) {
  225.         for (x = 0; x < width; x++) {
  226.             b = decode_sym_565(gb, lru[0], 5);
  227.             g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5);
  228.             r = decode_sym_565(gb, lru[2], 5);
  229.             dst[x * 3 + 0] = (r << 3) | (r >> 2);
  230.             dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2);
  231.             dst[x * 3 + 2] = (b << 3) | (b >> 2);
  232.         }
  233.  
  234.         dst += stride;
  235.     }
  236.  
  237.     return 0;
  238. }
  239.  
  240. static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
  241.                                 const uint8_t *src, int src_size, int is_565)
  242. {
  243.     GetByteContext gb;
  244.     GetBitContext  gb2;
  245.     int nslices, slice, slice_height;
  246.     uint32_t off, slice_size;
  247.     uint8_t *dst;
  248.     int ret;
  249.  
  250.     bytestream2_init(&gb, src, src_size);
  251.     nslices = bytestream2_get_le16(&gb);
  252.     off = FFALIGN(nslices * 4 + 2, 16);
  253.     if (src_size < off) {
  254.         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  255.         return AVERROR_INVALIDDATA;
  256.     }
  257.  
  258.     if (!nslices || avctx->height % nslices) {
  259.         avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  260.                               avctx->width, avctx->height);
  261.         return AVERROR_PATCHWELCOME;
  262.     }
  263.  
  264.     slice_height = avctx->height / nslices;
  265.     avctx->pix_fmt = AV_PIX_FMT_RGB24;
  266.     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  267.         return ret;
  268.  
  269.     dst = pic->data[0];
  270.     for (slice = 0; slice < nslices; slice++) {
  271.         slice_size = bytestream2_get_le32(&gb);
  272.         if (slice_size > src_size - off) {
  273.             av_log(avctx, AV_LOG_ERROR,
  274.                    "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
  275.                    slice_size, src_size - off);
  276.             return AVERROR_INVALIDDATA;
  277.         }
  278.         if (slice_size <= 16) {
  279.             av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
  280.             return AVERROR_INVALIDDATA;
  281.         }
  282.  
  283.         if (AV_RL32(src + off) != slice_size - 16) {
  284.             av_log(avctx, AV_LOG_ERROR,
  285.                    "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
  286.                    AV_RL32(src + off), slice_size - 16);
  287.         }
  288.         if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
  289.             return ret;
  290.         dx2_decode_slice_565(&gb2, avctx->width, slice_height, dst,
  291.                              pic->linesize[0], is_565);
  292.  
  293.         dst += pic->linesize[0] * slice_height;
  294.         off += slice_size;
  295.     }
  296.  
  297.     return 0;
  298. }
  299.  
  300. static int dx2_decode_slice_rgb(GetBitContext *gb, int width, int height,
  301.                                 uint8_t *dst, int stride)
  302. {
  303.     int x, y, i;
  304.     uint8_t lru[3][8];
  305.  
  306.     for (i = 0; i < 3; i++)
  307.         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
  308.  
  309.     for (y = 0; y < height; y++) {
  310.         for (x = 0; x < width; x++) {
  311.             dst[x * 3 + 0] = decode_sym(gb, lru[0]);
  312.             dst[x * 3 + 1] = decode_sym(gb, lru[1]);
  313.             dst[x * 3 + 2] = decode_sym(gb, lru[2]);
  314.         }
  315.  
  316.         dst += stride;
  317.     }
  318.  
  319.     return 0;
  320. }
  321.  
  322. static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
  323.                                 const uint8_t *src, int src_size)
  324. {
  325.     GetByteContext gb;
  326.     GetBitContext  gb2;
  327.     int nslices, slice, slice_height;
  328.     uint32_t off, slice_size;
  329.     uint8_t *dst;
  330.     int ret;
  331.  
  332.     bytestream2_init(&gb, src, src_size);
  333.     nslices = bytestream2_get_le16(&gb);
  334.     off = FFALIGN(nslices * 4 + 2, 16);
  335.     if (src_size < off) {
  336.         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  337.         return AVERROR_INVALIDDATA;
  338.     }
  339.  
  340.     if (!nslices || avctx->height % nslices) {
  341.         avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  342.                               avctx->width, avctx->height);
  343.         return AVERROR_PATCHWELCOME;
  344.     }
  345.  
  346.     slice_height = avctx->height / nslices;
  347.     avctx->pix_fmt = AV_PIX_FMT_BGR24;
  348.     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  349.         return ret;
  350.  
  351.     dst = pic->data[0];
  352.     for (slice = 0; slice < nslices; slice++) {
  353.         slice_size = bytestream2_get_le32(&gb);
  354.         if (slice_size > src_size - off) {
  355.             av_log(avctx, AV_LOG_ERROR,
  356.                    "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
  357.                    slice_size, src_size - off);
  358.             return AVERROR_INVALIDDATA;
  359.         }
  360.         if (slice_size <= 16) {
  361.             av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n",
  362.                    slice_size);
  363.             return AVERROR_INVALIDDATA;
  364.         }
  365.  
  366.         if (AV_RL32(src + off) != slice_size - 16) {
  367.             av_log(avctx, AV_LOG_ERROR,
  368.                    "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
  369.                    AV_RL32(src + off), slice_size - 16);
  370.         }
  371.         if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
  372.             return ret;
  373.         dx2_decode_slice_rgb(&gb2, avctx->width, slice_height, dst,
  374.                              pic->linesize[0]);
  375.  
  376.         dst += pic->linesize[0] * slice_height;
  377.         off += slice_size;
  378.     }
  379.  
  380.     return 0;
  381. }
  382.  
  383. static int dx2_decode_slice_410(GetBitContext *gb, int width, int height,
  384.                                 uint8_t *Y, uint8_t *U, uint8_t *V,
  385.                                 int ystride, int ustride, int vstride)
  386. {
  387.     int x, y, i, j;
  388.     uint8_t lru[3][8];
  389.  
  390.     for (i = 0; i < 3; i++)
  391.         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
  392.  
  393.     for (y = 0; y < height; y += 4) {
  394.         for (x = 0; x < width; x += 4) {
  395.             for (j = 0; j < 4; j++)
  396.                 for (i = 0; i < 4; i++)
  397.                     Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
  398.             U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
  399.             V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
  400.         }
  401.  
  402.         Y += ystride << 2;
  403.         U += ustride;
  404.         V += vstride;
  405.     }
  406.  
  407.     return 0;
  408. }
  409.  
  410. static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
  411.                                 const uint8_t *src, int src_size)
  412. {
  413.     GetByteContext gb;
  414.     GetBitContext  gb2;
  415.     int nslices, slice, slice_height;
  416.     int cur_y, next_y;
  417.     uint32_t off, slice_size;
  418.     uint8_t *Y, *U, *V;
  419.     int ret;
  420.  
  421.     bytestream2_init(&gb, src, src_size);
  422.     nslices = bytestream2_get_le16(&gb);
  423.     off = FFALIGN(nslices * 4 + 2, 16);
  424.     if (src_size < off) {
  425.         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  426.         return AVERROR_INVALIDDATA;
  427.     }
  428.  
  429.     if (!nslices) {
  430.         avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  431.                               avctx->width, avctx->height);
  432.         return AVERROR_PATCHWELCOME;
  433.     }
  434.  
  435.     if ((avctx->width & 3) || (avctx->height & 3)) {
  436.         avpriv_request_sample(avctx, "Frame dimensions %dx%d",
  437.                               avctx->width, avctx->height);
  438.     }
  439.  
  440.     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
  441.     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  442.         return ret;
  443.  
  444.     Y = pic->data[0];
  445.     U = pic->data[1];
  446.     V = pic->data[2];
  447.  
  448.     cur_y  = 0;
  449.     for (slice = 0; slice < nslices; slice++) {
  450.         slice_size   = bytestream2_get_le32(&gb);
  451.         next_y = ((slice + 1) * avctx->height) / nslices;
  452.         slice_height = (next_y & ~3) - (cur_y & ~3);
  453.         if (slice_size > src_size - off) {
  454.             av_log(avctx, AV_LOG_ERROR,
  455.                    "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
  456.                    slice_size, src_size - off);
  457.             return AVERROR_INVALIDDATA;
  458.         }
  459.         if (slice_size <= 16) {
  460.             av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
  461.             return AVERROR_INVALIDDATA;
  462.         }
  463.  
  464.         if (AV_RL32(src + off) != slice_size - 16) {
  465.             av_log(avctx, AV_LOG_ERROR,
  466.                    "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
  467.                    AV_RL32(src + off), slice_size - 16);
  468.         }
  469.         if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
  470.             return ret;
  471.         dx2_decode_slice_410(&gb2, avctx->width, slice_height, Y, U, V,
  472.                              pic->linesize[0], pic->linesize[1],
  473.                              pic->linesize[2]);
  474.  
  475.         Y += pic->linesize[0] *  slice_height;
  476.         U += pic->linesize[1] * (slice_height >> 2);
  477.         V += pic->linesize[2] * (slice_height >> 2);
  478.         off += slice_size;
  479.         cur_y   = next_y;
  480.     }
  481.  
  482.     return 0;
  483. }
  484.  
  485. static int dx2_decode_slice_420(GetBitContext *gb, int width, int height,
  486.                                 uint8_t *Y, uint8_t *U, uint8_t *V,
  487.                                 int ystride, int ustride, int vstride)
  488. {
  489.     int x, y, i;
  490.     uint8_t lru[3][8];
  491.  
  492.     for (i = 0; i < 3; i++)
  493.         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
  494.  
  495.     for (y = 0; y < height; y+=2) {
  496.         for (x = 0; x < width; x += 2) {
  497.             Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
  498.             Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
  499.             Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
  500.             Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
  501.             U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
  502.             V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
  503.         }
  504.  
  505.         Y += ystride << 1;
  506.         U += ustride;
  507.         V += vstride;
  508.     }
  509.  
  510.     return 0;
  511. }
  512.  
  513. static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
  514.                                 const uint8_t *src, int src_size)
  515. {
  516.     GetByteContext gb;
  517.     GetBitContext  gb2;
  518.     int nslices, slice, slice_height;
  519.     int cur_y, next_y;
  520.     uint32_t off, slice_size;
  521.     uint8_t *Y, *U, *V;
  522.     int ret;
  523.  
  524.     bytestream2_init(&gb, src, src_size);
  525.     nslices = bytestream2_get_le16(&gb);
  526.     off = FFALIGN(nslices * 4 + 2, 16);
  527.     if (src_size < off) {
  528.         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  529.         return AVERROR_INVALIDDATA;
  530.     }
  531.  
  532.     if (!nslices) {
  533.         avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  534.                               avctx->width, avctx->height);
  535.         return AVERROR_PATCHWELCOME;
  536.     }
  537.  
  538.     if ((avctx->width & 1) || (avctx->height & 1)) {
  539.         avpriv_request_sample(avctx, "Frame dimensions %dx%d",
  540.                               avctx->width, avctx->height);
  541.     }
  542.  
  543.     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  544.     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  545.         return ret;
  546.  
  547.     Y = pic->data[0];
  548.     U = pic->data[1];
  549.     V = pic->data[2];
  550.  
  551.     cur_y  = 0;
  552.     for (slice = 0; slice < nslices; slice++) {
  553.         slice_size   = bytestream2_get_le32(&gb);
  554.         next_y = ((slice + 1) * avctx->height) / nslices;
  555.         slice_height = (next_y & ~1) - (cur_y & ~1);
  556.         if (slice_size > src_size - off) {
  557.             av_log(avctx, AV_LOG_ERROR,
  558.                    "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
  559.                    slice_size, src_size - off);
  560.             return AVERROR_INVALIDDATA;
  561.         }
  562.         if (slice_size <= 16) {
  563.             av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
  564.             return AVERROR_INVALIDDATA;
  565.         }
  566.  
  567.         if (AV_RL32(src + off) != slice_size - 16) {
  568.             av_log(avctx, AV_LOG_ERROR,
  569.                    "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
  570.                    AV_RL32(src + off), slice_size - 16);
  571.         }
  572.         if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
  573.             return ret;
  574.         dx2_decode_slice_420(&gb2, avctx->width, slice_height, Y, U, V,
  575.                              pic->linesize[0], pic->linesize[1],
  576.                              pic->linesize[2]);
  577.  
  578.         Y += pic->linesize[0] *  slice_height;
  579.         U += pic->linesize[1] * (slice_height >> 1);
  580.         V += pic->linesize[2] * (slice_height >> 1);
  581.         off += slice_size;
  582.         cur_y   = next_y;
  583.     }
  584.  
  585.     return 0;
  586. }
  587.  
  588. static int dx2_decode_slice_444(GetBitContext *gb, int width, int height,
  589.                                 uint8_t *Y, uint8_t *U, uint8_t *V,
  590.                                 int ystride, int ustride, int vstride)
  591. {
  592.     int x, y, i;
  593.     uint8_t lru[3][8];
  594.  
  595.     for (i = 0; i < 3; i++)
  596.         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
  597.  
  598.     for (y = 0; y < height; y++) {
  599.         for (x = 0; x < width; x++) {
  600.             Y[x] = decode_sym(gb, lru[0]);
  601.             U[x] = decode_sym(gb, lru[1]) ^ 0x80;
  602.             V[x] = decode_sym(gb, lru[2]) ^ 0x80;
  603.         }
  604.  
  605.         Y += ystride;
  606.         U += ustride;
  607.         V += vstride;
  608.     }
  609.  
  610.     return 0;
  611. }
  612.  
  613. static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
  614.                                 const uint8_t *src, int src_size)
  615. {
  616.     GetByteContext gb;
  617.     GetBitContext  gb2;
  618.     int nslices, slice, slice_height;
  619.     uint32_t off, slice_size;
  620.     uint8_t *Y, *U, *V;
  621.     int ret;
  622.  
  623.     bytestream2_init(&gb, src, src_size);
  624.     nslices = bytestream2_get_le16(&gb);
  625.     off = FFALIGN(nslices * 4 + 2, 16);
  626.     if (src_size < off) {
  627.         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  628.         return AVERROR_INVALIDDATA;
  629.     }
  630.  
  631.     if (!nslices || avctx->height % nslices) {
  632.         avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  633.                               avctx->width, avctx->height);
  634.         return AVERROR_PATCHWELCOME;
  635.     }
  636.  
  637.     slice_height = avctx->height / nslices;
  638.  
  639.     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
  640.     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  641.         return ret;
  642.  
  643.     Y = pic->data[0];
  644.     U = pic->data[1];
  645.     V = pic->data[2];
  646.  
  647.     for (slice = 0; slice < nslices; slice++) {
  648.         slice_size = bytestream2_get_le32(&gb);
  649.         if (slice_size > src_size - off) {
  650.             av_log(avctx, AV_LOG_ERROR,
  651.                    "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
  652.                    slice_size, src_size - off);
  653.             return AVERROR_INVALIDDATA;
  654.         }
  655.         if (slice_size <= 16) {
  656.             av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
  657.             return AVERROR_INVALIDDATA;
  658.         }
  659.  
  660.         if (AV_RL32(src + off) != slice_size - 16) {
  661.             av_log(avctx, AV_LOG_ERROR,
  662.                    "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
  663.                    AV_RL32(src + off), slice_size - 16);
  664.         }
  665.         if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
  666.             return ret;
  667.         dx2_decode_slice_444(&gb2, avctx->width, slice_height, Y, U, V,
  668.                              pic->linesize[0], pic->linesize[1],
  669.                              pic->linesize[2]);
  670.  
  671.         Y += pic->linesize[0] * slice_height;
  672.         U += pic->linesize[1] * slice_height;
  673.         V += pic->linesize[2] * slice_height;
  674.         off += slice_size;
  675.     }
  676.  
  677.     return 0;
  678. }
  679.  
  680. static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
  681.                         AVPacket *avpkt)
  682. {
  683.     AVFrame *pic = data;
  684.     const uint8_t *src = avpkt->data;
  685.     int ret;
  686.  
  687.     if (avpkt->size < 16) {
  688.         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  689.         return AVERROR_INVALIDDATA;
  690.     }
  691.  
  692.     switch (AV_RB32(src)) {
  693.     case 0x01000001:
  694.         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
  695.                                    AV_PIX_FMT_BGR24, 3);
  696.         break;
  697.     case 0x01000009:
  698.         ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16);
  699.         break;
  700.     case 0x02000001:
  701.         ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16);
  702.         break;
  703.     case 0x02000009:
  704.         ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16);
  705.         break;
  706.     case 0x03000001:
  707.         ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16);
  708.         break;
  709.     case 0x03000009:
  710.         ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16);
  711.         break;
  712.     case 0x04000001:
  713.         ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16);
  714.         break;
  715.     case 0x04000009:
  716.         ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16);
  717.         break;
  718.     case 0x17000001:
  719.         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
  720.                                    AV_PIX_FMT_RGB565LE, 2);
  721.         break;
  722.     case 0x17000009:
  723.         ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1);
  724.         break;
  725.     case 0x18000001:
  726.     case 0x19000001:
  727.         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
  728.                                    AV_PIX_FMT_RGB555LE, 2);
  729.         break;
  730.     case 0x18000009:
  731.     case 0x19000009:
  732.         ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0);
  733.         break;
  734.     default:
  735.         avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src));
  736.         return AVERROR_PATCHWELCOME;
  737.     }
  738.  
  739.     if (ret)
  740.         return ret;
  741.  
  742.     pic->pict_type = AV_PICTURE_TYPE_I;
  743.     pic->key_frame = 1;
  744.     *got_frame = 1;
  745.  
  746.     return avpkt->size;
  747. }
  748.  
  749. AVCodec ff_dxtory_decoder = {
  750.     .name           = "dxtory",
  751.     .long_name      = NULL_IF_CONFIG_SMALL("Dxtory"),
  752.     .type           = AVMEDIA_TYPE_VIDEO,
  753.     .id             = AV_CODEC_ID_DXTORY,
  754.     .decode         = decode_frame,
  755.     .capabilities   = AV_CODEC_CAP_DR1,
  756. };
  757.