1 /******************************************************************************
2  *
3  * Project:  VICAR Driver; JPL/MIPL VICAR Format
4  * Purpose:  Implementation of VICARDataset
5  * Author:   Even Rouault, <even.rouault at spatialys.com>
6  *
7  ******************************************************************************
8  * Copyright (c) 2014, Sebastian Walter <sebastian dot walter at fu-berlin dot de>
9  * Copyright (c) 2019, Even Rouault, <even.rouault at spatialys.com>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  ****************************************************************************/
29 
30 #ifndef VICARDATASET_H
31 #define VICARDATASET_H
32 
33 #include "cpl_string.h"
34 #include "gdal_frmts.h"
35 #include "ogr_spatialref.h"
36 #include "ogrsf_frmts.h"
37 #include "rawdataset.h"
38 #include "vicarkeywordhandler.h"
39 #include <array>
40 
41 /************************************************************************/
42 /* ==================================================================== */
43 /*                             VICARDataset                             */
44 /* ==================================================================== */
45 /************************************************************************/
46 
47 class VICARDataset final: public RawDataset
48 {
49     friend class VICARRawRasterBand;
50     friend class VICARBASICRasterBand;
51 
52     VSILFILE    *fpImage = nullptr;
53 
54     VICARKeywordHandler  oKeywords;
55 
56     enum CompressMethod
57     {
58         COMPRESS_NONE,
59         COMPRESS_BASIC,
60         COMPRESS_BASIC2,
61     };
62     CompressMethod m_eCompress = COMPRESS_NONE;
63 
64     int          m_nRecordSize = 0;
65     vsi_l_offset m_nImageOffsetWithoutNBB = 0;
66     int          m_nLastRecordOffset = 0;
67     std::vector<vsi_l_offset> m_anRecordOffsets{}; // for BASIC/BASIC2
68     std::vector<GByte> m_abyCodedBuffer{};
69     vsi_l_offset m_nLabelSize = 0;
70 
71     CPLJSONObject m_oJSonLabel;
72     CPLStringList m_aosVICARMD;
73 
74     bool        m_bGotTransform = false;
75     std::array<double, 6> m_adfGeoTransform = {{0.0,1.0,0,0.0,0.0,1.0}};
76 
77     OGRSpatialReference m_oSRS;
78 
79     std::unique_ptr<OGRLayer> m_poLayer;
80 
81     CPLString   m_osLatitudeType; // creation only
82     CPLString   m_osLongitudeDirection; // creation only
83     CPLString   m_osTargetName; // creation only
84     bool          m_bIsLabelWritten = true; // creation only
85     bool          m_bUseSrcLabel = true; // creation only
86     bool          m_bUseSrcMap = false; // creation only
87     bool          m_bInitToNodata = false; // creation only
88     CPLJSONObject m_oSrcJSonLabel; // creation only
89 
90     const char *GetKeyword( const char *pszPath,
91                             const char *pszDefault = "");
92     void         WriteLabel();
93     void         PatchLabel();
94     void         BuildLabel();
95     void         InvalidateLabel();
96 
97     static VICARDataset *CreateInternal( const char * pszFilename,
98                                 int nXSize, int nYSize, int nBands,
99                                 GDALDataType eType, char ** papszOptions );
100 
101 public:
102     VICARDataset();
103     virtual ~VICARDataset();
104 
105     CPLErr GetGeoTransform( double * padfTransform ) override;
106     CPLErr SetGeoTransform( double * padfTransform ) override;
107 
108     const OGRSpatialReference* GetSpatialRef() const override;
109     CPLErr SetSpatialRef(const OGRSpatialReference* poSRS) override;
110 
111     bool GetRawBinaryLayout(GDALDataset::RawBinaryLayout&) override;
112 
113     char **GetMetadataDomainList() override;
114     char **GetMetadata( const char* pszDomain = "" ) override;
115     CPLErr SetMetadata( char** papszMD, const char* pszDomain = "" ) override;
116 
GetLayerCount()117     int GetLayerCount() override { return m_poLayer ? 1 : 0; }
GetLayer(int i)118     OGRLayer* GetLayer(int i) override {
119         return (m_poLayer && i == 0) ? m_poLayer.get() : nullptr; }
120 
121     static int          Identify( GDALOpenInfo * );
122     static int          GetLabelOffset( GDALOpenInfo * );
123     static GDALDataset *Open( GDALOpenInfo * );
124     static GDALDataset *Create( const char * pszFilename,
125                                 int nXSize, int nYSize, int nBands,
126                                 GDALDataType eType, char ** papszOptions );
127     static GDALDataset* CreateCopy( const char *pszFilename,
128                                        GDALDataset *poSrcDS,
129                                        int bStrict,
130                                        char ** papszOptions,
131                                        GDALProgressFunc pfnProgress,
132                                        void * pProgressData );
133 
134     static GDALDataType GetDataTypeFromFormat(const char* pszFormat);
135     static bool         GetSpacings(const VICARKeywordHandler& keywords,
136                                     GUInt64& nPixelOffset,
137                                     GUInt64& nLineOffset,
138                                     GUInt64& nBandOffset,
139                                     GUInt64& nImageOffsetWithoutNBB,
140                                     GUInt64& nNBB,
141                                     GUInt64& nImageSize);
142 
143     static vsi_l_offset GetVICARLabelOffsetFromPDS3(const char* pszHdr,
144                                                     VSILFILE* fp,
145                                                     std::string& osVICARHeader);
146 };
147 
148 #endif // VICARDATASET_H
149