Coverage Report

Created: 2025-12-31 08:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/pcidsk/sdk/channel/cpixelinterleavedchannel.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Purpose:  Implementation of the CPixelInterleavedChannel class.
4
 *
5
 ******************************************************************************
6
 * Copyright (c) 2009
7
 * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 ****************************************************************************/
11
12
#include "pcidsk_exception.h"
13
#include "core/pcidsk_utils.h"
14
#include "core/cpcidskfile.h"
15
#include "channel/cpixelinterleavedchannel.h"
16
#include <cassert>
17
#include <cstring>
18
19
using namespace PCIDSK;
20
21
/************************************************************************/
22
/*                      CPixelInterleavedChannel()                      */
23
/************************************************************************/
24
25
CPixelInterleavedChannel::CPixelInterleavedChannel( PCIDSKBuffer &image_headerIn,
26
                                                    uint64 ih_offsetIn,
27
                                                    CPL_UNUSED PCIDSKBuffer &file_headerIn,
28
                                                    int channelnumIn,
29
                                                    CPCIDSKFile *fileIn,
30
                                                    int image_offsetIn,
31
                                                    eChanType pixel_typeIn )
32
0
        : CPCIDSKChannel( image_headerIn, ih_offsetIn, fileIn, pixel_typeIn, channelnumIn)
33
34
0
{
35
0
    this->image_offset = image_offsetIn;
36
0
}
37
38
/************************************************************************/
39
/*                     ~CPixelInterleavedChannel()                      */
40
/************************************************************************/
41
42
CPixelInterleavedChannel::~CPixelInterleavedChannel()
43
44
0
{
45
0
}
46
47
/************************************************************************/
48
/*                             ReadBlock()                              */
49
/************************************************************************/
50
51
int CPixelInterleavedChannel::ReadBlock( int block_index, void *buffer,
52
                                         int win_xoff, int win_yoff,
53
                                         int win_xsize, int win_ysize )
54
55
0
{
56
/* -------------------------------------------------------------------- */
57
/*      Default window if needed.                                       */
58
/* -------------------------------------------------------------------- */
59
0
    if( win_xoff == -1 && win_yoff == -1 && win_xsize == -1 && win_ysize == -1 )
60
0
    {
61
0
        win_xoff = 0;
62
0
        win_yoff = 0;
63
0
        win_xsize = GetBlockWidth();
64
0
        win_ysize = GetBlockHeight();
65
0
    }
66
67
/* -------------------------------------------------------------------- */
68
/*      Validate Window                                                 */
69
/* -------------------------------------------------------------------- */
70
0
    if( win_xoff < 0 || win_xoff + win_xsize > GetBlockWidth()
71
0
        || win_yoff < 0 || win_yoff + win_ysize > GetBlockHeight() )
72
0
    {
73
0
        return ThrowPCIDSKException(0,
74
0
            "Invalid window in ReadBloc(): win_xoff=%d,win_yoff=%d,xsize=%d,ysize=%d",
75
0
            win_xoff, win_yoff, win_xsize, win_ysize );
76
0
    }
77
78
/* -------------------------------------------------------------------- */
79
/*      Work out sizes and offsets.                                     */
80
/* -------------------------------------------------------------------- */
81
0
    int pixel_group = file->GetPixelGroupSize();
82
0
    int pixel_size = DataTypeSize(GetType());
83
84
/* -------------------------------------------------------------------- */
85
/*      Read and lock the scanline.                                     */
86
/* -------------------------------------------------------------------- */
87
0
    uint8 *pixel_buffer = (uint8 *)
88
0
        file->ReadAndLockBlock( block_index, win_xoff, win_xsize);
89
90
/* -------------------------------------------------------------------- */
91
/*      Copy the data into our callers buffer.  Try to do this          */
92
/*      reasonably efficiently.  We might consider adding faster        */
93
/*      cases for 16/32bit data that is word aligned.                   */
94
/* -------------------------------------------------------------------- */
95
0
    if( pixel_size == pixel_group )
96
0
        memcpy( buffer, pixel_buffer, static_cast<size_t>(pixel_size) * win_xsize );
97
0
    else
98
0
    {
99
0
        int i;
100
0
        const uint8  *src = pixel_buffer + image_offset;
101
0
        uint8  *dst = static_cast<uint8 *>(buffer);
102
103
0
        if( pixel_size == 1 )
104
0
        {
105
0
            for( i = win_xsize; i != 0; i-- )
106
0
            {
107
0
                *dst = *src;
108
0
                dst++;
109
0
                src += pixel_group;
110
0
            }
111
0
        }
112
0
        else if( pixel_size == 2 )
113
0
        {
114
0
            for( i = win_xsize; i != 0; i-- )
115
0
            {
116
0
                *(dst++) = *(src++);
117
0
                *(dst++) = *(src++);
118
0
                src += pixel_group-2;
119
0
            }
120
0
        }
121
0
        else if( pixel_size == 4 )
122
0
        {
123
0
            for( i = win_xsize; i != 0; i-- )
124
0
            {
125
0
                *(dst++) = *(src++);
126
0
                *(dst++) = *(src++);
127
0
                *(dst++) = *(src++);
128
0
                *(dst++) = *(src++);
129
0
                src += pixel_group-4;
130
0
            }
131
0
        }
132
0
        else if( pixel_size == 8 )
133
0
        {
134
0
            for( i = win_xsize; i != 0; i-- )
135
0
            {
136
0
                *(dst++) = *(src++);
137
0
                *(dst++) = *(src++);
138
0
                *(dst++) = *(src++);
139
0
                *(dst++) = *(src++);
140
0
                *(dst++) = *(src++);
141
0
                *(dst++) = *(src++);
142
0
                *(dst++) = *(src++);
143
0
                *(dst++) = *(src++);
144
0
                src += pixel_group-8;
145
0
            }
146
0
        }
147
0
        else
148
0
            return ThrowPCIDSKException(0, "Unsupported pixel type..." );
149
0
    }
150
151
0
    file->UnlockBlock( false );
152
153
/* -------------------------------------------------------------------- */
154
/*      Do byte swapping if needed.                                     */
155
/* -------------------------------------------------------------------- */
156
0
    if( needs_swap )
157
0
        SwapPixels( buffer, pixel_type, win_xsize );
158
159
0
    return 1;
160
0
}
161
162
/************************************************************************/
163
/*                             CopyPixels()                             */
164
/************************************************************************/
165
166
template <typename T>
167
void CopyPixels(const T* const src, T* const dst,
168
                std::size_t offset, std::size_t count)
169
{
170
    for (std::size_t i = 0; i < count; i++)
171
    {
172
        dst[i] = src[(i + 1) * offset];
173
    }
174
}
175
176
/************************************************************************/
177
/*                             WriteBlock()                             */
178
/************************************************************************/
179
180
int CPixelInterleavedChannel::WriteBlock( int block_index, void *buffer )
181
182
0
{
183
0
    if( !file->GetUpdatable() )
184
0
        return ThrowPCIDSKException(0, "File not open for update in WriteBlock()" );
185
186
0
    InvalidateOverviews();
187
188
/* -------------------------------------------------------------------- */
189
/*      Work out sizes and offsets.                                     */
190
/* -------------------------------------------------------------------- */
191
0
    int pixel_group = file->GetPixelGroupSize();
192
0
    int pixel_size = DataTypeSize(GetType());
193
194
/* -------------------------------------------------------------------- */
195
/*      Read and lock the scanline.                                     */
196
/* -------------------------------------------------------------------- */
197
0
    uint8 *pixel_buffer = (uint8 *) file->ReadAndLockBlock( block_index );
198
199
/* -------------------------------------------------------------------- */
200
/*      Copy the data into our callers buffer.  Try to do this          */
201
/*      reasonably efficiently.  We might consider adding faster        */
202
/*      cases for 16/32bit data that is word aligned.                   */
203
/* -------------------------------------------------------------------- */
204
0
    if( pixel_size == pixel_group )
205
0
    {
206
0
        memcpy( pixel_buffer, buffer, static_cast<size_t>(pixel_size) * width );
207
208
0
        if( needs_swap )
209
0
        {
210
0
            bool complex = IsDataTypeComplex( GetType() );
211
212
0
            if( complex )
213
0
                SwapData( pixel_buffer, pixel_size/2, width*2 );
214
0
            else
215
0
                SwapData( pixel_buffer, pixel_size, width );
216
0
        }
217
0
    }
218
0
    else
219
0
    {
220
0
        int i;
221
0
        uint8  *dst = pixel_buffer + image_offset;
222
0
        const uint8  *src = static_cast<uint8 *>(buffer);
223
224
0
        if( pixel_size == 1 )
225
0
        {
226
0
            for( i = width; i != 0; i-- )
227
0
            {
228
0
                *dst = *src;
229
0
                src++;
230
0
                dst += pixel_group;
231
0
            }
232
0
        }
233
0
        else if( pixel_size == 2 )
234
0
        {
235
0
            for( i = width; i != 0; i-- )
236
0
            {
237
0
                *(dst++) = *(src++);
238
0
                *(dst++) = *(src++);
239
240
0
                if( needs_swap )
241
0
                    SwapData( dst-2, 2, 1 );
242
243
0
                dst += pixel_group-2;
244
0
            }
245
0
        }
246
0
        else if( pixel_size == 4 )
247
0
        {
248
0
            bool complex = IsDataTypeComplex( GetType() );
249
250
0
            for( i = width; i != 0; i-- )
251
0
            {
252
0
                *(dst++) = *(src++);
253
0
                *(dst++) = *(src++);
254
0
                *(dst++) = *(src++);
255
0
                *(dst++) = *(src++);
256
257
0
                if( needs_swap )
258
0
                {
259
0
                    if( complex )
260
0
                        SwapData( dst-4, 2, 2);
261
0
                    else
262
0
                        SwapData( dst-4, 4, 1);
263
0
                }
264
265
0
                dst += pixel_group-4;
266
0
            }
267
0
        }
268
0
        else if( pixel_size == 8 )
269
0
        {
270
0
            bool complex = IsDataTypeComplex( GetType() );
271
272
0
            for( i = width; i != 0; i-- )
273
0
            {
274
0
                *(dst++) = *(src++);
275
0
                *(dst++) = *(src++);
276
0
                *(dst++) = *(src++);
277
0
                *(dst++) = *(src++);
278
0
                *(dst++) = *(src++);
279
0
                *(dst++) = *(src++);
280
0
                *(dst++) = *(src++);
281
0
                *(dst++) = *(src++);
282
283
0
                if( needs_swap )
284
0
                {
285
0
                    if( complex )
286
0
                        SwapData( dst-8, 4, 2);
287
0
                    else
288
0
                        SwapData( dst-8, 8, 1);
289
0
                }
290
291
0
                dst += pixel_group-8;
292
0
            }
293
0
        }
294
0
        else
295
0
            return ThrowPCIDSKException(0, "Unsupported pixel type..." );
296
0
    }
297
298
0
    file->UnlockBlock( true );
299
300
0
    return 1;
301
0
}