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; }
public int laszip_open_writer(string file_name, bool compress) { if(file_name==null||file_name.Length==0) { error="string file_name pointer is zero"; return 1; } if(reader!=null) { error="reader is already open"; return 1; } if(writer!=null) { error="writer is already open"; return 1; } try { #region check header and prepare point uint vlrs_size=0; if(header.version_major!=1) { error=string.Format("unknown LAS version {0}.{1}", header.version_major, header.version_minor); return 1; } if(compress&&(header.point_data_format>5)) { error=string.Format("compressor does not yet support point data format {1}", header.point_data_format); return 1; } if(header.number_of_variable_length_records!=0) { if(header.vlrs==null) { error=string.Format("number_of_variable_length_records is {0} but vlrs pointer is zero", header.number_of_variable_length_records); return 1; } for(int i=0; i<header.number_of_variable_length_records; i++) { vlrs_size+=54; if(header.vlrs[i].record_length_after_header!=0) { if(header.vlrs==null) { error=string.Format("vlrs[{0}].record_length_after_header is {1} but vlrs[{0}].data pointer is zero", i, header.vlrs[i].record_length_after_header); return 1; } vlrs_size+=header.vlrs[i].record_length_after_header; } } } if((vlrs_size+header.header_size+header.user_data_after_header_size)!=header.offset_to_point_data) { error=string.Format("header_size ({0}) plus vlrs_size ({1}) plus user_data_after_header_size ({2}) does not equal offset_to_point_data ({3})", header.header_size, vlrs_size, header.user_data_after_header_size, header.offset_to_point_data); return 1; } LASzip laszip=null; try { laszip=new LASzip(); } catch { error="could not alloc LASzip"; return 1; } 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; } #region create point's item pointers for(uint 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; } } #endregion uint laszip_vrl_payload_size=0; if(compress) { if(!laszip.setup(header.point_data_format, header.point_data_record_length, LASzip.COMPRESSOR_DEFAULT)) { error=string.Format("cannot compress point_data_format {0} with point_data_record_length {1}", header.point_data_format, header.point_data_record_length); return 1; } laszip.request_version(2); laszip_vrl_payload_size=34u+6u*laszip.num_items; } else { laszip.request_version(0); } #endregion #region open the file try { streamout=new FileStream(file_name, FileMode.Create, FileAccess.Write, FileShare.Read); } catch { error=string.Format("cannot open file '{0}'", file_name); return 1; } #endregion #region write the header variable after variable try { streamout.WriteByte((byte)'L'); streamout.WriteByte((byte)'A'); streamout.WriteByte((byte)'S'); streamout.WriteByte((byte)'F'); } catch { error="writing header.file_signature"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.file_source_ID), 0, 2); } catch { error="writing header.file_source_ID"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.global_encoding), 0, 2); } catch { error="writing header.global_encoding"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.project_ID_GUID_data_1), 0, 4); } catch { error="writing header.project_ID_GUID_data_1"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.project_ID_GUID_data_2), 0, 2); } catch { error="writing header.project_ID_GUID_data_2"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.project_ID_GUID_data_3), 0, 2); } catch { error="writing header.project_ID_GUID_data_3"; return 1; } try { streamout.Write(header.project_ID_GUID_data_4, 0, 8); } catch { error="writing header.project_ID_GUID_data_4"; return 1; } try { streamout.WriteByte(header.version_major); } catch { error="writing header.version_major"; return 1; } try { streamout.WriteByte(header.version_minor); } catch { error="writing header.version_minor"; return 1; } try { streamout.Write(header.system_identifier, 0, 32); } catch { error="writing header.system_identifier"; return 1; } byte[] generatingSoftware=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)); Array.Copy(generatingSoftware, header.generating_software, Math.Min(generatingSoftware.Length, 32)); try { streamout.Write(header.generating_software, 0, 32); } catch { error="writing header.generating_software"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.file_creation_day), 0, 2); } catch { error="writing header.file_creation_day"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.file_creation_year), 0, 2); } catch { error="writing header.file_creation_year"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.header_size), 0, 2); } catch { error="writing header.header_size"; return 1; } if(compress) header.offset_to_point_data+=(54+laszip_vrl_payload_size); try { streamout.Write(BitConverter.GetBytes(header.offset_to_point_data), 0, 4); } catch { error="writing header.offset_to_point_data"; return 1; } if(compress) { header.offset_to_point_data-=(54+laszip_vrl_payload_size); header.number_of_variable_length_records+=1; } try { streamout.Write(BitConverter.GetBytes(header.number_of_variable_length_records), 0, 4); } catch { error="writing header.number_of_variable_length_records"; return 1; } if(compress) { header.number_of_variable_length_records-=1; header.point_data_format|=128; } try { streamout.WriteByte(header.point_data_format); } catch { error="writing header.point_data_format"; return 1; } if(compress) header.point_data_format&=127; try { streamout.Write(BitConverter.GetBytes(header.point_data_record_length), 0, 2); } catch { error="writing header.point_data_record_length"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.number_of_point_records), 0, 4); } catch { error="writing header.number_of_point_records"; return 1; } for(uint i=0; i<5; i++) { try { streamout.Write(BitConverter.GetBytes(header.number_of_points_by_return[i]), 0, 4); } catch { error=string.Format("writing header.number_of_points_by_return {0}", i); return 1; } } try { streamout.Write(BitConverter.GetBytes(header.x_scale_factor), 0, 8); } catch { error="writing header.x_scale_factor"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.y_scale_factor), 0, 8); } catch { error="writing header.y_scale_factor"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.z_scale_factor), 0, 8); } catch { error="writing header.z_scale_factor"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.x_offset), 0, 8); } catch { error="writing header.x_offset"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.y_offset), 0, 8); } catch { error="writing header.y_offset"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.z_offset), 0, 8); } catch { error="writing header.z_offset"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.max_x), 0, 8); } catch { error="writing header.max_x"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.min_x), 0, 8); } catch { error="writing header.min_x"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.max_y), 0, 8); } catch { error="writing header.max_y"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.min_y), 0, 8); } catch { error="writing header.min_y"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.max_z), 0, 8); } catch { error="writing header.max_z"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.min_z), 0, 8); } catch { error="writing header.min_z"; return 1; } #region 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; } try { streamout.Write(BitConverter.GetBytes(header.start_of_waveform_data_packet_record), 0, 8); } catch { error="writing header.start_of_waveform_data_packet_record"; return 1; } header.user_data_in_header_size=header.header_size-235u; } else header.user_data_in_header_size=header.header_size-227u; #endregion #region 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; } try { streamout.Write(BitConverter.GetBytes(header.start_of_first_extended_variable_length_record), 0, 8); } catch { error="writing header.start_of_first_extended_variable_length_record"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.number_of_extended_variable_length_records), 0, 4); } catch { error="writing header.number_of_extended_variable_length_records"; return 1; } try { streamout.Write(BitConverter.GetBytes(header.extended_number_of_point_records), 0, 8); } catch { error="writing header.extended_number_of_point_records"; return 1; } for(uint i=0; i<15; i++) { try { streamout.Write(BitConverter.GetBytes(header.extended_number_of_points_by_return[i]), 0, 8); } catch { error=string.Format("writing header.extended_number_of_points_by_return[{0}]", i); return 1; } } header.user_data_in_header_size=header.header_size-375u; } #endregion #region write any number of user-defined bytes that might have been added to the header if(header.user_data_in_header_size!=0) { try { streamout.Write(header.user_data_in_header, 0, (int)header.user_data_in_header_size); } catch { error=string.Format("writing {0} bytes of data into header.user_data_in_header", header.user_data_in_header_size); return 1; } } #endregion #region write variable length records into the header if(header.number_of_variable_length_records!=0) { for(int i=0; i<header.number_of_variable_length_records; i++) { // write variable length records variable after variable (to avoid alignment issues) try { streamout.Write(BitConverter.GetBytes(header.vlrs[i].reserved), 0, 2); } catch { error=string.Format("writing header.vlrs[{0}].reserved", i); return 1; } try { streamout.Write(header.vlrs[i].user_id, 0, 16); } catch { error=string.Format("writing header.vlrs[{0}].user_id", i); return 1; } try { streamout.Write(BitConverter.GetBytes(header.vlrs[i].record_id), 0, 2); } catch { error=string.Format("writing header.vlrs[{0}].record_id", i); return 1; } try { streamout.Write(BitConverter.GetBytes(header.vlrs[i].record_length_after_header), 0, 2); } catch { error=string.Format("writing header.vlrs[{0}].record_length_after_header", i); return 1; } try { streamout.Write(header.vlrs[i].description, 0, 32); } catch { error=string.Format("writing header.vlrs[{0}].description", i); return 1; } // write data following the header of the variable length record if(header.vlrs[i].record_length_after_header!=0) { try { streamout.Write(header.vlrs[i].data, 0, header.vlrs[i].record_length_after_header); } catch { error=string.Format("writing {0} bytes of data into header.vlrs[{1}].data", header.vlrs[i].record_length_after_header, i); return 1; } } } } if(compress) { #region write the LASzip VLR header uint i=header.number_of_variable_length_records; ushort reserved=0xAABB; try { streamout.Write(BitConverter.GetBytes(reserved), 0, 2); } catch { error=string.Format("writing header.vlrs[{0}].reserved", i); return 1; } byte[] user_id1=Encoding.ASCII.GetBytes("laszip encoded"); byte[] user_id=new byte[16]; Array.Copy(user_id1, user_id, Math.Min(16, user_id1.Length)); try { streamout.Write(user_id, 0, 16); } catch { error=string.Format("writing header.vlrs[{0}].user_id", i); return 1; } ushort record_id=22204; try { streamout.Write(BitConverter.GetBytes(record_id), 0, 2); } catch { error=string.Format("writing header.vlrs[{0}].record_id", i); return 1; } ushort record_length_after_header=(ushort)laszip_vrl_payload_size; try { streamout.Write(BitConverter.GetBytes(record_length_after_header), 0, 2); } catch { error=string.Format("writing header.vlrs[{0}].record_length_after_header", i); return 1; } byte[] description1=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)); byte[] description=new byte[32]; try { streamout.Write(description, 0, 32); } catch { error=string.Format("writing header.vlrs[{0}].description", i); return 1; } // write 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 try { streamout.Write(BitConverter.GetBytes(laszip.compressor), 0, 2); } catch { error=string.Format("writing compressor {0}", laszip.compressor); return 1; } try { streamout.Write(BitConverter.GetBytes(laszip.coder), 0, 2); } catch { error=string.Format("writing coder {0}", laszip.coder); return 1; } try { streamout.WriteByte(laszip.version_major); } catch { error=string.Format("writing version_major {0}", laszip.version_major); return 1; } try { streamout.WriteByte(laszip.version_minor); } catch { error=string.Format("writing version_minor {0}", laszip.version_minor); return 1; } try { streamout.Write(BitConverter.GetBytes(laszip.version_revision), 0, 2); } catch { error=string.Format("writing version_revision {0}", laszip.version_revision); return 1; } try { streamout.Write(BitConverter.GetBytes(laszip.options), 0, 4); } catch { error=string.Format("writing options {0}", laszip.options); return 1; } try { streamout.Write(BitConverter.GetBytes(laszip.chunk_size), 0, 4); } catch { error=string.Format("writing chunk_size {0}", laszip.chunk_size); return 1; } try { streamout.Write(BitConverter.GetBytes(laszip.number_of_special_evlrs), 0, 8); } catch { error=string.Format("writing number_of_special_evlrs {0}", laszip.number_of_special_evlrs); return 1; } try { streamout.Write(BitConverter.GetBytes(laszip.offset_to_special_evlrs), 0, 8); } catch { error=string.Format("writing offset_to_special_evlrs {0}", laszip.offset_to_special_evlrs); return 1; } try { streamout.Write(BitConverter.GetBytes(laszip.num_items), 0, 2); } catch { error=string.Format("writing num_items {0}", laszip.num_items); return 1; } for(uint j=0; j<laszip.num_items; j++) { ushort type=(ushort)laszip.items[j].type; try { streamout.Write(BitConverter.GetBytes(type), 0, 2); } catch { error=string.Format("writing type {0} of item {1}", laszip.items[j].type, j); return 1; } try { streamout.Write(BitConverter.GetBytes(laszip.items[j].size), 0, 2); } catch { error=string.Format("writing size {0} of item {1}", laszip.items[j].size, j); return 1; } try { streamout.Write(BitConverter.GetBytes(laszip.items[j].version), 0, 2); } catch { error=string.Format("writing version {0} of item {1}", laszip.items[j].version, j); return 1; } } #endregion } #endregion #region write any number of user-defined bytes that might have been added after the header if(header.user_data_after_header_size!=0) { try { streamout.Write(header.user_data_after_header, 0, (int)header.user_data_after_header_size); } catch { error=string.Format("writing {0} bytes of data into header.user_data_after_header", header.user_data_after_header_size); return 1; } } #endregion #endregion #region create the point writer try { writer=new LASwritePoint(); } catch { error="could not alloc LASwritePoint"; return 1; } if(!writer.setup(laszip.num_items, laszip.items, laszip)) { error="setup of LASwritePoint failed"; return 1; } if(!writer.init(streamout)) { error="init of LASwritePoint failed"; return 1; } #endregion // set the point number and point count npoints=header.number_of_point_records; p_count=0; } catch { error=string.Format("internal error in laszip_open_writer '{0}'", file_name); return 1; } error=null; return 0; }
public int laszip_close_writer() { if(writer==null) { error="closing writer before it was opened"; return 1; } try { if(!writer.done()) { error="done of LASwritePoint failed"; return 1; } writer=null; streamout.Close(); streamout=null; } catch { error="internal error in laszip_writer_close"; return 1; } error=null; return 0; }