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()));
64 dimensions.getX() * dimensions.getY()
67 return boost::gil::interleaved_view(
68 dimensions.getX(), dimensions.getY(),
69 (
typename _view_t::value_type* )r.second,
70 dimensions.getX()*
sizeof(
PixelT)
73 template <
typename PixelT>
77 if (offset.getX() < 0 || offset.getY() < 0 ||
78 offset.getX() + dimensions.getX() > view.width() ||
79 offset.getY() + dimensions.getY() > view.height()
82 lsst::pex::exceptions::LengthError,
83 (
boost::format(
"Box2I(Point2I(%d,%d),Extent2I(%d,%d)) doesn't fit in image %dx%d") %
84 offset.getX() % offset.getY() %
85 dimensions.getX() % dimensions.getY() %
86 view.width() % view.height()
90 return boost::gil::subimage_view(
92 offset.getX(), offset.getY(),
93 dimensions.getX(), dimensions.getY()
103 template <
typename PixelT>
106 ) : lsst::daf::base::Citizen(typeid(this)),
108 _gilView(_allocateView(dimensions, _manager))
116 template <
typename PixelT>
119 ) : lsst::daf::base::Citizen(typeid(this)),
120 _origin(bbox.getMin()), _manager(),
121 _gilView(_allocateView(bbox.getDimensions(), _manager))
130 template<
typename PixelT>
136 lsst::daf::base::Citizen(typeid(this)),
138 _manager(rhs._manager),
139 _gilView(rhs._gilView)
156 template<
typename PixelT>
164 lsst::daf::base::Citizen(typeid(this)),
166 _manager(rhs._manager),
167 _gilView(_makeSubView(bbox.getDimensions(),
_origin - rhs.
_origin, rhs._gilView))
185 template<
typename PixelT>
187 lsst::daf::base::Citizen(typeid(this)),
189 _manager(array.getManager()),
191 boost::gil::interleaved_view(
192 array.template getSize<1>(), array.template getSize<0>(),
193 (typename
_view_t::value_type* )array.getData(),
194 array.template getStride<0>() * sizeof(
PixelT)
211 template<
typename PixelT>
220 template<
typename PixelT>
223 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
227 copy_pixels(rhs.
_gilView, _gilView);
231 template<
typename PixelT>
239 template<
typename PixelT>
246 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
247 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
248 (
boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") %
249 x % y % (getWidth() - 1) % (getHeight() - 1)).str());
258 template<
typename PixelT>
261 return _gilView(x, y)[0];
265 template<
typename PixelT>
268 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
269 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
270 (
boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") %
271 x % y % (this->getWidth() - 1) % (this->getHeight() - 1)).str());
274 return _gilView(x, y)[0];
277 template<
typename PixelT>
286 template<
typename PixelT>
291 template <
typename PixelT>
293 int rowStride =
reinterpret_cast<PixelT*
>(row_begin(1)) - reinterpret_cast<PixelT*>(row_begin(0));
295 reinterpret_cast<PixelT*>(row_begin(0)),
303 template <
typename PixelT>
305 int rowStride =
reinterpret_cast<PixelT*
>(row_begin(1)) - reinterpret_cast<PixelT*>(row_begin(0));
307 reinterpret_cast<PixelT*>(row_begin(0)),
320 template<
typename PixelT>
322 return _gilView.begin();
326 template<
typename PixelT>
328 return _gilView.end();
332 template<
typename PixelT>
334 return _gilView.rbegin();
338 template<
typename PixelT>
340 return _gilView.rend();
344 template<
typename PixelT>
346 return _gilView.at(x, y);
353 template<
typename PixelT>
358 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
359 "Only contiguous == true makes sense");
361 if (!this->isContiguous()) {
362 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
363 "Image's pixels are not contiguous");
373 template<
typename PixelT>
378 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
379 "Only contiguous == true makes sense");
381 if (!this->isContiguous()) {
382 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
383 "Image's pixels are not contiguous");
386 return row_end(getHeight()-1);
391 template<
typename PixelT>
393 fill_pixels(_gilView, rhs);
408 template<
typename PixelT>
415 *
this = initialValue;
424 template<
typename PixelT>
430 *
this = initialValue;
436 template<
typename PixelT>
441 *
this = initialValue;
450 template<
typename PixelT>
465 template<
typename PixelT>
475 template<
typename PixelT>
489 template<
typename PixelT>
498 #ifndef DOXYGEN // doc for this section has been moved to header
500 template<
typename PixelT>
502 std::string
const & fileName,
509 fitsfile.setHdu(hdu);
511 *
this =
Image(fitsfile, metadata, bbox, origin);
512 }
catch(lsst::afw::fits::FitsError &e) {
514 if (fitsfile.getImageDim() == 0) {
520 template<
typename PixelT>
522 fits::MemFileManager & manager,
529 fitsfile.setHdu(hdu);
530 *
this =
Image(fitsfile, metadata, bbox, origin);
533 template<
typename PixelT>
535 fits::Fits & fitsfile,
541 typedef boost::mpl::vector<
556 fits_read_image<fits_image_types>(fitsfile, *
this, *metadata, bbox, origin);
559 template<
typename PixelT>
561 std::string
const & fileName,
563 std::string
const & mode
566 writeFits(fitsfile, metadata_i);
569 template<
typename PixelT>
571 fits::MemFileManager & manager,
573 std::string
const & mode
576 writeFits(fitsfile, metadata_i);
579 template<
typename PixelT>
581 fits::Fits & fitsfile,
587 this->getX0(), this->getY0());
589 metadata = metadata_i->deepCopy();
590 metadata->combine(wcsAMetadata);
592 metadata = wcsAMetadata;
601 template<
typename PixelT>
608 template<
typename PixelT>
621 namespace bl = boost::lambda;
625 template<
typename PixelT>
627 return static_cast<PixelT>(std::sqrt(x));
631 template<
typename PixelT>
633 transform_pixels(_getRawView(), _getRawView(),
634 boost::bind(mysqrt<PixelT>, bl::_1));
638 template<
typename PixelT>
640 transform_pixels(_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 + rhs));
644 template<
typename PixelT>
647 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
648 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
651 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 + bl::_2));
657 template<
typename PixelT>
661 for (
int y = 0;
y != this->getHeight(); ++
y) {
665 ptr != end; ++ptr, ++xPos) {
666 *ptr +=
function(xPos, yPos);
672 template<
typename PixelT>
675 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
676 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
679 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
680 bl::ret<PixelT>(bl::_1 + bl::ret<PixelT>(c*bl::_2)));
684 template<
typename PixelT>
686 transform_pixels(_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 - rhs));
690 template<
typename PixelT>
693 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
694 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
697 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 - bl::_2));
701 template<
typename PixelT>
704 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
705 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
708 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
709 bl::ret<PixelT>(bl::_1 - bl::ret<PixelT>(c*bl::_2)));
715 template<
typename PixelT>
719 for (
int y = 0;
y != this->getHeight(); ++
y) {
723 ptr != end; ++ptr, ++xPos) {
724 *ptr -=
function(xPos, yPos);
730 template<
typename PixelT>
732 transform_pixels(_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 * rhs));
736 template<
typename PixelT>
739 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
740 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
743 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 * bl::_2));
747 template<
typename PixelT>
750 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
751 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
754 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
755 bl::ret<PixelT>(bl::_1 * bl::ret<PixelT>(c*bl::_2)));
761 template<
typename PixelT>
763 transform_pixels(_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 / rhs));
768 namespace lsst {
namespace afw {
namespace image {
771 double const irhs = 1/rhs;
777 float const irhs = 1/rhs;
783 template<
typename PixelT>
786 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
787 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
790 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(), bl::ret<PixelT>(bl::_1 / bl::_2));
794 template<
typename PixelT>
797 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
798 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
801 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
802 bl::ret<PixelT>(bl::_1 / bl::ret<PixelT>(c*bl::_2)));
811 template<
typename LhsPixelT,
typename RhsPixelT>
813 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
814 return static_cast<LhsPixelT
>(lhs + rhs);
818 template<
typename LhsPixelT,
typename RhsPixelT>
820 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
821 return static_cast<LhsPixelT
>(lhs - rhs);
825 template<
typename LhsPixelT,
typename RhsPixelT>
827 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
828 return static_cast<LhsPixelT
>(lhs*rhs);
832 template<
typename LhsPixelT,
typename RhsPixelT>
834 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
835 return static_cast<LhsPixelT
>(lhs/rhs);
842 template<
typename LhsPixelT,
typename RhsPixelT>
849 template<
typename LhsPixelT,
typename RhsPixelT>
856 template<
typename LhsPixelT,
typename RhsPixelT>
863 template<
typename LhsPixelT,
typename RhsPixelT>
873 #define INSTANTIATE_OPERATOR(OP_EQ, T) \
874 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<boost::uint16_t> const& rhs); \
875 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<int> const& rhs); \
876 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<float> const& rhs); \
877 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<double> const& rhs); \
878 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<boost::uint64_t> const& rhs);
880 #define INSTANTIATE(T) \
881 template class image::ImageBase<T>; \
882 template class image::Image<T>; \
883 INSTANTIATE_OPERATOR(+=, T); \
884 INSTANTIATE_OPERATOR(-=, T); \
885 INSTANTIATE_OPERATOR(*=, T); \
886 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)
afw::table::Key< afw::table::Point< int > > dimensions
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.
boost::intrusive_ptr< Manager > Ptr
Image & operator=(const PixelT rhs)
Set the image's pixels to rhs.
Include files required for standard LSST Exception handling.
void operator*=(PixelT const rhs)
Multiply lhs by scalar rhs.
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.
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.
#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)