Opened 14 years ago

Closed 12 years ago

#2211 closed Bugs (fixed)

Can not create image of Regular type

Reported by: john.femiani@… Owned by: Hailin Jin
Milestone: Boost 1.36.0 Component: gil USE GITHUB
Version: Boost 1.36.0 Severity: Problem
Keywords: Cc:

Description

The GIL docs say images, views, and locator's can be created from any type that satisfies the GIL concept 'Regular'

quoted from boost/gil/image.hpp:

/// Note that its element type does not have to be a pixel. \p image can be instantiated with any Regular element,
/// in which case it models the weaker RandomAccess2DImageConcept and does not model PixelBasedConcept

Unfortunately this does not seem to be true, even the simple test attached fails to compile.

Depending upon whether I define the image to be planar or not, I get errors with different metafunctions: for IsPlanar == true:

the error is in the view_type_pixel metafunction, which invokes channel_type.

if IsPlanar == false:

the error is in the is_planar metafunction.

--John

Attachments (1)

test_gil_image_of_regular_type.cpp (445 bytes ) - added by john.femiani@… 14 years ago.
A Boost.Test testcase that fails to compile when it should succed AFIK.

Download all attachments as: .zip

Change History (4)

by john.femiani@…, 14 years ago

A Boost.Test testcase that fails to compile when it should succed AFIK.

comment:1 by john.femiani@…, 14 years ago

The issue is twofold:

  1. A regular type (like a single-chennel pixel) can be considered planer or interleaved. When the image type is planar, GIL tends to use the num_channels metafunction (valid only for PixelBased), so it is easier just to say Regular types are not planar.
  1. The is_planar metafunction had no default value. I think it is safe to say that the is_planar metafunction is short for is_planar_pixel, and so if the type is not a pixel it should return false_. In fact, I think it is reasonable to let it have a default value of false_.
  1. Some of the code first checks if the image is planar and then uses PixelBased operations if it is planar, but the code was laid out so that both branches of the if (!IsPLanar) condition had to compiles. I reorganized that code slightly.

Since I have had bad luck attaching patches on this Trac site (Trac thinks they ar spam!), the patch that made my test compile is attached (no clue if I broke anything else, I just have the headers here).

  • image.hpp

     
    193193        if (_memory) _alloc.deallocate(_memory, total_allocated_size_in_bytes(dimensions));
    194194    }
    195195
     196    struct _channels_in_image :
     197        mpl::eval_if<is_pixel<value_type>,
     198            num_channels<view_t>,
     199            mpl::int_<1>
     200            >::type
     201    {};
     202
    196203    std::size_t total_allocated_size_in_bytes(const point_t& dimensions) const {
    197204        std::size_t size_in_units = get_row_size_in_memunits(dimensions.x)*dimensions.y;
    198                 if (IsPlanar)
    199                         size_in_units = size_in_units*num_channels<view_t>::value;
    200205
     206        typedef typename view_t::x_iterator x_iterator;
     207
     208        if (IsPlanar)
     209                        size_in_units = size_in_units*_channels_in_image::value;
     210
    201211        // return the size rounded up to the nearest byte
    202         return (size_in_units + byte_to_memunit<typename view_t::x_iterator>::value - 1) / byte_to_memunit<typename view_t::x_iterator>::value
    203                         + (_align_in_bytes>0 ? _align_in_bytes-1:0);    // add extra padding in case we need to align the first image pixel
     212        return (size_in_units + byte_to_memunit<x_iterator>::value - 1) / byte_to_memunit<x_iterator>::value
     213                        + (_align_in_bytes>0 ? _align_in_bytes-1:0);
     214        // add extra padding in case we need to align the first image pixel
    204215    }
    205216
    206217    std::size_t get_row_size_in_memunits(x_coord_t width) const {   // number of units per row
  • pixel.hpp

     
    4242template <typename PixelBased> struct color_space_type;
    4343template <typename PixelBased> struct channel_mapping_type;
    4444template <typename PixelBased> struct channel_type;
    45 template <typename PixelBased> struct is_planar;
     45template <typename PixelBased> struct is_planar : mpl::false_{}; //False by default
    4646
    4747template <typename PixelBased> struct color_space_type<const PixelBased> : public color_space_type<PixelBased> {};
    4848template <typename PixelBased> struct channel_mapping_type<const PixelBased> : public channel_mapping_type<PixelBased> {};

in reply to:  1 comment:2 by anonymous, 14 years ago

Replying to john.femiani@asu.edu:

  1. A regular type (like a single-chennel pixel) can be considered planer or interleaved. When the image type is planar, GIL tends to use the num_channels metafunction (valid only for PixelBased), so it is easier just to say Regular types are not planar.

In order to make this clear, I suggest the following additional patch, to be applied after the first:

  • image.hpp

     
    4848////////////////////////////////////////////////////////////////////////////////////////
    4949
    50 template <typename Pixel, bool IsPlanar, typename Alloc=std::allocator<unsigned char> >   
     50template <typename Pixel,
     51          bool IsPlanar=false,
     52          typename Alloc=std::allocator<unsigned char> >
    5153class image {
    5254public:
    5355    typedef typename Alloc::template rebind<unsigned char>::other allocator_type;

This provides a default value for the IsPlanar template argument, so it can b left out if the image is a single channel pixel, so it does not create semantic 'noise'.

For example:

 gil::image<int> the_img(100,100);
 gil::image<int>::view_t the_view = view(img); 
 //NOTE: Why arent views constructible from images?

--John

comment:3 by chhenning, 12 years ago

Resolution: fixed
Status: newclosed

Patch has been applied. Closing this ticket.

Note: See TracTickets for help on using tickets.