1 : /*****************************************************************************
2 : * $Id: IngrTypes.cpp 25809 2013-03-27 21:54:18Z rouault $
3 : *
4 : * Project: Intergraph Raster Format support
5 : * Purpose: Types support function
6 : * Author: Ivan Lucena, ivan.lucena@pmldnet.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2007, Ivan Lucena
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 "IngrTypes.h"
31 : #include "JpegHelper.h"
32 :
33 : #ifdef DEBUG
34 : #include "stdio.h"
35 : #endif
36 :
37 : static const INGR_FormatDescription INGR_FormatTable[] = {
38 : {PackedBinary, "Packed Binary", GDT_Byte},
39 : {ByteInteger, "Byte Integer", GDT_Byte},
40 : {WordIntegers, "Word Integers", GDT_Int16},
41 : {Integers32Bit, "Integers 32Bit", GDT_Int32},
42 : {FloatingPoint32Bit, "Floating Point 32Bit", GDT_Float32},
43 : {FloatingPoint64Bit, "Floating Point 64Bit", GDT_Float64},
44 : {Complex, "Complex", GDT_CFloat32},
45 : {DoublePrecisionComplex, "Double Precision Complex", GDT_CFloat64},
46 : {RunLengthEncoded, "Run Length Encoded Bitonal", GDT_Byte},
47 : {RunLengthEncodedC, "Run Length Encoded Color", GDT_Byte},
48 : {FigureOfMerit, "Figure of Merit", GDT_Byte},
49 : {DTMFlags, "DTMFlags", GDT_Byte},
50 : {RLEVariableValuesWithZS, "RLE Variable Values With ZS", GDT_Byte},
51 : {RLEBinaryValues, "RLE Binary Values", GDT_Byte},
52 : {RLEVariableValues, "RLE Variable Values", GDT_Byte},
53 : {RLEVariableValuesWithZ, "RLE Variable Values With Z", GDT_Byte},
54 : {RLEVariableValuesC, "RLE Variable Values C", GDT_Byte},
55 : {RLEVariableValuesN, "RLE Variable Values N", GDT_Byte},
56 : {QuadTreeEncoded, "Quad Tree Encoded", GDT_Byte},
57 : {CCITTGroup4, "CCITT Group 4", GDT_Byte},
58 : {RunLengthEncodedRGB, "Run Length Encoded RGB", GDT_Byte},
59 : {VariableRunLength, "Variable Run Length", GDT_Byte},
60 : {AdaptiveRGB, "Adaptive RGB", GDT_Byte},
61 : {Uncompressed24bit, "Uncompressed 24bit", GDT_Byte},
62 : {AdaptiveGrayScale, "Adaptive Gray Scale", GDT_Byte},
63 : {JPEGGRAY, "JPEG GRAY", GDT_Byte},
64 : {JPEGRGB, "JPEG RGB", GDT_Byte},
65 : {JPEGCYMK, "JPEG CYMK", GDT_Byte},
66 : {TiledRasterData, "Tiled Raste Data", GDT_Byte},
67 : {NotUsedReserved, "Not Used( Reserved )", GDT_Byte},
68 : {ContinuousTone, "Continuous Tone", GDT_Byte},
69 : {LineArt, "LineArt", GDT_Byte}
70 : };
71 :
72 : static const char *IngrOrientation[] = {
73 : "Upper Left Vertical",
74 : "Upper Right Vertical",
75 : "Lower Left Vertical",
76 : "Lower Right Vertical",
77 : "Upper Left Horizontal",
78 : "Upper Right Horizontal",
79 : "Lower Left Horizontal",
80 : "Lower Right Horizontal"};
81 :
82 : static const GByte BitReverseTable[256] =
83 : {
84 : 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
85 : 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
86 : 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
87 : 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
88 : 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
89 : 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
90 : 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
91 : 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
92 : 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
93 : 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
94 : 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
95 : 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
96 : 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
97 : 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
98 : 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
99 : 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
100 : 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
101 : 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
102 : 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
103 : 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
104 : 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
105 : 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
106 : 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
107 : 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
108 : 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
109 : 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
110 : 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
111 : 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
112 : 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
113 : 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
114 : 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
115 : 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
116 : };
117 :
118 : // -----------------------------------------------------------------------------
119 : // Scanline Orientation Flip Matrix
120 : // -----------------------------------------------------------------------------
121 :
122 : static const double INGR_URV_Flip[16] =
123 : {
124 : 1.0, 0.0, 0.0, 0.0,
125 : 0.0, -1.0, 0.0, 0.0,
126 : 0.0, 0.0, 1.0, 0.0,
127 : 0.0, 0.0, 0.0, 1.0
128 : };
129 : static const double INGR_LLV_Flip[16] =
130 : {
131 : -1.0, 0.0, 0.0, 0.0,
132 : 0.0, 1.0, 0.0, 0.0,
133 : 0.0, 0.0, 1.0, 0.0,
134 : 0.0, 0.0, 0.0, 1.0
135 : };
136 : static const double INGR_LRV_Flip[16] =
137 : {
138 : -1.0, 0.0, 0.0, 0.0,
139 : 0.0, -1.0, 0.0, 0.0,
140 : 0.0, 0.0, 1.0, 0.0,
141 : 0.0, 0.0, 0.0, 1.0
142 : };
143 : static const double INGR_ULH_Flip[16] =
144 : {
145 : 1.0, 0.0, 0.0, 0.0,
146 : 0.0, 1.0, 0.0, 0.0,
147 : 0.0, 0.0, -1.0, 0.0,
148 : 0.0, 0.0, 0.0, 1.0
149 : };
150 : static const double INGR_URH_Flip[16] =
151 : {
152 : 1.0, 0.0, 0.0, 0.0,
153 : 0.0, -1.0, 0.0, 0.0,
154 : 0.0, 0.0, -1.0, 0.0,
155 : 0.0, 0.0, 0.0, 1.0
156 : };
157 : static const double INGR_LLH_Flip[16] =
158 : {
159 : -1.0, 0.0, 0.0, 0.0,
160 : 0.0, 1.0, 0.0, 0.0,
161 : 0.0, 0.0, -1.0, 0.0,
162 : 0.0, 0.0, 0.0, 1.0
163 : };
164 : static const double INGR_LRH_Flip[16] =
165 : {
166 : -1.0, 0.0, 0.0, 0.0,
167 : 0.0, -1.0, 0.0, 0.0,
168 : 0.0, 0.0, -1.0, 0.0,
169 : 0.0, 0.0, 0.0, 1.0
170 : };
171 :
172 12 : void INGR_MultiplyMatrix( double *padfA, real64 *padfB, const double *padfC )
173 : {
174 : int i;
175 : int j;
176 :
177 60 : for( i = 0; i < 4; i++ )
178 : {
179 240 : for( j = 0; j < 4; j++ )
180 : {
181 192 : padfA[(i * 4) + j] = (double)
182 384 : padfB[(i * 4) + 0] * padfC[(0 * 4) + j] +
183 384 : padfB[(i * 4) + 1] * padfC[(1 * 4) + j] +
184 384 : padfB[(i * 4) + 2] * padfC[(2 * 4) + j] +
185 1152 : padfB[(i * 4) + 3] * padfC[(3 * 4) + j];
186 : }
187 : }
188 12 : }
189 :
190 : // -----------------------------------------------------------------------------
191 : // INGR_GetDataType()
192 : // -----------------------------------------------------------------------------
193 :
194 114 : GDALDataType CPL_STDCALL INGR_GetDataType( uint16 eCode )
195 : {
196 : unsigned int i;
197 :
198 964 : for( i = 0; i < FORMAT_TAB_COUNT; i++ )
199 : {
200 964 : if( eCode == INGR_FormatTable[i].eFormatCode )
201 : {
202 114 : return INGR_FormatTable[i].eDataType;
203 : }
204 : }
205 :
206 0 : return GDT_Unknown;
207 : }
208 :
209 : // -----------------------------------------------------------------------------
210 : // INGR_GetFormatName()
211 : // -----------------------------------------------------------------------------
212 :
213 115 : const char * CPL_STDCALL INGR_GetFormatName( uint16 eCode )
214 : {
215 : unsigned int i;
216 :
217 973 : for( i = 0; i < FORMAT_TAB_COUNT; i++ )
218 : {
219 973 : if( eCode == INGR_FormatTable[i].eFormatCode )
220 : {
221 115 : return INGR_FormatTable[i].pszName;
222 : }
223 : }
224 :
225 0 : return "Not Identified";
226 : }
227 :
228 : // -----------------------------------------------------------------------------
229 : // INGR_GetOrientation()
230 : // -----------------------------------------------------------------------------
231 :
232 114 : const char * CPL_STDCALL INGR_GetOrientation( uint8 nIndex )
233 : {
234 114 : if (nIndex < sizeof(IngrOrientation) / sizeof(IngrOrientation[0]))
235 114 : return IngrOrientation[nIndex];
236 : else
237 0 : return "invalid orientation";
238 : }
239 :
240 : // -----------------------------------------------------------------------------
241 : // INGR_GetFormat()
242 : // -----------------------------------------------------------------------------
243 :
244 35 : INGR_Format CPL_STDCALL INGR_GetFormat( GDALDataType eType,
245 : const char *pszCompression )
246 : {
247 35 : if( EQUAL( pszCompression, "None" ) ||
248 : EQUAL( pszCompression, "" ) )
249 : {
250 34 : switch ( eType )
251 : {
252 16 : case GDT_Byte: return ByteInteger;
253 3 : case GDT_Int16: return WordIntegers;
254 3 : case GDT_UInt16: return WordIntegers;
255 3 : case GDT_Int32: return Integers32Bit;
256 3 : case GDT_UInt32: return Integers32Bit;
257 3 : case GDT_Float32: return FloatingPoint32Bit;
258 3 : case GDT_Float64: return FloatingPoint64Bit;
259 0 : default: return ByteInteger;
260 : }
261 : }
262 :
263 : unsigned int i;
264 :
265 9 : for( i = 0; i < FORMAT_TAB_COUNT; i++ )
266 : {
267 9 : if( EQUAL( pszCompression, INGR_FormatTable[i].pszName ) )
268 : {
269 1 : return (INGR_Format) INGR_FormatTable[i].eFormatCode;
270 : }
271 : }
272 :
273 0 : return ByteInteger;
274 : }
275 :
276 : // -----------------------------------------------------------------------------
277 : // INGR_GetTransMatrix()
278 : // -----------------------------------------------------------------------------
279 :
280 77 : void CPL_STDCALL INGR_GetTransMatrix( INGR_HeaderOne *pHeaderOne,
281 : double *padfGeoTransform )
282 : {
283 : // -------------------------------------------------------------
284 : // Check for empty transformation matrix
285 : // -------------------------------------------------------------
286 :
287 402 : if( pHeaderOne->TransformationMatrix[0] == 0.0 &&
288 65 : pHeaderOne->TransformationMatrix[2] == 0.0 &&
289 65 : pHeaderOne->TransformationMatrix[3] == 0.0 &&
290 65 : pHeaderOne->TransformationMatrix[4] == 0.0 &&
291 65 : pHeaderOne->TransformationMatrix[5] == 0.0 &&
292 65 : pHeaderOne->TransformationMatrix[7] == 0.0 )
293 : {
294 65 : padfGeoTransform[0] = 0.0;
295 65 : padfGeoTransform[1] = 1.0;
296 65 : padfGeoTransform[2] = 0.0;
297 65 : padfGeoTransform[3] = 0.0;
298 65 : padfGeoTransform[4] = 0.0;
299 65 : padfGeoTransform[5] = 1.0;
300 65 : return;
301 : }
302 :
303 : // -------------------------------------------------------------
304 : // Calculate Concatened Tranformation Matrix based on Orientation
305 : // -------------------------------------------------------------
306 :
307 : double adfConcat[16];
308 :
309 12 : switch( (INGR_Orientation ) pHeaderOne->ScanlineOrientation )
310 : {
311 : case UpperLeftVertical:
312 : {
313 0 : unsigned int i = 0;
314 0 : for(i = 0; i < 16; i++)
315 : {
316 0 : adfConcat[i] = (double) pHeaderOne->TransformationMatrix[i];
317 : }
318 : }
319 0 : break;
320 : case UpperRightVertical:
321 0 : INGR_MultiplyMatrix( adfConcat, pHeaderOne->TransformationMatrix, INGR_URV_Flip );
322 0 : break;
323 : case LowerLeftVertical:
324 0 : INGR_MultiplyMatrix( adfConcat, pHeaderOne->TransformationMatrix, INGR_LLV_Flip );
325 0 : break;
326 : case LowerRightVertical:
327 0 : INGR_MultiplyMatrix( adfConcat, pHeaderOne->TransformationMatrix, INGR_LRV_Flip );
328 0 : break;
329 : case UpperLeftHorizontal:
330 5 : INGR_MultiplyMatrix( adfConcat, pHeaderOne->TransformationMatrix, INGR_ULH_Flip );
331 5 : break;
332 : case UpperRightHorizontal:
333 0 : INGR_MultiplyMatrix( adfConcat, pHeaderOne->TransformationMatrix, INGR_URH_Flip );
334 0 : break;
335 : case LowerLeftHorizontal:
336 7 : INGR_MultiplyMatrix( adfConcat, pHeaderOne->TransformationMatrix, INGR_LLH_Flip );
337 7 : break;
338 : case LowerRightHorizontal:
339 0 : INGR_MultiplyMatrix( adfConcat, pHeaderOne->TransformationMatrix, INGR_LRH_Flip );
340 : break;
341 : }
342 :
343 : // -------------------------------------------------------------
344 : // Convert to GDAL GeoTransformation Matrix
345 : // -------------------------------------------------------------
346 :
347 12 : padfGeoTransform[0] = adfConcat[3] - adfConcat[0] / 2;
348 12 : padfGeoTransform[1] = adfConcat[0];
349 12 : padfGeoTransform[2] = adfConcat[1];
350 12 : padfGeoTransform[3] = adfConcat[7] + adfConcat[5] / 2;
351 12 : padfGeoTransform[4] = adfConcat[4];
352 12 : padfGeoTransform[5] = - adfConcat[5];
353 : }
354 :
355 : // -----------------------------------------------------------------------------
356 : // INGR_SetTransMatrix()
357 : // -----------------------------------------------------------------------------
358 :
359 31 : void CPL_STDCALL INGR_SetTransMatrix( real64 *padfMatrix, double *padfGeoTransform )
360 : {
361 : unsigned int i;
362 :
363 496 : for( i = 0; i < 15; i++ )
364 : {
365 465 : padfMatrix[i] = 0.0;
366 : }
367 :
368 31 : padfMatrix[10] = 1.0;
369 31 : padfMatrix[15] = 1.0;
370 :
371 31 : padfMatrix[3] = padfGeoTransform[0] + padfGeoTransform[1] / 2;
372 31 : padfMatrix[0] = padfGeoTransform[1];
373 31 : padfMatrix[1] = padfGeoTransform[2];
374 31 : padfMatrix[7] = padfGeoTransform[3] + padfGeoTransform[5] / 2;
375 31 : padfMatrix[4] = padfGeoTransform[4];
376 31 : padfMatrix[5] = - padfGeoTransform[5];
377 31 : }
378 :
379 : // -----------------------------------------------------------------------------
380 : // INGR_SetIGDSColors()
381 : // -----------------------------------------------------------------------------
382 :
383 1 : uint32 CPL_STDCALL INGR_SetIGDSColors( GDALColorTable *poColorTable,
384 : INGR_ColorTable256 *pColorTableIGDS )
385 : {
386 : GDALColorEntry oEntry;
387 : int i;
388 :
389 257 : for( i = 0; i < poColorTable->GetColorEntryCount(); i++ )
390 : {
391 256 : poColorTable->GetColorEntryAsRGB( i, &oEntry );
392 256 : pColorTableIGDS->Entry[i].v_red = (uint8) oEntry.c1;
393 256 : pColorTableIGDS->Entry[i].v_green = (uint8) oEntry.c2;
394 256 : pColorTableIGDS->Entry[i].v_blue = (uint8) oEntry.c3;
395 : }
396 :
397 1 : return i;
398 : }
399 :
400 : // -----------------------------------------------------------------------------
401 : // INGR_GetTileDirectory()
402 : // -----------------------------------------------------------------------------
403 :
404 5 : uint32 CPL_STDCALL INGR_GetTileDirectory( VSILFILE *fp,
405 : uint32 nOffset,
406 : int nBandXSize,
407 : int nBandYSize,
408 : INGR_TileHeader *pTileDir,
409 : INGR_TileItem **pahTiles)
410 : {
411 5 : if( fp == NULL ||
412 : nBandXSize < 1 ||
413 : nBandYSize < 1 ||
414 : pTileDir == NULL )
415 : {
416 0 : return 0;
417 : }
418 :
419 : // -------------------------------------------------------------
420 : // Read it from the begging of the data segment
421 : // -------------------------------------------------------------
422 :
423 : GByte abyBuf[SIZEOF_TDIR];
424 :
425 5 : if( ( VSIFSeekL( fp, nOffset, SEEK_SET ) == -1 ) ||
426 : ( VSIFReadL( abyBuf, 1, SIZEOF_TDIR, fp ) == 0 ) )
427 : {
428 0 : CPLDebug("INGR", "Error reading tiles header");
429 0 : return 0;
430 : }
431 :
432 5 : INGR_TileHeaderDiskToMem( pTileDir, abyBuf );
433 :
434 5 : if (pTileDir->TileSize == 0)
435 : {
436 : CPLError(CE_Failure, CPLE_AppDefined,
437 0 : "Invalid tile size : %d", pTileDir->TileSize);
438 0 : return 0;
439 : }
440 :
441 : // ----------------------------------------------------------------
442 : // Calculate the number of tiles
443 : // ----------------------------------------------------------------
444 :
445 5 : int nTilesPerCol = (int) ceil( (float) nBandXSize / pTileDir->TileSize );
446 5 : int nTilesPerRow = (int) ceil( (float) nBandYSize / pTileDir->TileSize );
447 :
448 5 : uint32 nTiles = nTilesPerCol * nTilesPerRow;
449 :
450 : // ----------------------------------------------------------------
451 : // Load the tile table (first tile s already read)
452 : // ----------------------------------------------------------------
453 :
454 5 : *pahTiles = (INGR_TileItem*) VSICalloc( nTiles, SIZEOF_TILE );
455 5 : GByte *pabyBuf = (GByte*) VSICalloc( ( nTiles - 1 ), SIZEOF_TILE );
456 :
457 5 : if (*pahTiles == NULL || pabyBuf == NULL)
458 : {
459 0 : CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");
460 0 : CPLFree( *pahTiles );
461 0 : *pahTiles = NULL;
462 0 : CPLFree( pabyBuf );
463 0 : return 0;
464 : }
465 :
466 5 : (*pahTiles)[0].Start = pTileDir->First.Start;
467 5 : (*pahTiles)[0].Allocated = pTileDir->First.Allocated;
468 5 : (*pahTiles)[0].Used = pTileDir->First.Used;
469 :
470 5 : if( nTiles > 1 &&
471 : ( VSIFReadL( pabyBuf, ( nTiles - 1 ), SIZEOF_TILE, fp ) == 0 ) )
472 : {
473 0 : CPLDebug("INGR", "Error reading tiles table");
474 0 : CPLFree( *pahTiles );
475 0 : *pahTiles = NULL;
476 0 : CPLFree( pabyBuf );
477 0 : return 0;
478 : }
479 :
480 : unsigned int i;
481 :
482 20 : for( i = 1; i < nTiles; i++ )
483 : {
484 : INGR_TileItemDiskToMem( &((*pahTiles)[i]),
485 15 : &pabyBuf[ (i - 1) * SIZEOF_TILE] );
486 : }
487 :
488 5 : CPLFree( pabyBuf );
489 5 : return nTiles;
490 : }
491 :
492 : // -----------------------------------------------------------------------------
493 : // INGR_GetIGDSColors()
494 : // -----------------------------------------------------------------------------
495 :
496 2 : void CPL_STDCALL INGR_GetIGDSColors( VSILFILE *fp,
497 : uint32 nOffset,
498 : uint32 nEntries,
499 : GDALColorTable *poColorTable )
500 : {
501 2 : if( fp == NULL ||
502 : nEntries == 0 ||
503 : nEntries > 256 ||
504 : poColorTable == NULL )
505 : {
506 0 : return;
507 : }
508 :
509 : // -------------------------------------------------------------
510 : // Read it from the middle of the second block
511 : // -------------------------------------------------------------
512 :
513 2 : uint32 nStart = nOffset + SIZEOF_HDR1 + SIZEOF_HDR2_A;
514 :
515 : INGR_ColorTable256 hIGDSColors;
516 :
517 : /* nEntries >= 0 && nEntries <= 256, so alloc is safe */
518 2 : GByte *pabyBuf = (GByte*) CPLCalloc( nEntries, SIZEOF_IGDS );
519 :
520 2 : if( ( VSIFSeekL( fp, nStart, SEEK_SET ) == -1 ) ||
521 : ( VSIFReadL( pabyBuf, nEntries, SIZEOF_IGDS, fp ) == 0 ) )
522 : {
523 0 : CPLFree( pabyBuf );
524 0 : return;
525 : }
526 :
527 2 : unsigned int i = 0;
528 2 : unsigned int n = 0;
529 :
530 514 : for( i = 0; i < nEntries; i++ )
531 : {
532 512 : BUF2STRC( pabyBuf, n, hIGDSColors.Entry[i].v_red );
533 512 : BUF2STRC( pabyBuf, n, hIGDSColors.Entry[i].v_green );
534 512 : BUF2STRC( pabyBuf, n, hIGDSColors.Entry[i].v_blue );
535 : }
536 :
537 2 : CPLFree( pabyBuf );
538 :
539 : // -------------------------------------------------------------
540 : // Read it to poColorTable
541 : // -------------------------------------------------------------
542 :
543 : GDALColorEntry oEntry;
544 :
545 2 : oEntry.c4 = 255;
546 :
547 514 : for( i = 0; i < nEntries; i++ )
548 : {
549 512 : oEntry.c1 = hIGDSColors.Entry[i].v_red;
550 512 : oEntry.c2 = hIGDSColors.Entry[i].v_green;
551 512 : oEntry.c3 = hIGDSColors.Entry[i].v_blue;
552 512 : poColorTable->SetColorEntry( i, &oEntry );
553 : }
554 : }
555 :
556 : // -----------------------------------------------------------------------------
557 : // INGR_SetEnvironColors()
558 : // -----------------------------------------------------------------------------
559 :
560 0 : uint32 CPL_STDCALL INGR_SetEnvironColors( GDALColorTable *poColorTable,
561 : INGR_ColorTableVar *pEnvironTable )
562 : {
563 : GDALColorEntry oEntry;
564 0 : real32 fNormFactor = 0xfff / 255;
565 : int i;
566 :
567 0 : for( i = 0; i < poColorTable->GetColorEntryCount(); i++ )
568 : {
569 0 : poColorTable->GetColorEntryAsRGB( i, &oEntry );
570 0 : pEnvironTable->Entry[i].v_slot = (uint16) i;
571 0 : pEnvironTable->Entry[i].v_red = (uint16) ( oEntry.c1 * fNormFactor );
572 0 : pEnvironTable->Entry[i].v_green = (uint16) ( oEntry.c2 * fNormFactor );
573 0 : pEnvironTable->Entry[i].v_blue = (uint16) ( oEntry.c3 * fNormFactor );
574 : }
575 :
576 0 : return i;
577 : }
578 :
579 : // -----------------------------------------------------------------------------
580 : // INGR_GetEnvironVColors()
581 : // -----------------------------------------------------------------------------
582 :
583 6 : void CPL_STDCALL INGR_GetEnvironVColors( VSILFILE *fp,
584 : uint32 nOffset,
585 : uint32 nEntries,
586 : GDALColorTable *poColorTable )
587 : {
588 6 : if( fp == NULL ||
589 : nEntries == 0 ||
590 : poColorTable == NULL )
591 : {
592 0 : return;
593 : }
594 :
595 : // -------------------------------------------------------------
596 : // Read it from the third block
597 : // -------------------------------------------------------------
598 :
599 6 : uint32 nStart = nOffset + SIZEOF_HDR1 + SIZEOF_HDR2;
600 :
601 : INGR_ColorTableVar hVLTColors;
602 :
603 6 : hVLTColors.Entry = (vlt_slot*) VSICalloc( nEntries, SIZEOF_VLTS );
604 :
605 6 : GByte *pabyBuf = (GByte*) VSICalloc( nEntries, SIZEOF_VLTS );
606 :
607 6 : if (hVLTColors.Entry == NULL || pabyBuf == NULL)
608 : {
609 0 : CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");
610 0 : CPLFree( pabyBuf );
611 0 : CPLFree( hVLTColors.Entry );
612 0 : return;
613 : }
614 :
615 6 : if( ( VSIFSeekL( fp, nStart, SEEK_SET ) == -1 ) ||
616 : ( VSIFReadL( pabyBuf, nEntries, SIZEOF_VLTS, fp ) == 0 ) )
617 : {
618 0 : CPLFree( pabyBuf );
619 0 : CPLFree( hVLTColors.Entry );
620 0 : return;
621 : }
622 :
623 6 : unsigned int i = 0;
624 6 : unsigned int n = 0;
625 :
626 1542 : for( i = 0; i < nEntries; i++ )
627 : {
628 1536 : BUF2STRC( pabyBuf, n, hVLTColors.Entry[i].v_slot );
629 1536 : BUF2STRC( pabyBuf, n, hVLTColors.Entry[i].v_red );
630 1536 : BUF2STRC( pabyBuf, n, hVLTColors.Entry[i].v_green );
631 1536 : BUF2STRC( pabyBuf, n, hVLTColors.Entry[i].v_blue );
632 : }
633 :
634 6 : CPLFree( pabyBuf );
635 :
636 :
637 : #if defined(CPL_MSB)
638 : for (i = 0; i < nEntries; i++)
639 : {
640 : CPL_LSBPTR16(&hVLTColors.Entry[i].v_slot);
641 : CPL_LSBPTR16(&hVLTColors.Entry[i].v_red);
642 : CPL_LSBPTR16(&hVLTColors.Entry[i].v_green);
643 : CPL_LSBPTR16(&hVLTColors.Entry[i].v_blue);
644 : }
645 : #endif
646 :
647 : // -------------------------------------------------------------
648 : // Get Maximum Intensity and Index Values
649 : // -------------------------------------------------------------
650 :
651 6 : real32 fMaxRed = 0.0;
652 6 : real32 fMaxGreen = 0.0;
653 6 : real32 fMaxBlues = 0.0;
654 :
655 1542 : for( i = 0; i < nEntries; i++ )
656 : {
657 1536 : fMaxRed = MAX( fMaxRed , hVLTColors.Entry[i].v_red );
658 1536 : fMaxGreen = MAX( fMaxGreen, hVLTColors.Entry[i].v_green );
659 1536 : fMaxBlues = MAX( fMaxBlues, hVLTColors.Entry[i].v_blue );
660 : }
661 :
662 : // -------------------------------------------------------------
663 : // Calculate Normalization Factor
664 : // -------------------------------------------------------------
665 :
666 6 : real32 fNormFactor = 0.0;
667 :
668 6 : fNormFactor = ( fMaxRed > fMaxGreen ? fMaxRed : fMaxGreen );
669 6 : fNormFactor = ( fNormFactor > fMaxBlues ? fNormFactor : fMaxBlues );
670 6 : if (fNormFactor)
671 6 : fNormFactor = 255 / fNormFactor;
672 :
673 : // -------------------------------------------------------------
674 : // Loads GDAL Color Table ( filling the wholes )
675 : // -------------------------------------------------------------
676 :
677 : GDALColorEntry oEntry;
678 :
679 1542 : for( i = 0; i < nEntries; i++ )
680 : {
681 1536 : oEntry.c1 = (short) ( hVLTColors.Entry[i].v_red * fNormFactor );
682 1536 : oEntry.c2 = (short) ( hVLTColors.Entry[i].v_green * fNormFactor );
683 1536 : oEntry.c3 = (short) ( hVLTColors.Entry[i].v_blue * fNormFactor );
684 1536 : oEntry.c4 = (short) 255;
685 1536 : poColorTable->SetColorEntry( hVLTColors.Entry[i].v_slot, &oEntry );
686 : }
687 :
688 6 : CPLFree( hVLTColors.Entry );
689 : }
690 :
691 : // -----------------------------------------------------------------------------
692 : // SetMiniMax()
693 : // -----------------------------------------------------------------------------
694 :
695 112 : INGR_MinMax CPL_STDCALL INGR_SetMinMax( GDALDataType eType, double dValue )
696 : {
697 : INGR_MinMax uResult;
698 :
699 112 : switch ( eType )
700 : {
701 : case GDT_Byte:
702 64 : uResult.AsUint8 = (uint8) dValue;
703 64 : break;
704 : case GDT_Int16:
705 10 : uResult.AsUint16 = (int16) dValue;
706 10 : break;
707 : case GDT_UInt16:
708 6 : uResult.AsUint16 = (uint16) dValue;
709 6 : break;
710 : case GDT_Int32:
711 10 : uResult.AsUint32 = (int32) dValue;
712 10 : break;
713 : case GDT_UInt32:
714 6 : uResult.AsUint32 = (uint32) dValue;
715 6 : break;
716 : case GDT_Float32:
717 8 : uResult.AsReal32 = (real32) dValue;
718 8 : break;
719 : case GDT_Float64:
720 8 : uResult.AsReal64 = (real64) dValue;
721 : default:
722 8 : uResult.AsUint8 = (uint8) 0;
723 : }
724 :
725 112 : return uResult;
726 : }
727 :
728 : // -----------------------------------------------------------------------------
729 : // INGR_GetMinMax()
730 : // -----------------------------------------------------------------------------
731 :
732 0 : double CPL_STDCALL INGR_GetMinMax( GDALDataType eType, INGR_MinMax hValue )
733 : {
734 0 : switch ( eType )
735 : {
736 0 : case GDT_Byte: return (double) hValue.AsUint8;
737 0 : case GDT_Int16: return (double) hValue.AsUint16;
738 0 : case GDT_UInt16: return (double) hValue.AsUint16;
739 0 : case GDT_Int32: return (double) hValue.AsUint32;
740 0 : case GDT_UInt32: return (double) hValue.AsUint32;
741 0 : case GDT_Float32: return (double) hValue.AsReal32;
742 0 : case GDT_Float64: return (double) hValue.AsReal64;
743 0 : default: return (double) 0.0;
744 : }
745 : }
746 :
747 : // -----------------------------------------------------------------------------
748 : // INGR_GetDataBlockSize()
749 : // -----------------------------------------------------------------------------
750 :
751 11 : uint32 CPL_STDCALL INGR_GetDataBlockSize( const char *pszFilename,
752 : uint32 nBandOffset,
753 : uint32 nDataOffset )
754 : {
755 11 : if( nBandOffset == 0 )
756 : {
757 : // -------------------------------------------------------------
758 : // Until the end of the file
759 : // -------------------------------------------------------------
760 :
761 : VSIStatBufL sStat;
762 11 : VSIStatL( pszFilename, &sStat );
763 11 : return (uint32) (sStat.st_size - nDataOffset);
764 : }
765 : else
766 : {
767 : // -------------------------------------------------------------
768 : // Until the end of the band
769 : // -------------------------------------------------------------
770 :
771 0 : return nBandOffset - nDataOffset;
772 : }
773 : }
774 :
775 : // -----------------------------------------------------------------------------
776 : // INGR_CreateVirtualFile()
777 : // -----------------------------------------------------------------------------
778 :
779 9 : INGR_VirtualFile CPL_STDCALL INGR_CreateVirtualFile( const char *pszFilename,
780 : INGR_Format eFormat,
781 : int nXSize,
782 : int nYSize,
783 : int nTileSize,
784 : int nQuality,
785 : GByte *pabyBuffer,
786 : int nBufferSize,
787 : int nBand )
788 : {
789 : INGR_VirtualFile hVirtual;
790 :
791 : hVirtual.pszFileName = CPLSPrintf( "/vsimem/%s.virtual",
792 9 : CPLGetBasename( pszFilename ) );
793 :
794 9 : int nJPGComponents = 1;
795 :
796 9 : switch( eFormat )
797 : {
798 : case JPEGRGB:
799 4 : nJPGComponents = 3;
800 : case JPEGGRAY:
801 : {
802 8 : GByte *pabyHeader = (GByte*) CPLCalloc( 1, 2048 );
803 : int nHeaderSize = JPGHLP_HeaderMaker( pabyHeader,
804 : nTileSize,
805 : nTileSize,
806 : nJPGComponents,
807 : 0,
808 8 : nQuality );
809 8 : VSILFILE *fp = VSIFOpenL( hVirtual.pszFileName, "w+" );
810 8 : VSIFWriteL( pabyHeader, 1, nHeaderSize, fp );
811 8 : VSIFWriteL( pabyBuffer, 1, nBufferSize, fp );
812 8 : VSIFCloseL( fp );
813 8 : CPLFree( pabyHeader );
814 8 : break;
815 : }
816 : case CCITTGroup4:
817 : {
818 1 : REVERSEBITSBUFFER( pabyBuffer, nBufferSize );
819 1 : TIFF *hTIFF = VSI_TIFFOpen( hVirtual.pszFileName, "w+" );
820 1 : TIFFSetField( hTIFF, TIFFTAG_IMAGEWIDTH, nXSize );
821 1 : TIFFSetField( hTIFF, TIFFTAG_IMAGELENGTH, nYSize );
822 1 : TIFFSetField( hTIFF, TIFFTAG_BITSPERSAMPLE, 1 );
823 1 : TIFFSetField( hTIFF, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT );
824 1 : TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
825 1 : TIFFSetField( hTIFF, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB );
826 1 : TIFFSetField( hTIFF, TIFFTAG_ROWSPERSTRIP, -1 );
827 1 : TIFFSetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, 1 );
828 1 : TIFFSetField( hTIFF, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE );
829 1 : TIFFSetField( hTIFF, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4 );
830 1 : TIFFWriteRawStrip( hTIFF, 0, pabyBuffer, nBufferSize );
831 1 : TIFFWriteDirectory( hTIFF );
832 1 : TIFFClose( hTIFF );
833 1 : break;
834 : }
835 : default:
836 0 : return hVirtual;
837 : }
838 :
839 9 : hVirtual.poDS = (GDALDataset*) GDALOpen( hVirtual.pszFileName, GA_ReadOnly );
840 :
841 9 : if( hVirtual.poDS )
842 : {
843 9 : hVirtual.poBand = (GDALRasterBand*) GDALGetRasterBand( hVirtual.poDS, nBand );
844 : }
845 :
846 9 : return hVirtual;
847 : }
848 :
849 : // -----------------------------------------------------------------------------
850 : // INGR_ReleaseVirtual()
851 : // -----------------------------------------------------------------------------
852 :
853 9 : void CPL_STDCALL INGR_ReleaseVirtual( INGR_VirtualFile *poTiffMem )
854 : {
855 9 : delete poTiffMem->poDS;
856 9 : VSIUnlink( poTiffMem->pszFileName );
857 9 : }
858 :
859 : // -----------------------------------------------------------------------------
860 : // INGR_ReleaseVirtual()
861 : // -----------------------------------------------------------------------------
862 :
863 4 : int CPL_STDCALL INGR_ReadJpegQuality( VSILFILE *fp, uint32 nAppDataOfseet,
864 : uint32 nSeekLimit )
865 : {
866 4 : if( nAppDataOfseet == 0 )
867 : {
868 0 : return INGR_JPEGQDEFAULT;
869 : }
870 :
871 : INGR_JPEGAppData hJpegData;
872 4 : uint32 nNext = nAppDataOfseet;
873 :
874 : GByte abyBuf[SIZEOF_JPGAD];
875 :
876 4 : do
877 : {
878 4 : if( ( VSIFSeekL( fp, nNext, SEEK_SET ) == -1 ) ||
879 : ( VSIFReadL( abyBuf, 1, SIZEOF_JPGAD, fp ) == 0 ) )
880 : {
881 0 : return INGR_JPEGQDEFAULT;
882 : }
883 :
884 4 : INGR_JPEGAppDataDiskToMem(&hJpegData, abyBuf);
885 :
886 4 : nNext += hJpegData.RemainingLength;
887 :
888 4 : if( nNext > ( nSeekLimit - SIZEOF_JPGAD ) )
889 : {
890 0 : return INGR_JPEGQDEFAULT;
891 : }
892 : }
893 : while( ! ( hJpegData.ApplicationType == 2 &&
894 : hJpegData.SubTypeCode == 12 ) );
895 :
896 4 : return hJpegData.JpegQuality;
897 : }
898 :
899 : // -----------------------------------------------------------------------------
900 : // INGR_Decode()
901 : //
902 : // Decode the various RLE compression options.
903 : //
904 : // Pass NULL as pabyDstData to obtain pnBytesConsumed and bypass decompression.
905 : // -----------------------------------------------------------------------------
906 :
907 : int CPL_STDCALL
908 507 : INGR_Decode( INGR_Format eFormat, GByte *pabySrcData, GByte *pabyDstData,
909 : uint32 nSrcBytes, uint32 nBlockSize, uint32 *pnBytesConsumed )
910 :
911 : {
912 507 : switch( eFormat )
913 : {
914 : case RunLengthEncoded:
915 : return INGR_DecodeRunLengthBitonal( pabySrcData, pabyDstData,
916 : nSrcBytes, nBlockSize,
917 405 : pnBytesConsumed );
918 :
919 : case RunLengthEncodedC:
920 : return INGR_DecodeRunLengthPaletted( pabySrcData, pabyDstData,
921 : nSrcBytes, nBlockSize,
922 100 : pnBytesConsumed );
923 :
924 : default:
925 : return INGR_DecodeRunLength( pabySrcData, pabyDstData,
926 : nSrcBytes, nBlockSize,
927 2 : pnBytesConsumed );
928 : }
929 : }
930 :
931 : // -----------------------------------------------------------------------------
932 : // INGR_DecodeRunLength()
933 : // -----------------------------------------------------------------------------
934 :
935 2 : int CPL_STDCALL INGR_DecodeRunLength( GByte *pabySrcData, GByte *pabyDstData,
936 : uint32 nSrcBytes, uint32 nBlockSize,
937 : uint32 *pnBytesConsumed )
938 : {
939 : signed char cAtomHead;
940 :
941 : unsigned int nRun;
942 : unsigned int i;
943 : unsigned int iInput;
944 : unsigned int iOutput;
945 : unsigned int inc;
946 :
947 2 : iInput = 0;
948 2 : iOutput = 0;
949 :
950 2405 : while( ( iInput < nSrcBytes ) && ( iOutput < nBlockSize ) )
951 : {
952 2401 : cAtomHead = (char) pabySrcData[iInput++];
953 :
954 2401 : if( cAtomHead > 0 )
955 : {
956 1411 : nRun = cAtomHead;
957 :
958 1411 : if (pabyDstData)
959 : {
960 73365 : for( i = 0; i < nRun && iInput < nSrcBytes && iOutput < nBlockSize; i++ )
961 : {
962 71954 : pabyDstData[iOutput++] = pabySrcData[iInput++];
963 : }
964 : }
965 : else
966 : {
967 0 : inc = MIN(nRun, MIN(nSrcBytes - iInput, nBlockSize - iOutput));
968 0 : iInput += inc;
969 0 : iOutput += inc;
970 : }
971 : }
972 990 : else if( cAtomHead < 0 )
973 : {
974 990 : nRun = abs( cAtomHead );
975 :
976 990 : if (pabyDstData)
977 : {
978 4036 : for( i = 0; i < nRun && iInput < nSrcBytes && iOutput < nBlockSize; i++ )
979 : {
980 3046 : pabyDstData[iOutput++] = pabySrcData[iInput];
981 : }
982 : }
983 : else
984 : {
985 0 : inc = MIN(nRun, MIN(nSrcBytes - iInput, nBlockSize - iOutput));
986 0 : iOutput += inc;
987 : }
988 990 : iInput++;
989 : }
990 : }
991 :
992 2 : if( pnBytesConsumed != NULL )
993 0 : *pnBytesConsumed = iInput;
994 :
995 2 : return iOutput;
996 : }
997 :
998 : // -----------------------------------------------------------------------------
999 : // INGR_DecodeRunLengthPaletted()
1000 : // -----------------------------------------------------------------------------
1001 :
1002 : int CPL_STDCALL
1003 100 : INGR_DecodeRunLengthPaletted( GByte *pabySrcData, GByte *pabyDstData,
1004 : uint32 nSrcBytes, uint32 nBlockSize,
1005 : uint32 *pnBytesConsumed )
1006 : {
1007 : unsigned short nColor;
1008 : unsigned short nCount;
1009 :
1010 : unsigned int i;
1011 : unsigned int iInput;
1012 : unsigned int iOutput;
1013 :
1014 100 : unsigned short *pauiSrc = (unsigned short *) pabySrcData;
1015 100 : unsigned int nSrcShorts = nSrcBytes / 2;
1016 :
1017 100 : iInput = 0;
1018 100 : iOutput = 0;
1019 :
1020 100 : if ( nSrcShorts == 0 )
1021 0 : return 0;
1022 :
1023 13720 : do
1024 : {
1025 13720 : nCount = 0;
1026 13720 : nColor = CPL_LSBWORD16( pauiSrc[ iInput ] );
1027 13720 : iInput++;
1028 :
1029 13720 : if( nColor == 0x5900 ||
1030 : nColor == 0x5901 )
1031 : {
1032 100 : iInput++;
1033 100 : continue;
1034 : }
1035 :
1036 13620 : if ( iInput < nSrcShorts )
1037 : {
1038 13620 : nCount = CPL_LSBWORD16( pauiSrc[ iInput ] );
1039 13620 : iInput++;
1040 : }
1041 :
1042 13620 : if (pabyDstData)
1043 : {
1044 28620 : for( i = 0; i < nCount && iOutput < nBlockSize; i++ )
1045 : {
1046 15000 : pabyDstData[iOutput++] = (unsigned char) nColor;
1047 : }
1048 : }
1049 : else
1050 : {
1051 0 : iOutput += MIN(nCount, nBlockSize - iOutput);
1052 : }
1053 : }
1054 : while( ( iInput < nSrcShorts ) && ( iOutput < nBlockSize) );
1055 :
1056 100 : if( pnBytesConsumed != NULL )
1057 100 : *pnBytesConsumed = iInput * 2;
1058 :
1059 100 : return iOutput;
1060 : }
1061 :
1062 : // -----------------------------------------------------------------------------
1063 : // INGR_DecodeRunLengthBitonal()
1064 : // -----------------------------------------------------------------------------
1065 :
1066 : int CPL_STDCALL
1067 405 : INGR_DecodeRunLengthBitonal( GByte *pabySrcData, GByte *pabyDstData,
1068 : uint32 nSrcBytes, uint32 nBlockSize,
1069 : uint32 *pnBytesConsumed )
1070 : {
1071 : unsigned short i;
1072 : unsigned int j;
1073 405 : unsigned int iInput = 0;
1074 405 : unsigned int iOutput = 0;
1075 405 : unsigned short *pauiSrc = (unsigned short *) pabySrcData;
1076 405 : unsigned int nSrcShorts = nSrcBytes / 2;
1077 : unsigned short nRun;
1078 405 : unsigned char nValue = 0;
1079 405 : bool bHeader = true;
1080 :
1081 405 : if (nSrcShorts == 0)
1082 0 : return 0;
1083 :
1084 :
1085 : // Check for scanline header
1086 : do
1087 : {
1088 : unsigned int nWordsInScanline;
1089 : unsigned int nTotal;
1090 :
1091 405 : if( CPL_LSBWORD16(pauiSrc[0]) != 0x5900 )
1092 : {
1093 135 : bHeader = false;
1094 135 : break;
1095 : }
1096 :
1097 270 : if (nBlockSize < 0x00005900)
1098 : {
1099 : // Can only be a header since we can never have a span of 22784
1100 : // if the width of the scanline is known to be less than that.
1101 270 : break;
1102 : }
1103 :
1104 : // Here follows a more stringent test that this is really a scanline header
1105 : // and not a span in a file that has no scanline headers.
1106 : // Here is the scanline header information
1107 : // 0: 0x5900
1108 : // 2: words to follow
1109 : // 4: line id (mod 16 bits)
1110 : // 6: 0x0000 (pixels to skip, assumed to be 0)
1111 :
1112 : // Scanline with header has minimum of 5 entries.
1113 0 : if (nSrcShorts < 5)
1114 : {
1115 0 : bHeader = false;
1116 0 : break;
1117 : }
1118 :
1119 : // Test that words to follow is at least 3 and odd
1120 : // Test that pixels to skip is 0
1121 0 : if ((CPL_LSBWORD16(pauiSrc[1]) < 3) ||
1122 0 : ((CPL_LSBWORD16(pauiSrc[1]) & 1) == 0) ||
1123 0 : (CPL_LSBWORD16(pauiSrc[3]) != 0))
1124 : {
1125 0 : bHeader = false;
1126 0 : break;
1127 : }
1128 :
1129 0 : nWordsInScanline = ((unsigned int) CPL_LSBWORD16(pauiSrc[1])) + 2;
1130 0 : if (nSrcShorts >= nWordsInScanline + 5)
1131 : {
1132 : // Do some quick extra tests on next scanline.
1133 :
1134 : // Check that the next scanline starts with 0x5900
1135 : // Check that the next scanline's words-to-follow is at least 3 and odd
1136 : // Check that the next scanline's skip pixel offset is 0
1137 : // Check that the next scanline's line number is 1 more than this one.
1138 0 : if ((CPL_LSBWORD16(pauiSrc[nWordsInScanline]) != 0x5900) ||
1139 0 : (CPL_LSBWORD16(pauiSrc[nWordsInScanline+1]) < 3) ||
1140 0 : ((CPL_LSBWORD16(pauiSrc[nWordsInScanline+1]) & 1) == 0) ||
1141 0 : (CPL_LSBWORD16(pauiSrc[nWordsInScanline+3]) != 0) ||
1142 0 : (((((unsigned int)CPL_LSBWORD16(pauiSrc[2])) + 1) & 0x0000FFFF) !=
1143 0 : ((unsigned int)CPL_LSBWORD16(pauiSrc[nWordsInScanline+2]))))
1144 : {
1145 0 : bHeader = false;
1146 0 : break;
1147 : }
1148 : }
1149 0 : else if (nSrcShorts < nWordsInScanline)
1150 : {
1151 : // Cannot be a header since there is not enough data.
1152 0 : bHeader = false;
1153 0 : break;
1154 : }
1155 :
1156 : // If we get here, we add all the span values and see if they add up to the nBlockSize.
1157 0 : j = 0;
1158 0 : nTotal = 0;
1159 :
1160 0 : for(;j < nWordsInScanline - 4; j++)
1161 : {
1162 0 : nTotal += (unsigned int) CPL_LSBWORD16(pauiSrc[j+4]);
1163 : }
1164 :
1165 0 : if (nTotal != nBlockSize)
1166 0 : bHeader = false;
1167 :
1168 : // Fall through. We have a valid scanline header... probably.
1169 :
1170 : } while(0);
1171 :
1172 405 : if( bHeader )
1173 270 : iInput+=4; // 0x5900 tag, line id, line data size, skip offset
1174 :
1175 405 : if (iInput >= nSrcShorts)
1176 0 : return 0;
1177 :
1178 10770 : do
1179 : {
1180 10770 : nRun = CPL_LSBWORD16(pauiSrc[ iInput ]);
1181 10770 : iInput++;
1182 :
1183 10770 : if (pabyDstData)
1184 : {
1185 87315 : for( i = 0; i < nRun && iOutput < nBlockSize; i++ )
1186 : {
1187 76545 : pabyDstData[ iOutput++ ] = nValue;
1188 : }
1189 :
1190 10770 : nValue = ( nValue == 1 ? 0 : 1 );
1191 : }
1192 : else
1193 : {
1194 0 : iOutput += MIN(nRun, nBlockSize - iOutput);
1195 : }
1196 :
1197 : }
1198 : while( ( iInput < nSrcShorts ) && ( iOutput < nBlockSize ) );
1199 :
1200 : // Skip over any empty end of line spans.
1201 405 : if ((iInput < nSrcShorts) && (CPL_LSBWORD16(pauiSrc[ iInput ]) == 0))
1202 : {
1203 1281 : while((iInput < nSrcShorts) && (CPL_LSBWORD16(pauiSrc[ iInput ]) == 0))
1204 503 : iInput++;
1205 :
1206 : // Should never be pairs of consecutive empty spans,
1207 : // except at end and start of two scanlines.
1208 : // We must adjust to start at the correct location in the
1209 : // next scanline, otherwise the colours will be inverted.
1210 : // iInput should be odd since scanline is
1211 : // supposed to start and end with OFF span.
1212 389 : if ((iInput&1) == 0)
1213 122 : iInput--;
1214 : }
1215 :
1216 :
1217 405 : if( pnBytesConsumed != NULL )
1218 405 : *pnBytesConsumed = iInput * 2;
1219 :
1220 405 : return iOutput;
1221 : }
1222 :
1223 : // -----------------------------------------------------------------------------
1224 : // INGR_DecodeRunLengthBitonalTiled()
1225 : // -----------------------------------------------------------------------------
1226 :
1227 : int CPL_STDCALL
1228 4 : INGR_DecodeRunLengthBitonalTiled( GByte *pabySrcData, GByte *pabyDstData,
1229 : uint32 nSrcBytes, uint32 nBlockSize,
1230 : uint32 *pnBytesConsumed )
1231 : {
1232 : unsigned short i;
1233 4 : unsigned int iInput = 0;
1234 4 : unsigned int iOutput = 0;
1235 4 : unsigned short *pauiSrc = (unsigned short *) pabySrcData;
1236 4 : unsigned int nSrcShorts = nSrcBytes / 2;
1237 4 : unsigned short nRun = 0;
1238 4 : unsigned char nValue = 0;
1239 4 : unsigned short previous = 0;
1240 :
1241 4 : if (nSrcShorts == 0)
1242 0 : return 0;
1243 :
1244 4 : if( CPL_LSBWORD16(pauiSrc[0]) != 0x5900 )
1245 : {
1246 4 : nRun = 256;
1247 4 : nValue = 0;
1248 4 : previous = 0;
1249 10313 : do
1250 : {
1251 10313 : previous = nRun;
1252 :
1253 10313 : nRun = CPL_LSBWORD16(pauiSrc[ iInput ]);
1254 10313 : iInput++;
1255 :
1256 10313 : if( nRun == 0 && previous == 0 ) // new line
1257 : {
1258 565 : nValue = 0;
1259 : }
1260 :
1261 75849 : for( i = 0; i < nRun && iOutput < nBlockSize; i++ )
1262 : {
1263 65536 : pabyDstData[ iOutput++ ] = nValue;
1264 : }
1265 :
1266 10313 : if( nRun != 0 )
1267 : {
1268 9059 : nValue = ( nValue == 1 ? 0 : 1 );
1269 : }
1270 : }
1271 : while( ( iInput < nSrcShorts ) && ( iOutput < nBlockSize ) );
1272 : }
1273 : else
1274 : {
1275 0 : do
1276 : {
1277 0 : nRun = CPL_LSBWORD16(pauiSrc[ iInput ]);
1278 0 : iInput++;
1279 :
1280 0 : if( nRun == 0x5900 )
1281 : {
1282 0 : iInput+=3; // line id, data size, skip offset
1283 0 : continue;
1284 : }
1285 :
1286 0 : for( i = 0; i < nRun && iOutput < nBlockSize; i++ )
1287 : {
1288 0 : pabyDstData[ iOutput++ ] = nValue;
1289 : }
1290 :
1291 0 : nValue = ( nValue == 1 ? 0 : 1 );
1292 : }
1293 : while( ( iInput < nSrcShorts ) && ( iOutput < nBlockSize ) );
1294 : }
1295 :
1296 4 : if( pnBytesConsumed != NULL )
1297 : {
1298 0 : *pnBytesConsumed = iInput * 2;
1299 : }
1300 :
1301 4 : return iOutput;
1302 : }
1303 :
1304 809 : void CPL_STDCALL INGR_HeaderOneDiskToMem(INGR_HeaderOne* pHeaderOne, const GByte *pabyBuf)
1305 : {
1306 809 : unsigned int n = 0;
1307 :
1308 809 : BUF2STRC( pabyBuf, n, pHeaderOne->HeaderType );
1309 809 : BUF2STRC( pabyBuf, n, pHeaderOne->WordsToFollow );
1310 809 : BUF2STRC( pabyBuf, n, pHeaderOne->DataTypeCode );
1311 809 : BUF2STRC( pabyBuf, n, pHeaderOne->ApplicationType );
1312 809 : BUF2STRC( pabyBuf, n, pHeaderOne->XViewOrigin );
1313 809 : BUF2STRC( pabyBuf, n, pHeaderOne->YViewOrigin );
1314 809 : BUF2STRC( pabyBuf, n, pHeaderOne->ZViewOrigin );
1315 809 : BUF2STRC( pabyBuf, n, pHeaderOne->XViewExtent );
1316 809 : BUF2STRC( pabyBuf, n, pHeaderOne->YViewExtent );
1317 809 : BUF2STRC( pabyBuf, n, pHeaderOne->ZViewExtent );
1318 809 : BUF2STRC( pabyBuf, n, pHeaderOne->TransformationMatrix );
1319 809 : BUF2STRC( pabyBuf, n, pHeaderOne->PixelsPerLine );
1320 809 : BUF2STRC( pabyBuf, n, pHeaderOne->NumberOfLines );
1321 809 : BUF2STRC( pabyBuf, n, pHeaderOne->DeviceResolution );
1322 809 : BUF2STRC( pabyBuf, n, pHeaderOne->ScanlineOrientation );
1323 809 : BUF2STRC( pabyBuf, n, pHeaderOne->ScannableFlag );
1324 809 : BUF2STRC( pabyBuf, n, pHeaderOne->RotationAngle );
1325 809 : BUF2STRC( pabyBuf, n, pHeaderOne->SkewAngle );
1326 809 : BUF2STRC( pabyBuf, n, pHeaderOne->DataTypeModifier );
1327 809 : BUF2STRC( pabyBuf, n, pHeaderOne->DesignFileName );
1328 809 : BUF2STRC( pabyBuf, n, pHeaderOne->DataBaseFileName );
1329 809 : BUF2STRC( pabyBuf, n, pHeaderOne->ParentGridFileName );
1330 809 : BUF2STRC( pabyBuf, n, pHeaderOne->FileDescription );
1331 809 : BUF2STRC( pabyBuf, n, pHeaderOne->Minimum );
1332 809 : BUF2STRC( pabyBuf, n, pHeaderOne->Maximum );
1333 809 : BUF2STRC( pabyBuf, n, pHeaderOne->Reserved );
1334 809 : BUF2STRC( pabyBuf, n, pHeaderOne->GridFileVersion );
1335 :
1336 : #if defined(CPL_MSB)
1337 : CPL_LSBPTR16(&pHeaderOne->WordsToFollow);
1338 : CPL_LSBPTR16(&pHeaderOne->DataTypeCode);
1339 : CPL_LSBPTR16(&pHeaderOne->ApplicationType);
1340 : CPL_LSBPTR32(&pHeaderOne->PixelsPerLine);
1341 : CPL_LSBPTR32(&pHeaderOne->NumberOfLines);
1342 : CPL_LSBPTR16(&pHeaderOne->DeviceResolution);
1343 : CPL_LSBPTR16(&pHeaderOne->DataTypeModifier);
1344 : switch (INGR_GetDataType(pHeaderOne->DataTypeCode))
1345 : {
1346 : case GDT_Byte:
1347 : pHeaderOne->Minimum.AsUint8 = *(uint8*)&(pHeaderOne->Minimum);
1348 : pHeaderOne->Maximum.AsUint8 = *(uint8*)&(pHeaderOne->Maximum);
1349 : break;
1350 : case GDT_Int16:
1351 : pHeaderOne->Minimum.AsUint16 = CPL_LSBWORD16(*(uint16*)&(pHeaderOne->Minimum));
1352 : pHeaderOne->Maximum.AsUint16 = CPL_LSBWORD16(*(uint16*)&(pHeaderOne->Maximum));
1353 : break;
1354 : case GDT_UInt16:
1355 : pHeaderOne->Minimum.AsUint16 = CPL_LSBWORD16(*(uint16*)&(pHeaderOne->Minimum));
1356 : pHeaderOne->Maximum.AsUint16 = CPL_LSBWORD16(*(uint16*)&(pHeaderOne->Maximum));
1357 : break;
1358 : case GDT_Int32:
1359 : pHeaderOne->Minimum.AsUint32 = CPL_LSBWORD32(*(uint32*)&(pHeaderOne->Minimum));
1360 : pHeaderOne->Maximum.AsUint32 = CPL_LSBWORD32(*(uint32*)&(pHeaderOne->Maximum));
1361 : break;
1362 : case GDT_UInt32:
1363 : pHeaderOne->Minimum.AsUint32 = CPL_LSBWORD32(*(uint32*)&(pHeaderOne->Minimum));
1364 : pHeaderOne->Maximum.AsUint32 = CPL_LSBWORD32(*(uint32*)&(pHeaderOne->Maximum));
1365 : break;
1366 : /* FIXME ? I'm not sure this is correct for floats */
1367 : case GDT_Float32:
1368 : pHeaderOne->Minimum.AsUint32 = CPL_LSBWORD32(*(uint32*)&(pHeaderOne->Minimum));
1369 : pHeaderOne->Maximum.AsUint32 = CPL_LSBWORD32(*(uint32*)&(pHeaderOne->Maximum));
1370 : break;
1371 : case GDT_Float64:
1372 : CPL_LSBPTR64(&pHeaderOne->Minimum.AsReal64); CPL_LSBPTR64(&pHeaderOne->Maximum.AsReal64);
1373 : break;
1374 : default: break;
1375 : }
1376 : #endif
1377 :
1378 : // --------------------------------------------------------------------
1379 : // Convert WAX REAL*8 to IEEE double
1380 : // --------------------------------------------------------------------
1381 :
1382 815 : if( pHeaderOne->GridFileVersion == 1 ||
1383 : ( pHeaderOne->GridFileVersion == 2 &&
1384 3 : ( pHeaderOne->TransformationMatrix[10] != 1.0 &&
1385 3 : pHeaderOne->TransformationMatrix[15] != 1.0 ) ) )
1386 : {
1387 5 : INGR_DGN2IEEEDouble( &pHeaderOne->XViewOrigin );
1388 5 : INGR_DGN2IEEEDouble( &pHeaderOne->YViewOrigin );
1389 5 : INGR_DGN2IEEEDouble( &pHeaderOne->ZViewOrigin );
1390 5 : INGR_DGN2IEEEDouble( &pHeaderOne->XViewExtent );
1391 5 : INGR_DGN2IEEEDouble( &pHeaderOne->YViewExtent );
1392 5 : INGR_DGN2IEEEDouble( &pHeaderOne->ZViewExtent );
1393 5 : INGR_DGN2IEEEDouble( &pHeaderOne->RotationAngle );
1394 5 : INGR_DGN2IEEEDouble( &pHeaderOne->SkewAngle );
1395 :
1396 : uint8 i;
1397 :
1398 85 : for( i = 0; i < 16; i++ )
1399 : {
1400 80 : INGR_DGN2IEEEDouble( &pHeaderOne->TransformationMatrix[i]);
1401 : }
1402 : }
1403 : else if (pHeaderOne->GridFileVersion == 3)
1404 : {
1405 : #ifdef CPL_MSB
1406 : CPL_LSBPTR64( &pHeaderOne->XViewOrigin );
1407 : CPL_LSBPTR64( &pHeaderOne->YViewOrigin );
1408 : CPL_LSBPTR64( &pHeaderOne->ZViewOrigin );
1409 : CPL_LSBPTR64( &pHeaderOne->XViewExtent );
1410 : CPL_LSBPTR64( &pHeaderOne->YViewExtent );
1411 : CPL_LSBPTR64( &pHeaderOne->ZViewExtent );
1412 : CPL_LSBPTR64( &pHeaderOne->RotationAngle );
1413 : CPL_LSBPTR64( &pHeaderOne->SkewAngle );
1414 :
1415 : uint8 i;
1416 :
1417 : for( i = 0; i < 16; i++ )
1418 : {
1419 : CPL_LSBPTR64( &pHeaderOne->TransformationMatrix[i]);
1420 : }
1421 : #endif
1422 : }
1423 809 : }
1424 :
1425 56 : void CPL_STDCALL INGR_HeaderOneMemToDisk(const INGR_HeaderOne* pHeaderOne, GByte *pabyBuf)
1426 : {
1427 56 : unsigned int n = 0;
1428 : INGR_HeaderOne* pLSBHeaderOne;
1429 : #if defined(CPL_MSB)
1430 : pLSBHeaderOne = (INGR_HeaderOne* )CPLMalloc(sizeof(INGR_HeaderOne));
1431 : memcpy(pLSBHeaderOne, pHeaderOne, sizeof(INGR_HeaderOne));
1432 :
1433 : switch (INGR_GetDataType(pLSBHeaderOne->DataTypeCode))
1434 : {
1435 : case GDT_Byte: *(uint8*)&(pLSBHeaderOne->Minimum) = pLSBHeaderOne->Minimum.AsUint8;
1436 : *(uint8*)&(pLSBHeaderOne->Maximum) = pLSBHeaderOne->Maximum.AsUint8; break;
1437 : case GDT_Int16: *(uint16*)&(pLSBHeaderOne->Minimum) = CPL_LSBWORD16(pLSBHeaderOne->Minimum.AsUint16);
1438 : *(uint16*)&(pLSBHeaderOne->Maximum) = CPL_LSBWORD16(pLSBHeaderOne->Maximum.AsUint16); break;
1439 : case GDT_UInt16: *(uint16*)&(pLSBHeaderOne->Minimum) = CPL_LSBWORD16(pLSBHeaderOne->Minimum.AsUint16);
1440 : *(uint16*)&(pLSBHeaderOne->Maximum) = CPL_LSBWORD16(pLSBHeaderOne->Maximum.AsUint16); break;
1441 : case GDT_Int32: *(uint32*)&(pLSBHeaderOne->Minimum) = CPL_LSBWORD32(pLSBHeaderOne->Minimum.AsUint32);
1442 : *(uint32*)&(pLSBHeaderOne->Maximum) = CPL_LSBWORD32(pLSBHeaderOne->Maximum.AsUint32); break;
1443 : case GDT_UInt32: *(uint32*)&(pLSBHeaderOne->Minimum) = CPL_LSBWORD32(pLSBHeaderOne->Minimum.AsUint32);
1444 : *(uint32*)&(pLSBHeaderOne->Maximum) = CPL_LSBWORD32(pLSBHeaderOne->Maximum.AsUint32); break;
1445 : /* FIXME ? I'm not sure this is correct for floats */
1446 : case GDT_Float32: *(uint32*)&(pLSBHeaderOne->Minimum) = CPL_LSBWORD32(pLSBHeaderOne->Minimum.AsUint32);
1447 : *(uint32*)&(pLSBHeaderOne->Maximum) = CPL_LSBWORD32(pLSBHeaderOne->Maximum.AsUint32); break;
1448 : case GDT_Float64: CPL_LSBPTR64(&pLSBHeaderOne->Minimum.AsReal64); CPL_LSBPTR64(&pLSBHeaderOne->Maximum.AsReal64); break;
1449 : default: break;
1450 : }
1451 :
1452 : CPL_LSBPTR16(&pLSBHeaderOne->WordsToFollow);
1453 : CPL_LSBPTR16(&pLSBHeaderOne->DataTypeCode);
1454 : CPL_LSBPTR16(&pLSBHeaderOne->ApplicationType);
1455 : CPL_LSBPTR32(&pLSBHeaderOne->PixelsPerLine);
1456 : CPL_LSBPTR32(&pLSBHeaderOne->NumberOfLines);
1457 : CPL_LSBPTR16(&pLSBHeaderOne->DeviceResolution);
1458 : CPL_LSBPTR16(&pLSBHeaderOne->DataTypeModifier);
1459 :
1460 : if (pLSBHeaderOne->GridFileVersion == 3)
1461 : {
1462 : CPL_LSBPTR64( &pLSBHeaderOne->XViewOrigin );
1463 : CPL_LSBPTR64( &pLSBHeaderOne->YViewOrigin );
1464 : CPL_LSBPTR64( &pLSBHeaderOne->ZViewOrigin );
1465 : CPL_LSBPTR64( &pLSBHeaderOne->XViewExtent );
1466 : CPL_LSBPTR64( &pLSBHeaderOne->YViewExtent );
1467 : CPL_LSBPTR64( &pLSBHeaderOne->ZViewExtent );
1468 : CPL_LSBPTR64( &pLSBHeaderOne->RotationAngle );
1469 : CPL_LSBPTR64( &pLSBHeaderOne->SkewAngle );
1470 :
1471 : uint8 i;
1472 :
1473 : for( i = 0; i < 16; i++ )
1474 : {
1475 : CPL_LSBPTR64( &pLSBHeaderOne->TransformationMatrix[i]);
1476 : }
1477 : }
1478 : #else
1479 56 : pLSBHeaderOne = (INGR_HeaderOne* )pHeaderOne;
1480 : #endif
1481 :
1482 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->HeaderType );
1483 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->WordsToFollow );
1484 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->DataTypeCode );
1485 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->ApplicationType );
1486 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->XViewOrigin );
1487 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->YViewOrigin );
1488 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->ZViewOrigin );
1489 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->XViewExtent );
1490 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->YViewExtent );
1491 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->ZViewExtent );
1492 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->TransformationMatrix );
1493 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->PixelsPerLine );
1494 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->NumberOfLines );
1495 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->DeviceResolution );
1496 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->ScanlineOrientation );
1497 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->ScannableFlag );
1498 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->RotationAngle );
1499 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->SkewAngle );
1500 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->DataTypeModifier );
1501 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->DesignFileName );
1502 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->DataBaseFileName );
1503 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->ParentGridFileName );
1504 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->FileDescription );
1505 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->Minimum );
1506 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->Maximum );
1507 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->Reserved );
1508 56 : STRC2BUF( pabyBuf, n, pLSBHeaderOne->GridFileVersion );
1509 :
1510 : #if defined(CPL_MSB)
1511 : CPLFree(pLSBHeaderOne);
1512 : #endif
1513 56 : }
1514 :
1515 77 : void CPL_STDCALL INGR_HeaderTwoADiskToMem(INGR_HeaderTwoA* pHeaderTwo, const GByte *pabyBuf)
1516 : {
1517 77 : unsigned int n = 0;
1518 :
1519 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->Gain );
1520 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->OffsetThreshold );
1521 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->View1 );
1522 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->View2 );
1523 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->ViewNumber );
1524 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->Reserved2 );
1525 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->Reserved3 );
1526 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->AspectRatio );
1527 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->CatenatedFilePointer );
1528 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->ColorTableType );
1529 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->Reserved8 );
1530 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->NumberOfCTEntries );
1531 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->ApplicationPacketPointer );
1532 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->ApplicationPacketLength );
1533 77 : BUF2STRC( pabyBuf, n, pHeaderTwo->Reserved );
1534 :
1535 : #if defined(CPL_MSB)
1536 : CPL_LSBPTR64(&pHeaderTwo->AspectRatio);
1537 : CPL_LSBPTR32(&pHeaderTwo->CatenatedFilePointer);
1538 : CPL_LSBPTR16(&pHeaderTwo->ColorTableType);
1539 : CPL_LSBPTR32(&pHeaderTwo->NumberOfCTEntries);
1540 : CPL_LSBPTR32(&pHeaderTwo->ApplicationPacketPointer);
1541 : CPL_LSBPTR32(&pHeaderTwo->ApplicationPacketLength);
1542 : #endif
1543 77 : }
1544 :
1545 56 : void CPL_STDCALL INGR_HeaderTwoAMemToDisk(const INGR_HeaderTwoA* pHeaderTwo, GByte *pabyBuf)
1546 : {
1547 56 : unsigned int n = 0;
1548 : INGR_HeaderTwoA* pLSBHeaderTwo;
1549 : #if defined(CPL_MSB)
1550 : pLSBHeaderTwo = (INGR_HeaderTwoA* )CPLMalloc(sizeof(INGR_HeaderTwoA));
1551 : memcpy(pLSBHeaderTwo, pHeaderTwo, sizeof(INGR_HeaderTwoA));
1552 :
1553 : CPL_LSBPTR64(&pLSBHeaderTwo->AspectRatio);
1554 : CPL_LSBPTR32(&pLSBHeaderTwo->CatenatedFilePointer);
1555 : CPL_LSBPTR16(&pLSBHeaderTwo->ColorTableType);
1556 : CPL_LSBPTR32(&pLSBHeaderTwo->NumberOfCTEntries);
1557 : CPL_LSBPTR32(&pLSBHeaderTwo->ApplicationPacketPointer);
1558 : CPL_LSBPTR32(&pLSBHeaderTwo->ApplicationPacketLength);
1559 : #else
1560 56 : pLSBHeaderTwo = (INGR_HeaderTwoA* )pHeaderTwo;
1561 : #endif
1562 :
1563 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->Gain );
1564 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->OffsetThreshold );
1565 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->View1 );
1566 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->View2 );
1567 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->ViewNumber );
1568 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->Reserved2 );
1569 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->Reserved3 );
1570 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->AspectRatio );
1571 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->CatenatedFilePointer );
1572 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->ColorTableType );
1573 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->Reserved8 );
1574 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->NumberOfCTEntries );
1575 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->ApplicationPacketPointer );
1576 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->ApplicationPacketLength );
1577 56 : STRC2BUF( pabyBuf, n, pLSBHeaderTwo->Reserved );
1578 :
1579 : #if defined(CPL_MSB)
1580 : CPLFree(pLSBHeaderTwo);
1581 : #endif
1582 56 : }
1583 :
1584 8 : void CPL_STDCALL INGR_TileHeaderDiskToMem(INGR_TileHeader* pTileHeader, const GByte *pabyBuf)
1585 : {
1586 8 : unsigned int n = 0;
1587 :
1588 8 : BUF2STRC( pabyBuf, n, pTileHeader->ApplicationType );
1589 8 : BUF2STRC( pabyBuf, n, pTileHeader->SubTypeCode );
1590 8 : BUF2STRC( pabyBuf, n, pTileHeader->WordsToFollow );
1591 8 : BUF2STRC( pabyBuf, n, pTileHeader->PacketVersion );
1592 8 : BUF2STRC( pabyBuf, n, pTileHeader->Identifier );
1593 8 : BUF2STRC( pabyBuf, n, pTileHeader->Reserved );
1594 8 : BUF2STRC( pabyBuf, n, pTileHeader->Properties );
1595 8 : BUF2STRC( pabyBuf, n, pTileHeader->DataTypeCode );
1596 8 : BUF2STRC( pabyBuf, n, pTileHeader->Reserved2 );
1597 8 : BUF2STRC( pabyBuf, n, pTileHeader->TileSize );
1598 8 : BUF2STRC( pabyBuf, n, pTileHeader->Reserved3 );
1599 8 : BUF2STRC( pabyBuf, n, pTileHeader->First.Start );
1600 8 : BUF2STRC( pabyBuf, n, pTileHeader->First.Allocated );
1601 8 : BUF2STRC( pabyBuf, n, pTileHeader->First.Used );
1602 :
1603 : #if defined(CPL_MSB)
1604 : CPL_LSBPTR16(&pTileHeader->ApplicationType);
1605 : CPL_LSBPTR16(&pTileHeader->SubTypeCode);
1606 : CPL_LSBPTR32(&pTileHeader->WordsToFollow);
1607 : CPL_LSBPTR16(&pTileHeader->PacketVersion);
1608 : CPL_LSBPTR16(&pTileHeader->Identifier);
1609 : CPL_LSBPTR16(&pTileHeader->Properties);
1610 : CPL_LSBPTR16(&pTileHeader->DataTypeCode);
1611 : CPL_LSBPTR32(&pTileHeader->TileSize);
1612 : CPL_LSBPTR32(&pTileHeader->First.Start);
1613 : CPL_LSBPTR32(&pTileHeader->First.Allocated);
1614 : CPL_LSBPTR32(&pTileHeader->First.Used);
1615 : #endif
1616 8 : }
1617 :
1618 15 : void CPL_STDCALL INGR_TileItemDiskToMem(INGR_TileItem* pTileItem, const GByte *pabyBuf)
1619 : {
1620 15 : unsigned int n = 0;
1621 :
1622 15 : BUF2STRC( pabyBuf, n, pTileItem->Start );
1623 15 : BUF2STRC( pabyBuf, n, pTileItem->Allocated );
1624 15 : BUF2STRC( pabyBuf, n, pTileItem->Used );
1625 :
1626 : #if defined(CPL_MSB)
1627 : CPL_LSBPTR32(&pTileItem->Start);
1628 : CPL_LSBPTR32(&pTileItem->Allocated);
1629 : CPL_LSBPTR32(&pTileItem->Used);
1630 : #endif
1631 15 : }
1632 :
1633 4 : void CPL_STDCALL INGR_JPEGAppDataDiskToMem(INGR_JPEGAppData* pJPEGAppData, const GByte *pabyBuf)
1634 : {
1635 4 : unsigned int n = 0;
1636 :
1637 4 : BUF2STRC( pabyBuf, n, pJPEGAppData->ApplicationType );
1638 4 : BUF2STRC( pabyBuf, n, pJPEGAppData->SubTypeCode );
1639 4 : BUF2STRC( pabyBuf, n, pJPEGAppData->RemainingLength );
1640 4 : BUF2STRC( pabyBuf, n, pJPEGAppData->PacketVersion );
1641 4 : BUF2STRC( pabyBuf, n, pJPEGAppData->JpegQuality );
1642 :
1643 : #if defined(CPL_MSB)
1644 : CPL_LSBPTR16(&pJPEGAppData->ApplicationType);
1645 : CPL_LSBPTR16(&pJPEGAppData->SubTypeCode);
1646 : CPL_LSBPTR32(&pJPEGAppData->RemainingLength);
1647 : CPL_LSBPTR16(&pJPEGAppData->PacketVersion);
1648 : CPL_LSBPTR16(&pJPEGAppData->JpegQuality);
1649 : #endif
1650 4 : }
1651 :
1652 :
1653 : // ------------------------------------------------------------------
1654 : // Pasted from the DNG OGR Driver to avoid dependency on OGR
1655 : // ------------------------------------------------------------------
1656 :
1657 : typedef struct dbl {
1658 : GUInt32 hi;
1659 : GUInt32 lo;
1660 : } double64_t;
1661 :
1662 : /************************************************************************/
1663 : /* INGR_DGN2IEEEDouble() */
1664 : /************************************************************************/
1665 :
1666 120 : void INGR_DGN2IEEEDouble(void * dbl)
1667 :
1668 : {
1669 : double64_t dt;
1670 : GUInt32 sign;
1671 : GUInt32 exponent;
1672 : GUInt32 rndbits;
1673 : unsigned char *src;
1674 : unsigned char *dest;
1675 :
1676 : /* -------------------------------------------------------------------- */
1677 : /* Arrange the VAX double so that it may be accessed by a */
1678 : /* double64_t structure, (two GUInt32s). */
1679 : /* -------------------------------------------------------------------- */
1680 120 : src = (unsigned char *) dbl;
1681 120 : dest = (unsigned char *) &dt;
1682 : #ifdef CPL_LSB
1683 120 : dest[2] = src[0];
1684 120 : dest[3] = src[1];
1685 120 : dest[0] = src[2];
1686 120 : dest[1] = src[3];
1687 120 : dest[6] = src[4];
1688 120 : dest[7] = src[5];
1689 120 : dest[4] = src[6];
1690 120 : dest[5] = src[7];
1691 : #else
1692 : dest[1] = src[0];
1693 : dest[0] = src[1];
1694 : dest[3] = src[2];
1695 : dest[2] = src[3];
1696 : dest[5] = src[4];
1697 : dest[4] = src[5];
1698 : dest[7] = src[6];
1699 : dest[6] = src[7];
1700 : #endif
1701 :
1702 : /* -------------------------------------------------------------------- */
1703 : /* Save the sign of the double */
1704 : /* -------------------------------------------------------------------- */
1705 120 : sign = dt.hi & 0x80000000;
1706 :
1707 : /* -------------------------------------------------------------------- */
1708 : /* Adjust the exponent so that we may work with it */
1709 : /* -------------------------------------------------------------------- */
1710 120 : exponent = dt.hi >> 23;
1711 120 : exponent = exponent & 0x000000ff;
1712 :
1713 120 : if (exponent)
1714 71 : exponent = exponent -129 + 1023;
1715 :
1716 : /* -------------------------------------------------------------------- */
1717 : /* Save the bits that we are discarding so we can round properly */
1718 : /* -------------------------------------------------------------------- */
1719 120 : rndbits = dt.lo & 0x00000007;
1720 :
1721 120 : dt.lo = dt.lo >> 3;
1722 120 : dt.lo = (dt.lo & 0x1fffffff) | (dt.hi << 29);
1723 :
1724 120 : if (rndbits)
1725 60 : dt.lo = dt.lo | 0x00000001;
1726 :
1727 : /* -------------------------------------------------------------------- */
1728 : /* Shift the hi-order int over 3 and insert the exponent and sign */
1729 : /* -------------------------------------------------------------------- */
1730 120 : dt.hi = dt.hi >> 3;
1731 120 : dt.hi = dt.hi & 0x000fffff;
1732 120 : dt.hi = dt.hi | (exponent << 20) | sign;
1733 :
1734 :
1735 :
1736 : #ifdef CPL_LSB
1737 : /* -------------------------------------------------------------------- */
1738 : /* Change the number to a byte swapped format */
1739 : /* -------------------------------------------------------------------- */
1740 120 : src = (unsigned char *) &dt;
1741 120 : dest = (unsigned char *) dbl;
1742 :
1743 120 : dest[0] = src[4];
1744 120 : dest[1] = src[5];
1745 120 : dest[2] = src[6];
1746 120 : dest[3] = src[7];
1747 120 : dest[4] = src[0];
1748 120 : dest[5] = src[1];
1749 120 : dest[6] = src[2];
1750 120 : dest[7] = src[3];
1751 : #else
1752 : memcpy( dbl, &dt, 8 );
1753 : #endif
1754 120 : }
|