FFmpeg  2.1.1
dxtory.c
Go to the documentation of this file.
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 #define BITSTREAM_READER_LE
24 #include "avcodec.h"
25 #include "bytestream.h"
26 #include "get_bits.h"
27 #include "internal.h"
28 #include "unary.h"
29 #include "libavutil/common.h"
30 #include "libavutil/intreadwrite.h"
31 
32 static int dxtory_decode_v1(AVCodecContext *avctx, AVFrame *pic,
33  const uint8_t *src, int src_size)
34 {
35  int h, w;
36  uint8_t *Y1, *Y2, *U, *V;
37  int ret;
38 
39  if (src_size < avctx->width * avctx->height * 3 / 2) {
40  av_log(avctx, AV_LOG_ERROR, "packet too small\n");
41  return AVERROR_INVALIDDATA;
42  }
43 
44  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
45  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
46  return ret;
47 
48  Y1 = pic->data[0];
49  Y2 = pic->data[0] + pic->linesize[0];
50  U = pic->data[1];
51  V = pic->data[2];
52  for (h = 0; h < avctx->height; h += 2) {
53  for (w = 0; w < avctx->width; w += 2) {
54  AV_COPY16(Y1 + w, src);
55  AV_COPY16(Y2 + w, src + 2);
56  U[w >> 1] = src[4] + 0x80;
57  V[w >> 1] = src[5] + 0x80;
58  src += 6;
59  }
60  Y1 += pic->linesize[0] << 1;
61  Y2 += pic->linesize[0] << 1;
62  U += pic->linesize[1];
63  V += pic->linesize[2];
64  }
65 
66  return 0;
67 }
68 
69 static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
70 
71 static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
72 {
73  uint8_t c, val;
74 
75  c = get_unary(gb, 0, 8);
76  if (!c) {
77  val = get_bits(gb, 8);
78  memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
79  } else {
80  val = lru[c - 1];
81  memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
82  }
83  lru[0] = val;
84 
85  return val;
86 }
87 
88 static int dx2_decode_slice(GetBitContext *gb, int width, int height,
89  uint8_t *Y, uint8_t *U, uint8_t *V,
90  int ystride, int ustride, int vstride)
91 {
92  int x, y, i;
93  uint8_t lru[3][8];
94 
95  for (i = 0; i < 3; i++)
96  memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
97 
98  for (y = 0; y < height; y+=2) {
99  for (x = 0; x < width; x += 2) {
100  Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
101  Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
102  Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
103  Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
104  U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
105  V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
106  }
107 
108  Y += ystride << 1;
109  U += ustride;
110  V += vstride;
111  }
112 
113  return 0;
114 }
115 
116 static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
117  const uint8_t *src, int src_size)
118 {
119  GetByteContext gb;
120  GetBitContext gb2;
121  int nslices, slice, slice_height;
122  uint32_t off, slice_size;
123  uint8_t *Y, *U, *V;
124  int ret;
125 
126  bytestream2_init(&gb, src, src_size);
127  nslices = bytestream2_get_le16(&gb);
128  off = FFALIGN(nslices * 4 + 2, 16);
129  if (src_size < off) {
130  av_log(avctx, AV_LOG_ERROR, "no slice data\n");
131  return AVERROR_INVALIDDATA;
132  }
133 
134  if (!nslices || avctx->height % nslices) {
135  avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
136  avctx->width, avctx->height);
137  return AVERROR(ENOSYS);
138  }
139 
140  slice_height = avctx->height / nslices;
141  if ((avctx->width & 1) || (slice_height & 1)) {
142  avpriv_request_sample(avctx, "slice dimensions %dx%d",
143  avctx->width, slice_height);
144  }
145 
146  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
147  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
148  return ret;
149 
150  Y = pic->data[0];
151  U = pic->data[1];
152  V = pic->data[2];
153 
154  for (slice = 0; slice < nslices; slice++) {
155  slice_size = bytestream2_get_le32(&gb);
156  if (slice_size > src_size - off) {
157  av_log(avctx, AV_LOG_ERROR,
158  "invalid slice size %d (only %d bytes left)\n",
159  slice_size, src_size - off);
160  return AVERROR_INVALIDDATA;
161  }
162  if (slice_size <= 16) {
163  av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
164  return AVERROR_INVALIDDATA;
165  }
166 
167  if (AV_RL32(src + off) != slice_size - 16) {
168  av_log(avctx, AV_LOG_ERROR,
169  "Slice sizes mismatch: got %d instead of %d\n",
170  AV_RL32(src + off), slice_size - 16);
171  }
172  init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
173  dx2_decode_slice(&gb2, avctx->width, slice_height, Y, U, V,
174  pic->linesize[0], pic->linesize[1], pic->linesize[2]);
175 
176  Y += pic->linesize[0] * slice_height;
177  U += pic->linesize[1] * (slice_height >> 1);
178  V += pic->linesize[2] * (slice_height >> 1);
179  off += slice_size;
180  }
181 
182  return 0;
183 }
184 
185 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
186  AVPacket *avpkt)
187 {
188  AVFrame *pic = data;
189  const uint8_t *src = avpkt->data;
190  int ret;
191 
192  if (avpkt->size < 16) {
193  av_log(avctx, AV_LOG_ERROR, "packet too small\n");
194  return AVERROR_INVALIDDATA;
195  }
196 
197  switch (AV_RB32(src)) {
198  case 0x02000001:
199  ret = dxtory_decode_v1(avctx, pic, src + 16, avpkt->size - 16);
200  break;
201  case 0x02000009:
202  ret = dxtory_decode_v2(avctx, pic, src + 16, avpkt->size - 16);
203  break;
204  default:
205  avpriv_request_sample(avctx, "Frame header %X", AV_RB32(src));
206  return AVERROR_PATCHWELCOME;
207  }
208 
209  if (ret)
210  return ret;
211 
213  pic->key_frame = 1;
214  *got_frame = 1;
215 
216  return avpkt->size;
217 }
218 
220  .name = "dxtory",
221  .long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
222  .type = AVMEDIA_TYPE_VIDEO,
223  .id = AV_CODEC_ID_DXTORY,
224  .decode = decode_frame,
225  .capabilities = CODEC_CAP_DR1,
226 };
const char const char void * val
Definition: avisynth_c.h:671
#define AVERROR_PATCHWELCOME
This structure describes decoded (raw) audio or video data.
Definition: frame.h:96
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:255
int size
Definition: avcodec.h:1064
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1342
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:131
AVCodec.
Definition: avcodec.h:2922
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
uint8_t
static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
Definition: dxtory.c:116
#define Y
Definition: vf_boxblur.c:76
const char * name
Name of the codec implementation.
Definition: avcodec.h:2929
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:742
const char data[16]
Definition: mxf.c:68
bitstream reader API header.
#define U(x)
Definition: vp56_arith.h:37
static const uint8_t def_lru[8]
Definition: dxtory.c:69
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: avcodec.h:4147
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:151
Libavcodec external API header.
int off
Definition: dsputil_bfin.c:29
#define V
Definition: options_table.h:35
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:167
float y
ret
Definition: avfilter.c:961
int width
picture width / height.
Definition: avcodec.h:1314
static int dx2_decode_slice(GetBitContext *gb, int width, int height, uint8_t *Y, uint8_t *U, uint8_t *V, int ystride, int ustride, int vstride)
Definition: dxtory.c:88
#define AV_COPY16(d, s)
Definition: intreadwrite.h:574
static uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
Definition: dxtory.c:71
planar YUV 4:2:0, 12bpp, (1 Cr &amp; Cb sample per 2x2 Y samples)
Definition: avcodec.h:4534
AVCodec ff_dxtory_decoder
Definition: dxtory.c:219
static int width
Definition: utils.c:158
AVS_Value src
Definition: avisynth_c.h:523
main external API structure.
Definition: avcodec.h:1146
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:941
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
uint8_t * data
Definition: avcodec.h:1063
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:405
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:124
static int dxtory_decode_v1(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
Definition: dxtory.c:32
common internal api header.
static int get_unary(GetBitContext *gb, int stop, int len)
Get unary code of limited length.
Definition: unary.h:33
static double c[64]
#define FFALIGN(x, a)
Definition: avcodec.h:930
#define AV_RB32(x)
Definition: intreadwrite.h:258
#define AVERROR_INVALIDDATA
#define AV_RL32(x)
Definition: intreadwrite.h:275
int key_frame
1 -&gt; keyframe, 0-&gt; not
Definition: frame.h:162
#define AVERROR(e)
This structure stores compressed data.
Definition: avcodec.h:1040
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:107
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: dxtory.c:185