Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
clfImage3D.cpp
1 /*
2  This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4  Copyright (C) 2003, 2004 (see file CONTACTS for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10  BIAS is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  BIAS is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with BIAS; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 #include <Base/Common/BIASpragma.hh>
26 #include <OpenCLFramework/clfImage3D.hh>
27 #include <OpenCLFramework/clfException.hh>
28 #include <Base/Debug/Error.hh>
29 
30 using namespace BIAS;
31 
32 std::vector<cl::ImageFormat> clfImage3D::imageFormatsReadable_;
33 std::vector<cl::ImageFormat> clfImage3D::imageFormatsWritable_;
34 std::vector<cl::ImageFormat> clfImage3D::imageFormatsReadWrite_;
35 
36 
37 clfImage3D::clfImage3D(cl::Context *context, cl::CommandQueue *queue) : clfMemory(context, queue) {
38  BIASWARN("clfImage3D is untested, use with care");
39  width_ = 0;
40  height_ = 0;
41  depth_ = 0;
42  stride_ = 0;
43  slideStride_ = 0;
46  if (imageFormatsReadable_.empty()) {
47  context_->getSupportedImageFormats(CL_MEM_READ_ONLY, CL_MEM_OBJECT_IMAGE3D, &imageFormatsReadable_);
48  }
49  if (imageFormatsWritable_.empty()) {
50  context_->getSupportedImageFormats(CL_MEM_READ_ONLY, CL_MEM_OBJECT_IMAGE3D, &imageFormatsWritable_);
51  }
52  if (imageFormatsReadWrite_.empty()) {
53  context_->getSupportedImageFormats(CL_MEM_READ_WRITE, CL_MEM_OBJECT_IMAGE3D, &imageFormatsReadWrite_);
54  }
55 }
56 
58 }
59 
62  unsigned int width, unsigned int height, unsigned int levels, unsigned int stride,
63  bool readonly, bool writeonly, const void *hostptr, bool copy) {
64 
65  int cl_mem_flags = DetermineMemFlags_(readonly, writeonly, hostptr, copy);
66  if (cm == BIAS::ImageBase::CM_RGB) {
67  BIASWARN("RGB not supported, interpreting as Grey, width*3");
69  height = height * 3;
70  }
71  cl::ImageFormat format = DetermineImageFormat_(st,cm);
72  if (!GetFormatSupported_(format, readonly, writeonly)) {
73  THROW_CL_EXCEPTION(cl::Error(-100, "requested image format is not supported by device."));
74  }
75  try {
76  if (stride == 0) {
77  switch (st) {
79  stride = BIAS::ImageBase::GetChannelcount(cm)*width*sizeof(float);
80  break;
82  stride = BIAS::ImageBase::GetChannelcount(cm)*width*sizeof(unsigned char);
83  break;
84  default:
85  stride = BIAS::ImageBase::GetChannelcount(cm)*width*sizeof(unsigned char);
86  THROW_CL_EXCEPTION(cl::Error(-100, "please provide stride for your data type or extend code for automatic support."));
87  break;
88  }
89  }
90  if (initialized_ && !sharedGL_ && stride_ == stride && width == width_ && height == height_) {
91  // already allocated with correct size
92  return;
93  }
94  width_ = width;
95  height_ = height;
96  depth_ = levels;
97  stride_ = stride;
98  slideStride_ = stride*height;
99  size_ = slideStride_*depth_;
100  st_ = st;
101  cm_ = cm;
102  buffer_ = cl::Image3D(*context_, cl_mem_flags, format, width_, height_, depth_, 0, 0, (void*)hostptr);
103 
104  } catch(cl::Error &err) {
105  THROW_CL_EXCEPTION(err);
106  }
107  initialized_ = true;
108  sharedGL_ = false;
109 }
110 
111 void clfImage3D::AllocateFromBiasTemplate(const BIAS::ImageBase &image, unsigned int levels, bool readonly, bool writeonly) {
112  Allocate(
113  image.GetStorageType(), image.GetColorModel(),
114  image.GetWidth(), image.GetHeight(), levels, 0,
115  readonly, writeonly);
116 }
117 
118 void clfImage3D::AllocateFromTemplate(const clfImage3D &src, bool readonly, bool writeonly) {
119  Allocate(src.st_, src.cm_, src.width_, src.height_, src.depth_, src.stride_, readonly, writeonly);
120 }
121 
122 void clfImage3D::AllocateFromTexture3D(BIAS::glfTexture3D &tex, bool readonly, bool writeonly) {
123  int cl_mem_flags = DetermineMemFlags_(readonly, writeonly);
124  try {
125 #ifdef CL_VERSION_1_2
126  buffer_ = cl::ImageGL(*context_, cl_mem_flags, tex.GetTextureTarget(), 0, tex.GetTextureID());
127 #else
128  buffer_ = cl::Image3DGL(*context_, cl_mem_flags, tex.GetTextureTarget(), 0, tex.GetTextureID());
129 #endif
130  size_t memsize;
131  buffer_.getInfo(CL_MEM_SIZE, &memsize);
132  size_ = memsize;
133  } catch(cl::Error &err) {
134  THROW_CL_EXCEPTION(err);
135  }
136  initialized_ = true;
137  sharedGL_ = true;
138 }
139 
140 cl::Image3D& clfImage3D::image() {
141  return (cl::Image3D&)buffer_;
142 }
143 
144 void clfImage3D::WriteToImage(const void *data,
145  unsigned int originX, unsigned int originY, unsigned int originZ,
146  unsigned int regionX, unsigned int regionY, unsigned int regionZ)
147 {
148  if (regionX == 0) {
149  regionX = width_;
150  }
151  if (regionY == 0) {
152  regionY = height_;
153  }
154  if (regionZ == 0) {
155  regionZ = depth_;
156  }
157  cl::size_t<3> origin, region;
158  MakeDim_(origin, originX, originY, originZ);
159  MakeDim_(region, regionX, regionY, regionZ);
160 
161  try {
162  queue_->enqueueWriteImage(image(), CL_TRUE, origin, region, 0, 0, (void*)data);
163  } catch (cl::Error &error) {
164  THROW_CL_EXCEPTION(error);
165  }
166 }
167 
169  unsigned int originX, unsigned int originY, unsigned int originZ,
170  unsigned int regionX, unsigned int regionY, unsigned int regionZ)
171 {
172  if (regionX == 0) {
173  regionX = width_;
174  }
175  if (regionY == 0) {
176  regionY = height_;
177  }
178  if (regionZ == 0) {
179  regionZ = depth_;
180  }
181  cl::size_t<3> origin, region;
182  MakeDim_(origin, originX, originY, originZ);
183  MakeDim_(region, regionX, regionY, regionZ);
184  try {
185  queue_->enqueueReadImage(image(), CL_TRUE, origin, region, 0, 0, data);
186  } catch (cl::Error &error) {
187  THROW_CL_EXCEPTION(error);
188  }
189 }
190 
192  unsigned int srcoriginX, unsigned int srcoriginY, unsigned int srcoriginZ,
193  unsigned int dstoriginX, unsigned int dstoriginY, unsigned int dstoriginZ,
194  unsigned int regionX, unsigned int regionY, unsigned int regionZ)
195 {
196  if (regionX == 0) {
197  regionX = width_;
198  }
199  if (regionY == 0) {
200  regionY = height_;
201  }
202  if (regionZ == 0) {
203  regionZ = depth_;
204  }
205  cl::size_t<3> srcorigin, dstorigin, region;
206  MakeDim_(srcorigin, srcoriginX, srcoriginY, srcoriginZ);
207  MakeDim_(dstorigin, dstoriginX, dstoriginY, dstoriginZ);
208  MakeDim_(region, regionX, regionY, regionZ);
209  try {
210  cl::Event event;
211  queue_->enqueueCopyImage(image(), outputimage.image(), srcorigin, dstorigin, region, NULL, &event);
212  event.wait();
213  } catch (cl::Error &error) {
214  THROW_CL_EXCEPTION(error);
215  }
216 }
217 
218 void* clfImage3D::MapImage(bool write,
219  unsigned int originX, unsigned int originY, unsigned int originZ,
220  unsigned int regionX, unsigned int regionY, unsigned int regionZ)
221 {
222  try {
223  cl_map_flags mapflags = 0;
224  if (write) {
225  mapflags = CL_MAP_WRITE;
226  } else {
227  mapflags = CL_MAP_READ;
228  }
229  if (regionX == 0) {
230  regionX = width_;
231  }
232  if (regionY == 0) {
233  regionY = height_;
234  }
235  if (regionZ == 0) {
236  regionZ = depth_;
237  }
238  cl::size_t<3> origin, region;
239  MakeDim_(origin, originX, originY, originZ);
240  MakeDim_(region, regionX, regionY, regionZ);
241  return queue_->enqueueMapImage(image(), CL_TRUE, mapflags, origin, region, 0, NULL);
242  } catch (cl::Error &error) {
243  THROW_CL_EXCEPTION(error);
244  }
245  return NULL;
246 }
247 
248 void clfImage3D::CopyToBiasImage(BIAS::ImageBase &image, unsigned int level,
249  unsigned int originX, unsigned int originY,
250  unsigned int regionX, unsigned int regionY)
251 {
252  if (regionX == 0) {
253  regionX = width_;
254  }
255  if (regionY == 0) {
256  regionY = height_;
257  }
258  int sx = regionX - originX;
259  int sy = regionY - originY;
260  if (!image.IsEmpty()) {
261  if (sx == (int)image.GetWidth() && sy == (int)image.GetHeight() && cm_ == image.GetColorModel() && st_ == image.GetStorageType()) {
262  // is already correctly initialized
263  } else {
264  image.Release(true);
265  image.Init(sx,sy, BIAS::ImageBase::GetChannelcount(cm_), st_);
266  }
267  } else {
268  image.Init(sx,sy, BIAS::ImageBase::GetChannelcount(cm_), st_);
269  }
270  ReadFromImage( image.GetImageData(), originX, originY, level, sx, sy, level+1 );
271 }
272 
273 std::vector<std::string> clfImage3D::GetSupportedImageFormats(bool readonly, bool writeonly) {
274  std::vector<cl::ImageFormat> *dat = NULL;
275  if (readonly) {
276  dat = &clfImage3D::imageFormatsReadable_;
277  } else if (writeonly) {
278  dat = &clfImage3D::imageFormatsWritable_;
279  } else {
280  dat = &clfImage3D::imageFormatsReadWrite_;
281  }
282  std::vector<std::string> result( dat->size() );
283  for (unsigned int i=0;i<dat->size();i++) {
284  switch ((*dat)[i].image_channel_order) {
285  case CL_R:
286  result[i] = "one channel (R) \t";
287  break;
288  case CL_A:
289  result[i] = "one channel (A) \t";
290  break;
291  case CL_INTENSITY:
292  result[i] = "one channel (Intensity)\t";
293  break;
294  case CL_LUMINANCE:
295  result[i] = "one channel (Luminance)\t";
296  break;
297  case CL_RG:
298  result[i] = "two channels (RG) \t";
299  break;
300  case CL_RA:
301  result[i] = "two channels (RA) \t";
302  break;
303  case CL_Rx:
304  result[i] = "two channels (Rx) \t";
305  break;
306  case CL_RGB:
307  result[i] = "three channels (RGB) \t";
308  break;
309  case CL_RGx:
310  result[i] = "three channels (RGx) \t";
311  break;
312  case CL_RGBA:
313  result[i] = "four channels (RGBA) \t";
314  break;
315  case CL_BGRA:
316  result[i] = "four channels (BGRA) \t";
317  break;
318  case CL_ARGB:
319  result[i] = "four channels (ARGB) \t";
320  break;
321  case CL_RGBx:
322  result[i] = "four channels (RGBx) \t";
323  break;
324  };
325  switch ((*dat)[i].image_channel_data_type) {
326  case CL_SNORM_INT8:
327  result[i] += "signed normalized char";
328  break;
329  case CL_SNORM_INT16:
330  result[i] += "signed normalized short";
331  break;
332  case CL_UNORM_INT8:
333  result[i] += "unsigned normalized char";
334  break;
335  case CL_UNORM_INT16:
336  result[i] += "unsigned normalized short";
337  break;
338  case CL_UNORM_SHORT_565:
339  result[i] += "unsigned normalized short 565";
340  break;
341  case CL_UNORM_SHORT_555:
342  result[i] += "unsigned normalized short 555";
343  break;
344  case CL_UNORM_INT_101010:
345  result[i] += "unsigned normalized int 101010";
346  break;
347  case CL_SIGNED_INT8:
348  result[i] += "signed char";
349  break;
350  case CL_SIGNED_INT16:
351  result[i] += "signed short";
352  break;
353  case CL_SIGNED_INT32:
354  result[i] += "signed int";
355  break;
356  case CL_UNSIGNED_INT8:
357  result[i] += "unsigned char";
358  break;
359  case CL_UNSIGNED_INT16:
360  result[i] += "unsigned short";
361  break;
362  case CL_UNSIGNED_INT32:
363  result[i] += "unsigned int";
364  break;
365  case CL_HALF_FLOAT:
366  result[i] += "half float";
367  break;
368  case CL_FLOAT:
369  result[i] += "float";
370  break;
371  }
372  }
373  return result;
374 }
375 
376 cl::ImageFormat clfImage3D::DetermineImageFormat_(BIAS::ImageBase::EStorageType st, BIAS::ImageBase::EColorModel cm) {
377  cl::ImageFormat format;
378  switch (st) {
380  format.image_channel_data_type = CL_SIGNED_INT8;
381  break;
383  format.image_channel_data_type = CL_UNSIGNED_INT16;
384  break;
386  format.image_channel_data_type = CL_SIGNED_INT16;
387  break;
389  format.image_channel_data_type = CL_UNSIGNED_INT32;
390  break;
392  format.image_channel_data_type = CL_SIGNED_INT32;
393  break;
395  format.image_channel_data_type = CL_FLOAT;
396  break;
398  format.image_channel_data_type = CL_UNSIGNED_INT8;
399  break;
402  default:
403  THROW_CL_EXCEPTION(cl::Error(-100, "image storage type not supported!"));
404  break;
405  }
406 
407  switch (cm) {
408  // one channel
414  format.image_channel_order = CL_R;
415  break;
418  format.image_channel_order = CL_INTENSITY;
419  break;
420  // two channel
424  format.image_channel_order = CL_RA;
425  break;
426  // three channel
435  format.image_channel_order = CL_RGB;
436  break;
437  // four channel
441  format.image_channel_order = CL_RGBA;
442  break;
443  default:
444  THROW_CL_EXCEPTION(cl::Error(-100, "color model not supported!"));
445  break;
446  }
447  return format;
448 }
449 
450 bool clfImage3D::GetFormatSupported_(cl::ImageFormat test, bool readonly, bool writeonly) {
451  std::vector<cl::ImageFormat> *dat = NULL;
452  if (readonly) {
453  dat = &clfImage3D::imageFormatsReadable_;
454  } else if (writeonly) {
455  dat = &clfImage3D::imageFormatsWritable_;
456  } else {
457  dat = &clfImage3D::imageFormatsReadWrite_;
458  }
459  for (unsigned int i=0;i<dat->size();i++) {
460  if (test.image_channel_data_type == (*dat)[i].image_channel_data_type) {
461  if (test.image_channel_order == (*dat)[i].image_channel_order) {
462  return true;
463  }
464  }
465  }
466  return false;
467 }
468 
469 void clfImage3D::MakeDim_(cl::size_t<3> &dest, int x, int y, int z) {
470  dest[0] = x;
471  dest[1] = y;
472  dest[2] = z;
473 }
EColorModel
These are the most often used color models.
Definition: ImageBase.hh:127
void CopyToImage(clfImage3D &outputimage, unsigned int srcoriginX=0, unsigned int srcoriginY=0, unsigned int srcoriginZ=0, unsigned int dstoriginX=0, unsigned int dstoriginY=0, unsigned int dstoriginZ=0, unsigned int regionX=0, unsigned int regionY=0, unsigned int regionZ=0)
Definition: clfImage3D.cpp:191
YUYV422, 2 channels, full luminance Y, subsampled half U,V.
Definition: ImageBase.hh:133
Bayer_GRBG, 1 channel RGB image Bayer tile.
Definition: ImageBase.hh:145
hsl, similar to HSL but euclidean (h,s) for CNCC
Definition: ImageBase.hh:148
LAB, 3 channels, http://en.wikipedia.org/wiki/Lab_color_space.
Definition: ImageBase.hh:157
(16bit) unsigned integer image storage type
Definition: ImageBase.hh:114
HSL, similar to HSV but space is a double tipped cone.
Definition: ImageBase.hh:147
gray values, 1 channel
Definition: ImageBase.hh:130
void CopyToBiasImage(BIAS::ImageBase &image, unsigned int level, unsigned int originX=0, unsigned int originY=0, unsigned int regionX=0, unsigned int regionY=0)
Definition: clfImage3D.cpp:248
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
(8bit) signed char image storage type
Definition: ImageBase.hh:113
Bayer_RGGB, 1 channel RGB image Bayer tile.
Definition: ImageBase.hh:143
float image storage type
Definition: ImageBase.hh:118
void * MapImage(bool write=false, unsigned int originX=0, unsigned int originY=0, unsigned int originZ=0, unsigned int regionX=0, unsigned int regionY=0, unsigned int regionZ=0)
Definition: clfImage3D.cpp:218
static int GetChannelcount(const enum BIAS::ImageBase::EColorModel &colormodel)
get the number of channels corresponding to the enum ColorModel Determines the number of (packed) dat...
Definition: ImageBase.cpp:1366
double image storage type
Definition: ImageBase.hh:119
XYZ, 3 channels, http://en.wikipedia.org/wiki/Xyz_color_space.
Definition: ImageBase.hh:156
unsigned int GetWidth() const
Definition: ImageBase.hh:312
void AllocateFromTemplate(const clfImage3D &src, bool readonly=false, bool writeonly=false)
Definition: clfImage3D.cpp:118
void AllocateFromBiasTemplate(const BIAS::ImageBase &image, unsigned int levels, bool readonly=false, bool writeonly=false)
Allocation of a memory buffer as 3D image (2d+level), biasimage is used as template for one level...
Definition: clfImage3D.cpp:111
int DetermineMemFlags_(bool readonly, bool writeonly, const void *hostptr=NULL, bool copy=false)
Definition: clfMemory.cpp:73
invalid not set image storage type
Definition: ImageBase.hh:111
cl::Context * context_
Definition: clfMemory.hh:54
GLuint GetTextureID() const
Returns the OpenGL texture id.
Definition: glfTexture.hh:144
(16bit) signed integer image storage type
Definition: ImageBase.hh:115
color values, 3 channels, order: blue,green,red
Definition: ImageBase.hh:132
Bayer_BGGR, 1 channel RGB image Bayer tile.
Definition: ImageBase.hh:146
const void * GetImageData() const
Definition: ImageBase.hh:280
Disparity images Q: should disp and depth be treated separately, if not what would be a good name to ...
Definition: ImageBase.hh:158
Bayer_GBRG, 1 channel RGB image Bayer tile.
Definition: ImageBase.hh:144
cl::CommandQueue * queue_
Definition: clfMemory.hh:55
virtual ~clfImage3D()
Definition: clfImage3D.cpp:57
color values, 3 channels, order: red,green,blue
Definition: ImageBase.hh:131
CIELUV color space, 3 channels, http://en.wikipedia.org/wiki/CIELUV_color_space.
Definition: ImageBase.hh:155
unsigned int GetHeight() const
Definition: ImageBase.hh:319
RGBA, 4 channels, order: red,green,blue,alpha.
Definition: ImageBase.hh:141
void Release(const bool reset_storage_type=false)
Free the allocated data structures Hands off: Do !!NOT!! change the default of reset_storage_type: Im...
Definition: ImageBase.cpp:350
clfImage3D(cl::Context *context, cl::CommandQueue *queue)
Definition: clfImage3D.cpp:37
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
(32bit) signed integer image storage type
Definition: ImageBase.hh:117
RGBE color values, 4 channels, RADIANCE hdr format, four low dynamic channels meaning: 3x mantissa (r...
Definition: ImageBase.hh:151
void Init(unsigned int width, unsigned int height, unsigned int nChannels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
Initialize image size and channels.
Definition: ImageBase.cpp:229
void Allocate(BIAS::ImageBase::EStorageType st, BIAS::ImageBase::EColorModel cm, unsigned int width, unsigned int height, unsigned int levels, unsigned int stride=0, bool readonly=false, bool writeonly=false, const void *hostptr=NULL, bool copy=false)
Allocation of a memory buffer as 3D image, either call directly or use wrapper for BIAS::ImageBase...
Definition: clfImage3D.cpp:60
void AllocateFromTexture3D(BIAS::glfTexture3D &tex, bool readonly=false, bool writeonly=false)
Allocation of a memory buffer from a GL Texture3D (works only on shared context!) ...
Definition: clfImage3D.cpp:122
OpenCL Image3D wrapper.
Definition: clfImage3D.hh:45
invalid (not set) image format
Definition: ImageBase.hh:129
enum EStorageType GetStorageType() const
Definition: ImageBase.hh:414
(8bit) unsigned char image storage type
Definition: ImageBase.hh:112
HSV, 3 channels, order: hue, sat , value.
Definition: ImageBase.hh:138
cl::Image3D & image()
Definition: clfImage3D.cpp:140
GLenum GetTextureTarget() const
Returns the OpenGL texture target.
Definition: glfTexture.hh:150
cl::Memory buffer_
Definition: clfMemory.hh:56
std::vector< std::string > GetSupportedImageFormats(bool readonly=false, bool writeonly=false)
Definition: clfImage3D.cpp:273
Todo: Unclear, I think one channel float, why isn&#39;t grey used for that?
Definition: ImageBase.hh:153
GreyA, 2 channels, grey plus Alpha.
Definition: ImageBase.hh:142
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
void WriteToImage(const void *data, unsigned int originX=0, unsigned int originY=0, unsigned int originZ=0, unsigned int regionX=0, unsigned int regionY=0, unsigned int regionZ=0)
write from host memory to image
Definition: clfImage3D.cpp:144
Depth images A: separated for now.
Definition: ImageBase.hh:159
void ReadFromImage(void *data, unsigned int originX=0, unsigned int originY=0, unsigned int originZ=0, unsigned int regionX=0, unsigned int regionY=0, unsigned int regionZ=0)
read from image to host memory
Definition: clfImage3D.cpp:168
BGRA color values, 4 channels, order: blue,green,red,alpha.
Definition: ImageBase.hh:150
unsigned int size_
Definition: clfMemory.hh:58
(32bit) unsigned integer image storage type
Definition: ImageBase.hh:116