1 /******************************************************************************
2  * $Id: jpipkakdataset.cpp 2008-10-01 nbarker $
3  *
4  * Project:  jpip read driver
5  * Purpose:  GDAL bindings for JPIP.
6  * Author:   Norman Barker, ITT VIS, norman.barker@gmail.com
7  *
8  ******************************************************************************
9  * ITT Visual Information Systems grants you use of this code, under the following license:
10  *
11  * Copyright (c) 2000-2007, ITT Visual Information Solutions
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a
14  * copy of this software and associated documentation files (the "Software"),
15  * to deal in the Software without restriction, including without limitation
16  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  * and/or sell copies of the Software, and to permit persons to whom the
18  * Software is furnished to do so, subject to the following conditions:
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21 
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29 **/
30 
31 #include "gdal_pam.h"
32 #include "gdaljp2metadata.h"
33 #include "cpl_conv.h"
34 #include "cpl_string.h"
35 #include "cpl_http.h"
36 #include "cpl_vsi.h"
37 #include "cpl_multiproc.h"
38 
39 #include "kdu_cache.h"
40 #include "kdu_region_decompressor.h"
41 #include "kdu_file_io.h"
42 
43 #include <time.h>
44 
45 
46 #if KDU_MAJOR_VERSION > 7 || (KDU_MAJOR_VERSION == 7 && KDU_MINOR_VERSION >= 5)
47     using namespace kdu_core;
48     using namespace kdu_supp;
49 #endif
50 
51 
52 static void JPIPWorkerFunc(void *);
53 
54 /************************************************************************/
55 /* ==================================================================== */
56 /*                           JPIPDataSegment                            */
57 /* ==================================================================== */
58 /************************************************************************/
59 class JPIPDataSegment
60 {
61 private:
62     long nId;
63     long nAux;
64     long nClassId;
65     long nCodestream;
66     long nOffset;
67     long nLen;
68     GByte* pabyData;
69     int bIsFinal;
70     int bIsEOR;
71 public:
GetId()72     int GetId(){return nId;}
GetAux()73     int GetAux(){return nAux;}
GetClassId()74     int GetClassId(){return nClassId;}
GetCodestreamIdx()75     int GetCodestreamIdx(){return nCodestream;}
GetOffset()76     int GetOffset(){return nOffset;}
GetLen()77     int GetLen(){return nLen;}
GetData()78     GByte* GetData(){return pabyData;}
IsFinal()79     int IsFinal(){return bIsFinal;}
IsEOR()80     int IsEOR(){return bIsEOR;}
81 
SetId(long nId)82     void SetId(long nId){this->nId = nId;}
SetAux(long nAux)83     void SetAux(long nAux){this->nAux = nAux;}
SetClassId(long nClassId)84     void SetClassId(long nClassId){this->nClassId = nClassId;}
SetCodestreamIdx(long nCodestream)85     void SetCodestreamIdx(long nCodestream){this->nCodestream = nCodestream;}
SetOffset(long nOffset)86     void SetOffset(long nOffset){this->nOffset = nOffset;}
SetLen(long nLen)87     void SetLen(long nLen){this->nLen = nLen;}
SetData(GByte * pabyData)88     void SetData(GByte* pabyData){this->pabyData = pabyData;}
SetFinal(int bIsFinal)89     void SetFinal(int bIsFinal){this->bIsFinal = bIsFinal;}
SetEOR(int bIsEOR)90     void SetEOR(int bIsEOR){this->bIsEOR = bIsEOR;}
91     JPIPDataSegment();
92     ~JPIPDataSegment();
93 };
94 
95 /************************************************************************/
96 /* ==================================================================== */
97 /*                           JPIPKAKDataset                             */
98 /* ==================================================================== */
99 /************************************************************************/
100 class JPIPKAKDataset: public GDALPamDataset
101 {
102 private:
103     int       bNeedReinitialize;
104     CPLString osRequestUrl;
105     char* pszTid;
106     char* pszPath;
107     char* pszCid;
108     char* pszProjection;
109 
110     int nPos;
111     int nVBASLen;
112     int nVBASFirstByte;
113     int nClassId;
114     int nQualityLayers;
115     int nResLevels;
116     int nComps;
117     int nBitDepth;
118     int bYCC;
119     GDALDataType eDT;
120 
121     int nCodestream;
122     long nDatabins;
123 
124     double adfGeoTransform[6];
125 
126     int bWindowDone;
127     int bGeoTransformValid;
128 
129     int nGCPCount;
130     GDAL_GCP *pasGCPList;
131 
132     // kakadu
133     kdu_codestream *poCodestream;
134     kdu_region_decompressor *poDecompressor;
135     kdu_cache *poCache;
136 
137     long ReadVBAS(GByte* pabyData, int nLen);
138     JPIPDataSegment* ReadSegment(GByte* pabyData, int nLen, int& bError);
139     int Initialize(const char* url, int bReinitializing );
140     void Deinitialize();
141     int KakaduClassId(int nClassId);
142 
143     CPLMutex *pGlobalMutex;
144 
145     // support two communication threads to the server, a main and an overview thread
146     volatile int bHighThreadRunning;
147     volatile int bLowThreadRunning;
148     volatile int bHighThreadFinished;
149     volatile int bLowThreadFinished;
150 
151     // transmission counts
152     volatile long nHighThreadByteCount;
153     volatile long nLowThreadByteCount;
154 
155 public:
156     JPIPKAKDataset();
157     virtual ~JPIPKAKDataset();
158 
159     // progressive methods
160     virtual GDALAsyncReader* BeginAsyncReader(int xOff, int yOff,
161                                               int xSize, int ySize,
162                                               void *pBuf,
163                                               int bufXSize, int bufYSize,
164                                               GDALDataType bufType,
165                                               int nBandCount, int* bandMap,
166                                               int nPixelSpace, int nLineSpace,
167                                               int nBandSpace,
168                                               char **papszOptions);
169 
170     virtual void EndAsyncReader(GDALAsyncReader *);
GetNQualityLayers()171     int GetNQualityLayers(){return nQualityLayers;}
GetNResolutionLevels()172     int GetNResolutionLevels(){return nResLevels;}
GetNComponents()173     int GetNComponents(){return nComps;}
174 
175     int ReadFromInput(GByte* pabyData, int nLen, int& bError );
176 
177     int TestUseBlockIO( int nXOff, int nYOff, int nXSize, int nYSize,
178                         int nBufXSize, int nBufYSize, GDALDataType eDataType,
179                         int nBandCount, int *panBandList );
180 
181     //gdaldataset methods
182     virtual CPLErr GetGeoTransform( double * );
183     virtual const char *GetProjectionRef(void);
184     virtual int    GetGCPCount();
185     virtual const char *GetGCPProjection();
186     virtual const GDAL_GCP *GetGCPs();
187     virtual CPLErr IRasterIO( GDALRWFlag eRWFlag,
188                               int nXOff, int nYOff, int nXSize, int nYSize,
189                               void * pData, int nBufXSize, int nBufYSize,
190                               GDALDataType eBufType,
191                               int nBandCount, int *panBandMap,
192                               GSpacing nPixelSpace, GSpacing nLineSpace,
193                               GSpacing nBandSpace,
194                               GDALRasterIOExtraArg* psExtraArg);
195 
196     static GDALDataset *Open(GDALOpenInfo *);
197     static const GByte JPIP_EOR_IMAGE_DONE = 1;
198     static const GByte JPIP_EOR_WINDOW_DONE = 2;
199     static const GByte MAIN_HEADER_DATA_BIN_CLASS = 6;
200     static const GByte META_DATA_BIN_CLASS = 8;
201     static const GByte PRECINCT_DATA_BIN_CLASS = 0;
202     static const GByte TILE_HEADER_DATA_BIN_CLASS = 2;
203     static const GByte TILE_DATA_BIN_CLASS = 4;
204 
205     friend class JPIPKAKAsyncReader;
206     friend class JPIPKAKRasterBand;
207     friend void JPIPWorkerFunc(void*);
208 };
209 
210 /************************************************************************/
211 /* ==================================================================== */
212 /*                            JPIPKAKRasterBand                          */
213 /* ==================================================================== */
214 /************************************************************************/
215 
216 class JPIPKAKRasterBand : public GDALPamRasterBand
217 {
218     friend class JPIPKAKDataset;
219 
220     JPIPKAKDataset *poBaseDS;
221 
222     int         nDiscardLevels;
223 
224     kdu_dims 	band_dims;
225 
226     int		nOverviewCount;
227     JPIPKAKRasterBand **papoOverviewBand;
228 
229     kdu_codestream *oCodeStream;
230 
231     GDALColorTable oCT;
232     GDALColorInterp eInterp;
233 
234 public:
235 
236     JPIPKAKRasterBand( int, int, kdu_codestream *, int,
237                        JPIPKAKDataset * );
238     ~JPIPKAKRasterBand();
239 
240     virtual CPLErr IReadBlock( int, int, void * );
241     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
242                               void *, int, int, GDALDataType,
243                               GSpacing nPixelSpace, GSpacing nLineSpace,
244                               GDALRasterIOExtraArg* psExtraArg );
245 
246     virtual int    GetOverviewCount();
247     virtual GDALRasterBand *GetOverview( int );
248 };
249 
250 /************************************************************************/
251 /* ==================================================================== */
252 /*                           JPIPKAKAsyncReader                         */
253 /* ==================================================================== */
254 /************************************************************************/
255 
256 class JPIPKAKAsyncReader : public GDALAsyncReader
257 {
258 private:
259     void *pAppBuf;
260     int  nAppPixelSpace, nAppLineSpace, nAppBandSpace;
261 
262     int nDataRead;
263     int nLevel;
264     int nQualityLayers;
265     int bHighPriority;
266     int bComplete;
267     kdu_channel_mapping channels;
268     kdu_coords exp_numerator, exp_denominator;
269 
270     kdu_dims rr_win; // user requested window expressed on reduced res level
271 
272     void Start();
273     void Stop();
274 
275 public:
276     JPIPKAKAsyncReader();
277     virtual ~JPIPKAKAsyncReader();
278 
279     virtual GDALAsyncStatusType GetNextUpdatedRegion(double timeout,
280                                                      int* pnxbufoff,
281                                                      int* pnybufoff,
282                                                      int* pnxbufsize,
283                                                      int* pnybufsize);
SetComplete(int bFinished)284     void SetComplete(int bFinished){this->bComplete = bFinished;};
285 
286     friend class JPIPKAKDataset;
287 
288     CPLString  osErrorMsg;
289 };
290 
291 /************************************************************************/
292 /* ==================================================================== */
293 /*                           JPIPRequest                                */
294 /* ==================================================================== */
295 /************************************************************************/
296 struct JPIPRequest
297 {
298     int bPriority;
299     CPLString osRequest;
300     JPIPKAKAsyncReader* poARIO;
301 };
302