Coverage Report

Created: 2025-06-09 07:43

/src/gdal/frmts/gtiff/gtiffsplitband.cpp
Line
Count
Source (jump to first uncovered line)
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 "gtiffsplitband.h"
15
16
#include "gtiffdataset.h"
17
18
/************************************************************************/
19
/*                           GTiffSplitBand()                           */
20
/************************************************************************/
21
22
GTiffSplitBand::GTiffSplitBand(GTiffDataset *poDSIn, int nBandIn)
23
1.74k
    : GTiffRasterBand(poDSIn, nBandIn)
24
1.74k
{
25
1.74k
    nBlockXSize = poDS->GetRasterXSize();
26
1.74k
    nBlockYSize = 1;
27
1.74k
}
28
29
/************************************************************************/
30
/*                       IGetDataCoverageStatus()                       */
31
/************************************************************************/
32
33
int GTiffSplitBand::IGetDataCoverageStatus(int, int, int, int, int, double *)
34
0
{
35
0
    return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
36
0
           GDAL_DATA_COVERAGE_STATUS_DATA;
37
0
}
38
39
/************************************************************************/
40
/*                             IReadBlock()                             */
41
/************************************************************************/
42
43
CPLErr GTiffSplitBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff,
44
                                  void *pImage)
45
46
38.1k
{
47
38.1k
    m_poGDS->Crystalize();
48
49
    // Optimization when reading the same line in a contig multi-band TIFF.
50
38.1k
    if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_CONTIG &&
51
38.1k
        m_poGDS->nBands > 1 && m_poGDS->m_nLoadedBlock == nBlockYOff)
52
0
    {
53
0
        goto extract_band_data;
54
0
    }
55
56
38.1k
    if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_CONTIG && m_poGDS->nBands > 1)
57
10.2k
    {
58
10.2k
        if (m_poGDS->m_pabyBlockBuf == nullptr)
59
8
        {
60
8
            m_poGDS->m_pabyBlockBuf = static_cast<GByte *>(
61
8
                VSI_MALLOC_VERBOSE(TIFFScanlineSize(m_poGDS->m_hTIFF)));
62
8
            if (m_poGDS->m_pabyBlockBuf == nullptr)
63
0
            {
64
0
                return CE_Failure;
65
0
            }
66
8
        }
67
10.2k
    }
68
27.8k
    else
69
27.8k
    {
70
27.8k
        CPLAssert(TIFFScanlineSize(m_poGDS->m_hTIFF) == nBlockXSize);
71
27.8k
    }
72
73
    /* -------------------------------------------------------------------- */
74
    /*      Read through to target scanline.                                */
75
    /* -------------------------------------------------------------------- */
76
38.1k
    if (m_poGDS->m_nLoadedBlock >= nBlockYOff)
77
51
        m_poGDS->m_nLoadedBlock = -1;
78
79
38.1k
    if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE &&
80
38.1k
        m_poGDS->nBands > 1)
81
27.7k
    {
82
        // If we change of band, we must start reading the
83
        // new strip from its beginning.
84
27.7k
        if (m_poGDS->m_nLastBandRead != nBand)
85
280
            m_poGDS->m_nLoadedBlock = -1;
86
27.7k
        m_poGDS->m_nLastBandRead = nBand;
87
27.7k
    }
88
89
75.9k
    while (m_poGDS->m_nLoadedBlock < nBlockYOff)
90
38.1k
    {
91
38.1k
        ++m_poGDS->m_nLoadedBlock;
92
38.1k
        if (TIFFReadScanline(m_poGDS->m_hTIFF,
93
38.1k
                             m_poGDS->m_pabyBlockBuf ? m_poGDS->m_pabyBlockBuf
94
38.1k
                                                     : pImage,
95
38.1k
                             m_poGDS->m_nLoadedBlock,
96
38.1k
                             (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE)
97
38.1k
                                 ? static_cast<uint16_t>(nBand - 1)
98
38.1k
                                 : 0) == -1 &&
99
38.1k
            !m_poGDS->m_bIgnoreReadErrors)
100
279
        {
101
279
            ReportError(CE_Failure, CPLE_AppDefined,
102
279
                        "TIFFReadScanline() failed.");
103
279
            m_poGDS->m_nLoadedBlock = -1;
104
279
            return CE_Failure;
105
279
        }
106
38.1k
    }
107
108
37.8k
extract_band_data:
109
    /* -------------------------------------------------------------------- */
110
    /*      Extract band data from contig buffer.                           */
111
    /* -------------------------------------------------------------------- */
112
37.8k
    if (m_poGDS->m_pabyBlockBuf != nullptr)
113
10.2k
    {
114
10.2k
        for (int iPixel = 0, iSrcOffset = nBand - 1, iDstOffset = 0;
115
40.8k
             iPixel < nBlockXSize;
116
30.6k
             ++iPixel, iSrcOffset += m_poGDS->nBands, ++iDstOffset)
117
30.6k
        {
118
30.6k
            static_cast<GByte *>(pImage)[iDstOffset] =
119
30.6k
                m_poGDS->m_pabyBlockBuf[iSrcOffset];
120
30.6k
        }
121
10.2k
    }
122
123
37.8k
    return CE_None;
124
38.1k
}
125
126
/************************************************************************/
127
/*                            IWriteBlock()                             */
128
/************************************************************************/
129
130
CPLErr GTiffSplitBand::IWriteBlock(int /* nBlockXOff */, int /* nBlockYOff */,
131
                                   void * /* pImage */)
132
133
0
{
134
0
    ReportError(CE_Failure, CPLE_AppDefined, "Split bands are read-only.");
135
0
    return CE_Failure;
136
0
}