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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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];
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }