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