diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/TerrainCompressor.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/TerrainCompressor.cs | 942 |
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 @@ | |||
33 | using System; | 33 | using System; |
34 | using System.Collections.Generic; | 34 | using System.Collections.Generic; |
35 | using System.Reflection; | 35 | using System.Reflection; |
36 | using System.Diagnostics; | ||
36 | 37 | ||
37 | using log4net; | 38 | using 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 | } |