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