Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GeoTIFF Driver 4 : * Purpose: GDAL GeoTIFF support. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 1998, 2002, Frank Warmerdam <warmerdam@pobox.com> 9 : * Copyright (c) 2007-2015, Even Rouault <even dot rouault at spatialys dot com> 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #include "gtiffsplitband.h" 15 : 16 : #include "gtiffdataset.h" 17 : 18 : /************************************************************************/ 19 : /* GTiffSplitBand() */ 20 : /************************************************************************/ 21 : 22 131118 : GTiffSplitBand::GTiffSplitBand(GTiffDataset *poDSIn, int nBandIn) 23 131118 : : GTiffRasterBand(poDSIn, nBandIn) 24 : { 25 131118 : nBlockXSize = poDS->GetRasterXSize(); 26 131118 : nBlockYSize = 1; 27 131118 : } 28 : 29 : /************************************************************************/ 30 : /* IGetDataCoverageStatus() */ 31 : /************************************************************************/ 32 : 33 0 : int GTiffSplitBand::IGetDataCoverageStatus(int, int, int, int, int, double *) 34 : { 35 : return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED | 36 0 : GDAL_DATA_COVERAGE_STATUS_DATA; 37 : } 38 : 39 : /************************************************************************/ 40 : /* IReadBlock() */ 41 : /************************************************************************/ 42 : 43 78291 : CPLErr GTiffSplitBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff, 44 : void *pImage) 45 : 46 : { 47 78291 : m_poGDS->Crystalize(); 48 : 49 : // Optimization when reading the same line in a contig multi-band TIFF. 50 78291 : if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_CONTIG && 51 48291 : m_poGDS->nBands > 1 && m_poGDS->m_nLoadedBlock == nBlockYOff) 52 : { 53 4011 : goto extract_band_data; 54 : } 55 : 56 74280 : if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_CONTIG && m_poGDS->nBands > 1) 57 : { 58 40276 : if (m_poGDS->m_pabyBlockBuf == nullptr) 59 : { 60 14 : m_poGDS->m_pabyBlockBuf = static_cast<GByte *>( 61 7 : VSI_MALLOC_VERBOSE(TIFFScanlineSize(m_poGDS->m_hTIFF))); 62 7 : if (m_poGDS->m_pabyBlockBuf == nullptr) 63 : { 64 1 : return CE_Failure; 65 : } 66 : } 67 : } 68 : else 69 : { 70 34004 : CPLAssert(TIFFScanlineSize(m_poGDS->m_hTIFF) == nBlockXSize); 71 : } 72 : 73 : /* -------------------------------------------------------------------- */ 74 : /* Read through to target scanline. */ 75 : /* -------------------------------------------------------------------- */ 76 74279 : if (m_poGDS->m_nLoadedBlock >= nBlockYOff) 77 33 : m_poGDS->m_nLoadedBlock = -1; 78 : 79 74279 : if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE && 80 30000 : m_poGDS->nBands > 1) 81 : { 82 : // If we change of band, we must start reading the 83 : // new strip from its beginning. 84 30000 : if (m_poGDS->m_nLastBandRead != nBand) 85 20 : m_poGDS->m_nLoadedBlock = -1; 86 30000 : m_poGDS->m_nLastBandRead = nBand; 87 : } 88 : 89 203674 : while (m_poGDS->m_nLoadedBlock < nBlockYOff) 90 : { 91 129397 : ++m_poGDS->m_nLoadedBlock; 92 194550 : if (TIFFReadScanline(m_poGDS->m_hTIFF, 93 61149 : m_poGDS->m_pabyBlockBuf ? m_poGDS->m_pabyBlockBuf 94 : : pImage, 95 129397 : m_poGDS->m_nLoadedBlock, 96 129397 : (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE) 97 64244 : ? static_cast<uint16_t>(nBand - 1) 98 129399 : : 0) == -1 && 99 2 : !m_poGDS->m_bIgnoreReadErrors) 100 : { 101 2 : ReportError(CE_Failure, CPLE_AppDefined, 102 : "TIFFReadScanline() failed."); 103 2 : m_poGDS->m_nLoadedBlock = -1; 104 2 : return CE_Failure; 105 : } 106 : } 107 : 108 74277 : extract_band_data: 109 : /* -------------------------------------------------------------------- */ 110 : /* Extract band data from contig buffer. */ 111 : /* -------------------------------------------------------------------- */ 112 78288 : if (m_poGDS->m_pabyBlockBuf != nullptr) 113 : { 114 44286 : for (int iPixel = 0, iSrcOffset = nBand - 1, iDstOffset = 0; 115 180732 : iPixel < nBlockXSize; 116 136446 : ++iPixel, iSrcOffset += m_poGDS->nBands, ++iDstOffset) 117 : { 118 136446 : static_cast<GByte *>(pImage)[iDstOffset] = 119 136446 : m_poGDS->m_pabyBlockBuf[iSrcOffset]; 120 : } 121 : } 122 : 123 78288 : return CE_None; 124 : } 125 : 126 : /************************************************************************/ 127 : /* IWriteBlock() */ 128 : /************************************************************************/ 129 : 130 0 : CPLErr GTiffSplitBand::IWriteBlock(int /* nBlockXOff */, int /* nBlockYOff */, 131 : void * /* pImage */) 132 : 133 : { 134 0 : ReportError(CE_Failure, CPLE_AppDefined, "Split bands are read-only."); 135 0 : return CE_Failure; 136 : }