30 #include "boost/mpl/vector.hpp"
31 #pragma clang diagnostic push
32 #pragma clang diagnostic ignored "-Wunused-variable"
33 #include "boost/lambda/lambda.hpp"
34 #pragma clang diagnostic pop
35 #include "boost/bind/bind.hpp"
36 #include "boost/format.hpp"
37 #include "boost/filesystem/path.hpp"
38 #include "boost/gil/gil_all.hpp"
49 namespace geom = lsst::afw::geom;
52 template <
typename PixelT>
57 if (dimensions.getX() < 0 || dimensions.getY() < 0) {
58 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
59 str(
boost::format(
"Both width and height must be non-negative: %d, %d")
60 % dimensions.getX() % dimensions.getY()));
62 if (dimensions.getX() != 0 && dimensions.getY() > std::numeric_limits<int>::max()/dimensions.getX()) {
64 str(
boost::format(
"Image dimensions (%d x %d) too large; int overflow detected.")
65 % dimensions.getX() % dimensions.getY()));
68 dimensions.getX() * dimensions.getY()
71 return boost::gil::interleaved_view(
72 dimensions.getX(), dimensions.getY(),
73 (
typename _view_t::value_type* )r.second,
74 dimensions.getX()*
sizeof(
PixelT)
77 template <
typename PixelT>
81 if (offset.getX() < 0 || offset.getY() < 0 ||
82 offset.getX() + dimensions.getX() > view.width() ||
83 offset.getY() + dimensions.getY() > view.height()
86 lsst::pex::exceptions::LengthError,
87 (
boost::format(
"Box2I(Point2I(%d,%d),Extent2I(%d,%d)) doesn't fit in image %dx%d") %
88 offset.getX() % offset.getY() %
89 dimensions.getX() % dimensions.getY() %
90 view.width() % view.height()
94 return boost::gil::subimage_view(
96 offset.getX(), offset.getY(),
97 dimensions.getX(), dimensions.getY()
107 template <
typename PixelT>
110 ) : lsst::daf::base::Citizen(typeid(this)),
112 _gilView(_allocateView(dimensions, _manager))
120 template <
typename PixelT>
123 ) : lsst::daf::base::Citizen(typeid(this)),
124 _origin(bbox.getMin()), _manager(),
125 _gilView(_allocateView(bbox.getDimensions(), _manager))
134 template<
typename PixelT>
140 lsst::daf::base::Citizen(typeid(this)),
142 _manager(rhs._manager),
143 _gilView(rhs._gilView)
160 template<
typename PixelT>
168 lsst::daf::base::Citizen(typeid(this)),
170 _manager(rhs._manager),
171 _gilView(_makeSubView(bbox.getDimensions(),
_origin - rhs.
_origin, rhs._gilView))
189 template<
typename PixelT>
191 lsst::daf::base::Citizen(typeid(this)),
193 _manager(array.getManager()),
195 boost::gil::interleaved_view(
196 array.template getSize<1>(), array.template getSize<0>(),
197 (typename
_view_t::value_type* )array.getData(),
198 array.template getStride<0>() * sizeof(
PixelT)
215 template<
typename PixelT>
224 template<
typename PixelT>
227 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
231 copy_pixels(rhs.
_gilView, _gilView);
235 template<
typename PixelT>
243 template<
typename PixelT>
250 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
251 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
252 (
boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") %
253 x % y % (getWidth() - 1) % (getHeight() - 1)).str());
262 template<
typename PixelT>
265 return _gilView(x, y)[0];
269 template<
typename PixelT>
272 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
273 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
274 (
boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") %
275 x % y % (this->getWidth() - 1) % (this->getHeight() - 1)).str());
278 return _gilView(x, y)[0];
281 template<
typename PixelT>
290 template<
typename PixelT>
295 template <
typename PixelT>
297 int rowStride =
reinterpret_cast<PixelT*
>(row_begin(1)) - reinterpret_cast<PixelT*>(row_begin(0));
299 reinterpret_cast<PixelT*>(row_begin(0)),
307 template <
typename PixelT>
309 int rowStride =
reinterpret_cast<PixelT*
>(row_begin(1)) - reinterpret_cast<PixelT*>(row_begin(0));
311 reinterpret_cast<PixelT*>(row_begin(0)),
324 template<
typename PixelT>
326 return _gilView.begin();
330 template<
typename PixelT>
332 return _gilView.end();
336 template<
typename PixelT>
338 return _gilView.rbegin();
342 template<
typename PixelT>
344 return _gilView.rend();
348 template<
typename PixelT>
350 return _gilView.at(x, y);
357 template<
typename PixelT>
362 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
363 "Only contiguous == true makes sense");
365 if (!this->isContiguous()) {
366 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
367 "Image's pixels are not contiguous");
377 template<
typename PixelT>
382 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
383 "Only contiguous == true makes sense");
385 if (!this->isContiguous()) {
386 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
387 "Image's pixels are not contiguous");
390 return row_end(getHeight()-1);
395 template<
typename PixelT>
397 fill_pixels(_gilView, rhs);
412 template<
typename PixelT>
419 *
this = initialValue;
428 template<
typename PixelT>
434 *
this = initialValue;
440 template<
typename PixelT>
445 *
this = initialValue;
454 template<
typename PixelT>
469 template<
typename PixelT>
479 template<
typename PixelT>
493 template<
typename PixelT>
502 #ifndef DOXYGEN // doc for this section has been moved to header
504 template<
typename PixelT>
506 std::string
const & fileName,
513 fitsfile.setHdu(hdu);
515 *
this =
Image(fitsfile, metadata, bbox, origin);
516 }
catch(lsst::afw::fits::FitsError &e) {
518 if (fitsfile.getImageDim() == 0) {
524 template<
typename PixelT>
526 fits::MemFileManager & manager,
533 fitsfile.setHdu(hdu);
534 *
this =
Image(fitsfile, metadata, bbox, origin);
537 template<
typename PixelT>
539 fits::Fits & fitsfile,
545 typedef boost::mpl::vector<
560 fits_read_image<fits_image_types>(fitsfile, *
this, *metadata, bbox, origin);
563 template<
typename PixelT>
565 std::string
const & fileName,
567 std::string
const & mode
570 writeFits(fitsfile, metadata_i);
573 template<
typename PixelT>
575 fits::MemFileManager & manager,
577 std::string
const & mode
580 writeFits(fitsfile, metadata_i);
583 template<
typename PixelT>
585 fits::Fits & fitsfile,
591 this->getX0(), this->getY0());
593 metadata = metadata_i->deepCopy();
594 metadata->combine(wcsAMetadata);
596 metadata = wcsAMetadata;
605 template<
typename PixelT>
612 template<
typename PixelT>
625 namespace bl = boost::lambda;
629 template<
typename PixelT>
631 return static_cast<PixelT>(std::sqrt(x));
635 template<
typename PixelT>
637 transform_pixels(_getRawView(), _getRawView(),
638 boost::bind(mysqrt<PixelT>, bl::_1));
642 template<
typename PixelT>
644 transform_pixels(_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 + rhs));
648 template<
typename PixelT>
651 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
652 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
655 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 + bl::_2));
661 template<
typename PixelT>
665 for (
int y = 0;
y != this->getHeight(); ++
y) {
669 ptr != end; ++ptr, ++xPos) {
670 *ptr +=
function(xPos, yPos);
676 template<
typename PixelT>
679 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
680 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
683 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
684 bl::ret<PixelT>(bl::_1 + bl::ret<PixelT>(c*bl::_2)));
688 template<
typename PixelT>
690 transform_pixels(_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 - rhs));
694 template<
typename PixelT>
697 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
698 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
701 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 - bl::_2));
705 template<
typename PixelT>
708 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
709 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
712 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
713 bl::ret<PixelT>(bl::_1 - bl::ret<PixelT>(c*bl::_2)));
719 template<
typename PixelT>
723 for (
int y = 0;
y != this->getHeight(); ++
y) {
727 ptr != end; ++ptr, ++xPos) {
728 *ptr -=
function(xPos, yPos);
734 template<
typename PixelT>
736 transform_pixels(_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 * rhs));
740 template<
typename PixelT>
743 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
744 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
747 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 * bl::_2));
751 template<
typename PixelT>
754 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
755 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
758 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
759 bl::ret<PixelT>(bl::_1 * bl::ret<PixelT>(c*bl::_2)));
765 template<
typename PixelT>
767 transform_pixels(_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 / rhs));
772 namespace lsst {
namespace afw {
namespace image {
775 double const irhs = 1/rhs;
781 float const irhs = 1/rhs;
787 template<
typename PixelT>
790 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
791 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
794 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 / bl::_2));
798 template<
typename PixelT>
801 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
802 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
805 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
806 bl::ret<PixelT>(bl::_1 / bl::ret<PixelT>(c*bl::_2)));
815 template<
typename LhsPixelT,
typename RhsPixelT>
817 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
818 return static_cast<LhsPixelT
>(lhs + rhs);
822 template<
typename LhsPixelT,
typename RhsPixelT>
824 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
825 return static_cast<LhsPixelT
>(lhs - rhs);
829 template<
typename LhsPixelT,
typename RhsPixelT>
831 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
832 return static_cast<LhsPixelT
>(lhs*rhs);
836 template<
typename LhsPixelT,
typename RhsPixelT>
838 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
839 return static_cast<LhsPixelT
>(lhs/rhs);
846 template<
typename LhsPixelT,
typename RhsPixelT>
853 template<
typename LhsPixelT,
typename RhsPixelT>
860 template<
typename LhsPixelT,
typename RhsPixelT>
867 template<
typename LhsPixelT,
typename RhsPixelT>
877 #define INSTANTIATE_OPERATOR(OP_EQ, T) \
878 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<boost::uint16_t> const& rhs); \
879 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<int> const& rhs); \
880 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<float> const& rhs); \
881 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<double> const& rhs); \
882 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<boost::uint64_t> const& rhs);
884 #define INSTANTIATE(T) \
885 template class image::ImageBase<T>; \
886 template class image::Image<T>; \
887 INSTANTIATE_OPERATOR(+=, T); \
888 INSTANTIATE_OPERATOR(-=, T); \
889 INSTANTIATE_OPERATOR(*=, T); \
890 INSTANTIATE_OPERATOR(/=, T)
iterator at(int x, int y) const
Return an STL compliant iterator at the point (x, y)
void scaledDivides(double const c, Image< PixelT >const &rhs)
Divide lhs by Image c*rhs (i.e. pixel-by-pixel division)
iterator end() const
Return an STL compliant iterator to the end of the image.
View< boost::fusion::vector1< index::Full > > view()
Start a view definition that includes the entire first dimension.
reverse_iterator rend() const
Return an STL compliant reverse iterator to the end of the image.
ConstReference< PixelT >::type PixelConstReference
A ConstReference to a PixelT.
double indexToPosition(double ind)
Convert image index to image position.
_view_t::reverse_iterator reverse_iterator
An STL compliant reverse iterator.
void swap(ImageBase< PixelT > &a, ImageBase< PixelT > &b)
Include files required for standard LSST Exception handling.
#define INSTANTIATE(MATCH)
detail::ExternalInitializer< T, N, Owner > external(T *data, Vector< int, N > const &shape, Vector< int, N > const &strides, Owner const &owner)
Create an expression that initializes an Array with externally allocated memory.
_view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
void operator/=(PixelT const rhs)
geom::Box2I getBBox(ImageOrigin origin=PARENT) const
static _view_t _makeSubView(geom::Extent2I const &dimensions, geom::Extent2I const &offset, const _view_t &view)
void for_each_pixel(Image< LhsT > &lhs, pixelOp0< LhsT > const &func)
lsst::daf::base::PropertyList PropertyList
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
The base class for all image classed (Image, Mask, MaskedImage, ...)
Extent< int, 2 > Extent2I
void operator*=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
void writeFits(std::string const &fileName, boost::shared_ptr< lsst::daf::base::PropertySet const > metadata=boost::shared_ptr< lsst::daf::base::PropertySet const >(), std::string const &mode="w") const
Write an image to a regular FITS file.
An integer coordinate rectangle.
void operator<<=(const ImageBase &rhs)
Set the lhs's pixel values to equal the rhs's.
table::Key< table::Array< Kernel::Pixel > > image
void scaledPlus(double const c, Image< PixelT >const &rhs)
Add Image c*rhs to lhs.
lsst::daf::base::PropertySet PropertySet
_view_t::iterator iterator
An STL compliant iterator.
afw::table::PointKey< int > dimensions
boost::intrusive_ptr< Manager > Ptr
Image & operator=(const PixelT rhs)
Set the image's pixels to rhs.
void operator*=(PixelT const rhs)
Multiply lhs by scalar rhs.
void ImageT ImageT int float saturatedPixelValue int const width
lsst::afw::image::detail::types_traits< PixelT >::view_t _view_t
geom::Extent2I getDimensions() const
Return the image's size; useful for passing to constructors.
_view_t _getRawView() const
Vector< T, N > makeVector(T v1, T v2,..., T vN)
Variadic constructor for Vector.
if(width!=gim.getWidth()||height!=gim.getHeight()||x0!=gim.getX0()||y0!=gim.getY0())
A class used to request that array accesses be checked.
int getHeight() const
Return the number of rows in the image.
boost::shared_ptr< lsst::daf::base::PropertyList > createTrivialWcsAsPropertySet(std::string const &wcsName, int const x0=0, int const y0=0)
void operator+=(PixelT const rhs)
Add scalar rhs to lhs.
void swap(ImageBase &rhs)
void operator-=(PixelT const rhs)
Subtract scalar rhs from lhs.
Support for functors over Image's pixels.
void ImageT ImageT int float saturatedPixelValue int const height
#define LSST_EXCEPT(type,...)
A multidimensional strided array.
static _view_t _allocateView(geom::Extent2I const &dimensions, Manager::Ptr &manager)
void scaledMinus(double const c, Image< PixelT >const &rhs)
Subtract Image c*rhs from lhs.
Class for storing generic metadata.
void operator/=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Reference< PixelT >::type PixelReference
A Reference to a PixelT.
afw::table::Key< double > b
void scaledMultiplies(double const c, Image< PixelT >const &rhs)
Multiply lhs by Image c*rhs (i.e. pixel-by-pixel multiplication)
void operator-=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
reverse_iterator rbegin() const
Return an STL compliant reverse iterator to the start of the image.
static std::pair< Manager::Ptr, T * > allocate(int size)
int getWidth() const
Return the number of columns in the image.
#define LSST_EXCEPT_ADD(e, m)
A class to represent a 2-dimensional array of pixels.
void fits_write_image(fits::Fits &fitsfile, const ImageT &image, boost::shared_ptr< daf::base::PropertySet const > metadata=boost::shared_ptr< daf::base::PropertySet const >())
std::string const wcsNameForXY0
ImageBase & operator=(const ImageBase &rhs)
PixelReference operator()(int x, int y)
Return a reference to the pixel (x, y)
void operator+=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)