1 : /******************************************************************************
2 : * $Id: hfa_p.h 17710 2009-09-29 14:02:33Z warmerdam $
3 : *
4 : * Project: Erdas Imagine (.img) Translator
5 : * Purpose: Private class declarations for the HFA classes used to read
6 : * Erdas Imagine (.img) files. Public (C callable) declarations
7 : * are in hfa.h.
8 : * Author: Frank Warmerdam, warmerdam@pobox.com
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 1999, Intergraph Corporation
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #ifndef _HFA_P_H_INCLUDED
33 : #define _HFA_P_H_INCLUDED
34 :
35 : #include "cpl_port.h"
36 : #include "cpl_error.h"
37 : #include "cpl_vsi.h"
38 :
39 : #ifdef CPL_LSB
40 : # define HFAStandard(n,p) {}
41 : #else
42 : void HFAStandard( int, void *);
43 : #endif
44 :
45 : class HFAEntry;
46 : class HFAType;
47 : class HFADictionary;
48 : class HFABand;
49 : class HFASpillFile;
50 :
51 : /************************************************************************/
52 : /* Flag indicating read/write, or read-only access to data. */
53 : /************************************************************************/
54 : typedef enum {
55 : /*! Read only (no update) access */ HFA_ReadOnly = 0,
56 : /*! Read/write access. */ HFA_Update = 1
57 : } HFAAccess;
58 :
59 : /************************************************************************/
60 : /* HFAInfo_t */
61 : /* */
62 : /* This is just a structure, and used hold info about the whole */
63 : /* dataset within hfaopen.cpp */
64 : /************************************************************************/
65 : typedef struct hfainfo {
66 : FILE *fp;
67 :
68 : char *pszPath;
69 : char *pszFilename; /* sans path */
70 : char *pszIGEFilename; /* sans path */
71 :
72 : HFAAccess eAccess;
73 :
74 : GUInt32 nEndOfFile;
75 : GUInt32 nRootPos;
76 : GUInt32 nDictionaryPos;
77 :
78 : GInt16 nEntryHeaderLength;
79 : GInt32 nVersion;
80 :
81 : int bTreeDirty;
82 : HFAEntry *poRoot;
83 :
84 : HFADictionary *poDictionary;
85 : char *pszDictionary;
86 :
87 : int nXSize;
88 : int nYSize;
89 :
90 : int nBands;
91 : HFABand **papoBand;
92 :
93 : void *pMapInfo;
94 : void *pDatum;
95 : void *pProParameters;
96 :
97 : struct hfainfo *psDependent;
98 : } HFAInfo_t;
99 :
100 : GUInt32 HFAAllocateSpace( HFAInfo_t *, GUInt32 );
101 : CPLErr HFAParseBandInfo( HFAInfo_t * );
102 : HFAInfo_t *HFAGetDependent( HFAInfo_t *, const char * );
103 : HFAInfo_t *HFACreateDependent( HFAInfo_t *psBase );
104 : int HFACreateSpillStack( HFAInfo_t *, int nXSize, int nYSize, int nLayers,
105 : int nBlockSize, int nDataType,
106 : GIntBig *pnValidFlagsOffset,
107 : GIntBig *pnDataOffset );
108 :
109 : const char ** GetHFAAuxMetaDataList();
110 :
111 : double *HFAReadBFUniqueBins( HFAEntry *poBinFunc, int nPCTColors );
112 :
113 : #define HFA_PRIVATE
114 :
115 : #include "hfa.h"
116 :
117 : /************************************************************************/
118 : /* HFABand */
119 : /************************************************************************/
120 :
121 : class HFABand
122 : {
123 : int nBlocks;
124 :
125 : // Used for single-file modification
126 : vsi_l_offset *panBlockStart;
127 : int *panBlockSize;
128 : int *panBlockFlag;
129 :
130 : // Used for spill-file modification
131 : vsi_l_offset nBlockStart;
132 : vsi_l_offset nBlockSize;
133 : int nLayerStackCount;
134 : int nLayerStackIndex;
135 :
136 : #define BFLG_VALID 0x01
137 : #define BFLG_COMPRESSED 0x02
138 :
139 : int nPCTColors;
140 : double *apadfPCT[4];
141 : double *padfPCTBins;
142 :
143 : CPLErr LoadBlockInfo();
144 : CPLErr LoadExternalBlockInfo();
145 :
146 : void ReAllocBlock( int iBlock, int nSize );
147 : void NullBlock( void * );
148 :
149 : public:
150 : HFABand( HFAInfo_t *, HFAEntry * );
151 : ~HFABand();
152 :
153 : HFAInfo_t *psInfo;
154 :
155 : FILE *fpExternal;
156 :
157 : int nDataType;
158 : HFAEntry *poNode;
159 :
160 : int nBlockXSize;
161 : int nBlockYSize;
162 :
163 : int nWidth;
164 : int nHeight;
165 :
166 : int nBlocksPerRow;
167 : int nBlocksPerColumn;
168 :
169 : int bNoDataSet;
170 : double dfNoData;
171 :
172 : int bOverviewsPending;
173 : int nOverviews;
174 : HFABand **papoOverviews;
175 :
176 : CPLErr GetRasterBlock( int nXBlock, int nYBlock, void * pData, int nDataSize );
177 : CPLErr SetRasterBlock( int nXBlock, int nYBlock, void * pData );
178 :
179 : const char * GetBandName();
180 : void SetBandName(const char *pszName);
181 :
182 : CPLErr SetNoDataValue( double dfValue );
183 :
184 : CPLErr GetPCT( int *, double **, double **, double **, double **,
185 : double ** );
186 : CPLErr SetPCT( int, double *, double *, double *, double * );
187 :
188 : int CreateOverview( int nOverviewLevel );
189 : CPLErr CleanOverviews();
190 :
191 : CPLErr LoadOverviews();
192 : };
193 :
194 :
195 : /************************************************************************/
196 : /* HFAEntry */
197 : /* */
198 : /* Base class for all entry types. Most entry types do not */
199 : /* have a subclass, and are just handled generically with this */
200 : /* class. */
201 : /************************************************************************/
202 : class HFAEntry
203 : {
204 : int bDirty;
205 : GUInt32 nFilePos;
206 :
207 : HFAInfo_t *psHFA;
208 : HFAEntry *poParent;
209 : HFAEntry *poPrev;
210 :
211 : GUInt32 nNextPos;
212 : HFAEntry *poNext;
213 :
214 : GUInt32 nChildPos;
215 : HFAEntry *poChild;
216 :
217 : char szName[64];
218 : char szType[32];
219 :
220 : HFAType *poType;
221 :
222 : GUInt32 nDataPos;
223 : GUInt32 nDataSize;
224 : GByte *pabyData;
225 :
226 : void LoadData();
227 :
228 : int GetFieldValue( const char *, char, void * );
229 : CPLErr SetFieldValue( const char *, char, void * );
230 :
231 : int bIsMIFObject;
232 :
233 : public:
234 : HFAEntry( HFAInfo_t * psHFA, GUInt32 nPos,
235 : HFAEntry * poParent, HFAEntry *poPrev);
236 :
237 : HFAEntry( HFAInfo_t *psHFA,
238 : const char *pszNodeName,
239 : const char *pszTypeName,
240 : HFAEntry *poParent );
241 :
242 : HFAEntry( HFAEntry *poContainer, const char *pszMIFObjectPath );
243 :
244 : virtual ~HFAEntry();
245 :
246 : CPLErr RemoveAndDestroy();
247 :
248 276 : GUInt32 GetFilePos() { return nFilePos; }
249 :
250 32029 : const char *GetName() { return szName; }
251 : void SetName( const char *pszNodeName );
252 :
253 1375 : const char *GetType() { return szType; }
254 : HFAType *GetTypeObject();
255 :
256 92 : GByte *GetData() { LoadData(); return pabyData; }
257 183 : GUInt32 GetDataPos() { return nDataPos; }
258 93 : GUInt32 GetDataSize() { return nDataSize; }
259 :
260 : HFAEntry *GetChild();
261 : HFAEntry *GetNext();
262 : HFAEntry *GetNamedChild( const char * );
263 :
264 : GInt32 GetIntField( const char *, CPLErr * = NULL );
265 : double GetDoubleField( const char *, CPLErr * = NULL );
266 : const char *GetStringField( const char *, CPLErr * = NULL );
267 : GIntBig GetBigIntField( const char *, CPLErr * = NULL );
268 : int GetFieldCount( const char *, CPLErr * = NULL );
269 :
270 : CPLErr SetIntField( const char *, int );
271 : CPLErr SetDoubleField( const char *, double );
272 : CPLErr SetStringField( const char *, const char * );
273 :
274 : void DumpFieldValues( FILE *, const char * = NULL );
275 :
276 : void SetPosition();
277 : CPLErr FlushToDisk();
278 :
279 : void MarkDirty();
280 : GByte *MakeData( int nSize = 0 );
281 : };
282 :
283 : /************************************************************************/
284 : /* HFAField */
285 : /* */
286 : /* A field in a HFAType in the dictionary. */
287 : /************************************************************************/
288 :
289 : class HFAField
290 : {
291 : public:
292 : int nBytes;
293 :
294 : int nItemCount;
295 : char chPointer; /* '\0', '*' or 'p' */
296 : char chItemType; /* 1|2|4|e|... */
297 :
298 : char *pszItemObjectType; /* if chItemType == 'o' */
299 : HFAType *poItemObjectType;
300 :
301 : char **papszEnumNames; /* normally NULL if not an enum */
302 :
303 : char *pszFieldName;
304 :
305 : char szNumberString[28]; /* buffer used to return an int as a string */
306 :
307 : HFAField();
308 : ~HFAField();
309 :
310 : const char *Initialize( const char * );
311 :
312 : void CompleteDefn( HFADictionary * );
313 :
314 : void Dump( FILE * );
315 :
316 : int ExtractInstValue( const char * pszField, int nIndexValue,
317 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
318 : char chReqType, void *pReqReturn );
319 :
320 : CPLErr SetInstValue( const char * pszField, int nIndexValue,
321 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
322 : char chReqType, void *pValue );
323 :
324 : void DumpInstValue( FILE *fpOut,
325 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
326 : const char *pszPrefix = NULL );
327 :
328 : int GetInstBytes( GByte *, int );
329 : int GetInstCount( GByte * pabyData, int nDataSize );
330 : };
331 :
332 :
333 : /************************************************************************/
334 : /* HFAType */
335 : /* */
336 : /* A type in the dictionary. */
337 : /************************************************************************/
338 :
339 : class HFAType
340 : {
341 : public:
342 : int nBytes;
343 :
344 : int nFields;
345 : HFAField **papoFields;
346 :
347 : char *pszTypeName;
348 :
349 : HFAType();
350 : ~HFAType();
351 :
352 : const char *Initialize( const char * );
353 :
354 : void CompleteDefn( HFADictionary * );
355 :
356 : void Dump( FILE * );
357 :
358 : int GetInstBytes( GByte *, int );
359 : int GetInstCount( const char *pszField,
360 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize);
361 : int ExtractInstValue( const char * pszField,
362 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
363 : char chReqType, void *pReqReturn );
364 : CPLErr SetInstValue( const char * pszField,
365 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
366 : char chReqType, void * pValue );
367 : void DumpInstValue( FILE *fpOut,
368 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
369 : const char *pszPrefix = NULL );
370 : };
371 :
372 : /************************************************************************/
373 : /* HFADictionary */
374 : /************************************************************************/
375 :
376 : class HFADictionary
377 : {
378 : public:
379 : int nTypes;
380 : int nTypesMax;
381 : HFAType **papoTypes;
382 :
383 : CPLString osDictionaryText;
384 : int bDictionaryTextDirty;
385 :
386 : HFADictionary( const char *pszDict );
387 : ~HFADictionary();
388 :
389 : HFAType *FindType( const char * );
390 : void AddType( HFAType * );
391 :
392 : static int GetItemSize( char );
393 :
394 : void Dump( FILE * );
395 : };
396 :
397 : /************************************************************************/
398 : /* HFACompress */
399 : /* */
400 : /* Class that given a block of memory compresses the contents */
401 : /* using run length encoding as used by Imagine. */
402 : /************************************************************************/
403 :
404 : class HFACompress
405 : {
406 : public:
407 : HFACompress( void *pData, GUInt32 nBlockSize, int nDataType );
408 : ~HFACompress();
409 :
410 : // This is the method that does the work.
411 : bool compressBlock();
412 :
413 : // static method to allow us to query whether HFA type supported
414 : static bool QueryDataTypeSupported( int nHFADataType );
415 :
416 : // Get methods - only valid after compressBlock has been called.
417 7 : GByte* getCounts() { return m_pCounts; };
418 7 : GUInt32 getCountSize() { return m_nSizeCounts; };
419 7 : GByte* getValues() { return m_pValues; };
420 7 : GUInt32 getValueSize() { return m_nSizeValues; };
421 7 : GUInt32 getMin() { return m_nMin; };
422 7 : GUInt32 getNumRuns() { return m_nNumRuns; };
423 7 : GByte getNumBits() { return m_nNumBits; };
424 :
425 : private:
426 : void makeCount( GUInt32 count, GByte *pCounter, GUInt32 *pnSizeCount );
427 : GUInt32 findMin( GByte *pNumBits );
428 : GUInt32 valueAsUInt32( GUInt32 index );
429 : void encodeValue( GUInt32 val, GUInt32 repeat );
430 :
431 : void *m_pData;
432 : GUInt32 m_nBlockSize;
433 : GUInt32 m_nBlockCount;
434 : int m_nDataType;
435 : int m_nDataTypeNumBits; // the number of bits the datatype we are trying to compress takes
436 :
437 : GByte *m_pCounts;
438 : GByte *m_pCurrCount;
439 : GUInt32 m_nSizeCounts;
440 :
441 : GByte *m_pValues;
442 : GByte *m_pCurrValues;
443 : GUInt32 m_nSizeValues;
444 :
445 : GUInt32 m_nMin;
446 : GUInt32 m_nNumRuns;
447 : GByte m_nNumBits; // the number of bits needed to compress the range of values in the block
448 :
449 : };
450 :
451 : #endif /* ndef _HFA_P_H_INCLUDED */
|