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.

157 lines
4.7KB

  1. /*
  2. * Renderware TeXture Dictionary (.txd) image decoder
  3. * Copyright (c) 2007 Ivo van Poorten
  4. *
  5. * See also: http://wiki.multimedia.cx/index.php?title=TXD
  6. *
  7. * This file is part of Libav.
  8. *
  9. * Libav is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * Libav is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with Libav; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. #include "libavutil/intreadwrite.h"
  24. #include "libavutil/imgutils.h"
  25. #include "avcodec.h"
  26. #include "bytestream.h"
  27. #include "internal.h"
  28. #include "texturedsp.h"
  29. #define TXD_DXT1 0x31545844
  30. #define TXD_DXT3 0x33545844
  31. static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
  32. AVPacket *avpkt) {
  33. GetByteContext gb;
  34. TextureDSPContext dxtc;
  35. AVFrame * const p = data;
  36. unsigned int version, w, h, d3d_format, depth, stride, flags;
  37. unsigned int y, v;
  38. uint8_t *ptr;
  39. uint32_t *pal;
  40. int i, j;
  41. int ret;
  42. ff_texturedsp_init(&dxtc);
  43. bytestream2_init(&gb, avpkt->data, avpkt->size);
  44. version = bytestream2_get_le32(&gb);
  45. bytestream2_skip(&gb, 72);
  46. d3d_format = bytestream2_get_le32(&gb);
  47. w = bytestream2_get_le16(&gb);
  48. h = bytestream2_get_le16(&gb);
  49. depth = bytestream2_get_byte(&gb);
  50. bytestream2_skip(&gb, 2);
  51. flags = bytestream2_get_byte(&gb);
  52. if (version < 8 || version > 9) {
  53. avpriv_report_missing_feature(avctx, "Texture data version %u", version);
  54. return AVERROR_PATCHWELCOME;
  55. }
  56. if (depth == 8) {
  57. avctx->pix_fmt = AV_PIX_FMT_PAL8;
  58. } else if (depth == 16 || depth == 32) {
  59. avctx->pix_fmt = AV_PIX_FMT_RGBA;
  60. } else {
  61. avpriv_report_missing_feature(avctx, "Color depth of %u", depth);
  62. return AVERROR_PATCHWELCOME;
  63. }
  64. if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
  65. return ret;
  66. avctx->coded_width = FFALIGN(w, 4);
  67. avctx->coded_height = FFALIGN(h, 4);
  68. if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
  69. av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
  70. return ret;
  71. }
  72. p->pict_type = AV_PICTURE_TYPE_I;
  73. ptr = p->data[0];
  74. stride = p->linesize[0];
  75. if (depth == 8) {
  76. pal = (uint32_t *) p->data[1];
  77. for (y = 0; y < 256; y++) {
  78. v = bytestream2_get_be32(&gb);
  79. pal[y] = (v >> 8) + (v << 24);
  80. }
  81. bytestream2_skip(&gb, 4);
  82. for (y=0; y<h; y++) {
  83. bytestream2_get_buffer(&gb, ptr, w);
  84. ptr += stride;
  85. }
  86. } else if (depth == 16) {
  87. bytestream2_skip(&gb, 4);
  88. switch (d3d_format) {
  89. case 0:
  90. if (!(flags & 1))
  91. goto unsupported;
  92. case TXD_DXT1:
  93. for (j = 0; j < avctx->height; j += 4) {
  94. for (i = 0; i < avctx->width; i += 4) {
  95. uint8_t *p = ptr + i * 4 + j * stride;
  96. int step = dxtc.dxt1_block(p, stride, gb.buffer);
  97. bytestream2_skip(&gb, step);
  98. }
  99. }
  100. break;
  101. case TXD_DXT3:
  102. for (j = 0; j < avctx->height; j += 4) {
  103. for (i = 0; i < avctx->width; i += 4) {
  104. uint8_t *p = ptr + i * 4 + j * stride;
  105. int step = dxtc.dxt3_block(p, stride, gb.buffer);
  106. bytestream2_skip(&gb, step);
  107. }
  108. }
  109. break;
  110. default:
  111. goto unsupported;
  112. }
  113. } else if (depth == 32) {
  114. switch (d3d_format) {
  115. case 0x15:
  116. case 0x16:
  117. for (y=0; y<h; y++) {
  118. bytestream2_get_buffer(&gb, ptr, w * 4);
  119. ptr += stride;
  120. }
  121. break;
  122. default:
  123. goto unsupported;
  124. }
  125. }
  126. *got_frame = 1;
  127. return avpkt->size;
  128. unsupported:
  129. avpriv_report_missing_feature(avctx, "d3d format (%08x)", d3d_format);
  130. return AVERROR_PATCHWELCOME;
  131. }
  132. AVCodec ff_txd_decoder = {
  133. .name = "txd",
  134. .long_name = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"),
  135. .type = AVMEDIA_TYPE_VIDEO,
  136. .id = AV_CODEC_ID_TXD,
  137. .decode = txd_decode_frame,
  138. .capabilities = AV_CODEC_CAP_DR1,
  139. };