You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
6.6KB

  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. #define BITSTREAM_READER_LE
  23. #include "avcodec.h"
  24. #include "bytestream.h"
  25. #include "get_bits.h"
  26. #include "internal.h"
  27. #include "unary.h"
  28. #include "libavutil/common.h"
  29. #include "libavutil/intreadwrite.h"
  30. static int dxtory_decode_v1(AVCodecContext *avctx, AVFrame *pic,
  31. const uint8_t *src, int src_size)
  32. {
  33. int h, w;
  34. uint8_t *Y1, *Y2, *U, *V;
  35. int ret;
  36. if (src_size < avctx->width * avctx->height * 3 / 2) {
  37. av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  38. return AVERROR_INVALIDDATA;
  39. }
  40. avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  41. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  42. return ret;
  43. Y1 = pic->data[0];
  44. Y2 = pic->data[0] + pic->linesize[0];
  45. U = pic->data[1];
  46. V = pic->data[2];
  47. for (h = 0; h < avctx->height; h += 2) {
  48. for (w = 0; w < avctx->width; w += 2) {
  49. AV_COPY16(Y1 + w, src);
  50. AV_COPY16(Y2 + w, src + 2);
  51. U[w >> 1] = src[4] + 0x80;
  52. V[w >> 1] = src[5] + 0x80;
  53. src += 6;
  54. }
  55. Y1 += pic->linesize[0] << 1;
  56. Y2 += pic->linesize[0] << 1;
  57. U += pic->linesize[1];
  58. V += pic->linesize[2];
  59. }
  60. return 0;
  61. }
  62. static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
  63. static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
  64. {
  65. uint8_t c, val;
  66. c = get_unary(gb, 0, 8);
  67. if (!c) {
  68. val = get_bits(gb, 8);
  69. memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
  70. } else {
  71. val = lru[c - 1];
  72. memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
  73. }
  74. lru[0] = val;
  75. return val;
  76. }
  77. static int dx2_decode_slice(GetBitContext *gb, int width, int height,
  78. uint8_t *Y, uint8_t *U, uint8_t *V,
  79. int ystride, int ustride, int vstride)
  80. {
  81. int x, y, i;
  82. uint8_t lru[3][8];
  83. for (i = 0; i < 3; i++)
  84. memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
  85. for (y = 0; y < height; y+=2) {
  86. for (x = 0; x < width; x += 2) {
  87. Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
  88. Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
  89. Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
  90. Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
  91. U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
  92. V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
  93. }
  94. Y += ystride << 1;
  95. U += ustride;
  96. V += vstride;
  97. }
  98. return 0;
  99. }
  100. static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
  101. const uint8_t *src, int src_size)
  102. {
  103. GetByteContext gb;
  104. GetBitContext gb2;
  105. int nslices, slice, slice_height;
  106. uint32_t off, slice_size;
  107. uint8_t *Y, *U, *V;
  108. int ret;
  109. bytestream2_init(&gb, src, src_size);
  110. nslices = bytestream2_get_le16(&gb);
  111. off = FFALIGN(nslices * 4 + 2, 16);
  112. if (src_size < off) {
  113. av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  114. return AVERROR_INVALIDDATA;
  115. }
  116. if (!nslices || avctx->height % nslices) {
  117. avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  118. avctx->width, avctx->height);
  119. return AVERROR(ENOSYS);
  120. }
  121. slice_height = avctx->height / nslices;
  122. if ((avctx->width & 1) || (slice_height & 1)) {
  123. avpriv_request_sample(avctx, "slice dimensions %dx%d",
  124. avctx->width, slice_height);
  125. }
  126. avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  127. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  128. return ret;
  129. Y = pic->data[0];
  130. U = pic->data[1];
  131. V = pic->data[2];
  132. for (slice = 0; slice < nslices; slice++) {
  133. slice_size = bytestream2_get_le32(&gb);
  134. if (slice_size > src_size - off) {
  135. av_log(avctx, AV_LOG_ERROR,
  136. "invalid slice size %d (only %d bytes left)\n",
  137. slice_size, src_size - off);
  138. return AVERROR_INVALIDDATA;
  139. }
  140. if (slice_size <= 16) {
  141. av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
  142. return AVERROR_INVALIDDATA;
  143. }
  144. if (AV_RL32(src + off) != slice_size - 16) {
  145. av_log(avctx, AV_LOG_ERROR,
  146. "Slice sizes mismatch: got %d instead of %d\n",
  147. AV_RL32(src + off), slice_size - 16);
  148. }
  149. init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
  150. dx2_decode_slice(&gb2, avctx->width, slice_height, Y, U, V,
  151. pic->linesize[0], pic->linesize[1], pic->linesize[2]);
  152. Y += pic->linesize[0] * slice_height;
  153. U += pic->linesize[1] * (slice_height >> 1);
  154. V += pic->linesize[2] * (slice_height >> 1);
  155. off += slice_size;
  156. }
  157. return 0;
  158. }
  159. static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
  160. AVPacket *avpkt)
  161. {
  162. AVFrame *pic = data;
  163. const uint8_t *src = avpkt->data;
  164. int ret;
  165. if (avpkt->size < 16) {
  166. av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  167. return AVERROR_INVALIDDATA;
  168. }
  169. switch (AV_RB32(src)) {
  170. case 0x02000001:
  171. ret = dxtory_decode_v1(avctx, pic, src + 16, avpkt->size - 16);
  172. break;
  173. case 0x02000009:
  174. ret = dxtory_decode_v2(avctx, pic, src + 16, avpkt->size - 16);
  175. break;
  176. default:
  177. avpriv_request_sample(avctx, "Frame header %X", AV_RB32(src));
  178. return AVERROR_PATCHWELCOME;
  179. }
  180. if (ret)
  181. return ret;
  182. pic->pict_type = AV_PICTURE_TYPE_I;
  183. pic->key_frame = 1;
  184. *got_frame = 1;
  185. return avpkt->size;
  186. }
  187. AVCodec ff_dxtory_decoder = {
  188. .name = "dxtory",
  189. .long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
  190. .type = AVMEDIA_TYPE_VIDEO,
  191. .id = AV_CODEC_ID_DXTORY,
  192. .decode = decode_frame,
  193. .capabilities = CODEC_CAP_DR1,
  194. };