1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libtremor/lib/tremor_mdct.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,510 @@ 1.4 +/******************************************************************** 1.5 + * * 1.6 + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * 1.7 + * * 1.8 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 1.9 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 1.10 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 1.11 + * * 1.12 + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * 1.13 + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * 1.14 + * * 1.15 + ******************************************************************** 1.16 + 1.17 + function: normalized modified discrete cosine transform 1.18 + power of two length transform only [64 <= n ] 1.19 + last mod: $Id: mdct.c,v 1.9 2002/10/16 09:17:39 xiphmont Exp $ 1.20 + 1.21 + Original algorithm adapted long ago from _The use of multirate filter 1.22 + banks for coding of high quality digital audio_, by T. Sporer, 1.23 + K. Brandenburg and B. Edler, collection of the European Signal 1.24 + Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp 1.25 + 211-214 1.26 + 1.27 + The below code implements an algorithm that no longer looks much like 1.28 + that presented in the paper, but the basic structure remains if you 1.29 + dig deep enough to see it. 1.30 + 1.31 + This module DOES NOT INCLUDE code to generate/apply the window 1.32 + function. Everybody has their own weird favorite including me... I 1.33 + happen to like the properties of y=sin(.5PI*sin^2(x)), but others may 1.34 + vehemently disagree. 1.35 + 1.36 + ********************************************************************/ 1.37 + 1.38 +#include "ivorbiscodec.h" 1.39 +#include "codebook.h" 1.40 +#include "misc.h" 1.41 +#include "mdct.h" 1.42 +#include "mdct_lookup.h" 1.43 + 1.44 + 1.45 +/* 8 point butterfly (in place) */ 1.46 +STIN void mdct_butterfly_8(DATA_TYPE *x){ 1.47 + 1.48 + REG_TYPE r0 = x[4] + x[0]; 1.49 + REG_TYPE r1 = x[4] - x[0]; 1.50 + REG_TYPE r2 = x[5] + x[1]; 1.51 + REG_TYPE r3 = x[5] - x[1]; 1.52 + REG_TYPE r4 = x[6] + x[2]; 1.53 + REG_TYPE r5 = x[6] - x[2]; 1.54 + REG_TYPE r6 = x[7] + x[3]; 1.55 + REG_TYPE r7 = x[7] - x[3]; 1.56 + 1.57 + x[0] = r5 + r3; 1.58 + x[1] = r7 - r1; 1.59 + x[2] = r5 - r3; 1.60 + x[3] = r7 + r1; 1.61 + x[4] = r4 - r0; 1.62 + x[5] = r6 - r2; 1.63 + x[6] = r4 + r0; 1.64 + x[7] = r6 + r2; 1.65 + MB(); 1.66 +} 1.67 + 1.68 +/* 16 point butterfly (in place, 4 register) */ 1.69 +STIN void mdct_butterfly_16(DATA_TYPE *x){ 1.70 + 1.71 + REG_TYPE r0, r1; 1.72 + 1.73 + r0 = x[ 0] - x[ 8]; x[ 8] += x[ 0]; 1.74 + r1 = x[ 1] - x[ 9]; x[ 9] += x[ 1]; 1.75 + x[ 0] = MULT31((r0 + r1) , cPI2_8); 1.76 + x[ 1] = MULT31((r1 - r0) , cPI2_8); 1.77 + MB(); 1.78 + 1.79 + r0 = x[10] - x[ 2]; x[10] += x[ 2]; 1.80 + r1 = x[ 3] - x[11]; x[11] += x[ 3]; 1.81 + x[ 2] = r1; x[ 3] = r0; 1.82 + MB(); 1.83 + 1.84 + r0 = x[12] - x[ 4]; x[12] += x[ 4]; 1.85 + r1 = x[13] - x[ 5]; x[13] += x[ 5]; 1.86 + x[ 4] = MULT31((r0 - r1) , cPI2_8); 1.87 + x[ 5] = MULT31((r0 + r1) , cPI2_8); 1.88 + MB(); 1.89 + 1.90 + r0 = x[14] - x[ 6]; x[14] += x[ 6]; 1.91 + r1 = x[15] - x[ 7]; x[15] += x[ 7]; 1.92 + x[ 6] = r0; x[ 7] = r1; 1.93 + MB(); 1.94 + 1.95 + mdct_butterfly_8(x); 1.96 + mdct_butterfly_8(x+8); 1.97 +} 1.98 + 1.99 +/* 32 point butterfly (in place, 4 register) */ 1.100 +STIN void mdct_butterfly_32(DATA_TYPE *x){ 1.101 + 1.102 + REG_TYPE r0, r1; 1.103 + 1.104 + r0 = x[30] - x[14]; x[30] += x[14]; 1.105 + r1 = x[31] - x[15]; x[31] += x[15]; 1.106 + x[14] = r0; x[15] = r1; 1.107 + MB(); 1.108 + 1.109 + r0 = x[28] - x[12]; x[28] += x[12]; 1.110 + r1 = x[29] - x[13]; x[29] += x[13]; 1.111 + XNPROD31( r0, r1, cPI1_8, cPI3_8, &x[12], &x[13] ); 1.112 + MB(); 1.113 + 1.114 + r0 = x[26] - x[10]; x[26] += x[10]; 1.115 + r1 = x[27] - x[11]; x[27] += x[11]; 1.116 + x[10] = MULT31((r0 - r1) , cPI2_8); 1.117 + x[11] = MULT31((r0 + r1) , cPI2_8); 1.118 + MB(); 1.119 + 1.120 + r0 = x[24] - x[ 8]; x[24] += x[ 8]; 1.121 + r1 = x[25] - x[ 9]; x[25] += x[ 9]; 1.122 + XNPROD31( r0, r1, cPI3_8, cPI1_8, &x[ 8], &x[ 9] ); 1.123 + MB(); 1.124 + 1.125 + r0 = x[22] - x[ 6]; x[22] += x[ 6]; 1.126 + r1 = x[ 7] - x[23]; x[23] += x[ 7]; 1.127 + x[ 6] = r1; x[ 7] = r0; 1.128 + MB(); 1.129 + 1.130 + r0 = x[ 4] - x[20]; x[20] += x[ 4]; 1.131 + r1 = x[ 5] - x[21]; x[21] += x[ 5]; 1.132 + XPROD31 ( r0, r1, cPI3_8, cPI1_8, &x[ 4], &x[ 5] ); 1.133 + MB(); 1.134 + 1.135 + r0 = x[ 2] - x[18]; x[18] += x[ 2]; 1.136 + r1 = x[ 3] - x[19]; x[19] += x[ 3]; 1.137 + x[ 2] = MULT31((r1 + r0) , cPI2_8); 1.138 + x[ 3] = MULT31((r1 - r0) , cPI2_8); 1.139 + MB(); 1.140 + 1.141 + r0 = x[ 0] - x[16]; x[16] += x[ 0]; 1.142 + r1 = x[ 1] - x[17]; x[17] += x[ 1]; 1.143 + XPROD31 ( r0, r1, cPI1_8, cPI3_8, &x[ 0], &x[ 1] ); 1.144 + MB(); 1.145 + 1.146 + mdct_butterfly_16(x); 1.147 + mdct_butterfly_16(x+16); 1.148 +} 1.149 + 1.150 +/* N/stage point generic N stage butterfly (in place, 2 register) */ 1.151 +STIN void mdct_butterfly_generic(DATA_TYPE *x,int points,int step){ 1.152 + 1.153 + LOOKUP_T *T = sincos_lookup0; 1.154 + DATA_TYPE *x1 = x + points - 8; 1.155 + DATA_TYPE *x2 = x + (points>>1) - 8; 1.156 + REG_TYPE r0; 1.157 + REG_TYPE r1; 1.158 + 1.159 + do{ 1.160 + r0 = x1[6] - x2[6]; x1[6] += x2[6]; 1.161 + r1 = x2[7] - x1[7]; x1[7] += x2[7]; 1.162 + XPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T+=step; 1.163 + 1.164 + r0 = x1[4] - x2[4]; x1[4] += x2[4]; 1.165 + r1 = x2[5] - x1[5]; x1[5] += x2[5]; 1.166 + XPROD31( r1, r0, T[0], T[1], &x2[4], &x2[5] ); T+=step; 1.167 + 1.168 + r0 = x1[2] - x2[2]; x1[2] += x2[2]; 1.169 + r1 = x2[3] - x1[3]; x1[3] += x2[3]; 1.170 + XPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T+=step; 1.171 + 1.172 + r0 = x1[0] - x2[0]; x1[0] += x2[0]; 1.173 + r1 = x2[1] - x1[1]; x1[1] += x2[1]; 1.174 + XPROD31( r1, r0, T[0], T[1], &x2[0], &x2[1] ); T+=step; 1.175 + 1.176 + x1-=8; x2-=8; 1.177 + }while(T<sincos_lookup0+1024); 1.178 + do{ 1.179 + r0 = x1[6] - x2[6]; x1[6] += x2[6]; 1.180 + r1 = x1[7] - x2[7]; x1[7] += x2[7]; 1.181 + XNPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T-=step; 1.182 + 1.183 + r0 = x1[4] - x2[4]; x1[4] += x2[4]; 1.184 + r1 = x1[5] - x2[5]; x1[5] += x2[5]; 1.185 + XNPROD31( r0, r1, T[0], T[1], &x2[4], &x2[5] ); T-=step; 1.186 + 1.187 + r0 = x1[2] - x2[2]; x1[2] += x2[2]; 1.188 + r1 = x1[3] - x2[3]; x1[3] += x2[3]; 1.189 + XNPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T-=step; 1.190 + 1.191 + r0 = x1[0] - x2[0]; x1[0] += x2[0]; 1.192 + r1 = x1[1] - x2[1]; x1[1] += x2[1]; 1.193 + XNPROD31( r0, r1, T[0], T[1], &x2[0], &x2[1] ); T-=step; 1.194 + 1.195 + x1-=8; x2-=8; 1.196 + }while(T>sincos_lookup0); 1.197 + do{ 1.198 + r0 = x2[6] - x1[6]; x1[6] += x2[6]; 1.199 + r1 = x2[7] - x1[7]; x1[7] += x2[7]; 1.200 + XPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T+=step; 1.201 + 1.202 + r0 = x2[4] - x1[4]; x1[4] += x2[4]; 1.203 + r1 = x2[5] - x1[5]; x1[5] += x2[5]; 1.204 + XPROD31( r0, r1, T[0], T[1], &x2[4], &x2[5] ); T+=step; 1.205 + 1.206 + r0 = x2[2] - x1[2]; x1[2] += x2[2]; 1.207 + r1 = x2[3] - x1[3]; x1[3] += x2[3]; 1.208 + XPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T+=step; 1.209 + 1.210 + r0 = x2[0] - x1[0]; x1[0] += x2[0]; 1.211 + r1 = x2[1] - x1[1]; x1[1] += x2[1]; 1.212 + XPROD31( r0, r1, T[0], T[1], &x2[0], &x2[1] ); T+=step; 1.213 + 1.214 + x1-=8; x2-=8; 1.215 + }while(T<sincos_lookup0+1024); 1.216 + do{ 1.217 + r0 = x1[6] - x2[6]; x1[6] += x2[6]; 1.218 + r1 = x2[7] - x1[7]; x1[7] += x2[7]; 1.219 + XNPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T-=step; 1.220 + 1.221 + r0 = x1[4] - x2[4]; x1[4] += x2[4]; 1.222 + r1 = x2[5] - x1[5]; x1[5] += x2[5]; 1.223 + XNPROD31( r1, r0, T[0], T[1], &x2[4], &x2[5] ); T-=step; 1.224 + 1.225 + r0 = x1[2] - x2[2]; x1[2] += x2[2]; 1.226 + r1 = x2[3] - x1[3]; x1[3] += x2[3]; 1.227 + XNPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T-=step; 1.228 + 1.229 + r0 = x1[0] - x2[0]; x1[0] += x2[0]; 1.230 + r1 = x2[1] - x1[1]; x1[1] += x2[1]; 1.231 + XNPROD31( r1, r0, T[0], T[1], &x2[0], &x2[1] ); T-=step; 1.232 + 1.233 + x1-=8; x2-=8; 1.234 + }while(T>sincos_lookup0); 1.235 +} 1.236 + 1.237 +STIN void mdct_butterflies(DATA_TYPE *x,int points,int shift){ 1.238 + 1.239 + int stages=8-shift; 1.240 + int i,j; 1.241 + 1.242 + for(i=0;--stages>0;i++){ 1.243 + for(j=0;j<(1<<i);j++) 1.244 + mdct_butterfly_generic(x+(points>>i)*j,points>>i,4<<(i+shift)); 1.245 + } 1.246 + 1.247 + for(j=0;j<points;j+=32) 1.248 + mdct_butterfly_32(x+j); 1.249 + 1.250 +} 1.251 + 1.252 +static unsigned char bitrev[16]={0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}; 1.253 + 1.254 +STIN int bitrev12(int x){ 1.255 + return bitrev[x>>8]|(bitrev[(x&0x0f0)>>4]<<4)|(((int)bitrev[x&0x00f])<<8); 1.256 +} 1.257 + 1.258 +STIN void mdct_bitreverse(DATA_TYPE *x,int n,int step,int shift){ 1.259 + 1.260 + int bit = 0; 1.261 + DATA_TYPE *w0 = x; 1.262 + DATA_TYPE *w1 = x = w0+(n>>1); 1.263 + LOOKUP_T *T = (step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1; 1.264 + LOOKUP_T *Ttop = T+1024; 1.265 + DATA_TYPE r2; 1.266 + 1.267 + do{ 1.268 + DATA_TYPE r3 = bitrev12(bit++); 1.269 + DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1; 1.270 + DATA_TYPE *x1 = x + (r3>>shift); 1.271 + 1.272 + REG_TYPE r0 = x0[0] + x1[0]; 1.273 + REG_TYPE r1 = x1[1] - x0[1]; 1.274 + 1.275 + XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step; 1.276 + 1.277 + w1 -= 4; 1.278 + 1.279 + r0 = (x0[1] + x1[1])>>1; 1.280 + r1 = (x0[0] - x1[0])>>1; 1.281 + w0[0] = r0 + r2; 1.282 + w0[1] = r1 + r3; 1.283 + w1[2] = r0 - r2; 1.284 + w1[3] = r3 - r1; 1.285 + 1.286 + r3 = bitrev12(bit++); 1.287 + x0 = x + ((r3 ^ 0xfff)>>shift) -1; 1.288 + x1 = x + (r3>>shift); 1.289 + 1.290 + r0 = x0[0] + x1[0]; 1.291 + r1 = x1[1] - x0[1]; 1.292 + 1.293 + XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step; 1.294 + 1.295 + r0 = (x0[1] + x1[1])>>1; 1.296 + r1 = (x0[0] - x1[0])>>1; 1.297 + w0[2] = r0 + r2; 1.298 + w0[3] = r1 + r3; 1.299 + w1[0] = r0 - r2; 1.300 + w1[1] = r3 - r1; 1.301 + 1.302 + w0 += 4; 1.303 + }while(T<Ttop); 1.304 + do{ 1.305 + DATA_TYPE r3 = bitrev12(bit++); 1.306 + DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1; 1.307 + DATA_TYPE *x1 = x + (r3>>shift); 1.308 + 1.309 + REG_TYPE r0 = x0[0] + x1[0]; 1.310 + REG_TYPE r1 = x1[1] - x0[1]; 1.311 + 1.312 + T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 ); 1.313 + 1.314 + w1 -= 4; 1.315 + 1.316 + r0 = (x0[1] + x1[1])>>1; 1.317 + r1 = (x0[0] - x1[0])>>1; 1.318 + w0[0] = r0 + r2; 1.319 + w0[1] = r1 + r3; 1.320 + w1[2] = r0 - r2; 1.321 + w1[3] = r3 - r1; 1.322 + 1.323 + r3 = bitrev12(bit++); 1.324 + x0 = x + ((r3 ^ 0xfff)>>shift) -1; 1.325 + x1 = x + (r3>>shift); 1.326 + 1.327 + r0 = x0[0] + x1[0]; 1.328 + r1 = x1[1] - x0[1]; 1.329 + 1.330 + T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 ); 1.331 + 1.332 + r0 = (x0[1] + x1[1])>>1; 1.333 + r1 = (x0[0] - x1[0])>>1; 1.334 + w0[2] = r0 + r2; 1.335 + w0[3] = r1 + r3; 1.336 + w1[0] = r0 - r2; 1.337 + w1[1] = r3 - r1; 1.338 + 1.339 + w0 += 4; 1.340 + }while(w0<w1); 1.341 +} 1.342 + 1.343 +void mdct_backward(int n, DATA_TYPE *in, DATA_TYPE *out){ 1.344 + int n2=n>>1; 1.345 + int n4=n>>2; 1.346 + DATA_TYPE *iX; 1.347 + DATA_TYPE *oX; 1.348 + LOOKUP_T *T; 1.349 + LOOKUP_T *V; 1.350 + int shift; 1.351 + int step; 1.352 + 1.353 + for (shift=6;!(n&(1<<shift));shift++); 1.354 + shift=13-shift; 1.355 + step=2<<shift; 1.356 + 1.357 + /* rotate */ 1.358 + 1.359 + iX = in+n2-7; 1.360 + oX = out+n2+n4; 1.361 + T = sincos_lookup0; 1.362 + 1.363 + do{ 1.364 + oX-=4; 1.365 + XPROD31( iX[4], iX[6], T[0], T[1], &oX[2], &oX[3] ); T+=step; 1.366 + XPROD31( iX[0], iX[2], T[0], T[1], &oX[0], &oX[1] ); T+=step; 1.367 + iX-=8; 1.368 + }while(iX>=in+n4); 1.369 + do{ 1.370 + oX-=4; 1.371 + XPROD31( iX[4], iX[6], T[1], T[0], &oX[2], &oX[3] ); T-=step; 1.372 + XPROD31( iX[0], iX[2], T[1], T[0], &oX[0], &oX[1] ); T-=step; 1.373 + iX-=8; 1.374 + }while(iX>=in); 1.375 + 1.376 + iX = in+n2-8; 1.377 + oX = out+n2+n4; 1.378 + T = sincos_lookup0; 1.379 + 1.380 + do{ 1.381 + T+=step; XNPROD31( iX[6], iX[4], T[0], T[1], &oX[0], &oX[1] ); 1.382 + T+=step; XNPROD31( iX[2], iX[0], T[0], T[1], &oX[2], &oX[3] ); 1.383 + iX-=8; 1.384 + oX+=4; 1.385 + }while(iX>=in+n4); 1.386 + do{ 1.387 + T-=step; XNPROD31( iX[6], iX[4], T[1], T[0], &oX[0], &oX[1] ); 1.388 + T-=step; XNPROD31( iX[2], iX[0], T[1], T[0], &oX[2], &oX[3] ); 1.389 + iX-=8; 1.390 + oX+=4; 1.391 + }while(iX>=in); 1.392 + 1.393 + mdct_butterflies(out+n2,n2,shift); 1.394 + mdct_bitreverse(out,n,step,shift); 1.395 + 1.396 + /* rotate + window */ 1.397 + 1.398 + step>>=2; 1.399 + { 1.400 + DATA_TYPE *oX1=out+n2+n4; 1.401 + DATA_TYPE *oX2=out+n2+n4; 1.402 + DATA_TYPE *iX =out; 1.403 + 1.404 + switch(step) { 1.405 + default: { 1.406 + T=(step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1; 1.407 + do{ 1.408 + oX1-=4; 1.409 + XPROD31( iX[0], -iX[1], T[0], T[1], &oX1[3], &oX2[0] ); T+=step; 1.410 + XPROD31( iX[2], -iX[3], T[0], T[1], &oX1[2], &oX2[1] ); T+=step; 1.411 + XPROD31( iX[4], -iX[5], T[0], T[1], &oX1[1], &oX2[2] ); T+=step; 1.412 + XPROD31( iX[6], -iX[7], T[0], T[1], &oX1[0], &oX2[3] ); T+=step; 1.413 + oX2+=4; 1.414 + iX+=8; 1.415 + }while(iX<oX1); 1.416 + break; 1.417 + } 1.418 + 1.419 + case 1: { 1.420 + /* linear interpolation between table values: offset=0.5, step=1 */ 1.421 + REG_TYPE t0,t1,v0,v1; 1.422 + T = sincos_lookup0; 1.423 + V = sincos_lookup1; 1.424 + t0 = (*T++)>>1; 1.425 + t1 = (*T++)>>1; 1.426 + do{ 1.427 + oX1-=4; 1.428 + 1.429 + t0 += (v0 = (*V++)>>1); 1.430 + t1 += (v1 = (*V++)>>1); 1.431 + XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] ); 1.432 + v0 += (t0 = (*T++)>>1); 1.433 + v1 += (t1 = (*T++)>>1); 1.434 + XPROD31( iX[2], -iX[3], v0, v1, &oX1[2], &oX2[1] ); 1.435 + t0 += (v0 = (*V++)>>1); 1.436 + t1 += (v1 = (*V++)>>1); 1.437 + XPROD31( iX[4], -iX[5], t0, t1, &oX1[1], &oX2[2] ); 1.438 + v0 += (t0 = (*T++)>>1); 1.439 + v1 += (t1 = (*T++)>>1); 1.440 + XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] ); 1.441 + 1.442 + oX2+=4; 1.443 + iX+=8; 1.444 + }while(iX<oX1); 1.445 + break; 1.446 + } 1.447 + 1.448 + case 0: { 1.449 + /* linear interpolation between table values: offset=0.25, step=0.5 */ 1.450 + REG_TYPE t0,t1,v0,v1,q0,q1; 1.451 + T = sincos_lookup0; 1.452 + V = sincos_lookup1; 1.453 + t0 = *T++; 1.454 + t1 = *T++; 1.455 + do{ 1.456 + oX1-=4; 1.457 + 1.458 + v0 = *V++; 1.459 + v1 = *V++; 1.460 + t0 += (q0 = (v0-t0)>>2); 1.461 + t1 += (q1 = (v1-t1)>>2); 1.462 + XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] ); 1.463 + t0 = v0-q0; 1.464 + t1 = v1-q1; 1.465 + XPROD31( iX[2], -iX[3], t0, t1, &oX1[2], &oX2[1] ); 1.466 + 1.467 + t0 = *T++; 1.468 + t1 = *T++; 1.469 + v0 += (q0 = (t0-v0)>>2); 1.470 + v1 += (q1 = (t1-v1)>>2); 1.471 + XPROD31( iX[4], -iX[5], v0, v1, &oX1[1], &oX2[2] ); 1.472 + v0 = t0-q0; 1.473 + v1 = t1-q1; 1.474 + XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] ); 1.475 + 1.476 + oX2+=4; 1.477 + iX+=8; 1.478 + }while(iX<oX1); 1.479 + break; 1.480 + } 1.481 + } 1.482 + 1.483 + iX=out+n2+n4; 1.484 + oX1=out+n4; 1.485 + oX2=oX1; 1.486 + 1.487 + do{ 1.488 + oX1-=4; 1.489 + iX-=4; 1.490 + 1.491 + oX2[0] = -(oX1[3] = iX[3]); 1.492 + oX2[1] = -(oX1[2] = iX[2]); 1.493 + oX2[2] = -(oX1[1] = iX[1]); 1.494 + oX2[3] = -(oX1[0] = iX[0]); 1.495 + 1.496 + oX2+=4; 1.497 + }while(oX2<iX); 1.498 + 1.499 + iX=out+n2+n4; 1.500 + oX1=out+n2+n4; 1.501 + oX2=out+n2; 1.502 + 1.503 + do{ 1.504 + oX1-=4; 1.505 + oX1[0]= iX[3]; 1.506 + oX1[1]= iX[2]; 1.507 + oX1[2]= iX[1]; 1.508 + oX1[3]= iX[0]; 1.509 + iX+=4; 1.510 + }while(oX1>oX2); 1.511 + } 1.512 +} 1.513 +