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 : CPLErrorAccumulator oErrorAccumulator; 88 : int nRet; 89 : { 90 23837 : auto oAccumulator = oErrorAccumulator.InstallForCurrentScope(); 91 23837 : nRet = TIFFReadScanline(m_poGDS->m_hTIFF, m_poGDS->m_pabyBlockBuf, 92 23837 : m_poGDS->m_nLoadedBlock, 0); 93 : } 94 : 95 24051 : for (const auto &oError : oErrorAccumulator.GetErrors()) 96 : { 97 214 : ReportError(oError.type, oError.no, "%s", oError.msg.c_str()); 98 : // FAX decoding only handles EOF condition as a warning, so 99 : // catch it so as to turn on error when attempting to read 100 : // following lines, to avoid performance issues. 101 428 : if (!m_poGDS->m_bIgnoreReadErrors && 102 214 : oError.msg.find("Premature EOF") != std::string::npos) 103 : { 104 0 : m_nLastLineValid = nBlockYOff; 105 0 : nRet = -1; 106 : } 107 : } 108 : 109 23837 : if (nRet == -1 && !m_poGDS->m_bIgnoreReadErrors) 110 : { 111 3 : ReportError(CE_Failure, CPLE_AppDefined, 112 : "TIFFReadScanline() failed."); 113 3 : m_poGDS->m_nLoadedBlock = -1; 114 3 : GTIFFGetThreadLocalLibtiffError() = 0; 115 3 : return CE_Failure; 116 : } 117 : } 118 23834 : GTIFFGetThreadLocalLibtiffError() = 0; 119 : 120 : /* -------------------------------------------------------------------- */ 121 : /* Translate 1bit data to eight bit. */ 122 : /* -------------------------------------------------------------------- */ 123 23834 : int iSrcOffset = 0; 124 23834 : int iDstOffset = 0; 125 : 126 21647500 : for (int iPixel = 0; iPixel < nBlockXSize; ++iPixel, ++iSrcOffset) 127 : { 128 21623700 : if (m_poGDS->m_pabyBlockBuf[iSrcOffset >> 3] & 129 21623700 : (0x80 >> (iSrcOffset & 0x7))) 130 21262600 : static_cast<GByte *>(pImage)[iDstOffset++] = 1; 131 : else 132 361064 : static_cast<GByte *>(pImage)[iDstOffset++] = 0; 133 : } 134 : 135 23834 : return CE_None; 136 : } 137 : 138 : /************************************************************************/ 139 : /* IWriteBlock() */ 140 : /************************************************************************/ 141 : 142 0 : CPLErr GTiffSplitBitmapBand::IWriteBlock(int /* nBlockXOff */, 143 : int /* nBlockYOff */, 144 : void * /* pImage */) 145 : 146 : { 147 0 : ReportError(CE_Failure, CPLE_AppDefined, 148 : "Split bitmap bands are read-only."); 149 0 : return CE_Failure; 150 : }