1 /*
2  * $Id: keadataset.h fa752ad6eabafaf630a704e1892a9d837d683cb3 2021-03-06 17:04:38 +0100 Even Rouault $
3  *  keadataset.h
4  *
5  *  Created by Pete Bunting on 01/08/2012.
6  *  Copyright 2012 LibKEA. All rights reserved.
7  *
8  *  This file is part of LibKEA.
9  *
10  *  Permission is hereby granted, free of charge, to any person
11  *  obtaining a copy of this software and associated documentation
12  *  files (the "Software"), to deal in the Software without restriction,
13  *  including without limitation the rights to use, copy, modify,
14  *  merge, publish, distribute, sublicense, and/or sell copies of the
15  *  Software, and to permit persons to whom the Software is furnished
16  *  to do so, subject to the following conditions:
17  *
18  *  The above copyright notice and this permission notice shall be
19  *  included in all copies or substantial portions of the Software.
20  *
21  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24  *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
25  *  ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
26  *  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28  *
29  */
30 
31 #ifndef KEADATASET_H
32 #define KEADATASET_H
33 
34 #include "gdal_pam.h"
35 #include "cpl_multiproc.h"
36 #include "libkea_headers.h"
37 
38 class LockedRefCount;
39 
40 // class that implements a GDAL dataset
41 class KEADataset final: public GDALPamDataset
42 {
43     static H5::H5File *CreateLL( const char * pszFilename,
44                                   int nXSize, int nYSize, int nBands,
45                                   GDALDataType eType,
46                                   char ** papszParamList  );
47 
48 public:
49     // constructor/destructor
50     KEADataset( H5::H5File *keaImgH5File, GDALAccess eAccess );
51     ~KEADataset();
52 
53     // static methods that handle open and creation
54     // the driver class has pointers to these
55     static GDALDataset *Open( GDALOpenInfo * );
56     static int Identify( GDALOpenInfo * poOpenInfo );
57     static GDALDataset *Create( const char * pszFilename,
58                                   int nXSize, int nYSize, int nBands,
59                                   GDALDataType eType,
60                                   char **  papszParamList );
61     static GDALDataset *CreateCopy( const char * pszFilename, GDALDataset *pSrcDs,
62                                 int bStrict, char **  papszParamList,
63                                 GDALProgressFunc pfnProgress, void *pProgressData );
64 
65     // virtual methods for dealing with transform and projection
66     CPLErr      GetGeoTransform( double * padfTransform ) override;
67     const char *_GetProjectionRef() override;
GetSpatialRef()68     const OGRSpatialReference* GetSpatialRef() const override {
69         return GetSpatialRefFromOldGetProjectionRef();
70     }
71 
72     CPLErr  SetGeoTransform (double *padfTransform ) override;
73     CPLErr _SetProjection( const char *pszWKT ) override;
SetSpatialRef(const OGRSpatialReference * poSRS)74     CPLErr SetSpatialRef(const OGRSpatialReference* poSRS) override {
75         return OldSetProjectionFromSetSpatialRef(poSRS);
76     }
77 
78     // method to get a pointer to the imageio class
79     void *GetInternalHandle (const char *) override;
80 
81     // virtual methods for dealing with metadata
82     CPLErr SetMetadataItem (const char *pszName, const char *pszValue, const char *pszDomain="") override;
83     const char *GetMetadataItem (const char *pszName, const char *pszDomain="") override;
84 
85     char **GetMetadata(const char *pszDomain="") override;
86     CPLErr SetMetadata(char **papszMetadata, const char *pszDomain="") override;
87 
88     // virtual method for adding new image bands
89     CPLErr AddBand(GDALDataType eType, char **papszOptions = nullptr) override;
90 
91     // GCPs
92     int GetGCPCount() override;
93     const char* _GetGCPProjection() override;
GetGCPSpatialRef()94     const OGRSpatialReference* GetGCPSpatialRef() const override {
95         return GetGCPSpatialRefFromOldGetGCPProjection();
96     }
97     const GDAL_GCP* GetGCPs() override;
98     CPLErr _SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList, const char *pszGCPProjection) override;
99     using GDALPamDataset::SetGCPs;
SetGCPs(int nGCPCount,const GDAL_GCP * pasGCPList,const OGRSpatialReference * poSRS)100     CPLErr SetGCPs( int nGCPCount, const GDAL_GCP *pasGCPList,
101                     const OGRSpatialReference* poSRS ) override {
102         return OldSetGCPsFromNew(nGCPCount, pasGCPList, poSRS);
103     }
104 
105 protected:
106     // this method builds overviews for the specified bands.
107     virtual CPLErr IBuildOverviews(const char *pszResampling, int nOverviews, int *panOverviewList,
108                                     int nListBands, int *panBandList, GDALProgressFunc pfnProgress,
109                                     void *pProgressData) override;
110 
111     // internal method to update m_papszMetadataList
112     void UpdateMetadataList();
113 
114     void DestroyGCPs();
115 
116 private:
117     // pointer to KEAImageIO class and the refcount for it
118     kealib::KEAImageIO  *m_pImageIO;
119     LockedRefCount      *m_pRefcount;
120     char               **m_papszMetadataList; // CSLStringList for metadata
121     GDAL_GCP            *m_pGCPs;
122     char                *m_pszGCPProjection;
123     CPLMutex            *m_hMutex;
124 };
125 
126 // conversion functions
127 GDALDataType KEA_to_GDAL_Type( kealib::KEADataType ekeaType );
128 kealib::KEADataType GDAL_to_KEA_Type( GDALDataType egdalType );
129 
130 // For unloading the VFL
131 void KEADatasetDriverUnload(GDALDriver*);
132 
133 // A thresafe reference count. Used to manage shared pointer to
134 // the kealib::KEAImageIO instance between bands and dataset.
135 class LockedRefCount
136 {
137 private:
138     int m_nRefCount;
139     CPLMutex *m_hMutex;
140 
CPL_DISALLOW_COPY_ASSIGN(LockedRefCount)141     CPL_DISALLOW_COPY_ASSIGN(LockedRefCount)
142 
143 public:
144     explicit LockedRefCount(int initCount=1)
145     {
146         m_nRefCount = initCount;
147         m_hMutex = CPLCreateMutex();
148         CPLReleaseMutex( m_hMutex );
149     }
~LockedRefCount()150     ~LockedRefCount()
151     {
152         CPLDestroyMutex( m_hMutex );
153         m_hMutex = nullptr;
154     }
155 
IncRef()156     void IncRef()
157     {
158         CPLMutexHolderD( &m_hMutex );
159         m_nRefCount++;
160     }
161 
162     // returns true if reference count now 0
DecRef()163     bool DecRef()
164     {
165         CPLMutexHolderD( &m_hMutex );
166         m_nRefCount--;
167         return m_nRefCount <= 0;
168     }
169 };
170 
171 #endif //KEADATASET_H
172