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