• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OSGeo / gdal / 13835348079

13 Mar 2025 01:06PM UTC coverage: 69.894% (-0.001%) from 69.895%
13835348079

Pull #11956

github

web-flow
Merge 553c1b974 into 7899cbe7a
Pull Request #11956: [Backport release/3.10] MiraMonVector: fixing a word in Catalan language

1 of 1 new or added line in 1 file covered. (100.0%)

55 existing lines in 23 files now uncovered.

548158 of 784270 relevant lines covered (69.89%)

583261.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.48
/alg/gdalchecksum.cpp
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  Compute simple checksum for a region of image data.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2003, Frank Warmerdam
9
 * Copyright (c) 2007-2008, Even Rouault <even dot rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13

14
#include "cpl_port.h"
15
#include "gdal_alg.h"
16

17
#include <cmath>
18
#include <cstddef>
19
#include <algorithm>
20

21
#include "cpl_conv.h"
22
#include "cpl_error.h"
23
#include "cpl_vsi.h"
24
#include "gdal.h"
25
#include "gdal_priv.h"
26

27
/************************************************************************/
28
/*                         GDALChecksumImage()                          */
29
/************************************************************************/
30

31
/**
32
 * Compute checksum for image region.
33
 *
34
 * Computes a 16bit (0-65535) checksum from a region of raster data on a GDAL
35
 * supported band.   Floating point data is converted to 32bit integer
36
 * so decimal portions of such raster data will not affect the checksum.
37
 * Real and Imaginary components of complex bands influence the result.
38
 *
39
 * @param hBand the raster band to read from.
40
 * @param nXOff pixel offset of window to read.
41
 * @param nYOff line offset of window to read.
42
 * @param nXSize pixel size of window to read.
43
 * @param nYSize line size of window to read.
44
 *
45
 * @return Checksum value, or -1 in case of error (starting with GDAL 3.6)
46
 */
47

48
int CPL_STDCALL GDALChecksumImage(GDALRasterBandH hBand, int nXOff, int nYOff,
111,396✔
49
                                  int nXSize, int nYSize)
50

51
{
52
    VALIDATE_POINTER1(hBand, "GDALChecksumImage", 0);
111,396✔
53

54
    const static int anPrimes[11] = {7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43};
55

56
    int nChecksum = 0;
111,396✔
57
    int iPrime = 0;
111,396✔
58
    const GDALDataType eDataType = GDALGetRasterDataType(hBand);
111,396✔
59
    const bool bComplex = CPL_TO_BOOL(GDALDataTypeIsComplex(eDataType));
111,396✔
60
    const bool bIsFloatingPoint =
111,396✔
61
        (eDataType == GDT_Float32 || eDataType == GDT_Float64 ||
109,608✔
62
         eDataType == GDT_CFloat32 || eDataType == GDT_CFloat64);
221,004✔
63

64
    const auto IntFromDouble = [](double dfVal)
225,895,500✔
65
    {
66
        int nVal;
67
        if (!std::isfinite(dfVal))
225,895,500✔
68
        {
69
            nVal = INT_MIN;
54,087✔
70
        }
71
        else
72
        {
73
            // Standard behavior of GDALCopyWords when converting
74
            // from floating point to Int32.
75
            dfVal += 0.5;
225,841,500✔
76

77
            if (dfVal < -2147483647.0)
225,841,500✔
78
                nVal = -2147483647;
3,645✔
79
            else if (dfVal > 2147483647)
225,837,900✔
80
                nVal = 2147483647;
8,070✔
81
            else
82
                nVal = static_cast<GInt32>(floor(dfVal));
225,829,800✔
83
        }
84
        return nVal;
225,895,500✔
85
    };
86

87
    if (bIsFloatingPoint && nXOff == 0 && nYOff == 0)
111,396✔
88
    {
89
        const GDALDataType eDstDataType = bComplex ? GDT_CFloat64 : GDT_Float64;
3,237✔
90
        int nBlockXSize = 0;
3,237✔
91
        int nBlockYSize = 0;
3,237✔
92
        GDALGetBlockSize(hBand, &nBlockXSize, &nBlockYSize);
3,237✔
93
        const int nDstDataTypeSize = GDALGetDataTypeSizeBytes(eDstDataType);
3,237✔
94
        int nChunkXSize = nBlockXSize;
3,237✔
95
        const int nChunkYSize = nBlockYSize;
3,237✔
96
        if (nBlockXSize < nXSize)
3,237✔
97
        {
98
            const GIntBig nMaxChunkSize =
99
                std::max(static_cast<GIntBig>(10 * 1000 * 1000),
288✔
100
                         GDALGetCacheMax64() / 10);
144✔
101
            if (nDstDataTypeSize > 0 &&
144✔
102
                static_cast<GIntBig>(nXSize) * nChunkYSize <
144✔
103
                    nMaxChunkSize / nDstDataTypeSize)
144✔
104
            {
105
                // A full line of height nChunkYSize can fit in the maximum
106
                // allowed memory
107
                nChunkXSize = nXSize;
144✔
108
            }
109
            else
110
            {
111
                // Otherwise compute a size that is a multiple of nBlockXSize
112
                nChunkXSize = static_cast<int>(std::min(
×
113
                    static_cast<GIntBig>(nXSize),
×
114
                    nBlockXSize *
×
115
                        std::max(static_cast<GIntBig>(1),
×
116
                                 nMaxChunkSize /
×
117
                                     (static_cast<GIntBig>(nBlockXSize) *
×
118
                                      nChunkYSize * nDstDataTypeSize))));
×
119
            }
120
        }
121

122
        double *padfLineData = static_cast<double *>(
123
            VSI_MALLOC3_VERBOSE(nChunkXSize, nChunkYSize, nDstDataTypeSize));
3,237✔
124
        if (padfLineData == nullptr)
3,237✔
125
        {
126
            return -1;
×
127
        }
128
        const int nValsPerIter = bComplex ? 2 : 1;
3,237✔
129

130
        const int nYBlocks = DIV_ROUND_UP(nYSize, nChunkYSize);
3,237✔
131
        const int nXBlocks = DIV_ROUND_UP(nXSize, nChunkXSize);
3,237✔
132
        for (int iYBlock = 0; iYBlock < nYBlocks; ++iYBlock)
80,880✔
133
        {
134
            const int iYStart = iYBlock * nChunkYSize;
77,643✔
135
            const int iYEnd =
77,643✔
136
                iYBlock == nYBlocks - 1 ? nYSize : iYStart + nChunkYSize;
77,643✔
137
            const int nChunkActualHeight = iYEnd - iYStart;
77,643✔
138
            for (int iXBlock = 0; iXBlock < nXBlocks; ++iXBlock)
155,283✔
139
            {
140
                const int iXStart = iXBlock * nChunkXSize;
77,643✔
141
                const int iXEnd =
77,643✔
142
                    iXBlock == nXBlocks - 1 ? nXSize : iXStart + nChunkXSize;
77,643✔
143
                const int nChunkActualXSize = iXEnd - iXStart;
77,643✔
144
                if (GDALRasterIO(
77,643✔
145
                        hBand, GF_Read, iXStart, iYStart, nChunkActualXSize,
146
                        nChunkActualHeight, padfLineData, nChunkActualXSize,
147
                        nChunkActualHeight, eDstDataType, 0, 0) != CE_None)
77,643✔
148
                {
149
                    CPLError(CE_Failure, CPLE_FileIO,
3✔
150
                             "Checksum value could not be computed due to I/O "
151
                             "read error.");
152
                    nChecksum = -1;
3✔
153
                    iYBlock = nYBlocks;
3✔
154
                    break;
3✔
155
                }
156
                const size_t xIters =
77,640✔
157
                    static_cast<size_t>(nValsPerIter) * nChunkActualXSize;
77,640✔
158
                for (int iY = iYStart; iY < iYEnd; ++iY)
234,615✔
159
                {
160
                    // Initialize iPrime so that it is consistent with a
161
                    // per full line iteration strategy
162
                    iPrime = (nValsPerIter *
156,975✔
163
                              (static_cast<int64_t>(iY) * nXSize + iXStart)) %
156,975✔
164
                             11;
165
                    const size_t nOffset = nValsPerIter *
156,975✔
166
                                           static_cast<size_t>(iY - iYStart) *
156,975✔
167
                                           nChunkActualXSize;
156,975✔
168
                    for (size_t i = 0; i < xIters; ++i)
226,051,200✔
169
                    {
170
                        const double dfVal = padfLineData[nOffset + i];
225,894,300✔
171
                        nChecksum += IntFromDouble(dfVal) % anPrimes[iPrime++];
225,894,300✔
172
                        if (iPrime > 10)
225,894,300✔
173
                            iPrime = 0;
20,534,460✔
174
                    }
175
                    nChecksum &= 0xffff;
156,975✔
176
                }
177
            }
178
        }
179

180
        CPLFree(padfLineData);
3,237✔
181
    }
182
    else if (bIsFloatingPoint)
108,159✔
183
    {
184
        const GDALDataType eDstDataType = bComplex ? GDT_CFloat64 : GDT_Float64;
9✔
185

186
        double *padfLineData = static_cast<double *>(VSI_MALLOC2_VERBOSE(
9✔
187
            nXSize, GDALGetDataTypeSizeBytes(eDstDataType)));
188
        if (padfLineData == nullptr)
9✔
189
        {
190
            return -1;
×
191
        }
192

193
        for (int iLine = nYOff; iLine < nYOff + nYSize; iLine++)
99✔
194
        {
195
            if (GDALRasterIO(hBand, GF_Read, nXOff, iLine, nXSize, 1,
90✔
196
                             padfLineData, nXSize, 1, eDstDataType, 0,
197
                             0) != CE_None)
90✔
198
            {
199
                CPLError(CE_Failure, CPLE_FileIO,
×
200
                         "Checksum value couldn't be computed due to "
201
                         "I/O read error.");
202
                nChecksum = -1;
×
203
                break;
×
204
            }
205
            const size_t nCount = bComplex ? static_cast<size_t>(nXSize) * 2
90✔
206
                                           : static_cast<size_t>(nXSize);
207

208
            for (size_t i = 0; i < nCount; i++)
1,440✔
209
            {
210
                const double dfVal = padfLineData[i];
1,350✔
211
                nChecksum += IntFromDouble(dfVal) % anPrimes[iPrime++];
1,350✔
212
                if (iPrime > 10)
1,350✔
213
                    iPrime = 0;
120✔
214

215
                nChecksum &= 0xffff;
1,350✔
216
            }
217
        }
218

219
        CPLFree(padfLineData);
9✔
220
    }
221
    else if (nXOff == 0 && nYOff == 0)
108,150✔
222
    {
223
        const GDALDataType eDstDataType = bComplex ? GDT_CInt32 : GDT_Int32;
107,961✔
224
        int nBlockXSize = 0;
107,961✔
225
        int nBlockYSize = 0;
107,961✔
226
        GDALGetBlockSize(hBand, &nBlockXSize, &nBlockYSize);
107,961✔
227
        const int nDstDataTypeSize = GDALGetDataTypeSizeBytes(eDstDataType);
107,961✔
228
        int nChunkXSize = nBlockXSize;
107,961✔
229
        const int nChunkYSize = nBlockYSize;
107,961✔
230
        if (nBlockXSize < nXSize)
107,961✔
231
        {
232
            const GIntBig nMaxChunkSize =
233
                std::max(static_cast<GIntBig>(10 * 1000 * 1000),
3,564✔
234
                         GDALGetCacheMax64() / 10);
1,782✔
235
            if (nDstDataTypeSize > 0 &&
1,782✔
236
                static_cast<GIntBig>(nXSize) * nChunkYSize <
1,782✔
237
                    nMaxChunkSize / nDstDataTypeSize)
1,782✔
238
            {
239
                // A full line of height nChunkYSize can fit in the maximum
240
                // allowed memory
241
                nChunkXSize = nXSize;
1,782✔
242
            }
243
            else
244
            {
245
                // Otherwise compute a size that is a multiple of nBlockXSize
246
                nChunkXSize = static_cast<int>(std::min(
×
247
                    static_cast<GIntBig>(nXSize),
×
248
                    nBlockXSize *
×
249
                        std::max(static_cast<GIntBig>(1),
×
250
                                 nMaxChunkSize /
×
251
                                     (static_cast<GIntBig>(nBlockXSize) *
×
252
                                      nChunkYSize * nDstDataTypeSize))));
×
253
            }
254
        }
255

256
        int *panChunkData = static_cast<GInt32 *>(
257
            VSI_MALLOC3_VERBOSE(nChunkXSize, nChunkYSize, nDstDataTypeSize));
107,961✔
258
        if (panChunkData == nullptr)
107,961✔
259
        {
260
            return -1;
×
261
        }
262
        const int nValsPerIter = bComplex ? 2 : 1;
107,961✔
263

264
        const int nYBlocks = DIV_ROUND_UP(nYSize, nChunkYSize);
107,961✔
265
        const int nXBlocks = DIV_ROUND_UP(nXSize, nChunkXSize);
107,961✔
266
        for (int iYBlock = 0; iYBlock < nYBlocks; ++iYBlock)
9,353,400✔
267
        {
268
            const int iYStart = iYBlock * nChunkYSize;
9,245,580✔
269
            const int iYEnd =
9,245,580✔
270
                iYBlock == nYBlocks - 1 ? nYSize : iYStart + nChunkYSize;
9,245,580✔
271
            const int nChunkActualHeight = iYEnd - iYStart;
9,245,580✔
272
            for (int iXBlock = 0; iXBlock < nXBlocks; ++iXBlock)
18,498,060✔
273
            {
274
                const int iXStart = iXBlock * nChunkXSize;
9,149,520✔
275
                const int iXEnd =
9,149,520✔
276
                    iXBlock == nXBlocks - 1 ? nXSize : iXStart + nChunkXSize;
9,149,520✔
277
                const int nChunkActualXSize = iXEnd - iXStart;
9,149,520✔
278
                if (GDALRasterIO(
9,149,520✔
279
                        hBand, GF_Read, iXStart, iYStart, nChunkActualXSize,
280
                        nChunkActualHeight, panChunkData, nChunkActualXSize,
281
                        nChunkActualHeight, eDstDataType, 0, 0) != CE_None)
9,252,720✔
282
                {
283
                    CPLError(CE_Failure, CPLE_FileIO,
264✔
284
                             "Checksum value could not be computed due to I/O "
285
                             "read error.");
UNCOV
286
                    nChecksum = -1;
×
UNCOV
287
                    iYBlock = nYBlocks;
×
UNCOV
288
                    break;
×
289
                }
290
                const size_t xIters =
9,252,480✔
291
                    static_cast<size_t>(nValsPerIter) * nChunkActualXSize;
9,252,480✔
292
                for (int iY = iYStart; iY < iYEnd; ++iY)
23,549,610✔
293
                {
294
                    // Initialize iPrime so that it is consistent with a
295
                    // per full line iteration strategy
296
                    iPrime = (nValsPerIter *
14,297,160✔
297
                              (static_cast<int64_t>(iY) * nXSize + iXStart)) %
14,297,160✔
298
                             11;
299
                    const size_t nOffset = nValsPerIter *
14,297,160✔
300
                                           static_cast<size_t>(iY - iYStart) *
14,297,160✔
301
                                           nChunkActualXSize;
14,297,160✔
302
                    for (size_t i = 0; i < xIters; ++i)
3,290,820,000✔
303
                    {
304
                        nChecksum +=
3,276,540,000✔
305
                            panChunkData[nOffset + i] % anPrimes[iPrime++];
3,276,540,000✔
306
                        if (iPrime > 10)
3,276,540,000✔
307
                            iPrime = 0;
322,830,000✔
308
                    }
309
                    nChecksum &= 0xffff;
14,297,160✔
310
                }
311
            }
312
        }
313

314
        CPLFree(panChunkData);
107,811✔
315
    }
316
    else
317
    {
318
        const GDALDataType eDstDataType = bComplex ? GDT_CInt32 : GDT_Int32;
189✔
319

320
        int *panLineData = static_cast<GInt32 *>(VSI_MALLOC2_VERBOSE(
189✔
321
            nXSize, GDALGetDataTypeSizeBytes(eDstDataType)));
322
        if (panLineData == nullptr)
189✔
323
        {
324
            return -1;
×
325
        }
326

327
        for (int iLine = nYOff; iLine < nYOff + nYSize; iLine++)
459✔
328
        {
329
            if (GDALRasterIO(hBand, GF_Read, nXOff, iLine, nXSize, 1,
270✔
330
                             panLineData, nXSize, 1, eDstDataType, 0,
331
                             0) != CE_None)
270✔
332
            {
333
                CPLError(CE_Failure, CPLE_FileIO,
×
334
                         "Checksum value could not be computed due to I/O "
335
                         "read error.");
336
                nChecksum = -1;
×
337
                break;
×
338
            }
339
            const size_t nCount = bComplex ? static_cast<size_t>(nXSize) * 2
270✔
340
                                           : static_cast<size_t>(nXSize);
341

342
            for (size_t i = 0; i < nCount; i++)
1,800✔
343
            {
344
                nChecksum += panLineData[i] % anPrimes[iPrime++];
1,530✔
345
                if (iPrime > 10)
1,530✔
346
                    iPrime = 0;
120✔
347

348
                nChecksum &= 0xffff;
1,530✔
349
            }
350
        }
351

352
        CPLFree(panLineData);
189✔
353
    }
354

355
    // coverity[return_overflow]
356
    return nChecksum;
111,252✔
357
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc