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.

233 lines
6.8KB

  1. /*
  2. * Dxtory decoder
  3. *
  4. * Copyright (c) 2011 Konstantin Shishkov
  5. *
  6. * This file is part of Libav.
  7. *
  8. * Libav 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. * Libav 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 Libav; 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. 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, ref_slice_height;
  106. int cur_y, next_y;
  107. uint32_t off, slice_size;
  108. uint8_t *Y, *U, *V;
  109. int ret;
  110. bytestream2_init(&gb, src, src_size);
  111. nslices = bytestream2_get_le16(&gb);
  112. off = FFALIGN(nslices * 4 + 2, 16);
  113. if (src_size < off) {
  114. av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  115. return AVERROR_INVALIDDATA;
  116. }
  117. if (!nslices || avctx->height % nslices) {
  118. avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  119. avctx->width, avctx->height);
  120. return AVERROR_PATCHWELCOME;
  121. }
  122. ref_slice_height = avctx->height / nslices;
  123. if ((avctx->width & 1) || (avctx->height & 1)) {
  124. avpriv_request_sample(avctx, "Frame dimensions %dx%d",
  125. avctx->width, avctx->height);
  126. }
  127. avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  128. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  129. return ret;
  130. Y = pic->data[0];
  131. U = pic->data[1];
  132. V = pic->data[2];
  133. cur_y = 0;
  134. next_y = ref_slice_height;
  135. for (slice = 0; slice < nslices; slice++) {
  136. slice_size = bytestream2_get_le32(&gb);
  137. slice_height = (next_y & ~1) - (cur_y & ~1);
  138. if (slice_size > src_size - off) {
  139. av_log(avctx, AV_LOG_ERROR,
  140. "invalid slice size %d (only %d bytes left)\n",
  141. slice_size, src_size - off);
  142. return AVERROR_INVALIDDATA;
  143. }
  144. if (slice_size <= 16) {
  145. av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
  146. return AVERROR_INVALIDDATA;
  147. }
  148. if (AV_RL32(src + off) != slice_size - 16) {
  149. av_log(avctx, AV_LOG_ERROR,
  150. "Slice sizes mismatch: got %d instead of %d\n",
  151. AV_RL32(src + off), slice_size - 16);
  152. }
  153. init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
  154. dx2_decode_slice(&gb2, avctx->width, slice_height, Y, U, V,
  155. pic->linesize[0], pic->linesize[1], pic->linesize[2]);
  156. Y += pic->linesize[0] * slice_height;
  157. U += pic->linesize[1] * (slice_height >> 1);
  158. V += pic->linesize[2] * (slice_height >> 1);
  159. off += slice_size;
  160. cur_y = next_y;
  161. next_y += ref_slice_height;
  162. }
  163. return 0;
  164. }
  165. static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
  166. AVPacket *avpkt)
  167. {
  168. AVFrame *pic = data;
  169. const uint8_t *src = avpkt->data;
  170. int ret;
  171. if (avpkt->size < 16) {
  172. av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  173. return AVERROR_INVALIDDATA;
  174. }
  175. switch (AV_RB32(src)) {
  176. case 0x02000001:
  177. ret = dxtory_decode_v1(avctx, pic, src + 16, avpkt->size - 16);
  178. break;
  179. case 0x02000009:
  180. ret = dxtory_decode_v2(avctx, pic, src + 16, avpkt->size - 16);
  181. break;
  182. default:
  183. avpriv_request_sample(avctx, "Frame header %X", AV_RB32(src));
  184. return AVERROR_PATCHWELCOME;
  185. }
  186. if (ret)
  187. return ret;
  188. pic->pict_type = AV_PICTURE_TYPE_I;
  189. pic->key_frame = 1;
  190. *got_frame = 1;
  191. return avpkt->size;
  192. }
  193. AVCodec ff_dxtory_decoder = {
  194. .name = "dxtory",
  195. .long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
  196. .type = AVMEDIA_TYPE_VIDEO,
  197. .id = AV_CODEC_ID_DXTORY,
  198. .decode = decode_frame,
  199. .capabilities = CODEC_CAP_DR1,
  200. };