1 /******************************************************************************
2  * $Id: aitest.c 3b0bbf7a8a012d69a783ee1f9cfeb5c52b370021 2017-06-27 20:57:02Z Even Rouault $
3  *
4  * Project:  Arc/Info Binary Grid Translator
5  * Purpose:  Test mainline for examining AIGrid files.
6  * Author:   Frank Warmerdam, warmerdam@pobox.com
7  *
8  ******************************************************************************
9  * Copyright (c) 1999, 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 "aigrid.h"
31 
32 CPL_CVSID("$Id: aitest.c 3b0bbf7a8a012d69a783ee1f9cfeb5c52b370021 2017-06-27 20:57:02Z Even Rouault $")
33 
34 /************************************************************************/
35 /*                             DumpMagic()                              */
36 /*                                                                      */
37 /*      Dump the magic ``block type byte'' for each existing block.     */
38 /************************************************************************/
39 
DumpMagic(AIGInfo_t * psInfo,int bVerbose)40 static void DumpMagic( AIGInfo_t * psInfo, int bVerbose )
41 
42 {
43     int		i;
44     AIGTileInfo *psTInfo = psInfo->pasTileInfo + 0;
45 
46     for( i = 0; i < psTInfo->nBlocks; i++ )
47     {
48         GByte	byMagic;
49         int	bReport = bVerbose;
50         unsigned char abyBlockSize[2];
51         const char *pszMessage = "";
52 
53         if( psTInfo->panBlockSize[i] == 0 )
54             continue;
55 
56         VSIFSeekL( psTInfo->fpGrid, psTInfo->panBlockOffset[i], SEEK_SET );
57         VSIFReadL( abyBlockSize, 2, 1, psTInfo->fpGrid );
58 
59         if( psInfo->nCellType == AIG_CELLTYPE_INT && psInfo->bCompressed )
60         {
61             VSIFReadL( &byMagic, 1, 1, psTInfo->fpGrid );
62 
63             if( byMagic != 0 && byMagic != 0x43 && byMagic != 0x04
64                 && byMagic != 0x08 && byMagic != 0x10 && byMagic != 0xd7
65                 && byMagic != 0xdf && byMagic != 0xe0 && byMagic != 0xfc
66                 && byMagic != 0xf8 && byMagic != 0xff && byMagic != 0x41
67                 && byMagic != 0x40 && byMagic != 0x42 && byMagic != 0xf0
68                 && byMagic != 0xcf && byMagic != 0x01 )
69             {
70                 pszMessage = "(unhandled magic number)";
71                 bReport = TRUE;
72             }
73 
74             if( byMagic == 0 && psTInfo->panBlockSize[i] > 8 )
75             {
76                 pszMessage = "(wrong size for 0x00 block, should be 8 bytes)";
77                 bReport = TRUE;
78             }
79 
80             if( (abyBlockSize[0] * 256 + abyBlockSize[1])*2 !=
81                 psTInfo->panBlockSize[i] )
82             {
83                 pszMessage = "(block size in data doesn't match index)";
84                 bReport = TRUE;
85             }
86         }
87         else
88         {
89             if( psTInfo->panBlockSize[i] !=
90                 psInfo->nBlockXSize*psInfo->nBlockYSize*sizeof(float) )
91             {
92                 pszMessage = "(floating point block size is wrong)";
93                 bReport = TRUE;
94             }
95         }
96 
97         if( bReport )
98         {
99             printf( " %02x %5d %5d @ %u %s\n", byMagic, i,
100                     psTInfo->panBlockSize[i],
101                     psTInfo->panBlockOffset[i],
102                     pszMessage );
103         }
104     }
105 }
106 
107 
108 /************************************************************************/
109 /*                                main()                                */
110 /************************************************************************/
111 
main(int argc,char ** argv)112 int main( int argc, char ** argv )
113 
114 {
115     AIGInfo_t	*psInfo;
116     GInt32 	*panRaster;
117     int		i, j;
118     int		bMagic = FALSE, bSuppressMagic = FALSE;
119     int         iTestTileX = 0, iTestTileY = 0;
120 
121 /* -------------------------------------------------------------------- */
122 /*      Process arguments.                                              */
123 /* -------------------------------------------------------------------- */
124     while( argc > 1 && argv[1][0] == '-' )
125     {
126         if( EQUAL(argv[1],"-magic") )
127             bMagic = TRUE;
128 
129         else if( EQUAL(argv[1],"-nomagic") )
130             bSuppressMagic = TRUE;
131 
132         else if( EQUAL(argv[1],"-t") && argc > 2 )
133         {
134             iTestTileX = atoi(argv[2]);
135             iTestTileY = atoi(argv[3]);
136             argc -= 2;
137             argv += 2;
138         }
139 
140         argc--;
141         argv++;
142     }
143 
144     if( argc < 2 ) {
145         printf( "Usage: aitest [-magic] coverage [block numbers...]\n" );
146         exit( 1 );
147     }
148 
149 /* -------------------------------------------------------------------- */
150 /*      Open dataset.                                                   */
151 /* -------------------------------------------------------------------- */
152     psInfo = AIGOpen( argv[1], "r" );
153     if( psInfo == NULL )
154         exit( 1 );
155 
156     AIGAccessTile( psInfo, iTestTileX, iTestTileY );
157 
158 /* -------------------------------------------------------------------- */
159 /*      Dump general information                                        */
160 /* -------------------------------------------------------------------- */
161     printf( "%d pixels x %d lines.\n", psInfo->nPixels, psInfo->nLines );
162     printf( "Lower Left = (%f,%f)   Upper Right = (%f,%f)\n",
163             psInfo->dfLLX,
164             psInfo->dfLLY,
165             psInfo->dfURX,
166             psInfo->dfURY );
167 
168     if( psInfo->nCellType == AIG_CELLTYPE_INT )
169         printf( "%s Integer coverage, %dx%d blocks.\n",
170                 psInfo->bCompressed ? "Compressed" : "Uncompressed",
171                 psInfo->nBlockXSize, psInfo->nBlockYSize );
172     else
173         printf( "%s Floating point coverage, %dx%d blocks.\n",
174                 psInfo->bCompressed ? "Compressed" : "Uncompressed",
175                 psInfo->nBlockXSize, psInfo->nBlockYSize );
176 
177     printf( "Stats - Min=%f, Max=%f, Mean=%f, StdDev=%f\n",
178             psInfo->dfMin,
179             psInfo->dfMax,
180             psInfo->dfMean,
181             psInfo->dfStdDev );
182 
183 /* -------------------------------------------------------------------- */
184 /*      Do we want a dump of all the ``magic'' numbers for              */
185 /*      instantiated blocks?                                            */
186 /* -------------------------------------------------------------------- */
187     if( !bSuppressMagic )
188         DumpMagic( psInfo, bMagic );
189 
190 /* -------------------------------------------------------------------- */
191 /*      Read a block, and report its contents.                          */
192 /* -------------------------------------------------------------------- */
193     panRaster = (GInt32 *)
194         CPLMalloc(psInfo->nBlockXSize * psInfo->nBlockYSize * 4);
195 
196     while( argc > 2 && (atoi(argv[2]) > 0 || argv[2][0] == '0') )
197     {
198         int	nBlock = atoi(argv[2]);
199         CPLErr  eErr;
200         AIGTileInfo *psTInfo = psInfo->pasTileInfo + 0;
201 
202         argv++;
203         argc--;
204 
205         eErr = AIGReadBlock( psTInfo->fpGrid,
206                              psTInfo->panBlockOffset[nBlock],
207                              psTInfo->panBlockSize[nBlock],
208                              psInfo->nBlockXSize, psInfo->nBlockYSize,
209                              panRaster, psInfo->nCellType, psInfo->bCompressed);
210 
211         printf( "\nBlock %d:\n", nBlock );
212 
213         if( eErr != CE_None )
214         {
215             printf( "  Error! Skipping block.\n" );
216             continue;
217         }
218 
219         for( j = 0; j < psInfo->nBlockYSize; j++ )
220         {
221             for( i = 0; i < psInfo->nBlockXSize; i++ )
222             {
223                 if( i > 18 )
224                 {
225                     printf( "..." );
226                     break;
227                 }
228 
229                 if( panRaster[i+j*psInfo->nBlockXSize] == ESRI_GRID_NO_DATA )
230                     printf( "-*- " );
231                 else if( psInfo->nCellType == AIG_CELLTYPE_FLOAT )
232                     printf( "%f ",
233                             ((float *) panRaster)[i+j*psInfo->nBlockXSize] );
234                 else
235                     printf( "%3d ", panRaster[i+j*psInfo->nBlockXSize] );
236             }
237             printf( "\n" );
238         }
239     }
240 
241     CPLFree( panRaster );
242 
243     AIGClose( psInfo );
244 
245     exit( 0 );
246 }
247