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; }
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; }