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); }
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); } } }
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]; } } } }
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); } }
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; } }
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); }
private static uint XYToYInverted(this LayerPatch p, uint lineWidth, uint maxY) { return((maxY - p.Y) * lineWidth + p.X); }