From 409f70eb6524aa1416c4dcfe6265ed4f23023a91 Mon Sep 17 00:00:00 2001 From: Davis King Date: Wed, 18 Feb 2015 07:55:53 -0500 Subject: [PATCH] Made sub_image() a little more robust with regards to object lifetime and const correctness. --- dlib/image_transforms/interpolation.h | 91 +++++++++++++++---- .../image_transforms/interpolation_abstract.h | 40 ++++++-- 2 files changed, 107 insertions(+), 24 deletions(-) diff --git a/dlib/image_transforms/interpolation.h b/dlib/image_transforms/interpolation.h index 34d2cbb06..3aa07a5b6 100644 --- a/dlib/image_transforms/interpolation.h +++ b/dlib/image_transforms/interpolation.h @@ -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::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 + struct const_sub_image_proxy + { + const_sub_image_proxy ( + const T& img, + rectangle rect + ) + { + rect = rect.intersect(get_rect(img)); + typedef typename image_traits::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 @@ -39,32 +72,53 @@ namespace dlib { typedef typename image_traits::pixel_type pixel_type; }; + template + struct image_traits > + { + typedef typename image_traits::pixel_type pixel_type; + }; + template + struct image_traits > + { + typedef typename image_traits::pixel_type pixel_type; + }; template - inline long num_rows( const sub_image_proxy& img) { return img.rect.height(); } + inline long num_rows( const sub_image_proxy& img) { return img._nr; } template - inline long num_columns( const sub_image_proxy& img) { return img.rect.width(); } + inline long num_columns( const sub_image_proxy& img) { return img._nc; } + + template + inline long num_rows( const const_sub_image_proxy& img) { return img._nr; } + template + inline long num_columns( const const_sub_image_proxy& img) { return img._nc; } template inline void* image_data( sub_image_proxy& img) { - typedef typename image_traits::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 inline const void* image_data( const sub_image_proxy& img) { - typedef typename image_traits::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 + inline const void* image_data( const const_sub_image_proxy& img) + { + return img._data; } template inline long width_step( const sub_image_proxy& img - ) - { - return width_step(img.img); - } + ) { return img._width_step; } + + template + inline long width_step( + const const_sub_image_proxy& img + ) { return img._width_step; } template < typename image_type @@ -80,14 +134,15 @@ namespace dlib template < typename image_type > - const sub_image_proxy sub_image ( + const const_sub_image_proxy sub_image ( const image_type& img, const rectangle& rect ) { - return sub_image_proxy(img,rect); + return const_sub_image_proxy(img,rect); } +// ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- class interpolate_nearest_neighbor diff --git a/dlib/image_transforms/interpolation_abstract.h b/dlib/image_transforms/interpolation_abstract.h index 11ccaff2b..dcb441b7b 100644 --- a/dlib/image_transforms/interpolation_abstract.h +++ b/dlib/image_transforms/interpolation_abstract.h @@ -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(img,rect) !*/ +// ---------------------------------------------------------------------------------------- + template < typename image_type > - const sub_image_proxy 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 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(img,rect) + - returns const_sub_image_proxy(img,rect) !*/ // ----------------------------------------------------------------------------------------