Exemple #1
0
		public int laszip_close_reader()
		{
			if(reader==null)
			{
				error="closing reader before it was opened";
				return 1;
			}

			try
			{
				if(!reader.done())
				{
					error="done of LASreadPoint failed";
					return 1;
				}

				reader=null;
				streamin.Close();
				streamin=null;
			}
			catch
			{
				error="internal error in laszip_close_reader";
				return 1;
			}

			error=null;
			return 0;
		}
Exemple #2
0
		public int laszip_clean()
		{
			try
			{
				if(reader!=null)
				{
					error="cannot clean while reader is open.";
					return 1;
				}

				if(writer!=null)
				{
					error="cannot clean while writer is open.";
					return 1;
				}

				// zero everything
				header.file_source_ID=0;
				header.global_encoding=0;
				header.project_ID_GUID_data_1=0;
				header.project_ID_GUID_data_2=0;
				header.project_ID_GUID_data_3=0;
				header.project_ID_GUID_data_4=new byte[8];
				header.version_major=0;
				header.version_minor=0;
				header.system_identifier=new byte[32];
				header.generating_software=new byte[32];
				header.file_creation_day=0;
				header.file_creation_year=0;
				header.header_size=0;
				header.offset_to_point_data=0;
				header.number_of_variable_length_records=0;
				header.point_data_format=0;
				header.point_data_record_length=0;
				header.number_of_point_records=0;
				header.number_of_points_by_return=new uint[5];
				header.x_scale_factor=0;
				header.y_scale_factor=0;
				header.z_scale_factor=0;
				header.x_offset=0;
				header.y_offset=0;
				header.z_offset=0;
				header.max_x=0;
				header.min_x=0;
				header.max_y=0;
				header.min_y=0;
				header.max_z=0;
				header.min_z=0;
				header.start_of_waveform_data_packet_record=0;
				header.start_of_first_extended_variable_length_record=0;
				header.number_of_extended_variable_length_records=0;
				header.extended_number_of_point_records=0;
				header.extended_number_of_points_by_return=new ulong[15];
				header.user_data_in_header_size=0;
				header.user_data_in_header=null;
				header.vlrs=null;
				header.user_data_after_header_size=0;
				header.user_data_after_header=null;

				p_count=0;
				npoints=0;

				point.X=0;
				point.Y=0;
				point.Z=0;
				point.intensity=0;
				point.return_number=0;// : 3;
				point.number_of_returns_of_given_pulse=0;// : 3;
				point.scan_direction_flag=0;// : 1;
				point.edge_of_flight_line=0;// : 1;
				point.classification=0;
				point.scan_angle_rank=0;
				point.user_data=0;
				point.point_source_ID=0;
				point.gps_time=0;
				point.rgb=new ushort[4];
				point.wave_packet=new byte[29];
				point.extended_point_type=0;// : 2;
				point.extended_scanner_channel=0;// : 2;
				point.extended_classification_flags=0;// : 4;
				point.extended_classification=0;
				point.extended_return_number=0;// : 4;
				point.extended_number_of_returns_of_given_pulse=0;// : 4;
				point.extended_scan_angle=0;
				point.num_extra_bytes=0;
				point.extra_bytes=null;

				streamin=null;
				reader=null;

				streamout=null;
				writer=null;

				error=null;
				warning=null;

				// create default header
				Array.Copy(Encoding.ASCII.GetBytes(string.Format("LASzip DLL {0}.{1} r{2} ({3})", LASzip.VERSION_MAJOR, LASzip.VERSION_MINOR, LASzip.VERSION_REVISION, LASzip.VERSION_BUILD_DATE)), header.generating_software, 32);
				header.version_major=1;
				header.version_minor=2;
				header.header_size=227;
				header.offset_to_point_data=227;
				header.point_data_format=1;
				header.point_data_record_length=28;
				header.x_scale_factor=0.01;
				header.y_scale_factor=0.01;
				header.z_scale_factor=0.01;
			}
			catch
			{
				error="internal error in laszip_clean";
				return 1;
			}

			return 0;
		}
Exemple #3
0
        public int laszip_open_reader(Stream stream, ref bool is_compressed)
		{
            if (stream == null)
            {
                error = "file stream is empty";
                return 1;
            }

            streamin = stream;

			try
			{
				byte[] buffer=new byte[32];

				#region read the header variable after variable
				if(streamin.Read(buffer, 0, 4)!=4)
				{
					error="reading header.file_signature";
					return 1;
				}

				if(buffer[0]!='L'&&buffer[1]!='A'&&buffer[2]!='S'&&buffer[3]!='F')
				{
					error="wrong file_signature. not a LAS/LAZ file.";
					return 1;
				}

				if(streamin.Read(buffer, 0, 2)!=2)
				{
					error="reading header.file_source_ID";
					return 1;
				}
				header.file_source_ID=BitConverter.ToUInt16(buffer, 0);

				if(streamin.Read(buffer, 0, 2)!=2)
				{
					error="reading header.global_encoding";
					return 1;
				}
				header.global_encoding=BitConverter.ToUInt16(buffer, 0);

				if(streamin.Read(buffer, 0, 4)!=4)
				{
					error="reading header.project_ID_GUID_data_1";
					return 1;
				}
				header.project_ID_GUID_data_1=BitConverter.ToUInt32(buffer, 0);

				if(streamin.Read(buffer, 0, 2)!=2)
				{
					error="reading header.project_ID_GUID_data_2";
					return 1;
				}
				header.project_ID_GUID_data_2=BitConverter.ToUInt16(buffer, 0);

				if(streamin.Read(buffer, 0, 2)!=2)
				{
					error="reading header.project_ID_GUID_data_3";
					return 1;
				}
				header.project_ID_GUID_data_3=BitConverter.ToUInt16(buffer, 0);

				if(streamin.Read(header.project_ID_GUID_data_4, 0, 8)!=8)
				{
					error="reading header.project_ID_GUID_data_4";
					return 1;
				}

				if(streamin.Read(buffer, 0, 1)!=1)
				{
					error="reading header.version_major";
					return 1;
				}
				header.version_major=buffer[0];

				if(streamin.Read(buffer, 0, 1)!=1)
				{
					error="reading header.version_minor";
					return 1;
				}
				header.version_minor=buffer[0];

				if(streamin.Read(header.system_identifier, 0, 32)!=32)
				{
					error="reading header.system_identifier";
					return 1;
				}

				if(streamin.Read(header.generating_software, 0, 32)!=32)
				{
					error="reading header.generating_software";
					return 1;
				}

				if(streamin.Read(buffer, 0, 2)!=2)
				{
					error="reading header.file_creation_day";
					return 1;
				}
				header.file_creation_day=BitConverter.ToUInt16(buffer, 0);

				if(streamin.Read(buffer, 0, 2)!=2)
				{
					error="reading header.file_creation_year";
					return 1;
				}
				header.file_creation_year=BitConverter.ToUInt16(buffer, 0);

				if(streamin.Read(buffer, 0, 2)!=2)
				{
					error="reading header.header_size";
					return 1;
				}
				header.header_size=BitConverter.ToUInt16(buffer, 0);

				if(streamin.Read(buffer, 0, 4)!=4)
				{
					error="reading header.offset_to_point_data";
					return 1;
				}
				header.offset_to_point_data=BitConverter.ToUInt32(buffer, 0);

				if(streamin.Read(buffer, 0, 4)!=4)
				{
					error="reading header.number_of_variable_length_records";
					return 1;
				}
				header.number_of_variable_length_records=BitConverter.ToUInt32(buffer, 0);

				if(streamin.Read(buffer, 0, 1)!=1)
				{
					error="reading header.point_data_format";
					return 1;
				}
				header.point_data_format=buffer[0];

				if(streamin.Read(buffer, 0, 2)!=2)
				{
					error="reading header.point_data_record_length";
					return 1;
				}
				header.point_data_record_length=BitConverter.ToUInt16(buffer, 0);

				if(streamin.Read(buffer, 0, 4)!=4)
				{
					error="reading header.number_of_point_records";
					return 1;
				}
				header.number_of_point_records=BitConverter.ToUInt32(buffer, 0);

				for(int i=0; i<5; i++)
				{
					if(streamin.Read(buffer, 0, 4)!=4)
					{
						error=string.Format("reading header.number_of_points_by_return {0}", i);
						return 1;
					}
					header.number_of_points_by_return[i]=BitConverter.ToUInt32(buffer, 0);
				}

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.x_scale_factor";
					return 1;
				}
				header.x_scale_factor=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.y_scale_factor";
					return 1;
				}
				header.y_scale_factor=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.z_scale_factor";
					return 1;
				}
				header.z_scale_factor=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.x_offset";
					return 1;
				}
				header.x_offset=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.y_offset";
					return 1;
				}
				header.y_offset=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.z_offset";
					return 1;
				}
				header.z_offset=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.max_x";
					return 1;
				}
				header.max_x=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.min_x";
					return 1;
				}
				header.min_x=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.max_y";
					return 1;
				}
				header.max_y=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.min_y";
					return 1;
				}
				header.min_y=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.max_z";
					return 1;
				}
				header.max_z=BitConverter.ToDouble(buffer, 0);

				if(streamin.Read(buffer, 0, 8)!=8)
				{
					error="reading header.min_z";
					return 1;
				}
				header.min_z=BitConverter.ToDouble(buffer, 0);

				// special handling for LAS 1.3
				if((header.version_major==1)&&(header.version_minor>=3))
				{
					if(header.header_size<235)
					{
						error=string.Format("for LAS 1.{0} header_size should at least be 235 but it is only {1}", header.version_minor, header.header_size);
						return 1;
					}
					else
					{
						if(streamin.Read(buffer, 0, 8)!=8)
						{
							error="reading header.start_of_waveform_data_packet_record";
							return 1;
						}
						header.start_of_waveform_data_packet_record=BitConverter.ToUInt64(buffer, 0);
						header.user_data_in_header_size=(uint)header.header_size-235;
					}
				}
				else
				{
					header.user_data_in_header_size=(uint)header.header_size-227;
				}

				// special handling for LAS 1.4
				if((header.version_major==1)&&(header.version_minor>=4))
				{
					if(header.header_size<375)
					{
						error=string.Format("for LAS 1.{0} header_size should at least be 375 but it is only {1}", header.version_minor, header.header_size);
						return 1;
					}
					else
					{
						if(streamin.Read(buffer, 0, 8)!=8)
						{
							error="reading header.start_of_first_extended_variable_length_record";
							return 1;
						}
						header.start_of_first_extended_variable_length_record=BitConverter.ToUInt64(buffer, 0);

						if(streamin.Read(buffer, 0, 4)!=4)
						{
							error="reading header.number_of_extended_variable_length_records";
							return 1;
						}
						header.number_of_extended_variable_length_records=BitConverter.ToUInt32(buffer, 0);

						if(streamin.Read(buffer, 0, 8)!=8)
						{
							error="reading header.extended_number_of_point_records";
							return 1;
						}
						header.extended_number_of_point_records=BitConverter.ToUInt64(buffer, 0);

						for(int i=0; i<15; i++)
						{
							if(streamin.Read(buffer, 0, 8)!=8)
							{
								error=string.Format("reading header.extended_number_of_points_by_return[{0}]", i);
								return 1;
							}
							header.extended_number_of_points_by_return[i]=BitConverter.ToUInt64(buffer, 0);
						}
						header.user_data_in_header_size=(uint)header.header_size-375;
					}
				}

				// load any number of user-defined bytes that might have been added to the header
				if(header.user_data_in_header_size!=0)
				{
					header.user_data_in_header=new byte[header.user_data_in_header_size];

					if(streamin.Read(header.user_data_in_header, 0, (int)header.user_data_in_header_size)!=header.user_data_in_header_size)
					{
						error=string.Format("reading {0} bytes of data into header.user_data_in_header", header.user_data_in_header_size);
						return 1;
					}
				}
				#endregion

				#region read variable length records into the header
				uint vlrs_size=0;
				LASzip laszip=null;

				if(header.number_of_variable_length_records!=0)
				{
					header.vlrs=new List<laszip_vlr>();

					for(int i=0; i<header.number_of_variable_length_records; i++)
					{
						header.vlrs.Add(new laszip_vlr());

						// make sure there are enough bytes left to read a variable length record before the point block starts
						if(((int)header.offset_to_point_data-vlrs_size-header.header_size)<54)
						{
							warning=string.Format("only {0} bytes until point block after reading {1} of {2} vlrs. skipping remaining vlrs ...", (int)header.offset_to_point_data-vlrs_size-header.header_size, i, header.number_of_variable_length_records);
							header.number_of_variable_length_records=(uint)i;
							break;
						}

						// read variable length records variable after variable (to avoid alignment issues)
						if(streamin.Read(buffer, 0, 2)!=2)
						{
							error=string.Format("reading header.vlrs[{0}].reserved", i);
							return 1;
						}
						header.vlrs[i].reserved=BitConverter.ToUInt16(buffer, 0);

						if(streamin.Read(header.vlrs[i].user_id, 0, 16)!=16)
						{
							error=string.Format("reading header.vlrs[{0}].user_id", i);
							return 1;
						}

						if(streamin.Read(buffer, 0, 2)!=2)
						{
							error=string.Format("reading header.vlrs[{0}].record_id", i);
							return 1;
						}
						header.vlrs[i].record_id=BitConverter.ToUInt16(buffer, 0);

						if(streamin.Read(buffer, 0, 2)!=2)
						{
							error=string.Format("reading header.vlrs[{0}].record_length_after_header", i);
							return 1;
						}
						header.vlrs[i].record_length_after_header=BitConverter.ToUInt16(buffer, 0);

						if(streamin.Read(header.vlrs[i].description, 0, 32)!=32)
						{
							error=string.Format("reading header.vlrs[{0}].description", i);
							return 1;
						}

						// keep track on the number of bytes we have read so far
						vlrs_size+=54;

						// check variable length record contents
						if(header.vlrs[i].reserved!=0xAABB)
						{
							warning=string.Format("wrong header.vlrs[{0}].reserved: {1} != 0xAABB", i, header.vlrs[i].reserved);
						}

						// make sure there are enough bytes left to read the data of the variable length record before the point block starts
						if(((int)header.offset_to_point_data-vlrs_size-header.header_size)<header.vlrs[i].record_length_after_header)
						{
							warning=string.Format("only {0} bytes until point block when trying to read {1} bytes into header.vlrs[{2}].data", (int)header.offset_to_point_data-vlrs_size-header.header_size, header.vlrs[i].record_length_after_header, i);
							header.vlrs[i].record_length_after_header=(ushort)(header.offset_to_point_data-vlrs_size-header.header_size);
						}

						string userid="";
						for(int a=0; a<header.vlrs[i].user_id.Length; a++)
						{
							if(header.vlrs[i].user_id[a]==0) break;
							userid+=(char)header.vlrs[i].user_id[a];
						}

						// load data following the header of the variable length record
						if(header.vlrs[i].record_length_after_header!=0)
						{
							if(userid=="laszip encoded")
							{
								laszip=new LASzip();

								// read the LASzip VLR payload

								//     U16  compressor                2 bytes 
								//     U32  coder                     2 bytes 
								//     U8   version_major             1 byte 
								//     U8   version_minor             1 byte
								//     U16  version_revision          2 bytes
								//     U32  options                   4 bytes 
								//     I32  chunk_size                4 bytes
								//     I64  number_of_special_evlrs   8 bytes
								//     I64  offset_to_special_evlrs   8 bytes
								//     U16  num_items                 2 bytes
								//        U16 type                2 bytes * num_items
								//        U16 size                2 bytes * num_items
								//        U16 version             2 bytes * num_items
								// which totals 34+6*num_items

								if(streamin.Read(buffer, 0, 2)!=2)
								{
									error="reading compressor";
									return 1;
								}
								laszip.compressor=BitConverter.ToUInt16(buffer, 0);

								if(streamin.Read(buffer, 0, 2)!=2)
								{
									error="reading coder";
									return 1;
								}
								laszip.coder=BitConverter.ToUInt16(buffer, 0);

								if(streamin.Read(buffer, 0, 1)!=1)
								{
									error="reading version_major";
									return 1;
								}
								laszip.version_major=buffer[0];

								if(streamin.Read(buffer, 0, 1)!=1)
								{
									error="reading version_minor";
									return 1;
								}
								laszip.version_minor=buffer[0];

								if(streamin.Read(buffer, 0, 2)!=2)
								{
									error="reading version_revision";
									return 1;
								}
								laszip.version_revision=BitConverter.ToUInt16(buffer, 0);

								if(streamin.Read(buffer, 0, 4)!=4)
								{
									error="reading options";
									return 1;
								}
								laszip.options=BitConverter.ToUInt32(buffer, 0);

								if(streamin.Read(buffer, 0, 4)!=4)
								{
									error="reading chunk_size";
									return 1;
								}
								laszip.chunk_size=BitConverter.ToUInt32(buffer, 0);

								if(streamin.Read(buffer, 0, 8)!=8)
								{
									error="reading number_of_special_evlrs";
									return 1;
								}
								laszip.number_of_special_evlrs=BitConverter.ToInt64(buffer, 0);

								if(streamin.Read(buffer, 0, 8)!=8)
								{
									error="reading offset_to_special_evlrs";
									return 1;
								}
								laszip.offset_to_special_evlrs=BitConverter.ToInt64(buffer, 0);

								if(streamin.Read(buffer, 0, 2)!=2)
								{
									error="reading num_items";
									return 1;
								}
								laszip.num_items=BitConverter.ToUInt16(buffer, 0);

								laszip.items=new LASitem[laszip.num_items];
								for(int j=0; j<laszip.num_items; j++)
								{
									laszip.items[j]=new LASitem();

									if(streamin.Read(buffer, 0, 2)!=2)
									{
										error=string.Format("reading type of item {0}", j);
										return 1;
									}
									laszip.items[j].type=(LASitem.Type)BitConverter.ToUInt16(buffer, 0);

									if(streamin.Read(buffer, 0, 2)!=2)
									{
										error=string.Format("reading size of item {0}", j);
										return 1;
									}
									laszip.items[j].size=BitConverter.ToUInt16(buffer, 0);

									if(streamin.Read(buffer, 0, 2)!=2)
									{
										error=string.Format("reading version of item {0}", j);
										return 1;
									}
									laszip.items[j].version=BitConverter.ToUInt16(buffer, 0);
								}
							}
							else
							{
								header.vlrs[i].data=new byte[header.vlrs[i].record_length_after_header];
								if(streamin.Read(header.vlrs[i].data, 0, header.vlrs[i].record_length_after_header)!=header.vlrs[i].record_length_after_header)
								{
									error=string.Format("reading {0} bytes of data into header.vlrs[{1}].data", header.vlrs[i].record_length_after_header, i);
									return 1;
								}
							}
						}
						else
						{
							header.vlrs[i].data=null;
						}

						// keep track on the number of bytes we have read so far
						vlrs_size+=header.vlrs[i].record_length_after_header;

						// special handling for LASzip VLR
						if(userid=="laszip encoded")
						{
							// we take our the VLR for LASzip away
							header.offset_to_point_data-=(uint)(54+header.vlrs[i].record_length_after_header);
							vlrs_size-=(uint)(54+header.vlrs[i].record_length_after_header);
							header.vlrs.RemoveAt(i);
							i--;
							header.number_of_variable_length_records--;
						}
					}
				}
				#endregion

				// load any number of user-defined bytes that might have been added after the header
				header.user_data_after_header_size=header.offset_to_point_data-vlrs_size-header.header_size;
				if(header.user_data_after_header_size!=0)
				{
					header.user_data_after_header=new byte[header.user_data_after_header_size];

					if(streamin.Read(header.user_data_after_header, 0, (int)header.user_data_after_header_size)!=header.user_data_after_header_size)
					{
						error=string.Format("reading {0} bytes of data into header.user_data_after_header", header.user_data_after_header_size);
						return 1;
					}
				}

				// remove extra bits in point data type
				if((header.point_data_format&128)!=0||(header.point_data_format&64)!=0)
				{
					if(laszip==null)
					{
						error="this file was compressed with an experimental version of LASzip. contact '*****@*****.**' for assistance";
						return 1;
					}
					header.point_data_format&=127;
				}

				// check if file is compressed
				if(laszip!=null)
				{
					// yes. check the compressor state
					is_compressed=true;
					if(!laszip.check())
					{
						error=string.Format("{0} upgrade to the latest release of LAStools (with LASzip) or contact '*****@*****.**' for assistance", laszip.get_error());
						return 1;
					}
				}
				else
				{
					// no. setup an un-compressed read
					is_compressed=false;
					laszip=new LASzip();
					if(!laszip.setup(header.point_data_format, header.point_data_record_length, LASzip.COMPRESSOR_NONE))
					{
						error=string.Format("invalid combination of point_data_format {0} and point_data_record_length {1}", header.point_data_format, header.point_data_record_length);
						return 1;
					}
				}

				// create point's item pointers
				for(int i=0; i<laszip.num_items; i++)
				{
					switch(laszip.items[i].type)
					{
						case LASitem.Type.POINT14:
						case LASitem.Type.POINT10:
						case LASitem.Type.GPSTIME11:
						case LASitem.Type.RGBNIR14:
						case LASitem.Type.RGB12:
						case LASitem.Type.WAVEPACKET13:
							break;
						case LASitem.Type.BYTE:
							point.num_extra_bytes=laszip.items[i].size;
							point.extra_bytes=new byte[point.num_extra_bytes];
							break;
						default:
							error=string.Format("unknown LASitem type {0}", laszip.items[i].type);
							return 1;
					}
				}

				// create the point reader
				reader=new LASreadPoint();
				if(!reader.setup(laszip.num_items, laszip.items, laszip))
				{
					error="setup of LASreadPoint failed";
					return 1;
				}

				if(!reader.init(streamin))
				{
					error="init of LASreadPoint failed";
					return 1;
				}

				laszip=null;

				// set the point number and point count
				npoints=header.number_of_point_records;
				p_count=0;
			}
			catch
			{
				error="internal error in laszip_open_reader";
				return 1;
			}

			error=null;
			return 0;
		}