]> git.sesse.net Git - ffmpeg/blob - libavcodec/interplayvideo.c
avformat/hlsenc: reindent the code
[ffmpeg] / libavcodec / interplayvideo.c
1 /*
2  * Interplay MVE Video Decoder
3  * Copyright (C) 2003 The FFmpeg project
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file
24  * Interplay MVE Video Decoder by Mike Melanson (melanson@pcisys.net)
25  * For more information about the Interplay MVE format, visit:
26  *   http://www.pcisys.net/~melanson/codecs/interplay-mve.txt
27  * This code is written in such a way that the identifiers match up
28  * with the encoding descriptions in the document.
29  *
30  * This decoder presently only supports a PAL8 output colorspace.
31  *
32  * An Interplay video frame consists of 2 parts: The decoding map and
33  * the video data. A demuxer must load these 2 parts together in a single
34  * buffer before sending it through the stream to this decoder.
35  */
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #include "libavutil/intreadwrite.h"
42
43 #define BITSTREAM_READER_LE
44 #include "avcodec.h"
45 #include "bytestream.h"
46 #include "get_bits.h"
47 #include "hpeldsp.h"
48 #include "internal.h"
49
50 #define PALETTE_COUNT 256
51
52 typedef struct IpvideoContext {
53
54     AVCodecContext *avctx;
55     HpelDSPContext hdsp;
56     AVFrame *second_last_frame;
57     AVFrame *last_frame;
58
59     /* For format 0x10 */
60     AVFrame *cur_decode_frame;
61     AVFrame *prev_decode_frame;
62
63     const unsigned char *decoding_map;
64     int decoding_map_size;
65     const unsigned char *skip_map;
66     int skip_map_size;
67
68     int is_16bpp;
69     GetByteContext stream_ptr, mv_ptr;
70     unsigned char *pixel_ptr;
71     int line_inc;
72     int stride;
73     int upper_motion_limit_offset;
74
75     uint32_t pal[256];
76 } IpvideoContext;
77
78 static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y)
79 {
80     int width = dst->width;
81     int current_offset = s->pixel_ptr - dst->data[0];
82     int x = (current_offset % dst->linesize[0]) / (1 + s->is_16bpp);
83     int y = current_offset / dst->linesize[0];
84     int dx = delta_x + x - ((delta_x + x >= width) - (delta_x + x < 0)) * width;
85     int dy = delta_y + y + (delta_x + x >= width) - (delta_x + x < 0);
86     int motion_offset = dy * src->linesize[0] + dx * (1 + s->is_16bpp);
87
88     if (motion_offset < 0) {
89         av_log(s->avctx, AV_LOG_ERROR, "motion offset < 0 (%d)\n", motion_offset);
90         return AVERROR_INVALIDDATA;
91     } else if (motion_offset > s->upper_motion_limit_offset) {
92         av_log(s->avctx, AV_LOG_ERROR, "motion offset above limit (%d >= %d)\n",
93             motion_offset, s->upper_motion_limit_offset);
94         return AVERROR_INVALIDDATA;
95     }
96     if (!src->data[0]) {
97         av_log(s->avctx, AV_LOG_ERROR, "Invalid decode type, corrupted header?\n");
98         return AVERROR(EINVAL);
99     }
100     s->hdsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
101                                             dst->linesize[0], 8);
102     return 0;
103 }
104
105 static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s, AVFrame *frame)
106 {
107     return copy_from(s, s->last_frame, frame, 0, 0);
108 }
109
110 static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s, AVFrame *frame)
111 {
112     return copy_from(s, s->second_last_frame, frame, 0, 0);
113 }
114
115 static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s, AVFrame *frame)
116 {
117     unsigned char B;
118     int x, y;
119
120     /* copy block from 2 frames ago using a motion vector; need 1 more byte */
121     if (!s->is_16bpp) {
122         B = bytestream2_get_byte(&s->stream_ptr);
123     } else {
124         B = bytestream2_get_byte(&s->mv_ptr);
125     }
126
127     if (B < 56) {
128         x = 8 + (B % 7);
129         y = B / 7;
130     } else {
131         x = -14 + ((B - 56) % 29);
132         y =   8 + ((B - 56) / 29);
133     }
134
135     ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
136     return copy_from(s, s->second_last_frame, frame, x, y);
137 }
138
139 static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s, AVFrame *frame)
140 {
141     unsigned char B;
142     int x, y;
143
144     /* copy 8x8 block from current frame from an up/left block */
145
146     /* need 1 more byte for motion */
147     if (!s->is_16bpp) {
148         B = bytestream2_get_byte(&s->stream_ptr);
149     } else {
150         B = bytestream2_get_byte(&s->mv_ptr);
151     }
152
153     if (B < 56) {
154         x = -(8 + (B % 7));
155         y = -(B / 7);
156     } else {
157         x = -(-14 + ((B - 56) % 29));
158         y = -(  8 + ((B - 56) / 29));
159     }
160
161     ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
162     return copy_from(s, frame, frame, x, y);
163 }
164
165 static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s, AVFrame *frame)
166 {
167     int x, y;
168     unsigned char B, BL, BH;
169
170     /* copy a block from the previous frame; need 1 more byte */
171     if (!s->is_16bpp) {
172         B = bytestream2_get_byte(&s->stream_ptr);
173     } else {
174         B = bytestream2_get_byte(&s->mv_ptr);
175     }
176
177     BL = B & 0x0F;
178     BH = (B >> 4) & 0x0F;
179     x = -8 + BL;
180     y = -8 + BH;
181
182     ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
183     return copy_from(s, s->last_frame, frame, x, y);
184 }
185
186 static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s, AVFrame *frame)
187 {
188     signed char x, y;
189
190     /* copy a block from the previous frame using an expanded range;
191      * need 2 more bytes */
192     x = bytestream2_get_byte(&s->stream_ptr);
193     y = bytestream2_get_byte(&s->stream_ptr);
194
195     ff_tlog(s->avctx, "motion bytes = %d, %d\n", x, y);
196     return copy_from(s, s->last_frame, frame, x, y);
197 }
198
199 static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s, AVFrame *frame)
200 {
201     /* mystery opcode? skip multiple blocks? */
202     av_log(s->avctx, AV_LOG_ERROR, "Help! Mystery opcode 0x6 seen\n");
203
204     /* report success */
205     return 0;
206 }
207
208 static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s, AVFrame *frame)
209 {
210     int x, y;
211     unsigned char P[2];
212     unsigned int flags;
213
214     if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) {
215         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x7\n");
216         return AVERROR_INVALIDDATA;
217     }
218
219     /* 2-color encoding */
220     P[0] = bytestream2_get_byte(&s->stream_ptr);
221     P[1] = bytestream2_get_byte(&s->stream_ptr);
222
223     if (P[0] <= P[1]) {
224
225         /* need 8 more bytes from the stream */
226         for (y = 0; y < 8; y++) {
227             flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
228             for (; flags != 1; flags >>= 1)
229                 *s->pixel_ptr++ = P[flags & 1];
230             s->pixel_ptr += s->line_inc;
231         }
232
233     } else {
234
235         /* need 2 more bytes from the stream */
236         flags = bytestream2_get_le16(&s->stream_ptr);
237         for (y = 0; y < 8; y += 2) {
238             for (x = 0; x < 8; x += 2, flags >>= 1) {
239                 s->pixel_ptr[x                ] =
240                 s->pixel_ptr[x + 1            ] =
241                 s->pixel_ptr[x +     s->stride] =
242                 s->pixel_ptr[x + 1 + s->stride] = P[flags & 1];
243             }
244             s->pixel_ptr += s->stride * 2;
245         }
246     }
247
248     /* report success */
249     return 0;
250 }
251
252 static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s, AVFrame *frame)
253 {
254     int x, y;
255     unsigned char P[4];
256     unsigned int flags = 0;
257
258     if (bytestream2_get_bytes_left(&s->stream_ptr) < 12) {
259         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x8\n");
260         return AVERROR_INVALIDDATA;
261     }
262
263     /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
264      * either top and bottom or left and right halves */
265     P[0] = bytestream2_get_byte(&s->stream_ptr);
266     P[1] = bytestream2_get_byte(&s->stream_ptr);
267
268     if (P[0] <= P[1]) {
269         for (y = 0; y < 16; y++) {
270             // new values for each 4x4 block
271             if (!(y & 3)) {
272                 if (y) {
273                     P[0]  = bytestream2_get_byte(&s->stream_ptr);
274                     P[1]  = bytestream2_get_byte(&s->stream_ptr);
275                 }
276                 flags = bytestream2_get_le16(&s->stream_ptr);
277             }
278
279             for (x = 0; x < 4; x++, flags >>= 1)
280                 *s->pixel_ptr++ = P[flags & 1];
281             s->pixel_ptr += s->stride - 4;
282             // switch to right half
283             if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
284         }
285
286     } else {
287         flags = bytestream2_get_le32(&s->stream_ptr);
288         P[2] = bytestream2_get_byte(&s->stream_ptr);
289         P[3] = bytestream2_get_byte(&s->stream_ptr);
290
291         if (P[2] <= P[3]) {
292
293             /* vertical split; left & right halves are 2-color encoded */
294
295             for (y = 0; y < 16; y++) {
296                 for (x = 0; x < 4; x++, flags >>= 1)
297                     *s->pixel_ptr++ = P[flags & 1];
298                 s->pixel_ptr += s->stride - 4;
299                 // switch to right half
300                 if (y == 7) {
301                     s->pixel_ptr -= 8 * s->stride - 4;
302                     P[0]  = P[2];
303                     P[1]  = P[3];
304                     flags = bytestream2_get_le32(&s->stream_ptr);
305                 }
306             }
307
308         } else {
309
310             /* horizontal split; top & bottom halves are 2-color encoded */
311
312             for (y = 0; y < 8; y++) {
313                 if (y == 4) {
314                     P[0]  = P[2];
315                     P[1]  = P[3];
316                     flags = bytestream2_get_le32(&s->stream_ptr);
317                 }
318
319                 for (x = 0; x < 8; x++, flags >>= 1)
320                     *s->pixel_ptr++ = P[flags & 1];
321                 s->pixel_ptr += s->line_inc;
322             }
323         }
324     }
325
326     /* report success */
327     return 0;
328 }
329
330 static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s, AVFrame *frame)
331 {
332     int x, y;
333     unsigned char P[4];
334
335     if (bytestream2_get_bytes_left(&s->stream_ptr) < 8) {
336         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x9\n");
337         return AVERROR_INVALIDDATA;
338     }
339
340     /* 4-color encoding */
341     bytestream2_get_buffer(&s->stream_ptr, P, 4);
342
343     if (P[0] <= P[1]) {
344         if (P[2] <= P[3]) {
345
346             /* 1 of 4 colors for each pixel, need 16 more bytes */
347             for (y = 0; y < 8; y++) {
348                 /* get the next set of 8 2-bit flags */
349                 int flags = bytestream2_get_le16(&s->stream_ptr);
350                 for (x = 0; x < 8; x++, flags >>= 2)
351                     *s->pixel_ptr++ = P[flags & 0x03];
352                 s->pixel_ptr += s->line_inc;
353             }
354
355         } else {
356             uint32_t flags;
357
358             /* 1 of 4 colors for each 2x2 block, need 4 more bytes */
359             flags = bytestream2_get_le32(&s->stream_ptr);
360
361             for (y = 0; y < 8; y += 2) {
362                 for (x = 0; x < 8; x += 2, flags >>= 2) {
363                     s->pixel_ptr[x                ] =
364                     s->pixel_ptr[x + 1            ] =
365                     s->pixel_ptr[x +     s->stride] =
366                     s->pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
367                 }
368                 s->pixel_ptr += s->stride * 2;
369             }
370
371         }
372     } else {
373         uint64_t flags;
374
375         /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */
376         flags = bytestream2_get_le64(&s->stream_ptr);
377         if (P[2] <= P[3]) {
378             for (y = 0; y < 8; y++) {
379                 for (x = 0; x < 8; x += 2, flags >>= 2) {
380                     s->pixel_ptr[x    ] =
381                     s->pixel_ptr[x + 1] = P[flags & 0x03];
382                 }
383                 s->pixel_ptr += s->stride;
384             }
385         } else {
386             for (y = 0; y < 8; y += 2) {
387                 for (x = 0; x < 8; x++, flags >>= 2) {
388                     s->pixel_ptr[x            ] =
389                     s->pixel_ptr[x + s->stride] = P[flags & 0x03];
390                 }
391                 s->pixel_ptr += s->stride * 2;
392             }
393         }
394     }
395
396     /* report success */
397     return 0;
398 }
399
400 static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s, AVFrame *frame)
401 {
402     int x, y;
403     unsigned char P[8];
404     int flags = 0;
405
406     if (bytestream2_get_bytes_left(&s->stream_ptr) < 16) {
407         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xA\n");
408         return AVERROR_INVALIDDATA;
409     }
410
411     bytestream2_get_buffer(&s->stream_ptr, P, 4);
412
413     /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
414      * either top and bottom or left and right halves */
415     if (P[0] <= P[1]) {
416
417         /* 4-color encoding for each quadrant; need 32 bytes */
418         for (y = 0; y < 16; y++) {
419             // new values for each 4x4 block
420             if (!(y & 3)) {
421                 if (y) bytestream2_get_buffer(&s->stream_ptr, P, 4);
422                 flags = bytestream2_get_le32(&s->stream_ptr);
423             }
424
425             for (x = 0; x < 4; x++, flags >>= 2)
426                 *s->pixel_ptr++ = P[flags & 0x03];
427
428             s->pixel_ptr += s->stride - 4;
429             // switch to right half
430             if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
431         }
432
433     } else {
434         // vertical split?
435         int vert;
436         uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
437
438         bytestream2_get_buffer(&s->stream_ptr, P + 4, 4);
439         vert = P[4] <= P[5];
440
441         /* 4-color encoding for either left and right or top and bottom
442          * halves */
443
444         for (y = 0; y < 16; y++) {
445             for (x = 0; x < 4; x++, flags >>= 2)
446                 *s->pixel_ptr++ = P[flags & 0x03];
447
448             if (vert) {
449                 s->pixel_ptr += s->stride - 4;
450                 // switch to right half
451                 if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
452             } else if (y & 1) s->pixel_ptr += s->line_inc;
453
454             // load values for second half
455             if (y == 7) {
456                 memcpy(P, P + 4, 4);
457                 flags = bytestream2_get_le64(&s->stream_ptr);
458             }
459         }
460     }
461
462     /* report success */
463     return 0;
464 }
465
466 static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s, AVFrame *frame)
467 {
468     int y;
469
470     /* 64-color encoding (each pixel in block is a different color) */
471     for (y = 0; y < 8; y++) {
472         bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
473         s->pixel_ptr  += s->stride;
474     }
475
476     /* report success */
477     return 0;
478 }
479
480 static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s, AVFrame *frame)
481 {
482     int x, y;
483
484     /* 16-color block encoding: each 2x2 block is a different color */
485     for (y = 0; y < 8; y += 2) {
486         for (x = 0; x < 8; x += 2) {
487             s->pixel_ptr[x                ] =
488             s->pixel_ptr[x + 1            ] =
489             s->pixel_ptr[x +     s->stride] =
490             s->pixel_ptr[x + 1 + s->stride] = bytestream2_get_byte(&s->stream_ptr);
491         }
492         s->pixel_ptr += s->stride * 2;
493     }
494
495     /* report success */
496     return 0;
497 }
498
499 static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s, AVFrame *frame)
500 {
501     int y;
502     unsigned char P[2];
503
504     if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) {
505         av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xD\n");
506         return AVERROR_INVALIDDATA;
507     }
508
509     /* 4-color block encoding: each 4x4 block is a different color */
510     for (y = 0; y < 8; y++) {
511         if (!(y & 3)) {
512             P[0] = bytestream2_get_byte(&s->stream_ptr);
513             P[1] = bytestream2_get_byte(&s->stream_ptr);
514         }
515         memset(s->pixel_ptr,     P[0], 4);
516         memset(s->pixel_ptr + 4, P[1], 4);
517         s->pixel_ptr += s->stride;
518     }
519
520     /* report success */
521     return 0;
522 }
523
524 static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s, AVFrame *frame)
525 {
526     int y;
527     unsigned char pix;
528
529     /* 1-color encoding: the whole block is 1 solid color */
530     pix = bytestream2_get_byte(&s->stream_ptr);
531
532     for (y = 0; y < 8; y++) {
533         memset(s->pixel_ptr, pix, 8);
534         s->pixel_ptr += s->stride;
535     }
536
537     /* report success */
538     return 0;
539 }
540
541 static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s, AVFrame *frame)
542 {
543     int x, y;
544     unsigned char sample[2];
545
546     /* dithered encoding */
547     sample[0] = bytestream2_get_byte(&s->stream_ptr);
548     sample[1] = bytestream2_get_byte(&s->stream_ptr);
549
550     for (y = 0; y < 8; y++) {
551         for (x = 0; x < 8; x += 2) {
552             *s->pixel_ptr++ = sample[  y & 1 ];
553             *s->pixel_ptr++ = sample[!(y & 1)];
554         }
555         s->pixel_ptr += s->line_inc;
556     }
557
558     /* report success */
559     return 0;
560 }
561
562 static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s, AVFrame *frame)
563 {
564     signed char x, y;
565
566     /* copy a block from the second last frame using an expanded range */
567     x = bytestream2_get_byte(&s->stream_ptr);
568     y = bytestream2_get_byte(&s->stream_ptr);
569
570     ff_tlog(s->avctx, "motion bytes = %d, %d\n", x, y);
571     return copy_from(s, s->second_last_frame, frame, x, y);
572 }
573
574 static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s, AVFrame *frame)
575 {
576     int x, y;
577     uint16_t P[2];
578     unsigned int flags;
579     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
580
581     /* 2-color encoding */
582     P[0] = bytestream2_get_le16(&s->stream_ptr);
583     P[1] = bytestream2_get_le16(&s->stream_ptr);
584
585     if (!(P[0] & 0x8000)) {
586
587         for (y = 0; y < 8; y++) {
588             flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
589             for (; flags != 1; flags >>= 1)
590                 *pixel_ptr++ = P[flags & 1];
591             pixel_ptr += s->line_inc;
592         }
593
594     } else {
595
596         flags = bytestream2_get_le16(&s->stream_ptr);
597         for (y = 0; y < 8; y += 2) {
598             for (x = 0; x < 8; x += 2, flags >>= 1) {
599                 pixel_ptr[x                ] =
600                 pixel_ptr[x + 1            ] =
601                 pixel_ptr[x +     s->stride] =
602                 pixel_ptr[x + 1 + s->stride] = P[flags & 1];
603             }
604             pixel_ptr += s->stride * 2;
605         }
606     }
607
608     return 0;
609 }
610
611 static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s, AVFrame *frame)
612 {
613     int x, y;
614     uint16_t P[4];
615     unsigned int flags = 0;
616     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
617
618     /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
619      * either top and bottom or left and right halves */
620     P[0] = bytestream2_get_le16(&s->stream_ptr);
621     P[1] = bytestream2_get_le16(&s->stream_ptr);
622
623     if (!(P[0] & 0x8000)) {
624
625         for (y = 0; y < 16; y++) {
626             // new values for each 4x4 block
627             if (!(y & 3)) {
628                 if (y) {
629                     P[0] = bytestream2_get_le16(&s->stream_ptr);
630                     P[1] = bytestream2_get_le16(&s->stream_ptr);
631                 }
632                 flags = bytestream2_get_le16(&s->stream_ptr);
633             }
634
635             for (x = 0; x < 4; x++, flags >>= 1)
636                 *pixel_ptr++ = P[flags & 1];
637             pixel_ptr += s->stride - 4;
638             // switch to right half
639             if (y == 7) pixel_ptr -= 8 * s->stride - 4;
640         }
641
642     } else {
643
644         flags = bytestream2_get_le32(&s->stream_ptr);
645         P[2]  = bytestream2_get_le16(&s->stream_ptr);
646         P[3]  = bytestream2_get_le16(&s->stream_ptr);
647
648         if (!(P[2] & 0x8000)) {
649
650             /* vertical split; left & right halves are 2-color encoded */
651
652             for (y = 0; y < 16; y++) {
653                 for (x = 0; x < 4; x++, flags >>= 1)
654                     *pixel_ptr++ = P[flags & 1];
655                 pixel_ptr += s->stride - 4;
656                 // switch to right half
657                 if (y == 7) {
658                     pixel_ptr -= 8 * s->stride - 4;
659                     P[0]  = P[2];
660                     P[1]  = P[3];
661                     flags = bytestream2_get_le32(&s->stream_ptr);
662                 }
663             }
664
665         } else {
666
667             /* horizontal split; top & bottom halves are 2-color encoded */
668
669             for (y = 0; y < 8; y++) {
670                 if (y == 4) {
671                     P[0]  = P[2];
672                     P[1]  = P[3];
673                     flags = bytestream2_get_le32(&s->stream_ptr);
674                 }
675
676                 for (x = 0; x < 8; x++, flags >>= 1)
677                     *pixel_ptr++ = P[flags & 1];
678                 pixel_ptr += s->line_inc;
679             }
680         }
681     }
682
683     /* report success */
684     return 0;
685 }
686
687 static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s, AVFrame *frame)
688 {
689     int x, y;
690     uint16_t P[4];
691     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
692
693     /* 4-color encoding */
694     for (x = 0; x < 4; x++)
695         P[x] = bytestream2_get_le16(&s->stream_ptr);
696
697     if (!(P[0] & 0x8000)) {
698         if (!(P[2] & 0x8000)) {
699
700             /* 1 of 4 colors for each pixel */
701             for (y = 0; y < 8; y++) {
702                 /* get the next set of 8 2-bit flags */
703                 int flags = bytestream2_get_le16(&s->stream_ptr);
704                 for (x = 0; x < 8; x++, flags >>= 2)
705                     *pixel_ptr++ = P[flags & 0x03];
706                 pixel_ptr += s->line_inc;
707             }
708
709         } else {
710             uint32_t flags;
711
712             /* 1 of 4 colors for each 2x2 block */
713             flags = bytestream2_get_le32(&s->stream_ptr);
714
715             for (y = 0; y < 8; y += 2) {
716                 for (x = 0; x < 8; x += 2, flags >>= 2) {
717                     pixel_ptr[x                ] =
718                     pixel_ptr[x + 1            ] =
719                     pixel_ptr[x +     s->stride] =
720                     pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
721                 }
722                 pixel_ptr += s->stride * 2;
723             }
724
725         }
726     } else {
727         uint64_t flags;
728
729         /* 1 of 4 colors for each 2x1 or 1x2 block */
730         flags = bytestream2_get_le64(&s->stream_ptr);
731         if (!(P[2] & 0x8000)) {
732             for (y = 0; y < 8; y++) {
733                 for (x = 0; x < 8; x += 2, flags >>= 2) {
734                     pixel_ptr[x    ] =
735                     pixel_ptr[x + 1] = P[flags & 0x03];
736                 }
737                 pixel_ptr += s->stride;
738             }
739         } else {
740             for (y = 0; y < 8; y += 2) {
741                 for (x = 0; x < 8; x++, flags >>= 2) {
742                     pixel_ptr[x            ] =
743                     pixel_ptr[x + s->stride] = P[flags & 0x03];
744                 }
745                 pixel_ptr += s->stride * 2;
746             }
747         }
748     }
749
750     /* report success */
751     return 0;
752 }
753
754 static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s, AVFrame *frame)
755 {
756     int x, y;
757     uint16_t P[8];
758     int flags = 0;
759     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
760
761     for (x = 0; x < 4; x++)
762         P[x] = bytestream2_get_le16(&s->stream_ptr);
763
764     /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
765      * either top and bottom or left and right halves */
766     if (!(P[0] & 0x8000)) {
767
768         /* 4-color encoding for each quadrant */
769         for (y = 0; y < 16; y++) {
770             // new values for each 4x4 block
771             if (!(y & 3)) {
772                 if (y)
773                     for (x = 0; x < 4; x++)
774                         P[x] = bytestream2_get_le16(&s->stream_ptr);
775                 flags = bytestream2_get_le32(&s->stream_ptr);
776             }
777
778             for (x = 0; x < 4; x++, flags >>= 2)
779                 *pixel_ptr++ = P[flags & 0x03];
780
781             pixel_ptr += s->stride - 4;
782             // switch to right half
783             if (y == 7) pixel_ptr -= 8 * s->stride - 4;
784         }
785
786     } else {
787         // vertical split?
788         int vert;
789         uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
790
791         for (x = 4; x < 8; x++)
792             P[x] = bytestream2_get_le16(&s->stream_ptr);
793         vert = !(P[4] & 0x8000);
794
795         /* 4-color encoding for either left and right or top and bottom
796          * halves */
797
798         for (y = 0; y < 16; y++) {
799             for (x = 0; x < 4; x++, flags >>= 2)
800                 *pixel_ptr++ = P[flags & 0x03];
801
802             if (vert) {
803                 pixel_ptr += s->stride - 4;
804                 // switch to right half
805                 if (y == 7) pixel_ptr -= 8 * s->stride - 4;
806             } else if (y & 1) pixel_ptr += s->line_inc;
807
808             // load values for second half
809             if (y == 7) {
810                 memcpy(P, P + 4, 8);
811                 flags = bytestream2_get_le64(&s->stream_ptr);
812             }
813         }
814     }
815
816     /* report success */
817     return 0;
818 }
819
820 static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s, AVFrame *frame)
821 {
822     int x, y;
823     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
824
825     /* 64-color encoding (each pixel in block is a different color) */
826     for (y = 0; y < 8; y++) {
827         for (x = 0; x < 8; x++)
828             pixel_ptr[x] = bytestream2_get_le16(&s->stream_ptr);
829         pixel_ptr  += s->stride;
830     }
831
832     /* report success */
833     return 0;
834 }
835
836 static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s, AVFrame *frame)
837 {
838     int x, y;
839     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
840
841     /* 16-color block encoding: each 2x2 block is a different color */
842     for (y = 0; y < 8; y += 2) {
843         for (x = 0; x < 8; x += 2) {
844             pixel_ptr[x                ] =
845             pixel_ptr[x + 1            ] =
846             pixel_ptr[x +     s->stride] =
847             pixel_ptr[x + 1 + s->stride] = bytestream2_get_le16(&s->stream_ptr);
848         }
849         pixel_ptr += s->stride * 2;
850     }
851
852     /* report success */
853     return 0;
854 }
855
856 static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s, AVFrame *frame)
857 {
858     int x, y;
859     uint16_t P[2];
860     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
861
862     /* 4-color block encoding: each 4x4 block is a different color */
863     for (y = 0; y < 8; y++) {
864         if (!(y & 3)) {
865             P[0] = bytestream2_get_le16(&s->stream_ptr);
866             P[1] = bytestream2_get_le16(&s->stream_ptr);
867         }
868         for (x = 0; x < 8; x++)
869             pixel_ptr[x] = P[x >> 2];
870         pixel_ptr += s->stride;
871     }
872
873     /* report success */
874     return 0;
875 }
876
877 static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s, AVFrame *frame)
878 {
879     int x, y;
880     uint16_t pix;
881     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
882
883     /* 1-color encoding: the whole block is 1 solid color */
884     pix = bytestream2_get_le16(&s->stream_ptr);
885
886     for (y = 0; y < 8; y++) {
887         for (x = 0; x < 8; x++)
888             pixel_ptr[x] = pix;
889         pixel_ptr += s->stride;
890     }
891
892     /* report success */
893     return 0;
894 }
895
896 static int (* const ipvideo_decode_block[])(IpvideoContext *s, AVFrame *frame) = {
897     ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1,
898     ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3,
899     ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5,
900     ipvideo_decode_block_opcode_0x6, ipvideo_decode_block_opcode_0x7,
901     ipvideo_decode_block_opcode_0x8, ipvideo_decode_block_opcode_0x9,
902     ipvideo_decode_block_opcode_0xA, ipvideo_decode_block_opcode_0xB,
903     ipvideo_decode_block_opcode_0xC, ipvideo_decode_block_opcode_0xD,
904     ipvideo_decode_block_opcode_0xE, ipvideo_decode_block_opcode_0xF,
905 };
906
907 static int (* const ipvideo_decode_block16[])(IpvideoContext *s, AVFrame *frame) = {
908     ipvideo_decode_block_opcode_0x0,    ipvideo_decode_block_opcode_0x1,
909     ipvideo_decode_block_opcode_0x2,    ipvideo_decode_block_opcode_0x3,
910     ipvideo_decode_block_opcode_0x4,    ipvideo_decode_block_opcode_0x5,
911     ipvideo_decode_block_opcode_0x6_16, ipvideo_decode_block_opcode_0x7_16,
912     ipvideo_decode_block_opcode_0x8_16, ipvideo_decode_block_opcode_0x9_16,
913     ipvideo_decode_block_opcode_0xA_16, ipvideo_decode_block_opcode_0xB_16,
914     ipvideo_decode_block_opcode_0xC_16, ipvideo_decode_block_opcode_0xD_16,
915     ipvideo_decode_block_opcode_0xE_16, ipvideo_decode_block_opcode_0x1,
916 };
917
918 static void ipvideo_format_06_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
919 {
920     int line;
921
922     if (!opcode) {
923         for (line = 0; line < 8; ++line) {
924             bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
925             s->pixel_ptr += s->stride;
926         }
927     } else {
928         /* Don't try to copy second_last_frame data on the first frames */
929         if (s->avctx->frame_number > 2)
930             copy_from(s, s->second_last_frame, frame, 0, 0);
931     }
932 }
933
934 static void ipvideo_format_06_secondpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
935 {
936     int off_x, off_y;
937
938     if (opcode < 0) {
939         off_x = ((uint16_t)opcode - 0xC000) % frame->width;
940         off_y = ((uint16_t)opcode - 0xC000) / frame->width;
941         copy_from(s, s->last_frame, frame, off_x, off_y);
942     } else if (opcode > 0) {
943         off_x = ((uint16_t)opcode - 0x4000) % frame->width;
944         off_y = ((uint16_t)opcode - 0x4000) / frame->width;
945         copy_from(s, frame, frame, off_x, off_y);
946     }
947 }
948
949 static void (* const ipvideo_format_06_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op) = {
950     ipvideo_format_06_firstpass, ipvideo_format_06_secondpass,
951 };
952
953 static void ipvideo_decode_format_06_opcodes(IpvideoContext *s, AVFrame *frame)
954 {
955     int pass, x, y;
956     int16_t opcode;
957     GetByteContext decoding_map_ptr;
958
959     /* this is PAL8, so make the palette available */
960     memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
961     s->stride = frame->linesize[0];
962
963     s->line_inc = s->stride - 8;
964     s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
965                                   + (s->avctx->width - 8) * (1 + s->is_16bpp);
966
967     bytestream2_init(&decoding_map_ptr, s->decoding_map, s->decoding_map_size);
968
969     for (pass = 0; pass < 2; ++pass) {
970         bytestream2_seek(&decoding_map_ptr, 0, SEEK_SET);
971         for (y = 0; y < s->avctx->height; y += 8) {
972             for (x = 0; x < s->avctx->width; x += 8) {
973                 opcode = bytestream2_get_le16(&decoding_map_ptr);
974
975                 ff_tlog(s->avctx,
976                         "  block @ (%3d, %3d): opcode 0x%X, data ptr offset %d\n",
977                         x, y, opcode, bytestream2_tell(&s->stream_ptr));
978
979                 s->pixel_ptr = frame->data[0] + x + y * frame->linesize[0];
980                 ipvideo_format_06_passes[pass](s, frame, opcode);
981             }
982         }
983     }
984
985     if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
986         av_log(s->avctx, AV_LOG_DEBUG,
987                "decode finished with %d bytes left over\n",
988                bytestream2_get_bytes_left(&s->stream_ptr));
989     }
990 }
991
992 static void ipvideo_format_10_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
993 {
994     int line;
995
996     if (!opcode) {
997         for (line = 0; line < 8; ++line) {
998             bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
999             s->pixel_ptr += s->stride;
1000         }
1001     }
1002 }
1003
1004 static void ipvideo_format_10_secondpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
1005 {
1006     int off_x, off_y;
1007
1008     if (opcode < 0) {
1009         off_x = ((uint16_t)opcode - 0xC000) % s->cur_decode_frame->width;
1010         off_y = ((uint16_t)opcode - 0xC000) / s->cur_decode_frame->width;
1011         copy_from(s, s->prev_decode_frame, s->cur_decode_frame, off_x, off_y);
1012     } else if (opcode > 0) {
1013         off_x = ((uint16_t)opcode - 0x4000) % s->cur_decode_frame->width;
1014         off_y = ((uint16_t)opcode - 0x4000) / s->cur_decode_frame->width;
1015         copy_from(s, s->cur_decode_frame, s->cur_decode_frame, off_x, off_y);
1016     }
1017 }
1018
1019 static void (* const ipvideo_format_10_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op) = {
1020     ipvideo_format_10_firstpass, ipvideo_format_10_secondpass,
1021 };
1022
1023 static void ipvideo_decode_format_10_opcodes(IpvideoContext *s, AVFrame *frame)
1024 {
1025     int pass, x, y, changed_block;
1026     int16_t opcode, skip;
1027     GetByteContext decoding_map_ptr;
1028     GetByteContext skip_map_ptr;
1029
1030     bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
1031
1032     /* this is PAL8, so make the palette available */
1033     memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
1034     s->stride = frame->linesize[0];
1035
1036     s->line_inc = s->stride - 8;
1037     s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
1038                                   + (s->avctx->width - 8) * (1 + s->is_16bpp);
1039
1040     bytestream2_init(&decoding_map_ptr, s->decoding_map, s->decoding_map_size);
1041     bytestream2_init(&skip_map_ptr, s->skip_map, s->skip_map_size);
1042
1043     for (pass = 0; pass < 2; ++pass) {
1044         bytestream2_seek(&decoding_map_ptr, 0, SEEK_SET);
1045         bytestream2_seek(&skip_map_ptr, 0, SEEK_SET);
1046         skip = bytestream2_get_le16(&skip_map_ptr);
1047
1048         for (y = 0; y < s->avctx->height; y += 8) {
1049             for (x = 0; x < s->avctx->width; x += 8) {
1050                 s->pixel_ptr = s->cur_decode_frame->data[0] + x + y * s->cur_decode_frame->linesize[0];
1051
1052                 while (skip <= 0)  {
1053                     if (skip != -0x8000 && skip) {
1054                         opcode = bytestream2_get_le16(&decoding_map_ptr);
1055                         ipvideo_format_10_passes[pass](s, frame, opcode);
1056                         break;
1057                     }
1058                     if (bytestream2_get_bytes_left(&skip_map_ptr) < 2)
1059                         return;
1060                     skip = bytestream2_get_le16(&skip_map_ptr);
1061                 }
1062                 skip *= 2;
1063             }
1064         }
1065     }
1066
1067     bytestream2_seek(&skip_map_ptr, 0, SEEK_SET);
1068     skip = bytestream2_get_le16(&skip_map_ptr);
1069     for (y = 0; y < s->avctx->height; y += 8) {
1070         for (x = 0; x < s->avctx->width; x += 8) {
1071             changed_block = 0;
1072             s->pixel_ptr = frame->data[0] + x + y*frame->linesize[0];
1073
1074             while (skip <= 0)  {
1075                 if (skip != -0x8000 && skip) {
1076                     changed_block = 1;
1077                     break;
1078                 }
1079                 if (bytestream2_get_bytes_left(&skip_map_ptr) < 2)
1080                     return;
1081                 skip = bytestream2_get_le16(&skip_map_ptr);
1082             }
1083
1084             if (changed_block) {
1085                 copy_from(s, s->cur_decode_frame, frame, 0, 0);
1086             } else {
1087                 /* Don't try to copy last_frame data on the first frame */
1088                 if (s->avctx->frame_number)
1089                     copy_from(s, s->last_frame, frame, 0, 0);
1090             }
1091             skip *= 2;
1092         }
1093     }
1094
1095     FFSWAP(AVFrame*, s->prev_decode_frame, s->cur_decode_frame);
1096
1097     if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
1098         av_log(s->avctx, AV_LOG_DEBUG,
1099                "decode finished with %d bytes left over\n",
1100                bytestream2_get_bytes_left(&s->stream_ptr));
1101     }
1102 }
1103
1104 static void ipvideo_decode_format_11_opcodes(IpvideoContext *s, AVFrame *frame)
1105 {
1106     int x, y;
1107     unsigned char opcode;
1108     int ret;
1109     GetBitContext gb;
1110
1111     bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
1112     if (!s->is_16bpp) {
1113         /* this is PAL8, so make the palette available */
1114         memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
1115
1116         s->stride = frame->linesize[0];
1117     } else {
1118         s->stride = frame->linesize[0] >> 1;
1119         s->mv_ptr = s->stream_ptr;
1120         bytestream2_skip(&s->mv_ptr, bytestream2_get_le16(&s->stream_ptr));
1121     }
1122     s->line_inc = s->stride - 8;
1123     s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
1124                                   + (s->avctx->width - 8) * (1 + s->is_16bpp);
1125
1126     init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8);
1127     for (y = 0; y < s->avctx->height; y += 8) {
1128         for (x = 0; x < s->avctx->width; x += 8) {
1129             if (get_bits_left(&gb) < 4)
1130                 return;
1131             opcode = get_bits(&gb, 4);
1132
1133             ff_tlog(s->avctx,
1134                     "  block @ (%3d, %3d): encoding 0x%X, data ptr offset %d\n",
1135                     x, y, opcode, bytestream2_tell(&s->stream_ptr));
1136
1137             if (!s->is_16bpp) {
1138                 s->pixel_ptr = frame->data[0] + x
1139                               + y*frame->linesize[0];
1140                 ret = ipvideo_decode_block[opcode](s, frame);
1141             } else {
1142                 s->pixel_ptr = frame->data[0] + x*2
1143                               + y*frame->linesize[0];
1144                 ret = ipvideo_decode_block16[opcode](s, frame);
1145             }
1146             if (ret != 0) {
1147                 av_log(s->avctx, AV_LOG_ERROR, "decode problem on frame %d, @ block (%d, %d)\n",
1148                        s->avctx->frame_number, x, y);
1149                 return;
1150             }
1151         }
1152     }
1153     if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
1154         av_log(s->avctx, AV_LOG_DEBUG,
1155                "decode finished with %d bytes left over\n",
1156                bytestream2_get_bytes_left(&s->stream_ptr));
1157     }
1158 }
1159
1160 static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
1161 {
1162     IpvideoContext *s = avctx->priv_data;
1163
1164     s->avctx = avctx;
1165
1166     s->is_16bpp = avctx->bits_per_coded_sample == 16;
1167     avctx->pix_fmt = s->is_16bpp ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_PAL8;
1168
1169     ff_hpeldsp_init(&s->hdsp, avctx->flags);
1170
1171     s->last_frame        = av_frame_alloc();
1172     s->second_last_frame = av_frame_alloc();
1173     s->cur_decode_frame  = av_frame_alloc();
1174     s->prev_decode_frame = av_frame_alloc();
1175     if (!s->last_frame || !s->second_last_frame ||
1176         !s->cur_decode_frame || !s->prev_decode_frame) {
1177         return AVERROR(ENOMEM);
1178     }
1179
1180     s->cur_decode_frame->width   = avctx->width;
1181     s->prev_decode_frame->width  = avctx->width;
1182     s->cur_decode_frame->height  = avctx->height;
1183     s->prev_decode_frame->height = avctx->height;
1184     s->cur_decode_frame->format  = avctx->pix_fmt;
1185     s->prev_decode_frame->format = avctx->pix_fmt;
1186
1187     return 0;
1188 }
1189
1190 static int ipvideo_decode_frame(AVCodecContext *avctx,
1191                                 void *data, int *got_frame,
1192                                 AVPacket *avpkt)
1193 {
1194     const uint8_t *buf = avpkt->data;
1195     int buf_size = avpkt->size;
1196     IpvideoContext *s = avctx->priv_data;
1197     AVFrame *frame = data;
1198     int ret;
1199     int send_buffer;
1200     int frame_format;
1201     int video_data_size;
1202
1203     if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {
1204         av_frame_unref(s->last_frame);
1205         av_frame_unref(s->second_last_frame);
1206         av_frame_unref(s->cur_decode_frame);
1207         av_frame_unref(s->prev_decode_frame);
1208     }
1209
1210     if (!s->cur_decode_frame->data[0]) {
1211         ret = ff_get_buffer(avctx, s->cur_decode_frame, 0);
1212         if (ret < 0)
1213             return ret;
1214
1215         ret = ff_get_buffer(avctx, s->prev_decode_frame, 0);
1216         if (ret < 0) {
1217             av_frame_unref(s->cur_decode_frame);
1218             return ret;
1219         }
1220     }
1221
1222     if (buf_size < 8)
1223         return AVERROR_INVALIDDATA;
1224
1225     frame_format         = AV_RL8(buf);
1226     send_buffer          = AV_RL8(buf + 1);
1227     video_data_size      = AV_RL16(buf + 2);
1228     s->decoding_map_size = AV_RL16(buf + 4);
1229     s->skip_map_size     = AV_RL16(buf + 6);
1230
1231     switch (frame_format) {
1232     case 0x06:
1233         if (s->decoding_map_size) {
1234             av_log(avctx, AV_LOG_ERROR, "Decoding map for format 0x06\n");
1235             return AVERROR_INVALIDDATA;
1236         }
1237
1238         if (s->skip_map_size) {
1239             av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x06\n");
1240             return AVERROR_INVALIDDATA;
1241         }
1242
1243         if (s->is_16bpp) {
1244             av_log(avctx, AV_LOG_ERROR, "Video format 0x06 does not support 16bpp movies\n");
1245             return AVERROR_INVALIDDATA;
1246         }
1247
1248         /* Decoding map for 0x06 frame format is at the top of pixeldata */
1249         s->decoding_map_size = ((s->avctx->width / 8) * (s->avctx->height / 8)) * 2;
1250         s->decoding_map = buf + 8 + 14; /* 14 bits of op data */
1251         video_data_size -= s->decoding_map_size + 14;
1252         if (video_data_size <= 0 || s->decoding_map_size == 0)
1253             return AVERROR_INVALIDDATA;
1254
1255         if (buf_size < 8 + s->decoding_map_size + 14 + video_data_size)
1256             return AVERROR_INVALIDDATA;
1257
1258         bytestream2_init(&s->stream_ptr, buf + 8 + s->decoding_map_size + 14, video_data_size);
1259
1260         break;
1261
1262     case 0x10:
1263         if (! s->decoding_map_size) {
1264             av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x10\n");
1265             return AVERROR_INVALIDDATA;
1266         }
1267
1268         if (! s->skip_map_size) {
1269             av_log(avctx, AV_LOG_ERROR, "Empty skip map for format 0x10\n");
1270             return AVERROR_INVALIDDATA;
1271         }
1272
1273         if (s->is_16bpp) {
1274             av_log(avctx, AV_LOG_ERROR, "Video format 0x10 does not support 16bpp movies\n");
1275             return AVERROR_INVALIDDATA;
1276         }
1277
1278         if (buf_size < 8 + video_data_size + s->decoding_map_size + s->skip_map_size)
1279             return AVERROR_INVALIDDATA;
1280
1281         bytestream2_init(&s->stream_ptr, buf + 8, video_data_size);
1282         s->decoding_map = buf + 8 + video_data_size;
1283         s->skip_map = buf + 8 + video_data_size + s->decoding_map_size;
1284
1285         break;
1286
1287     case 0x11:
1288         if (! s->decoding_map_size) {
1289             av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x11\n");
1290             return AVERROR_INVALIDDATA;
1291         }
1292
1293         if (s->skip_map_size) {
1294             av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x11\n");
1295             return AVERROR_INVALIDDATA;
1296         }
1297
1298         if (buf_size < 8 + video_data_size + s->decoding_map_size)
1299             return AVERROR_INVALIDDATA;
1300
1301         bytestream2_init(&s->stream_ptr, buf + 8, video_data_size);
1302         s->decoding_map = buf + 8 + video_data_size;
1303
1304         break;
1305
1306     default:
1307         av_log(avctx, AV_LOG_ERROR, "Frame type 0x%02X unsupported\n", frame_format);
1308     }
1309
1310     /* ensure we can't overread the packet */
1311     if (buf_size < 8 + s->decoding_map_size + video_data_size + s->skip_map_size) {
1312         av_log(avctx, AV_LOG_ERROR, "Invalid IP packet size\n");
1313         return AVERROR_INVALIDDATA;
1314     }
1315
1316     if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
1317         return ret;
1318
1319     if (!s->is_16bpp) {
1320         int size;
1321         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size);
1322         if (pal && size == AVPALETTE_SIZE) {
1323             frame->palette_has_changed = 1;
1324             memcpy(s->pal, pal, AVPALETTE_SIZE);
1325         } else if (pal) {
1326             av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
1327         }
1328     }
1329
1330     switch (frame_format) {
1331     case 0x06:
1332         ipvideo_decode_format_06_opcodes(s, frame);
1333         break;
1334     case 0x10:
1335         ipvideo_decode_format_10_opcodes(s, frame);
1336         break;
1337     case 0x11:
1338         ipvideo_decode_format_11_opcodes(s, frame);
1339         break;
1340     }
1341
1342     *got_frame = send_buffer;
1343
1344     /* shuffle frames */
1345     av_frame_unref(s->second_last_frame);
1346     FFSWAP(AVFrame*, s->second_last_frame, s->last_frame);
1347     if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
1348         return ret;
1349
1350     /* report that the buffer was completely consumed */
1351     return buf_size;
1352 }
1353
1354 static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
1355 {
1356     IpvideoContext *s = avctx->priv_data;
1357
1358     av_frame_free(&s->last_frame);
1359     av_frame_free(&s->second_last_frame);
1360     av_frame_free(&s->cur_decode_frame);
1361     av_frame_free(&s->prev_decode_frame);
1362
1363     return 0;
1364 }
1365
1366 AVCodec ff_interplay_video_decoder = {
1367     .name           = "interplayvideo",
1368     .long_name      = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
1369     .type           = AVMEDIA_TYPE_VIDEO,
1370     .id             = AV_CODEC_ID_INTERPLAY_VIDEO,
1371     .priv_data_size = sizeof(IpvideoContext),
1372     .init           = ipvideo_decode_init,
1373     .close          = ipvideo_decode_end,
1374     .decode         = ipvideo_decode_frame,
1375     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE,
1376     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1377 };