Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

rasterio.cpp

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

Generated at Thu Mar 28 09:47:31 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000