/src/gdal/frmts/gtiff/gtiffsplitbitmapband.cpp
Line | Count | Source |
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 | | GTiffSplitBitmapBand::GTiffSplitBitmapBand(GTiffDataset *poDSIn, int nBandIn) |
26 | 0 | : GTiffBitmapBand(poDSIn, nBandIn) |
27 | | |
28 | 0 | { |
29 | 0 | nBlockXSize = poDS->GetRasterXSize(); |
30 | 0 | nBlockYSize = 1; |
31 | 0 | } |
32 | | |
33 | | /************************************************************************/ |
34 | | /* ~GTiffSplitBitmapBand() */ |
35 | | /************************************************************************/ |
36 | | |
37 | | GTiffSplitBitmapBand::~GTiffSplitBitmapBand() |
38 | 0 | { |
39 | 0 | } |
40 | | |
41 | | /************************************************************************/ |
42 | | /* IGetDataCoverageStatus() */ |
43 | | /************************************************************************/ |
44 | | |
45 | | int GTiffSplitBitmapBand::IGetDataCoverageStatus(int, int, int, int, int, |
46 | | double *) |
47 | 0 | { |
48 | 0 | return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED | |
49 | 0 | GDAL_DATA_COVERAGE_STATUS_DATA; |
50 | 0 | } |
51 | | |
52 | | /************************************************************************/ |
53 | | /* IReadBlock() */ |
54 | | /************************************************************************/ |
55 | | |
56 | | CPLErr GTiffSplitBitmapBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff, |
57 | | void *pImage) |
58 | | |
59 | 0 | { |
60 | 0 | m_poGDS->Crystalize(); |
61 | |
|
62 | 0 | if (m_nLastLineValid >= 0 && nBlockYOff > m_nLastLineValid) |
63 | 0 | return CE_Failure; |
64 | | |
65 | 0 | if (m_poGDS->m_pabyBlockBuf == nullptr) |
66 | 0 | { |
67 | 0 | m_poGDS->m_pabyBlockBuf = static_cast<GByte *>( |
68 | 0 | VSI_MALLOC_VERBOSE(TIFFScanlineSize(m_poGDS->m_hTIFF))); |
69 | 0 | if (m_poGDS->m_pabyBlockBuf == nullptr) |
70 | 0 | { |
71 | 0 | return CE_Failure; |
72 | 0 | } |
73 | 0 | } |
74 | | |
75 | | /* -------------------------------------------------------------------- */ |
76 | | /* Read through to target scanline. */ |
77 | | /* -------------------------------------------------------------------- */ |
78 | 0 | 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 | 0 | GTIFFGetThreadLocalLibtiffError() = 1; |
84 | 0 | while (m_poGDS->m_nLoadedBlock < nBlockYOff) |
85 | 0 | { |
86 | 0 | ++m_poGDS->m_nLoadedBlock; |
87 | |
|
88 | 0 | CPLErrorAccumulator oErrorAccumulator; |
89 | 0 | int nRet; |
90 | 0 | { |
91 | 0 | auto oAccumulator = oErrorAccumulator.InstallForCurrentScope(); |
92 | 0 | nRet = TIFFReadScanline(m_poGDS->m_hTIFF, m_poGDS->m_pabyBlockBuf, |
93 | 0 | m_poGDS->m_nLoadedBlock, 0); |
94 | 0 | } |
95 | |
|
96 | 0 | for (const auto &oError : oErrorAccumulator.GetErrors()) |
97 | 0 | { |
98 | 0 | 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 | 0 | if (!m_poGDS->m_bIgnoreReadErrors && |
103 | 0 | oError.msg.find("Premature EOF") != std::string::npos) |
104 | 0 | { |
105 | 0 | m_nLastLineValid = nBlockYOff; |
106 | 0 | nRet = -1; |
107 | 0 | } |
108 | 0 | } |
109 | |
|
110 | 0 | if (nRet == -1 && !m_poGDS->m_bIgnoreReadErrors) |
111 | 0 | { |
112 | 0 | ReportError(CE_Failure, CPLE_AppDefined, |
113 | 0 | "TIFFReadScanline() failed."); |
114 | 0 | m_poGDS->m_nLoadedBlock = -1; |
115 | 0 | GTIFFGetThreadLocalLibtiffError() = 0; |
116 | 0 | return CE_Failure; |
117 | 0 | } |
118 | 0 | } |
119 | 0 | GTIFFGetThreadLocalLibtiffError() = 0; |
120 | | |
121 | | /* -------------------------------------------------------------------- */ |
122 | | /* Translate 1bit data to eight bit. */ |
123 | | /* -------------------------------------------------------------------- */ |
124 | 0 | int iSrcOffset = 0; |
125 | 0 | int iDstOffset = 0; |
126 | |
|
127 | 0 | for (int iPixel = 0; iPixel < nBlockXSize; ++iPixel, ++iSrcOffset) |
128 | 0 | { |
129 | 0 | if (m_poGDS->m_pabyBlockBuf[iSrcOffset >> 3] & |
130 | 0 | (0x80 >> (iSrcOffset & 0x7))) |
131 | 0 | static_cast<GByte *>(pImage)[iDstOffset++] = 1; |
132 | 0 | else |
133 | 0 | static_cast<GByte *>(pImage)[iDstOffset++] = 0; |
134 | 0 | } |
135 | |
|
136 | 0 | return CE_None; |
137 | 0 | } |
138 | | |
139 | | /************************************************************************/ |
140 | | /* IWriteBlock() */ |
141 | | /************************************************************************/ |
142 | | |
143 | | CPLErr GTiffSplitBitmapBand::IWriteBlock(int /* nBlockXOff */, |
144 | | int /* nBlockYOff */, |
145 | | void * /* pImage */) |
146 | | |
147 | 0 | { |
148 | 0 | ReportError(CE_Failure, CPLE_AppDefined, |
149 | 0 | "Split bitmap bands are read-only."); |
150 | 0 | return CE_Failure; |
151 | 0 | } |