00001
00002
00003
00004
00005 #if !defined (AQSENSE_SAL3DPP_FRAME_HPP)
00006 #define AQSENSE_SAL3DPP_FRAME_HPP
00007
00008 #if defined (_MSC_VER) && (_MSC_VER >= 1020)
00009 #pragma once
00010 #endif
00011
00012 #include <sal3d/frame.h>
00013 #include <cstddef>
00014 #include <stdexcept>
00015 #include <string>
00016 #include <sal3dpp/Common.hpp>
00017
00018 namespace sal3d
00019 {
00020
00021 class Frame;
00022
00168 class Frame
00169 {
00170 public:
00172 typedef sal3d_frame_vpat VPAT;
00173
00189 template <typename T>
00190 class Plane
00191 {
00192 public:
00193 class Row
00194 {
00195 public:
00196 Row(char *baseaddr, sal3d::Frame::VPAT vpa)
00197 :_baseaddr(baseaddr), _vpa(vpa)
00198 {
00199 }
00200
00201 const T & operator[](int x) const
00202 {
00203 return *reinterpret_cast<T *>(_baseaddr + _vpa[x].x);
00204 }
00205
00206 T & operator[](int x)
00207 {
00208 return const_cast<T &> (
00209 static_cast<const Row &>(*this).operator[](x));
00210 }
00211
00212 private:
00213 char *_baseaddr;
00214 VPAT _vpa;
00215 };
00216
00222 Plane(const Frame &f, int plane)
00223 {
00224 f.vpa(plane, &_baseaddr, &_vpa);
00225 _width = f.width();
00226 _height = f.height();
00227 }
00228
00232 int width() const
00233 {
00234 return _width;
00235 }
00236
00240 int height() const
00241 {
00242 return _height;
00243 }
00244
00248 const Row operator[](int y) const
00249 {
00250 return Row(_baseaddr + _vpa[y].y, _vpa);
00251 }
00252
00256 Row operator[](int y)
00257 {
00258 return static_cast<const Plane &>(*this)[y];
00259 }
00260
00264 const T & pixel(int x, int y) const
00265 {
00266 return *reinterpret_cast<T *>(_baseaddr + _vpa[y].y + _vpa[x].x);
00267 }
00268
00272 T & pixel(int x, int y)
00273 {
00274 return const_cast<T &>(
00275 static_cast<const Plane &>(*this).pixel(x, y));
00276 }
00277
00278 private:
00279 char *_baseaddr;
00280 VPAT _vpa;
00281 int _width;
00282 int _height;
00283 };
00284
00300 template <typename T>
00301 class RGBPlane
00302 {
00303 public:
00308 struct RGBPixel
00309 {
00317 RGBPixel(T r, T g, T b):
00318 r(r),
00319 g(g),
00320 b(b)
00321 {}
00322
00323 T r;
00324 T g;
00325 T b;
00326 };
00327
00337 RGBPlane(const Frame &f):
00338 _width(f.width()),
00339 _height(f.height())
00340 {
00341 f.vpa(0, &_baseaddrR, &_vpaR);
00342 f.vpa(1, &_baseaddrG, &_vpaG);
00343 f.vpa(2, &_baseaddrB, &_vpaB);
00344 }
00345
00349 int width() const
00350 {
00351 return _width;
00352 }
00353
00357 int height() const
00358 {
00359 return _height;
00360 }
00361
00368 RGBPixel getPixel(int x, int y) const
00369 {
00370 return RGBPixel(*reinterpret_cast<T *>(_baseaddrR + _vpaR[y].y + _vpaR[x].x),
00371 *reinterpret_cast<T *>(_baseaddrG + _vpaG[y].y + _vpaG[x].x),
00372 *reinterpret_cast<T *>(_baseaddrB + _vpaB[y].y + _vpaB[x].x));
00373 }
00374
00381 void setPixel(int x, int y, const RGBPixel &p)
00382 {
00383 *reinterpret_cast<T *>(_baseaddrR + _vpaR[y].y + _vpaR[x].x) = p.r;
00384 *reinterpret_cast<T *>(_baseaddrG + _vpaG[y].y + _vpaG[x].x) = p.g;
00385 *reinterpret_cast<T *>(_baseaddrB + _vpaB[y].y + _vpaB[x].x) = p.b;
00386 }
00387
00388 private:
00389 char *_baseaddrR;
00390 char *_baseaddrG;
00391 char *_baseaddrB;
00392 VPAT _vpaR;
00393 VPAT _vpaG;
00394 VPAT _vpaB;
00395 int _width;
00396 int _height;
00397 };
00398
00403 struct Area
00404 {
00406 int x0;
00408 int y0;
00409
00411 int x1;
00413 int y1;
00414
00423 Area (int x0, int y0, int x1, int y1):
00424 x0 (x0),
00425 y0 (y0),
00426 x1 (x1),
00427 y1 (y1)
00428 {
00429 }
00430
00437 Area (int width, int height):
00438 x0 (0),
00439 y0 (0),
00440 x1 (width - 1),
00441 y1 (height - 1)
00442 {
00443 }
00444
00451 explicit inline Area (const sal3d::Frame &frame):
00452 x0 (0),
00453 y0 (0),
00454 x1 (frame.width () - 1),
00455 y1 (frame.height () - 1)
00456 {
00457 }
00458 };
00459
00476 Frame (int width, int height,
00477 int dimension, int dataType = 8)
00478 {
00479 Error e;
00480 _frame.p = 0;
00481 sal3d_frame_new_with_datatype (width, height, dimension,
00482 dataType, &_frame, &e.e);
00483 if ( 0 > e.e.value )
00484 throw e;
00485 }
00486
00494 explicit Frame (const std::string &fileName)
00495 {
00496 Error e;
00497 _frame.p = 0;
00498 sal3d_frame_new_from_file (fileName.c_str (), &_frame, &e.e);
00499 if ( 0 > e.e.value )
00500 throw e;
00501 }
00502
00551 Frame (void *data, int width, int height,
00552 int dimension, int datatype, std::ptrdiff_t strideX,
00553 std::ptrdiff_t strideY, std::ptrdiff_t stridePlane,
00554 SAL3DFRAMEDELETER deleter, void *userData = 0,
00555 const int *planeOrder = 0)
00556 {
00557 Error e;
00558 _frame.p = 0;
00559 sal3d_frame_new_from_pointer (data, width, height,
00560 dimension, datatype, strideX, strideY, stridePlane,
00561 planeOrder, deleter, userData, &_frame, &e.e);
00562 if ( 0 > e.e.value )
00563 throw e;
00564 }
00565
00578 explicit Frame (sal3d_frame frame):
00579 _frame (frame)
00580 {
00581 Error e;
00582 sal3d_frame_check_validity (frame, &e.e);
00583 if ( 0 > e.e.value )
00584 throw e;
00585 }
00586
00592 Frame (const Frame &frame):
00593 _frame (frame._frame)
00594 {
00595 Error e;
00596 sal3d_frame_share (_frame, &e.e);
00597 if ( 0 > e.e.value )
00598 throw e;
00599 }
00600
00619 Frame (const Frame &frame, float ratio)
00620 {
00621 Error e;
00622 _frame.p = 0;
00623 sal3d_frame_new_from_frame_with_zoom (
00624 frame.c_frame (), ratio, &_frame, &e.e);
00625 if ( 0 > e.e.value )
00626 throw e;
00627 }
00628
00646 Frame (const Frame &frame, const Area &area)
00647 {
00648 _frame.p = 0;
00649 sal3d_frame_area c_area;
00650 c_area.x0 = area.x0;
00651 c_area.y0 = area.y0;
00652 c_area.x1 = area.x1;
00653 c_area.y1 = area.y1;
00654
00655 Error e;
00656 sal3d_frame_new_subframe (frame.c_frame (), c_area, &_frame,
00657 &e.e);
00658 if ( 0 > e.e.value )
00659 throw e;
00660 }
00661
00665 ~Frame ()
00666 {
00667 sal3d_frame_release (_frame);
00668 }
00669
00679 sal3d_frame
00680 c_frame () const
00681 {
00682 return _frame;
00683 }
00684
00700 Frame
00701 copy () const
00702 {
00703 sal3d_frame newframe;
00704
00705 Error e;
00706 sal3d_frame_new_copy_from_frame(_frame, &newframe, &e.e);
00707 if ( 0 > e.e.value )
00708 throw e;
00709
00710 return Frame(newframe);
00711 }
00712
00739 int
00740 dataType (int plane) const
00741 {
00742 Error e;
00743 int type = sal3d_frame_get_data_type (_frame, plane, &e.e);
00744 if ( 0 > e.e.value )
00745 throw e;
00746 return type;
00747 }
00748
00756 int
00757 dimension () const
00758 {
00759 Error e;
00760 int dim = sal3d_frame_get_dimension (_frame, &e.e);
00761 if ( 0 > e.e.value )
00762 throw e;
00763 return dim;
00764 }
00765
00773 int
00774 height () const
00775 {
00776 Error e;
00777 int num = sal3d_frame_get_height (_frame, &e.e);
00778 if ( 0 > e.e.value )
00779 throw e;
00780 return num;
00781 }
00782
00793 void
00794 transpose()
00795 {
00796 Error e;
00797 sal3d_frame_transpose(_frame, &e.e);
00798 if ( 0 > e.e.value )
00799 throw e;
00800 }
00801
00811 Frame &
00812 operator= (const Frame &rhs)
00813 {
00814 Error e;
00815 sal3d_frame_share (rhs._frame, &e.e);
00816 if ( 0 > e.e.value )
00817 throw e;
00818 sal3d_frame_release (_frame);
00819 _frame = rhs._frame;
00820
00821 return *this;
00822 }
00823
00832 void
00833 saveToFile (const std::string &fileName) const
00834 {
00835 Error e;
00836 sal3d_frame_save_to_file (_frame, fileName.c_str (), &e.e);
00837 if ( 0 > e.e.value )
00838 throw e;
00839 }
00840
00856 void
00857 vpa (int plane, char **baseAddress, VPAT *vpat) const
00858 {
00859 Error e;
00860 sal3d_frame_get_vpa (_frame, plane, baseAddress, vpat, &e.e);
00861 if ( 0 > e.e.value )
00862 throw e;
00863 }
00864
00872 int
00873 width () const
00874 {
00875 Error e;
00876 int num = sal3d_frame_get_width (_frame, &e.e);
00877 if ( 0 > e.e.value )
00878 throw e;
00879 return num;
00880 }
00881
00906 sal3d::Frame
00907 scaleDepth(int datatype, double *inputMin = 0,
00908 double *inputMax = 0) const
00909 {
00910 sal3d_frame c_frame;
00911 Error e;
00912 sal3d_frame_new_scale_depth (_frame, datatype, 0, 0, 0, 0,
00913 &c_frame, inputMin, inputMax, &e.e);
00914 if ( 0 > e.e.value )
00915 throw e;
00916
00917 return Frame(c_frame);
00918 }
00919
00942 sal3d::Frame
00943 scaleDepth(int datatype, double inputMin, double inputMax) const
00944 {
00945 sal3d_frame c_frame;
00946 Error e;
00947 sal3d_frame_new_scale_depth (_frame, datatype, &inputMin,
00948 &inputMax, 0, 0, &c_frame, 0, 0, &e.e);
00949 if ( 0 > e.e.value )
00950 throw e;
00951
00952 return Frame(c_frame);
00953 }
00954
00979 sal3d::Frame
00980 scaleDepthToRange(int datatype, double outputMin, double outputMax,
00981 double *inputMin = 0, double *inputMax = 0) const
00982 {
00983 sal3d_frame c_frame;
00984 Error e;
00985 sal3d_frame_new_scale_depth (_frame, datatype, 0, 0,
00986 &outputMin, &outputMax, &c_frame, inputMin, inputMax,
00987 &e.e);
00988 if ( 0 > e.e.value )
00989 throw e;
00990
00991 return Frame(c_frame);
00992 }
00993
01016 sal3d::Frame
01017 scaleDepthToRange(int datatype,double inputMin, double inputMax,
01018 double outputMin, double outputMax) const
01019 {
01020 sal3d_frame c_frame;
01021 Error e;
01022 sal3d_frame_new_scale_depth (_frame, datatype, &inputMin,
01023 &inputMax, &outputMin, &outputMax, &c_frame, 0, 0,
01024 &e.e);
01025 if ( 0 > e.e.value )
01026 throw e;
01027
01028 return Frame(c_frame);
01029 }
01030
01036 template <typename T>
01037 const Plane<T>
01038 plane(int p = 0) const
01039 {
01040 return Plane<T>(*this, p);
01041 }
01042
01048 template <typename T>
01049 Plane<T>
01050 plane(int p = 0)
01051 {
01052 return static_cast<const Frame &>(*this).plane<T>(p);
01053 }
01054
01061 template <typename T>
01062 const typename Plane<T>::Row
01063 row(int y, int plane = 0) const
01064 {
01065 char *baseaddr;
01066 sal3d::Frame::VPAT vpat;
01067
01068 vpa(plane, &baseaddr, &vpat);
01069 return typename Plane<T>::Row(baseaddr + vpat[y].y, vpat);
01070 }
01071
01078 template <typename T>
01079 typename Plane<T>::Row
01080 row(int y, int plane = 0)
01081 {
01082 return static_cast<const Frame &>(*this).row<T>(y, plane);
01083 }
01084
01092 template <typename T>
01093 const T &
01094 pixel(int x, int y, int plane = 0) const
01095 {
01096 char *baseaddr;
01097 sal3d::Frame::VPAT vpat;
01098
01099 vpa(plane, &baseaddr, &vpat);
01100 return *reinterpret_cast<T *>(baseaddr + vpat[y].y + vpat[x].x);
01101 }
01102
01110 template <typename T>
01111 T &
01112 pixel(int x, int y, int plane = 0)
01113 {
01114 return const_cast<T &>(
01115 static_cast<const Frame &>(*this).pixel<T>(x, y, plane));
01116 }
01117
01118 private:
01120 sal3d_frame _frame;
01121 };
01122 }
01123
01124 #endif // !AQSENSE_SAL3DPP_FRAME_HPP