buffer.cc
Go to the documentation of this file.
00001 /*
00002  * This file is part of the rc_genicam_api package.
00003  *
00004  * Copyright (c) 2017 Roboception GmbH
00005  * All rights reserved
00006  *
00007  * Author: Heiko Hirschmueller
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright notice,
00013  * this list of conditions and the following disclaimer.
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  * this list of conditions and the following disclaimer in the documentation
00017  * and/or other materials provided with the distribution.
00018  *
00019  * 3. Neither the name of the copyright holder nor the names of its contributors
00020  * may be used to endorse or promote products derived from this software without
00021  * specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  * POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 #include "buffer.h"
00037 #include "stream.h"
00038 
00039 #include "gentl_wrapper.h"
00040 #include "exception.h"
00041 
00042 namespace rcg
00043 {
00044 
00045 namespace
00046 {
00047 
00048 template<class T> inline T getBufferValue(const std::shared_ptr<const GenTLWrapper> &gentl,
00049                                           void *stream, void *buffer, GenTL::BUFFER_INFO_CMD cmd)
00050 {
00051   T ret=0;
00052 
00053   GenTL::INFO_DATATYPE type;
00054   size_t size=sizeof(T);
00055 
00056   if (stream != 0 && buffer != 0)
00057   {
00058     gentl->DSGetBufferInfo(stream, buffer, cmd, &type, &ret, &size);
00059   }
00060 
00061   return ret;
00062 }
00063 
00064 inline bool getBufferBool(const std::shared_ptr<const GenTLWrapper> &gentl,
00065                           void *stream, void *buffer, GenTL::BUFFER_INFO_CMD cmd)
00066 {
00067   bool8_t ret=0;
00068 
00069   GenTL::INFO_DATATYPE type;
00070   size_t size=sizeof(ret);
00071 
00072   if (stream != 0 && buffer != 0)
00073   {
00074     gentl->DSGetBufferInfo(stream, buffer, cmd, &type, &ret, &size);
00075   }
00076 
00077   return ret != 0;
00078 }
00079 
00080 inline std::string getBufferString(const std::shared_ptr<const GenTLWrapper> &gentl,
00081                                    void *stream, void *buffer, GenTL::BUFFER_INFO_CMD cmd)
00082 {
00083   std::string ret;
00084 
00085   GenTL::INFO_DATATYPE type;
00086   char tmp[1024]="";
00087   size_t size=sizeof(tmp);
00088 
00089   if (stream != 0 && buffer != 0)
00090   {
00091     if (gentl->DSGetBufferInfo(stream, buffer, cmd, &type, &ret, &size) == GenTL::GC_ERR_SUCCESS)
00092     {
00093       if (type == GenTL::INFO_DATATYPE_STRING)
00094       {
00095         ret=tmp;
00096       }
00097     }
00098   }
00099 
00100   return ret;
00101 }
00102 
00103 template<class T> inline T getBufferPartValue(const std::shared_ptr<const GenTLWrapper> &gentl,
00104                                               void *stream, void *buffer, std::uint32_t part,
00105                                               GenTL::BUFFER_PART_INFO_CMD cmd)
00106 {
00107   T ret=0;
00108 
00109   GenTL::INFO_DATATYPE type;
00110   size_t size=sizeof(T);
00111 
00112   if (stream != 0 && buffer != 0)
00113   {
00114     gentl->DSGetBufferPartInfo(stream, buffer, part, cmd, &type, &ret, &size);
00115   }
00116 
00117   return ret;
00118 }
00119 
00120 }
00121 
00122 Buffer::Buffer(const std::shared_ptr<const GenTLWrapper> &_gentl, Stream *_parent)
00123 {
00124   parent=_parent;
00125   gentl=_gentl;
00126   buffer=0;
00127   multipart=false;
00128 }
00129 
00130 void Buffer::setHandle(void *handle)
00131 {
00132   buffer=handle;
00133 
00134   multipart=false;
00135   if (buffer != 0)
00136   {
00137     multipart=getBufferValue<size_t>(gentl, parent->getHandle(), buffer,
00138                                      GenTL::BUFFER_INFO_PAYLOADTYPE) == PAYLOAD_TYPE_MULTI_PART;
00139   }
00140 }
00141 
00142 uint32_t Buffer::getNumberOfParts() const
00143 {
00144   uint32_t ret=0;
00145 
00146   if (multipart)
00147   {
00148     gentl->DSGetNumBufferParts(parent->getHandle(), buffer, &ret);
00149   }
00150   else
00151   {
00152     size_t type=getBufferValue<size_t>(gentl, parent->getHandle(), buffer,
00153                                        GenTL::BUFFER_INFO_PAYLOADTYPE);
00154 
00155     if (type != PAYLOAD_TYPE_CHUNK_ONLY)
00156     {
00157       ret=1;
00158     }
00159   }
00160 
00161   return ret;
00162 }
00163 
00164 void *Buffer::getGlobalBase() const
00165 {
00166   return getBufferValue<void *>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_BASE);
00167 }
00168 
00169 size_t Buffer::getGlobalSize() const
00170 {
00171   return getBufferValue<size_t>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_SIZE);
00172 }
00173 
00174 void *Buffer::getBase(std::uint32_t part) const
00175 {
00176   if (multipart)
00177   {
00178     return getBufferPartValue<void *>(gentl, parent->getHandle(), buffer, part,
00179                                       GenTL::BUFFER_PART_INFO_BASE);
00180   }
00181   else
00182   {
00183     void *ret=getBufferValue<void *>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_BASE);
00184 
00185     size_t offset=getBufferValue<size_t>(gentl, parent->getHandle(), buffer,
00186                                          GenTL::BUFFER_INFO_IMAGEOFFSET);
00187 
00188     if (offset > 0)
00189     {
00190       ret=reinterpret_cast<char *>(ret)+offset;
00191     }
00192 
00193     return ret;
00194   }
00195 }
00196 
00197 size_t Buffer::getSize(std::uint32_t part) const
00198 {
00199   if (multipart)
00200   {
00201     return getBufferPartValue<size_t>(gentl, parent->getHandle(), buffer, part,
00202                                       GenTL::BUFFER_PART_INFO_DATA_SIZE);
00203   }
00204   else
00205   {
00206     size_t size=getBufferValue<size_t>(gentl, parent->getHandle(), buffer,
00207                                        GenTL::BUFFER_INFO_SIZE);
00208 
00209     size_t offset=getBufferValue<size_t>(gentl, parent->getHandle(), buffer,
00210                                          GenTL::BUFFER_INFO_IMAGEOFFSET);
00211 
00212     return size-offset;
00213   }
00214 }
00215 
00216 void *Buffer::getUserPtr() const
00217 {
00218   return getBufferValue<void *>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_USER_PTR);
00219 }
00220 
00221 uint64_t Buffer::getTimestamp() const
00222 {
00223   return getBufferValue<uint64_t>(gentl, parent->getHandle(), buffer,
00224                                   GenTL::BUFFER_INFO_TIMESTAMP);
00225 }
00226 
00227 bool Buffer::getNewData() const
00228 {
00229   return getBufferBool(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_NEW_DATA);
00230 }
00231 
00232 bool Buffer::getIsQueued() const
00233 {
00234   return getBufferBool(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_IS_QUEUED);
00235 }
00236 
00237 bool Buffer::getIsAcquiring() const
00238 {
00239   return getBufferBool(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_IS_ACQUIRING);
00240 }
00241 
00242 bool Buffer::getIsIncomplete() const
00243 {
00244   return getBufferBool(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_IS_INCOMPLETE);
00245 }
00246 
00247 std::string Buffer::getTLType() const
00248 {
00249   return getBufferString(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_TLTYPE);
00250 }
00251 
00252 size_t Buffer::getSizeFilled() const
00253 {
00254   return getBufferValue<size_t>(gentl, parent->getHandle(), buffer,
00255                                 GenTL::BUFFER_INFO_SIZE_FILLED);
00256 }
00257 
00258 size_t Buffer::getPartDataType(uint32_t part) const
00259 {
00260   if (multipart)
00261   {
00262     return getBufferPartValue<size_t>(gentl, parent->getHandle(), buffer, part,
00263                                       GenTL::BUFFER_PART_INFO_DATA_TYPE);
00264   }
00265   else
00266   {
00267     return 0;
00268   }
00269 }
00270 
00271 size_t Buffer::getWidth(std::uint32_t part) const
00272 {
00273   if (multipart)
00274   {
00275     return getBufferPartValue<size_t>(gentl, parent->getHandle(), buffer, part,
00276                                       GenTL::BUFFER_PART_INFO_WIDTH);
00277   }
00278   else
00279   {
00280     return getBufferValue<size_t>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_WIDTH);
00281   }
00282 }
00283 
00284 size_t Buffer::getHeight(std::uint32_t part) const
00285 {
00286   if (multipart)
00287   {
00288     return getBufferPartValue<size_t>(gentl, parent->getHandle(), buffer, part,
00289                                       GenTL::BUFFER_PART_INFO_HEIGHT);
00290   }
00291   else
00292   {
00293     return getBufferValue<size_t>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_HEIGHT);
00294   }
00295 }
00296 
00297 size_t Buffer::getXOffset(std::uint32_t part) const
00298 {
00299   if (multipart)
00300   {
00301     return getBufferPartValue<size_t>(gentl, parent->getHandle(), buffer, part,
00302                                       GenTL::BUFFER_PART_INFO_XOFFSET);
00303   }
00304   else
00305   {
00306     return getBufferValue<size_t>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_XOFFSET);
00307   }
00308 }
00309 
00310 size_t Buffer::getYOffset(std::uint32_t part) const
00311 {
00312   if (multipart)
00313   {
00314     return getBufferPartValue<size_t>(gentl, parent->getHandle(), buffer, part,
00315                                       GenTL::BUFFER_PART_INFO_YOFFSET);
00316   }
00317   else
00318   {
00319     return getBufferValue<size_t>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_YOFFSET);
00320   }
00321 }
00322 
00323 size_t Buffer::getXPadding(std::uint32_t part) const
00324 {
00325   if (multipart)
00326   {
00327     return getBufferPartValue<size_t>(gentl, parent->getHandle(), buffer, part,
00328                                       GenTL::BUFFER_PART_INFO_XPADDING);
00329   }
00330   else
00331   {
00332     return getBufferValue<size_t>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_XPADDING);
00333   }
00334 }
00335 
00336 size_t Buffer::getYPadding() const
00337 {
00338   return getBufferValue<size_t>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_YPADDING);
00339 }
00340 
00341 uint64_t Buffer::getFrameID() const
00342 {
00343   return getBufferValue<uint64_t>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_FRAMEID);
00344 }
00345 
00346 bool Buffer::getImagePresent(uint32_t part) const
00347 {
00348   if (multipart)
00349   {
00350     size_t type=getBufferPartValue<size_t>(gentl, parent->getHandle(), buffer, part,
00351                                            GenTL::BUFFER_PART_INFO_DATA_TYPE);
00352 
00353     bool ret;
00354 
00355     switch (type)
00356     {
00357       case PART_DATATYPE_2D_IMAGE:
00358       case PART_DATATYPE_2D_PLANE_BIPLANAR:
00359       case PART_DATATYPE_2D_PLANE_TRIPLANAR:
00360       case PART_DATATYPE_2D_PLANE_QUADPLANAR:
00361       case PART_DATATYPE_3D_IMAGE:
00362       case PART_DATATYPE_3D_PLANE_BIPLANAR:
00363       case PART_DATATYPE_3D_PLANE_TRIPLANAR:
00364       case PART_DATATYPE_3D_PLANE_QUADPLANAR:
00365       case PART_DATATYPE_CONFIDENCE_MAP:
00366         ret=true;
00367         break;
00368 
00369       default:
00370         ret=false;
00371         break;
00372     }
00373 
00374     return ret;
00375   }
00376   else
00377   {
00378     return getBufferBool(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_IMAGEPRESENT);
00379   }
00380 }
00381 
00382 size_t Buffer::getPayloadType() const
00383 {
00384   return getBufferValue<size_t>(gentl, parent->getHandle(), buffer,
00385                                 GenTL::BUFFER_INFO_PAYLOADTYPE);
00386 }
00387 
00388 uint64_t Buffer::getPixelFormat(uint32_t part) const
00389 {
00390   if (multipart)
00391   {
00392     return getBufferPartValue<uint64_t>(gentl, parent->getHandle(), buffer, part,
00393                                         GenTL::BUFFER_PART_INFO_DATA_FORMAT);
00394   }
00395   else
00396   {
00397     return getBufferValue<uint64_t>(gentl, parent->getHandle(), buffer,
00398                                     GenTL::BUFFER_INFO_PIXELFORMAT);
00399   }
00400 }
00401 
00402 uint64_t Buffer::getPixelFormatNamespace(uint32_t part) const
00403 {
00404   if (multipart)
00405   {
00406     return getBufferPartValue<uint64_t>(gentl, parent->getHandle(), buffer, part,
00407                                         GenTL::BUFFER_PART_INFO_DATA_FORMAT_NAMESPACE);
00408   }
00409   else
00410   {
00411     return getBufferValue<uint64_t>(gentl, parent->getHandle(), buffer,
00412                                     GenTL::BUFFER_INFO_PIXELFORMAT_NAMESPACE);
00413   }
00414 }
00415 
00416 uint64_t Buffer::getPartSourceID(std::uint32_t part) const
00417 {
00418   if (multipart)
00419   {
00420     return getBufferPartValue<uint64_t>(gentl, parent->getHandle(), buffer, part,
00421                                       GenTL::BUFFER_PART_INFO_SOURCE_ID);
00422   }
00423   else
00424   {
00425     return 0;
00426   }
00427 }
00428 
00429 size_t Buffer::getDeliveredImageHeight(uint32_t part) const
00430 {
00431   if (multipart)
00432   {
00433     return getBufferPartValue<size_t>(gentl, parent->getHandle(), buffer, part,
00434                                       GenTL::BUFFER_PART_INFO_DELIVERED_IMAGEHEIGHT);
00435   }
00436   else
00437   {
00438     return getBufferValue<size_t>(gentl, parent->getHandle(), buffer,
00439                                   GenTL::BUFFER_INFO_DELIVERED_IMAGEHEIGHT);
00440   }
00441 }
00442 
00443 size_t Buffer::getDeliveredChunkPayloadSize() const
00444 {
00445   return getBufferValue<size_t>(gentl, parent->getHandle(), buffer,
00446                                 GenTL::BUFFER_INFO_DELIVERED_CHUNKPAYLOADSIZE);
00447 }
00448 
00449 uint64_t Buffer::getChunkLayoutID() const
00450 {
00451   return getBufferValue<uint64_t>(gentl, parent->getHandle(), buffer,
00452                                   GenTL::BUFFER_INFO_CHUNKLAYOUTID);
00453 }
00454 
00455 std::string Buffer::getFilename() const
00456 {
00457   return getBufferString(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_FILENAME);
00458 }
00459 
00460 bool Buffer::isBigEndian() const
00461 {
00462   bool ret=false;
00463 
00464   GenTL::INFO_DATATYPE type;
00465   int32_t v;
00466   size_t size=sizeof(v);
00467   GenTL::GC_ERROR err=GenTL::GC_ERR_SUCCESS;
00468 
00469   if (parent->getHandle() != 0 && buffer != 0)
00470   {
00471     err=gentl->DSGetBufferInfo(parent->getHandle(), buffer, GenTL::BUFFER_INFO_PIXEL_ENDIANNESS,
00472                                &type, &v, &size);
00473 
00474     if (err == GenTL::GC_ERR_SUCCESS && type == GenTL::INFO_DATATYPE_INT32 &&
00475         v == GenTL::PIXELENDIANNESS_BIG)
00476     {
00477       ret=true;
00478     }
00479   }
00480 
00481   return ret;
00482 }
00483 
00484 size_t Buffer::getDataSize() const
00485 {
00486   return getBufferValue<size_t>(gentl, parent->getHandle(), buffer, GenTL::BUFFER_INFO_DATA_SIZE);
00487 }
00488 
00489 uint64_t Buffer::getTimestampNS() const
00490 {
00491   uint64_t ret=getBufferValue<uint64_t>(gentl, parent->getHandle(), buffer,
00492                                         GenTL::BUFFER_INFO_TIMESTAMP_NS);
00493 
00494   // if timestamp in nano seconds is not available, then compute it from
00495   // timestamp and device frequency
00496 
00497   if (ret == 0)
00498   {
00499     const uint64_t ns_freq=1000000000ul;
00500     uint64_t freq=parent->getParent()->getTimestampFrequency();
00501 
00502     if (freq == 0)
00503     {
00504       freq=ns_freq;
00505     }
00506 
00507     ret=getBufferValue<uint64_t>(gentl, parent->getHandle(), buffer,
00508                                  GenTL::BUFFER_INFO_TIMESTAMP);
00509 
00510     if (freq != ns_freq)
00511     {
00512       ret=ret/freq*ns_freq+(ns_freq*(ret%freq))/freq;
00513     }
00514   }
00515 
00516   return ret;
00517 }
00518 
00519 bool Buffer::getDataLargerThanBuffer() const
00520 {
00521   return getBufferBool(gentl, parent->getHandle(), buffer,
00522                        GenTL::BUFFER_INFO_DATA_LARGER_THAN_BUFFER);
00523 }
00524 
00525 bool Buffer::getContainsChunkdata() const
00526 {
00527   return getBufferBool(gentl, parent->getHandle(), buffer,
00528                        GenTL::BUFFER_INFO_CONTAINS_CHUNKDATA);
00529 }
00530 
00531 void *Buffer::getHandle() const
00532 {
00533   return buffer;
00534 }
00535 
00536 bool isHostBigEndian()
00537 {
00538   int p=1;
00539   char *c=reinterpret_cast<char *>(&p);
00540 
00541   if (c[0] == 1)
00542   {
00543     return false;
00544   }
00545 
00546   return true;
00547 }
00548 
00549 }


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Thu Jun 6 2019 18:42:46