aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
diff options
context:
space:
mode:
authorUbitUmarov2015-09-25 05:46:06 +0100
committerUbitUmarov2015-09-25 05:46:06 +0100
commit2b0587770a554a3851847f2bc2a5ed155509a425 (patch)
tree797c08924b544656f5141cb59ffc1b02ec136547 /OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
parent we still don't have extended wind and cloud neither do viewers (diff)
downloadopensim-SC-2b0587770a554a3851847f2bc2a5ed155509a425.zip
opensim-SC-2b0587770a554a3851847f2bc2a5ed155509a425.tar.gz
opensim-SC-2b0587770a554a3851847f2bc2a5ed155509a425.tar.bz2
opensim-SC-2b0587770a554a3851847f2bc2a5ed155509a425.tar.xz
add butterflies to terrain
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/TerrainCompressor.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainCompressor.cs942
1 files changed, 757 insertions, 185 deletions
diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
index 0db1033..32fd263 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
@@ -33,6 +33,7 @@
33using System; 33using System;
34using System.Collections.Generic; 34using System.Collections.Generic;
35using System.Reflection; 35using System.Reflection;
36using System.Diagnostics;
36 37
37using log4net; 38using log4net;
38 39
@@ -47,7 +48,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
47{ 48{
48 public static class OpenSimTerrainCompressor 49 public static class OpenSimTerrainCompressor
49 { 50 {
50// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 52
52#pragma warning disable 414 53#pragma warning disable 414
53 private static string LogHeader = "[TERRAIN COMPRESSOR]"; 54 private static string LogHeader = "[TERRAIN COMPRESSOR]";
@@ -64,8 +65,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
64 private const int NEGATIVE_VALUE = 0x7; 65 private const int NEGATIVE_VALUE = 0x7;
65 66
66 67
67 private static readonly float[] CosineTable16 = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 68 private static readonly float[] CosineTable16 = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
68 private static readonly int[] CopyMatrix16 = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 69 private static readonly int[] CopyMatrix16 = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
69 70
70 private static readonly float[] QuantizeTable16 = 71 private static readonly float[] QuantizeTable16 =
71 new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; 72 new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
@@ -84,13 +85,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
84 // Used to send cloud and wind patches 85 // Used to send cloud and wind patches
85 public static LayerDataPacket CreateLayerDataPacketStandardSize(TerrainPatch[] patches, byte type) 86 public static LayerDataPacket CreateLayerDataPacketStandardSize(TerrainPatch[] patches, byte type)
86 { 87 {
87 LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}}; 88 LayerDataPacket layer = new LayerDataPacket { LayerID = { Type = type } };
88 89
89 TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader 90 TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
90 {Stride = STRIDE, PatchSize = Constants.TerrainPatchSize}; 91 { Stride = STRIDE, PatchSize = Constants.TerrainPatchSize };
91 92
92 // Should be enough to fit even the most poorly packed data 93 // Should be enough to fit even the most poorly packed data
93 byte[] data = new byte[patches.Length*Constants.TerrainPatchSize*Constants.TerrainPatchSize*2]; 94 byte[] data = new byte[patches.Length * Constants.TerrainPatchSize * Constants.TerrainPatchSize * 2];
94 BitPack bitpack = new BitPack(data, 0); 95 BitPack bitpack = new BitPack(data, 0);
95 bitpack.PackBits(header.Stride, 16); 96 bitpack.PackBits(header.Stride, 16);
96 bitpack.PackBits(header.PatchSize, 8); 97 bitpack.PackBits(header.PatchSize, 8);
@@ -161,16 +162,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
161 } 162 }
162 163
163 float[] ftemp = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; 164 float[] ftemp = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
164 int[] itemp = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; 165 int[] iout = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
165 166
166 wbits = (prequant >> 1); 167 wbits = (prequant >> 1);
167 168
168 for (int o = 0; o < Constants.TerrainPatchSize; o++) 169 dct16x16(block, iout, ref wbits);
169 DCTLine16(block, ftemp, o);
170 for (int o = 0; o < Constants.TerrainPatchSize; o++)
171 wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits);
172 170
173 return itemp; 171 return iout;
174 } 172 }
175 173
176 // new using terrain data and patchs indexes 174 // new using terrain data and patchs indexes
@@ -204,7 +202,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
204 // start another 202 // start another
205 layer = new LayerDataPacket(); 203 layer = new LayerDataPacket();
206 layer.LayerID.Type = landPacketType; 204 layer.LayerID.Type = landPacketType;
207 205
208 bitpack = new BitPack(data, 0); 206 bitpack = new BitPack(data, 0);
209 bitpack.PackBits(STRIDE, 16); 207 bitpack.PackBits(STRIDE, 16);
210 bitpack.PackBits(Constants.TerrainPatchSize, 8); 208 bitpack.PackBits(Constants.TerrainPatchSize, 8);
@@ -256,7 +254,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 header.PatchIDs += (patchX << 5); 254 header.PatchIDs += (patchX << 5);
257 } 255 }
258 256
259 if(Math.Round((double)frange,2) == 1.0) 257 if (Math.Round((double)frange, 2) == 1.0)
260 { 258 {
261 // flat terrain speed up things 259 // flat terrain speed up things
262 260
@@ -270,20 +268,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
270 output.PackBits(header.PatchIDs, 32); 268 output.PackBits(header.PatchIDs, 32);
271 else 269 else
272 output.PackBits(header.PatchIDs, 10); 270 output.PackBits(header.PatchIDs, 10);
273 271
274 // and thats all 272 // and thats all
275 output.PackBits(ZERO_EOB, 2); 273 output.PackBits(ZERO_EOB, 2);
276 return; 274 return;
277 } 275 }
278 276
279 int wbits; 277 int wbits;
280 int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits); 278 int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits);
281 EncodePatchHeader(output, header, patch, largeRegion, ref wbits); 279 EncodePatchHeader(output, header, patch, largeRegion, ref wbits);
282 EncodePatch(output, patch, 0, wbits); 280 EncodePatch(output, patch, 0, wbits);
283 } 281 }
284 282
285
286
287 // Scan the height info we're returning and return a patch packet header for this patch. 283 // Scan the height info we're returning and return a patch packet header for this patch.
288 private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY, out float frange) 284 private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY, out float frange)
289 { 285 {
@@ -312,7 +308,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
312 308
313 public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack) 309 public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack)
314 { 310 {
315 TerrainPatch.Header header = new TerrainPatch.Header {QuantWBits = bitpack.UnpackBits(8)}; 311 TerrainPatch.Header header = new TerrainPatch.Header { QuantWBits = bitpack.UnpackBits(8) };
316 312
317 // Quantized word bits 313 // Quantized word bits
318 if (header.QuantWBits == END_OF_PATCHES) 314 if (header.QuantWBits == END_OF_PATCHES)
@@ -328,7 +324,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
328 header.PatchIDs = bitpack.UnpackBits(10); 324 header.PatchIDs = bitpack.UnpackBits(10);
329 325
330 // Word bits 326 // Word bits
331 header.WordBits = (uint) ((header.QuantWBits & 0x0f) + 2); 327 header.WordBits = (uint)((header.QuantWBits & 0x0f) + 2);
332 328
333 return header; 329 return header;
334 } 330 }
@@ -356,136 +352,39 @@ namespace OpenSim.Region.ClientStack.LindenUDP
356 { 352 {
357 for (int n = 0; n < Constants.TerrainPatchSize; n++) 353 for (int n = 0; n < Constants.TerrainPatchSize; n++)
358 { 354 {
359 float total = OO_SQRT2*linein[column]; 355 float total = OO_SQRT2 * linein[column];
360 356
361 for (int u = 1; u < Constants.TerrainPatchSize; u++) 357 for (int u = 1; u < Constants.TerrainPatchSize; u++)
362 { 358 {
363 int usize = u*Constants.TerrainPatchSize; 359 int usize = u * Constants.TerrainPatchSize;
364 total += linein[usize + column]*CosineTable16[usize + n]; 360 total += linein[usize + column] * CosineTable16[usize + n];
365 } 361 }
366 362
367 lineout[Constants.TerrainPatchSize*n + column] = total; 363 lineout[Constants.TerrainPatchSize * n + column] = total;
368 } 364 }
369 } 365 }
370 366
371 private static void IDCTLine16(float[] linein, float[] lineout, int line) 367 private static void IDCTLine16(float[] linein, float[] lineout, int line)
372 { 368 {
373 const float oosob = 2.0f/Constants.TerrainPatchSize; 369 const float oosob = 2.0f / Constants.TerrainPatchSize;
374 int lineSize = line*Constants.TerrainPatchSize; 370 int lineSize = line * Constants.TerrainPatchSize;
375 371
376 for (int n = 0; n < Constants.TerrainPatchSize; n++) 372 for (int n = 0; n < Constants.TerrainPatchSize; n++)
377 { 373 {
378 float total = OO_SQRT2*linein[lineSize]; 374 float total = OO_SQRT2 * linein[lineSize];
379 375
380 for (int u = 1; u < Constants.TerrainPatchSize; u++) 376 for (int u = 1; u < Constants.TerrainPatchSize; u++)
381 { 377 {
382 total += linein[lineSize + u]*CosineTable16[u*Constants.TerrainPatchSize + n]; 378 total += linein[lineSize + u] * CosineTable16[u * Constants.TerrainPatchSize + n];
383 }
384
385 lineout[lineSize + n] = total*oosob;
386 }
387 }
388
389 private static void DCTLine16(float[] linein, float[] lineout, int line)
390 {
391 // outputs transpose data
392
393 float total = 0.0f;
394 int lineSize = line*Constants.TerrainPatchSize;
395
396 for (int n = 0; n < Constants.TerrainPatchSize; n++)
397 {
398 total += linein[lineSize + n];
399 }
400
401 lineout[line] = OO_SQRT2*total;
402
403 for (int u = Constants.TerrainPatchSize;
404 u < Constants.TerrainPatchSize*Constants.TerrainPatchSize;
405 u += Constants.TerrainPatchSize)
406 {
407 total = 0.0f;
408 for (int ptrn = lineSize, ptru = u; ptrn < lineSize + Constants.TerrainPatchSize; ptrn++,ptru++)
409 {
410 total += linein[ptrn]*CosineTable16[ptru];
411 } 379 }
412 380
413 lineout[line + u] = total; 381 lineout[lineSize + n] = total * oosob;
414 } 382 }
415 } 383 }
416 384
417 private static int DCTColumn16Wbits(float[] linein, int[] lineout, int column, int wbits)
418 {
419 // input columns are in fact stored in lines now
420
421 const int maxwbits = 17; // per header encoding
422
423 bool dowbits = wbits < 17;
424
425 int wbitsMaxValue = 1 << wbits;
426
427 float total = 0.0f;
428 // const float oosob = 2.0f / Constants.TerrainPatchSize;
429 int inlinesptr = Constants.TerrainPatchSize*column;
430
431 for (int n = 0; n < Constants.TerrainPatchSize; n++)
432 {
433 total += linein[inlinesptr + n];
434 }
435
436 int tmp = (int) (OO_SQRT2*total*QuantizeTable16[column]);
437 lineout[CopyMatrix16[column]] = tmp;
438
439 if (dowbits)
440 {
441 if (tmp < 0) tmp *= -1;
442 while (tmp > wbitsMaxValue)
443 {
444 wbits++;
445 wbitsMaxValue = 1 << wbits;
446 if (wbits == maxwbits)
447 {
448 dowbits = false;
449 break;
450 }
451 }
452 }
453
454 for (int uptr = Constants.TerrainPatchSize;
455 uptr < Constants.TerrainPatchSize*Constants.TerrainPatchSize;
456 uptr += Constants.TerrainPatchSize)
457 {
458 total = 0.0f;
459
460 for (int n = inlinesptr, ptru = uptr; n < inlinesptr + Constants.TerrainPatchSize; n++, ptru++)
461 {
462 total += linein[n]*CosineTable16[ptru];
463 }
464
465 tmp = (int) (total*QuantizeTable16[uptr + column]);
466 lineout[CopyMatrix16[uptr + column]] = tmp;
467
468 if (dowbits)
469 {
470 if (tmp < 0) tmp *= -1;
471 while (tmp > wbitsMaxValue)
472 {
473 wbits++;
474 wbitsMaxValue = 1 << wbits;
475 if (wbits == maxwbits)
476 {
477 dowbits = false;
478 break;
479 }
480 }
481 }
482 }
483 return wbits;
484 }
485
486 public static void DecodePatch(int[] patches, BitPack bitpack, TerrainPatch.Header header, int size) 385 public static void DecodePatch(int[] patches, BitPack bitpack, TerrainPatch.Header header, int size)
487 { 386 {
488 for (int n = 0; n < size*size; n++) 387 for (int n = 0; n < size * size; n++)
489 { 388 {
490 // ? 389 // ?
491 int temp = bitpack.UnpackBits(1); 390 int temp = bitpack.UnpackBits(1);
@@ -500,13 +399,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
500 if (temp != 0) 399 if (temp != 0)
501 { 400 {
502 // Negative 401 // Negative
503 temp = bitpack.UnpackBits((int) header.WordBits); 402 temp = bitpack.UnpackBits((int)header.WordBits);
504 patches[n] = temp*-1; 403 patches[n] = temp * -1;
505 } 404 }
506 else 405 else
507 { 406 {
508 // Positive 407 // Positive
509 temp = bitpack.UnpackBits((int) header.WordBits); 408 temp = bitpack.UnpackBits((int)header.WordBits);
510 patches[n] = temp; 409 patches[n] = temp;
511 } 410 }
512 } 411 }
@@ -514,7 +413,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
514 { 413 {
515 // Set the rest to zero 414 // Set the rest to zero
516 // TODO: This might not be necessary 415 // TODO: This might not be necessary
517 for (int o = n; o < size*size; o++) 416 for (int o = n; o < size * size; o++)
518 { 417 {
519 patches[o] = 0; 418 patches[o] = 0;
520 } 419 }
@@ -552,7 +451,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
552 { 451 {
553 bool eob = true; 452 bool eob = true;
554 453
555 for (int j = i; j < lastZeroindx ; j++) 454 for (int j = i; j < lastZeroindx; j++)
556 { 455 {
557 if (patch[j] != 0) 456 if (patch[j] != 0)
558 { 457 {
@@ -590,52 +489,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
590 } 489 }
591 } 490 }
592 491
593
594 private static int[] CompressPatch(float[,] patchData, TerrainPatch.Header header, int prequant, out int wbits)
595 {
596 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
597 float oozrange = 1.0f/header.Range;
598 float range = (1 << prequant);
599 float premult = oozrange*range;
600
601 float sub = 0.5f * header.Range + header.DCOffset;
602
603 int wordsize = (prequant - 2) & 0x0f;
604 header.QuantWBits = wordsize;
605 header.QuantWBits |= wordsize << 4;
606
607 int k = 0;
608 for (int j = 0; j < Constants.TerrainPatchSize; j++)
609 {
610 for (int i = 0; i < Constants.TerrainPatchSize; i++)
611 block[k++] = (patchData[j, i] - sub) * premult;
612 }
613
614 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
615 int[] itemp = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
616
617 wbits = (prequant >> 1);
618
619 for (int o = 0; o < Constants.TerrainPatchSize; o++)
620 DCTLine16(block, ftemp, o);
621 for (int o = 0; o < Constants.TerrainPatchSize; o++)
622 wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits);
623
624 return itemp;
625 }
626
627 private static int[] CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header, 492 private static int[] CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header,
628 int prequant, out int wbits) 493 int prequant, out int wbits)
629 { 494 {
630 float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 495 float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
631 496
632 float oozrange = 1.0f/header.Range; 497 float oozrange = 1.0f / header.Range;
633 float invprequat = (1 << prequant); 498 float invprequat = (1 << prequant);
634 float premult = oozrange* invprequat; 499 float premult = oozrange * invprequat;
635 500
636 float sub = 0.5f * header.Range + header.DCOffset; 501 float sub = 0.5f * header.Range + header.DCOffset;
637 502
638 int wordsize = (prequant -2 ) & 0x0f; 503 int wordsize = (prequant - 2) & 0x0f;
639 header.QuantWBits = wordsize; 504 header.QuantWBits = wordsize;
640 header.QuantWBits |= wordsize << 4; 505 header.QuantWBits |= wordsize << 4;
641 506
@@ -653,21 +518,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
653 { 518 {
654 for (int xx = patchX * Constants.TerrainPatchSize; xx < xPatchLimit; xx++) 519 for (int xx = patchX * Constants.TerrainPatchSize; xx < xPatchLimit; xx++)
655 { 520 {
656 block[k++] = (terrData[xx, yy] - sub) * premult; 521 block[k++] = (terrData[xx, yy] - sub) * premult;
657 } 522 }
658 } 523 }
524
659 525
660 float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 526 float[] ftemp = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
661 int[] itemp = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize]; 527 int[] iout = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
662 528
663 wbits = (prequant >> 1); 529 wbits = (prequant >> 1);
664 530
665 for (int o = 0; o < Constants.TerrainPatchSize; o++) 531 dct16x16(block, iout, ref wbits);
666 DCTLine16(block, ftemp, o);
667 for (int o = 0; o < Constants.TerrainPatchSize; o++)
668 wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits);
669 532
670 return itemp; 533 return iout;
671 } 534 }
672 535
673 #region Initialization 536 #region Initialization
@@ -678,32 +541,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
678 { 541 {
679 for (int i = 0; i < Constants.TerrainPatchSize; i++) 542 for (int i = 0; i < Constants.TerrainPatchSize; i++)
680 { 543 {
681 DequantizeTable16[j*Constants.TerrainPatchSize + i] = 1.0f + 2.0f*(i + j); 544 DequantizeTable16[j * Constants.TerrainPatchSize + i] = 1.0f + 2.0f * (i + j);
682 } 545 }
683 } 546 }
684 } 547 }
685 548
686 private static void BuildQuantizeTable16() 549 private static void BuildQuantizeTable16()
687 { 550 {
688 const float oosob = 2.0f/Constants.TerrainPatchSize; 551 const float oosob = 2.0f / Constants.TerrainPatchSize;
689 for (int j = 0; j < Constants.TerrainPatchSize; j++) 552 for (int j = 0; j < Constants.TerrainPatchSize; j++)
690 { 553 {
691 for (int i = 0; i < Constants.TerrainPatchSize; i++) 554 for (int i = 0; i < Constants.TerrainPatchSize; i++)
692 { 555 {
693 QuantizeTable16[j*Constants.TerrainPatchSize + i] = oosob/(1.0f + 2.0f*(i + (float) j)); 556 QuantizeTable16[j * Constants.TerrainPatchSize + i] = oosob / (1.0f + 2.0f * (i + (float)j));
694 } 557 }
695 } 558 }
696 } 559 }
697 560
698 private static void SetupCosines16() 561 private static void SetupCosines16()
699 { 562 {
700 const float hposz = (float) Math.PI*0.5f/Constants.TerrainPatchSize; 563 const float hposz = (float)Math.PI * 0.5f / Constants.TerrainPatchSize;
701 564
702 for (int u = 0; u < Constants.TerrainPatchSize; u++) 565 for (int u = 0; u < Constants.TerrainPatchSize; u++)
703 { 566 {
704 for (int n = 0; n < Constants.TerrainPatchSize; n++) 567 for (int n = 0; n < Constants.TerrainPatchSize; n++)
705 { 568 {
706 CosineTable16[u*Constants.TerrainPatchSize + n] = (float) Math.Cos((2.0f*n + 1.0f)*u*hposz); 569 CosineTable16[u * Constants.TerrainPatchSize + n] = (float)Math.Cos((2.0f * n + 1.0f) * u * hposz);
707 } 570 }
708 } 571 }
709 } 572 }
@@ -718,7 +581,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
718 581
719 while (i < Constants.TerrainPatchSize && j < Constants.TerrainPatchSize) 582 while (i < Constants.TerrainPatchSize && j < Constants.TerrainPatchSize)
720 { 583 {
721 CopyMatrix16[j*Constants.TerrainPatchSize + i] = count++; 584 CopyMatrix16[j * Constants.TerrainPatchSize + i] = count++;
722 585
723 if (!diag) 586 if (!diag)
724 { 587 {
@@ -758,5 +621,714 @@ namespace OpenSim.Region.ClientStack.LindenUDP
758 } 621 }
759 622
760 #endregion Initialization 623 #endregion Initialization
624
625 #region DCT
626 /* DCT (Discrete Cosine Transform)
627 adaptation from
628 General Purpose 2D,3D FFT (Fast Fourier Transform) Package
629 by Takuya OOURA (email: ooura@kurims.kyoto-u.ac.jp)
630
631 -------- 16x16 DCT (Discrete Cosine Transform) / Inverse of DCT --------
632 [definition]
633 <case1> Normalized 16x16 IDCT
634 C[k1 + k2] = (1/8) * sum_j1=0^15 sum_j2=0^15
635 tmp[j1 + j2] * s[j1] * s[j2] *
636 cos(pi*j1*(k1+1/2)/16) *
637 cos(pi*j2*(k2+1/2)/16), 0<=k1<16, 0<=k2<16
638 (s[0] = 1/sqrt(2), s[j] = 1, j > 0)
639 <case2> Normalized 16x16 DCT
640 C[k1 + k2] = (1/8) * s[k1] * s[k2] * sum_j1=0^15 sum_j2=0^15
641 tmp[j1 + j2] *
642 cos(pi*(j1+1/2)*k1/16) *
643 cos(pi*(j2+1/2)*k2/16), 0<=k1<16, 0<=k2<16
644 (s[0] = 1/sqrt(2), s[j] = 1, j > 0)
645 */
646
647 /* Cn_kR = sqrt(2.0/n) * cos(pi/2*k/n) */
648 /* Cn_kI = sqrt(2.0/n) * sin(pi/2*k/n) */
649 /* Wn_kR = cos(pi/2*k/n) */
650 /* Wn_kI = sin(pi/2*k/n) */
651
652 const float C16_1R = 0.35185093438159561476f * 2.82842712474619f;
653 const float C16_1I = 0.03465429229977286565f * 2.82842712474619f;
654 const float C16_2R = 0.34675996133053686546f * 2.82842712474619f;
655 const float C16_2I = 0.06897484482073575308f * 2.82842712474619f;
656 const float C16_3R = 0.33832950029358816957f * 2.82842712474619f;
657 const float C16_3I = 0.10263113188058934529f * 2.82842712474619f;
658 const float C16_4R = 0.32664074121909413196f * 2.82842712474619f;
659 const float C16_4I = 0.13529902503654924610f * 2.82842712474619f;
660 const float C16_5R = 0.31180625324666780814f * 2.82842712474619f;
661 const float C16_5I = 0.16666391461943662432f * 2.82842712474619f;
662 const float C16_6R = 0.29396890060483967924f * 2.82842712474619f;
663 const float C16_6I = 0.19642373959677554532f * 2.82842712474619f;
664 const float C16_7R = 0.27330046675043937206f * 2.82842712474619f;
665 const float C16_7I = 0.22429189658565907106f * 2.82842712474619f;
666 const float C16_8R = 0.25f * 2.82842712474619f;
667 const float W16_4R = 0.92387953251128675613f;
668 const float W16_4I = 0.38268343236508977173f;
669 const float W16_8R = 0.70710678118654752440f;
670
671 static void dct16x16(float[] a, int[] iout, ref int wbits)
672 {
673 float[] tmp = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
674
675 float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
676 float x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i;
677 float xr, xi;
678 float ftmp;
679
680 int itmp;
681 int j, k;
682 int indx;
683
684 const int maxwbits = 17; // per header encoding
685 bool dowbits = wbits < 17;
686 int wbitsMaxValue = 1 << wbits;
687
688 int fullSize = Constants.TerrainPatchSize * Constants.TerrainPatchSize;
689
690 for (j = 0, k = 0; j < fullSize; j += Constants.TerrainPatchSize, k++)
691 {
692 x4r = a[0 + j] - a[15 + j];
693 xr = a[0 + j] + a[15 + j];
694 x4i = a[8 + j] - a[7 + j];
695 xi = a[8 + j] + a[7 + j];
696 x0r = xr + xi;
697 x0i = xr - xi;
698 x5r = a[2 + j] - a[13 + j];
699 xr = a[2 + j] + a[13 + j];
700 x5i = a[10 + j] - a[5 + j];
701 xi = a[10 + j] + a[5 + j];
702 x1r = xr + xi;
703 x1i = xr - xi;
704 x6r = a[4 + j] - a[11 + j];
705 xr = a[4 + j] + a[11 + j];
706 x6i = a[12 + j] - a[3 + j];
707 xi = a[12 + j] + a[3 + j];
708 x2r = xr + xi;
709 x2i = xr - xi;
710 x7r = a[6 + j] - a[9 + j];
711 xr = a[6 + j] + a[9 + j];
712 x7i = a[14 + j] - a[1 + j];
713 xi = a[14 + j] + a[1 + j];
714 x3r = xr + xi;
715 x3i = xr - xi;
716 xr = x0r + x2r;
717 xi = x1r + x3r;
718 tmp[k] = C16_8R * (xr + xi); //
719 tmp[8 * Constants.TerrainPatchSize + k] = C16_8R * (xr - xi); //
720 xr = x0r - x2r;
721 xi = x1r - x3r;
722 tmp[4 * Constants.TerrainPatchSize + k] = C16_4R * xr - C16_4I * xi; //
723 tmp[12 * Constants.TerrainPatchSize + k] = C16_4R * xi + C16_4I * xr; //
724 x0r = W16_8R * (x1i - x3i);
725 x2r = W16_8R * (x1i + x3i);
726 xr = x0i + x0r;
727 xi = x2r + x2i;
728 tmp[2 * Constants.TerrainPatchSize + k] = C16_2R * xr - C16_2I * xi; //
729 tmp[14 * Constants.TerrainPatchSize + k] = C16_2R * xi + C16_2I * xr; //
730 xr = x0i - x0r;
731 xi = x2r - x2i;
732 tmp[6 * Constants.TerrainPatchSize + k] = C16_6R * xr - C16_6I * xi; //
733 tmp[10 * Constants.TerrainPatchSize + k] = C16_6R * xi + C16_6I * xr; //
734 xr = W16_8R * (x6r - x6i);
735 xi = W16_8R * (x6i + x6r);
736 x6r = x4r - xr;
737 x6i = x4i - xi;
738 x4r += xr;
739 x4i += xi;
740 xr = W16_4I * x7r - W16_4R * x7i;
741 xi = W16_4I * x7i + W16_4R * x7r;
742 x7r = W16_4R * x5r - W16_4I * x5i;
743 x7i = W16_4R * x5i + W16_4I * x5r;
744 x5r = x7r + xr;
745 x5i = x7i + xi;
746 x7r -= xr;
747 x7i -= xi;
748 xr = x4r + x5r;
749 xi = x5i + x4i;
750 tmp[Constants.TerrainPatchSize + k] = C16_1R * xr - C16_1I * xi; //
751 tmp[15 * Constants.TerrainPatchSize + k] = C16_1R * xi + C16_1I * xr; //
752 xr = x4r - x5r;
753 xi = x5i - x4i;
754 tmp[7 * Constants.TerrainPatchSize + k] = C16_7R * xr - C16_7I * xi; //
755 tmp[9 * Constants.TerrainPatchSize + k] = C16_7R * xi + C16_7I * xr; //
756 xr = x6r - x7i;
757 xi = x7r + x6i;
758 tmp[5 * Constants.TerrainPatchSize + k] = C16_5R * xr - C16_5I * xi; //
759 tmp[11 * Constants.TerrainPatchSize + k] = C16_5R * xi + C16_5I * xr; //
760 xr = x6r + x7i;
761 xi = x7r - x6i;
762 tmp[3 * Constants.TerrainPatchSize + k] = C16_3R * xr - C16_3I * xi; //
763 tmp[13 * Constants.TerrainPatchSize + k] = C16_3R * xi + C16_3I * xr; //
764 }
765
766 for (j = 0, k = 0; j < fullSize; j += Constants.TerrainPatchSize, k++)
767 {
768 x4r = tmp[0 + j] - tmp[15 + j];
769 xr = tmp[0 + j] + tmp[15 + j];
770 x4i = tmp[8 + j] - tmp[7 + j];
771 xi = tmp[8 + j] + tmp[7 + j];
772 x0r = xr + xi;
773 x0i = xr - xi;
774 x5r = tmp[2 + j] - tmp[13 + j];
775 xr = tmp[2 + j] + tmp[13 + j];
776 x5i = tmp[10 + j] - tmp[5 + j];
777 xi = tmp[10 + j] + tmp[5 + j];
778 x1r = xr + xi;
779 x1i = xr - xi;
780 x6r = tmp[4 + j] - tmp[11 + j];
781 xr = tmp[4 + j] + tmp[11 + j];
782 x6i = tmp[12 + j] - tmp[3 + j];
783 xi = tmp[12 + j] + tmp[3 + j];
784 x2r = xr + xi;
785 x2i = xr - xi;
786 x7r = tmp[6 + j] - tmp[9 + j];
787 xr = tmp[6 + j] + tmp[9 + j];
788 x7i = tmp[14 + j] - tmp[1 + j];
789 xi = tmp[14 + j] + tmp[1 + j];
790 x3r = xr + xi;
791 x3i = xr - xi;
792 xr = x0r + x2r;
793 xi = x1r + x3r;
794
795 //tmp[0 + k] = C16_8R * (xr + xi); //
796 ftmp = C16_8R * (xr + xi);
797 itmp = (int)(ftmp * QuantizeTable16[k]);
798 iout[CopyMatrix16[k]] = itmp;
799
800 if (dowbits)
801 {
802 if (itmp < 0) itmp *= -1;
803 while (itmp > wbitsMaxValue)
804 {
805 wbits++;
806 wbitsMaxValue = 1 << wbits;
807 if (wbits == maxwbits)
808 {
809 dowbits = false;
810 break;
811 }
812 }
813 }
814
815 //tmp[8 * Constants.TerrainPatchSize + k] = C16_8R * (xr - xi); //
816 ftmp = C16_8R * (xr - xi);
817 indx = 8 * Constants.TerrainPatchSize + k;
818 itmp = (int)(ftmp * QuantizeTable16[indx]);
819 iout[CopyMatrix16[indx]] = itmp;
820
821 if (dowbits)
822 {
823 if (itmp < 0) itmp *= -1;
824 while (itmp > wbitsMaxValue)
825 {
826 wbits++;
827 wbitsMaxValue = 1 << wbits;
828 if (wbits == maxwbits)
829 {
830 dowbits = false;
831 break;
832 }
833 }
834 }
835
836 xr = x0r - x2r;
837 xi = x1r - x3r;
838
839 //tmp[4 * Constants.TerrainPatchSize + k] = C16_4R * xr - C16_4I * xi; //
840 ftmp = C16_4R * xr - C16_4I * xi;
841 indx = 4 * Constants.TerrainPatchSize + k;
842 itmp = (int)(ftmp * QuantizeTable16[indx]);
843 iout[CopyMatrix16[indx]] = itmp;
844
845 if (dowbits)
846 {
847 if (itmp < 0) itmp *= -1;
848 while (itmp > wbitsMaxValue)
849 {
850 wbits++;
851 wbitsMaxValue = 1 << wbits;
852 if (wbits == maxwbits)
853 {
854 dowbits = false;
855 break;
856 }
857 }
858 }
859
860 //tmp[12 * Constants.TerrainPatchSize + k] = C16_4R * xi + C16_4I * xr; //
861 ftmp = C16_4R * xi + C16_4I * xr;
862 indx = 12 * Constants.TerrainPatchSize + k;
863 itmp = (int)(ftmp * QuantizeTable16[indx]);
864 iout[CopyMatrix16[indx]] = itmp;
865
866 if (dowbits)
867 {
868 if (itmp < 0) itmp *= -1;
869 while (itmp > wbitsMaxValue)
870 {
871 wbits++;
872 wbitsMaxValue = 1 << wbits;
873 if (wbits == maxwbits)
874 {
875 dowbits = false;
876 break;
877 }
878 }
879 }
880
881 x0r = W16_8R * (x1i - x3i);
882 x2r = W16_8R * (x1i + x3i);
883 xr = x0i + x0r;
884 xi = x2r + x2i;
885
886 //tmp[2 * Constants.TerrainPatchSize + k] = C16_2R * xr - C16_2I * xi; //
887 ftmp = C16_2R * xr - C16_2I * xi;
888 indx = 2 * Constants.TerrainPatchSize + k;
889 itmp = (int)(ftmp * QuantizeTable16[indx]);
890 iout[CopyMatrix16[indx]] = itmp;
891
892 if (dowbits)
893 {
894 if (itmp < 0) itmp *= -1;
895 while (itmp > wbitsMaxValue)
896 {
897 wbits++;
898 wbitsMaxValue = 1 << wbits;
899 if (wbits == maxwbits)
900 {
901 dowbits = false;
902 break;
903 }
904 }
905 }
906
907 //tmp[14 * Constants.TerrainPatchSize + k] = C16_2R * xi + C16_2I * xr; //
908 ftmp = C16_2R * xi + C16_2I * xr;
909 indx = 14 * Constants.TerrainPatchSize + k;
910 itmp = (int)(ftmp * QuantizeTable16[indx]);
911 iout[CopyMatrix16[indx]] = itmp;
912
913 if (dowbits)
914 {
915 if (itmp < 0) itmp *= -1;
916 while (itmp > wbitsMaxValue)
917 {
918 wbits++;
919 wbitsMaxValue = 1 << wbits;
920 if (wbits == maxwbits)
921 {
922 dowbits = false;
923 break;
924 }
925 }
926 }
927
928 xr = x0i - x0r;
929 xi = x2r - x2i;
930
931 //tmp[6 * Constants.TerrainPatchSize + k] = C16_6R * xr - C16_6I * xi; //
932 ftmp = C16_6R * xr - C16_6I * xi;
933 indx = 6 * Constants.TerrainPatchSize + k;
934 itmp = (int)(ftmp * QuantizeTable16[indx]);
935 iout[CopyMatrix16[indx]] = itmp;
936
937 if (dowbits)
938 {
939 if (itmp < 0) itmp *= -1;
940 while (itmp > wbitsMaxValue)
941 {
942 wbits++;
943 wbitsMaxValue = 1 << wbits;
944 if (wbits == maxwbits)
945 {
946 dowbits = false;
947 break;
948 }
949 }
950 }
951
952 //tmp[10 * Constants.TerrainPatchSize + k] = C16_6R * xi + C16_6I * xr; //
953 ftmp = C16_6R * xi + C16_6I * xr;
954 indx = 10 * Constants.TerrainPatchSize + k;
955 itmp = (int)(ftmp * QuantizeTable16[indx]);
956 iout[CopyMatrix16[indx]] = itmp;
957
958 if (dowbits)
959 {
960 if (itmp < 0) itmp *= -1;
961 while (itmp > wbitsMaxValue)
962 {
963 wbits++;
964 wbitsMaxValue = 1 << wbits;
965 if (wbits == maxwbits)
966 {
967 dowbits = false;
968 break;
969 }
970 }
971 }
972
973 xr = W16_8R * (x6r - x6i);
974 xi = W16_8R * (x6i + x6r);
975 x6r = x4r - xr;
976 x6i = x4i - xi;
977 x4r += xr;
978 x4i += xi;
979 xr = W16_4I * x7r - W16_4R * x7i;
980 xi = W16_4I * x7i + W16_4R * x7r;
981 x7r = W16_4R * x5r - W16_4I * x5i;
982 x7i = W16_4R * x5i + W16_4I * x5r;
983 x5r = x7r + xr;
984 x5i = x7i + xi;
985 x7r -= xr;
986 x7i -= xi;
987 xr = x4r + x5r;
988 xi = x5i + x4i;
989
990 //tmp[1 * Constants.TerrainPatchSize + k] = C16_1R * xr - C16_1I * xi; //
991 ftmp = C16_1R * xr - C16_1I * xi;
992 indx = Constants.TerrainPatchSize + k;
993 itmp = (int)(ftmp * QuantizeTable16[indx]);
994 iout[CopyMatrix16[indx]] = itmp;
995
996 if (dowbits)
997 {
998 if (itmp < 0) itmp *= -1;
999 while (itmp > wbitsMaxValue)
1000 {
1001 wbits++;
1002 wbitsMaxValue = 1 << wbits;
1003 if (wbits == maxwbits)
1004 {
1005 dowbits = false;
1006 break;
1007 }
1008 }
1009 }
1010
1011 //tmp[15 * Constants.TerrainPatchSize + k] = C16_1R * xi + C16_1I * xr; //
1012 ftmp = C16_1R * xi + C16_1I * xr;
1013 indx = 15 * Constants.TerrainPatchSize + k;
1014 itmp = (int)(ftmp * QuantizeTable16[indx]);
1015 iout[CopyMatrix16[indx]] = itmp;
1016
1017 if (dowbits)
1018 {
1019 if (itmp < 0) itmp *= -1;
1020 while (itmp > wbitsMaxValue)
1021 {
1022 wbits++;
1023 wbitsMaxValue = 1 << wbits;
1024 if (wbits == maxwbits)
1025 {
1026 dowbits = false;
1027 break;
1028 }
1029 }
1030 }
1031
1032 xr = x4r - x5r;
1033 xi = x5i - x4i;
1034
1035 //tmp[7 * Constants.TerrainPatchSize + k] = C16_7R * xr - C16_7I * xi; //
1036 ftmp = C16_7R * xr - C16_7I * xi;
1037 indx = 7 * Constants.TerrainPatchSize + k;
1038 itmp = (int)(ftmp * QuantizeTable16[indx]);
1039 iout[CopyMatrix16[indx]] = itmp;
1040
1041 if (dowbits)
1042 {
1043 if (itmp < 0) itmp *= -1;
1044 while (itmp > wbitsMaxValue)
1045 {
1046 wbits++;
1047 wbitsMaxValue = 1 << wbits;
1048 if (wbits == maxwbits)
1049 {
1050 dowbits = false;
1051 break;
1052 }
1053 }
1054 }
1055
1056 //tmp[9 * Constants.TerrainPatchSize + k] = C16_7R * xi + C16_7I * xr; //
1057 ftmp = C16_7R * xi + C16_7I * xr;
1058 indx = 9 * Constants.TerrainPatchSize + k;
1059 itmp = (int)(ftmp * QuantizeTable16[indx]);
1060 iout[CopyMatrix16[indx]] = itmp;
1061
1062 if (dowbits)
1063 {
1064 if (itmp < 0) itmp *= -1;
1065 while (itmp > wbitsMaxValue)
1066 {
1067 wbits++;
1068 wbitsMaxValue = 1 << wbits;
1069 if (wbits == maxwbits)
1070 {
1071 dowbits = false;
1072 break;
1073 }
1074 }
1075 }
1076
1077 xr = x6r - x7i;
1078 xi = x7r + x6i;
1079
1080 //tmp[5 * Constants.TerrainPatchSize + k] = C16_5R * xr - C16_5I * xi; //
1081 ftmp = C16_5R * xr - C16_5I * xi;
1082 indx = 5 * Constants.TerrainPatchSize + k;
1083 itmp = (int)(ftmp * QuantizeTable16[indx]);
1084 iout[CopyMatrix16[indx]] = itmp;
1085
1086 if (dowbits)
1087 {
1088 if (itmp < 0) itmp *= -1;
1089 while (itmp > wbitsMaxValue)
1090 {
1091 wbits++;
1092 wbitsMaxValue = 1 << wbits;
1093 if (wbits == maxwbits)
1094 {
1095 dowbits = false;
1096 break;
1097 }
1098 }
1099 }
1100
1101 //tmp[11 * Constants.TerrainPatchSize + k] = C16_5R * xi + C16_5I * xr; //
1102 ftmp = C16_5R * xi + C16_5I * xr;
1103 indx = 11 * Constants.TerrainPatchSize + k;
1104 itmp = (int)(ftmp * QuantizeTable16[indx]);
1105 iout[CopyMatrix16[indx]] = itmp;
1106
1107 if (dowbits)
1108 {
1109 if (itmp < 0) itmp *= -1;
1110 while (itmp > wbitsMaxValue)
1111 {
1112 wbits++;
1113 wbitsMaxValue = 1 << wbits;
1114 if (wbits == maxwbits)
1115 {
1116 dowbits = false;
1117 break;
1118 }
1119 }
1120 }
1121
1122 xr = x6r + x7i;
1123 xi = x7r - x6i;
1124
1125 //tmp[3 * Constants.TerrainPatchSize + k] = C16_3R * xr - C16_3I * xi; //
1126 ftmp = C16_3R * xr - C16_3I * xi;
1127 indx = 3 * Constants.TerrainPatchSize + k;
1128 itmp = (int)(ftmp * QuantizeTable16[indx]);
1129 iout[CopyMatrix16[indx]] = itmp;
1130
1131 if (dowbits)
1132 {
1133 if (itmp < 0) itmp *= -1;
1134 while (itmp > wbitsMaxValue)
1135 {
1136 wbits++;
1137 wbitsMaxValue = 1 << wbits;
1138 if (wbits == maxwbits)
1139 {
1140 dowbits = false;
1141 break;
1142 }
1143 }
1144 }
1145
1146 //tmp[13 * Constants.TerrainPatchSize + k] = C16_3R * xi + C16_3I * xr; //
1147 ftmp = C16_3R * xi + C16_3I * xr;
1148 indx = 13 * Constants.TerrainPatchSize + k;
1149 itmp = (int)(ftmp * QuantizeTable16[indx]);
1150 iout[CopyMatrix16[indx]] = itmp;
1151
1152 if (dowbits)
1153 {
1154 if (itmp < 0) itmp *= -1;
1155 while (itmp > wbitsMaxValue)
1156 {
1157 wbits++;
1158 wbitsMaxValue = 1 << wbits;
1159 if (wbits == maxwbits)
1160 {
1161 dowbits = false;
1162 break;
1163 }
1164 }
1165 }
1166 }
1167 }
1168
1169 /* not in use, and still not fixed
1170 static void idct16x16(float[] a)
1171 {
1172 int j;
1173 float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
1174 float x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i;
1175 float xr, xi;
1176
1177 int fullSize = Constants.TerrainPatchSize * Constants.TerrainPatchSize;
1178
1179 for (j = 0; j < fullSize; j += Constants.TerrainPatchSize)
1180 {
1181 x5r = C16_1R * tmp[1 + j] + C16_1I * tmp[15 + j];
1182 x5i = C16_1R * tmp[15 + j] - C16_1I * tmp[1 + j];
1183 xr = C16_7R * tmp[7 + j] + C16_7I * tmp[9 + j];
1184 xi = C16_7R * tmp[9 + j] - C16_7I * tmp[7 + j];
1185 x4r = x5r + xr;
1186 x4i = x5i - xi;
1187 x5r -= xr;
1188 x5i += xi;
1189 x7r = C16_5R * tmp[5 + j] + C16_5I * tmp[11 + j];
1190 x7i = C16_5R * tmp[11 + j] - C16_5I * tmp[5 + j];
1191 xr = C16_3R * tmp[3 + j] + C16_3I * tmp[13 + j];
1192 xi = C16_3R * tmp[13 + j] - C16_3I * tmp[3 + j];
1193 x6r = x7r + xr;
1194 x6i = x7i - xi;
1195 x7r -= xr;
1196 x7i += xi;
1197 xr = x4r - x6r;
1198 xi = x4i - x6i;
1199 x4r += x6r;
1200 x4i += x6i;
1201 x6r = W16_8R * (xi + xr);
1202 x6i = W16_8R * (xi - xr);
1203 xr = x5r + x7i;
1204 xi = x5i - x7r;
1205 x5r -= x7i;
1206 x5i += x7r;
1207 x7r = W16_4I * x5r + W16_4R * x5i;
1208 x7i = W16_4I * x5i - W16_4R * x5r;
1209 x5r = W16_4R * xr + W16_4I * xi;
1210 x5i = W16_4R * xi - W16_4I * xr;
1211 xr = C16_4R * tmp[4 + j] + C16_4I * tmp[12 + j];
1212 xi = C16_4R * tmp[12 + j] - C16_4I * tmp[4 + j];
1213 x2r = C16_8R * (tmp[0 + j] + tmp[8 + j]);
1214 x3r = C16_8R * (tmp[0 + j] - tmp[8 + j]);
1215 x0r = x2r + xr;
1216 x1r = x3r + xi;
1217 x2r -= xr;
1218 x3r -= xi;
1219 x0i = C16_2R * tmp[2 + j] + C16_2I * tmp[14 + j];
1220 x2i = C16_2R * tmp[14 + j] - C16_2I * tmp[2 + j];
1221 x1i = C16_6R * tmp[6 + j] + C16_6I * tmp[10 + j];
1222 x3i = C16_6R * tmp[10 + j] - C16_6I * tmp[6 + j];
1223 xr = x0i - x1i;
1224 xi = x2i + x3i;
1225 x0i += x1i;
1226 x2i -= x3i;
1227 x1i = W16_8R * (xi + xr);
1228 x3i = W16_8R * (xi - xr);
1229 xr = x0r + x0i;
1230 xi = x0r - x0i;
1231 tmp[0 + j] = xr + x4r;
1232 tmp[15 + j] = xr - x4r;
1233 tmp[8 + j] = xi + x4i;
1234 tmp[7 + j] = xi - x4i;
1235 xr = x1r + x1i;
1236 xi = x1r - x1i;
1237 tmp[2 + j] = xr + x5r;
1238 tmp[13 + j] = xr - x5r;
1239 tmp[10 + j] = xi + x5i;
1240 tmp[5 + j] = xi - x5i;
1241 xr = x2r + x2i;
1242 xi = x2r - x2i;
1243 tmp[4 + j] = xr + x6r;
1244 tmp[11 + j] = xr - x6r;
1245 tmp[12 + j] = xi + x6i;
1246 tmp[3 + j] = xi - x6i;
1247 xr = x3r + x3i;
1248 xi = x3r - x3i;
1249 tmp[6 + j] = xr + x7r;
1250 tmp[9 + j] = xr - x7r;
1251 tmp[14 + j] = xi + x7i;
1252 tmp[1 + j] = xi - x7i;
1253 }
1254 for (j = 0; j < fullSize; j += Constants.TerrainPatchSize)
1255 {
1256 x5r = C16_1R * tmp[j + 1] + C16_1I * tmp[j + 15];
1257 x5i = C16_1R * tmp[j + 15] - C16_1I * tmp[j + 1];
1258 xr = C16_7R * tmp[j + 7] + C16_7I * tmp[j + 9];
1259 xi = C16_7R * tmp[j + 9] - C16_7I * tmp[j + 7];
1260 x4r = x5r + xr;
1261 x4i = x5i - xi;
1262 x5r -= xr;
1263 x5i += xi;
1264 x7r = C16_5R * tmp[j + 5] + C16_5I * tmp[j + 11];
1265 x7i = C16_5R * tmp[j + 11] - C16_5I * tmp[j + 5];
1266 xr = C16_3R * tmp[j + 3] + C16_3I * tmp[j + 13];
1267 xi = C16_3R * tmp[j + 13] - C16_3I * tmp[j + 3];
1268 x6r = x7r + xr;
1269 x6i = x7i - xi;
1270 x7r -= xr;
1271 x7i += xi;
1272 xr = x4r - x6r;
1273 xi = x4i - x6i;
1274 x4r += x6r;
1275 x4i += x6i;
1276 x6r = W16_8R * (xi + xr);
1277 x6i = W16_8R * (xi - xr);
1278 xr = x5r + x7i;
1279 xi = x5i - x7r;
1280 x5r -= x7i;
1281 x5i += x7r;
1282 x7r = W16_4I * x5r + W16_4R * x5i;
1283 x7i = W16_4I * x5i - W16_4R * x5r;
1284 x5r = W16_4R * xr + W16_4I * xi;
1285 x5i = W16_4R * xi - W16_4I * xr;
1286 xr = C16_4R * tmp[j + 4] + C16_4I * tmp[j + 12];
1287 xi = C16_4R * tmp[j + 12] - C16_4I * tmp[j + 4];
1288 x2r = C16_8R * (tmp[j + 0] + tmp[j + 8]);
1289 x3r = C16_8R * (tmp[j + 0] - tmp[j + 8]);
1290 x0r = x2r + xr;
1291 x1r = x3r + xi;
1292 x2r -= xr;
1293 x3r -= xi;
1294 x0i = C16_2R * tmp[j + 2] + C16_2I * tmp[j + 14];
1295 x2i = C16_2R * tmp[j + 14] - C16_2I * tmp[j + 2];
1296 x1i = C16_6R * tmp[j + 6] + C16_6I * tmp[j + 10];
1297 x3i = C16_6R * tmp[j + 10] - C16_6I * tmp[j + 6];
1298 xr = x0i - x1i;
1299 xi = x2i + x3i;
1300 x0i += x1i;
1301 x2i -= x3i;
1302 x1i = W16_8R * (xi + xr);
1303 x3i = W16_8R * (xi - xr);
1304 xr = x0r + x0i;
1305 xi = x0r - x0i;
1306 tmp[j + 0] = xr + x4r;
1307 tmp[j + 15] = xr - x4r;
1308 tmp[j + 8] = xi + x4i;
1309 tmp[j + 7] = xi - x4i;
1310 xr = x1r + x1i;
1311 xi = x1r - x1i;
1312 tmp[j + 2] = xr + x5r;
1313 tmp[j + 13] = xr - x5r;
1314 tmp[j + 10] = xi + x5i;
1315 tmp[j + 5] = xi - x5i;
1316 xr = x2r + x2i;
1317 xi = x2r - x2i;
1318 tmp[j + 4] = xr + x6r;
1319 tmp[j + 11] = xr - x6r;
1320 tmp[j + 12] = xi + x6i;
1321 tmp[j + 3] = xi - x6i;
1322 xr = x3r + x3i;
1323 xi = x3r - x3i;
1324 tmp[j + 6] = xr + x7r;
1325 tmp[j + 9] = xr - x7r;
1326 tmp[j + 14] = xi + x7i;
1327 tmp[j + 1] = xi - x7i;
1328 }
1329 }
1330 */
1331 #endregion DCT
761 } 1332 }
1333
762} 1334}