Mercurial > libavcodec.hg
annotate msrledec.c @ 9896:bbefbca72722 libavcodec
Drop code that attempts to decode frames that are prefixed by junk.
Too often it ends up decoding random data into noise without detecting
it (for example after seeking of some MP3 data with oddly often occurring
startcode emulation).
Fixes issue1154.
| author | michael |
|---|---|
| date | Tue, 30 Jun 2009 03:57:27 +0000 |
| parents | e7032c44d4a7 |
| children | 71cf44ecaa70 |
| rev | line source |
|---|---|
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
1 /* |
| 9684 | 2 * Microsoft RLE decoder |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
3 * Copyright (C) 2008 Konstantin Shishkov |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
4 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
5 * This file is part of FFmpeg. |
|
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
6 * |
|
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
11 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
15 * Lesser General Public License for more details. |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
16 * |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
|
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
20 */ |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
21 |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
22 /** |
|
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8573
diff
changeset
|
23 * @file libavcodec/msrledec.c |
| 9684 | 24 * MS RLE decoder based on decoder by Mike Melanson and my own for TSCC |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
25 * For more information about the MS RLE format, visit: |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
26 * http://www.multimedia.cx/msrle.txt |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
27 */ |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
28 |
|
8573
2acf0ae7b041
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
8266
diff
changeset
|
29 #include "libavutil/intreadwrite.h" |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
30 #include "avcodec.h" |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
31 |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
32 #define FETCH_NEXT_STREAM_BYTE() \ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
33 if (stream_ptr >= data_size) \ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
34 { \ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
35 av_log(avctx, AV_LOG_ERROR, " MS RLE: stream ptr just went out of bounds (1)\n"); \ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
36 return -1; \ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
37 } \ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
38 stream_byte = data[stream_ptr++]; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
39 |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
40 static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
41 const uint8_t *data, int data_size) |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
42 { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
43 int stream_ptr = 0; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
44 unsigned char rle_code; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
45 unsigned char extra_byte, odd_pixel; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
46 unsigned char stream_byte; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
47 int pixel_ptr = 0; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
48 int row_dec = pic->linesize[0]; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
49 int row_ptr = (avctx->height - 1) * row_dec; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
50 int frame_size = row_dec * avctx->height; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
51 int i; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
52 |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
53 while (row_ptr >= 0) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
54 FETCH_NEXT_STREAM_BYTE(); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
55 rle_code = stream_byte; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
56 if (rle_code == 0) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
57 /* fetch the next byte to see how to handle escape code */ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
58 FETCH_NEXT_STREAM_BYTE(); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
59 if (stream_byte == 0) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
60 /* line is done, goto the next one */ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
61 row_ptr -= row_dec; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
62 pixel_ptr = 0; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
63 } else if (stream_byte == 1) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
64 /* decode is done */ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
65 return 0; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
66 } else if (stream_byte == 2) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
67 /* reposition frame decode coordinates */ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
68 FETCH_NEXT_STREAM_BYTE(); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
69 pixel_ptr += stream_byte; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
70 FETCH_NEXT_STREAM_BYTE(); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
71 row_ptr -= stream_byte * row_dec; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
72 } else { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
73 // copy pixels from encoded stream |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
74 odd_pixel = stream_byte & 1; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
75 rle_code = (stream_byte + 1) / 2; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
76 extra_byte = rle_code & 0x01; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
77 if ((row_ptr + pixel_ptr + stream_byte > frame_size) || |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
78 (row_ptr < 0)) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
79 av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
80 return -1; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
81 } |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
82 |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
83 for (i = 0; i < rle_code; i++) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
84 if (pixel_ptr >= avctx->width) |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
85 break; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
86 FETCH_NEXT_STREAM_BYTE(); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
87 pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
88 pixel_ptr++; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
89 if (i + 1 == rle_code && odd_pixel) |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
90 break; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
91 if (pixel_ptr >= avctx->width) |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
92 break; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
93 pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
94 pixel_ptr++; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
95 } |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
96 |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
97 // if the RLE code is odd, skip a byte in the stream |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
98 if (extra_byte) |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
99 stream_ptr++; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
100 } |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
101 } else { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
102 // decode a run of data |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
103 if ((row_ptr + pixel_ptr + stream_byte > frame_size) || |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
104 (row_ptr < 0)) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
105 av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
106 return -1; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
107 } |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
108 FETCH_NEXT_STREAM_BYTE(); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
109 for (i = 0; i < rle_code; i++) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
110 if (pixel_ptr >= avctx->width) |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
111 break; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
112 if ((i & 1) == 0) |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
113 pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
114 else |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
115 pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
116 pixel_ptr++; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
117 } |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
118 } |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
119 } |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
120 |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
121 /* one last sanity check on the way out */ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
122 if (stream_ptr < data_size) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
123 av_log(avctx, AV_LOG_ERROR, " MS RLE: ended frame decode with bytes left over (%d < %d)\n", |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
124 stream_ptr, data_size); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
125 return -1; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
126 } |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
127 |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
128 return 0; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
129 } |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
130 |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
131 |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
132 static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int depth, |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
133 const uint8_t *data, int srcsize) |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
134 { |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
135 uint8_t *output, *output_end; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
136 const uint8_t* src = data; |
|
9657
8a65ae8929fb
Fix off-by-one error in MS RLE decoder which may result into writing past
kostya
parents:
8803
diff
changeset
|
137 int p1, p2, line=avctx->height - 1, pos=0, i; |
|
8803
096ab16191a9
Add av_uninit macro to variables to avoid false positive warnings:
diego
parents:
8718
diff
changeset
|
138 uint16_t av_uninit(pix16); |
|
096ab16191a9
Add av_uninit macro to variables to avoid false positive warnings:
diego
parents:
8718
diff
changeset
|
139 uint32_t av_uninit(pix32); |
| 2967 | 140 |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
141 output = pic->data[0] + (avctx->height - 1) * pic->linesize[0]; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
142 output_end = pic->data[0] + (avctx->height) * pic->linesize[0]; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
143 while(src < data + srcsize) { |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
144 p1 = *src++; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
145 if(p1 == 0) { //Escape code |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
146 p2 = *src++; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
147 if(p2 == 0) { //End-of-line |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
148 output = pic->data[0] + (--line) * pic->linesize[0]; |
| 9719 | 149 if (line < 0 && !(src+1 < data + srcsize && AV_RB16(src) == 1)) { |
| 8265 | 150 av_log(avctx, AV_LOG_ERROR, "Next line is beyond picture bounds\n"); |
| 2455 | 151 return -1; |
| 8265 | 152 } |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
153 pos = 0; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
154 continue; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
155 } else if(p2 == 1) { //End-of-picture |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
156 return 0; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
157 } else if(p2 == 2) { //Skip |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
158 p1 = *src++; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
159 p2 = *src++; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
160 line -= p2; |
| 8265 | 161 if (line < 0){ |
| 162 av_log(avctx, AV_LOG_ERROR, "Skip beyond picture bounds\n"); | |
| 2455 | 163 return -1; |
| 8265 | 164 } |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
165 pos += p1; |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
166 output = pic->data[0] + line * pic->linesize[0] + pos * (depth >> 3); |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
167 continue; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
168 } |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
169 // Copy data |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
170 if (output + p2 * (depth >> 3) > output_end) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
171 src += p2 * (depth >> 3); |
| 2455 | 172 continue; |
| 173 } | |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
174 if ((depth == 8) || (depth == 24)) { |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
175 for(i = 0; i < p2 * (depth >> 3); i++) { |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
176 *output++ = *src++; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
177 } |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
178 // RLE8 copy is actually padded - and runs are not! |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
179 if(depth == 8 && (p2 & 1)) { |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
180 src++; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
181 } |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
182 } else if (depth == 16) { |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
183 for(i = 0; i < p2; i++) { |
| 4364 | 184 pix16 = AV_RL16(src); |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
185 src += 2; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
186 *(uint16_t*)output = pix16; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
187 output += 2; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
188 } |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
189 } else if (depth == 32) { |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
190 for(i = 0; i < p2; i++) { |
| 4364 | 191 pix32 = AV_RL32(src); |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
192 src += 4; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
193 *(uint32_t*)output = pix32; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
194 output += 4; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
195 } |
| 2979 | 196 } |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
197 pos += p2; |
| 9684 | 198 } else { //run of pixels |
| 8266 | 199 uint8_t pix[3]; //original pixel |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
200 switch(depth){ |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
201 case 8: pix[0] = *src++; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
202 break; |
| 4364 | 203 case 16: pix16 = AV_RL16(src); |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
204 src += 2; |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
205 break; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
206 case 24: pix[0] = *src++; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
207 pix[1] = *src++; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
208 pix[2] = *src++; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
209 break; |
| 4364 | 210 case 32: pix32 = AV_RL32(src); |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
211 src += 4; |
| 2481 | 212 break; |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
213 } |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
214 if (output + p1 * (depth >> 3) > output_end) |
| 2455 | 215 continue; |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
216 for(i = 0; i < p1; i++) { |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
217 switch(depth){ |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
218 case 8: *output++ = pix[0]; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
219 break; |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
220 case 16: *(uint16_t*)output = pix16; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
221 output += 2; |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
222 break; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
223 case 24: *output++ = pix[0]; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
224 *output++ = pix[1]; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
225 *output++ = pix[2]; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
226 break; |
|
3121
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
227 case 32: *(uint32_t*)output = pix32; |
|
99cbff5f8038
make TSCC endian-safe, PPC testing courtesy of Diego B.
melanson
parents:
3036
diff
changeset
|
228 output += 4; |
| 2481 | 229 break; |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
230 } |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
231 } |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
232 pos += p1; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
233 } |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
234 } |
| 2967 | 235 |
| 9684 | 236 av_log(avctx, AV_LOG_WARNING, "MS RLE warning: no end-of-picture code\n"); |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
237 return 0; |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
238 } |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
239 |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
240 |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
241 int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth, |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
242 const uint8_t* data, int data_size) |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
243 { |
|
7885
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
244 switch(depth){ |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
245 case 4: |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
246 return msrle_decode_pal4(avctx, pic, data, data_size); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
247 case 8: |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
248 case 16: |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
249 case 24: |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
250 case 32: |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
251 return msrle_decode_8_16_24_32(avctx, pic, depth, data, data_size); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
252 default: |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
253 av_log(avctx, AV_LOG_ERROR, "Unknown depth %d\n", depth); |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
254 return -1; |
|
f874e1d5cf07
Factorize out code used for MS RLE format decoding in different decoders.
kostya
parents:
7823
diff
changeset
|
255 } |
|
2170
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
256 } |
|
51da590b31a3
TechSmith Camtasia (TSCC) video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff
changeset
|
257 |
