1/*
2 * Duck TrueMotion 1.0 Decoder
3 * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
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 * Duck TrueMotion v1 Video Decoder by
25 * Alex Beregszaszi and
26 * Mike Melanson (melanson@pcisys.net)
27 *
28 * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and
29 * outputs RGB555 (or RGB565) data. 24-bit TM1 data is not supported yet.
30 */
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include "avcodec.h"
37#include "codec_internal.h"
38#include "internal.h"
39#include "libavutil/imgutils.h"
40#include "libavutil/internal.h"
41#include "libavutil/intreadwrite.h"
42#include "libavutil/mem.h"
43
44#include "truemotion1data.h"
45
46typedef struct TrueMotion1Context {
47    AVCodecContext *avctx;
48    AVFrame *frame;
49
50    const uint8_t *buf;
51    int size;
52
53    const uint8_t *mb_change_bits;
54    int mb_change_bits_row_size;
55    const uint8_t *index_stream;
56    int index_stream_size;
57
58    int flags;
59    int x, y, w, h;
60
61    uint32_t y_predictor_table[1024];
62    uint32_t c_predictor_table[1024];
63    uint32_t fat_y_predictor_table[1024];
64    uint32_t fat_c_predictor_table[1024];
65
66    int compression;
67    int block_type;
68    int block_width;
69    int block_height;
70
71    int16_t ydt[8];
72    int16_t cdt[8];
73    int16_t fat_ydt[8];
74    int16_t fat_cdt[8];
75
76    int last_deltaset, last_vectable;
77
78    unsigned int *vert_pred;
79    int vert_pred_size;
80
81} TrueMotion1Context;
82
83#define FLAG_SPRITE         32
84#define FLAG_KEYFRAME       16
85#define FLAG_INTERFRAME      8
86#define FLAG_INTERPOLATED    4
87
88struct frame_header {
89    uint8_t header_size;
90    uint8_t compression;
91    uint8_t deltaset;
92    uint8_t vectable;
93    uint16_t ysize;
94    uint16_t xsize;
95    uint16_t checksum;
96    uint8_t version;
97    uint8_t header_type;
98    uint8_t flags;
99    uint8_t control;
100    uint16_t xoffset;
101    uint16_t yoffset;
102    uint16_t width;
103    uint16_t height;
104};
105
106#define ALGO_NOP        0
107#define ALGO_RGB16V     1
108#define ALGO_RGB16H     2
109#define ALGO_RGB24H     3
110
111/* these are the various block sizes that can occupy a 4x4 block */
112#define BLOCK_2x2  0
113#define BLOCK_2x4  1
114#define BLOCK_4x2  2
115#define BLOCK_4x4  3
116
117typedef struct comp_types {
118    int algorithm;
119    int block_width; // vres
120    int block_height; // hres
121    int block_type;
122} comp_types;
123
124/* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */
125static const comp_types compression_types[17] = {
126    { ALGO_NOP,    0, 0, 0 },
127
128    { ALGO_RGB16V, 4, 4, BLOCK_4x4 },
129    { ALGO_RGB16H, 4, 4, BLOCK_4x4 },
130    { ALGO_RGB16V, 4, 2, BLOCK_4x2 },
131    { ALGO_RGB16H, 4, 2, BLOCK_4x2 },
132
133    { ALGO_RGB16V, 2, 4, BLOCK_2x4 },
134    { ALGO_RGB16H, 2, 4, BLOCK_2x4 },
135    { ALGO_RGB16V, 2, 2, BLOCK_2x2 },
136    { ALGO_RGB16H, 2, 2, BLOCK_2x2 },
137
138    { ALGO_NOP,    4, 4, BLOCK_4x4 },
139    { ALGO_RGB24H, 4, 4, BLOCK_4x4 },
140    { ALGO_NOP,    4, 2, BLOCK_4x2 },
141    { ALGO_RGB24H, 4, 2, BLOCK_4x2 },
142
143    { ALGO_NOP,    2, 4, BLOCK_2x4 },
144    { ALGO_RGB24H, 2, 4, BLOCK_2x4 },
145    { ALGO_NOP,    2, 2, BLOCK_2x2 },
146    { ALGO_RGB24H, 2, 2, BLOCK_2x2 }
147};
148
149static void select_delta_tables(TrueMotion1Context *s, int delta_table_index)
150{
151    int i;
152
153    if (delta_table_index > 3)
154        return;
155
156    memcpy(s->ydt, ydts[delta_table_index], 8 * sizeof(int16_t));
157    memcpy(s->cdt, cdts[delta_table_index], 8 * sizeof(int16_t));
158    memcpy(s->fat_ydt, fat_ydts[delta_table_index], 8 * sizeof(int16_t));
159    memcpy(s->fat_cdt, fat_cdts[delta_table_index], 8 * sizeof(int16_t));
160
161    /* Y skinny deltas need to be halved for some reason; maybe the
162     * skinny Y deltas should be modified */
163    for (i = 0; i < 8; i++)
164    {
165        /* drop the lsb before dividing by 2-- net effect: round down
166         * when dividing a negative number (e.g., -3/2 = -2, not -1) */
167        s->ydt[i] &= 0xFFFE;
168        s->ydt[i] /= 2;
169    }
170}
171
172#if HAVE_BIGENDIAN
173static int make_ydt15_entry(int p2, int p1, int16_t *ydt)
174#else
175static int make_ydt15_entry(int p1, int p2, int16_t *ydt)
176#endif
177{
178    int lo, hi;
179
180    lo = ydt[p1];
181    lo += (lo * 32) + (lo * 1024);
182    hi = ydt[p2];
183    hi += (hi * 32) + (hi * 1024);
184    return (lo + (hi * (1U << 16))) * 2;
185}
186
187static int make_cdt15_entry(int p1, int p2, int16_t *cdt)
188{
189    int r, b, lo;
190
191    b = cdt[p2];
192    r = cdt[p1] * 1024;
193    lo = b + r;
194    return (lo + (lo * (1U << 16))) * 2;
195}
196
197#if HAVE_BIGENDIAN
198static int make_ydt16_entry(int p2, int p1, int16_t *ydt)
199#else
200static int make_ydt16_entry(int p1, int p2, int16_t *ydt)
201#endif
202{
203    int lo, hi;
204
205    lo = ydt[p1];
206    lo += (lo << 6) + (lo << 11);
207    hi = ydt[p2];
208    hi += (hi << 6) + (hi << 11);
209    return (lo + (hi << 16)) << 1;
210}
211
212static int make_cdt16_entry(int p1, int p2, int16_t *cdt)
213{
214    int r, b, lo;
215
216    b = cdt[p2];
217    r = cdt[p1] << 11;
218    lo = b + r;
219    return (lo + (lo * (1 << 16))) * 2;
220}
221
222static int make_ydt24_entry(int p1, int p2, int16_t *ydt)
223{
224    int lo, hi;
225
226    lo = ydt[p1];
227    hi = ydt[p2];
228    return (lo + (hi * (1 << 8)) + (hi * (1 << 16))) * 2;
229}
230
231static int make_cdt24_entry(int p1, int p2, int16_t *cdt)
232{
233    int r, b;
234
235    b = cdt[p2];
236    r = cdt[p1] * (1 << 16);
237    return (b+r) * 2;
238}
239
240static void gen_vector_table15(TrueMotion1Context *s, const uint8_t *sel_vector_table)
241{
242    int len, i, j;
243    unsigned char delta_pair;
244
245    for (i = 0; i < 1024; i += 4)
246    {
247        len = *sel_vector_table++ / 2;
248        for (j = 0; j < len; j++)
249        {
250            delta_pair = *sel_vector_table++;
251            s->y_predictor_table[i+j] = 0xfffffffe &
252                make_ydt15_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
253            s->c_predictor_table[i+j] = 0xfffffffe &
254                make_cdt15_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
255        }
256        s->y_predictor_table[i+(j-1)] |= 1;
257        s->c_predictor_table[i+(j-1)] |= 1;
258    }
259}
260
261static void gen_vector_table16(TrueMotion1Context *s, const uint8_t *sel_vector_table)
262{
263    int len, i, j;
264    unsigned char delta_pair;
265
266    for (i = 0; i < 1024; i += 4)
267    {
268        len = *sel_vector_table++ / 2;
269        for (j = 0; j < len; j++)
270        {
271            delta_pair = *sel_vector_table++;
272            s->y_predictor_table[i+j] = 0xfffffffe &
273                make_ydt16_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
274            s->c_predictor_table[i+j] = 0xfffffffe &
275                make_cdt16_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
276        }
277        s->y_predictor_table[i+(j-1)] |= 1;
278        s->c_predictor_table[i+(j-1)] |= 1;
279    }
280}
281
282static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table)
283{
284    int len, i, j;
285    unsigned char delta_pair;
286
287    for (i = 0; i < 1024; i += 4)
288    {
289        len = *sel_vector_table++ / 2;
290        for (j = 0; j < len; j++)
291        {
292            delta_pair = *sel_vector_table++;
293            s->y_predictor_table[i+j] = 0xfffffffe &
294                make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
295            s->c_predictor_table[i+j] = 0xfffffffe &
296                make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
297            s->fat_y_predictor_table[i+j] = 0xfffffffe &
298                make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_ydt);
299            s->fat_c_predictor_table[i+j] = 0xfffffffe &
300                make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_cdt);
301        }
302        s->y_predictor_table[i+(j-1)] |= 1;
303        s->c_predictor_table[i+(j-1)] |= 1;
304        s->fat_y_predictor_table[i+(j-1)] |= 1;
305        s->fat_c_predictor_table[i+(j-1)] |= 1;
306    }
307}
308
309/* Returns the number of bytes consumed from the bytestream. Returns -1 if
310 * there was an error while decoding the header */
311static int truemotion1_decode_header(TrueMotion1Context *s)
312{
313    int i, ret;
314    int width_shift = 0;
315    int new_pix_fmt;
316    struct frame_header header;
317    uint8_t header_buffer[128] = { 0 };  /* logical maximum size of the header */
318    const uint8_t *sel_vector_table;
319
320    header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
321    if (s->buf[0] < 0x10)
322    {
323        av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]);
324        return AVERROR_INVALIDDATA;
325    }
326
327    if (header.header_size + 1 > s->size) {
328        av_log(s->avctx, AV_LOG_ERROR, "Input packet too small.\n");
329        return AVERROR_INVALIDDATA;
330    }
331
332    /* unscramble the header bytes with a XOR operation */
333    for (i = 1; i < header.header_size; i++)
334        header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1];
335
336    header.compression = header_buffer[0];
337    header.deltaset = header_buffer[1];
338    header.vectable = header_buffer[2];
339    header.ysize = AV_RL16(&header_buffer[3]);
340    header.xsize = AV_RL16(&header_buffer[5]);
341    header.checksum = AV_RL16(&header_buffer[7]);
342    header.version = header_buffer[9];
343    header.header_type = header_buffer[10];
344    header.flags = header_buffer[11];
345    header.control = header_buffer[12];
346
347    /* Version 2 */
348    if (header.version >= 2)
349    {
350        if (header.header_type > 3)
351        {
352            av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type);
353            return AVERROR_INVALIDDATA;
354        } else if ((header.header_type == 2) || (header.header_type == 3)) {
355            s->flags = header.flags;
356            if (!(s->flags & FLAG_INTERFRAME))
357                s->flags |= FLAG_KEYFRAME;
358        } else
359            s->flags = FLAG_KEYFRAME;
360    } else /* Version 1 */
361        s->flags = FLAG_KEYFRAME;
362
363    if (s->flags & FLAG_SPRITE) {
364        avpriv_request_sample(s->avctx, "Frame with sprite");
365        /* FIXME header.width, height, xoffset and yoffset aren't initialized */
366        return AVERROR_PATCHWELCOME;
367    } else {
368        s->w = header.xsize;
369        s->h = header.ysize;
370        if (header.header_type < 2) {
371            if ((s->w < 213) && (s->h >= 176))
372            {
373                s->flags |= FLAG_INTERPOLATED;
374                avpriv_request_sample(s->avctx, "Interpolated frame");
375            }
376        }
377    }
378
379    if (header.compression >= 17) {
380        av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression);
381        return AVERROR_INVALIDDATA;
382    }
383
384    if ((header.deltaset != s->last_deltaset) ||
385        (header.vectable != s->last_vectable))
386        select_delta_tables(s, header.deltaset);
387
388    if ((header.compression & 1) && header.header_type)
389        sel_vector_table = pc_tbl2;
390    else {
391        if (header.vectable > 0 && header.vectable < 4)
392            sel_vector_table = tables[header.vectable - 1];
393        else {
394            av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable);
395            return AVERROR_INVALIDDATA;
396        }
397    }
398
399    if (compression_types[header.compression].algorithm == ALGO_RGB24H) {
400        new_pix_fmt = AV_PIX_FMT_0RGB32;
401        width_shift = 1;
402    } else
403        new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well
404
405    s->w >>= width_shift;
406    if (s->w & 1) {
407        avpriv_request_sample(s->avctx, "Frame with odd width");
408        return AVERROR_PATCHWELCOME;
409    }
410
411    if (s->w != s->avctx->width || s->h != s->avctx->height ||
412        new_pix_fmt != s->avctx->pix_fmt) {
413        av_frame_unref(s->frame);
414        s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
415        s->avctx->pix_fmt = new_pix_fmt;
416
417        if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
418            return ret;
419
420        ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);
421
422        av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
423        if (!s->vert_pred)
424            return AVERROR(ENOMEM);
425    }
426
427    /* There is 1 change bit per 4 pixels, so each change byte represents
428     * 32 pixels; divide width by 4 to obtain the number of change bits and
429     * then round up to the nearest byte. */
430    s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3;
431
432    if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable))
433    {
434        if (compression_types[header.compression].algorithm == ALGO_RGB24H)
435            gen_vector_table24(s, sel_vector_table);
436        else
437        if (s->avctx->pix_fmt == AV_PIX_FMT_RGB555)
438            gen_vector_table15(s, sel_vector_table);
439        else
440            gen_vector_table16(s, sel_vector_table);
441    }
442
443    /* set up pointers to the other key data chunks */
444    s->mb_change_bits = s->buf + header.header_size;
445    if (s->flags & FLAG_KEYFRAME) {
446        /* no change bits specified for a keyframe; only index bytes */
447        s->index_stream = s->mb_change_bits;
448        if (s->avctx->width * s->avctx->height / 2048 + header.header_size > s->size)
449            return AVERROR_INVALIDDATA;
450    } else {
451        /* one change bit per 4x4 block */
452        s->index_stream = s->mb_change_bits +
453            (s->mb_change_bits_row_size * (s->avctx->height >> 2));
454    }
455    s->index_stream_size = s->size - (s->index_stream - s->buf);
456
457    s->last_deltaset = header.deltaset;
458    s->last_vectable = header.vectable;
459    s->compression = header.compression;
460    s->block_width = compression_types[header.compression].block_width;
461    s->block_height = compression_types[header.compression].block_height;
462    s->block_type = compression_types[header.compression].block_type;
463
464    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
465        av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
466            s->last_deltaset, s->last_vectable, s->compression, s->block_width,
467            s->block_height, s->block_type,
468            s->flags & FLAG_KEYFRAME ? " KEY" : "",
469            s->flags & FLAG_INTERFRAME ? " INTER" : "",
470            s->flags & FLAG_SPRITE ? " SPRITE" : "",
471            s->flags & FLAG_INTERPOLATED ? " INTERPOL" : "");
472
473    return header.header_size;
474}
475
476static av_cold int truemotion1_decode_init(AVCodecContext *avctx)
477{
478    TrueMotion1Context *s = avctx->priv_data;
479
480    s->avctx = avctx;
481
482    // FIXME: it may change ?
483//    if (avctx->bits_per_sample == 24)
484//        avctx->pix_fmt = AV_PIX_FMT_RGB24;
485//    else
486//        avctx->pix_fmt = AV_PIX_FMT_RGB555;
487
488    s->frame = av_frame_alloc();
489    if (!s->frame)
490        return AVERROR(ENOMEM);
491
492    /* there is a vertical predictor for each pixel in a line; each vertical
493     * predictor is 0 to start with */
494    av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
495    if (!s->vert_pred)
496        return AVERROR(ENOMEM);
497
498    return 0;
499}
500
501/*
502Block decoding order:
503
504dxi: Y-Y
505dxic: Y-C-Y
506dxic2: Y-C-Y-C
507
508hres,vres,i,i%vres (0 < i < 4)
5092x2 0: 0 dxic2
5102x2 1: 1 dxi
5112x2 2: 0 dxic2
5122x2 3: 1 dxi
5132x4 0: 0 dxic2
5142x4 1: 1 dxi
5152x4 2: 2 dxi
5162x4 3: 3 dxi
5174x2 0: 0 dxic
5184x2 1: 1 dxi
5194x2 2: 0 dxic
5204x2 3: 1 dxi
5214x4 0: 0 dxic
5224x4 1: 1 dxi
5234x4 2: 2 dxi
5244x4 3: 3 dxi
525*/
526
527#define GET_NEXT_INDEX() \
528{\
529    if (index_stream_index >= s->index_stream_size) { \
530        av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
531        return; \
532    } \
533    index = s->index_stream[index_stream_index++] * 4; \
534}
535
536#define INC_INDEX                                                   \
537do {                                                                \
538    if (index >= 1023) {                                            \
539        av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n");   \
540        return;                                                     \
541    }                                                               \
542    index++;                                                        \
543} while (0)
544
545#define APPLY_C_PREDICTOR() \
546    predictor_pair = s->c_predictor_table[index]; \
547    horiz_pred += (predictor_pair >> 1); \
548    if (predictor_pair & 1) { \
549        GET_NEXT_INDEX() \
550        if (!index) { \
551            GET_NEXT_INDEX() \
552            predictor_pair = s->c_predictor_table[index]; \
553            horiz_pred += ((predictor_pair >> 1) * 5); \
554            if (predictor_pair & 1) \
555                GET_NEXT_INDEX() \
556            else \
557                INC_INDEX; \
558        } \
559    } else \
560        INC_INDEX;
561
562#define APPLY_C_PREDICTOR_24() \
563    predictor_pair = s->c_predictor_table[index]; \
564    horiz_pred += (predictor_pair >> 1); \
565    if (predictor_pair & 1) { \
566        GET_NEXT_INDEX() \
567        if (!index) { \
568            GET_NEXT_INDEX() \
569            predictor_pair = s->fat_c_predictor_table[index]; \
570            horiz_pred += (predictor_pair >> 1); \
571            if (predictor_pair & 1) \
572                GET_NEXT_INDEX() \
573            else \
574                INC_INDEX; \
575        } \
576    } else \
577        INC_INDEX;
578
579
580#define APPLY_Y_PREDICTOR() \
581    predictor_pair = s->y_predictor_table[index]; \
582    horiz_pred += (predictor_pair >> 1); \
583    if (predictor_pair & 1) { \
584        GET_NEXT_INDEX() \
585        if (!index) { \
586            GET_NEXT_INDEX() \
587            predictor_pair = s->y_predictor_table[index]; \
588            horiz_pred += ((predictor_pair >> 1) * 5); \
589            if (predictor_pair & 1) \
590                GET_NEXT_INDEX() \
591            else \
592                INC_INDEX; \
593        } \
594    } else \
595        INC_INDEX;
596
597#define APPLY_Y_PREDICTOR_24() \
598    predictor_pair = s->y_predictor_table[index]; \
599    horiz_pred += (predictor_pair >> 1); \
600    if (predictor_pair & 1) { \
601        GET_NEXT_INDEX() \
602        if (!index) { \
603            GET_NEXT_INDEX() \
604            predictor_pair = s->fat_y_predictor_table[index]; \
605            horiz_pred += (predictor_pair >> 1); \
606            if (predictor_pair & 1) \
607                GET_NEXT_INDEX() \
608            else \
609                INC_INDEX; \
610        } \
611    } else \
612        INC_INDEX;
613
614#define OUTPUT_PIXEL_PAIR() \
615    *current_pixel_pair = *vert_pred + horiz_pred; \
616    *vert_pred++ = *current_pixel_pair++;
617
618static void truemotion1_decode_16bit(TrueMotion1Context *s)
619{
620    int y;
621    int pixels_left;  /* remaining pixels on this line */
622    unsigned int predictor_pair;
623    unsigned int horiz_pred;
624    unsigned int *vert_pred;
625    unsigned int *current_pixel_pair;
626    unsigned char *current_line = s->frame->data[0];
627    int keyframe = s->flags & FLAG_KEYFRAME;
628
629    /* these variables are for managing the stream of macroblock change bits */
630    const unsigned char *mb_change_bits = s->mb_change_bits;
631    unsigned char mb_change_byte;
632    unsigned char mb_change_byte_mask;
633    int mb_change_index;
634
635    /* these variables are for managing the main index stream */
636    int index_stream_index = 0;  /* yes, the index into the index stream */
637    int index;
638
639    /* clean out the line buffer */
640    memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
641
642    GET_NEXT_INDEX();
643
644    for (y = 0; y < s->avctx->height; y++) {
645
646        /* re-init variables for the next line iteration */
647        horiz_pred = 0;
648        current_pixel_pair = (unsigned int *)current_line;
649        vert_pred = s->vert_pred;
650        mb_change_index = 0;
651        if (!keyframe)
652            mb_change_byte = mb_change_bits[mb_change_index++];
653        mb_change_byte_mask = 0x01;
654        pixels_left = s->avctx->width;
655
656        while (pixels_left > 0) {
657
658            if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
659
660                switch (y & 3) {
661                case 0:
662                    /* if macroblock width is 2, apply C-Y-C-Y; else
663                     * apply C-Y-Y */
664                    if (s->block_width == 2) {
665                        APPLY_C_PREDICTOR();
666                        APPLY_Y_PREDICTOR();
667                        OUTPUT_PIXEL_PAIR();
668                        APPLY_C_PREDICTOR();
669                        APPLY_Y_PREDICTOR();
670                        OUTPUT_PIXEL_PAIR();
671                    } else {
672                        APPLY_C_PREDICTOR();
673                        APPLY_Y_PREDICTOR();
674                        OUTPUT_PIXEL_PAIR();
675                        APPLY_Y_PREDICTOR();
676                        OUTPUT_PIXEL_PAIR();
677                    }
678                    break;
679
680                case 1:
681                case 3:
682                    /* always apply 2 Y predictors on these iterations */
683                    APPLY_Y_PREDICTOR();
684                    OUTPUT_PIXEL_PAIR();
685                    APPLY_Y_PREDICTOR();
686                    OUTPUT_PIXEL_PAIR();
687                    break;
688
689                case 2:
690                    /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
691                     * depending on the macroblock type */
692                    if (s->block_type == BLOCK_2x2) {
693                        APPLY_C_PREDICTOR();
694                        APPLY_Y_PREDICTOR();
695                        OUTPUT_PIXEL_PAIR();
696                        APPLY_C_PREDICTOR();
697                        APPLY_Y_PREDICTOR();
698                        OUTPUT_PIXEL_PAIR();
699                    } else if (s->block_type == BLOCK_4x2) {
700                        APPLY_C_PREDICTOR();
701                        APPLY_Y_PREDICTOR();
702                        OUTPUT_PIXEL_PAIR();
703                        APPLY_Y_PREDICTOR();
704                        OUTPUT_PIXEL_PAIR();
705                    } else {
706                        APPLY_Y_PREDICTOR();
707                        OUTPUT_PIXEL_PAIR();
708                        APPLY_Y_PREDICTOR();
709                        OUTPUT_PIXEL_PAIR();
710                    }
711                    break;
712                }
713
714            } else {
715
716                /* skip (copy) four pixels, but reassign the horizontal
717                 * predictor */
718                *vert_pred++ = *current_pixel_pair++;
719                horiz_pred = *current_pixel_pair - *vert_pred;
720                *vert_pred++ = *current_pixel_pair++;
721
722            }
723
724            if (!keyframe) {
725                mb_change_byte_mask <<= 1;
726
727                /* next byte */
728                if (!mb_change_byte_mask) {
729                    mb_change_byte = mb_change_bits[mb_change_index++];
730                    mb_change_byte_mask = 0x01;
731                }
732            }
733
734            pixels_left -= 4;
735        }
736
737        /* next change row */
738        if (((y + 1) & 3) == 0)
739            mb_change_bits += s->mb_change_bits_row_size;
740
741        current_line += s->frame->linesize[0];
742    }
743}
744
745static void truemotion1_decode_24bit(TrueMotion1Context *s)
746{
747    int y;
748    int pixels_left;  /* remaining pixels on this line */
749    unsigned int predictor_pair;
750    unsigned int horiz_pred;
751    unsigned int *vert_pred;
752    unsigned int *current_pixel_pair;
753    unsigned char *current_line = s->frame->data[0];
754    int keyframe = s->flags & FLAG_KEYFRAME;
755
756    /* these variables are for managing the stream of macroblock change bits */
757    const unsigned char *mb_change_bits = s->mb_change_bits;
758    unsigned char mb_change_byte;
759    unsigned char mb_change_byte_mask;
760    int mb_change_index;
761
762    /* these variables are for managing the main index stream */
763    int index_stream_index = 0;  /* yes, the index into the index stream */
764    int index;
765
766    /* clean out the line buffer */
767    memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
768
769    GET_NEXT_INDEX();
770
771    for (y = 0; y < s->avctx->height; y++) {
772
773        /* re-init variables for the next line iteration */
774        horiz_pred = 0;
775        current_pixel_pair = (unsigned int *)current_line;
776        vert_pred = s->vert_pred;
777        mb_change_index = 0;
778        mb_change_byte = mb_change_bits[mb_change_index++];
779        mb_change_byte_mask = 0x01;
780        pixels_left = s->avctx->width;
781
782        while (pixels_left > 0) {
783
784            if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
785
786                switch (y & 3) {
787                case 0:
788                    /* if macroblock width is 2, apply C-Y-C-Y; else
789                     * apply C-Y-Y */
790                    if (s->block_width == 2) {
791                        APPLY_C_PREDICTOR_24();
792                        APPLY_Y_PREDICTOR_24();
793                        OUTPUT_PIXEL_PAIR();
794                        APPLY_C_PREDICTOR_24();
795                        APPLY_Y_PREDICTOR_24();
796                        OUTPUT_PIXEL_PAIR();
797                    } else {
798                        APPLY_C_PREDICTOR_24();
799                        APPLY_Y_PREDICTOR_24();
800                        OUTPUT_PIXEL_PAIR();
801                        APPLY_Y_PREDICTOR_24();
802                        OUTPUT_PIXEL_PAIR();
803                    }
804                    break;
805
806                case 1:
807                case 3:
808                    /* always apply 2 Y predictors on these iterations */
809                    APPLY_Y_PREDICTOR_24();
810                    OUTPUT_PIXEL_PAIR();
811                    APPLY_Y_PREDICTOR_24();
812                    OUTPUT_PIXEL_PAIR();
813                    break;
814
815                case 2:
816                    /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
817                     * depending on the macroblock type */
818                    if (s->block_type == BLOCK_2x2) {
819                        APPLY_C_PREDICTOR_24();
820                        APPLY_Y_PREDICTOR_24();
821                        OUTPUT_PIXEL_PAIR();
822                        APPLY_C_PREDICTOR_24();
823                        APPLY_Y_PREDICTOR_24();
824                        OUTPUT_PIXEL_PAIR();
825                    } else if (s->block_type == BLOCK_4x2) {
826                        APPLY_C_PREDICTOR_24();
827                        APPLY_Y_PREDICTOR_24();
828                        OUTPUT_PIXEL_PAIR();
829                        APPLY_Y_PREDICTOR_24();
830                        OUTPUT_PIXEL_PAIR();
831                    } else {
832                        APPLY_Y_PREDICTOR_24();
833                        OUTPUT_PIXEL_PAIR();
834                        APPLY_Y_PREDICTOR_24();
835                        OUTPUT_PIXEL_PAIR();
836                    }
837                    break;
838                }
839
840            } else {
841
842                /* skip (copy) four pixels, but reassign the horizontal
843                 * predictor */
844                *vert_pred++ = *current_pixel_pair++;
845                horiz_pred = *current_pixel_pair - *vert_pred;
846                *vert_pred++ = *current_pixel_pair++;
847
848            }
849
850            if (!keyframe) {
851                mb_change_byte_mask <<= 1;
852
853                /* next byte */
854                if (!mb_change_byte_mask) {
855                    mb_change_byte = mb_change_bits[mb_change_index++];
856                    mb_change_byte_mask = 0x01;
857                }
858            }
859
860            pixels_left -= 2;
861        }
862
863        /* next change row */
864        if (((y + 1) & 3) == 0)
865            mb_change_bits += s->mb_change_bits_row_size;
866
867        current_line += s->frame->linesize[0];
868    }
869}
870
871
872static int truemotion1_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
873                                    int *got_frame, AVPacket *avpkt)
874{
875    const uint8_t *buf = avpkt->data;
876    int ret, buf_size = avpkt->size;
877    TrueMotion1Context *s = avctx->priv_data;
878
879    s->buf = buf;
880    s->size = buf_size;
881
882    if ((ret = truemotion1_decode_header(s)) < 0)
883        return ret;
884
885    if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
886        return ret;
887
888    if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
889        truemotion1_decode_24bit(s);
890    } else if (compression_types[s->compression].algorithm != ALGO_NOP) {
891        truemotion1_decode_16bit(s);
892    }
893
894    if ((ret = av_frame_ref(rframe, s->frame)) < 0)
895        return ret;
896
897    *got_frame      = 1;
898
899    /* report that the buffer was completely consumed */
900    return buf_size;
901}
902
903static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
904{
905    TrueMotion1Context *s = avctx->priv_data;
906
907    av_frame_free(&s->frame);
908    av_freep(&s->vert_pred);
909
910    return 0;
911}
912
913const FFCodec ff_truemotion1_decoder = {
914    .p.name         = "truemotion1",
915    .p.long_name    = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),
916    .p.type         = AVMEDIA_TYPE_VIDEO,
917    .p.id           = AV_CODEC_ID_TRUEMOTION1,
918    .priv_data_size = sizeof(TrueMotion1Context),
919    .init           = truemotion1_decode_init,
920    .close          = truemotion1_decode_end,
921    FF_CODEC_DECODE_CB(truemotion1_decode_frame),
922    .p.capabilities = AV_CODEC_CAP_DR1,
923    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
924};
925