public override void read(laszip_point item) { for (uint i = 0; i < number; i++) { int value = (int)(last_item[i] + dec.decodeSymbol(m_byte[i])); item.extra_bytes[i] = (byte)MyDefs.U8_FOLD(value); } Buffer.BlockCopy(item.extra_bytes, 0, last_item, 0, (int)number); }
public override bool write(laszip_point item) { for (uint i = 0; i < number; i++) { int diff = item.extra_bytes[i] - last_item[i]; enc.encodeSymbol(m_byte[i], (byte)MyDefs.U8_FOLD(diff)); } Buffer.BlockCopy(item.extra_bytes, 0, last_item, 0, (int)number); return(true); }
public unsafe override void read(laszip_point item) { if (instream.Read(buffer, 0, 30) != 30) throw new EndOfStreamException(); fixed(byte *pBuffer = buffer) { LAStempReadPoint14 *p14 = (LAStempReadPoint14 *)pBuffer; item.X = p14->x; item.Y = p14->y; item.Z = p14->z; item.intensity = p14->intensity; if (p14->number_of_returns_of_given_pulse > 7) { if (p14->return_number > 6) { if (p14->return_number >= p14->number_of_returns_of_given_pulse) { item.number_of_returns_of_given_pulse = 7; } else { item.number_of_returns_of_given_pulse = 6; } } else { item.return_number = p14->return_number; } item.number_of_returns_of_given_pulse = 7; } else { item.return_number = p14->return_number; item.number_of_returns_of_given_pulse = p14->number_of_returns_of_given_pulse; } item.scan_direction_flag = p14->scan_direction_flag; item.edge_of_flight_line = p14->edge_of_flight_line; item.classification = (byte)((p14->classification_flags << 5) | (p14->classification & 31)); item.scan_angle_rank = MyDefs.I8_CLAMP(MyDefs.I16_QUANTIZE(p14->scan_angle * 0.006)); item.user_data = p14->user_data; item.point_source_ID = p14->point_source_ID; item.extended_scanner_channel = p14->scanner_channel; item.extended_classification_flags = (byte)(p14->classification_flags & 8); // TODO Häää? item.extended_classification = p14->classification; item.extended_return_number = p14->return_number; item.extended_number_of_returns_of_given_pulse = p14->number_of_returns_of_given_pulse; item.extended_scan_angle = p14->scan_angle; item.gps_time = p14->gps_time; } }
public unsafe override bool write(laszip_point item) { fixed(byte *pBuffer = buffer) { LAStempWritePoint14 *p14 = (LAStempWritePoint14 *)pBuffer; p14->x = item.X; p14->y = item.Y; p14->z = item.Z; p14->intensity = item.intensity; p14->scan_direction_flag = item.scan_direction_flag; p14->edge_of_flight_line = item.edge_of_flight_line; p14->classification = (byte)(item.classification & 31); p14->user_data = item.user_data; p14->point_source_ID = item.point_source_ID; if (item.extended_point_type != 0) { p14->classification_flags = (byte)(item.extended_classification_flags | (item.classification >> 5)); if (item.extended_classification > 31) { p14->classification = item.extended_classification; } p14->scanner_channel = item.extended_scanner_channel; p14->return_number = item.extended_return_number; p14->number_of_returns_of_given_pulse = item.extended_number_of_returns_of_given_pulse; p14->scan_angle = item.extended_scan_angle; } else { p14->classification_flags = (byte)(item.classification >> 5); p14->scanner_channel = 0; p14->return_number = item.return_number; p14->number_of_returns_of_given_pulse = item.number_of_returns_of_given_pulse; p14->scan_angle = MyDefs.I16_QUANTIZE(item.scan_angle_rank / 0.006f); } p14->gps_time = item.gps_time; } try { outstream.Write(buffer, 0, 30); } catch { return(false); } return(true); }
public override bool write(laszip_point item) { int diff_l = 0; int diff_h = 0; uint sym = 0; bool rl = (last_item[0] & 0x00FF) != (item.rgb[0] & 0x00FF); if (rl) { sym |= 1; } bool rh = (last_item[0] & 0xFF00) != (item.rgb[0] & 0xFF00); if (rh) { sym |= 2; } bool gl = (last_item[1] & 0x00FF) != (item.rgb[1] & 0x00FF); if (gl) { sym |= 4; } bool gh = (last_item[1] & 0xFF00) != (item.rgb[1] & 0xFF00); if (gh) { sym |= 8; } bool bl = (last_item[2] & 0x00FF) != (item.rgb[2] & 0x00FF); if (bl) { sym |= 16; } bool bh = (last_item[2] & 0xFF00) != (item.rgb[2] & 0xFF00); if (bh) { sym |= 32; } bool allColors = ((item.rgb[0] & 0x00FF) != (item.rgb[1] & 0x00FF)) || ((item.rgb[0] & 0x00FF) != (item.rgb[2] & 0x00FF)) || ((item.rgb[0] & 0xFF00) != (item.rgb[1] & 0xFF00)) || ((item.rgb[0] & 0xFF00) != (item.rgb[2] & 0xFF00)); if (allColors) { sym |= 64; } enc.encodeSymbol(m_byte_used, sym); if (rl) { diff_l = ((int)(item.rgb[0] & 255)) - (last_item[0] & 255); enc.encodeSymbol(m_rgb_diff_0, (byte)MyDefs.U8_FOLD(diff_l)); } if (rh) { diff_h = ((int)(item.rgb[0] >> 8)) - (last_item[0] >> 8); enc.encodeSymbol(m_rgb_diff_1, (byte)MyDefs.U8_FOLD(diff_h)); } if (allColors) { if (gl) { int corr = ((int)(item.rgb[1] & 255)) - MyDefs.U8_CLAMP(diff_l + (last_item[1] & 255)); enc.encodeSymbol(m_rgb_diff_2, (byte)MyDefs.U8_FOLD(corr)); } if (bl) { diff_l = (diff_l + (item.rgb[1] & 255) - (last_item[1] & 255)) / 2; int corr = ((int)(item.rgb[2] & 255)) - MyDefs.U8_CLAMP(diff_l + (last_item[2] & 255)); enc.encodeSymbol(m_rgb_diff_4, (byte)MyDefs.U8_FOLD(corr)); } if (gh) { int corr = ((int)(item.rgb[1] >> 8)) - MyDefs.U8_CLAMP(diff_h + (last_item[1] >> 8)); enc.encodeSymbol(m_rgb_diff_3, (byte)MyDefs.U8_FOLD(corr)); } if (bh) { diff_h = (diff_h + (item.rgb[1] >> 8) - (last_item[1] >> 8)) / 2; int corr = ((int)(item.rgb[2] >> 8)) - MyDefs.U8_CLAMP(diff_h + (last_item[2] >> 8)); enc.encodeSymbol(m_rgb_diff_5, (byte)MyDefs.U8_FOLD(corr)); } } last_item[0] = item.rgb[0]; last_item[1] = item.rgb[1]; last_item[2] = item.rgb[2]; return(true); }
public override void read(laszip_point item) { int corr; int diff = 0; uint sym = dec.decodeSymbol(m_byte_used); if ((sym & (1 << 0)) != 0) { corr = (int)dec.decodeSymbol(m_rgb_diff_0); item.rgb[0] = (ushort)MyDefs.U8_FOLD(corr + (last_item[0] & 255)); } else { item.rgb[0] = (ushort)(last_item[0] & 0xFF); } if ((sym & (1 << 1)) != 0) { corr = (int)dec.decodeSymbol(m_rgb_diff_1); item.rgb[0] |= (ushort)((MyDefs.U8_FOLD(corr + (last_item[0] >> 8))) << 8); } else { item.rgb[0] |= (ushort)(last_item[0] & 0xFF00); } if ((sym & (1 << 6)) != 0) { diff = (item.rgb[0] & 0x00FF) - (last_item[0] & 0x00FF); if ((sym & (1 << 2)) != 0) { corr = (int)dec.decodeSymbol(m_rgb_diff_2); item.rgb[1] = (ushort)MyDefs.U8_FOLD(corr + MyDefs.U8_CLAMP(diff + (last_item[1] & 255))); } else { item.rgb[1] = (ushort)(last_item[1] & 0xFF); } if ((sym & (1 << 4)) != 0) { corr = (int)dec.decodeSymbol(m_rgb_diff_4); diff = (diff + ((item.rgb[1] & 0x00FF) - (last_item[1] & 0x00FF))) / 2; item.rgb[2] = (ushort)MyDefs.U8_FOLD(corr + MyDefs.U8_CLAMP(diff + (last_item[2] & 255))); } else { item.rgb[2] = (ushort)(last_item[2] & 0xFF); } diff = (item.rgb[0] >> 8) - (last_item[0] >> 8); if ((sym & (1 << 3)) != 0) { corr = (int)dec.decodeSymbol(m_rgb_diff_3); item.rgb[1] |= (ushort)((MyDefs.U8_FOLD(corr + MyDefs.U8_CLAMP(diff + (last_item[1] >> 8)))) << 8); } else { item.rgb[1] |= (ushort)(last_item[1] & 0xFF00); } if ((sym & (1 << 5)) != 0) { corr = (int)dec.decodeSymbol(m_rgb_diff_5); diff = (diff + ((item.rgb[1] >> 8) - (last_item[1] >> 8))) / 2; item.rgb[2] |= (ushort)((MyDefs.U8_FOLD(corr + MyDefs.U8_CLAMP(diff + (last_item[2] >> 8)))) << 8); } else { item.rgb[2] |= (ushort)(last_item[2] & 0xFF00); } } else { item.rgb[1] = item.rgb[0]; item.rgb[2] = item.rgb[0]; } last_item[0] = item.rgb[0]; last_item[1] = item.rgb[1]; last_item[2] = item.rgb[2]; }
public override bool write(laszip_point item) { uint r = item.return_number; uint n = item.number_of_returns_of_given_pulse; uint m = Laszip_Common_v2.number_return_map[n, r]; uint l = Laszip_Common_v2.number_return_level[n, r]; // compress which other values have changed uint changed_values = 0; bool needFlags = last.flags != item.flags; if (needFlags) { changed_values |= 32; // bit_byte } bool needIntensity = last_intensity[m] != item.intensity; if (needIntensity) { changed_values |= 16; } bool needClassification = last.classification != item.classification; if (needClassification) { changed_values |= 8; } bool needScanAngleRank = last.scan_angle_rank != item.scan_angle_rank; if (needScanAngleRank) { changed_values |= 4; } bool needUserData = last.user_data != item.user_data; if (needUserData) { changed_values |= 2; } bool needPointSourceID = last.point_source_ID != item.point_source_ID; if (needPointSourceID) { changed_values |= 1; } enc.encodeSymbol(m_changed_values, changed_values); // compress the bit_byte (edge_of_flight_line, scan_direction_flag, returns, ...) if it has changed if (needFlags) { if (m_bit_byte[last.flags] == null) { m_bit_byte[last.flags] = enc.createSymbolModel(256); enc.initSymbolModel(m_bit_byte[last.flags]); } enc.encodeSymbol(m_bit_byte[last.flags], item.flags); } // compress the intensity if it has changed if (needIntensity) { ic_intensity.compress(last_intensity[m], item.intensity, (m < 3?m:3u)); last_intensity[m] = item.intensity; } // compress the classification ... if it has changed if (needClassification) { if (m_classification[last.classification] == null) { m_classification[last.classification] = enc.createSymbolModel(256); enc.initSymbolModel(m_classification[last.classification]); } enc.encodeSymbol(m_classification[last.classification], item.classification); } // compress the scan_angle_rank ... if it has changed if (needScanAngleRank) { enc.encodeSymbol(m_scan_angle_rank[item.scan_direction_flag], (uint)MyDefs.U8_FOLD(item.scan_angle_rank - last.scan_angle_rank)); } // compress the user_data ... if it has changed if (needUserData) { if (m_user_data[last.user_data] == null) { m_user_data[last.user_data] = enc.createSymbolModel(256); enc.initSymbolModel(m_user_data[last.user_data]); } enc.encodeSymbol(m_user_data[last.user_data], item.user_data); } // compress the point_source_ID ... if it has changed if (needPointSourceID) { ic_point_source_ID.compress(last.point_source_ID, item.point_source_ID); } // compress x coordinate int median = last_x_diff_median5[m].get(); int diff = item.X - last.x; ic_dx.compress(median, diff, n == 1?1u:0u); last_x_diff_median5[m].add(diff); // compress y coordinate uint k_bits = ic_dx.getK(); median = last_y_diff_median5[m].get(); diff = item.Y - last.y; ic_dy.compress(median, diff, (n == 1?1u:0u) + (k_bits < 20?k_bits & 0xFEu:20u)); // &0xFE round k_bits to next even number last_y_diff_median5[m].add(diff); // compress z coordinate k_bits = (ic_dx.getK() + ic_dy.getK()) / 2; ic_z.compress(last_height[l], item.Z, (n == 1?1u:0u) + (k_bits < 18?k_bits & 0xFEu:18u)); // &0xFE round k_bits to next even number last_height[l] = item.Z; // copy the last point last.x = item.X; last.y = item.Y; last.z = item.Z; last.intensity = item.intensity; last.flags = item.flags; last.classification = item.classification; last.scan_angle_rank = item.scan_angle_rank; last.user_data = item.user_data; last.point_source_ID = item.point_source_ID; return(true); }
public override bool write(laszip_point item) { U64I64F64 this_gpstime = new U64I64F64(); this_gpstime.f64 = item.gps_time; if (last_gpstime_diff[last] == 0) // if the last integer difference was zero { if (this_gpstime.i64 == last_gpstime[last].i64) { enc.encodeSymbol(m_gpstime_0diff, 0); // the doubles have not changed } else { // calculate the difference between the two doubles as an integer long curr_gpstime_diff_64 = this_gpstime.i64 - last_gpstime[last].i64; int curr_gpstime_diff = (int)curr_gpstime_diff_64; if (curr_gpstime_diff_64 == (long)(curr_gpstime_diff)) { enc.encodeSymbol(m_gpstime_0diff, 1); // the difference can be represented with 32 bits ic_gpstime.compress(0, curr_gpstime_diff, 0); last_gpstime_diff[last] = curr_gpstime_diff; multi_extreme_counter[last] = 0; } else // the difference is huge { // maybe the double belongs to another time sequence for (uint i = 1; i < 4; i++) { long other_gpstime_diff_64 = this_gpstime.i64 - last_gpstime[(last + i) & 3].i64; int other_gpstime_diff = (int)other_gpstime_diff_64; if (other_gpstime_diff_64 == (long)(other_gpstime_diff)) { enc.encodeSymbol(m_gpstime_0diff, i + 2); // it belongs to another sequence last = (last + i) & 3; return(write(item)); } } // no other sequence found. start new sequence. enc.encodeSymbol(m_gpstime_0diff, 2); ic_gpstime.compress((int)(last_gpstime[last].u64 >> 32), (int)(this_gpstime.u64 >> 32), 8); enc.writeInt((uint)(this_gpstime.u64)); next = (next + 1) & 3; last = next; last_gpstime_diff[last] = 0; multi_extreme_counter[last] = 0; } last_gpstime[last].i64 = this_gpstime.i64; } } else // the last integer difference was *not* zero { if (this_gpstime.i64 == last_gpstime[last].i64) { // if the doubles have not changed use a special symbol enc.encodeSymbol(m_gpstime_multi, LASZIP_GPSTIME_MULTI_UNCHANGED); } else { // calculate the difference between the two doubles as an integer long curr_gpstime_diff_64 = this_gpstime.i64 - last_gpstime[last].i64; int curr_gpstime_diff = (int)curr_gpstime_diff_64; // if the current gpstime difference can be represented with 32 bits if (curr_gpstime_diff_64 == (long)(curr_gpstime_diff)) { // compute multiplier between current and last integer difference double multi_f = (double)curr_gpstime_diff / (double)(last_gpstime_diff[last]); int multi = MyDefs.I32_QUANTIZE(multi_f); // compress the residual curr_gpstime_diff in dependance on the multiplier if (multi == 1) { // this is the case we assume we get most often for regular spaced pulses enc.encodeSymbol(m_gpstime_multi, 1); ic_gpstime.compress(last_gpstime_diff[last], curr_gpstime_diff, 1); multi_extreme_counter[last] = 0; } else if (multi > 0) { if (multi < LASZIP_GPSTIME_MULTI) // positive multipliers up to LASZIP_GPSTIME_MULTI are compressed directly { enc.encodeSymbol(m_gpstime_multi, (uint)multi); if (multi < 10) { ic_gpstime.compress(multi * last_gpstime_diff[last], curr_gpstime_diff, 2); } else { ic_gpstime.compress(multi * last_gpstime_diff[last], curr_gpstime_diff, 3); } } else { enc.encodeSymbol(m_gpstime_multi, LASZIP_GPSTIME_MULTI); ic_gpstime.compress(LASZIP_GPSTIME_MULTI * last_gpstime_diff[last], curr_gpstime_diff, 4); multi_extreme_counter[last]++; if (multi_extreme_counter[last] > 3) { last_gpstime_diff[last] = curr_gpstime_diff; multi_extreme_counter[last] = 0; } } } else if (multi < 0) { if (multi > LASZIP_GPSTIME_MULTI_MINUS) // negative multipliers larger than LASZIP_GPSTIME_MULTI_MINUS are compressed directly { enc.encodeSymbol(m_gpstime_multi, (uint)(LASZIP_GPSTIME_MULTI - multi)); ic_gpstime.compress(multi * last_gpstime_diff[last], curr_gpstime_diff, 5); } else { enc.encodeSymbol(m_gpstime_multi, LASZIP_GPSTIME_MULTI - LASZIP_GPSTIME_MULTI_MINUS); ic_gpstime.compress(LASZIP_GPSTIME_MULTI_MINUS * last_gpstime_diff[last], curr_gpstime_diff, 6); multi_extreme_counter[last]++; if (multi_extreme_counter[last] > 3) { last_gpstime_diff[last] = curr_gpstime_diff; multi_extreme_counter[last] = 0; } } } else { enc.encodeSymbol(m_gpstime_multi, 0); ic_gpstime.compress(0, curr_gpstime_diff, 7); multi_extreme_counter[last]++; if (multi_extreme_counter[last] > 3) { last_gpstime_diff[last] = curr_gpstime_diff; multi_extreme_counter[last] = 0; } } } else // the difference is huge { // maybe the double belongs to another time sequence for (uint i = 1; i < 4; i++) { long other_gpstime_diff_64 = this_gpstime.i64 - last_gpstime[(last + i) & 3].i64; int other_gpstime_diff = (int)other_gpstime_diff_64; if (other_gpstime_diff_64 == (long)(other_gpstime_diff)) { // it belongs to this sequence enc.encodeSymbol(m_gpstime_multi, LASZIP_GPSTIME_MULTI_CODE_FULL + i); last = (last + i) & 3; return(write(item)); } } // no other sequence found. start new sequence. enc.encodeSymbol(m_gpstime_multi, LASZIP_GPSTIME_MULTI_CODE_FULL); ic_gpstime.compress((int)(last_gpstime[last].u64 >> 32), (int)(this_gpstime.u64 >> 32), 8); enc.writeInt((uint)(this_gpstime.u64)); next = (next + 1) & 3; last = next; last_gpstime_diff[last] = 0; multi_extreme_counter[last] = 0; } last_gpstime[last].i64 = this_gpstime.i64; } } return(true); }