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.

753 lines
23KB

  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_rgb(AVCodecContext *avctx, AVFrame *pic,
  31. const uint8_t *src, int src_size,
  32. int id, int bpp)
  33. {
  34. int h;
  35. uint8_t *dst;
  36. int ret;
  37. if (src_size < avctx->width * avctx->height * bpp) {
  38. av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  39. return AVERROR_INVALIDDATA;
  40. }
  41. avctx->pix_fmt = id;
  42. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  43. return ret;
  44. dst = pic->data[0];
  45. for (h = 0; h < avctx->height; h++) {
  46. memcpy(dst, src, avctx->width * bpp);
  47. src += avctx->width * bpp;
  48. dst += pic->linesize[0];
  49. }
  50. return 0;
  51. }
  52. static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
  53. const uint8_t *src, int src_size)
  54. {
  55. int h, w;
  56. uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
  57. int ret;
  58. if (src_size < avctx->width * avctx->height * 18 / 16) {
  59. av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  60. return AVERROR_INVALIDDATA;
  61. }
  62. avctx->pix_fmt = AV_PIX_FMT_YUV410P;
  63. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  64. return ret;
  65. Y1 = pic->data[0];
  66. Y2 = pic->data[0] + pic->linesize[0];
  67. Y3 = pic->data[0] + pic->linesize[0] * 2;
  68. Y4 = pic->data[0] + pic->linesize[0] * 3;
  69. U = pic->data[1];
  70. V = pic->data[2];
  71. for (h = 0; h < avctx->height; h += 4) {
  72. for (w = 0; w < avctx->width; w += 4) {
  73. AV_COPY32(Y1 + w, src);
  74. AV_COPY32(Y2 + w, src + 4);
  75. AV_COPY32(Y3 + w, src + 8);
  76. AV_COPY32(Y4 + w, src + 12);
  77. U[w >> 2] = src[16] + 0x80;
  78. V[w >> 2] = src[17] + 0x80;
  79. src += 18;
  80. }
  81. Y1 += pic->linesize[0] << 2;
  82. Y2 += pic->linesize[0] << 2;
  83. Y3 += pic->linesize[0] << 2;
  84. Y4 += pic->linesize[0] << 2;
  85. U += pic->linesize[1];
  86. V += pic->linesize[2];
  87. }
  88. return 0;
  89. }
  90. static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
  91. const uint8_t *src, int src_size)
  92. {
  93. int h, w;
  94. uint8_t *Y1, *Y2, *U, *V;
  95. int ret;
  96. if (src_size < avctx->width * avctx->height * 3 / 2) {
  97. av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  98. return AVERROR_INVALIDDATA;
  99. }
  100. avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  101. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  102. return ret;
  103. Y1 = pic->data[0];
  104. Y2 = pic->data[0] + pic->linesize[0];
  105. U = pic->data[1];
  106. V = pic->data[2];
  107. for (h = 0; h < avctx->height; h += 2) {
  108. for (w = 0; w < avctx->width; w += 2) {
  109. AV_COPY16(Y1 + w, src);
  110. AV_COPY16(Y2 + w, src + 2);
  111. U[w >> 1] = src[4] + 0x80;
  112. V[w >> 1] = src[5] + 0x80;
  113. src += 6;
  114. }
  115. Y1 += pic->linesize[0] << 1;
  116. Y2 += pic->linesize[0] << 1;
  117. U += pic->linesize[1];
  118. V += pic->linesize[2];
  119. }
  120. return 0;
  121. }
  122. static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
  123. const uint8_t *src, int src_size)
  124. {
  125. int h, w;
  126. uint8_t *Y, *U, *V;
  127. int ret;
  128. if (src_size < avctx->width * avctx->height * 3) {
  129. av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  130. return AVERROR_INVALIDDATA;
  131. }
  132. avctx->pix_fmt = AV_PIX_FMT_YUV444P;
  133. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  134. return ret;
  135. Y = pic->data[0];
  136. U = pic->data[1];
  137. V = pic->data[2];
  138. for (h = 0; h < avctx->height; h++) {
  139. for (w = 0; w < avctx->width; w++) {
  140. Y[w] = *src++;
  141. U[w] = *src++ ^ 0x80;
  142. V[w] = *src++ ^ 0x80;
  143. }
  144. Y += pic->linesize[0];
  145. U += pic->linesize[1];
  146. V += pic->linesize[2];
  147. }
  148. return 0;
  149. }
  150. const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
  151. const uint8_t def_lru_555[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F };
  152. const uint8_t def_lru_565[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F };
  153. static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
  154. {
  155. uint8_t c, val;
  156. c = get_unary(gb, 0, 8);
  157. if (!c) {
  158. val = get_bits(gb, 8);
  159. memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
  160. } else {
  161. val = lru[c - 1];
  162. memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
  163. }
  164. lru[0] = val;
  165. return val;
  166. }
  167. static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8],
  168. int bits)
  169. {
  170. uint8_t c, val;
  171. c = get_unary(gb, 0, bits);
  172. if (!c) {
  173. val = get_bits(gb, bits);
  174. memmove(lru + 1, lru, sizeof(*lru) * (6 - 1));
  175. } else {
  176. val = lru[c - 1];
  177. memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
  178. }
  179. lru[0] = val;
  180. return val;
  181. }
  182. static int dx2_decode_slice_565(GetBitContext *gb, int width, int height,
  183. uint8_t *dst, int stride, int is_565)
  184. {
  185. int x, y;
  186. int r, g, b;
  187. uint8_t lru[3][8];
  188. memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
  189. memcpy(lru[1], is_565 ? def_lru_565 : def_lru_555, 8 * sizeof(*def_lru));
  190. memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
  191. for (y = 0; y < height; y++) {
  192. for (x = 0; x < width; x++) {
  193. b = decode_sym_565(gb, lru[0], 5);
  194. g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5);
  195. r = decode_sym_565(gb, lru[2], 5);
  196. dst[x * 3 + 0] = (r << 3) | (r >> 2);
  197. dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2);
  198. dst[x * 3 + 2] = (b << 3) | (b >> 2);
  199. }
  200. dst += stride;
  201. }
  202. return 0;
  203. }
  204. static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
  205. const uint8_t *src, int src_size, int is_565)
  206. {
  207. GetByteContext gb;
  208. GetBitContext gb2;
  209. int nslices, slice, slice_height;
  210. uint32_t off, slice_size;
  211. uint8_t *dst;
  212. int ret;
  213. bytestream2_init(&gb, src, src_size);
  214. nslices = bytestream2_get_le16(&gb);
  215. off = FFALIGN(nslices * 4 + 2, 16);
  216. if (src_size < off) {
  217. av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  218. return AVERROR_INVALIDDATA;
  219. }
  220. if (!nslices || avctx->height % nslices) {
  221. avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  222. avctx->width, avctx->height);
  223. return AVERROR_PATCHWELCOME;
  224. }
  225. slice_height = avctx->height / nslices;
  226. avctx->pix_fmt = AV_PIX_FMT_RGB24;
  227. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  228. return ret;
  229. dst = pic->data[0];
  230. for (slice = 0; slice < nslices; slice++) {
  231. slice_size = bytestream2_get_le32(&gb);
  232. if (slice_size > src_size - off) {
  233. av_log(avctx, AV_LOG_ERROR,
  234. "invalid slice size %d (only %d bytes left)\n",
  235. slice_size, src_size - off);
  236. return AVERROR_INVALIDDATA;
  237. }
  238. if (slice_size <= 16) {
  239. av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
  240. return AVERROR_INVALIDDATA;
  241. }
  242. if (AV_RL32(src + off) != slice_size - 16) {
  243. av_log(avctx, AV_LOG_ERROR,
  244. "Slice sizes mismatch: got %d instead of %d\n",
  245. AV_RL32(src + off), slice_size - 16);
  246. }
  247. init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
  248. dx2_decode_slice_565(&gb2, avctx->width, slice_height, dst,
  249. pic->linesize[0], is_565);
  250. dst += pic->linesize[0] * slice_height;
  251. off += slice_size;
  252. }
  253. return 0;
  254. }
  255. static int dx2_decode_slice_rgb(GetBitContext *gb, int width, int height,
  256. uint8_t *dst, int stride)
  257. {
  258. int x, y, i;
  259. uint8_t lru[3][8];
  260. for (i = 0; i < 3; i++)
  261. memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
  262. for (y = 0; y < height; y++) {
  263. for (x = 0; x < width; x++) {
  264. dst[x * 3 + 0] = decode_sym(gb, lru[0]);
  265. dst[x * 3 + 1] = decode_sym(gb, lru[1]);
  266. dst[x * 3 + 2] = decode_sym(gb, lru[2]);
  267. }
  268. dst += stride;
  269. }
  270. return 0;
  271. }
  272. static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
  273. const uint8_t *src, int src_size)
  274. {
  275. GetByteContext gb;
  276. GetBitContext gb2;
  277. int nslices, slice, slice_height;
  278. uint32_t off, slice_size;
  279. uint8_t *dst;
  280. int ret;
  281. bytestream2_init(&gb, src, src_size);
  282. nslices = bytestream2_get_le16(&gb);
  283. off = FFALIGN(nslices * 4 + 2, 16);
  284. if (src_size < off) {
  285. av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  286. return AVERROR_INVALIDDATA;
  287. }
  288. if (!nslices || avctx->height % nslices) {
  289. avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  290. avctx->width, avctx->height);
  291. return AVERROR_PATCHWELCOME;
  292. }
  293. slice_height = avctx->height / nslices;
  294. avctx->pix_fmt = AV_PIX_FMT_BGR24;
  295. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  296. return ret;
  297. dst = pic->data[0];
  298. for (slice = 0; slice < nslices; slice++) {
  299. slice_size = bytestream2_get_le32(&gb);
  300. if (slice_size > src_size - off) {
  301. av_log(avctx, AV_LOG_ERROR,
  302. "invalid slice size %d (only %d bytes left)\n",
  303. slice_size, src_size - off);
  304. return AVERROR_INVALIDDATA;
  305. }
  306. if (slice_size <= 16) {
  307. av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
  308. return AVERROR_INVALIDDATA;
  309. }
  310. if (AV_RL32(src + off) != slice_size - 16) {
  311. av_log(avctx, AV_LOG_ERROR,
  312. "Slice sizes mismatch: got %d instead of %d\n",
  313. AV_RL32(src + off), slice_size - 16);
  314. }
  315. init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
  316. dx2_decode_slice_rgb(&gb2, avctx->width, slice_height, dst,
  317. pic->linesize[0]);
  318. dst += pic->linesize[0] * slice_height;
  319. off += slice_size;
  320. }
  321. return 0;
  322. }
  323. static int dx2_decode_slice_410(GetBitContext *gb, int width, int height,
  324. uint8_t *Y, uint8_t *U, uint8_t *V,
  325. int ystride, int ustride, int vstride)
  326. {
  327. int x, y, i, j;
  328. uint8_t lru[3][8];
  329. for (i = 0; i < 3; i++)
  330. memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
  331. for (y = 0; y < height; y += 4) {
  332. for (x = 0; x < width; x += 4) {
  333. for (j = 0; j < 4; j++)
  334. for (i = 0; i < 4; i++)
  335. Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
  336. U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
  337. V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
  338. }
  339. Y += ystride << 2;
  340. U += ustride;
  341. V += vstride;
  342. }
  343. return 0;
  344. }
  345. static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
  346. const uint8_t *src, int src_size)
  347. {
  348. GetByteContext gb;
  349. GetBitContext gb2;
  350. int nslices, slice, slice_height, ref_slice_height;
  351. int cur_y, next_y;
  352. uint32_t off, slice_size;
  353. uint8_t *Y, *U, *V;
  354. int ret;
  355. bytestream2_init(&gb, src, src_size);
  356. nslices = bytestream2_get_le16(&gb);
  357. off = FFALIGN(nslices * 4 + 2, 16);
  358. if (src_size < off) {
  359. av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  360. return AVERROR_INVALIDDATA;
  361. }
  362. if (!nslices || avctx->height % nslices) {
  363. avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  364. avctx->width, avctx->height);
  365. return AVERROR_PATCHWELCOME;
  366. }
  367. ref_slice_height = avctx->height / nslices;
  368. if ((avctx->width & 3) || (avctx->height & 3)) {
  369. avpriv_request_sample(avctx, "Frame dimensions %dx%d",
  370. avctx->width, avctx->height);
  371. }
  372. avctx->pix_fmt = AV_PIX_FMT_YUV410P;
  373. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  374. return ret;
  375. Y = pic->data[0];
  376. U = pic->data[1];
  377. V = pic->data[2];
  378. cur_y = 0;
  379. next_y = ref_slice_height;
  380. for (slice = 0; slice < nslices; slice++) {
  381. slice_size = bytestream2_get_le32(&gb);
  382. slice_height = (next_y & ~3) - (cur_y & ~3);
  383. if (slice_size > src_size - off) {
  384. av_log(avctx, AV_LOG_ERROR,
  385. "invalid slice size %d (only %d bytes left)\n",
  386. slice_size, src_size - off);
  387. return AVERROR_INVALIDDATA;
  388. }
  389. if (slice_size <= 16) {
  390. av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
  391. return AVERROR_INVALIDDATA;
  392. }
  393. if (AV_RL32(src + off) != slice_size - 16) {
  394. av_log(avctx, AV_LOG_ERROR,
  395. "Slice sizes mismatch: got %d instead of %d\n",
  396. AV_RL32(src + off), slice_size - 16);
  397. }
  398. init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
  399. dx2_decode_slice_410(&gb2, avctx->width, slice_height, Y, U, V,
  400. pic->linesize[0], pic->linesize[1],
  401. pic->linesize[2]);
  402. Y += pic->linesize[0] * slice_height;
  403. U += pic->linesize[1] * (slice_height >> 2);
  404. V += pic->linesize[2] * (slice_height >> 2);
  405. off += slice_size;
  406. cur_y = next_y;
  407. next_y += ref_slice_height;
  408. }
  409. return 0;
  410. }
  411. static int dx2_decode_slice_420(GetBitContext *gb, int width, int height,
  412. uint8_t *Y, uint8_t *U, uint8_t *V,
  413. int ystride, int ustride, int vstride)
  414. {
  415. int x, y, i;
  416. uint8_t lru[3][8];
  417. for (i = 0; i < 3; i++)
  418. memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
  419. for (y = 0; y < height; y+=2) {
  420. for (x = 0; x < width; x += 2) {
  421. Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
  422. Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
  423. Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
  424. Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
  425. U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
  426. V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
  427. }
  428. Y += ystride << 1;
  429. U += ustride;
  430. V += vstride;
  431. }
  432. return 0;
  433. }
  434. static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
  435. const uint8_t *src, int src_size)
  436. {
  437. GetByteContext gb;
  438. GetBitContext gb2;
  439. int nslices, slice, slice_height, ref_slice_height;
  440. int cur_y, next_y;
  441. uint32_t off, slice_size;
  442. uint8_t *Y, *U, *V;
  443. int ret;
  444. bytestream2_init(&gb, src, src_size);
  445. nslices = bytestream2_get_le16(&gb);
  446. off = FFALIGN(nslices * 4 + 2, 16);
  447. if (src_size < off) {
  448. av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  449. return AVERROR_INVALIDDATA;
  450. }
  451. if (!nslices || avctx->height % nslices) {
  452. avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  453. avctx->width, avctx->height);
  454. return AVERROR_PATCHWELCOME;
  455. }
  456. ref_slice_height = avctx->height / nslices;
  457. if ((avctx->width & 1) || (avctx->height & 1)) {
  458. avpriv_request_sample(avctx, "Frame dimensions %dx%d",
  459. avctx->width, avctx->height);
  460. }
  461. avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  462. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  463. return ret;
  464. Y = pic->data[0];
  465. U = pic->data[1];
  466. V = pic->data[2];
  467. cur_y = 0;
  468. next_y = ref_slice_height;
  469. for (slice = 0; slice < nslices; slice++) {
  470. slice_size = bytestream2_get_le32(&gb);
  471. slice_height = (next_y & ~1) - (cur_y & ~1);
  472. if (slice_size > src_size - off) {
  473. av_log(avctx, AV_LOG_ERROR,
  474. "invalid slice size %d (only %d bytes left)\n",
  475. slice_size, src_size - off);
  476. return AVERROR_INVALIDDATA;
  477. }
  478. if (slice_size <= 16) {
  479. av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
  480. return AVERROR_INVALIDDATA;
  481. }
  482. if (AV_RL32(src + off) != slice_size - 16) {
  483. av_log(avctx, AV_LOG_ERROR,
  484. "Slice sizes mismatch: got %d instead of %d\n",
  485. AV_RL32(src + off), slice_size - 16);
  486. }
  487. init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
  488. dx2_decode_slice_420(&gb2, avctx->width, slice_height, Y, U, V,
  489. pic->linesize[0], pic->linesize[1],
  490. pic->linesize[2]);
  491. Y += pic->linesize[0] * slice_height;
  492. U += pic->linesize[1] * (slice_height >> 1);
  493. V += pic->linesize[2] * (slice_height >> 1);
  494. off += slice_size;
  495. cur_y = next_y;
  496. next_y += ref_slice_height;
  497. }
  498. return 0;
  499. }
  500. static int dx2_decode_slice_444(GetBitContext *gb, int width, int height,
  501. uint8_t *Y, uint8_t *U, uint8_t *V,
  502. int ystride, int ustride, int vstride)
  503. {
  504. int x, y, i;
  505. uint8_t lru[3][8];
  506. for (i = 0; i < 3; i++)
  507. memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
  508. for (y = 0; y < height; y++) {
  509. for (x = 0; x < width; x++) {
  510. Y[x] = decode_sym(gb, lru[0]);
  511. U[x] = decode_sym(gb, lru[1]) ^ 0x80;
  512. V[x] = decode_sym(gb, lru[2]) ^ 0x80;
  513. }
  514. Y += ystride;
  515. U += ustride;
  516. V += vstride;
  517. }
  518. return 0;
  519. }
  520. static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
  521. const uint8_t *src, int src_size)
  522. {
  523. GetByteContext gb;
  524. GetBitContext gb2;
  525. int nslices, slice, slice_height;
  526. uint32_t off, slice_size;
  527. uint8_t *Y, *U, *V;
  528. int ret;
  529. bytestream2_init(&gb, src, src_size);
  530. nslices = bytestream2_get_le16(&gb);
  531. off = FFALIGN(nslices * 4 + 2, 16);
  532. if (src_size < off) {
  533. av_log(avctx, AV_LOG_ERROR, "no slice data\n");
  534. return AVERROR_INVALIDDATA;
  535. }
  536. if (!nslices || avctx->height % nslices) {
  537. avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
  538. avctx->width, avctx->height);
  539. return AVERROR_PATCHWELCOME;
  540. }
  541. slice_height = avctx->height / nslices;
  542. avctx->pix_fmt = AV_PIX_FMT_YUV444P;
  543. if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  544. return ret;
  545. Y = pic->data[0];
  546. U = pic->data[1];
  547. V = pic->data[2];
  548. for (slice = 0; slice < nslices; slice++) {
  549. slice_size = bytestream2_get_le32(&gb);
  550. if (slice_size > src_size - off) {
  551. av_log(avctx, AV_LOG_ERROR,
  552. "invalid slice size %d (only %d bytes left)\n",
  553. slice_size, src_size - off);
  554. return AVERROR_INVALIDDATA;
  555. }
  556. if (slice_size <= 16) {
  557. av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
  558. return AVERROR_INVALIDDATA;
  559. }
  560. if (AV_RL32(src + off) != slice_size - 16) {
  561. av_log(avctx, AV_LOG_ERROR,
  562. "Slice sizes mismatch: got %d instead of %d\n",
  563. AV_RL32(src + off), slice_size - 16);
  564. }
  565. init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
  566. dx2_decode_slice_444(&gb2, avctx->width, slice_height, Y, U, V,
  567. pic->linesize[0], pic->linesize[1],
  568. pic->linesize[2]);
  569. Y += pic->linesize[0] * slice_height;
  570. U += pic->linesize[1] * slice_height;
  571. V += pic->linesize[2] * slice_height;
  572. off += slice_size;
  573. }
  574. return 0;
  575. }
  576. static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
  577. AVPacket *avpkt)
  578. {
  579. AVFrame *pic = data;
  580. const uint8_t *src = avpkt->data;
  581. int ret;
  582. if (avpkt->size < 16) {
  583. av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  584. return AVERROR_INVALIDDATA;
  585. }
  586. switch (AV_RB32(src)) {
  587. case 0x01000001:
  588. ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
  589. AV_PIX_FMT_BGR24, 3);
  590. break;
  591. case 0x01000009:
  592. ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16);
  593. break;
  594. case 0x02000001:
  595. ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16);
  596. break;
  597. case 0x02000009:
  598. ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16);
  599. break;
  600. case 0x03000001:
  601. ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16);
  602. break;
  603. case 0x03000009:
  604. ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16);
  605. break;
  606. case 0x04000001:
  607. ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16);
  608. break;
  609. case 0x04000009:
  610. ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16);
  611. break;
  612. case 0x17000001:
  613. ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
  614. AV_PIX_FMT_RGB565LE, 2);
  615. break;
  616. case 0x17000009:
  617. ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1);
  618. break;
  619. case 0x18000001:
  620. case 0x19000001:
  621. ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
  622. AV_PIX_FMT_RGB555LE, 2);
  623. break;
  624. case 0x18000009:
  625. case 0x19000009:
  626. ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0);
  627. break;
  628. default:
  629. avpriv_request_sample(avctx, "Frame header %X", AV_RB32(src));
  630. return AVERROR_PATCHWELCOME;
  631. }
  632. if (ret)
  633. return ret;
  634. pic->pict_type = AV_PICTURE_TYPE_I;
  635. pic->key_frame = 1;
  636. *got_frame = 1;
  637. return avpkt->size;
  638. }
  639. AVCodec ff_dxtory_decoder = {
  640. .name = "dxtory",
  641. .long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
  642. .type = AVMEDIA_TYPE_VIDEO,
  643. .id = AV_CODEC_ID_DXTORY,
  644. .decode = decode_frame,
  645. .capabilities = CODEC_CAP_DR1,
  646. };