CPLErr WEBPRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void * pImage ) { WEBPDataset* poGDS = (WEBPDataset*) poDS; if( poGDS->Uncompress() != CE_None ) return CE_Failure; int i; GByte* pabyUncompressed = &poGDS->pabyUncompressed[nBlockYOff * nRasterXSize * poGDS->nBands + nBand - 1]; for(i=0;i<nRasterXSize;i++) ((GByte*)pImage)[i] = pabyUncompressed[poGDS->nBands * i]; return CE_None; }
CPLErr WEBPRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { WEBPDataset* poGDS = (WEBPDataset*) poDS; poGDS->Uncompress(); int i; GByte* pabyUncompressed = &poGDS->pabyUncompressed[nBlockYOff * nRasterXSize * 3 + nBand - 1]; for(i=0;i<nRasterXSize;i++) ((GByte*)pImage)[i] = pabyUncompressed[3 * i]; return CE_None; }
GDALDataset * WEBPDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); /* -------------------------------------------------------------------- */ /* WEBP library initialization */ /* -------------------------------------------------------------------- */ WebPPicture sPicture; if (!WebPPictureInit(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureInit() failed"); return NULL; } /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ if( nXSize > 16383 || nYSize > 16383 ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP maximum image dimensions are 16383 x 16383."); return NULL; } if( nBands != 3 #if WEBP_ENCODER_ABI_VERSION >= 0x0100 && nBands != 4 #endif ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP driver doesn't support %d bands. Must be 3 (RGB) " #if WEBP_ENCODER_ABI_VERSION >= 0x0100 "or 4 (RGBA) " #endif "bands.", nBands ); return NULL; } GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eDT != GDT_Byte ) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "WEBP driver doesn't support data type %s. " "Only eight bit byte bands supported.", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); if (bStrict) return NULL; } /* -------------------------------------------------------------------- */ /* What options has the user selected? */ /* -------------------------------------------------------------------- */ float fQuality = 75.0f; const char* pszQUALITY = CSLFetchNameValue(papszOptions, "QUALITY"); if( pszQUALITY != NULL ) { fQuality = (float) CPLAtof(pszQUALITY); if( fQuality < 0.0f || fQuality > 100.0f ) { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "QUALITY", pszQUALITY); return NULL; } } WebPPreset nPreset = WEBP_PRESET_DEFAULT; const char* pszPRESET = CSLFetchNameValueDef(papszOptions, "PRESET", "DEFAULT"); if (EQUAL(pszPRESET, "DEFAULT")) nPreset = WEBP_PRESET_DEFAULT; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "PHOTO")) nPreset = WEBP_PRESET_PHOTO; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "DRAWING")) nPreset = WEBP_PRESET_DRAWING; else if (EQUAL(pszPRESET, "ICON")) nPreset = WEBP_PRESET_ICON; else if (EQUAL(pszPRESET, "TEXT")) nPreset = WEBP_PRESET_TEXT; else { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "PRESET", pszPRESET ); return NULL; } WebPConfig sConfig; if (!WebPConfigInitInternal(&sConfig, nPreset, fQuality, WEBP_ENCODER_ABI_VERSION)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPConfigInit() failed"); return NULL; } #define FETCH_AND_SET_OPTION_INT(name, fieldname, minval, maxval) \ { \ const char* pszVal = CSLFetchNameValue(papszOptions, name); \ if (pszVal != NULL) \ { \ sConfig.fieldname = atoi(pszVal); \ if (sConfig.fieldname < minval || sConfig.fieldname > maxval) \ { \ CPLError( CE_Failure, CPLE_IllegalArg, \ "%s=%s is not a legal value.", name, pszVal ); \ return NULL; \ } \ } \ } FETCH_AND_SET_OPTION_INT("TARGETSIZE", target_size, 0, INT_MAX); const char* pszPSNR = CSLFetchNameValue(papszOptions, "PSNR"); if (pszPSNR) { sConfig.target_PSNR = CPLAtof(pszPSNR); if (sConfig.target_PSNR < 0) { CPLError( CE_Failure, CPLE_IllegalArg, "PSNR=%s is not a legal value.", pszPSNR ); return NULL; } } FETCH_AND_SET_OPTION_INT("METHOD", method, 0, 6); FETCH_AND_SET_OPTION_INT("SEGMENTS", segments, 1, 4); FETCH_AND_SET_OPTION_INT("SNS_STRENGTH", sns_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_STRENGTH", filter_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_SHARPNESS", filter_sharpness, 0, 7); FETCH_AND_SET_OPTION_INT("FILTER_TYPE", filter_type, 0, 1); FETCH_AND_SET_OPTION_INT("AUTOFILTER", autofilter, 0, 1); FETCH_AND_SET_OPTION_INT("PASS", pass, 1, 10); FETCH_AND_SET_OPTION_INT("PREPROCESSING", preprocessing, 0, 1); FETCH_AND_SET_OPTION_INT("PARTITIONS", partitions, 0, 3); #if WEBP_ENCODER_ABI_VERSION >= 0x0002 FETCH_AND_SET_OPTION_INT("PARTITION_LIMIT", partition_limit, 0, 100); #endif #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sConfig.lossless = CSLFetchBoolean(papszOptions, "LOSSLESS", FALSE); if (sConfig.lossless) sPicture.use_argb = 1; #endif if (!WebPValidateConfig(&sConfig)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPValidateConfig() failed"); return NULL; } /* -------------------------------------------------------------------- */ /* Allocate memory */ /* -------------------------------------------------------------------- */ GByte *pabyBuffer; pabyBuffer = (GByte *) VSIMalloc( nBands * nXSize * nYSize ); if (pabyBuffer == NULL) { return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ VSILFILE *fpImage; fpImage = VSIFOpenL( pszFilename, "wb" ); if( fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create WEBP file %s.\n", pszFilename ); VSIFree(pabyBuffer); return NULL; } WebPUserData sUserData; sUserData.fp = fpImage; sUserData.pfnProgress = pfnProgress ? pfnProgress : GDALDummyProgress; sUserData.pProgressData = pProgressData; /* -------------------------------------------------------------------- */ /* WEBP library settings */ /* -------------------------------------------------------------------- */ sPicture.width = nXSize; sPicture.height = nYSize; sPicture.writer = WEBPDatasetWriter; sPicture.custom_ptr = &sUserData; #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sPicture.progress_hook = WEBPDatasetProgressHook; #endif if (!WebPPictureAlloc(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureAlloc() failed"); VSIFree(pabyBuffer); VSIFCloseL( fpImage ); return NULL; } /* -------------------------------------------------------------------- */ /* Acquire source imagery. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; eErr = poSrcDS->RasterIO( GF_Read, 0, 0, nXSize, nYSize, pabyBuffer, nXSize, nYSize, GDT_Byte, nBands, NULL, nBands, nBands * nXSize, 1, NULL ); /* -------------------------------------------------------------------- */ /* Import and write to file */ /* -------------------------------------------------------------------- */ #if WEBP_ENCODER_ABI_VERSION >= 0x0100 if (eErr == CE_None && nBands == 4) { if (!WebPPictureImportRGBA(&sPicture, pabyBuffer, nBands * nXSize)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGBA() failed"); eErr = CE_Failure; } } else #endif if (eErr == CE_None && !WebPPictureImportRGB(&sPicture, pabyBuffer, nBands * nXSize)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGB() failed"); eErr = CE_Failure; } if (eErr == CE_None && !WebPEncode(&sConfig, &sPicture)) { const char* pszErrorMsg = NULL; #if WEBP_ENCODER_ABI_VERSION >= 0x0100 switch(sPicture.error_code) { case VP8_ENC_ERROR_OUT_OF_MEMORY: pszErrorMsg = "Out of memory"; break; case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: pszErrorMsg = "Out of memory while flushing bits"; break; case VP8_ENC_ERROR_NULL_PARAMETER: pszErrorMsg = "A pointer parameter is NULL"; break; case VP8_ENC_ERROR_INVALID_CONFIGURATION: pszErrorMsg = "Configuration is invalid"; break; case VP8_ENC_ERROR_BAD_DIMENSION: pszErrorMsg = "Picture has invalid width/height"; break; case VP8_ENC_ERROR_PARTITION0_OVERFLOW: pszErrorMsg = "Partition is bigger than 512k. Try using less SEGMENTS, or increase PARTITION_LIMIT value"; break; case VP8_ENC_ERROR_PARTITION_OVERFLOW: pszErrorMsg = "Partition is bigger than 16M"; break; case VP8_ENC_ERROR_BAD_WRITE: pszErrorMsg = "Error while flusing bytes"; break; case VP8_ENC_ERROR_FILE_TOO_BIG: pszErrorMsg = "File is bigger than 4G"; break; case VP8_ENC_ERROR_USER_ABORT: pszErrorMsg = "User interrupted"; break; default: break; } #endif if (pszErrorMsg) CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed : %s", pszErrorMsg); else CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed"); eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Cleanup and close. */ /* -------------------------------------------------------------------- */ CPLFree( pabyBuffer ); WebPPictureFree(&sPicture); VSIFCloseL( fpImage ); if( eErr != CE_None ) { VSIUnlink( pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxiliary pam information. */ /* -------------------------------------------------------------------- */ GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly); /* If outputing to stdout, we can't reopen it, so we'll return */ /* a fake dataset to make the caller happy */ CPLPushErrorHandler(CPLQuietErrorHandler); WEBPDataset *poDS = (WEBPDataset*) WEBPDataset::Open( &oOpenInfo ); CPLPopErrorHandler(); if( poDS ) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; } return NULL; }
GDALDataset *WEBPDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) || poOpenInfo->fpL == NULL ) return NULL; int nWidth, nHeight; if (!WebPGetInfo((const uint8_t*)poOpenInfo->pabyHeader, (uint32_t)poOpenInfo->nHeaderBytes, &nWidth, &nHeight)) return NULL; int nBands = 3; #if WEBP_DECODER_ABI_VERSION >= 0x0002 WebPDecoderConfig config; if (!WebPInitDecoderConfig(&config)) return NULL; int bOK = WebPGetFeatures(poOpenInfo->pabyHeader, poOpenInfo->nHeaderBytes, &config.input) == VP8_STATUS_OK; if (config.input.has_alpha) nBands = 4; WebPFreeDecBuffer(&config.output); if (!bOK) return NULL; #endif if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The WEBP driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ WEBPDataset *poDS; poDS = new WEBPDataset(); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nHeight; poDS->fpImage = poOpenInfo->fpL; poOpenInfo->fpL = NULL; /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < nBands; iBand++ ) poDS->SetBand( iBand+1, new WEBPRasterBand( poDS, iBand+1 ) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML( poOpenInfo->GetSiblingFiles() ); /* -------------------------------------------------------------------- */ /* Open overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles() ); return poDS; }
GDALDataset * WEBPDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); /* -------------------------------------------------------------------- */ /* WEBP library initialization */ /* -------------------------------------------------------------------- */ WebPPicture sPicture; if (!WebPPictureInit(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureInit() failed"); return NULL; } /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ if( nXSize > 16383 || nYSize > 16383 ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP maximum image dimensions are 16383 x 16383."); return NULL; } if( nBands != 3 ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP driver doesn't support %d bands. Must be 3 (RGB) bands.", nBands ); return NULL; } GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eDT != GDT_Byte ) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "WEBP driver doesn't support data type %s. " "Only eight bit byte bands supported.", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); if (bStrict) return NULL; } /* -------------------------------------------------------------------- */ /* What options has the user selected? */ /* -------------------------------------------------------------------- */ float fQuality = 75.0f; const char* pszQUALITY = CSLFetchNameValue(papszOptions, "QUALITY"); if( pszQUALITY != NULL ) { fQuality = (float) atof(pszQUALITY); if( fQuality < 0.0f || fQuality > 100.0f ) { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "QUALITY", pszQUALITY); return NULL; } } WebPPreset nPreset = WEBP_PRESET_DEFAULT; const char* pszPRESET = CSLFetchNameValueDef(papszOptions, "PRESET", "DEFAULT"); if (EQUAL(pszPRESET, "DEFAULT")) nPreset = WEBP_PRESET_DEFAULT; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "PHOTO")) nPreset = WEBP_PRESET_PHOTO; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "DRAWING")) nPreset = WEBP_PRESET_DRAWING; else if (EQUAL(pszPRESET, "ICON")) nPreset = WEBP_PRESET_ICON; else if (EQUAL(pszPRESET, "TEXT")) nPreset = WEBP_PRESET_TEXT; else { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "PRESET", pszPRESET ); return NULL; } WebPConfig sConfig; if (!WebPConfigInitInternal(&sConfig, nPreset, fQuality, WEBP_ENCODER_ABI_VERSION)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPConfigInit() failed"); return NULL; } #define FETCH_AND_SET_OPTION_INT(name, fieldname, minval, maxval) \ { \ const char* pszVal = CSLFetchNameValue(papszOptions, name); \ if (pszVal != NULL) \ { \ sConfig.fieldname = atoi(pszVal); \ if (sConfig.fieldname < minval || sConfig.fieldname > maxval) \ { \ CPLError( CE_Failure, CPLE_IllegalArg, \ "%s=%s is not a legal value.", name, pszVal ); \ return NULL; \ } \ } \ } FETCH_AND_SET_OPTION_INT("TARGETSIZE", target_size, 0, INT_MAX); const char* pszPSNR = CSLFetchNameValue(papszOptions, "PSNR"); if (pszPSNR) { sConfig.target_PSNR = atof(pszPSNR); if (sConfig.target_PSNR < 0) { CPLError( CE_Failure, CPLE_IllegalArg, "PSNR=%s is not a legal value.", pszPSNR ); return NULL; } } FETCH_AND_SET_OPTION_INT("METHOD", method, 0, 6); FETCH_AND_SET_OPTION_INT("SEGMENTS", segments, 1, 4); FETCH_AND_SET_OPTION_INT("SNS_STRENGTH", sns_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_STRENGTH", filter_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_SHARPNESS", filter_sharpness, 0, 7); FETCH_AND_SET_OPTION_INT("FILTER_TYPE", filter_type, 0, 1); FETCH_AND_SET_OPTION_INT("AUTOFILTER", autofilter, 0, 1); FETCH_AND_SET_OPTION_INT("PASS", pass, 1, 10); FETCH_AND_SET_OPTION_INT("PREPROCESSING", preprocessing, 0, 1); FETCH_AND_SET_OPTION_INT("PARTITIONS", partitions, 0, 3); if (!WebPValidateConfig(&sConfig)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPValidateConfig() failed"); return NULL; } /* -------------------------------------------------------------------- */ /* Allocate memory */ /* -------------------------------------------------------------------- */ GByte *pabyBuffer; pabyBuffer = (GByte *) VSIMalloc( 3 * nXSize * nYSize ); if (pabyBuffer == NULL) { return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ VSILFILE *fpImage; fpImage = VSIFOpenL( pszFilename, "wb" ); if( fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create WEBP file %s.\n", pszFilename ); VSIFree(pabyBuffer); return NULL; } /* -------------------------------------------------------------------- */ /* WEBP library settings */ /* -------------------------------------------------------------------- */ sPicture.colorspace = 0; sPicture.width = nXSize; sPicture.height = nYSize; sPicture.writer = WEBPDatasetWriter; sPicture.custom_ptr = fpImage; if (!WebPPictureAlloc(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureAlloc() failed"); VSIFree(pabyBuffer); VSIFCloseL( fpImage ); return NULL; } /* -------------------------------------------------------------------- */ /* Acquire source imagery. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; eErr = poSrcDS->RasterIO( GF_Read, 0, 0, nXSize, nYSize, pabyBuffer, nXSize, nYSize, GDT_Byte, 3, NULL, 3, 3 * nXSize, 1 ); /* -------------------------------------------------------------------- */ /* Import and write to file */ /* -------------------------------------------------------------------- */ if (eErr == CE_None && !WebPPictureImportRGB(&sPicture, pabyBuffer, 3 * nXSize)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGB() failed"); eErr = CE_Failure; } if (eErr == CE_None && !WebPEncode(&sConfig, &sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed"); eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Cleanup and close. */ /* -------------------------------------------------------------------- */ CPLFree( pabyBuffer ); WebPPictureFree(&sPicture); VSIFCloseL( fpImage ); if( eErr != CE_None ) { VSIUnlink( pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxilary pam information. */ /* -------------------------------------------------------------------- */ GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly); /* If outputing to stdout, we can't reopen it, so we'll return */ /* a fake dataset to make the caller happy */ CPLPushErrorHandler(CPLQuietErrorHandler); WEBPDataset *poDS = (WEBPDataset*) WEBPDataset::Open( &oOpenInfo ); CPLPopErrorHandler(); if( poDS ) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; } return NULL; }
GDALDataset *WEBPDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; int nWidth, nHeight; if (!WebPGetInfo((const uint8_t*)poOpenInfo->pabyHeader, (uint32_t)poOpenInfo->nHeaderBytes, &nWidth, &nHeight)) return NULL; if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The WEBP driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the file using the large file api. */ /* -------------------------------------------------------------------- */ VSILFILE* fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpImage == NULL ) return NULL; GByte* pabyUncompressed = (GByte*)VSIMalloc3(nWidth, nHeight, 3); if (pabyUncompressed == NULL) { VSIFCloseL(fpImage); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ WEBPDataset *poDS; poDS = new WEBPDataset(); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nHeight; poDS->fpImage = fpImage; poDS->pabyUncompressed = pabyUncompressed; /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < 3; iBand++ ) poDS->SetBand( iBand+1, new WEBPRasterBand( poDS, iBand+1 ) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML( poOpenInfo->papszSiblingFiles ); /* -------------------------------------------------------------------- */ /* Open overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles ); return poDS; }