Coverage Report

Created: 2025-06-13 06:18

/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
0
    : GTiffRasterBand(poDSIn, nBandIn)
24
0
{
25
0
    nBlockXSize = poDS->GetRasterXSize();
26
0
    nBlockYSize = 1;
27
0
}
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
0
{
47
0
    m_poGDS->Crystalize();
48
49
    // Optimization when reading the same line in a contig multi-band TIFF.
50
0
    if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_CONTIG &&
51
0
        m_poGDS->nBands > 1 && m_poGDS->m_nLoadedBlock == nBlockYOff)
52
0
    {
53
0
        goto extract_band_data;
54
0
    }
55
56
0
    if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_CONTIG && m_poGDS->nBands > 1)
57
0
    {
58
0
        if (m_poGDS->m_pabyBlockBuf == nullptr)
59
0
        {
60
0
            m_poGDS->m_pabyBlockBuf = static_cast<GByte *>(
61
0
                VSI_MALLOC_VERBOSE(TIFFScanlineSize(m_poGDS->m_hTIFF)));
62
0
            if (m_poGDS->m_pabyBlockBuf == nullptr)
63
0
            {
64
0
                return CE_Failure;
65
0
            }
66
0
        }
67
0
    }
68
0
    else
69
0
    {
70
0
        CPLAssert(TIFFScanlineSize(m_poGDS->m_hTIFF) == nBlockXSize);
71
0
    }
72
73
    /* -------------------------------------------------------------------- */
74
    /*      Read through to target scanline.                                */
75
    /* -------------------------------------------------------------------- */
76
0
    if (m_poGDS->m_nLoadedBlock >= nBlockYOff)
77
0
        m_poGDS->m_nLoadedBlock = -1;
78
79
0
    if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE &&
80
0
        m_poGDS->nBands > 1)
81
0
    {
82
        // If we change of band, we must start reading the
83
        // new strip from its beginning.
84
0
        if (m_poGDS->m_nLastBandRead != nBand)
85
0
            m_poGDS->m_nLoadedBlock = -1;
86
0
        m_poGDS->m_nLastBandRead = nBand;
87
0
    }
88
89
0
    while (m_poGDS->m_nLoadedBlock < nBlockYOff)
90
0
    {
91
0
        ++m_poGDS->m_nLoadedBlock;
92
0
        if (TIFFReadScanline(m_poGDS->m_hTIFF,
93
0
                             m_poGDS->m_pabyBlockBuf ? m_poGDS->m_pabyBlockBuf
94
0
                                                     : pImage,
95
0
                             m_poGDS->m_nLoadedBlock,
96
0
                             (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE)
97
0
                                 ? static_cast<uint16_t>(nBand - 1)
98
0
                                 : 0) == -1 &&
99
0
            !m_poGDS->m_bIgnoreReadErrors)
100
0
        {
101
0
            ReportError(CE_Failure, CPLE_AppDefined,
102
0
                        "TIFFReadScanline() failed.");
103
0
            m_poGDS->m_nLoadedBlock = -1;
104
0
            return CE_Failure;
105
0
        }
106
0
    }
107
108
0
extract_band_data:
109
    /* -------------------------------------------------------------------- */
110
    /*      Extract band data from contig buffer.                           */
111
    /* -------------------------------------------------------------------- */
112
0
    if (m_poGDS->m_pabyBlockBuf != nullptr)
113
0
    {
114
0
        for (int iPixel = 0, iSrcOffset = nBand - 1, iDstOffset = 0;
115
0
             iPixel < nBlockXSize;
116
0
             ++iPixel, iSrcOffset += m_poGDS->nBands, ++iDstOffset)
117
0
        {
118
0
            static_cast<GByte *>(pImage)[iDstOffset] =
119
0
                m_poGDS->m_pabyBlockBuf[iSrcOffset];
120
0
        }
121
0
    }
122
123
0
    return CE_None;
124
0
}
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
}