00001 /****************************************************************************** 00002 * $Id: rasterio_cpp-source.html,v 1.5 2000/11/06 04:49:01 warmerda Exp $ 00003 * 00004 * Project: GDAL Core 00005 * Purpose: Contains default implementation of GDALRasterBand::IRasterIO() 00006 * and supporting functions of broader utility. 00007 * Author: Frank Warmerdam, warmerda@home.com 00008 * 00009 ****************************************************************************** 00010 * Copyright (c) 1998, Frank Warmerdam 00011 * 00012 * Permission is hereby granted, free of charge, to any person obtaining a 00013 * copy of this software and associated documentation files (the "Software"), 00014 * to deal in the Software without restriction, including without limitation 00015 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00016 * and/or sell copies of the Software, and to permit persons to whom the 00017 * Software is furnished to do so, subject to the following conditions: 00018 * 00019 * The above copyright notice and this permission notice shall be included 00020 * in all copies or substantial portions of the Software. 00021 * 00022 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00023 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00025 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00027 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00028 * DEALINGS IN THE SOFTWARE. 00029 ****************************************************************************** 00030 * 00031 * $Log: rasterio_cpp-source.html,v $ 00031 * Revision 1.5 2000/11/06 04:49:01 warmerda 00031 * *** empty log message *** 00031 * 00032 * Revision 1.13 2000/08/16 15:50:52 warmerda 00033 * fixed some bugs with floating (datasetless) bands 00034 * 00035 * Revision 1.12 2000/07/13 13:08:53 warmerda 00036 * fixed GDALSwapWords with skip value different from word size 00037 * 00038 * Revision 1.11 2000/06/05 17:24:05 warmerda 00039 * added real complex support 00040 * 00041 * Revision 1.10 2000/05/15 14:33:49 warmerda 00042 * don't crash on read failure 00043 * 00044 * Revision 1.9 2000/04/04 15:25:13 warmerda 00045 * Fixed embarrasing bug in GDALCopyWords() for some cases. 00046 * 00047 * Revision 1.8 2000/03/06 18:57:07 warmerda 00048 * Fixed bug in 1:1 special case code. 00049 * 00050 * Revision 1.7 2000/03/06 02:22:13 warmerda 00051 * added overview support 00052 * 00053 * Revision 1.6 1999/11/23 18:44:10 warmerda 00054 * Fixed GDALCopyWords! 00055 * 00056 * Revision 1.5 1999/07/23 19:36:09 warmerda 00057 * added support for data type translation and a swapping function 00058 * 00059 * Revision 1.4 1999/01/11 15:38:38 warmerda 00060 * Added optimized case for simple 1:1 copies. 00061 * 00062 * Revision 1.3 1999/01/02 21:14:01 warmerda 00063 * Added write support 00064 * 00065 * Revision 1.2 1998/12/31 18:54:25 warmerda 00066 * Implement initial GDALRasterBlock support, and block cache 00067 * 00068 * Revision 1.1 1998/12/06 22:15:42 warmerda 00069 * New 00070 */ 00071 00072 #include "gdal_priv.h" 00073 00074 /************************************************************************/ 00075 /* IRasterIO() */ 00076 /* */ 00077 /* Default internal implementation of RasterIO() ... utilizes */ 00078 /* the Block access methods to satisfy the request. This would */ 00079 /* normally only be overridden by formats with overviews. */ 00080 /************************************************************************/ 00081 00082 CPLErr GDALRasterBand::IRasterIO( GDALRWFlag eRWFlag, 00083 int nXOff, int nYOff, int nXSize, int nYSize, 00084 void * pData, int nBufXSize, int nBufYSize, 00085 GDALDataType eBufType, 00086 int nPixelSpace, int nLineSpace ) 00087 00088 { 00089 int nBandDataSize = GDALGetDataTypeSize( eDataType ) / 8; 00090 GByte *pabySrcBlock = NULL; 00091 GDALRasterBlock *poBlock; 00092 int nLBlockX=-1, nLBlockY=-1, iBufYOff, iBufXOff, iSrcY; 00093 00094 /* ==================================================================== */ 00095 /* A common case is the data requested with it's inherent data */ 00096 /* type, the destination is packed, and the block width is the */ 00097 /* raster width. */ 00098 /* ==================================================================== */ 00099 if( eBufType == eDataType 00100 && nPixelSpace == GDALGetDataTypeSize(eBufType)/8 00101 && nLineSpace == nPixelSpace * nXSize 00102 && nBlockXSize == GetXSize() 00103 && nBufXSize == nXSize 00104 && nBufYSize == nYSize ) 00105 { 00106 for( iBufYOff = 0; iBufYOff < nBufYSize; iBufYOff++ ) 00107 { 00108 int nSrcByteOffset; 00109 00110 iSrcY = iBufYOff + nYOff; 00111 00112 if( iSrcY < nLBlockY * nBlockYSize 00113 || iSrcY >= (nLBlockY+1) * nBlockYSize ) 00114 { 00115 nLBlockY = iSrcY / nBlockYSize; 00116 00117 poBlock = GetBlockRef( 0, nLBlockY ); 00118 if( poBlock == NULL ) 00119 { 00120 return( CE_Failure ); 00121 } 00122 00123 if( eRWFlag == GF_Write ) 00124 poBlock->MarkDirty(); 00125 00126 pabySrcBlock = (GByte *) poBlock->GetDataRef(); 00127 } 00128 00129 nSrcByteOffset = ((iSrcY-nLBlockY*nBlockYSize)*nBlockXSize + nXOff) 00130 * nPixelSpace; 00131 00132 if( eRWFlag == GF_Write ) 00133 memcpy( pabySrcBlock + nSrcByteOffset, 00134 ((GByte *) pData) + iBufYOff * nLineSpace, 00135 nLineSpace ); 00136 else 00137 memcpy( ((GByte *) pData) + iBufYOff * nLineSpace, 00138 pabySrcBlock + nSrcByteOffset, 00139 nLineSpace ); 00140 } 00141 00142 return CE_None; 00143 } 00144 00145 /* ==================================================================== */ 00146 /* Do we have overviews that would be appropriate to satisfy */ 00147 /* this request? */ 00148 /* ==================================================================== */ 00149 if( (nBufXSize < nXSize || nBufYSize < nYSize) 00150 && GetOverviewCount() > 0 && eRWFlag == GF_Read ) 00151 { 00152 if( OverviewRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 00153 pData, nBufXSize, nBufYSize, 00154 eBufType, nPixelSpace, nLineSpace ) == CE_None ) 00155 return CE_None; 00156 } 00157 00158 /* ==================================================================== */ 00159 /* Loop reading required source blocks to satisfy output */ 00160 /* request. This is the most general implementation. */ 00161 /* ==================================================================== */ 00162 00163 /* -------------------------------------------------------------------- */ 00164 /* Compute stepping increment. */ 00165 /* -------------------------------------------------------------------- */ 00166 double dfSrcX, dfSrcY, dfSrcXInc, dfSrcYInc; 00167 int iSrcX; 00168 00169 dfSrcXInc = nXSize / (double) nBufXSize; 00170 dfSrcYInc = nYSize / (double) nBufYSize; 00171 00172 /* -------------------------------------------------------------------- */ 00173 /* Loop over buffer computing source locations. */ 00174 /* -------------------------------------------------------------------- */ 00175 for( iBufYOff = 0; iBufYOff < nBufYSize; iBufYOff++ ) 00176 { 00177 int iBufOffset, iSrcOffset; 00178 00179 dfSrcY = (iBufYOff+0.5) * dfSrcYInc + nYOff; 00180 iSrcY = (int) dfSrcY; 00181 00182 iBufOffset = iBufYOff * nLineSpace; 00183 00184 for( iBufXOff = 0; iBufXOff < nBufXSize; iBufXOff++ ) 00185 { 00186 dfSrcX = (iBufXOff+0.5) * dfSrcXInc + nXOff; 00187 00188 iSrcX = (int) dfSrcX; 00189 00190 /* -------------------------------------------------------------------- */ 00191 /* Ensure we have the appropriate block loaded. */ 00192 /* -------------------------------------------------------------------- */ 00193 if( iSrcX < nLBlockX * nBlockXSize 00194 || iSrcX >= (nLBlockX+1) * nBlockXSize 00195 || iSrcY < nLBlockY * nBlockYSize 00196 || iSrcY >= (nLBlockY+1) * nBlockYSize ) 00197 { 00198 nLBlockX = iSrcX / nBlockXSize; 00199 nLBlockY = iSrcY / nBlockYSize; 00200 00201 poBlock = GetBlockRef( nLBlockX, nLBlockY ); 00202 if( poBlock == NULL ) 00203 { 00204 return( CE_Failure ); 00205 } 00206 00207 if( eRWFlag == GF_Write ) 00208 poBlock->MarkDirty(); 00209 00210 pabySrcBlock = (GByte *) poBlock->GetDataRef(); 00211 if( pabySrcBlock == NULL ) 00212 return CE_Failure; 00213 } 00214 00215 /* -------------------------------------------------------------------- */ 00216 /* Copy over this pixel of data. */ 00217 /* -------------------------------------------------------------------- */ 00218 iSrcOffset = (iSrcX - nLBlockX*nBlockXSize 00219 + (iSrcY - nLBlockY*nBlockYSize) * nBlockXSize)*nBandDataSize; 00220 00221 if( eDataType == eBufType ) 00222 { 00223 if( eRWFlag == GF_Read ) 00224 memcpy( ((GByte *) pData) + iBufOffset, 00225 pabySrcBlock + iSrcOffset, nBandDataSize ); 00226 else 00227 memcpy( pabySrcBlock + iSrcOffset, 00228 ((GByte *) pData) + iBufOffset, nBandDataSize ); 00229 } 00230 else 00231 { 00232 /* type to type conversion ... ouch, this is expensive way 00233 of handling single words */ 00234 00235 if( eRWFlag == GF_Read ) 00236 GDALCopyWords( pabySrcBlock + iSrcOffset, eDataType, 0, 00237 ((GByte *) pData) + iBufOffset, eBufType, 0, 00238 1 ); 00239 else 00240 GDALCopyWords( ((GByte *) pData) + iBufOffset, eBufType, 0, 00241 pabySrcBlock + iSrcOffset, eDataType, 0, 00242 1 ); 00243 } 00244 00245 iBufOffset += nPixelSpace; 00246 } 00247 } 00248 00249 return( CE_None ); 00250 } 00251 00252 /************************************************************************/ 00253 /* GDALSwapWords() */ 00254 /************************************************************************/ 00255 00256 void GDALSwapWords( void *pData, int nWordSize, int nWordCount, 00257 int nWordSkip ) 00258 00259 { 00260 int i; 00261 GByte *pabyData = (GByte *) pData; 00262 00263 switch( nWordSize ) 00264 { 00265 case 1: 00266 break; 00267 00268 case 2: 00269 CPLAssert( nWordSize >= 2 ); 00270 for( i = 0; i < nWordCount; i++ ) 00271 { 00272 GByte byTemp; 00273 00274 byTemp = pabyData[0]; 00275 pabyData[0] = pabyData[1]; 00276 pabyData[1] = byTemp; 00277 00278 pabyData += nWordSkip; 00279 } 00280 break; 00281 00282 case 4: 00283 CPLAssert( nWordSize >= 4 ); 00284 for( i = 0; i < nWordCount; i++ ) 00285 { 00286 GByte byTemp; 00287 00288 byTemp = pabyData[0]; 00289 pabyData[0] = pabyData[3]; 00290 pabyData[3] = byTemp; 00291 00292 byTemp = pabyData[1]; 00293 pabyData[1] = pabyData[2]; 00294 pabyData[2] = byTemp; 00295 00296 pabyData += nWordSkip; 00297 } 00298 break; 00299 00300 case 8: 00301 CPLAssert( nWordSize >= 8 ); 00302 for( i = 0; i < nWordCount; i++ ) 00303 { 00304 GByte byTemp; 00305 00306 byTemp = pabyData[0]; 00307 pabyData[0] = pabyData[7]; 00308 pabyData[7] = byTemp; 00309 00310 byTemp = pabyData[1]; 00311 pabyData[1] = pabyData[6]; 00312 pabyData[6] = byTemp; 00313 00314 byTemp = pabyData[2]; 00315 pabyData[2] = pabyData[5]; 00316 pabyData[5] = byTemp; 00317 00318 byTemp = pabyData[3]; 00319 pabyData[3] = pabyData[4]; 00320 pabyData[4] = byTemp; 00321 00322 pabyData += nWordSkip; 00323 } 00324 break; 00325 00326 default: 00327 CPLAssert( FALSE ); 00328 } 00329 } 00330 00331 /************************************************************************/ 00332 /* GDALCopyWords() */ 00333 /************************************************************************/ 00334 00335 void 00336 GDALCopyWords( void * pSrcData, GDALDataType eSrcType, int nSrcPixelOffset, 00337 void * pDstData, GDALDataType eDstType, int nDstPixelOffset, 00338 int nWordCount ) 00339 00340 { 00341 /* -------------------------------------------------------------------- */ 00342 /* Special case when no data type translation is required. */ 00343 /* -------------------------------------------------------------------- */ 00344 if( eSrcType == eDstType ) 00345 { 00346 int nWordSize = GDALGetDataTypeSize(eSrcType)/8; 00347 int i; 00348 00349 // contiguous blocks. 00350 if( nWordSize == nSrcPixelOffset && nWordSize == nDstPixelOffset ) 00351 { 00352 memcpy( pDstData, pSrcData, nSrcPixelOffset * nWordCount ); 00353 return; 00354 } 00355 00356 // source or destination is not contiguous 00357 for( i = 0; i < nWordCount; i++ ) 00358 { 00359 memcpy( ((GByte *)pDstData) + i * nDstPixelOffset, 00360 ((GByte *)pSrcData) + i * nSrcPixelOffset, 00361 nWordSize ); 00362 } 00363 00364 return; 00365 } 00366 00367 /* ==================================================================== */ 00368 /* General translation case */ 00369 /* ==================================================================== */ 00370 for( int iWord = 0; iWord < nWordCount; iWord++ ) 00371 { 00372 GByte *pabySrcWord, *pabyDstWord; 00373 double dfPixelValue, dfPixelValueI=0.0; 00374 00375 pabySrcWord = ((GByte *) pSrcData) + iWord * nSrcPixelOffset; 00376 00377 /* -------------------------------------------------------------------- */ 00378 /* Fetch source value based on data type. */ 00379 /* -------------------------------------------------------------------- */ 00380 switch( eSrcType ) 00381 { 00382 case GDT_Byte: 00383 dfPixelValue = *pabySrcWord; 00384 break; 00385 00386 case GDT_UInt16: 00387 { 00388 GUInt16 nVal; 00389 00390 memcpy( &nVal, pabySrcWord, 2 ); 00391 dfPixelValue = nVal; 00392 } 00393 break; 00394 00395 case GDT_Int16: 00396 { 00397 GInt16 nVal; 00398 00399 memcpy( &nVal, pabySrcWord, 2 ); 00400 dfPixelValue = nVal; 00401 } 00402 break; 00403 00404 case GDT_Int32: 00405 { 00406 GInt32 nVal; 00407 00408 memcpy( &nVal, pabySrcWord, 4 ); 00409 dfPixelValue = nVal; 00410 } 00411 break; 00412 00413 case GDT_UInt32: 00414 { 00415 GUInt32 nVal; 00416 00417 memcpy( &nVal, pabySrcWord, 4 ); 00418 dfPixelValue = nVal; 00419 } 00420 break; 00421 00422 case GDT_Float32: 00423 { 00424 float fVal; 00425 00426 memcpy( &fVal, pabySrcWord, 4 ); 00427 dfPixelValue = fVal; 00428 } 00429 break; 00430 00431 case GDT_Float64: 00432 { 00433 memcpy( &dfPixelValue, pabySrcWord, 8 ); 00434 } 00435 break; 00436 00437 case GDT_CInt16: 00438 { 00439 GInt16 nVal; 00440 00441 memcpy( &nVal, pabySrcWord, 2 ); 00442 dfPixelValue = nVal; 00443 memcpy( &nVal, pabySrcWord+2, 2 ); 00444 dfPixelValueI = nVal; 00445 } 00446 break; 00447 00448 case GDT_CInt32: 00449 { 00450 GInt32 nVal; 00451 00452 memcpy( &nVal, pabySrcWord, 4 ); 00453 dfPixelValue = nVal; 00454 memcpy( &nVal, pabySrcWord+4, 4 ); 00455 dfPixelValueI = nVal; 00456 } 00457 break; 00458 00459 case GDT_CFloat32: 00460 { 00461 float fVal; 00462 00463 memcpy( &fVal, pabySrcWord, 4 ); 00464 dfPixelValue = fVal; 00465 memcpy( &fVal, pabySrcWord+4, 4 ); 00466 dfPixelValueI = fVal; 00467 } 00468 break; 00469 00470 case GDT_CFloat64: 00471 { 00472 memcpy( &dfPixelValue, pabySrcWord, 8 ); 00473 memcpy( &dfPixelValueI, pabySrcWord+8, 8 ); 00474 } 00475 break; 00476 00477 default: 00478 CPLAssert( FALSE ); 00479 } 00480 00481 /* -------------------------------------------------------------------- */ 00482 /* Set the destination pixel, doing range clipping as needed. */ 00483 /* -------------------------------------------------------------------- */ 00484 pabyDstWord = ((GByte *) pDstData) + iWord * nDstPixelOffset; 00485 switch( eDstType ) 00486 { 00487 case GDT_Byte: 00488 { 00489 if( dfPixelValue < 0.0 ) 00490 *pabyDstWord = 0; 00491 else if( dfPixelValue > 255.0 ) 00492 *pabyDstWord = 255; 00493 else 00494 *pabyDstWord = (GByte) dfPixelValue; 00495 } 00496 break; 00497 00498 case GDT_UInt16: 00499 { 00500 GUInt16 nVal; 00501 00502 if( dfPixelValue < 0.0 ) 00503 nVal = 0; 00504 else if( dfPixelValue > 65535.0 ) 00505 nVal = 65535; 00506 else 00507 nVal = (GUInt16) dfPixelValue; 00508 00509 memcpy( pabyDstWord, &nVal, 2 ); 00510 } 00511 break; 00512 00513 case GDT_Int16: 00514 { 00515 GInt16 nVal; 00516 00517 if( dfPixelValue < -32768 ) 00518 nVal = -32768; 00519 else if( dfPixelValue > 32767 ) 00520 nVal = 32767; 00521 else 00522 nVal = (GInt16) dfPixelValue; 00523 00524 memcpy( pabyDstWord, &nVal, 2 ); 00525 } 00526 break; 00527 00528 case GDT_UInt32: 00529 { 00530 GUInt32 nVal; 00531 00532 if( dfPixelValue < 0 ) 00533 nVal = 0; 00534 else if( dfPixelValue > 4294967295U ) 00535 nVal = 4294967295U; 00536 else 00537 nVal = (GInt32) dfPixelValue; 00538 00539 memcpy( pabyDstWord, &nVal, 4 ); 00540 } 00541 break; 00542 00543 case GDT_Int32: 00544 { 00545 GInt32 nVal; 00546 00547 if( dfPixelValue < -2147483647.0 ) 00548 nVal = -2147483647; 00549 else if( dfPixelValue > 2147483647 ) 00550 nVal = 2147483647; 00551 else 00552 nVal = (GInt32) dfPixelValue; 00553 00554 memcpy( pabyDstWord, &nVal, 4 ); 00555 } 00556 break; 00557 00558 case GDT_Float32: 00559 { 00560 float fVal; 00561 00562 fVal = dfPixelValue; 00563 00564 memcpy( pabyDstWord, &fVal, 4 ); 00565 } 00566 break; 00567 00568 case GDT_Float64: 00569 memcpy( pabyDstWord, &dfPixelValue, 8 ); 00570 break; 00571 00572 case GDT_CInt16: 00573 { 00574 GInt16 nVal; 00575 00576 if( dfPixelValue < -32768 ) 00577 nVal = -32768; 00578 else if( dfPixelValue > 32767 ) 00579 nVal = 32767; 00580 else 00581 nVal = (GInt16) dfPixelValue; 00582 memcpy( pabyDstWord, &nVal, 2 ); 00583 00584 if( dfPixelValueI < -32768 ) 00585 nVal = -32768; 00586 else if( dfPixelValueI > 32767 ) 00587 nVal = 32767; 00588 else 00589 nVal = (GInt16) dfPixelValueI; 00590 memcpy( pabyDstWord+2, &nVal, 2 ); 00591 } 00592 break; 00593 00594 case GDT_CInt32: 00595 { 00596 GInt32 nVal; 00597 00598 if( dfPixelValue < -2147483647.0 ) 00599 nVal = -2147483647; 00600 else if( dfPixelValue > 2147483647 ) 00601 nVal = 2147483647; 00602 else 00603 nVal = (GInt32) dfPixelValue; 00604 00605 memcpy( pabyDstWord, &nVal, 4 ); 00606 00607 if( dfPixelValueI < -2147483647.0 ) 00608 nVal = -2147483647; 00609 else if( dfPixelValueI > 2147483647 ) 00610 nVal = 2147483647; 00611 else 00612 nVal = (GInt32) dfPixelValueI; 00613 00614 memcpy( pabyDstWord+4, &nVal, 4 ); 00615 } 00616 break; 00617 00618 case GDT_CFloat32: 00619 { 00620 float fVal; 00621 00622 fVal = dfPixelValue; 00623 memcpy( pabyDstWord, &fVal, 4 ); 00624 fVal = dfPixelValueI; 00625 memcpy( pabyDstWord+4, &fVal, 4 ); 00626 } 00627 break; 00628 00629 case GDT_CFloat64: 00630 memcpy( pabyDstWord, &dfPixelValue, 8 ); 00631 memcpy( pabyDstWord+8, &dfPixelValueI, 8 ); 00632 break; 00633 00634 default: 00635 CPLAssert( FALSE ); 00636 } 00637 } /* next iWord */ 00638 } 00639 00640 /************************************************************************/ 00641 /* OverviewRasterIO() */ 00642 /* */ 00643 /* Special work function to utilize available overviews to */ 00644 /* more efficiently satisfy downsampled requests. It will */ 00645 /* return CE_Failure if there are no appropriate overviews */ 00646 /* available but it doesn't emit any error messages. */ 00647 /************************************************************************/ 00648 00649 CPLErr GDALRasterBand::OverviewRasterIO( GDALRWFlag eRWFlag, 00650 int nXOff, int nYOff, int nXSize, int nYSize, 00651 void * pData, int nBufXSize, int nBufYSize, 00652 GDALDataType eBufType, 00653 int nPixelSpace, int nLineSpace ) 00654 00655 00656 { 00657 GDALRasterBand *poBestOverview = NULL; 00658 int nOverviewCount = GetOverviewCount(); 00659 double dfDesiredResolution, dfBestResolution = 1.0; 00660 00661 /* -------------------------------------------------------------------- */ 00662 /* Find the Compute the desired resolution. The resolution is */ 00663 /* based on the least reduced axis, and represents the number */ 00664 /* of source pixels to one destination pixel. */ 00665 /* -------------------------------------------------------------------- */ 00666 if( (nXSize / (double) nBufXSize) < (nYSize / (double) nBufYSize ) 00667 || nBufYSize == 1 ) 00668 dfDesiredResolution = nXSize / (double) nBufXSize; 00669 else 00670 dfDesiredResolution = nYSize / (double) nBufYSize; 00671 00672 /* -------------------------------------------------------------------- */ 00673 /* Find the overview level that largest resolution value (most */ 00674 /* downsampled) that is still less than (or only a little more) */ 00675 /* downsampled than the request. */ 00676 /* -------------------------------------------------------------------- */ 00677 for( int iOverview = 0; iOverview < nOverviewCount; iOverview++ ) 00678 { 00679 GDALRasterBand *poOverview = GetOverview( iOverview ); 00680 double dfResolution; 00681 00682 if( (GetXSize() / (double) poOverview->GetXSize()) 00683 < (GetYSize() / (double) poOverview->GetYSize()) ) 00684 dfResolution = 00685 GetXSize() / (double) poOverview->GetXSize(); 00686 else 00687 dfResolution = 00688 GetYSize() / (double) poOverview->GetYSize(); 00689 00690 if( dfResolution < dfDesiredResolution * 1.2 00691 && dfResolution > dfBestResolution ) 00692 { 00693 poBestOverview = poOverview; 00694 dfBestResolution = dfResolution; 00695 } 00696 } 00697 00698 /* -------------------------------------------------------------------- */ 00699 /* If we didn't find an overview that helps us, just return */ 00700 /* indicating failure and the full resolution image will be used. */ 00701 /* -------------------------------------------------------------------- */ 00702 if( poBestOverview == NULL ) 00703 return CE_Failure; 00704 00705 /* -------------------------------------------------------------------- */ 00706 /* Recompute the source window in terms of the selected */ 00707 /* overview. */ 00708 /* -------------------------------------------------------------------- */ 00709 int nOXOff, nOYOff, nOXSize, nOYSize; 00710 double dfXRes, dfYRes; 00711 00712 dfXRes = GetXSize() / (double) poBestOverview->GetXSize(); 00713 dfYRes = GetYSize() / (double) poBestOverview->GetYSize(); 00714 00715 nOXOff = MIN(poBestOverview->GetXSize()-1,(int) (nXOff/dfXRes+0.5)); 00716 nOYOff = MIN(poBestOverview->GetYSize()-1,(int) (nYOff/dfYRes+0.5)); 00717 nOXSize = MAX(1,(int) (nXSize/dfXRes + 0.5)); 00718 nOYSize = MAX(1,(int) (nYSize/dfYRes + 0.5)); 00719 if( nOXOff + nOXSize > poBestOverview->GetXSize() ) 00720 nOXSize = poBestOverview->GetXSize() - nOXOff; 00721 if( nOYOff + nOYSize > poBestOverview->GetYSize() ) 00722 nOYSize = poBestOverview->GetYSize() - nOYOff; 00723 00724 /* -------------------------------------------------------------------- */ 00725 /* Recast the call in terms of the new raster layer. */ 00726 /* -------------------------------------------------------------------- */ 00727 return poBestOverview->RasterIO( eRWFlag, nOXOff, nOYOff, nOXSize, nOYSize, 00728 pData, nBufXSize, nBufYSize, eBufType, 00729 nPixelSpace, nLineSpace ); 00730 } 00731