interplayvideo.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  1. /*
  2. * Interplay MVE Video Decoder
  3. * Copyright (C) 2003 the ffmpeg project
  4. *
  5. * This file is part of Libav.
  6. *
  7. * Libav is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * Libav is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with Libav; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file
  23. * Interplay MVE Video Decoder by Mike Melanson (melanson@pcisys.net)
  24. * For more information about the Interplay MVE format, visit:
  25. * http://www.pcisys.net/~melanson/codecs/interplay-mve.txt
  26. * This code is written in such a way that the identifiers match up
  27. * with the encoding descriptions in the document.
  28. *
  29. * This decoder presently only supports a PAL8 output colorspace.
  30. *
  31. * An Interplay video frame consists of 2 parts: The decoding map and
  32. * the video data. A demuxer must load these 2 parts together in a single
  33. * buffer before sending it through the stream to this decoder.
  34. */
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include "avcodec.h"
  39. #include "bytestream.h"
  40. #include "dsputil.h"
  41. #define ALT_BITSTREAM_READER_LE
  42. #include "get_bits.h"
  43. #define PALETTE_COUNT 256
  44. /* debugging support */
  45. #define DEBUG_INTERPLAY 0
  46. #if DEBUG_INTERPLAY
  47. #define debug_interplay(x,...) av_log(NULL, AV_LOG_DEBUG, x, __VA_ARGS__)
  48. #else
  49. static inline void debug_interplay(const char *format, ...) { }
  50. #endif
  51. typedef struct IpvideoContext {
  52. AVCodecContext *avctx;
  53. DSPContext dsp;
  54. AVFrame second_last_frame;
  55. AVFrame last_frame;
  56. AVFrame current_frame;
  57. const unsigned char *decoding_map;
  58. int decoding_map_size;
  59. const unsigned char *buf;
  60. int size;
  61. int is_16bpp;
  62. const unsigned char *stream_ptr;
  63. const unsigned char *stream_end;
  64. const uint8_t *mv_ptr;
  65. const uint8_t *mv_end;
  66. unsigned char *pixel_ptr;
  67. int line_inc;
  68. int stride;
  69. int upper_motion_limit_offset;
  70. uint32_t pal[256];
  71. } IpvideoContext;
  72. #define CHECK_STREAM_PTR(stream_ptr, stream_end, n) \
  73. if (stream_end - stream_ptr < n) { \
  74. av_log(s->avctx, AV_LOG_ERROR, "Interplay video warning: stream_ptr out of bounds (%p >= %p)\n", \
  75. stream_ptr + n, stream_end); \
  76. return -1; \
  77. }
  78. static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y)
  79. {
  80. int current_offset = s->pixel_ptr - s->current_frame.data[0];
  81. int motion_offset = current_offset + delta_y * s->current_frame.linesize[0]
  82. + delta_x * (1 + s->is_16bpp);
  83. if (motion_offset < 0) {
  84. av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset < 0 (%d)\n", motion_offset);
  85. return -1;
  86. } else if (motion_offset > s->upper_motion_limit_offset) {
  87. av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset above limit (%d >= %d)\n",
  88. motion_offset, s->upper_motion_limit_offset);
  89. return -1;
  90. }
  91. if (src->data[0] == NULL) {
  92. av_log(s->avctx, AV_LOG_ERROR, "Invalid decode type, corrupted header?\n");
  93. return AVERROR(EINVAL);
  94. }
  95. s->dsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
  96. s->current_frame.linesize[0], 8);
  97. return 0;
  98. }
  99. static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s)
  100. {
  101. return copy_from(s, &s->last_frame, 0, 0);
  102. }
  103. static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s)
  104. {
  105. return copy_from(s, &s->second_last_frame, 0, 0);
  106. }
  107. static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s)
  108. {
  109. unsigned char B;
  110. int x, y;
  111. /* copy block from 2 frames ago using a motion vector; need 1 more byte */
  112. if (!s->is_16bpp) {
  113. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1);
  114. B = *s->stream_ptr++;
  115. } else {
  116. CHECK_STREAM_PTR(s->mv_ptr, s->mv_end, 1);
  117. B = *s->mv_ptr++;
  118. }
  119. if (B < 56) {
  120. x = 8 + (B % 7);
  121. y = B / 7;
  122. } else {
  123. x = -14 + ((B - 56) % 29);
  124. y = 8 + ((B - 56) / 29);
  125. }
  126. debug_interplay (" motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
  127. return copy_from(s, &s->second_last_frame, x, y);
  128. }
  129. static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s)
  130. {
  131. unsigned char B;
  132. int x, y;
  133. /* copy 8x8 block from current frame from an up/left block */
  134. /* need 1 more byte for motion */
  135. if (!s->is_16bpp) {
  136. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1);
  137. B = *s->stream_ptr++;
  138. } else {
  139. CHECK_STREAM_PTR(s->mv_ptr, s->mv_end, 1);
  140. B = *s->mv_ptr++;
  141. }
  142. if (B < 56) {
  143. x = -(8 + (B % 7));
  144. y = -(B / 7);
  145. } else {
  146. x = -(-14 + ((B - 56) % 29));
  147. y = -( 8 + ((B - 56) / 29));
  148. }
  149. debug_interplay (" motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
  150. return copy_from(s, &s->current_frame, x, y);
  151. }
  152. static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s)
  153. {
  154. int x, y;
  155. unsigned char B, BL, BH;
  156. /* copy a block from the previous frame; need 1 more byte */
  157. if (!s->is_16bpp) {
  158. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1);
  159. B = *s->stream_ptr++;
  160. } else {
  161. CHECK_STREAM_PTR(s->mv_ptr, s->mv_end, 1);
  162. B = *s->mv_ptr++;
  163. }
  164. BL = B & 0x0F;
  165. BH = (B >> 4) & 0x0F;
  166. x = -8 + BL;
  167. y = -8 + BH;
  168. debug_interplay (" motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
  169. return copy_from(s, &s->last_frame, x, y);
  170. }
  171. static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s)
  172. {
  173. signed char x, y;
  174. /* copy a block from the previous frame using an expanded range;
  175. * need 2 more bytes */
  176. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2);
  177. x = *s->stream_ptr++;
  178. y = *s->stream_ptr++;
  179. debug_interplay (" motion bytes = %d, %d\n", x, y);
  180. return copy_from(s, &s->last_frame, x, y);
  181. }
  182. static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s)
  183. {
  184. /* mystery opcode? skip multiple blocks? */
  185. av_log(s->avctx, AV_LOG_ERROR, " Interplay video: Help! Mystery opcode 0x6 seen\n");
  186. /* report success */
  187. return 0;
  188. }
  189. static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)
  190. {
  191. int x, y;
  192. unsigned char P[2];
  193. unsigned int flags;
  194. /* 2-color encoding */
  195. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2);
  196. P[0] = *s->stream_ptr++;
  197. P[1] = *s->stream_ptr++;
  198. if (P[0] <= P[1]) {
  199. /* need 8 more bytes from the stream */
  200. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
  201. for (y = 0; y < 8; y++) {
  202. flags = *s->stream_ptr++ | 0x100;
  203. for (; flags != 1; flags >>= 1)
  204. *s->pixel_ptr++ = P[flags & 1];
  205. s->pixel_ptr += s->line_inc;
  206. }
  207. } else {
  208. /* need 2 more bytes from the stream */
  209. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2);
  210. flags = bytestream_get_le16(&s->stream_ptr);
  211. for (y = 0; y < 8; y += 2) {
  212. for (x = 0; x < 8; x += 2, flags >>= 1) {
  213. s->pixel_ptr[x ] =
  214. s->pixel_ptr[x + 1 ] =
  215. s->pixel_ptr[x + s->stride] =
  216. s->pixel_ptr[x + 1 + s->stride] = P[flags & 1];
  217. }
  218. s->pixel_ptr += s->stride * 2;
  219. }
  220. }
  221. /* report success */
  222. return 0;
  223. }
  224. static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
  225. {
  226. int x, y;
  227. unsigned char P[2];
  228. unsigned int flags = 0;
  229. /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
  230. * either top and bottom or left and right halves */
  231. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2);
  232. P[0] = *s->stream_ptr++;
  233. P[1] = *s->stream_ptr++;
  234. if (P[0] <= P[1]) {
  235. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 14);
  236. s->stream_ptr -= 2;
  237. for (y = 0; y < 16; y++) {
  238. // new values for each 4x4 block
  239. if (!(y & 3)) {
  240. P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++;
  241. flags = bytestream_get_le16(&s->stream_ptr);
  242. }
  243. for (x = 0; x < 4; x++, flags >>= 1)
  244. *s->pixel_ptr++ = P[flags & 1];
  245. s->pixel_ptr += s->stride - 4;
  246. // switch to right half
  247. if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
  248. }
  249. } else {
  250. /* need 10 more bytes */
  251. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 10);
  252. if (s->stream_ptr[4] <= s->stream_ptr[5]) {
  253. flags = bytestream_get_le32(&s->stream_ptr);
  254. /* vertical split; left & right halves are 2-color encoded */
  255. for (y = 0; y < 16; y++) {
  256. for (x = 0; x < 4; x++, flags >>= 1)
  257. *s->pixel_ptr++ = P[flags & 1];
  258. s->pixel_ptr += s->stride - 4;
  259. // switch to right half
  260. if (y == 7) {
  261. s->pixel_ptr -= 8 * s->stride - 4;
  262. P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++;
  263. flags = bytestream_get_le32(&s->stream_ptr);
  264. }
  265. }
  266. } else {
  267. /* horizontal split; top & bottom halves are 2-color encoded */
  268. for (y = 0; y < 8; y++) {
  269. if (y == 4) {
  270. P[0] = *s->stream_ptr++;
  271. P[1] = *s->stream_ptr++;
  272. }
  273. flags = *s->stream_ptr++ | 0x100;
  274. for (; flags != 1; flags >>= 1)
  275. *s->pixel_ptr++ = P[flags & 1];
  276. s->pixel_ptr += s->line_inc;
  277. }
  278. }
  279. }
  280. /* report success */
  281. return 0;
  282. }
  283. static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)
  284. {
  285. int x, y;
  286. unsigned char P[4];
  287. /* 4-color encoding */
  288. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4);
  289. memcpy(P, s->stream_ptr, 4);
  290. s->stream_ptr += 4;
  291. if (P[0] <= P[1]) {
  292. if (P[2] <= P[3]) {
  293. /* 1 of 4 colors for each pixel, need 16 more bytes */
  294. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 16);
  295. for (y = 0; y < 8; y++) {
  296. /* get the next set of 8 2-bit flags */
  297. int flags = bytestream_get_le16(&s->stream_ptr);
  298. for (x = 0; x < 8; x++, flags >>= 2)
  299. *s->pixel_ptr++ = P[flags & 0x03];
  300. s->pixel_ptr += s->line_inc;
  301. }
  302. } else {
  303. uint32_t flags;
  304. /* 1 of 4 colors for each 2x2 block, need 4 more bytes */
  305. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4);
  306. flags = bytestream_get_le32(&s->stream_ptr);
  307. for (y = 0; y < 8; y += 2) {
  308. for (x = 0; x < 8; x += 2, flags >>= 2) {
  309. s->pixel_ptr[x ] =
  310. s->pixel_ptr[x + 1 ] =
  311. s->pixel_ptr[x + s->stride] =
  312. s->pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
  313. }
  314. s->pixel_ptr += s->stride * 2;
  315. }
  316. }
  317. } else {
  318. uint64_t flags;
  319. /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */
  320. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
  321. flags = bytestream_get_le64(&s->stream_ptr);
  322. if (P[2] <= P[3]) {
  323. for (y = 0; y < 8; y++) {
  324. for (x = 0; x < 8; x += 2, flags >>= 2) {
  325. s->pixel_ptr[x ] =
  326. s->pixel_ptr[x + 1] = P[flags & 0x03];
  327. }
  328. s->pixel_ptr += s->stride;
  329. }
  330. } else {
  331. for (y = 0; y < 8; y += 2) {
  332. for (x = 0; x < 8; x++, flags >>= 2) {
  333. s->pixel_ptr[x ] =
  334. s->pixel_ptr[x + s->stride] = P[flags & 0x03];
  335. }
  336. s->pixel_ptr += s->stride * 2;
  337. }
  338. }
  339. }
  340. /* report success */
  341. return 0;
  342. }
  343. static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s)
  344. {
  345. int x, y;
  346. unsigned char P[4];
  347. int flags = 0;
  348. /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
  349. * either top and bottom or left and right halves */
  350. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 24);
  351. if (s->stream_ptr[0] <= s->stream_ptr[1]) {
  352. /* 4-color encoding for each quadrant; need 32 bytes */
  353. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 32);
  354. for (y = 0; y < 16; y++) {
  355. // new values for each 4x4 block
  356. if (!(y & 3)) {
  357. memcpy(P, s->stream_ptr, 4);
  358. s->stream_ptr += 4;
  359. flags = bytestream_get_le32(&s->stream_ptr);
  360. }
  361. for (x = 0; x < 4; x++, flags >>= 2)
  362. *s->pixel_ptr++ = P[flags & 0x03];
  363. s->pixel_ptr += s->stride - 4;
  364. // switch to right half
  365. if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
  366. }
  367. } else {
  368. // vertical split?
  369. int vert = s->stream_ptr[12] <= s->stream_ptr[13];
  370. uint64_t flags = 0;
  371. /* 4-color encoding for either left and right or top and bottom
  372. * halves */
  373. for (y = 0; y < 16; y++) {
  374. // load values for each half
  375. if (!(y & 7)) {
  376. memcpy(P, s->stream_ptr, 4);
  377. s->stream_ptr += 4;
  378. flags = bytestream_get_le64(&s->stream_ptr);
  379. }
  380. for (x = 0; x < 4; x++, flags >>= 2)
  381. *s->pixel_ptr++ = P[flags & 0x03];
  382. if (vert) {
  383. s->pixel_ptr += s->stride - 4;
  384. // switch to right half
  385. if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
  386. } else if (y & 1) s->pixel_ptr += s->line_inc;
  387. }
  388. }
  389. /* report success */
  390. return 0;
  391. }
  392. static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s)
  393. {
  394. int y;
  395. /* 64-color encoding (each pixel in block is a different color) */
  396. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 64);
  397. for (y = 0; y < 8; y++) {
  398. memcpy(s->pixel_ptr, s->stream_ptr, 8);
  399. s->stream_ptr += 8;
  400. s->pixel_ptr += s->stride;
  401. }
  402. /* report success */
  403. return 0;
  404. }
  405. static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s)
  406. {
  407. int x, y;
  408. /* 16-color block encoding: each 2x2 block is a different color */
  409. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 16);
  410. for (y = 0; y < 8; y += 2) {
  411. for (x = 0; x < 8; x += 2) {
  412. s->pixel_ptr[x ] =
  413. s->pixel_ptr[x + 1 ] =
  414. s->pixel_ptr[x + s->stride] =
  415. s->pixel_ptr[x + 1 + s->stride] = *s->stream_ptr++;
  416. }
  417. s->pixel_ptr += s->stride * 2;
  418. }
  419. /* report success */
  420. return 0;
  421. }
  422. static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s)
  423. {
  424. int y;
  425. unsigned char P[2];
  426. /* 4-color block encoding: each 4x4 block is a different color */
  427. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4);
  428. for (y = 0; y < 8; y++) {
  429. if (!(y & 3)) {
  430. P[0] = *s->stream_ptr++;
  431. P[1] = *s->stream_ptr++;
  432. }
  433. memset(s->pixel_ptr, P[0], 4);
  434. memset(s->pixel_ptr + 4, P[1], 4);
  435. s->pixel_ptr += s->stride;
  436. }
  437. /* report success */
  438. return 0;
  439. }
  440. static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s)
  441. {
  442. int y;
  443. unsigned char pix;
  444. /* 1-color encoding: the whole block is 1 solid color */
  445. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1);
  446. pix = *s->stream_ptr++;
  447. for (y = 0; y < 8; y++) {
  448. memset(s->pixel_ptr, pix, 8);
  449. s->pixel_ptr += s->stride;
  450. }
  451. /* report success */
  452. return 0;
  453. }
  454. static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s)
  455. {
  456. int x, y;
  457. unsigned char sample[2];
  458. /* dithered encoding */
  459. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2);
  460. sample[0] = *s->stream_ptr++;
  461. sample[1] = *s->stream_ptr++;
  462. for (y = 0; y < 8; y++) {
  463. for (x = 0; x < 8; x += 2) {
  464. *s->pixel_ptr++ = sample[ y & 1 ];
  465. *s->pixel_ptr++ = sample[!(y & 1)];
  466. }
  467. s->pixel_ptr += s->line_inc;
  468. }
  469. /* report success */
  470. return 0;
  471. }
  472. static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s)
  473. {
  474. signed char x, y;
  475. /* copy a block from the second last frame using an expanded range */
  476. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2);
  477. x = *s->stream_ptr++;
  478. y = *s->stream_ptr++;
  479. debug_interplay (" motion bytes = %d, %d\n", x, y);
  480. return copy_from(s, &s->second_last_frame, x, y);
  481. }
  482. static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s)
  483. {
  484. int x, y;
  485. uint16_t P[2];
  486. unsigned int flags;
  487. uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
  488. /* 2-color encoding */
  489. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4);
  490. P[0] = bytestream_get_le16(&s->stream_ptr);
  491. P[1] = bytestream_get_le16(&s->stream_ptr);
  492. if (!(P[0] & 0x8000)) {
  493. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
  494. for (y = 0; y < 8; y++) {
  495. flags = *s->stream_ptr++ | 0x100;
  496. for (; flags != 1; flags >>= 1)
  497. *pixel_ptr++ = P[flags & 1];
  498. pixel_ptr += s->line_inc;
  499. }
  500. } else {
  501. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2);
  502. flags = bytestream_get_le16(&s->stream_ptr);
  503. for (y = 0; y < 8; y += 2) {
  504. for (x = 0; x < 8; x += 2, flags >>= 1) {
  505. pixel_ptr[x ] =
  506. pixel_ptr[x + 1 ] =
  507. pixel_ptr[x + s->stride] =
  508. pixel_ptr[x + 1 + s->stride] = P[flags & 1];
  509. }
  510. pixel_ptr += s->stride * 2;
  511. }
  512. }
  513. return 0;
  514. }
  515. static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s)
  516. {
  517. int x, y;
  518. uint16_t P[2];
  519. unsigned int flags = 0;
  520. uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
  521. /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
  522. * either top and bottom or left and right halves */
  523. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4);
  524. P[0] = bytestream_get_le16(&s->stream_ptr);
  525. P[1] = bytestream_get_le16(&s->stream_ptr);
  526. if (!(P[0] & 0x8000)) {
  527. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 24);
  528. s->stream_ptr -= 4;
  529. for (y = 0; y < 16; y++) {
  530. // new values for each 4x4 block
  531. if (!(y & 3)) {
  532. P[0] = bytestream_get_le16(&s->stream_ptr);
  533. P[1] = bytestream_get_le16(&s->stream_ptr);
  534. flags = bytestream_get_le16(&s->stream_ptr);
  535. }
  536. for (x = 0; x < 4; x++, flags >>= 1)
  537. *pixel_ptr++ = P[flags & 1];
  538. pixel_ptr += s->stride - 4;
  539. // switch to right half
  540. if (y == 7) pixel_ptr -= 8 * s->stride - 4;
  541. }
  542. } else {
  543. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 12);
  544. if (!(AV_RL16(s->stream_ptr + 4) & 0x8000)) {
  545. flags = bytestream_get_le32(&s->stream_ptr);
  546. /* vertical split; left & right halves are 2-color encoded */
  547. for (y = 0; y < 16; y++) {
  548. for (x = 0; x < 4; x++, flags >>= 1)
  549. *pixel_ptr++ = P[flags & 1];
  550. pixel_ptr += s->stride - 4;
  551. // switch to right half
  552. if (y == 7) {
  553. pixel_ptr -= 8 * s->stride - 4;
  554. P[0] = bytestream_get_le16(&s->stream_ptr);
  555. P[1] = bytestream_get_le16(&s->stream_ptr);
  556. flags = bytestream_get_le32(&s->stream_ptr);
  557. }
  558. }
  559. } else {
  560. /* horizontal split; top & bottom halves are 2-color encoded */
  561. for (y = 0; y < 8; y++) {
  562. if (y == 4) {
  563. P[0] = bytestream_get_le16(&s->stream_ptr);
  564. P[1] = bytestream_get_le16(&s->stream_ptr);
  565. }
  566. flags = *s->stream_ptr++ | 0x100;
  567. for (; flags != 1; flags >>= 1)
  568. *pixel_ptr++ = P[flags & 1];
  569. pixel_ptr += s->line_inc;
  570. }
  571. }
  572. }
  573. /* report success */
  574. return 0;
  575. }
  576. static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s)
  577. {
  578. int x, y;
  579. uint16_t P[4];
  580. uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
  581. /* 4-color encoding */
  582. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
  583. for (x = 0; x < 4; x++)
  584. P[x] = bytestream_get_le16(&s->stream_ptr);
  585. if (!(P[0] & 0x8000)) {
  586. if (!(P[2] & 0x8000)) {
  587. /* 1 of 4 colors for each pixel */
  588. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 16);
  589. for (y = 0; y < 8; y++) {
  590. /* get the next set of 8 2-bit flags */
  591. int flags = bytestream_get_le16(&s->stream_ptr);
  592. for (x = 0; x < 8; x++, flags >>= 2)
  593. *pixel_ptr++ = P[flags & 0x03];
  594. pixel_ptr += s->line_inc;
  595. }
  596. } else {
  597. uint32_t flags;
  598. /* 1 of 4 colors for each 2x2 block */
  599. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4);
  600. flags = bytestream_get_le32(&s->stream_ptr);
  601. for (y = 0; y < 8; y += 2) {
  602. for (x = 0; x < 8; x += 2, flags >>= 2) {
  603. pixel_ptr[x ] =
  604. pixel_ptr[x + 1 ] =
  605. pixel_ptr[x + s->stride] =
  606. pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
  607. }
  608. pixel_ptr += s->stride * 2;
  609. }
  610. }
  611. } else {
  612. uint64_t flags;
  613. /* 1 of 4 colors for each 2x1 or 1x2 block */
  614. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
  615. flags = bytestream_get_le64(&s->stream_ptr);
  616. if (!(P[2] & 0x8000)) {
  617. for (y = 0; y < 8; y++) {
  618. for (x = 0; x < 8; x += 2, flags >>= 2) {
  619. pixel_ptr[x ] =
  620. pixel_ptr[x + 1] = P[flags & 0x03];
  621. }
  622. pixel_ptr += s->stride;
  623. }
  624. } else {
  625. for (y = 0; y < 8; y += 2) {
  626. for (x = 0; x < 8; x++, flags >>= 2) {
  627. pixel_ptr[x ] =
  628. pixel_ptr[x + s->stride] = P[flags & 0x03];
  629. }
  630. pixel_ptr += s->stride * 2;
  631. }
  632. }
  633. }
  634. /* report success */
  635. return 0;
  636. }
  637. static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s)
  638. {
  639. int x, y;
  640. uint16_t P[4];
  641. int flags = 0;
  642. uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
  643. /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
  644. * either top and bottom or left and right halves */
  645. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 24);
  646. if (!(AV_RL16(s->stream_ptr) & 0x8000)) {
  647. /* 4-color encoding for each quadrant */
  648. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 48);
  649. for (y = 0; y < 16; y++) {
  650. // new values for each 4x4 block
  651. if (!(y & 3)) {
  652. for (x = 0; x < 4; x++)
  653. P[x] = bytestream_get_le16(&s->stream_ptr);
  654. flags = bytestream_get_le32(&s->stream_ptr);
  655. }
  656. for (x = 0; x < 4; x++, flags >>= 2)
  657. *pixel_ptr++ = P[flags & 0x03];
  658. pixel_ptr += s->stride - 4;
  659. // switch to right half
  660. if (y == 7) pixel_ptr -= 8 * s->stride - 4;
  661. }
  662. } else {
  663. // vertical split?
  664. int vert = !(AV_RL16(s->stream_ptr + 16) & 0x8000);
  665. uint64_t flags = 0;
  666. /* 4-color encoding for either left and right or top and bottom
  667. * halves */
  668. for (y = 0; y < 16; y++) {
  669. // load values for each half
  670. if (!(y & 7)) {
  671. for (x = 0; x < 4; x++)
  672. P[x] = bytestream_get_le16(&s->stream_ptr);
  673. flags = bytestream_get_le64(&s->stream_ptr);
  674. }
  675. for (x = 0; x < 4; x++, flags >>= 2)
  676. *pixel_ptr++ = P[flags & 0x03];
  677. if (vert) {
  678. pixel_ptr += s->stride - 4;
  679. // switch to right half
  680. if (y == 7) pixel_ptr -= 8 * s->stride - 4;
  681. } else if (y & 1) pixel_ptr += s->line_inc;
  682. }
  683. }
  684. /* report success */
  685. return 0;
  686. }
  687. static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s)
  688. {
  689. int x, y;
  690. uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
  691. /* 64-color encoding (each pixel in block is a different color) */
  692. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 128);
  693. for (y = 0; y < 8; y++) {
  694. for (x = 0; x < 8; x++)
  695. pixel_ptr[x] = bytestream_get_le16(&s->stream_ptr);
  696. pixel_ptr += s->stride;
  697. }
  698. /* report success */
  699. return 0;
  700. }
  701. static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s)
  702. {
  703. int x, y;
  704. uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
  705. /* 16-color block encoding: each 2x2 block is a different color */
  706. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 32);
  707. for (y = 0; y < 8; y += 2) {
  708. for (x = 0; x < 8; x += 2) {
  709. pixel_ptr[x ] =
  710. pixel_ptr[x + 1 ] =
  711. pixel_ptr[x + s->stride] =
  712. pixel_ptr[x + 1 + s->stride] = bytestream_get_le16(&s->stream_ptr);
  713. }
  714. pixel_ptr += s->stride * 2;
  715. }
  716. /* report success */
  717. return 0;
  718. }
  719. static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s)
  720. {
  721. int x, y;
  722. uint16_t P[2];
  723. uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
  724. /* 4-color block encoding: each 4x4 block is a different color */
  725. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
  726. for (y = 0; y < 8; y++) {
  727. if (!(y & 3)) {
  728. P[0] = bytestream_get_le16(&s->stream_ptr);
  729. P[1] = bytestream_get_le16(&s->stream_ptr);
  730. }
  731. for (x = 0; x < 8; x++)
  732. pixel_ptr[x] = P[x >> 2];
  733. pixel_ptr += s->stride;
  734. }
  735. /* report success */
  736. return 0;
  737. }
  738. static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s)
  739. {
  740. int x, y;
  741. uint16_t pix;
  742. uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
  743. /* 1-color encoding: the whole block is 1 solid color */
  744. CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2);
  745. pix = bytestream_get_le16(&s->stream_ptr);
  746. for (y = 0; y < 8; y++) {
  747. for (x = 0; x < 8; x++)
  748. pixel_ptr[x] = pix;
  749. pixel_ptr += s->stride;
  750. }
  751. /* report success */
  752. return 0;
  753. }
  754. static int (* const ipvideo_decode_block[])(IpvideoContext *s) = {
  755. ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1,
  756. ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3,
  757. ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5,
  758. ipvideo_decode_block_opcode_0x6, ipvideo_decode_block_opcode_0x7,
  759. ipvideo_decode_block_opcode_0x8, ipvideo_decode_block_opcode_0x9,
  760. ipvideo_decode_block_opcode_0xA, ipvideo_decode_block_opcode_0xB,
  761. ipvideo_decode_block_opcode_0xC, ipvideo_decode_block_opcode_0xD,
  762. ipvideo_decode_block_opcode_0xE, ipvideo_decode_block_opcode_0xF,
  763. };
  764. static int (* const ipvideo_decode_block16[])(IpvideoContext *s) = {
  765. ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1,
  766. ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3,
  767. ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5,
  768. ipvideo_decode_block_opcode_0x6_16, ipvideo_decode_block_opcode_0x7_16,
  769. ipvideo_decode_block_opcode_0x8_16, ipvideo_decode_block_opcode_0x9_16,
  770. ipvideo_decode_block_opcode_0xA_16, ipvideo_decode_block_opcode_0xB_16,
  771. ipvideo_decode_block_opcode_0xC_16, ipvideo_decode_block_opcode_0xD_16,
  772. ipvideo_decode_block_opcode_0xE_16, ipvideo_decode_block_opcode_0x1,
  773. };
  774. static void ipvideo_decode_opcodes(IpvideoContext *s)
  775. {
  776. int x, y;
  777. unsigned char opcode;
  778. int ret;
  779. static int frame = 0;
  780. GetBitContext gb;
  781. debug_interplay("------------------ frame %d\n", frame);
  782. frame++;
  783. if (!s->is_16bpp) {
  784. /* this is PAL8, so make the palette available */
  785. memcpy(s->current_frame.data[1], s->pal, AVPALETTE_SIZE);
  786. s->stride = s->current_frame.linesize[0];
  787. s->stream_ptr = s->buf + 14; /* data starts 14 bytes in */
  788. s->stream_end = s->buf + s->size;
  789. } else {
  790. s->stride = s->current_frame.linesize[0] >> 1;
  791. s->stream_ptr = s->buf + 16;
  792. s->stream_end =
  793. s->mv_ptr = s->buf + 14 + AV_RL16(s->buf+14);
  794. s->mv_end = s->buf + s->size;
  795. }
  796. s->line_inc = s->stride - 8;
  797. s->upper_motion_limit_offset = (s->avctx->height - 8) * s->current_frame.linesize[0]
  798. + (s->avctx->width - 8) * (1 + s->is_16bpp);
  799. init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8);
  800. for (y = 0; y < s->avctx->height; y += 8) {
  801. for (x = 0; x < s->avctx->width; x += 8) {
  802. opcode = get_bits(&gb, 4);
  803. debug_interplay(" block @ (%3d, %3d): encoding 0x%X, data ptr @ %p\n",
  804. x, y, opcode, s->stream_ptr);
  805. if (!s->is_16bpp) {
  806. s->pixel_ptr = s->current_frame.data[0] + x
  807. + y*s->current_frame.linesize[0];
  808. ret = ipvideo_decode_block[opcode](s);
  809. } else {
  810. s->pixel_ptr = s->current_frame.data[0] + x*2
  811. + y*s->current_frame.linesize[0];
  812. ret = ipvideo_decode_block16[opcode](s);
  813. }
  814. if (ret != 0) {
  815. av_log(s->avctx, AV_LOG_ERROR, " Interplay video: decode problem on frame %d, @ block (%d, %d)\n",
  816. frame, x, y);
  817. return;
  818. }
  819. }
  820. }
  821. if (s->stream_end - s->stream_ptr > 1) {
  822. av_log(s->avctx, AV_LOG_ERROR, " Interplay video: decode finished with %td bytes left over\n",
  823. s->stream_end - s->stream_ptr);
  824. }
  825. }
  826. static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
  827. {
  828. IpvideoContext *s = avctx->priv_data;
  829. s->avctx = avctx;
  830. s->is_16bpp = avctx->bits_per_coded_sample == 16;
  831. avctx->pix_fmt = s->is_16bpp ? PIX_FMT_RGB555 : PIX_FMT_PAL8;
  832. dsputil_init(&s->dsp, avctx);
  833. /* decoding map contains 4 bits of information per 8x8 block */
  834. s->decoding_map_size = avctx->width * avctx->height / (8 * 8 * 2);
  835. s->current_frame.data[0] = s->last_frame.data[0] =
  836. s->second_last_frame.data[0] = NULL;
  837. return 0;
  838. }
  839. static int ipvideo_decode_frame(AVCodecContext *avctx,
  840. void *data, int *data_size,
  841. AVPacket *avpkt)
  842. {
  843. const uint8_t *buf = avpkt->data;
  844. int buf_size = avpkt->size;
  845. IpvideoContext *s = avctx->priv_data;
  846. /* compressed buffer needs to be large enough to at least hold an entire
  847. * decoding map */
  848. if (buf_size < s->decoding_map_size)
  849. return buf_size;
  850. s->decoding_map = buf;
  851. s->buf = buf + s->decoding_map_size;
  852. s->size = buf_size - s->decoding_map_size;
  853. s->current_frame.reference = 3;
  854. if (avctx->get_buffer(avctx, &s->current_frame)) {
  855. av_log(avctx, AV_LOG_ERROR, " Interplay Video: get_buffer() failed\n");
  856. return -1;
  857. }
  858. if (!s->is_16bpp) {
  859. const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
  860. if (pal) {
  861. s->current_frame.palette_has_changed = 1;
  862. memcpy(s->pal, pal, AVPALETTE_SIZE);
  863. }
  864. }
  865. ipvideo_decode_opcodes(s);
  866. *data_size = sizeof(AVFrame);
  867. *(AVFrame*)data = s->current_frame;
  868. /* shuffle frames */
  869. if (s->second_last_frame.data[0])
  870. avctx->release_buffer(avctx, &s->second_last_frame);
  871. s->second_last_frame = s->last_frame;
  872. s->last_frame = s->current_frame;
  873. s->current_frame.data[0] = NULL; /* catch any access attempts */
  874. /* report that the buffer was completely consumed */
  875. return buf_size;
  876. }
  877. static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
  878. {
  879. IpvideoContext *s = avctx->priv_data;
  880. /* release the last frame */
  881. if (s->last_frame.data[0])
  882. avctx->release_buffer(avctx, &s->last_frame);
  883. if (s->second_last_frame.data[0])
  884. avctx->release_buffer(avctx, &s->second_last_frame);
  885. return 0;
  886. }
  887. AVCodec ff_interplay_video_decoder = {
  888. "interplayvideo",
  889. AVMEDIA_TYPE_VIDEO,
  890. CODEC_ID_INTERPLAY_VIDEO,
  891. sizeof(IpvideoContext),
  892. ipvideo_decode_init,
  893. NULL,
  894. ipvideo_decode_end,
  895. ipvideo_decode_frame,
  896. CODEC_CAP_DR1,
  897. .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
  898. };