~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to frmts/gtiff/geotiff.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: geotiff.cpp 20144 2010-07-27 21:09:41Z rouault $
 
2
 * $Id: geotiff.cpp 23561 2011-12-13 05:47:58Z warmerdam $
3
3
 *
4
4
 * Project:  GeoTIFF Driver
5
5
 * Purpose:  GDAL GeoTIFF support.
27
27
 * DEALINGS IN THE SOFTWARE.
28
28
 ****************************************************************************/
29
29
 
 
30
/* If we use sunpro compiler on linux. Weird idea indeed ! */
 
31
#if defined(__SUNPRO_CC) && defined(__linux__)
 
32
#define _GNU_SOURCE
 
33
#elif defined(__GNUC__) && !defined(_GNU_SOURCE)
 
34
/* Required to use RTLD_DEFAULT of dlfcn.h */
 
35
#define _GNU_SOURCE
 
36
#endif
 
37
 
30
38
#include "gdal_pam.h"
31
39
#define CPL_SERV_H_INCLUDED
32
40
 
33
 
#include "tiffio.h"
34
41
#include "xtiffio.h"
35
 
#include "geotiff.h"
36
 
#include "geo_normalize.h"
37
42
#include "geovalues.h"
38
43
#include "cpl_string.h"
39
44
#include "cpl_csv.h"
40
45
#include "cpl_minixml.h"
41
46
#include "gt_overview.h"
42
47
#include "ogr_spatialref.h"
43
 
 
44
 
CPL_CVSID("$Id: geotiff.cpp 20144 2010-07-27 21:09:41Z rouault $");
45
 
 
46
 
CPL_C_START
47
 
char CPL_DLL *  GTIFGetOGISDefn( GTIF *, GTIFDefn * );
48
 
int  CPL_DLL   GTIFSetFromOGISDefn( GTIF *, const char * );
49
 
const char * GDALDefaultCSVFilename( const char *pszBasename );
50
 
GUInt32 HalfToFloat( GUInt16 );
51
 
GUInt32 TripleToFloat( GUInt32 );
52
 
void    GTiffOneTimeInit();
53
 
CPL_C_END
54
 
 
55
 
#define TIFFTAG_GDAL_METADATA  42112
56
 
#define TIFFTAG_GDAL_NODATA    42113
57
 
#define TIFFTAG_RPCCOEFFICIENT 50844
58
 
 
59
 
#if TIFFLIB_VERSION >= 20081217 && defined(BIGTIFF_SUPPORT)
60
 
#  define HAVE_UNSETFIELD
61
 
#endif
62
 
 
63
 
TIFF* VSI_TIFFOpen(const char* name, const char* mode);
 
48
#include "tif_float.h"
 
49
#include "gtiff.h"
 
50
#include "gdal_csv.h"
 
51
#include "gt_wkt_srs.h"
 
52
#include "tifvsi.h"
 
53
#include "cpl_multiproc.h"
 
54
 
 
55
CPL_CVSID("$Id: geotiff.cpp 23561 2011-12-13 05:47:58Z warmerdam $");
 
56
 
 
57
/************************************************************************/
 
58
/* ==================================================================== */
 
59
/*                                GDALOverviewDS                        */
 
60
/* ==================================================================== */
 
61
/************************************************************************/
 
62
 
 
63
/* GDALOverviewDS is not specific to GTiff and could probably be moved */
 
64
/* in gcore. It is currently used to generate a fake */
 
65
/* dataset from the overview levels of the source dataset that is taken */
 
66
/* by CreateCopy() */
 
67
 
 
68
#include "gdal_proxy.h"
 
69
 
 
70
class GDALOverviewBand;
 
71
 
 
72
class GDALOverviewDS : public GDALDataset
 
73
{
 
74
    private:
 
75
 
 
76
        friend class GDALOverviewBand;
 
77
 
 
78
        GDALDataset* poDS;
 
79
        GDALDataset* poOvrDS;
 
80
        int          nOvrLevel;
 
81
 
 
82
    public:
 
83
                        GDALOverviewDS(GDALDataset* poDS, int nOvrLevel);
 
84
        virtual        ~GDALOverviewDS();
 
85
 
 
86
        virtual char  **GetMetadata( const char * pszDomain = "" );
 
87
        virtual const char *GetMetadataItem( const char * pszName,
 
88
                                             const char * pszDomain = "" );
 
89
};
 
90
 
 
91
class GDALOverviewBand : public GDALProxyRasterBand
 
92
{
 
93
    protected:
 
94
        GDALRasterBand*         poUnderlyingBand;
 
95
        virtual GDALRasterBand* RefUnderlyingRasterBand();
 
96
 
 
97
    public:
 
98
                    GDALOverviewBand(GDALOverviewDS* poDS, int nBand);
 
99
        virtual    ~GDALOverviewBand();
 
100
};
 
101
 
 
102
GDALOverviewDS::GDALOverviewDS(GDALDataset* poDS, int nOvrLevel)
 
103
{
 
104
    this->poDS = poDS;
 
105
    this->nOvrLevel = nOvrLevel;
 
106
    eAccess = poDS->GetAccess();
 
107
    nRasterXSize = poDS->GetRasterBand(1)->GetOverview(nOvrLevel)->GetXSize();
 
108
    nRasterYSize = poDS->GetRasterBand(1)->GetOverview(nOvrLevel)->GetYSize();
 
109
    poOvrDS = poDS->GetRasterBand(1)->GetOverview(nOvrLevel)->GetDataset();
 
110
    nBands = poDS->GetRasterCount();
 
111
    int i;
 
112
    for(i=0;i<nBands;i++)
 
113
        SetBand(i+1, new GDALOverviewBand(this, i+1));
 
114
}
 
115
 
 
116
GDALOverviewDS::~GDALOverviewDS()
 
117
{
 
118
    FlushCache();
 
119
}
 
120
 
 
121
char  **GDALOverviewDS::GetMetadata( const char * pszDomain )
 
122
{
 
123
    if (poOvrDS != NULL)
 
124
        return poOvrDS->GetMetadata(pszDomain);
 
125
 
 
126
    return poDS->GetMetadata(pszDomain);
 
127
}
 
128
 
 
129
const char *GDALOverviewDS::GetMetadataItem( const char * pszName, const char * pszDomain )
 
130
{
 
131
    if (poOvrDS != NULL)
 
132
        return poOvrDS->GetMetadataItem(pszName, pszDomain);
 
133
 
 
134
    return poDS->GetMetadataItem(pszName, pszDomain);
 
135
}
 
136
 
 
137
GDALOverviewBand::GDALOverviewBand(GDALOverviewDS* poDS, int nBand)
 
138
{
 
139
    this->poDS = poDS;
 
140
    this->nBand = nBand;
 
141
    poUnderlyingBand = poDS->poDS->GetRasterBand(nBand)->GetOverview(poDS->nOvrLevel);
 
142
    nRasterXSize = poDS->nRasterXSize;
 
143
    nRasterYSize = poDS->nRasterYSize;
 
144
    eDataType = poUnderlyingBand->GetRasterDataType();
 
145
    poUnderlyingBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
 
146
}
 
147
 
 
148
GDALOverviewBand::~GDALOverviewBand()
 
149
{
 
150
    FlushCache();
 
151
}
 
152
 
 
153
GDALRasterBand* GDALOverviewBand::RefUnderlyingRasterBand()
 
154
{
 
155
    return poUnderlyingBand;
 
156
}
 
157
 
 
158
/************************************************************************/
 
159
/*                            IsPowerOfTwo()                            */
 
160
/************************************************************************/
 
161
 
 
162
static int IsPowerOfTwo(unsigned int i)
 
163
{
 
164
    int nBitSet = 0;
 
165
    while(i != 0)
 
166
    {
 
167
        if ((i & 1))
 
168
            nBitSet ++;
 
169
        i >>= 1;
 
170
    }
 
171
    return nBitSet == 1;
 
172
}
 
173
 
 
174
/************************************************************************/
 
175
/*                     GTIFFGetOverviewBlockSize()                      */
 
176
/************************************************************************/
 
177
 
 
178
void GTIFFGetOverviewBlockSize(int* pnBlockXSize, int* pnBlockYSize)
 
179
{
 
180
    static int bHasWarned = FALSE;
 
181
    const char* pszVal = CPLGetConfigOption("GDAL_TIFF_OVR_BLOCKSIZE", "128");
 
182
    int nOvrBlockSize = atoi(pszVal);
 
183
    if (nOvrBlockSize < 64 || nOvrBlockSize > 4096 ||
 
184
        !IsPowerOfTwo(nOvrBlockSize))
 
185
    {
 
186
        if (!bHasWarned)
 
187
        {
 
188
            CPLError(CE_Warning, CPLE_NotSupported,
 
189
                    "Wrong value for GDAL_TIFF_OVR_BLOCKSIZE : %s. "
 
190
                    "Should be a power of 2 between 64 and 4096. Defaulting to 128",
 
191
                    pszVal);
 
192
            bHasWarned = TRUE;
 
193
        }
 
194
        nOvrBlockSize = 128;
 
195
    }
 
196
 
 
197
    *pnBlockXSize = nOvrBlockSize;
 
198
    *pnBlockYSize = nOvrBlockSize;
 
199
}
64
200
 
65
201
enum
66
202
{
87
223
    friend class GTiffBitmapBand;
88
224
    friend class GTiffSplitBitmapBand;
89
225
    friend class GTiffOddBitsBand;
 
226
 
 
227
    friend void    GTIFFSetJpegQuality(GDALDatasetH hGTIFFDS, int nJpegQuality);
90
228
    
91
229
    TIFF        *hTIFF;
92
230
    GTiffDataset **ppoActiveDSRef;
93
231
    GTiffDataset *poActiveDS; /* only used in actual base */
94
232
 
 
233
    int         bScanDeferred;
 
234
    void        ScanDirectories();
 
235
 
95
236
    toff_t      nDirOffset;
96
237
    int         bBase;
97
238
    int         bCloseTIFFHandle; /* usefull for closing TIFF handle opened by GTIFF_DIR: */
115
256
 
116
257
    CPLErr      LoadBlockBuf( int nBlockId, int bReadFromDisk = TRUE );
117
258
    CPLErr      FlushBlockBuf();
 
259
    int         bWriteErrorInFlushBlockBuf;
118
260
 
119
261
    char        *pszProjection;
120
262
    int         bLookedForProjection;
121
263
 
122
264
    void        LookForProjection();
 
265
#ifdef ESRI_BUILD
 
266
    void        AdjustLinearUnit( short UOMLength );
 
267
#endif
123
268
 
124
269
    double      adfGeoTransform[6];
125
270
    int         bGeoTransformValid;
165
310
 
166
311
    void*        pabyTempWriteBuffer;
167
312
    int          nTempWriteBufferSize;
168
 
    int          WriteEncodedTile(uint32 tile, void* data, int bPreserveDataBuffer);
169
 
    int          WriteEncodedStrip(uint32 strip, void* data, int bPreserveDataBuffer);
 
313
    int          WriteEncodedTile(uint32 tile, GByte* pabyData, int bPreserveDataBuffer);
 
314
    int          WriteEncodedStrip(uint32 strip, GByte* pabyData, int bPreserveDataBuffer);
170
315
 
171
316
    GTiffDataset* poMaskDS;
172
317
    GTiffDataset* poBaseDS;
185
330
    int           bTreatAsSplit;
186
331
    int           bTreatAsSplitBitmap;
187
332
 
 
333
    int           bClipWarn;
 
334
 
 
335
    CPLString     osRPBFile;
 
336
    int           FindRPBFile();
 
337
    CPLString     osRPCFile;
 
338
    int           FindRPCFile();
 
339
    CPLString     osIMDFile;
 
340
    int           FindIMDFile();
 
341
    int           bHasSearchedRPC;
 
342
    void          LoadRPCRPB();
 
343
    int           bHasSearchedIMD;
 
344
    void          LoadIMD();
 
345
 
 
346
    int           bHasWarnedDisableAggressiveBandCaching;
 
347
 
188
348
    int           bDontReloadFirstBlock; /* Hack for libtiff 3.X and #3633 */
189
349
 
 
350
    int           nZLevel;
 
351
    int           nLZMAPreset;
 
352
    int           nJpegQuality;
 
353
    
 
354
    int           bPromoteTo8Bits;
 
355
 
 
356
    int           bDebugDontWriteBlocks;
 
357
 
 
358
    CPLErr        RegisterNewOverviewDataset(toff_t nOverviewOffset);
 
359
    CPLErr        CreateOverviewsFromSrcOverviews(GDALDataset* poSrcDS);
 
360
    CPLErr        CreateInternalMaskOverviews(int nOvrBlockXSize,
 
361
                                              int nOvrBlockYSize);
 
362
 
 
363
    int           bIsFinalized;
 
364
    int           Finalize();
 
365
 
 
366
    int           bIgnoreReadErrors;
 
367
 
 
368
    CPLString     osWldFilename;
 
369
 
 
370
    int           bDirectIO;
 
371
 
 
372
  protected:
 
373
    virtual int         CloseDependentDatasets();
 
374
 
190
375
  public:
191
376
                 GTiffDataset();
192
377
                 ~GTiffDataset();
207
392
                                    GDALProgressFunc, void * );
208
393
 
209
394
    CPLErr         OpenOffset( TIFF *, GTiffDataset **ppoActiveDSRef, 
210
 
                               toff_t nDirOffset, int, GDALAccess, 
211
 
                               int bAllowRGBAInterface = TRUE);
 
395
                               toff_t nDirOffset, int bBaseIn, GDALAccess, 
 
396
                               int bAllowRGBAInterface = TRUE, int bReadGeoTransform = FALSE,
 
397
                               char** papszSiblingFiles = NULL);
212
398
 
213
399
    static GDALDataset *OpenDir( GDALOpenInfo * );
214
400
    static GDALDataset *Open( GDALOpenInfo * );
240
426
 
241
427
    static TIFF *   CreateLL( const char * pszFilename,
242
428
                              int nXSize, int nYSize, int nBands,
243
 
                              GDALDataType eType, char **papszParmList );
 
429
                              GDALDataType eType,
 
430
                              double dfExtraSpaceForOverviews,
 
431
                              char **papszParmList );
244
432
 
245
433
    CPLErr   WriteEncodedTileOrStrip(uint32 tile_or_strip, void* data, int bPreserveDataBuffer);
246
434
};
247
435
 
248
436
/************************************************************************/
 
437
/*                        GTIFFSetJpegQuality()                         */
 
438
/* Called by GTIFFBuildOverviews() to set the jpeg quality on the IFD   */
 
439
/* of the .ovr file                                                     */
 
440
/************************************************************************/
 
441
 
 
442
void    GTIFFSetJpegQuality(GDALDatasetH hGTIFFDS, int nJpegQuality)
 
443
{
 
444
    CPLAssert(EQUAL(GDALGetDriverShortName(GDALGetDatasetDriver(hGTIFFDS)), "GTIFF"));
 
445
 
 
446
    GTiffDataset* poDS = (GTiffDataset*)hGTIFFDS;
 
447
    poDS->nJpegQuality = nJpegQuality;
 
448
 
 
449
    poDS->ScanDirectories();
 
450
 
 
451
    int i;
 
452
    for(i=0;i<poDS->nOverviewCount;i++)
 
453
        poDS->papoOverviewDS[i]->nJpegQuality = nJpegQuality;
 
454
}
 
455
 
 
456
/************************************************************************/
249
457
/* ==================================================================== */
250
458
/*                            GTiffRasterBand                           */
251
459
/* ==================================================================== */
260
468
    int                bHaveOffsetScale;
261
469
    double             dfOffset;
262
470
    double             dfScale;
 
471
    CPLString          osUnitType;
 
472
 
 
473
    CPLErr DirectIO( GDALRWFlag eRWFlag,
 
474
                                  int nXOff, int nYOff, int nXSize, int nYSize,
 
475
                                  void * pData, int nBufXSize, int nBufYSize,
 
476
                                  GDALDataType eBufType,
 
477
                                  int nPixelSpace, int nLineSpace );
263
478
 
264
479
protected:
265
480
    GTiffDataset       *poGDS;
269
484
    double             dfNoDataValue;
270
485
 
271
486
    void NullBlock( void *pData );
 
487
    CPLErr FillCacheForOtherBands( int nBlockXOff, int nBlockYOff );
272
488
 
273
489
public:
274
490
                   GTiffRasterBand( GTiffDataset *, int );
275
491
 
276
 
    // should override RasterIO eventually.
277
 
    
278
492
    virtual CPLErr IReadBlock( int, int, void * );
279
 
    virtual CPLErr IWriteBlock( int, int, void * ); 
 
493
    virtual CPLErr IWriteBlock( int, int, void * );
 
494
 
 
495
    virtual CPLErr IRasterIO( GDALRWFlag eRWFlag,
 
496
                                  int nXOff, int nYOff, int nXSize, int nYSize,
 
497
                                  void * pData, int nBufXSize, int nBufYSize,
 
498
                                  GDALDataType eBufType,
 
499
                                  int nPixelSpace, int nLineSpace );
280
500
 
281
501
    virtual GDALColorInterp GetColorInterpretation();
282
502
    virtual GDALColorTable *GetColorTable();
288
508
    virtual CPLErr SetOffset( double dfNewValue );
289
509
    virtual double GetScale( int *pbSuccess = NULL );
290
510
    virtual CPLErr SetScale( double dfNewValue );
 
511
    virtual const char* GetUnitType();
 
512
    virtual CPLErr SetUnitType( const char *pszNewValue );
291
513
    virtual CPLErr SetColorInterpretation( GDALColorInterp );
292
514
 
293
515
    virtual CPLErr  SetMetadata( char **, const char * = "" );
370
592
/* -------------------------------------------------------------------- */
371
593
/*      Try to work out band color interpretation.                      */
372
594
/* -------------------------------------------------------------------- */
 
595
    int bLookForExtraSamples = FALSE;
 
596
 
373
597
    if( poDS->poColorTable != NULL && nBand == 1 ) 
374
598
        eBandInterp = GCI_PaletteIndex;
375
599
    else if( poDS->nPhotometric == PHOTOMETRIC_RGB 
385
609
        else if( nBand == 3 )
386
610
            eBandInterp = GCI_BlueBand;
387
611
        else
388
 
        {
389
 
            uint16 *v;
390
 
            uint16 count = 0;
391
 
 
392
 
            if( TIFFGetField( poDS->hTIFF, TIFFTAG_EXTRASAMPLES, &count, &v) )
393
 
            {
394
 
                if( nBand - 3 <= count && v[nBand-4] == EXTRASAMPLE_ASSOCALPHA )
395
 
                    eBandInterp = GCI_AlphaBand;
396
 
                else
397
 
                    eBandInterp = GCI_Undefined;
398
 
            }
399
 
            else if( nBand == 4 )
400
 
                eBandInterp = GCI_AlphaBand;
401
 
            else
402
 
                eBandInterp = GCI_Undefined;
403
 
        }
 
612
            bLookForExtraSamples = TRUE;
404
613
    }
405
614
    else if( poDS->nPhotometric == PHOTOMETRIC_YCBCR )
406
615
    {
411
620
        else if( nBand == 3 )
412
621
            eBandInterp = GCI_YCbCr_CrBand;
413
622
        else
414
 
        {
415
 
            uint16 *v;
416
 
            uint16 count = 0;
417
 
 
418
 
            if( TIFFGetField( poDS->hTIFF, TIFFTAG_EXTRASAMPLES, &count, &v) )
419
 
            {
420
 
                if( nBand - 3 <= count && v[nBand-4] == EXTRASAMPLE_ASSOCALPHA )
421
 
                    eBandInterp = GCI_AlphaBand;
422
 
                else
423
 
                    eBandInterp = GCI_Undefined;
424
 
            }
425
 
            else if( nBand == 4 )
426
 
                eBandInterp = GCI_AlphaBand;
427
 
            else
428
 
                eBandInterp = GCI_Undefined;
429
 
        }
 
623
            bLookForExtraSamples = TRUE;
430
624
    }
431
625
    else if( poDS->nPhotometric == PHOTOMETRIC_SEPARATED )
432
626
    {
436
630
            eBandInterp = GCI_MagentaBand;
437
631
        else if( nBand == 3 )
438
632
            eBandInterp = GCI_YellowBand;
439
 
        else
 
633
        else if( nBand == 4 )
440
634
            eBandInterp = GCI_BlackBand;
 
635
        else
 
636
            bLookForExtraSamples = TRUE;
441
637
    }
442
638
    else if( poDS->nPhotometric == PHOTOMETRIC_MINISBLACK && nBand == 1 )
443
639
        eBandInterp = GCI_GrayIndex;
444
640
    else
 
641
        bLookForExtraSamples = TRUE;
 
642
        
 
643
    if( bLookForExtraSamples )
445
644
    {
446
645
        uint16 *v;
447
646
        uint16 count = 0;
452
651
            nBaseSamples = poDS->nSamplesPerPixel - count;
453
652
 
454
653
            if( nBand > nBaseSamples 
455
 
                && v[nBand-nBaseSamples-1] == EXTRASAMPLE_ASSOCALPHA )
 
654
                && (v[nBand-nBaseSamples-1] == EXTRASAMPLE_ASSOCALPHA
 
655
                    || v[nBand-nBaseSamples-1] == EXTRASAMPLE_UNASSALPHA) )
456
656
                eBandInterp = GCI_AlphaBand;
457
657
            else
458
658
                eBandInterp = GCI_Undefined;
472
672
}
473
673
 
474
674
/************************************************************************/
 
675
/*                           DirectIO()                                 */
 
676
/************************************************************************/
 
677
 
 
678
/* Reads directly bytes from the file using ReadMultiRange(), and by-pass */
 
679
/* block reading. Restricted to simple TIFF configurations (single-band, un-tiled, */
 
680
/* uncompressed data, standard data types). Particularly usefull to extract */
 
681
/* sub-windows of data on a large /vsicurl dataset). */
 
682
 
 
683
CPLErr GTiffRasterBand::DirectIO( GDALRWFlag eRWFlag,
 
684
                                  int nXOff, int nYOff, int nXSize, int nYSize,
 
685
                                  void * pData, int nBufXSize, int nBufYSize,
 
686
                                  GDALDataType eBufType,
 
687
                                  int nPixelSpace, int nLineSpace )
 
688
{
 
689
    if( !(eRWFlag == GF_Read && poGDS->nBands == 1 &&
 
690
          poGDS->nCompression == COMPRESSION_NONE &&
 
691
          (poGDS->nBitsPerSample == 8 || (poGDS->nBitsPerSample == 16) ||
 
692
           poGDS->nBitsPerSample == 32 || poGDS->nBitsPerSample == 64) &&
 
693
          poGDS->nBitsPerSample == GDALGetDataTypeSize(eDataType) &&
 
694
          !TIFFIsTiled( poGDS->hTIFF )) )
 
695
    {
 
696
        return CE_Failure;
 
697
    }
 
698
 
 
699
/* ==================================================================== */
 
700
/*      Do we have overviews that would be appropriate to satisfy       */
 
701
/*      this request?                                                   */
 
702
/* ==================================================================== */
 
703
    if( (nBufXSize < nXSize || nBufYSize < nYSize)
 
704
        && GetOverviewCount() > 0 && eRWFlag == GF_Read )
 
705
    {
 
706
        int         nOverview;
 
707
 
 
708
        nOverview =
 
709
            GDALBandGetBestOverviewLevel(this, nXOff, nYOff, nXSize, nYSize,
 
710
                                        nBufXSize, nBufYSize);
 
711
        if (nOverview >= 0)
 
712
        {
 
713
            GDALRasterBand* poOverviewBand = GetOverview(nOverview);
 
714
            if (poOverviewBand == NULL)
 
715
                return CE_Failure;
 
716
 
 
717
            return poOverviewBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
 
718
                                            pData, nBufXSize, nBufYSize, eBufType,
 
719
                                            nPixelSpace, nLineSpace );
 
720
        }
 
721
    }
 
722
 
 
723
    /* Make sure that TIFFTAG_STRIPOFFSETS is up-to-date */
 
724
    if (poGDS->GetAccess() == GA_Update)
 
725
        poGDS->FlushCache();
 
726
 
 
727
    /* Get strip offsets */
 
728
    toff_t *panTIFFOffsets = NULL;
 
729
    if ( !TIFFGetField( poGDS->hTIFF, TIFFTAG_STRIPOFFSETS, &panTIFFOffsets ) ||
 
730
         panTIFFOffsets == NULL )
 
731
    {
 
732
        return CE_Failure;
 
733
    }
 
734
 
 
735
    int iLine;
 
736
    int nReqXSize = nXSize; /* sub-sampling or over-sampling can only be done at last stage */
 
737
    int nReqYSize = MIN(nBufYSize, nYSize); /* we can do sub-sampling at the extraction stage */
 
738
    void** ppData = (void**) VSIMalloc(nReqYSize * sizeof(void*));
 
739
    vsi_l_offset* panOffsets = (vsi_l_offset*)
 
740
                            VSIMalloc(nReqYSize * sizeof(vsi_l_offset));
 
741
    size_t* panSizes = (size_t*) VSIMalloc(nReqYSize * sizeof(size_t));
 
742
    int eDTSize = GDALGetDataTypeSize(eDataType) / 8;
 
743
    void* pTmpBuffer = NULL;
 
744
    CPLErr eErr = CE_None;
 
745
 
 
746
    if (ppData == NULL || panOffsets == NULL || panSizes == NULL)
 
747
        eErr = CE_Failure;
 
748
    else if (nXSize != nBufXSize || nYSize != nBufYSize ||
 
749
             eBufType != eDataType ||
 
750
             nPixelSpace != GDALGetDataTypeSize(eBufType) / 8)
 
751
    {
 
752
        /* We need a temporary buffer for over-sampling/sub-sampling */
 
753
        /* and/or data type conversion */
 
754
        pTmpBuffer = VSIMalloc(nReqXSize * nReqYSize * eDTSize);
 
755
        if (pTmpBuffer == NULL)
 
756
            eErr = CE_Failure;
 
757
    }
 
758
 
 
759
    /* Prepare data extraction */
 
760
    for(iLine=0;eErr == CE_None && iLine<nReqYSize;iLine++)
 
761
    {
 
762
        if (pTmpBuffer == NULL)
 
763
            ppData[iLine] = ((GByte*)pData) + iLine * nLineSpace;
 
764
        else
 
765
            ppData[iLine] = ((GByte*)pTmpBuffer) + iLine * nReqXSize * eDTSize;
 
766
        int nSrcLine;
 
767
        if (nBufYSize < nYSize) /* Sub-sampling in y */
 
768
            nSrcLine = nYOff + (int)((iLine + 0.5) * nYSize / nBufYSize);
 
769
        else
 
770
            nSrcLine = nYOff + iLine;
 
771
        panOffsets[iLine] = panTIFFOffsets[nSrcLine / nBlockYSize];
 
772
        if (panOffsets[iLine] == 0) /* We don't support sparse files */
 
773
            eErr = CE_Failure;
 
774
 
 
775
        panOffsets[iLine] += (nXOff + (nSrcLine % nBlockYSize) * nBlockXSize) * eDTSize;
 
776
        panSizes[iLine] = nReqXSize * eDTSize;
 
777
    }
 
778
 
 
779
    /* Extract data from the file */
 
780
    if (eErr == CE_None)
 
781
    {
 
782
        VSILFILE* fp = (VSILFILE*) TIFFClientdata( poGDS->hTIFF );
 
783
        int nRet = VSIFReadMultiRangeL(nReqYSize, ppData, panOffsets, panSizes, fp);
 
784
        if (nRet != 0)
 
785
            eErr = CE_Failure;
 
786
    }
 
787
 
 
788
    /* Byte-swap if necessary */
 
789
    if (eErr == CE_None && TIFFIsByteSwapped(poGDS->hTIFF))
 
790
    {
 
791
        for(iLine=0;iLine<nReqYSize;iLine++)
 
792
        {
 
793
            GDALSwapWords( ppData[iLine], eDTSize, nReqXSize, eDTSize);
 
794
        }
 
795
    }
 
796
 
 
797
    /* Over-sampling/sub-sampling and/or data type conversion */
 
798
    if (eErr == CE_None && pTmpBuffer != NULL)
 
799
    {
 
800
        for(int iY=0;iY<nBufYSize;iY++)
 
801
        {
 
802
            int iSrcY = (nBufYSize <= nYSize) ? iY :
 
803
                            (int)((iY + 0.5) * nYSize / nBufYSize);
 
804
            if (nBufXSize == nXSize)
 
805
            {
 
806
                GDALCopyWords( ppData[iSrcY], eDataType, eDTSize,
 
807
                                ((GByte*)pData) + iY * nLineSpace,
 
808
                                eBufType, nPixelSpace,
 
809
                                nReqXSize);
 
810
            }
 
811
            else
 
812
            {
 
813
                for(int iX=0;iX<nBufXSize;iX++)
 
814
                {
 
815
                    int iSrcX = (nBufXSize == nXSize) ? iX :
 
816
                                    (int)((iX+0.5) * nXSize / nBufXSize);
 
817
                    GDALCopyWords( ((GByte*)ppData[iSrcY]) + iSrcX * eDTSize,
 
818
                                    eDataType, 0,
 
819
                                    ((GByte*)pData) + iX * nPixelSpace + iY * nLineSpace,
 
820
                                    eBufType, 0, 1);
 
821
                }
 
822
            }
 
823
        }
 
824
    }
 
825
 
 
826
    /* Cleanup */
 
827
    CPLFree(pTmpBuffer);
 
828
    CPLFree(ppData);
 
829
    CPLFree(panOffsets);
 
830
    CPLFree(panSizes);
 
831
 
 
832
    return eErr;
 
833
}
 
834
 
 
835
/************************************************************************/
 
836
/*                            IRasterIO()                               */
 
837
/************************************************************************/
 
838
 
 
839
CPLErr GTiffRasterBand::IRasterIO( GDALRWFlag eRWFlag,
 
840
                                  int nXOff, int nYOff, int nXSize, int nYSize,
 
841
                                  void * pData, int nBufXSize, int nBufYSize,
 
842
                                  GDALDataType eBufType,
 
843
                                  int nPixelSpace, int nLineSpace )
 
844
{
 
845
    CPLErr eErr;
 
846
 
 
847
    //CPLDebug("GTiff", "RasterIO(%d, %d, %d, %d, %d, %d)",
 
848
    //         nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize);
 
849
 
 
850
    if (poGDS->bDirectIO)
 
851
    {
 
852
        eErr = DirectIO(eRWFlag, nXOff, nYOff, nXSize, nYSize,
 
853
                        pData, nBufXSize, nBufYSize, eBufType,
 
854
                        nPixelSpace, nLineSpace);
 
855
 
 
856
        if (eErr == CE_None)
 
857
            return eErr;
 
858
    }
 
859
 
 
860
    if (poGDS->nBands != 1 &&
 
861
        poGDS->nPlanarConfig == PLANARCONFIG_CONTIG &&
 
862
        eRWFlag == GF_Read &&
 
863
        nXSize == nBufXSize && nYSize == nBufYSize)
 
864
    {
 
865
        int nBlockX1 = nXOff / nBlockXSize;
 
866
        int nBlockY1 = nYOff / nBlockYSize;
 
867
        int nBlockX2 = (nXOff + nXSize - 1) / nBlockXSize;
 
868
        int nBlockY2 = (nYOff + nYSize - 1) / nBlockYSize;
 
869
        int nXBlocks = nBlockX2 - nBlockX1 + 1;
 
870
        int nYBlocks = nBlockY2 - nBlockY1 + 1;
 
871
        GIntBig nRequiredMem = (GIntBig)poGDS->nBands * nXBlocks * nYBlocks *
 
872
                                nBlockXSize * nBlockYSize *
 
873
                               (GDALGetDataTypeSize(eDataType) / 8);
 
874
        if (nRequiredMem > GDALGetCacheMax64())
 
875
        {
 
876
            if (!poGDS->bHasWarnedDisableAggressiveBandCaching)
 
877
            {
 
878
                CPLDebug("GTiff", "Disable aggressive band caching. Cache not big enough. "
 
879
                         "At least " CPL_FRMT_GIB " bytes necessary", nRequiredMem);
 
880
                poGDS->bHasWarnedDisableAggressiveBandCaching = TRUE;
 
881
            }
 
882
            poGDS->bLoadingOtherBands = TRUE;
 
883
        }
 
884
    }
 
885
 
 
886
    eErr = GDALPamRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize,
 
887
                                        pData, nBufXSize, nBufYSize, eBufType,
 
888
                                        nPixelSpace, nLineSpace);
 
889
 
 
890
    poGDS->bLoadingOtherBands = FALSE;
 
891
 
 
892
    return eErr;
 
893
}
 
894
 
 
895
/************************************************************************/
475
896
/*                             IReadBlock()                             */
476
897
/************************************************************************/
477
898
 
493
914
        nBlockBufSize = TIFFStripSize( poGDS->hTIFF );
494
915
    }
495
916
 
 
917
    CPLAssert(nBlocksPerRow != 0);
496
918
    nBlockIdBand0 = nBlockXOff + nBlockYOff * nBlocksPerRow;
497
919
    if( poGDS->nPlanarConfig == PLANARCONFIG_SEPARATE )
498
920
        nBlockId = nBlockIdBand0 + (nBand-1) * poGDS->nBlocksPerBand;
534
956
        if( TIFFIsTiled( poGDS->hTIFF ) )
535
957
        {
536
958
            if( TIFFReadEncodedTile( poGDS->hTIFF, nBlockId, pImage,
537
 
                                     nBlockReqSize ) == -1 )
 
959
                                     nBlockReqSize ) == -1
 
960
                && !poGDS->bIgnoreReadErrors )
538
961
            {
539
962
                memset( pImage, 0, nBlockBufSize );
540
963
                CPLError( CE_Failure, CPLE_AppDefined,
546
969
        else
547
970
        {
548
971
            if( TIFFReadEncodedStrip( poGDS->hTIFF, nBlockId, pImage,
549
 
                                      nBlockReqSize ) == -1 )
 
972
                                      nBlockReqSize ) == -1
 
973
                && !poGDS->bIgnoreReadErrors )
550
974
            {
551
975
                memset( pImage, 0, nBlockBufSize );
552
976
                CPLError( CE_Failure, CPLE_AppDefined,
553
 
                          "TIFFReadEncodedStrip() failed.\n" );
554
 
                
 
977
                        "TIFFReadEncodedStrip() failed.\n" );
 
978
 
555
979
                eErr = CE_Failure;
556
980
            }
557
981
        }
673
1097
                }
674
1098
            }
675
1099
        }
 
1100
#undef COPY_TO_DST_BUFFER
676
1101
    }
677
1102
 
678
1103
    else
694
1119
        }
695
1120
    }
696
1121
 
 
1122
    if (eErr == CE_None)
 
1123
        eErr = FillCacheForOtherBands(nBlockXOff, nBlockYOff);
 
1124
 
 
1125
    return eErr;
 
1126
}
 
1127
 
 
1128
 
 
1129
/************************************************************************/
 
1130
/*                       FillCacheForOtherBands()                       */
 
1131
/************************************************************************/
 
1132
 
 
1133
CPLErr GTiffRasterBand::FillCacheForOtherBands( int nBlockXOff, int nBlockYOff )
 
1134
 
 
1135
{
 
1136
    CPLErr eErr = CE_None;
697
1137
/* -------------------------------------------------------------------- */
698
1138
/*      In the fairly common case of pixel interleaved 8bit data        */
699
1139
/*      that is multi-band, lets push the rest of the data into the     */
710
1150
/*      If there are many bands and the block cache size is not big     */
711
1151
/*      enough to accomodate the size of all the blocks, don't enter    */
712
1152
/* -------------------------------------------------------------------- */
713
 
    if( poGDS->nBands != 1 && eErr == CE_None && !poGDS->bLoadingOtherBands &&
714
 
        nBlockXSize * nBlockYSize * (GDALGetDataTypeSize(eDataType) / 8) < GDALGetCacheMax() / poGDS->nBands)
 
1153
    if( poGDS->nBands != 1 && !poGDS->bLoadingOtherBands &&
 
1154
        nBlockXSize * nBlockYSize * (GDALGetDataTypeSize(eDataType) / 8) < GDALGetCacheMax64() / poGDS->nBands)
715
1155
    {
716
1156
        int iOtherBand;
717
1157
 
751
1191
    int         nBlockId;
752
1192
    CPLErr      eErr = CE_None;
753
1193
 
 
1194
    if (poGDS->bDebugDontWriteBlocks)
 
1195
        return CE_None;
 
1196
 
 
1197
    if (poGDS->bWriteErrorInFlushBlockBuf)
 
1198
    {
 
1199
        /* Report as an error if a previously loaded block couldn't be */
 
1200
        /* written correctly */
 
1201
        poGDS->bWriteErrorInFlushBlockBuf = FALSE;
 
1202
        return CE_Failure;
 
1203
    }
 
1204
 
754
1205
    if (!poGDS->SetDirectory())
755
1206
        return CE_Failure;
756
1207
 
758
1209
               && nBlockXOff >= 0
759
1210
               && nBlockYOff >= 0
760
1211
               && pImage != NULL );
 
1212
    CPLAssert(nBlocksPerRow != 0);
761
1213
 
762
1214
/* -------------------------------------------------------------------- */
763
1215
/*      Handle case of "separate" images                                */
776
1228
/* -------------------------------------------------------------------- */
777
1229
/*      Handle case of pixel interleaved (PLANARCONFIG_CONTIG) images.  */
778
1230
/* -------------------------------------------------------------------- */
779
 
 
780
1231
    nBlockId = nBlockXOff + nBlockYOff * nBlocksPerRow;
781
1232
        
782
1233
    eErr = poGDS->LoadBlockBuf( nBlockId );
790
1241
/* -------------------------------------------------------------------- */
791
1242
    int iBand; 
792
1243
    int nWordBytes = poGDS->nBitsPerSample / 8;
 
1244
    int nBands = poGDS->nBands;
793
1245
 
794
 
    for( iBand = 0; iBand < poGDS->nBands; iBand++ )
 
1246
    for( iBand = 0; iBand < nBands; iBand++ )
795
1247
    {
796
1248
        const GByte *pabyThisImage = NULL;
797
1249
        GDALRasterBlock *poBlock = NULL;
818
1270
        int i, nBlockPixels = nBlockXSize * nBlockYSize;
819
1271
        GByte *pabyOut = poGDS->pabyBlockBuf + iBand*nWordBytes;
820
1272
 
821
 
        for( i = 0; i < nBlockPixels; i++ )
822
 
        {
823
 
            memcpy( pabyOut, pabyThisImage, nWordBytes );
824
 
            
825
 
            pabyOut += nWordBytes * poGDS->nBands;
826
 
            pabyThisImage += nWordBytes;
 
1273
        if (nWordBytes == 1)
 
1274
        {
 
1275
 
 
1276
/* ==================================================================== */
 
1277
/*     Optimization for high number of words to transfer and some       */
 
1278
/*     typical band numbers : we unroll the loop.                       */
 
1279
/* ==================================================================== */
 
1280
#define COPY_TO_DST_BUFFER(nBands) \
 
1281
            if (nBlockPixels > 100) \
 
1282
            { \
 
1283
                for ( i = nBlockPixels / 16; i != 0; i -- ) \
 
1284
                { \
 
1285
                    pabyOut[0*nBands] = pabyThisImage[0]; \
 
1286
                    pabyOut[1*nBands] = pabyThisImage[1]; \
 
1287
                    pabyOut[2*nBands] = pabyThisImage[2]; \
 
1288
                    pabyOut[3*nBands] = pabyThisImage[3]; \
 
1289
                    pabyOut[4*nBands] = pabyThisImage[4]; \
 
1290
                    pabyOut[5*nBands] = pabyThisImage[5]; \
 
1291
                    pabyOut[6*nBands] = pabyThisImage[6]; \
 
1292
                    pabyOut[7*nBands] = pabyThisImage[7]; \
 
1293
                    pabyOut[8*nBands] = pabyThisImage[8]; \
 
1294
                    pabyOut[9*nBands] = pabyThisImage[9]; \
 
1295
                    pabyOut[10*nBands] = pabyThisImage[10]; \
 
1296
                    pabyOut[11*nBands] = pabyThisImage[11]; \
 
1297
                    pabyOut[12*nBands] = pabyThisImage[12]; \
 
1298
                    pabyOut[13*nBands] = pabyThisImage[13]; \
 
1299
                    pabyOut[14*nBands] = pabyThisImage[14]; \
 
1300
                    pabyOut[15*nBands] = pabyThisImage[15]; \
 
1301
                    pabyThisImage += 16; \
 
1302
                    pabyOut += 16*nBands; \
 
1303
                } \
 
1304
                nBlockPixels = nBlockPixels % 16; \
 
1305
            } \
 
1306
            for( i = 0; i < nBlockPixels; i++ ) \
 
1307
            { \
 
1308
                *pabyOut = pabyThisImage[i]; \
 
1309
                pabyOut += nBands; \
 
1310
            }
 
1311
 
 
1312
            switch (nBands)
 
1313
            {
 
1314
                case 3:  COPY_TO_DST_BUFFER(3); break;
 
1315
                case 4:  COPY_TO_DST_BUFFER(4); break;
 
1316
                default:
 
1317
                {
 
1318
                    for( i = 0; i < nBlockPixels; i++ )
 
1319
                    {
 
1320
                        *pabyOut = pabyThisImage[i];
 
1321
                        pabyOut += nBands;
 
1322
                    }
 
1323
                }
 
1324
            }
 
1325
#undef COPY_TO_DST_BUFFER
 
1326
        }
 
1327
        else
 
1328
        {
 
1329
            for( i = 0; i < nBlockPixels; i++ )
 
1330
            {
 
1331
                memcpy( pabyOut, pabyThisImage, nWordBytes );
 
1332
 
 
1333
                pabyOut += nWordBytes * nBands;
 
1334
                pabyThisImage += nWordBytes;
 
1335
            }
827
1336
        }
828
1337
        
829
1338
        if( poBlock != NULL )
893
1402
}
894
1403
 
895
1404
/************************************************************************/
 
1405
/*                            GetUnitType()                             */
 
1406
/************************************************************************/
 
1407
 
 
1408
const char* GTiffRasterBand::GetUnitType()
 
1409
 
 
1410
{
 
1411
    return osUnitType.c_str();
 
1412
}
 
1413
 
 
1414
/************************************************************************/
 
1415
/*                           SetUnitType()                              */
 
1416
/************************************************************************/
 
1417
 
 
1418
CPLErr GTiffRasterBand::SetUnitType( const char* pszNewValue )
 
1419
 
 
1420
{
 
1421
    CPLString osNewValue(pszNewValue ? pszNewValue : "");
 
1422
    if( osNewValue.compare(osUnitType) != 0 )
 
1423
        poGDS->bMetadataChanged = TRUE;
 
1424
 
 
1425
    osUnitType = osNewValue;
 
1426
    return CE_None;
 
1427
}
 
1428
 
 
1429
/************************************************************************/
896
1430
/*                            GetMetadata()                             */
897
1431
/************************************************************************/
898
1432
 
1020
1554
/* -------------------------------------------------------------------- */
1021
1555
/*      Check if this is even a candidate for applying a PCT.           */
1022
1556
/* -------------------------------------------------------------------- */
1023
 
    if( poGDS->nSamplesPerPixel != 1 )
 
1557
    if( nBand != 1)
 
1558
    {
 
1559
        CPLError( CE_Failure, CPLE_NotSupported, 
 
1560
                  "SetColorTable() can only be called on band 1." );
 
1561
        return CE_Failure;
 
1562
    }
 
1563
 
 
1564
    if( poGDS->nSamplesPerPixel != 1 && poGDS->nSamplesPerPixel != 2)
1024
1565
    {
1025
1566
        CPLError( CE_Failure, CPLE_NotSupported, 
1026
1567
                  "SetColorTable() not supported for multi-sample TIFF files." );
1193
1734
    double dfNoData = GetNoDataValue( &bNoDataSet );
1194
1735
    if( !bNoDataSet )
1195
1736
    {
 
1737
#ifdef ESRI_BUILD
 
1738
        if ( poGDS->nBitsPerSample >= 2 )
 
1739
            memset( pData, 0, nWords*nChunkSize );
 
1740
        else
 
1741
            memset( pData, 1, nWords*nChunkSize );
 
1742
#else
1196
1743
        memset( pData, 0, nWords*nChunkSize );
 
1744
#endif
1197
1745
    }
1198
1746
    else
1199
1747
    {
1210
1758
int GTiffRasterBand::GetOverviewCount()
1211
1759
 
1212
1760
{
 
1761
    poGDS->ScanDirectories();
 
1762
 
1213
1763
    if( poGDS->nOverviewCount > 0 )
1214
1764
        return poGDS->nOverviewCount;
1215
1765
    else
1223
1773
GDALRasterBand *GTiffRasterBand::GetOverview( int i )
1224
1774
 
1225
1775
{
 
1776
    poGDS->ScanDirectories();
 
1777
 
1226
1778
    if( poGDS->nOverviewCount > 0 )
1227
1779
    {
1228
1780
        if( i < 0 || i >= poGDS->nOverviewCount )
1240
1792
 
1241
1793
int GTiffRasterBand::GetMaskFlags()
1242
1794
{
 
1795
    poGDS->ScanDirectories();
 
1796
 
1243
1797
    if( poGDS->poMaskDS != NULL )
1244
1798
    {
1245
 
        int iBand;
1246
 
        int nMaskFlag = 0;
1247
1799
        if( poGDS->poMaskDS->GetRasterCount() == 1)
1248
1800
        {
1249
 
            iBand = 1;
1250
 
            nMaskFlag = GMF_PER_DATASET;
1251
 
        }
1252
 
        else
1253
 
        {
1254
 
            iBand = nBand;
1255
 
        }
1256
 
        if( poGDS->poMaskDS->GetRasterBand(iBand)->GetMetadataItem( "NBITS", "IMAGE_STRUCTURE" ) != NULL 
1257
 
            && atoi(poGDS->poMaskDS->GetRasterBand(iBand)->GetMetadataItem( "NBITS", "IMAGE_STRUCTURE" )) == 1)
1258
 
        {
1259
 
            return nMaskFlag;
1260
 
        }
1261
 
        else
1262
 
        {
1263
 
            return nMaskFlag | GMF_ALPHA;
 
1801
            return GMF_PER_DATASET;
 
1802
        }
 
1803
        else
 
1804
        {
 
1805
            return 0;
1264
1806
        }
1265
1807
    }
1266
1808
    else
1273
1815
 
1274
1816
GDALRasterBand *GTiffRasterBand::GetMaskBand()
1275
1817
{
 
1818
    poGDS->ScanDirectories();
 
1819
 
1276
1820
    if( poGDS->poMaskDS != NULL )
1277
1821
    {
1278
1822
        if( poGDS->poMaskDS->GetRasterCount() == 1)
1374
1918
        if( TIFFReadScanline( poGDS->hTIFF,
1375
1919
                              poGDS->pabyBlockBuf ? poGDS->pabyBlockBuf : pImage,
1376
1920
                              ++poGDS->nLastLineRead,
1377
 
                              (poGDS->nPlanarConfig == PLANARCONFIG_SEPARATE) ? nBand-1 : 0 ) == -1 )
 
1921
                              (poGDS->nPlanarConfig == PLANARCONFIG_SEPARATE) ? (uint16) (nBand-1) : 0 ) == -1
 
1922
            && !poGDS->bIgnoreReadErrors )
1378
1923
        {
1379
1924
            CPLError( CE_Failure, CPLE_AppDefined,
1380
1925
                      "TIFFReadScanline() failed." );
1474
2019
    if (!poGDS->SetDirectory())
1475
2020
        return CE_Failure;
1476
2021
 
 
2022
    CPLAssert(nBlocksPerRow != 0);
1477
2023
    nBlockBufSize = 4 * nBlockXSize * nBlockYSize;
1478
2024
    nBlockId = nBlockXOff + nBlockYOff * nBlocksPerRow;
1479
2025
 
1497
2043
            if( TIFFReadRGBATile(poGDS->hTIFF, 
1498
2044
                                 nBlockXOff * nBlockXSize, 
1499
2045
                                 nBlockYOff * nBlockYSize,
1500
 
                                 (uint32 *) poGDS->pabyBlockBuf) == -1 )
 
2046
                                 (uint32 *) poGDS->pabyBlockBuf) == -1
 
2047
                && !poGDS->bIgnoreReadErrors )
1501
2048
            {
1502
2049
                /* Once TIFFError() is properly hooked, this can go away */
1503
2050
                CPLError( CE_Failure, CPLE_AppDefined,
1512
2059
        {
1513
2060
            if( TIFFReadRGBAStrip(poGDS->hTIFF, 
1514
2061
                                  nBlockId * nBlockYSize,
1515
 
                                  (uint32 *) poGDS->pabyBlockBuf) == -1 )
 
2062
                                  (uint32 *) poGDS->pabyBlockBuf) == -1
 
2063
                && !poGDS->bIgnoreReadErrors )
1516
2064
            {
1517
2065
                /* Once TIFFError() is properly hooked, this can go away */
1518
2066
                CPLError( CE_Failure, CPLE_AppDefined,
1556
2104
                       nBlockXSize );
1557
2105
    }
1558
2106
 
 
2107
    if (eErr == CE_None)
 
2108
        eErr = FillCacheForOtherBands(nBlockXOff, nBlockYOff);
 
2109
 
1559
2110
    return eErr;
1560
2111
}
1561
2112
 
1632
2183
    int         nBlockId;
1633
2184
    CPLErr      eErr = CE_None;
1634
2185
 
 
2186
    if (poGDS->bWriteErrorInFlushBlockBuf)
 
2187
    {
 
2188
        /* Report as an error if a previously loaded block couldn't be */
 
2189
        /* written correctly */
 
2190
        poGDS->bWriteErrorInFlushBlockBuf = FALSE;
 
2191
        return CE_Failure;
 
2192
    }
 
2193
 
1635
2194
    if (!poGDS->SetDirectory())
1636
2195
        return CE_Failure;
1637
2196
 
1650
2209
/* -------------------------------------------------------------------- */
1651
2210
/*      Load the block buffer.                                          */
1652
2211
/* -------------------------------------------------------------------- */
 
2212
    CPLAssert(nBlocksPerRow != 0);
1653
2213
    nBlockId = nBlockXOff + nBlockYOff * nBlocksPerRow;
1654
2214
 
1655
2215
    if( poGDS->nPlanarConfig == PLANARCONFIG_SEPARATE )
1661
2221
    if( eErr != CE_None )
1662
2222
        return eErr;
1663
2223
 
 
2224
    GUInt32 nMaxVal = (1 << poGDS->nBitsPerSample) - 1;
 
2225
 
1664
2226
/* -------------------------------------------------------------------- */
1665
2227
/*      Handle case of "separate" images or single band images where    */
1666
2228
/*      no interleaving with other data is required.                    */
1700
2262
 
1701
2263
            for( iX = 0; iX < nBlockXSize; iX++ )
1702
2264
            {
1703
 
                int  nInWord = 0;
 
2265
                GUInt32  nInWord = 0;
1704
2266
                if( eDataType == GDT_Byte )
1705
2267
                    nInWord = ((GByte *) pImage)[iPixel++];
1706
2268
                else if( eDataType == GDT_UInt16 )
1710
2272
                else
1711
2273
                    CPLAssert(0);
1712
2274
 
 
2275
                if (nInWord > nMaxVal)
 
2276
                {
 
2277
                    nInWord = nMaxVal;
 
2278
                    if( !poGDS->bClipWarn )
 
2279
                    {
 
2280
                        poGDS->bClipWarn = TRUE;
 
2281
                        CPLError( CE_Warning, CPLE_AppDefined,
 
2282
                                  "One or more pixels clipped to fit %d bit domain.", poGDS->nBitsPerSample );
 
2283
                    }
 
2284
                }
1713
2285
 
1714
2286
                if (poGDS->nBitsPerSample == 24)
1715
2287
                {
1803
2375
 
1804
2376
            for( iX = 0; iX < nBlockXSize; iX++ )
1805
2377
            {
1806
 
                int  nInWord = 0;
 
2378
                GUInt32  nInWord = 0;
1807
2379
                if( eDataType == GDT_Byte )
1808
2380
                    nInWord = ((GByte *) pabyThisImage)[iPixel++];
1809
2381
                else if( eDataType == GDT_UInt16 )
1813
2385
                else
1814
2386
                    CPLAssert(0);
1815
2387
 
 
2388
                if (nInWord > nMaxVal)
 
2389
                {
 
2390
                    nInWord = nMaxVal;
 
2391
                    if( !poGDS->bClipWarn )
 
2392
                    {
 
2393
                        poGDS->bClipWarn = TRUE;
 
2394
                        CPLError( CE_Warning, CPLE_AppDefined,
 
2395
                                  "One or more pixels clipped to fit %d bit domain.", poGDS->nBitsPerSample );
 
2396
                    }
 
2397
                }
1816
2398
 
1817
2399
                if (poGDS->nBitsPerSample == 24)
1818
2400
                {
1883
2465
    if (!poGDS->SetDirectory())
1884
2466
        return CE_Failure;
1885
2467
 
 
2468
    CPLAssert(nBlocksPerRow != 0);
1886
2469
    nBlockId = nBlockXOff + nBlockYOff * nBlocksPerRow;
1887
2470
 
1888
2471
    if( poGDS->nPlanarConfig == PLANARCONFIG_SEPARATE )
1919
2502
            int iSrcOffset, iPixel;
1920
2503
 
1921
2504
            iSrcOffset = ((nBlockXSize+7) >> 3) * 8 * iLine;
 
2505
            
 
2506
            GByte bSetVal = (poGDS->bPromoteTo8Bits) ? 255 : 1;
1922
2507
 
1923
2508
            for( iPixel = 0; iPixel < nBlockXSize; iPixel++, iSrcOffset++ )
1924
2509
            {
1925
2510
                if( pabyBlockBuf[iSrcOffset >>3] & (0x80 >> (iSrcOffset & 0x7)) )
1926
 
                    ((GByte *) pImage)[iDstOffset++] = 1;
 
2511
                    ((GByte *) pImage)[iDstOffset++] = bSetVal;
1927
2512
                else
1928
2513
                    ((GByte *) pImage)[iDstOffset++] = 0;
1929
2514
            }
2170
2755
        poColorTable = poDS->poColorTable->Clone();
2171
2756
    else
2172
2757
    {
 
2758
#ifdef ESRI_BUILD
 
2759
        poColorTable = NULL;
 
2760
#else
2173
2761
        GDALColorEntry  oWhite, oBlack;
2174
2762
 
2175
2763
        oWhite.c1 = 255;
2194
2782
            poColorTable->SetColorEntry( 0, &oBlack );
2195
2783
            poColorTable->SetColorEntry( 1, &oWhite );
2196
2784
        }
 
2785
#endif /* not defined ESRI_BUILD */
2197
2786
    }
2198
2787
}
2199
2788
 
2214
2803
GDALColorInterp GTiffBitmapBand::GetColorInterpretation()
2215
2804
 
2216
2805
{
2217
 
    return GCI_PaletteIndex;
 
2806
    if (poGDS->bPromoteTo8Bits)
 
2807
        return GCI_Undefined;
 
2808
    else
 
2809
        return GCI_PaletteIndex;
2218
2810
}
2219
2811
 
2220
2812
/************************************************************************/
2224
2816
GDALColorTable *GTiffBitmapBand::GetColorTable()
2225
2817
 
2226
2818
{
2227
 
    return poColorTable;
 
2819
    if (poGDS->bPromoteTo8Bits)
 
2820
        return NULL;
 
2821
    else
 
2822
        return poColorTable;
2228
2823
}
2229
2824
 
2230
2825
/************************************************************************/
2293
2888
 
2294
2889
    while( poGDS->nLastLineRead < nBlockYOff )
2295
2890
    {
2296
 
        if( TIFFReadScanline( poGDS->hTIFF, poGDS->pabyBlockBuf, ++poGDS->nLastLineRead, 0 ) == -1 )
 
2891
        if( TIFFReadScanline( poGDS->hTIFF, poGDS->pabyBlockBuf, ++poGDS->nLastLineRead, 0 ) == -1
 
2892
            && !poGDS->bIgnoreReadErrors )
2297
2893
        {
2298
2894
            CPLError( CE_Failure, CPLE_AppDefined,
2299
2895
                      "TIFFReadScanline() failed." );
2351
2947
    nLoadedBlock = -1;
2352
2948
    bLoadedBlockDirty = FALSE;
2353
2949
    pabyBlockBuf = NULL;
 
2950
    bWriteErrorInFlushBlockBuf = FALSE;
2354
2951
    hTIFF = NULL;
2355
2952
    bNeedsRewrite = FALSE;
2356
2953
    bMetadataChanged = FALSE;
2397
2994
    nLastBandRead = -1;
2398
2995
    bTreatAsSplit = FALSE;
2399
2996
    bTreatAsSplitBitmap = FALSE;
 
2997
    bClipWarn = FALSE;
 
2998
    bHasWarnedDisableAggressiveBandCaching = FALSE;
2400
2999
    bDontReloadFirstBlock = FALSE;
 
3000
 
 
3001
    nZLevel = -1;
 
3002
    nLZMAPreset = -1;
 
3003
    nJpegQuality = -1;
 
3004
    
 
3005
    bPromoteTo8Bits = FALSE;
 
3006
 
 
3007
    bDebugDontWriteBlocks = CSLTestBoolean(CPLGetConfigOption("GTIFF_DONT_WRITE_BLOCKS", "NO"));
 
3008
 
 
3009
    bIsFinalized = FALSE;
 
3010
    bIgnoreReadErrors = CSLTestBoolean(CPLGetConfigOption("GTIFF_IGNORE_READ_ERRORS", "NO"));
 
3011
 
 
3012
    bHasSearchedRPC = FALSE;
 
3013
    bHasSearchedIMD = FALSE;
 
3014
 
 
3015
    bScanDeferred = TRUE;
 
3016
 
 
3017
    bDirectIO = CSLTestBoolean(CPLGetConfigOption("GTIFF_DIRECT_IO", "NO"));
2401
3018
}
2402
3019
 
2403
3020
/************************************************************************/
2407
3024
GTiffDataset::~GTiffDataset()
2408
3025
 
2409
3026
{
 
3027
    Finalize();
 
3028
}
 
3029
 
 
3030
/************************************************************************/
 
3031
/*                             Finalize()                               */
 
3032
/************************************************************************/
 
3033
 
 
3034
int GTiffDataset::Finalize()
 
3035
{
 
3036
    if (bIsFinalized)
 
3037
        return FALSE;
 
3038
 
 
3039
    int bHasDroppedRef = FALSE;
 
3040
 
2410
3041
    Crystalize();
2411
3042
 
2412
3043
/* -------------------------------------------------------------------- */
 
3044
/*      Handle forcing xml:ESRI data to be written to PAM.              */
 
3045
/* -------------------------------------------------------------------- */
 
3046
    if( CSLTestBoolean(CPLGetConfigOption( "ESRI_XML_PAM", "NO" )) )
 
3047
    {
 
3048
        char **papszESRIMD = GetMetadata("xml:ESRI");
 
3049
        if( papszESRIMD )
 
3050
        {
 
3051
            GDALPamDataset::SetMetadata( papszESRIMD, "xml:ESRI");
 
3052
        }
 
3053
    }
 
3054
 
 
3055
/* -------------------------------------------------------------------- */
2413
3056
/*      Ensure any blocks write cached by GDAL gets pushed through libtiff.*/
2414
3057
/* -------------------------------------------------------------------- */
2415
3058
    GDALPamDataset::FlushCache();
2448
3091
        for( int i = 0; i < nOverviewCount; i++ )
2449
3092
        {
2450
3093
            delete papoOverviewDS[i];
 
3094
            bHasDroppedRef = TRUE;
2451
3095
        }
 
3096
        nOverviewCount = 0;
2452
3097
    }
2453
3098
 
2454
3099
    /* If we are a mask dataset, we can have overviews, but we don't */
2455
3100
    /* own them. We can only free the array, not the overviews themselves */
2456
3101
    CPLFree( papoOverviewDS );
 
3102
    papoOverviewDS = NULL;
2457
3103
 
2458
3104
    /* poMaskDS is owned by the main image and the overviews */
2459
3105
    /* so because of the latter case, we can delete it even if */
2460
3106
    /* we are not the base image */
2461
3107
    if (poMaskDS)
 
3108
    {
2462
3109
        delete poMaskDS;
 
3110
        poMaskDS = NULL;
 
3111
        bHasDroppedRef = TRUE;
 
3112
    }
2463
3113
 
2464
3114
    if( poColorTable != NULL )
2465
3115
        delete poColorTable;
 
3116
    poColorTable = NULL;
2466
3117
 
2467
3118
    if( bBase || bCloseTIFFHandle )
2468
3119
    {
2469
3120
        XTIFFClose( hTIFF );
 
3121
        hTIFF = NULL;
2470
3122
    }
2471
3123
 
2472
3124
    if( nGCPCount > 0 )
2473
3125
    {
2474
3126
        GDALDeinitGCPs( nGCPCount, pasGCPList );
2475
3127
        CPLFree( pasGCPList );
 
3128
        pasGCPList = NULL;
 
3129
        nGCPCount = 0;
2476
3130
    }
2477
3131
 
2478
3132
    CPLFree( pszProjection );
 
3133
    pszProjection = NULL;
2479
3134
 
2480
3135
    CSLDestroy( papszCreationOptions );
 
3136
    papszCreationOptions = NULL;
2481
3137
 
2482
3138
    CPLFree(pabyTempWriteBuffer);
 
3139
    pabyTempWriteBuffer = NULL;
2483
3140
 
2484
3141
    if( *ppoActiveDSRef == this )
2485
3142
        *ppoActiveDSRef = NULL;
 
3143
    ppoActiveDSRef = NULL;
 
3144
 
 
3145
    bIsFinalized = TRUE;
 
3146
 
 
3147
    return bHasDroppedRef;
 
3148
}
 
3149
 
 
3150
/************************************************************************/
 
3151
/*                        CloseDependentDatasets()                      */
 
3152
/************************************************************************/
 
3153
 
 
3154
int GTiffDataset::CloseDependentDatasets()
 
3155
{
 
3156
    if (!bBase)
 
3157
        return FALSE;
 
3158
 
 
3159
    int bHasDroppedRef = GDALPamDataset::CloseDependentDatasets();
 
3160
 
 
3161
    bHasDroppedRef |= Finalize();
 
3162
 
 
3163
    return bHasDroppedRef;
2486
3164
}
2487
3165
 
2488
3166
/************************************************************************/
2514
3192
    else
2515
3193
        TIFFGetField( hTIFF, TIFFTAG_STRIPBYTECOUNTS, &panByteCounts );
2516
3194
 
 
3195
    if (panByteCounts == NULL)
 
3196
    {
 
3197
        /* Got here with libtiff 3.9.3 and tiff_write_8 test */
 
3198
        CPLError(CE_Failure, CPLE_AppDefined, "FillEmptyTiles() failed because panByteCounts == NULL");
 
3199
        return;
 
3200
    }
 
3201
 
2517
3202
/* -------------------------------------------------------------------- */
2518
3203
/*      Prepare a blank data buffer to write for uninitialized blocks.  */
2519
3204
/* -------------------------------------------------------------------- */
2538
3223
    for( iBlock = 0; iBlock < nBlockCount; iBlock++ )
2539
3224
    {
2540
3225
        if( panByteCounts[iBlock] == 0 )
2541
 
            WriteEncodedTileOrStrip( iBlock, pabyData, FALSE );
 
3226
        {
 
3227
            if( WriteEncodedTileOrStrip( iBlock, pabyData, FALSE ) != CE_None )
 
3228
                break;
 
3229
        }
2542
3230
    }
2543
3231
 
2544
3232
    CPLFree( pabyData );
2548
3236
/*                        WriteEncodedTile()                            */
2549
3237
/************************************************************************/
2550
3238
 
2551
 
int GTiffDataset::WriteEncodedTile(uint32 tile, void* data,
 
3239
int GTiffDataset::WriteEncodedTile(uint32 tile, GByte *pabyData,
2552
3240
                                   int bPreserveDataBuffer)
2553
3241
{
2554
 
    /* TIFFWriteEncodedTile can alter the passed buffer if byte-swapping is necessary */
2555
 
    /* so we use a temporary buffer before calling it */
2556
3242
    int cc = TIFFTileSize( hTIFF );
2557
 
    if (bPreserveDataBuffer && TIFFIsByteSwapped(hTIFF))
 
3243
    int bNeedTileFill = FALSE;
 
3244
    int iRow=0, iColumn=0;
 
3245
    int nBlocksPerRow=1, nBlocksPerColumn=1;
 
3246
 
 
3247
    /* 
 
3248
    ** Do we need to spread edge values right or down for a partial 
 
3249
    ** JPEG encoded tile?  We do this to avoid edge artifacts. 
 
3250
    */
 
3251
    if( nCompression == COMPRESSION_JPEG )
 
3252
    {
 
3253
        nBlocksPerRow = (nRasterXSize + nBlockXSize - 1) / nBlockXSize;
 
3254
        nBlocksPerColumn = (nRasterYSize + nBlockYSize - 1) / nBlockYSize;
 
3255
 
 
3256
        iColumn = (tile % nBlocksPerBand) % nBlocksPerRow;
 
3257
        iRow = (tile % nBlocksPerBand) / nBlocksPerRow;
 
3258
 
 
3259
        // Is this a partial right edge tile?
 
3260
        if( iRow == nBlocksPerRow - 1
 
3261
            && nRasterXSize % nBlockXSize != 0 )
 
3262
            bNeedTileFill = TRUE;
 
3263
 
 
3264
        // Is this a partial bottom edge tile?
 
3265
        if( iColumn == nBlocksPerColumn - 1
 
3266
            && nRasterYSize % nBlockYSize != 0 )
 
3267
            bNeedTileFill = TRUE;
 
3268
    }
 
3269
 
 
3270
    /* 
 
3271
    ** If we need to fill out the tile, or if we want to prevent
 
3272
    ** TIFFWriteEncodedTile from altering the buffer as part of
 
3273
    ** byte swapping the data on write then we will need a temporary
 
3274
    ** working buffer.  If not, we can just do a direct write. 
 
3275
    */
 
3276
    if (bPreserveDataBuffer 
 
3277
        && (TIFFIsByteSwapped(hTIFF) || bNeedTileFill) )
2558
3278
    {
2559
3279
        if (cc != nTempWriteBufferSize)
2560
3280
        {
2561
3281
            pabyTempWriteBuffer = CPLRealloc(pabyTempWriteBuffer, cc);
2562
3282
            nTempWriteBufferSize = cc;
2563
3283
        }
2564
 
        memcpy(pabyTempWriteBuffer, data, cc);
2565
 
        return TIFFWriteEncodedTile(hTIFF, tile, pabyTempWriteBuffer, cc);
2566
 
    }
2567
 
    else
2568
 
        return TIFFWriteEncodedTile(hTIFF, tile, data, cc);
 
3284
        memcpy(pabyTempWriteBuffer, pabyData, cc);
 
3285
 
 
3286
        pabyData = (GByte *) pabyTempWriteBuffer;
 
3287
    }
 
3288
 
 
3289
    /*
 
3290
    ** Perform tile fill if needed.
 
3291
    */
 
3292
    if( bNeedTileFill )
 
3293
    {
 
3294
        int nRightPixelsToFill = 0;
 
3295
        int nBottomPixelsToFill = 0;
 
3296
        int nPixelSize = cc / (nBlockXSize * nBlockYSize);
 
3297
        unsigned int iX, iY, iSrcX, iSrcY;
 
3298
        
 
3299
        CPLDebug( "GTiff", "Filling out jpeg edge tile on write." );
 
3300
 
 
3301
        if( iColumn == nBlocksPerRow - 1 )
 
3302
            nRightPixelsToFill = nBlockXSize * (iColumn+1) - nRasterXSize;
 
3303
        if( iRow == nBlocksPerColumn - 1 )
 
3304
            nBottomPixelsToFill = nBlockYSize * (iRow+1) - nRasterYSize;
 
3305
 
 
3306
        // Fill out to the right. 
 
3307
        iSrcX = nBlockXSize - nRightPixelsToFill - 1;
 
3308
 
 
3309
        for( iX = iSrcX+1; iX < nBlockXSize; iX++ )
 
3310
        {
 
3311
            for( iY = 0; iY < nBlockYSize; iY++ )
 
3312
            {
 
3313
                memcpy( pabyData + (nBlockXSize * iY + iX) * nPixelSize, 
 
3314
                        pabyData + (nBlockXSize * iY + iSrcX) * nPixelSize, 
 
3315
                        nPixelSize );
 
3316
            }
 
3317
        }
 
3318
 
 
3319
        // now fill out the bottom.
 
3320
        iSrcY = nBlockYSize - nBottomPixelsToFill - 1;
 
3321
        for( iY = iSrcY+1; iY < nBlockYSize; iY++ )
 
3322
        {
 
3323
            memcpy( pabyData + nBlockXSize * nPixelSize * iY, 
 
3324
                    pabyData + nBlockXSize * nPixelSize * iSrcY, 
 
3325
                    nPixelSize * nBlockXSize );
 
3326
        }
 
3327
    }
 
3328
 
 
3329
    return TIFFWriteEncodedTile(hTIFF, tile, pabyData, cc);
2569
3330
}
2570
3331
 
2571
3332
/************************************************************************/
2572
3333
/*                        WriteEncodedStrip()                           */
2573
3334
/************************************************************************/
2574
3335
 
2575
 
int  GTiffDataset::WriteEncodedStrip(uint32 strip, void* data,
 
3336
int  GTiffDataset::WriteEncodedStrip(uint32 strip, GByte* pabyData,
2576
3337
                                     int bPreserveDataBuffer)
2577
3338
{
2578
3339
    int cc = TIFFStripSize( hTIFF );
2604
3365
            pabyTempWriteBuffer = CPLRealloc(pabyTempWriteBuffer, cc);
2605
3366
            nTempWriteBufferSize = cc;
2606
3367
        }
2607
 
        memcpy(pabyTempWriteBuffer, data, cc);
 
3368
        memcpy(pabyTempWriteBuffer, pabyData, cc);
2608
3369
        return TIFFWriteEncodedStrip(hTIFF, strip, pabyTempWriteBuffer, cc);
2609
3370
    }
2610
3371
    else
2611
 
        return TIFFWriteEncodedStrip(hTIFF, strip, data, cc);
 
3372
        return TIFFWriteEncodedStrip(hTIFF, strip, pabyData, cc);
2612
3373
}
2613
3374
 
2614
3375
/************************************************************************/
2622
3383
 
2623
3384
    if( TIFFIsTiled( hTIFF ) )
2624
3385
    {
2625
 
        if( WriteEncodedTile(tile_or_strip, data, bPreserveDataBuffer) == -1 )
 
3386
        if( WriteEncodedTile(tile_or_strip, (GByte*) data, 
 
3387
                             bPreserveDataBuffer) == -1 )
2626
3388
        {
2627
3389
            eErr = CE_Failure;
2628
3390
        }
2629
3391
    }
2630
3392
    else
2631
3393
    {
2632
 
        if( WriteEncodedStrip(tile_or_strip, data, bPreserveDataBuffer) == -1 )
 
3394
        if( WriteEncodedStrip(tile_or_strip, (GByte *) data, 
 
3395
                              bPreserveDataBuffer) == -1 )
2633
3396
        {
2634
3397
            eErr = CE_Failure;
2635
3398
        }
2660
3423
    {
2661
3424
        CPLError( CE_Failure, CPLE_AppDefined,
2662
3425
                    "WriteEncodedTile/Strip() failed." );
 
3426
        bWriteErrorInFlushBlockBuf = TRUE;
2663
3427
    }
2664
3428
 
2665
3429
    return eErr;
2778
3542
    if( TIFFIsTiled( hTIFF ) )
2779
3543
    {
2780
3544
        if( TIFFReadEncodedTile(hTIFF, nBlockId, pabyBlockBuf,
2781
 
                                nBlockReqSize) == -1 )
 
3545
                                nBlockReqSize) == -1
 
3546
            && !bIgnoreReadErrors )
2782
3547
        {
2783
3548
            /* Once TIFFError() is properly hooked, this can go away */
2784
3549
            CPLError( CE_Failure, CPLE_AppDefined,
2792
3557
    else
2793
3558
    {
2794
3559
        if( TIFFReadEncodedStrip(hTIFF, nBlockId, pabyBlockBuf,
2795
 
                                 nBlockReqSize) == -1 )
 
3560
                                 nBlockReqSize) == -1
 
3561
            && !bIgnoreReadErrors )
2796
3562
        {
2797
3563
            /* Once TIFFError() is properly hooked, this can go away */
2798
3564
            CPLError( CE_Failure, CPLE_AppDefined,
2835
3601
 
2836
3602
        TIFFWriteCheck( hTIFF, TIFFIsTiled(hTIFF), "GTiffDataset::Crystalize");
2837
3603
 
2838
 
        // Keep zip and tiff quality, and jpegcolormode which get reset when we call 
 
3604
        // Keep zip and tiff quality, and jpegcolormode which get reset when we call 
2839
3605
        // TIFFWriteDirectory 
2840
3606
        int jquality = -1, zquality = -1, nColorMode = -1; 
2841
3607
        TIFFGetField(hTIFF, TIFFTAG_JPEGQUALITY, &jquality); 
2896
3662
void GTiffDataset::FlushCache()
2897
3663
 
2898
3664
{
 
3665
    if (bIsFinalized)
 
3666
        return;
 
3667
 
2899
3668
    GDALPamDataset::FlushCache();
2900
3669
 
2901
3670
    if( bLoadedBlockDirty && nLoadedBlock != -1 )
2940
3709
        if( bNeedsRewrite )
2941
3710
        {
2942
3711
#if defined(TIFFLIB_VERSION)
2943
 
/* We need at least TIFF 3.7.0 for TIFFGetSizeProc and TIFFClientdata */
2944
 
#if  TIFFLIB_VERSION > 20041016
 
3712
#if defined(HAVE_TIFFGETSIZEPROC)
2945
3713
            if (!SetDirectory())
2946
3714
                return;
2947
3715
 
2968
3736
    // there are some circumstances in which we can reach this point
2969
3737
    // without having made this our directory (SetDirectory()) in which
2970
3738
    // case we should not risk a flush. 
2971
 
    if( TIFFCurrentDirOffset(hTIFF) == nDirOffset )
2972
 
        TIFFFlush( hTIFF );
 
3739
    if( GetAccess() == GA_Update && TIFFCurrentDirOffset(hTIFF) == nDirOffset )
 
3740
    {
 
3741
#if defined(BIGTIFF_SUPPORT)
 
3742
        TIFFSizeProc pfnSizeProc = TIFFGetSizeProc( hTIFF );
 
3743
 
 
3744
        toff_t nNewDirOffset = pfnSizeProc( TIFFClientdata( hTIFF ) );
 
3745
        if( (nNewDirOffset % 2) == 1 )
 
3746
            nNewDirOffset++;
 
3747
 
 
3748
        TIFFFlush( hTIFF );
 
3749
 
 
3750
        if( nDirOffset != TIFFCurrentDirOffset( hTIFF ) )
 
3751
        {
 
3752
            nDirOffset = nNewDirOffset;
 
3753
            CPLDebug( "GTiff", 
 
3754
                      "directory moved during flush in FlushDirectory()" );
 
3755
        }
 
3756
#else
 
3757
        /* For libtiff 3.X, the above causes regressions and crashes in */
 
3758
        /* tiff_write.py and tiff_ovr.py */
 
3759
        TIFFFlush( hTIFF );
 
3760
#endif
 
3761
    }
2973
3762
}
2974
3763
 
2975
3764
/************************************************************************/
3007
3796
{
3008
3797
    CPLAssert( bBase );
3009
3798
 
 
3799
    ScanDirectories();
 
3800
 
3010
3801
    FlushDirectory();
3011
3802
    *ppoActiveDSRef = NULL;
3012
3803
 
3040
3831
            {
3041
3832
                CPLDebug( "GTiff", "%d -> %d", 
3042
3833
                          (int) anOvDirOffsets[i], iThisOffset );
3043
 
                anOvDirIndexes.push_back( iThisOffset );
 
3834
                anOvDirIndexes.push_back( (uint16) iThisOffset );
3044
3835
            }
3045
3836
        }
3046
3837
        
3073
3864
    return CE_None;
3074
3865
}
3075
3866
 
 
3867
 
 
3868
/************************************************************************/
 
3869
/*                   RegisterNewOverviewDataset()                       */
 
3870
/************************************************************************/
 
3871
 
 
3872
CPLErr GTiffDataset::RegisterNewOverviewDataset(toff_t nOverviewOffset)
 
3873
{
 
3874
    GTiffDataset* poODS = new GTiffDataset();
 
3875
    poODS->nJpegQuality = nJpegQuality;
 
3876
    poODS->nZLevel = nZLevel;
 
3877
    poODS->nLZMAPreset = nLZMAPreset;
 
3878
 
 
3879
    if( nCompression == COMPRESSION_JPEG )
 
3880
    {
 
3881
        if ( CPLGetConfigOption( "JPEG_QUALITY_OVERVIEW", NULL ) != NULL )
 
3882
        {
 
3883
            poODS->nJpegQuality =  atoi(CPLGetConfigOption("JPEG_QUALITY_OVERVIEW","75"));
 
3884
        }
 
3885
        TIFFSetField( hTIFF, TIFFTAG_JPEGQUALITY,
 
3886
                        poODS->nJpegQuality );
 
3887
    }
 
3888
 
 
3889
    if( poODS->OpenOffset( hTIFF, ppoActiveDSRef, nOverviewOffset, FALSE,
 
3890
                            GA_Update ) != CE_None )
 
3891
    {
 
3892
        delete poODS;
 
3893
        return CE_Failure;
 
3894
    }
 
3895
    else
 
3896
    {
 
3897
        nOverviewCount++;
 
3898
        papoOverviewDS = (GTiffDataset **)
 
3899
            CPLRealloc(papoOverviewDS,
 
3900
                        nOverviewCount * (sizeof(void*)));
 
3901
        papoOverviewDS[nOverviewCount-1] = poODS;
 
3902
        poODS->poBaseDS = this;
 
3903
        return CE_None;
 
3904
    }
 
3905
}
 
3906
 
 
3907
/************************************************************************/
 
3908
/*                  CreateOverviewsFromSrcOverviews()                   */
 
3909
/************************************************************************/
 
3910
 
 
3911
CPLErr GTiffDataset::CreateOverviewsFromSrcOverviews(GDALDataset* poSrcDS)
 
3912
{
 
3913
    CPLAssert(poSrcDS->GetRasterCount() != 0);
 
3914
    CPLAssert(nOverviewCount == 0);
 
3915
 
 
3916
    ScanDirectories();
 
3917
 
 
3918
/* -------------------------------------------------------------------- */
 
3919
/*      Move to the directory for this dataset.                         */
 
3920
/* -------------------------------------------------------------------- */
 
3921
    if (!SetDirectory())
 
3922
        return CE_Failure;
 
3923
    FlushDirectory();
 
3924
 
 
3925
    int nOvBitsPerSample = nBitsPerSample;
 
3926
 
 
3927
/* -------------------------------------------------------------------- */
 
3928
/*      Do we have a palette?  If so, create a TIFF compatible version. */
 
3929
/* -------------------------------------------------------------------- */
 
3930
    std::vector<unsigned short> anTRed, anTGreen, anTBlue;
 
3931
    unsigned short      *panRed=NULL, *panGreen=NULL, *panBlue=NULL;
 
3932
 
 
3933
    if( nPhotometric == PHOTOMETRIC_PALETTE && poColorTable != NULL )
 
3934
    {
 
3935
        int nColors;
 
3936
 
 
3937
        if( nOvBitsPerSample == 8 )
 
3938
            nColors = 256;
 
3939
        else if( nOvBitsPerSample < 8 )
 
3940
            nColors = 1 << nOvBitsPerSample;
 
3941
        else
 
3942
            nColors = 65536;
 
3943
 
 
3944
        anTRed.resize(nColors,0);
 
3945
        anTGreen.resize(nColors,0);
 
3946
        anTBlue.resize(nColors,0);
 
3947
 
 
3948
        for( int iColor = 0; iColor < nColors; iColor++ )
 
3949
        {
 
3950
            if( iColor < poColorTable->GetColorEntryCount() )
 
3951
            {
 
3952
                GDALColorEntry  sRGB;
 
3953
 
 
3954
                poColorTable->GetColorEntryAsRGB( iColor, &sRGB );
 
3955
 
 
3956
                anTRed[iColor] = (unsigned short) (256 * sRGB.c1);
 
3957
                anTGreen[iColor] = (unsigned short) (256 * sRGB.c2);
 
3958
                anTBlue[iColor] = (unsigned short) (256 * sRGB.c3);
 
3959
            }
 
3960
            else
 
3961
            {
 
3962
                anTRed[iColor] = anTGreen[iColor] = anTBlue[iColor] = 0;
 
3963
            }
 
3964
        }
 
3965
 
 
3966
        panRed = &(anTRed[0]);
 
3967
        panGreen = &(anTGreen[0]);
 
3968
        panBlue = &(anTBlue[0]);
 
3969
    }
 
3970
 
 
3971
/* -------------------------------------------------------------------- */
 
3972
/*      Do we need some metadata for the overviews?                     */
 
3973
/* -------------------------------------------------------------------- */
 
3974
    CPLString osMetadata;
 
3975
 
 
3976
    GTIFFBuildOverviewMetadata( "NONE", this, osMetadata );
 
3977
 
 
3978
/* -------------------------------------------------------------------- */
 
3979
/*      Fetch extra sample tag                                          */
 
3980
/* -------------------------------------------------------------------- */
 
3981
    uint16 *panExtraSampleValues = NULL;
 
3982
    uint16 nExtraSamples = 0;
 
3983
 
 
3984
    if( TIFFGetField( hTIFF, TIFFTAG_EXTRASAMPLES, &nExtraSamples, &panExtraSampleValues) )
 
3985
    {
 
3986
        uint16* panExtraSampleValuesNew = (uint16*) CPLMalloc(nExtraSamples * sizeof(uint16));
 
3987
        memcpy(panExtraSampleValuesNew, panExtraSampleValues, nExtraSamples * sizeof(uint16));
 
3988
        panExtraSampleValues = panExtraSampleValuesNew;
 
3989
    }
 
3990
    else
 
3991
    {
 
3992
        panExtraSampleValues = NULL;
 
3993
        nExtraSamples = 0;
 
3994
    }
 
3995
 
 
3996
/* -------------------------------------------------------------------- */
 
3997
/*      Fetch predictor tag                                             */
 
3998
/* -------------------------------------------------------------------- */
 
3999
    uint16 nPredictor = PREDICTOR_NONE;
 
4000
    if ( nCompression == COMPRESSION_LZW ||
 
4001
         nCompression == COMPRESSION_ADOBE_DEFLATE )
 
4002
        TIFFGetField( hTIFF, TIFFTAG_PREDICTOR, &nPredictor );
 
4003
    int nOvrBlockXSize, nOvrBlockYSize;
 
4004
    GTIFFGetOverviewBlockSize(&nOvrBlockXSize, &nOvrBlockYSize);
 
4005
 
 
4006
    int nSrcOverviews = poSrcDS->GetRasterBand(1)->GetOverviewCount();
 
4007
    int i;
 
4008
    CPLErr eErr = CE_None;
 
4009
 
 
4010
    for(i=0;i<nSrcOverviews && eErr == CE_None;i++)
 
4011
    {
 
4012
        GDALRasterBand* poOvrBand = poSrcDS->GetRasterBand(1)->GetOverview(i);
 
4013
 
 
4014
        int         nOXSize = poOvrBand->GetXSize(), nOYSize = poOvrBand->GetYSize();
 
4015
 
 
4016
        toff_t nOverviewOffset =
 
4017
                GTIFFWriteDirectory(hTIFF, FILETYPE_REDUCEDIMAGE,
 
4018
                                    nOXSize, nOYSize,
 
4019
                                    nOvBitsPerSample, nPlanarConfig,
 
4020
                                    nSamplesPerPixel, nOvrBlockXSize, nOvrBlockYSize, TRUE,
 
4021
                                    nCompression, nPhotometric, nSampleFormat,
 
4022
                                    nPredictor,
 
4023
                                    panRed, panGreen, panBlue,
 
4024
                                    nExtraSamples, panExtraSampleValues,
 
4025
                                    osMetadata );
 
4026
 
 
4027
        if( nOverviewOffset == 0 )
 
4028
            eErr = CE_Failure;
 
4029
        else
 
4030
            eErr = RegisterNewOverviewDataset(nOverviewOffset);
 
4031
    }
 
4032
 
 
4033
    CPLFree(panExtraSampleValues);
 
4034
    panExtraSampleValues = NULL;
 
4035
 
 
4036
/* -------------------------------------------------------------------- */
 
4037
/*      Create overviews for the mask.                                  */
 
4038
/* -------------------------------------------------------------------- */
 
4039
    if (eErr == CE_None)
 
4040
        eErr = CreateInternalMaskOverviews(nOvrBlockXSize, nOvrBlockYSize);
 
4041
 
 
4042
    return eErr;
 
4043
}
 
4044
 
 
4045
 
 
4046
/************************************************************************/
 
4047
/*                       CreateInternalMaskOverviews()                  */
 
4048
/************************************************************************/
 
4049
 
 
4050
CPLErr GTiffDataset::CreateInternalMaskOverviews(int nOvrBlockXSize,
 
4051
                                                 int nOvrBlockYSize)
 
4052
{
 
4053
    GTiffDataset *poODS;
 
4054
 
 
4055
    ScanDirectories();
 
4056
 
 
4057
/* -------------------------------------------------------------------- */
 
4058
/*      Create overviews for the mask.                                  */
 
4059
/* -------------------------------------------------------------------- */
 
4060
    CPLErr eErr = CE_None;
 
4061
 
 
4062
    if (poMaskDS != NULL &&
 
4063
        poMaskDS->GetRasterCount() == 1 &&
 
4064
        CSLTestBoolean(CPLGetConfigOption("GDAL_TIFF_INTERNAL_MASK", "NO")))
 
4065
    {
 
4066
        int nMaskOvrCompression;
 
4067
        if( strstr(GDALGetMetadataItem(GDALGetDriverByName( "GTiff" ),
 
4068
                                       GDAL_DMD_CREATIONOPTIONLIST, NULL ),
 
4069
                   "<Value>DEFLATE</Value>") != NULL )
 
4070
            nMaskOvrCompression = COMPRESSION_ADOBE_DEFLATE;
 
4071
        else
 
4072
            nMaskOvrCompression = COMPRESSION_PACKBITS;
 
4073
 
 
4074
        int i;
 
4075
        for( i = 0; i < nOverviewCount; i++ )
 
4076
        {
 
4077
            if (papoOverviewDS[i]->poMaskDS == NULL)
 
4078
            {
 
4079
                toff_t  nOverviewOffset;
 
4080
 
 
4081
                nOverviewOffset =
 
4082
                    GTIFFWriteDirectory(hTIFF, FILETYPE_REDUCEDIMAGE | FILETYPE_MASK,
 
4083
                                        papoOverviewDS[i]->nRasterXSize, papoOverviewDS[i]->nRasterYSize,
 
4084
                                        1, PLANARCONFIG_CONTIG,
 
4085
                                        1, nOvrBlockXSize, nOvrBlockYSize, TRUE,
 
4086
                                        nMaskOvrCompression, PHOTOMETRIC_MASK, SAMPLEFORMAT_UINT, PREDICTOR_NONE,
 
4087
                                        NULL, NULL, NULL, 0, NULL,
 
4088
                                        "" );
 
4089
 
 
4090
                if( nOverviewOffset == 0 )
 
4091
                {
 
4092
                    eErr = CE_Failure;
 
4093
                    continue;
 
4094
                }
 
4095
 
 
4096
                poODS = new GTiffDataset();
 
4097
                if( poODS->OpenOffset( hTIFF, ppoActiveDSRef,
 
4098
                                       nOverviewOffset, FALSE,
 
4099
                                       GA_Update ) != CE_None )
 
4100
                {
 
4101
                    delete poODS;
 
4102
                    eErr = CE_Failure;
 
4103
                }
 
4104
                else
 
4105
                {
 
4106
                    poODS->bPromoteTo8Bits = CSLTestBoolean(CPLGetConfigOption("GDAL_TIFF_INTERNAL_MASK_TO_8BIT", "YES"));
 
4107
                    poODS->poBaseDS = this;
 
4108
                    papoOverviewDS[i]->poMaskDS = poODS;
 
4109
                    poMaskDS->nOverviewCount++;
 
4110
                    poMaskDS->papoOverviewDS = (GTiffDataset **)
 
4111
                    CPLRealloc(poMaskDS->papoOverviewDS,
 
4112
                               poMaskDS->nOverviewCount * (sizeof(void*)));
 
4113
                    poMaskDS->papoOverviewDS[poMaskDS->nOverviewCount-1] = poODS;
 
4114
                }
 
4115
            }
 
4116
        }
 
4117
    }
 
4118
 
 
4119
    return eErr;
 
4120
}
 
4121
 
3076
4122
/************************************************************************/
3077
4123
/*                          IBuildOverviews()                           */
3078
4124
/************************************************************************/
3087
4133
    CPLErr       eErr = CE_None;
3088
4134
    int          i;
3089
4135
    GTiffDataset *poODS;
 
4136
    int          bUseGenericHandling = FALSE;
 
4137
 
 
4138
    ScanDirectories();
 
4139
 
 
4140
/* -------------------------------------------------------------------- */
 
4141
/*      If RRD or external OVR overviews requested, then invoke         */
 
4142
/*      generic handling.                                               */
 
4143
/* -------------------------------------------------------------------- */
 
4144
    if( CSLTestBoolean(CPLGetConfigOption( "USE_RRD", "NO" )) 
 
4145
        || CSLTestBoolean(CPLGetConfigOption( "TIFF_USE_OVR", "NO" )) )
 
4146
    {
 
4147
        bUseGenericHandling = TRUE;
 
4148
    }
3090
4149
 
3091
4150
/* -------------------------------------------------------------------- */
3092
4151
/*      If we don't have read access, then create the overviews         */
3098
4157
                  "File open for read-only accessing, "
3099
4158
                  "creating overviews externally." );
3100
4159
 
3101
 
        return GDALDataset::IBuildOverviews( 
3102
 
            pszResampling, nOverviews, panOverviewList, 
3103
 
            nBands, panBandList, pfnProgress, pProgressData );
 
4160
        bUseGenericHandling = TRUE;
3104
4161
    }
3105
4162
 
3106
 
/* -------------------------------------------------------------------- */
3107
 
/*      If RRD overviews requested, then invoke generic handling.       */
3108
 
/* -------------------------------------------------------------------- */
3109
 
    if( CSLTestBoolean(CPLGetConfigOption( "USE_RRD", "NO" )) )
 
4163
    if( bUseGenericHandling )
3110
4164
    {
3111
 
        return GDALDataset::IBuildOverviews( 
3112
 
            pszResampling, nOverviews, panOverviewList, 
 
4165
        if (nOverviewCount != 0)
 
4166
        {
 
4167
            CPLError(CE_Failure, CPLE_NotSupported,
 
4168
                     "Cannot add external overviews when there are already internal overviews");
 
4169
            return CE_Failure;
 
4170
        }
 
4171
 
 
4172
        return GDALDataset::IBuildOverviews(
 
4173
            pszResampling, nOverviews, panOverviewList,
3113
4174
            nBands, panBandList, pfnProgress, pProgressData );
3114
4175
    }
3115
4176
 
3235
4296
    }
3236
4297
 
3237
4298
/* -------------------------------------------------------------------- */
 
4299
/*      Fetch predictor tag                                             */
 
4300
/* -------------------------------------------------------------------- */
 
4301
    uint16 nPredictor = PREDICTOR_NONE;
 
4302
    if ( nCompression == COMPRESSION_LZW ||
 
4303
         nCompression == COMPRESSION_ADOBE_DEFLATE )
 
4304
        TIFFGetField( hTIFF, TIFFTAG_PREDICTOR, &nPredictor );
 
4305
 
 
4306
/* -------------------------------------------------------------------- */
3238
4307
/*      Establish which of the overview levels we already have, and     */
3239
4308
/*      which are new.  We assume that band 1 of the file is            */
3240
4309
/*      representative.                                                 */
3241
4310
/* -------------------------------------------------------------------- */
 
4311
    int nOvrBlockXSize, nOvrBlockYSize;
 
4312
    GTIFFGetOverviewBlockSize(&nOvrBlockXSize, &nOvrBlockYSize);
3242
4313
    for( i = 0; i < nOverviews && eErr == CE_None; i++ )
3243
4314
    {
3244
4315
        int   j;
3245
4316
 
3246
 
        for( j = 0; j < nOverviewCount; j++ )
 
4317
        for( j = 0; j < nOverviewCount && eErr == CE_None; j++ )
3247
4318
        {
3248
4319
            int    nOvFactor;
3249
4320
 
3272
4343
                GTIFFWriteDirectory(hTIFF, FILETYPE_REDUCEDIMAGE,
3273
4344
                                    nOXSize, nOYSize, 
3274
4345
                                    nOvBitsPerSample, nPlanarConfig,
3275
 
                                    nSamplesPerPixel, 128, 128, TRUE,
 
4346
                                    nSamplesPerPixel, nOvrBlockXSize, nOvrBlockYSize, TRUE,
3276
4347
                                    nCompression, nPhotometric, nSampleFormat, 
 
4348
                                    nPredictor,
3277
4349
                                    panRed, panGreen, panBlue,
3278
4350
                                    nExtraSamples, panExtraSampleValues,
3279
4351
                                    osMetadata );
3280
4352
 
 
4353
 
3281
4354
            if( nOverviewOffset == 0 )
3282
 
            {
3283
 
                eErr = CE_Failure;
3284
 
                continue;
3285
 
            }
3286
 
 
3287
 
            poODS = new GTiffDataset();
3288
 
            if( poODS->OpenOffset( hTIFF, ppoActiveDSRef, nOverviewOffset, FALSE, 
3289
 
                                   GA_Update ) != CE_None )
3290
 
            {
3291
 
                delete poODS;
3292
 
                eErr = CE_Failure;
3293
 
            }
 
4355
                eErr = CE_Failure;
3294
4356
            else
3295
 
            {
3296
 
                nOverviewCount++;
3297
 
                papoOverviewDS = (GTiffDataset **)
3298
 
                    CPLRealloc(papoOverviewDS, 
3299
 
                               nOverviewCount * (sizeof(void*)));
3300
 
                papoOverviewDS[nOverviewCount-1] = poODS;
3301
 
                poODS->poBaseDS = this;
3302
 
            }
 
4357
                eErr = RegisterNewOverviewDataset(nOverviewOffset);
3303
4358
        }
3304
4359
        else
3305
4360
            panOverviewList[i] *= -1;
3311
4366
/* -------------------------------------------------------------------- */
3312
4367
/*      Create overviews for the mask.                                  */
3313
4368
/* -------------------------------------------------------------------- */
3314
 
 
3315
 
    if (poMaskDS != NULL &&
3316
 
        poMaskDS->GetRasterCount() == 1 &&
3317
 
        CSLTestBoolean(CPLGetConfigOption("GDAL_TIFF_INTERNAL_MASK", "NO")))
3318
 
    {
3319
 
        for( i = 0; i < nOverviewCount; i++ )
3320
 
        {
3321
 
            if (papoOverviewDS[i]->poMaskDS == NULL)
3322
 
            {
3323
 
                toff_t  nOverviewOffset;
3324
 
 
3325
 
                nOverviewOffset = 
3326
 
                    GTIFFWriteDirectory(hTIFF, FILETYPE_REDUCEDIMAGE | FILETYPE_MASK,
3327
 
                                        papoOverviewDS[i]->nRasterXSize, papoOverviewDS[i]->nRasterYSize, 
3328
 
                                        1, PLANARCONFIG_CONTIG,
3329
 
                                        1, 128, 128, TRUE,
3330
 
                                        COMPRESSION_NONE, PHOTOMETRIC_MASK, SAMPLEFORMAT_UINT, 
3331
 
                                        NULL, NULL, NULL, 0, NULL,
3332
 
                                        "" );
3333
 
 
3334
 
                if( nOverviewOffset == 0 )
3335
 
                {
3336
 
                    eErr = CE_Failure;
3337
 
                    continue;
3338
 
                }
3339
 
 
3340
 
                poODS = new GTiffDataset();
3341
 
                if( poODS->OpenOffset( hTIFF, ppoActiveDSRef, 
3342
 
                                       nOverviewOffset, FALSE, 
3343
 
                                       GA_Update ) != CE_None )
3344
 
                {
3345
 
                    delete poODS;
3346
 
                    eErr = CE_Failure;
3347
 
                }
3348
 
                else
3349
 
                {
3350
 
                    poODS->poBaseDS = this;
3351
 
                    papoOverviewDS[i]->poMaskDS = poODS;
3352
 
                    poMaskDS->nOverviewCount++;
3353
 
                    poMaskDS->papoOverviewDS = (GTiffDataset **)
3354
 
                    CPLRealloc(poMaskDS->papoOverviewDS, 
3355
 
                               poMaskDS->nOverviewCount * (sizeof(void*)));
3356
 
                    poMaskDS->papoOverviewDS[poMaskDS->nOverviewCount-1] = poODS;
3357
 
                }
3358
 
            }
3359
 
        }
3360
 
    }
 
4369
    if (eErr == CE_None)
 
4370
        eErr = CreateInternalMaskOverviews(nOvrBlockXSize, nOvrBlockYSize);
 
4371
    else
 
4372
        return eErr;
3361
4373
 
3362
4374
/* -------------------------------------------------------------------- */
3363
4375
/*      Refresh overviews for the mask                                  */
3544
4556
void GTiffDataset::WriteGeoTIFFInfo()
3545
4557
 
3546
4558
{
 
4559
    bool bPixelIsPoint = false;
 
4560
    int  bPointGeoIgnore = FALSE;
 
4561
 
 
4562
    if( GetMetadataItem( GDALMD_AREA_OR_POINT ) 
 
4563
        && EQUAL(GetMetadataItem(GDALMD_AREA_OR_POINT),
 
4564
                 GDALMD_AOP_POINT) )
 
4565
    {
 
4566
        bPixelIsPoint = true;
 
4567
        bPointGeoIgnore = 
 
4568
            CSLTestBoolean( CPLGetConfigOption("GTIFF_POINT_GEO_IGNORE",
 
4569
                                               "FALSE") );
 
4570
    }
 
4571
 
3547
4572
/* -------------------------------------------------------------------- */
3548
4573
/*      If the geotransform is the default, don't bother writing it.    */
3549
4574
/* -------------------------------------------------------------------- */
3567
4592
/*      Write the transform.  If we have a normal north-up image we     */
3568
4593
/*      use the tiepoint plus pixelscale otherwise we use a matrix.     */
3569
4594
/* -------------------------------------------------------------------- */
3570
 
        if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 
3571
 
            && adfGeoTransform[5] < 0.0 )
3572
 
        {
3573
 
            double      adfPixelScale[3], adfTiePoints[6];
 
4595
        if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0
 
4596
                && adfGeoTransform[5] < 0.0 )
 
4597
        {
 
4598
            double      adfPixelScale[3], adfTiePoints[6];
3574
4599
 
3575
 
            adfPixelScale[0] = adfGeoTransform[1];
3576
 
            adfPixelScale[1] = fabs(adfGeoTransform[5]);
3577
 
            adfPixelScale[2] = 0.0;
 
4600
            adfPixelScale[0] = adfGeoTransform[1];
 
4601
            adfPixelScale[1] = fabs(adfGeoTransform[5]);
 
4602
            adfPixelScale[2] = 0.0;
3578
4603
 
3579
4604
            if( !EQUAL(osProfile,"BASELINE") )
3580
4605
                TIFFSetField( hTIFF, TIFFTAG_GEOPIXELSCALE, 3, adfPixelScale );
3581
 
            
3582
 
            adfTiePoints[0] = 0.0;
3583
 
            adfTiePoints[1] = 0.0;
3584
 
            adfTiePoints[2] = 0.0;
3585
 
            adfTiePoints[3] = adfGeoTransform[0];
3586
 
            adfTiePoints[4] = adfGeoTransform[3];
3587
 
            adfTiePoints[5] = 0.0;
3588
 
            
 
4606
 
 
4607
            adfTiePoints[0] = 0.0;
 
4608
            adfTiePoints[1] = 0.0;
 
4609
            adfTiePoints[2] = 0.0;
 
4610
            adfTiePoints[3] = adfGeoTransform[0];
 
4611
            adfTiePoints[4] = adfGeoTransform[3];
 
4612
            adfTiePoints[5] = 0.0;
 
4613
 
 
4614
            if( bPixelIsPoint && !bPointGeoIgnore )
 
4615
            {
 
4616
                adfTiePoints[3] += adfGeoTransform[1] * 0.5 + adfGeoTransform[2] * 0.5;
 
4617
                adfTiePoints[4] += adfGeoTransform[4] * 0.5 + adfGeoTransform[5] * 0.5;
 
4618
            }
 
4619
 
3589
4620
            if( !EQUAL(osProfile,"BASELINE") )
3590
4621
                TIFFSetField( hTIFF, TIFFTAG_GEOTIEPOINTS, 6, adfTiePoints );
3591
 
        }
3592
 
        else
3593
 
        {
3594
 
            double      adfMatrix[16];
3595
 
            
3596
 
            memset(adfMatrix,0,sizeof(double) * 16);
3597
 
            
3598
 
            adfMatrix[0] = adfGeoTransform[1];
3599
 
            adfMatrix[1] = adfGeoTransform[2];
3600
 
            adfMatrix[3] = adfGeoTransform[0];
3601
 
            adfMatrix[4] = adfGeoTransform[4];
3602
 
            adfMatrix[5] = adfGeoTransform[5];
3603
 
            adfMatrix[7] = adfGeoTransform[3];
3604
 
            adfMatrix[15] = 1.0;
3605
 
            
 
4622
        }
 
4623
        else
 
4624
        {
 
4625
            double      adfMatrix[16];
 
4626
 
 
4627
            memset(adfMatrix,0,sizeof(double) * 16);
 
4628
 
 
4629
            adfMatrix[0] = adfGeoTransform[1];
 
4630
            adfMatrix[1] = adfGeoTransform[2];
 
4631
            adfMatrix[3] = adfGeoTransform[0];
 
4632
            adfMatrix[4] = adfGeoTransform[4];
 
4633
            adfMatrix[5] = adfGeoTransform[5];
 
4634
            adfMatrix[7] = adfGeoTransform[3];
 
4635
            adfMatrix[15] = 1.0;
 
4636
 
 
4637
            if( bPixelIsPoint && !bPointGeoIgnore )
 
4638
            {
 
4639
                adfMatrix[3] += adfGeoTransform[1] * 0.5 + adfGeoTransform[2] * 0.5;
 
4640
                adfMatrix[7] += adfGeoTransform[4] * 0.5 + adfGeoTransform[5] * 0.5;
 
4641
            }
 
4642
 
3606
4643
            if( !EQUAL(osProfile,"BASELINE") )
3607
4644
                TIFFSetField( hTIFF, TIFFTAG_GEOTRANSMATRIX, 16, adfMatrix );
3608
 
        }
 
4645
        }
3609
4646
 
3610
4647
        // Do we need a world file?
3611
4648
        if( CSLFetchBoolean( papszCreationOptions, "TFW", FALSE ) )
3615
4652
    }
3616
4653
    else if( GetGCPCount() > 0 )
3617
4654
    {
3618
 
        double  *padfTiePoints;
3619
 
        int             iGCP;
 
4655
        double  *padfTiePoints;
 
4656
        int             iGCP;
 
4657
 
3620
4658
        bNeedsRewrite = TRUE;
3621
 
        
3622
 
        padfTiePoints = (double *) 
3623
 
            CPLMalloc( 6 * sizeof(double) * GetGCPCount() );
3624
 
 
3625
 
        for( iGCP = 0; iGCP < GetGCPCount(); iGCP++ )
3626
 
        {
3627
 
 
3628
 
            padfTiePoints[iGCP*6+0] = pasGCPList[iGCP].dfGCPPixel;
3629
 
            padfTiePoints[iGCP*6+1] = pasGCPList[iGCP].dfGCPLine;
3630
 
            padfTiePoints[iGCP*6+2] = 0;
3631
 
            padfTiePoints[iGCP*6+3] = pasGCPList[iGCP].dfGCPX;
3632
 
            padfTiePoints[iGCP*6+4] = pasGCPList[iGCP].dfGCPY;
3633
 
            padfTiePoints[iGCP*6+5] = pasGCPList[iGCP].dfGCPZ;
3634
 
        }
 
4659
 
 
4660
        padfTiePoints = (double *)
 
4661
            CPLMalloc( 6 * sizeof(double) * GetGCPCount() );
 
4662
 
 
4663
        for( iGCP = 0; iGCP < GetGCPCount(); iGCP++ )
 
4664
        {
 
4665
 
 
4666
            padfTiePoints[iGCP*6+0] = pasGCPList[iGCP].dfGCPPixel;
 
4667
            padfTiePoints[iGCP*6+1] = pasGCPList[iGCP].dfGCPLine;
 
4668
            padfTiePoints[iGCP*6+2] = 0;
 
4669
            padfTiePoints[iGCP*6+3] = pasGCPList[iGCP].dfGCPX;
 
4670
            padfTiePoints[iGCP*6+4] = pasGCPList[iGCP].dfGCPY;
 
4671
            padfTiePoints[iGCP*6+5] = pasGCPList[iGCP].dfGCPZ;
 
4672
 
 
4673
            if( bPixelIsPoint && !bPointGeoIgnore )
 
4674
            {
 
4675
                padfTiePoints[iGCP*6+0] += 0.5;
 
4676
                padfTiePoints[iGCP*6+1] += 0.5;
 
4677
            }
 
4678
        }
3635
4679
 
3636
4680
        if( !EQUAL(osProfile,"BASELINE") )
3637
4681
            TIFFSetField( hTIFF, TIFFTAG_GEOTIEPOINTS, 
3638
4682
                          6 * GetGCPCount(), padfTiePoints );
3639
 
        CPLFree( padfTiePoints );
 
4683
        CPLFree( padfTiePoints );
3640
4684
    }
3641
4685
 
3642
4686
/* -------------------------------------------------------------------- */
3671
4715
        // set according to coordinate system.
3672
4716
        GTIFSetFromOGISDefn( psGTIF, pszProjection );
3673
4717
 
3674
 
        if( GetMetadataItem( GDALMD_AREA_OR_POINT ) 
3675
 
            && EQUAL(GetMetadataItem(GDALMD_AREA_OR_POINT),
3676
 
                     GDALMD_AOP_POINT) )
 
4718
        if( bPixelIsPoint )
3677
4719
        {
3678
4720
            GTIFKeySet(psGTIF, GTRasterTypeGeoKey, TYPE_SHORT, 1,
3679
4721
                       RasterPixelIsPoint);
3769
4811
            continue; // ignored
3770
4812
        if( EQUAL(papszDomainList[iDomain], "RPC") )
3771
4813
            continue; // handled elsewhere
 
4814
        if( EQUAL(papszDomainList[iDomain], "xml:ESRI") 
 
4815
            && CSLTestBoolean(CPLGetConfigOption( "ESRI_XML_PAM", "NO" )) )
 
4816
            continue; // handled elsewhere
 
4817
 
3772
4818
        if( EQUALN(papszDomainList[iDomain], "xml:",4 ) )
3773
4819
            bIsXML = TRUE;
3774
4820
 
3811
4857
                else if( EQUAL(pszItemName,"TIFFTAG_COPYRIGHT") )
3812
4858
                    TIFFSetField( hTIFF, TIFFTAG_COPYRIGHT, pszItemValue );
3813
4859
                else if( EQUAL(pszItemName,"TIFFTAG_XRESOLUTION") )
3814
 
                    TIFFSetField( hTIFF, TIFFTAG_XRESOLUTION, atof(pszItemValue) );
 
4860
                    TIFFSetField( hTIFF, TIFFTAG_XRESOLUTION, CPLAtof(pszItemValue) );
3815
4861
                else if( EQUAL(pszItemName,"TIFFTAG_YRESOLUTION") )
3816
 
                    TIFFSetField( hTIFF, TIFFTAG_YRESOLUTION, atof(pszItemValue) );
 
4862
                    TIFFSetField( hTIFF, TIFFTAG_YRESOLUTION, CPLAtof(pszItemValue) );
3817
4863
                else if( EQUAL(pszItemName,"TIFFTAG_RESOLUTIONUNIT") )
3818
4864
                    TIFFSetField( hTIFF, TIFFTAG_RESOLUTIONUNIT, atoi(pszItemValue) );
 
4865
                else if( EQUAL(pszItemName,"TIFFTAG_MINSAMPLEVALUE") )
 
4866
                    TIFFSetField( hTIFF, TIFFTAG_MINSAMPLEVALUE, atoi(pszItemValue) );
 
4867
                else if( EQUAL(pszItemName,"TIFFTAG_MAXSAMPLEVALUE") )
 
4868
                    TIFFSetField( hTIFF, TIFFTAG_MAXSAMPLEVALUE, atoi(pszItemValue) );
 
4869
                else
 
4870
                    CPLError(CE_Warning, CPLE_NotSupported,
 
4871
                             "%s metadata item is unhandled and will not be written",
 
4872
                             pszItemName);
3819
4873
            }
3820
4874
            else if( nBand == 0 && EQUAL(pszItemName,GDALMD_AREA_OR_POINT) )
3821
4875
                /* do nothing, handled elsewhere */;
3933
4987
            AppendMetadataItem( &psRoot, &psTail, "SCALE", szValue, nBand, 
3934
4988
                                "scale", "" );
3935
4989
        }
 
4990
 
 
4991
        const char* pszUnitType = poBand->GetUnitType();
 
4992
        if (pszUnitType != NULL && pszUnitType[0] != '\0')
 
4993
            AppendMetadataItem( &psRoot, &psTail, "UNITTYPE", pszUnitType, nBand, 
 
4994
                                "unittype", "" );
3936
4995
    }
3937
4996
 
3938
4997
/* -------------------------------------------------------------------- */
3972
5031
 
3973
5032
        return bRet;
3974
5033
    }
 
5034
    else
 
5035
    {
 
5036
        /* If we have no more metadata but it existed before, remove the GDAL_METADATA tag */
 
5037
        if( EQUAL(pszProfile,"GDALGeoTIFF") )
 
5038
        {
 
5039
            char* pszText = NULL;
 
5040
            if( TIFFGetField( hTIFF, TIFFTAG_GDAL_METADATA, &pszText ) )
 
5041
            {
 
5042
#ifdef HAVE_UNSETFIELD
 
5043
                TIFFUnsetField( hTIFF, TIFFTAG_GDAL_METADATA );
 
5044
#else
 
5045
                TIFFSetField( hTIFF, TIFFTAG_GDAL_METADATA, "" );
 
5046
#endif
 
5047
            }
 
5048
        }
 
5049
    }
3975
5050
 
3976
5051
    return TRUE;
3977
5052
}
4046
5121
/* -------------------------------------------------------------------- */
4047
5122
        if( poBand != NULL )
4048
5123
        {
4049
 
            int bSuccess;
4050
 
            double dfOffset = poBand->GetOffset( &bSuccess );
4051
 
            double dfScale = poBand->GetScale();
4052
 
 
4053
 
            if( bSuccess && (dfOffset != 0.0 || dfScale != 1.0) )
4054
 
            {
4055
 
                poBand->GDALPamRasterBand::SetScale( dfScale );
4056
 
                poBand->GDALPamRasterBand::SetOffset( dfOffset );
4057
 
            }
 
5124
            poBand->GDALPamRasterBand::SetOffset( poBand->GetOffset() );
 
5125
            poBand->GDALPamRasterBand::SetScale( poBand->GetScale() );
 
5126
            poBand->GDALPamRasterBand::SetUnitType( poBand->GetUnitType() );
4058
5127
        }
4059
5128
    }
4060
5129
}
4206
5275
void GTiffDataset::WriteNoDataValue( TIFF *hTIFF, double dfNoData )
4207
5276
 
4208
5277
{
4209
 
    TIFFSetField( hTIFF, TIFFTAG_GDAL_NODATA, 
4210
 
                  CPLString().Printf( "%.18g", dfNoData ).c_str() );
 
5278
    char szVal[400];
 
5279
    if (CPLIsNan(dfNoData))
 
5280
        strcpy(szVal, "nan");
 
5281
        else
 
5282
        snprintf(szVal, sizeof(szVal), "%.18g", dfNoData);
 
5283
    TIFFSetField( hTIFF, TIFFTAG_GDAL_NODATA, szVal );
4211
5284
}
4212
5285
 
4213
5286
/************************************************************************/
4231
5304
        return TRUE;
4232
5305
    }
4233
5306
 
4234
 
    int jquality = -1, zquality = -1; 
4235
 
 
4236
5307
    if( GetAccess() == GA_Update )
4237
5308
    {
4238
 
        TIFFGetField(hTIFF, TIFFTAG_JPEGQUALITY, &jquality); 
4239
 
        TIFFGetField(hTIFF, TIFFTAG_ZIPQUALITY, &zquality); 
4240
 
 
4241
5309
        if( *ppoActiveDSRef != NULL )
4242
5310
            (*ppoActiveDSRef)->FlushDirectory();
4243
5311
    }
4279
5347
/* -------------------------------------------------------------------- */
4280
5348
    if( GetAccess() == GA_Update )
4281
5349
    {
4282
 
        // Now, reset zip and jpeg quality. 
4283
 
        if(jquality > 0) 
 
5350
        // Now, reset zip and jpeg quality.
 
5351
        if(nJpegQuality > 0 && nCompression == COMPRESSION_JPEG)
4284
5352
        {
4285
5353
            CPLDebug( "GTiff", "Propgate JPEG_QUALITY(%d) in SetDirectory()",
4286
 
                      jquality );
4287
 
            TIFFSetField(hTIFF, TIFFTAG_JPEGQUALITY, jquality); 
 
5354
                      nJpegQuality );
 
5355
            TIFFSetField(hTIFF, TIFFTAG_JPEGQUALITY, nJpegQuality); 
4288
5356
        }
4289
 
        if(zquality > 0) 
4290
 
            TIFFSetField(hTIFF, TIFFTAG_ZIPQUALITY, zquality);
 
5357
        if(nZLevel > 0 && nCompression == COMPRESSION_ADOBE_DEFLATE)
 
5358
            TIFFSetField(hTIFF, TIFFTAG_ZIPQUALITY, nZLevel);
 
5359
        if(nLZMAPreset > 0 && nCompression == COMPRESSION_LZMA)
 
5360
            TIFFSetField(hTIFF, TIFFTAG_LZMAPRESET, nLZMAPreset);
4291
5361
    }
4292
5362
 
4293
5363
    return nSetDirResult;
4376
5446
    if( EQUALN(pszFilename,"GTIFF_DIR:",strlen("GTIFF_DIR:")) )
4377
5447
        return OpenDir( poOpenInfo );
4378
5448
 
4379
 
    GTiffOneTimeInit();
 
5449
    if (!GTiffOneTimeInit())
 
5450
        return NULL;
4380
5451
 
4381
5452
/* -------------------------------------------------------------------- */
4382
5453
/*      Try opening the dataset.                                        */
4402
5473
    if( poDS->OpenOffset( hTIFF, &(poDS->poActiveDS),
4403
5474
                          TIFFCurrentDirOffset(hTIFF), TRUE,
4404
5475
                          poOpenInfo->eAccess, 
4405
 
                          bAllowRGBAInterface ) != CE_None )
 
5476
                          bAllowRGBAInterface, TRUE,
 
5477
                          poOpenInfo->papszSiblingFiles) != CE_None )
4406
5478
    {
4407
5479
        delete poDS;
4408
5480
        return NULL;
4411
5483
/* -------------------------------------------------------------------- */
4412
5484
/*      Initialize any PAM information.                                 */
4413
5485
/* -------------------------------------------------------------------- */
4414
 
    poDS->TryLoadXML();
 
5486
    poDS->TryLoadXML( poOpenInfo->papszSiblingFiles);
4415
5487
    poDS->ApplyPamInfo();
4416
5488
 
 
5489
    int i;
 
5490
    for(i=1;i<=poDS->nBands;i++)
 
5491
    {
 
5492
        GTiffRasterBand* poBand = (GTiffRasterBand*) poDS->GetRasterBand(i);
 
5493
 
 
5494
        /* Load scale, offset and unittype from PAM if available */
 
5495
        if (!poBand->bHaveOffsetScale)
 
5496
        {
 
5497
            poBand->dfScale = poBand->GDALPamRasterBand::GetScale(&poBand->bHaveOffsetScale);
 
5498
            poBand->dfOffset = poBand->GDALPamRasterBand::GetOffset();
 
5499
        }
 
5500
        if (poBand->osUnitType.size() == 0)
 
5501
        {
 
5502
            const char* pszUnitType = poBand->GDALPamRasterBand::GetUnitType();
 
5503
            if (pszUnitType)
 
5504
                poBand->osUnitType = pszUnitType;
 
5505
        }
 
5506
    }
 
5507
 
4417
5508
    poDS->bMetadataChanged = FALSE;
4418
5509
    poDS->bGeoTIFFInfoChanged = FALSE;
4419
5510
 
4420
5511
/* -------------------------------------------------------------------- */
4421
5512
/*      Check for external overviews.                                   */
4422
5513
/* -------------------------------------------------------------------- */
4423
 
    poDS->oOvManager.Initialize( poDS, pszFilename );
 
5514
    poDS->oOvManager.Initialize( poDS, pszFilename, poOpenInfo->papszSiblingFiles );
4424
5515
    
4425
5516
    return poDS;
4426
5517
}
4481
5572
        // Is this a pixel-is-point dataset?
4482
5573
        short nRasterType;
4483
5574
 
 
5575
        // check the tif linear unit and the CS linear unit 
 
5576
#ifdef ESRI_BUILD
 
5577
        AdjustLinearUnit(sGTIFDefn.UOMLength); 
 
5578
#endif
 
5579
 
4484
5580
        if( GTIFKeyGet(hGTIF, GTRasterTypeGeoKey, &nRasterType, 
4485
5581
                       0, 1 ) == 1 )
4486
5582
        {
4502
5598
}
4503
5599
 
4504
5600
/************************************************************************/
 
5601
/*                          AdjustLinearUnit()                          */
 
5602
/*                                                                      */
 
5603
/*      The following code is only used in ESRI Builds and there is     */
 
5604
/*      outstanding discussion on whether it is even appropriate        */
 
5605
/*      then.                                                           */
 
5606
/************************************************************************/
 
5607
#ifdef ESRI_BUILD
 
5608
 
 
5609
void GTiffDataset::AdjustLinearUnit(short UOMLength)
 
5610
{
 
5611
    if (!pszProjection || strlen(pszProjection) == 0)
 
5612
        return;
 
5613
    if( UOMLength == 9001)
 
5614
    {
 
5615
        char* pstr = strstr(pszProjection, "PARAMETER");
 
5616
        if (!pstr)
 
5617
            return;
 
5618
        pstr = strstr(pstr, "UNIT[");
 
5619
        if (!pstr)
 
5620
            return;
 
5621
        pstr = strchr(pstr, ',') + 1;
 
5622
        if (!pstr)
 
5623
            return;
 
5624
        char* pstr1 = strchr(pstr, ']');
 
5625
        if (!pstr1 || pstr1 - pstr >= 128)
 
5626
            return;
 
5627
        char csUnitStr[128];
 
5628
        strncpy(csUnitStr, pstr, pstr1-pstr);
 
5629
        csUnitStr[pstr1-pstr] = '\0';
 
5630
        double csUnit = CPLAtof(csUnitStr);
 
5631
        if(fabs(csUnit - 1.0) > 0.000001)
 
5632
        {
 
5633
            for(long i=0; i<6; i++)
 
5634
                adfGeoTransform[i] /= csUnit;
 
5635
        }
 
5636
    }
 
5637
}
 
5638
 
 
5639
#endif /* def ESRI_BUILD */
 
5640
 
 
5641
/************************************************************************/
4505
5642
/*                            ApplyPamInfo()                            */
4506
5643
/*                                                                      */
4507
5644
/*      PAM Information, if available, overrides the GeoTIFF            */
4529
5666
    {
4530
5667
        CPLFree( pszProjection );
4531
5668
        pszProjection = CPLStrdup( pszPamSRS );
4532
 
        bLookedForProjection= TRUE;
 
5669
        bLookedForProjection = TRUE;
 
5670
    }
 
5671
 
 
5672
    int nPamGCPCount = GDALPamDataset::GetGCPCount();
 
5673
    if( nPamGCPCount > 0 )
 
5674
    {
 
5675
        if( nGCPCount > 0 )
 
5676
        {
 
5677
            GDALDeinitGCPs( nGCPCount, pasGCPList );
 
5678
            CPLFree( pasGCPList );
 
5679
            pasGCPList = NULL;
 
5680
        }
 
5681
 
 
5682
        nGCPCount = nPamGCPCount;
 
5683
        pasGCPList = GDALDuplicateGCPs(nGCPCount, GDALPamDataset::GetGCPs());
 
5684
 
 
5685
        CPLFree( pszProjection );
 
5686
        pszProjection = NULL;
 
5687
 
 
5688
        const char *pszPamGCPProjection = GDALPamDataset::GetGCPProjection();
 
5689
        if( pszPamGCPProjection != NULL && strlen(pszPamGCPProjection) > 0 )
 
5690
            pszProjection = CPLStrdup(pszPamGCPProjection);
 
5691
 
 
5692
        bLookedForProjection = TRUE;
4533
5693
    }
4534
5694
 
4535
5695
/* -------------------------------------------------------------------- */
4536
 
/*      Copy any PAM metadata into our GeoTIFF context, but with the    */
4537
 
/*      GeoTIFF context overriding the PAM info.                        */
 
5696
/*      Copy any PAM metadata into our GeoTIFF context, and with        */
 
5697
/*      the PAM info overriding the GeoTIFF context.                    */
4538
5698
/* -------------------------------------------------------------------- */
4539
5699
    char **papszPamDomains = oMDMD.GetDomainList();
4540
5700
 
4541
5701
    for( int iDomain = 0; papszPamDomains && papszPamDomains[iDomain] != NULL; iDomain++ )
4542
5702
    {
4543
5703
        const char *pszDomain = papszPamDomains[iDomain];
4544
 
        char **papszGT_MD = oGTiffMDMD.GetMetadata( pszDomain );
4545
 
        char **papszPAM_MD = CSLDuplicate(oMDMD.GetMetadata( pszDomain ));
4546
 
 
4547
 
        papszPAM_MD = CSLMerge( papszPAM_MD, papszGT_MD );
4548
 
 
4549
 
        oGTiffMDMD.SetMetadata( papszPAM_MD, pszDomain );
4550
 
        CSLDestroy( papszPAM_MD );
 
5704
        char **papszGT_MD = CSLDuplicate(oGTiffMDMD.GetMetadata( pszDomain ));
 
5705
        char **papszPAM_MD = oMDMD.GetMetadata( pszDomain );
 
5706
 
 
5707
        papszGT_MD = CSLMerge( papszGT_MD, papszPAM_MD );
 
5708
 
 
5709
        oGTiffMDMD.SetMetadata( papszGT_MD, pszDomain );
 
5710
        CSLDestroy( papszGT_MD );
4551
5711
    }
4552
5712
 
4553
5713
    for( int i = 1; i <= GetRasterCount(); i++)
4558
5718
        for( int iDomain = 0; papszPamDomains && papszPamDomains[iDomain] != NULL; iDomain++ )
4559
5719
        {
4560
5720
            const char *pszDomain = papszPamDomains[iDomain];
4561
 
            char **papszGT_MD = poBand->oGTiffMDMD.GetMetadata( pszDomain );
4562
 
            char **papszPAM_MD = CSLDuplicate(poBand->oMDMD.GetMetadata( pszDomain ));
4563
 
 
4564
 
            papszPAM_MD = CSLMerge( papszPAM_MD, papszGT_MD );
4565
 
 
4566
 
            poBand->oGTiffMDMD.SetMetadata( papszPAM_MD, pszDomain );
4567
 
            CSLDestroy( papszPAM_MD );
 
5721
            char **papszGT_MD = CSLDuplicate(poBand->oGTiffMDMD.GetMetadata( pszDomain ));
 
5722
            char **papszPAM_MD = poBand->oMDMD.GetMetadata( pszDomain );
 
5723
 
 
5724
            papszGT_MD = CSLMerge( papszGT_MD, papszPAM_MD );
 
5725
 
 
5726
            poBand->oGTiffMDMD.SetMetadata( papszGT_MD, pszDomain );
 
5727
            CSLDestroy( papszGT_MD );
4568
5728
        }
4569
5729
    }
4570
5730
}
4621
5781
/* -------------------------------------------------------------------- */
4622
5782
    TIFF        *hTIFF;
4623
5783
 
4624
 
    GTiffOneTimeInit();
 
5784
    if (!GTiffOneTimeInit())
 
5785
        return NULL;
4625
5786
 
4626
5787
    hTIFF = VSI_TIFFOpen( pszFilename, "r" );
4627
5788
    if( hTIFF == NULL )
4672
5833
    }
4673
5834
 
4674
5835
    if( poDS->OpenOffset( hTIFF, &(poDS->poActiveDS),
4675
 
                          nOffset, FALSE, GA_ReadOnly, bAllowRGBAInterface ) != CE_None )
 
5836
                          nOffset, FALSE, GA_ReadOnly,
 
5837
                          bAllowRGBAInterface, TRUE,
 
5838
                          poOpenInfo->papszSiblingFiles ) != CE_None )
4676
5839
    {
4677
5840
        delete poDS;
4678
5841
        return NULL;
4696
5859
                                 GTiffDataset **ppoActiveDSRef,
4697
5860
                                 toff_t nDirOffsetIn, 
4698
5861
                                 int bBaseIn, GDALAccess eAccess,
4699
 
                                 int bAllowRGBAInterface)
 
5862
                                 int bAllowRGBAInterface,
 
5863
                                 int bReadGeoTransform,
 
5864
                                 char** papszSiblingFiles )
4700
5865
 
4701
5866
{
4702
5867
    uint32      nXSize, nYSize;
4872
6037
    {
4873
6038
        /* libtiff 3.9.2 (20091104) and older, libtiff 4.0.0beta5 (also 20091104) */
4874
6039
        /* and older will crash when trying to open a all-in-one-strip */
4875
 
        /* YCbCr JPEG compressed TIFF (see #3259). BUG_3259_FIXED is defined */
4876
 
        /* in internal libtiff tif_config.h until a 4.0.0beta6 is released */
 
6040
        /* YCbCr JPEG compressed TIFF (see #3259). */
4877
6041
#if (TIFFLIB_VERSION <= 20091104 && !defined(BIGTIFF_SUPPORT)) || \
4878
 
    (TIFFLIB_VERSION <= 20091104 && defined(BIGTIFF_SUPPORT) && !defined(BUG_3259_FIXED))
 
6042
    (TIFFLIB_VERSION <= 20091104 && defined(BIGTIFF_SUPPORT))
4879
6043
        if (nPhotometric == PHOTOMETRIC_YCBCR  &&
4880
6044
            nCompression == COMPRESSION_JPEG)
4881
6045
        {
5009
6173
/* -------------------------------------------------------------------- */
5010
6174
/*      Get the transform or gcps from the GeoTIFF file.                */
5011
6175
/* -------------------------------------------------------------------- */
5012
 
    if( bBaseIn )
 
6176
    if( bReadGeoTransform )
5013
6177
    {
5014
6178
        char    *pszTabWKT = NULL;
5015
6179
        double  *padfTiePoints, *padfScale, *padfMatrix;
5016
6180
        uint16  nCount;
 
6181
        bool    bPixelIsPoint = false;
 
6182
        short nRasterType;
 
6183
        GTIF    *psGTIF;
 
6184
        int     bPointGeoIgnore = FALSE;
 
6185
 
 
6186
        psGTIF = GTIFNew( hTIFF ); // I wonder how expensive this is?
 
6187
 
 
6188
        if( psGTIF )
 
6189
        {
 
6190
            if( GTIFKeyGet(psGTIF, GTRasterTypeGeoKey, &nRasterType,
 
6191
                        0, 1 ) == 1
 
6192
                && nRasterType == (short) RasterPixelIsPoint )
 
6193
            {
 
6194
                bPixelIsPoint = true;
 
6195
                bPointGeoIgnore =
 
6196
                    CSLTestBoolean( CPLGetConfigOption("GTIFF_POINT_GEO_IGNORE",
 
6197
                                                    "FALSE") );
 
6198
            }
 
6199
 
 
6200
            GTIFFree( psGTIF );
 
6201
        }
5017
6202
 
5018
6203
        adfGeoTransform[0] = 0.0;
5019
6204
        adfGeoTransform[1] = 1.0;
5037
6222
                adfGeoTransform[3] =
5038
6223
                    padfTiePoints[4] - padfTiePoints[1] * adfGeoTransform[5];
5039
6224
 
 
6225
                if( bPixelIsPoint && !bPointGeoIgnore )
 
6226
                {
 
6227
                    adfGeoTransform[0] -= (adfGeoTransform[1] * 0.5 + adfGeoTransform[2] * 0.5);
 
6228
                    adfGeoTransform[3] -= (adfGeoTransform[4] * 0.5 + adfGeoTransform[5] * 0.5);
 
6229
                }
 
6230
 
5040
6231
                bGeoTransformValid = TRUE;
5041
6232
            }
5042
6233
        }
5050
6241
            adfGeoTransform[3] = padfMatrix[7];
5051
6242
            adfGeoTransform[4] = padfMatrix[4];
5052
6243
            adfGeoTransform[5] = padfMatrix[5];
 
6244
 
 
6245
            if( bPixelIsPoint && !bPointGeoIgnore )
 
6246
            {
 
6247
                adfGeoTransform[0] -= (adfGeoTransform[1] * 0.5 + adfGeoTransform[2] * 0.5);
 
6248
                adfGeoTransform[3] -= (adfGeoTransform[4] * 0.5 + adfGeoTransform[5] * 0.5);
 
6249
            }
 
6250
 
5053
6251
            bGeoTransformValid = TRUE;
5054
6252
        }
5055
6253
 
5058
6256
/* -------------------------------------------------------------------- */
5059
6257
        else
5060
6258
        {
5061
 
            bGeoTransformValid = 
5062
 
                GDALReadWorldFile( osFilename, NULL, adfGeoTransform );
 
6259
            char* pszWldFilename = NULL;
 
6260
 
 
6261
            bGeoTransformValid =
 
6262
                GDALReadWorldFile2( osFilename, NULL, adfGeoTransform,
 
6263
                                    papszSiblingFiles, &pszWldFilename);
5063
6264
 
5064
6265
            if( !bGeoTransformValid )
5065
6266
            {
5066
 
                bGeoTransformValid = 
5067
 
                    GDALReadWorldFile( osFilename, "wld", adfGeoTransform );
 
6267
                bGeoTransformValid =
 
6268
                    GDALReadWorldFile2( osFilename, "wld", adfGeoTransform,
 
6269
                                        papszSiblingFiles, &pszWldFilename);
5068
6270
            }
5069
6271
 
5070
6272
            if( !bGeoTransformValid )
5071
6273
            {
5072
 
                int bTabFileOK = 
5073
 
                    GDALReadTabFile( osFilename, adfGeoTransform, 
5074
 
                                     &pszTabWKT, &nGCPCount, &pasGCPList );
 
6274
                int bTabFileOK =
 
6275
                    GDALReadTabFile2( osFilename, adfGeoTransform,
 
6276
                                      &pszTabWKT, &nGCPCount, &pasGCPList,
 
6277
                                      papszSiblingFiles, &pszWldFilename );
5075
6278
 
5076
6279
                if( bTabFileOK && nGCPCount == 0 )
5077
6280
                    bGeoTransformValid = TRUE;
5078
6281
            }
 
6282
 
 
6283
            if (pszWldFilename)
 
6284
            {
 
6285
                osWldFilename = pszWldFilename;
 
6286
                CPLFree(pszWldFilename);
 
6287
            }
5079
6288
        }
5080
6289
 
5081
6290
/* -------------------------------------------------------------------- */
5100
6309
                pasGCPList[iGCP].dfGCPX = padfTiePoints[iGCP*6+3];
5101
6310
                pasGCPList[iGCP].dfGCPY = padfTiePoints[iGCP*6+4];
5102
6311
                pasGCPList[iGCP].dfGCPZ = padfTiePoints[iGCP*6+5];
 
6312
 
 
6313
                if( bPixelIsPoint && !bPointGeoIgnore )
 
6314
                {
 
6315
                    pasGCPList[iGCP].dfGCPPixel -= 0.5;
 
6316
                    pasGCPList[iGCP].dfGCPLine -= 0.5;
 
6317
                }
5103
6318
            }
5104
6319
        }
5105
6320
 
5185
6400
        SetMetadataItem( "TIFFTAG_RESOLUTIONUNIT", szWorkMDI );
5186
6401
    }
5187
6402
 
 
6403
    int nTagSize;
 
6404
    void* pData;
 
6405
    if( TIFFGetField( hTIFF, TIFFTAG_XMLPACKET, &nTagSize, &pData ) )
 
6406
    {
 
6407
        char* pszXMP = (char*)VSIMalloc(nTagSize + 1);
 
6408
        if (pszXMP)
 
6409
        {
 
6410
            memcpy(pszXMP, pData, nTagSize);
 
6411
            pszXMP[nTagSize] = '\0';
 
6412
 
 
6413
            char *apszMDList[2];
 
6414
            apszMDList[0] = pszXMP;
 
6415
            apszMDList[1] = NULL;
 
6416
            SetMetadata(apszMDList, "xml:XMP");
 
6417
 
 
6418
            CPLFree(pszXMP);
 
6419
        }
 
6420
    }
 
6421
 
5188
6422
    if( nCompression == COMPRESSION_NONE )
5189
6423
        /* no compression tag */;
5190
6424
    else if( nCompression == COMPRESSION_CCITTRLE )
5230
6464
        SetMetadataItem( "COMPRESSION", "SGILOG24", "IMAGE_STRUCTURE" );
5231
6465
    else if( nCompression == COMPRESSION_JP2000 )
5232
6466
        SetMetadataItem( "COMPRESSION", "JP2000", "IMAGE_STRUCTURE" );
 
6467
    else if( nCompression == COMPRESSION_LZMA )
 
6468
        SetMetadataItem( "COMPRESSION", "LZMA", "IMAGE_STRUCTURE" );
 
6469
 
5233
6470
    else
5234
6471
    {
5235
6472
        CPLString oComp;
5304
6541
                if( poBand != NULL )
5305
6542
                {
5306
6543
                    if( EQUAL(pszRole,"scale") )
5307
 
                        poBand->SetScale( atof(pszUnescapedValue) );
 
6544
                        poBand->SetScale( CPLAtofM(pszUnescapedValue) );
5308
6545
                    else if( EQUAL(pszRole,"offset") )
5309
 
                        poBand->SetOffset( atof(pszUnescapedValue) );
 
6546
                        poBand->SetOffset( CPLAtofM(pszUnescapedValue) );
 
6547
                    else if( EQUAL(pszRole,"unittype") )
 
6548
                        poBand->SetUnitType( pszUnescapedValue );
5310
6549
                    else
5311
6550
                    {
5312
6551
                        if( bIsXML )
5329
6568
    bMetadataChanged = FALSE;
5330
6569
 
5331
6570
/* -------------------------------------------------------------------- */
5332
 
/*      Check for RPC metadata in an RPB file.                          */
5333
 
/* -------------------------------------------------------------------- */
5334
 
    if( bBaseIn )
5335
 
    {
5336
 
        char **papszRPCMD = GDALLoadRPBFile( osFilename, NULL );
5337
 
        
5338
 
        if( papszRPCMD != NULL )
5339
 
        {
5340
 
            oGTiffMDMD.SetMetadata( papszRPCMD, "RPC" );
5341
 
            CSLDestroy( papszRPCMD );
5342
 
            bMetadataChanged = FALSE;
5343
 
        }
5344
 
        else
5345
 
            ReadRPCTag();
5346
 
    }
5347
 
 
5348
 
/* -------------------------------------------------------------------- */
5349
 
/*      Check for RPC metadata in an RPB file.                          */
5350
 
/* -------------------------------------------------------------------- */
5351
 
    if( bBaseIn )
5352
 
    {
5353
 
        char **papszIMDMD = GDALLoadIMDFile( osFilename, NULL );
5354
 
 
5355
 
        if( papszIMDMD != NULL )
5356
 
        {
5357
 
            oGTiffMDMD.SetMetadata( papszIMDMD, "IMD" );
5358
 
            CSLDestroy( papszIMDMD );
5359
 
            bMetadataChanged = FALSE;
5360
 
        }
5361
 
    }
5362
 
 
5363
 
/* -------------------------------------------------------------------- */
5364
6571
/*      Check for NODATA                                                */
5365
6572
/* -------------------------------------------------------------------- */
5366
6573
    if( TIFFGetField( hTIFF, TIFFTAG_GDAL_NODATA, &pszText ) )
5367
6574
    {
5368
6575
        bNoDataSet = TRUE;
5369
 
        dfNoDataValue = atof( pszText );
 
6576
        dfNoDataValue = CPLAtofM( pszText );
5370
6577
    }
5371
6578
 
5372
6579
/* -------------------------------------------------------------------- */
5375
6582
/* -------------------------------------------------------------------- */
5376
6583
    if( bBase )
5377
6584
    {
5378
 
        char **papszSubdatasets = NULL;
5379
 
        int  iDirIndex = 0;
5380
 
 
5381
 
        FlushDirectory();  
5382
 
        while( !TIFFLastDirectory( hTIFF ) 
5383
 
               && (iDirIndex == 0 || TIFFReadDirectory( hTIFF ) != 0) )
5384
 
        {
5385
 
            toff_t      nThisDir = TIFFCurrentDirOffset(hTIFF);
5386
 
            uint32      nSubType = 0;
5387
 
 
5388
 
            *ppoActiveDSRef = NULL; // our directory no longer matches this ds
5389
 
            
5390
 
            iDirIndex++;
5391
 
 
5392
 
            if( !TIFFGetField(hTIFF, TIFFTAG_SUBFILETYPE, &nSubType) )
5393
 
                nSubType = 0;
5394
 
 
5395
 
            /* Embedded overview of the main image */
5396
 
            if ((nSubType & FILETYPE_REDUCEDIMAGE) != 0 &&
5397
 
                (nSubType & FILETYPE_MASK) == 0 &&
5398
 
                iDirIndex != 1 )
5399
 
            {
5400
 
                GTiffDataset    *poODS;
5401
 
                
5402
 
                poODS = new GTiffDataset();
5403
 
                if( poODS->OpenOffset( hTIFF, ppoActiveDSRef, nThisDir, FALSE, 
5404
 
                                       eAccess ) != CE_None 
5405
 
                    || poODS->GetRasterCount() != GetRasterCount() )
5406
 
                {
5407
 
                    delete poODS;
5408
 
                }
5409
 
                else
5410
 
                {
5411
 
                    CPLDebug( "GTiff", "Opened %dx%d overview.\n", 
5412
 
                              poODS->GetRasterXSize(), poODS->GetRasterYSize());
5413
 
                    nOverviewCount++;
5414
 
                    papoOverviewDS = (GTiffDataset **)
5415
 
                        CPLRealloc(papoOverviewDS, 
5416
 
                                   nOverviewCount * (sizeof(void*)));
5417
 
                    papoOverviewDS[nOverviewCount-1] = poODS;
5418
 
                    poODS->poBaseDS = this;
5419
 
                }
5420
 
            }
5421
 
            
5422
 
            /* Embedded mask of the main image */
5423
 
            else if ((nSubType & FILETYPE_MASK) != 0 &&
5424
 
                     (nSubType & FILETYPE_REDUCEDIMAGE) == 0 &&
5425
 
                     poMaskDS == NULL )
5426
 
            {
5427
 
                poMaskDS = new GTiffDataset();
5428
 
                
5429
 
                /* The TIFF6 specification - page 37 - only allows 1 SamplesPerPixel and 1 BitsPerSample
5430
 
                   Here we support either 1 or 8 bit per sample
5431
 
                   and we support either 1 sample per pixel or as many samples as in the main image
5432
 
                   We don't check the value of the PhotometricInterpretation tag, which should be
5433
 
                   set to "Transparency mask" (4) according to the specification (page 36)
5434
 
                   ... But the TIFF6 specification allows image masks to have a higher resolution than
5435
 
                   the main image, what we don't support here
5436
 
                */
5437
 
 
5438
 
                if( poMaskDS->OpenOffset( hTIFF, ppoActiveDSRef, nThisDir, 
5439
 
                                          FALSE, eAccess ) != CE_None 
5440
 
                    || poMaskDS->GetRasterCount() == 0
5441
 
                    || !(poMaskDS->GetRasterCount() == 1 || poMaskDS->GetRasterCount() == GetRasterCount())
5442
 
                    || poMaskDS->GetRasterXSize() != GetRasterXSize()
5443
 
                    || poMaskDS->GetRasterYSize() != GetRasterYSize()
5444
 
                    || poMaskDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte)
5445
 
                {
5446
 
                    delete poMaskDS;
5447
 
                    poMaskDS = NULL;
5448
 
                }
5449
 
                else
5450
 
                {
5451
 
                    CPLDebug( "GTiff", "Opened band mask.\n");
5452
 
                    poMaskDS->poBaseDS = this;
5453
 
                }
5454
 
            }
5455
 
            
5456
 
            /* Embedded mask of an overview */
5457
 
            /* The TIFF6 specification allows the combination of the FILETYPE_xxxx masks */
5458
 
            else if (nSubType & (FILETYPE_REDUCEDIMAGE | FILETYPE_MASK))
5459
 
            {
5460
 
                GTiffDataset* poDS = new GTiffDataset();
5461
 
                if( poDS->OpenOffset( hTIFF, ppoActiveDSRef, nThisDir, FALSE, 
5462
 
                                      eAccess ) != CE_None
5463
 
                    || poDS->GetRasterCount() == 0
5464
 
                    || poDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte)
 
6585
        //ScanDirectories();
 
6586
    }
 
6587
 
 
6588
    return( CE_None );
 
6589
}
 
6590
 
 
6591
/************************************************************************/
 
6592
/*                          ScanDirectories()                           */
 
6593
/*                                                                      */
 
6594
/*      Scan through all the directories finding overviews, masks       */
 
6595
/*      and subdatasets.                                                */
 
6596
/************************************************************************/
 
6597
 
 
6598
void GTiffDataset::ScanDirectories()
 
6599
 
 
6600
{
 
6601
/* -------------------------------------------------------------------- */
 
6602
/*      We only scan once.  We do not scan for non-base datasets.       */
 
6603
/* -------------------------------------------------------------------- */
 
6604
    if( !bScanDeferred )
 
6605
        return;
 
6606
 
 
6607
    bScanDeferred = FALSE;
 
6608
 
 
6609
    if( !bBase )
 
6610
        return;
 
6611
 
 
6612
    if( TIFFLastDirectory( hTIFF ) )
 
6613
        return;
 
6614
 
 
6615
    CPLDebug( "GTiff", "ScanDirectories()" );
 
6616
 
 
6617
/* ==================================================================== */
 
6618
/*      Scan all directories.                                           */
 
6619
/* ==================================================================== */
 
6620
    char **papszSubdatasets = NULL;
 
6621
    int  iDirIndex = 0;
 
6622
 
 
6623
    FlushDirectory();  
 
6624
    while( !TIFFLastDirectory( hTIFF ) 
 
6625
           && (iDirIndex == 0 || TIFFReadDirectory( hTIFF ) != 0) )
 
6626
    {
 
6627
        toff_t  nThisDir = TIFFCurrentDirOffset(hTIFF);
 
6628
        uint32  nSubType = 0;
 
6629
 
 
6630
        *ppoActiveDSRef = NULL; // our directory no longer matches this ds
 
6631
            
 
6632
        iDirIndex++;
 
6633
 
 
6634
        if( !TIFFGetField(hTIFF, TIFFTAG_SUBFILETYPE, &nSubType) )
 
6635
            nSubType = 0;
 
6636
 
 
6637
        /* Embedded overview of the main image */
 
6638
        if ((nSubType & FILETYPE_REDUCEDIMAGE) != 0 &&
 
6639
            (nSubType & FILETYPE_MASK) == 0 &&
 
6640
            iDirIndex != 1 )
 
6641
        {
 
6642
            GTiffDataset        *poODS;
 
6643
                
 
6644
            poODS = new GTiffDataset();
 
6645
            if( poODS->OpenOffset( hTIFF, ppoActiveDSRef, nThisDir, FALSE, 
 
6646
                                   eAccess ) != CE_None 
 
6647
                || poODS->GetRasterCount() != GetRasterCount() )
 
6648
            {
 
6649
                delete poODS;
 
6650
            }
 
6651
            else
 
6652
            {
 
6653
                CPLDebug( "GTiff", "Opened %dx%d overview.\n", 
 
6654
                          poODS->GetRasterXSize(), poODS->GetRasterYSize());
 
6655
                nOverviewCount++;
 
6656
                papoOverviewDS = (GTiffDataset **)
 
6657
                    CPLRealloc(papoOverviewDS, 
 
6658
                               nOverviewCount * (sizeof(void*)));
 
6659
                papoOverviewDS[nOverviewCount-1] = poODS;
 
6660
                poODS->poBaseDS = this;
 
6661
            }
 
6662
        }
 
6663
            
 
6664
        /* Embedded mask of the main image */
 
6665
        else if ((nSubType & FILETYPE_MASK) != 0 &&
 
6666
                 (nSubType & FILETYPE_REDUCEDIMAGE) == 0 &&
 
6667
                 poMaskDS == NULL )
 
6668
        {
 
6669
            poMaskDS = new GTiffDataset();
 
6670
                
 
6671
            /* The TIFF6 specification - page 37 - only allows 1 SamplesPerPixel and 1 BitsPerSample
 
6672
               Here we support either 1 or 8 bit per sample
 
6673
               and we support either 1 sample per pixel or as many samples as in the main image
 
6674
               We don't check the value of the PhotometricInterpretation tag, which should be
 
6675
               set to "Transparency mask" (4) according to the specification (page 36)
 
6676
               ... But the TIFF6 specification allows image masks to have a higher resolution than
 
6677
               the main image, what we don't support here
 
6678
            */
 
6679
 
 
6680
            if( poMaskDS->OpenOffset( hTIFF, ppoActiveDSRef, nThisDir, 
 
6681
                                      FALSE, eAccess ) != CE_None 
 
6682
                || poMaskDS->GetRasterCount() == 0
 
6683
                || !(poMaskDS->GetRasterCount() == 1 || poMaskDS->GetRasterCount() == GetRasterCount())
 
6684
                || poMaskDS->GetRasterXSize() != GetRasterXSize()
 
6685
                || poMaskDS->GetRasterYSize() != GetRasterYSize()
 
6686
                || poMaskDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte)
 
6687
            {
 
6688
                delete poMaskDS;
 
6689
                poMaskDS = NULL;
 
6690
            }
 
6691
            else
 
6692
            {
 
6693
                CPLDebug( "GTiff", "Opened band mask.\n");
 
6694
                poMaskDS->poBaseDS = this;
 
6695
                    
 
6696
                poMaskDS->bPromoteTo8Bits = CSLTestBoolean(CPLGetConfigOption("GDAL_TIFF_INTERNAL_MASK_TO_8BIT", "YES"));
 
6697
            }
 
6698
        }
 
6699
            
 
6700
        /* Embedded mask of an overview */
 
6701
        /* The TIFF6 specification allows the combination of the FILETYPE_xxxx masks */
 
6702
        else if ((nSubType & FILETYPE_REDUCEDIMAGE) != 0 &&
 
6703
                 (nSubType & FILETYPE_MASK) != 0)
 
6704
        {
 
6705
            GTiffDataset* poDS = new GTiffDataset();
 
6706
            if( poDS->OpenOffset( hTIFF, ppoActiveDSRef, nThisDir, FALSE, 
 
6707
                                  eAccess ) != CE_None
 
6708
                || poDS->GetRasterCount() == 0
 
6709
                || poDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte)
 
6710
            {
 
6711
                delete poDS;
 
6712
            }
 
6713
            else
 
6714
            {
 
6715
                int i;
 
6716
                for(i=0;i<nOverviewCount;i++)
 
6717
                {
 
6718
                    if (((GTiffDataset*)papoOverviewDS[i])->poMaskDS == NULL &&
 
6719
                        poDS->GetRasterXSize() == papoOverviewDS[i]->GetRasterXSize() &&
 
6720
                        poDS->GetRasterYSize() == papoOverviewDS[i]->GetRasterYSize() &&
 
6721
                        (poDS->GetRasterCount() == 1 || poDS->GetRasterCount() == GetRasterCount()))
 
6722
                    {
 
6723
                        CPLDebug( "GTiff", "Opened band mask for %dx%d overview.\n",
 
6724
                                  poDS->GetRasterXSize(), poDS->GetRasterYSize());
 
6725
                        ((GTiffDataset*)papoOverviewDS[i])->poMaskDS = poDS;
 
6726
                        poDS->bPromoteTo8Bits = CSLTestBoolean(CPLGetConfigOption("GDAL_TIFF_INTERNAL_MASK_TO_8BIT", "YES"));
 
6727
                        poDS->poBaseDS = this;
 
6728
                        break;
 
6729
                    }
 
6730
                }
 
6731
                if (i == nOverviewCount)
5465
6732
                {
5466
6733
                    delete poDS;
5467
6734
                }
5468
 
                else
5469
 
                {
5470
 
                    int i;
5471
 
                    for(i=0;i<nOverviewCount;i++)
5472
 
                    {
5473
 
                        if (((GTiffDataset*)papoOverviewDS[i])->poMaskDS == NULL &&
5474
 
                            poDS->GetRasterXSize() == papoOverviewDS[i]->GetRasterXSize() &&
5475
 
                            poDS->GetRasterYSize() == papoOverviewDS[i]->GetRasterYSize() &&
5476
 
                            (poDS->GetRasterCount() == 1 || poDS->GetRasterCount() == GetRasterCount()))
5477
 
                        {
5478
 
                            CPLDebug( "GTiff", "Opened band mask for %dx%d overview.\n",
5479
 
                                      poDS->GetRasterXSize(), poDS->GetRasterYSize());
5480
 
                            ((GTiffDataset*)papoOverviewDS[i])->poMaskDS = poDS;
5481
 
                            poDS->poBaseDS = this;
5482
 
                            break;
5483
 
                        }
5484
 
                    }
5485
 
                    if (i == nOverviewCount)
5486
 
                    {
5487
 
                        delete poDS;
5488
 
                    }
5489
 
                }
5490
 
            }
5491
 
            else if( nSubType == 0 ) {
5492
 
                CPLString osName, osDesc;
5493
 
                uint32  nXSize, nYSize;
5494
 
                uint16  nSPP;
5495
 
 
5496
 
                TIFFGetField( hTIFF, TIFFTAG_IMAGEWIDTH, &nXSize );
5497
 
                TIFFGetField( hTIFF, TIFFTAG_IMAGELENGTH, &nYSize );
5498
 
                if( !TIFFGetField(hTIFF, TIFFTAG_SAMPLESPERPIXEL, &nSPP ) )
5499
 
                    nSPP = 1;
5500
 
 
5501
 
                osName.Printf( "SUBDATASET_%d_NAME=GTIFF_DIR:%d:%s", 
5502
 
                               iDirIndex, iDirIndex, osFilename.c_str() );
5503
 
                osDesc.Printf( "SUBDATASET_%d_DESC=Page %d (%dP x %dL x %dB)", 
5504
 
                               iDirIndex, iDirIndex, 
5505
 
                               (int)nXSize, (int)nYSize, nSPP );
5506
 
 
5507
 
                papszSubdatasets = 
5508
 
                    CSLAddString( papszSubdatasets, osName );
5509
 
                papszSubdatasets = 
5510
 
                    CSLAddString( papszSubdatasets, osDesc );
5511
 
            }
5512
 
 
5513
 
            // Make sure we are stepping from the expected directory regardless
5514
 
            // of churn done processing the above.
5515
 
            if( TIFFCurrentDirOffset(hTIFF) != nThisDir )
5516
 
                TIFFSetSubDirectory( hTIFF, nThisDir );
5517
 
            *ppoActiveDSRef = NULL;
5518
 
        }
5519
 
 
5520
 
        /* If we have a mask for the main image, loop over the overviews, and if they */
5521
 
        /* have a mask, let's set this mask as an overview of the main mask... */
5522
 
        if (poMaskDS != NULL)
 
6735
            }
 
6736
        }
 
6737
        else if( nSubType == 0 || nSubType == FILETYPE_PAGE ) {
 
6738
            CPLString osName, osDesc;
 
6739
            uint32      nXSize, nYSize;
 
6740
            uint16  nSPP;
 
6741
 
 
6742
            TIFFGetField( hTIFF, TIFFTAG_IMAGEWIDTH, &nXSize );
 
6743
            TIFFGetField( hTIFF, TIFFTAG_IMAGELENGTH, &nYSize );
 
6744
            if( !TIFFGetField(hTIFF, TIFFTAG_SAMPLESPERPIXEL, &nSPP ) )
 
6745
                nSPP = 1;
 
6746
 
 
6747
            osName.Printf( "SUBDATASET_%d_NAME=GTIFF_DIR:%d:%s", 
 
6748
                           iDirIndex, iDirIndex, osFilename.c_str() );
 
6749
            osDesc.Printf( "SUBDATASET_%d_DESC=Page %d (%dP x %dL x %dB)", 
 
6750
                           iDirIndex, iDirIndex, 
 
6751
                           (int)nXSize, (int)nYSize, nSPP );
 
6752
 
 
6753
            papszSubdatasets = 
 
6754
                CSLAddString( papszSubdatasets, osName );
 
6755
            papszSubdatasets = 
 
6756
                CSLAddString( papszSubdatasets, osDesc );
 
6757
        }
 
6758
 
 
6759
        // Make sure we are stepping from the expected directory regardless
 
6760
        // of churn done processing the above.
 
6761
        if( TIFFCurrentDirOffset(hTIFF) != nThisDir )
 
6762
            TIFFSetSubDirectory( hTIFF, nThisDir );
 
6763
        *ppoActiveDSRef = NULL;
 
6764
    }
 
6765
 
 
6766
    /* If we have a mask for the main image, loop over the overviews, and if they */
 
6767
    /* have a mask, let's set this mask as an overview of the main mask... */
 
6768
    if (poMaskDS != NULL)
 
6769
    {
 
6770
        int i;
 
6771
        for(i=0;i<nOverviewCount;i++)
5523
6772
        {
5524
 
            int i;
5525
 
            for(i=0;i<nOverviewCount;i++)
 
6773
            if (((GTiffDataset*)papoOverviewDS[i])->poMaskDS != NULL)
5526
6774
            {
5527
 
                if (((GTiffDataset*)papoOverviewDS[i])->poMaskDS != NULL)
5528
 
                {
5529
 
                    poMaskDS->nOverviewCount++;
5530
 
                    poMaskDS->papoOverviewDS = (GTiffDataset **)
5531
 
                        CPLRealloc(poMaskDS->papoOverviewDS, 
5532
 
                                poMaskDS->nOverviewCount * (sizeof(void*)));
5533
 
                    poMaskDS->papoOverviewDS[poMaskDS->nOverviewCount-1] =
5534
 
                            ((GTiffDataset*)papoOverviewDS[i])->poMaskDS;
5535
 
                }
 
6775
                poMaskDS->nOverviewCount++;
 
6776
                poMaskDS->papoOverviewDS = (GTiffDataset **)
 
6777
                    CPLRealloc(poMaskDS->papoOverviewDS, 
 
6778
                               poMaskDS->nOverviewCount * (sizeof(void*)));
 
6779
                poMaskDS->papoOverviewDS[poMaskDS->nOverviewCount-1] =
 
6780
                    ((GTiffDataset*)papoOverviewDS[i])->poMaskDS;
5536
6781
            }
5537
6782
        }
 
6783
    }
5538
6784
 
5539
6785
/* -------------------------------------------------------------------- */
5540
6786
/*      Only keep track of subdatasets if we have more than one         */
5541
6787
/*      subdataset (pair).                                              */
5542
6788
/* -------------------------------------------------------------------- */
5543
 
        if( CSLCount(papszSubdatasets) > 2 )
 
6789
    if( CSLCount(papszSubdatasets) > 2 )
 
6790
    {
 
6791
        oGTiffMDMD.SetMetadata( papszSubdatasets, "SUBDATASETS" );
 
6792
    }
 
6793
    CSLDestroy( papszSubdatasets );
 
6794
    
 
6795
}
 
6796
 
 
6797
 
 
6798
static int GTiffGetLZMAPreset(char** papszOptions)
 
6799
{
 
6800
    int nLZMAPreset = -1;
 
6801
    const char* pszValue = CSLFetchNameValue( papszOptions, "LZMA_PRESET" );
 
6802
    if( pszValue  != NULL )
 
6803
    {
 
6804
        nLZMAPreset =  atoi( pszValue );
 
6805
        if (!(nLZMAPreset >= 0 && nLZMAPreset <= 9))
5544
6806
        {
5545
 
            oGTiffMDMD.SetMetadata( papszSubdatasets, "SUBDATASETS" );
 
6807
            CPLError( CE_Warning, CPLE_IllegalArg,
 
6808
                    "LZMA_PRESET=%s value not recognised, ignoring.",
 
6809
                    pszValue );
 
6810
            nLZMAPreset = -1;
5546
6811
        }
5547
 
        CSLDestroy( papszSubdatasets );
5548
6812
    }
5549
 
 
5550
 
    return( CE_None );
 
6813
    return nLZMAPreset;
5551
6814
}
5552
6815
 
 
6816
 
5553
6817
static int GTiffGetZLevel(char** papszOptions)
5554
6818
{
5555
6819
    int nZLevel = -1;
5597
6861
TIFF *GTiffDataset::CreateLL( const char * pszFilename,
5598
6862
                              int nXSize, int nYSize, int nBands,
5599
6863
                              GDALDataType eType,
 
6864
                              double dfExtraSpaceForOverviews,
5600
6865
                              char **papszParmList )
5601
6866
 
5602
6867
{
5603
6868
    TIFF                *hTIFF;
5604
6869
    int                 nBlockXSize = 0, nBlockYSize = 0;
5605
6870
    int                 bTiled = FALSE;
5606
 
    uint16              nCompression = COMPRESSION_NONE;
5607
 
    int                 nPredictor = 1, nJpegQuality = -1, nZLevel = -1;
 
6871
    int                 nCompression = COMPRESSION_NONE;
 
6872
    int                 nPredictor = PREDICTOR_NONE, nJpegQuality = -1, nZLevel = -1,
 
6873
                        nLZMAPreset = -1;
5608
6874
    uint16              nSampleFormat;
5609
6875
    int                 nPlanar;
5610
6876
    const char          *pszValue;
5611
6877
    const char          *pszProfile;
5612
6878
    int                 bCreateBigTIFF = FALSE;
5613
6879
 
5614
 
    GTiffOneTimeInit();
 
6880
    if (!GTiffOneTimeInit())
 
6881
        return NULL;
5615
6882
 
5616
6883
/* -------------------------------------------------------------------- */
5617
6884
/*      Blow on a few errors.                                           */
5677
6944
    pszValue = CSLFetchNameValue( papszParmList, "COMPRESS" );
5678
6945
    if( pszValue  != NULL )
5679
6946
    {
5680
 
        if( EQUAL( pszValue, "NONE" ) )
5681
 
            nCompression = COMPRESSION_NONE;
5682
 
        else if( EQUAL( pszValue, "JPEG" ) )
5683
 
            nCompression = COMPRESSION_JPEG;
5684
 
        else if( EQUAL( pszValue, "LZW" ) )
5685
 
            nCompression = COMPRESSION_LZW;
5686
 
        else if( EQUAL( pszValue, "PACKBITS" ))
5687
 
            nCompression = COMPRESSION_PACKBITS;
5688
 
        else if( EQUAL( pszValue, "DEFLATE" ) || EQUAL( pszValue, "ZIP" ))
5689
 
            nCompression = COMPRESSION_ADOBE_DEFLATE;
5690
 
        else if( EQUAL( pszValue, "FAX3" )
5691
 
                 || EQUAL( pszValue, "CCITTFAX3" ))
5692
 
            nCompression = COMPRESSION_CCITTFAX3;
5693
 
        else if( EQUAL( pszValue, "FAX4" )
5694
 
                 || EQUAL( pszValue, "CCITTFAX4" ))
5695
 
            nCompression = COMPRESSION_CCITTFAX4;
5696
 
        else if( EQUAL( pszValue, "CCITTRLE" ) )
5697
 
            nCompression = COMPRESSION_CCITTRLE;
5698
 
        else
5699
 
            CPLError( CE_Warning, CPLE_IllegalArg, 
5700
 
                      "COMPRESS=%s value not recognised, ignoring.",
5701
 
                      pszValue );
5702
 
 
5703
 
#if defined(TIFFLIB_VERSION) && TIFFLIB_VERSION > 20031007 /* 3.6.0 */
5704
 
        if (nCompression != COMPRESSION_NONE &&
5705
 
            !TIFFIsCODECConfigured(nCompression))
5706
 
        {
5707
 
            CPLError( CE_Failure, CPLE_AppDefined,
5708
 
                    "Cannot create TIFF file due to missing codec for %s.", pszValue );
 
6947
        nCompression = GTIFFGetCompressionMethod(pszValue, "COMPRESS");
 
6948
        if (nCompression < 0)
5709
6949
            return NULL;
5710
 
        }
5711
 
#endif
5712
6950
    }
5713
6951
 
5714
6952
    pszValue = CSLFetchNameValue( papszParmList, "PREDICTOR" );
5716
6954
        nPredictor =  atoi( pszValue );
5717
6955
 
5718
6956
    nZLevel = GTiffGetZLevel(papszParmList);
5719
 
 
 
6957
    nLZMAPreset = GTiffGetLZMAPreset(papszParmList);
5720
6958
    nJpegQuality = GTiffGetJpegQuality(papszParmList);
5721
6959
 
5722
6960
/* -------------------------------------------------------------------- */
5726
6964
 
5727
6965
    dfUncompressedImageSize = 
5728
6966
        nXSize * ((double)nYSize) * nBands * (GDALGetDataTypeSize(eType)/8);
 
6967
    dfUncompressedImageSize += dfExtraSpaceForOverviews;
5729
6968
 
5730
6969
    if( nCompression == COMPRESSION_NONE 
5731
6970
        && dfUncompressedImageSize > 4200000000.0 )
6115
7354
    if (nCompression == COMPRESSION_ADOBE_DEFLATE
6116
7355
        && nZLevel != -1)
6117
7356
        TIFFSetField( hTIFF, TIFFTAG_ZIPQUALITY, nZLevel );
6118
 
    if( nCompression == COMPRESSION_JPEG 
 
7357
    else if( nCompression == COMPRESSION_JPEG 
6119
7358
        && nJpegQuality != -1 )
6120
7359
        TIFFSetField( hTIFF, TIFFTAG_JPEGQUALITY, nJpegQuality );
 
7360
    else if( nCompression == COMPRESSION_LZMA && nLZMAPreset != -1)
 
7361
        TIFFSetField( hTIFF, TIFFTAG_LZMAPRESET, nLZMAPreset );
6121
7362
 
6122
7363
/* -------------------------------------------------------------------- */
6123
7364
/*      If we forced production of a file with photometric=palette,     */
6184
7425
/*      Create the underlying TIFF file.                                */
6185
7426
/* -------------------------------------------------------------------- */
6186
7427
    hTIFF = CreateLL( pszFilename, nXSize, nYSize, nBands, 
6187
 
                      eType, papszParmList );
 
7428
                      eType, 0, papszParmList );
6188
7429
 
6189
7430
    if( hTIFF == NULL )
6190
7431
        return NULL;
6293
7534
/*      to decide if a TFW file should be written).                     */
6294
7535
/* -------------------------------------------------------------------- */
6295
7536
    poDS->papszCreationOptions = CSLDuplicate( papszParmList );
6296
 
    
 
7537
 
 
7538
    poDS->nZLevel = GTiffGetZLevel(papszParmList);
 
7539
    poDS->nLZMAPreset = GTiffGetLZMAPreset(papszParmList);
 
7540
    poDS->nJpegQuality = GTiffGetJpegQuality(papszParmList);
 
7541
 
 
7542
/* -------------------------------------------------------------------- */
 
7543
/*      If we are writing jpeg compression we need to write some        */
 
7544
/*      imagery to force the jpegtables to get created.  This is,       */
 
7545
/*      likely only needed with libtiff >= 3.9.3 (#3633)                */
 
7546
/* -------------------------------------------------------------------- */
 
7547
    if( poDS->nCompression == COMPRESSION_JPEG
 
7548
        && strstr(TIFFLIB_VERSION_STR, "Version 3.9") != NULL )
 
7549
    {
 
7550
        CPLDebug( "GDAL",
 
7551
                  "Writing zero block to force creation of JPEG tables." );
 
7552
        if( TIFFIsTiled( hTIFF ) )
 
7553
        {
 
7554
            int cc = TIFFTileSize( hTIFF );
 
7555
            unsigned char *pabyZeros = (unsigned char *) CPLCalloc(cc,1);
 
7556
            TIFFWriteEncodedTile(hTIFF, 0, pabyZeros, cc);
 
7557
            CPLFree( pabyZeros );
 
7558
        }
 
7559
        else
 
7560
        {
 
7561
            int cc = TIFFStripSize( hTIFF );
 
7562
            unsigned char *pabyZeros = (unsigned char *) CPLCalloc(cc,1);
 
7563
            TIFFWriteEncodedStrip(hTIFF, 0, pabyZeros, cc);
 
7564
            CPLFree( pabyZeros );
 
7565
        }
 
7566
        poDS->bDontReloadFirstBlock = TRUE;
 
7567
    }
 
7568
 
6297
7569
/* -------------------------------------------------------------------- */
6298
7570
/*      Create band information objects.                                */
6299
7571
/* -------------------------------------------------------------------- */
6317
7589
        }
6318
7590
    }
6319
7591
 
 
7592
    poDS->oOvManager.Initialize( poDS, pszFilename );
 
7593
 
6320
7594
    return( poDS );
6321
7595
}
6322
7596
 
6425
7699
                             poPBand->GetMetadataItem( 
6426
7700
                                 "PIXELTYPE", "IMAGE_STRUCTURE" ) );
6427
7701
    }
6428
 
 
 
7702
    
 
7703
    int nSrcOverviews = poSrcDS->GetRasterBand(1)->GetOverviewCount();
 
7704
    double dfExtraSpaceForOverviews = 0;
 
7705
    if (nSrcOverviews != 0 &&
 
7706
        CSLFetchBoolean(papszOptions, "COPY_SRC_OVERVIEWS", FALSE))
 
7707
    {
 
7708
        int i;
 
7709
        for(i=0;i<nSrcOverviews;i++)
 
7710
        {
 
7711
            dfExtraSpaceForOverviews += ((double)poSrcDS->GetRasterBand(1)->GetOverview(i)->GetXSize()) *
 
7712
                                        poSrcDS->GetRasterBand(1)->GetOverview(i)->GetYSize();
 
7713
        }
 
7714
        dfExtraSpaceForOverviews *= nBands * (GDALGetDataTypeSize(eType) / 8);
 
7715
    }
 
7716
    
6429
7717
/* -------------------------------------------------------------------- */
6430
7718
/*      Create the file.                                                */
6431
7719
/* -------------------------------------------------------------------- */
6432
7720
    hTIFF = CreateLL( pszFilename, nXSize, nYSize, nBands, 
6433
 
                      eType, papszCreateOptions );
 
7721
                      eType, dfExtraSpaceForOverviews, papszCreateOptions );
6434
7722
 
6435
7723
    CSLDestroy( papszCreateOptions );
6436
7724
 
6490
7778
/*      Does the source image consist of one band, with a palette?      */
6491
7779
/*      If so, copy over.                                               */
6492
7780
/* -------------------------------------------------------------------- */
6493
 
    if( nBands == 1 && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL 
 
7781
    if( (nBands == 1 || nBands == 2) && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL 
6494
7782
        && eType == GDT_Byte )
6495
7783
    {
6496
7784
        unsigned short  anTRed[256], anTGreen[256], anTBlue[256];
6520
7808
            TIFFSetField( hTIFF, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE );
6521
7809
        TIFFSetField( hTIFF, TIFFTAG_COLORMAP, anTRed, anTGreen, anTBlue );
6522
7810
    }
6523
 
    else if( nBands == 1 
 
7811
    else if( (nBands == 1 || nBands == 2) 
6524
7812
             && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL 
6525
7813
             && eType == GDT_UInt16 )
6526
7814
    {
6562
7850
    else if( poSrcDS->GetRasterBand(1)->GetColorTable() != NULL )
6563
7851
        CPLError( CE_Warning, CPLE_AppDefined,
6564
7852
                  "Unable to export color table to GeoTIFF file.  Color tables\n"
6565
 
                  "can only be written to 1 band Byte or UInt16 GeoTIFF files." );
 
7853
                  "can only be written to 1 band or 2 bands Byte or UInt16 GeoTIFF files." );
 
7854
 
 
7855
    if( nBands == 2
 
7856
        && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL 
 
7857
        && (eType == GDT_Byte || eType == GDT_UInt16) )
 
7858
    {
 
7859
        uint16 v[1] = { EXTRASAMPLE_UNASSALPHA };
 
7860
 
 
7861
        TIFFSetField(hTIFF, TIFFTAG_EXTRASAMPLES, 1, v );
 
7862
    }
6566
7863
 
6567
7864
/* -------------------------------------------------------------------- */
6568
7865
/*      Transfer some TIFF specific metadata, if available.             */
6588
7885
    }
6589
7886
 
6590
7887
/* -------------------------------------------------------------------- */
 
7888
/*      Are we addressing PixelIsPoint mode?                            */
 
7889
/* -------------------------------------------------------------------- */
 
7890
    bool bPixelIsPoint = false;
 
7891
    int  bPointGeoIgnore = FALSE;
 
7892
 
 
7893
    if( poSrcDS->GetMetadataItem( GDALMD_AREA_OR_POINT ) 
 
7894
        && EQUAL(poSrcDS->GetMetadataItem(GDALMD_AREA_OR_POINT),
 
7895
                 GDALMD_AOP_POINT) )
 
7896
    {
 
7897
        bPixelIsPoint = true;
 
7898
        bPointGeoIgnore = 
 
7899
            CSLTestBoolean( CPLGetConfigOption("GTIFF_POINT_GEO_IGNORE",
 
7900
                                               "FALSE") );
 
7901
    }
 
7902
 
 
7903
/* -------------------------------------------------------------------- */
6591
7904
/*      Write affine transform if it is meaningful.                     */
6592
7905
/* -------------------------------------------------------------------- */
6593
7906
    const char *pszProjection = NULL;
6596
7909
    if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None
6597
7910
        && (adfGeoTransform[0] != 0.0 || adfGeoTransform[1] != 1.0
6598
7911
            || adfGeoTransform[2] != 0.0 || adfGeoTransform[3] != 0.0
6599
 
            || adfGeoTransform[4] != 0.0 || ABS(adfGeoTransform[5]) != 1.0 ))
 
7912
            || adfGeoTransform[4] != 0.0 || adfGeoTransform[5] != 1.0 ))
6600
7913
    {
6601
7914
        if( bGeoTIFF )
6602
7915
        {
6618
7931
                adfTiePoints[3] = adfGeoTransform[0];
6619
7932
                adfTiePoints[4] = adfGeoTransform[3];
6620
7933
                adfTiePoints[5] = 0.0;
6621
 
        
 
7934
                
 
7935
                if( bPixelIsPoint && !bPointGeoIgnore )
 
7936
                {
 
7937
                    adfTiePoints[3] += adfGeoTransform[1] * 0.5 + adfGeoTransform[2] * 0.5;
 
7938
                    adfTiePoints[4] += adfGeoTransform[4] * 0.5 + adfGeoTransform[5] * 0.5;
 
7939
                }
 
7940
            
6622
7941
                TIFFSetField( hTIFF, TIFFTAG_GEOTIEPOINTS, 6, adfTiePoints );
6623
7942
            }
6624
7943
            else
6634
7953
                adfMatrix[5] = adfGeoTransform[5];
6635
7954
                adfMatrix[7] = adfGeoTransform[3];
6636
7955
                adfMatrix[15] = 1.0;
 
7956
                
 
7957
                if( bPixelIsPoint && !bPointGeoIgnore )
 
7958
                {
 
7959
                    adfMatrix[3] += adfGeoTransform[1] * 0.5 + adfGeoTransform[2] * 0.5;
 
7960
                    adfMatrix[7] += adfGeoTransform[4] * 0.5 + adfGeoTransform[5] * 0.5;
 
7961
                }
6637
7962
 
6638
7963
                TIFFSetField( hTIFF, TIFFTAG_GEOTRANSMATRIX, 16, adfMatrix );
6639
7964
            }
6670
7995
            padfTiePoints[iGCP*6+3] = pasGCPs[iGCP].dfGCPX;
6671
7996
            padfTiePoints[iGCP*6+4] = pasGCPs[iGCP].dfGCPY;
6672
7997
            padfTiePoints[iGCP*6+5] = pasGCPs[iGCP].dfGCPZ;
 
7998
 
 
7999
            if( bPixelIsPoint && !bPointGeoIgnore )
 
8000
            {
 
8001
                padfTiePoints[iGCP*6+0] += 0.5;
 
8002
                padfTiePoints[iGCP*6+1] += 0.5;
 
8003
            }
6673
8004
        }
6674
8005
 
6675
8006
        TIFFSetField( hTIFF, TIFFTAG_GEOTIEPOINTS, 
6714
8045
/* -------------------------------------------------------------------- */
6715
8046
/*      If we are writing jpeg compression we need to write some        */
6716
8047
/*      imagery to force the jpegtables to get created.  This is,       */
6717
 
/*      likely only needed with libtiff 3.9.x.                          */
 
8048
/*      likely only needed with libtiff >= 3.9.3 (#3633)                */
6718
8049
/* -------------------------------------------------------------------- */
6719
8050
    int bDontReloadFirstBlock = FALSE;
6720
8051
    if( nCompression == COMPRESSION_JPEG
6775
8106
    }
6776
8107
 
6777
8108
    poDS->osProfile = pszProfile;
6778
 
    poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
 
8109
    poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT & ~GCIF_MASK );
6779
8110
    poDS->papszCreationOptions = CSLDuplicate( papszOptions );
6780
8111
    poDS->bDontReloadFirstBlock = bDontReloadFirstBlock;
6781
8112
 
6798
8129
         nBand <= MIN(poDS->GetRasterCount(), poSrcDS->GetRasterCount()) ;
6799
8130
         nBand++ )
6800
8131
    {
6801
 
        char **papszSRC_MD = poSrcDS->GetRasterBand(nBand)->GetMetadata();
6802
 
        char **papszDST_MD = CSLDuplicate(poDS->GetRasterBand(nBand)->GetMetadata());
 
8132
        GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(nBand);
 
8133
        GDALRasterBand* poDstBand = poDS->GetRasterBand(nBand);
 
8134
        char **papszSRC_MD = poSrcBand->GetMetadata();
 
8135
        char **papszDST_MD = CSLDuplicate(poDstBand->GetMetadata());
6803
8136
 
6804
8137
        papszDST_MD = CSLMerge( papszDST_MD, papszSRC_MD );
6805
8138
 
6806
 
        poDS->GetRasterBand(nBand)->SetMetadata( papszDST_MD );
 
8139
        poDstBand->SetMetadata( papszDST_MD );
6807
8140
        CSLDestroy( papszDST_MD );
 
8141
 
 
8142
        char** papszCatNames;
 
8143
        papszCatNames = poSrcBand->GetCategoryNames();
 
8144
        if (NULL != papszCatNames)
 
8145
            poDstBand->SetCategoryNames( papszCatNames );
6808
8146
    }
6809
8147
 
6810
8148
    hTIFF = (TIFF*) poDS->GetInternalHandle(NULL);
6811
8149
 
6812
8150
/* -------------------------------------------------------------------- */
 
8151
/*      Handle forcing xml:ESRI data to be written to PAM.              */
 
8152
/* -------------------------------------------------------------------- */
 
8153
    if( CSLTestBoolean(CPLGetConfigOption( "ESRI_XML_PAM", "NO" )) )
 
8154
    {
 
8155
        char **papszESRIMD = poSrcDS->GetMetadata("xml:ESRI");
 
8156
        if( papszESRIMD )
 
8157
        {
 
8158
            poDS->SetMetadata( papszESRIMD, "xml:ESRI");
 
8159
        }
 
8160
    }
 
8161
 
 
8162
/* -------------------------------------------------------------------- */
6813
8163
/*      Second chance : now that we have a PAM dataset, it is possible  */
6814
8164
/*      to write metadata that we couldn't be writen as TIFF tag        */
6815
8165
/* -------------------------------------------------------------------- */
6816
8166
    if (!bHasWrittenMDInGeotiffTAG)
6817
8167
        GTiffDataset::WriteMetadata( poDS, hTIFF, TRUE, pszProfile,
6818
 
                                     pszFilename, papszOptions, TRUE /* don't write RPC and IMG file again */);
 
8168
                                     pszFilename, papszOptions, TRUE /* don't write RPC and IMD file again */);
6819
8169
 
6820
8170
    /* To avoid unnecessary directory rewriting */
6821
8171
    poDS->bMetadataChanged = FALSE;
6825
8175
    /* been lost a few lines above when closing the newly create TIFF file */
6826
8176
    /* The TIFFTAG_ZIPQUALITY & TIFFTAG_JPEGQUALITY are not store in the TIFF file. */
6827
8177
    /* They are just TIFF session parameters */
 
8178
 
 
8179
    poDS->nZLevel = GTiffGetZLevel(papszOptions);
 
8180
    poDS->nLZMAPreset = GTiffGetLZMAPreset(papszOptions);
 
8181
    poDS->nJpegQuality = GTiffGetJpegQuality(papszOptions);
 
8182
 
6828
8183
    if (nCompression == COMPRESSION_ADOBE_DEFLATE)
6829
8184
    {
6830
 
        int nZLevel = GTiffGetZLevel(papszOptions);
6831
 
        if (nZLevel != -1)
 
8185
        if (poDS->nZLevel != -1)
6832
8186
        {
6833
 
            TIFFSetField( hTIFF, TIFFTAG_ZIPQUALITY, nZLevel );
 
8187
            TIFFSetField( hTIFF, TIFFTAG_ZIPQUALITY, poDS->nZLevel );
6834
8188
        }
6835
8189
    }
6836
8190
    else if( nCompression == COMPRESSION_JPEG)
6837
8191
    {
6838
 
        int nJpegQuality = GTiffGetJpegQuality(papszOptions);
6839
 
        if (nJpegQuality != -1)
6840
 
        {
6841
 
            TIFFSetField( hTIFF, TIFFTAG_JPEGQUALITY, nJpegQuality );
 
8192
        if (poDS->nJpegQuality != -1)
 
8193
        {
 
8194
            TIFFSetField( hTIFF, TIFFTAG_JPEGQUALITY, poDS->nJpegQuality );
 
8195
        }
 
8196
    }
 
8197
    else if( nCompression == COMPRESSION_LZMA)
 
8198
    {
 
8199
        if (poDS->nLZMAPreset != -1)
 
8200
        {
 
8201
            TIFFSetField( hTIFF, TIFFTAG_LZMAPRESET, poDS->nLZMAPreset );
 
8202
        }
 
8203
    }
 
8204
 
 
8205
    /* Precreate (internal) mask, so that the IBuildOverviews() below */
 
8206
    /* has a chance to create also the overviews of the mask */
 
8207
    int nMaskFlags = poSrcDS->GetRasterBand(1)->GetMaskFlags();
 
8208
    if( eErr == CE_None
 
8209
        && !(nMaskFlags & (GMF_ALL_VALID|GMF_ALPHA|GMF_NODATA) )
 
8210
        && (nMaskFlags & GMF_PER_DATASET) )
 
8211
    {
 
8212
        eErr = poDS->CreateMaskBand( nMaskFlags );
 
8213
    }
 
8214
 
 
8215
/* -------------------------------------------------------------------- */
 
8216
/*      Create and then copy existing overviews if requested            */
 
8217
/*  We do it such that all the IFDs are at the beginning of the file,   */
 
8218
/*  and that the imagery data for the smallest overview is written      */
 
8219
/*  first, that way the file is more usable when embedded in a          */
 
8220
/*  compressed stream.                                                  */
 
8221
/* -------------------------------------------------------------------- */
 
8222
 
 
8223
    /* For scaled progress due to overview copying */
 
8224
    double dfTotalPixels = ((double)nXSize) * nYSize;
 
8225
    double dfCurPixels = 0;
 
8226
 
 
8227
    if (eErr == CE_None &&
 
8228
        nSrcOverviews != 0 &&
 
8229
        CSLFetchBoolean(papszOptions, "COPY_SRC_OVERVIEWS", FALSE))
 
8230
    {
 
8231
        eErr = poDS->CreateOverviewsFromSrcOverviews(poSrcDS);
 
8232
 
 
8233
        if (poDS->nOverviewCount != nSrcOverviews)
 
8234
        {
 
8235
            CPLError(CE_Failure, CPLE_AppDefined,
 
8236
                     "Did only manage to instanciate %d overview levels, whereas source contains %d",
 
8237
                     poDS->nOverviewCount, nSrcOverviews);
 
8238
            eErr = CE_Failure;
 
8239
        }
 
8240
 
 
8241
        int i;
 
8242
        for(i=0;i<nSrcOverviews;i++)
 
8243
        {
 
8244
            GDALRasterBand* poOvrBand = poSrcDS->GetRasterBand(1)->GetOverview(i);
 
8245
            dfTotalPixels += ((double)poOvrBand->GetXSize()) *
 
8246
                                      poOvrBand->GetYSize();
 
8247
        }
 
8248
 
 
8249
        char* papszCopyWholeRasterOptions[2] = { NULL, NULL };
 
8250
        if (nCompression != COMPRESSION_NONE)
 
8251
            papszCopyWholeRasterOptions[0] = (char*) "COMPRESSED=YES";
 
8252
        /* Now copy the imagery */
 
8253
        for(i=0;eErr == CE_None && i<nSrcOverviews;i++)
 
8254
        {
 
8255
            /* Begin with the smallest overview */
 
8256
            int iOvrLevel = nSrcOverviews-1-i;
 
8257
            
 
8258
            /* Create a fake dataset with the source overview level so that */
 
8259
            /* GDALDatasetCopyWholeRaster can cope with it */
 
8260
            GDALDataset* poSrcOvrDS = new GDALOverviewDS(poSrcDS, iOvrLevel);
 
8261
            
 
8262
            GDALRasterBand* poOvrBand =
 
8263
                    poSrcDS->GetRasterBand(1)->GetOverview(iOvrLevel);
 
8264
            double dfNextCurPixels = dfCurPixels +
 
8265
                    ((double)poOvrBand->GetXSize()) * poOvrBand->GetYSize();
 
8266
 
 
8267
            void* pScaledData = GDALCreateScaledProgress( dfCurPixels / dfTotalPixels,
 
8268
                                      dfNextCurPixels / dfTotalPixels,
 
8269
                                      pfnProgress, pProgressData);
 
8270
                                
 
8271
            eErr = GDALDatasetCopyWholeRaster( (GDALDatasetH) poSrcOvrDS,
 
8272
                                                (GDALDatasetH) poDS->papoOverviewDS[iOvrLevel],
 
8273
                                                papszCopyWholeRasterOptions,
 
8274
                                                GDALScaledProgress, pScaledData );
 
8275
                                                
 
8276
            dfCurPixels = dfNextCurPixels;
 
8277
            GDALDestroyScaledProgress(pScaledData);
 
8278
 
 
8279
            delete poSrcOvrDS;
 
8280
            poDS->papoOverviewDS[iOvrLevel]->FlushCache();
 
8281
 
 
8282
            /* Copy mask of the overview */
 
8283
            if (eErr == CE_None && poDS->poMaskDS != NULL)
 
8284
            {
 
8285
                eErr = GDALRasterBandCopyWholeRaster( poOvrBand->GetMaskBand(),
 
8286
                                                    poDS->papoOverviewDS[iOvrLevel]->poMaskDS->GetRasterBand(1),
 
8287
                                                    papszCopyWholeRasterOptions,
 
8288
                                                    GDALDummyProgress, NULL);
 
8289
                poDS->papoOverviewDS[iOvrLevel]->poMaskDS->FlushCache();
 
8290
            }
6842
8291
        }
6843
8292
    }
6844
8293
 
6845
8294
/* -------------------------------------------------------------------- */
6846
8295
/*      Copy actual imagery.                                            */
6847
8296
/* -------------------------------------------------------------------- */
 
8297
    void* pScaledData = GDALCreateScaledProgress( dfCurPixels / dfTotalPixels,
 
8298
                                                  1.0,
 
8299
                                                  pfnProgress, pProgressData);
6848
8300
 
6849
8301
    if (poDS->bTreatAsSplit || poDS->bTreatAsSplitBitmap)
6850
8302
    {
6855
8307
        {
6856
8308
            int j;
6857
8309
            GByte* pabyScanline = (GByte *) CPLMalloc(TIFFScanlineSize(hTIFF));
6858
 
            eErr = CE_None;
6859
8310
            for(j=0;j<nYSize && eErr == CE_None;j++)
6860
8311
            {
6861
8312
                eErr = poSrcDS->RasterIO(GF_Read, 0, j, nXSize, 1,
6868
8319
                              "TIFFWriteScanline() failed." );
6869
8320
                    eErr = CE_Failure;
6870
8321
                }
6871
 
                if( !pfnProgress( (j+1) * 1.0 / nYSize, NULL, pProgressData ) )
 
8322
                if( !GDALScaledProgress( (j+1) * 1.0 / nYSize, NULL, pScaledData ) )
6872
8323
                    eErr = CE_Failure;
6873
8324
            }
6874
8325
            CPLFree(pabyScanline);
6898
8349
                        }
6899
8350
                    }
6900
8351
                    if (eErr == CE_None &&
6901
 
                        TIFFWriteScanline( hTIFF, pabyScanline, j, iBand - 1) == -1)
 
8352
                        TIFFWriteScanline( hTIFF, pabyScanline, j, (uint16) (iBand-1)) == -1)
6902
8353
                    {
6903
8354
                        CPLError( CE_Failure, CPLE_AppDefined,
6904
8355
                                  "TIFFWriteScanline() failed." );
6905
8356
                        eErr = CE_Failure;
6906
8357
                    }
6907
 
                    if( !pfnProgress( (j+1 + (iBand - 1) * nYSize) * 1.0 /
6908
 
                                      (nBands * nYSize), NULL, pProgressData ) )
 
8358
                    if( !GDALScaledProgress( (j+1 + (iBand - 1) * nYSize) * 1.0 /
 
8359
                                      (nBands * nYSize), NULL, pScaledData ) )
6909
8360
                        eErr = CE_Failure;
6910
8361
                }
6911
8362
            }
6913
8364
        }
6914
8365
        
6915
8366
        /* Necessary to be able to read the file without re-opening */
 
8367
#if defined(HAVE_TIFFGETSIZEPROC)
 
8368
        TIFFSizeProc pfnSizeProc = TIFFGetSizeProc( hTIFF );
 
8369
 
 
8370
        TIFFFlushData( hTIFF );
 
8371
 
 
8372
        toff_t nNewDirOffset = pfnSizeProc( TIFFClientdata( hTIFF ) );
 
8373
        if( (nNewDirOffset % 2) == 1 )
 
8374
            nNewDirOffset++;
 
8375
#endif
 
8376
 
6916
8377
        TIFFFlush( hTIFF );
 
8378
 
 
8379
#if defined(HAVE_TIFFGETSIZEPROC)
 
8380
        if( poDS->nDirOffset != TIFFCurrentDirOffset( hTIFF ) )
 
8381
        {
 
8382
            poDS->nDirOffset = nNewDirOffset;
 
8383
            CPLDebug( "GTiff", "directory moved during flush." );
 
8384
        }
 
8385
#endif
6917
8386
    }
6918
 
    else
 
8387
    else if (eErr == CE_None)
6919
8388
    {
6920
8389
        char* papszCopyWholeRasterOptions[2] = { NULL, NULL };
6921
8390
        if (nCompression != COMPRESSION_NONE)
6923
8392
        eErr = GDALDatasetCopyWholeRaster( (GDALDatasetH) poSrcDS, 
6924
8393
                                            (GDALDatasetH) poDS,
6925
8394
                                            papszCopyWholeRasterOptions,
6926
 
                                            pfnProgress, pProgressData );
 
8395
                                            GDALScaledProgress, pScaledData );
 
8396
    }
 
8397
    
 
8398
    GDALDestroyScaledProgress(pScaledData);
 
8399
 
 
8400
    if (eErr == CE_None)
 
8401
    {
 
8402
        if (poDS->poMaskDS)
 
8403
        {
 
8404
            const char* papszOptions[2] = { "COMPRESSED=YES", NULL };
 
8405
            eErr = GDALRasterBandCopyWholeRaster(
 
8406
                                    poSrcDS->GetRasterBand(1)->GetMaskBand(),
 
8407
                                    poDS->GetRasterBand(1)->GetMaskBand(),
 
8408
                                    (char**)papszOptions,
 
8409
                                    GDALDummyProgress, NULL);
 
8410
        }
 
8411
        else
 
8412
            eErr = GDALDriver::DefaultCopyMasks( poSrcDS, poDS, bStrict );
6927
8413
    }
6928
8414
 
6929
8415
    if( eErr == CE_Failure )
6931
8417
        delete poDS;
6932
8418
        poDS = NULL;
6933
8419
 
6934
 
        VSIUnlink( pszFilename ); // should really delete more carefully.
 
8420
        if (CSLTestBoolean(CPLGetConfigOption("GTIFF_DELETE_ON_ERROR", "YES")))
 
8421
            VSIUnlink( pszFilename ); // should really delete more carefully.
6935
8422
    }
6936
8423
 
6937
8424
    return poDS;
6968
8455
 
6969
8456
    if( !EQUALN(pszNewProjection,"GEOGCS",6)
6970
8457
        && !EQUALN(pszNewProjection,"PROJCS",6)
6971
 
        && !EQUALN(pszNewProjection,"LOCAL_CS",6)
 
8458
        && !EQUALN(pszNewProjection,"LOCAL_CS",8)
 
8459
        && !EQUALN(pszNewProjection,"COMPD_CS",8)
 
8460
        && !EQUALN(pszNewProjection,"GEOCCS",6)
6972
8461
        && !EQUAL(pszNewProjection,"") )
6973
8462
    {
6974
8463
        CPLError( CE_Failure, CPLE_AppDefined,
7020
8509
    else
7021
8510
    {
7022
8511
        CPLError( CE_Failure, CPLE_NotSupported,
7023
 
      "SetGeoTransform() is only supported on newly created GeoTIFF files." );
 
8512
                  "Attempt to call SetGeoTransform() on a read-only GeoTIFF file." );
7024
8513
        return CE_Failure;
7025
8514
    }
7026
8515
}
7045
8534
    if( nGCPCount > 0 )
7046
8535
    {
7047
8536
        LookForProjection();
 
8537
    }
 
8538
    if (pszProjection != NULL)
7048
8539
        return pszProjection;
7049
 
    }
7050
8540
    else
7051
 
        return GDALPamDataset::GetGCPProjection();
 
8541
        return "";
7052
8542
}
7053
8543
 
7054
8544
/************************************************************************/
7105
8595
    if( pszDomain != NULL && EQUAL(pszDomain,"ProxyOverviewRequest") )
7106
8596
        return GDALPamDataset::GetMetadata( pszDomain );
7107
8597
 
 
8598
    else if( pszDomain != NULL && EQUAL(pszDomain,"RPC") )
 
8599
        LoadRPCRPB();
 
8600
 
 
8601
    else if( pszDomain != NULL && EQUAL(pszDomain,"IMD") )
 
8602
        LoadIMD();
 
8603
    
 
8604
    else if( pszDomain != NULL && EQUAL(pszDomain,"SUBDATASETS") )
 
8605
        ScanDirectories();
 
8606
 
7108
8607
    /* FIXME ? Should we call LookForProjection() to load GDALMD_AREA_OR_POINT ? */
7109
8608
    /* This can impact performances */
7110
8609
 
7149
8648
    if( pszDomain != NULL && EQUAL(pszDomain,"ProxyOverviewRequest") )
7150
8649
        return GDALPamDataset::GetMetadataItem( pszName, pszDomain );
7151
8650
 
7152
 
    if( (pszDomain == NULL || EQUAL(pszDomain, "")) &&
 
8651
    else if( pszDomain != NULL && EQUAL(pszDomain,"RPC") )
 
8652
        LoadRPCRPB();
 
8653
 
 
8654
    else if( pszDomain != NULL && EQUAL(pszDomain,"IMD") )
 
8655
        LoadIMD();
 
8656
 
 
8657
    else if( pszDomain != NULL && EQUAL(pszDomain,"SUBDATASETS") )
 
8658
        ScanDirectories();
 
8659
 
 
8660
    else if( (pszDomain == NULL || EQUAL(pszDomain, "")) &&
7153
8661
        pszName != NULL && EQUAL(pszName, GDALMD_AREA_OR_POINT) )
7154
8662
    {
7155
8663
        LookForProjection();
7190
8698
    return hTIFF;
7191
8699
}
7192
8700
 
 
8701
 
 
8702
/************************************************************************/
 
8703
/*                           FindRPBFile()                             */
 
8704
/************************************************************************/
 
8705
 
 
8706
int GTiffDataset::FindRPBFile()
 
8707
{
 
8708
    osRPBFile = GDALFindAssociatedFile( osFilename, "RPB", 
 
8709
                                        oOvManager.GetSiblingFiles(), 0 );
 
8710
 
 
8711
    return osRPBFile != "";
 
8712
}
 
8713
 
 
8714
/************************************************************************/
 
8715
/*                           FindIMDFile()                             */
 
8716
/************************************************************************/
 
8717
 
 
8718
int GTiffDataset::FindIMDFile()
 
8719
{
 
8720
    osIMDFile = GDALFindAssociatedFile( osFilename, "IMD", 
 
8721
                                        oOvManager.GetSiblingFiles(), 0 );
 
8722
 
 
8723
    return osIMDFile != "";
 
8724
}
 
8725
 
 
8726
/************************************************************************/
 
8727
/*                           FindRPCFile()                             */
 
8728
/************************************************************************/
 
8729
 
 
8730
int GTiffDataset::FindRPCFile()
 
8731
{
 
8732
    CPLString osSrcPath = osFilename;
 
8733
    CPLString soPt(".");
 
8734
    size_t found = osSrcPath.rfind(soPt);
 
8735
    if (found == CPLString::npos)
 
8736
        return FALSE;
 
8737
    osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.txt");
 
8738
    CPLString osTarget = osSrcPath; 
 
8739
 
 
8740
    char** papszSiblingFiles = oOvManager.GetSiblingFiles();
 
8741
    if( papszSiblingFiles == NULL )
 
8742
    {
 
8743
        VSIStatBufL sStatBuf;
 
8744
 
 
8745
        if( VSIStatExL( osTarget, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 )
 
8746
        {
 
8747
            osSrcPath = osFilename;
 
8748
            osSrcPath.replace (found, osSrcPath.size() - found, "_RPC.TXT");
 
8749
            osTarget = osSrcPath; 
 
8750
 
 
8751
            if( VSIStatExL( osTarget, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 )
 
8752
            {
 
8753
                osSrcPath = osFilename;
 
8754
                osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.TXT");
 
8755
                osTarget = osSrcPath; 
 
8756
 
 
8757
                if( VSIStatExL( osTarget, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 )
 
8758
                {
 
8759
                    return FALSE;
 
8760
                }
 
8761
            }
 
8762
        }
 
8763
    }
 
8764
    else
 
8765
    {
 
8766
        int iSibling = CSLFindString( papszSiblingFiles, 
 
8767
                                    CPLGetFilename(osTarget) );
 
8768
        if( iSibling < 0 )
 
8769
            return FALSE;
 
8770
 
 
8771
        osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling]));
 
8772
        osTarget += papszSiblingFiles[iSibling];
 
8773
    }
 
8774
 
 
8775
    osRPCFile = osTarget;
 
8776
    return TRUE;
 
8777
}
 
8778
 
 
8779
/************************************************************************/
 
8780
/*                            LoadRPCRPB()                              */
 
8781
/************************************************************************/
 
8782
 
 
8783
void GTiffDataset::LoadRPCRPB()
 
8784
{
 
8785
    if (bHasSearchedRPC)
 
8786
        return;
 
8787
 
 
8788
    bHasSearchedRPC = TRUE;
 
8789
 
 
8790
    char **papszRPCMD = NULL;
 
8791
    /* Read Digital Globe .RPB file */
 
8792
    if (FindRPBFile())
 
8793
        papszRPCMD = GDALLoadRPBFile( osRPBFile.c_str(), NULL );
 
8794
 
 
8795
    /* Read GeoEye _rpc.txt file */
 
8796
    if(papszRPCMD == NULL && FindRPCFile())
 
8797
        papszRPCMD = GDALLoadRPCFile( osRPCFile.c_str(), NULL );
 
8798
 
 
8799
    if( papszRPCMD != NULL )
 
8800
    {
 
8801
        oGTiffMDMD.SetMetadata( papszRPCMD, "RPC" );
 
8802
        CSLDestroy( papszRPCMD );
 
8803
    }
 
8804
    else
 
8805
        ReadRPCTag();
 
8806
}
 
8807
 
 
8808
/************************************************************************/
 
8809
/*                              LoadIMD()                               */
 
8810
/************************************************************************/
 
8811
 
 
8812
void GTiffDataset::LoadIMD()
 
8813
{
 
8814
    if (bHasSearchedIMD)
 
8815
        return;
 
8816
 
 
8817
    bHasSearchedIMD = TRUE;
 
8818
 
 
8819
    if (FindIMDFile())
 
8820
    {
 
8821
        char **papszIMDMD = GDALLoadIMDFile( osIMDFile.c_str(), NULL );
 
8822
 
 
8823
        if( papszIMDMD != NULL )
 
8824
        {
 
8825
            oGTiffMDMD.SetMetadata( papszIMDMD, "IMD" );
 
8826
            CSLDestroy( papszIMDMD );
 
8827
        }
 
8828
    }
 
8829
}
 
8830
 
7193
8831
/************************************************************************/
7194
8832
/*                            GetFileList()                             */
7195
8833
/************************************************************************/
7198
8836
 
7199
8837
{
7200
8838
    char **papszFileList = GDALPamDataset::GetFileList();
7201
 
    VSIStatBufL sStatBuf;
7202
 
 
7203
 
/* -------------------------------------------------------------------- */
7204
 
/*      Check for .imd file.                                            */
7205
 
/* -------------------------------------------------------------------- */
7206
 
    CPLString osTarget = CPLResetExtension( osFilename, "IMD" );
7207
 
    if( VSIStatL( osTarget, &sStatBuf ) == 0 )
7208
 
        papszFileList = CSLAddString( papszFileList, osTarget );
7209
 
    else
7210
 
    {
7211
 
        osTarget = CPLResetExtension( osFilename, "imd" );
7212
 
        if( VSIStatL( osTarget, &sStatBuf ) == 0 )
7213
 
            papszFileList = CSLAddString( papszFileList, osTarget );
7214
 
    }
7215
 
    
7216
 
/* -------------------------------------------------------------------- */
7217
 
/*      Check for .rpb file.                                            */
7218
 
/* -------------------------------------------------------------------- */
7219
 
    osTarget = CPLResetExtension( osFilename, "RPB" );
7220
 
    if( VSIStatL( osTarget, &sStatBuf ) == 0 )
7221
 
        papszFileList = CSLAddString( papszFileList, osTarget );
7222
 
    else
7223
 
    {
7224
 
        osTarget = CPLResetExtension( osFilename, "rpb" );
7225
 
        if( VSIStatL( osTarget, &sStatBuf ) == 0 )
7226
 
            papszFileList = CSLAddString( papszFileList, osTarget );
 
8839
 
 
8840
    LoadRPCRPB();
 
8841
    LoadIMD();
 
8842
 
 
8843
    if (osIMDFile.size() != 0)
 
8844
        papszFileList = CSLAddString( papszFileList, osIMDFile );
 
8845
    if (osRPBFile.size() != 0)
 
8846
        papszFileList = CSLAddString( papszFileList, osRPBFile );
 
8847
    if (osRPCFile.size() != 0)
 
8848
        papszFileList = CSLAddString( papszFileList, osRPCFile );
 
8849
 
 
8850
    if (osWldFilename.size() != 0 &&
 
8851
        CSLFindString(papszFileList, osWldFilename) == -1)
 
8852
    {
 
8853
        papszFileList = CSLAddString( papszFileList, osWldFilename );
7227
8854
    }
7228
8855
 
7229
8856
    return papszFileList;
7235
8862
 
7236
8863
CPLErr GTiffDataset::CreateMaskBand(int nFlags)
7237
8864
{
 
8865
    ScanDirectories();
 
8866
 
7238
8867
    if (poMaskDS != NULL)
7239
8868
    {
7240
8869
        CPLError(CE_Failure, CPLE_AppDefined,
7247
8876
        int     bIsTiled;
7248
8877
        int     bIsOverview = FALSE;
7249
8878
        uint32  nSubType;
 
8879
        int     nCompression;
7250
8880
 
7251
8881
        if (nFlags != GMF_PER_DATASET)
7252
8882
        {
7255
8885
            return CE_Failure;
7256
8886
        }
7257
8887
 
 
8888
        if( strstr(GDALGetMetadataItem(GDALGetDriverByName( "GTiff" ),
 
8889
                                       GDAL_DMD_CREATIONOPTIONLIST, NULL ),
 
8890
                   "<Value>DEFLATE</Value>") != NULL )
 
8891
            nCompression = COMPRESSION_ADOBE_DEFLATE;
 
8892
        else
 
8893
            nCompression = COMPRESSION_PACKBITS;
 
8894
 
7258
8895
    /* -------------------------------------------------------------------- */
7259
8896
    /*      If we don't have read access, then create the mask externally.  */
7260
8897
    /* -------------------------------------------------------------------- */
7287
8924
            }
7288
8925
        }
7289
8926
 
7290
 
        TIFFFlush( hTIFF );
7291
 
 
7292
8927
        bIsTiled = TIFFIsTiled(hTIFF);
7293
 
 
 
8928
        
 
8929
        FlushDirectory();
 
8930
        
7294
8931
        nOffset = GTIFFWriteDirectory(hTIFF,
7295
8932
                                      (bIsOverview) ? FILETYPE_REDUCEDIMAGE | FILETYPE_MASK : FILETYPE_MASK,
7296
 
                                       nRasterXSize, nRasterYSize,
7297
 
                                       1, PLANARCONFIG_CONTIG, 1,
7298
 
                                       nBlockXSize, nBlockYSize,
7299
 
                                       bIsTiled, COMPRESSION_NONE, PHOTOMETRIC_MASK,
7300
 
                                       SAMPLEFORMAT_UINT, NULL, NULL, NULL, 0, NULL, "");
 
8933
                                      nRasterXSize, nRasterYSize,
 
8934
                                      1, PLANARCONFIG_CONTIG, 1,
 
8935
                                      nBlockXSize, nBlockYSize,
 
8936
                                      bIsTiled, nCompression, 
 
8937
                                      PHOTOMETRIC_MASK, PREDICTOR_NONE,
 
8938
                                      SAMPLEFORMAT_UINT, NULL, NULL, NULL, 0, NULL, "");
7301
8939
        if (nOffset == 0)
7302
8940
            return CE_Failure;
7303
8941
 
7304
8942
        poMaskDS = new GTiffDataset();
 
8943
        poMaskDS->bPromoteTo8Bits = CSLTestBoolean(CPLGetConfigOption("GDAL_TIFF_INTERNAL_MASK_TO_8BIT", "YES"));
7305
8944
        if( poMaskDS->OpenOffset( hTIFF, ppoActiveDSRef, nOffset, 
7306
8945
                                  FALSE, GA_Update ) != CE_None)
7307
8946
        {
7324
8963
 
7325
8964
CPLErr GTiffRasterBand::CreateMaskBand(int nFlags)
7326
8965
{
 
8966
    poGDS->ScanDirectories();
 
8967
 
7327
8968
    if (poGDS->poMaskDS != NULL)
7328
8969
    {
7329
8970
        CPLError(CE_Failure, CPLE_AppDefined,
7380
9021
{
7381
9022
    char        *pszModFmt;
7382
9023
 
7383
 
    if( strstr(fmt,"unknown field") != NULL )
 
9024
    if( strstr(fmt,"nknown field") != NULL )
7384
9025
        return;
7385
9026
 
7386
9027
    pszModFmt = PrepareTIFFErrorFormat( module, fmt );
7387
 
    CPLErrorV( CE_Warning, CPLE_AppDefined, pszModFmt, ap );
 
9028
    if( strstr(fmt, "does not end in null byte") != NULL )
 
9029
    {
 
9030
        CPLString osMsg;
 
9031
        osMsg.vPrintf(pszModFmt, ap);
 
9032
        CPLDebug( "GTiff", "%s", osMsg.c_str() );
 
9033
    }
 
9034
    else
 
9035
        CPLErrorV( CE_Warning, CPLE_AppDefined, pszModFmt, ap );
7388
9036
    CPLFree( pszModFmt );
7389
9037
}
7390
9038
 
7391
9039
/************************************************************************/
7392
 
/*                        GTiffWarningHandler()                         */
 
9040
/*                         GTiffErrorHandler()                          */
7393
9041
/************************************************************************/
7394
9042
void
7395
9043
GTiffErrorHandler(const char* module, const char* fmt, va_list ap )
7437
9085
/*      unnecessary paging in of the library for GDAL apps that         */
7438
9086
/*      don't use it.                                                   */
7439
9087
/************************************************************************/
 
9088
#if defined(HAVE_DLFCN_H) && !defined(WIN32)
 
9089
#include <dlfcn.h>
 
9090
#endif
7440
9091
 
7441
 
void GTiffOneTimeInit()
 
9092
int GTiffOneTimeInit()
7442
9093
 
7443
9094
{
 
9095
    static int bInitIsOk = TRUE;
7444
9096
    static int bOneTimeInitDone = FALSE;
7445
 
    
 
9097
    static void* hMutex = NULL;
 
9098
    CPLMutexHolder oHolder( &hMutex);
7446
9099
    if( bOneTimeInitDone )
7447
 
        return;
 
9100
        return bInitIsOk;
7448
9101
 
7449
9102
    bOneTimeInitDone = TRUE;
7450
9103
 
 
9104
    /* This is a frequent configuration error that is difficult to track down */
 
9105
    /* for people unaware of the issue : GDAL built against internal libtiff (4.X) */
 
9106
    /* but used by an application that links with external libtiff (3.X) */
 
9107
    /* Note: on my conf, the order that cause GDAL to crash - and that is detected */
 
9108
    /* by the following code - is "-ltiff -lgdal". "-lgdal -ltiff" works for the */
 
9109
    /* GTiff driver but probably breaks the application that believes it uses libtiff 3.X */
 
9110
    /* but we cannot detect that... */
 
9111
#if defined(BIGTIFF_SUPPORT) && !defined(RENAME_INTERNAL_LIBTIFF_SYMBOLS)
 
9112
#if defined(HAVE_DLFCN_H) && !defined(WIN32)
 
9113
    const char* (*pfnVersion)(void);
 
9114
    pfnVersion = (const char* (*)(void)) dlsym(RTLD_DEFAULT, "TIFFGetVersion");
 
9115
    if (pfnVersion)
 
9116
    {
 
9117
        const char* pszVersion = pfnVersion();
 
9118
        if (pszVersion && strstr(pszVersion, "Version 3.") != NULL)
 
9119
        {
 
9120
            CPLError(CE_Warning, CPLE_AppDefined,
 
9121
                     "libtiff version mismatch : You're linking against libtiff 3.X, but GDAL has been compiled against libtiff >= 4.0.0");
 
9122
        }
 
9123
    }
 
9124
#endif
 
9125
#endif
 
9126
 
7451
9127
    _ParentExtender = TIFFSetTagExtender(GTiffTagExtender);
7452
9128
 
7453
9129
    TIFFSetWarningHandler( GTiffWarningHandler );
7456
9132
    // This only really needed if we are linked to an external libgeotiff
7457
9133
    // with its own (lame) file searching logic. 
7458
9134
    SetCSVFilenameHook( GDALDefaultCSVFilename );
 
9135
 
 
9136
    return TRUE;
7459
9137
}
7460
9138
 
7461
9139
/************************************************************************/
7465
9143
void GDALDeregister_GTiff( GDALDriver * )
7466
9144
 
7467
9145
{
7468
 
    CPLDebug( "GDAL", "GDALDeregister_GTiff() called." );
7469
9146
    CSVDeaccess( NULL );
7470
9147
 
7471
9148
#if defined(LIBGEOTIFF_VERSION) && LIBGEOTIFF_VERSION > 1150
7474
9151
}
7475
9152
 
7476
9153
/************************************************************************/
 
9154
/*                   GTIFFGetCompressionMethod()                        */
 
9155
/************************************************************************/
 
9156
 
 
9157
int GTIFFGetCompressionMethod(const char* pszValue, const char* pszVariableName)
 
9158
{
 
9159
    int nCompression = COMPRESSION_NONE;
 
9160
    if( EQUAL( pszValue, "NONE" ) )
 
9161
        nCompression = COMPRESSION_NONE;
 
9162
    else if( EQUAL( pszValue, "JPEG" ) )
 
9163
        nCompression = COMPRESSION_JPEG;
 
9164
    else if( EQUAL( pszValue, "LZW" ) )
 
9165
        nCompression = COMPRESSION_LZW;
 
9166
    else if( EQUAL( pszValue, "PACKBITS" ))
 
9167
        nCompression = COMPRESSION_PACKBITS;
 
9168
    else if( EQUAL( pszValue, "DEFLATE" ) || EQUAL( pszValue, "ZIP" ))
 
9169
        nCompression = COMPRESSION_ADOBE_DEFLATE;
 
9170
    else if( EQUAL( pszValue, "FAX3" )
 
9171
                || EQUAL( pszValue, "CCITTFAX3" ))
 
9172
        nCompression = COMPRESSION_CCITTFAX3;
 
9173
    else if( EQUAL( pszValue, "FAX4" )
 
9174
                || EQUAL( pszValue, "CCITTFAX4" ))
 
9175
        nCompression = COMPRESSION_CCITTFAX4;
 
9176
    else if( EQUAL( pszValue, "CCITTRLE" ) )
 
9177
        nCompression = COMPRESSION_CCITTRLE;
 
9178
    else if( EQUAL( pszValue, "LZMA" ) )
 
9179
        nCompression = COMPRESSION_LZMA;
 
9180
    else
 
9181
        CPLError( CE_Warning, CPLE_IllegalArg,
 
9182
                    "%s=%s value not recognised, ignoring.",
 
9183
                    pszVariableName,pszValue );
 
9184
 
 
9185
#if defined(TIFFLIB_VERSION) && TIFFLIB_VERSION > 20031007 /* 3.6.0 */
 
9186
    if (nCompression != COMPRESSION_NONE &&
 
9187
        !TIFFIsCODECConfigured((uint16) nCompression))
 
9188
    {
 
9189
        CPLError( CE_Failure, CPLE_AppDefined,
 
9190
                "Cannot create TIFF file due to missing codec for %s.", pszValue );
 
9191
        return -1;
 
9192
    }
 
9193
#endif
 
9194
 
 
9195
    return nCompression;
 
9196
}
 
9197
/************************************************************************/
7477
9198
/*                          GDALRegister_GTiff()                        */
7478
9199
/************************************************************************/
7479
9200
 
7485
9206
        GDALDriver      *poDriver;
7486
9207
        char szCreateOptions[3072];
7487
9208
        char szOptionalCompressItems[500];
7488
 
        int bHasJPEG = FALSE, bHasLZW = FALSE, bHasDEFLATE = FALSE;
 
9209
        int bHasJPEG = FALSE, bHasLZW = FALSE, bHasDEFLATE = FALSE, bHasLZMA = FALSE;
7489
9210
 
7490
9211
        poDriver = new GDALDriver();
7491
9212
        
7539
9260
            else if( c->scheme == COMPRESSION_CCITTFAX4 )
7540
9261
                strcat( szOptionalCompressItems,
7541
9262
                        "       <Value>CCITTFAX4</Value>" );
 
9263
            else if( c->scheme == COMPRESSION_LZMA )
 
9264
            {
 
9265
                bHasLZMA = TRUE;
 
9266
                strcat( szOptionalCompressItems,
 
9267
                        "       <Value>LZMA</Value>" );
 
9268
            }
7542
9269
        }
7543
9270
        _TIFFfree( codecs );
7544
9271
#endif        
7560
9287
        if (bHasDEFLATE)
7561
9288
            strcat( szCreateOptions, ""
7562
9289
"   <Option name='ZLEVEL' type='int' description='DEFLATE compression level 1-9' default='6'/>");
 
9290
        if (bHasLZMA)
 
9291
            strcat( szCreateOptions, ""
 
9292
"   <Option name='LZMA_PRESET' type='int' description='LZMA compression level 0(fast)-9(slow)' default='6'/>");
7563
9293
        strcat( szCreateOptions, ""
7564
9294
"   <Option name='NBITS' type='int' description='BITS for sub-byte files (1-7), sub-uint16 (9-15), sub-uint32 (17-31)'/>"
7565
9295
"   <Option name='INTERLEAVE' type='string-select' default='PIXEL'>"
7607
9337
"       <Value>LITTLE</Value>"
7608
9338
"       <Value>BIG</Value>"
7609
9339
"   </Option>"
 
9340
"   <Option name='COPY_SRC_OVERVIEWS' type='boolean' default='NO' description='Force copy of overviews of source dataset (CreateCopy())'/>"
7610
9341
"</CreationOptionList>" );
7611
9342
                 
7612
9343
/* -------------------------------------------------------------------- */