Made sub_image() a little more robust with regards to object lifetime

and const correctness.
This commit is contained in:
Davis King 2015-02-18 07:55:53 -05:00
parent 5152781818
commit 409f70eb65
2 changed files with 107 additions and 24 deletions

View File

@ -20,13 +20,46 @@ namespace dlib
struct sub_image_proxy
{
sub_image_proxy (
T& img_,
const rectangle& rect_
) : img(img_), rect(rect_.intersect(get_rect(img_)))
{}
T& img,
rectangle rect
)
{
rect = rect.intersect(get_rect(img));
typedef typename image_traits<T>::pixel_type pixel_type;
T& img;
const rectangle rect;
_nr = rect.height();
_nc = rect.width();
_width_step = width_step(img);
_data = (char*)image_data(img) + sizeof(pixel_type)*rect.left() + rect.top()*_width_step;
}
void* _data;
long _width_step;
long _nr;
long _nc;
};
template <typename T>
struct const_sub_image_proxy
{
const_sub_image_proxy (
const T& img,
rectangle rect
)
{
rect = rect.intersect(get_rect(img));
typedef typename image_traits<T>::pixel_type pixel_type;
_nr = rect.height();
_nc = rect.width();
_width_step = width_step(img);
_data = (const char*)image_data(img) + sizeof(pixel_type)*rect.left() + rect.top()*_width_step;
}
const void* _data;
long _width_step;
long _nr;
long _nc;
};
template <typename T>
@ -39,32 +72,53 @@ namespace dlib
{
typedef typename image_traits<T>::pixel_type pixel_type;
};
template <typename T>
struct image_traits<const_sub_image_proxy<T> >
{
typedef typename image_traits<T>::pixel_type pixel_type;
};
template <typename T>
struct image_traits<const const_sub_image_proxy<T> >
{
typedef typename image_traits<T>::pixel_type pixel_type;
};
template <typename T>
inline long num_rows( const sub_image_proxy<T>& img) { return img.rect.height(); }
inline long num_rows( const sub_image_proxy<T>& img) { return img._nr; }
template <typename T>
inline long num_columns( const sub_image_proxy<T>& img) { return img.rect.width(); }
inline long num_columns( const sub_image_proxy<T>& img) { return img._nc; }
template <typename T>
inline long num_rows( const const_sub_image_proxy<T>& img) { return img._nr; }
template <typename T>
inline long num_columns( const const_sub_image_proxy<T>& img) { return img._nc; }
template <typename T>
inline void* image_data( sub_image_proxy<T>& img)
{
typedef typename image_traits<T>::pixel_type pixel_type;
return (char*)image_data(img.img) + sizeof(pixel_type)*img.rect.left() + img.rect.top()*width_step(img);
return img._data;
}
template <typename T>
inline const void* image_data( const sub_image_proxy<T>& img)
{
typedef typename image_traits<T>::pixel_type pixel_type;
return (const char*)image_data(img.img) + sizeof(pixel_type)*img.rect.left() + img.rect.top()*width_step(img);
return img._data;
}
template <typename T>
inline const void* image_data( const const_sub_image_proxy<T>& img)
{
return img._data;
}
template <typename T>
inline long width_step(
const sub_image_proxy<T>& img
)
{
return width_step(img.img);
}
) { return img._width_step; }
template <typename T>
inline long width_step(
const const_sub_image_proxy<T>& img
) { return img._width_step; }
template <
typename image_type
@ -80,14 +134,15 @@ namespace dlib
template <
typename image_type
>
const sub_image_proxy<const image_type> sub_image (
const const_sub_image_proxy<image_type> sub_image (
const image_type& img,
const rectangle& rect
)
{
return sub_image_proxy<const image_type>(img,rect);
return const_sub_image_proxy<image_type>(img,rect);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
class interpolate_nearest_neighbor

View File

@ -1155,10 +1155,10 @@ namespace dlib
any function that expects a generic image, excepting that you cannot change
the size of a sub_image_proxy.
Note that it only stores a pointer to the image given to its constructor
and therefore does not perform a copy. Moreover, this means that an
instance of this object becomes invalid after the image it references is
destroyed.
Note that it only stores a pointer to the image data given to its
constructor and therefore does not perform a copy. Moreover, this means
that an instance of this object becomes invalid after the underlying image
data it references is destroyed.
!*/
sub_image_proxy (
T& img,
@ -1187,10 +1187,38 @@ namespace dlib
- returns sub_image_proxy<image_type>(img,rect)
!*/
// ----------------------------------------------------------------------------------------
template <
typename image_type
>
const sub_image_proxy<const image_type> sub_image (
struct const_sub_image_proxy
{
/*!
REQUIREMENTS ON image_type
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
WHAT THIS OBJECT REPRESENTS
This object is just like sub_image_proxy except that it does not allow the
pixel data to be modified.
!*/
const_sub_image_proxy (
const T& img,
const rectangle& rect
);
/*!
ensures
- This object is an image that represents the part of img contained within
rect. If rect is larger than img then rect is cropped so that it does
not go outside img.
!*/
};
template <
typename image_type
>
const const_sub_image_proxy<image_type> sub_image (
const image_type& img,
const rectangle& rect
);
@ -1199,7 +1227,7 @@ namespace dlib
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
ensures
- returns sub_image_proxy<const image_type>(img,rect)
- returns const_sub_image_proxy<image_type>(img,rect)
!*/
// ----------------------------------------------------------------------------------------