1 : /******************************************************************************
2 : * $Id: gdalchecksum.cpp 13893 2008-02-28 21:08:37Z rouault $
3 : *
4 : * Project: GDAL
5 : * Purpose: Compute simple checksum for a region of image data.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2003, Frank Warmerdam
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "gdal_alg.h"
31 : #include "cpl_conv.h"
32 :
33 : CPL_CVSID("$Id: gdalchecksum.cpp 13893 2008-02-28 21:08:37Z rouault $");
34 :
35 : /************************************************************************/
36 : /* GDALChecksumImage() */
37 : /************************************************************************/
38 :
39 : /**
40 : * Compute checksum for image region.
41 : *
42 : * Computes a 16bit (0-65535) checksum from a region of raster data on a GDAL
43 : * supported band. Floating point data is converted to 32bit integer
44 : * so decimal portions of such raster data will not affect the checksum.
45 : * Real and Imaginary components of complex bands influence the result.
46 : *
47 : * @param hBand the raster band to read from.
48 : * @param nXOff pixel offset of window to read.
49 : * @param nYOff line offset of window to read.
50 : * @param nXSize pixel size of window to read.
51 : * @param nYSize line size of window to read.
52 : *
53 : * @return Checksum value.
54 : */
55 :
56 : int CPL_STDCALL
57 1999 : GDALChecksumImage( GDALRasterBandH hBand,
58 : int nXOff, int nYOff, int nXSize, int nYSize )
59 :
60 : {
61 1999 : VALIDATE_POINTER1( hBand, "GDALChecksumImage", 0 );
62 :
63 : const static int anPrimes[11] =
64 : { 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43 };
65 :
66 1999 : int iLine, i, nChecksum = 0, iPrime = 0, nCount;
67 1999 : GDALDataType eDataType = GDALGetRasterDataType( hBand );
68 1999 : int bComplex = GDALDataTypeIsComplex( eDataType );
69 :
70 2429 : if (eDataType == GDT_Float32 || eDataType == GDT_Float64 ||
71 : eDataType == GDT_CFloat32 || eDataType == GDT_CFloat64)
72 : {
73 : double* padfLineData;
74 430 : GDALDataType eDstDataType = (bComplex) ? GDT_CFloat64 : GDT_Float64;
75 :
76 430 : padfLineData = (double *) VSIMalloc2(nXSize, sizeof(double) * 2);
77 430 : if (padfLineData == NULL)
78 : {
79 : CPLError( CE_Failure, CPLE_OutOfMemory,
80 : "VSIMalloc2(): Out of memory in GDALChecksumImage. "
81 0 : "Checksum value couldn't be computed\n");
82 0 : return 0;
83 : }
84 :
85 9379 : for( iLine = nYOff; iLine < nYOff + nYSize; iLine++ )
86 : {
87 8949 : if (GDALRasterIO( hBand, GF_Read, nXOff, iLine, nXSize, 1,
88 : padfLineData, nXSize, 1, eDstDataType, 0, 0 ) != CE_None)
89 : {
90 : CPLError( CE_Failure, CPLE_FileIO,
91 0 : "Checksum value couldn't be computed due to I/O read error.\n");
92 0 : break;
93 : }
94 8949 : nCount = (bComplex) ? nXSize * 2 : nXSize;
95 :
96 925007 : for( i = 0; i < nCount; i++ )
97 : {
98 916058 : double dfVal = padfLineData[i];
99 : int nVal;
100 916118 : if (CPLIsNan(dfVal) || CPLIsInf(dfVal))
101 : {
102 : /* Most compilers seem to cast NaN or Inf to 0x80000000. */
103 : /* but VC7 is an exception. So we force the result */
104 : /* of such a cast */
105 60 : nVal = 0x80000000;
106 : }
107 : else
108 : {
109 : /* Standard behaviour of GDALCopyWords when converting */
110 : /* from floating point to Int32 */
111 915998 : dfVal += 0.5;
112 :
113 915998 : if( dfVal < -2147483647.0 )
114 23439 : nVal = -2147483647;
115 892559 : else if( dfVal > 2147483647 )
116 2690 : nVal = 2147483647;
117 : else
118 889869 : nVal = (GInt32) floor(dfVal);
119 : }
120 :
121 916058 : nChecksum += (nVal % anPrimes[iPrime++]);
122 916058 : if( iPrime > 10 )
123 83093 : iPrime = 0;
124 :
125 916058 : nChecksum &= 0xffff;
126 : }
127 : }
128 :
129 430 : CPLFree(padfLineData);
130 : }
131 : else
132 : {
133 : int *panLineData;
134 1569 : GDALDataType eDstDataType = (bComplex) ? GDT_CInt32 : GDT_Int32;
135 :
136 1569 : panLineData = (GInt32 *) VSIMalloc2(nXSize, sizeof(GInt32) * 2);
137 1569 : if (panLineData == NULL)
138 : {
139 : CPLError( CE_Failure, CPLE_OutOfMemory,
140 : "VSIMalloc2(): Out of memory in GDALChecksumImage. "
141 0 : "Checksum value couldn't be computed\n");
142 0 : return 0;
143 : }
144 :
145 323743 : for( iLine = nYOff; iLine < nYOff + nYSize; iLine++ )
146 : {
147 322180 : if (GDALRasterIO( hBand, GF_Read, nXOff, iLine, nXSize, 1,
148 : panLineData, nXSize, 1, eDstDataType, 0, 0 ) != CE_None)
149 : {
150 : CPLError( CE_Failure, CPLE_FileIO,
151 6 : "Checksum value couldn't be computed due to I/O read error.\n");
152 6 : break;
153 : }
154 322174 : nCount = (bComplex) ? nXSize * 2 : nXSize;
155 :
156 159477981 : for( i = 0; i < nCount; i++ )
157 : {
158 159155807 : nChecksum += (panLineData[i] % anPrimes[iPrime++]);
159 159155807 : if( iPrime > 10 )
160 14468140 : iPrime = 0;
161 :
162 159155807 : nChecksum &= 0xffff;
163 : }
164 : }
165 :
166 1569 : CPLFree( panLineData );
167 : }
168 :
169 1999 : return nChecksum;
170 : }
171 :
|