OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimGdalTiledDataset.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: Garrett Potts
8 //
9 // $Id: ossimGdalTiledDataset.cpp 19668 2011-05-27 13:26:58Z gpotts $
10 //------------------------------------------------------------------------
11 #include "ossimGdalTiledDataset.h"
12 #include <ossim/vpfutil/set.h>
13 #include "ossimGdalType.h"
14 
19 #include <cpl_string.h>
20 
21 static GDALDriver *poMEMTiledDriver = NULL;
22 
23 #include <ossim/base/ossimTrace.h>
24 static ossimTrace traceDebug(ossimString("ossimGdalTiledDataset:debug"));
25 
26 GDALRasterBandH MEMTiledCreateRasterBand( GDALDataset *poDS, int nBand,
27  GByte *pabyData, GDALDataType eType,
28  int nPixelOffset, int nLineOffset,
29  int bAssumeOwnership )
30 
31 {
32  return (GDALRasterBandH)
33  new MEMTiledRasterBand( poDS, nBand, pabyData, eType, nPixelOffset,
34  nLineOffset, bAssumeOwnership );
35 }
36 
37 /************************************************************************/
38 /* MEMTiledRasterBand() */
39 /************************************************************************/
40 
42  int nBand,
43  GByte *pabyData,
44  GDALDataType eType,
45  int nPixelOffset,
46  int nLineOffset,
47  int bAssumeOwnership )
48  :
49  MEMRasterBand(poDS,
50  nBand,
51  pabyData,
52  eType,
53  nPixelOffset,
54  nLineOffset,
55  bAssumeOwnership),
56  theDataset(NULL),
57  theInterface(NULL)
58 {
59 }
60 
61 /************************************************************************/
62 /* ~MEMTiledRasterBand() */
63 /************************************************************************/
64 
66 
67 {
68  CPLDebug( "MEM", "~MEMTiledRasterBand(%p)", this );
69  if( bOwnData )
70  {
71  CPLDebug( "MEM", "~MEMTiledRasterBand() - free raw data." );
72  VSIFree( pabyData );
73  }
74 }
75 
76 
77 /************************************************************************/
78 /* IReadBlock() */
79 /************************************************************************/
80 
81 CPLErr MEMTiledRasterBand::IReadBlock( int nBlockXOff,
82  int nBlockYOff,
83  void * pImage )
84 
85 {
86 #if 0
87  if (traceDebug())
88  {
90  << "MEMTiledRasterBand::IReadBlock DEBUG: entered..."
91  << "\nnBlockXSize: " << nBlockXSize
92  << "\nnBlockYSize: " << nBlockYSize
93  << "\nnBlockXOff: " << nBlockXSize
94  << "\nnBlockYOff: " << nBlockYSize
95 
96  << endl;
97  }
98 #endif
99 
100  if (!theDataset->theData) // Check for a valid buffer.
101  {
102  return CE_None;
103  }
104 
106 
107  ossimIpt ul(theDataset->theAreaOfInterest.ul().x + nBlockXOff*nBlockXSize,
108  theDataset->theAreaOfInterest.ul().y + nBlockYOff*nBlockYSize);
109 
110  ossimIrect requestRect(ul.x,
111  ul.y,
112  ul.x + nBlockXSize - 1,
113  ul.y + nBlockYSize - 1);
114 #if 0
115  if (traceDebug())
116  {
118  << "\nrequestRect: " << requestRect
119  << "\nbufferRect: " << bufferRect
120  << endl;
121  }
122 #endif
123 
124  if(requestRect.height() > 1)
125  {
127  << "MEMTiledRasterBand::IReadBlock WARN!"
128  << "\nOnly one scanline block reads allowed" << endl;
129  return CE_None;
130  }
131 
132  if(nBlockYOff==0)
133  {
135  }
136 
137  bool loadBuffer = false;
138 
139  if ( (requestRect.completely_within(bufferRect) == false) ||
141  {
142  loadBuffer = true;
143  }
144 
145 #if 0
146  ossim_int32 scanlineTile = ((nBlockYOff*nBlockYSize)%theDataset->theTileSize.y);
147  if (traceDebug())
148  {
150  << "\nscanlineTile: " << scanlineTile
151  << endl;
152  }
153 #endif
154 
155  if(loadBuffer)
156  {
158  theDataset->theData->setOrigin(requestRect.ul());
159  // fill the tile with one row;
161  for(ossim_uint32 i = 0; i < numberOfTiles; ++i)
162  {
163  ossimIpt tileOrigin(ul.x+theDataset->theTileSize.x*i, ul.y);
164 #if 0
165  if (traceDebug())
166  {
168  << "\ntileOrigin: " << tileOrigin << endl;
169  }
170 #endif
173  ossimIrect(tileOrigin.x,
174  tileOrigin.y,
175  tileOrigin.x + (theDataset->theTileSize.x - 1),
176  tileOrigin.y + (theDataset->theTileSize.y - 1)));
177  if(data.valid())
178  {
179  if (data->getBuf())
180  {
181  theDataset->theData->loadTile(data.get());
182  }
183  else
184  {
185  // Hmmm???
186  ossimRefPtr<ossimImageData> tempData =
187  (ossimImageData*)data->dup();
188  tempData->initialize();
189  theDataset->theData->loadTile(tempData.get());
190  }
191  }
192  }
194 
195  // Capture the buffer rectangle.
196  bufferRect = theDataset->theData->getImageRectangle();
197  }
198 
199 #if 0
200  if (traceDebug())
201  {
203  << "nBlockYOff: " << nBlockYOff
204  << "\ntheDataset->theData->getImageRectangle()"
206  << endl;
207  }
208 #endif
209 
210  // Bytes per pixel.
211  const ossim_int32 BPP = static_cast<ossim_int32>(
213 
215  {
216  copyNulls(pImage, nBlockYSize * nBlockXSize);
217  }
218  else
219  {
220  int nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
221  CPLAssert( nBlockXOff == 0 );
222 
223  if( nPixelOffset == nWordSize )
224  {
225  ossim_uint32 offset = (ul.y - bufferRect.ul().y) *
226  bufferRect.width() * BPP +
227  (ul.x - bufferRect.ul().x) * BPP;
228 
229  GByte *pabyCur = ((GByte*) (theDataset->theData->getBuf(nBand-1)))
230  + offset;
231 
232  memcpy( pImage,
233  pabyCur,
234  nPixelOffset * nBlockXSize);
235  }
236  else
237  {
239  << "MEMTiledRasterBand::IReadBlock WARN!"
240  << "\nUnhandled wordsize..."
241  << endl;
242 #if 0
243  // shift to start of scanline
244  GByte *pabyCur = (GByte*) (theDataset->theData->getBuf(nBand-1))
246  theDataset->theData->getWidth()*scanlineTile);
247 
248  for( int iPixel = 0; iPixel < nBlockXSize; iPixel++ )
249  {
250  memcpy( (GByte *) pImage+ iPixel*nWordSize,
251  pabyCur + iPixel*nPixelOffset,
252  nWordSize );
253  }
254 #endif
255  }
256  }
257 
258  return CE_None;
259 }
260 
261 /************************************************************************/
262 /* IWriteBlock() */
263 /************************************************************************/
264 
265 CPLErr MEMTiledRasterBand::IWriteBlock( int /*nBlockXOff*/, int /*nBlockYOff*/,
266  void * /*pImage*/ )
267 
268 {
269 // int nWordSize = GDALGetDataTypeSize( eDataType );
270 // CPLAssert( nBlockXOff == 0 );
271 
272 // if( nPixelOffset*8 == nWordSize )
273 // {
274 // memcpy( pabyData+nLineOffset*nBlockYOff,
275 // pImage,
276 // nPixelOffset * nBlockXSize );
277 // }
278 // else
279 // {
280 // GByte *pabyCur = pabyData + nLineOffset*nBlockYOff;
281 
282 // for( int iPixel = 0; iPixel < nBlockXSize; iPixel++ )
283 // {
284 // memcpy( pabyCur + iPixel*nPixelOffset,
285 // ((GByte *) pImage) + iPixel*nWordSize,
286 // nWordSize );
287 // }
288 // }
289 
290  return CE_None;
291 }
292 
293 /************************************************************************/
294 /* ==================================================================== */
295 /* MEMTiledDataset */
296 /* ==================================================================== */
297 /************************************************************************/
298 
299 
300 /************************************************************************/
301 /* MEMTiledDataset() */
302 /************************************************************************/
303 
305  :
306  MEMDataset(),
307  theData(),
308  theInterface(NULL),
309  theTileSize(),
310  theAreaOfInterest(),
311  theJustCreatedFlag(false),
312  theSetNoDataValueFlag(true)
313 {
314 }
315 
317  :
318  MEMDataset(),
319  theData(),
320  theInterface(iface),
321  theTileSize(),
322  theAreaOfInterest(),
323  theJustCreatedFlag(false),
324  theSetNoDataValueFlag(true)
325 {
327 }
328 
329 /************************************************************************/
330 /* ~MEMTiledDataset() */
331 /************************************************************************/
332 
334 
335 {
336  FlushCache();
337 }
338 
339 /************************************************************************/
340 /* Create() */
341 /************************************************************************/
343 {
344  if (traceDebug())
345  {
347  << "MEMTiledDataset::create DEBUG: entered..."
348  << endl;
349  }
350 
351  theInterface = iface;
352 
353  if(theInterface)
354  {
355 
356  ossimKeywordlist kwl;
357 
358  GByte **papBandData;
359  int nBands = theInterface->getNumberOfOutputBands();
360  theData = ossimImageDataFactory::instance()->create(NULL, // no owner specified
361  theInterface);
362 
363  GDALDataType gdalType = ossimGdalType().toGdal(theInterface->getOutputScalarType());
364  int nWordSize = GDALGetDataTypeSize(gdalType) / 8;
365  int tw = theInterface->getTileWidth();
366  int th = theInterface->getTileHeight();
367  int band = 0;
368 
369  papBandData = (GByte **) CPLCalloc(sizeof(void *),nBands);
370 
371  for( band = 0; band < nBands; band++ )
372  {
373  papBandData[band] = (GByte *) VSICalloc( nWordSize, tw * th );
374  }
375 
376  poDriver = poMEMTiledDriver;
378 
381 
382  nRasterXSize = bounds.width();
383  nRasterYSize = bounds.height();
384 
385  if (traceDebug())
386  {
388  << "DEBUG:"
389  << "\nnRasterXSize" << nRasterXSize
390  << "\nnRasterYSize" << nRasterYSize
391  << endl;
392  }
393 
394  eAccess = GA_Update;
395  if(theData.valid())
396  {
397  theData->setWidth(nRasterXSize);
399  theData->initialize();
400  }
401 
402  if (traceDebug())
403  {
405  << "DEBUG:"
406  << "\ntheData: " << *theData.get()
407  << endl;
408  }
409 
410 
411 /* -------------------------------------------------------------------- */
412 /* Create band information objects. */
413 /* -------------------------------------------------------------------- */
414 
415  for( band = 0; band < nBands; band++ )
416  {
417 
418  MEMTiledRasterBand* rasterBand =
419  new MEMTiledRasterBand( this,
420  band+1,
421  papBandData[band],
422  gdalType,
423  0,
424  0,
425  TRUE );
426  rasterBand->theDataset = this;
428  {
429  rasterBand->SetNoDataValue(theInterface->getNullPixelValue(band));
430  }
431  SetBand( band+1,
432  rasterBand);
433  }
434 
435  theJustCreatedFlag = true;
436  CPLFree( papBandData );
437 
439 /* -------------------------------------------------------------------- */
440 /* Try to return a regular handle on the file. */
441 /* -------------------------------------------------------------------- */
442  }
443 
444  if (traceDebug())
445  {
447  << "MEMTiledDataset::create DEBUG: exited..."
448  << endl;
449  }
450 
451 }
452 
454 {
455  theSetNoDataValueFlag = flag;
456 }
457 
458 /************************************************************************/
459 /* GDALRegister_MEM() */
460 /************************************************************************/
461 
463 
464 {
465  GDALDriver *poDriver;
466 
467  if( poMEMTiledDriver == NULL )
468  {
469  poMEMTiledDriver = poDriver = new GDALDriver();
470 
471  poDriver->SetDescription( "MEM TILED" );
472  poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
473  "In Memory Raster OSSIM tile bridge" );
474 
475  poDriver->pfnOpen = MEMDataset::Open;
476  poDriver->pfnCreate = MEMDataset::Create;
477 
478  GetGDALDriverManager()->RegisterDriver( poDriver );
479  }
480 }
481 
482 void MEMTiledRasterBand::copyNulls(void* pImage, int count) const
483 {
484  if (theDataset && pImage)
485  {
486  if (theDataset->theData.valid())
487  {
488  switch (theDataset->theData->getScalarType())
489  {
490  case OSSIM_UINT8:
491  {
492  return copyNulls(pImage, count, ossim_uint8(0));
493  }
494  case OSSIM_SINT8:
495  {
496  return copyNulls(pImage, count, ossim_sint8(0));
497  }
498 
499  case OSSIM_UINT16:
500  case OSSIM_USHORT11:
501  {
502  return copyNulls(pImage, count, ossim_uint16(0));
503  }
504  case OSSIM_SINT16:
505  {
506  return copyNulls(pImage, count, ossim_sint16(0));
507  }
508 
509  case OSSIM_UINT32:
510  {
511  return copyNulls(pImage, count, ossim_uint32(0));
512  }
513  case OSSIM_SINT32:
514  {
515  return copyNulls(pImage, count, ossim_sint32(0));
516  }
517  case OSSIM_FLOAT32:
519  {
520  return copyNulls(pImage, count, ossim_float32(0.0));
521  }
522 
524  case OSSIM_FLOAT64:
525  {
526  return copyNulls(pImage, count, ossim_float64(0.0));
527  }
529  default:
530  {
531  break;
532  }
533 
534  } // End of "switch (theDataset->theData->getScalarType())"
535 
536  } // End of "if (theDataset->theData.valid())"
537 
538  } // End of "if (theDataset && pImage)"
539 }
540 
541 template <class T>
543  int count,
544  T /* dummyTemplate */ ) const
545 {
546  // All pointer checking performed by caller.
547 
548  T* p = static_cast<T*>(pImage);
549  T nullPix = static_cast<T>(theDataset->theData->getNullPix(0));
550 
551  for (int i = 0; i < count; ++i)
552  {
553  p[i] = nullPix;
554  }
555 }
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
8 bit signed integer
bool theSetNoDataValueFlag
DRB - 20081020 If true (default) the no data value will be set to null pixel value.
virtual ossim_uint32 getWidth() const
64 bit floating point
16 bit unsigned integer
virtual ossim_uint32 getTileWidth() const
Returns the default processing tile width.
GDALRasterBandH MEMTiledCreateRasterBand(GDALDataset *poDS, int nBand, GByte *pabyData, GDALDataType eType, int nPixelOffset, int nLineOffset, int bAssumeOwnership)
Represents serializable keyword/value map.
MEMTiledRasterBand(GDALDataset *poDS, int nBand, GByte *pabyData, GDALDataType eType, int nPixelOffset, int nLineOffset, int bAssumeOwnership)
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
bool valid() const
Definition: ossimRefPtr.h:75
float ossim_float32
ossim_uint32 height() const
Definition: ossimIrect.h:487
ossimIrect theAreaOfInterest
16 bit signed integer
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimDataObjectStatus getDataObjectStatus() const
signed char ossim_sint8
32 bit floating point
void setNoDataValueFlag(bool flag)
DRB - 20081020 If true (default) the no data value will be set to null pixel value.
unsigned short ossim_uint16
32 bit unsigned integer
virtual void initialize()
Initialize the data buffer.
MEMTiledDataset * theDataset
virtual ossimObject * dup() const
double ossim_float64
virtual void loadTile(const void *src, const ossimIrect &src_rect, ossimInterleaveType il_type)
virtual void setHeight(ossim_uint32 height)
static ossimImageDataFactory * instance()
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
void create(ossimImageSourceSequencer *iface)
virtual ossimDataObjectStatus validate() const
signed short ossim_sint16
32 bit signed integer
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
This will return the bounding rect of the source.
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
32 bit normalized floating point
signed int ossim_sint32
virtual void setWidth(ossim_uint32 width)
virtual ossimIrect getImageRectangle() const
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
virtual CPLErr IReadBlock(int, int, void *)
virtual void setOrigin(const ossimIpt &origin)
virtual ossim_uint32 getScalarSizeInBytes() const
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
void GDALRegister_MEMTiled()
virtual ossimScalarType getScalarType() const
virtual void makeBlank()
Initializes data to null pixel values.
64 bit normalized floating point
16 bit unsigned integer (11 bits used)
ossim_int64 getNumberOfTilesHorizontal() const
virtual ossim_uint32 getTileHeight() const
Returns the default processing tile height.
ossimImageSourceSequencer * theInterface
ossim_int32 y
Definition: ossimIpt.h:142
virtual const void * getBuf() const
friend class MEMTiledRasterBand
ossim_int32 x
Definition: ossimIpt.h:141
8 bit unsigned integer
GDALDataType toGdal(ossimScalarType) const
virtual CPLErr IWriteBlock(int, int, void *)
unsigned char ossim_uint8
ossimRefPtr< ossimImageData > theData
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
int ossim_int32
void copyNulls(void *pImage, int count) const
Copies null values to pImage.