Browse code

Factorize out code used for MS RLE format decoding in different decoders.

Originally committed as revision 15356 to svn://svn.ffmpeg.org/ffmpeg/trunk

Kostya Shishkov authored on 2008/09/18 14:20:54
Showing 6 changed files
... ...
@@ -26,7 +26,7 @@ HEADERS = avcodec.h opt.h
26 26
 OBJS-$(CONFIG_ENCODERS)                += faandct.o jfdctfst.o jfdctint.o
27 27
 
28 28
 OBJS-$(CONFIG_AAC_DECODER)             += aac.o aactab.o mdct.o fft.o
29
-OBJS-$(CONFIG_AASC_DECODER)            += aasc.o
29
+OBJS-$(CONFIG_AASC_DECODER)            += aasc.o msrledec.o
30 30
 OBJS-$(CONFIG_AC3_DECODER)             += eac3dec.o ac3dec.o ac3tab.o ac3dec_data.o ac3.o mdct.o fft.o
31 31
 OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc.o ac3tab.o ac3.o
32 32
 OBJS-$(CONFIG_ALAC_DECODER)            += alac.o
... ...
@@ -136,7 +136,7 @@ OBJS-$(CONFIG_MSMPEG4V2_DECODER)       += msmpeg4.o msmpeg4data.o h263dec.o h263
136 136
 OBJS-$(CONFIG_MSMPEG4V2_ENCODER)       += msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o mpeg12data.o mpegvideo.o error_resilience.o
137 137
 OBJS-$(CONFIG_MSMPEG4V3_DECODER)       += msmpeg4.o msmpeg4data.o h263dec.o h263.o mpeg12data.o mpegvideo.o error_resilience.o
138 138
 OBJS-$(CONFIG_MSMPEG4V3_ENCODER)       += msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o mpeg12data.o mpegvideo.o error_resilience.o
139
-OBJS-$(CONFIG_MSRLE_DECODER)           += msrle.o
139
+OBJS-$(CONFIG_MSRLE_DECODER)           += msrle.o msrledec.o
140 140
 OBJS-$(CONFIG_MSVIDEO1_DECODER)        += msvideo1.o
141 141
 OBJS-$(CONFIG_MSZH_DECODER)            += lcldec.o
142 142
 OBJS-$(CONFIG_NELLYMOSER_DECODER)      += nellymoserdec.o nellymoser.o mdct.o fft.o
... ...
@@ -197,7 +197,7 @@ OBJS-$(CONFIG_TIFF_ENCODER)            += tiffenc.o rle.o lzwenc.o
197 197
 OBJS-$(CONFIG_TRUEMOTION1_DECODER)     += truemotion1.o
198 198
 OBJS-$(CONFIG_TRUEMOTION2_DECODER)     += truemotion2.o
199 199
 OBJS-$(CONFIG_TRUESPEECH_DECODER)      += truespeech.o
200
-OBJS-$(CONFIG_TSCC_DECODER)            += tscc.o
200
+OBJS-$(CONFIG_TSCC_DECODER)            += tscc.o msrledec.o
201 201
 OBJS-$(CONFIG_TTA_DECODER)             += tta.o
202 202
 OBJS-$(CONFIG_TXD_DECODER)             += txd.o s3tc.o
203 203
 OBJS-$(CONFIG_ULTI_DECODER)            += ulti.o
... ...
@@ -30,6 +30,7 @@
30 30
 
31 31
 #include "avcodec.h"
32 32
 #include "dsputil.h"
33
+#include "msrledec.h"
33 34
 
34 35
 typedef struct AascContext {
35 36
     AVCodecContext *avctx;
... ...
@@ -61,13 +62,6 @@ static int aasc_decode_frame(AVCodecContext *avctx,
61 61
                               const uint8_t *buf, int buf_size)
62 62
 {
63 63
     AascContext *s = avctx->priv_data;
64
-    int stream_ptr = 4;
65
-    unsigned char rle_code;
66
-    unsigned char stream_byte;
67
-    int pixel_ptr = 0;
68
-    int row_dec, row_ptr;
69
-    int frame_size;
70
-    int i;
71 64
 
72 65
     s->frame.reference = 1;
73 66
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
... ...
@@ -76,72 +70,7 @@ static int aasc_decode_frame(AVCodecContext *avctx,
76 76
         return -1;
77 77
     }
78 78
 
79
-    row_dec = s->frame.linesize[0];
80
-    row_ptr = (s->avctx->height - 1) * row_dec;
81
-    frame_size = row_dec * s->avctx->height;
82
-
83
-    while (row_ptr >= 0) {
84
-        FETCH_NEXT_STREAM_BYTE();
85
-        rle_code = stream_byte;
86
-        if (rle_code == 0) {
87
-            /* fetch the next byte to see how to handle escape code */
88
-            FETCH_NEXT_STREAM_BYTE();
89
-            if (stream_byte == 0) {
90
-                /* line is done, goto the next one */
91
-                row_ptr -= row_dec;
92
-                pixel_ptr = 0;
93
-            } else if (stream_byte == 1) {
94
-                /* decode is done */
95
-                break;
96
-            } else if (stream_byte == 2) {
97
-                /* reposition frame decode coordinates */
98
-                FETCH_NEXT_STREAM_BYTE();
99
-                pixel_ptr += stream_byte;
100
-                FETCH_NEXT_STREAM_BYTE();
101
-                row_ptr -= stream_byte * row_dec;
102
-            } else {
103
-                /* copy pixels from encoded stream */
104
-                if ((pixel_ptr + stream_byte > avctx->width * 3) ||
105
-                    (row_ptr < 0)) {
106
-                    av_log(s->avctx, AV_LOG_ERROR, " AASC: frame ptr just went out of bounds (copy1)\n");
107
-                    break;
108
-                }
109
-
110
-                rle_code = stream_byte;
111
-                if (stream_ptr + rle_code > buf_size) {
112
-                    av_log(s->avctx, AV_LOG_ERROR, " AASC: stream ptr just went out of bounds (copy2)\n");
113
-                    break;
114
-                }
115
-
116
-                for (i = 0; i < rle_code; i++) {
117
-                    FETCH_NEXT_STREAM_BYTE();
118
-                    s->frame.data[0][row_ptr + pixel_ptr] = stream_byte;
119
-                    pixel_ptr++;
120
-                }
121
-                if (rle_code & 1)
122
-                    stream_ptr++;
123
-            }
124
-        } else {
125
-            /* decode a run of data */
126
-            if ((pixel_ptr + rle_code > avctx->width * 3) ||
127
-                (row_ptr < 0)) {
128
-                av_log(s->avctx, AV_LOG_ERROR, " AASC: frame ptr just went out of bounds (run1)\n");
129
-                break;
130
-            }
131
-
132
-            FETCH_NEXT_STREAM_BYTE();
133
-
134
-            while(rle_code--) {
135
-                s->frame.data[0][row_ptr + pixel_ptr] = stream_byte;
136
-                pixel_ptr++;
137
-            }
138
-        }
139
-    }
140
-
141
-    /* one last sanity check on the way out */
142
-    if (stream_ptr < buf_size)
143
-        av_log(s->avctx, AV_LOG_ERROR, " AASC: ended frame decode with bytes left over (%d < %d)\n",
144
-            stream_ptr, buf_size);
79
+    ff_msrle_decode(avctx, &s->frame, 8, buf, buf_size);
145 80
 
146 81
     *data_size = sizeof(AVFrame);
147 82
     *(AVFrame*)data = s->frame;
... ...
@@ -38,6 +38,7 @@
38 38
 
39 39
 #include "avcodec.h"
40 40
 #include "dsputil.h"
41
+#include "msrledec.h"
41 42
 
42 43
 typedef struct MsrleContext {
43 44
     AVCodecContext *avctx;
... ...
@@ -48,194 +49,6 @@ typedef struct MsrleContext {
48 48
 
49 49
 } MsrleContext;
50 50
 
51
-#define FETCH_NEXT_STREAM_BYTE() \
52
-    if (stream_ptr >= s->size) \
53
-    { \
54
-      av_log(s->avctx, AV_LOG_ERROR, " MS RLE: stream ptr just went out of bounds (1)\n"); \
55
-      return; \
56
-    } \
57
-    stream_byte = s->buf[stream_ptr++];
58
-
59
-static void msrle_decode_pal4(MsrleContext *s)
60
-{
61
-    int stream_ptr = 0;
62
-    unsigned char rle_code;
63
-    unsigned char extra_byte, odd_pixel;
64
-    unsigned char stream_byte;
65
-    int pixel_ptr = 0;
66
-    int row_dec = s->frame.linesize[0];
67
-    int row_ptr = (s->avctx->height - 1) * row_dec;
68
-    int frame_size = row_dec * s->avctx->height;
69
-    int i;
70
-
71
-    /* make the palette available */
72
-    memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
73
-    if (s->avctx->palctrl->palette_changed) {
74
-        s->frame.palette_has_changed = 1;
75
-        s->avctx->palctrl->palette_changed = 0;
76
-    }
77
-
78
-    while (row_ptr >= 0) {
79
-        FETCH_NEXT_STREAM_BYTE();
80
-        rle_code = stream_byte;
81
-        if (rle_code == 0) {
82
-            /* fetch the next byte to see how to handle escape code */
83
-            FETCH_NEXT_STREAM_BYTE();
84
-            if (stream_byte == 0) {
85
-                /* line is done, goto the next one */
86
-                row_ptr -= row_dec;
87
-                pixel_ptr = 0;
88
-            } else if (stream_byte == 1) {
89
-                /* decode is done */
90
-                return;
91
-            } else if (stream_byte == 2) {
92
-                /* reposition frame decode coordinates */
93
-                FETCH_NEXT_STREAM_BYTE();
94
-                pixel_ptr += stream_byte;
95
-                FETCH_NEXT_STREAM_BYTE();
96
-                row_ptr -= stream_byte * row_dec;
97
-        } else {
98
-            // copy pixels from encoded stream
99
-            odd_pixel =  stream_byte & 1;
100
-            rle_code = (stream_byte + 1) / 2;
101
-            extra_byte = rle_code & 0x01;
102
-            if ((row_ptr + pixel_ptr + stream_byte > frame_size) ||
103
-                (row_ptr < 0)) {
104
-                av_log(s->avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n");
105
-                return;
106
-            }
107
-
108
-            for (i = 0; i < rle_code; i++) {
109
-                if (pixel_ptr >= s->avctx->width)
110
-                    break;
111
-                FETCH_NEXT_STREAM_BYTE();
112
-                s->frame.data[0][row_ptr + pixel_ptr] = stream_byte >> 4;
113
-                pixel_ptr++;
114
-                if (i + 1 == rle_code && odd_pixel)
115
-                    break;
116
-                if (pixel_ptr >= s->avctx->width)
117
-                    break;
118
-                s->frame.data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F;
119
-                pixel_ptr++;
120
-            }
121
-
122
-            // if the RLE code is odd, skip a byte in the stream
123
-            if (extra_byte)
124
-              stream_ptr++;
125
-            }
126
-        } else {
127
-            // decode a run of data
128
-            if ((row_ptr + pixel_ptr + stream_byte > frame_size) ||
129
-                (row_ptr < 0)) {
130
-                av_log(s->avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n");
131
-                return;
132
-            }
133
-            FETCH_NEXT_STREAM_BYTE();
134
-            for (i = 0; i < rle_code; i++) {
135
-                if (pixel_ptr >= s->avctx->width)
136
-                    break;
137
-                if ((i & 1) == 0)
138
-                    s->frame.data[0][row_ptr + pixel_ptr] = stream_byte >> 4;
139
-                else
140
-                    s->frame.data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F;
141
-                pixel_ptr++;
142
-            }
143
-        }
144
-    }
145
-
146
-    /* one last sanity check on the way out */
147
-    if (stream_ptr < s->size)
148
-        av_log(s->avctx, AV_LOG_ERROR, " MS RLE: ended frame decode with bytes left over (%d < %d)\n",
149
-            stream_ptr, s->size);
150
-}
151
-
152
-
153
-
154
-static void msrle_decode_pal8(MsrleContext *s)
155
-{
156
-    int stream_ptr = 0;
157
-    unsigned char rle_code;
158
-    unsigned char extra_byte;
159
-    unsigned char stream_byte;
160
-    int pixel_ptr = 0;
161
-    int row_dec = s->frame.linesize[0];
162
-    int row_ptr = (s->avctx->height - 1) * row_dec;
163
-    int frame_size = row_dec * s->avctx->height;
164
-
165
-    /* make the palette available */
166
-    memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
167
-    if (s->avctx->palctrl->palette_changed) {
168
-        s->frame.palette_has_changed = 1;
169
-        s->avctx->palctrl->palette_changed = 0;
170
-    }
171
-
172
-    while (row_ptr >= 0) {
173
-        FETCH_NEXT_STREAM_BYTE();
174
-        rle_code = stream_byte;
175
-        if (rle_code == 0) {
176
-            /* fetch the next byte to see how to handle escape code */
177
-            FETCH_NEXT_STREAM_BYTE();
178
-            if (stream_byte == 0) {
179
-                /* line is done, goto the next one */
180
-                row_ptr -= row_dec;
181
-                pixel_ptr = 0;
182
-            } else if (stream_byte == 1) {
183
-                /* decode is done */
184
-                return;
185
-            } else if (stream_byte == 2) {
186
-                /* reposition frame decode coordinates */
187
-                FETCH_NEXT_STREAM_BYTE();
188
-                pixel_ptr += stream_byte;
189
-                FETCH_NEXT_STREAM_BYTE();
190
-                row_ptr -= stream_byte * row_dec;
191
-            } else {
192
-                /* copy pixels from encoded stream */
193
-                if ((row_ptr + pixel_ptr + stream_byte > frame_size) ||
194
-                    (row_ptr < 0)) {
195
-                    av_log(s->avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n");
196
-                    return;
197
-                }
198
-
199
-                rle_code = stream_byte;
200
-                extra_byte = stream_byte & 0x01;
201
-                if (stream_ptr + rle_code + extra_byte > s->size) {
202
-                    av_log(s->avctx, AV_LOG_ERROR, " MS RLE: stream ptr just went out of bounds (2)\n");
203
-                    return;
204
-                }
205
-
206
-                while (rle_code--) {
207
-                    FETCH_NEXT_STREAM_BYTE();
208
-                    s->frame.data[0][row_ptr + pixel_ptr] = stream_byte;
209
-                    pixel_ptr++;
210
-                }
211
-
212
-                /* if the RLE code is odd, skip a byte in the stream */
213
-                if (extra_byte)
214
-                    stream_ptr++;
215
-            }
216
-        } else {
217
-            /* decode a run of data */
218
-            if ((row_ptr + pixel_ptr + stream_byte > frame_size) ||
219
-                (row_ptr < 0)) {
220
-                av_log(s->avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (2)\n");
221
-                return;
222
-            }
223
-
224
-            FETCH_NEXT_STREAM_BYTE();
225
-
226
-            while(rle_code--) {
227
-                s->frame.data[0][row_ptr + pixel_ptr] = stream_byte;
228
-                pixel_ptr++;
229
-            }
230
-        }
231
-    }
232
-
233
-    /* one last sanity check on the way out */
234
-    if (stream_ptr < s->size)
235
-        av_log(s->avctx, AV_LOG_ERROR, " MS RLE: ended frame decode with bytes left over (%d < %d)\n",
236
-            stream_ptr, s->size);
237
-}
238
-
239 51
 static av_cold int msrle_decode_init(AVCodecContext *avctx)
240 52
 {
241 53
     MsrleContext *s = avctx->priv_data;
... ...
@@ -264,18 +77,15 @@ static int msrle_decode_frame(AVCodecContext *avctx,
264 264
         return -1;
265 265
     }
266 266
 
267
-    switch (avctx->bits_per_coded_sample) {
268
-        case 8:
269
-            msrle_decode_pal8(s);
270
-            break;
271
-        case 4:
272
-            msrle_decode_pal4(s);
273
-            break;
274
-        default:
275
-            av_log(avctx, AV_LOG_ERROR, "Don't know how to decode depth %u.\n",
276
-                   avctx->bits_per_coded_sample);
267
+    /* make the palette available */
268
+    memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
269
+    if (s->avctx->palctrl->palette_changed) {
270
+        s->frame.palette_has_changed = 1;
271
+        s->avctx->palctrl->palette_changed = 0;
277 272
     }
278 273
 
274
+    ff_msrle_decode(avctx, &s->frame, avctx->bits_per_coded_sample, buf, buf_size);
275
+
279 276
     *data_size = sizeof(AVFrame);
280 277
     *(AVFrame*)data = s->frame;
281 278
 
282 279
new file mode 100644
... ...
@@ -0,0 +1,254 @@
0
+/*
1
+ * Micrsoft RLE Decoder
2
+ * Copyright (C) 2008 Konstantin Shishkov
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+/**
22
+ * @file msrledec.c
23
+ * MS RLE Decoder based on decoder by Mike Melanson and my own for TSCC
24
+ * For more information about the MS RLE format, visit:
25
+ *   http://www.multimedia.cx/msrle.txt
26
+ */
27
+
28
+#include "avcodec.h"
29
+
30
+#define FETCH_NEXT_STREAM_BYTE() \
31
+    if (stream_ptr >= data_size) \
32
+    { \
33
+      av_log(avctx, AV_LOG_ERROR, " MS RLE: stream ptr just went out of bounds (1)\n"); \
34
+      return -1; \
35
+    } \
36
+    stream_byte = data[stream_ptr++];
37
+
38
+static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic,
39
+                              const uint8_t *data, int data_size)
40
+{
41
+    int stream_ptr = 0;
42
+    unsigned char rle_code;
43
+    unsigned char extra_byte, odd_pixel;
44
+    unsigned char stream_byte;
45
+    int pixel_ptr = 0;
46
+    int row_dec = pic->linesize[0];
47
+    int row_ptr = (avctx->height - 1) * row_dec;
48
+    int frame_size = row_dec * avctx->height;
49
+    int i;
50
+
51
+    while (row_ptr >= 0) {
52
+        FETCH_NEXT_STREAM_BYTE();
53
+        rle_code = stream_byte;
54
+        if (rle_code == 0) {
55
+            /* fetch the next byte to see how to handle escape code */
56
+            FETCH_NEXT_STREAM_BYTE();
57
+            if (stream_byte == 0) {
58
+                /* line is done, goto the next one */
59
+                row_ptr -= row_dec;
60
+                pixel_ptr = 0;
61
+            } else if (stream_byte == 1) {
62
+                /* decode is done */
63
+                return 0;
64
+            } else if (stream_byte == 2) {
65
+                /* reposition frame decode coordinates */
66
+                FETCH_NEXT_STREAM_BYTE();
67
+                pixel_ptr += stream_byte;
68
+                FETCH_NEXT_STREAM_BYTE();
69
+                row_ptr -= stream_byte * row_dec;
70
+        } else {
71
+            // copy pixels from encoded stream
72
+            odd_pixel =  stream_byte & 1;
73
+            rle_code = (stream_byte + 1) / 2;
74
+            extra_byte = rle_code & 0x01;
75
+            if ((row_ptr + pixel_ptr + stream_byte > frame_size) ||
76
+                (row_ptr < 0)) {
77
+                av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n");
78
+                return -1;
79
+            }
80
+
81
+            for (i = 0; i < rle_code; i++) {
82
+                if (pixel_ptr >= avctx->width)
83
+                    break;
84
+                FETCH_NEXT_STREAM_BYTE();
85
+                pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4;
86
+                pixel_ptr++;
87
+                if (i + 1 == rle_code && odd_pixel)
88
+                    break;
89
+                if (pixel_ptr >= avctx->width)
90
+                    break;
91
+                pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F;
92
+                pixel_ptr++;
93
+            }
94
+
95
+            // if the RLE code is odd, skip a byte in the stream
96
+            if (extra_byte)
97
+              stream_ptr++;
98
+            }
99
+        } else {
100
+            // decode a run of data
101
+            if ((row_ptr + pixel_ptr + stream_byte > frame_size) ||
102
+                (row_ptr < 0)) {
103
+                av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n");
104
+                return -1;
105
+            }
106
+            FETCH_NEXT_STREAM_BYTE();
107
+            for (i = 0; i < rle_code; i++) {
108
+                if (pixel_ptr >= avctx->width)
109
+                    break;
110
+                if ((i & 1) == 0)
111
+                    pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4;
112
+                else
113
+                    pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F;
114
+                pixel_ptr++;
115
+            }
116
+        }
117
+    }
118
+
119
+    /* one last sanity check on the way out */
120
+    if (stream_ptr < data_size) {
121
+        av_log(avctx, AV_LOG_ERROR, " MS RLE: ended frame decode with bytes left over (%d < %d)\n",
122
+            stream_ptr, data_size);
123
+        return -1;
124
+    }
125
+
126
+    return 0;
127
+}
128
+
129
+
130
+static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int depth,
131
+                                    const uint8_t *data, int srcsize)
132
+{
133
+    uint8_t *output, *output_end;
134
+    const uint8_t* src = data;
135
+    int p1, p2, line=avctx->height, pos=0, i;
136
+    uint16_t pix16;
137
+    uint32_t pix32;
138
+
139
+    output = pic->data[0] + (avctx->height - 1) * pic->linesize[0];
140
+    output_end = pic->data[0] + (avctx->height) * pic->linesize[0];
141
+    while(src < data + srcsize) {
142
+        p1 = *src++;
143
+        if(p1 == 0) { //Escape code
144
+            p2 = *src++;
145
+            if(p2 == 0) { //End-of-line
146
+                output = pic->data[0] + (--line) * pic->linesize[0];
147
+                if (line < 0)
148
+                    return -1;
149
+                pos = 0;
150
+                continue;
151
+            } else if(p2 == 1) { //End-of-picture
152
+                return 0;
153
+            } else if(p2 == 2) { //Skip
154
+                p1 = *src++;
155
+                p2 = *src++;
156
+                line -= p2;
157
+                if (line < 0)
158
+                    return -1;
159
+                pos += p1;
160
+                output = pic->data[0] + line * pic->linesize[0] + pos * (depth >> 3);
161
+                continue;
162
+            }
163
+            // Copy data
164
+            if (output + p2 * (depth >> 3) > output_end) {
165
+                src += p2 * (depth >> 3);
166
+                continue;
167
+            }
168
+            if ((depth == 8) || (depth == 24)) {
169
+                for(i = 0; i < p2 * (depth >> 3); i++) {
170
+                    *output++ = *src++;
171
+                }
172
+                // RLE8 copy is actually padded - and runs are not!
173
+                if(depth == 8 && (p2 & 1)) {
174
+                    src++;
175
+                }
176
+            } else if (depth == 16) {
177
+                for(i = 0; i < p2; i++) {
178
+                    pix16 = AV_RL16(src);
179
+                    src += 2;
180
+                    *(uint16_t*)output = pix16;
181
+                    output += 2;
182
+                }
183
+            } else if (depth == 32) {
184
+                for(i = 0; i < p2; i++) {
185
+                    pix32 = AV_RL32(src);
186
+                    src += 4;
187
+                    *(uint32_t*)output = pix32;
188
+                    output += 4;
189
+                }
190
+            }
191
+            pos += p2;
192
+        } else { //Run of pixels
193
+            int pix[4]; //original pixel
194
+            switch(depth){
195
+            case  8: pix[0] = *src++;
196
+                     break;
197
+            case 16: pix16 = AV_RL16(src);
198
+                     src += 2;
199
+                     *(uint16_t*)pix = pix16;
200
+                     break;
201
+            case 24: pix[0] = *src++;
202
+                     pix[1] = *src++;
203
+                     pix[2] = *src++;
204
+                     break;
205
+            case 32: pix32 = AV_RL32(src);
206
+                     src += 4;
207
+                     *(uint32_t*)pix = pix32;
208
+                     break;
209
+            }
210
+            if (output + p1 * (depth >> 3) > output_end)
211
+                continue;
212
+            for(i = 0; i < p1; i++) {
213
+                switch(depth){
214
+                case  8: *output++ = pix[0];
215
+                         break;
216
+                case 16: *(uint16_t*)output = pix16;
217
+                         output += 2;
218
+                         break;
219
+                case 24: *output++ = pix[0];
220
+                         *output++ = pix[1];
221
+                         *output++ = pix[2];
222
+                         break;
223
+                case 32: *(uint32_t*)output = pix32;
224
+                         output += 4;
225
+                         break;
226
+                }
227
+            }
228
+            pos += p1;
229
+        }
230
+    }
231
+
232
+    av_log(avctx, AV_LOG_WARNING, "MS RLE warning: no End-of-picture code\n");
233
+    return 0;
234
+}
235
+
236
+
237
+int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth,
238
+                    const uint8_t* data, int data_size)
239
+{
240
+    switch(depth){
241
+    case  4:
242
+        return msrle_decode_pal4(avctx, pic, data, data_size);
243
+    case  8:
244
+    case 16:
245
+    case 24:
246
+    case 32:
247
+        return msrle_decode_8_16_24_32(avctx, pic, depth, data, data_size);
248
+    default:
249
+        av_log(avctx, AV_LOG_ERROR, "Unknown depth %d\n", depth);
250
+        return -1;
251
+    }
252
+}
253
+
0 254
new file mode 100644
... ...
@@ -0,0 +1,40 @@
0
+/*
1
+ * Micrsoft RLE Decoder
2
+ * Copyright (C) 2008 Konstantin Shishkov
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#ifndef AVCODEC_MSRLEDEC_H
22
+#define AVCODEC_MSRLEDEC_H
23
+
24
+#include "avcodec.h"
25
+
26
+/**
27
+ * decode stream in MS RLE format into frame
28
+ *
29
+ * @param avctx     codec context
30
+ * @param pic       destination frame
31
+ * @param depth     bit depth
32
+ * @param data      input stream
33
+ * @param data_size input size
34
+ */
35
+int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth,
36
+                    const uint8_t* data, int data_size);
37
+
38
+#endif /* AVCODEC_MSRLEDEC_H */
39
+
... ...
@@ -39,6 +39,7 @@
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,118 +68,6 @@ typedef struct TsccContext {
67 67
 
68 68
 /*
69 69
  *
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 70
  * Decode a frame
183 71
  *
184 72
  */
... ...
@@ -223,7 +112,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const
223 223
 
224 224
 
225 225
     if(zret != Z_DATA_ERROR)
226
-        decode_rle(c, c->zstream.avail_out);
226
+        ff_msrle_decode(avctx, &c->pic, c->bpp, c->decomp_buf, c->zstream.avail_out);
227 227
 
228 228
     /* make the palette available on the way out */
229 229
     if (c->avctx->pix_fmt == PIX_FMT_PAL8) {