WIP. Scale cover art option. Seems to work
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user