diff options
author | UbitUmarov | 2015-09-25 17:41:50 +0100 |
---|---|---|
committer | UbitUmarov | 2015-09-25 17:41:50 +0100 |
commit | e6f675b81b73804b625efd2bdc98a9841a607729 (patch) | |
tree | a656e8a6cb86b95c6d3cf27f7e57706cf41531ff /OpenSim/Region/Framework/Scenes/TerrainCompressor.cs | |
parent | add butterflies to terrain (diff) | |
download | opensim-SC_OLD-e6f675b81b73804b625efd2bdc98a9841a607729.zip opensim-SC_OLD-e6f675b81b73804b625efd2bdc98a9841a607729.tar.gz opensim-SC_OLD-e6f675b81b73804b625efd2bdc98a9841a607729.tar.bz2 opensim-SC_OLD-e6f675b81b73804b625efd2bdc98a9841a607729.tar.xz |
rearrange source code
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/TerrainCompressor.cs | 617 |
1 files changed, 304 insertions, 313 deletions
diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs index 32fd263..e744202 100644 --- a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs +++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs | |||
@@ -65,7 +65,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
65 | private const int NEGATIVE_VALUE = 0x7; | 65 | private const int NEGATIVE_VALUE = 0x7; |
66 | 66 | ||
67 | 67 | ||
68 | private static readonly float[] CosineTable16 = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; | 68 | // private static readonly float[] CosineTable16 = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; |
69 | private static readonly int[] CopyMatrix16 = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; | 69 | private static readonly int[] CopyMatrix16 = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; |
70 | 70 | ||
71 | private static readonly float[] QuantizeTable16 = | 71 | private static readonly float[] QuantizeTable16 = |
@@ -77,7 +77,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
77 | { | 77 | { |
78 | // Initialize the decompression tables | 78 | // Initialize the decompression tables |
79 | BuildDequantizeTable16(); | 79 | BuildDequantizeTable16(); |
80 | SetupCosines16(); | 80 | // SetupCosines16(); |
81 | BuildCopyMatrix16(); | 81 | BuildCopyMatrix16(); |
82 | BuildQuantizeTable16(); | 82 | BuildQuantizeTable16(); |
83 | } | 83 | } |
@@ -140,6 +140,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
140 | 140 | ||
141 | return header; | 141 | return header; |
142 | } | 142 | } |
143 | |||
143 | private static int[] CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant, out int wbits) | 144 | private static int[] CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant, out int wbits) |
144 | { | 145 | { |
145 | float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; | 146 | float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; |
@@ -189,7 +190,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
189 | 190 | ||
190 | for (int i = 0; i < x.Length; i++) | 191 | for (int i = 0; i < x.Length; i++) |
191 | { | 192 | { |
192 | CreatePatchFromHeightmap(bitpack, terrData, x[i], y[i]); | 193 | CreatePatchFromTerrainData(bitpack, terrData, x[i], y[i]); |
193 | if (bitpack.BytePos > 1000 && i != x.Length - 1) | 194 | if (bitpack.BytePos > 1000 && i != x.Length - 1) |
194 | { | 195 | { |
195 | //finish this packet | 196 | //finish this packet |
@@ -219,22 +220,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
219 | return ret; | 220 | return ret; |
220 | } | 221 | } |
221 | 222 | ||
222 | /// <summary> | 223 | public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY) |
223 | /// Add a patch of terrain to a BitPacker | ||
224 | /// </summary> | ||
225 | /// <param name="output">BitPacker to write the patch to</param> | ||
226 | /// <param name="heightmap"> | ||
227 | /// Heightmap of the simulator. Presumed to be an sizeX*sizeY array. | ||
228 | /// </param> | ||
229 | /// <param name="patchX"> | ||
230 | /// X offset of the patch to create. | ||
231 | /// </param> | ||
232 | /// <param name="patchY"> | ||
233 | /// Y offset of the patch to create. | ||
234 | /// </param> | ||
235 | /// <param name="pRegionSizeX"></param> | ||
236 | /// <param name="pRegionSizeY"></param> | ||
237 | public static void CreatePatchFromHeightmap(BitPack output, TerrainData terrData, int patchX, int patchY) | ||
238 | { | 224 | { |
239 | float frange; | 225 | float frange; |
240 | TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY, out frange); | 226 | TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY, out frange); |
@@ -284,8 +270,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
284 | private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY, out float frange) | 270 | private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY, out float frange) |
285 | { | 271 | { |
286 | TerrainPatch.Header header = new TerrainPatch.Header(); | 272 | TerrainPatch.Header header = new TerrainPatch.Header(); |
287 | float zmax = -99999999.0f; | 273 | float zmax = float.MinValue; |
288 | float zmin = 99999999.0f; | 274 | float zmin = float.MaxValue; |
275 | |||
289 | int startx = patchX * Constants.TerrainPatchSize; | 276 | int startx = patchX * Constants.TerrainPatchSize; |
290 | int starty = patchY * Constants.TerrainPatchSize; | 277 | int starty = patchY * Constants.TerrainPatchSize; |
291 | 278 | ||
@@ -306,29 +293,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
306 | return header; | 293 | return header; |
307 | } | 294 | } |
308 | 295 | ||
309 | public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack) | ||
310 | { | ||
311 | TerrainPatch.Header header = new TerrainPatch.Header { QuantWBits = bitpack.UnpackBits(8) }; | ||
312 | |||
313 | // Quantized word bits | ||
314 | if (header.QuantWBits == END_OF_PATCHES) | ||
315 | return header; | ||
316 | |||
317 | // DC offset | ||
318 | header.DCOffset = bitpack.UnpackFloat(); | ||
319 | |||
320 | // Range | ||
321 | header.Range = bitpack.UnpackBits(16); | ||
322 | |||
323 | // Patch IDs (10 bits) | ||
324 | header.PatchIDs = bitpack.UnpackBits(10); | ||
325 | |||
326 | // Word bits | ||
327 | header.WordBits = (uint)((header.QuantWBits & 0x0f) + 2); | ||
328 | |||
329 | return header; | ||
330 | } | ||
331 | |||
332 | private static void EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, bool largeRegion, ref int wbits) | 296 | private static void EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, bool largeRegion, ref int wbits) |
333 | { | 297 | { |
334 | if (wbits > 17) | 298 | if (wbits > 17) |
@@ -348,85 +312,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
348 | output.PackBits(header.PatchIDs, 10); | 312 | output.PackBits(header.PatchIDs, 10); |
349 | } | 313 | } |
350 | 314 | ||
351 | private static void IDCTColumn16(float[] linein, float[] lineout, int column) | ||
352 | { | ||
353 | for (int n = 0; n < Constants.TerrainPatchSize; n++) | ||
354 | { | ||
355 | float total = OO_SQRT2 * linein[column]; | ||
356 | |||
357 | for (int u = 1; u < Constants.TerrainPatchSize; u++) | ||
358 | { | ||
359 | int usize = u * Constants.TerrainPatchSize; | ||
360 | total += linein[usize + column] * CosineTable16[usize + n]; | ||
361 | } | ||
362 | |||
363 | lineout[Constants.TerrainPatchSize * n + column] = total; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | private static void IDCTLine16(float[] linein, float[] lineout, int line) | ||
368 | { | ||
369 | const float oosob = 2.0f / Constants.TerrainPatchSize; | ||
370 | int lineSize = line * Constants.TerrainPatchSize; | ||
371 | |||
372 | for (int n = 0; n < Constants.TerrainPatchSize; n++) | ||
373 | { | ||
374 | float total = OO_SQRT2 * linein[lineSize]; | ||
375 | |||
376 | for (int u = 1; u < Constants.TerrainPatchSize; u++) | ||
377 | { | ||
378 | total += linein[lineSize + u] * CosineTable16[u * Constants.TerrainPatchSize + n]; | ||
379 | } | ||
380 | |||
381 | lineout[lineSize + n] = total * oosob; | ||
382 | } | ||
383 | } | ||
384 | |||
385 | public static void DecodePatch(int[] patches, BitPack bitpack, TerrainPatch.Header header, int size) | ||
386 | { | ||
387 | for (int n = 0; n < size * size; n++) | ||
388 | { | ||
389 | // ? | ||
390 | int temp = bitpack.UnpackBits(1); | ||
391 | if (temp != 0) | ||
392 | { | ||
393 | // Value or EOB | ||
394 | temp = bitpack.UnpackBits(1); | ||
395 | if (temp != 0) | ||
396 | { | ||
397 | // Value | ||
398 | temp = bitpack.UnpackBits(1); | ||
399 | if (temp != 0) | ||
400 | { | ||
401 | // Negative | ||
402 | temp = bitpack.UnpackBits((int)header.WordBits); | ||
403 | patches[n] = temp * -1; | ||
404 | } | ||
405 | else | ||
406 | { | ||
407 | // Positive | ||
408 | temp = bitpack.UnpackBits((int)header.WordBits); | ||
409 | patches[n] = temp; | ||
410 | } | ||
411 | } | ||
412 | else | ||
413 | { | ||
414 | // Set the rest to zero | ||
415 | // TODO: This might not be necessary | ||
416 | for (int o = n; o < size * size; o++) | ||
417 | { | ||
418 | patches[o] = 0; | ||
419 | } | ||
420 | break; | ||
421 | } | ||
422 | } | ||
423 | else | ||
424 | { | ||
425 | patches[n] = 0; | ||
426 | } | ||
427 | } | ||
428 | } | ||
429 | |||
430 | private static void EncodePatch(BitPack output, int[] patch, int postquant, int wbits) | 315 | private static void EncodePatch(BitPack output, int[] patch, int postquant, int wbits) |
431 | { | 316 | { |
432 | int maxwbitssize = (1 << wbits) - 1; | 317 | int maxwbitssize = (1 << wbits) - 1; |
@@ -493,6 +378,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
493 | int prequant, out int wbits) | 378 | int prequant, out int wbits) |
494 | { | 379 | { |
495 | float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; | 380 | float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; |
381 | int[] iout = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; | ||
496 | 382 | ||
497 | float oozrange = 1.0f / header.Range; | 383 | float oozrange = 1.0f / header.Range; |
498 | float invprequat = (1 << prequant); | 384 | float invprequat = (1 << prequant); |
@@ -505,27 +391,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
505 | header.QuantWBits |= wordsize << 4; | 391 | header.QuantWBits |= wordsize << 4; |
506 | 392 | ||
507 | int k = 0; | 393 | int k = 0; |
508 | 394 | int startX = patchX * Constants.TerrainPatchSize; | |
509 | int yPatchLimit = patchY >= (terrData.SizeY / Constants.TerrainPatchSize) ? | 395 | int startY = patchY * Constants.TerrainPatchSize; |
510 | (terrData.SizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchY; | 396 | for (int y = startY; y < startY + Constants.TerrainPatchSize; y++) |
511 | yPatchLimit = (yPatchLimit + 1) * Constants.TerrainPatchSize; | ||
512 | |||
513 | int xPatchLimit = patchX >= (terrData.SizeX / Constants.TerrainPatchSize) ? | ||
514 | (terrData.SizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchX; | ||
515 | xPatchLimit = (xPatchLimit + 1) * Constants.TerrainPatchSize; | ||
516 | |||
517 | for (int yy = patchY * Constants.TerrainPatchSize; yy < yPatchLimit; yy++) | ||
518 | { | 397 | { |
519 | for (int xx = patchX * Constants.TerrainPatchSize; xx < xPatchLimit; xx++) | 398 | for (int x = startX; x < startX + Constants.TerrainPatchSize; x++) |
520 | { | 399 | { |
521 | block[k++] = (terrData[xx, yy] - sub) * premult; | 400 | block[k++] = (terrData[x, y] - sub) * premult; |
522 | } | 401 | } |
523 | } | 402 | } |
524 | 403 | ||
525 | |||
526 | float[] ftemp = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; | ||
527 | int[] iout = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize]; | ||
528 | |||
529 | wbits = (prequant >> 1); | 404 | wbits = (prequant >> 1); |
530 | 405 | ||
531 | dct16x16(block, iout, ref wbits); | 406 | dct16x16(block, iout, ref wbits); |
@@ -558,19 +433,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
558 | } | 433 | } |
559 | } | 434 | } |
560 | 435 | ||
561 | private static void SetupCosines16() | ||
562 | { | ||
563 | const float hposz = (float)Math.PI * 0.5f / Constants.TerrainPatchSize; | ||
564 | |||
565 | for (int u = 0; u < Constants.TerrainPatchSize; u++) | ||
566 | { | ||
567 | for (int n = 0; n < Constants.TerrainPatchSize; n++) | ||
568 | { | ||
569 | CosineTable16[u * Constants.TerrainPatchSize + n] = (float)Math.Cos((2.0f * n + 1.0f) * u * hposz); | ||
570 | } | ||
571 | } | ||
572 | } | ||
573 | |||
574 | private static void BuildCopyMatrix16() | 436 | private static void BuildCopyMatrix16() |
575 | { | 437 | { |
576 | bool diag = false; | 438 | bool diag = false; |
@@ -622,7 +484,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
622 | 484 | ||
623 | #endregion Initialization | 485 | #endregion Initialization |
624 | 486 | ||
487 | |||
488 | |||
489 | |||
625 | #region DCT | 490 | #region DCT |
491 | |||
626 | /* DCT (Discrete Cosine Transform) | 492 | /* DCT (Discrete Cosine Transform) |
627 | adaptation from | 493 | adaptation from |
628 | General Purpose 2D,3D FFT (Fast Fourier Transform) Package | 494 | General Purpose 2D,3D FFT (Fast Fourier Transform) Package |
@@ -677,15 +543,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
677 | float xr, xi; | 543 | float xr, xi; |
678 | float ftmp; | 544 | float ftmp; |
679 | 545 | ||
546 | int fullSize = Constants.TerrainPatchSize * Constants.TerrainPatchSize; | ||
680 | int itmp; | 547 | int itmp; |
681 | int j, k; | 548 | int j, k; |
682 | int indx; | 549 | int indx; |
683 | 550 | ||
684 | const int maxwbits = 17; // per header encoding | 551 | const int maxwbits = 17; // per header encoding |
685 | bool dowbits = wbits < 17; | ||
686 | int wbitsMaxValue = 1 << wbits; | 552 | int wbitsMaxValue = 1 << wbits; |
687 | 553 | bool dowbits = wbits < 17; | |
688 | int fullSize = Constants.TerrainPatchSize * Constants.TerrainPatchSize; | ||
689 | 554 | ||
690 | for (j = 0, k = 0; j < fullSize; j += Constants.TerrainPatchSize, k++) | 555 | for (j = 0, k = 0; j < fullSize; j += Constants.TerrainPatchSize, k++) |
691 | { | 556 | { |
@@ -1166,169 +1031,295 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1166 | } | 1031 | } |
1167 | } | 1032 | } |
1168 | 1033 | ||
1169 | /* not in use, and still not fixed | 1034 | #endregion DCT |
1170 | static void idct16x16(float[] a) | 1035 | |
1036 | #region Decode | ||
1037 | /* | ||
1038 | public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack) | ||
1171 | { | 1039 | { |
1172 | int j; | 1040 | TerrainPatch.Header header = new TerrainPatch.Header { QuantWBits = bitpack.UnpackBits(8) }; |
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 | 1041 | ||
1177 | int fullSize = Constants.TerrainPatchSize * Constants.TerrainPatchSize; | 1042 | // Quantized word bits |
1043 | if (header.QuantWBits == END_OF_PATCHES) | ||
1044 | return header; | ||
1178 | 1045 | ||
1179 | for (j = 0; j < fullSize; j += Constants.TerrainPatchSize) | 1046 | // DC offset |
1180 | { | 1047 | header.DCOffset = bitpack.UnpackFloat(); |
1181 | x5r = C16_1R * tmp[1 + j] + C16_1I * tmp[15 + j]; | 1048 | |
1182 | x5i = C16_1R * tmp[15 + j] - C16_1I * tmp[1 + j]; | 1049 | // Range |
1183 | xr = C16_7R * tmp[7 + j] + C16_7I * tmp[9 + j]; | 1050 | header.Range = bitpack.UnpackBits(16); |
1184 | xi = C16_7R * tmp[9 + j] - C16_7I * tmp[7 + j]; | 1051 | |
1185 | x4r = x5r + xr; | 1052 | // Patch IDs (10 bits) |
1186 | x4i = x5i - xi; | 1053 | header.PatchIDs = bitpack.UnpackBits(10); |
1187 | x5r -= xr; | 1054 | |
1188 | x5i += xi; | 1055 | // Word bits |
1189 | x7r = C16_5R * tmp[5 + j] + C16_5I * tmp[11 + j]; | 1056 | header.WordBits = (uint)((header.QuantWBits & 0x0f) + 2); |
1190 | x7i = C16_5R * tmp[11 + j] - C16_5I * tmp[5 + j]; | 1057 | |
1191 | xr = C16_3R * tmp[3 + j] + C16_3I * tmp[13 + j]; | 1058 | return header; |
1192 | xi = C16_3R * tmp[13 + j] - C16_3I * tmp[3 + j]; | 1059 | } |
1193 | x6r = x7r + xr; | 1060 | */ |
1194 | x6i = x7i - xi; | 1061 | |
1195 | x7r -= xr; | 1062 | /* |
1196 | x7i += xi; | 1063 | public static void DecodePatch(int[] patches, BitPack bitpack, TerrainPatch.Header header, int size) |
1197 | xr = x4r - x6r; | 1064 | { |
1198 | xi = x4i - x6i; | 1065 | for (int n = 0; n < size * size; n++) |
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 | { | 1066 | { |
1256 | x5r = C16_1R * tmp[j + 1] + C16_1I * tmp[j + 15]; | 1067 | // ? |
1257 | x5i = C16_1R * tmp[j + 15] - C16_1I * tmp[j + 1]; | 1068 | int temp = bitpack.UnpackBits(1); |
1258 | xr = C16_7R * tmp[j + 7] + C16_7I * tmp[j + 9]; | 1069 | if (temp != 0) |
1259 | xi = C16_7R * tmp[j + 9] - C16_7I * tmp[j + 7]; | 1070 | { |
1260 | x4r = x5r + xr; | 1071 | // Value or EOB |
1261 | x4i = x5i - xi; | 1072 | temp = bitpack.UnpackBits(1); |
1262 | x5r -= xr; | 1073 | if (temp != 0) |
1263 | x5i += xi; | 1074 | { |
1264 | x7r = C16_5R * tmp[j + 5] + C16_5I * tmp[j + 11]; | 1075 | // Value |
1265 | x7i = C16_5R * tmp[j + 11] - C16_5I * tmp[j + 5]; | 1076 | temp = bitpack.UnpackBits(1); |
1266 | xr = C16_3R * tmp[j + 3] + C16_3I * tmp[j + 13]; | 1077 | if (temp != 0) |
1267 | xi = C16_3R * tmp[j + 13] - C16_3I * tmp[j + 3]; | 1078 | { |
1268 | x6r = x7r + xr; | 1079 | // Negative |
1269 | x6i = x7i - xi; | 1080 | temp = bitpack.UnpackBits((int)header.WordBits); |
1270 | x7r -= xr; | 1081 | patches[n] = temp * -1; |
1271 | x7i += xi; | 1082 | } |
1272 | xr = x4r - x6r; | 1083 | else |
1273 | xi = x4i - x6i; | 1084 | { |
1274 | x4r += x6r; | 1085 | // Positive |
1275 | x4i += x6i; | 1086 | temp = bitpack.UnpackBits((int)header.WordBits); |
1276 | x6r = W16_8R * (xi + xr); | 1087 | patches[n] = temp; |
1277 | x6i = W16_8R * (xi - xr); | 1088 | } |
1278 | xr = x5r + x7i; | 1089 | } |
1279 | xi = x5i - x7r; | 1090 | else |
1280 | x5r -= x7i; | 1091 | { |
1281 | x5i += x7r; | 1092 | // Set the rest to zero |
1282 | x7r = W16_4I * x5r + W16_4R * x5i; | 1093 | // TODO: This might not be necessary |
1283 | x7i = W16_4I * x5i - W16_4R * x5r; | 1094 | for (int o = n; o < size * size; o++) |
1284 | x5r = W16_4R * xr + W16_4I * xi; | 1095 | { |
1285 | x5i = W16_4R * xi - W16_4I * xr; | 1096 | patches[o] = 0; |
1286 | xr = C16_4R * tmp[j + 4] + C16_4I * tmp[j + 12]; | 1097 | } |
1287 | xi = C16_4R * tmp[j + 12] - C16_4I * tmp[j + 4]; | 1098 | break; |
1288 | x2r = C16_8R * (tmp[j + 0] + tmp[j + 8]); | 1099 | } |
1289 | x3r = C16_8R * (tmp[j + 0] - tmp[j + 8]); | 1100 | } |
1290 | x0r = x2r + xr; | 1101 | else |
1291 | x1r = x3r + xi; | 1102 | { |
1292 | x2r -= xr; | 1103 | patches[n] = 0; |
1293 | x3r -= xi; | 1104 | } |
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 | } | 1105 | } |
1329 | } | 1106 | } |
1330 | */ | 1107 | */ |
1331 | #endregion DCT | 1108 | #region IDCT |
1109 | /* not in use | ||
1110 | private static void IDCTColumn16(float[] linein, float[] lineout, int column) | ||
1111 | { | ||
1112 | for (int n = 0; n < Constants.TerrainPatchSize; n++) | ||
1113 | { | ||
1114 | float total = OO_SQRT2 * linein[column]; | ||
1115 | |||
1116 | for (int u = 1; u < Constants.TerrainPatchSize; u++) | ||
1117 | { | ||
1118 | int usize = u * Constants.TerrainPatchSize; | ||
1119 | total += linein[usize + column] * CosineTable16[usize + n]; | ||
1120 | } | ||
1121 | |||
1122 | lineout[Constants.TerrainPatchSize * n + column] = total; | ||
1123 | } | ||
1124 | } | ||
1125 | |||
1126 | private static void IDCTLine16(float[] linein, float[] lineout, int line) | ||
1127 | { | ||
1128 | const float oosob = 2.0f / Constants.TerrainPatchSize; | ||
1129 | int lineSize = line * Constants.TerrainPatchSize; | ||
1130 | |||
1131 | for (int n = 0; n < Constants.TerrainPatchSize; n++) | ||
1132 | { | ||
1133 | float total = OO_SQRT2 * linein[lineSize]; | ||
1134 | |||
1135 | for (int u = 1; u < Constants.TerrainPatchSize; u++) | ||
1136 | { | ||
1137 | total += linein[lineSize + u] * CosineTable16[u * Constants.TerrainPatchSize + n]; | ||
1138 | } | ||
1139 | |||
1140 | lineout[lineSize + n] = total * oosob; | ||
1141 | } | ||
1142 | } | ||
1143 | |||
1144 | /* | ||
1145 | private static void SetupCosines16() | ||
1146 | { | ||
1147 | const float hposz = (float)Math.PI * 0.5f / Constants.TerrainPatchSize; | ||
1148 | |||
1149 | for (int u = 0; u < Constants.TerrainPatchSize; u++) | ||
1150 | { | ||
1151 | for (int n = 0; n < Constants.TerrainPatchSize; n++) | ||
1152 | { | ||
1153 | CosineTable16[u * Constants.TerrainPatchSize + n] = (float)Math.Cos((2.0f * n + 1.0f) * u * hposz); | ||
1154 | } | ||
1155 | } | ||
1156 | } | ||
1157 | */ | ||
1158 | //not in use, and still not fixed | ||
1159 | /* | ||
1160 | static void idct16x16(float[] a) | ||
1161 | { | ||
1162 | int j; | ||
1163 | float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; | ||
1164 | float x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i; | ||
1165 | float xr, xi; | ||
1166 | |||
1167 | int fullSize = Constants.TerrainPatchSize * Constants.TerrainPatchSize; | ||
1168 | |||
1169 | for (j = 0; j < fullSize; j += Constants.TerrainPatchSize) | ||
1170 | { | ||
1171 | x5r = C16_1R * tmp[1 + j] + C16_1I * tmp[15 + j]; | ||
1172 | x5i = C16_1R * tmp[15 + j] - C16_1I * tmp[1 + j]; | ||
1173 | xr = C16_7R * tmp[7 + j] + C16_7I * tmp[9 + j]; | ||
1174 | xi = C16_7R * tmp[9 + j] - C16_7I * tmp[7 + j]; | ||
1175 | x4r = x5r + xr; | ||
1176 | x4i = x5i - xi; | ||
1177 | x5r -= xr; | ||
1178 | x5i += xi; | ||
1179 | x7r = C16_5R * tmp[5 + j] + C16_5I * tmp[11 + j]; | ||
1180 | x7i = C16_5R * tmp[11 + j] - C16_5I * tmp[5 + j]; | ||
1181 | xr = C16_3R * tmp[3 + j] + C16_3I * tmp[13 + j]; | ||
1182 | xi = C16_3R * tmp[13 + j] - C16_3I * tmp[3 + j]; | ||
1183 | x6r = x7r + xr; | ||
1184 | x6i = x7i - xi; | ||
1185 | x7r -= xr; | ||
1186 | x7i += xi; | ||
1187 | xr = x4r - x6r; | ||
1188 | xi = x4i - x6i; | ||
1189 | x4r += x6r; | ||
1190 | x4i += x6i; | ||
1191 | x6r = W16_8R * (xi + xr); | ||
1192 | x6i = W16_8R * (xi - xr); | ||
1193 | xr = x5r + x7i; | ||
1194 | xi = x5i - x7r; | ||
1195 | x5r -= x7i; | ||
1196 | x5i += x7r; | ||
1197 | x7r = W16_4I * x5r + W16_4R * x5i; | ||
1198 | x7i = W16_4I * x5i - W16_4R * x5r; | ||
1199 | x5r = W16_4R * xr + W16_4I * xi; | ||
1200 | x5i = W16_4R * xi - W16_4I * xr; | ||
1201 | xr = C16_4R * tmp[4 + j] + C16_4I * tmp[12 + j]; | ||
1202 | xi = C16_4R * tmp[12 + j] - C16_4I * tmp[4 + j]; | ||
1203 | x2r = C16_8R * (tmp[0 + j] + tmp[8 + j]); | ||
1204 | x3r = C16_8R * (tmp[0 + j] - tmp[8 + j]); | ||
1205 | x0r = x2r + xr; | ||
1206 | x1r = x3r + xi; | ||
1207 | x2r -= xr; | ||
1208 | x3r -= xi; | ||
1209 | x0i = C16_2R * tmp[2 + j] + C16_2I * tmp[14 + j]; | ||
1210 | x2i = C16_2R * tmp[14 + j] - C16_2I * tmp[2 + j]; | ||
1211 | x1i = C16_6R * tmp[6 + j] + C16_6I * tmp[10 + j]; | ||
1212 | x3i = C16_6R * tmp[10 + j] - C16_6I * tmp[6 + j]; | ||
1213 | xr = x0i - x1i; | ||
1214 | xi = x2i + x3i; | ||
1215 | x0i += x1i; | ||
1216 | x2i -= x3i; | ||
1217 | x1i = W16_8R * (xi + xr); | ||
1218 | x3i = W16_8R * (xi - xr); | ||
1219 | xr = x0r + x0i; | ||
1220 | xi = x0r - x0i; | ||
1221 | tmp[0 + j] = xr + x4r; | ||
1222 | tmp[15 + j] = xr - x4r; | ||
1223 | tmp[8 + j] = xi + x4i; | ||
1224 | tmp[7 + j] = xi - x4i; | ||
1225 | xr = x1r + x1i; | ||
1226 | xi = x1r - x1i; | ||
1227 | tmp[2 + j] = xr + x5r; | ||
1228 | tmp[13 + j] = xr - x5r; | ||
1229 | tmp[10 + j] = xi + x5i; | ||
1230 | tmp[5 + j] = xi - x5i; | ||
1231 | xr = x2r + x2i; | ||
1232 | xi = x2r - x2i; | ||
1233 | tmp[4 + j] = xr + x6r; | ||
1234 | tmp[11 + j] = xr - x6r; | ||
1235 | tmp[12 + j] = xi + x6i; | ||
1236 | tmp[3 + j] = xi - x6i; | ||
1237 | xr = x3r + x3i; | ||
1238 | xi = x3r - x3i; | ||
1239 | tmp[6 + j] = xr + x7r; | ||
1240 | tmp[9 + j] = xr - x7r; | ||
1241 | tmp[14 + j] = xi + x7i; | ||
1242 | tmp[1 + j] = xi - x7i; | ||
1243 | } | ||
1244 | for (j = 0; j < fullSize; j += Constants.TerrainPatchSize) | ||
1245 | { | ||
1246 | x5r = C16_1R * tmp[j + 1] + C16_1I * tmp[j + 15]; | ||
1247 | x5i = C16_1R * tmp[j + 15] - C16_1I * tmp[j + 1]; | ||
1248 | xr = C16_7R * tmp[j + 7] + C16_7I * tmp[j + 9]; | ||
1249 | xi = C16_7R * tmp[j + 9] - C16_7I * tmp[j + 7]; | ||
1250 | x4r = x5r + xr; | ||
1251 | x4i = x5i - xi; | ||
1252 | x5r -= xr; | ||
1253 | x5i += xi; | ||
1254 | x7r = C16_5R * tmp[j + 5] + C16_5I * tmp[j + 11]; | ||
1255 | x7i = C16_5R * tmp[j + 11] - C16_5I * tmp[j + 5]; | ||
1256 | xr = C16_3R * tmp[j + 3] + C16_3I * tmp[j + 13]; | ||
1257 | xi = C16_3R * tmp[j + 13] - C16_3I * tmp[j + 3]; | ||
1258 | x6r = x7r + xr; | ||
1259 | x6i = x7i - xi; | ||
1260 | x7r -= xr; | ||
1261 | x7i += xi; | ||
1262 | xr = x4r - x6r; | ||
1263 | xi = x4i - x6i; | ||
1264 | x4r += x6r; | ||
1265 | x4i += x6i; | ||
1266 | x6r = W16_8R * (xi + xr); | ||
1267 | x6i = W16_8R * (xi - xr); | ||
1268 | xr = x5r + x7i; | ||
1269 | xi = x5i - x7r; | ||
1270 | x5r -= x7i; | ||
1271 | x5i += x7r; | ||
1272 | x7r = W16_4I * x5r + W16_4R * x5i; | ||
1273 | x7i = W16_4I * x5i - W16_4R * x5r; | ||
1274 | x5r = W16_4R * xr + W16_4I * xi; | ||
1275 | x5i = W16_4R * xi - W16_4I * xr; | ||
1276 | xr = C16_4R * tmp[j + 4] + C16_4I * tmp[j + 12]; | ||
1277 | xi = C16_4R * tmp[j + 12] - C16_4I * tmp[j + 4]; | ||
1278 | x2r = C16_8R * (tmp[j + 0] + tmp[j + 8]); | ||
1279 | x3r = C16_8R * (tmp[j + 0] - tmp[j + 8]); | ||
1280 | x0r = x2r + xr; | ||
1281 | x1r = x3r + xi; | ||
1282 | x2r -= xr; | ||
1283 | x3r -= xi; | ||
1284 | x0i = C16_2R * tmp[j + 2] + C16_2I * tmp[j + 14]; | ||
1285 | x2i = C16_2R * tmp[j + 14] - C16_2I * tmp[j + 2]; | ||
1286 | x1i = C16_6R * tmp[j + 6] + C16_6I * tmp[j + 10]; | ||
1287 | x3i = C16_6R * tmp[j + 10] - C16_6I * tmp[j + 6]; | ||
1288 | xr = x0i - x1i; | ||
1289 | xi = x2i + x3i; | ||
1290 | x0i += x1i; | ||
1291 | x2i -= x3i; | ||
1292 | x1i = W16_8R * (xi + xr); | ||
1293 | x3i = W16_8R * (xi - xr); | ||
1294 | xr = x0r + x0i; | ||
1295 | xi = x0r - x0i; | ||
1296 | tmp[j + 0] = xr + x4r; | ||
1297 | tmp[j + 15] = xr - x4r; | ||
1298 | tmp[j + 8] = xi + x4i; | ||
1299 | tmp[j + 7] = xi - x4i; | ||
1300 | xr = x1r + x1i; | ||
1301 | xi = x1r - x1i; | ||
1302 | tmp[j + 2] = xr + x5r; | ||
1303 | tmp[j + 13] = xr - x5r; | ||
1304 | tmp[j + 10] = xi + x5i; | ||
1305 | tmp[j + 5] = xi - x5i; | ||
1306 | xr = x2r + x2i; | ||
1307 | xi = x2r - x2i; | ||
1308 | tmp[j + 4] = xr + x6r; | ||
1309 | tmp[j + 11] = xr - x6r; | ||
1310 | tmp[j + 12] = xi + x6i; | ||
1311 | tmp[j + 3] = xi - x6i; | ||
1312 | xr = x3r + x3i; | ||
1313 | xi = x3r - x3i; | ||
1314 | tmp[j + 6] = xr + x7r; | ||
1315 | tmp[j + 9] = xr - x7r; | ||
1316 | tmp[j + 14] = xi + x7i; | ||
1317 | tmp[j + 1] = xi - x7i; | ||
1318 | } | ||
1319 | } | ||
1320 | */ | ||
1321 | #endregion IDCT | ||
1322 | #endregion Decode | ||
1332 | } | 1323 | } |
1333 | 1324 | ||
1334 | } | 1325 | } |