Example #1
0
        private static PatchHeader PrescanPatch(LayerPatch patch)
        {
            var   header = new PatchHeader();
            float zmax   = -99999999.0f;
            float zmin   = 99999999.0f;

            for (int y = 0; y < LAYER_PATCH_NUM_XY_ENTRIES; y++)
            {
                for (int x = 0; x < LAYER_PATCH_NUM_XY_ENTRIES; x++)
                {
                    float val = patch[x, y];
                    if (val > zmax)
                    {
                        zmax = val;
                    }
                    if (val < zmin)
                    {
                        zmin = val;
                    }
                }
            }

            header.DCOffset = zmin;
            header.Range    = (int)((zmax - zmin) + 1.0f);

            return(header);
        }
Example #2
0
        public static void LoadLLRawStream(this Stream input, int suggested_width, int suggested_height, Action <LayerPatch> del)
        {
            var  vals = new float[LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, suggested_width / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES];
            uint maxY = (uint)suggested_height / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES - 1;

            for (uint patchy = 0; patchy < suggested_height / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++patchy)
            {
                /* we have to load 16 lines at a time */
                for (uint liney = 0; liney < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++liney)
                {
                    for (uint x = 0; x < suggested_width; ++x)
                    {
                        vals[liney, x] = ReadLLRAWElev(input);
                    }
                }

                /* now build patches from those 16 lines */
                for (uint patchx = 0; patchx < suggested_width / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++patchx)
                {
                    var patch = new LayerPatch
                    {
                        X = patchx,
                        Y = maxY - patchy
                    };
                    for (uint y = 0; y < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++y)
                    {
                        for (uint x = 0; x < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++x)
                        {
                            patch[x, LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES - 1 - y] = vals[y, x + patchx * LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES];
                        }
                    }
                    del(patch);
                }
            }
        }
Example #3
0
        public LayerPatch(LayerPatch p)
        {
            PackedData = new BitPacker(PackedDataBytes);
            X          = p.X;
            Y          = p.Y;

            lock (m_Lock)
            {
                Serial = p.Serial;
                for (int y = 0; y < 16; ++y)
                {
                    for (int x = 0; x < 16; ++x)
                    {
                        Data[y, x] = p.Data[y, x];
                    }
                }
            }
        }
Example #4
0
        private static bool CompressPatch(BitPacker pack, LayerPatch layerpatch, bool extended, ref int remainingbits)
        {
            lock (layerpatch)
            {
                /* check whether we have to run terrain compression */
                if (layerpatch.Serial != layerpatch.PackedSerial)
                {
                    layerpatch.PackedData.Reset();
                    if (layerpatch.Data.Length != LAYER_PATCH_NUM_XY_ENTRIES * LAYER_PATCH_NUM_XY_ENTRIES)
                    {
                        throw new ArgumentException("Patch data must be a 16x16 array");
                    }

                    var pheader = PrescanPatch(layerpatch);
                    pheader.QuantWBits = 136;
                    if (extended)
                    {
                        pheader.PatchIDs  = layerpatch.Y & 0xFFFF;
                        pheader.PatchIDs += layerpatch.X << 16;
                    }
                    else
                    {
                        pheader.PatchIDs  = layerpatch.Y & 0x1F;
                        pheader.PatchIDs += layerpatch.X << 5;
                    }

                    int[] patch = CompressPatch(layerpatch, pheader, 10);
                    int   wbits = EncodePatchHeader(layerpatch.PackedData, pheader, patch, extended);
                    EncodePatch(layerpatch.PackedData, patch, 0, wbits);
                    layerpatch.PackedSerial = layerpatch.Serial;
                }

                if (layerpatch.PackedData.BitLength <= remainingbits)
                {
                    remainingbits -= layerpatch.PackedData.BitLength;
                    pack.PackBits(layerpatch.PackedData);
                    return(true);
                }
                return(false);
            }
        }
Example #5
0
        public void Update(LayerPatch p)
        {
            if (X != p.X || Y != p.Y)
            {
                throw new ArgumentException("p does not match in its parameters X and Y.");
            }

            lock (m_Lock)
            {
                for (int y = 0; y < 16; ++y)
                {
                    for (int x = 0; x < 16; ++x)
                    {
                        Data[y, x] = p.Data[y, x];
                    }
                }
                if (++m_Serial == 0)
                {
                    m_Serial = 1;
                }
                Dirty = true;
            }
        }
Example #6
0
        private static int[] CompressPatch(LayerPatch patchData, PatchHeader header, int prequant)
        {
            var   block    = new float[LAYER_PATCH_NUM_XY_ENTRIES * LAYER_PATCH_NUM_XY_ENTRIES];
            int   wordsize = prequant;
            float oozrange = 1.0f / (float)header.Range;
            var   range    = (float)(1 << prequant);
            float premult  = oozrange * range;
            float sub      = (1 << (prequant - 1)) + header.DCOffset * premult;

            header.QuantWBits  = wordsize - 2;
            header.QuantWBits |= (prequant - 2) << 4;

            int k = 0;

            for (int y = 0; y < LAYER_PATCH_NUM_XY_ENTRIES; y++)
            {
                for (int x = 0; x < LAYER_PATCH_NUM_XY_ENTRIES; x++)
                {
                    block[k++] = patchData[x, y] * premult - sub;
                }
            }

            var ftemp = new float[LAYER_PATCH_NUM_XY_ENTRIES * LAYER_PATCH_NUM_XY_ENTRIES];
            var itemp = new int[LAYER_PATCH_NUM_XY_ENTRIES * LAYER_PATCH_NUM_XY_ENTRIES];

            for (int o = 0; o < LAYER_PATCH_NUM_XY_ENTRIES; o++)
            {
                DCTLine16(block, ftemp, o);
            }
            for (int o = 0; o < LAYER_PATCH_NUM_XY_ENTRIES; o++)
            {
                DCTColumn16(ftemp, itemp, o);
            }

            return(itemp);
        }
Example #7
0
 private static uint XYToYInverted(this LayerPatch p, uint lineWidth, uint maxY)
 {
     return((maxY - p.Y) * lineWidth + p.X);
 }