Coverage Report

Created: 2025-11-16 06:25

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