30#include "boost/format.hpp" 
   31#include "boost/gil.hpp" 
   44template <
typename PixelT>
 
   46                                                                     Manager::Ptr& manager) {
 
   47    if (dimensions.getX() < 0 || dimensions.getY() < 0) {
 
   49                          str(boost::format(
"Both width and height must be non-negative: %d, %d") %
 
   50                              dimensions.getX() % dimensions.getY()));
 
   54                          str(boost::format(
"Image dimensions (%d x %d) too large; int overflow detected.") %
 
   55                              dimensions.getX() % dimensions.getY()));
 
   58            ndarray::SimpleManager<PixelT>::allocate(dimensions.getX() * dimensions.getY());
 
   60    return boost::gil::interleaved_view(dimensions.getX(), dimensions.getY(),
 
   61                                        (
typename _view_t::value_type*)r.second,
 
   62                                        dimensions.getX() * 
sizeof(PixelT));
 
 
   64template <
typename PixelT>
 
   67                                                                    const _view_t& view) {
 
   68    if (offset.getX() < 0 || offset.getY() < 0 || offset.getX() + dimensions.getX() > view.width() ||
 
   69        offset.getY() + dimensions.getY() > view.height()) {
 
   73                         "Box2I(Point2I(%d,%d),lsst::geom::Extent2I(%d,%d)) doesn't fit in image %dx%d") %
 
   74                 offset.getX() % offset.getY() % dimensions.getX() % dimensions.getY() % view.width() %
 
   78    if (dimensions.getX() == 0 && dimensions.getY() == 0
 
   79        && view.width() == 0 && view.height() == 0) {
 
   83        return boost::gil::subimage_view(view, offset.getX(), offset.getY(), dimensions.getX(),
 
   88template <
typename PixelT>
 
   90        : _origin(0, 0), _manager(), _gilView(
_allocateView(dimensions, _manager)) {}
 
 
   92template <
typename PixelT>
 
   96template <
typename PixelT>
 
  100        : _origin(rhs._origin), _manager(rhs._manager), _gilView(rhs._gilView) {
 
 
  108template <
typename PixelT>
 
  111template <
typename PixelT>
 
  117          _manager(rhs._manager),  
 
  126template <
typename PixelT>
 
  129          _manager(array.getManager()),
 
  130          _gilView(
boost::gil::interleaved_view(array.template getSize<1>(), array.template getSize<0>(),
 
  131                                                (typename _view_t::value_type*)array.getData(),
 
  132                                                array.template getStride<0>() * sizeof(PixelT))) {
 
 
  139template <
typename PixelT>
 
  147template <
typename PixelT>
 
  152template <
typename PixelT>
 
  154    auto lhsDim = bbox.isEmpty() ? 
getDimensions() : bbox.getDimensions();
 
  157                          (boost::format(
"Dimension mismatch: %dx%d v. %dx%d") % lhsDim.getX() %
 
  161    if (bbox.isEmpty()) {
 
  162        copy_pixels(rhs._gilView, _gilView);
 
  165        auto lhsGilView = 
_makeSubView(lhsDim, lhsOff, _gilView);
 
  166        copy_pixels(rhs._gilView, lhsGilView);
 
 
  170template <
typename PixelT>
 
  176template <
typename PixelT>
 
  181                          (boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") % x % y %
 
  190template <
typename PixelT>
 
  192    return _gilView(x, y)[0];
 
  195template <
typename PixelT>
 
  200                          (boost::format(
"Index (%d, %d) is out of range [0--%d], [0--%d]") % x % y %
 
  205    return _gilView(x, y)[0];
 
  208template <
typename PixelT>
 
  211    int x = index.getX();
 
  212    int y = index.getY();
 
  217    return _gilView(x, y)[0];
 
 
  220template <
typename PixelT>
 
  223    int x = index.getX();
 
  224    int y = index.getY();
 
  229    return _gilView(x, y)[0];
 
 
  232template <
typename PixelT>
 
  236    swap(_manager, rhs._manager);  
 
  237    swap(_gilView, rhs._gilView);
 
  238    swap(_origin, rhs._origin);
 
 
  241template <
typename PixelT>
 
  249template <
typename PixelT>
 
  251    return _gilView.begin();
 
  254template <
typename PixelT>
 
  256    return _gilView.end();
 
 
  259template <
typename PixelT>
 
  261    return _gilView.rbegin();
 
 
  264template <
typename PixelT>
 
  266    return _gilView.rend();
 
 
  269template <
typename PixelT>
 
  271    return _gilView.at(x, y);
 
 
  274template <
typename PixelT>
 
  286template <
typename PixelT>
 
  298template <
typename PixelT>
 
  300    fill_pixels(_gilView, rhs);
 
 
  308template <
typename PixelT>
 
  311    *
this = initialValue;
 
 
  314template <
typename PixelT>
 
  317    *
this = initialValue;
 
 
  320template <
typename PixelT>
 
  322    *
this = initialValue;
 
 
  325template <
typename PixelT>
 
  328template <
typename PixelT>
 
  331template <
typename PixelT>
 
  336template <
typename PixelT>
 
  343template <
typename PixelT>
 
  350template <
typename PixelT>
 
  357template <
typename PixelT>
 
  361    *
this = reader.
read<PixelT>(bbox, origin, allowUnsafe);
 
  367template <
typename PixelT>
 
  372    *
this = reader.
read<PixelT>(bbox, origin, allowUnsafe);
 
  378template <
typename PixelT>
 
  382    *
this = reader.
read<PixelT>(bbox, origin, allowUnsafe);
 
  388template <
typename PixelT>
 
  393    writeFits(fitsfile, metadata_i);
 
  396template <
typename PixelT>
 
  401    writeFits(fitsfile, metadata_i);
 
  405template <
typename PixelT>
 
  411template <
typename PixelT>
 
  416    writeFits(fitsfile, 
options, header, mask);
 
  419template <
typename PixelT>
 
  424    writeFits(fitsfile, 
options, header, mask);
 
  427template <
typename PixelT>
 
  429                              daf::base::PropertySet 
const * header,
 
  431    fitsfile.writeImage(*
this, 
options, header, mask);
 
  436template <
typename PixelT>
 
  442template <
typename PixelT>
 
  448template <
typename PixelT>
 
  451                     [](PixelT 
const& l) -> PixelT { 
return static_cast<PixelT
>(
std::sqrt(l)); });
 
 
  454template <
typename PixelT>
 
  460template <
typename PixelT>
 
  464                          (boost::format(
"Images are of different size, %dx%d v %dx%d") % this->
getWidth() %
 
  468    transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
 
  469                     [](PixelT 
const& l, PixelT 
const& r) -> PixelT { 
return l + r; });
 
  473template <
typename PixelT>
 
  475    for (
int y = 0; y != this->
getHeight(); ++y) {
 
  480            *ptr += function(xPos, yPos);
 
 
  486template <
typename PixelT>
 
  490                          (boost::format(
"Images are of different size, %dx%d v %dx%d") % this->
getWidth() %
 
  496            [&c](PixelT 
const& l, PixelT 
const& r) -> PixelT { 
return l + (c * r); });
 
 
  499template <
typename PixelT>
 
  505template <
typename PixelT>
 
  509                          (boost::format(
"Images are of different size, %dx%d v %dx%d") % this->
getWidth() %
 
  514                     [](PixelT 
const& l, PixelT 
const& r) -> PixelT { 
return l - r; });
 
 
  518template <
typename PixelT>
 
  522                          (boost::format(
"Images are of different size, %dx%d v %dx%d") % this->
getWidth() %
 
  528            [&c](PixelT 
const& l, PixelT 
const& r) -> PixelT { 
return l - (c * r); });
 
 
  531template <
typename PixelT>
 
  533    for (
int y = 0; y != this->
getHeight(); ++y) {
 
  538            *ptr -= function(xPos, yPos);
 
 
  544template <
typename PixelT>
 
  550template <
typename PixelT>
 
  554                          (boost::format(
"Images are of different size, %dx%d v %dx%d") % this->
getWidth() %
 
  559                     [](PixelT 
const& l, PixelT 
const& r) -> PixelT { 
return l * r; });
 
 
  563template <
typename PixelT>
 
  567                          (boost::format(
"Images are of different size, %dx%d v %dx%d") % this->
getWidth() %
 
  573            [&c](PixelT 
const& l, PixelT 
const& r) -> PixelT { 
return l * (c * r); });
 
 
  576template <
typename PixelT>
 
  586    double const irhs = 1 / rhs;
 
 
  593    float const irhs = 1 / rhs;
 
 
  598template <
typename PixelT>
 
  602                          (boost::format(
"Images are of different size, %dx%d v %dx%d") % this->
getWidth() %
 
  607                     [](PixelT 
const& l, PixelT 
const& r) -> PixelT { 
return l / r; });
 
 
  611template <
typename PixelT>
 
  615                          (boost::format(
"Images are of different size, %dx%d v %dx%d") % this->
getWidth() %
 
  621            [&c](PixelT 
const& l, PixelT 
const& r) -> PixelT { 
return l / (c * r); });
 
 
  628template <
typename LhsPixelT, 
typename RhsPixelT>
 
  629struct plusEq : 
public pixelOp2<LhsPixelT, RhsPixelT> {
 
  630    LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
 const override {
 
  631        return static_cast<LhsPixelT
>(lhs + rhs);
 
  635template <
typename LhsPixelT, 
typename RhsPixelT>
 
  636struct minusEq : 
public pixelOp2<LhsPixelT, RhsPixelT> {
 
  637    LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
 const override {
 
  638        return static_cast<LhsPixelT
>(lhs - rhs);
 
  642template <
typename LhsPixelT, 
typename RhsPixelT>
 
  643struct timesEq : 
public pixelOp2<LhsPixelT, RhsPixelT> {
 
  644    LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
 const override {
 
  645        return static_cast<LhsPixelT
>(lhs * rhs);
 
  649template <
typename LhsPixelT, 
typename RhsPixelT>
 
  650struct divideEq : 
public pixelOp2<LhsPixelT, RhsPixelT> {
 
  651    LhsPixelT operator()(LhsPixelT lhs, RhsPixelT rhs)
 const override {
 
  652        return static_cast<LhsPixelT
>(lhs / rhs);
 
  657template <
typename LhsPixelT, 
typename RhsPixelT>
 
  663template <
typename LhsPixelT, 
typename RhsPixelT>
 
  669template <
typename LhsPixelT, 
typename RhsPixelT>
 
  675template <
typename LhsPixelT, 
typename RhsPixelT>
 
  683    if (metadata.
exists(
"ZNAXIS1") && metadata.
exists(
"ZNAXIS2")) {
 
 
  692template <
typename T1, 
typename T2>
 
  703    auto beg1Addr = arr1.front().begin();
 
  704    auto end1Addr = arr1.back().end();
 
  707    auto beg2Addr = arr2.front().begin();
 
  708    auto end2Addr = arr2.back().end();
 
  711    return ptrLess(beg1Addr, end2Addr) && ptrLess(beg2Addr, end1Addr);
 
 
  718#define INSTANTIATE_OPERATOR(OP_EQ, T)                                                 \ 
  719    template Image<T>& operator OP_EQ(Image<T>& lhs, Image<std::uint16_t> const& rhs); \ 
  720    template Image<T>& operator OP_EQ(Image<T>& lhs, Image<int> const& rhs);           \ 
  721    template Image<T>& operator OP_EQ(Image<T>& lhs, Image<float> const& rhs);         \ 
  722    template Image<T>& operator OP_EQ(Image<T>& lhs, Image<double> const& rhs);        \ 
  723    template Image<T>& operator OP_EQ(Image<T>& lhs, Image<std::uint64_t> const& rhs); 
  725#define INSTANTIATE(T)           \ 
  726    template class ImageBase<T>; \ 
  727    template class Image<T>;     \ 
  728    INSTANTIATE_OPERATOR(+=, T); \ 
  729    INSTANTIATE_OPERATOR(-=, T); \ 
  730    INSTANTIATE_OPERATOR(*=, T); \ 
  731    INSTANTIATE_OPERATOR(/=, T) 
  733#define INSTANTIATE2(T1, T2) template bool imagesOverlap<T1, T2>(ImageBase<T1> const&, ImageBase<T2> const&); 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#define INSTANTIATE(FROMSYS, TOSYS)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
#define INSTANTIATE2(ImagePixelT1, ImagePixelT2)
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
void writeImage(ndarray::Array< T const, N, C > const &array)
Write an ndarray::Array to a FITS image HDU.
Lifetime-management for memory that goes into FITS memory files.
A class used to request that array accesses be checked.
std::shared_ptr< daf::base::PropertyList > readMetadata()
Read the image's FITS header.
The base class for all image classed (Image, Mask, MaskedImage, ...)
iterator end() const
Return an STL compliant iterator to the end of the image.
int getX0() const
Return the image's column-origin.
iterator begin() const
Return an STL compliant iterator to the start of the image.
static _view_t _allocateView(lsst::geom::Extent2I const &dimensions, Manager::Ptr &manager)
typename Reference< PixelT >::type PixelReference
A Reference to a PixelT.
typename _view_t::iterator iterator
An STL compliant iterator.
PixelReference operator()(int x, int y)
Return a reference to the pixel (x, y) in LOCAL coordinates.
static _view_t _makeSubView(lsst::geom::Extent2I const &dimensions, lsst::geom::Extent2I const &offset, const _view_t &view)
int getWidth() const
Return the number of columns in the image.
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
int getY0() const
Return the image's row-origin.
int getArea() const
Return the area of the image.
lsst::geom::Extent2I getDimensions() const
typename ndarray::Array< PixelT, 2, 1 > Array
A mutable ndarray representation of the image.
void assign(ImageBase const &rhs, lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT)
Copy pixels from another image to a specified subregion of this image.
x_iterator fast_iterator
A fast STL compliant iterator for contiguous images N.b.
typename _view_t::reverse_iterator reverse_iterator
An STL compliant reverse iterator.
int getHeight() const
Return the number of rows in the image.
ImageBase & operator=(const ImageBase &rhs)
Shallow assignment operator.
bool isContiguous() const
iterator at(int x, int y) const
Return an STL compliant iterator at the point (x, y)
x_iterator row_begin(int y) const
x_iterator row_end(int y) const
Return an x_iterator to the end of the y'th row.
reverse_iterator rbegin() const
Return an STL compliant reverse iterator to the start of the image.
_view_t _getRawView() const
PixelReference get(lsst::geom::Point2I const &index, ImageOrigin origin)
Return a reference to a single pixel (with no bounds check).
void swap(ImageBase &rhs)
typename ConstReference< PixelT >::type PixelConstReference
A ConstReference to a PixelT.
reverse_iterator rend() const
Return an STL compliant reverse iterator to the end of the image.
A FITS reader class for regular Images.
Image< PixelT > read(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool allowUnsafe=false)
Read the Image.
A class to represent a 2-dimensional array of pixels.
A Function taking two arguments.
Class for storing generic metadata.
int getAsInt(std::string const &name) const
Get the last value for a bool/char/short/int property name (possibly hierarchical).
bool exists(std::string const &name) const
Determine if a name (possibly hierarchical) exists.
Image< double, Image< double > > & operator*=(double value)
Image< double, Image< double > > & operator+=(double value)
Image(size_t n_rows, size_t n_cols, const double *value_init=lsst::gauss2d::Image< double, Image< double > >::_value_default_ptr(), const std::shared_ptr< const lsst::gauss2d::CoordinateSystem > coordsys=nullptr)
An integer coordinate rectangle.
Reports attempts to exceed implementation-defined length limits for some classes.
Reports errors that are due to events beyond the control of the program.
std::string const wcsNameForXY0
Image< LhsPixelT > & operator+=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Add lhs to Image rhs (i.e. pixel-by-pixel addition) where types are different.
Image< LhsPixelT > & operator-=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Subtract lhs from Image rhs (i.e. pixel-by-pixel subtraction) where types are different.
void for_each_pixel(Image< LhsT > &lhs, pixelOp0< LhsT > const &func)
Set each pixel in an Image<LhsT> to func()
lsst::geom::Box2I bboxFromMetadata(daf::base::PropertySet &metadata)
Determine the image bounding box from its metadata (FITS header)
Image< LhsPixelT > & operator/=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Divide lhs by Image rhs (i.e. pixel-by-pixel division) where types are different.
double indexToPosition(double ind)
Convert image index to image position.
Image< LhsPixelT > & operator*=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Multiply lhs by Image rhs (i.e. pixel-by-pixel multiplication) where types are different.
bool imagesOverlap(ImageBase< T1 > const &image1, ImageBase< T2 > const &image2)
Return true if the pixels for two images or masks overlap in memory.
void swap(Image< PixelT > &a, Image< PixelT > &b)
Extent< int, 2 > Extent2I
Options for writing an image to FITS.
A functor class equivalent to std::function<LhsT (LhsT, RhsT)>, but with a virtual operator()
g2d::python::Image< double > Image
g2d::python::Image< bool > Mask