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