Coverage Report

Created: 2025-11-16 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}