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