~ubuntu-branches/ubuntu/hardy/avidemux/hardy

« back to all changes in this revision

Viewing changes to avidemux/ADM_libraries/ADM_lavcodec/msrle.c

  • Committer: Bazaar Package Importer
  • Author(s): Matvey Kozhev
  • Date: 2007-12-18 13:53:04 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20071218135304-cdqec2lg2bglyz15
Tags: 1:2.4~preview3-0.0ubuntu1
* Upload to Ubuntu. (LP: #163287, LP: #126572)
* debian/changelog: re-added Ubuntu releases.
* debian/control:
  - Require debhelper >= 5.0.51 (for dh_icons) and imagemagick.
  - Build-depend on libsdl1.2-dev instead of libsdl-dev.
  - Build against newer libx264-dev. (LP: #138854)
  - Removed libamrnb-dev, not in Ubuntu yet.
* debian/rules:
  - Install all icon sizes, using convert (upstream installs none).
  - Added missing calls to dh_installmenu, dh_installman, dh_icons and
    dh_desktop.
* debian/menu, debian/avidemux-qt.menu:
  - Corrected package and executable names.
* debian/avidemux-common.install: Install icons.
* debian/avidemux.common.manpages: Install man/avidemux.1.
* debian/links, debian/avidemux-cli.links, debian/avidemux-gtk.links:
  - Link manpages to avidemux.1.gz.
* debian/install, debian/avidemux-qt.install, debian/avidemux-gtk.desktop,
  debian/avidemux-qt.desktop: Install desktop files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Micrsoft RLE 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 msrle.c
 
24
 * MS RLE Video Decoder by Mike Melanson (melanson@pcisys.net)
 
25
 * For more information about the MS RLE format, visit:
 
26
 *   http://www.pcisys.net/~melanson/codecs/
 
27
 *
 
28
 * The MS RLE decoder outputs PAL8 colorspace data.
 
29
 *
 
30
 * Note that this decoder expects the palette colors from the end of the
 
31
 * BITMAPINFO header passed through palctrl.
 
32
 */
 
33
 
 
34
#include <stdio.h>
 
35
#include <stdlib.h>
 
36
#include <string.h>
 
37
#include <unistd.h>
 
38
 
 
39
#include "avcodec.h"
 
40
#include "dsputil.h"
 
41
 
 
42
typedef struct MsrleContext {
 
43
    AVCodecContext *avctx;
 
44
    AVFrame frame;
 
45
 
 
46
    unsigned char *buf;
 
47
    int size;
 
48
 
 
49
} MsrleContext;
 
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
static int msrle_decode_init(AVCodecContext *avctx)
 
240
{
 
241
    MsrleContext *s = avctx->priv_data;
 
242
 
 
243
    s->avctx = avctx;
 
244
 
 
245
    avctx->pix_fmt = PIX_FMT_PAL8;
 
246
    s->frame.data[0] = NULL;
 
247
 
 
248
    return 0;
 
249
}
 
250
 
 
251
static int msrle_decode_frame(AVCodecContext *avctx,
 
252
                              void *data, int *data_size,
 
253
                              uint8_t *buf, int buf_size)
 
254
{
 
255
    MsrleContext *s = avctx->priv_data;
 
256
 
 
257
    s->buf = buf;
 
258
    s->size = buf_size;
 
259
 
 
260
    s->frame.reference = 1;
 
261
    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
 
262
    if (avctx->reget_buffer(avctx, &s->frame)) {
 
263
        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
 
264
        return -1;
 
265
    }
 
266
 
 
267
    switch (avctx->bits_per_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_sample);
 
277
    }
 
278
 
 
279
    *data_size = sizeof(AVFrame);
 
280
    *(AVFrame*)data = s->frame;
 
281
 
 
282
    /* report that the buffer was completely consumed */
 
283
    return buf_size;
 
284
}
 
285
 
 
286
static int msrle_decode_end(AVCodecContext *avctx)
 
287
{
 
288
    MsrleContext *s = avctx->priv_data;
 
289
 
 
290
    /* release the last frame */
 
291
    if (s->frame.data[0])
 
292
        avctx->release_buffer(avctx, &s->frame);
 
293
 
 
294
    return 0;
 
295
}
 
296
 
 
297
AVCodec msrle_decoder = {
 
298
    "msrle",
 
299
    CODEC_TYPE_VIDEO,
 
300
    CODEC_ID_MSRLE,
 
301
    sizeof(MsrleContext),
 
302
    msrle_decode_init,
 
303
    NULL,
 
304
    msrle_decode_end,
 
305
    msrle_decode_frame,
 
306
    CODEC_CAP_DR1,
 
307
};