00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 00031 00031 00031 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070
00071
00072 #include "gdal_priv.h"
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 CPLErr GDALRasterBand::IRasterIO( GDALRWFlag eRWFlag,
00083 int nXOff, int nYOff, int nXSize, int nYSize,
00084 void * pData, int nBufXSize, int nBufYSize,
00085 GDALDataType eBufType,
00086 int nPixelSpace, int nLineSpace )
00087
00088 {
00089 int nBandDataSize = GDALGetDataTypeSize( eDataType ) / 8;
00090 GByte *pabySrcBlock = NULL;
00091 GDALRasterBlock *poBlock;
00092 int nLBlockX=-1, nLBlockY=-1, iBufYOff, iBufXOff, iSrcY;
00093
00094
00095
00096
00097
00098
00099 if( eBufType == eDataType
00100 && nPixelSpace == GDALGetDataTypeSize(eBufType)/8
00101 && nLineSpace == nPixelSpace * nXSize
00102 && nBlockXSize == GetXSize()
00103 && nBufXSize == nXSize
00104 && nBufYSize == nYSize )
00105 {
00106 for( iBufYOff = 0; iBufYOff < nBufYSize; iBufYOff++ )
00107 {
00108 int nSrcByteOffset;
00109
00110 iSrcY = iBufYOff + nYOff;
00111
00112 if( iSrcY < nLBlockY * nBlockYSize
00113 || iSrcY >= (nLBlockY+1) * nBlockYSize )
00114 {
00115 nLBlockY = iSrcY / nBlockYSize;
00116
00117 poBlock = GetBlockRef( 0, nLBlockY );
00118 if( poBlock == NULL )
00119 {
00120 return( CE_Failure );
00121 }
00122
00123 if( eRWFlag == GF_Write )
00124 poBlock->MarkDirty();
00125
00126 pabySrcBlock = (GByte *) poBlock->GetDataRef();
00127 }
00128
00129 nSrcByteOffset = ((iSrcY-nLBlockY*nBlockYSize)*nBlockXSize + nXOff)
00130 * nPixelSpace;
00131
00132 if( eRWFlag == GF_Write )
00133 memcpy( pabySrcBlock + nSrcByteOffset,
00134 ((GByte *) pData) + iBufYOff * nLineSpace,
00135 nLineSpace );
00136 else
00137 memcpy( ((GByte *) pData) + iBufYOff * nLineSpace,
00138 pabySrcBlock + nSrcByteOffset,
00139 nLineSpace );
00140 }
00141
00142 return CE_None;
00143 }
00144
00145
00146
00147
00148
00149 if( (nBufXSize < nXSize || nBufYSize < nYSize)
00150 && GetOverviewCount() > 0 && eRWFlag == GF_Read )
00151 {
00152 if( OverviewRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
00153 pData, nBufXSize, nBufYSize,
00154 eBufType, nPixelSpace, nLineSpace ) == CE_None )
00155 return CE_None;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 double dfSrcX, dfSrcY, dfSrcXInc, dfSrcYInc;
00167 int iSrcX;
00168
00169 dfSrcXInc = nXSize / (double) nBufXSize;
00170 dfSrcYInc = nYSize / (double) nBufYSize;
00171
00172
00173
00174
00175 for( iBufYOff = 0; iBufYOff < nBufYSize; iBufYOff++ )
00176 {
00177 int iBufOffset, iSrcOffset;
00178
00179 dfSrcY = (iBufYOff+0.5) * dfSrcYInc + nYOff;
00180 iSrcY = (int) dfSrcY;
00181
00182 iBufOffset = iBufYOff * nLineSpace;
00183
00184 for( iBufXOff = 0; iBufXOff < nBufXSize; iBufXOff++ )
00185 {
00186 dfSrcX = (iBufXOff+0.5) * dfSrcXInc + nXOff;
00187
00188 iSrcX = (int) dfSrcX;
00189
00190
00191
00192
00193 if( iSrcX < nLBlockX * nBlockXSize
00194 || iSrcX >= (nLBlockX+1) * nBlockXSize
00195 || iSrcY < nLBlockY * nBlockYSize
00196 || iSrcY >= (nLBlockY+1) * nBlockYSize )
00197 {
00198 nLBlockX = iSrcX / nBlockXSize;
00199 nLBlockY = iSrcY / nBlockYSize;
00200
00201 poBlock = GetBlockRef( nLBlockX, nLBlockY );
00202 if( poBlock == NULL )
00203 {
00204 return( CE_Failure );
00205 }
00206
00207 if( eRWFlag == GF_Write )
00208 poBlock->MarkDirty();
00209
00210 pabySrcBlock = (GByte *) poBlock->GetDataRef();
00211 if( pabySrcBlock == NULL )
00212 return CE_Failure;
00213 }
00214
00215
00216
00217
00218 iSrcOffset = (iSrcX - nLBlockX*nBlockXSize
00219 + (iSrcY - nLBlockY*nBlockYSize) * nBlockXSize)*nBandDataSize;
00220
00221 if( eDataType == eBufType )
00222 {
00223 if( eRWFlag == GF_Read )
00224 memcpy( ((GByte *) pData) + iBufOffset,
00225 pabySrcBlock + iSrcOffset, nBandDataSize );
00226 else
00227 memcpy( pabySrcBlock + iSrcOffset,
00228 ((GByte *) pData) + iBufOffset, nBandDataSize );
00229 }
00230 else
00231 {
00232 00233
00234
00235 if( eRWFlag == GF_Read )
00236 GDALCopyWords( pabySrcBlock + iSrcOffset, eDataType, 0,
00237 ((GByte *) pData) + iBufOffset, eBufType, 0,
00238 1 );
00239 else
00240 GDALCopyWords( ((GByte *) pData) + iBufOffset, eBufType, 0,
00241 pabySrcBlock + iSrcOffset, eDataType, 0,
00242 1 );
00243 }
00244
00245 iBufOffset += nPixelSpace;
00246 }
00247 }
00248
00249 return( CE_None );
00250 }
00251
00252
00253
00254
00255
00256 void GDALSwapWords( void *pData, int nWordSize, int nWordCount,
00257 int nWordSkip )
00258
00259 {
00260 int i;
00261 GByte *pabyData = (GByte *) pData;
00262
00263 switch( nWordSize )
00264 {
00265 case 1:
00266 break;
00267
00268 case 2:
00269 CPLAssert( nWordSize >= 2 );
00270 for( i = 0; i < nWordCount; i++ )
00271 {
00272 GByte byTemp;
00273
00274 byTemp = pabyData[0];
00275 pabyData[0] = pabyData[1];
00276 pabyData[1] = byTemp;
00277
00278 pabyData += nWordSkip;
00279 }
00280 break;
00281
00282 case 4:
00283 CPLAssert( nWordSize >= 4 );
00284 for( i = 0; i < nWordCount; i++ )
00285 {
00286 GByte byTemp;
00287
00288 byTemp = pabyData[0];
00289 pabyData[0] = pabyData[3];
00290 pabyData[3] = byTemp;
00291
00292 byTemp = pabyData[1];
00293 pabyData[1] = pabyData[2];
00294 pabyData[2] = byTemp;
00295
00296 pabyData += nWordSkip;
00297 }
00298 break;
00299
00300 case 8:
00301 CPLAssert( nWordSize >= 8 );
00302 for( i = 0; i < nWordCount; i++ )
00303 {
00304 GByte byTemp;
00305
00306 byTemp = pabyData[0];
00307 pabyData[0] = pabyData[7];
00308 pabyData[7] = byTemp;
00309
00310 byTemp = pabyData[1];
00311 pabyData[1] = pabyData[6];
00312 pabyData[6] = byTemp;
00313
00314 byTemp = pabyData[2];
00315 pabyData[2] = pabyData[5];
00316 pabyData[5] = byTemp;
00317
00318 byTemp = pabyData[3];
00319 pabyData[3] = pabyData[4];
00320 pabyData[4] = byTemp;
00321
00322 pabyData += nWordSkip;
00323 }
00324 break;
00325
00326 default:
00327 CPLAssert( FALSE );
00328 }
00329 }
00330
00331
00332
00333
00334
00335 void
00336 GDALCopyWords( void * pSrcData, GDALDataType eSrcType, int nSrcPixelOffset,
00337 void * pDstData, GDALDataType eDstType, int nDstPixelOffset,
00338 int nWordCount )
00339
00340 {
00341
00342
00343
00344 if( eSrcType == eDstType )
00345 {
00346 int nWordSize = GDALGetDataTypeSize(eSrcType)/8;
00347 int i;
00348
00349
00350 if( nWordSize == nSrcPixelOffset && nWordSize == nDstPixelOffset )
00351 {
00352 memcpy( pDstData, pSrcData, nSrcPixelOffset * nWordCount );
00353 return;
00354 }
00355
00356
00357 for( i = 0; i < nWordCount; i++ )
00358 {
00359 memcpy( ((GByte *)pDstData) + i * nDstPixelOffset,
00360 ((GByte *)pSrcData) + i * nSrcPixelOffset,
00361 nWordSize );
00362 }
00363
00364 return;
00365 }
00366
00367
00368
00369
00370 for( int iWord = 0; iWord < nWordCount; iWord++ )
00371 {
00372 GByte *pabySrcWord, *pabyDstWord;
00373 double dfPixelValue, dfPixelValueI=0.0;
00374
00375 pabySrcWord = ((GByte *) pSrcData) + iWord * nSrcPixelOffset;
00376
00377
00378
00379
00380 switch( eSrcType )
00381 {
00382 case GDT_Byte:
00383 dfPixelValue = *pabySrcWord;
00384 break;
00385
00386 case GDT_UInt16:
00387 {
00388 GUInt16 nVal;
00389
00390 memcpy( &nVal, pabySrcWord, 2 );
00391 dfPixelValue = nVal;
00392 }
00393 break;
00394
00395 case GDT_Int16:
00396 {
00397 GInt16 nVal;
00398
00399 memcpy( &nVal, pabySrcWord, 2 );
00400 dfPixelValue = nVal;
00401 }
00402 break;
00403
00404 case GDT_Int32:
00405 {
00406 GInt32 nVal;
00407
00408 memcpy( &nVal, pabySrcWord, 4 );
00409 dfPixelValue = nVal;
00410 }
00411 break;
00412
00413 case GDT_UInt32:
00414 {
00415 GUInt32 nVal;
00416
00417 memcpy( &nVal, pabySrcWord, 4 );
00418 dfPixelValue = nVal;
00419 }
00420 break;
00421
00422 case GDT_Float32:
00423 {
00424 float fVal;
00425
00426 memcpy( &fVal, pabySrcWord, 4 );
00427 dfPixelValue = fVal;
00428 }
00429 break;
00430
00431 case GDT_Float64:
00432 {
00433 memcpy( &dfPixelValue, pabySrcWord, 8 );
00434 }
00435 break;
00436
00437 case GDT_CInt16:
00438 {
00439 GInt16 nVal;
00440
00441 memcpy( &nVal, pabySrcWord, 2 );
00442 dfPixelValue = nVal;
00443 memcpy( &nVal, pabySrcWord+2, 2 );
00444 dfPixelValueI = nVal;
00445 }
00446 break;
00447
00448 case GDT_CInt32:
00449 {
00450 GInt32 nVal;
00451
00452 memcpy( &nVal, pabySrcWord, 4 );
00453 dfPixelValue = nVal;
00454 memcpy( &nVal, pabySrcWord+4, 4 );
00455 dfPixelValueI = nVal;
00456 }
00457 break;
00458
00459 case GDT_CFloat32:
00460 {
00461 float fVal;
00462
00463 memcpy( &fVal, pabySrcWord, 4 );
00464 dfPixelValue = fVal;
00465 memcpy( &fVal, pabySrcWord+4, 4 );
00466 dfPixelValueI = fVal;
00467 }
00468 break;
00469
00470 case GDT_CFloat64:
00471 {
00472 memcpy( &dfPixelValue, pabySrcWord, 8 );
00473 memcpy( &dfPixelValueI, pabySrcWord+8, 8 );
00474 }
00475 break;
00476
00477 default:
00478 CPLAssert( FALSE );
00479 }
00480
00481
00482
00483
00484 pabyDstWord = ((GByte *) pDstData) + iWord * nDstPixelOffset;
00485 switch( eDstType )
00486 {
00487 case GDT_Byte:
00488 {
00489 if( dfPixelValue < 0.0 )
00490 *pabyDstWord = 0;
00491 else if( dfPixelValue > 255.0 )
00492 *pabyDstWord = 255;
00493 else
00494 *pabyDstWord = (GByte) dfPixelValue;
00495 }
00496 break;
00497
00498 case GDT_UInt16:
00499 {
00500 GUInt16 nVal;
00501
00502 if( dfPixelValue < 0.0 )
00503 nVal = 0;
00504 else if( dfPixelValue > 65535.0 )
00505 nVal = 65535;
00506 else
00507 nVal = (GUInt16) dfPixelValue;
00508
00509 memcpy( pabyDstWord, &nVal, 2 );
00510 }
00511 break;
00512
00513 case GDT_Int16:
00514 {
00515 GInt16 nVal;
00516
00517 if( dfPixelValue < -32768 )
00518 nVal = -32768;
00519 else if( dfPixelValue > 32767 )
00520 nVal = 32767;
00521 else
00522 nVal = (GInt16) dfPixelValue;
00523
00524 memcpy( pabyDstWord, &nVal, 2 );
00525 }
00526 break;
00527
00528 case GDT_UInt32:
00529 {
00530 GUInt32 nVal;
00531
00532 if( dfPixelValue < 0 )
00533 nVal = 0;
00534 else if( dfPixelValue > 4294967295U )
00535 nVal = 4294967295U;
00536 else
00537 nVal = (GInt32) dfPixelValue;
00538
00539 memcpy( pabyDstWord, &nVal, 4 );
00540 }
00541 break;
00542
00543 case GDT_Int32:
00544 {
00545 GInt32 nVal;
00546
00547 if( dfPixelValue < -2147483647.0 )
00548 nVal = -2147483647;
00549 else if( dfPixelValue > 2147483647 )
00550 nVal = 2147483647;
00551 else
00552 nVal = (GInt32) dfPixelValue;
00553
00554 memcpy( pabyDstWord, &nVal, 4 );
00555 }
00556 break;
00557
00558 case GDT_Float32:
00559 {
00560 float fVal;
00561
00562 fVal = dfPixelValue;
00563
00564 memcpy( pabyDstWord, &fVal, 4 );
00565 }
00566 break;
00567
00568 case GDT_Float64:
00569 memcpy( pabyDstWord, &dfPixelValue, 8 );
00570 break;
00571
00572 case GDT_CInt16:
00573 {
00574 GInt16 nVal;
00575
00576 if( dfPixelValue < -32768 )
00577 nVal = -32768;
00578 else if( dfPixelValue > 32767 )
00579 nVal = 32767;
00580 else
00581 nVal = (GInt16) dfPixelValue;
00582 memcpy( pabyDstWord, &nVal, 2 );
00583
00584 if( dfPixelValueI < -32768 )
00585 nVal = -32768;
00586 else if( dfPixelValueI > 32767 )
00587 nVal = 32767;
00588 else
00589 nVal = (GInt16) dfPixelValueI;
00590 memcpy( pabyDstWord+2, &nVal, 2 );
00591 }
00592 break;
00593
00594 case GDT_CInt32:
00595 {
00596 GInt32 nVal;
00597
00598 if( dfPixelValue < -2147483647.0 )
00599 nVal = -2147483647;
00600 else if( dfPixelValue > 2147483647 )
00601 nVal = 2147483647;
00602 else
00603 nVal = (GInt32) dfPixelValue;
00604
00605 memcpy( pabyDstWord, &nVal, 4 );
00606
00607 if( dfPixelValueI < -2147483647.0 )
00608 nVal = -2147483647;
00609 else if( dfPixelValueI > 2147483647 )
00610 nVal = 2147483647;
00611 else
00612 nVal = (GInt32) dfPixelValueI;
00613
00614 memcpy( pabyDstWord+4, &nVal, 4 );
00615 }
00616 break;
00617
00618 case GDT_CFloat32:
00619 {
00620 float fVal;
00621
00622 fVal = dfPixelValue;
00623 memcpy( pabyDstWord, &fVal, 4 );
00624 fVal = dfPixelValueI;
00625 memcpy( pabyDstWord+4, &fVal, 4 );
00626 }
00627 break;
00628
00629 case GDT_CFloat64:
00630 memcpy( pabyDstWord, &dfPixelValue, 8 );
00631 memcpy( pabyDstWord+8, &dfPixelValueI, 8 );
00632 break;
00633
00634 default:
00635 CPLAssert( FALSE );
00636 }
00637 }
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 CPLErr GDALRasterBand::OverviewRasterIO( GDALRWFlag eRWFlag,
00650 int nXOff, int nYOff, int nXSize, int nYSize,
00651 void * pData, int nBufXSize, int nBufYSize,
00652 GDALDataType eBufType,
00653 int nPixelSpace, int nLineSpace )
00654
00655
00656 {
00657 GDALRasterBand *poBestOverview = NULL;
00658 int nOverviewCount = GetOverviewCount();
00659 double dfDesiredResolution, dfBestResolution = 1.0;
00660
00661
00662
00663
00664
00665
00666 if( (nXSize / (double) nBufXSize) < (nYSize / (double) nBufYSize )
00667 || nBufYSize == 1 )
00668 dfDesiredResolution = nXSize / (double) nBufXSize;
00669 else
00670 dfDesiredResolution = nYSize / (double) nBufYSize;
00671
00672
00673
00674
00675
00676
00677 for( int iOverview = 0; iOverview < nOverviewCount; iOverview++ )
00678 {
00679 GDALRasterBand *poOverview = GetOverview( iOverview );
00680 double dfResolution;
00681
00682 if( (GetXSize() / (double) poOverview->GetXSize())
00683 < (GetYSize() / (double) poOverview->GetYSize()) )
00684 dfResolution =
00685 GetXSize() / (double) poOverview->GetXSize();
00686 else
00687 dfResolution =
00688 GetYSize() / (double) poOverview->GetYSize();
00689
00690 if( dfResolution < dfDesiredResolution * 1.2
00691 && dfResolution > dfBestResolution )
00692 {
00693 poBestOverview = poOverview;
00694 dfBestResolution = dfResolution;
00695 }
00696 }
00697
00698
00699
00700
00701
00702 if( poBestOverview == NULL )
00703 return CE_Failure;
00704
00705
00706
00707
00708
00709 int nOXOff, nOYOff, nOXSize, nOYSize;
00710 double dfXRes, dfYRes;
00711
00712 dfXRes = GetXSize() / (double) poBestOverview->GetXSize();
00713 dfYRes = GetYSize() / (double) poBestOverview->GetYSize();
00714
00715 nOXOff = MIN(poBestOverview->GetXSize()-1,(int) (nXOff/dfXRes+0.5));
00716 nOYOff = MIN(poBestOverview->GetYSize()-1,(int) (nYOff/dfYRes+0.5));
00717 nOXSize = MAX(1,(int) (nXSize/dfXRes + 0.5));
00718 nOYSize = MAX(1,(int) (nYSize/dfYRes + 0.5));
00719 if( nOXOff + nOXSize > poBestOverview->GetXSize() )
00720 nOXSize = poBestOverview->GetXSize() - nOXOff;
00721 if( nOYOff + nOYSize > poBestOverview->GetYSize() )
00722 nOYSize = poBestOverview->GetYSize() - nOYOff;
00723
00724
00725
00726
00727 return poBestOverview->RasterIO( eRWFlag, nOXOff, nOYOff, nOXSize, nOYSize,
00728 pData, nBufXSize, nBufYSize, eBufType,
00729 nPixelSpace, nLineSpace );
00730 }
00731