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 "gtiffsplitbitmapband.h" 15 : 16 : #include "gtiffdataset.h" 17 : 18 : #include "cpl_error_internal.h" 19 : 20 : /************************************************************************/ 21 : /* GTiffSplitBitmapBand() */ 22 : /************************************************************************/ 23 : 24 10 : GTiffSplitBitmapBand::GTiffSplitBitmapBand(GTiffDataset *poDSIn, int nBandIn) 25 10 : : GTiffBitmapBand(poDSIn, nBandIn) 26 : 27 : { 28 10 : nBlockXSize = poDS->GetRasterXSize(); 29 10 : nBlockYSize = 1; 30 10 : } 31 : 32 : /************************************************************************/ 33 : /* ~GTiffSplitBitmapBand() */ 34 : /************************************************************************/ 35 : 36 20 : GTiffSplitBitmapBand::~GTiffSplitBitmapBand() 37 : { 38 20 : } 39 : 40 : /************************************************************************/ 41 : /* IGetDataCoverageStatus() */ 42 : /************************************************************************/ 43 : 44 0 : int GTiffSplitBitmapBand::IGetDataCoverageStatus(int, int, int, int, int, 45 : double *) 46 : { 47 : return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED | 48 0 : GDAL_DATA_COVERAGE_STATUS_DATA; 49 : } 50 : 51 : /************************************************************************/ 52 : /* IReadBlock() */ 53 : /************************************************************************/ 54 : 55 23837 : CPLErr GTiffSplitBitmapBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff, 56 : void *pImage) 57 : 58 : { 59 23837 : m_poGDS->Crystalize(); 60 : 61 23837 : if (m_nLastLineValid >= 0 && nBlockYOff > m_nLastLineValid) 62 0 : return CE_Failure; 63 : 64 23837 : if (m_poGDS->m_pabyBlockBuf == nullptr) 65 : { 66 14 : m_poGDS->m_pabyBlockBuf = static_cast<GByte *>( 67 7 : VSI_MALLOC_VERBOSE(TIFFScanlineSize(m_poGDS->m_hTIFF))); 68 7 : if (m_poGDS->m_pabyBlockBuf == nullptr) 69 : { 70 0 : return CE_Failure; 71 : } 72 : } 73 : 74 : /* -------------------------------------------------------------------- */ 75 : /* Read through to target scanline. */ 76 : /* -------------------------------------------------------------------- */ 77 23837 : if (m_poGDS->m_nLoadedBlock >= nBlockYOff) 78 0 : m_poGDS->m_nLoadedBlock = -1; 79 : 80 : // Set to 1 to allow GTiffErrorHandler to implement limitation on error 81 : // messages 82 23837 : GTIFFGetThreadLocalLibtiffError() = 1; 83 47671 : while (m_poGDS->m_nLoadedBlock < nBlockYOff) 84 : { 85 23837 : ++m_poGDS->m_nLoadedBlock; 86 : 87 23837 : std::vector<CPLErrorHandlerAccumulatorStruct> aoErrors; 88 23837 : CPLInstallErrorHandlerAccumulator(aoErrors); 89 47674 : int nRet = TIFFReadScanline(m_poGDS->m_hTIFF, m_poGDS->m_pabyBlockBuf, 90 23837 : m_poGDS->m_nLoadedBlock, 0); 91 23837 : CPLUninstallErrorHandlerAccumulator(); 92 : 93 24051 : for (size_t iError = 0; iError < aoErrors.size(); ++iError) 94 : { 95 214 : ReportError(aoErrors[iError].type, aoErrors[iError].no, "%s", 96 214 : aoErrors[iError].msg.c_str()); 97 : // FAX decoding only handles EOF condition as a warning, so 98 : // catch it so as to turn on error when attempting to read 99 : // following lines, to avoid performance issues. 100 428 : if (!m_poGDS->m_bIgnoreReadErrors && 101 214 : aoErrors[iError].msg.find("Premature EOF") != std::string::npos) 102 : { 103 0 : m_nLastLineValid = nBlockYOff; 104 0 : nRet = -1; 105 : } 106 : } 107 : 108 23837 : if (nRet == -1 && !m_poGDS->m_bIgnoreReadErrors) 109 : { 110 3 : ReportError(CE_Failure, CPLE_AppDefined, 111 : "TIFFReadScanline() failed."); 112 3 : m_poGDS->m_nLoadedBlock = -1; 113 3 : GTIFFGetThreadLocalLibtiffError() = 0; 114 3 : return CE_Failure; 115 : } 116 : } 117 23834 : GTIFFGetThreadLocalLibtiffError() = 0; 118 : 119 : /* -------------------------------------------------------------------- */ 120 : /* Translate 1bit data to eight bit. */ 121 : /* -------------------------------------------------------------------- */ 122 23834 : int iSrcOffset = 0; 123 23834 : int iDstOffset = 0; 124 : 125 21647500 : for (int iPixel = 0; iPixel < nBlockXSize; ++iPixel, ++iSrcOffset) 126 : { 127 21623700 : if (m_poGDS->m_pabyBlockBuf[iSrcOffset >> 3] & 128 21623700 : (0x80 >> (iSrcOffset & 0x7))) 129 21262600 : static_cast<GByte *>(pImage)[iDstOffset++] = 1; 130 : else 131 361064 : static_cast<GByte *>(pImage)[iDstOffset++] = 0; 132 : } 133 : 134 23834 : return CE_None; 135 : } 136 : 137 : /************************************************************************/ 138 : /* IWriteBlock() */ 139 : /************************************************************************/ 140 : 141 0 : CPLErr GTiffSplitBitmapBand::IWriteBlock(int /* nBlockXOff */, 142 : int /* nBlockYOff */, 143 : void * /* pImage */) 144 : 145 : { 146 0 : ReportError(CE_Failure, CPLE_AppDefined, 147 : "Split bitmap bands are read-only."); 148 0 : return CE_Failure; 149 : }