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;
		}
Ejemplo n.º 2
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);
        }