bool loadStackHDF5( const char* fileName, Image4DSimple& img ) { #ifdef USE_HDF5 H5::Exception::dontPrint(); H5::H5File file( fileName, H5F_ACC_RDONLY ); for ( size_t i = 0; i < file.getObjCount(); i++ ) { H5std_string name = file.getObjnameByIdx( i ); if ( name == "Channels" ) { H5::Group channels = file.openGroup( name ); // Grab the attributes H5::Attribute attr = channels.openAttribute( "width" ); H5::DataType type = attr.getDataType(); long width, height; attr.read( type, &width ); attr.close(); attr = channels.openAttribute( "height" ); attr.read( type, &height ); attr.close(); int num_channels = 0; // Count the number of channels for ( size_t obj = 0; obj < channels.getNumObjs(); obj++ ) if ( channels.getObjTypeByIdx( obj ) == H5G_DATASET ) num_channels++; int channel_idx = 0; for ( size_t obj = 0; obj < channels.getNumObjs(); obj++ ) { if ( channels.getObjTypeByIdx( obj ) == H5G_DATASET ) { H5std_string ds_name = channels.getObjnameByIdx( obj ); H5::DataSet data = channels.openDataSet( ds_name ); uint8_t* buffer = new uint8_t[ data.getStorageSize() ]; data.read( buffer, data.getDataType() ); QByteArray qbarray( ( const char* )buffer, data.getStorageSize() ); data.close(); if ( !loadIndexedStackFFMpeg( &qbarray, img, channel_idx++, num_channels, width, height ) ) { v3d_msg( "Error happened in HDF file reading. Stop. \n", false ); return false; } delete [] buffer; } } } } #endif return true; }
bool readDataset1D(const H5::H5File &file, const std::string &name, std::vector<_Tp> &data) { H5::DataSet dataset = file.openDataSet(name); H5::DataSpace dataspace = dataset.getSpace(); hsize_t dims_out[1]; int rank = dataspace.getSimpleExtentDims( dims_out, NULL); int _type; bool read = getNodeType(dataset, _type); read &= (_type == StorageNode::SEQ); read &= (rank == 1); if (!read) return read; data.resize(dims_out[0]); dataset.read(data.data(), dataset.getDataType()); return true; }
bool ossim_hdf5::getValidBoundingRect( H5::DataSet& dataset, const std::string& name, ossimIrect& rect ) { bool result = false; H5::DataSpace imageDataspace = dataset.getSpace(); const ossim_int32 IN_DIM_COUNT = imageDataspace.getSimpleExtentNdims(); if ( IN_DIM_COUNT == 2 ) { // Get the extents. Assuming dimensions are same for lat lon dataset. std::vector<hsize_t> dimsOut(IN_DIM_COUNT); imageDataspace.getSimpleExtentDims( &dimsOut.front(), 0 ); if ( dimsOut[0] && dimsOut[1] ) { //--- // Capture the rectangle: // dimsOut[0] is height, dimsOut[1] is width: //--- rect = ossimIrect( 0, 0, static_cast<ossim_int32>( dimsOut[1]-1 ), static_cast<ossim_int32>( dimsOut[0]-1 ) ); const ossim_int32 WIDTH = rect.width(); std::vector<hsize_t> inputCount(IN_DIM_COUNT); std::vector<hsize_t> inputOffset(IN_DIM_COUNT); inputOffset[0] = 0; inputOffset[1] = 0; inputCount[0] = 1; inputCount[1] = WIDTH; // Output dataspace dimensions. const ossim_int32 OUT_DIM_COUNT = 3; std::vector<hsize_t> outputCount(OUT_DIM_COUNT); outputCount[0] = 1; // single band outputCount[1] = 1; // single line outputCount[2] = WIDTH; // whole line // Output dataspace offset. std::vector<hsize_t> outputOffset(OUT_DIM_COUNT); outputOffset[0] = 0; outputOffset[1] = 0; outputOffset[2] = 0; ossimScalarType scalar = ossim_hdf5::getScalarType( &dataset ); if ( scalar == OSSIM_FLOAT32 ) { // See if we need to swap bytes: ossimEndian* endian = 0; if ( ( ossim::byteOrder() != ossim_hdf5::getByteOrder( &dataset ) ) ) { endian = new ossimEndian(); } // Native type: H5::DataType datatype = dataset.getDataType(); // Output dataspace always the same one line. H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front()); bufferDataSpace.selectHyperslab( H5S_SELECT_SET, &outputCount.front(), &outputOffset.front() ); //--- // Dataset sample has NULL lines at the end so scan for valid rect. // Use "<= -999" for test as per NOAA as it seems the NULL value is // fuzzy. e.g. -999.3. //--- const ossim_float32 NULL_VALUE = -999.0; //--- // VIIRS Radiance data has a -1.5e-9 in the first column. // Treat this as a null. //--- const ossim_float32 NULL_VALUE2 = ( name == "/All_Data/VIIRS-DNB-SDR_All/Radiance" ) ? -1.5e-9 : NULL_VALUE; const ossim_float32 TOLERANCE = 0.1e-9; // For ossim::almostEqual() // Hold one line: std::vector<ossim_float32> values( WIDTH ); // Find the ul pixel: ossimIpt ulIpt = rect.ul(); bool found = false; // Line loop to find upper left pixel: while ( ulIpt.y <= rect.lr().y ) { inputOffset[0] = static_cast<hsize_t>(ulIpt.y); imageDataspace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); // Read data from file into the buffer. dataset.read( (void*)&values.front(), datatype, bufferDataSpace, imageDataspace ); if ( endian ) { // If the endian pointer is initialized(not zero) swap the bytes. endian->swap( scalar, (void*)&values.front(), WIDTH ); } // Sample loop: ulIpt.x = rect.ul().x; ossim_int32 index = 0; while ( ulIpt.x <= rect.lr().x ) { if ( !ossim::almostEqual(values[index], NULL_VALUE2, TOLERANCE) && ( values[index] > NULL_VALUE ) ) { found = true; // Found valid pixel. break; } ++ulIpt.x; ++index; } // End: sample loop if ( found ) { break; } ++ulIpt.y; } // End line loop to find ul pixel: // Find the lower right pixel: ossimIpt lrIpt = rect.lr(); found = false; // Line loop to find last pixel: while ( lrIpt.y >= rect.ul().y ) { inputOffset[0] = static_cast<hsize_t>(lrIpt.y); imageDataspace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); // Read data from file into the buffer. dataset.read( (void*)&values.front(), datatype, bufferDataSpace, imageDataspace ); if ( endian ) { // If the endian pointer is initialized(not zero) swap the bytes. endian->swap( scalar, (void*)&values.front(), WIDTH ); } // Sample loop: lrIpt.x = rect.lr().x; ossim_int32 index = WIDTH-1; while ( lrIpt.x >= rect.ul().x ) { if ( !ossim::almostEqual(values[index], NULL_VALUE2, TOLERANCE) && ( values[index] > NULL_VALUE ) ) { found = true; // Found valid pixel. break; } --lrIpt.x; --index; } // End: sample loop if ( found ) { break; } --lrIpt.y; } // End line loop to find lower right pixel. rect = ossimIrect( ulIpt, lrIpt ); // Cleanup: if ( endian ) { delete endian; endian = 0; } result = true; } else // Matches: if ( scalar == OSSIM_FLOAT32 ){...} { ossimNotify(ossimNotifyLevel_WARN) << "ossim_hdf5::getBoundingRect WARNING!" << "\nUnhandled scalar type: " << ossimScalarTypeLut::instance()->getEntryString( scalar ) << std::endl; } } // Matches: if ( dimsOut... } // Matches: if ( IN_DIM_COUNT == 2 ) imageDataspace.close(); return result; } // End: ossim_hdf5::getBoundingRect(...)
ossimRefPtr<ossimProjection> ossim_hdf5::getBilinearProjection( H5::DataSet& latDataSet, H5::DataSet& lonDataSet, const ossimIrect& validRect ) { ossimRefPtr<ossimProjection> proj = 0; // Get dataspace of the dataset. H5::DataSpace latDataSpace = latDataSet.getSpace(); H5::DataSpace lonDataSpace = lonDataSet.getSpace(); // Number of dimensions of the input dataspace: const ossim_int32 DIM_COUNT = latDataSpace.getSimpleExtentNdims(); if ( DIM_COUNT == 2 ) { // Get the extents. Assuming dimensions are same for lat lon dataset. std::vector<hsize_t> dimsOut(DIM_COUNT); latDataSpace.getSimpleExtentDims( &dimsOut.front(), 0 ); if ( dimsOut[0] && dimsOut[1] ) { std::vector<hsize_t> inputCount(DIM_COUNT); std::vector<hsize_t> inputOffset(DIM_COUNT); inputOffset[0] = 0; inputOffset[1] = 0; inputCount[0] = 1; inputCount[1] = 1; // Output dataspace dimensions. const ossim_int32 OUT_DIM_COUNT = 3; std::vector<hsize_t> outputCount(OUT_DIM_COUNT); outputCount[0] = 1; // single band outputCount[1] = 1; // single line outputCount[2] = 1; // single sample // Output dataspace offset. std::vector<hsize_t> outputOffset(OUT_DIM_COUNT); outputOffset[0] = 0; outputOffset[1] = 0; outputOffset[2] = 0; ossimScalarType scalar = ossim_hdf5::getScalarType( &latDataSet ); if ( scalar == OSSIM_FLOAT32 ) { // See if we need to swap bytes: ossimEndian* endian = 0; if ( ( ossim::byteOrder() != ossim_hdf5::getByteOrder( &latDataSet ) ) ) { endian = new ossimEndian(); } // Native type: H5::DataType latDataType = latDataSet.getDataType(); H5::DataType lonDataType = lonDataSet.getDataType(); std::vector<ossimDpt> ipts; std::vector<ossimGpt> gpts; ossimGpt gpt(0.0, 0.0, 0.0); // Assuming WGS84... ossim_float32 latValue = 0.0; ossim_float32 lonValue = 0.0; // Only grab every 256th value.: const ossim_int32 GRID_SIZE = 256; // Output dataspace always the same one pixel. H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front()); bufferDataSpace.selectHyperslab( H5S_SELECT_SET, &outputCount.front(), &outputOffset.front() ); //--- // Dataset sample has NULL lines at the end so scan for valid rect. // Use "<= -999" for test as per NOAA as it seems the NULL value is // fuzzy. e.g. -999.3. //--- const ossim_float32 NULL_VALUE = -999.0; //--- // Get the tie points within the valid rect: //--- ossimDpt ipt = validRect.ul(); while ( ipt.y <= validRect.lr().y ) { inputOffset[0] = static_cast<hsize_t>(ipt.y); // Sample loop: ipt.x = validRect.ul().x; while ( ipt.x <= validRect.lr().x ) { inputOffset[1] = static_cast<hsize_t>(ipt.x); latDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); lonDataSpace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); // Read data from file into the buffer. latDataSet.read( &latValue, latDataType, bufferDataSpace, latDataSpace ); lonDataSet.read( &lonValue, lonDataType, bufferDataSpace, lonDataSpace ); if ( endian ) { // If the endian pointer is initialized(not zero) swap the bytes. endian->swap( latValue ); endian->swap( lonValue ); } if ( ( latValue > NULL_VALUE ) && ( lonValue > NULL_VALUE ) ) { gpt.lat = latValue; gpt.lon = lonValue; gpts.push_back( gpt ); // Add the image point subtracting the image offset. ossimIpt shiftedIpt = ipt - validRect.ul(); ipts.push_back( shiftedIpt ); } // Go to next point: if ( ipt.x < validRect.lr().x ) { ipt.x += GRID_SIZE; if ( ipt.x > validRect.lr().x ) { ipt.x = validRect.lr().x; // Clamp to last sample. } } else { break; // At the end: } } // End sample loop. if ( ipt.y < validRect.lr().y ) { ipt.y += GRID_SIZE; if ( ipt.y > validRect.lr().y ) { ipt.y = validRect.lr().y; // Clamp to last line. } } else { break; // At the end: } } // End line loop. if ( ipts.size() ) { // Create the projection: ossimRefPtr<ossimBilinearProjection> bp = new ossimBilinearProjection(); // Add the tie points: bp->setTiePoints( ipts, gpts ); // Assign to output projection: proj = bp.get(); } // Cleanup: if ( endian ) { delete endian; endian = 0; } } else // Matches: if ( scalar == OSSIM_FLOAT32 ){...} { ossimNotify(ossimNotifyLevel_WARN) << "ossim_hdf5::getBilinearProjection WARNING!" << "\nUnhandled scalar type: " << ossimScalarTypeLut::instance()->getEntryString( scalar ) << std::endl; } } // Matches: if ( dimsOut... } // Matches: if ( IN_DIM_COUNT == 2 ) latDataSpace.close(); lonDataSpace.close(); return proj; } // End: ossim_hdf5::getBilinearProjection()
bool ossim_hdf5::crossesDateline( H5::DataSet& dataset, const ossimIrect& validRect ) { bool result = false; H5::DataSpace dataspace = dataset.getSpace(); // Number of dimensions of the input dataspace: const ossim_int32 DIM_COUNT = dataspace.getSimpleExtentNdims(); if ( DIM_COUNT == 2 ) { const ossim_uint32 ROWS = validRect.height(); const ossim_uint32 COLS = validRect.width(); // Get the extents. Assuming dimensions are same for lat lon dataset. std::vector<hsize_t> dimsOut(DIM_COUNT); dataspace.getSimpleExtentDims( &dimsOut.front(), 0 ); if ( (ROWS <= dimsOut[0]) && (COLS <= dimsOut[1]) ) { std::vector<hsize_t> inputCount(DIM_COUNT); std::vector<hsize_t> inputOffset(DIM_COUNT); inputCount[0] = 1; // row inputCount[1] = COLS; // col // Output dataspace dimensions. const ossim_int32 OUT_DIM_COUNT = 3; std::vector<hsize_t> outputCount(OUT_DIM_COUNT); outputCount[0] = 1; // single band outputCount[1] = 1; // single line outputCount[2] = COLS; // single sample // Output dataspace offset. std::vector<hsize_t> outputOffset(OUT_DIM_COUNT); outputOffset[0] = 0; outputOffset[1] = 0; outputOffset[2] = 0; ossimScalarType scalar = ossim_hdf5::getScalarType( &dataset ); if ( scalar == OSSIM_FLOAT32 ) { // See if we need to swap bytes: ossimEndian* endian = 0; if ( ( ossim::byteOrder() != ossim_hdf5::getByteOrder( &dataset ) ) ) { endian = new ossimEndian(); } // Native type: H5::DataType datatype = dataset.getDataType(); // Output dataspace always the same one line. H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front()); bufferDataSpace.selectHyperslab( H5S_SELECT_SET, &outputCount.front(), &outputOffset.front() ); //--- // Dataset sample has NULL lines at the end so scan for valid rect. // Use "<= -999" for test as per NOAA as it seems the NULL value is // fuzzy. e.g. -999.3. //--- // Buffer to hold a line: std::vector<ossim_float32> lineBuffer(validRect.width()); // Read the first line: inputOffset[0] = static_cast<hsize_t>(validRect.ul().y); inputOffset[1] = static_cast<hsize_t>(validRect.ul().x); dataspace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); dataset.read( &(lineBuffer.front()), datatype, bufferDataSpace, dataspace ); if ( endian ) { // If the endian pointer is initialized(not zero) swap the bytes. endian->swap( &(lineBuffer.front()), COLS ); } // Test the first line: result = ossim_hdf5::crossesDateline( lineBuffer ); if ( !result ) { // Test the last line: inputOffset[0] = static_cast<hsize_t>(validRect.ll().y); inputOffset[1] = static_cast<hsize_t>(validRect.ll().x); dataspace.selectHyperslab( H5S_SELECT_SET, &inputCount.front(), &inputOffset.front() ); dataset.read( &(lineBuffer.front()), datatype, bufferDataSpace, dataspace ); result = ossim_hdf5::crossesDateline( lineBuffer ); } if ( endian ) { delete endian; endian = 0; } } else // Matches: if ( scalar == OSSIM_FLOAT32 ){...} { ossimNotify(ossimNotifyLevel_WARN) << "ossim_hdf5::crossesDateline WARNING!" << "\nUnhandled scalar type: " << ossimScalarTypeLut::instance()->getEntryString( scalar ) << std::endl; } } // Matches: if ( dimsOut... } // Matches: if ( IN_DIM_COUNT == 2 ) dataspace.close(); return result; } // End: ossim_hdf5::crossesDateline(...)