1 : /*****************************************************************************
2 : * $Id: IntergraphBand.cpp 25785 2013-03-23 11:34:53Z rouault $
3 : *
4 : * Project: Intergraph Raster Format support
5 : * Purpose: Read/Write Intergraph Raster Format, band support
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 "gdal_priv.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 : #include "cpl_csv.h"
34 : #include "ogr_spatialref.h"
35 : #include "gdal_pam.h"
36 : #include "gdal_alg.h"
37 : #include "math.h"
38 :
39 : #include "IntergraphDataset.h"
40 : #include "IntergraphBand.h"
41 : #include "IngrTypes.h"
42 :
43 : // ----------------------------------------------------------------------------
44 : // IntergraphRasterBand::IntergraphRasterBand()
45 : // ----------------------------------------------------------------------------
46 :
47 114 : IntergraphRasterBand::IntergraphRasterBand( IntergraphDataset *poDS,
48 : int nBand,
49 : int nBandOffset,
50 114 : GDALDataType eType )
51 : {
52 114 : this->poColorTable = new GDALColorTable();
53 :
54 114 : this->poDS = poDS;
55 114 : this->nBand = nBand != 0 ? nBand : poDS->nBands;
56 114 : this->nTiles = 0;
57 114 : this->eDataType = eType;
58 114 : this->pabyBlockBuf = NULL;
59 114 : this->pahTiles = NULL;
60 114 : this->nRGBIndex = 0;
61 114 : this->nBandStart = nBandOffset;
62 114 : this->bTiled = FALSE;
63 :
64 : // --------------------------------------------------------------------
65 : // Get Header Info
66 : // --------------------------------------------------------------------
67 :
68 114 : memcpy(&hHeaderOne, &poDS->hHeaderOne, sizeof(hHeaderOne));
69 114 : memcpy(&hHeaderTwo, &poDS->hHeaderTwo, sizeof(hHeaderTwo));
70 :
71 : // --------------------------------------------------------------------
72 : // Get the image start from Words to Follow (WTF)
73 : // --------------------------------------------------------------------
74 :
75 114 : nDataOffset = nBandOffset + 2 + ( 2 * ( hHeaderOne.WordsToFollow + 1 ) );
76 :
77 : // --------------------------------------------------------------------
78 : // Get Color Tabel from Color Table Type (CTV)
79 : // --------------------------------------------------------------------
80 :
81 114 : uint32 nEntries = hHeaderTwo.NumberOfCTEntries;
82 :
83 114 : if( nEntries > 0 )
84 : {
85 8 : switch ( hHeaderTwo.ColorTableType )
86 : {
87 : case EnvironVColorTable:
88 6 : INGR_GetEnvironVColors( poDS->fp, nBandOffset, nEntries, poColorTable );
89 6 : if (poColorTable->GetColorEntryCount() == 0)
90 0 : return;
91 6 : break;
92 : case IGDSColorTable:
93 2 : INGR_GetIGDSColors( poDS->fp, nBandOffset, nEntries, poColorTable );
94 2 : if (poColorTable->GetColorEntryCount() == 0)
95 0 : return;
96 2 : break;
97 : default:
98 : CPLDebug( "INGR", "Wrong Color table type (%d), number of colors (%d)",
99 0 : hHeaderTwo.ColorTableType, nEntries );
100 : }
101 : }
102 :
103 : // --------------------------------------------------------------------
104 : // Set Dimension
105 : // --------------------------------------------------------------------
106 :
107 114 : nRasterXSize = hHeaderOne.PixelsPerLine;
108 114 : nRasterYSize = hHeaderOne.NumberOfLines;
109 :
110 114 : nBlockXSize = nRasterXSize;
111 114 : nBlockYSize = 1;
112 :
113 : // --------------------------------------------------------------------
114 : // Get tile directory
115 : // --------------------------------------------------------------------
116 :
117 114 : this->eFormat = (INGR_Format) hHeaderOne.DataTypeCode;
118 :
119 114 : this->bTiled = (hHeaderOne.DataTypeCode == TiledRasterData);
120 :
121 114 : if( bTiled )
122 : {
123 : nTiles = INGR_GetTileDirectory( poDS->fp,
124 : nDataOffset,
125 : nRasterXSize,
126 : nRasterYSize,
127 : &hTileDir,
128 5 : &pahTiles );
129 5 : if (nTiles == 0)
130 0 : return;
131 :
132 5 : eFormat = (INGR_Format) hTileDir.DataTypeCode;
133 :
134 : // ----------------------------------------------------------------
135 : // Set blocks dimensions based on tiles
136 : // ----------------------------------------------------------------
137 5 : nBlockXSize = hTileDir.TileSize;
138 5 : nBlockYSize = hTileDir.TileSize;
139 : }
140 :
141 114 : if (nBlockXSize <= 0 || nBlockYSize <= 0)
142 : {
143 0 : pabyBlockBuf = NULL;
144 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid block dimensions");
145 0 : return;
146 : }
147 :
148 : // --------------------------------------------------------------------
149 : // Incomplete tiles have Block Offset greater than:
150 : // --------------------------------------------------------------------
151 :
152 114 : nFullBlocksX = ( nRasterXSize / nBlockXSize );
153 114 : nFullBlocksY = ( nRasterYSize / nBlockYSize );
154 :
155 : // --------------------------------------------------------------------
156 : // Get the Data Type from Format
157 : // --------------------------------------------------------------------
158 :
159 114 : this->eDataType = INGR_GetDataType( (uint16) eFormat );
160 :
161 : // --------------------------------------------------------------------
162 : // Allocate buffer for a Block of data
163 : // --------------------------------------------------------------------
164 :
165 : nBlockBufSize = nBlockXSize * nBlockYSize *
166 114 : GDALGetDataTypeSize( eDataType ) / 8;
167 :
168 114 : if (eFormat == RunLengthEncoded)
169 : {
170 : pabyBlockBuf = (GByte*) VSIMalloc3( nBlockXSize*4+2, nBlockYSize,
171 7 : GDALGetDataTypeSize( eDataType ) / 8);
172 : }
173 : else
174 : {
175 : pabyBlockBuf = (GByte*) VSIMalloc3( nBlockXSize, nBlockYSize,
176 107 : GDALGetDataTypeSize( eDataType ) / 8);
177 : }
178 :
179 114 : if (pabyBlockBuf == NULL)
180 : {
181 0 : CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nBlockBufSize);
182 0 : return;
183 : }
184 :
185 : // --------------------------------------------------------------------
186 : // More Metadata Information
187 : // --------------------------------------------------------------------
188 :
189 : SetMetadataItem( "FORMAT", INGR_GetFormatName( (uint16) eFormat ),
190 114 : "IMAGE_STRUCTURE" );
191 :
192 114 : if( bTiled )
193 : {
194 : SetMetadataItem( "TILESSIZE", CPLSPrintf ("%d", hTileDir.TileSize),
195 5 : "IMAGE_STRUCTURE" );
196 : }
197 : else
198 : {
199 109 : SetMetadataItem( "TILED", "NO", "IMAGE_STRUCTURE" );
200 : }
201 :
202 : SetMetadataItem( "ORIENTATION",
203 : INGR_GetOrientation( hHeaderOne.ScanlineOrientation ),
204 114 : "IMAGE_STRUCTURE" );
205 :
206 114 : if( eFormat == PackedBinary ||
207 : eFormat == RunLengthEncoded ||
208 : eFormat == CCITTGroup4 )
209 : {
210 8 : SetMetadataItem( "NBITS", "1", "IMAGE_STRUCTURE" );
211 : }
212 :
213 114 : this->nRLEOffset = 0;
214 0 : }
215 :
216 : // ----------------------------------------------------------------------------
217 : // IntergraphRasterBand::~IntergraphRasterBand()
218 : // ----------------------------------------------------------------------------
219 :
220 114 : IntergraphRasterBand::~IntergraphRasterBand()
221 : {
222 114 : if( pabyBlockBuf )
223 : {
224 114 : CPLFree( pabyBlockBuf );
225 : }
226 :
227 114 : if( pahTiles )
228 : {
229 5 : CPLFree( pahTiles );
230 : }
231 :
232 114 : if( poColorTable )
233 : {
234 114 : delete poColorTable;
235 : }
236 114 : }
237 :
238 : // ----------------------------------------------------------------------------
239 : // IntergraphRasterBand::GetMinimum()
240 : // ----------------------------------------------------------------------------
241 :
242 0 : double IntergraphRasterBand::GetMinimum( int *pbSuccess )
243 : {
244 :
245 0 : double dMinimum = INGR_GetMinMax( eDataType, hHeaderOne.Minimum );
246 0 : double dMaximum = INGR_GetMinMax( eDataType, hHeaderOne.Maximum );
247 :
248 0 : if( pbSuccess )
249 : {
250 0 : *pbSuccess = dMinimum == dMaximum ? FALSE : TRUE;
251 : }
252 :
253 0 : return dMinimum;
254 : }
255 :
256 : // ----------------------------------------------------------------------------
257 : // IntergraphRasterBand::GetMaximum()
258 : // ----------------------------------------------------------------------------
259 :
260 0 : double IntergraphRasterBand::GetMaximum( int *pbSuccess )
261 : {
262 0 : double dMinimum = INGR_GetMinMax( eDataType, hHeaderOne.Minimum );
263 0 : double dMaximum = INGR_GetMinMax( eDataType, hHeaderOne.Maximum );
264 :
265 0 : if( pbSuccess )
266 : {
267 0 : *pbSuccess = dMinimum == dMaximum ? FALSE : TRUE;
268 : }
269 :
270 0 : return dMaximum;
271 : }
272 :
273 : // ----------------------------------------------------------------------------
274 : // IntergraphRasterBand::GetColorInterpretation()
275 : // ----------------------------------------------------------------------------
276 :
277 0 : GDALColorInterp IntergraphRasterBand::GetColorInterpretation()
278 : {
279 0 : if( eFormat == AdaptiveRGB ||
280 : eFormat == Uncompressed24bit ||
281 : eFormat == ContinuousTone )
282 : {
283 0 : switch( nRGBIndex )
284 : {
285 : case 1:
286 0 : return GCI_RedBand;
287 : case 2:
288 0 : return GCI_GreenBand;
289 : case 3:
290 0 : return GCI_BlueBand;
291 : }
292 0 : return GCI_GrayIndex;
293 : }
294 : else
295 : {
296 0 : if( poColorTable->GetColorEntryCount() > 0 )
297 : {
298 0 : return GCI_PaletteIndex;
299 : }
300 : else
301 : {
302 0 : return GCI_GrayIndex;
303 : }
304 : }
305 :
306 : }
307 :
308 : // ----------------------------------------------------------------------------
309 : // IntergraphRasterBand::GetColorTable()
310 : // ----------------------------------------------------------------------------
311 :
312 3 : GDALColorTable *IntergraphRasterBand::GetColorTable()
313 : {
314 3 : if( poColorTable->GetColorEntryCount() == 0 )
315 : {
316 1 : return NULL;
317 : }
318 : else
319 : {
320 2 : return poColorTable;
321 : }
322 : }
323 :
324 : // ----------------------------------------------------------------------------
325 : // IntergraphRasterBand::SetColorTable()
326 : // ----------------------------------------------------------------------------
327 :
328 20 : CPLErr IntergraphRasterBand::SetColorTable( GDALColorTable *poColorTable )
329 : {
330 20 : if( poColorTable == NULL )
331 : {
332 19 : return CE_None;
333 : }
334 :
335 1 : delete this->poColorTable;
336 1 : this->poColorTable = poColorTable->Clone();
337 :
338 1 : return CE_None;
339 : }
340 :
341 : // ----------------------------------------------------------------------------
342 : // IntergraphRasterBand::SetStatistics()
343 : // ----------------------------------------------------------------------------
344 :
345 21 : CPLErr IntergraphRasterBand::SetStatistics( double dfMin,
346 : double dfMax,
347 : double dfMean,
348 : double dfStdDev )
349 : {
350 21 : hHeaderOne.Minimum = INGR_SetMinMax( eDataType, dfMin );
351 21 : hHeaderOne.Maximum = INGR_SetMinMax( eDataType, dfMax );
352 :
353 21 : return GDALRasterBand::SetStatistics( dfMin, dfMax, dfMean, dfStdDev );
354 : }
355 :
356 : // ----------------------------------------------------------------------------
357 : // IntergraphRasterBand::IReadBlock()
358 : // ----------------------------------------------------------------------------
359 :
360 1360 : CPLErr IntergraphRasterBand::IReadBlock( int nBlockXOff,
361 : int nBlockYOff,
362 : void *pImage )
363 : {
364 : // --------------------------------------------------------------------
365 : // Load Block Buffer
366 : // --------------------------------------------------------------------
367 1360 : if (HandleUninstantiatedTile( nBlockXOff, nBlockYOff, pImage ))
368 0 : return CE_None;
369 :
370 1360 : uint32 nBytesRead = LoadBlockBuf( nBlockXOff, nBlockYOff, nBlockBufSize, pabyBlockBuf );
371 :
372 1360 : if( nBytesRead == 0 )
373 : {
374 : memset( pImage, 0, nBlockXSize * nBlockYSize *
375 0 : GDALGetDataTypeSize( eDataType ) / 8 );
376 : CPLError( CE_Failure, CPLE_FileIO,
377 : "Can't read (%s) tile with X offset %d and Y offset %d.\n",
378 0 : ((IntergraphDataset*)poDS)->pszFilename, nBlockXOff, nBlockYOff );
379 0 : return CE_Failure;
380 : }
381 :
382 : // --------------------------------------------------------------------
383 : // Reshape blocks if needed
384 : // --------------------------------------------------------------------
385 :
386 1360 : if( nBlockXOff == nFullBlocksX ||
387 : nBlockYOff == nFullBlocksY )
388 : {
389 0 : ReshapeBlock( nBlockXOff, nBlockYOff, nBlockBufSize, pabyBlockBuf );
390 : }
391 :
392 : // --------------------------------------------------------------------
393 : // Copy block buffer to image
394 : // --------------------------------------------------------------------
395 :
396 : memcpy( pImage, pabyBlockBuf, nBlockXSize * nBlockYSize *
397 1360 : GDALGetDataTypeSize( eDataType ) / 8 );
398 :
399 : #ifdef CPL_MSB
400 : if( eDataType == GDT_Int16 || eDataType == GDT_UInt16)
401 : GDALSwapWords( pImage, 2, nBlockXSize * nBlockYSize, 2 );
402 : else if( eDataType == GDT_Int32 || eDataType == GDT_UInt32 || eDataType == GDT_Float32 )
403 : GDALSwapWords( pImage, 4, nBlockXSize * nBlockYSize, 4 );
404 : else if (eDataType == GDT_Float64 )
405 : GDALSwapWords( pImage, 8, nBlockXSize * nBlockYSize, 8 );
406 : #endif
407 :
408 1360 : return CE_None;
409 : }
410 :
411 : // ----------------------------------------------------------------------------
412 : // IntergraphRasterBand::HandleUninstantiatedTile()
413 : // ----------------------------------------------------------------------------
414 :
415 1379 : int IntergraphRasterBand::HandleUninstantiatedTile(int nBlockXOff,
416 : int nBlockYOff,
417 : void* pImage)
418 : {
419 1379 : if( bTiled && pahTiles[nBlockXOff + nBlockYOff * nBlocksPerRow].Start == 0 )
420 : {
421 : // ------------------------------------------------------------
422 : // Uninstantieted tile, unique value
423 : // ------------------------------------------------------------
424 0 : int nColor = pahTiles[nBlockXOff + nBlockYOff * nBlocksPerRow].Used;
425 0 : switch( GetColorInterpretation() )
426 : {
427 : case GCI_RedBand:
428 0 : nColor >>= 16; break;
429 : case GCI_GreenBand:
430 0 : nColor >>= 8; break;
431 : default:
432 : break;
433 : }
434 : memset( pImage, nColor, nBlockXSize * nBlockYSize *
435 0 : GDALGetDataTypeSize( eDataType ) / 8 );
436 0 : return TRUE;
437 : }
438 : else
439 1379 : return FALSE;
440 : }
441 :
442 : // ----------------------------------------------------------------------------
443 : // IntergraphRGBBand::IntergraphRGBBand()
444 : // ----------------------------------------------------------------------------
445 :
446 18 : IntergraphRGBBand::IntergraphRGBBand( IntergraphDataset *poDS,
447 : int nBand,
448 : int nBandOffset,
449 : int nRGorB )
450 18 : : IntergraphRasterBand( poDS, nBand, nBandOffset )
451 : {
452 18 : if (pabyBlockBuf == NULL)
453 0 : return;
454 :
455 18 : nRGBIndex = (uint8) nRGorB;
456 :
457 : // --------------------------------------------------------------------
458 : // Reallocate buffer for a block of RGB Data
459 : // --------------------------------------------------------------------
460 :
461 18 : nBlockBufSize *= 3;
462 18 : CPLFree( pabyBlockBuf );
463 18 : pabyBlockBuf = (GByte*) VSIMalloc( nBlockBufSize );
464 18 : if (pabyBlockBuf == NULL)
465 : {
466 0 : CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nBlockBufSize);
467 : }
468 0 : }
469 :
470 : // ----------------------------------------------------------------------------
471 : // IntergraphRGBBand::IReadBlock()
472 : // ----------------------------------------------------------------------------
473 :
474 120 : CPLErr IntergraphRGBBand::IReadBlock( int nBlockXOff,
475 : int nBlockYOff,
476 : void *pImage )
477 : {
478 120 : if( IntergraphRasterBand::IReadBlock( nBlockXOff,
479 : nBlockYOff,
480 : pImage ) != CE_None )
481 : {
482 0 : return CE_Failure;
483 : }
484 :
485 : // --------------------------------------------------------------------
486 : // Extract the band of interest from the block buffer
487 : // --------------------------------------------------------------------
488 :
489 : int i, j;
490 :
491 15520 : for ( i = 0, j = ( nRGBIndex - 1 );
492 : i < ( nBlockXSize * nBlockYSize );
493 : i++, j += 3 )
494 : {
495 15400 : ( (GByte*) pImage )[i] = pabyBlockBuf[j];
496 : }
497 :
498 120 : return CE_None;
499 : }
500 :
501 : // ----------------------------------------------------------------------------
502 : // IntergraphRLEBand::IntergraphRLEBand()
503 : // ----------------------------------------------------------------------------
504 :
505 11 : IntergraphRLEBand::IntergraphRLEBand( IntergraphDataset *poDS,
506 : int nBand,
507 : int nBandOffset,
508 : int nRGorB )
509 11 : : IntergraphRasterBand( poDS, nBand, nBandOffset )
510 : {
511 11 : nRLESize = 0;
512 11 : nRGBIndex = (uint8) nRGorB;
513 11 : bRLEBlockLoaded = FALSE;
514 11 : pabyRLEBlock = NULL;
515 11 : panRLELineOffset = NULL;
516 :
517 11 : if (pabyBlockBuf == NULL)
518 0 : return;
519 :
520 11 : if( ! this->bTiled )
521 : {
522 : // ------------------------------------------------------------
523 : // Load all rows at once
524 : // ------------------------------------------------------------
525 :
526 10 : nFullBlocksX = 1;
527 :
528 16 : if( eFormat == RunLengthEncodedC || eFormat == RunLengthEncoded )
529 : {
530 6 : nBlockYSize = 1;
531 : panRLELineOffset = (uint32 *)
532 6 : CPLCalloc(sizeof(uint32),nRasterYSize);
533 6 : nFullBlocksY = nRasterYSize;
534 : }
535 : else
536 : {
537 4 : nBlockYSize = nRasterYSize;
538 4 : nFullBlocksY = 1;
539 : }
540 :
541 : nRLESize = INGR_GetDataBlockSize( poDS->pszFilename,
542 : hHeaderTwo.CatenatedFilePointer,
543 10 : nDataOffset);
544 :
545 10 : nBlockBufSize = nBlockXSize * nBlockYSize;
546 : }
547 : else
548 : {
549 : // ------------------------------------------------------------
550 : // Find the biggest tile
551 : // ------------------------------------------------------------
552 :
553 : uint32 iTiles;
554 5 : for( iTiles = 0; iTiles < nTiles; iTiles++)
555 : {
556 4 : nRLESize = MAX( pahTiles[iTiles].Used, nRLESize );
557 : }
558 : }
559 :
560 : // ----------------------------------------------------------------
561 : // Realocate the decompressed Buffer
562 : // ----------------------------------------------------------------
563 :
564 11 : if( eFormat == AdaptiveRGB ||
565 : eFormat == ContinuousTone )
566 : {
567 3 : nBlockBufSize *= 3;
568 : }
569 :
570 11 : CPLFree( pabyBlockBuf );
571 11 : pabyBlockBuf = (GByte*) VSIMalloc( nBlockBufSize );
572 11 : if (pabyBlockBuf == NULL)
573 : {
574 0 : CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nBlockBufSize);
575 : }
576 :
577 : // ----------------------------------------------------------------
578 : // Create a RLE buffer
579 : // ----------------------------------------------------------------
580 :
581 11 : pabyRLEBlock = (GByte*) VSIMalloc( nRLESize );
582 11 : if (pabyRLEBlock == NULL)
583 : {
584 0 : CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nRLESize);
585 : }
586 :
587 : // ----------------------------------------------------------------
588 : // Set a black and white Color Table
589 : // ----------------------------------------------------------------
590 :
591 11 : if( eFormat == RunLengthEncoded )
592 : {
593 6 : BlackWhiteCT( true );
594 : }
595 :
596 0 : }
597 :
598 : // ----------------------------------------------------------------------------
599 : // IntergraphRLEBand::IntergraphRLEBand()
600 : // ----------------------------------------------------------------------------
601 :
602 11 : IntergraphRLEBand::~IntergraphRLEBand()
603 : {
604 11 : CPLFree( pabyRLEBlock );
605 11 : CPLFree( panRLELineOffset );
606 11 : }
607 :
608 : // ----------------------------------------------------------------------------
609 : // IntergraphRLEBand::IReadBlock()
610 : // ----------------------------------------------------------------------------
611 :
612 511 : CPLErr IntergraphRLEBand::IReadBlock( int nBlockXOff,
613 : int nBlockYOff,
614 : void *pImage )
615 : {
616 : // --------------------------------------------------------------------
617 : // Load Block Buffer
618 : // --------------------------------------------------------------------
619 :
620 : uint32 nBytesRead;
621 :
622 521 : if( bTiled || !bRLEBlockLoaded )
623 : {
624 10 : if (HandleUninstantiatedTile( nBlockXOff, nBlockYOff, pImage ))
625 0 : return CE_None;
626 :
627 10 : if (!bTiled)
628 : {
629 : // With RLE, we want to load all of the data.
630 : // So load (0,0) since that's the only offset that will load everything.
631 6 : nBytesRead = LoadBlockBuf( 0, 0, nRLESize, pabyRLEBlock );
632 : }
633 : else
634 : {
635 4 : nBytesRead = LoadBlockBuf( nBlockXOff, nBlockYOff, nRLESize, pabyRLEBlock );
636 : }
637 10 : bRLEBlockLoaded = TRUE;
638 : }
639 : else
640 501 : nBytesRead = nRLESize;
641 :
642 511 : if( nBytesRead == 0 )
643 : {
644 : memset( pImage, 0, nBlockXSize * nBlockYSize *
645 0 : GDALGetDataTypeSize( eDataType ) / 8 );
646 : CPLError( CE_Failure, CPLE_FileIO,
647 : "Can't read (%s) tile with X offset %d and Y offset %d.\n%s",
648 : ((IntergraphDataset*)poDS)->pszFilename, nBlockXOff, nBlockYOff,
649 0 : VSIStrerror( errno ) );
650 0 : return CE_Failure;
651 : }
652 :
653 : // ----------------------------------------------------------------
654 : // Calculate the resulting image dimmention
655 : // ----------------------------------------------------------------
656 :
657 511 : int nVirtualXSize = nBlockXSize;
658 511 : int nVirtualYSize = nBlockYSize;
659 :
660 511 : if( nBlockXOff == nFullBlocksX )
661 : {
662 2 : nVirtualXSize = nRasterXSize % nBlockXSize;
663 : }
664 :
665 511 : if( nBlockYOff == nFullBlocksY )
666 : {
667 2 : nVirtualYSize = nRasterYSize % nBlockYSize;
668 : }
669 :
670 : // --------------------------------------------------------------------
671 : // Decode Run Length
672 : // --------------------------------------------------------------------
673 :
674 515 : if( bTiled && eFormat == RunLengthEncoded )
675 : {
676 : nBytesRead =
677 : INGR_DecodeRunLengthBitonalTiled( pabyRLEBlock, pabyBlockBuf,
678 4 : nRLESize, nBlockBufSize, NULL );
679 : }
680 :
681 509 : else if( bTiled || panRLELineOffset == NULL )
682 : {
683 : nBytesRead = INGR_Decode( eFormat, pabyRLEBlock, pabyBlockBuf,
684 : nRLESize, nBlockBufSize,
685 2 : NULL );
686 : }
687 :
688 : else
689 : {
690 : uint32 nBytesConsumed;
691 :
692 : // If we are missing the offset to this line, process all
693 : // preceding lines that are not initialized.
694 505 : if( nBlockYOff > 0 && panRLELineOffset[nBlockYOff] == 0 )
695 : {
696 0 : int iLine = nBlockYOff - 1;
697 : // Find the last line that is initialized (or line 0).
698 0 : while ((iLine != 0) && (panRLELineOffset[iLine] == 0))
699 0 : iLine--;
700 0 : for( ; iLine < nBlockYOff; iLine++ )
701 : {
702 : // Pass NULL as destination so that no decompression
703 : // actually takes place.
704 : INGR_Decode( eFormat,
705 0 : pabyRLEBlock + panRLELineOffset[iLine],
706 0 : NULL, nRLESize - panRLELineOffset[iLine], nBlockBufSize,
707 0 : &nBytesConsumed );
708 :
709 0 : if( iLine < nRasterYSize-1 )
710 0 : panRLELineOffset[iLine+1] =
711 0 : panRLELineOffset[iLine] + nBytesConsumed;
712 : }
713 : }
714 :
715 : // Read the requested line.
716 : nBytesRead =
717 : INGR_Decode( eFormat,
718 505 : pabyRLEBlock + panRLELineOffset[nBlockYOff],
719 505 : pabyBlockBuf, nRLESize - panRLELineOffset[nBlockYOff], nBlockBufSize,
720 1515 : &nBytesConsumed );
721 :
722 505 : if( nBlockYOff < nRasterYSize-1 )
723 501 : panRLELineOffset[nBlockYOff+1] =
724 501 : panRLELineOffset[nBlockYOff] + nBytesConsumed;
725 : }
726 :
727 : // --------------------------------------------------------------------
728 : // Reshape blocks if needed
729 : // --------------------------------------------------------------------
730 :
731 511 : if( nBlockXOff == nFullBlocksX ||
732 : nBlockYOff == nFullBlocksY )
733 : {
734 3 : ReshapeBlock( nBlockXOff, nBlockYOff, nBlockBufSize, pabyBlockBuf );
735 : }
736 :
737 : // --------------------------------------------------------------------
738 : // Extract the band of interest from the block buffer (BIL)
739 : // --------------------------------------------------------------------
740 :
741 512 : if( eFormat == AdaptiveRGB ||
742 : eFormat == ContinuousTone )
743 : {
744 : int i, j;
745 1 : GByte *pabyImage = (GByte*) pImage;
746 1 : j = ( nRGBIndex - 1 ) * nVirtualXSize;
747 101 : for ( i = 0; i < nVirtualYSize; i++ )
748 : {
749 100 : memcpy( &pabyImage[i * nBlockXSize], &pabyBlockBuf[j], nBlockXSize );
750 100 : j += ( 3 * nBlockXSize );
751 : }
752 : }
753 : else
754 : {
755 510 : memcpy( pImage, pabyBlockBuf, nBlockBufSize );
756 : }
757 :
758 511 : return CE_None;
759 : }
760 :
761 : // ----------------------------------------------------------------------------
762 : // IntergraphBitmapBand::IntergraphBitmapBand()
763 : // ----------------------------------------------------------------------------
764 :
765 5 : IntergraphBitmapBand::IntergraphBitmapBand( IntergraphDataset *poDS,
766 : int nBand,
767 : int nBandOffset,
768 : int nRGorB )
769 5 : : IntergraphRasterBand( poDS, nBand, nBandOffset, GDT_Byte )
770 : {
771 5 : nBMPSize = 0;
772 5 : nRGBBand = nRGorB;
773 5 : pabyBMPBlock = NULL;
774 :
775 5 : if (pabyBlockBuf == NULL)
776 0 : return;
777 :
778 :
779 5 : if( ! this->bTiled )
780 : {
781 : // ------------------------------------------------------------
782 : // Load all rows at once
783 : // ------------------------------------------------------------
784 :
785 1 : nBlockYSize = nRasterYSize;
786 : nBMPSize = INGR_GetDataBlockSize( poDS->pszFilename,
787 : hHeaderTwo.CatenatedFilePointer,
788 1 : nDataOffset);
789 : }
790 : else
791 : {
792 : // ------------------------------------------------------------
793 : // Find the biggest tile
794 : // ------------------------------------------------------------
795 :
796 : uint32 iTiles;
797 20 : for( iTiles = 0; iTiles < nTiles; iTiles++)
798 : {
799 16 : nBMPSize = MAX( pahTiles[iTiles].Used, nBMPSize );
800 : }
801 : }
802 :
803 : // ----------------------------------------------------------------
804 : // Create a Bitmap buffer
805 : // ----------------------------------------------------------------
806 :
807 5 : pabyBMPBlock = (GByte*) VSIMalloc( nBMPSize );
808 5 : if (pabyBMPBlock == NULL)
809 : {
810 0 : CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nBMPSize);
811 : }
812 :
813 : // ----------------------------------------------------------------
814 : // Set a black and white Color Table
815 : // ----------------------------------------------------------------
816 :
817 5 : if( eFormat == CCITTGroup4 )
818 : {
819 1 : BlackWhiteCT( true );
820 : }
821 :
822 : // ----------------------------------------------------------------
823 : // Read JPEG Quality from Application Data
824 : // ----------------------------------------------------------------
825 :
826 5 : if( eFormat == JPEGGRAY ||
827 : eFormat == JPEGRGB ||
828 : eFormat == JPEGCYMK )
829 : {
830 : nQuality = INGR_ReadJpegQuality( poDS->fp,
831 : hHeaderTwo.ApplicationPacketPointer,
832 4 : nDataOffset );
833 : }
834 0 : }
835 :
836 : // ----------------------------------------------------------------------------
837 : // IntergraphBitmapBand::~IntergraphBitmapBand()
838 : // ----------------------------------------------------------------------------
839 :
840 5 : IntergraphBitmapBand::~IntergraphBitmapBand()
841 : {
842 5 : CPLFree( pabyBMPBlock );
843 5 : }
844 :
845 : // ----------------------------------------------------------------------------
846 : // IntergraphBitmapBand::GetColorInterpretation()
847 : // ----------------------------------------------------------------------------
848 :
849 0 : GDALColorInterp IntergraphBitmapBand::GetColorInterpretation()
850 : {
851 0 : if( eFormat == JPEGRGB)
852 : {
853 0 : switch( nRGBBand )
854 : {
855 : case 1:
856 0 : return GCI_RedBand;
857 : case 2:
858 0 : return GCI_GreenBand;
859 : case 3:
860 0 : return GCI_BlueBand;
861 : }
862 0 : return GCI_GrayIndex;
863 : }
864 : else
865 : {
866 0 : if( poColorTable->GetColorEntryCount() > 0 )
867 : {
868 0 : return GCI_PaletteIndex;
869 : }
870 : else
871 : {
872 0 : return GCI_GrayIndex;
873 : }
874 : }
875 :
876 : }
877 :
878 : // ----------------------------------------------------------------------------
879 : // IntergraphBitmapBand::IReadBlock()
880 : // ----------------------------------------------------------------------------
881 :
882 9 : CPLErr IntergraphBitmapBand::IReadBlock( int nBlockXOff,
883 : int nBlockYOff,
884 : void *pImage )
885 : {
886 9 : IntergraphDataset *poGDS = ( IntergraphDataset * ) poDS;
887 :
888 : // ----------------------------------------------------------------
889 : // Load the block of a tile or a whole image
890 : // ----------------------------------------------------------------
891 9 : if (HandleUninstantiatedTile( nBlockXOff, nBlockYOff, pImage ))
892 0 : return CE_None;
893 :
894 9 : uint32 nBytesRead = LoadBlockBuf( nBlockXOff, nBlockYOff, nBMPSize, pabyBMPBlock );
895 :
896 9 : if( nBytesRead == 0 )
897 : {
898 : memset( pImage, 0, nBlockXSize * nBlockYSize *
899 0 : GDALGetDataTypeSize( eDataType ) / 8 );
900 : CPLError( CE_Failure, CPLE_FileIO,
901 : "Can't read (%s) tile with X offset %d and Y offset %d.\n%s",
902 : ((IntergraphDataset*)poDS)->pszFilename, nBlockXOff, nBlockYOff,
903 0 : VSIStrerror( errno ) );
904 0 : return CE_Failure;
905 : }
906 :
907 : // ----------------------------------------------------------------
908 : // Calculate the resulting image dimmention
909 : // ----------------------------------------------------------------
910 :
911 9 : int nVirtualXSize = nBlockXSize;
912 9 : int nVirtualYSize = nBlockYSize;
913 :
914 9 : if( nBlockXOff == nFullBlocksX )
915 : {
916 4 : nVirtualXSize = nRasterXSize % nBlockXSize;
917 : }
918 :
919 9 : if( nBlockYOff == nFullBlocksY )
920 : {
921 4 : nVirtualYSize = nRasterYSize % nBlockYSize;
922 : }
923 :
924 : // ----------------------------------------------------------------
925 : // Create an in memory small tiff file (~400K)
926 : // ----------------------------------------------------------------
927 :
928 : poGDS->hVirtual = INGR_CreateVirtualFile( poGDS->pszFilename,
929 : eFormat,
930 : nVirtualXSize,
931 : nVirtualYSize,
932 : hTileDir.TileSize,
933 : nQuality,
934 : pabyBMPBlock,
935 : nBytesRead,
936 9 : nRGBBand );
937 :
938 9 : if( poGDS->hVirtual.poDS == NULL )
939 : {
940 : memset( pImage, 0, nBlockXSize * nBlockYSize *
941 0 : GDALGetDataTypeSize( eDataType ) / 8 );
942 : CPLError( CE_Failure, CPLE_AppDefined,
943 : "Unable to open virtual file.\n"
944 0 : "Is the GTIFF and JPEG driver available?" );
945 0 : return CE_Failure;
946 : }
947 :
948 : // ----------------------------------------------------------------
949 : // Read the unique block from the in memory file and release it
950 : // ----------------------------------------------------------------
951 :
952 : poGDS->hVirtual.poBand->RasterIO( GF_Read, 0, 0,
953 : nVirtualXSize, nVirtualYSize, pImage,
954 9 : nVirtualXSize, nVirtualYSize, GDT_Byte, 0, 0 );
955 :
956 : // --------------------------------------------------------------------
957 : // Reshape blocks if needed
958 : // --------------------------------------------------------------------
959 :
960 9 : if( nBlockXOff == nFullBlocksX ||
961 : nBlockYOff == nFullBlocksY )
962 : {
963 6 : ReshapeBlock( nBlockXOff, nBlockYOff, nBlockBufSize, (GByte*) pImage );
964 : }
965 :
966 9 : INGR_ReleaseVirtual( &poGDS->hVirtual );
967 :
968 9 : return CE_None;
969 : }
970 :
971 : // ----------------------------------------------------------------------------
972 : // IntergraphRasterBand::LoadBlockBuf()
973 : // ----------------------------------------------------------------------------
974 :
975 1379 : int IntergraphRasterBand::LoadBlockBuf( int nBlockXOff,
976 : int nBlockYOff,
977 : int nBlobkBytes,
978 : GByte *pabyBlock )
979 : {
980 1379 : IntergraphDataset *poGDS = ( IntergraphDataset * ) poDS;
981 :
982 1379 : uint32 nSeekOffset = 0;
983 1379 : uint32 nReadSize = 0;
984 1379 : uint32 nBlockId = 0;
985 :
986 : // --------------------------------------------------------------------
987 : // Read from tiles or read from strip
988 : // --------------------------------------------------------------------
989 :
990 1379 : if( bTiled )
991 : {
992 12 : nBlockId = nBlockXOff + nBlockYOff * nBlocksPerRow;
993 :
994 12 : if( pahTiles[nBlockId].Start == 0 )
995 : {
996 0 : return 0;
997 : }
998 :
999 12 : nSeekOffset = pahTiles[nBlockId].Start + nDataOffset;
1000 12 : nReadSize = pahTiles[nBlockId].Used;
1001 :
1002 12 : if( (int) nReadSize > nBlobkBytes )
1003 : {
1004 : CPLDebug( "INGR",
1005 : "LoadBlockBuf(%d,%d) - trimmed tile size from %d to %d.",
1006 : nBlockXOff, nBlockYOff,
1007 0 : (int) nReadSize, (int) nBlobkBytes );
1008 0 : nReadSize = nBlobkBytes;
1009 : }
1010 : }
1011 : else
1012 : {
1013 1367 : nSeekOffset = nDataOffset + ( nBlockBufSize * nBlockYOff );
1014 1367 : nReadSize = nBlobkBytes;
1015 : }
1016 :
1017 1379 : if( VSIFSeekL( poGDS->fp, nSeekOffset, SEEK_SET ) < 0 )
1018 : {
1019 0 : return 0;
1020 : }
1021 :
1022 1379 : return VSIFReadL( pabyBlock, 1, nReadSize, poGDS->fp );
1023 : }
1024 :
1025 : // ----------------------------------------------------------------------------
1026 : // IntergraphRasterBand::ReshapeBlock()
1027 : // ----------------------------------------------------------------------------
1028 :
1029 : /**
1030 : * Complete Tile with zeroes to fill up a Block
1031 : *
1032 : * ### ##000 ###### ###00
1033 : * ### => ##000 , 000000 or ###00
1034 : * ##000 000000 00000
1035 : ***/
1036 :
1037 9 : void IntergraphRasterBand::ReshapeBlock( int nBlockXOff,
1038 : int nBlockYOff,
1039 : int nBlockBytes,
1040 : GByte *pabyBlock )
1041 : {
1042 9 : GByte *pabyTile = (GByte*) CPLCalloc( 1, nBlockBufSize );
1043 :
1044 9 : memcpy( pabyTile, pabyBlock, nBlockBytes );
1045 9 : memset( pabyBlock, 0, nBlockBytes );
1046 :
1047 9 : int nColSize = nBlockXSize;
1048 9 : int nRowSize = nBlockYSize;
1049 9 : int nCellBytes = GDALGetDataTypeSize( eDataType ) / 8;
1050 :
1051 9 : if( nBlockXOff + 1 == nBlocksPerRow )
1052 : {
1053 6 : nColSize = nRasterXSize % nBlockXSize;
1054 : }
1055 :
1056 9 : if( nBlockYOff + 1 == nBlocksPerColumn )
1057 : {
1058 6 : nRowSize = nRasterYSize % nBlockYSize;
1059 : }
1060 :
1061 9 : if( nRGBIndex > 0 )
1062 : {
1063 0 : nCellBytes = nCellBytes * 3;
1064 : }
1065 :
1066 495 : for( int iRow = 0; iRow < nRowSize; iRow++ )
1067 : {
1068 : memcpy( pabyBlock + ( iRow * nCellBytes * nBlockXSize ),
1069 : pabyTile + ( iRow * nCellBytes * nColSize ),
1070 486 : nCellBytes * nColSize);
1071 : }
1072 :
1073 9 : CPLFree( pabyTile );
1074 9 : }
1075 :
1076 : // ----------------------------------------------------------------------------
1077 : // IntergraphRasterBand::IWriteBlock()
1078 : // ----------------------------------------------------------------------------
1079 :
1080 795 : CPLErr IntergraphRasterBand::IWriteBlock( int nBlockXOff,
1081 : int nBlockYOff,
1082 : void *pImage )
1083 : {
1084 795 : uint32 nBlockSize = nBlockBufSize;
1085 795 : uint32 nBlockOffset = nBlockBufSize * nBlockYOff;
1086 :
1087 795 : IntergraphDataset *poGDS = ( IntergraphDataset * ) poDS;
1088 :
1089 795 : if( ( nBlockXOff == 0 ) && ( nBlockYOff == 0 ) )
1090 : {
1091 25 : FlushBandHeader();
1092 : }
1093 :
1094 795 : if( nRGBIndex > 0 )
1095 : {
1096 30 : if( nBand > 1 )
1097 : {
1098 20 : VSIFSeekL( poGDS->fp, nDataOffset + ( nBlockBufSize * nBlockYOff ), SEEK_SET );
1099 20 : VSIFReadL( pabyBlockBuf, 1, nBlockBufSize, poGDS->fp );
1100 : }
1101 : int i, j;
1102 330 : for( i = 0, j = ( 3 - nRGBIndex ); i < nBlockXSize; i++, j += 3 )
1103 : {
1104 300 : pabyBlockBuf[j] = ( ( GByte * ) pImage )[i];
1105 : }
1106 : }
1107 765 : else if (eFormat == RunLengthEncoded)
1108 : {
1109 : // Series of [OFF, ON,] OFF spans.
1110 135 : int nLastCount = 0;
1111 135 : GByte *pInput = ( GByte * ) pImage;
1112 135 : GInt16 *pOutput = ( GInt16 * ) pabyBlockBuf;
1113 :
1114 135 : nBlockOffset = this->nRLEOffset * 2;
1115 135 : int nRLECount = 0;
1116 135 : GByte nValue = 0; // Start with OFF spans.
1117 :
1118 25650 : for(uint32 i=0; i<nBlockBufSize; i++)
1119 : {
1120 47575 : if (((nValue == 0) && (pInput[i] == 0)) || ((nValue == 1) && pInput[i]))
1121 : {
1122 22060 : nLastCount++;
1123 : }
1124 : else
1125 : {
1126 : // Change of span type.
1127 6910 : while(nLastCount>32767)
1128 : {
1129 0 : pOutput[nRLECount++] = CPL_LSBWORD16(32767);
1130 0 : pOutput[nRLECount++] = CPL_LSBWORD16(0);
1131 0 : nLastCount -= 32767;
1132 : }
1133 3455 : pOutput[nRLECount++] = CPL_LSBWORD16(nLastCount);
1134 3455 : nLastCount = 1;
1135 3455 : nValue ^= 1;
1136 : }
1137 : }
1138 :
1139 : // Output tail end of scanline
1140 270 : while(nLastCount>32767)
1141 : {
1142 0 : pOutput[nRLECount++] = CPL_LSBWORD16(32767);
1143 0 : pOutput[nRLECount++] = CPL_LSBWORD16(0);
1144 0 : nLastCount -= 32767;
1145 : }
1146 :
1147 135 : if (nLastCount != 0)
1148 : {
1149 135 : pOutput[nRLECount++] = CPL_LSBWORD16(nLastCount);
1150 135 : nLastCount = 0;
1151 135 : nValue ^= 1;
1152 : }
1153 :
1154 135 : if (nValue == 0)
1155 127 : pOutput[nRLECount++] = CPL_LSBWORD16(0);
1156 :
1157 135 : this->nRLEOffset += nRLECount;
1158 135 : nBlockSize = nRLECount * 2;
1159 : }
1160 : else
1161 : {
1162 630 : memcpy( pabyBlockBuf, pImage, nBlockBufSize );
1163 : #ifdef CPL_MSB
1164 : if( eDataType == GDT_Int16 || eDataType == GDT_UInt16)
1165 : GDALSwapWords( pabyBlockBuf, 2, nBlockXSize * nBlockYSize, 2 );
1166 : else if( eDataType == GDT_Int32 || eDataType == GDT_UInt32 || eDataType == GDT_Float32 )
1167 : GDALSwapWords( pabyBlockBuf, 4, nBlockXSize * nBlockYSize, 4 );
1168 : else if (eDataType == GDT_Float64 )
1169 : GDALSwapWords( pabyBlockBuf, 8, nBlockXSize * nBlockYSize, 8 );
1170 : #endif
1171 : }
1172 :
1173 795 : VSIFSeekL( poGDS->fp, nDataOffset + nBlockOffset, SEEK_SET );
1174 :
1175 795 : if( ( uint32 ) VSIFWriteL( pabyBlockBuf, 1, nBlockSize, poGDS->fp ) < nBlockSize )
1176 : {
1177 : CPLError( CE_Failure, CPLE_FileIO,
1178 : "Can't write (%s) block with X offset %d and Y offset %d.\n%s",
1179 0 : poGDS->pszFilename, nBlockXOff, nBlockYOff, VSIStrerror( errno ) );
1180 0 : return CE_Failure;
1181 : }
1182 :
1183 795 : return CE_None;
1184 : }
1185 :
1186 : // ----------------------------------------------------------------------------
1187 : // IntergraphRasterBand::FlushBandHeader()
1188 : // ----------------------------------------------------------------------------
1189 :
1190 25 : void IntergraphRasterBand::FlushBandHeader( void )
1191 : {
1192 25 : if( nRGBIndex > 1 )
1193 : {
1194 2 : return;
1195 : }
1196 :
1197 23 : IntergraphDataset *poGDS = ( IntergraphDataset* ) poDS;
1198 :
1199 : INGR_ColorTable256 hCTab;
1200 :
1201 23 : if( poColorTable->GetColorEntryCount() > 0 )
1202 : {
1203 1 : hHeaderTwo.ColorTableType = IGDSColorTable;
1204 1 : hHeaderTwo.NumberOfCTEntries = poColorTable->GetColorEntryCount();
1205 1 : INGR_SetIGDSColors( poColorTable, &hCTab );
1206 : }
1207 :
1208 23 : if( nBand > poDS->GetRasterCount() )
1209 : {
1210 : hHeaderTwo.CatenatedFilePointer = nBand *
1211 0 : ( ( 3 * SIZEOF_HDR1 ) + ( nBlockBufSize * nRasterYSize ) );
1212 : }
1213 :
1214 23 : VSIFSeekL( poGDS->fp, nBandStart, SEEK_SET );
1215 :
1216 : GByte abyBuf[MAX(SIZEOF_HDR1,SIZEOF_CTAB)];
1217 :
1218 23 : INGR_HeaderOneMemToDisk( &hHeaderOne, abyBuf );
1219 :
1220 23 : VSIFWriteL( abyBuf, 1, SIZEOF_HDR1, poGDS->fp );
1221 :
1222 23 : INGR_HeaderTwoAMemToDisk( &hHeaderTwo, abyBuf );
1223 :
1224 23 : VSIFWriteL( abyBuf, 1, SIZEOF_HDR2_A, poGDS->fp );
1225 :
1226 23 : unsigned int i = 0;
1227 23 : unsigned int n = 0;
1228 :
1229 5911 : for( i = 0; i < 256; i++ )
1230 : {
1231 5888 : STRC2BUF( abyBuf, n, hCTab.Entry[i].v_red );
1232 5888 : STRC2BUF( abyBuf, n, hCTab.Entry[i].v_green );
1233 5888 : STRC2BUF( abyBuf, n, hCTab.Entry[i].v_blue );
1234 : }
1235 :
1236 23 : VSIFWriteL( abyBuf, 1, SIZEOF_CTAB, poGDS->fp );
1237 : }
1238 :
1239 : // ----------------------------------------------------------------------------
1240 : // IntergraphRasterBand::BlackWhiteCT()
1241 : // ----------------------------------------------------------------------------
1242 :
1243 7 : void IntergraphRasterBand::BlackWhiteCT( bool bReverse )
1244 : {
1245 : GDALColorEntry oBlack;
1246 : GDALColorEntry oWhite;
1247 :
1248 7 : oWhite.c1 = (short) 255;
1249 7 : oWhite.c2 = (short) 255;
1250 7 : oWhite.c3 = (short) 255;
1251 7 : oWhite.c4 = (short) 255;
1252 :
1253 7 : oBlack.c1 = (short) 0;
1254 7 : oBlack.c2 = (short) 0;
1255 7 : oBlack.c3 = (short) 0;
1256 7 : oBlack.c4 = (short) 255;
1257 :
1258 7 : if( bReverse )
1259 : {
1260 7 : poColorTable->SetColorEntry( 0, &oWhite );
1261 7 : poColorTable->SetColorEntry( 1, &oBlack );
1262 : }
1263 : else
1264 : {
1265 0 : poColorTable->SetColorEntry( 0, &oBlack );
1266 0 : poColorTable->SetColorEntry( 1, &oWhite );
1267 : }
1268 7 : }
|