BOOL LASwriterLAS::open(ByteStreamOut* stream, const LASheader* header, U32 compressor, I32 requested_version, I32 chunk_size) { U32 i, j; if (stream == 0) { fprintf(stderr,"ERROR: ByteStreamOut pointer is zero\n"); return FALSE; } this->stream = stream; if (header == 0) { fprintf(stderr,"ERROR: LASheader pointer is zero\n"); return FALSE; } // check header contents if (!header->check()) return FALSE; // copy scale_and_offset quantizer.x_scale_factor = header->x_scale_factor; quantizer.y_scale_factor = header->y_scale_factor; quantizer.z_scale_factor = header->z_scale_factor; quantizer.x_offset = header->x_offset; quantizer.y_offset = header->y_offset; quantizer.z_offset = header->z_offset; // check if the requested point type is supported LASpoint point; U8 point_data_format; U16 point_data_record_length; BOOL point_is_standard = TRUE; if (header->laszip) { if (!point.init(&quantizer, header->laszip->num_items, header->laszip->items, header)) return FALSE; point_is_standard = header->laszip->is_standard(&point_data_format, &point_data_record_length); } else { if (!point.init(&quantizer, header->point_data_format, header->point_data_record_length, header)) return FALSE; point_data_format = header->point_data_format; point_data_record_length = header->point_data_record_length; } // do we need a LASzip VLR (because we compress or use non-standard points?) LASzip* laszip = 0; U32 laszip_vlr_data_size = 0; if (compressor || point_is_standard == FALSE) { laszip = new LASzip(); laszip->setup(point.num_items, point.items, compressor); if (chunk_size > -1) laszip->set_chunk_size((U32)chunk_size); if (compressor == LASZIP_COMPRESSOR_NONE) laszip->request_version(0); else if (chunk_size == 0) { fprintf(stderr,"ERROR: adaptive chunking is depricated\n"); return FALSE; } else if (requested_version) laszip->request_version(requested_version); else laszip->request_version(2); laszip_vlr_data_size = 34 + 6*laszip->num_items; } // create and setup the point writer writer = new LASwritePoint(); if (laszip) { if (!writer->setup(laszip->num_items, laszip->items, laszip)) { fprintf(stderr,"ERROR: point type %d of size %d not supported (with LASzip)\n", header->point_data_format, header->point_data_record_length); return FALSE; } } else { if (!writer->setup(point.num_items, point.items)) { fprintf(stderr,"ERROR: point type %d of size %d not supported\n", header->point_data_format, header->point_data_record_length); return FALSE; } } // save the position where we start writing the header header_start_position = stream->tell(); // write header variable after variable (to avoid alignment issues) if (!stream->putBytes((U8*)&(header->file_signature), 4)) { fprintf(stderr,"ERROR: writing header->file_signature\n"); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->file_source_ID))) { fprintf(stderr,"ERROR: writing header->file_source_ID\n"); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->global_encoding))) { fprintf(stderr,"ERROR: writing header->global_encoding\n"); return FALSE; } if (!stream->put32bitsLE((U8*)&(header->project_ID_GUID_data_1))) { fprintf(stderr,"ERROR: writing header->project_ID_GUID_data_1\n"); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->project_ID_GUID_data_2))) { fprintf(stderr,"ERROR: writing header->project_ID_GUID_data_2\n"); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->project_ID_GUID_data_3))) { fprintf(stderr,"ERROR: writing header->project_ID_GUID_data_3\n"); return FALSE; } if (!stream->putBytes((U8*)header->project_ID_GUID_data_4, 8)) { fprintf(stderr,"ERROR: writing header->project_ID_GUID_data_4\n"); return FALSE; } // check version major U8 version_major = header->version_major; if (header->version_major != 1) { fprintf(stderr,"WARNING: header->version_major is %d. writing 1 instead.\n", header->version_major); version_major = 1; } if (!stream->putByte(header->version_major)) { fprintf(stderr,"ERROR: writing header->version_major\n"); return FALSE; } // check version minor U8 version_minor = header->version_minor; if (version_minor > 4) { fprintf(stderr,"WARNING: header->version_minor is %d. writing 4 instead.\n", version_minor); version_minor = 4; } if (!stream->putByte(version_minor)) { fprintf(stderr,"ERROR: writing header->version_minor\n"); return FALSE; } if (!stream->putBytes((U8*)header->system_identifier, 32)) { fprintf(stderr,"ERROR: writing header->system_identifier\n"); return FALSE; } if (!stream->putBytes((U8*)header->generating_software, 32)) { fprintf(stderr,"ERROR: writing header->generating_software\n"); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->file_creation_day))) { fprintf(stderr,"ERROR: writing header->file_creation_day\n"); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->file_creation_year))) { fprintf(stderr,"ERROR: writing header->file_creation_year\n"); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->header_size))) { fprintf(stderr,"ERROR: writing header->header_size\n"); return FALSE; } U32 offset_to_point_data = header->offset_to_point_data; if (laszip) offset_to_point_data += (54 + laszip_vlr_data_size); if (header->vlr_lastiling) offset_to_point_data += (54 + 28); if (header->vlr_lasoriginal) offset_to_point_data += (54 + 176); if (!stream->put32bitsLE((U8*)&offset_to_point_data)) { fprintf(stderr,"ERROR: writing header->offset_to_point_data\n"); return FALSE; } U32 number_of_variable_length_records = header->number_of_variable_length_records; if (laszip) number_of_variable_length_records++; if (header->vlr_lastiling) number_of_variable_length_records++; if (header->vlr_lasoriginal) number_of_variable_length_records++; if (!stream->put32bitsLE((U8*)&(number_of_variable_length_records))) { fprintf(stderr,"ERROR: writing header->number_of_variable_length_records\n"); return FALSE; } if (compressor) point_data_format |= 128; if (!stream->putByte(point_data_format)) { fprintf(stderr,"ERROR: writing header->point_data_format\n"); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->point_data_record_length))) { fprintf(stderr,"ERROR: writing header->point_data_record_length\n"); return FALSE; } if (!stream->put32bitsLE((U8*)&(header->number_of_point_records))) { fprintf(stderr,"ERROR: writing header->number_of_point_records\n"); return FALSE; } for (i = 0; i < 5; i++) { if (!stream->put32bitsLE((U8*)&(header->number_of_points_by_return[i]))) { fprintf(stderr,"ERROR: writing header->number_of_points_by_return[%d]\n", i); return FALSE; } } if (!stream->put64bitsLE((U8*)&(header->x_scale_factor))) { fprintf(stderr,"ERROR: writing header->x_scale_factor\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->y_scale_factor))) { fprintf(stderr,"ERROR: writing header->y_scale_factor\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->z_scale_factor))) { fprintf(stderr,"ERROR: writing header->z_scale_factor\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->x_offset))) { fprintf(stderr,"ERROR: writing header->x_offset\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->y_offset))) { fprintf(stderr,"ERROR: writing header->y_offset\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->z_offset))) { fprintf(stderr,"ERROR: writing header->z_offset\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->max_x))) { fprintf(stderr,"ERROR: writing header->max_x\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->min_x))) { fprintf(stderr,"ERROR: writing header->min_x\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->max_y))) { fprintf(stderr,"ERROR: writing header->max_y\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->min_y))) { fprintf(stderr,"ERROR: writing header->min_y\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->max_z))) { fprintf(stderr,"ERROR: writing header->max_z\n"); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->min_z))) { fprintf(stderr,"ERROR: writing header->min_z\n"); return FALSE; } // special handling for LAS 1.3 or higher. if (version_minor >= 3) { U64 start_of_waveform_data_packet_record = header->start_of_waveform_data_packet_record; if (start_of_waveform_data_packet_record != 0) { #ifdef _WIN32 fprintf(stderr,"WARNING: header->start_of_waveform_data_packet_record is %I64d. writing 0 instead.\n", start_of_waveform_data_packet_record); #else fprintf(stderr,"WARNING: header->start_of_waveform_data_packet_record is %lld. writing 0 instead.\n", start_of_waveform_data_packet_record); #endif start_of_waveform_data_packet_record = 0; } if (!stream->put64bitsLE((U8*)&start_of_waveform_data_packet_record)) { fprintf(stderr,"ERROR: writing start_of_waveform_data_packet_record\n"); return FALSE; } } // special handling for LAS 1.4 or higher. if (version_minor >= 4) { writing_las_1_4 = TRUE; if (header->point_data_format >= 6) { writing_new_point_type = TRUE; } else { writing_new_point_type = FALSE; } U64 start_of_first_extended_variable_length_record = header->start_of_first_extended_variable_length_record; if (start_of_first_extended_variable_length_record != 0) { #ifdef _WIN32 fprintf(stderr,"WARNING: EVLRs not supported. header->start_of_first_extended_variable_length_record is %I64d. writing 0 instead.\n", start_of_first_extended_variable_length_record); #else fprintf(stderr,"WARNING: EVLRs not supported. header->start_of_first_extended_variable_length_record is %lld. writing 0 instead.\n", start_of_first_extended_variable_length_record); #endif start_of_first_extended_variable_length_record = 0; } if (!stream->put64bitsLE((U8*)&(start_of_first_extended_variable_length_record))) { fprintf(stderr,"ERROR: writing header->start_of_first_extended_variable_length_record\n"); return FALSE; } U32 number_of_extended_variable_length_records = header->number_of_extended_variable_length_records; if (number_of_extended_variable_length_records != 0) { fprintf(stderr,"WARNING: EVLRs not supported. header->number_of_extended_variable_length_records is %u. writing 0 instead.\n", number_of_extended_variable_length_records); number_of_extended_variable_length_records = 0; } if (!stream->put32bitsLE((U8*)&(number_of_extended_variable_length_records))) { fprintf(stderr,"ERROR: writing header->number_of_extended_variable_length_records\n"); return FALSE; } U64 extended_number_of_point_records; if (header->number_of_point_records) extended_number_of_point_records = header->number_of_point_records; else extended_number_of_point_records = header->extended_number_of_point_records; if (!stream->put64bitsLE((U8*)&extended_number_of_point_records)) { fprintf(stderr,"ERROR: writing header->extended_number_of_point_records\n"); return FALSE; } U64 extended_number_of_points_by_return; for (i = 0; i < 15; i++) { if ((i < 5) && header->number_of_points_by_return[i]) extended_number_of_points_by_return = header->number_of_points_by_return[i]; else extended_number_of_points_by_return = header->extended_number_of_points_by_return[i]; if (!stream->put64bitsLE((U8*)&extended_number_of_points_by_return)) { fprintf(stderr,"ERROR: writing header->extended_number_of_points_by_return[%d]\n", i); return FALSE; } } } else { writing_las_1_4 = FALSE; writing_new_point_type = FALSE; } // write any number of user-defined bytes that might have been added into the header if (header->user_data_in_header_size) { if (header->user_data_in_header) { if (!stream->putBytes((U8*)header->user_data_in_header, header->user_data_in_header_size)) { fprintf(stderr,"ERROR: writing %d bytes of data from header->user_data_in_header\n", header->user_data_in_header_size); return FALSE; } } else { fprintf(stderr,"ERROR: there should be %d bytes of data in header->user_data_in_header\n", header->user_data_in_header_size); return FALSE; } } // write variable length records variable after variable (to avoid alignment issues) for (i = 0; i < header->number_of_variable_length_records; i++) { // check variable length records contents if (header->vlrs[i].reserved != 0xAABB) { // fprintf(stderr,"WARNING: wrong header->vlrs[%d].reserved: %d != 0xAABB\n", i, header->vlrs[i].reserved); } // write variable length records variable after variable (to avoid alignment issues) if (!stream->put16bitsLE((U8*)&(header->vlrs[i].reserved))) { fprintf(stderr,"ERROR: writing header->vlrs[%d].reserved\n", i); return FALSE; } if (!stream->putBytes((U8*)header->vlrs[i].user_id, 16)) { fprintf(stderr,"ERROR: writing header->vlrs[%d].user_id\n", i); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->vlrs[i].record_id))) { fprintf(stderr,"ERROR: writing header->vlrs[%d].record_id\n", i); return FALSE; } if (!stream->put16bitsLE((U8*)&(header->vlrs[i].record_length_after_header))) { fprintf(stderr,"ERROR: writing header->vlrs[%d].record_length_after_header\n", i); return FALSE; } if (!stream->putBytes((U8*)header->vlrs[i].description, 32)) { fprintf(stderr,"ERROR: writing header->vlrs[%d].description\n", i); return FALSE; } // write the data following the header of the variable length record if (header->vlrs[i].record_length_after_header) { if (header->vlrs[i].data) { if (!stream->putBytes((U8*)header->vlrs[i].data, header->vlrs[i].record_length_after_header)) { fprintf(stderr,"ERROR: writing %d bytes of data from header->vlrs[%d].data\n", header->vlrs[i].record_length_after_header, i); return FALSE; } } else { fprintf(stderr,"ERROR: there should be %d bytes of data in header->vlrs[%d].data\n", header->vlrs[i].record_length_after_header, i); return FALSE; } } } // write laszip VLR with compression parameters if (laszip) { // write variable length records variable after variable (to avoid alignment issues) U16 reserved = 0xAABB; if (!stream->put16bitsLE((U8*)&(reserved))) { fprintf(stderr,"ERROR: writing reserved %d\n", (I32)reserved); return FALSE; } U8 user_id[16] = "laszip encoded\0"; if (!stream->putBytes((U8*)user_id, 16)) { fprintf(stderr,"ERROR: writing user_id %s\n", user_id); return FALSE; } U16 record_id = 22204; if (!stream->put16bitsLE((U8*)&(record_id))) { fprintf(stderr,"ERROR: writing record_id %d\n", (I32)record_id); return FALSE; } U16 record_length_after_header = laszip_vlr_data_size; if (!stream->put16bitsLE((U8*)&(record_length_after_header))) { fprintf(stderr,"ERROR: writing record_length_after_header %d\n", (I32)record_length_after_header); return FALSE; } char description[32]; memset(description, 0, 32); sprintf(description, "by laszip of LAStools (%d)", LAS_TOOLS_VERSION); if (!stream->putBytes((U8*)description, 32)) { fprintf(stderr,"ERROR: writing description %s\n", description); return FALSE; } // write the data following the header of the variable length record // 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 (!stream->put16bitsLE((U8*)&(laszip->compressor))) { fprintf(stderr,"ERROR: writing compressor %d\n", (I32)compressor); return FALSE; } if (!stream->put16bitsLE((U8*)&(laszip->coder))) { fprintf(stderr,"ERROR: writing coder %d\n", (I32)laszip->coder); return FALSE; } if (!stream->putByte(laszip->version_major)) { fprintf(stderr,"ERROR: writing version_major %d\n", laszip->version_major); return FALSE; } if (!stream->putByte(laszip->version_minor)) { fprintf(stderr,"ERROR: writing version_minor %d\n", laszip->version_minor); return FALSE; } if (!stream->put16bitsLE((U8*)&(laszip->version_revision))) { fprintf(stderr,"ERROR: writing version_revision %d\n", laszip->version_revision); return FALSE; } if (!stream->put32bitsLE((U8*)&(laszip->options))) { fprintf(stderr,"ERROR: writing options %d\n", (I32)laszip->options); return FALSE; } if (!stream->put32bitsLE((U8*)&(laszip->chunk_size))) { fprintf(stderr,"ERROR: writing chunk_size %d\n", laszip->chunk_size); return FALSE; } if (!stream->put64bitsLE((U8*)&(laszip->number_of_special_evlrs))) { fprintf(stderr,"ERROR: writing number_of_special_evlrs %d\n", (I32)laszip->number_of_special_evlrs); return FALSE; } if (!stream->put64bitsLE((U8*)&(laszip->offset_to_special_evlrs))) { fprintf(stderr,"ERROR: writing offset_to_special_evlrs %d\n", (I32)laszip->offset_to_special_evlrs); return FALSE; } if (!stream->put16bitsLE((U8*)&(laszip->num_items))) { fprintf(stderr,"ERROR: writing num_items %d\n", laszip->num_items); return FALSE; } for (i = 0; i < laszip->num_items; i++) { if (!stream->put16bitsLE((U8*)&(laszip->items[i].type))) { fprintf(stderr,"ERROR: writing type %d of item %d\n", laszip->items[i].type, i); return FALSE; } if (!stream->put16bitsLE((U8*)&(laszip->items[i].size))) { fprintf(stderr,"ERROR: writing size %d of item %d\n", laszip->items[i].size, i); return FALSE; } if (!stream->put16bitsLE((U8*)&(laszip->items[i].version))) { fprintf(stderr,"ERROR: writing version %d of item %d\n", laszip->items[i].version, i); return FALSE; } } delete laszip; laszip = 0; } // write lastiling VLR with the tile parameters if (header->vlr_lastiling) { // write variable length records variable after variable (to avoid alignment issues) U16 reserved = 0xAABB; if (!stream->put16bitsLE((U8*)&(reserved))) { fprintf(stderr,"ERROR: writing reserved %d\n", (I32)reserved); return FALSE; } U8 user_id[16] = "LAStools\0\0\0\0\0\0\0"; if (!stream->putBytes((U8*)user_id, 16)) { fprintf(stderr,"ERROR: writing user_id %s\n", user_id); return FALSE; } U16 record_id = 10; if (!stream->put16bitsLE((U8*)&(record_id))) { fprintf(stderr,"ERROR: writing record_id %d\n", (I32)record_id); return FALSE; } U16 record_length_after_header = 28; if (!stream->put16bitsLE((U8*)&(record_length_after_header))) { fprintf(stderr,"ERROR: writing record_length_after_header %d\n", (I32)record_length_after_header); return FALSE; } CHAR description[32] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; sprintf(description, "tile %s buffer %s", (header->vlr_lastiling->buffer ? "with" : "without"), (header->vlr_lastiling->reversible ? ", reversible" : "")); if (!stream->putBytes((U8*)description, 32)) { fprintf(stderr,"ERROR: writing description %s\n", description); return FALSE; } // write the payload of this VLR which contains 28 bytes // U32 level 4 bytes // U32 level_index 4 bytes // U32 implicit_levels + buffer bit + reversible bit 4 bytes // F32 min_x 4 bytes // F32 max_x 4 bytes // F32 min_y 4 bytes // F32 max_y 4 bytes if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->level))) { fprintf(stderr,"ERROR: writing header->vlr_lastiling->level %u\n", header->vlr_lastiling->level); return FALSE; } if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->level_index))) { fprintf(stderr,"ERROR: writing header->vlr_lastiling->level_index %u\n", header->vlr_lastiling->level_index); return FALSE; } if (!stream->put32bitsLE(((U8*)header->vlr_lastiling)+8)) { fprintf(stderr,"ERROR: writing header->vlr_lastiling->implicit_levels %u\n", header->vlr_lastiling->implicit_levels); return FALSE; } if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->min_x))) { fprintf(stderr,"ERROR: writing header->vlr_lastiling->min_x %g\n", header->vlr_lastiling->min_x); return FALSE; } if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->max_x))) { fprintf(stderr,"ERROR: writing header->vlr_lastiling->max_x %g\n", header->vlr_lastiling->max_x); return FALSE; } if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->min_y))) { fprintf(stderr,"ERROR: writing header->vlr_lastiling->min_y %g\n", header->vlr_lastiling->min_y); return FALSE; } if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->max_y))) { fprintf(stderr,"ERROR: writing header->vlr_lastiling->max_y %g\n", header->vlr_lastiling->max_y); return FALSE; } } // write lasoriginal VLR with the original (unbuffered) counts and bounding box extent if (header->vlr_lasoriginal) { // write variable length records variable after variable (to avoid alignment issues) U16 reserved = 0xAABB; if (!stream->put16bitsLE((U8*)&(reserved))) { fprintf(stderr,"ERROR: writing reserved %d\n", (I32)reserved); return FALSE; } U8 user_id[16] = "LAStools\0\0\0\0\0\0\0"; if (!stream->putBytes((U8*)user_id, 16)) { fprintf(stderr,"ERROR: writing user_id %s\n", user_id); return FALSE; } U16 record_id = 20; if (!stream->put16bitsLE((U8*)&(record_id))) { fprintf(stderr,"ERROR: writing record_id %d\n", (I32)record_id); return FALSE; } U16 record_length_after_header = 176; if (!stream->put16bitsLE((U8*)&(record_length_after_header))) { fprintf(stderr,"ERROR: writing record_length_after_header %d\n", (I32)record_length_after_header); return FALSE; } U8 description[32] = "counters and bbox of original\0\0"; if (!stream->putBytes((U8*)description, 32)) { fprintf(stderr,"ERROR: writing description %s\n", description); return FALSE; } // write the payload of this VLR which contains 176 bytes if (!stream->put64bitsLE((U8*)&(header->vlr_lasoriginal->number_of_point_records))) { fprintf(stderr,"ERROR: writing header->vlr_lasoriginal->number_of_point_records %u\n", (U32)header->vlr_lasoriginal->number_of_point_records); return FALSE; } for (j = 0; j < 15; j++) { if (!stream->put64bitsLE((U8*)&(header->vlr_lasoriginal->number_of_points_by_return[j]))) { fprintf(stderr,"ERROR: writing header->vlr_lasoriginal->number_of_points_by_return[%u] %u\n", j, (U32)header->vlr_lasoriginal->number_of_points_by_return[j]); return FALSE; } } if (!stream->put64bitsLE((U8*)&(header->vlr_lasoriginal->min_x))) { fprintf(stderr,"ERROR: writing header->vlr_lasoriginal->min_x %g\n", header->vlr_lasoriginal->min_x); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->vlr_lasoriginal->max_x))) { fprintf(stderr,"ERROR: writing header->vlr_lasoriginal->max_x %g\n", header->vlr_lasoriginal->max_x); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->vlr_lasoriginal->min_y))) { fprintf(stderr,"ERROR: writing header->vlr_lasoriginal->min_y %g\n", header->vlr_lasoriginal->min_y); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->vlr_lasoriginal->max_y))) { fprintf(stderr,"ERROR: writing header->vlr_lasoriginal->max_y %g\n", header->vlr_lasoriginal->max_y); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->vlr_lasoriginal->min_z))) { fprintf(stderr,"ERROR: writing header->vlr_lasoriginal->min_z %g\n", header->vlr_lasoriginal->min_z); return FALSE; } if (!stream->put64bitsLE((U8*)&(header->vlr_lasoriginal->max_z))) { fprintf(stderr,"ERROR: writing header->vlr_lasoriginal->max_z %g\n", header->vlr_lasoriginal->max_z); return FALSE; } } // write any number of user-defined bytes that might have been added after the header if (header->user_data_after_header_size) { if (header->user_data_after_header) { if (!stream->putBytes((U8*)header->user_data_after_header, header->user_data_after_header_size)) { fprintf(stderr,"ERROR: writing %d bytes of data from header->user_data_after_header\n", header->user_data_after_header_size); return FALSE; } } else { fprintf(stderr,"ERROR: there should be %d bytes of data in header->user_data_after_header\n", header->user_data_after_header_size); return FALSE; } } // initialize the point writer if (!writer->init(stream)) return FALSE; npoints = (header->number_of_point_records ? header->number_of_point_records : header->extended_number_of_point_records); p_count = 0; return TRUE; }
int32_t laszip_open_reader(laszip_dll_struct * laszip_dll, const char* file_name, laszip_BOOL* is_compressed) { if (laszip_dll == 0) return 1; try { if (file_name == 0) { sprintf(laszip_dll->error, "char pointer 'file_name' is zero"); return 1; } if (is_compressed == 0) { sprintf(laszip_dll->error, "laszip_BOOL pointer 'is_compressed' is zero"); return 1; } if (laszip_dll->reader) { sprintf(laszip_dll->error, "reader is already open"); return 1; } // open the file laszip_dll->file = fopen(file_name, "rb"); if (laszip_dll->file == 0) { sprintf(laszip_dll->error, "cannot open file '%s'", file_name); return 1; } if (setvbuf(laszip_dll->file, NULL, _IOFBF, 262144) != 0) { sprintf(laszip_dll->warning, "setvbuf() failed with buffer size 262144\n"); } laszip_dll->streamin = new ByteStreamIn(laszip_dll->file); if (laszip_dll->streamin == 0) { sprintf(laszip_dll->error, "could not alloc ByteStreamInFile"); return 1; } // read the header variable after variable U32 i; CHAR file_signature[5]; try { laszip_dll->streamin->getBytes((U8*)file_signature, 4); } catch(...) { sprintf(laszip_dll->error, "reading header.file_signature"); return 1; } if (strncmp(file_signature, "LASF", 4) != 0) { sprintf(laszip_dll->error, "wrong file_signature. not a LAS/LAZ file."); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.file_source_ID)); } catch(...) { sprintf(laszip_dll->error, "reading header.file_source_ID"); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.global_encoding)); } catch(...) { sprintf(laszip_dll->error, "reading header.global_encoding"); return 1; } try { laszip_dll->streamin->get32bitsLE((U8*)&(laszip_dll->header.project_ID_GUID_data_1)); } catch(...) { sprintf(laszip_dll->error, "reading header.project_ID_GUID_data_1"); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.project_ID_GUID_data_2)); } catch(...) { sprintf(laszip_dll->error, "reading header.project_ID_GUID_data_2"); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.project_ID_GUID_data_3)); } catch(...) { sprintf(laszip_dll->error, "reading header.project_ID_GUID_data_3"); return 1; } try { laszip_dll->streamin->getBytes((U8*)laszip_dll->header.project_ID_GUID_data_4, 8); } catch(...) { sprintf(laszip_dll->error, "reading header.project_ID_GUID_data_4"); return 1; } try { laszip_dll->streamin->getBytes((U8*)&(laszip_dll->header.version_major), 1); } catch(...) { sprintf(laszip_dll->error, "reading header.version_major"); return 1; } try { laszip_dll->streamin->getBytes((U8*)&(laszip_dll->header.version_minor), 1); } catch(...) { sprintf(laszip_dll->error, "reading header.version_minor"); return 1; } try { laszip_dll->streamin->getBytes((U8*)laszip_dll->header.system_identifier, 32); } catch(...) { sprintf(laszip_dll->error, "reading header.system_identifier"); return 1; } try { laszip_dll->streamin->getBytes((U8*)laszip_dll->header.generating_software, 32); } catch(...) { sprintf(laszip_dll->error, "reading header.generating_software"); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.file_creation_day)); } catch(...) { sprintf(laszip_dll->error, "reading header.file_creation_day"); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.file_creation_year)); } catch(...) { sprintf(laszip_dll->error, "reading header.file_creation_year"); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.header_size)); } catch(...) { sprintf(laszip_dll->error, "reading header.header_size"); return 1; } try { laszip_dll->streamin->get32bitsLE((U8*)&(laszip_dll->header.offset_to_point_data)); } catch(...) { sprintf(laszip_dll->error, "reading header.offset_to_point_data"); return 1; } try { laszip_dll->streamin->get32bitsLE((U8*)&(laszip_dll->header.number_of_variable_length_records)); } catch(...) { sprintf(laszip_dll->error, "reading header.number_of_variable_length_records"); return 1; } try { laszip_dll->streamin->getBytes((U8*)&(laszip_dll->header.point_data_format), 1); } catch(...) { sprintf(laszip_dll->error, "reading header.point_data_format"); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.point_data_record_length)); } catch(...) { sprintf(laszip_dll->error, "reading header.point_data_record_length"); return 1; } try { laszip_dll->streamin->get32bitsLE((U8*)&(laszip_dll->header.number_of_point_records)); } catch(...) { sprintf(laszip_dll->error, "reading header.number_of_point_records"); return 1; } for (i = 0; i < 5; i++) { try { laszip_dll->streamin->get32bitsLE((U8*)&(laszip_dll->header.number_of_points_by_return[i])); } catch(...) { sprintf(laszip_dll->error, "reading header.number_of_points_by_return %d", i); return 1; } } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.x_scale_factor)); } catch(...) { sprintf(laszip_dll->error, "reading header.x_scale_factor"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.y_scale_factor)); } catch(...) { sprintf(laszip_dll->error, "reading header.y_scale_factor"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.z_scale_factor)); } catch(...) { sprintf(laszip_dll->error, "reading header.z_scale_factor"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.x_offset)); } catch(...) { sprintf(laszip_dll->error, "reading header.x_offset"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.y_offset)); } catch(...) { sprintf(laszip_dll->error, "reading header.y_offset"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.z_offset)); } catch(...) { sprintf(laszip_dll->error, "reading header.z_offset"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.max_x)); } catch(...) { sprintf(laszip_dll->error, "reading header.max_x"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.min_x)); } catch(...) { sprintf(laszip_dll->error, "reading header.min_x"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.max_y)); } catch(...) { sprintf(laszip_dll->error, "reading header.max_y"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.min_y)); } catch(...) { sprintf(laszip_dll->error, "reading header.min_y"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.max_z)); } catch(...) { sprintf(laszip_dll->error, "reading header.max_z"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.min_z)); } catch(...) { sprintf(laszip_dll->error, "reading header.min_z"); return 1; } // special handling for LAS 1.3 if ((laszip_dll->header.version_major == 1) && (laszip_dll->header.version_minor >= 3)) { if (laszip_dll->header.header_size < 235) { sprintf(laszip_dll->error, "for LAS 1.%d header_size should at least be 235 but it is only %d", laszip_dll->header.version_minor, laszip_dll->header.header_size); return 1; } else { try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.start_of_waveform_data_packet_record)); } catch(...) { sprintf(laszip_dll->error, "reading header.start_of_waveform_data_packet_record"); return 1; } laszip_dll->header.user_data_in_header_size = laszip_dll->header.header_size - 235; } } else { laszip_dll->header.user_data_in_header_size = laszip_dll->header.header_size - 227; } // special handling for LAS 1.4 if ((laszip_dll->header.version_major == 1) && (laszip_dll->header.version_minor >= 4)) { if (laszip_dll->header.header_size < 375) { sprintf(laszip_dll->error, "for LAS 1.%d header_size should at least be 375 but it is only %d", laszip_dll->header.version_minor, laszip_dll->header.header_size); return 1; } else { try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.start_of_first_extended_variable_length_record)); } catch(...) { sprintf(laszip_dll->error, "reading header.start_of_first_extended_variable_length_record"); return 1; } try { laszip_dll->streamin->get32bitsLE((U8*)&(laszip_dll->header.number_of_extended_variable_length_records)); } catch(...) { sprintf(laszip_dll->error, "reading header.number_of_extended_variable_length_records"); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.extended_number_of_point_records)); } catch(...) { sprintf(laszip_dll->error, "reading header.extended_number_of_point_records"); return 1; } for (i = 0; i < 15; i++) { try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip_dll->header.extended_number_of_points_by_return[i])); } catch(...) { sprintf(laszip_dll->error, "reading header.extended_number_of_points_by_return[%d]", i); return 1; } } laszip_dll->header.user_data_in_header_size = laszip_dll->header.header_size - 375; } } // load any number of user-defined bytes that might have been added to the header if (laszip_dll->header.user_data_in_header_size) { if (laszip_dll->header.user_data_in_header) { delete [] laszip_dll->header.user_data_in_header; } laszip_dll->header.user_data_in_header = new U8[laszip_dll->header.user_data_in_header_size]; try { laszip_dll->streamin->getBytes((U8*)laszip_dll->header.user_data_in_header, laszip_dll->header.user_data_in_header_size); } catch(...) { sprintf(laszip_dll->error, "reading %u bytes of data into header.user_data_in_header", laszip_dll->header.user_data_in_header_size); return 1; } } // read variable length records into the header U32 vlrs_size = 0; LASzip* laszip = 0; if (laszip_dll->header.number_of_variable_length_records) { U32 i; laszip_dll->header.vlrs = (laszip_vlr*)malloc(sizeof(laszip_vlr)*laszip_dll->header.number_of_variable_length_records); if (laszip_dll->header.vlrs == 0) { sprintf(laszip_dll->error, "allocating %u VLRs", laszip_dll->header.number_of_variable_length_records); return 1; } for (i = 0; i < laszip_dll->header.number_of_variable_length_records; i++) { // make sure there are enough bytes left to read a variable length record before the point block starts if (((int)laszip_dll->header.offset_to_point_data - vlrs_size - laszip_dll->header.header_size) < 54) { sprintf(laszip_dll->warning, "only %d bytes until point block after reading %d of %d vlrs. skipping remaining vlrs ...", (int)laszip_dll->header.offset_to_point_data - vlrs_size - laszip_dll->header.header_size, i, laszip_dll->header.number_of_variable_length_records); laszip_dll->header.number_of_variable_length_records = i; break; } // read variable length records variable after variable (to avoid alignment issues) try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.vlrs[i].reserved)); } catch(...) { sprintf(laszip_dll->error, "reading header.vlrs[%u].reserved", i); return 1; } try { laszip_dll->streamin->getBytes((U8*)laszip_dll->header.vlrs[i].user_id, 16); } catch(...) { sprintf(laszip_dll->error, "reading header.vlrs[%u].user_id", i); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.vlrs[i].record_id)); } catch(...) { sprintf(laszip_dll->error, "reading header.vlrs[%u].record_id", i); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip_dll->header.vlrs[i].record_length_after_header)); } catch(...) { sprintf(laszip_dll->error, "reading header.vlrs[%u].record_length_after_header", i); return 1; } try { laszip_dll->streamin->getBytes((U8*)laszip_dll->header.vlrs[i].description, 32); } catch(...) { sprintf(laszip_dll->error, "reading header.vlrs[%u].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 (laszip_dll->header.vlrs[i].reserved != 0xAABB) { sprintf(laszip_dll->warning,"wrong header.vlrs[%d].reserved: %d != 0xAABB", i, laszip_dll->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)laszip_dll->header.offset_to_point_data - vlrs_size - laszip_dll->header.header_size) < laszip_dll->header.vlrs[i].record_length_after_header) { sprintf(laszip_dll->warning, "only %d bytes until point block when trying to read %d bytes into header.vlrs[%d].data", (int)laszip_dll->header.offset_to_point_data - vlrs_size - laszip_dll->header.header_size, laszip_dll->header.vlrs[i].record_length_after_header, i); laszip_dll->header.vlrs[i].record_length_after_header = (int)laszip_dll->header.offset_to_point_data - vlrs_size - laszip_dll->header.header_size; } // load data following the header of the variable length record if (laszip_dll->header.vlrs[i].record_length_after_header) { if ((strcmp(laszip_dll->header.vlrs[i].user_id, "laszip encoded") == 0) && (laszip_dll->header.vlrs[i].record_id == 22204)) { if (laszip) { delete laszip; } laszip = new LASzip(); if (laszip == 0) { sprintf(laszip_dll->error, "could not alloc LASzip"); return 1; } // 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 try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip->compressor)); } catch(...) { sprintf(laszip_dll->error, "reading compressor %d", (I32)laszip->compressor); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip->coder)); } catch(...) { sprintf(laszip_dll->error, "reading coder %d", (I32)laszip->coder); return 1; } try { laszip_dll->streamin->getBytes((U8*)&(laszip->version_major), 1); } catch(...) { sprintf(laszip_dll->error, "reading version_major %d", (I32)laszip->version_major); return 1; } try { laszip_dll->streamin->getBytes((U8*)&(laszip->version_minor), 1); } catch(...) { sprintf(laszip_dll->error, "reading version_minor %d", (I32)laszip->version_minor); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip->version_revision)); } catch(...) { sprintf(laszip_dll->error, "reading version_revision %d", (I32)laszip->version_revision); return 1; } try { laszip_dll->streamin->get32bitsLE((U8*)&(laszip->options)); } catch(...) { sprintf(laszip_dll->error, "reading options %u", laszip->options); return 1; } try { laszip_dll->streamin->get32bitsLE((U8*)&(laszip->chunk_size)); } catch(...) { sprintf(laszip_dll->error, "reading chunk_size %u", laszip->chunk_size); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip->number_of_special_evlrs)); } catch(...) { sprintf(laszip_dll->error, "reading number_of_special_evlrs %d", (I32)laszip->number_of_special_evlrs); return 1; } try { laszip_dll->streamin->get64bitsLE((U8*)&(laszip->offset_to_special_evlrs)); } catch(...) { sprintf(laszip_dll->error, "reading offset_to_special_evlrs %d", (I32)laszip->offset_to_special_evlrs); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip->num_items)); } catch(...) { sprintf(laszip_dll->error, "reading num_items %d", (I32)laszip->num_items); return 1; } laszip->items = new LASitem[laszip->num_items]; U32 j; for (j = 0; j < laszip->num_items; j++) { U16 type; try { laszip_dll->streamin->get16bitsLE((U8*)&type); } catch(...) { sprintf(laszip_dll->error, "reading type of item %u", j); return 1; } laszip->items[j].type = (LASitem::Type)type; try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip->items[j].size)); } catch(...) { sprintf(laszip_dll->error, "reading size of item %u", j); return 1; } try { laszip_dll->streamin->get16bitsLE((U8*)&(laszip->items[j].version)); } catch(...) { sprintf(laszip_dll->error, "reading version of item %u", j); return 1; } } } else { laszip_dll->header.vlrs[i].data = new U8[laszip_dll->header.vlrs[i].record_length_after_header]; try { laszip_dll->streamin->getBytes(laszip_dll->header.vlrs[i].data, laszip_dll->header.vlrs[i].record_length_after_header); } catch(...) { sprintf(laszip_dll->error, "reading %d bytes of data into header.vlrs[%u].data", (I32)laszip_dll->header.vlrs[i].record_length_after_header, i); return 1; } } } else { laszip_dll->header.vlrs[i].data = 0; } // keep track on the number of bytes we have read so far vlrs_size += laszip_dll->header.vlrs[i].record_length_after_header; // special handling for LASzip VLR if ((strcmp(laszip_dll->header.vlrs[i].user_id, "laszip encoded") == 0) && (laszip_dll->header.vlrs[i].record_id == 22204)) { // we take our the VLR for LASzip away laszip_dll->header.offset_to_point_data -= (54+laszip_dll->header.vlrs[i].record_length_after_header); vlrs_size -= (54+laszip_dll->header.vlrs[i].record_length_after_header); i--; laszip_dll->header.number_of_variable_length_records--; // free or resize the VLR array if (laszip_dll->header.number_of_variable_length_records == 0) { free(laszip_dll->header.vlrs); laszip_dll->header.vlrs = 0; } else { laszip_dll->header.vlrs = (laszip_vlr*)realloc(laszip_dll->header.vlrs, sizeof(laszip_vlr)*laszip_dll->header.number_of_variable_length_records); } } } } // load any number of user-defined bytes that might have been added after the header laszip_dll->header.user_data_after_header_size = (I32)laszip_dll->header.offset_to_point_data - vlrs_size - laszip_dll->header.header_size; if (laszip_dll->header.user_data_after_header_size) { if (laszip_dll->header.user_data_after_header) { delete [] laszip_dll->header.user_data_after_header; } laszip_dll->header.user_data_after_header = new U8[laszip_dll->header.user_data_after_header_size]; try { laszip_dll->streamin->getBytes((U8*)laszip_dll->header.user_data_after_header, laszip_dll->header.user_data_after_header_size); } catch(...) { sprintf(laszip_dll->error, "reading %u bytes of data into header.user_data_after_header", laszip_dll->header.user_data_after_header_size); return 1; } } // remove extra bits in point data type if ((laszip_dll->header.point_data_format & 128) || (laszip_dll->header.point_data_format & 64)) { if (!laszip) { sprintf(laszip_dll->error, "this file was compressed with an experimental version of LASzip. contact '*****@*****.**' for assistance"); return 1; } laszip_dll->header.point_data_format &= 127; } // check if file is compressed if (laszip) { // yes. check the compressor state *is_compressed = 1; if (!laszip->check()) { sprintf(laszip_dll->error, "%s upgrade to the latest release of LASzip or contact '*****@*****.**' for assistance", laszip->get_error()); return 1; } } else { // no. setup an un-compressed read *is_compressed = 0; laszip = new LASzip; if (laszip == 0) { sprintf(laszip_dll->error, "could not alloc LASzip"); return 1; } if (!laszip->setup(laszip_dll->header.point_data_format, laszip_dll->header.point_data_record_length, LASZIP_COMPRESSOR_NONE)) { sprintf(laszip_dll->error, "invalid combination of point_data_format %d and point_data_record_length %d", (I32)laszip_dll->header.point_data_format, (I32)laszip_dll->header.point_data_record_length); return 1; } } // create point's item pointers laszip_dll->point_items = new U8*[laszip->num_items]; if (laszip_dll->point_items == 0) { sprintf(laszip_dll->error, "could not alloc point_items"); return 1; } for (i = 0; i < laszip->num_items; i++) { switch (laszip->items[i].type) { case LASitem::POINT14: case LASitem::POINT10: laszip_dll->point_items[i] = (U8*)&(laszip_dll->point.X); break; case LASitem::GPSTIME11: laszip_dll->point_items[i] = (U8*)&(laszip_dll->point.gps_time); break; case LASitem::RGBNIR14: case LASitem::RGB12: laszip_dll->point_items[i] = (U8*)laszip_dll->point.rgb; break; case LASitem::WAVEPACKET13: laszip_dll->point_items[i] = (U8*)&(laszip_dll->point.wave_packet); break; case LASitem::BYTE: laszip_dll->point.num_extra_bytes = laszip->items[i].size; if (laszip_dll->point.extra_bytes) delete [] laszip_dll->point.extra_bytes; laszip_dll->point.extra_bytes = new U8[laszip_dll->point.num_extra_bytes]; laszip_dll->point_items[i] = laszip_dll->point.extra_bytes; break; default: sprintf(laszip_dll->error, "unknown LASitem type %d", (I32)laszip->items[i].type); return 1; } } // create the point reader laszip_dll->reader = new LASreadPoint(); if (laszip_dll->reader == 0) { sprintf(laszip_dll->error, "could not alloc LASreadPoint"); return 1; } if (!laszip_dll->reader->setup(laszip->num_items, laszip->items, laszip)) { sprintf(laszip_dll->error, "setup of LASreadPoint failed"); return 1; } if (!laszip_dll->reader->init(laszip_dll->streamin)) { sprintf(laszip_dll->error, "init of LASreadPoint failed"); return 1; } delete laszip; // set the point number and point count laszip_dll->npoints = (laszip_dll->header.number_of_point_records ? laszip_dll->header.number_of_point_records : laszip_dll->header.extended_number_of_point_records); laszip_dll->p_count = 0; } catch (...) { sprintf(laszip_dll->error, "internal error in laszip_open_reader"); return 1; } laszip_dll->error[0] = '\0'; return 0; }
static void run_test(const char* filename, PointData& data, unsigned short compressor, int requested_version=-1, int chunk_size=-1, bool random_seeks=false) { // // COMPRESSION // // setting up LASzip parameters LASzip laszip; if (!laszip.setup(data.point_type, data.point_size, compressor)) { log("ERROR on laszip.setup(): %s\n", laszip.get_error()); } if (requested_version > -1) laszip.request_version((unsigned short)requested_version); if (chunk_size > -1) laszip.set_chunk_size((unsigned int)chunk_size); // packing up LASzip unsigned char* bytes; int num; if (!laszip.pack(bytes, num)) { log("ERROR on laszip.pack(): %s\n", laszip.get_error()); } // creating the output stream OStream* ost = new OStream(settings->use_iostream, filename); // creating the zipper LASzipper* laszipper = make_zipper(ost, &laszip); // allocating the data to read from data.setup(laszip.num_items, laszip.items); // writing the points if (chunk_size == 0) { if (random_seeks) write_points_explicit_chunk_seek(laszipper, data); else write_points_explicit_chunk(laszipper, data); } else { if (random_seeks) write_points_seek(laszipper, data); else write_points(laszipper, data); } // cleaning up delete laszipper; delete ost; // // DECOMPRESSION // // setting up LASzip parameters LASzip laszip_dec; if (!laszip_dec.unpack(bytes, num)) { log("ERROR on laszip_dec.unpack(): %s\n", laszip_dec.get_error()); } // creating the input stream IStream* ist = new IStream(settings->use_iostream, filename); // creating the unzipper LASunzipper* lasunzipper = make_unzipper(ist, &laszip_dec); // allocating the data to write into data.setup(laszip_dec.num_items, laszip_dec.items); // reading the points if (random_seeks) read_points_seek(lasunzipper, data); else read_points(lasunzipper, data); // cleaning up delete lasunzipper; delete ist; return; }