bool ReaderImpl::ReadHeader(LASHeader& header) { using detail::read_n; // Helper variables uint8_t n1 = 0; uint16_t n2 = 0; uint32_t n4 = 0; double x1 = 0; double y1 = 0; double z1 = 0; double x2 = 0; double y2 = 0; double z2 = 0; std::string buf; std::string fsig; m_ifs.seekg(0); // 1. File Signature read_n(fsig, m_ifs, 4); header.SetFileSignature(fsig); // 2. Reserved // This data must always contain Zeros. read_n(n4, m_ifs, sizeof(n4)); // 3-6. GUID data uint32_t d1 = 0; uint16_t d2 = 0; uint16_t d3 = 0; uint8_t d4[8] = { 0 }; read_n(d1, m_ifs, sizeof(d1)); read_n(d2, m_ifs, sizeof(d2)); read_n(d3, m_ifs, sizeof(d3)); read_n(d4, m_ifs, sizeof(d4)); liblas::guid g(d1, d2, d3, d4); header.SetProjectId(g); // 7. Version major read_n(n1, m_ifs, sizeof(n1)); header.SetVersionMajor(n1); // 8. Version minor read_n(n1, m_ifs, sizeof(n1)); header.SetVersionMinor(n1); // 9. System ID read_n(buf, m_ifs, 32); header.SetSystemId(buf); // 10. Generating Software ID read_n(buf, m_ifs, 32); header.SetSoftwareId(buf); // 11. Flight Date Julian read_n(n2, m_ifs, sizeof(n2)); header.SetCreationDOY(n2); // 12. Year read_n(n2, m_ifs, sizeof(n2)); header.SetCreationYear(n2); // 13. Header Size // NOTE: Size of the stanard header block must always be 227 bytes read_n(n2, m_ifs, sizeof(n2)); // 14. Offset to data read_n(n4, m_ifs, sizeof(n4)); if (n4 < header.GetHeaderSize()) { // TODO: Move this test to LASHeader::Validate() throw std::domain_error("offset to point data smaller than header size"); } header.SetDataOffset(n4); // 15. Number of variable length records read_n(n4, m_ifs, sizeof(n4)); header.SetRecordsCount(n4); // 16. Point Data Format ID read_n(n1, m_ifs, sizeof(n1)); if (n1 == LASHeader::ePointFormat0) { header.SetDataFormatId(LASHeader::ePointFormat0); } else if (n1 == LASHeader::ePointFormat1) { header.SetDataFormatId(LASHeader::ePointFormat1); } else if (n1 == LASHeader::ePointFormat2) { header.SetDataFormatId(LASHeader::ePointFormat2); } else if (n1 == LASHeader::ePointFormat3) { header.SetDataFormatId(LASHeader::ePointFormat3); } else { throw std::domain_error("invalid point data format"); } // 17. Point Data Record Length // NOTE: No need to set record length because it's // determined on basis of point data format. read_n(n2, m_ifs, sizeof(n2)); // 18. Number of point records read_n(n4, m_ifs, sizeof(n4)); header.SetPointRecordsCount(n4); // 19. Number of points by return std::vector<uint32_t>::size_type const srbyr = 5; uint32_t rbyr[srbyr] = { 0 }; read_n(rbyr, m_ifs, sizeof(rbyr)); for (std::size_t i = 0; i < srbyr; ++i) { header.SetPointRecordsByReturnCount(i, rbyr[i]); } // 20-22. Scale factors read_n(x1, m_ifs, sizeof(x1)); read_n(y1, m_ifs, sizeof(y1)); read_n(z1, m_ifs, sizeof(z1)); header.SetScale(x1, y1, z1); // 23-25. Offsets read_n(x1, m_ifs, sizeof(x1)); read_n(y1, m_ifs, sizeof(y1)); read_n(z1, m_ifs, sizeof(z1)); header.SetOffset(x1, y1, z1); // 26-27. Max/Min X read_n(x1, m_ifs, sizeof(x1)); read_n(x2, m_ifs, sizeof(x2)); // 28-29. Max/Min Y read_n(y1, m_ifs, sizeof(y1)); read_n(y2, m_ifs, sizeof(y2)); // 30-31. Max/Min Z read_n(z1, m_ifs, sizeof(z1)); read_n(z2, m_ifs, sizeof(z2)); header.SetMax(x1, y1, z1); header.SetMin(x2, y2, z2); Reset(header); return true; }