FFmpeg
txd.c
Go to the documentation of this file.
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 FFmpeg.
8  *
9  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "bytestream.h"
25 #include "avcodec.h"
26 #include "codec_internal.h"
27 #include "decode.h"
28 #include "libavutil/attributes.h"
29 #include "texturedsp.h"
30 
31 #define TXD_DXT1 0x31545844
32 #define TXD_DXT3 0x33545844
33 
35  int *got_frame, AVPacket *avpkt)
36 {
37  GetByteContext gb;
38  TextureDSPContext dxtc;
39  unsigned int version, w, h, d3d_format, depth, stride, flags;
40  unsigned int y, v;
41  uint8_t *ptr;
42  uint32_t *pal;
43  int i, j;
44  int ret;
45 
46  if (avpkt->size < 88)
47  return AVERROR_INVALIDDATA;
48 
49  ff_texturedsp_init(&dxtc);
50 
51  bytestream2_init(&gb, avpkt->data, avpkt->size);
52  version = bytestream2_get_le32(&gb);
53  bytestream2_skip(&gb, 72);
54  d3d_format = bytestream2_get_le32(&gb);
55  w = bytestream2_get_le16(&gb);
56  h = bytestream2_get_le16(&gb);
57  depth = bytestream2_get_byte(&gb);
58  bytestream2_skip(&gb, 2);
59  flags = bytestream2_get_byte(&gb);
60 
61  if (version < 8 || version > 9) {
62  avpriv_report_missing_feature(avctx, "Texture data version %u", version);
63  return AVERROR_PATCHWELCOME;
64  }
65 
66  if (depth == 8) {
67  avctx->pix_fmt = AV_PIX_FMT_PAL8;
68  if (bytestream2_get_bytes_left(&gb) < w * h + 4 * 256)
69  return AVERROR_INVALIDDATA;
70  } else if (depth == 16) {
71  avctx->pix_fmt = AV_PIX_FMT_RGBA;
72  switch (d3d_format) {
73  case 0:
74  if (!(flags & 1))
75  goto unsupported;
77  case TXD_DXT1:
78  if (bytestream2_get_bytes_left(&gb) < AV_CEIL_RSHIFT(w, 2) * AV_CEIL_RSHIFT(h, 2) * 8 + 4)
79  return AVERROR_INVALIDDATA;
80  break;
81  case TXD_DXT3:
82  if (bytestream2_get_bytes_left(&gb) < AV_CEIL_RSHIFT(w, 2) * AV_CEIL_RSHIFT(h, 2) * 16 + 4)
83  return AVERROR_INVALIDDATA;
84  }
85  } else if (depth == 32) {
86  avctx->pix_fmt = AV_PIX_FMT_RGBA;
87  if (bytestream2_get_bytes_left(&gb) < h * w * 4)
88  return AVERROR_INVALIDDATA;
89  } else {
90  avpriv_report_missing_feature(avctx, "Color depth of %u", depth);
91  return AVERROR_PATCHWELCOME;
92  }
93 
94  if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
95  return ret;
96 
97  avctx->coded_width = FFALIGN(w, 4);
98  avctx->coded_height = FFALIGN(h, 4);
99 
100  if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
101  return ret;
102 
103  p->pict_type = AV_PICTURE_TYPE_I;
104 
105  ptr = p->data[0];
106  stride = p->linesize[0];
107 
108  if (depth == 8) {
109  pal = (uint32_t *) p->data[1];
110  for (y = 0; y < 256; y++) {
111  v = bytestream2_get_be32(&gb);
112  pal[y] = (v >> 8) + (v << 24);
113  }
114  bytestream2_skip(&gb, 4);
115  for (y=0; y<h; y++) {
116  bytestream2_get_buffer(&gb, ptr, w);
117  ptr += stride;
118  }
119  } else if (depth == 16) {
120  bytestream2_skip(&gb, 4);
121  switch (d3d_format) {
122  case 0:
123  case TXD_DXT1:
124  for (j = 0; j < avctx->height; j += 4) {
125  for (i = 0; i < avctx->width; i += 4) {
126  uint8_t *p = ptr + i * 4 + j * stride;
127  int step = dxtc.dxt1_block(p, stride, gb.buffer);
128  bytestream2_skip(&gb, step);
129  }
130  }
131  break;
132  case TXD_DXT3:
133  for (j = 0; j < avctx->height; j += 4) {
134  for (i = 0; i < avctx->width; i += 4) {
135  uint8_t *p = ptr + i * 4 + j * stride;
136  int step = dxtc.dxt3_block(p, stride, gb.buffer);
137  bytestream2_skip(&gb, step);
138  }
139  }
140  break;
141  default:
142  goto unsupported;
143  }
144  } else if (depth == 32) {
145  switch (d3d_format) {
146  case 0x15:
147  case 0x16:
148  for (y=0; y<h; y++) {
149  bytestream2_get_buffer(&gb, ptr, w * 4);
150  ptr += stride;
151  }
152  break;
153  default:
154  goto unsupported;
155  }
156  }
157 
158  *got_frame = 1;
159 
160  return avpkt->size;
161 
163  avpriv_report_missing_feature(avctx, "d3d format (%08x)", d3d_format);
164  return AVERROR_PATCHWELCOME;
165 }
166 
168  .p.name = "txd",
169  CODEC_LONG_NAME("Renderware TXD (TeXture Dictionary) image"),
170  .p.type = AVMEDIA_TYPE_VIDEO,
171  .p.id = AV_CODEC_ID_TXD,
172  .p.capabilities = AV_CODEC_CAP_DR1,
174 };
flags
const SwsFlags flags[]
Definition: swscale.c:72
TextureDSPContext::dxt1_block
int(* dxt1_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:46
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition: bytestream.h:158
GetByteContext
Definition: bytestream.h:33
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:435
AV_CODEC_ID_TXD
@ AV_CODEC_ID_TXD
Definition: codec_id.h:157
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
AVPacket::data
uint8_t * data
Definition: packet.h:595
FFCodec
Definition: codec_internal.h:127
TXD_DXT3
#define TXD_DXT3
Definition: txd.c:32
TextureDSPContext
Definition: texturedsp.h:45
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:91
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
texturedsp.h
d3d_format
DXGI_FORMAT d3d_format
Definition: hwcontext_d3d11va.c:94
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:615
TXD_DXT1
#define TXD_DXT1
Definition: txd.c:31
txd_decode_frame
static int txd_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, AVPacket *avpkt)
Definition: txd.c:34
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:347
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
decode.h
ff_texturedsp_init
av_cold void ff_texturedsp_init(TextureDSPContext *c)
Definition: texturedsp.c:640
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:332
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1765
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:596
codec_internal.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
attributes.h
version
version
Definition: libkvazaar.c:313
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
AVCodecContext::height
int height
Definition: avcodec.h:600
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:639
avcodec.h
ff_txd_decoder
const FFCodec ff_txd_decoder
Definition: txd.c:167
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:84
ret
ret
Definition: filter_design.txt:187
AVCodecContext
main external API structure.
Definition: avcodec.h:439
TextureDSPContext::dxt3_block
int(* dxt3_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
Definition: texturedsp.h:49
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:615
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
unsupported
static int unsupported(AVCodecContext *avctx)
Definition: iff.c:1461
w
uint8_t w
Definition: llvidencdsp.c:39
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:572
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:600
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
h
h
Definition: vp9dsp_template.c:2070
stride
#define stride
Definition: h264pred_template.c:536