31 #include "boost/mpl/vector.hpp"
32 #pragma clang diagnostic push
33 #pragma clang diagnostic ignored "-Wunused-variable"
34 #pragma clang diagnostic pop
35 #include "boost/format.hpp"
36 #include "boost/filesystem/path.hpp"
37 #include "boost/gil/gil_all.hpp"
48 namespace geom = lsst::afw::geom;
51 template <
typename PixelT>
54 Manager::Ptr & manager
56 if (dimensions.getX() < 0 || dimensions.getY() < 0) {
57 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
58 str(
boost::format(
"Both width and height must be non-negative: %d, %d")
59 % dimensions.getX() % dimensions.getY()));
61 if (dimensions.getX() != 0 && dimensions.getY() > std::numeric_limits<int>::max()/dimensions.getX()) {
63 str(
boost::format(
"Image dimensions (%d x %d) too large; int overflow detected.")
64 % dimensions.getX() % dimensions.getY()));
66 std::pair<Manager::Ptr,PixelT*> r = ndarray::SimpleManager<PixelT>::allocate(
67 dimensions.getX() * dimensions.getY()
70 return boost::gil::interleaved_view(
71 dimensions.getX(), dimensions.getY(),
72 (
typename _view_t::value_type* )r.second,
73 dimensions.getX()*
sizeof(
PixelT)
76 template <
typename PixelT>
80 if (offset.getX() < 0 || offset.getY() < 0 ||
81 offset.getX() + dimensions.getX() > view.width() ||
82 offset.getY() + dimensions.getY() > view.height()
85 lsst::pex::exceptions::LengthError,
86 (
boost::format(
"Box2I(Point2I(%d,%d),Extent2I(%d,%d)) doesn't fit in image %dx%d") %
87 offset.getX() % offset.getY() %
88 dimensions.getX() % dimensions.getY() %
89 view.width() % view.height()
93 return boost::gil::subimage_view(
95 offset.getX(), offset.getY(),
96 dimensions.getX(), dimensions.getY()
106 template <
typename PixelT>
109 ) : lsst::daf::base::Citizen(typeid(this)),
111 _gilView(_allocateView(dimensions, _manager))
119 template <
typename PixelT>
122 ) : lsst::daf::base::Citizen(typeid(this)),
123 _origin(bbox.getMin()), _manager(),
124 _gilView(_allocateView(bbox.getDimensions(), _manager))
133 template<
typename PixelT>
139 lsst::daf::base::Citizen(typeid(this)),
141 _manager(rhs._manager),
142 _gilView(rhs._gilView)
159 template<
typename PixelT>
167 lsst::daf::base::Citizen(typeid(this)),
169 _manager(rhs._manager),
170 _gilView(_makeSubView(bbox.getDimensions(),
_origin - rhs.
_origin, rhs._gilView))
188 template<
typename PixelT>
190 lsst::daf::base::Citizen(typeid(this)),
192 _manager(array.getManager()),
194 boost::gil::interleaved_view(
195 array.template getSize<1>(), array.template getSize<0>(),
196 (typename
_view_t::value_type* )array.getData(),
197 array.template getStride<0>() * sizeof(
PixelT)
214 template<
typename PixelT>
225 template<
typename PixelT>
241 template<
typename PixelT>
245 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
250 copy_pixels(rhs.
_gilView, _gilView);
253 auto lhsGilView = _makeSubView(lhsDim, lhsOff, _gilView);
254 copy_pixels(rhs.
_gilView, lhsGilView);
259 template<
typename PixelT>
267 template<
typename PixelT>
274 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
275 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
276 (
boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") %
277 x % y % (getWidth() - 1) % (getHeight() - 1)).str());
286 template<
typename PixelT>
289 return _gilView(x, y)[0];
293 template<
typename PixelT>
296 if (check && (x < 0 || x >= getWidth() || y < 0 || y >= getHeight())) {
297 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
298 (
boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") %
299 x % y % (this->getWidth() - 1) % (this->getHeight() - 1)).str());
302 return _gilView(x, y)[0];
305 template<
typename PixelT>
314 template<
typename PixelT>
319 template <
typename PixelT>
321 int rowStride =
reinterpret_cast<PixelT*
>(row_begin(1)) - reinterpret_cast<PixelT*>(row_begin(0));
322 return ndarray::external(
323 reinterpret_cast<PixelT*>(row_begin(0)),
324 ndarray::makeVector(getHeight(), getWidth()),
325 ndarray::makeVector(rowStride, 1),
331 template <
typename PixelT>
333 int rowStride =
reinterpret_cast<PixelT*
>(row_begin(1)) - reinterpret_cast<PixelT*>(row_begin(0));
334 return ndarray::external(
335 reinterpret_cast<PixelT*>(row_begin(0)),
336 ndarray::makeVector(getHeight(), getWidth()),
337 ndarray::makeVector(rowStride, 1),
348 template<
typename PixelT>
350 return _gilView.begin();
354 template<
typename PixelT>
356 return _gilView.end();
360 template<
typename PixelT>
362 return _gilView.rbegin();
366 template<
typename PixelT>
368 return _gilView.rend();
372 template<
typename PixelT>
374 return _gilView.at(x, y);
381 template<
typename PixelT>
386 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
387 "Only contiguous == true makes sense");
389 if (!this->isContiguous()) {
390 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
391 "Image's pixels are not contiguous");
401 template<
typename PixelT>
406 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
407 "Only contiguous == true makes sense");
409 if (!this->isContiguous()) {
410 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
411 "Image's pixels are not contiguous");
414 return row_end(getHeight()-1);
419 template<
typename PixelT>
421 fill_pixels(_gilView, rhs);
436 template<
typename PixelT>
443 *
this = initialValue;
452 template<
typename PixelT>
458 *
this = initialValue;
464 template<
typename PixelT>
469 *
this = initialValue;
478 template<
typename PixelT>
493 template<
typename PixelT>
503 template<
typename PixelT>
517 template<
typename PixelT>
526 #ifndef DOXYGEN // doc for this section has been moved to header
528 template<
typename PixelT>
530 std::string
const & fileName,
537 fitsfile.setHdu(hdu);
539 *
this =
Image(fitsfile, metadata, bbox, origin);
540 }
catch(lsst::afw::fits::FitsError &e) {
542 if (fitsfile.getImageDim() == 0) {
548 template<
typename PixelT>
550 fits::MemFileManager & manager,
557 fitsfile.setHdu(hdu);
558 *
this =
Image(fitsfile, metadata, bbox, origin);
561 template<
typename PixelT>
563 fits::Fits & fitsfile,
569 typedef boost::mpl::vector<
584 fits_read_image<fits_image_types>(fitsfile, *
this, *metadata, bbox, origin);
587 template<
typename PixelT>
589 std::string
const & fileName,
591 std::string
const & mode
594 writeFits(fitsfile, metadata_i);
597 template<
typename PixelT>
599 fits::MemFileManager & manager,
601 std::string
const & mode
604 writeFits(fitsfile, metadata_i);
607 template<
typename PixelT>
609 fits::Fits & fitsfile,
615 this->getX0(), this->getY0());
617 metadata = metadata_i->deepCopy();
618 metadata->combine(wcsAMetadata);
620 metadata = wcsAMetadata;
629 template<
typename PixelT>
636 template<
typename PixelT>
644 template<
typename PixelT>
646 transform_pixels(_getRawView(), _getRawView(),
651 template<
typename PixelT>
653 transform_pixels(_getRawView(), _getRawView(),
658 template<
typename PixelT>
661 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
662 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
665 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
672 template<
typename PixelT>
676 for (
int y = 0;
y != this->getHeight(); ++
y) {
680 ptr != end; ++ptr, ++xPos) {
681 *ptr +=
function(xPos, yPos);
687 template<
typename PixelT>
690 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
691 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
694 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
699 template<
typename PixelT>
701 transform_pixels(_getRawView(), _getRawView(),
706 template<
typename PixelT>
709 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
710 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
713 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
718 template<
typename PixelT>
721 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
722 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
725 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
732 template<
typename PixelT>
736 for (
int y = 0;
y != this->getHeight(); ++
y) {
740 ptr != end; ++ptr, ++xPos) {
741 *ptr -=
function(xPos, yPos);
747 template<
typename PixelT>
749 transform_pixels(_getRawView(), _getRawView(),
754 template<
typename PixelT>
757 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
758 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
761 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
766 template<
typename PixelT>
769 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
770 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
773 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
780 template<
typename PixelT>
782 transform_pixels(_getRawView(), _getRawView(),
788 namespace lsst {
namespace afw {
namespace image {
791 double const irhs = 1/rhs;
797 float const irhs = 1/rhs;
803 template<
typename PixelT>
806 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
807 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
810 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
815 template<
typename PixelT>
818 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
819 (
boost::format(
"Images are of different size, %dx%d v %dx%d") %
822 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
832 template<
typename LhsPixelT,
typename RhsPixelT>
834 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
835 return static_cast<LhsPixelT
>(lhs + rhs);
839 template<
typename LhsPixelT,
typename RhsPixelT>
841 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
842 return static_cast<LhsPixelT
>(lhs - rhs);
846 template<
typename LhsPixelT,
typename RhsPixelT>
848 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
849 return static_cast<LhsPixelT
>(lhs*rhs);
853 template<
typename LhsPixelT,
typename RhsPixelT>
855 LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
const {
856 return static_cast<LhsPixelT
>(lhs/rhs);
863 template<
typename LhsPixelT,
typename RhsPixelT>
870 template<
typename LhsPixelT,
typename RhsPixelT>
877 template<
typename LhsPixelT,
typename RhsPixelT>
884 template<
typename LhsPixelT,
typename RhsPixelT>
894 #define INSTANTIATE_OPERATOR(OP_EQ, T) \
895 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<std::uint16_t> const& rhs); \
896 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<int> const& rhs); \
897 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<float> const& rhs); \
898 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<double> const& rhs); \
899 template void image::operator OP_EQ(image::Image<T>& lhs, image::Image<std::uint64_t> const& rhs);
901 #define INSTANTIATE(T) \
902 template class image::ImageBase<T>; \
903 template class image::Image<T>; \
904 INSTANTIATE_OPERATOR(+=, T); \
905 INSTANTIATE_OPERATOR(-=, T); \
906 INSTANTIATE_OPERATOR(*=, T); \
907 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.
A functor class equivalent to tr1::function<LhsT (LhsT, RhsT)>, but with a virtual operator() ...
x_iterator fast_iterator
A fast STL compliant iterator for contiguous images N.b.
reverse_iterator rend() const
Return an STL compliant reverse iterator to the end of the image.
Point2I const getMin() const
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.
Include files required for standard LSST Exception handling.
Extent2I const getDimensions() const
_view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
boost::shared_ptr< lsst::daf::base::PropertyList > createTrivialWcsAsPropertySet(std::string const &wcsName, int const x0, int const y0)
Define a trivial WCS that maps the lower left corner (LLC) pixel of an image to a given value...
void operator/=(PixelT const rhs)
Divide lhs by scalar 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)
Set each pixel in an Image<LhsT> to func()
void swap(Mask< PixelT > &a, Mask< PixelT > &b)
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, ...)
void operator*=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Multiply lhs by Image rhs (i.e.
A Function taking two arguments.
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
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.
void assign(ImageBase const &rsh, geom::Box2I const &bbox=geom::Box2I(), ImageOrigin origin=PARENT)
Copy pixels from another image to a specified subregion of this image.
_view_t _getRawView() const
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.
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
ndarray::Array< PixelT const, 2, 1 > ConstArray
An immutable ndarray representation of the image.
Utilities for working with FITS files.
#define LSST_EXCEPT(type,...)
Create an exception with a given type and message and optionally other arguments (dependent on the ty...
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)
Divide lhs by Image rhs (i.e.
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)
Subtract lhs from Image rhs (i.e.
bool isEmpty() const
Return true if the box contains no points.
iterator begin() const
Return an STL compliant iterator to the start of the image.
reverse_iterator rbegin() const
Return an STL compliant reverse iterator to the start of the image.
#define CONST_PTR(...)
A shared pointer to a const object.
int getWidth() const
Return the number of columns in the image.
#define LSST_EXCEPT_ADD(e, m)
Add the current location and a message to an existing exception before rethrowing it...
ndarray::Array< PixelT, 2, 1 > Array
A mutable ndarray representation of the image.
A class to represent a 2-dimensional array of pixels.
Extent< int, 2 > Extent2I
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)
Shallow assignment operator.
PixelReference operator()(int x, int y)
Return a reference to the pixel (x, y)
void operator+=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Add lhs to Image rhs (i.e.