Revision 44aa9771 libavcodec/tscc.c

View differences:

libavcodec/tscc.c
39 39
#include <stdlib.h>
40 40

  
41 41
#include "avcodec.h"
42
#include "msrledec.h"
42 43

  
43 44
#ifdef CONFIG_ZLIB
44 45
#include <zlib.h>
......
67 68

  
68 69
/*
69 70
 *
70
 * Decode RLE - almost identical to Windows BMP RLE8
71
 *              and enhanced to bigger color depths
72
 *
73
 */
74

  
75
static int decode_rle(CamtasiaContext *c, unsigned int srcsize)
76
{
77
    unsigned char *src = c->decomp_buf;
78
    unsigned char *output, *output_end;
79
    int p1, p2, line=c->height, pos=0, i;
80
    uint16_t pix16;
81
    uint32_t pix32;
82

  
83
    output = c->pic.data[0] + (c->height - 1) * c->pic.linesize[0];
84
    output_end = c->pic.data[0] + (c->height) * c->pic.linesize[0];
85
    while(src < c->decomp_buf + srcsize) {
86
        p1 = *src++;
87
        if(p1 == 0) { //Escape code
88
            p2 = *src++;
89
            if(p2 == 0) { //End-of-line
90
                output = c->pic.data[0] + (--line) * c->pic.linesize[0];
91
                if (line < 0)
92
                    return -1;
93
                pos = 0;
94
                continue;
95
            } else if(p2 == 1) { //End-of-picture
96
                return 0;
97
            } else if(p2 == 2) { //Skip
98
                p1 = *src++;
99
                p2 = *src++;
100
                line -= p2;
101
                if (line < 0)
102
                    return -1;
103
                pos += p1;
104
                output = c->pic.data[0] + line * c->pic.linesize[0] + pos * (c->bpp / 8);
105
                continue;
106
            }
107
            // Copy data
108
            if (output + p2 * (c->bpp / 8) > output_end) {
109
                src += p2 * (c->bpp / 8);
110
                continue;
111
            }
112
            if ((c->bpp == 8) || (c->bpp == 24)) {
113
                for(i = 0; i < p2 * (c->bpp / 8); i++) {
114
                    *output++ = *src++;
115
                }
116
                // RLE8 copy is actually padded - and runs are not!
117
                if(c->bpp == 8 && (p2 & 1)) {
118
                    src++;
119
                }
120
            } else if (c->bpp == 16) {
121
                for(i = 0; i < p2; i++) {
122
                    pix16 = AV_RL16(src);
123
                    src += 2;
124
                    *(uint16_t*)output = pix16;
125
                    output += 2;
126
                }
127
            } else if (c->bpp == 32) {
128
                for(i = 0; i < p2; i++) {
129
                    pix32 = AV_RL32(src);
130
                    src += 4;
131
                    *(uint32_t*)output = pix32;
132
                    output += 4;
133
                }
134
            }
135
            pos += p2;
136
        } else { //Run of pixels
137
            int pix[4]; //original pixel
138
            switch(c->bpp){
139
            case  8: pix[0] = *src++;
140
                     break;
141
            case 16: pix16 = AV_RL16(src);
142
                     src += 2;
143
                     *(uint16_t*)pix = pix16;
144
                     break;
145
            case 24: pix[0] = *src++;
146
                     pix[1] = *src++;
147
                     pix[2] = *src++;
148
                     break;
149
            case 32: pix32 = AV_RL32(src);
150
                     src += 4;
151
                     *(uint32_t*)pix = pix32;
152
                     break;
153
            }
154
            if (output + p1 * (c->bpp / 8) > output_end)
155
                continue;
156
            for(i = 0; i < p1; i++) {
157
                switch(c->bpp){
158
                case  8: *output++ = pix[0];
159
                         break;
160
                case 16: *(uint16_t*)output = pix16;
161
                         output += 2;
162
                         break;
163
                case 24: *output++ = pix[0];
164
                         *output++ = pix[1];
165
                         *output++ = pix[2];
166
                         break;
167
                case 32: *(uint32_t*)output = pix32;
168
                         output += 4;
169
                         break;
170
                }
171
            }
172
            pos += p1;
173
        }
174
    }
175

  
176
    av_log(c->avctx, AV_LOG_ERROR, "Camtasia warning: no End-of-picture code\n");
177
    return 1;
178
}
179

  
180
/*
181
 *
182 71
 * Decode a frame
183 72
 *
184 73
 */
......
223 112

  
224 113

  
225 114
    if(zret != Z_DATA_ERROR)
226
        decode_rle(c, c->zstream.avail_out);
115
        ff_msrle_decode(avctx, &c->pic, c->bpp, c->decomp_buf, c->zstream.avail_out);
227 116

  
228 117
    /* make the palette available on the way out */
229 118
    if (c->avctx->pix_fmt == PIX_FMT_PAL8) {

Also available in: Unified diff