Mercurial > libavcodec.hg
annotate indeo3.c @ 12483:0159a19bfff7 libavcodec
aacdec: Rework channel mapping compatibility hacks.
For a PCE based configuration map the channels solely based on tags.
For an indexed configuration map the channels solely based on position.
This works with all known exotic samples including al17, elem_id0, bad_concat,
and lfe_is_sce.
author | alexc |
---|---|
date | Fri, 10 Sep 2010 18:01:48 +0000 |
parents | ffb3668ff7af |
children |
rev | line source |
---|---|
1190 | 1 /* |
2 * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg | |
3 * written, produced, and directed by Alan Smithee | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1190 | 8 * modify it under the terms of the GNU Lesser General Public |
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:
3776
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1190 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1190 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
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 |
1190 | 20 */ |
21 | |
22 #include <stdio.h> | |
23 #include <stdlib.h> | |
24 #include <string.h> | |
25 | |
12372
914f484bb476
Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents:
12129
diff
changeset
|
26 #include "libavcore/imgutils.h" |
1190 | 27 #include "avcodec.h" |
28 #include "dsputil.h" | |
6239 | 29 #include "bytestream.h" |
1190 | 30 |
31 #include "indeo3data.h" | |
32 | |
33 typedef struct | |
34 { | |
7955 | 35 uint8_t *Ybuf; |
36 uint8_t *Ubuf; | |
37 uint8_t *Vbuf; | |
38 unsigned short y_w, y_h; | |
39 unsigned short uv_w, uv_h; | |
1190 | 40 } YUVBufs; |
41 | |
42 typedef struct Indeo3DecodeContext { | |
43 AVCodecContext *avctx; | |
44 int width, height; | |
45 AVFrame frame; | |
46 | |
7952 | 47 uint8_t *buf; |
1190 | 48 YUVBufs iv_frame[2]; |
49 YUVBufs *cur_frame; | |
50 YUVBufs *ref_frame; | |
51 | |
7947 | 52 uint8_t *ModPred; |
7946 | 53 uint8_t *corrector_type; |
1190 | 54 } Indeo3DecodeContext; |
55 | |
7944 | 56 static const uint8_t corrector_type_0[24] = { |
7955 | 57 195, 159, 133, 115, 101, 93, 87, 77, |
58 195, 159, 133, 115, 101, 93, 87, 77, | |
59 128, 79, 79, 79, 79, 79, 79, 79 | |
1190 | 60 }; |
61 | |
7944 | 62 static const uint8_t corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 }; |
1190 | 63 |
7950 | 64 static av_cold int build_modpred(Indeo3DecodeContext *s) |
1190 | 65 { |
7955 | 66 int i, j; |
1190 | 67 |
7955 | 68 if (!(s->ModPred = av_malloc(8 * 128))) |
69 return AVERROR(ENOMEM); | |
1190 | 70 |
7955 | 71 for (i=0; i < 128; ++i) { |
72 s->ModPred[i+0*128] = i > 126 ? 254 : 2*(i + 1 - ((i + 1) % 2)); | |
73 s->ModPred[i+1*128] = i == 7 ? 20 : | |
74 i == 119 || | |
75 i == 120 ? 236 : 2*(i + 2 - ((i + 1) % 3)); | |
76 s->ModPred[i+2*128] = i > 125 ? 248 : 2*(i + 2 - ((i + 2) % 4)); | |
77 s->ModPred[i+3*128] = 2*(i + 1 - ((i - 3) % 5)); | |
78 s->ModPred[i+4*128] = i == 8 ? 20 : 2*(i + 1 - ((i - 3) % 6)); | |
79 s->ModPred[i+5*128] = 2*(i + 4 - ((i + 3) % 7)); | |
80 s->ModPred[i+6*128] = i > 123 ? 240 : 2*(i + 4 - ((i + 4) % 8)); | |
81 s->ModPred[i+7*128] = 2*(i + 5 - ((i + 4) % 9)); | |
82 } | |
1190 | 83 |
7955 | 84 if (!(s->corrector_type = av_malloc(24 * 256))) |
85 return AVERROR(ENOMEM); | |
1190 | 86 |
7955 | 87 for (i=0; i < 24; ++i) { |
88 for (j=0; j < 256; ++j) { | |
89 s->corrector_type[i*256+j] = j < corrector_type_0[i] ? 1 : | |
90 j < 248 || (i == 16 && j == 248) ? 0 : | |
91 corrector_type_2[j - 248]; | |
92 } | |
1190 | 93 } |
7950 | 94 |
95 return 0; | |
1190 | 96 } |
97 | |
7950 | 98 static av_cold int iv_alloc_frames(Indeo3DecodeContext *s) |
1190 | 99 { |
7963 | 100 int luma_width = (s->width + 3) & ~3, |
101 luma_height = (s->height + 3) & ~3, | |
102 chroma_width = ((luma_width >> 2) + 3) & ~3, | |
103 chroma_height = ((luma_height >> 2) + 3) & ~3, | |
104 luma_pixels = luma_width * luma_height, | |
105 chroma_pixels = chroma_width * chroma_height, | |
106 i; | |
107 unsigned int bufsize = luma_pixels * 2 + luma_width * 3 + | |
108 (chroma_pixels + chroma_width) * 4; | |
1190 | 109 |
9927
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
110 av_freep(&s->buf); |
7955 | 111 if(!(s->buf = av_malloc(bufsize))) |
112 return AVERROR(ENOMEM); | |
113 s->iv_frame[0].y_w = s->iv_frame[1].y_w = luma_width; | |
114 s->iv_frame[0].y_h = s->iv_frame[1].y_h = luma_height; | |
115 s->iv_frame[0].uv_w = s->iv_frame[1].uv_w = chroma_width; | |
116 s->iv_frame[0].uv_h = s->iv_frame[1].uv_h = chroma_height; | |
1190 | 117 |
7955 | 118 s->iv_frame[0].Ybuf = s->buf + luma_width; |
119 i = luma_pixels + luma_width * 2; | |
120 s->iv_frame[1].Ybuf = s->buf + i; | |
121 i += (luma_pixels + luma_width); | |
122 s->iv_frame[0].Ubuf = s->buf + i; | |
123 i += (chroma_pixels + chroma_width); | |
124 s->iv_frame[1].Ubuf = s->buf + i; | |
125 i += (chroma_pixels + chroma_width); | |
126 s->iv_frame[0].Vbuf = s->buf + i; | |
127 i += (chroma_pixels + chroma_width); | |
128 s->iv_frame[1].Vbuf = s->buf + i; | |
1190 | 129 |
7955 | 130 for(i = 1; i <= luma_width; i++) |
131 s->iv_frame[0].Ybuf[-i] = s->iv_frame[1].Ybuf[-i] = | |
132 s->iv_frame[0].Ubuf[-i] = 0x80; | |
1190 | 133 |
7955 | 134 for(i = 1; i <= chroma_width; i++) { |
135 s->iv_frame[1].Ubuf[-i] = 0x80; | |
136 s->iv_frame[0].Vbuf[-i] = 0x80; | |
137 s->iv_frame[1].Vbuf[-i] = 0x80; | |
138 s->iv_frame[1].Vbuf[chroma_pixels+i-1] = 0x80; | |
139 } | |
7950 | 140 |
7955 | 141 return 0; |
1190 | 142 } |
143 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6450
diff
changeset
|
144 static av_cold void iv_free_func(Indeo3DecodeContext *s) |
1190 | 145 { |
9928 | 146 av_freep(&s->buf); |
147 av_freep(&s->ModPred); | |
148 av_freep(&s->corrector_type); | |
1190 | 149 } |
150 | |
8314
e983153e2d72
Replace 'typedef struct ustr_t' by 'struct ustr', _t is POSIX namespace.
diego
parents:
7975
diff
changeset
|
151 struct ustr { |
7955 | 152 long xpos; |
153 long ypos; | |
154 long width; | |
155 long height; | |
156 long split_flag; | |
157 long split_direction; | |
158 long usl7; | |
8314
e983153e2d72
Replace 'typedef struct ustr_t' by 'struct ustr', _t is POSIX namespace.
diego
parents:
7975
diff
changeset
|
159 }; |
1190 | 160 |
161 | |
1198
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
162 #define LV1_CHECK(buf1,rle_v3,lv1,lp2) \ |
7955 | 163 if((lv1 & 0x80) != 0) { \ |
164 if(rle_v3 != 0) \ | |
165 rle_v3 = 0; \ | |
166 else { \ | |
167 rle_v3 = 1; \ | |
168 buf1 -= 2; \ | |
169 } \ | |
170 } \ | |
171 lp2 = 4; | |
1198
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
172 |
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
173 |
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
174 #define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) \ |
7955 | 175 if(rle_v3 == 0) { \ |
176 rle_v2 = *buf1; \ | |
177 rle_v1 = 1; \ | |
178 if(rle_v2 > 32) { \ | |
179 rle_v2 -= 32; \ | |
180 rle_v1 = 0; \ | |
181 } \ | |
182 rle_v3 = 1; \ | |
183 } \ | |
184 buf1--; | |
1198
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
185 |
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
186 |
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
187 #define LP2_CHECK(buf1,rle_v3,lp2) \ |
7955 | 188 if(lp2 == 0 && rle_v3 != 0) \ |
189 rle_v3 = 0; \ | |
190 else { \ | |
191 buf1--; \ | |
192 rle_v3 = 1; \ | |
193 } | |
1198
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
194 |
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
195 |
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
196 #define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \ |
7955 | 197 rle_v2--; \ |
198 if(rle_v2 == 0) { \ | |
199 rle_v3 = 0; \ | |
200 buf1 += 2; \ | |
201 } \ | |
202 lp2 = 4; | |
1198
cae31b22b14e
code redundancy reduction, courtesy of suxen_drol -at- hotmail.com
tmmm
parents:
1190
diff
changeset
|
203 |
1190 | 204 static void iv_Decode_Chunk(Indeo3DecodeContext *s, |
7955 | 205 uint8_t *cur, uint8_t *ref, int width, int height, |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
206 const uint8_t *buf1, long cb_offset, const uint8_t *hdr, |
7955 | 207 const uint8_t *buf2, int min_width_160) |
1190 | 208 { |
7955 | 209 uint8_t bit_buf; |
210 unsigned long bit_pos, lv, lv1, lv2; | |
211 long *width_tbl, width_tbl_arr[10]; | |
212 const signed char *ref_vectors; | |
213 uint8_t *cur_frm_pos, *ref_frm_pos, *cp, *cp2; | |
214 uint32_t *cur_lp, *ref_lp; | |
215 const uint32_t *correction_lp[2], *correctionloworder_lp[2], *correctionhighorder_lp[2]; | |
216 uint8_t *correction_type_sp[2]; | |
8314
e983153e2d72
Replace 'typedef struct ustr_t' by 'struct ustr', _t is POSIX namespace.
diego
parents:
7975
diff
changeset
|
217 struct ustr strip_tbl[20], *strip; |
7955 | 218 int i, j, k, lp1, lp2, flag1, cmd, blks_width, blks_height, region_160_width, |
219 rle_v1, rle_v2, rle_v3; | |
220 unsigned short res; | |
1190 | 221 |
7955 | 222 bit_buf = 0; |
223 ref_vectors = NULL; | |
1190 | 224 |
7955 | 225 width_tbl = width_tbl_arr + 1; |
226 i = (width < 0 ? width + 3 : width)/4; | |
227 for(j = -1; j < 8; j++) | |
228 width_tbl[j] = i * j; | |
1190 | 229 |
7955 | 230 strip = strip_tbl; |
231 | |
232 for(region_160_width = 0; region_160_width < (width - min_width_160); region_160_width += min_width_160); | |
1190 | 233 |
7955 | 234 strip->ypos = strip->xpos = 0; |
235 for(strip->width = min_width_160; width > strip->width; strip->width *= 2); | |
236 strip->height = height; | |
237 strip->split_direction = 0; | |
238 strip->split_flag = 0; | |
239 strip->usl7 = 0; | |
1190 | 240 |
7955 | 241 bit_pos = 0; |
242 | |
243 rle_v1 = rle_v2 = rle_v3 = 0; | |
1190 | 244 |
7955 | 245 while(strip >= strip_tbl) { |
246 if(bit_pos <= 0) { | |
247 bit_pos = 8; | |
248 bit_buf = *buf1++; | |
1190 | 249 } |
250 | |
7955 | 251 bit_pos -= 2; |
252 cmd = (bit_buf >> bit_pos) & 0x03; | |
1190 | 253 |
7955 | 254 if(cmd == 0) { |
255 strip++; | |
8669
16b978f64d9e
Fix an exploit in indeo by checking we are not writing out of the strip array.
benoit
parents:
8323
diff
changeset
|
256 if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) { |
16b978f64d9e
Fix an exploit in indeo by checking we are not writing out of the strip array.
benoit
parents:
8323
diff
changeset
|
257 av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n"); |
16b978f64d9e
Fix an exploit in indeo by checking we are not writing out of the strip array.
benoit
parents:
8323
diff
changeset
|
258 break; |
16b978f64d9e
Fix an exploit in indeo by checking we are not writing out of the strip array.
benoit
parents:
8323
diff
changeset
|
259 } |
8323 | 260 memcpy(strip, strip-1, sizeof(*strip)); |
7955 | 261 strip->split_flag = 1; |
262 strip->split_direction = 0; | |
263 strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4); | |
264 continue; | |
265 } else if(cmd == 1) { | |
266 strip++; | |
8669
16b978f64d9e
Fix an exploit in indeo by checking we are not writing out of the strip array.
benoit
parents:
8323
diff
changeset
|
267 if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) { |
16b978f64d9e
Fix an exploit in indeo by checking we are not writing out of the strip array.
benoit
parents:
8323
diff
changeset
|
268 av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n"); |
16b978f64d9e
Fix an exploit in indeo by checking we are not writing out of the strip array.
benoit
parents:
8323
diff
changeset
|
269 break; |
16b978f64d9e
Fix an exploit in indeo by checking we are not writing out of the strip array.
benoit
parents:
8323
diff
changeset
|
270 } |
8323 | 271 memcpy(strip, strip-1, sizeof(*strip)); |
7955 | 272 strip->split_flag = 1; |
273 strip->split_direction = 1; | |
274 strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4); | |
275 continue; | |
276 } else if(cmd == 2) { | |
277 if(strip->usl7 == 0) { | |
278 strip->usl7 = 1; | |
279 ref_vectors = NULL; | |
280 continue; | |
281 } | |
282 } else if(cmd == 3) { | |
283 if(strip->usl7 == 0) { | |
284 strip->usl7 = 1; | |
285 ref_vectors = (const signed char*)buf2 + (*buf1 * 2); | |
286 buf1++; | |
287 continue; | |
288 } | |
289 } | |
1190 | 290 |
7955 | 291 cur_frm_pos = cur + width * strip->ypos + strip->xpos; |
292 | |
293 if((blks_width = strip->width) < 0) | |
294 blks_width += 3; | |
295 blks_width >>= 2; | |
296 blks_height = strip->height; | |
1190 | 297 |
7955 | 298 if(ref_vectors != NULL) { |
299 ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width + | |
300 ref_vectors[1] + strip->xpos; | |
301 } else | |
302 ref_frm_pos = cur_frm_pos - width_tbl[4]; | |
1190 | 303 |
7955 | 304 if(cmd == 2) { |
305 if(bit_pos <= 0) { | |
306 bit_pos = 8; | |
307 bit_buf = *buf1++; | |
1190 | 308 } |
309 | |
7955 | 310 bit_pos -= 2; |
311 cmd = (bit_buf >> bit_pos) & 0x03; | |
1190 | 312 |
7955 | 313 if(cmd == 0 || ref_vectors != NULL) { |
314 for(lp1 = 0; lp1 < blks_width; lp1++) { | |
315 for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1]) | |
316 ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j]; | |
317 cur_frm_pos += 4; | |
318 ref_frm_pos += 4; | |
319 } | |
320 } else if(cmd != 1) | |
321 return; | |
322 } else { | |
323 k = *buf1 >> 4; | |
324 j = *buf1 & 0x0f; | |
325 buf1++; | |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
326 lv = j + cb_offset; |
1190 | 327 |
7955 | 328 if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) { |
329 cp2 = s->ModPred + ((lv - 8) << 7); | |
330 cp = ref_frm_pos; | |
331 for(i = 0; i < blks_width << 2; i++) { | |
332 int v = *cp >> 1; | |
333 *(cp++) = cp2[v]; | |
334 } | |
335 } | |
1190 | 336 |
7955 | 337 if(k == 1 || k == 4) { |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
338 lv = (hdr[j] & 0xf) + cb_offset; |
7955 | 339 correction_type_sp[0] = s->corrector_type + (lv << 8); |
340 correction_lp[0] = correction + (lv << 8); | |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
341 lv = (hdr[j] >> 4) + cb_offset; |
7955 | 342 correction_lp[1] = correction + (lv << 8); |
343 correction_type_sp[1] = s->corrector_type + (lv << 8); | |
344 } else { | |
345 correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8); | |
346 correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8); | |
347 correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8); | |
348 correction_lp[0] = correction_lp[1] = correction + (lv << 8); | |
1190 | 349 } |
350 | |
7955 | 351 switch(k) { |
352 case 1: | |
353 case 0: /********** CASE 0 **********/ | |
354 for( ; blks_height > 0; blks_height -= 4) { | |
355 for(lp1 = 0; lp1 < blks_width; lp1++) { | |
356 for(lp2 = 0; lp2 < 4; ) { | |
357 k = *buf1++; | |
358 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2]; | |
359 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2]; | |
1190 | 360 |
7955 | 361 switch(correction_type_sp[0][k]) { |
362 case 0: | |
12129 | 363 *cur_lp = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); |
7955 | 364 lp2++; |
365 break; | |
366 case 1: | |
12129 | 367 res = ((av_le2ne16(((unsigned short *)(ref_lp))[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1; |
368 ((unsigned short *)cur_lp)[0] = av_le2ne16(res); | |
369 res = ((av_le2ne16(((unsigned short *)(ref_lp))[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1; | |
370 ((unsigned short *)cur_lp)[1] = av_le2ne16(res); | |
7955 | 371 buf1++; |
372 lp2++; | |
373 break; | |
374 case 2: | |
375 if(lp2 == 0) { | |
376 for(i = 0, j = 0; i < 2; i++, j += width_tbl[1]) | |
377 cur_lp[j] = ref_lp[j]; | |
378 lp2 += 2; | |
379 } | |
380 break; | |
381 case 3: | |
382 if(lp2 < 2) { | |
383 for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1]) | |
384 cur_lp[j] = ref_lp[j]; | |
385 lp2 = 3; | |
386 } | |
387 break; | |
388 case 8: | |
389 if(lp2 == 0) { | |
390 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) | |
391 | |
7965 | 392 if(rle_v1 == 1 || ref_vectors != NULL) { |
393 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) | |
394 cur_lp[j] = ref_lp[j]; | |
395 } | |
7955 | 396 |
397 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) | |
7965 | 398 break; |
7955 | 399 } else { |
400 rle_v1 = 1; | |
401 rle_v2 = *buf1 - 1; | |
402 } | |
403 case 5: | |
404 LP2_CHECK(buf1,rle_v3,lp2) | |
405 case 4: | |
406 for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1]) | |
407 cur_lp[j] = ref_lp[j]; | |
408 lp2 = 4; | |
409 break; | |
1190 | 410 |
7955 | 411 case 7: |
412 if(rle_v3 != 0) | |
413 rle_v3 = 0; | |
414 else { | |
415 buf1--; | |
416 rle_v3 = 1; | |
417 } | |
418 case 6: | |
419 if(ref_vectors != NULL) { | |
420 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) | |
421 cur_lp[j] = ref_lp[j]; | |
422 } | |
423 lp2 = 4; | |
424 break; | |
425 | |
426 case 9: | |
427 lv1 = *buf1++; | |
428 lv = (lv1 & 0x7F) << 1; | |
429 lv += (lv << 8); | |
430 lv += (lv << 16); | |
431 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) | |
432 cur_lp[j] = lv; | |
433 | |
434 LV1_CHECK(buf1,rle_v3,lv1,lp2) | |
7965 | 435 break; |
7955 | 436 default: |
437 return; | |
438 } | |
439 } | |
440 | |
441 cur_frm_pos += 4; | |
442 ref_frm_pos += 4; | |
443 } | |
1190 | 444 |
7955 | 445 cur_frm_pos += ((width - blks_width) * 4); |
446 ref_frm_pos += ((width - blks_width) * 4); | |
447 } | |
448 break; | |
449 | |
450 case 4: | |
451 case 3: /********** CASE 3 **********/ | |
452 if(ref_vectors != NULL) | |
453 return; | |
454 flag1 = 1; | |
455 | |
456 for( ; blks_height > 0; blks_height -= 8) { | |
457 for(lp1 = 0; lp1 < blks_width; lp1++) { | |
458 for(lp2 = 0; lp2 < 4; ) { | |
459 k = *buf1++; | |
460 | |
461 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2]; | |
462 ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1]; | |
1190 | 463 |
7955 | 464 switch(correction_type_sp[lp2 & 0x01][k]) { |
465 case 0: | |
12129 | 466 cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); |
7955 | 467 if(lp2 > 0 || flag1 == 0 || strip->ypos != 0) |
468 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; | |
469 else | |
12129 | 470 cur_lp[0] = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); |
7955 | 471 lp2++; |
472 break; | |
473 | |
474 case 1: | |
12129 | 475 res = ((av_le2ne16(((unsigned short *)ref_lp)[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1; |
476 ((unsigned short *)cur_lp)[width_tbl[2]] = av_le2ne16(res); | |
477 res = ((av_le2ne16(((unsigned short *)ref_lp)[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1; | |
478 ((unsigned short *)cur_lp)[width_tbl[2]+1] = av_le2ne16(res); | |
7955 | 479 |
480 if(lp2 > 0 || flag1 == 0 || strip->ypos != 0) | |
481 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; | |
482 else | |
483 cur_lp[0] = cur_lp[width_tbl[1]]; | |
484 buf1++; | |
485 lp2++; | |
486 break; | |
1190 | 487 |
7955 | 488 case 2: |
489 if(lp2 == 0) { | |
490 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) | |
491 cur_lp[j] = *ref_lp; | |
492 lp2 += 2; | |
493 } | |
494 break; | |
495 | |
496 case 3: | |
497 if(lp2 < 2) { | |
498 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) | |
499 cur_lp[j] = *ref_lp; | |
500 lp2 = 3; | |
501 } | |
502 break; | |
503 | |
504 case 6: | |
505 lp2 = 4; | |
506 break; | |
507 | |
508 case 7: | |
509 if(rle_v3 != 0) | |
510 rle_v3 = 0; | |
511 else { | |
512 buf1--; | |
513 rle_v3 = 1; | |
514 } | |
515 lp2 = 4; | |
516 break; | |
517 | |
518 case 8: | |
519 if(lp2 == 0) { | |
520 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) | |
1190 | 521 |
7955 | 522 if(rle_v1 == 1) { |
523 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) | |
524 cur_lp[j] = ref_lp[j]; | |
525 } | |
526 | |
527 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) | |
528 break; | |
529 } else { | |
530 rle_v2 = (*buf1) - 1; | |
531 rle_v1 = 1; | |
532 } | |
533 case 5: | |
534 LP2_CHECK(buf1,rle_v3,lp2) | |
535 case 4: | |
536 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) | |
537 cur_lp[j] = *ref_lp; | |
538 lp2 = 4; | |
539 break; | |
540 | |
541 case 9: | |
542 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n"); | |
543 lv1 = *buf1++; | |
544 lv = (lv1 & 0x7F) << 1; | |
545 lv += (lv << 8); | |
546 lv += (lv << 16); | |
547 | |
548 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) | |
549 cur_lp[j] = lv; | |
550 | |
551 LV1_CHECK(buf1,rle_v3,lv1,lp2) | |
552 break; | |
553 | |
554 default: | |
555 return; | |
556 } | |
1190 | 557 } |
7955 | 558 |
559 cur_frm_pos += 4; | |
560 } | |
1190 | 561 |
7955 | 562 cur_frm_pos += (((width * 2) - blks_width) * 4); |
563 flag1 = 0; | |
564 } | |
565 break; | |
566 | |
567 case 10: /********** CASE 10 **********/ | |
568 if(ref_vectors == NULL) { | |
569 flag1 = 1; | |
570 | |
571 for( ; blks_height > 0; blks_height -= 8) { | |
572 for(lp1 = 0; lp1 < blks_width; lp1 += 2) { | |
573 for(lp2 = 0; lp2 < 4; ) { | |
574 k = *buf1++; | |
575 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2]; | |
576 ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1]; | |
577 lv1 = ref_lp[0]; | |
578 lv2 = ref_lp[1]; | |
579 if(lp2 == 0 && flag1 != 0) { | |
9985 | 580 #if HAVE_BIGENDIAN |
7955 | 581 lv1 = lv1 & 0xFF00FF00; |
582 lv1 = (lv1 >> 8) | lv1; | |
583 lv2 = lv2 & 0xFF00FF00; | |
584 lv2 = (lv2 >> 8) | lv2; | |
585 #else | |
586 lv1 = lv1 & 0x00FF00FF; | |
587 lv1 = (lv1 << 8) | lv1; | |
588 lv2 = lv2 & 0x00FF00FF; | |
589 lv2 = (lv2 << 8) | lv2; | |
590 #endif | |
591 } | |
592 | |
593 switch(correction_type_sp[lp2 & 0x01][k]) { | |
594 case 0: | |
12129 | 595 cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1); |
596 cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(lv2) >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1); | |
7955 | 597 if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) { |
598 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; | |
599 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; | |
600 } else { | |
601 cur_lp[0] = cur_lp[width_tbl[1]]; | |
602 cur_lp[1] = cur_lp[width_tbl[1]+1]; | |
603 } | |
604 lp2++; | |
605 break; | |
606 | |
607 case 1: | |
12129 | 608 cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1]) << 1); |
609 cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(lv2) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1); | |
7955 | 610 if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) { |
611 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; | |
612 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; | |
613 } else { | |
614 cur_lp[0] = cur_lp[width_tbl[1]]; | |
615 cur_lp[1] = cur_lp[width_tbl[1]+1]; | |
616 } | |
617 buf1++; | |
618 lp2++; | |
619 break; | |
620 | |
621 case 2: | |
622 if(lp2 == 0) { | |
623 if(flag1 != 0) { | |
624 for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) { | |
625 cur_lp[j] = lv1; | |
626 cur_lp[j+1] = lv2; | |
627 } | |
628 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; | |
629 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; | |
630 } else { | |
631 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) { | |
632 cur_lp[j] = lv1; | |
633 cur_lp[j+1] = lv2; | |
634 } | |
635 } | |
636 lp2 += 2; | |
637 } | |
638 break; | |
1190 | 639 |
7955 | 640 case 3: |
641 if(lp2 < 2) { | |
642 if(lp2 == 0 && flag1 != 0) { | |
643 for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) { | |
644 cur_lp[j] = lv1; | |
645 cur_lp[j+1] = lv2; | |
646 } | |
647 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; | |
648 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; | |
649 } else { | |
650 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) { | |
651 cur_lp[j] = lv1; | |
652 cur_lp[j+1] = lv2; | |
653 } | |
654 } | |
655 lp2 = 3; | |
656 } | |
657 break; | |
1190 | 658 |
7955 | 659 case 8: |
660 if(lp2 == 0) { | |
661 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) | |
662 if(rle_v1 == 1) { | |
663 if(flag1 != 0) { | |
664 for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) { | |
665 cur_lp[j] = lv1; | |
666 cur_lp[j+1] = lv2; | |
667 } | |
668 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; | |
669 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; | |
670 } else { | |
671 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) { | |
672 cur_lp[j] = lv1; | |
673 cur_lp[j+1] = lv2; | |
674 } | |
675 } | |
676 } | |
677 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) | |
678 break; | |
679 } else { | |
680 rle_v1 = 1; | |
681 rle_v2 = (*buf1) - 1; | |
682 } | |
683 case 5: | |
684 LP2_CHECK(buf1,rle_v3,lp2) | |
685 case 4: | |
686 if(lp2 == 0 && flag1 != 0) { | |
687 for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) { | |
688 cur_lp[j] = lv1; | |
689 cur_lp[j+1] = lv2; | |
690 } | |
691 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; | |
692 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; | |
693 } else { | |
694 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) { | |
695 cur_lp[j] = lv1; | |
696 cur_lp[j+1] = lv2; | |
697 } | |
698 } | |
699 lp2 = 4; | |
700 break; | |
1190 | 701 |
7955 | 702 case 6: |
703 lp2 = 4; | |
704 break; | |
1190 | 705 |
7955 | 706 case 7: |
707 if(lp2 == 0) { | |
708 if(rle_v3 != 0) | |
709 rle_v3 = 0; | |
710 else { | |
711 buf1--; | |
712 rle_v3 = 1; | |
713 } | |
714 lp2 = 4; | |
715 } | |
716 break; | |
1190 | 717 |
7955 | 718 case 9: |
719 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n"); | |
720 lv1 = *buf1; | |
721 lv = (lv1 & 0x7F) << 1; | |
722 lv += (lv << 8); | |
723 lv += (lv << 16); | |
724 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) | |
725 cur_lp[j] = lv; | |
726 LV1_CHECK(buf1,rle_v3,lv1,lp2) | |
727 break; | |
728 | |
729 default: | |
730 return; | |
731 } | |
732 } | |
733 | |
734 cur_frm_pos += 8; | |
735 } | |
1190 | 736 |
7955 | 737 cur_frm_pos += (((width * 2) - blks_width) * 4); |
738 flag1 = 0; | |
739 } | |
740 } else { | |
741 for( ; blks_height > 0; blks_height -= 8) { | |
742 for(lp1 = 0; lp1 < blks_width; lp1 += 2) { | |
743 for(lp2 = 0; lp2 < 4; ) { | |
744 k = *buf1++; | |
745 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2]; | |
746 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2]; | |
747 | |
748 switch(correction_type_sp[lp2 & 0x01][k]) { | |
749 case 0: | |
750 lv1 = correctionloworder_lp[lp2 & 0x01][k]; | |
751 lv2 = correctionhighorder_lp[lp2 & 0x01][k]; | |
12129 | 752 cur_lp[0] = av_le2ne32(((av_le2ne32(ref_lp[0]) >> 1) + lv1) << 1); |
753 cur_lp[1] = av_le2ne32(((av_le2ne32(ref_lp[1]) >> 1) + lv2) << 1); | |
754 cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1); | |
755 cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1); | |
7955 | 756 lp2++; |
757 break; | |
1190 | 758 |
7955 | 759 case 1: |
760 lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++]; | |
761 lv2 = correctionloworder_lp[lp2 & 0x01][k]; | |
12129 | 762 cur_lp[0] = av_le2ne32(((av_le2ne32(ref_lp[0]) >> 1) + lv1) << 1); |
763 cur_lp[1] = av_le2ne32(((av_le2ne32(ref_lp[1]) >> 1) + lv2) << 1); | |
764 cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1); | |
765 cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1); | |
7955 | 766 lp2++; |
767 break; | |
768 | |
769 case 2: | |
770 if(lp2 == 0) { | |
771 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) { | |
772 cur_lp[j] = ref_lp[j]; | |
773 cur_lp[j+1] = ref_lp[j+1]; | |
774 } | |
775 lp2 += 2; | |
776 } | |
777 break; | |
778 | |
779 case 3: | |
780 if(lp2 < 2) { | |
781 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) { | |
782 cur_lp[j] = ref_lp[j]; | |
783 cur_lp[j+1] = ref_lp[j+1]; | |
784 } | |
785 lp2 = 3; | |
786 } | |
787 break; | |
1190 | 788 |
7955 | 789 case 8: |
790 if(lp2 == 0) { | |
791 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) | |
792 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) { | |
793 ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j]; | |
794 ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1]; | |
795 } | |
796 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) | |
797 break; | |
798 } else { | |
799 rle_v1 = 1; | |
800 rle_v2 = (*buf1) - 1; | |
801 } | |
802 case 5: | |
803 case 7: | |
804 LP2_CHECK(buf1,rle_v3,lp2) | |
805 case 6: | |
806 case 4: | |
807 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) { | |
808 cur_lp[j] = ref_lp[j]; | |
809 cur_lp[j+1] = ref_lp[j+1]; | |
810 } | |
811 lp2 = 4; | |
812 break; | |
1190 | 813 |
7955 | 814 case 9: |
815 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n"); | |
816 lv1 = *buf1; | |
817 lv = (lv1 & 0x7F) << 1; | |
818 lv += (lv << 8); | |
819 lv += (lv << 16); | |
820 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) | |
821 ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv; | |
822 LV1_CHECK(buf1,rle_v3,lv1,lp2) | |
823 break; | |
1190 | 824 |
7955 | 825 default: |
826 return; | |
827 } | |
828 } | |
829 | |
830 cur_frm_pos += 8; | |
831 ref_frm_pos += 8; | |
1190 | 832 } |
7955 | 833 |
834 cur_frm_pos += (((width * 2) - blks_width) * 4); | |
835 ref_frm_pos += (((width * 2) - blks_width) * 4); | |
836 } | |
837 } | |
838 break; | |
839 | |
840 case 11: /********** CASE 11 **********/ | |
841 if(ref_vectors == NULL) | |
842 return; | |
843 | |
844 for( ; blks_height > 0; blks_height -= 8) { | |
845 for(lp1 = 0; lp1 < blks_width; lp1++) { | |
846 for(lp2 = 0; lp2 < 4; ) { | |
847 k = *buf1++; | |
848 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2]; | |
849 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2]; | |
850 | |
851 switch(correction_type_sp[lp2 & 0x01][k]) { | |
852 case 0: | |
12129 | 853 cur_lp[0] = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); |
854 cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); | |
7955 | 855 lp2++; |
856 break; | |
857 | |
858 case 1: | |
859 lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]); | |
860 lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]); | |
12129 | 861 res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[0]) >> 1) + lv1) << 1); |
862 ((unsigned short *)cur_lp)[0] = av_le2ne16(res); | |
863 res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[1]) >> 1) + lv2) << 1); | |
864 ((unsigned short *)cur_lp)[1] = av_le2ne16(res); | |
865 res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[width_tbl[2]]) >> 1) + lv1) << 1); | |
866 ((unsigned short *)cur_lp)[width_tbl[2]] = av_le2ne16(res); | |
867 res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[width_tbl[2]+1]) >> 1) + lv2) << 1); | |
868 ((unsigned short *)cur_lp)[width_tbl[2]+1] = av_le2ne16(res); | |
7955 | 869 lp2++; |
870 break; | |
871 | |
872 case 2: | |
873 if(lp2 == 0) { | |
874 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) | |
875 cur_lp[j] = ref_lp[j]; | |
876 lp2 += 2; | |
877 } | |
878 break; | |
879 | |
880 case 3: | |
881 if(lp2 < 2) { | |
882 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) | |
883 cur_lp[j] = ref_lp[j]; | |
884 lp2 = 3; | |
885 } | |
886 break; | |
1190 | 887 |
7955 | 888 case 8: |
889 if(lp2 == 0) { | |
890 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) | |
891 | |
892 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) | |
893 cur_lp[j] = ref_lp[j]; | |
894 | |
895 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) | |
896 break; | |
897 } else { | |
898 rle_v1 = 1; | |
899 rle_v2 = (*buf1) - 1; | |
900 } | |
901 case 5: | |
902 case 7: | |
903 LP2_CHECK(buf1,rle_v3,lp2) | |
904 case 4: | |
905 case 6: | |
906 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) | |
907 cur_lp[j] = ref_lp[j]; | |
908 lp2 = 4; | |
909 break; | |
1190 | 910 |
7955 | 911 case 9: |
912 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n"); | |
913 lv1 = *buf1++; | |
914 lv = (lv1 & 0x7F) << 1; | |
915 lv += (lv << 8); | |
916 lv += (lv << 16); | |
917 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) | |
918 cur_lp[j] = lv; | |
919 LV1_CHECK(buf1,rle_v3,lv1,lp2) | |
920 break; | |
1190 | 921 |
7955 | 922 default: |
923 return; | |
924 } | |
925 } | |
1190 | 926 |
7955 | 927 cur_frm_pos += 4; |
928 ref_frm_pos += 4; | |
929 } | |
930 | |
931 cur_frm_pos += (((width * 2) - blks_width) * 4); | |
932 ref_frm_pos += (((width * 2) - blks_width) * 4); | |
933 } | |
934 break; | |
935 | |
936 default: | |
937 return; | |
1190 | 938 } |
7955 | 939 } |
1190 | 940 |
7955 | 941 for( ; strip >= strip_tbl; strip--) { |
942 if(strip->split_flag != 0) { | |
943 strip->split_flag = 0; | |
944 strip->usl7 = (strip-1)->usl7; | |
1190 | 945 |
7955 | 946 if(strip->split_direction) { |
947 strip->xpos += strip->width; | |
948 strip->width = (strip-1)->width - strip->width; | |
949 if(region_160_width <= strip->xpos && width < strip->width + strip->xpos) | |
950 strip->width = width - strip->xpos; | |
951 } else { | |
952 strip->ypos += strip->height; | |
953 strip->height = (strip-1)->height - strip->height; | |
1190 | 954 } |
7955 | 955 break; |
1190 | 956 } |
7955 | 957 } |
1190 | 958 } |
959 } | |
960 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6450
diff
changeset
|
961 static av_cold int indeo3_decode_init(AVCodecContext *avctx) |
1190 | 962 { |
963 Indeo3DecodeContext *s = avctx->priv_data; | |
7950 | 964 int ret = 0; |
1190 | 965 |
966 s->avctx = avctx; | |
967 s->width = avctx->width; | |
968 s->height = avctx->height; | |
969 avctx->pix_fmt = PIX_FMT_YUV410P; | |
970 | |
7950 | 971 if (!(ret = build_modpred(s))) |
7955 | 972 ret = iv_alloc_frames(s); |
7950 | 973 if (ret) |
7955 | 974 iv_free_func(s); |
1190 | 975 |
7950 | 976 return ret; |
1190 | 977 } |
978 | |
9926
773041579748
Change iv_decode_frame to get AVCodecContext as argument, so that
reimar
parents:
9794
diff
changeset
|
979 static int iv_decode_frame(AVCodecContext *avctx, |
8988 | 980 const uint8_t *buf, int buf_size) |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
981 { |
9926
773041579748
Change iv_decode_frame to get AVCodecContext as argument, so that
reimar
parents:
9794
diff
changeset
|
982 Indeo3DecodeContext *s = avctx->priv_data; |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
983 unsigned int image_width, image_height, |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
984 chroma_width, chroma_height; |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
985 unsigned long flags, cb_offset, data_size, |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
986 y_offset, v_offset, u_offset, mc_vector_count; |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
987 const uint8_t *hdr_pos, *buf_pos; |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
988 |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
989 buf_pos = buf; |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
990 buf_pos += 18; /* skip OS header (16 bytes) and version number */ |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
991 |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
992 flags = bytestream_get_le16(&buf_pos); |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
993 data_size = bytestream_get_le32(&buf_pos); |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
994 cb_offset = *buf_pos++; |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
995 buf_pos += 3; /* skip reserved byte and checksum */ |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
996 image_height = bytestream_get_le16(&buf_pos); |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
997 image_width = bytestream_get_le16(&buf_pos); |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
998 |
12462
ffb3668ff7af
Use new imgutils.h API names, fix deprecation warnings.
stefano
parents:
12372
diff
changeset
|
999 if(av_image_check_size(image_width, image_height, 0, avctx)) |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1000 return -1; |
9927
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1001 if (image_width != avctx->width || image_height != avctx->height) { |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1002 int ret; |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1003 avcodec_set_dimensions(avctx, image_width, image_height); |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1004 s->width = avctx->width; |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1005 s->height = avctx->height; |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1006 ret = iv_alloc_frames(s); |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1007 if (ret < 0) { |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1008 s->width = s->height = 0; |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1009 return ret; |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1010 } |
f954ea120c78
Reallocate internal buffer when coded frame size changes.
reimar
parents:
9926
diff
changeset
|
1011 } |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1012 |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1013 chroma_height = ((image_height >> 2) + 3) & 0x7ffc; |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1014 chroma_width = ((image_width >> 2) + 3) & 0x7ffc; |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1015 y_offset = bytestream_get_le32(&buf_pos); |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1016 v_offset = bytestream_get_le32(&buf_pos); |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1017 u_offset = bytestream_get_le32(&buf_pos); |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1018 buf_pos += 4; /* reserved */ |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1019 hdr_pos = buf_pos; |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1020 if(data_size == 0x80) return 4; |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1021 |
8986 | 1022 if(FFMAX3(y_offset, v_offset, u_offset) >= buf_size-16) { |
1023 av_log(s->avctx, AV_LOG_ERROR, "y/u/v offset outside buffer\n"); | |
1024 return -1; | |
1025 } | |
1026 | |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1027 if(flags & 0x200) { |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1028 s->cur_frame = s->iv_frame + 1; |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1029 s->ref_frame = s->iv_frame; |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1030 } else { |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1031 s->cur_frame = s->iv_frame; |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1032 s->ref_frame = s->iv_frame + 1; |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1033 } |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1034 |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1035 buf_pos = buf + 16 + y_offset; |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1036 mc_vector_count = bytestream_get_le32(&buf_pos); |
8986 | 1037 if(2LL*mc_vector_count >= buf_size-16-y_offset) { |
1038 av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n"); | |
1039 return -1; | |
1040 } | |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1041 |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1042 iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, image_width, |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1043 image_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos, |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1044 FFMIN(image_width, 160)); |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1045 |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1046 if (!(s->avctx->flags & CODEC_FLAG_GRAY)) |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1047 { |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1048 |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1049 buf_pos = buf + 16 + v_offset; |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1050 mc_vector_count = bytestream_get_le32(&buf_pos); |
8986 | 1051 if(2LL*mc_vector_count >= buf_size-16-v_offset) { |
1052 av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n"); | |
1053 return -1; | |
1054 } | |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1055 |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1056 iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width, |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1057 chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos, |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1058 FFMIN(chroma_width, 40)); |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1059 |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1060 buf_pos = buf + 16 + u_offset; |
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1061 mc_vector_count = bytestream_get_le32(&buf_pos); |
8986 | 1062 if(2LL*mc_vector_count >= buf_size-16-u_offset) { |
1063 av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n"); | |
1064 return -1; | |
1065 } | |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1066 |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1067 iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width, |
7975
d9faf3f9f379
Rename some variables and add some comments to try to be a bit more clear.
benoit
parents:
7965
diff
changeset
|
1068 chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos, |
7957
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1069 FFMIN(chroma_width, 40)); |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1070 |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1071 } |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1072 |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1073 return 8; |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1074 } |
fbe8fabdbc63
Move iv_decode_frame function to remove a forward declaration.
benoit
parents:
7956
diff
changeset
|
1075 |
1190 | 1076 static int indeo3_decode_frame(AVCodecContext *avctx, |
1077 void *data, int *data_size, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8988
diff
changeset
|
1078 AVPacket *avpkt) |
1190 | 1079 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8988
diff
changeset
|
1080 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8988
diff
changeset
|
1081 int buf_size = avpkt->size; |
1190 | 1082 Indeo3DecodeContext *s=avctx->priv_data; |
7947 | 1083 uint8_t *src, *dest; |
1190 | 1084 int y; |
1085 | |
9926
773041579748
Change iv_decode_frame to get AVCodecContext as argument, so that
reimar
parents:
9794
diff
changeset
|
1086 if (iv_decode_frame(avctx, buf, buf_size) < 0) |
8986 | 1087 return -1; |
1190 | 1088 |
1228 | 1089 if(s->frame.data[0]) |
1090 avctx->release_buffer(avctx, &s->frame); | |
1091 | |
1190 | 1092 s->frame.reference = 0; |
1093 if(avctx->get_buffer(avctx, &s->frame) < 0) { | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1481
diff
changeset
|
1094 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
1190 | 1095 return -1; |
1096 } | |
1097 | |
1098 src = s->cur_frame->Ybuf; | |
1099 dest = s->frame.data[0]; | |
1100 for (y = 0; y < s->height; y++) { | |
7955 | 1101 memcpy(dest, src, s->cur_frame->y_w); |
1102 src += s->cur_frame->y_w; | |
1103 dest += s->frame.linesize[0]; | |
1190 | 1104 } |
1105 | |
2244
4a0cfd63f078
greyscale decoding (option to skip u,v planes) support
alex
parents:
2028
diff
changeset
|
1106 if (!(s->avctx->flags & CODEC_FLAG_GRAY)) |
4a0cfd63f078
greyscale decoding (option to skip u,v planes) support
alex
parents:
2028
diff
changeset
|
1107 { |
7955 | 1108 src = s->cur_frame->Ubuf; |
1109 dest = s->frame.data[1]; | |
1110 for (y = 0; y < s->height / 4; y++) { | |
1111 memcpy(dest, src, s->cur_frame->uv_w); | |
1112 src += s->cur_frame->uv_w; | |
1113 dest += s->frame.linesize[1]; | |
1114 } | |
1190 | 1115 |
7955 | 1116 src = s->cur_frame->Vbuf; |
1117 dest = s->frame.data[2]; | |
1118 for (y = 0; y < s->height / 4; y++) { | |
1119 memcpy(dest, src, s->cur_frame->uv_w); | |
1120 src += s->cur_frame->uv_w; | |
1121 dest += s->frame.linesize[2]; | |
1122 } | |
2244
4a0cfd63f078
greyscale decoding (option to skip u,v planes) support
alex
parents:
2028
diff
changeset
|
1123 } |
1190 | 1124 |
1125 *data_size=sizeof(AVFrame); | |
1126 *(AVFrame*)data= s->frame; | |
1127 | |
1128 return buf_size; | |
1129 } | |
1130 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6450
diff
changeset
|
1131 static av_cold int indeo3_decode_end(AVCodecContext *avctx) |
1190 | 1132 { |
1133 Indeo3DecodeContext *s = avctx->priv_data; | |
1134 | |
1135 iv_free_func(s); | |
1136 | |
1137 return 0; | |
1138 } | |
1139 | |
1140 AVCodec indeo3_decoder = { | |
1141 "indeo3", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
9985
diff
changeset
|
1142 AVMEDIA_TYPE_VIDEO, |
1190 | 1143 CODEC_ID_INDEO3, |
1144 sizeof(Indeo3DecodeContext), | |
1145 indeo3_decode_init, | |
1146 NULL, | |
1147 indeo3_decode_end, | |
1148 indeo3_decode_frame, | |
9794
fd3481a592b2
indeo3 decoder uses get_buffer, set CODEC_CAP_DR1
bcoudurier
parents:
9355
diff
changeset
|
1149 CODEC_CAP_DR1, |
6710 | 1150 NULL, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
1151 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"), |
1190 | 1152 }; |