GDALDataset *KRODataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) || poOpenInfo->fpL == nullptr ) return nullptr; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ KRODataset *poDS = new KRODataset(); poDS->eAccess = poOpenInfo->eAccess; poDS->fpImage = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; /* -------------------------------------------------------------------- */ /* Read the file header. */ /* -------------------------------------------------------------------- */ char achHeader[20] = { '\0' }; CPL_IGNORE_RET_VAL(VSIFReadL( achHeader, 1, 20, poDS->fpImage )); int nXSize; memcpy(&nXSize, achHeader + 4, 4); CPL_MSBPTR32( &nXSize ); int nYSize = 0; memcpy(&nYSize, achHeader + 8, 4); CPL_MSBPTR32( &nYSize ); int nDepth = 0; memcpy(&nDepth, achHeader + 12, 4); CPL_MSBPTR32( &nDepth ); int nComp = 0; memcpy(&nComp, achHeader + 16, 4); CPL_MSBPTR32( &nComp ); if( !GDALCheckDatasetDimensions(nXSize, nYSize) || !GDALCheckBandCount(nComp, FALSE) ) { delete poDS; return nullptr; } poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; GDALDataType eDT = GDT_Unknown; if( nDepth == 8 ) { eDT = GDT_Byte; } else if( nDepth == 16 ) { eDT = GDT_UInt16; } else if( nDepth == 32 ) { eDT = GDT_Float32; } else { CPLError( CE_Failure, CPLE_AppDefined, "Unhandled depth : %d", nDepth ); delete poDS; return nullptr; } const int nDataTypeSize = nDepth / 8; if( nComp == 0 || nDataTypeSize == 0 || poDS->nRasterXSize > INT_MAX / (nComp * nDataTypeSize) ) { CPLError( CE_Failure, CPLE_AppDefined, "Too large width / number of bands" ); delete poDS; return nullptr; } vsi_l_offset nExpectedSize = static_cast<vsi_l_offset>(poDS->nRasterXSize) * poDS->nRasterYSize * nComp * nDataTypeSize + 20; VSIFSeekL(poDS->fpImage, 0, SEEK_END); if( VSIFTellL(poDS->fpImage) < nExpectedSize ) { CPLError( CE_Failure, CPLE_FileIO, "File too short" ); delete poDS; return nullptr; } /* -------------------------------------------------------------------- */ /* Create bands. */ /* -------------------------------------------------------------------- */ CPLErrorReset(); for( int iBand = 0; iBand < nComp; iBand++ ) { RawRasterBand *poBand = new RawRasterBand( poDS, iBand+1, poDS->fpImage, 20 + nDataTypeSize * iBand, nComp * nDataTypeSize, poDS->nRasterXSize * nComp * nDataTypeSize, eDT, !CPL_IS_LSB, RawRasterBand::OwnFP::NO ); if( nComp == 3 || nComp == 4 ) { poBand->SetColorInterpretation( static_cast<GDALColorInterp>(GCI_RedBand + iBand) ); } poDS->SetBand( iBand+1, poBand ); if( CPLGetLastErrorType() != CE_None ) { delete poDS; return nullptr; } } if( nComp > 1 ) poDS->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }
GDALDataset *KRODataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ KRODataset *poDS; poDS = new KRODataset(); poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); else poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); if( poDS->fpImage == NULL ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Read the file header. */ /* -------------------------------------------------------------------- */ char achHeader[20]; int nXSize, nYSize, nDepth, nComp; VSIFReadL( achHeader, 1, 20, poDS->fpImage ); memcpy(&nXSize, achHeader + 4, 4); CPL_MSBPTR32( &nXSize ); memcpy(&nYSize, achHeader + 8, 4); CPL_MSBPTR32( &nYSize ); memcpy(&nDepth, achHeader + 12, 4); CPL_MSBPTR32( &nDepth ); memcpy(&nComp, achHeader + 16, 4); CPL_MSBPTR32( &nComp ); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nComp, FALSE)) { delete poDS; return NULL; } poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; GDALDataType eDT; if( nDepth == 8 ) eDT = GDT_Byte; else if( nDepth == 16 ) eDT = GDT_UInt16; else if( nDepth == 32 ) eDT = GDT_Float32; else { CPLError(CE_Failure, CPLE_AppDefined, "Unhandled depth : %d", nDepth); delete poDS; return NULL; } int nDataTypeSize = nDepth / 8; /* -------------------------------------------------------------------- */ /* Create bands. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < nComp; iBand++ ) { RawRasterBand *poBand = new RawRasterBand( poDS, iBand+1, poDS->fpImage, 20 + nDataTypeSize * iBand, nComp * nDataTypeSize, poDS->nRasterXSize * nComp * nDataTypeSize, eDT, !CPL_IS_LSB, TRUE, FALSE ); if( nComp == 3 || nComp == 4 ) { poBand->SetColorInterpretation( (GDALColorInterp) (GCI_RedBand + iBand) ); } poDS->SetBand( iBand+1, poBand ); } if( nComp > 1 ) poDS->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }