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

« back to all changes in this revision

Viewing changes to frmts/jpeg/jpgdataset.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: jpgdataset.cpp 18301 2009-12-15 05:42:12Z warmerdam $
 
2
 * $Id: jpgdataset.cpp 22847 2011-08-01 13:26:16Z rouault $
3
3
 *
4
4
 * Project:  JPEG JFIF Driver
5
5
 * Purpose:  Implement GDAL JPEG Support based on IJG libjpeg.
38
38
#include <setjmp.h>
39
39
 
40
40
 
41
 
CPL_CVSID("$Id: jpgdataset.cpp 18301 2009-12-15 05:42:12Z warmerdam $");
 
41
CPL_CVSID("$Id: jpgdataset.cpp 22847 2011-08-01 13:26:16Z rouault $");
42
42
 
43
43
CPL_C_START
44
44
#ifdef LIBJPEG_12_PATH 
48
48
#endif
49
49
CPL_C_END
50
50
 
 
51
// we believe it is ok to use setjmp() in this situation.
 
52
#ifdef _MSC_VER
 
53
#  pragma warning(disable:4611)
 
54
#endif
 
55
 
51
56
#if defined(JPEG_DUAL_MODE_8_12) && !defined(JPGDataset)
52
57
GDALDataset* JPEGDataset12Open(GDALOpenInfo* poOpenInfo);
53
 
GDALDataset*
54
 
        JPEGCreateCopy12( const char * pszFilename, GDALDataset *poSrcDS, 
55
 
                          int bStrict, char ** papszOptions, 
56
 
                          GDALProgressFunc pfnProgress, void * pProgressData );
 
58
GDALDataset* JPEGDataset12CreateCopy( const char * pszFilename,
 
59
                                    GDALDataset *poSrcDS,
 
60
                                    int bStrict, char ** papszOptions,
 
61
                                    GDALProgressFunc pfnProgress,
 
62
                                    void * pProgressData );
57
63
#endif
58
64
 
59
65
CPL_C_START
60
66
void    GDALRegister_JPEG(void);
61
67
CPL_C_END
62
68
 
63
 
void jpeg_vsiio_src (j_decompress_ptr cinfo, FILE * infile);
64
 
void jpeg_vsiio_dest (j_compress_ptr cinfo, FILE * outfile);
 
69
void jpeg_vsiio_src (j_decompress_ptr cinfo, VSILFILE * infile);
 
70
void jpeg_vsiio_dest (j_compress_ptr cinfo, VSILFILE * outfile);
65
71
 
66
72
/*  
67
73
* Do we want to do special processing suitable for when JSAMPLE is a 
97
103
    int    nGCPCount;
98
104
    GDAL_GCP *pasGCPList;
99
105
 
100
 
    FILE   *fpImage;
 
106
    VSILFILE   *fpImage;
101
107
    GUIntBig nSubfileOffset;
102
108
 
103
109
    int    nLoadedScanline;
104
110
    GByte  *pabyScanline;
105
111
 
106
112
    int    bHasReadEXIFMetadata;
 
113
    int    bHasReadXMPMetadata;
107
114
    char   **papszMetadata;
108
115
    char   **papszSubDatasets;
109
116
    int    bigendian;
113
120
    int    bSwabflag;
114
121
    int    nTiffDirStart;
115
122
    int    nTIFFHEADER;
 
123
    int    bHasDoneJpegCreateDecompress;
116
124
    int    bHasDoneJpegStartDecompress;
117
125
 
118
126
    CPLErr LoadScanline(int);
119
127
    void   Restart();
120
128
    
121
 
    CPLErr EXIFExtractMetadata(FILE *, int);
122
 
    int    EXIFInit(FILE *);
 
129
    CPLErr EXIFExtractMetadata(VSILFILE *, int);
 
130
    int    EXIFInit(VSILFILE *);
123
131
    void   EXIFPrintData(char *, GUInt16, GUInt32, unsigned char* );
124
132
 
125
133
    int    nQLevel;
129
137
    void   DecompressMask();
130
138
 
131
139
    void   ReadEXIFMetadata();
 
140
    void   ReadXMPMetadata();
132
141
 
133
142
    int    bHasCheckedForMask;
134
143
    JPGMaskBand *poMaskBand;
140
149
    J_COLOR_SPACE eGDALColorSpace;   /* color space exposed by GDAL. Not necessarily the in_color_space nor */
141
150
                                     /* the out_color_space of JPEG library */
142
151
 
 
152
    int    bIsSubfile;
 
153
    int    bHasTriedLoadWorldFileOrTab;
 
154
    void   LoadWorldFileOrTab();
 
155
    CPLString osWldFilename;
 
156
 
143
157
  public:
144
158
                 JPGDataset();
145
159
                 ~JPGDataset();
158
172
    virtual const char *GetMetadataItem( const char * pszName,
159
173
                                         const char * pszDomain = "" );
160
174
 
 
175
    virtual char **GetFileList(void);
161
176
 
162
177
    static GDALDataset *Open( GDALOpenInfo * );
163
178
    static int          Identify( GDALOpenInfo * );
 
179
    static GDALDataset* CreateCopy( const char * pszFilename,
 
180
                                    GDALDataset *poSrcDS,
 
181
                                    int bStrict, char ** papszOptions,
 
182
                                    GDALProgressFunc pfnProgress,
 
183
                                    void * pProgressData );
164
184
 
165
185
    static void ErrorExit(j_common_ptr cinfo);
166
186
};
252
272
}
253
273
 
254
274
/************************************************************************/
 
275
/*                        ReadXMPMetadata()                             */
 
276
/************************************************************************/
 
277
 
 
278
/* See §2.1.3 of http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart3.pdf */
 
279
 
 
280
void JPGDataset::ReadXMPMetadata()
 
281
{
 
282
    if (bHasReadXMPMetadata)
 
283
        return;
 
284
 
 
285
    /* Save current position to avoid disturbing JPEG stream decoding */
 
286
    vsi_l_offset nCurOffset = VSIFTellL(fpImage);
 
287
 
 
288
/* -------------------------------------------------------------------- */
 
289
/*      Search for APP1 chunk.                                          */
 
290
/* -------------------------------------------------------------------- */
 
291
    GByte abyChunkHeader[2+2+29];
 
292
    int nChunkLoc = 2;
 
293
    int bFoundXMP = TRUE;
 
294
 
 
295
    for( ; TRUE; )
 
296
    {
 
297
        if( VSIFSeekL( fpImage, nChunkLoc, SEEK_SET ) != 0 )
 
298
            break;
 
299
 
 
300
        if( VSIFReadL( abyChunkHeader, sizeof(abyChunkHeader), 1, fpImage ) != 1 )
 
301
            break;
 
302
 
 
303
        if( abyChunkHeader[0] != 0xFF
 
304
            || (abyChunkHeader[1] & 0xf0) != 0xe0 )
 
305
            break; // Not an APP chunk.
 
306
 
 
307
        if( abyChunkHeader[1] == 0xe1
 
308
            && strncmp((const char *) abyChunkHeader + 4,"http://ns.adobe.com/xap/1.0/",28) == 0 )
 
309
        {
 
310
            bFoundXMP = TRUE;
 
311
            break; // APP1 - XMP
 
312
        }
 
313
 
 
314
        nChunkLoc += 2 + abyChunkHeader[2] * 256 + abyChunkHeader[3];
 
315
    }
 
316
 
 
317
    if (bFoundXMP)
 
318
    {
 
319
        int nXMPLength = abyChunkHeader[2] * 256 + abyChunkHeader[3];
 
320
        if (nXMPLength > 2 + 29)
 
321
        {
 
322
            char* pszXMP = (char*)VSIMalloc(nXMPLength - 2 - 29 + 1);
 
323
            if (pszXMP)
 
324
            {
 
325
                if (VSIFReadL( pszXMP, nXMPLength - 2 - 29, 1, fpImage ) == 1)
 
326
                {
 
327
                    pszXMP[nXMPLength - 2 - 29] = '\0';
 
328
 
 
329
                    /* Avoid setting the PAM dirty bit just for that */
 
330
                    int nOldPamFlags = nPamFlags;
 
331
 
 
332
                    char *apszMDList[2];
 
333
                    apszMDList[0] = pszXMP;
 
334
                    apszMDList[1] = NULL;
 
335
                    SetMetadata(apszMDList, "xml:XMP");
 
336
 
 
337
                    nPamFlags = nOldPamFlags;
 
338
                }
 
339
                VSIFree(pszXMP);
 
340
            }
 
341
        }
 
342
    }
 
343
 
 
344
    VSIFSeekL( fpImage, nCurOffset, SEEK_SET );
 
345
 
 
346
    bHasReadXMPMetadata = TRUE;
 
347
}
 
348
 
 
349
/************************************************************************/
255
350
/*                           GetMetadata()                              */
256
351
/************************************************************************/
257
352
char  **JPGDataset::GetMetadata( const char * pszDomain )
258
353
{
 
354
    if (fpImage == NULL)
 
355
        return NULL;
259
356
    if (eAccess == GA_ReadOnly && !bHasReadEXIFMetadata &&
260
357
        (pszDomain == NULL || EQUAL(pszDomain, "")))
261
358
        ReadEXIFMetadata();
 
359
    if (eAccess == GA_ReadOnly && !bHasReadXMPMetadata &&
 
360
        (pszDomain != NULL && EQUAL(pszDomain, "xml:XMP")))
 
361
        ReadXMPMetadata();
262
362
    return GDALPamDataset::GetMetadata(pszDomain);
263
363
}
264
364
 
268
368
const char *JPGDataset::GetMetadataItem( const char * pszName,
269
369
                                         const char * pszDomain )
270
370
{
 
371
    if (fpImage == NULL)
 
372
        return NULL;
271
373
    if (eAccess == GA_ReadOnly && !bHasReadEXIFMetadata &&
272
374
        (pszDomain == NULL || EQUAL(pszDomain, "")) &&
273
375
        pszName != NULL && EQUALN(pszName, "EXIF_", 5))
274
376
        ReadEXIFMetadata();
 
377
    if (eAccess == GA_ReadOnly && !bHasReadXMPMetadata &&
 
378
        (pszDomain != NULL && EQUAL(pszDomain, "xml:XMP")))
 
379
        ReadXMPMetadata();
275
380
    return GDALPamDataset::GetMetadataItem(pszName, pszDomain);
276
381
}
277
382
 
427
532
/*                                                                      */
428
533
/*           Create Metadata from Information file directory APP1       */
429
534
/************************************************************************/
430
 
int JPGDataset::EXIFInit(FILE *fp)
 
535
int JPGDataset::EXIFInit(VSILFILE *fp)
431
536
{
432
537
    int           one = 1;
433
538
    TIFFHeader    hdr;
452
557
            || (abyChunkHeader[1] & 0xf0) != 0xe0 )
453
558
            return FALSE; // Not an APP chunk.
454
559
 
455
 
        if( abyChunkHeader[1] == 0xe1 
 
560
        if( abyChunkHeader[1] == 0xe1
456
561
            && strncmp((const char *) abyChunkHeader + 4,"Exif",4) == 0 )
457
562
        {
458
563
            nTIFFHEADER = nChunkLoc + 10;
505
610
/*                                                                      */
506
611
/*      Extract all entry from a IFD                                    */
507
612
/************************************************************************/
508
 
CPLErr JPGDataset::EXIFExtractMetadata(FILE *fp, int nOffset)
 
613
CPLErr JPGDataset::EXIFExtractMetadata(VSILFILE *fp, int nOffset)
509
614
{
510
615
    GUInt16        nEntryCount;
511
616
    int space;
848
953
    
849
954
    CPLAssert( nBlockXOff == 0 );
850
955
 
 
956
    if (poGDS->fpImage == NULL)
 
957
    {
 
958
        memset( pImage, 0, nXSize * nWordSize );
 
959
        return CE_None;
 
960
    }
 
961
 
851
962
/* -------------------------------------------------------------------- */
852
963
/*      Load the desired scanline into the working buffer.              */
853
964
/* -------------------------------------------------------------------- */
887
998
                {
888
999
                    int C = poGDS->pabyScanline[i * 4 + 0];
889
1000
                    int K = poGDS->pabyScanline[i * 4 + 3];
890
 
                    ((GByte*)pImage)[i] = (C * K) / 255;
 
1001
                    ((GByte*)pImage)[i] = (GByte) ((C * K) / 255);
891
1002
                }
892
1003
            }
893
1004
            else  if (nBand == 2)
896
1007
                {
897
1008
                    int M = poGDS->pabyScanline[i * 4 + 1];
898
1009
                    int K = poGDS->pabyScanline[i * 4 + 3];
899
 
                    ((GByte*)pImage)[i] = (M * K) / 255;
 
1010
                    ((GByte*)pImage)[i] = (GByte) ((M * K) / 255);
900
1011
                }
901
1012
            }
902
1013
            else if (nBand == 3)
905
1016
                {
906
1017
                    int Y = poGDS->pabyScanline[i * 4 + 2];
907
1018
                    int K = poGDS->pabyScanline[i * 4 + 3];
908
 
                    ((GByte*)pImage)[i] = (Y * K) / 255;
 
1019
                    ((GByte*)pImage)[i] = (GByte) ((Y * K) / 255);
909
1020
                }
910
1021
            }
911
1022
        }
931
1042
        {
932
1043
            poBlock = 
933
1044
                poGDS->GetRasterBand(iBand)->GetLockedBlockRef(nBlockXOff,nBlockYOff);
934
 
            poBlock->DropLock();
 
1045
            if( poBlock != NULL )
 
1046
                poBlock->DropLock();
935
1047
        }
936
1048
    }
937
1049
 
1003
1115
GDALRasterBand *JPGRasterBand::GetMaskBand()
1004
1116
 
1005
1117
{
 
1118
    if (poGDS->fpImage == NULL)
 
1119
        return NULL;
 
1120
 
1006
1121
    if( !poGDS->bHasCheckedForMask)
1007
1122
    {
1008
1123
        poGDS->CheckForMask();
1026
1141
int JPGRasterBand::GetMaskFlags()
1027
1142
 
1028
1143
{
 
1144
    if (poGDS->fpImage == NULL)
 
1145
        return 0;
 
1146
 
1029
1147
    GetMaskBand();
1030
1148
    if( poGDS->poMaskBand != NULL )
1031
1149
        return GMF_PER_DATASET;
1047
1165
JPGDataset::JPGDataset()
1048
1166
 
1049
1167
{
 
1168
    fpImage = NULL;
 
1169
 
1050
1170
    pabyScanline = NULL;
1051
1171
    nLoadedScanline = -1;
1052
1172
 
1053
1173
    bHasReadEXIFMetadata = FALSE;
 
1174
    bHasReadXMPMetadata = FALSE;
1054
1175
    papszMetadata   = NULL;
1055
1176
    papszSubDatasets= NULL;
1056
1177
    nExifOffset     = -1;
1068
1189
    nGCPCount = 0;
1069
1190
    pasGCPList = NULL;
1070
1191
 
 
1192
    bHasDoneJpegCreateDecompress = FALSE;
1071
1193
    bHasDoneJpegStartDecompress = FALSE;
1072
1194
 
1073
1195
    bHasCheckedForMask = FALSE;
1077
1199
    nCMaskSize = 0;
1078
1200
 
1079
1201
    eGDALColorSpace = JCS_UNKNOWN;
 
1202
 
 
1203
    sDInfo.data_precision = 8;
 
1204
 
 
1205
    bIsSubfile = FALSE;
 
1206
    bHasTriedLoadWorldFileOrTab = FALSE;
1080
1207
}
1081
1208
 
1082
1209
/************************************************************************/
1088
1215
{
1089
1216
    FlushCache();
1090
1217
 
1091
 
    jpeg_abort_decompress( &sDInfo );
1092
 
    jpeg_destroy_decompress( &sDInfo );
 
1218
    if (bHasDoneJpegStartDecompress)
 
1219
    {
 
1220
        jpeg_abort_decompress( &sDInfo );
 
1221
    }
 
1222
    if (bHasDoneJpegCreateDecompress)
 
1223
    {
 
1224
        jpeg_destroy_decompress( &sDInfo );
 
1225
    }
1093
1226
 
1094
1227
    if( fpImage != NULL )
1095
1228
        VSIFCloseL( fpImage );
1387
1520
CPLErr JPGDataset::GetGeoTransform( double * padfTransform )
1388
1521
 
1389
1522
{
 
1523
    LoadWorldFileOrTab();
 
1524
 
1390
1525
    if( bGeoTransformValid )
1391
1526
    {
1392
1527
        memcpy( padfTransform, adfGeoTransform, sizeof(double)*6 );
1404
1539
int JPGDataset::GetGCPCount()
1405
1540
 
1406
1541
{
 
1542
    LoadWorldFileOrTab();
 
1543
 
1407
1544
    return nGCPCount;
1408
1545
}
1409
1546
 
1414
1551
const char *JPGDataset::GetGCPProjection()
1415
1552
 
1416
1553
{
 
1554
    LoadWorldFileOrTab();
 
1555
 
1417
1556
    if( pszProjection && nGCPCount > 0 )
1418
1557
        return pszProjection;
1419
1558
    else
1427
1566
const GDAL_GCP *JPGDataset::GetGCPs()
1428
1567
 
1429
1568
{
 
1569
    LoadWorldFileOrTab();
 
1570
 
1430
1571
    return pasGCPList;
1431
1572
}
1432
1573
 
1490
1631
}
1491
1632
 
1492
1633
/************************************************************************/
 
1634
/*                    JPEGDatasetIsJPEGLS()                             */
 
1635
/************************************************************************/
 
1636
 
 
1637
static int JPEGDatasetIsJPEGLS( GDALOpenInfo * poOpenInfo )
 
1638
 
 
1639
{
 
1640
    GByte  *pabyHeader = poOpenInfo->pabyHeader;
 
1641
    int    nHeaderBytes = poOpenInfo->nHeaderBytes;
 
1642
 
 
1643
    if( nHeaderBytes < 10 )
 
1644
        return FALSE;
 
1645
 
 
1646
    if( pabyHeader[0] != 0xff
 
1647
        || pabyHeader[1] != 0xd8 )
 
1648
        return FALSE;
 
1649
 
 
1650
    int nOffset = 2;
 
1651
    for (;nOffset + 4 < nHeaderBytes;)
 
1652
    {
 
1653
        if (pabyHeader[nOffset] != 0xFF)
 
1654
            return FALSE;
 
1655
 
 
1656
        int nMarker = pabyHeader[nOffset + 1];
 
1657
        if (nMarker == 0xF7 /* JPEG Extension 7, JPEG-LS */)
 
1658
            return TRUE;
 
1659
        if (nMarker == 0xF8 /* JPEG Extension 8, JPEG-LS Extension */)
 
1660
            return TRUE;
 
1661
        if (nMarker == 0xC3 /* Start of Frame 3 */)
 
1662
            return TRUE;
 
1663
        if (nMarker == 0xC7 /* Start of Frame 7 */)
 
1664
            return TRUE;
 
1665
        if (nMarker == 0xCB /* Start of Frame 11 */)
 
1666
            return TRUE;
 
1667
        if (nMarker == 0xCF /* Start of Frame 15 */)
 
1668
            return TRUE;
 
1669
 
 
1670
        nOffset += 2 + pabyHeader[nOffset + 2] * 256 + pabyHeader[nOffset + 3];
 
1671
    }
 
1672
 
 
1673
    return FALSE;
 
1674
}
 
1675
 
 
1676
/************************************************************************/
1493
1677
/*                              Identify()                              */
1494
1678
/************************************************************************/
1495
1679
 
1519
1703
        || pabyHeader[2] != 0xff )
1520
1704
        return FALSE;
1521
1705
 
 
1706
    if (JPEGDatasetIsJPEGLS(poOpenInfo))
 
1707
    {
 
1708
        return FALSE;
 
1709
    }
 
1710
 
1522
1711
    return TRUE;
1523
1712
}
1524
1713
 
1549
1738
    const char *real_filename = poOpenInfo->pszFilename;
1550
1739
    int nQLevel = -1;
1551
1740
 
1552
 
    if( ( poOpenInfo->fp == NULL ) &&
1553
 
        ( EQUALN(poOpenInfo->pszFilename,"JPEG_SUBFILE:",13) ) )
 
1741
    if( EQUALN(poOpenInfo->pszFilename,"JPEG_SUBFILE:",13) )
1554
1742
    {
1555
1743
        char** papszTokens;
1556
1744
        int bScan = FALSE;
1609
1797
    }
1610
1798
 
1611
1799
/* -------------------------------------------------------------------- */
 
1800
/*      Open the file using the large file api.                         */
 
1801
/* -------------------------------------------------------------------- */
 
1802
    VSILFILE* fpImage = VSIFOpenL( real_filename, "rb" );
 
1803
 
 
1804
    if( fpImage == NULL )
 
1805
    {
 
1806
        CPLError( CE_Failure, CPLE_OpenFailed,
 
1807
                  "VSIFOpenL(%s) failed unexpectedly in jpgdataset.cpp",
 
1808
                  real_filename );
 
1809
        return NULL;
 
1810
    }
 
1811
 
 
1812
/* -------------------------------------------------------------------- */
1612
1813
/*      Create a corresponding GDALDataset.                             */
1613
1814
/* -------------------------------------------------------------------- */
1614
1815
    JPGDataset  *poDS;
1615
1816
 
1616
1817
    poDS = new JPGDataset();
1617
1818
    poDS->nQLevel = nQLevel;
1618
 
 
1619
 
/* -------------------------------------------------------------------- */
1620
 
/*      Open the file using the large file api.                         */
1621
 
/* -------------------------------------------------------------------- */
1622
 
    poDS->fpImage = VSIFOpenL( real_filename, "rb" );
1623
 
    
1624
 
    if( poDS->fpImage == NULL )
1625
 
    {
1626
 
        CPLError( CE_Failure, CPLE_OpenFailed, 
1627
 
                  "VSIFOpenL(%s) failed unexpectedly in jpgdataset.cpp", 
1628
 
                  real_filename );
1629
 
        delete poDS;
1630
 
        return NULL;
1631
 
    }
 
1819
    poDS->fpImage = fpImage;
1632
1820
 
1633
1821
/* -------------------------------------------------------------------- */
1634
1822
/*      Move to the start of jpeg data.                                 */
1643
1831
    poDS->sDInfo.client_data = (void *) &(poDS->setjmp_buffer);
1644
1832
 
1645
1833
    jpeg_create_decompress( &(poDS->sDInfo) );
 
1834
    poDS->bHasDoneJpegCreateDecompress = TRUE;
1646
1835
 
1647
1836
    /* This is to address bug related in ticket #1795 */
1648
1837
    if (CPLGetConfigOption("JPEGMEM", NULL) == NULL)
1781
1970
    poDS->SetDescription( poOpenInfo->pszFilename );
1782
1971
    
1783
1972
    if( !bIsSubfile )
1784
 
        poDS->TryLoadXML();
 
1973
        poDS->TryLoadXML( poOpenInfo->papszSiblingFiles );
1785
1974
    else
1786
1975
        poDS->nPamFlags |= GPF_NOSAVE;
1787
1976
 
1788
1977
/* -------------------------------------------------------------------- */
1789
1978
/*      Open overviews.                                                 */
1790
1979
/* -------------------------------------------------------------------- */
1791
 
    poDS->oOvManager.Initialize( poDS, real_filename );
1792
 
 
1793
 
/* -------------------------------------------------------------------- */
1794
 
/*      Check for world file.                                           */
1795
 
/* -------------------------------------------------------------------- */
1796
 
    if( !bIsSubfile )
1797
 
    {
1798
 
        poDS->bGeoTransformValid = 
1799
 
            GDALReadWorldFile( poOpenInfo->pszFilename, NULL, 
1800
 
                               poDS->adfGeoTransform )
1801
 
            || GDALReadWorldFile( poOpenInfo->pszFilename, ".jpw", 
1802
 
                                  poDS->adfGeoTransform )
1803
 
            || GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", 
1804
 
                                  poDS->adfGeoTransform );
1805
 
 
1806
 
        if( !poDS->bGeoTransformValid )
1807
 
        {
1808
 
            int bTabFileOK =
1809
 
                GDALReadTabFile( poOpenInfo->pszFilename, poDS->adfGeoTransform,
1810
 
                                 &poDS->pszProjection,
1811
 
                                 &poDS->nGCPCount, &poDS->pasGCPList );
1812
 
            
1813
 
            if( bTabFileOK && poDS->nGCPCount == 0 )
1814
 
                poDS->bGeoTransformValid = TRUE;
1815
 
        }
1816
 
    }
 
1980
    poDS->oOvManager.Initialize( poDS, real_filename, poOpenInfo->papszSiblingFiles );
 
1981
 
 
1982
    poDS->bIsSubfile = bIsSubfile;
1817
1983
 
1818
1984
    return poDS;
1819
1985
}
1820
1986
 
1821
1987
/************************************************************************/
 
1988
/*                       LoadWorldFileOrTab()                           */
 
1989
/************************************************************************/
 
1990
 
 
1991
void JPGDataset::LoadWorldFileOrTab()
 
1992
{
 
1993
    if (bIsSubfile)
 
1994
        return;
 
1995
    if (bHasTriedLoadWorldFileOrTab)
 
1996
        return;
 
1997
    bHasTriedLoadWorldFileOrTab = TRUE;
 
1998
 
 
1999
    char* pszWldFilename = NULL;
 
2000
 
 
2001
    /* TIROS3 JPEG files have a .wld extension, so don't look for .wld as */
 
2002
    /* as worldfile ! */
 
2003
    int bEndsWithWld = strlen(GetDescription()) > 4 &&
 
2004
                        EQUAL( GetDescription() + strlen(GetDescription()) - 4, ".wld");
 
2005
    bGeoTransformValid =
 
2006
        GDALReadWorldFile2( GetDescription(), NULL,
 
2007
                            adfGeoTransform,
 
2008
                            oOvManager.GetSiblingFiles(), &pszWldFilename )
 
2009
        || GDALReadWorldFile2( GetDescription(), ".jpw",
 
2010
                                adfGeoTransform,
 
2011
                               oOvManager.GetSiblingFiles(), &pszWldFilename )
 
2012
        || ( !bEndsWithWld && GDALReadWorldFile2( GetDescription(), ".wld",
 
2013
                                adfGeoTransform,
 
2014
                                oOvManager.GetSiblingFiles(), &pszWldFilename ));
 
2015
 
 
2016
    if( !bGeoTransformValid )
 
2017
    {
 
2018
        int bTabFileOK =
 
2019
            GDALReadTabFile2( GetDescription(), adfGeoTransform,
 
2020
                              &pszProjection,
 
2021
                              &nGCPCount, &pasGCPList,
 
2022
                              oOvManager.GetSiblingFiles(), &pszWldFilename );
 
2023
 
 
2024
        if( bTabFileOK && nGCPCount == 0 )
 
2025
            bGeoTransformValid = TRUE;
 
2026
    }
 
2027
 
 
2028
    if (pszWldFilename)
 
2029
    {
 
2030
        osWldFilename = pszWldFilename;
 
2031
        CPLFree(pszWldFilename);
 
2032
    }
 
2033
}
 
2034
 
 
2035
/************************************************************************/
 
2036
/*                            GetFileList()                             */
 
2037
/************************************************************************/
 
2038
 
 
2039
char **JPGDataset::GetFileList()
 
2040
 
 
2041
{
 
2042
    char **papszFileList = GDALPamDataset::GetFileList();
 
2043
 
 
2044
    LoadWorldFileOrTab();
 
2045
 
 
2046
    if (osWldFilename.size() != 0 &&
 
2047
        CSLFindString(papszFileList, osWldFilename) == -1)
 
2048
    {
 
2049
        papszFileList = CSLAddString( papszFileList, osWldFilename );
 
2050
    }
 
2051
 
 
2052
    return papszFileList;
 
2053
}
 
2054
 
 
2055
/************************************************************************/
1822
2056
/*                            CheckForMask()                            */
1823
2057
/************************************************************************/
1824
2058
 
1969
2203
/*      file (or really any file) pulled from an existing mask band.    */
1970
2204
/************************************************************************/
1971
2205
 
 
2206
// MSVC does not know that memset() has initialized sStream.
 
2207
#ifdef _MSC_VER
 
2208
#  pragma warning(disable:4701)
 
2209
#endif
 
2210
 
1972
2211
static void JPGAppendMask( const char *pszJPGFilename, GDALRasterBand *poMask )
1973
2212
 
1974
2213
{
1977
2216
    int nBitBufSize = nYSize * ((nXSize+7)/8);
1978
2217
    int iX, iY;
1979
2218
    GByte *pabyBitBuf, *pabyMaskLine;
 
2219
    CPLErr eErr = CE_None;
1980
2220
 
1981
2221
/* -------------------------------------------------------------------- */
1982
2222
/*      Allocate uncompressed bit buffer.                               */
1983
2223
/* -------------------------------------------------------------------- */
1984
 
    pabyBitBuf = (GByte *) CPLCalloc(1,nBitBufSize);
 
2224
    pabyBitBuf = (GByte *) VSICalloc(1,nBitBufSize);
1985
2225
 
1986
 
    pabyMaskLine = (GByte *) CPLMalloc(nXSize);
 
2226
    pabyMaskLine = (GByte *) VSIMalloc(nXSize);
 
2227
    if (pabyBitBuf == NULL || pabyMaskLine == NULL)
 
2228
    {
 
2229
        CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory");
 
2230
        eErr = CE_Failure;
 
2231
    }
1987
2232
 
1988
2233
/* -------------------------------------------------------------------- */
1989
2234
/*      Set bit buffer from mask band, scanline by scanline.            */
1990
2235
/* -------------------------------------------------------------------- */
1991
 
    CPLErr eErr = CE_None;
1992
2236
    int iBit = 0;
1993
 
    for( iY = 0; iY < nYSize; iY++ )
 
2237
    for( iY = 0; eErr == CE_None && iY < nYSize; iY++ )
1994
2238
    {
1995
2239
        eErr = poMask->RasterIO( GF_Read, 0, iY, nXSize, 1,
1996
2240
                                 pabyMaskLine, nXSize, 1, GDT_Byte, 0, 0 );
2016
2260
 
2017
2261
    if( eErr == CE_None )
2018
2262
    {
2019
 
        pabyCMask = (GByte *) CPLMalloc(nBitBufSize + 30);
 
2263
        pabyCMask = (GByte *) VSIMalloc(nBitBufSize + 30);
 
2264
        if (pabyCMask == NULL)
 
2265
        {
 
2266
            CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory");
 
2267
            eErr = CE_Failure;
 
2268
        }
 
2269
    }
2020
2270
 
 
2271
    if ( eErr == CE_None )
 
2272
    {
2021
2273
        memset( &sStream, 0, sizeof(z_stream) );
2022
2274
        
2023
2275
        deflateInit( &sStream, 9 );
2045
2297
/* -------------------------------------------------------------------- */
2046
2298
    if( eErr == CE_None )
2047
2299
    {
2048
 
        FILE *fpOut;
 
2300
        VSILFILE *fpOut;
2049
2301
        GUInt32 nImageSize;
2050
2302
 
2051
2303
        fpOut = VSIFOpenL( pszJPGFilename, "r+" );
2059
2311
        {
2060
2312
            VSIFSeekL( fpOut, 0, SEEK_END );
2061
2313
 
2062
 
            nImageSize = VSIFTellL( fpOut );
 
2314
            nImageSize = (GUInt32) VSIFTellL( fpOut );
2063
2315
            CPL_LSBPTR32( &nImageSize );
2064
2316
 
2065
2317
            if( VSIFWriteL( pabyCMask, 1, sStream.total_out, fpOut ) 
2082
2334
}
2083
2335
 
2084
2336
/************************************************************************/
2085
 
/*                           JPEGCreateCopy()                           */
 
2337
/*                              CreateCopy()                            */
2086
2338
/************************************************************************/
2087
2339
 
2088
2340
GDALDataset *
2089
 
JPEGCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
2090
 
                int bStrict, char ** papszOptions, 
2091
 
                GDALProgressFunc pfnProgress, void * pProgressData )
 
2341
JPGDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
 
2342
                        int bStrict, char ** papszOptions,
 
2343
                        GDALProgressFunc pfnProgress, void * pProgressData )
2092
2344
 
2093
2345
{
2094
2346
    int  nBands = poSrcDS->GetRasterCount();
2142
2394
    if( eDT == GDT_UInt16 || eDT == GDT_Int16 )
2143
2395
    {
2144
2396
#if defined(JPEG_DUAL_MODE_8_12) && !defined(JPGDataset)
2145
 
        return JPEGCreateCopy12(pszFilename, poSrcDS,
 
2397
        return JPEGDataset12CreateCopy(pszFilename, poSrcDS,
2146
2398
                                bStrict, papszOptions, 
2147
2399
                                pfnProgress, pProgressData );
2148
2400
#else
2188
2440
/* -------------------------------------------------------------------- */
2189
2441
/*      Create the dataset.                                             */
2190
2442
/* -------------------------------------------------------------------- */
2191
 
    FILE        *fpImage;
 
2443
    VSILFILE    *fpImage;
2192
2444
 
2193
2445
    fpImage = VSIFOpenL( pszFilename, "wb" );
2194
2446
    if( fpImage == NULL )
2353
2605
/* -------------------------------------------------------------------- */
2354
2606
/*      Re-open dataset, and copy any auxilary pam information.         */
2355
2607
/* -------------------------------------------------------------------- */
2356
 
    JPGDataset *poDS = (JPGDataset *) GDALOpen( pszFilename, GA_ReadOnly );
 
2608
    GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly);
2357
2609
 
 
2610
    /* If outputing to stdout, we can't reopen it, so we'll return */
 
2611
    /* a fake dataset to make the caller happy */
 
2612
    CPLPushErrorHandler(CPLQuietErrorHandler);
 
2613
    JPGDataset *poDS = (JPGDataset*) JPGDataset::Open( &oOpenInfo );
 
2614
    CPLPopErrorHandler();
2358
2615
    if( poDS )
 
2616
    {
2359
2617
        poDS->CloneInfo( poSrcDS, nCloneFlags );
2360
 
 
2361
 
    return poDS;
 
2618
        return poDS;
 
2619
    }
 
2620
 
 
2621
    CPLErrorReset();
 
2622
 
 
2623
    JPGDataset* poJPG_DS = new JPGDataset();
 
2624
    poJPG_DS->nRasterXSize = nXSize;
 
2625
    poJPG_DS->nRasterYSize = nYSize;
 
2626
    for(int i=0;i<nBands;i++)
 
2627
        poJPG_DS->SetBand( i+1, new JPGRasterBand( poJPG_DS, i+1) );
 
2628
    return poJPG_DS;
2362
2629
}
2363
2630
 
2364
2631
/************************************************************************/
2401
2668
 
2402
2669
        poDriver->pfnIdentify = JPGDataset::Identify;
2403
2670
        poDriver->pfnOpen = JPGDataset::Open;
2404
 
        poDriver->pfnCreateCopy = JPEGCreateCopy;
 
2671
        poDriver->pfnCreateCopy = JPGDataset::CreateCopy;
2405
2672
 
2406
2673
        GetGDALDriverManager()->RegisterDriver( poDriver );
2407
2674
    }