OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimTilePatch.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Garrett Potts
9 //
10 //*******************************************************************
11 // $Id: ossimTilePatch.cpp 17195 2010-04-23 17:32:18Z dburken $
12 
13 #include <vector>
14 using namespace std;
15 
22 
24 {
25  thePatchData = ossimImageDataFactory::instance()->create(NULL, input);
26  thePatchData->initialize();
27 }
28 
30  long numberOfComponents,
31  long width,
32  long height)
33  :thePatchData(NULL)
34 {
36  scalarType,
37  numberOfComponents,
38  width,
39  height);
40 
42 }
43 
45 {
46 }
47 
49 {
51 }
52 
54  const ossimDpt &p2,
55  const ossimDpt &p3,
56  const ossimDpt &p4)
57 {
58  vector<ossimDpt> points(4);
59 
60  points[0] = p1;
61  points[1] = p2;
62  points[2] = p3;
63  points[3] = p4;
64 
65  return ossimDrect(points);
66 }
67 
69  long resLevel)
70 {
71  // long w = tileSource->getTileWidth();
72  // long h = tileSource->getTileHeight();
73 
74  if(thePatchData.valid())
75  {
78  // ossimIpt origin(rect.ul());
79  ossimRefPtr<ossimImageData> aTile = tileSource->getTile(rect, resLevel);
80  thePatchData->loadTile(aTile.get());
81  }
82 }
83 
85 {
86  thePatchData = patchData;
87 }
88 
90 {
91  if(!kernel) return;
92 
93  long w = thePatchData->getWidth();
94  long h = thePatchData->getHeight();
95 
96  long kW = kernel->getWidth();
97  long kH = kernel->getHeight();
98  ossimIpt origin = thePatchData->getOrigin();
99 
100  if( (w < kW) || (h < kH))
101  {
102  cerr << " Error ossimTilePatch::convolve(kernel): patch is smaller than kernel size" << endl;
103  return;
104  }
106 
107  // now let's make the buffer just fit the convolution filter
108  //
109  kernelBuffer->setWidth(w - kW);
110  kernelBuffer->setHeight(h - kH);
111  kernelBuffer->setOrigin(ossimDpt(origin.x + kW/2.0,
112  origin.y + kH/2.0));
113  kernelBuffer->initialize();
114 
115  fillTile(kernelBuffer, kernel);
116 
117  kernelBuffer->validate();
118  // now copy the data back to the buffer
119  //
120  thePatchData->loadTile(kernelBuffer.get());
121 
122  // now make sure we validate the buffer.
124 }
125 
127 {
128  if(aTile.valid() &&
130  (aTile->getBuf())&&
131  (thePatchData->getBuf())&&
133  {
134  aTile->loadTile(thePatchData.get());
135  }
136 }
137 
139  ossimDiscreteConvolutionKernel* kernel)const
140 {
141  if(!kernel)
142  {
143  cerr << "Error: Kernel is NULL in ossimTilePatch::fillTile(tile, kernel)!!" << endl;
144  }
145  if(thePatchData->getScalarType() != result->getScalarType())
146  {
147  //ERROR
148  return;
149  }
150  else
151  {
152  switch(thePatchData->getScalarType())
153  {
154  case OSSIM_UCHAR:
155  {
156  fillTileTemplate(static_cast<ossim_uint8>(0),
157  result,
158  kernel);
159  break;
160  }
161  case OSSIM_USHORT16:
162  case OSSIM_USHORT11:
163  case OSSIM_USHORT12:
164  case OSSIM_USHORT13:
165  case OSSIM_USHORT14:
166  case OSSIM_USHORT15:
167  {
168  fillTileTemplate(static_cast<ossim_uint16>(0),
169  result,
170  kernel);
171  break;
172  }
173  case OSSIM_SSHORT16:
174  {
175  fillTileTemplate(static_cast<ossim_sint16>(0),
176  result,
177  kernel);
178  break;
179  }
180  case OSSIM_FLOAT:
182  {
183  fillTileTemplate(static_cast<float>(0),
184  result,
185  kernel);
186  break;
187  }
188  case OSSIM_DOUBLE:
190  {
191  fillTileTemplate(static_cast<double>(0),
192  result,
193  kernel);
194  break;
195  }
196  default:
197  {
198  ossimSetError("ossimTilePatch",
200  "unhandled scalar type %d",
201  (int)thePatchData->getScalarType());
202  break;
203  }
204  }
205  }
206 }
207 
208 
209 
211  const ossimDpt &ul,
212  const ossimDpt &ur,
213  const ossimDpt &deltaUl,
214  const ossimDpt &deltaUr,
215  const ossimDpt &length)const
216 {
220  result->makeBlank();
221  if(thePatchData->getScalarType() != result->getScalarType())
222  {
223  //ERROR
224  return;
225  }
226  else
227  {
228  switch(thePatchData->getScalarType())
229  {
230  case OSSIM_UCHAR:
231  {
232  fillTileTemplate(static_cast<ossim_uint8>(0),
233  result,
234  ul,
235  ur,
236  deltaUl,
237  deltaUr,
238  length);
239  break;
240  }
241  case OSSIM_USHORT16:
242  case OSSIM_USHORT11:
243  case OSSIM_USHORT12:
244  case OSSIM_USHORT13:
245  case OSSIM_USHORT14:
246  case OSSIM_USHORT15:
247  {
248  fillTileTemplate(static_cast<ossim_uint16>(0),
249  result,
250  ul,
251  ur,
252  deltaUl,
253  deltaUr,
254  length);
255  break;
256  }
257  case OSSIM_SSHORT16:
258  {
259  fillTileTemplate(static_cast<ossim_sint16>(0),
260  result,
261  ul,
262  ur,
263  deltaUl,
264  deltaUr,
265  length);
266  break;
267  }
268  case OSSIM_FLOAT:
270  {
271  fillTileTemplate(static_cast<float>(0),
272  result,
273  ul,
274  ur,
275  deltaUl,
276  deltaUr,
277  length);
278  break;
279  }
280  case OSSIM_DOUBLE:
282  {
283  fillTileTemplate(static_cast<double>(0),
284  result,
285  ul,
286  ur,
287  deltaUl,
288  deltaUr,
289  length);
290  break;
291  }
292  default:
293  {
294  ossimSetError("ossimTilePatch",
296  "unhandled scalar type %d",
297  (int)thePatchData->getScalarType());
298  break;
299  }
300  }
301  }
302 
303 }
304 
305 
306 template<class T>
307 void ossimTilePatch::fillTileTemplate(T /* dummyVariable */,
309  ossimDiscreteConvolutionKernel* kernel)const
310 {
311  // get the origin. The convolution could be
312  // an offset into the patch.
313  //
314  ossimIpt startOrigin = result->getOrigin();
315 
316  // Make sure that the patch is not empty or NULL
317  //
319  if((status==OSSIM_EMPTY)||
320  (status == OSSIM_NULL))
321  {
322  return;
323  }
324  ossimDpt startDelta(fabs((double)startOrigin.x - thePatchData->getOrigin().x),
325  fabs((double)startOrigin.y - thePatchData->getOrigin().y));
326 
327  // let's setup some variables that we will need to do the
328  // convolution algorithm.
329  //
331  long tileHeight = result->getHeight();
332  long tileWidth = result->getWidth();
333  long outputBands = result->getNumberOfBands();
334  long convolutionWidth = kernel->getWidth();
335  long convolutionHeight = kernel->getHeight();
336  long convolutionOffsetX= convolutionWidth/2;
337  long convolutionOffsetY= convolutionHeight/2;
338  long patchWidth = patchRect.width();
339  long patchCenterOffset = (long)(patchWidth*startDelta.y + startDelta.x);
340  long patchConvolutionOffsetDelta = patchWidth*convolutionOffsetY + convolutionOffsetX;
341  long patchLineStartOffset = patchCenterOffset - patchConvolutionOffsetDelta;
342  long outputOffset = 0;
343  double min = 1.0;
344  double max = 255.0;
345  if(status == OSSIM_PARTIAL) // must check for NULLS
346  {
347  for(long y = 0; y <tileHeight; y++)
348  {
349  patchCenterOffset = patchLineStartOffset;
350 
351  for(long x =0; x < tileWidth; x++)
352  {
353  if(!thePatchData->isNull(patchCenterOffset))
354  {
355  double convolveResult = 0;
356  for(long b = 0; b < outputBands; ++b)
357  {
358  min=result->getMinPix(b);
359  max=result->getMaxPix(b);
360  T* buf = (T*)(thePatchData->getBuf(b)) + patchCenterOffset;
361  T* outBuf = (T*)(result->getBuf(b));
362 
363  kernel->convolveSubImage(buf,
364  patchWidth,
365  convolveResult);
366  convolveResult = convolveResult < min?min:convolveResult;
367  convolveResult = convolveResult > max?max:convolveResult;
368  outBuf[outputOffset] = (ossim_uint8)convolveResult;
369  }
370  }
371  else
372  {
373  result->setNull(outputOffset);
374  }
375  ++outputOffset;
376  ++patchCenterOffset;
377  }
378  patchLineStartOffset += patchWidth;
379  }
380  }
381  else
382  {
383  for(long b = 0; b < outputBands; ++b)
384  {
385  double convolveResult = 0;
386  const T* buf = (const T*)thePatchData->getBuf(b);
387  T* outBuf = (T*)(result->getBuf(b));
388  outputOffset = 0;
389  patchCenterOffset = (long)(patchWidth*startDelta.y + startDelta.x);
390  patchLineStartOffset = patchCenterOffset - patchConvolutionOffsetDelta;
391  min=result->getMinPix(b);
392  max=result->getMaxPix(b);
393 
394  for(long y = 0; y <tileHeight; y++)
395  {
396  patchCenterOffset = patchLineStartOffset;
397 
398  for(long x =0; x < tileWidth; x++)
399  {
400  kernel->convolveSubImage(&buf[patchCenterOffset],
401  patchWidth,
402  convolveResult);
403  convolveResult = convolveResult < min? min:convolveResult;
404  convolveResult = convolveResult > max?max:convolveResult;
405  outBuf[outputOffset] = (T)convolveResult;
406  ++outputOffset;
407  ++patchCenterOffset;
408  }
409  patchLineStartOffset += patchWidth;
410  }
411  }
412  }
413 }
414 
415 
416 template <class T>
417 void ossimTilePatch::fillTileTemplate(T /* dummyVariable */,
419  const ossimDpt &ul,
420  const ossimDpt &ur,
421  const ossimDpt &deltaUl,
422  const ossimDpt &deltaUr,
423  const ossimDpt &length)const
424 {
425  double stepSizeWidth = 1.0/length.x;
426  double stepSizeHeight = 1.0/length.y;
427  long patchWidth = thePatchData->getWidth();
428  long patchHeight = thePatchData->getHeight();
429 
430 
432 
433  ossimDpt startSave(ul.x - rect.ul().x,
434  ul.y - rect.ul().y );
435  ossimDpt endSave(ur.x - rect.ul().x,
436  ur.y - rect.ul().y);
437  for(ossim_uint32 band = 0; band < thePatchData->getNumberOfBands(); ++band)
438  {
439  T *resultBuf = (T*)result->getBuf(band);
440  const T *sourceBuf = (T*)thePatchData->getBuf(band);
441  ossimDpt start = startSave;
442  ossimDpt end = endSave;
443  T nullPix = static_cast<T>(result->getNullPix(band));
444  for(long y = 0; y < length.y; y++)
445  {
446  double deltaX = (end.x - start.x)*stepSizeWidth;
447  double deltaY = (end.y - start.y)*stepSizeHeight;
448  ossimDpt pointXY = start;
449  for(long x = 0; x < length.x; x++)
450  {
451  int xPixel = pointXY.x<0?(int)floor(pointXY.x):(int)pointXY.x;
452  int yPixel = pointXY.y<0?(int)floor(pointXY.y):(int)pointXY.y;
453  if( (xPixel >=0) && (xPixel < patchWidth) &&
454  (yPixel >=0) && (yPixel < patchHeight))
455  {
456  *resultBuf = sourceBuf[yPixel*patchWidth + xPixel];
457  }
458  else
459  {
460  *resultBuf = nullPix;
461  }
462 
463  resultBuf++;
464  pointXY.y += deltaY;
465  pointXY.x += deltaX;
466  }
467 
468  start.x += deltaUl.x;
469  start.y += deltaUl.y;
470  end.x += deltaUr.x;
471  end.y += deltaUr.y;
472  }
473  }
474 }
475 
476 
478  const ossimDpt &p2,
479  const ossimDpt &p3,
480  const ossimDpt &p4,
481  const ossimDpt &tile_size,
482  const ossimDpt &padding)
483 {
484  setRect(findBoundingRect(p1, p2, p3, p4),
485  tile_size,
486  padding);
487 }
488 
490  const ossimDpt &rect_size,
491  const ossimDpt &tile_size,
492  const ossimDpt &padding)
493 {
494  ossimDpt ul (center - rect_size/2.0);
495  ossimDpt lr (center + rect_size/2.0);
496  ossimDrect rect (ul, lr);
497  setRect(rect, tile_size, padding);
498 }
499 
501  const ossimDpt& /* tile_size*/,
502  const ossimDpt& padding)
503 {
504  ossimDpt ul(aRect.ul().x - padding.x,
505  aRect.ul().y - padding.y);
506  ossimDpt lr(aRect.lr().x + padding.x,
507  aRect.lr().y + padding.y);
508 
509  ossimDrect rect(ul, lr);
510  rect.stretchOut();
511 
512 // rect = alignRectToBoundary(rect, tile_size);
513 
514  if(thePatchData.valid())
515  {
516  if( ((long)thePatchData->getWidth() != (long)rect.width()) ||
517  ((long)thePatchData->getHeight() != (long)rect.height()))
518  {
519  thePatchData->setWidth((long)rect.width());
520  thePatchData->setHeight((long)rect.height());
521  }
522  thePatchData->setOrigin(rect.ul());
524  }
525 }
526 
OSSIMDLLEXPORT void ossimSetError(const char *className, ossim_int32 error, const char *fmtString=0,...)
16 bit unsigned integer (15 bits used)
virtual void fillPatch(ossimImageSource *imageSource, long resLevel=0)
virtual ossim_uint32 getWidth() const
ossim_uint32 x
void setData(ossimRefPtr< ossimImageData > &patchData)
virtual const ossim_float64 * getMaxPix() const
static ossimDiscreteNearestNeighbor nearestNeighborKernel
virtual ossim_uint32 getNumberOfBands() const
virtual ossimIrect getRect() const
ossim_uint32 y
bool valid() const
Definition: ossimRefPtr.h:75
ossimRefPtr< ossimImageData > thePatchData
const ossimDpt & ul() const
Definition: ossimDrect.h:339
double y
Definition: ossimDpt.h:165
virtual void fillTile(ossimRefPtr< ossimImageData > &aTile) const
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossim_uint32 getHeight() const
16 bit unsigned integer (14 bits used)
static const ossimErrorCode OSSIM_ERROR
16 bit unsigned integer (13 bits used)
virtual void initialize()
Initialize the data buffer.
virtual ossimObject * dup() const
bool isNull(ossim_uint32 offset) const
virtual void loadTile(const void *src, const ossimIrect &src_rect, ossimInterleaveType il_type)
virtual void setHeight(ossim_uint32 height)
virtual void setNullPix(ossim_float64 null_pix)
static ossimImageDataFactory * instance()
void convolve(ossimDiscreteConvolutionKernel *kernel)
virtual ossimDataObjectStatus validate() const
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
32 bit normalized floating point
virtual void setWidth(ossim_uint32 width)
virtual ossimIrect getImageRectangle() const
void fillTileTemplate(T dummyVariable, ossimRefPtr< ossimImageData > &result, const ossimDpt &ul, const ossimDpt &ur, const ossimDpt &deltaUl, const ossimDpt &deltaUr, const ossimDpt &length) const
static ossimDrect findBoundingRect(const ossimDpt &p1, const ossimDpt &p2, const ossimDpt &p3, const ossimDpt &p4)
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
virtual void setRect(const ossimDpt &p1, const ossimDpt &p2, const ossimDpt &p3, const ossimDpt &p4, const ossimDpt &tile_size, const ossimDpt &padding=ossimDpt(0, 0))
void setNull(ossim_uint32 offset)
ossimScalarType
virtual void setOrigin(const ossimIpt &origin)
virtual const ossim_float64 * getMinPix() const
return status
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)
virtual void setMaxPix(ossim_float64 max_pix)
#define max(a, b)
Definition: auxiliary.h:76
ossim_int32 y
Definition: ossimIpt.h:142
virtual const void * getBuf() const
double x
Definition: ossimDpt.h:164
virtual void convolveSubImage(const float *data, long dataWidth, double &result, float nullPixel=OSSIM_DEFAULT_NULL_PIX_FLOAT) const
ossim_int32 x
Definition: ossimIpt.h:141
virtual ~ossimTilePatch()
ossimDataObjectStatus
Definitions for data object status.
ossimTilePatch(ossimImageSource *input)
32 bit floating point
const ossimDpt & lr() const
Definition: ossimDrect.h:341
virtual void setMinPix(ossim_float64 min_pix)
16 bit unsigned iteger
64 bit floating point
16 bit signed integer
virtual const ossimIpt & getOrigin() const
unsigned char ossim_uint8
8 bit unsigned iteger
#define min(a, b)
Definition: auxiliary.h:75
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
16 bit unsigned integer (12 bits used)