WIP. Scale cover art option. Seems to work

This commit is contained in:
emeric
2014-06-14 20:44:03 +02:00
parent 1d67a548c9
commit 9bada5ee2a
92 changed files with 15866 additions and 1890 deletions
@@ -0,0 +1,115 @@
/*
Copyright 2005-2007 Adobe Systems Incorporated
Use, modification and distribution are subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
See http://opensource.adobe.com/gil for most recent version including documentation.
*/
/*************************************************************************************************/
#ifndef BOOST_GIL_EXTENSION_TOOLBOX_DYNAMIC_IMAGES_HPP_INCLUDED
#define BOOST_GIL_EXTENSION_TOOLBOX_DYNAMIC_IMAGES_HPP_INCLUDED
/// \file
/// \brief Generic io functions for dealing with dynamic images
//
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated May 30, 2006
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
#include <boost/gil/gil_config.hpp>
#include <boost/gil/extension/io_new/detail/io_error.hpp>
#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
namespace boost { namespace gil {
// need this for various meta functions.
struct any_image_pixel_t {};
struct any_image_channel_t {};
struct any_image_color_space_t {};
namespace detail {
template <long N>
struct construct_matched_t {
template <typename Images,typename Pred>
static bool apply(any_image<Images>& im,Pred pred) {
if (pred.template apply<typename mpl::at_c<Images,N-1>::type>()) {
typename mpl::at_c<Images,N-1>::type x;
im.move_in(x);
return true;
} else return construct_matched_t<N-1>::apply(im,pred);
}
};
template <>
struct construct_matched_t<0> {
template <typename Images,typename Pred>
static bool apply(any_image<Images>&,Pred) {return false;}
};
// A function object that can be passed to apply_operation.
// Given a predicate IsSupported taking a view type and returning an MPL boolean,
// calls the apply method of OpClass with the view if the given view IsSupported, or throws an exception otherwise
template <typename IsSupported, typename OpClass>
class dynamic_io_fnobj {
OpClass* _op;
template <typename View>
void apply(const View& view,mpl::true_ ) {_op->apply(view);}
template <typename View, typename Info >
void apply( const View& view
, const Info& info
, const mpl::true_
)
{
_op->apply( view, info );
}
template <typename View>
void apply(const View& /* view */ ,mpl::false_) {io_error("dynamic_io: unsupported view type for the given file format");}
template <typename View, typename Info >
void apply( const View& /* view */
, const Info& /* info */
, const mpl::false_
)
{
io_error( "dynamic_io: unsupported view type for the given file format" );
}
public:
dynamic_io_fnobj(OpClass* op) : _op(op) {}
typedef void result_type;
template <typename View>
void operator()(const View& view) {apply(view,typename IsSupported::template apply<View>::type());}
template< typename View, typename Info >
void operator()(const View& view, const Info& info )
{
apply( view
, info
, typename IsSupported::template apply< View >::type()
);
}
};
} // namespace detail
/// \brief Within the any_image, constructs an image with the given dimensions
/// and a type that satisfies the given predicate
template <typename Images,typename Pred>
inline bool construct_matched(any_image<Images>& im,Pred pred) {
return detail::construct_matched_t<mpl::size<Images>::value>::apply(im,pred);
}
} } // namespace boost::gil
#endif // BOOST_GIL_EXTENSION_TOOLBOX_DYNAMIC_IMAGES_HPP_INCLUDED
@@ -0,0 +1,281 @@
/*
Copyright 2010 Christian Henning, Andreas Pokorny, Lubomir Bourdev
Use, modification and distribution are subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
*/
/*************************************************************************************************/
#ifndef BOOST_GIL_EXTENSION_TOOLBOX_GIL_EXTENSIONS_HPP_INCLUDED
#define BOOST_GIL_EXTENSION_TOOLBOX_GIL_EXTENSIONS_HPP_INCLUDED
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Definitions of is_bit_aligned, is_homogeneous, and is_similar metafunctions and
/// some other goodies.
/// \author Christian Henning, Andreas Pokorny, Lubomir Bourdev \n
///
/// \date 2008 \n
///
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/gil/gil_all.hpp>
#include <boost/mpl/if.hpp>
#include <boost/gil/extension/toolbox/dynamic_images.hpp>
namespace boost { namespace gil {
/// is_bit_aligned metafunctions
/// \brief Determines whether the given type is bit_aligned.
template< typename PixelRef >
struct is_bit_aligned : mpl::false_{};
template <typename B, typename C, typename L, bool M>
struct is_bit_aligned<bit_aligned_pixel_reference<B,C,L,M> > : mpl::true_{};
template <typename B, typename C, typename L, bool M>
struct is_bit_aligned<const bit_aligned_pixel_reference<B,C,L,M> > : mpl::true_{};
template <typename B, typename C, typename L>
struct is_bit_aligned<packed_pixel<B,C,L> > : mpl::true_{};
template <typename B, typename C, typename L>
struct is_bit_aligned<const packed_pixel<B,C,L> > : mpl::true_{};
/// is_similar metafunctions
/// \brief Determines if two pixel types are similar.
template< typename A, typename B >
struct is_similar : mpl::false_ {};
template<typename A>
struct is_similar< A, A > : mpl::true_ {};
template<typename B,int I, int S, bool M, int I2>
struct is_similar< packed_channel_reference< B, I, S, M >
, packed_channel_reference< B, I2, S, M >
> : mpl::true_ {};
/// is_homogeneous metafunctions
/// \brief Determines if a pixel types are homogeneous.
template<typename C,typename CMP, int Next, int Last> struct is_homogeneous_impl;
template<typename C,typename CMP, int Last>
struct is_homogeneous_impl<C,CMP,Last,Last> : mpl::true_{};
template<typename C,typename CMP, int Next, int Last>
struct is_homogeneous_impl : mpl::and_< is_homogeneous_impl< C, CMP,Next + 1, Last >
, is_same< CMP, typename mpl::at_c<C,Next>::type
> > {};
template < typename P > struct is_homogeneous : mpl::false_ {};
// pixel
template < typename C, typename L > struct is_homogeneous< pixel<C,L> > : mpl::true_ {};
template < typename C, typename L > struct is_homogeneous<const pixel<C,L> > : mpl::true_ {};
template < typename C, typename L > struct is_homogeneous< pixel<C,L>& > : mpl::true_ {};
template < typename C, typename L > struct is_homogeneous<const pixel<C,L>& > : mpl::true_ {};
// planar pixel reference
template <typename Channel, typename ColorSpace>
struct is_homogeneous< planar_pixel_reference< Channel, ColorSpace > > : mpl::true_ {};
template <typename Channel, typename ColorSpace>
struct is_homogeneous< const planar_pixel_reference< Channel, ColorSpace > > : mpl::true_ {};
template<typename C,typename CMP, int I,int Last>
struct is_homogeneous_impl_p {};
// for packed_pixel
template <typename B, typename C, typename L >
struct is_homogeneous<packed_pixel< B, C, L > >
: is_homogeneous_impl_p< C
, typename mpl::at_c< C, 0 >::type
, 1
, mpl::size< C >::type::value
> {};
template< typename B
, typename C
, typename L
>
struct is_homogeneous< const packed_pixel< B, C, L > >
: is_homogeneous_impl_p< C
, typename mpl::at_c<C,0>::type
, 1
, mpl::size< C >::type::value
> {};
// for bit_aligned_pixel_reference
template <typename B, typename C, typename L, bool M>
struct is_homogeneous<bit_aligned_pixel_reference<B,C,L,M> >
: is_homogeneous_impl<C,typename mpl::at_c<C,0>::type,1,mpl::size<C>::type::value>
{};
template <typename B, typename C, typename L, bool M>
struct is_homogeneous<const bit_aligned_pixel_reference<B,C,L,M> >
: is_homogeneous_impl<C,typename mpl::at_c<C,0>::type,1,mpl::size<C>::type::value>
{};
//////////////////////
/// other goodies
/// get_num_bits metafunctions
/// \brief Determines the numbers of bits for the given channel type.
template <typename T>
struct get_num_bits;
template< typename B, int I, int S, bool M >
struct get_num_bits< packed_channel_reference< B, I, S, M > >
{
BOOST_STATIC_CONSTANT( int, value = S );
};
template<typename B,int I, int S, bool M>
struct get_num_bits< const packed_channel_reference< B, I, S, M > >
{
BOOST_STATIC_CONSTANT( int, value = S );
};
/// channel_type metafunction
/// \brief Generates the channel type for
template <typename B, typename C, typename L, bool M>
struct gen_chan_ref
{
typedef packed_dynamic_channel_reference< B
, mpl::at_c< C, 0 >::type::value
, M
> type;
};
//! This implementation works for bit_algined_pixel_reference
//! with a homogeneous channel layout.
//! The result type will be a packed_dynamic_channel_reference, since the
//! offset info will be missing.
// bit_aligned_pixel_reference
template <typename B, typename C, typename L, bool M>
struct channel_type< bit_aligned_pixel_reference<B,C,L,M> >
: lazy_enable_if< is_homogeneous< bit_aligned_pixel_reference< B, C, L, M > >
, gen_chan_ref< B, C, L, M >
> {};
template <typename B, typename C, typename L, bool M>
struct channel_type<const bit_aligned_pixel_reference<B,C,L,M> >
: lazy_enable_if< is_homogeneous< bit_aligned_pixel_reference< B, C, L, M > >
, gen_chan_ref< B, C, L, M >
> {};
template <typename B, typename C, typename L>
struct gen_chan_ref_p
{
typedef packed_dynamic_channel_reference< B
, get_num_bits< typename mpl::at_c<C,0>::type>::value
, true
> type;
};
// packed_pixel
template < typename BitField
, typename ChannelRefVec
, typename Layout
>
struct channel_type< packed_pixel< BitField
, ChannelRefVec
, Layout
>
> : lazy_enable_if< is_homogeneous< packed_pixel< BitField
, ChannelRefVec
, Layout
>
>
, gen_chan_ref_p< BitField
, ChannelRefVec
, Layout
>
> {};
template <typename B, typename C, typename L>
struct channel_type< const packed_pixel< B, C, L > >
: lazy_enable_if< is_homogeneous<packed_pixel< B, C, L > >
, gen_chan_ref_p< B, C, L >
>
{};
template<>
struct channel_type< any_image_pixel_t >
{
typedef any_image_channel_t type;
};
template<>
struct color_space_type< any_image_pixel_t >
{
typedef any_image_color_space_t type;
};
/// get_pixel_type metafunction
/// \brief Depending on Image this function generates either
/// the pixel type or the reference type in case
/// the image is bit_aligned.
template< typename View >
struct get_pixel_type : mpl::if_< typename is_bit_aligned< typename View::value_type >::type
, typename View::reference
, typename View::value_type
> {};
template< typename ImageViewTypes >
struct get_pixel_type< any_image_view< ImageViewTypes > >
{
typedef any_image_pixel_t type;
};
namespace detail {
/// - performance specialization double
/// - to eliminate compiler warning 4244
template <typename GrayChannelValue>
struct rgb_to_luminance_fn< double, double, double, GrayChannelValue >
{
GrayChannelValue operator()( const double& red
, const double& green
, const double& blue ) const
{
return channel_convert<GrayChannelValue>( red * 0.30 + green * 0.59 + blue * 0.11 );
}
};
} // namespace detail
/// This one is missing in gil ( color_convert.hpp ).
template <>
struct default_color_converter_impl<gray_t,rgba_t>
{
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const
{
get_color(dst,red_t()) =
channel_convert<typename color_element_type<P2, red_t >::type>(get_color(src,gray_color_t()));
get_color(dst,green_t())=
channel_convert<typename color_element_type<P2, green_t>::type>(get_color(src,gray_color_t()));
get_color(dst,blue_t()) =
channel_convert<typename color_element_type<P2, blue_t >::type>(get_color(src,gray_color_t()));
typedef typename channel_type< P2 >::type channel_t;
get_color(dst,alpha_t()) = channel_traits< channel_t >::max_value();
}
};
} // namespace gil
} // namespace boost
#endif // BOOST_GIL_EXTENSION_TOOLBOX_GIL_EXTENSIONS_HPP_INCLUDED
+101
View File
@@ -0,0 +1,101 @@
/*
Copyright 2007-2008 Andreas Pokorny
Use, modification and distribution are subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
*/
/*************************************************************************************************/
#ifndef BOOST_GIL_GRAY_ALPHA_HPP_INCLUDED
#define BOOST_GIL_GRAY_ALPHA_HPP_INCLUDED
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief
/// \author Andreas Pokorny \n
///
/// \date 2007-2008 \n
///
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/gil/gil_config.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/gil/gray.hpp>
#include <boost/gil/typedefs.hpp>
namespace boost { namespace gil {
typedef mpl::vector2<gray_color_t,alpha_t> gray_alpha_t;
typedef layout<gray_alpha_t> gray_alpha_layout_t;
typedef layout<gray_alpha_layout_t, mpl::vector2_c<int,1,0> > alpha_gray_layout_t;
GIL_DEFINE_BASE_TYPEDEFS(8, alpha_gray)
GIL_DEFINE_BASE_TYPEDEFS(8s, alpha_gray)
GIL_DEFINE_BASE_TYPEDEFS(16, alpha_gray)
GIL_DEFINE_BASE_TYPEDEFS(16s,alpha_gray)
GIL_DEFINE_BASE_TYPEDEFS(32 ,alpha_gray)
GIL_DEFINE_BASE_TYPEDEFS(32s,alpha_gray)
GIL_DEFINE_BASE_TYPEDEFS(32f,alpha_gray)
GIL_DEFINE_ALL_TYPEDEFS(8, gray_alpha)
GIL_DEFINE_ALL_TYPEDEFS(8s, gray_alpha)
GIL_DEFINE_ALL_TYPEDEFS(16, gray_alpha)
GIL_DEFINE_ALL_TYPEDEFS(16s,gray_alpha)
GIL_DEFINE_ALL_TYPEDEFS(32 ,gray_alpha)
GIL_DEFINE_ALL_TYPEDEFS(32s,gray_alpha)
GIL_DEFINE_ALL_TYPEDEFS(32f,gray_alpha)
/// \ingroup ColorConvert
/// \brief Gray Alpha to RGBA
template <>
struct default_color_converter_impl<gray_alpha_t,rgba_t> {
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const {
get_color(dst,red_t()) =
channel_convert<typename color_element_type<P2, red_t>::type>(get_color(src,gray_color_t()));
get_color(dst,green_t())=
channel_convert<typename color_element_type<P2, green_t>::type>(get_color(src,gray_color_t()));
get_color(dst,blue_t()) =
channel_convert<typename color_element_type<P2, blue_t>::type>(get_color(src,gray_color_t()));
get_color(dst,alpha_t()) =
channel_convert<typename color_element_type<P2, alpha_t>::type>(get_color(src,alpha_t()));
}
};
template <>
struct default_color_converter_impl<gray_alpha_t,rgb_t> {
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const {
get_color(dst,red_t()) =
channel_convert<typename color_element_type<P2, red_t>::type>(
channel_multiply(get_color(src,gray_color_t()),get_color(src,alpha_t()) )
);
get_color(dst,green_t()) =
channel_convert<typename color_element_type<P2, green_t>::type>(
channel_multiply(get_color(src,gray_color_t()),get_color(src,alpha_t()) )
);
get_color(dst,blue_t()) =
channel_convert<typename color_element_type<P2, blue_t>::type>(
channel_multiply(get_color(src,gray_color_t()),get_color(src,alpha_t()) )
);
}
};
template <>
struct default_color_converter_impl<gray_alpha_t,gray_t> {
template <typename P1, typename P2>
void operator()(const P1& src, P2& dst) const {
get_color(dst,gray_color_t()) =
channel_convert<typename color_element_type<P2, gray_color_t>::type>(
channel_multiply(get_color(src,gray_color_t()),get_color(src,alpha_t()) )
);
}
};
} // gil
} // boost
#endif // BOOST_GIL_GRAY_ALPHA_HPP_INCLUDED
+262
View File
@@ -0,0 +1,262 @@
// Copyright 2007 Christian Henning.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
/*************************************************************************************************/
#ifndef GIL_HSL_H
#define GIL_HSL_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for HSL color space
/// \author Christian Henning \n
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/gil/gil_all.hpp>
namespace boost { namespace gil {
/// \addtogroup ColorNameModel
/// \{
namespace hsl_color_space
{
/// \brief Hue
struct hue_t {};
/// \brief Saturation
struct saturation_t {};
/// \brief Lightness
struct lightness_t {};
}
/// \}
/// \ingroup ColorSpaceModel
typedef mpl::vector3< hsl_color_space::hue_t
, hsl_color_space::saturation_t
, hsl_color_space::lightness_t
> hsl_t;
/// \ingroup LayoutModel
typedef layout<hsl_t> hsl_layout_t;
GIL_DEFINE_ALL_TYPEDEFS( 32f, hsl );
/// \ingroup ColorConvert
/// \brief RGB to HSL
template <>
struct default_color_converter_impl< rgb_t, hsl_t >
{
template <typename P1, typename P2>
void operator()( const P1& src, P2& dst ) const
{
using namespace hsl_color_space;
// only bits32f for hsl is supported
bits32f temp_red = channel_convert<bits32f>( get_color( src, red_t() ));
bits32f temp_green = channel_convert<bits32f>( get_color( src, green_t() ));
bits32f temp_blue = channel_convert<bits32f>( get_color( src, blue_t() ));
bits32f hue, saturation, lightness;
bits32f min_color = (std::min)( temp_red, (std::min)( temp_green, temp_blue ));
bits32f max_color = (std::max)( temp_red, (std::max)( temp_green, temp_blue ));
if( abs( min_color - max_color ) < 0.001 )
{
// rgb color is gray
hue = 0.f;
saturation = 0.f;
// doesn't matter which rgb channel we use.
lightness = temp_red;
}
else
{
bits32f diff = max_color - min_color;
// lightness calculation
lightness = ( min_color + max_color ) / 2.f;
// saturation calculation
if( lightness < 0.5f )
{
saturation = diff
/ ( min_color + max_color );
}
else
{
saturation = ( max_color - min_color )
/ ( 2.f - diff );
}
// hue calculation
if( abs( max_color - temp_red ) < 0.0001f )
{
// max_color is red
hue = ( temp_green - temp_blue )
/ diff;
}
else if( abs( max_color - temp_green) < 0.0001f )
{
// max_color is green
// 2.0 + (b - r) / (maxColor - minColor);
hue = 2.f
+ ( temp_blue - temp_red )
/ diff;
}
else
{
// max_color is blue
hue = 4.f
+ ( temp_red - temp_blue )
/ diff;
}
hue /= 6.f;
if( hue < 0.f )
{
hue += 1.f;
}
}
get_color( dst,hue_t() ) = hue;
get_color( dst,saturation_t() ) = saturation;
get_color( dst,lightness_t() ) = lightness;
}
};
/// \ingroup ColorConvert
/// \brief HSL to RGB
template <>
struct default_color_converter_impl<hsl_t,rgb_t>
{
template <typename P1, typename P2>
void operator()( const P1& src, P2& dst) const
{
using namespace hsl_color_space;
bits32f red, green, blue;
if( abs( get_color( src, saturation_t() )) < 0.0001 )
{
// If saturation is 0, the color is a shade of gray
red = get_color( src, lightness_t() );
green = get_color( src, lightness_t() );
blue = get_color( src, lightness_t() );
}
else
{
float temp1, temp2;
float tempr, tempg, tempb;
//Set the temporary values
if( get_color( src, lightness_t() ) < 0.5 )
{
temp2 = get_color( src, lightness_t() )
* ( 1.f + get_color( src, saturation_t() ) );
}
else
{
temp2 = ( get_color( src, lightness_t() ) + get_color( src, saturation_t() ))
- ( get_color( src, lightness_t() ) * get_color( src, saturation_t() ));
}
temp1 = 2.f
* get_color( src, lightness_t() )
- temp2;
tempr = get_color( src, hue_t() ) + 1.f / 3.f;
if( tempr > 1.f )
{
tempr--;
}
tempg = get_color( src, hue_t() );
tempb = get_color( src, hue_t() ) - 1.f / 3.f;
if( tempb < 0.f )
{
tempb++;
}
//Red
if( tempr < 1.f / 6.f )
{
red = temp1 + ( temp2 - temp1 ) * 6.f * tempr;
}
else if( tempr < 0.5f )
{
red = temp2;
}
else if( tempr < 2.f / 3.f )
{
red = temp1 + (temp2 - temp1)
* (( 2.f / 3.f ) - tempr) * 6.f;
}
else
{
red = temp1;
}
//Green
if( tempg < 1.f / 6.f )
{
green = temp1 + ( temp2 - temp1 ) * 6.f * tempg;
}
else if( tempg < 0.5f )
{
green = temp2;
}
else if( tempg < 2.f / 3.f )
{
green = temp1 + ( temp2 - temp1 )
* (( 2.f / 3.f ) - tempg) * 6.f;
}
else
{
green = temp1;
}
//Blue
if( tempb < 1.f / 6.f )
{
blue = temp1 + (temp2 - temp1) * 6.f * tempb;
}
else if( tempb < 0.5f )
{
blue = temp2;
}
else if( tempb < 2.f / 3.f )
{
blue = temp1 + (temp2 - temp1)
* (( 2.f / 3.f ) - tempb) * 6.f;
}
else
{
blue = temp1;
}
}
get_color(dst,red_t()) =
channel_convert<typename color_element_type< P2, red_t >::type>( red );
get_color(dst,green_t())=
channel_convert<typename color_element_type< P2, green_t >::type>( green );
get_color(dst,blue_t()) =
channel_convert<typename color_element_type< P2, blue_t >::type>( blue );
}
};
} } // namespace boost::gil
#endif // GIL_HSL_H
+231
View File
@@ -0,0 +1,231 @@
// Copyright 2004 Christian Henning.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
/*************************************************************************************************/
#ifndef GIL_HSV_H
#define GIL_HSV_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for HSV color space
/// \author Christian Henning \n
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/cast.hpp>
#include <boost/gil/gil_all.hpp>
namespace boost { namespace gil {
/// \addtogroup ColorNameModel
/// \{
namespace hsv_color_space
{
/// \brief Hue
struct hue_t {};
/// \brief Saturation
struct saturation_t{};
/// \brief Value
struct value_t {};
}
/// \}
/// \ingroup ColorSpaceModel
typedef mpl::vector3< hsv_color_space::hue_t
, hsv_color_space::saturation_t
, hsv_color_space::value_t
> hsv_t;
/// \ingroup LayoutModel
typedef layout<hsv_t> hsv_layout_t;
GIL_DEFINE_ALL_TYPEDEFS( 32f, hsv )
/// \ingroup ColorConvert
/// \brief RGB to HSV
template <>
struct default_color_converter_impl< rgb_t, hsv_t >
{
template <typename P1, typename P2>
void operator()( const P1& src, P2& dst ) const
{
using namespace hsv_color_space;
// only bits32f for hsv is supported
bits32f temp_red = channel_convert<bits32f>( get_color( src, red_t() ));
bits32f temp_green = channel_convert<bits32f>( get_color( src, green_t() ));
bits32f temp_blue = channel_convert<bits32f>( get_color( src, blue_t() ));
bits32f hue, saturation, value;
bits32f min_color = (std::min)( temp_red, (std::min)( temp_green, temp_blue ));
bits32f max_color = (std::max)( temp_red, (std::max)( temp_green, temp_blue ));
value = max_color;
bits32f diff = max_color - min_color;
if( max_color < 0.0001f )
{
saturation = 0.f;
}
else
{
saturation = diff / max_color;
}
if( saturation < 0.0001f )
{
//it doesn't matter what value it has
hue = 0.f;
}
else
{
if( (std::abs)( boost::numeric_cast<int>(temp_red - max_color) ) < 0.0001f )
{
hue = ( temp_green - temp_blue )
/ diff;
}
else if( temp_green == max_color )
{
hue = 2.f + ( temp_blue - temp_red )
/ diff;
}
else
{
hue = 4.f + ( temp_red - temp_green )
/ diff;
}
//to bring it to a number between 0 and 1
hue /= 6.f;
if( hue < 0.f )
{
hue++;
}
}
get_color( dst, hue_t() ) = hue;
get_color( dst, saturation_t() ) = saturation;
get_color( dst, value_t() ) = value;
}
};
/// \ingroup ColorConvert
/// \brief HSV to RGB
template <>
struct default_color_converter_impl<hsv_t,rgb_t>
{
template <typename P1, typename P2>
void operator()( const P1& src, P2& dst) const
{
using namespace hsv_color_space;
bits32f red, green, blue;
//If saturation is 0, the color is a shade of gray
if( abs( get_color( src, saturation_t() )) < 0.0001f )
{
// If saturation is 0, the color is a shade of gray
red = get_color( src, value_t() );
green = get_color( src, value_t() );
blue = get_color( src, value_t() );
}
else
{
bits32f frac, p, q, t, h;
bits32 i;
//to bring hue to a number between 0 and 6, better for the calculations
h = get_color( src, hue_t() );
h *= 6.f;
i = static_cast<bits32>( floor( h ));
frac = h - i;
p = get_color( src, value_t() )
* ( 1.f - get_color( src, saturation_t() ));
q = get_color( src, value_t() )
* ( 1.f - ( get_color( src, saturation_t() ) * frac ));
t = get_color( src, value_t() )
* ( 1.f - ( get_color( src, saturation_t() ) * ( 1.f - frac )));
switch( i )
{
case 0:
{
red = get_color( src, value_t() );
green = t;
blue = p;
break;
}
case 1:
{
red = q;
green = get_color( src, value_t() );
blue = p;
break;
}
case 2:
{
red = p;
green = get_color( src, value_t() );
blue = t;
break;
}
case 3:
{
red = p;
green = q;
blue = get_color( src, value_t() );
break;
}
case 4:
{
red = t;
green = p;
blue = get_color( src, value_t() );
break;
}
case 5:
{
red = get_color( src, value_t() );
green = p;
blue = q;
break;
}
}
}
get_color(dst,red_t()) =
channel_convert<typename color_element_type< P2, red_t >::type>( red );
get_color(dst,green_t())=
channel_convert<typename color_element_type< P2, green_t >::type>( green );
get_color(dst,blue_t()) =
channel_convert<typename color_element_type< P2, blue_t >::type>( blue );
}
};
} } // namespace boost::gil
#endif // GIL_HSV_H
+255
View File
@@ -0,0 +1,255 @@
// Copyright 2008 Chung-Lin Wen.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
/*************************************************************************************************/
#ifndef GIL_LAB_H
#define GIL_LAB_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for CIE Lab color space
/// \author Chung-Lin Wen \n
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/cast.hpp>
#include <boost/gil/gil_all.hpp>
namespace boost { namespace gil {
/// \addtogroup ColorNameModel
/// \{
namespace lab_color_space
{
/// \brief Luminance
struct luminance_t {};
/// \brief a Color Component
struct a_color_opponent_t {};
/// \brief b Color Component
struct b_color_opponent_t {};
}
/// \}
/// \ingroup ColorSpaceModel
typedef mpl::vector3< lab_color_space::luminance_t
, lab_color_space::a_color_opponent_t
, lab_color_space::b_color_opponent_t
> lab_t;
/// \ingroup LayoutModel
typedef layout<lab_t> lab_layout_t;
GIL_DEFINE_ALL_TYPEDEFS( 32f, lab );
/// \ingroup ColorConvert
/// \brief RGB to LAB
template <>
struct default_color_converter_impl< rgb_t, lab_t >
{
template <typename P1, typename P2>
void operator()( const P1& src, P2& dst ) const
{
using namespace lab_color_space;
// only bits32f for lab is supported
bits32f temp_red = channel_convert<bits32f>( get_color( src, red_t() ));
bits32f temp_green = channel_convert<bits32f>( get_color( src, green_t() ));
bits32f temp_blue = channel_convert<bits32f>( get_color( src, blue_t() ));
// first, transfer to xyz color space
bits32f normalized_r = temp_red / 255.f;
bits32f normalized_g = temp_green / 255.f;
bits32f normalized_b = temp_blue / 255.f;
if( normalized_r > 0.04045f )
{
normalized_r = pow( (( normalized_r + 0.055f ) / 1.055f ), 2.4f );
}
else
{
normalized_r /= 12.92f;
}
if( normalized_g > 0.04045f )
{
normalized_g = pow((( normalized_g + 0.055f ) / 1.055f ), 2.4f );
}
else
{
normalized_g /= 12.92f;
}
if( normalized_b > 0.04045f )
{
normalized_b = pow( (( normalized_b + 0.055f ) / 1.055f ), 2.4f );
}
else
{
normalized_b /= 12.92f;
}
normalized_r *= 100.f;
normalized_g *= 100.f;
normalized_b *= 100.f;
bits32f x, y, z;
x = normalized_r * 0.4124f + normalized_g * 0.3576f + normalized_b * 0.1805f;
y = normalized_r * 0.2126f + normalized_g * 0.7152f + normalized_b * 0.0722f;
z = normalized_r * 0.0193f + normalized_g * 0.1192f + normalized_b * 0.9505f;
// then, transfer to lab color space
bits32f ref_x = 95.047f;
bits32f ref_y = 100.000f;
bits32f ref_z = 108.883f;
bits32f normalized_x = x / ref_x;
bits32f normalized_y = y / ref_y;
bits32f normalized_z = z / ref_z;
if( normalized_x > 0.008856f )
{
normalized_x = pow( normalized_x, 0.333f );
}
else
{
normalized_x = (7.787f * normalized_x) + ( 16.f/116.f );
}
if( normalized_y > 0.008856f )
{
normalized_y = pow( normalized_y, 0.333f );
}
else
{
normalized_y = (7.787f * normalized_y) + ( 16.f/116.f );
}
if( normalized_z > 0.008856f )
{
normalized_z = pow( normalized_z, 0.333f );
}
else
{
normalized_z = ( 7.787f * normalized_z ) + ( 16.f/116.f );
}
bits32f luminance, a_color_opponent, b_color_opponent;
luminance = ( 116.f * normalized_y ) - 16.f;
a_color_opponent = 500.f * ( normalized_x - normalized_y );
b_color_opponent = 200.f * ( normalized_y - normalized_z );
get_color( dst, luminance_t() ) = luminance;
get_color( dst, a_color_opponent_t() ) = a_color_opponent;
get_color( dst, b_color_opponent_t() ) = b_color_opponent;
}
};
/// \ingroup ColorConvert
/// \brief LAB to RGB
template <>
struct default_color_converter_impl<lab_t,rgb_t>
{
template <typename P1, typename P2>
void operator()( const P1& src, P2& dst) const
{
using namespace lab_color_space;
bits32f luminance = get_color( src, luminance_t() );
bits32f a_color_opponent = get_color( src, a_color_opponent_t() );
bits32f b_color_opponent = get_color( src, b_color_opponent_t() );
// first, transfer to xyz color space
bits32f normalized_y = ( luminance + 16.f ) / 116.f;
bits32f normalized_x = ( a_color_opponent / 500.f ) + normalized_y;
bits32f normalized_z = normalized_y - ( b_color_opponent / 200.f );
if( pow( normalized_y, 3.f ) > 0.008856f )
{
normalized_y = pow( normalized_y, 3.f );
}
else
{
normalized_y = ( normalized_y - 16.f / 116.f ) / 7.787f;
}
if( pow( normalized_x, 3.f ) > 0.008856f )
{
normalized_x = pow( normalized_x, 3.f );
}
else
{
normalized_x = ( normalized_x - 16.f / 116.f ) / 7.787f;
}
if( pow( normalized_z, 3.f ) > 0.008856f )
{
normalized_z = pow( normalized_z, 3.f );
}
else
{
normalized_z = ( normalized_z - 16.f / 116.f ) / 7.787f;
}
bits32f reference_x = 95.047f;
bits32f reference_y = 100.000f;
bits32f reference_z = 108.883f;
bits32f x, y, z;
x = reference_x * normalized_x;
y = reference_y * normalized_y;
z = reference_z * normalized_z;
// then, transfer to rgb color space
normalized_x = x / 100.f;
normalized_y = y / 100.f;
normalized_z = z / 100.f;
bits32f result_r = normalized_x * 3.2406f + normalized_y * -1.5372f + normalized_z * -0.4986f;
bits32f result_g = normalized_x * -0.9689f + normalized_y * 1.8758f + normalized_z * 0.0415f;
bits32f result_b = normalized_x * 0.0557f + normalized_y * -0.2040f + normalized_z * 1.0570f;
if( result_r > 0.0031308f )
{
result_r = 1.055f * pow( result_r, 1.f/2.4f ) - 0.055f;
}
else
{
result_r = 12.92f * result_r;
}
if( result_g > 0.0031308f )
{
result_g = 1.055f * pow( result_g, 1.f/2.4f ) - 0.055f;
}
else
{
result_g = 12.92f * result_g;
}
if( result_b > 0.0031308f )
{
result_b = 1.055f * pow( result_b, 1.f/2.4f ) - 0.055f;
}
else
{
result_b = 12.92f * result_b;
}
bits32f red, green, blue;
red = result_r * 255.f;
green = result_g * 255.f;
blue = result_b * 255.f;
get_color(dst,red_t()) =
channel_convert<typename color_element_type<P2, red_t>::type>( red );
get_color(dst,green_t())=
channel_convert<typename color_element_type<P2, green_t>::type>( green );
get_color(dst,blue_t()) =
channel_convert<typename color_element_type<P2, blue_t>::type>( blue );
}
};
} } // namespace boost::gil
#endif // GIL_LAB_H
+173
View File
@@ -0,0 +1,173 @@
// Copyright 2008 Chung-Lin Wen.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
/*************************************************************************************************/
#ifndef GIL_XYZ_H
#define GIL_XYZ_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for CIE XYZ color space
/// \author Chung-Lin Wen \n
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/cast.hpp>
#include <boost/gil/gil_all.hpp>
namespace boost { namespace gil {
/// \addtogroup ColorNameModel
/// \{
namespace xyz_color_space
{
/// \brief x Color Component
struct x_t {};
/// \brief y Color Component
struct y_t {};
/// \brief z Color Component
struct z_t {};
}
/// \}
/// \ingroup ColorSpaceModel
typedef mpl::vector3< xyz_color_space::x_t
, xyz_color_space::y_t
, xyz_color_space::z_t
> xyz_t;
/// \ingroup LayoutModel
typedef layout<xyz_t> xyz_layout_t;
GIL_DEFINE_ALL_TYPEDEFS( 32f, xyz );
/// \ingroup ColorConvert
/// \brief RGB to XYZ
template <>
struct default_color_converter_impl< rgb_t, xyz_t >
{
template <typename P1, typename P2>
void operator()( const P1& src, P2& dst ) const
{
using namespace xyz_color_space;
// only bits32f for xyz is supported
bits32f temp_red = channel_convert<bits32f>( get_color( src, red_t() ));
bits32f temp_green = channel_convert<bits32f>( get_color( src, green_t() ));
bits32f temp_blue = channel_convert<bits32f>( get_color( src, blue_t() ));
bits32f normalized_r = temp_red / 255.f;
bits32f normalized_g = temp_green / 255.f;
bits32f normalized_b = temp_blue / 255.f;
if( normalized_r > 0.04045f )
{
normalized_r = pow((( normalized_r + 0.055f ) / 1.055f ), 2.4f );
}
else
{
normalized_r /= 12.92f;
}
if( normalized_g > 0.04045f )
{
normalized_g = pow((( normalized_g + 0.055f ) / 1.055f ), 2.4f );
}
else
{
normalized_g /= 12.92f;
}
if( normalized_b > 0.04045f )
{
normalized_b = pow((( normalized_b + 0.055f ) / 1.055f ), 2.4f );
}
else
{
normalized_b /= 12.92f;
}
normalized_r *= 100.f;
normalized_g *= 100.f;
normalized_b *= 100.f;
bits32f x, y, z;
x = normalized_r * 0.4124f + normalized_g * 0.3576f + normalized_b * 0.1805f;
y = normalized_r * 0.2126f + normalized_g * 0.7152f + normalized_b * 0.0722f;
z = normalized_r * 0.0193f + normalized_g * 0.1192f + normalized_b * 0.9505f;
get_color( dst, x_t() ) = x;
get_color( dst, y_t() ) = y;
get_color( dst, z_t() ) = z;
}
};
/// \ingroup ColorConvert
/// \brief XYZ to RGB
template <>
struct default_color_converter_impl<xyz_t,rgb_t>
{
template <typename P1, typename P2>
void operator()( const P1& src, P2& dst) const
{
using namespace xyz_color_space;
bits32f x = get_color( src, x_t() );
bits32f y = get_color( src, y_t() );
bits32f z = get_color( src, z_t() );
bits32f normalized_x = x / 100.f;
bits32f normalized_y = y / 100.f;
bits32f normalized_z = z / 100.f;
bits32f result_r = normalized_x * 3.2406f + normalized_y * -1.5372f + normalized_z * -0.4986f;
bits32f result_g = normalized_x * -0.9689f + normalized_y * 1.8758f + normalized_z * 0.0415f;
bits32f result_b = normalized_x * 0.0557f + normalized_y * -0.2040f + normalized_z * 1.0570f;
if ( result_r > 0.0031308f )
{
result_r = 1.055f * pow( result_r, 1.f/2.4f ) - 0.055f;
}
else
{
result_r = 12.92f * result_r;
}
if ( result_g > 0.0031308f )
{
result_g = 1.055f * pow( result_g, 1.f/2.4f ) - 0.055f;
}
else
{
result_g = 12.92f * result_g;
}
if ( result_b > 0.0031308f )
{
result_b = 1.055f * pow( result_b, 1.f/2.4f ) - 0.055f;
}
else
{
result_b = 12.92f * result_b;
}
bits32f red, green, blue;
red = result_r * 255.f;
green = result_g * 255.f;
blue = result_b * 255.f;
get_color(dst,red_t()) =
channel_convert<typename color_element_type<P2, red_t>::type>( red );
get_color(dst,green_t())=
channel_convert<typename color_element_type<P2, green_t>::type>( green );
get_color(dst,blue_t()) =
channel_convert<typename color_element_type<P2, blue_t>::type>( blue );
}
};
} } // namespace boost::gil
#endif // GIL_XYZ_H