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

Generated at Sat Dec 21 14:02:00 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000