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