1 : /******************************************************************************
2 : * $Id: hfa_p.h 19686 2010-05-13 12:02:36Z 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 : CPLString osOverName;
150 :
151 : public:
152 : HFABand( HFAInfo_t *, HFAEntry * );
153 : ~HFABand();
154 :
155 : HFAInfo_t *psInfo;
156 :
157 : FILE *fpExternal;
158 :
159 : int nDataType;
160 : HFAEntry *poNode;
161 :
162 : int nBlockXSize;
163 : int nBlockYSize;
164 :
165 : int nWidth;
166 : int nHeight;
167 :
168 : int nBlocksPerRow;
169 : int nBlocksPerColumn;
170 :
171 : int bNoDataSet;
172 : double dfNoData;
173 :
174 : int bOverviewsPending;
175 : int nOverviews;
176 : HFABand **papoOverviews;
177 :
178 : CPLErr GetRasterBlock( int nXBlock, int nYBlock, void * pData, int nDataSize );
179 : CPLErr SetRasterBlock( int nXBlock, int nYBlock, void * pData );
180 :
181 : const char * GetBandName();
182 : void SetBandName(const char *pszName);
183 :
184 : CPLErr SetNoDataValue( double dfValue );
185 :
186 : CPLErr GetPCT( int *, double **, double **, double **, double **,
187 : double ** );
188 : CPLErr SetPCT( int, double *, double *, double *, double * );
189 :
190 : int CreateOverview( int nOverviewLevel );
191 : CPLErr CleanOverviews();
192 :
193 : CPLErr LoadOverviews();
194 : };
195 :
196 :
197 : /************************************************************************/
198 : /* HFAEntry */
199 : /* */
200 : /* Base class for all entry types. Most entry types do not */
201 : /* have a subclass, and are just handled generically with this */
202 : /* class. */
203 : /************************************************************************/
204 : class HFAEntry
205 : {
206 : int bDirty;
207 : GUInt32 nFilePos;
208 :
209 : HFAInfo_t *psHFA;
210 : HFAEntry *poParent;
211 : HFAEntry *poPrev;
212 :
213 : GUInt32 nNextPos;
214 : HFAEntry *poNext;
215 :
216 : GUInt32 nChildPos;
217 : HFAEntry *poChild;
218 :
219 : char szName[64];
220 : char szType[32];
221 :
222 : HFAType *poType;
223 :
224 : GUInt32 nDataPos;
225 : GUInt32 nDataSize;
226 : GByte *pabyData;
227 :
228 : void LoadData();
229 :
230 : int GetFieldValue( const char *, char, void *,
231 : int *pnRemainingDataSize );
232 : CPLErr SetFieldValue( const char *, char, void * );
233 :
234 : int bIsMIFObject;
235 :
236 : HFAEntry( HFAEntry *poContainer,
237 : const char *pszMIFObjectPath,
238 : const char * pszDictionnary,
239 : const char * pszTypeName,
240 : int nDataSizeIn,
241 : GByte* pabyDataIn );
242 :
243 : public:
244 : HFAEntry( HFAInfo_t * psHFA, GUInt32 nPos,
245 : HFAEntry * poParent, HFAEntry *poPrev);
246 :
247 : HFAEntry( HFAInfo_t *psHFA,
248 : const char *pszNodeName,
249 : const char *pszTypeName,
250 : HFAEntry *poParent );
251 :
252 :
253 : virtual ~HFAEntry();
254 :
255 : static HFAEntry* BuildEntryFromMIFObject( HFAEntry *poContainer, const char *pszMIFObjectPath );
256 :
257 : CPLErr RemoveAndDestroy();
258 :
259 316 : GUInt32 GetFilePos() { return nFilePos; }
260 :
261 39932 : const char *GetName() { return szName; }
262 : void SetName( const char *pszNodeName );
263 :
264 2472 : const char *GetType() { return szType; }
265 : HFAType *GetTypeObject();
266 :
267 160 : GByte *GetData() { LoadData(); return pabyData; }
268 254 : GUInt32 GetDataPos() { return nDataPos; }
269 162 : GUInt32 GetDataSize() { return nDataSize; }
270 :
271 : HFAEntry *GetChild();
272 : HFAEntry *GetNext();
273 : HFAEntry *GetNamedChild( const char * );
274 :
275 : GInt32 GetIntField( const char *, CPLErr * = NULL );
276 : double GetDoubleField( const char *, CPLErr * = NULL );
277 : const char *GetStringField( const char *, CPLErr * = NULL, int *pnRemainingDataSize = NULL );
278 : GIntBig GetBigIntField( const char *, CPLErr * = NULL );
279 : int GetFieldCount( const char *, CPLErr * = NULL );
280 :
281 : CPLErr SetIntField( const char *, int );
282 : CPLErr SetDoubleField( const char *, double );
283 : CPLErr SetStringField( const char *, const char * );
284 :
285 : void DumpFieldValues( FILE *, const char * = NULL );
286 :
287 : void SetPosition();
288 : CPLErr FlushToDisk();
289 :
290 : void MarkDirty();
291 : GByte *MakeData( int nSize = 0 );
292 : };
293 :
294 : /************************************************************************/
295 : /* HFAField */
296 : /* */
297 : /* A field in a HFAType in the dictionary. */
298 : /************************************************************************/
299 :
300 : class HFAField
301 : {
302 : public:
303 : int nBytes;
304 :
305 : int nItemCount;
306 : char chPointer; /* '\0', '*' or 'p' */
307 : char chItemType; /* 1|2|4|e|... */
308 :
309 : char *pszItemObjectType; /* if chItemType == 'o' */
310 : HFAType *poItemObjectType;
311 :
312 : char **papszEnumNames; /* normally NULL if not an enum */
313 :
314 : char *pszFieldName;
315 :
316 : char szNumberString[36]; /* buffer used to return an int as a string */
317 :
318 : HFAField();
319 : ~HFAField();
320 :
321 : const char *Initialize( const char * );
322 :
323 : void CompleteDefn( HFADictionary * );
324 :
325 : void Dump( FILE * );
326 :
327 : int ExtractInstValue( const char * pszField, int nIndexValue,
328 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
329 : char chReqType, void *pReqReturn, int *pnRemainingDataSize = NULL );
330 :
331 : CPLErr SetInstValue( const char * pszField, int nIndexValue,
332 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
333 : char chReqType, void *pValue );
334 :
335 : void DumpInstValue( FILE *fpOut,
336 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
337 : const char *pszPrefix = NULL );
338 :
339 : int GetInstBytes( GByte *, int );
340 : int GetInstCount( GByte * pabyData, int nDataSize );
341 : };
342 :
343 :
344 : /************************************************************************/
345 : /* HFAType */
346 : /* */
347 : /* A type in the dictionary. */
348 : /************************************************************************/
349 :
350 : class HFAType
351 : {
352 : public:
353 : int nBytes;
354 :
355 : int nFields;
356 : HFAField **papoFields;
357 :
358 : char *pszTypeName;
359 :
360 : HFAType();
361 : ~HFAType();
362 :
363 : const char *Initialize( const char * );
364 :
365 : void CompleteDefn( HFADictionary * );
366 :
367 : void Dump( FILE * );
368 :
369 : int GetInstBytes( GByte *, int );
370 : int GetInstCount( const char *pszField,
371 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize);
372 : int ExtractInstValue( const char * pszField,
373 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
374 : char chReqType, void *pReqReturn, int *pnRemainingDataSize );
375 : CPLErr SetInstValue( const char * pszField,
376 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
377 : char chReqType, void * pValue );
378 : void DumpInstValue( FILE *fpOut,
379 : GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
380 : const char *pszPrefix = NULL );
381 : };
382 :
383 : /************************************************************************/
384 : /* HFADictionary */
385 : /************************************************************************/
386 :
387 : class HFADictionary
388 : {
389 : public:
390 : int nTypes;
391 : int nTypesMax;
392 : HFAType **papoTypes;
393 :
394 : CPLString osDictionaryText;
395 : int bDictionaryTextDirty;
396 :
397 : HFADictionary( const char *pszDict );
398 : ~HFADictionary();
399 :
400 : HFAType *FindType( const char * );
401 : void AddType( HFAType * );
402 :
403 : static int GetItemSize( char );
404 :
405 : void Dump( FILE * );
406 : };
407 :
408 : /************************************************************************/
409 : /* HFACompress */
410 : /* */
411 : /* Class that given a block of memory compresses the contents */
412 : /* using run length encoding as used by Imagine. */
413 : /************************************************************************/
414 :
415 : class HFACompress
416 : {
417 : public:
418 : HFACompress( void *pData, GUInt32 nBlockSize, int nDataType );
419 : ~HFACompress();
420 :
421 : // This is the method that does the work.
422 : bool compressBlock();
423 :
424 : // static method to allow us to query whether HFA type supported
425 : static bool QueryDataTypeSupported( int nHFADataType );
426 :
427 : // Get methods - only valid after compressBlock has been called.
428 7 : GByte* getCounts() { return m_pCounts; };
429 7 : GUInt32 getCountSize() { return m_nSizeCounts; };
430 7 : GByte* getValues() { return m_pValues; };
431 7 : GUInt32 getValueSize() { return m_nSizeValues; };
432 7 : GUInt32 getMin() { return m_nMin; };
433 7 : GUInt32 getNumRuns() { return m_nNumRuns; };
434 7 : GByte getNumBits() { return m_nNumBits; };
435 :
436 : private:
437 : void makeCount( GUInt32 count, GByte *pCounter, GUInt32 *pnSizeCount );
438 : GUInt32 findMin( GByte *pNumBits );
439 : GUInt32 valueAsUInt32( GUInt32 index );
440 : void encodeValue( GUInt32 val, GUInt32 repeat );
441 :
442 : void *m_pData;
443 : GUInt32 m_nBlockSize;
444 : GUInt32 m_nBlockCount;
445 : int m_nDataType;
446 : int m_nDataTypeNumBits; // the number of bits the datatype we are trying to compress takes
447 :
448 : GByte *m_pCounts;
449 : GByte *m_pCurrCount;
450 : GUInt32 m_nSizeCounts;
451 :
452 : GByte *m_pValues;
453 : GByte *m_pCurrValues;
454 : GUInt32 m_nSizeValues;
455 :
456 : GUInt32 m_nMin;
457 : GUInt32 m_nNumRuns;
458 : GByte m_nNumBits; // the number of bits needed to compress the range of values in the block
459 :
460 : };
461 :
462 : #endif /* ndef _HFA_P_H_INCLUDED */
|