示例#1
0
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;
}
示例#2
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;
}