FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 #include <inttypes.h>
24 
25 #define BITSTREAM_READER_LE
26 #include "avcodec.h"
27 #include "bytestream.h"
28 #include "get_bits.h"
29 #include "internal.h"
30 #include "unary.h"
31 #include "libavutil/common.h"
32 #include "libavutil/intreadwrite.h"
33 
35  const uint8_t *src, int src_size,
36  int id, int bpp)
37 {
38  int h;
39  uint8_t *dst;
40  int ret;
41 
42  if (src_size < avctx->width * avctx->height * (int64_t)bpp) {
43  av_log(avctx, AV_LOG_ERROR, "packet too small\n");
44  return AVERROR_INVALIDDATA;
45  }
46 
47  avctx->pix_fmt = id;
48  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
49  return ret;
50 
51  dst = pic->data[0];
52  for (h = 0; h < avctx->height; h++) {
53  memcpy(dst, src, avctx->width * bpp);
54  src += avctx->width * bpp;
55  dst += pic->linesize[0];
56  }
57 
58  return 0;
59 }
60 
62  const uint8_t *src, int src_size)
63 {
64  int h, w;
65  uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
66  int ret;
67 
68  if (src_size < avctx->width * avctx->height * 9LL / 8) {
69  av_log(avctx, AV_LOG_ERROR, "packet too small\n");
70  return AVERROR_INVALIDDATA;
71  }
72 
73  avctx->pix_fmt = AV_PIX_FMT_YUV410P;
74  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
75  return ret;
76 
77  Y1 = pic->data[0];
78  Y2 = pic->data[0] + pic->linesize[0];
79  Y3 = pic->data[0] + pic->linesize[0] * 2;
80  Y4 = pic->data[0] + pic->linesize[0] * 3;
81  U = pic->data[1];
82  V = pic->data[2];
83  for (h = 0; h < avctx->height; h += 4) {
84  for (w = 0; w < avctx->width; w += 4) {
85  AV_COPY32U(Y1 + w, src);
86  AV_COPY32U(Y2 + w, src + 4);
87  AV_COPY32U(Y3 + w, src + 8);
88  AV_COPY32U(Y4 + w, src + 12);
89  U[w >> 2] = src[16] + 0x80;
90  V[w >> 2] = src[17] + 0x80;
91  src += 18;
92  }
93  Y1 += pic->linesize[0] << 2;
94  Y2 += pic->linesize[0] << 2;
95  Y3 += pic->linesize[0] << 2;
96  Y4 += pic->linesize[0] << 2;
97  U += pic->linesize[1];
98  V += pic->linesize[2];
99  }
100 
101  return 0;
102 }
103 
105  const uint8_t *src, int src_size)
106 {
107  int h, w;
108  uint8_t *Y1, *Y2, *U, *V;
109  int ret;
110 
111  if (src_size < avctx->width * avctx->height * 3LL / 2) {
112  av_log(avctx, AV_LOG_ERROR, "packet too small\n");
113  return AVERROR_INVALIDDATA;
114  }
115 
116  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
117  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
118  return ret;
119 
120  Y1 = pic->data[0];
121  Y2 = pic->data[0] + pic->linesize[0];
122  U = pic->data[1];
123  V = pic->data[2];
124  for (h = 0; h < avctx->height; h += 2) {
125  for (w = 0; w < avctx->width; w += 2) {
126  AV_COPY16(Y1 + w, src);
127  AV_COPY16(Y2 + w, src + 2);
128  U[w >> 1] = src[4] + 0x80;
129  V[w >> 1] = src[5] + 0x80;
130  src += 6;
131  }
132  Y1 += pic->linesize[0] << 1;
133  Y2 += pic->linesize[0] << 1;
134  U += pic->linesize[1];
135  V += pic->linesize[2];
136  }
137 
138  return 0;
139 }
140 
142  const uint8_t *src, int src_size)
143 {
144  int h, w;
145  uint8_t *Y, *U, *V;
146  int ret;
147 
148  if (src_size < avctx->width * avctx->height * 3LL) {
149  av_log(avctx, AV_LOG_ERROR, "packet too small\n");
150  return AVERROR_INVALIDDATA;
151  }
152 
153  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
154  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
155  return ret;
156 
157  Y = pic->data[0];
158  U = pic->data[1];
159  V = pic->data[2];
160  for (h = 0; h < avctx->height; h++) {
161  for (w = 0; w < avctx->width; w++) {
162  Y[w] = *src++;
163  U[w] = *src++ ^ 0x80;
164  V[w] = *src++ ^ 0x80;
165  }
166  Y += pic->linesize[0];
167  U += pic->linesize[1];
168  V += pic->linesize[2];
169  }
170 
171  return 0;
172 }
173 
174 static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
175 static const uint8_t def_lru_555[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F };
176 static const uint8_t def_lru_565[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F };
177 
178 static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
179 {
180  uint8_t c, val;
181 
182  c = get_unary(gb, 0, 8);
183  if (!c) {
184  val = get_bits(gb, 8);
185  memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
186  } else {
187  val = lru[c - 1];
188  memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
189  }
190  lru[0] = val;
191 
192  return val;
193 }
194 
195 static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8],
196  int bits)
197 {
198  uint8_t c, val;
199 
200  c = get_unary(gb, 0, bits);
201  if (!c) {
202  val = get_bits(gb, bits);
203  memmove(lru + 1, lru, sizeof(*lru) * (6 - 1));
204  } else {
205  val = lru[c - 1];
206  memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
207  }
208  lru[0] = val;
209 
210  return val;
211 }
212 
214  uint8_t *dst, int stride, int is_565)
215 {
216  int x, y;
217  int r, g, b;
218  uint8_t lru[3][8];
219 
220  memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
221  memcpy(lru[1], is_565 ? def_lru_565 : def_lru_555, 8 * sizeof(*def_lru));
222  memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
223 
224  for (y = 0; y < height; y++) {
225  for (x = 0; x < width; x++) {
226  b = decode_sym_565(gb, lru[0], 5);
227  g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5);
228  r = decode_sym_565(gb, lru[2], 5);
229  dst[x * 3 + 0] = (r << 3) | (r >> 2);
230  dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2);
231  dst[x * 3 + 2] = (b << 3) | (b >> 2);
232  }
233 
234  dst += stride;
235  }
236 
237  return 0;
238 }
239 
241  const uint8_t *src, int src_size, int is_565)
242 {
243  GetByteContext gb;
244  GetBitContext gb2;
245  int nslices, slice, slice_height;
246  uint32_t off, slice_size;
247  uint8_t *dst;
248  int ret;
249 
250  bytestream2_init(&gb, src, src_size);
251  nslices = bytestream2_get_le16(&gb);
252  off = FFALIGN(nslices * 4 + 2, 16);
253  if (src_size < off) {
254  av_log(avctx, AV_LOG_ERROR, "no slice data\n");
255  return AVERROR_INVALIDDATA;
256  }
257 
258  if (!nslices || avctx->height % nslices) {
259  avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
260  avctx->width, avctx->height);
261  return AVERROR_PATCHWELCOME;
262  }
263 
264  slice_height = avctx->height / nslices;
265  avctx->pix_fmt = AV_PIX_FMT_RGB24;
266  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
267  return ret;
268 
269  dst = pic->data[0];
270  for (slice = 0; slice < nslices; slice++) {
271  slice_size = bytestream2_get_le32(&gb);
272  if (slice_size > src_size - off) {
273  av_log(avctx, AV_LOG_ERROR,
274  "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
275  slice_size, src_size - off);
276  return AVERROR_INVALIDDATA;
277  }
278  if (slice_size <= 16) {
279  av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
280  return AVERROR_INVALIDDATA;
281  }
282 
283  if (AV_RL32(src + off) != slice_size - 16) {
284  av_log(avctx, AV_LOG_ERROR,
285  "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
286  AV_RL32(src + off), slice_size - 16);
287  }
288  if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
289  return ret;
290  dx2_decode_slice_565(&gb2, avctx->width, slice_height, dst,
291  pic->linesize[0], is_565);
292 
293  dst += pic->linesize[0] * slice_height;
294  off += slice_size;
295  }
296 
297  return 0;
298 }
299 
301  uint8_t *dst, int stride)
302 {
303  int x, y, i;
304  uint8_t lru[3][8];
305 
306  for (i = 0; i < 3; i++)
307  memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
308 
309  for (y = 0; y < height; y++) {
310  for (x = 0; x < width; x++) {
311  dst[x * 3 + 0] = decode_sym(gb, lru[0]);
312  dst[x * 3 + 1] = decode_sym(gb, lru[1]);
313  dst[x * 3 + 2] = decode_sym(gb, lru[2]);
314  }
315 
316  dst += stride;
317  }
318 
319  return 0;
320 }
321 
323  const uint8_t *src, int src_size)
324 {
325  GetByteContext gb;
326  GetBitContext gb2;
327  int nslices, slice, slice_height;
328  uint32_t off, slice_size;
329  uint8_t *dst;
330  int ret;
331 
332  bytestream2_init(&gb, src, src_size);
333  nslices = bytestream2_get_le16(&gb);
334  off = FFALIGN(nslices * 4 + 2, 16);
335  if (src_size < off) {
336  av_log(avctx, AV_LOG_ERROR, "no slice data\n");
337  return AVERROR_INVALIDDATA;
338  }
339 
340  if (!nslices || avctx->height % nslices) {
341  avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
342  avctx->width, avctx->height);
343  return AVERROR_PATCHWELCOME;
344  }
345 
346  slice_height = avctx->height / nslices;
347  avctx->pix_fmt = AV_PIX_FMT_BGR24;
348  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
349  return ret;
350 
351  dst = pic->data[0];
352  for (slice = 0; slice < nslices; slice++) {
353  slice_size = bytestream2_get_le32(&gb);
354  if (slice_size > src_size - off) {
355  av_log(avctx, AV_LOG_ERROR,
356  "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
357  slice_size, src_size - off);
358  return AVERROR_INVALIDDATA;
359  }
360  if (slice_size <= 16) {
361  av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n",
362  slice_size);
363  return AVERROR_INVALIDDATA;
364  }
365 
366  if (AV_RL32(src + off) != slice_size - 16) {
367  av_log(avctx, AV_LOG_ERROR,
368  "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
369  AV_RL32(src + off), slice_size - 16);
370  }
371  if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
372  return ret;
373  dx2_decode_slice_rgb(&gb2, avctx->width, slice_height, dst,
374  pic->linesize[0]);
375 
376  dst += pic->linesize[0] * slice_height;
377  off += slice_size;
378  }
379 
380  return 0;
381 }
382 
384  uint8_t *Y, uint8_t *U, uint8_t *V,
385  int ystride, int ustride, int vstride)
386 {
387  int x, y, i, j;
388  uint8_t lru[3][8];
389 
390  for (i = 0; i < 3; i++)
391  memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
392 
393  for (y = 0; y < height; y += 4) {
394  for (x = 0; x < width; x += 4) {
395  for (j = 0; j < 4; j++)
396  for (i = 0; i < 4; i++)
397  Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
398  U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
399  V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
400  }
401 
402  Y += ystride << 2;
403  U += ustride;
404  V += vstride;
405  }
406 
407  return 0;
408 }
409 
411  const uint8_t *src, int src_size)
412 {
413  GetByteContext gb;
414  GetBitContext gb2;
415  int nslices, slice, slice_height;
416  int cur_y, next_y;
417  uint32_t off, slice_size;
418  uint8_t *Y, *U, *V;
419  int ret;
420 
421  bytestream2_init(&gb, src, src_size);
422  nslices = bytestream2_get_le16(&gb);
423  off = FFALIGN(nslices * 4 + 2, 16);
424  if (src_size < off) {
425  av_log(avctx, AV_LOG_ERROR, "no slice data\n");
426  return AVERROR_INVALIDDATA;
427  }
428 
429  if (!nslices) {
430  avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
431  avctx->width, avctx->height);
432  return AVERROR_PATCHWELCOME;
433  }
434 
435  if ((avctx->width & 3) || (avctx->height & 3)) {
436  avpriv_request_sample(avctx, "Frame dimensions %dx%d",
437  avctx->width, avctx->height);
438  }
439 
440  avctx->pix_fmt = AV_PIX_FMT_YUV410P;
441  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
442  return ret;
443 
444  Y = pic->data[0];
445  U = pic->data[1];
446  V = pic->data[2];
447 
448  cur_y = 0;
449  for (slice = 0; slice < nslices; slice++) {
450  slice_size = bytestream2_get_le32(&gb);
451  next_y = ((slice + 1) * avctx->height) / nslices;
452  slice_height = (next_y & ~3) - (cur_y & ~3);
453  if (slice_size > src_size - off) {
454  av_log(avctx, AV_LOG_ERROR,
455  "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
456  slice_size, src_size - off);
457  return AVERROR_INVALIDDATA;
458  }
459  if (slice_size <= 16) {
460  av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
461  return AVERROR_INVALIDDATA;
462  }
463 
464  if (AV_RL32(src + off) != slice_size - 16) {
465  av_log(avctx, AV_LOG_ERROR,
466  "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
467  AV_RL32(src + off), slice_size - 16);
468  }
469  if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
470  return ret;
471  dx2_decode_slice_410(&gb2, avctx->width, slice_height, Y, U, V,
472  pic->linesize[0], pic->linesize[1],
473  pic->linesize[2]);
474 
475  Y += pic->linesize[0] * slice_height;
476  U += pic->linesize[1] * (slice_height >> 2);
477  V += pic->linesize[2] * (slice_height >> 2);
478  off += slice_size;
479  cur_y = next_y;
480  }
481 
482  return 0;
483 }
484 
486  uint8_t *Y, uint8_t *U, uint8_t *V,
487  int ystride, int ustride, int vstride)
488 {
489  int x, y, i;
490  uint8_t lru[3][8];
491 
492  for (i = 0; i < 3; i++)
493  memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
494 
495  for (y = 0; y < height; y+=2) {
496  for (x = 0; x < width; x += 2) {
497  Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
498  Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
499  Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
500  Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
501  U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
502  V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
503  }
504 
505  Y += ystride << 1;
506  U += ustride;
507  V += vstride;
508  }
509 
510  return 0;
511 }
512 
514  const uint8_t *src, int src_size)
515 {
516  GetByteContext gb;
517  GetBitContext gb2;
518  int nslices, slice, slice_height;
519  int cur_y, next_y;
520  uint32_t off, slice_size;
521  uint8_t *Y, *U, *V;
522  int ret;
523 
524  bytestream2_init(&gb, src, src_size);
525  nslices = bytestream2_get_le16(&gb);
526  off = FFALIGN(nslices * 4 + 2, 16);
527  if (src_size < off) {
528  av_log(avctx, AV_LOG_ERROR, "no slice data\n");
529  return AVERROR_INVALIDDATA;
530  }
531 
532  if (!nslices) {
533  avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
534  avctx->width, avctx->height);
535  return AVERROR_PATCHWELCOME;
536  }
537 
538  if ((avctx->width & 1) || (avctx->height & 1)) {
539  avpriv_request_sample(avctx, "Frame dimensions %dx%d",
540  avctx->width, avctx->height);
541  }
542 
543  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
544  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
545  return ret;
546 
547  Y = pic->data[0];
548  U = pic->data[1];
549  V = pic->data[2];
550 
551  cur_y = 0;
552  for (slice = 0; slice < nslices; slice++) {
553  slice_size = bytestream2_get_le32(&gb);
554  next_y = ((slice + 1) * avctx->height) / nslices;
555  slice_height = (next_y & ~1) - (cur_y & ~1);
556  if (slice_size > src_size - off) {
557  av_log(avctx, AV_LOG_ERROR,
558  "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
559  slice_size, src_size - off);
560  return AVERROR_INVALIDDATA;
561  }
562  if (slice_size <= 16) {
563  av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
564  return AVERROR_INVALIDDATA;
565  }
566 
567  if (AV_RL32(src + off) != slice_size - 16) {
568  av_log(avctx, AV_LOG_ERROR,
569  "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
570  AV_RL32(src + off), slice_size - 16);
571  }
572  if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
573  return ret;
574  dx2_decode_slice_420(&gb2, avctx->width, slice_height, Y, U, V,
575  pic->linesize[0], pic->linesize[1],
576  pic->linesize[2]);
577 
578  Y += pic->linesize[0] * slice_height;
579  U += pic->linesize[1] * (slice_height >> 1);
580  V += pic->linesize[2] * (slice_height >> 1);
581  off += slice_size;
582  cur_y = next_y;
583  }
584 
585  return 0;
586 }
587 
589  uint8_t *Y, uint8_t *U, uint8_t *V,
590  int ystride, int ustride, int vstride)
591 {
592  int x, y, i;
593  uint8_t lru[3][8];
594 
595  for (i = 0; i < 3; i++)
596  memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
597 
598  for (y = 0; y < height; y++) {
599  for (x = 0; x < width; x++) {
600  Y[x] = decode_sym(gb, lru[0]);
601  U[x] = decode_sym(gb, lru[1]) ^ 0x80;
602  V[x] = decode_sym(gb, lru[2]) ^ 0x80;
603  }
604 
605  Y += ystride;
606  U += ustride;
607  V += vstride;
608  }
609 
610  return 0;
611 }
612 
614  const uint8_t *src, int src_size)
615 {
616  GetByteContext gb;
617  GetBitContext gb2;
618  int nslices, slice, slice_height;
619  uint32_t off, slice_size;
620  uint8_t *Y, *U, *V;
621  int ret;
622 
623  bytestream2_init(&gb, src, src_size);
624  nslices = bytestream2_get_le16(&gb);
625  off = FFALIGN(nslices * 4 + 2, 16);
626  if (src_size < off) {
627  av_log(avctx, AV_LOG_ERROR, "no slice data\n");
628  return AVERROR_INVALIDDATA;
629  }
630 
631  if (!nslices || avctx->height % nslices) {
632  avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
633  avctx->width, avctx->height);
634  return AVERROR_PATCHWELCOME;
635  }
636 
637  slice_height = avctx->height / nslices;
638 
639  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
640  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
641  return ret;
642 
643  Y = pic->data[0];
644  U = pic->data[1];
645  V = pic->data[2];
646 
647  for (slice = 0; slice < nslices; slice++) {
648  slice_size = bytestream2_get_le32(&gb);
649  if (slice_size > src_size - off) {
650  av_log(avctx, AV_LOG_ERROR,
651  "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
652  slice_size, src_size - off);
653  return AVERROR_INVALIDDATA;
654  }
655  if (slice_size <= 16) {
656  av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
657  return AVERROR_INVALIDDATA;
658  }
659 
660  if (AV_RL32(src + off) != slice_size - 16) {
661  av_log(avctx, AV_LOG_ERROR,
662  "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
663  AV_RL32(src + off), slice_size - 16);
664  }
665  if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
666  return ret;
667  dx2_decode_slice_444(&gb2, avctx->width, slice_height, Y, U, V,
668  pic->linesize[0], pic->linesize[1],
669  pic->linesize[2]);
670 
671  Y += pic->linesize[0] * slice_height;
672  U += pic->linesize[1] * slice_height;
673  V += pic->linesize[2] * slice_height;
674  off += slice_size;
675  }
676 
677  return 0;
678 }
679 
680 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
681  AVPacket *avpkt)
682 {
683  AVFrame *pic = data;
684  const uint8_t *src = avpkt->data;
685  int ret;
686 
687  if (avpkt->size < 16) {
688  av_log(avctx, AV_LOG_ERROR, "packet too small\n");
689  return AVERROR_INVALIDDATA;
690  }
691 
692  switch (AV_RB32(src)) {
693  case 0x01000001:
694  ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
695  AV_PIX_FMT_BGR24, 3);
696  break;
697  case 0x01000009:
698  ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16);
699  break;
700  case 0x02000001:
701  ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16);
702  break;
703  case 0x02000009:
704  ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16);
705  break;
706  case 0x03000001:
707  ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16);
708  break;
709  case 0x03000009:
710  ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16);
711  break;
712  case 0x04000001:
713  ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16);
714  break;
715  case 0x04000009:
716  ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16);
717  break;
718  case 0x17000001:
719  ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
721  break;
722  case 0x17000009:
723  ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1);
724  break;
725  case 0x18000001:
726  case 0x19000001:
727  ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
729  break;
730  case 0x18000009:
731  case 0x19000009:
732  ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0);
733  break;
734  default:
735  avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src));
736  return AVERROR_PATCHWELCOME;
737  }
738 
739  if (ret)
740  return ret;
741 
743  pic->key_frame = 1;
744  *got_frame = 1;
745 
746  return avpkt->size;
747 }
748 
750  .name = "dxtory",
751  .long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
752  .type = AVMEDIA_TYPE_VIDEO,
753  .id = AV_CODEC_ID_DXTORY,
754  .decode = decode_frame,
755  .capabilities = AV_CODEC_CAP_DR1,
756 };
static int dx2_decode_slice_444(GetBitContext *gb, int width, int height, uint8_t *Y, uint8_t *U, uint8_t *V, int ystride, int ustride, int vstride)
Definition: dxtory.c:588
static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
Definition: dxtory.c:322
const char const char void * val
Definition: avisynth_c.h:634
static int dx2_decode_slice_rgb(GetBitContext *gb, int width, int height, uint8_t *dst, int stride)
Definition: dxtory.c:300
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:171
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
enum AVCodecID id
Definition: mxfenc.c:101
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:68
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:260
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:65
const char * g
Definition: vf_curves.c:108
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined ...
Definition: pixfmt.h:117
int size
Definition: avcodec.h:1424
const char * b
Definition: vf_curves.c:109
static const uint8_t def_lru_555[8]
Definition: dxtory.c:175
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1722
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
AVCodec.
Definition: avcodec.h:3472
static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
Definition: dxtory.c:513
#define FFALIGN(x, a)
Definition: common.h:86
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
Definition: pixfmt.h:115
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 bits
Definition: crc.c:295
uint8_t
#define Y
Definition: vf_boxblur.c:76
static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
Definition: dxtory.c:613
static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
Definition: dxtory.c:104
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:87
static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
Definition: dxtory.c:61
uint8_t * data
Definition: avcodec.h:1423
bitstream reader API header.
static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
Definition: dxtory.c:141
#define av_log(a,...)
#define U(x)
Definition: vp56_arith.h:37
static const uint8_t def_lru[8]
Definition: dxtory.c:174
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static int dx2_decode_slice_420(GetBitContext *gb, int width, int height, uint8_t *Y, uint8_t *U, uint8_t *V, int ystride, int ustride, int vstride)
Definition: dxtory.c:485
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:175
const char * r
Definition: vf_curves.c:107
const char * name
Name of the codec implementation.
Definition: avcodec.h:3479
Libavcodec external API header.
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:242
#define AV_COPY16(d, s)
Definition: intreadwrite.h:582
float y
int width
picture width / height.
Definition: avcodec.h:1681
#define AV_COPY32U(d, s)
Definition: intreadwrite.h:557
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:66
static uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
Definition: dxtory.c:178
static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
Definition: dxtory.c:410
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
AVCodec ff_dxtory_decoder
Definition: dxtory.c:749
AVS_Value src
Definition: avisynth_c.h:482
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:199
static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, int is_565)
Definition: dxtory.c:240
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:441
main external API structure.
Definition: avcodec.h:1502
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:1040
BYTE int const BYTE int int int height
Definition: avisynth_c.h:676
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:69
static int dx2_decode_slice_565(GetBitContext *gb, int width, int height, uint8_t *dst, int stride, int is_565)
Definition: dxtory.c:213
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:182
static const uint8_t def_lru_565[8]
Definition: dxtory.c:176
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:105
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:63
common internal api header.
common internal and external 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]
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:237
static int dx2_decode_slice_410(GetBitContext *gb, int width, int height, uint8_t *Y, uint8_t *U, uint8_t *V, int ystride, int ustride, int vstride)
Definition: dxtory.c:383
static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, int id, int bpp)
Definition: dxtory.c:34
#define stride
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
This structure stores compressed data.
Definition: avcodec.h:1400
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:857
static uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8], int bits)
Definition: dxtory.c:195
#define V
Definition: avdct.c:30
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: dxtory.c:680
static int width