123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /* Freely adapted from the Aurora version of the terrain compressor.
- * Copyright (c) Contributors, http://aurora-sim.org/, http://opensimulator.org/
- * Aurora version created from libOpenMetaverse Library terrain compressor
- */
- // terrain patchs must be 16mx16m
- using System;
- using System.Collections.Generic;
- using log4net;
- using OpenSim.Framework;
- using OpenMetaverse;
- using OpenMetaverse.Packets;
- namespace OpenSim.Region.ClientStack.LindenUDP
- {
- public static class OpenSimTerrainCompressor
- {
- private const float OO_SQRT2 = 0.7071068f;
- private const int END_OF_PATCHES = 97;
- private const int STRIDE = 264;
- private const int ZERO_CODE = 0x0;
- private const int ZERO_EOB = 0x2;
- private const int POSITIVE_VALUE = 0x6;
- private const int NEGATIVE_VALUE = 0x7;
- private static readonly int[] CopyMatrix16 = new int[256];
- private static readonly float[] QuantizeTable16 = new float[256];
- private static readonly float[] DequantizeTable16 = new float[256];
- static OpenSimTerrainCompressor()
- {
- if(Constants.TerrainPatchSize != 16)
- throw new Exception("Terrain patch size must be 16m x 16m");
- // Initialize the compression tables
- BuildQuantizeTables16();
- BuildCopyMatrix16();
- }
- // Used to send cloud and wind patches
- public static LayerDataPacket CreateLayerDataPacketStandardSize(TerrainPatch[] patches, byte type)
- {
- LayerDataPacket layer = new LayerDataPacket { LayerID = { Type = type } };
- TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader { Stride = STRIDE, PatchSize = 16 };
- // Should be enough to fit even the most poorly packed data
- byte[] data = new byte[patches.Length * 256 * 2];
- BitPack bitpack = new BitPack(data, 0);
- bitpack.PackBits(header.Stride, 16);
- bitpack.PackBits(header.PatchSize, 8);
- bitpack.PackBits(type, 8);
- foreach (TerrainPatch t in patches)
- CreatePatchtStandardSize(bitpack, t.Data, t.X, t.Y);
- bitpack.PackBits(END_OF_PATCHES, 8);
- layer.LayerData.Data = new byte[bitpack.BytePos + 1];
- Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);
- return layer;
- }
- public unsafe static void CreatePatchtStandardSize(BitPack output, float[] patchData, int x, int y)
- {
- TerrainPatch.Header header = PrescanPatch(patchData);
- header.QuantWBits = 136;
- header.PatchIDs = (y & 0x1F);
- header.PatchIDs += (x << 5);
- int wbits;
- int* patch = stackalloc int[256];
- CompressPatch(patchData, header, 10, out wbits, patch);
- EncodePatchHeader(output, header, false, ref wbits);
- EncodePatch(output, patch, 0, wbits);
- }
- private static TerrainPatch.Header PrescanPatch(float[] patch)
- {
- TerrainPatch.Header header = new TerrainPatch.Header();
- float zmax = -99999999.0f;
- float zmin = 99999999.0f;
- for (int i = 0; i < 256; i++)
- {
- float val = patch[i];
- if (val > zmax) zmax = val;
- if (val < zmin) zmin = val;
- }
- header.DCOffset = zmin;
- header.Range = (int)((zmax - zmin) + 1.0f);
- return header;
- }
- private unsafe static void CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant, out int wbits, int* iout)
- {
- float* block = stackalloc float[256];
- float oozrange = 1.0f / header.Range;
- float range = (1 << prequant);
- float premult = oozrange * range;
- float sub = 0.5f * header.Range + header.DCOffset;
- int wordsize = (prequant - 2) & 0x0f;
- header.QuantWBits = wordsize | (wordsize << 4);
- int k = 0;
- for (int j = 0; j < 256 ; j += 16)
- {
- int nj = j + 16;
- for (int i = j; i < nj; ++i)
- block[k++] = (patchData[i] - sub) * premult;
- }
- wbits = (prequant >> 1);
- dct16x16(block, iout, ref wbits);
- }
- public unsafe static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY)
- {
- TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY, out float frange);
- header.QuantWBits = 130;
- bool largeRegion = terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize;
- if (Math.Round(frange, 2) == 1.0)
- {
- // flat terrain speed up things
- output.PackBitsFromByte(0); //QuantWBits
- output.PackFloat(header.DCOffset - 0.5f);
- output.PackBitsFromByte(1); //range low
- output.PackBitsFromByte(0); //range high
- if (largeRegion)
- output.PackBits((patchX << 16) | (patchY & 0xFFFF), 32);
- else
- output.PackBits((patchX << 5) | (patchY & 0x1F) , 10);
- // and thats all
- output.PackBits(ZERO_EOB, 2);
- return;
- }
- header.PatchIDs = largeRegion ?
- (patchX << 16) | (patchY & 0xFFFF) :
- (patchX << 5) | (patchY & 0x1F);
- int* patch = stackalloc int[256];
- CompressPatch(terrData, patchX, patchY, header, 10, out int wbits, patch);
- EncodePatchHeader(output, header, largeRegion, ref wbits);
- EncodePatch(output, patch, 0, wbits);
- }
- // Scan the height info we're returning and return a patch packet header for this patch.
- private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY, out float frange)
- {
- terrData.GetPatchMinMax(patchX, patchY, out float zmin, out float zmax);
- frange = ((zmax - zmin) + 1.0f);
- TerrainPatch.Header header = new TerrainPatch.Header()
- {
- DCOffset = zmin,
- Range = (int)frange
- };
- return header;
- }
- private static void EncodePatchHeader(BitPack output, TerrainPatch.Header header, bool largeRegion, ref int wbits)
- {
- if (wbits > 17)
- wbits = 17;
- else if (wbits < 2)
- wbits = 2;
- header.QuantWBits &= 0xf0;
- header.QuantWBits |= (wbits - 2);
- output.PackBitsFromByte((byte)header.QuantWBits);
- output.PackFloat(header.DCOffset);
- output.PackBits(header.Range, 16);
- output.PackBits(header.PatchIDs, largeRegion ? 32 : 10);
- }
- private unsafe static void EncodePatch(BitPack output, int* patch, int postquant, int wbits)
- {
- int maxwbitssize = (1 << wbits) - 1;
- if (postquant > 256 || postquant < 0)
- {
- Logger.Log("Postquant is outside the range of allowed values in EncodePatch()", Helpers.LogLevel.Error);
- return;
- }
- int lastZeroindx = 256 - postquant;
- if (lastZeroindx != 256)
- patch[lastZeroindx] = 0;
- int i = 0;
- while(i < 256)
- {
- int temp = patch[i];
- if (temp == 0)
- {
- int j = i + 1;
- while(j < lastZeroindx)
- {
- if (patch[j] != 0)
- break;
- ++j;
- }
- if (j == lastZeroindx)
- {
- output.PackBits(ZERO_EOB, 2);
- return;
- }
- i = j - i;
- while(i > 8)
- {
- output.PackBitsFromByte(ZERO_CODE);
- i -= 8;
- }
- if( i > 0)
- output.PackBitsFromByte(ZERO_CODE, i);
- i = j;
- continue;
- }
- else if (temp < 0)
- {
- temp *= -1;
- output.PackBits(NEGATIVE_VALUE, 3);
- }
- else
- {
- output.PackBits(POSITIVE_VALUE, 3);
- }
- output.PackBits(temp > maxwbitssize ? maxwbitssize : temp, wbits);
- ++i;
- }
- }
- private unsafe static void CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header,
- int prequant, out int wbits, int* iout)
- {
- float* block = stackalloc float[256];
- float sub = header.Range;
- float premult = (1 << prequant) / sub;
- sub = 0.5f * sub + header.DCOffset;
- terrData.GetPatchBlock(block, patchX, patchY, sub, premult);
- int wordsize = (prequant - 2) & 0x0f;
- header.QuantWBits = wordsize | (wordsize << 4);
- wbits = (prequant >> 1);
- dct16x16(block, iout, ref wbits);
- }
- #region Initialization
- private unsafe static void BuildQuantizeTables16()
- {
- const float oosob = 2.0f / 16;
- float tmp;
- fixed(float* fQuantizeTable16 = QuantizeTable16, fDeQuantizeTable16 = DequantizeTable16)
- {
- float* dqptr = fDeQuantizeTable16;
- float* qptr = fQuantizeTable16;
- for (int j = 0; j < 16; j++)
- {
- for (int i = 0; i < 16; i++)
- {
- tmp = 1.0f + 2.0f * (i + j);
- *dqptr++ = tmp;
- *qptr++ = oosob / tmp;
- }
- }
- }
- }
- private unsafe static void BuildCopyMatrix16()
- {
- bool diag = false;
- bool right = true;
- int i = 0;
- int j = 0;
- int count = 0;
- fixed (int* fCopyMatrix16 = CopyMatrix16)
- {
- while (i < 16 && j < 16)
- {
- fCopyMatrix16[j * 16 + i] = count++;
- if (!diag)
- {
- if (right)
- {
- if (i < 15) i++;
- else j++;
- right = false;
- diag = true;
- }
- else
- {
- if (j < 15 ) j++;
- else i++;
- right = true;
- diag = true;
- }
- }
- else
- {
- if (right)
- {
- i++;
- j--;
- if (i == 15 || j == 0) diag = false;
- }
- else
- {
- i--;
- j++;
- if (j == 15 || i == 0) diag = false;
- }
- }
- }
- }
- }
- #endregion Initialization
- #region DCT
- /* DCT (Discrete Cosine Transform)
- adaptation from
- General Purpose 2D,3D FFT (Fast Fourier Transform) Package
- by Takuya OOURA (email: [email protected])
- -------- 16x16 DCT (Discrete Cosine Transform) / Inverse of DCT --------
- [definition]
- <case1> Normalized 16x16 IDCT
- C[k1 + k2] = (1/8) * sum_j1=0^15 sum_j2=0^15
- tmp[j1 + j2] * s[j1] * s[j2] *
- cos(pi*j1*(k1+1/2)/16) *
- cos(pi*j2*(k2+1/2)/16), 0<=k1<16, 0<=k2<16
- (s[0] = 1/sqrt(2), s[j] = 1, j > 0)
- <case2> Normalized 16x16 DCT
- C[k1 + k2] = (1/8) * s[k1] * s[k2] * sum_j1=0^15 sum_j2=0^15
- tmp[j1 + j2] *
- cos(pi*(j1+1/2)*k1/16) *
- cos(pi*(j2+1/2)*k2/16), 0<=k1<16, 0<=k2<16
- (s[0] = 1/sqrt(2), s[j] = 1, j > 0)
- */
- /* Cn_kR = sqrt(2.0/n) * cos(pi/2*k/n) */
- /* Cn_kI = sqrt(2.0/n) * sin(pi/2*k/n) */
- /* Wn_kR = cos(pi/2*k/n) */
- /* Wn_kI = sin(pi/2*k/n) */
- const float C16_1R = 0.35185093438159561476f * 2.82842712474619f;
- const float C16_1I = 0.03465429229977286565f * 2.82842712474619f;
- const float C16_2R = 0.34675996133053686546f * 2.82842712474619f;
- const float C16_2I = 0.06897484482073575308f * 2.82842712474619f;
- const float C16_3R = 0.33832950029358816957f * 2.82842712474619f;
- const float C16_3I = 0.10263113188058934529f * 2.82842712474619f;
- const float C16_4R = 0.32664074121909413196f * 2.82842712474619f;
- const float C16_4I = 0.13529902503654924610f * 2.82842712474619f;
- const float C16_5R = 0.31180625324666780814f * 2.82842712474619f;
- const float C16_5I = 0.16666391461943662432f * 2.82842712474619f;
- const float C16_6R = 0.29396890060483967924f * 2.82842712474619f;
- const float C16_6I = 0.19642373959677554532f * 2.82842712474619f;
- const float C16_7R = 0.27330046675043937206f * 2.82842712474619f;
- const float C16_7I = 0.22429189658565907106f * 2.82842712474619f;
- const float C16_8R = 0.25f * 2.82842712474619f;
- const float W16_4R = 0.92387953251128675613f;
- const float W16_4I = 0.38268343236508977173f;
- const float W16_8R = 0.70710678118654752440f;
- unsafe static void dct16x16(float* a, int* iout, ref int wbits)
- {
- float* tmp = stackalloc float[256];
- float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
- float x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i;
- float xr, xi;
- float ftmp;
- int itmp;
- int j, k;
- int indx;
- const int maxwbits = 17; // per header encoding
- int wbitsMaxValue = 1 << wbits;
- bool dowbits = wbits < 17;
- fixed (float* fQuantizeTable16 = QuantizeTable16)
- fixed (int* fCopyMatrix16 = CopyMatrix16)
- {
- for (j = 0, k = 0; j < 256; j += 16, k++)
- {
- x4r = a[0 + j] - a[15 + j];
- xr = a[0 + j] + a[15 + j];
- x4i = a[8 + j] - a[7 + j];
- xi = a[8 + j] + a[7 + j];
- x0r = xr + xi;
- x0i = xr - xi;
- x5r = a[2 + j] - a[13 + j];
- xr = a[2 + j] + a[13 + j];
- x5i = a[10 + j] - a[5 + j];
- xi = a[10 + j] + a[5 + j];
- x1r = xr + xi;
- x1i = xr - xi;
- x6r = a[4 + j] - a[11 + j];
- xr = a[4 + j] + a[11 + j];
- x6i = a[12 + j] - a[3 + j];
- xi = a[12 + j] + a[3 + j];
- x2r = xr + xi;
- x2i = xr - xi;
- x7r = a[6 + j] - a[9 + j];
- xr = a[6 + j] + a[9 + j];
- x7i = a[14 + j] - a[1 + j];
- xi = a[14 + j] + a[1 + j];
- x3r = xr + xi;
- x3i = xr - xi;
- xr = x0r + x2r;
- xi = x1r + x3r;
- tmp[k] = C16_8R * (xr + xi); //
- tmp[8 * 16 + k] = C16_8R * (xr - xi); //
- xr = x0r - x2r;
- xi = x1r - x3r;
- tmp[4 * 16 + k] = C16_4R * xr - C16_4I * xi; //
- tmp[12 * 16 + k] = C16_4R * xi + C16_4I * xr; //
- x0r = W16_8R * (x1i - x3i);
- x2r = W16_8R * (x1i + x3i);
- xr = x0i + x0r;
- xi = x2r + x2i;
- tmp[2 * 16 + k] = C16_2R * xr - C16_2I * xi; //
- tmp[14 * 16 + k] = C16_2R * xi + C16_2I * xr; //
- xr = x0i - x0r;
- xi = x2r - x2i;
- tmp[6 * 16 + k] = C16_6R * xr - C16_6I * xi; //
- tmp[10 * 16 + k] = C16_6R * xi + C16_6I * xr; //
- xr = W16_8R * (x6r - x6i);
- xi = W16_8R * (x6i + x6r);
- x6r = x4r - xr;
- x6i = x4i - xi;
- x4r += xr;
- x4i += xi;
- xr = W16_4I * x7r - W16_4R * x7i;
- xi = W16_4I * x7i + W16_4R * x7r;
- x7r = W16_4R * x5r - W16_4I * x5i;
- x7i = W16_4R * x5i + W16_4I * x5r;
- x5r = x7r + xr;
- x5i = x7i + xi;
- x7r -= xr;
- x7i -= xi;
- xr = x4r + x5r;
- xi = x5i + x4i;
- tmp[16 + k] = C16_1R * xr - C16_1I * xi; //
- tmp[15 * 16 + k] = C16_1R * xi + C16_1I * xr; //
- xr = x4r - x5r;
- xi = x5i - x4i;
- tmp[7 * 16 + k] = C16_7R * xr - C16_7I * xi; //
- tmp[9 * 16 + k] = C16_7R * xi + C16_7I * xr; //
- xr = x6r - x7i;
- xi = x7r + x6i;
- tmp[5 * 16 + k] = C16_5R * xr - C16_5I * xi; //
- tmp[11 * 16 + k] = C16_5R * xi + C16_5I * xr; //
- xr = x6r + x7i;
- xi = x7r - x6i;
- tmp[3 * 16 + k] = C16_3R * xr - C16_3I * xi; //
- tmp[13 * 16 + k] = C16_3R * xi + C16_3I * xr; //
- }
- for (j = 0, k = 0; j < 256; j += 16, k++)
- {
- x4r = tmp[0 + j] - tmp[15 + j];
- xr = tmp[0 + j] + tmp[15 + j];
- x4i = tmp[8 + j] - tmp[7 + j];
- xi = tmp[8 + j] + tmp[7 + j];
- x0r = xr + xi;
- x0i = xr - xi;
- x5r = tmp[2 + j] - tmp[13 + j];
- xr = tmp[2 + j] + tmp[13 + j];
- x5i = tmp[10 + j] - tmp[5 + j];
- xi = tmp[10 + j] + tmp[5 + j];
- x1r = xr + xi;
- x1i = xr - xi;
- x6r = tmp[4 + j] - tmp[11 + j];
- xr = tmp[4 + j] + tmp[11 + j];
- x6i = tmp[12 + j] - tmp[3 + j];
- xi = tmp[12 + j] + tmp[3 + j];
- x2r = xr + xi;
- x2i = xr - xi;
- x7r = tmp[6 + j] - tmp[9 + j];
- xr = tmp[6 + j] + tmp[9 + j];
- x7i = tmp[14 + j] - tmp[1 + j];
- xi = tmp[14 + j] + tmp[1 + j];
- x3r = xr + xi;
- x3i = xr - xi;
- xr = x0r + x2r;
- xi = x1r + x3r;
- //tmp[0 + k] = C16_8R * (xr + xi); //
- ftmp = C16_8R * (xr + xi);
- itmp = (int)(ftmp * fQuantizeTable16[k]);
- iout[fCopyMatrix16[k]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- //tmp[8 * Constants.TerrainPatchSize + k] = C16_8R * (xr - xi); //
- ftmp = C16_8R * (xr - xi);
- indx = 8 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- xr = x0r - x2r;
- xi = x1r - x3r;
- //tmp[4 * Constants.TerrainPatchSize + k] = C16_4R * xr - C16_4I * xi; //
- ftmp = C16_4R * xr - C16_4I * xi;
- indx = 4 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- //tmp[12 * Constants.TerrainPatchSize + k] = C16_4R * xi + C16_4I * xr; //
- ftmp = C16_4R * xi + C16_4I * xr;
- indx = 12 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- x0r = W16_8R * (x1i - x3i);
- x2r = W16_8R * (x1i + x3i);
- xr = x0i + x0r;
- xi = x2r + x2i;
- //tmp[2 * Constants.TerrainPatchSize + k] = C16_2R * xr - C16_2I * xi; //
- ftmp = C16_2R * xr - C16_2I * xi;
- indx = 2 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- //tmp[14 * Constants.TerrainPatchSize + k] = C16_2R * xi + C16_2I * xr; //
- ftmp = C16_2R * xi + C16_2I * xr;
- indx = 14 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- xr = x0i - x0r;
- xi = x2r - x2i;
- //tmp[6 * Constants.TerrainPatchSize + k] = C16_6R * xr - C16_6I * xi; //
- ftmp = C16_6R * xr - C16_6I * xi;
- indx = 6 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- //tmp[10 * Constants.TerrainPatchSize + k] = C16_6R * xi + C16_6I * xr; //
- ftmp = C16_6R * xi + C16_6I * xr;
- indx = 10 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- xr = W16_8R * (x6r - x6i);
- xi = W16_8R * (x6i + x6r);
- x6r = x4r - xr;
- x6i = x4i - xi;
- x4r += xr;
- x4i += xi;
- xr = W16_4I * x7r - W16_4R * x7i;
- xi = W16_4I * x7i + W16_4R * x7r;
- x7r = W16_4R * x5r - W16_4I * x5i;
- x7i = W16_4R * x5i + W16_4I * x5r;
- x5r = x7r + xr;
- x5i = x7i + xi;
- x7r -= xr;
- x7i -= xi;
- xr = x4r + x5r;
- xi = x5i + x4i;
- //tmp[1 * Constants.TerrainPatchSize + k] = C16_1R * xr - C16_1I * xi; //
- ftmp = C16_1R * xr - C16_1I * xi;
- indx = 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- //tmp[15 * Constants.TerrainPatchSize + k] = C16_1R * xi + C16_1I * xr; //
- ftmp = C16_1R * xi + C16_1I * xr;
- indx = 15 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- xr = x4r - x5r;
- xi = x5i - x4i;
- //tmp[7 * Constants.TerrainPatchSize + k] = C16_7R * xr - C16_7I * xi; //
- ftmp = C16_7R * xr - C16_7I * xi;
- indx = 7 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- //tmp[9 * Constants.TerrainPatchSize + k] = C16_7R * xi + C16_7I * xr; //
- ftmp = C16_7R * xi + C16_7I * xr;
- indx = 9 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- xr = x6r - x7i;
- xi = x7r + x6i;
- //tmp[5 * Constants.TerrainPatchSize + k] = C16_5R * xr - C16_5I * xi; //
- ftmp = C16_5R * xr - C16_5I * xi;
- indx = 5 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- //tmp[11 * Constants.TerrainPatchSize + k] = C16_5R * xi + C16_5I * xr; //
- ftmp = C16_5R * xi + C16_5I * xr;
- indx = 11 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- xr = x6r + x7i;
- xi = x7r - x6i;
- //tmp[3 * Constants.TerrainPatchSize + k] = C16_3R * xr - C16_3I * xi; //
- ftmp = C16_3R * xr - C16_3I * xi;
- indx = 3 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- //tmp[13 * Constants.TerrainPatchSize + k] = C16_3R * xi + C16_3I * xr; //
- ftmp = C16_3R * xi + C16_3I * xr;
- indx = 13 * 16 + k;
- itmp = (int)(ftmp * fQuantizeTable16[indx]);
- iout[fCopyMatrix16[indx]] = itmp;
- if (dowbits)
- {
- if (itmp < 0) itmp *= -1;
- while (itmp > wbitsMaxValue)
- {
- wbits++;
- wbitsMaxValue = 1 << wbits;
- if (wbits == maxwbits)
- {
- dowbits = false;
- break;
- }
- }
- }
- }
- }
- }
- #endregion DCT
- #region IDCT
- /* not in use
- private static void IDCTColumn16(float[] linein, float[] lineout, int column)
- {
- for (int n = 0; n < Constants.TerrainPatchSize; n++)
- {
- float total = OO_SQRT2 * linein[column];
- for (int u = 1; u < Constants.TerrainPatchSize; u++)
- {
- int usize = u * Constants.TerrainPatchSize;
- total += linein[usize + column] * CosineTable16[usize + n];
- }
- lineout[Constants.TerrainPatchSize * n + column] = total;
- }
- }
- private static void IDCTLine16(float[] linein, float[] lineout, int line)
- {
- const float oosob = 2.0f / Constants.TerrainPatchSize;
- int lineSize = line * Constants.TerrainPatchSize;
- for (int n = 0; n < Constants.TerrainPatchSize; n++)
- {
- float total = OO_SQRT2 * linein[lineSize];
- for (int u = 1; u < Constants.TerrainPatchSize; u++)
- {
- total += linein[lineSize + u] * CosineTable16[u * Constants.TerrainPatchSize + n];
- }
- lineout[lineSize + n] = total * oosob;
- }
- }
- //not in use, and still not fixed
- /*
- static void idct16x16(float[] a)
- {
- int j;
- float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
- float x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i;
- float xr, xi;
- int fullSize = Constants.TerrainPatchSize * Constants.TerrainPatchSize;
- for (j = 0; j < fullSize; j += Constants.TerrainPatchSize)
- {
- x5r = C16_1R * tmp[1 + j] + C16_1I * tmp[15 + j];
- x5i = C16_1R * tmp[15 + j] - C16_1I * tmp[1 + j];
- xr = C16_7R * tmp[7 + j] + C16_7I * tmp[9 + j];
- xi = C16_7R * tmp[9 + j] - C16_7I * tmp[7 + j];
- x4r = x5r + xr;
- x4i = x5i - xi;
- x5r -= xr;
- x5i += xi;
- x7r = C16_5R * tmp[5 + j] + C16_5I * tmp[11 + j];
- x7i = C16_5R * tmp[11 + j] - C16_5I * tmp[5 + j];
- xr = C16_3R * tmp[3 + j] + C16_3I * tmp[13 + j];
- xi = C16_3R * tmp[13 + j] - C16_3I * tmp[3 + j];
- x6r = x7r + xr;
- x6i = x7i - xi;
- x7r -= xr;
- x7i += xi;
- xr = x4r - x6r;
- xi = x4i - x6i;
- x4r += x6r;
- x4i += x6i;
- x6r = W16_8R * (xi + xr);
- x6i = W16_8R * (xi - xr);
- xr = x5r + x7i;
- xi = x5i - x7r;
- x5r -= x7i;
- x5i += x7r;
- x7r = W16_4I * x5r + W16_4R * x5i;
- x7i = W16_4I * x5i - W16_4R * x5r;
- x5r = W16_4R * xr + W16_4I * xi;
- x5i = W16_4R * xi - W16_4I * xr;
- xr = C16_4R * tmp[4 + j] + C16_4I * tmp[12 + j];
- xi = C16_4R * tmp[12 + j] - C16_4I * tmp[4 + j];
- x2r = C16_8R * (tmp[0 + j] + tmp[8 + j]);
- x3r = C16_8R * (tmp[0 + j] - tmp[8 + j]);
- x0r = x2r + xr;
- x1r = x3r + xi;
- x2r -= xr;
- x3r -= xi;
- x0i = C16_2R * tmp[2 + j] + C16_2I * tmp[14 + j];
- x2i = C16_2R * tmp[14 + j] - C16_2I * tmp[2 + j];
- x1i = C16_6R * tmp[6 + j] + C16_6I * tmp[10 + j];
- x3i = C16_6R * tmp[10 + j] - C16_6I * tmp[6 + j];
- xr = x0i - x1i;
- xi = x2i + x3i;
- x0i += x1i;
- x2i -= x3i;
- x1i = W16_8R * (xi + xr);
- x3i = W16_8R * (xi - xr);
- xr = x0r + x0i;
- xi = x0r - x0i;
- tmp[0 + j] = xr + x4r;
- tmp[15 + j] = xr - x4r;
- tmp[8 + j] = xi + x4i;
- tmp[7 + j] = xi - x4i;
- xr = x1r + x1i;
- xi = x1r - x1i;
- tmp[2 + j] = xr + x5r;
- tmp[13 + j] = xr - x5r;
- tmp[10 + j] = xi + x5i;
- tmp[5 + j] = xi - x5i;
- xr = x2r + x2i;
- xi = x2r - x2i;
- tmp[4 + j] = xr + x6r;
- tmp[11 + j] = xr - x6r;
- tmp[12 + j] = xi + x6i;
- tmp[3 + j] = xi - x6i;
- xr = x3r + x3i;
- xi = x3r - x3i;
- tmp[6 + j] = xr + x7r;
- tmp[9 + j] = xr - x7r;
- tmp[14 + j] = xi + x7i;
- tmp[1 + j] = xi - x7i;
- }
- for (j = 0; j < fullSize; j += Constants.TerrainPatchSize)
- {
- x5r = C16_1R * tmp[j + 1] + C16_1I * tmp[j + 15];
- x5i = C16_1R * tmp[j + 15] - C16_1I * tmp[j + 1];
- xr = C16_7R * tmp[j + 7] + C16_7I * tmp[j + 9];
- xi = C16_7R * tmp[j + 9] - C16_7I * tmp[j + 7];
- x4r = x5r + xr;
- x4i = x5i - xi;
- x5r -= xr;
- x5i += xi;
- x7r = C16_5R * tmp[j + 5] + C16_5I * tmp[j + 11];
- x7i = C16_5R * tmp[j + 11] - C16_5I * tmp[j + 5];
- xr = C16_3R * tmp[j + 3] + C16_3I * tmp[j + 13];
- xi = C16_3R * tmp[j + 13] - C16_3I * tmp[j + 3];
- x6r = x7r + xr;
- x6i = x7i - xi;
- x7r -= xr;
- x7i += xi;
- xr = x4r - x6r;
- xi = x4i - x6i;
- x4r += x6r;
- x4i += x6i;
- x6r = W16_8R * (xi + xr);
- x6i = W16_8R * (xi - xr);
- xr = x5r + x7i;
- xi = x5i - x7r;
- x5r -= x7i;
- x5i += x7r;
- x7r = W16_4I * x5r + W16_4R * x5i;
- x7i = W16_4I * x5i - W16_4R * x5r;
- x5r = W16_4R * xr + W16_4I * xi;
- x5i = W16_4R * xi - W16_4I * xr;
- xr = C16_4R * tmp[j + 4] + C16_4I * tmp[j + 12];
- xi = C16_4R * tmp[j + 12] - C16_4I * tmp[j + 4];
- x2r = C16_8R * (tmp[j + 0] + tmp[j + 8]);
- x3r = C16_8R * (tmp[j + 0] - tmp[j + 8]);
- x0r = x2r + xr;
- x1r = x3r + xi;
- x2r -= xr;
- x3r -= xi;
- x0i = C16_2R * tmp[j + 2] + C16_2I * tmp[j + 14];
- x2i = C16_2R * tmp[j + 14] - C16_2I * tmp[j + 2];
- x1i = C16_6R * tmp[j + 6] + C16_6I * tmp[j + 10];
- x3i = C16_6R * tmp[j + 10] - C16_6I * tmp[j + 6];
- xr = x0i - x1i;
- xi = x2i + x3i;
- x0i += x1i;
- x2i -= x3i;
- x1i = W16_8R * (xi + xr);
- x3i = W16_8R * (xi - xr);
- xr = x0r + x0i;
- xi = x0r - x0i;
- tmp[j + 0] = xr + x4r;
- tmp[j + 15] = xr - x4r;
- tmp[j + 8] = xi + x4i;
- tmp[j + 7] = xi - x4i;
- xr = x1r + x1i;
- xi = x1r - x1i;
- tmp[j + 2] = xr + x5r;
- tmp[j + 13] = xr - x5r;
- tmp[j + 10] = xi + x5i;
- tmp[j + 5] = xi - x5i;
- xr = x2r + x2i;
- xi = x2r - x2i;
- tmp[j + 4] = xr + x6r;
- tmp[j + 11] = xr - x6r;
- tmp[j + 12] = xi + x6i;
- tmp[j + 3] = xi - x6i;
- xr = x3r + x3i;
- xi = x3r - x3i;
- tmp[j + 6] = xr + x7r;
- tmp[j + 9] = xr - x7r;
- tmp[j + 14] = xi + x7i;
- tmp[j + 1] = xi - x7i;
- }
- }
- */
- #endregion IDCT
- }
- }
|