diff options
author | Thorsten Behrens <thb@openoffice.org> | 2006-07-06 09:02:07 +0000 |
---|---|---|
committer | Thorsten Behrens <thb@openoffice.org> | 2006-07-06 09:02:07 +0000 |
commit | 8b7ded16f1756beeb1489709a35fbc19d76e42de (patch) | |
tree | 65dc26b293ce107b799882dd3497b42fcbd5065b /basebmp | |
parent | 58254b2673dda4a31fb38ae6765c8ac85e332135 (diff) |
#i65904# Reworked accessor framework, is now a hierarchy of nested functionality; added traits for color, iterator and accessor behaviour; finished missing bitmap formats, slightly changed set of predefined formats; swapped order of xor/palette accessor application for the BitmapDevice, which should yield much more sensible results; added a few tests for the new formats
Diffstat (limited to 'basebmp')
-rw-r--r-- | basebmp/inc/basebmp/accessor.hxx | 60 | ||||
-rw-r--r-- | basebmp/inc/basebmp/accessoradapters.hxx | 577 | ||||
-rw-r--r-- | basebmp/inc/basebmp/accessortraits.hxx | 183 | ||||
-rw-r--r-- | basebmp/inc/basebmp/color.hxx | 7 | ||||
-rw-r--r-- | basebmp/inc/basebmp/colorblendaccessoradapter.hxx | 155 | ||||
-rw-r--r-- | basebmp/inc/basebmp/colormisc.hxx | 32 | ||||
-rw-r--r-- | basebmp/inc/basebmp/colortraits.hxx | 99 | ||||
-rw-r--r-- | basebmp/inc/basebmp/endian.hxx | 65 | ||||
-rw-r--r-- | basebmp/inc/basebmp/iteratortraits.hxx | 63 | ||||
-rw-r--r-- | basebmp/inc/basebmp/metafunctions.hxx | 58 | ||||
-rw-r--r-- | basebmp/inc/basebmp/packedpixeliterator.hxx | 30 | ||||
-rw-r--r-- | basebmp/inc/basebmp/paletteimageaccessor.hxx | 215 | ||||
-rw-r--r-- | basebmp/inc/basebmp/scanlineformats.hxx | 17 | ||||
-rw-r--r-- | basebmp/inc/basebmp/truecolormaskaccessor.hxx | 298 | ||||
-rw-r--r-- | basebmp/source/bitmapdevice.cxx | 814 | ||||
-rw-r--r-- | basebmp/source/debug.cxx | 18 | ||||
-rw-r--r-- | basebmp/test/basictest.cxx | 58 |
17 files changed, 2060 insertions, 689 deletions
diff --git a/basebmp/inc/basebmp/accessor.hxx b/basebmp/inc/basebmp/accessor.hxx index a21edd8280ec..ffbe159e224f 100644 --- a/basebmp/inc/basebmp/accessor.hxx +++ b/basebmp/inc/basebmp/accessor.hxx @@ -4,9 +4,9 @@ * * $RCSfile: accessor.hxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: thb $ $Date: 2006-06-02 08:36:13 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:39 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -41,14 +41,64 @@ namespace basebmp { +/** Standard accessor type + + Accesses the iterator values the standard way (i.e. via + *operator()/operator[]) + */ template<typename ValueType> class StandardAccessor { public: typedef ValueType value_type; + // ------------------------------------------------------- + template< class Iterator > - value_type operator()(Iterator const& i) const { return i.get(); } - value_type operator()(value_type const* i) const { return *i; } + value_type operator()(Iterator const& i) const + { + return *i; + } + + template< class Iterator, class Difference > + value_type operator()(Iterator const& i, Difference const& diff) const + { + return i[diff]; + } + + // ------------------------------------------------------- + + template< typename V, class Iterator > + void set(V const& value, Iterator const& i) const + { + *i = vigra::detail::RequiresExplicitCast<value_type>::cast(value); + } + + template< typename V, class Iterator, class Difference > + void set(V const& value, Iterator const& i, Difference const& diff) const + { + i[diff] = vigra::detail::RequiresExplicitCast<value_type>::cast(value); + } +}; + +//----------------------------------------------------------------------------- + +/** Non-standard accessor type + + Uses getter/setter methods at the given iterator type, to access + the underlying values. + */ +template<typename ValueType> class NonStandardAccessor +{ +public: + typedef ValueType value_type; + + // ------------------------------------------------------- + + template< class Iterator > + value_type operator()(Iterator const& i) const + { + return i.get(); + } template< class Iterator, class Difference > value_type operator()(Iterator const& i, Difference const& diff) const @@ -56,6 +106,8 @@ public: return i.get(diff); } + // ------------------------------------------------------- + template< typename V, class Iterator > void set(V const& value, Iterator const& i) const { diff --git a/basebmp/inc/basebmp/accessoradapters.hxx b/basebmp/inc/basebmp/accessoradapters.hxx index 83e390319e8e..e8586f99181e 100644 --- a/basebmp/inc/basebmp/accessoradapters.hxx +++ b/basebmp/inc/basebmp/accessoradapters.hxx @@ -4,9 +4,9 @@ * * $RCSfile: accessoradapters.hxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: thb $ $Date: 2006-06-28 16:50:18 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:39 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,510 +36,277 @@ #ifndef INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX #define INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX -#include <basebmp/metafunctions.hxx> -#include <basebmp/packedpixeliterator.hxx> -#include <basebmp/paletteimageaccessor.hxx> - #include <vigra/numerictraits.hxx> namespace basebmp { -/** Interpose given accessor's set methods with a binary function, - taking both old and new value. +/** Interpose given accessor's set and get methods with two unary + functors. - All other wrappee methods are inherited as-is. + @tpl WrappedAccessor + Wrapped type must provide the usual get and set accessor methods, + with the usual signatures (see StandardAccessor for a conforming + example). Furthermore, the type must provide a wrapped typedef + value_type */ -template< class WrappedAccessor, typename Functor > class BinarySetterFunctionAccessorAdapter : - public WrappedAccessor +template< class WrappedAccessor, + typename GetterFunctor, + typename SetterFunctor > class UnaryFunctionAccessorAdapter { private: - Functor maFunctor; + // we don't derive from wrapped type, to avoid ambiguities + // regarding templatized getter/setter methods. + WrappedAccessor maAccessor; + GetterFunctor maGetterFunctor; + SetterFunctor maSetterFunctor; public: - BinarySetterFunctionAccessorAdapter() : - WrappedAccessor(), - maFunctor() + typedef typename WrappedAccessor::value_type value_type; + + UnaryFunctionAccessorAdapter() : + maAccessor(), + maGetterFunctor(), + maSetterFunctor() {} - explicit BinarySetterFunctionAccessorAdapter( WrappedAccessor accessor ) : - WrappedAccessor( accessor ), - maFunctor() + template< class T > explicit UnaryFunctionAccessorAdapter( T accessor ) : + maAccessor( accessor ), + maGetterFunctor(), + maSetterFunctor() {} - BinarySetterFunctionAccessorAdapter( WrappedAccessor accessor, - Functor functor ) : - WrappedAccessor( accessor ), - maFunctor( functor ) + template< class T > UnaryFunctionAccessorAdapter( T accessor, + GetterFunctor getterFunctor, + SetterFunctor setterFunctor) : + maAccessor( accessor ), + maGetterFunctor( getterFunctor ), + maSetterFunctor( setterFunctor ) {} + // ------------------------------------------------------- + + WrappedAccessor const& getWrappedAccessor() const { return maAccessor; } + WrappedAccessor& getWrappedAccessor() { return maAccessor; } + + // ------------------------------------------------------- + + template< class Iterator > + value_type operator()(Iterator const& i) const + { + return maGetterFunctor( maAccessor(i) ); + } + + template< class Iterator, class Difference > + value_type operator()(Iterator const& i, Difference const& diff) const + { + return maGetterFunctor( maAccessor(i,diff) ); + } + + // ------------------------------------------------------- + template< typename V, class Iterator > void set(V const& value, Iterator const& i) const { - WrappedAccessor::set( - maFunctor(WrappedAccessor::operator()(i), - vigra::detail::RequiresExplicitCast<typename WrappedAccessor::value_type>::cast(value)), - i ); + maAccessor.set( + maSetterFunctor( + vigra::detail::RequiresExplicitCast<value_type>::cast(value) )); } template< typename V, class Iterator, class Difference > void set(V const& value, Iterator const& i, Difference const& diff) const { - WrappedAccessor::set( - maFunctor(WrappedAccessor::operator()(i,diff), - vigra::detail::RequiresExplicitCast<typename WrappedAccessor::value_type>::cast(value)), - i, - diff ); + maAccessor.set( + maSetterFunctor( + vigra::detail::RequiresExplicitCast<value_type>::cast(value) )); } + }; -/** Read from a CompositeIterator via two given accessors, pipe that - through given functor, and write result to the first iterator +//----------------------------------------------------------------------------- - Note: iterator type is fixed, to facilitate type-safe mask - optimizations (see below). +/** Interpose given accessor's set methods with a binary function, + taking both old and new value. - Passed iterator must fulfill the CompositeIterator concept + The wrappee's getter methods kept as-is. - Set functionality is unimplemented + @tpl WrappedAccessor + Wrapped type must provide the usual get and set accessor methods, + with the usual signatures (see StandardAccessor for a conforming + example). Furthermore, the type must provide a wrapped typedef + value_type */ -template< class WrappedAccessor1, - class WrappedAccessor2, - typename Iterator1, - typename Iterator2, - typename Functor > class BinaryInputAccessorAdapter +template< class WrappedAccessor, + typename SetterFunctor > class BinarySetterFunctionAccessorAdapter { private: - WrappedAccessor1 ma1stAccessor; - WrappedAccessor2 ma2ndAccessor; - Functor maFunctor; + WrappedAccessor maAccessor; + SetterFunctor maFunctor; public: - typedef typename WrappedAccessor1::value_type value_type; + typedef typename WrappedAccessor::value_type value_type; - BinaryInputAccessorAdapter() : - ma1stAccessor(), - ma2ndAccessor(), + BinarySetterFunctionAccessorAdapter() : + maAccessor(), maFunctor() {} - explicit BinaryInputAccessorAdapter( WrappedAccessor1 accessor1 ) : - ma1stAccessor( accessor1 ), - ma2ndAccessor(), + template< class T > explicit BinarySetterFunctionAccessorAdapter( T accessor ) : + maAccessor( accessor ), maFunctor() {} - BinaryInputAccessorAdapter( WrappedAccessor1 accessor1, - WrappedAccessor2 accessor2 ) : - ma1stAccessor( accessor1 ), - ma2ndAccessor( accessor2 ), - maFunctor() + template< class T > BinarySetterFunctionAccessorAdapter( T accessor, + SetterFunctor functor ) : + maAccessor( accessor ), + maFunctor( functor ) {} - BinaryInputAccessorAdapter( WrappedAccessor1 accessor1, - WrappedAccessor2 accessor2, - Functor func ) : - ma1stAccessor( accessor1 ), - ma2ndAccessor( accessor2 ), - maFunctor( func ) - {} + // ------------------------------------------------------- + + WrappedAccessor const& getWrappedAccessor() const { return maAccessor; } + WrappedAccessor& getWrappedAccessor() { return maAccessor; } + + // ------------------------------------------------------- - template< typename Iterator > value_type operator()(Iterator const& i) const + template< class Iterator > + value_type operator()(Iterator const& i) const { - return maFunctor(ma1stAccessor(i.first()), - ma2ndAccessor(i.second())); + return maAccessor(i); } - template< typename Iterator, typename Difference > + + template< class Iterator, class Difference > value_type operator()(Iterator const& i, Difference const& diff) const { - return maFunctor(ma1stAccessor(i.first(),diff), - ma2ndAccessor(i.second(),diff)); + return maAccessor(i,diff); + } + + // ------------------------------------------------------- + + template< typename V, class Iterator > + void set(V const& value, Iterator const& i) const + { + maAccessor.set( + maFunctor(maAccessor(i), + vigra::detail::RequiresExplicitCast<value_type>::cast(value)), + i ); } + + template< typename V, class Iterator, class Difference > + void set(V const& value, Iterator const& i, Difference const& diff) const + { + maAccessor.set( + maFunctor(maAccessor(i,diff), + vigra::detail::RequiresExplicitCast<value_type>::cast(value)), + i, + diff ); + } + }; +//----------------------------------------------------------------------------- + /** Write through a CompositeIterator's first wrapped iterator, by piping the first wrapped iterator value, the second iterator value, and the specified new value through a ternary function. - Passed iterator must fulfill the CompositeIterator concept + Passed iterator must fulfill the CompositeIterator concept. Note + that the getter/setter methods are not templatized regarding the + iterator type, to make the mask calculation optimization below + safe (see the maskedAccessor template metafunction below) - All other wrappee methods are inherited as-is. + @tpl WrappedAccessor1 + Wrapped type must provide the usual get and set accessor methods, + with the usual signatures (see StandardAccessor for a conforming + example). Furthermore, the type must provide a wrapped typedef + value_type */ template< class WrappedAccessor1, class WrappedAccessor2, - typename Iterator1, - typename Iterator2, - typename Functor > class TernarySetterFunctionAccessorAdapter : public WrappedAccessor1 + typename Functor > class TernarySetterFunctionAccessorAdapter { private: + WrappedAccessor1 ma1stAccessor; WrappedAccessor2 ma2ndAccessor; Functor maFunctor; public: + typedef typename WrappedAccessor1::value_type value_type; + TernarySetterFunctionAccessorAdapter() : - WrappedAccessor1(), + ma1stAccessor(), ma2ndAccessor(), maFunctor() {} - explicit TernarySetterFunctionAccessorAdapter( WrappedAccessor1 accessor1 ) : - WrappedAccessor1( accessor1 ), + template< class T > explicit TernarySetterFunctionAccessorAdapter( T accessor ) : + ma1stAccessor( accessor ), ma2ndAccessor(), maFunctor() {} - TernarySetterFunctionAccessorAdapter( WrappedAccessor1 accessor1, - WrappedAccessor2 accessor2 ) : - WrappedAccessor1( accessor1 ), + template< class T1, class T2 > + TernarySetterFunctionAccessorAdapter( T1 accessor1, + T2 accessor2 ) : + ma1stAccessor( accessor1 ), ma2ndAccessor( accessor2 ), maFunctor() {} - TernarySetterFunctionAccessorAdapter( WrappedAccessor1 accessor1, - WrappedAccessor2 accessor2, - Functor func ) : - WrappedAccessor1( accessor1 ), + template< class T1, class T2 > + TernarySetterFunctionAccessorAdapter( T1 accessor1, + T2 accessor2, + Functor func ) : + ma1stAccessor( accessor1 ), ma2ndAccessor( accessor2 ), maFunctor( func ) {} - template< typename V, typename Iterator > - void set(V const& value, Iterator const& i) const - { - WrappedAccessor1::set( - maFunctor(WrappedAccessor1::operator()(i.first()), - ma2ndAccessor(i.second()), - vigra::detail::RequiresExplicitCast<typename WrappedAccessor1::value_type>::cast(value)), - i.first() ); - } - - template< typename V, typename Iterator, typename Difference > - void set(V const& value, Iterator const& i, Difference const& diff) const - { - WrappedAccessor1::set( - maFunctor(WrappedAccessor1::operator()(i.first(),diff), - ma2ndAccessor(i.second(),diff), - vigra::detail::RequiresExplicitCast<typename WrappedAccessor1::value_type>::cast(value)), - i.first(), - diff ); - } -}; - - -/// Traits template, to determine alpha blending between two values -template< typename ValueType, typename AlphaType > struct BlendFunctor -{ - ValueType operator()( AlphaType alpha, - ValueType v1, - ValueType v2 ) const - { - const typename vigra::NumericTraits<AlphaType>::RealPromote fAlpha( - vigra::NumericTraits<AlphaType>::toRealPromote(alpha)); - return (vigra::NumericTraits<AlphaType>::one()-fAlpha)*v1 + fAlpha*v2; - } -}; - -template< typename ValueType, typename AlphaType > struct IntegerBlendFunctor -{ - ValueType operator()( AlphaType alpha, - ValueType v1, - ValueType v2 ) const - { - return (vigra::NumericTraits<AlphaType>::toPromote( - vigra::NumericTraits<AlphaType>::max()-alpha)*v1 + alpha*v2) / - vigra::NumericTraits<AlphaType>::max(); - } -}; - -/// Metafunction to select blend functor from value and alpha type -template< typename ValueType, typename AlphaType > struct blendFunctorSelector : public - ifScalarIntegral< AlphaType, - IntegerBlendFunctor< ValueType, AlphaType >, - BlendFunctor< ValueType, AlphaType > > -{ -}; - -/** Accessor adapter that blends input value against fixed color value - - Used to blend an alpha mask 'through' a fixed color value into the - destination. - - The getter functors return a constant value (usually the zero of - the value type, this preserves the original destination content - when blitting through a mask) - there really isn't no sensible - default behaviour for these methods. - */ -template< class WrappedAccessor, - typename AlphaType > class ConstantColorBlendSetterAccessorAdapter -{ -public: - typedef AlphaType alpha_type; - typedef AlphaType value_type; - typedef typename WrappedAccessor::value_type color_type; - -private: - typename blendFunctorSelector< color_type, alpha_type >::type maFunctor; - WrappedAccessor maWrappee; - color_type maBlendColor; - value_type maGetterValue; - - // TODO(Q2): Merge with - // BinarySetterFunctionAccessorAdapter. Problem there: how to - // generate the functor, needs construction with accessor and - // fixed color - -public: - ConstantColorBlendSetterAccessorAdapter() : - maFunctor(), - maWrappee(), - maBlendColor(), - maGetterValue() - {} - - explicit ConstantColorBlendSetterAccessorAdapter( WrappedAccessor acc ) : - maFunctor(), - maWrappee(acc), - maBlendColor(), - maGetterValue() - {} + // ------------------------------------------------------- - ConstantColorBlendSetterAccessorAdapter( WrappedAccessor acc, - color_type col ) : - maFunctor(), - maWrappee(acc), - maBlendColor(col), - maGetterValue() - {} + WrappedAccessor1 const& get1stWrappedAccessor() const { return ma1stAccessor; } + WrappedAccessor1& get1stWrappedAccessor() { return ma1stAccessor; } - ConstantColorBlendSetterAccessorAdapter( WrappedAccessor acc, - color_type col, - value_type val ) : - maFunctor(), - maWrappee(acc), - maBlendColor(col), - maGetterValue(val) - {} + WrappedAccessor2 const& get2ndWrappedAccessor() const { return ma2ndAccessor; } + WrappedAccessor2& get2ndWrappedAccessor() { return ma2ndAccessor; } - void setColor( color_type col ) { maBlendColor=col; } - color_type getColor() { return maBlendColor; } - void setGetterValue( value_type val ) { maGetterValue=val; } - value_type getGetterValue() { return maGetterValue; } + // ------------------------------------------------------- - /// @return constant value, regardless of iterator content - template< typename IteratorType > value_type operator()(IteratorType const& ) const - { - return maGetterValue; - } - /// @return constant value, regardless of iterator content - template< typename IteratorType, class Difference > - value_type operator()(IteratorType const& , Difference const& ) const + template< class Iterator > + value_type operator()(Iterator const& i) const { - return maGetterValue; + return ma1stAccessor(i); } - template< typename V, typename IteratorType > - void set(V const& value, IteratorType const& i) const - { - maWrappee.set( - maFunctor( - vigra::detail::RequiresExplicitCast<alpha_type>::cast(value), - maWrappee(i), - maBlendColor), - i ); - } - - template< typename V, typename IteratorType, class Difference > - void set(V const& value, IteratorType const& i, Difference const& diff) const - { - maWrappee.set( - maFunctor( - vigra::detail::RequiresExplicitCast<alpha_type>::cast(value), - maWrappee(i,diff), - maBlendColor), - i, - diff ); - } -}; - - -// Some common accessor wrappers -// ------------------------------------------------------------ - -// XOR -template< typename T > struct XorFunctor -{ - T operator()( T v1, T v2 ) const { return v1 ^ v2; } -}; -template< class WrappedAccessor > struct xorAccessor -{ - typedef BinarySetterFunctionAccessorAdapter< WrappedAccessor, - XorFunctor< typename WrappedAccessor::value_type > > - type; -}; - - -// Masking functors for binary input -//-------------------------------------------------------- - -template< typename T, typename M > struct GenericInputMaskFunctor -{ - /** Mask v with state of m - - @return v, if m != 0, and vigra::NumericTraits<T>::zero - otherwise. - */ - T operator()( T v, M m ) const - { - return m == 0 ? vigra::NumericTraits<T>::zero : v; - } -}; - -template< typename T, typename M > struct IntegerInputMaskFunctor -{ - /** Mask v with state of m - - @return v, if m != 0, and vigra::NumericTraits<T>::zero - otherwise. - */ - T operator()( T v, M m ) const - { - typedef typename make_unsigned<T>::type unsigned_T; - - // mask will be 0, iff m == 0, and 1 otherwise - const unsigned_T mask( - unsigned_cast<T>(m | -m) >> (sizeof(unsigned_T)*8 - 1) ); - return v*mask; - } -}; - -template< typename T, typename M > struct FastIntegerInputMaskFunctor -{ - T operator()( T v, M m ) const - { - return v*m; - } -}; - - -// Masking functors for TernarySetterFunctionAccessorAdapter -//----------------------------------------------------------- - -template< typename T, typename M > struct GenericOutputMaskFunctor -{ - /// Ternary mask operation - selects v1 for m == 0, v2 otherwise - T operator()( T v1, M m, T v2 ) const + template< class Iterator, class Difference > + value_type operator()(Iterator const& i, Difference const& diff) const { - return m == 0 ? v1 : v2; + return ma1stAccessor(i,diff); } -}; -template< typename T, typename M > struct IntegerOutputMaskFunctor -{ - /** Mask v with state of m + // ------------------------------------------------------- - @return v2, if m != 0, v1 otherwise. - */ - T operator()( T v1, M m, T v2 ) const + template< typename V, class Iterator > + void set(V const& value, Iterator const& i) const { - typedef typename make_unsigned<T>::type unsigned_T; - - // mask will be 0, iff m == 0, and 1 otherwise - const T mask( unsigned_cast<T>(m | -m) >> (sizeof(unsigned_T)*8 - 1) ); - return v1*(M)(1-mask) + v2*mask; + ma1stAccessor.set( + maFunctor(ma1stAccessor(i.first()), + ma2ndAccessor(i.second()), + vigra::detail::RequiresExplicitCast<value_type>::cast(value)), + i.first() ); } -}; -template< typename T, typename M > struct FastIntegerOutputMaskFunctor -{ - T operator()( T v1, M m, T v2 ) const + template< typename V, class Iterator, class Difference > + void set(V const& value, Iterator const& i, Difference const& diff) const { - return v1*(M)(1-m) + v2*m; + ma1stAccessor.set( + maFunctor(ma1stAccessor(i.first(), diff), + ma2ndAccessor(i.second(),diff), + vigra::detail::RequiresExplicitCast<value_type>::cast(value)), + i.first(), + diff ); } -}; - -struct FastMask; -struct NoFastMask; -/// Metafunction to select output mask functor from iterator and mask value type -template< typename T, typename M, typename DUMMY > struct outputMaskFunctorSelector : public - ifBothScalarIntegral< T, M, - IntegerOutputMaskFunctor< T, M >, - GenericOutputMaskFunctor< T, M > > -{ -}; -template< typename T, typename M > struct outputMaskFunctorSelector< T, M, FastMask > : public - ifBothScalarIntegral< T, M, - FastIntegerOutputMaskFunctor< T, M >, - GenericOutputMaskFunctor< T, M > > -{ -}; - -// Chosen function crucially depends on iterator - we can choose the -// faster direkt masking for 1bpp packed pixel iterators -template< class WrappedAccessor, - class MaskAccessor, - class Iterator, - class MaskIterator > struct maskedAccessor -{ - typedef TernarySetterFunctionAccessorAdapter< - WrappedAccessor, - MaskAccessor, - Iterator, - MaskIterator, - typename outputMaskFunctorSelector< - typename WrappedAccessor::value_type, - typename MaskAccessor::value_type, - NoFastMask>::type > - type; -}; -// partial specialization, to use fast 1bpp mask function for -// corresponding iterator type -template< class WrappedAccessor, - class MaskAccessor, - class Iterator > struct maskedAccessor< WrappedAccessor, - MaskAccessor, - Iterator, - PackedPixelIterator< typename MaskAccessor::value_type, - 1, - true > > -{ - typedef TernarySetterFunctionAccessorAdapter< - WrappedAccessor, - MaskAccessor, - Iterator, - PackedPixelIterator< - typename MaskAccessor::value_type, - 1, - true >, - typename outputMaskFunctorSelector< - typename WrappedAccessor::value_type, - typename MaskAccessor::value_type, - FastMask>::type > - type; -}; - -template< class WrappedAccessor, - class MaskAccessor, - class Iterator > struct maskedAccessor< WrappedAccessor, - MaskAccessor, - Iterator, - PackedPixelIterator< typename MaskAccessor::value_type, - 1, - false > > -{ - typedef TernarySetterFunctionAccessorAdapter< - WrappedAccessor, - MaskAccessor, - Iterator, - PackedPixelIterator< - typename MaskAccessor::value_type, - 1, - false >, - typename outputMaskFunctorSelector< - typename WrappedAccessor::value_type, - typename MaskAccessor::value_type, - FastMask>::type > - type; }; } // namespace basebmp diff --git a/basebmp/inc/basebmp/accessortraits.hxx b/basebmp/inc/basebmp/accessortraits.hxx new file mode 100644 index 000000000000..581337acfcc0 --- /dev/null +++ b/basebmp/inc/basebmp/accessortraits.hxx @@ -0,0 +1,183 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: accessortraits.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2006-07-06 10:02:07 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_BASEBMP_ACCESSORTRAITS_HXX +#define INCLUDED_BASEBMP_ACCESSORTRAITS_HXX + +#include <osl/diagnose.h> +#include <basebmp/accessoradapters.hxx> + +#include <functional> + +namespace basebmp +{ + +// Some common accessor functors +// ------------------------------------------------------------ + + +//----------------------------------------------------------------------------- + +// XOR +template< typename T > struct XorFunctor +{ + T operator()( T v1, T v2 ) const { return v1 ^ v2; } +}; + +//----------------------------------------------------------------------------- + +// Mask +template< typename T, typename M > struct GenericOutputMaskFunctor +{ + /// Ternary mask operation - selects v1 for m == 0, v2 otherwise + T operator()( T v1, M m, T v2 ) const + { + return m == 0 ? v1 : v2; + } +}; + +template< typename T, typename M > struct IntegerOutputMaskFunctor +{ + /** Mask v with state of m + + @return v2, if m != 0, v1 otherwise. + */ + T operator()( T v1, M m, T v2 ) const + { + typedef typename make_unsigned<T>::type unsigned_T; + + // mask will be 0, iff m == 0, and 1 otherwise + const T mask( unsigned_cast<T>(m | -m) >> (sizeof(unsigned_T)*8 - 1) ); + return v1*(M)(1-mask) + v2*mask; + } +}; + +template< typename T, typename M > struct FastIntegerOutputMaskFunctor +{ + /// Specialization, only valid if mask can only attain 0 or 1 + T operator()( T v1, M m, T v2 ) const + { + OSL_ASSERT(m<=1); + + return v1*(M)(1-m) + v2*m; + } +}; + +//----------------------------------------------------------------------------- + +struct FastMask; +struct NoFastMask; + +/// Metafunction to select output mask functor from iterator and mask value type +template< typename T, typename M, typename DUMMY > struct outputMaskFunctorSelector : public + ifBothScalarIntegral< T, M, + IntegerOutputMaskFunctor< T, M >, + GenericOutputMaskFunctor< T, M > > +{ +}; +template< typename T, typename M > struct outputMaskFunctorSelector< T, M, FastMask > : public + ifBothScalarIntegral< T, M, + FastIntegerOutputMaskFunctor< T, M >, + GenericOutputMaskFunctor< T, M > > +{ +}; + +/** Metafunction providing a point of configuration for iterators + capable of employing the fast output mask functor. + + Specialize this metafunction for your case, and pass FastMask to + the outputMaskFunctorSelector. + */ +template< class Accessor, + class MaskAccessor, + class Iterator, + class MaskIterator > struct maskedAccessorSelector +{ + typedef TernarySetterFunctionAccessorAdapter< + Accessor, + MaskAccessor, + typename outputMaskFunctorSelector< + typename Accessor::value_type, + typename MaskAccessor::value_type, + NoFastMask > ::type > + type; +}; + +//----------------------------------------------------------------------------- + +/** Traits template for Accessor + + Provides wrapped types for color lookup, raw pixel access, xor and + mask accessors. + */ +template< class Accessor > struct AccessorTraits +{ + /// value type of described accessor + typedef typename Accessor::value_type value_type; + + /// Retrieve stand-alone color lookup function for given Accessor type + typedef std::project2nd< Accessor, value_type > color_lookup; + + /// Retrieve raw pixel data accessor for given Accessor type + typedef Accessor raw_accessor; + + /// Retrieve wrapped accessor for XOR setter access + typedef BinarySetterFunctionAccessorAdapter< + Accessor, + XorFunctor< value_type > > xor_accessor; + + /** Retrieve masked accessor for given types + + A masked accessor works like a filter, where the mask gates + the accessor's setter methods (if the mask contains a 0 at a + given iterator position, the original value is + preserved. Otherwise, the new value gets set). + + @attention be careful when retrieving a masked accessor for a + set of types, and using it for a different one - there are + partial specializations that take an optimized functor for + certain mask accessors. + */ + template< class MaskAccessor, + class Iterator, + class MaskIterator > struct masked_accessor : + public maskedAccessorSelector< Accessor,MaskAccessor,Iterator,MaskIterator > + {}; + +}; + +} // namespace basebmp + +#endif /* INCLUDED_BASEBMP_ACCESSORTRAITS_HXX */ diff --git a/basebmp/inc/basebmp/color.hxx b/basebmp/inc/basebmp/color.hxx index e41bc250b9a7..e469a68aba4e 100644 --- a/basebmp/inc/basebmp/color.hxx +++ b/basebmp/inc/basebmp/color.hxx @@ -4,9 +4,9 @@ * * $RCSfile: color.hxx,v $ * - * $Revision: 1.10 $ + * $Revision: 1.11 $ * - * last change: $Author: thb $ $Date: 2006-06-30 13:36:14 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:39 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -50,6 +50,9 @@ private: sal_uInt32 mnColor; public: + typedef sal_uInt32 value_type; + typedef sal_uInt8 component_type; + Color() : mnColor(0) {} explicit Color( sal_uInt32 nVal ) : mnColor(nVal) {} Color( sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue ) : diff --git a/basebmp/inc/basebmp/colorblendaccessoradapter.hxx b/basebmp/inc/basebmp/colorblendaccessoradapter.hxx new file mode 100644 index 000000000000..168ee9b2c21a --- /dev/null +++ b/basebmp/inc/basebmp/colorblendaccessoradapter.hxx @@ -0,0 +1,155 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: colorblendaccessoradapter.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2006-07-06 10:02:07 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_BASEBMP_COLORBLENDACCESSORADAPTER_HXX +#define INCLUDED_BASEBMP_COLORBLENDACCESSORADAPTER_HXX + +#include <basebmp/colortraits.hxx> + +namespace basebmp +{ + +/** Accessor adapter that blends input value against fixed color value + + Used to blend an alpha mask 'through' a fixed color value into the + destination. + + The getter functors return a constant value (usually the zero of + the value type, this preserves the original destination content + when blitting through a mask) - there really isn't no sensible + default behaviour for these methods. + */ +template< class WrappedAccessor, + typename AlphaType > class ConstantColorBlendSetterAccessorAdapter +{ +public: + typedef AlphaType alpha_type; + typedef AlphaType value_type; + typedef typename WrappedAccessor::value_type color_type; + +private: + typename ColorTraits< color_type >:: + template blend_functor<alpha_type>::type maFunctor; + WrappedAccessor maWrappee; + color_type maBlendColor; + value_type maGetterValue; + +public: + ConstantColorBlendSetterAccessorAdapter() : + maFunctor(), + maWrappee(), + maBlendColor(), + maGetterValue() + {} + + template< class T > explicit ConstantColorBlendSetterAccessorAdapter( T acc ) : + maFunctor(), + maWrappee(acc), + maBlendColor(), + maGetterValue() + {} + + template< class T > ConstantColorBlendSetterAccessorAdapter( T acc, + color_type col ) : + maFunctor(), + maWrappee(acc), + maBlendColor(col), + maGetterValue() + {} + + template< class T > ConstantColorBlendSetterAccessorAdapter( T acc, + color_type col, + value_type val ) : + maFunctor(), + maWrappee(acc), + maBlendColor(col), + maGetterValue(val) + {} + + // ------------------------------------------------------- + + void setColor( color_type col ) { maBlendColor=col; } + color_type getColor() { return maBlendColor; } + void setGetterValue( value_type val ) { maGetterValue=val; } + value_type getGetterValue() { return maGetterValue; } + + // ------------------------------------------------------- + + WrappedAccessor const& getWrappedAccessor() const { return maWrappee; } + WrappedAccessor& getWrappedAccessor() { return maWrappee; } + + // ------------------------------------------------------- + + /// @return constant value, regardless of iterator content + template< typename IteratorType > value_type operator()(IteratorType const& ) const + { + return maGetterValue; + } + /// @return constant value, regardless of iterator content + template< typename IteratorType, class Difference > + value_type operator()(IteratorType const& , Difference const& ) const + { + return maGetterValue; + } + + // ------------------------------------------------------- + + template< typename V, typename IteratorType > + void set(V const& value, IteratorType const& i) const + { + maWrappee.set( + maFunctor( + vigra::detail::RequiresExplicitCast<alpha_type>::cast(value), + maWrappee(i), + maBlendColor), + i ); + } + + template< typename V, typename IteratorType, class Difference > + void set(V const& value, IteratorType const& i, Difference const& diff) const + { + maWrappee.set( + maFunctor( + vigra::detail::RequiresExplicitCast<alpha_type>::cast(value), + maWrappee(i,diff), + maBlendColor), + i, + diff ); + } +}; + +} // namespace basebmp + +#endif /* INCLUDED_BASEBMP_COLORBLENDACCESSORADAPTER_HXX */ diff --git a/basebmp/inc/basebmp/colormisc.hxx b/basebmp/inc/basebmp/colormisc.hxx index 62ad4a971e41..dbb61900cdb9 100644 --- a/basebmp/inc/basebmp/colormisc.hxx +++ b/basebmp/inc/basebmp/colormisc.hxx @@ -4,9 +4,9 @@ * * $RCSfile: colormisc.hxx,v $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: thb $ $Date: 2006-06-30 13:36:14 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:39 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,6 +36,7 @@ #ifndef INCLUDED_BASEBMP_COLORMISC_HXX #define INCLUDED_BASEBMP_COLORMISC_HXX +#include <osl/diagnose.h> #include <basebmp/color.hxx> #include <basebmp/accessoradapters.hxx> #include <vigra/mathutil.hxx> @@ -52,6 +53,8 @@ struct ColorBitmaskOutputMaskFunctor { Color operator()( Color v1, sal_uInt8 m, Color v2 ) const { + OSL_ASSERT(m<=1); + return Color(v1.toInt32()*(sal_uInt8)(1-m) + v2.toInt32()*m); } }; @@ -81,8 +84,29 @@ struct ColorBlendFunctor } }; -/// Specialized metafunction to select blend functor for Color value types -template<> struct blendFunctorSelector<Color, sal_uInt8> +//----------------------------------------------------------------------------- + +template<> struct ColorTraits< Color > +{ + /// @return number of color channels + static int numChannels() { return 3; } + + /// Type of a color component (i.e. the type of an individual channel) + typedef sal_uInt8 component_type; + + /// Metafunction to select blend functor from color and alpha type + template< typename AlphaType > struct blend_functor; + + /// Calculate normalized distance between color c1 and c2 + static double distance( const Color& c1, + const Color& c2 ) + { + return (c1 - c2).magnitude(); + } +}; + +/// Only defined for 8 bit alpha, currently +template<> template<> struct ColorTraits< Color >::blend_functor< sal_uInt8 > { typedef ColorBlendFunctor type; }; diff --git a/basebmp/inc/basebmp/colortraits.hxx b/basebmp/inc/basebmp/colortraits.hxx new file mode 100644 index 000000000000..21706a9a72de --- /dev/null +++ b/basebmp/inc/basebmp/colortraits.hxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: colortraits.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2006-07-06 10:00:40 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_BASEBMP_COLORTRAITS_HXX +#define INCLUDED_BASEBMP_COLORTRAITS_HXX + +#include <basebmp/accessoradapters.hxx> +#include <basebmp/colortraits.hxx> + +#include <vigra/mathutil.hxx> + +namespace basebmp +{ + +/// Functor template, to calculate alpha blending between two values. Float case. +template< typename ValueType, typename AlphaType > struct BlendFunctor +{ + ValueType operator()( AlphaType alpha, + ValueType v1, + ValueType v2 ) const + { + const typename vigra::NumericTraits<AlphaType>::RealPromote fAlpha( + vigra::NumericTraits<AlphaType>::toRealPromote(alpha)); + return (vigra::NumericTraits<AlphaType>::one()-fAlpha)*v1 + fAlpha*v2; + } +}; + +/// Functor template, to calculate alpha blending between two values. Integer case. +template< typename ValueType, typename AlphaType > struct IntegerBlendFunctor +{ + ValueType operator()( AlphaType alpha, + ValueType v1, + ValueType v2 ) const + { + return (vigra::NumericTraits<AlphaType>::toPromote( + vigra::NumericTraits<AlphaType>::max()-alpha)*v1 + alpha*v2) / + vigra::NumericTraits<AlphaType>::max(); + } +}; + +//----------------------------------------------------------------------------- + +template< typename ColorType > struct ColorTraits +{ + /// Metafunction to select blend functor from color and alpha type + template< typename AlphaType > struct blend_functor : public + ifScalarIntegral< AlphaType, + IntegerBlendFunctor< ColorType, AlphaType >, + BlendFunctor< ColorType, AlphaType > > {}; + + /// @return number of color channels + static int numChannels() { return 1; } + + /// Type of a color component (i.e. the type of an individual channel) + typedef ColorType component_type; + + /// Calculate normalized distance between color c1 and c2 + static vigra::NormTraits<ColorType> distance( ColorType c1, + ColorType c2 ) + { + return vigra::norm(c1 - c2); + } +}; + +} // namespace basebmp + +#endif /* INCLUDED_BASEBMP_COLORTRAITS_HXX */ diff --git a/basebmp/inc/basebmp/endian.hxx b/basebmp/inc/basebmp/endian.hxx new file mode 100644 index 000000000000..427c09528466 --- /dev/null +++ b/basebmp/inc/basebmp/endian.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: endian.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2006-07-06 10:00:40 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_BASEBMP_ENDIAN_HXX +#define INCLUDED_BASEBMP_ENDIAN_HXX + +#include <osl/endian.h> + +namespace basebmp +{ + +/// Swap the order of bytes for the given POD type +template< typename T > inline T byteSwap( T ); + +#define BASEBMP_BYTE_SWAP(Type,SwapFunc) \ + template<> inline Type byteSwap<Type>( Type v ) \ + { \ + return SwapFunc(v); \ + } + +// byteSwap<T> shall fail for any type T not in the list below +BASEBMP_BYTE_SWAP(sal_Int8,) +BASEBMP_BYTE_SWAP(sal_uInt8,) +BASEBMP_BYTE_SWAP(sal_Int16,OSL_SWAPWORD) +BASEBMP_BYTE_SWAP(sal_uInt16,OSL_SWAPWORD) +BASEBMP_BYTE_SWAP(sal_Int32,OSL_SWAPDWORD) +BASEBMP_BYTE_SWAP(sal_uInt32,OSL_SWAPDWORD) + +#undef BASEBMP_BYTE_SWAP + +} // namespace basebmp + +#endif /* INCLUDED_BASEBMP_ENDIAN_HXX */ diff --git a/basebmp/inc/basebmp/iteratortraits.hxx b/basebmp/inc/basebmp/iteratortraits.hxx new file mode 100644 index 000000000000..c3dbd091c8da --- /dev/null +++ b/basebmp/inc/basebmp/iteratortraits.hxx @@ -0,0 +1,63 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: iteratortraits.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2006-07-06 10:00:40 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_BASEBMP_ITERATORTRAITS_HXX +#define INCLUDED_BASEBMP_ITERATORTRAITS_HXX + +#include <basebmp/accessor.hxx> +#include <basebmp/nonstandarditerator.hxx> + +namespace basebmp +{ + +template< class Iterator > struct IteratorTraits +{ + /// VigraTrueType, if iterator does not provide *operator()/operator[] methods + typedef typename vigra::IsDerivedFrom<Iterator,NonStandardIterator>::result + isNonStandardIterator; + + /// Retrieve default accessor for this iterator (and given value type) + template< typename ValueType > struct defaultAccessor : public + // select according to non-standardness of iterator type + vigra::If< isNonStandardIterator, + NonStandardAccessor< ValueType >, + StandardAccessor< ValueType > > + {}; + +}; + +} // namespace basebmp + +#endif /* INCLUDED_BASEBMP_ITERATORTRAITS_HXX */ diff --git a/basebmp/inc/basebmp/metafunctions.hxx b/basebmp/inc/basebmp/metafunctions.hxx index 0f15a5346795..42e887bd9cbe 100644 --- a/basebmp/inc/basebmp/metafunctions.hxx +++ b/basebmp/inc/basebmp/metafunctions.hxx @@ -4,9 +4,9 @@ * * $RCSfile: metafunctions.hxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:40 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,6 +36,7 @@ #ifndef INCLUDED_BASEBMP_METAFUNCTIONS_HXX #define INCLUDED_BASEBMP_METAFUNCTIONS_HXX +#include <boost/mpl/integral_c.hpp> #include <vigra/metaprogramming.hxx> #include <vigra/numerictraits.hxx> @@ -44,7 +45,9 @@ namespace basebmp // TODO(Q3): move to generic place (o3tl?) -/// template meta function: add const qualifier, if given 2nd type has it +/** template meta function: add const qualifier to 2nd type, if given + 1st type has it +*/ template<typename A, typename B> struct clone_const { typedef B type; @@ -54,6 +57,18 @@ template<typename A, typename B> struct clone_const<const A,B> typedef const B type; }; +/** template meta function: add const qualifier to plain type (if not + already there) + */ +template <typename T> struct add_const +{ + typedef const T type; +}; +template <typename T> struct add_const<const T> +{ + typedef const T type; +}; + /// template meta function: remove const qualifier from plain type template <typename T> struct remove_const { @@ -64,6 +79,8 @@ template <typename T> struct remove_const<const T> typedef T type; }; +//-------------------------------------------------------------- + /** template meta function: ensure that given integer type is unsigned If given integer type is already unsigned, return as-is - @@ -93,6 +110,8 @@ template< typename T > inline typename make_unsigned<T>::type unsigned_cast( T v return static_cast< typename make_unsigned<T>::type >(value); } +//-------------------------------------------------------------- + /// returns true, if given number is strictly less than 0 template< typename T > inline bool is_negative( T x ) { @@ -106,6 +125,8 @@ inline bool is_negative( int x ) return static_cast<unsigned int>(x) >> (sizeof(int)*8-1); } +//-------------------------------------------------------------- + /// Results in VigraTrueType, if T is of integer type and scalar template< typename T, typename trueCase, typename falseCase > struct ifScalarIntegral @@ -148,6 +169,37 @@ struct ifBothScalarIntegral falseCase >::type type; }; +//-------------------------------------------------------------- + +/// Count number of trailing zeros +template< int val > struct numberOfTrailingZeros +{ + enum { next = val >> 1 }; + enum { value = vigra::IfBool< (val & 1) == 0, + numberOfTrailingZeros<next>, + boost::mpl::integral_c< int,-1 > > ::type::value + 1 }; +}; + +template<> struct numberOfTrailingZeros<0> +{ + enum { value = 0 }; +}; + +//-------------------------------------------------------------- + +/// Count number of one bits +template< int val > struct bitcount +{ + enum { next = val >> 1 }; + enum { value = bitcount<next>::value + (val & 1) }; +}; + +template<> struct bitcount<0> +{ + enum { value = 0 }; +}; + + } // namespace basebmp #endif /* INCLUDED_BASEBMP_METAFUNCTIONS_HXX */ diff --git a/basebmp/inc/basebmp/packedpixeliterator.hxx b/basebmp/inc/basebmp/packedpixeliterator.hxx index c9824b6ed1c0..3d3a0f2f3784 100644 --- a/basebmp/inc/basebmp/packedpixeliterator.hxx +++ b/basebmp/inc/basebmp/packedpixeliterator.hxx @@ -4,9 +4,9 @@ * * $RCSfile: packedpixeliterator.hxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:40 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -39,6 +39,7 @@ #include <basebmp/metafunctions.hxx> #include <basebmp/stridedarrayiterator.hxx> #include <basebmp/nonstandarditerator.hxx> +#include <basebmp/accessortraits.hxx> #include <boost/static_assert.hpp> #include <vigra/metaprogramming.hxx> @@ -651,6 +652,31 @@ public: } }; +//----------------------------------------------------------------------------- + +// partial specialization for the accessor traits masked_accessor +// selector metafunction - can employ fast mask functor for the 1bpp +// case. +template< class Accessor, + class MaskAccessor, + class Iterator, + bool MsbFirst > struct maskedAccessorSelector< Accessor, + MaskAccessor, + Iterator, + PackedPixelIterator< typename MaskAccessor::value_type, + 1, + MsbFirst > > +{ + typedef TernarySetterFunctionAccessorAdapter< + Accessor, + MaskAccessor, + typename outputMaskFunctorSelector< + typename Accessor::value_type, + typename MaskAccessor::value_type, + FastMask>::type > + type; +}; + } // namespace basebmp #endif /* INCLUDED_BASEBMP_PACKEDPIXELITERATOR_HXX */ diff --git a/basebmp/inc/basebmp/paletteimageaccessor.hxx b/basebmp/inc/basebmp/paletteimageaccessor.hxx index ccc97c25b1fa..84039879ed55 100644 --- a/basebmp/inc/basebmp/paletteimageaccessor.hxx +++ b/basebmp/inc/basebmp/paletteimageaccessor.hxx @@ -4,9 +4,9 @@ * * $RCSfile: paletteimageaccessor.hxx,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:40 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,11 +36,11 @@ #ifndef INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX #define INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX -#include <basebmp/metafunctions.hxx> -#include <basebmp/accessor.hxx> +#include <basebmp/colortraits.hxx> +#include <basebmp/accessortraits.hxx> #include <vigra/numerictraits.hxx> -#include <vigra/mathutil.hxx> +#include <vigra/metaprogramming.hxx> #include <algorithm> #include <functional> @@ -48,133 +48,131 @@ namespace basebmp { -/** Access (possibly packed-pixel) data via palette indirection +/** Access pixel data via palette indirection + + @tpl Accessor + Raw accessor, to be used to actually access the pixel values + + @tpl ColorType + The color value type to use - e.g. the palette is an array of that + type */ -template< typename Valuetype, typename Datatype > class PaletteImageAccessor +template< class Accessor, typename ColorType > class PaletteImageAccessor { public: - typedef Valuetype value_type; - typedef Datatype data_type; - typedef typename remove_const<data_type>::type count_type; - + typedef typename Accessor::value_type data_type; + typedef ColorType value_type; +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +// making all members public, if no member template friends private: - const value_type* palette; - count_type num_entries; + template<class A, typename C> friend class PaletteImageAccessor; +#endif - double norm( value_type const& rLHS, - value_type const& rRHS ) const - { - return (rRHS - rLHS).magnitude(); - } + Accessor maAccessor; + const value_type* mpPalette; + std::size_t mnNumEntries; + +public: + PaletteImageAccessor() : + maAccessor(), + mpPalette(0), + mnNumEntries(0) + {} + + template< class A > explicit + PaletteImageAccessor( PaletteImageAccessor<A,ColorType> const& rSrc ) : + maAccessor( rSrc.maAccessor ), + mpPalette( rSrc.mpPalette ), + mnNumEntries( rSrc.mnNumEntries ) + {} + + PaletteImageAccessor( const value_type* pPalette, + std::size_t numEntries ) : + maAccessor(), + mpPalette(pPalette), + mnNumEntries(numEntries) + {} + + template< class T > PaletteImageAccessor( T accessor, + const value_type* pPalette, + std::size_t numEntries ) : + maAccessor(accessor), + mpPalette(pPalette), + mnNumEntries(numEntries) + {} + + // ------------------------------------------------------- - data_type find_best_match(value_type const& v) const + Accessor const& getWrappedAccessor() const { return maAccessor; } + Accessor& getWrappedAccessor() { return maAccessor; } + + // ------------------------------------------------------- + + data_type lookup(value_type const& v) const { // TODO(P3): use table-based/octree approach here! const value_type* best_entry; - const value_type* palette_end( palette+num_entries ); - if( (best_entry=std::find( palette, palette_end, v)) != palette_end ) - return best_entry-palette; - - // TODO(F3): HACK. Need palette traits, and an error function - // here. We blatantly assume value_type is a normed linear - // space. - const value_type* curr_entry( palette ); + const value_type* palette_end( mpPalette+mnNumEntries ); + if( (best_entry=std::find( mpPalette, palette_end, v)) != palette_end ) + return best_entry-mpPalette; + + const value_type* curr_entry( mpPalette ); best_entry = curr_entry; while( curr_entry != palette_end ) { - if( norm(*curr_entry,*best_entry) > norm(*curr_entry,v) ) + if( ColorTraits<value_type>::distance(*curr_entry, + *best_entry) + > ColorTraits<value_type>::distance(*curr_entry, + v) ) + { best_entry = curr_entry; + } ++curr_entry; } - return best_entry-palette; + return best_entry-mpPalette; } - value_type toCol( value_type const& rCol ) const - { - return rCol; - } - -public: - PaletteImageAccessor() : - palette(0), - num_entries(0) - {} - - PaletteImageAccessor( const value_type* pPalette, - data_type numEntries ) : - palette(pPalette), - num_entries(numEntries) - {} - - data_type lookup(value_type const& v) const { return find_best_match(v); } + // ------------------------------------------------------- template< class Iterator > - value_type operator()(Iterator const& i) const { return toCol(palette[i.get()]); } - value_type operator()(data_type const* i) const { return toCol(palette[*i]); } + value_type operator()(Iterator const& i) const + { + return mpPalette[ maAccessor(i) ]; + } template< class Iterator, class Difference > value_type operator()(Iterator const& i, Difference const& diff) const { - return toCol(palette[i.get(diff)]); + return mpPalette[ maAccessor(i,diff) ]; } + // ------------------------------------------------------- + template< typename V, class Iterator > void set(V const& value, Iterator const& i) const { - i.set( - find_best_match( - vigra::detail::RequiresExplicitCast<value_type>::cast(value) )); + maAccessor.set( + lookup( + vigra::detail::RequiresExplicitCast<value_type>::cast(value) ), + i ); } template< typename V, class Iterator, class Difference > void set(V const& value, Iterator const& i, Difference const& diff) const { - i.set( - find_best_match( - vigra::detail::RequiresExplicitCast<value_type>::cast(value)), + maAccessor.set( + lookup( + vigra::detail::RequiresExplicitCast<value_type>::cast(value) ), + i, diff ); } }; - -//----------------------------------------------------------------------------- - -/// Retrieve raw pixel data accessor for given Accessor type -template< class Accessor > struct rawAccessor -{ - // generic case: both accessors are the same - typedef Accessor type; -}; - -template< typename DataType > struct RawAccessor : public StandardAccessor< DataType > -{ - RawAccessor() {} - // converting constructor, which in fact discards argument - template< typename ValueType > explicit RawAccessor( - const PaletteImageAccessor< ValueType, DataType >& ) {} -}; - -// specialization for PaletteImageAccessor, to provide the -// corresponding StandardAccessor to the pixel index values -template< typename ValueType, typename DataType > -struct rawAccessor< PaletteImageAccessor< ValueType, DataType > > -{ - typedef RawAccessor< DataType > type; -}; - - //----------------------------------------------------------------------------- -/// Retrieve stand-alone color lookup function for given Accessor type -template< class Accessor > struct colorLookup -{ - // generic case: accessor has no lookup functionality - typedef std::project2nd< Accessor, typename Accessor::value_type > type; -}; - /** Lookup index value for given Color value in PaletteImageAccessor */ template< class Accessor > struct ColorLookup @@ -186,12 +184,39 @@ template< class Accessor > struct ColorLookup } }; -// specialization for PaletteImageAccessor, to provide the -// corresponding ColorLookup functor -template< typename ValueType, typename DataType > -struct colorLookup< PaletteImageAccessor< ValueType, DataType > > +//----------------------------------------------------------------------------- + +// partial specialization for PaletteAccessor +template< class Accessor, typename ColorType > struct AccessorTraits< + PaletteImageAccessor< Accessor, ColorType > > { - typedef ColorLookup< PaletteImageAccessor< ValueType, DataType > > type; + /// value type of described accessor + typedef typename PaletteImageAccessor< Accessor, ColorType >::value_type value_type; + + /// Retrieve stand-alone color lookup function for given Accessor type + typedef ColorLookup< PaletteImageAccessor< Accessor, ColorType > > color_lookup; + + /// Retrieve raw pixel data accessor for given Accessor type + typedef Accessor raw_accessor; + + /** accessor for XOR setter access is disabled, since the results + * are usually completely unintended - you'll usually want to + * wrap an xor_accessor with a PaletteAccessor, not the other way + * around. + */ + typedef vigra::VigraFalseType xor_accessor; + + /** accessor for masked setter access is disabled, since the + * results are usually completely unintended - you'll usually + * want to wrap a masked_accessor with a PaletteAccessor, not the + * other way around. + */ + template< class MaskAccessor, + class Iterator, + class MaskIterator > struct masked_accessor + { + typedef vigra::VigraFalseType type; + }; }; } // namespace basebmp diff --git a/basebmp/inc/basebmp/scanlineformats.hxx b/basebmp/inc/basebmp/scanlineformats.hxx index 5999ee96db6a..6e25b565c28a 100644 --- a/basebmp/inc/basebmp/scanlineformats.hxx +++ b/basebmp/inc/basebmp/scanlineformats.hxx @@ -2,9 +2,9 @@ * * $RCSfile: scanlineformats.hxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: hdu $ $Date: 2006-06-15 08:11:27 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:40 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -75,16 +75,17 @@ namespace basebmp { namespace Format static const sal_Int32 ONE_BIT_LSB_GRAY = (sal_Int32)0x02; static const sal_Int32 ONE_BIT_MSB_PAL = (sal_Int32)0x03; static const sal_Int32 ONE_BIT_LSB_PAL = (sal_Int32)0x04; - static const sal_Int32 TWO_BIT_MSB_PAL = (sal_Int32)0x05; - static const sal_Int32 TWO_BIT_LSB_PAL = (sal_Int32)0x06; + static const sal_Int32 FOUR_BIT_MSB_GRAY = (sal_Int32)0x05; + static const sal_Int32 FOUR_BIT_LSB_GRAY = (sal_Int32)0x06; static const sal_Int32 FOUR_BIT_MSB_PAL = (sal_Int32)0x07; static const sal_Int32 FOUR_BIT_LSB_PAL = (sal_Int32)0x08; static const sal_Int32 EIGHT_BIT_PAL = (sal_Int32)0x09; static const sal_Int32 EIGHT_BIT_GRAY = (sal_Int32)0x0A; - static const sal_Int32 SIXTEEN_BIT_TC_MASK = (sal_Int32)0x0B; - static const sal_Int32 TWENTYFOUR_BIT_TC_MASK = (sal_Int32)0x0C; - static const sal_Int32 THIRTYTWO_BIT_TC_MASK = (sal_Int32)0x0D; - static const sal_Int32 MAX = (sal_Int32)0x0D; + static const sal_Int32 SIXTEEN_BIT_LSB_TC_MASK= (sal_Int32)0x0B; + static const sal_Int32 SIXTEEN_BIT_MSB_TC_MASK= (sal_Int32)0x0C; + static const sal_Int32 TWENTYFOUR_BIT_TC_MASK = (sal_Int32)0x0D; + static const sal_Int32 THIRTYTWO_BIT_TC_MASK = (sal_Int32)0x0E; + static const sal_Int32 MAX = (sal_Int32)0x0E; } } #endif /* INCLUDED_BASEBMP_SCANLINEFORMATS_HXX */ diff --git a/basebmp/inc/basebmp/truecolormaskaccessor.hxx b/basebmp/inc/basebmp/truecolormaskaccessor.hxx new file mode 100644 index 000000000000..e4bdb2f8b340 --- /dev/null +++ b/basebmp/inc/basebmp/truecolormaskaccessor.hxx @@ -0,0 +1,298 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: truecolormaskaccessor.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2006-07-06 10:00:40 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_BASEBMP_TRUECOLORMASKACCESSOR_HXX +#define INCLUDED_BASEBMP_TRUECOLORMASKACCESSOR_HXX + +#include <basebmp/colortraits.hxx> +#include <basebmp/accessortraits.hxx> +#include <basebmp/metafunctions.hxx> +#include <basebmp/endian.hxx> + +#include <vigra/numerictraits.hxx> +#include <vigra/metaprogramming.hxx> + +namespace basebmp +{ + +namespace +{ + /// Shift left for positive shift value, and right otherwise + template< typename T > inline T shiftLeft( T v, int shift ) + { + return shift > 0 ? v << shift : v >> (-shift); + } + + /// Shift right for positive shift value, and left otherwise + template< typename T > inline T shiftRight( T v, int shift ) + { + return shift > 0 ? v >> shift : v << (-shift); + } +} + +/** Access true color data, which is pixel-packed into a POD. + + @tpl Accessor + Wrapped accessor, used to access the actual pixel values + + @tpl ColorType + Underlying color type, to convert the pixel values into + + @tpl RedMask + Bitmask, to access the red bits in the data type + + @tpl GreenMask + Bitmask, to access the green bits in the data type + + @tpl BlueMask + Bitmask, to access the blue bits in the data type + + @tpl SwapBytes + When true, the final pixel values will be byte-swapped before + passed to/from the iterator. + */ +template< class Accessor, + typename ColorType, + int RedMask, + int GreenMask, + int BlueMask, + bool SwapBytes > class TrueColorMaskAccessor +{ +public: + typedef typename Accessor::value_type data_type; + typedef ColorType value_type; + typedef typename make_unsigned<data_type>::type unsigned_data_type; + typedef typename ColorTraits<ColorType>::component_type component_type; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +// making all members public, if no member template friends +private: + template<class A, typename C, int R, int G, int B, bool S> friend class TrueColorMaskAccessor; +#endif + + Accessor maAccessor; + +public: + // calc corrective shifts for all three channels in advance + enum { + red_shift = numberOfTrailingZeros<RedMask>::value, + green_shift = numberOfTrailingZeros<GreenMask>::value, + blue_shift = numberOfTrailingZeros<BlueMask>::value, + + red_bits = bitcount<RedMask>::value, + green_bits = bitcount<GreenMask>::value, + blue_bits = bitcount<BlueMask>::value + }; + + // ------------------------------------------------------- + + TrueColorMaskAccessor() : + maAccessor() + {} + + template< class A > explicit + TrueColorMaskAccessor( TrueColorMaskAccessor< A, + ColorType, + RedMask, + GreenMask, + BlueMask, + SwapBytes > const& rSrc ) : + maAccessor( rSrc.maAccessor ) + {} + + template< class T > explicit TrueColorMaskAccessor( T accessor ) : + maAccessor(accessor) + {} + + // ------------------------------------------------------- + + Accessor const& getWrappedAccessor() const { return maAccessor; } + Accessor& getWrappedAccessor() { return maAccessor; } + + // ------------------------------------------------------- + + value_type toValue( unsigned_data_type v ) const + { + v = SwapBytes ? byteSwap(v) : v; + + const unsigned_data_type red (v & RedMask); + const unsigned_data_type green(v & GreenMask); + const unsigned_data_type blue (v & BlueMask); + + value_type res( (shiftRight(red, + red_shift-8*sizeof(component_type)+red_bits)) | + (shiftRight(red, + red_shift-8*sizeof(component_type)+2*red_bits)), + + (shiftRight(green, + green_shift-8*sizeof(component_type)+green_bits)) | + (shiftRight(green, + green_shift-8*sizeof(component_type)+2*green_bits)), + + (shiftRight(blue, + blue_shift-8*sizeof(component_type)+blue_bits)) | + (shiftRight(blue, + blue_shift-8*sizeof(component_type)+2*blue_bits)) ); + return res; + } + + data_type toPacked( value_type v ) const + { + const unsigned_data_type red (v.getRed()); + const unsigned_data_type green(v.getGreen()); + const unsigned_data_type blue (v.getBlue()); + + unsigned_data_type res( + (shiftLeft(red, + red_shift-8*sizeof(component_type)+red_bits) & RedMask) | + (shiftLeft(green, + green_shift-8*sizeof(component_type)+green_bits) & GreenMask) | + (shiftLeft(blue, + blue_shift-8*sizeof(component_type)+blue_bits) & BlueMask) ); + + return SwapBytes ? byteSwap(res) : res; + } + + // ------------------------------------------------------- + + template< class Iterator > + value_type operator()(Iterator const& i) const + { + return toValue( + unsigned_cast<data_type>( maAccessor(i)) ); + } + + template< class Iterator, class Difference > + value_type operator()(Iterator const& i, Difference const& diff) const + { + return toValue( + unsigned_cast<data_type>( maAccessor(i,diff)) ); + } + + // ------------------------------------------------------- + + template< typename V, class Iterator > + void set(V const& value, Iterator const& i) const + { + maAccessor.set( + toPacked( + vigra::detail::RequiresExplicitCast<value_type>::cast( + value) ), + i); + } + + template< typename V, class Iterator, class Difference > + void set(V const& value, Iterator const& i, Difference const& diff) const + { + maAccessor.set( + toPacked( + vigra::detail::RequiresExplicitCast<value_type>::cast( + value)), + i, + diff ); + } +}; + +//----------------------------------------------------------------------------- + +/** Convert Color to packed true color value for TrueColorMaskAccessor + */ +template< class Accessor > struct ColorConvert +{ + typename Accessor::data_type operator()( const Accessor& acc, + typename Accessor::value_type v ) + { + return acc.toPacked(v); + } +}; + +//----------------------------------------------------------------------------- + +// partial specialization for TrueColorMaskAccessor +template< class Accessor, + typename ColorType, + int RedMask, + int GreenMask, + int BlueMask, + bool SwapBytes > struct AccessorTraits< + TrueColorMaskAccessor< Accessor, + ColorType, + RedMask, + GreenMask, + BlueMask, + SwapBytes > > +{ + /// value type of described accessor + typedef typename TrueColorMaskAccessor< Accessor, + ColorType, + RedMask, + GreenMask, + BlueMask, + SwapBytes >::value_type value_type; + + /// Retrieve stand-alone color lookup function for given Accessor type + typedef ColorConvert< TrueColorMaskAccessor< Accessor, + ColorType, + RedMask, + GreenMask, + BlueMask, + SwapBytes > > color_lookup; + + /// Retrieve raw pixel data accessor for given Accessor type + typedef Accessor raw_accessor; + + /** accessor for XOR setter access is disabled, since the results + * are usually completely unintended - you'll usually want to + * wrap an xor_accessor with a TrueColorMaskAccessor, not the + * other way around. + */ + typedef vigra::VigraFalseType xor_accessor; + + /** accessor for masked setter access is disabled, since the + * results are usually completely unintended - you'll usually + * want to wrap a masked_accessor with a TrueColorMaskAccessor, + * not the other way around. + */ + template< class MaskAccessor, + class Iterator, + class MaskIterator > struct masked_accessor + { + typedef vigra::VigraFalseType type; + }; +}; + +} // namespace basebmp + +#endif /* INCLUDED_BASEBMP_TRUECOLORMASKACCESSOR_HXX */ diff --git a/basebmp/source/bitmapdevice.cxx b/basebmp/source/bitmapdevice.cxx index 1f8e164d1377..03e73525918c 100644 --- a/basebmp/source/bitmapdevice.cxx +++ b/basebmp/source/bitmapdevice.cxx @@ -4,9 +4,9 @@ * * $RCSfile: bitmapdevice.cxx,v $ * - * $Revision: 1.15 $ + * $Revision: 1.16 $ * - * last change: $Author: thb $ $Date: 2006-06-30 13:36:14 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:40 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -34,16 +34,25 @@ ************************************************************************/ #include "basebmp/bitmapdevice.hxx" -#include "basebmp/packedpixeliterator.hxx" + #include "basebmp/pixeliterator.hxx" +#include "basebmp/packedpixeliterator.hxx" +#include "basebmp/compositeiterator.hxx" +#include "basebmp/iteratortraits.hxx" + +#include "basebmp/accessor.hxx" +#include "basebmp/accessortraits.hxx" +#include "basebmp/accessoradapters.hxx" +#include "basebmp/colorblendaccessoradapter.hxx" #include "basebmp/paletteimageaccessor.hxx" +#include "basebmp/truecolormaskaccessor.hxx" + #include "basebmp/color.hxx" #include "basebmp/colormisc.hxx" -#include "basebmp/accessor.hxx" -#include "basebmp/accessoradapters.hxx" +#include "basebmp/colortraits.hxx" + #include "basebmp/scanlineformats.hxx" #include "basebmp/clippedlinerenderer.hxx" -#include "basebmp/compositeiterator.hxx" #include <rtl/alloc.h> #include <rtl/memory.h> @@ -60,12 +69,28 @@ #include <basegfx/point/b2ipoint.hxx> #include <basegfx/vector/b2ivector.hxx> -#include <vigra/basicimage.hxx> -#include <vigra/imageiterator.hxx> +#include <vigra/rgbvalue.hxx> #include <vigra/resizeimage.hxx> #include <vigra/copyimage.hxx> #include <vigra/tuple.hxx> +#include <boost/mpl/identity.hpp> + +namespace vigra +{ +/// componentwise xor of an RGBValue (missing from rgbvalue.hxx) +template< class Value, unsigned int RedIndex, unsigned int BlueIndex, unsigned int GreenIndex > +inline RGBValue<Value, RedIndex, GreenIndex, BlueIndex> +operator^( RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& lhs, + RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& rhs ) +{ + RGBValue<Value, RedIndex, GreenIndex, BlueIndex> res( + lhs[0] ^ rhs[0], + lhs[1] ^ rhs[1], + lhs[2] ^ rhs[2]); + return res; +} +} namespace basebmp { @@ -75,18 +100,21 @@ namespace // Common accessor and iterator types //------------------------------------------------------------------------ - typedef PaletteImageAccessor<Color,sal_uInt8> PaletteAccessor; - typedef PackedPixelIterator< sal_uInt8, 1, - true > MaskIterator; - typedef StandardAccessor< sal_uInt8 > MaskAccessor; + true > MaskIterator; + typedef NonStandardAccessor< sal_uInt8 > MaskAccessor; - typedef PixelIterator< sal_uInt8 > AlphaMaskIterator; - typedef vigra::AccessorTraits< sal_uInt8 >::default_accessor AlphaMaskAccessor; + typedef PixelIterator< sal_uInt8 > AlphaMaskIterator; + typedef StandardAccessor< sal_uInt8 > AlphaMaskAccessor; - typedef PixelIterator<Color> ThirtyTwoBitPixelIterator; - typedef vigra::AccessorTraits<Color>::default_accessor ThirtyTwoBitAccessor; + template< class Accessor > struct PaletteAccessorSelector + { + typedef PaletteImageAccessor< Accessor, Color > type; + }; + + typedef vigra::RGBValue<sal_uInt8> TwentyFourBitPixelRGB; + typedef vigra::RGBValue<sal_uInt8,2,1,0> TwentyFourBitPixelBGR; // metafunctions to retrieve correct POD from/to basebmp::Color @@ -99,6 +127,19 @@ namespace DataType operator()( Color c ) { return c.getGrayscale(); } }; + /// type-safe conversion between color and RgbValue + template< class RgbVal > struct RgbValueFromColor + { + RgbVal operator()( Color c ) + { + RgbVal res; + res.setRed(c.getRed()); + res.setGreen(c.getGreen()); + res.setBlue(c.getBlue()); + return res; + } + }; + /// type-safe conversion between pod and color template< typename DataType > struct ColorFromGreyScale { @@ -106,12 +147,31 @@ namespace Color operator()( DataType c ) { return Color(c,c,c); } }; + /// type-safe conversion between RgbValue and color + template< class RgbVal > struct ColorFromRgbValue + { + Color operator()( RgbVal const& c ) + { + return Color(c.red(),c.green(),c.blue()); + } + }; + + /// type-safe conversion from Color to packed int32 struct UInt32FromColor { sal_uInt32 operator()( const Color& c ) { return c.toInt32(); } }; + /// type-safe conversion from RgbValue to packed int32 + template< class RgbVal > struct UInt32FromRgbValue + { + sal_uInt32 operator()( RgbVal const& c ) + { + return (c[0] << 16) | (c[1] << 8) | c[2]; + } + }; + /// Get converter from color to given data type template< typename DataType > struct fromColorConverter; template<> struct fromColorConverter< sal_uInt8 > @@ -122,6 +182,21 @@ namespace { typedef std::identity<Color> type; }; + template< unsigned int RedIndex, + unsigned int GreenIndex, + unsigned int BlueIndex > struct fromColorConverter< + vigra::RGBValue< sal_uInt8, + RedIndex, + GreenIndex, + BlueIndex > > + { + typedef RgbValueFromColor< + vigra::RGBValue< sal_uInt8, + RedIndex, + GreenIndex, + BlueIndex > > + type; + }; /// Get converter from given data type to Color template< typename DataType > struct toColorConverter; @@ -133,6 +208,21 @@ namespace { typedef std::identity<Color> type; }; + template< unsigned int RedIndex, + unsigned int GreenIndex, + unsigned int BlueIndex > struct toColorConverter< + vigra::RGBValue< sal_uInt8, + RedIndex, + GreenIndex, + BlueIndex > > + { + typedef ColorFromRgbValue< + vigra::RGBValue< sal_uInt8, + RedIndex, + GreenIndex, + BlueIndex > > + type; + }; /// Get converter from given data type to sal_uInt32 template< typename DataType > struct toUInt32Converter @@ -143,6 +233,21 @@ namespace { typedef UInt32FromColor type; }; + template< unsigned int RedIndex, + unsigned int GreenIndex, + unsigned int BlueIndex > struct toUInt32Converter< + vigra::RGBValue< sal_uInt8, + RedIndex, + GreenIndex, + BlueIndex > > + { + typedef UInt32FromRgbValue< + vigra::RGBValue< sal_uInt8, + RedIndex, + GreenIndex, + BlueIndex > > + type; + }; // Polygon scanline conversion @@ -230,70 +335,110 @@ namespace // Actual BitmapDevice implementation (templatized by accessor and iterator) //-------------------------------------------------------------------------- - template< class DestIterator, - class DestAccessor > class BitmapRenderer : public BitmapDevice + /** Implementation of the BitmapDevice interface + + @tpl DestIterator + Iterator to access bitmap memory + + @tpl RawAccessor + Raw accessor, to access pixel values directly + + @tpl VanillaAccessorSelector + Accessor adapter selector, which, when applied to one of the + raw bitmap accessors, yields a member type named 'type', which + is a wrapped accessor that map color values. + */ + template< class DestIterator, + class RawAccessor, + template< typename > class VanillaAccessorSelector > class BitmapRenderer : + public BitmapDevice { public: typedef BitmapRenderer<MaskIterator, - MaskAccessor> MaskBitmap; + MaskAccessor, + boost::mpl::identity> MaskBitmap; typedef BitmapRenderer<AlphaMaskIterator, - AlphaMaskAccessor> AlphaMaskBitmap; - typedef typename colorLookup<DestAccessor>::type ColorLookupFunctor; - typedef typename fromColorConverter< - typename DestAccessor::value_type>::type FromColorFunctor; - typedef typename toColorConverter< - typename DestAccessor::value_type>::type ToColorFunctor; - typedef typename rawAccessor<DestAccessor>::type RawAccessor; + AlphaMaskAccessor, + boost::mpl::identity> AlphaMaskBitmap; + + // ------------------------------------------------------- + + typedef AccessorTraits< RawAccessor > RawAccessorTraits; typedef typename toUInt32Converter< - typename RawAccessor::value_type>::type ToUInt32Functor; - typedef typename xorAccessor<DestAccessor>::type XorAccessor; - typedef typename xorAccessor<RawAccessor>::type RawXorAccessor; - typedef typename maskedAccessor<DestAccessor, - MaskAccessor, - DestIterator, - MaskIterator>::type MaskedAccessor; - typedef typename maskedAccessor<RawAccessor, - MaskAccessor, - DestIterator, - MaskIterator>::type RawMaskedAccessor; - typedef typename maskedAccessor<XorAccessor, - MaskAccessor, - DestIterator, - MaskIterator>::type MaskedXorAccessor; + typename RawAccessor::value_type>::type ToUInt32Functor; + + // ------------------------------------------------------- + + typedef typename VanillaAccessorSelector< + RawAccessor >::type DestAccessor; + typedef AccessorTraits< DestAccessor > AccTraits; + + // ------------------------------------------------------- + + typedef typename RawAccessorTraits::xor_accessor RawXorAccessor; + typedef AccessorTraits<RawXorAccessor> RawXorAccessorTraits; + typedef typename VanillaAccessorSelector< + RawXorAccessor >::type XorAccessor; + typedef AccessorTraits<XorAccessor> XorAccessorTraits; + + // ------------------------------------------------------- + + typedef typename RawAccessorTraits::template masked_accessor< + MaskAccessor, + DestIterator, + MaskIterator>::type RawMaskedAccessor; + typedef typename VanillaAccessorSelector< + RawMaskedAccessor >::type MaskedAccessor; + typedef typename RawXorAccessorTraits::template masked_accessor< + MaskAccessor, + DestIterator, + MaskIterator>::type RawMaskedXorAccessor; + typedef typename VanillaAccessorSelector< + RawMaskedXorAccessor >::type MaskedXorAccessor; + + // ------------------------------------------------------- + typedef ConstantColorBlendSetterAccessorAdapter< DestAccessor, - typename AlphaMaskAccessor::value_type> ColorBlendAccessor; - typedef typename maskedAccessor<ColorBlendAccessor, - MaskAccessor, - DestIterator, - MaskIterator>::type MaskedColorBlendAcc; - typedef typename maskedAccessor<RawXorAccessor, - MaskAccessor, - DestIterator, - MaskIterator>::type RawMaskedXorAccessor; - - typedef DestIterator dest_iterator; - typedef DestAccessor dest_accessor; + typename AlphaMaskAccessor::value_type> ColorBlendAccessor; + typedef AccessorTraits<ColorBlendAccessor> BlendAccessorTraits; + typedef typename BlendAccessorTraits::template masked_accessor< + MaskAccessor, + DestIterator, + MaskIterator>::type MaskedColorBlendAcc; + + // ------------------------------------------------------- + + typedef typename fromColorConverter< + typename AccTraits::value_type>::type FromColorFunctor; + typedef typename toColorConverter< + typename AccTraits::value_type>::type ToColorFunctor; + + // ------------------------------------------------------- + + typedef DestIterator dest_iterator; + typedef DestAccessor dest_accessor; typedef CompositeIterator2D< DestIterator, - MaskIterator > composite_iterator_type; - - DestIterator maBegin; - DestIterator maEnd; - ColorLookupFunctor maColorLookup; - FromColorFunctor maFromColorConverter; - ToColorFunctor maToColorConverter; - ToUInt32Functor maToUInt32Converter; - DestAccessor maAccessor; - RawAccessor maRawAccessor; - XorAccessor maXorAccessor; - RawXorAccessor maRawXorAccessor; - MaskedAccessor maMaskedAccessor; - MaskedColorBlendAcc maMaskedColorBlendAccessor; - MaskedXorAccessor maMaskedXorAccessor; - RawMaskedAccessor maRawMaskedAccessor; - RawMaskedXorAccessor maRawMaskedXorAccessor; - int mnWidth; - int mnHeight; + MaskIterator > composite_iterator_type; + + DestIterator maBegin; + DestIterator maEnd; + typename AccTraits::color_lookup maColorLookup; + FromColorFunctor maFromColorConverter; + ToColorFunctor maToColorConverter; + ToUInt32Functor maToUInt32Converter; + DestAccessor maAccessor; + ColorBlendAccessor maColorBlendAccessor; + RawAccessor maRawAccessor; + XorAccessor maXorAccessor; + RawXorAccessor maRawXorAccessor; + MaskedAccessor maMaskedAccessor; + MaskedColorBlendAcc maMaskedColorBlendAccessor; + MaskedXorAccessor maMaskedXorAccessor; + RawMaskedAccessor maRawMaskedAccessor; + RawMaskedXorAccessor maRawMaskedXorAccessor; + int mnWidth; + int mnHeight; BitmapRenderer( const basegfx::B2IVector& rSize, bool bTopDown, @@ -312,15 +457,15 @@ namespace maToColorConverter(), maToUInt32Converter(), maAccessor( accessor ), - maRawAccessor( accessor ), + maColorBlendAccessor( accessor ), + maRawAccessor(), maXorAccessor( accessor ), - maRawXorAccessor( maRawAccessor ), + maRawXorAccessor(), maMaskedAccessor( accessor ), - maMaskedColorBlendAccessor( - ColorBlendAccessor(accessor) ), - maMaskedXorAccessor( maXorAccessor ), - maRawMaskedAccessor( maRawAccessor ), - maRawMaskedXorAccessor( maRawXorAccessor ), + maMaskedColorBlendAccessor( maColorBlendAccessor ), + maMaskedXorAccessor( accessor ), + maRawMaskedAccessor(), + maRawMaskedXorAccessor(), mnWidth( maEnd.x - maBegin.x ), mnHeight( maEnd.y - maBegin.y ) {} @@ -450,13 +595,13 @@ namespace return maToUInt32Converter(maRawAccessor(pixel)); } - template< typename Range, typename Col, typename RawAccessor > + template< typename Range, typename Col, typename RawAcc > void implRenderLine2( const basegfx::B2IPoint& rPt1, const basegfx::B2IPoint& rPt2, const basegfx::B2IRange& rBounds, Col col, const Range& range, - const RawAccessor& rawAcc ) + const RawAcc& rawAcc ) { renderClippedLine( rPt1, rPt2, @@ -466,14 +611,14 @@ namespace rawAcc ); } - template< typename Range, typename Accessor, typename RawAccessor > + template< typename Range, typename Accessor, typename RawAcc > void implRenderLine( const basegfx::B2IPoint& rPt1, const basegfx::B2IPoint& rPt2, const basegfx::B2IRange& rBounds, Color col, const Range& range, const Accessor& acc, - const RawAccessor& rawAcc ) + const RawAcc& rawAcc ) { implRenderLine2( rPt1,rPt2,rBounds, maColorLookup( acc, @@ -483,14 +628,14 @@ namespace rawAcc ); } - template< typename Range, typename RawAccessor, typename XorAccessor > + template< typename Range, typename RawAcc, typename XorAcc > void implDrawLine( const basegfx::B2IPoint& rPt1, const basegfx::B2IPoint& rPt2, const basegfx::B2IRange& rBounds, Color col, const Range& range, - const RawAccessor& rawAcc, - const XorAccessor& xorAcc, + const RawAcc& rawAcc, + const XorAcc& xorAcc, DrawMode drawMode ) { if( drawMode == DrawMode_XOR ) @@ -539,12 +684,12 @@ namespace maRawMaskedAccessor,maRawMaskedXorAccessor,drawMode); } - template< typename Range, typename RawAccessor > + template< typename Range, typename RawAcc > void implDrawPolygon( const basegfx::B2DPolygon& rPoly, const basegfx::B2IRange& rBounds, Color col, const Range& range, - const RawAccessor& acc ) + const RawAcc& acc ) { basegfx::B2DPolygon aPoly( rPoly ); if( rPoly.areControlVectorsUsed() ) @@ -605,11 +750,11 @@ namespace maRawMaskedAccessor ); } - template< typename Range, typename RawAccessor > + template< typename Range, typename RawAcc > void implFillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly, Color col, const Range& range, - const RawAccessor& acc, + const RawAcc& acc, const basegfx::B2IRange& rBounds ) { basegfx::B2DPolyPolygon aPoly( rPoly ); @@ -663,12 +808,12 @@ namespace rBounds ); } - template< typename Range, typename RawAccessor > + template< typename Range, typename RawAcc > void implDrawBitmap(const BitmapDeviceSharedPtr& rSrcBitmap, const basegfx::B2IRange& rSrcRect, const basegfx::B2IRange& rDstRect, const Range& range, - const RawAccessor& acc) + const RawAcc& acc) { boost::shared_ptr<BitmapRenderer> pSrcBmp( getCompatibleBitmap(rSrcBitmap) ); OSL_ASSERT( pSrcBmp ); @@ -728,6 +873,7 @@ namespace { boost::shared_ptr<AlphaMaskBitmap> pAlpha( getCompatibleAlphaMask(rAlphaMask) ); OSL_ASSERT( pAlpha ); + maColorBlendAccessor.setColor( maFromColorConverter(aSrcColor) ); vigra::copyImage( pAlpha->maBegin + vigra::Diff2D(rSrcRect.getMinX(), rSrcRect.getMinY()), @@ -736,8 +882,7 @@ namespace pAlpha->maAccessor, maBegin + vigra::Diff2D(rDstPoint.getX(), rDstPoint.getY()), - ColorBlendAccessor( maAccessor, - maFromColorConverter(aSrcColor)) ); + maColorBlendAccessor ); } virtual void drawMaskedColor_i(Color aSrcColor, @@ -751,7 +896,8 @@ namespace const vigra::pair<composite_iterator_type, composite_iterator_type> aRange( getMaskedRange(rClip) ); - maMaskedColorBlendAccessor.setColor( maFromColorConverter(aSrcColor) ); + maMaskedColorBlendAccessor.get1stWrappedAccessor().setColor( + maFromColorConverter(aSrcColor) ); vigra::copyImage( pAlpha->maBegin + vigra::Diff2D(rSrcRect.getMinX(), rSrcRect.getMinY()), @@ -1373,33 +1519,195 @@ void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, //---------------------------------------------------------------------------------- -typedef BitmapRenderer<MaskIterator, - MaskAccessor > OneBitMsbMaskRenderer; -typedef BitmapRenderer<MaskIterator,PaletteAccessor> OneBitMsbPaletteRenderer; -typedef BitmapRenderer<AlphaMaskIterator, - AlphaMaskAccessor > EightBitGrayRenderer; -typedef BitmapRenderer<ThirtyTwoBitPixelIterator, - ThirtyTwoBitAccessor> ThirtyTwoBitTrueColorRenderer; +/// Produces a specialized renderer for the given packed pixel format +template< int Bits, + bool MsbFirst, + template<typename> class VanillaAccessorSelector, + class Accessor > +BitmapDeviceSharedPtr createPackedPixelRenderer( + const basegfx::B2IVector& rSize, + bool bTopDown, + sal_Int32 nScanlineFormat, + sal_Int32 nScanlineStride, + sal_uInt8* pFirstScanline, + const typename VanillaAccessorSelector< + Accessor>::type & rAccessor, + boost::shared_array< sal_uInt8 > pMem, + const PaletteMemorySharedVector& pPal ) +{ + typedef PackedPixelIterator< sal_uInt8,Bits,MsbFirst > Iterator; + typedef BitmapRenderer< Iterator, + Accessor, + VanillaAccessorSelector > Renderer; + + return BitmapDeviceSharedPtr( + new Renderer( rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + Iterator(pFirstScanline, + nScanlineStride), + Iterator(pFirstScanline, + nScanlineStride) + + vigra::Diff2D(rSize.getX(), + rSize.getY()), + rAccessor, + pMem, + pPal )); +} + +/// Create standard grey level palette +PaletteMemorySharedVector createStandardPalette( + const PaletteMemorySharedVector& pPal, + sal_Int32 nNumEntries ) +{ + if( pPal || nNumEntries <= 0 ) + return pPal; + + boost::shared_ptr< std::vector<Color> > pLocalPal( + new std::vector<Color>(nNumEntries) ); + + const sal_Int32 nIncrement( 0x00FFFFFF/nNumEntries ); + --nNumEntries; + for( sal_Int32 i=0, c=0; i<nNumEntries; ++i,c+=nIncrement ) + pLocalPal->at(i) = Color(0xFF000000 | c); + + pLocalPal->at(nNumEntries) = Color(0xFFFFFFFF); + + return pLocalPal; +} + +//---------------------------------------------------------------------------------- + +// TODO(Q3): consolidate with canvas/canvastools.hxx! Best move this +// to o3tl or sal/bithacks.hxx ... + +/** Compute the next highest power of 2 of a 32-bit value + + Code devised by Sean Anderson, in good ole HAKMEM + tradition. + + @return 1 << (lg(x - 1) + 1) +*/ +inline sal_uInt32 nextPow2( sal_uInt32 x ) +{ + --x; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return ++x; +} + +//---------------------------------------------------------------------------------- + +typedef PaletteImageAccessor< + StandardAccessor<sal_uInt8>,Color> StandardPaletteAccessor; +typedef PaletteImageAccessor< + NonStandardAccessor<sal_uInt8>,Color> NonStandardPaletteAccessor; + +// ------------------------------------------------------- + +#ifdef OSL_LITENDIAN +# define SIXTEENBIT_LSB_SWAP false +# define SIXTEENBIT_MSB_SWAP true +#else +# ifdef OSL_BIGENDIAN +# define SIXTEENBIT_LSB_SWAP true +# define SIXTEENBIT_MSB_SWAP false +# else +# error Undetermined endianness! +# endif +#endif + +typedef PixelIterator<sal_uInt16> SixteenBitPixelIterator; +typedef StandardAccessor<sal_uInt16> SixteenBitRawAccessor; +template< class Accessor > struct TrueColorLsbMaskAccessorSelector +{ + typedef TrueColorMaskAccessor<Accessor, + Color, + 0xF800, + 0x07E0, + 0x001F, + SIXTEENBIT_LSB_SWAP> type; +}; +typedef TrueColorLsbMaskAccessorSelector< + SixteenBitRawAccessor>::type SixteenBitLsbAccessor; + +template< class Accessor > struct TrueColorMsbMaskAccessorSelector +{ + typedef TrueColorMaskAccessor<Accessor, + Color, + 0xF800, + 0x07E0, + 0x001F, + SIXTEENBIT_MSB_SWAP> type; +}; +typedef TrueColorMsbMaskAccessorSelector< + SixteenBitRawAccessor>::type SixteenBitMsbAccessor; + +// ------------------------------------------------------- + +typedef PixelIterator<TwentyFourBitPixelRGB> TwentyFourBitRGBIterator; +typedef StandardAccessor<TwentyFourBitPixelRGB> TwentyFourBitRGBAccessor; + +// ------------------------------------------------------- + +typedef PixelIterator<TwentyFourBitPixelBGR> TwentyFourBitBGRIterator; +typedef StandardAccessor<TwentyFourBitPixelBGR> TwentyFourBitBGRAccessor; + +// ------------------------------------------------------- + +typedef PixelIterator<Color> ThirtyTwoBitPixelIterator; +typedef StandardAccessor<Color> ThirtyTwoBitAccessor; + namespace { -BitmapDeviceSharedPtr createBitmapDeviceImpl( const basegfx::B2IVector& rSize, - bool bTopDown, - sal_Int32 nScanlineFormat, - boost::shared_array< sal_uInt8 > pMem, - PaletteMemorySharedVector pPal ) +BitmapDeviceSharedPtr createBitmapDeviceImpl( const basegfx::B2IVector& rSize, + bool bTopDown, + sal_Int32 nScanlineFormat, + boost::shared_array< sal_uInt8 > pMem, + PaletteMemorySharedVector pPal ) { + if( nScanlineFormat <= Format::NONE || + nScanlineFormat > Format::MAX ) + return BitmapDeviceSharedPtr(); + + static const sal_uInt8 bitsPerPixel[] = + { + 0, // NONE + 1, // ONE_BIT_MSB_GRAY + 1, // ONE_BIT_LSB_GRAY + 1, // ONE_BIT_MSB_PAL + 1, // ONE_BIT_LSB_PAL + 4, // FOUR_BIT_MSB_GRAY + 4, // FOUR_BIT_LSB_GRAY + 4, // FOUR_BIT_MSB_PAL + 4, // FOUR_BIT_LSB_PAL + 8, // EIGHT_BIT_PAL + 8, // EIGHT_BIT_GRAY + 16, // SIXTEEN_BIT_LSB_TC_MASK + 16, // SIXTEEN_BIT_MSB_TC_MASK + 24, // TWENTYFOUR_BIT_TC_MASK + 32, // THIRTYTWO_BIT_TC_MASK + }; + sal_Int32 nScanlineStride(0); - // HACK: 1bpp and 32bpp only, currently - if( nScanlineFormat == Format::ONE_BIT_MSB_PAL - || nScanlineFormat == Format::ONE_BIT_MSB_GRAY ) - nScanlineStride = (rSize.getX() + 7) >> 3; - else if( nScanlineFormat == Format::EIGHT_BIT_GRAY ) - nScanlineStride = rSize.getX(); - else if( nScanlineFormat == Format::THIRTYTWO_BIT_TC_MASK ) - nScanlineStride = 4*rSize.getX(); + // round up to full 8 bit, divide by 8 + nScanlineStride = (rSize.getX()*bitsPerPixel[nScanlineFormat] + 7) >> 3; + // rounded up to next full power-of-two number of bytes + const sal_uInt32 bytesPerPixel = nextPow2( + (bitsPerPixel[nScanlineFormat] + 7) >> 3); + + // now make nScanlineStride a multiple of bytesPerPixel + nScanlineStride = (nScanlineStride + bytesPerPixel - 1) / bytesPerPixel * bytesPerPixel; + + // factor in bottom-up scanline order case nScanlineStride *= bTopDown ? 1 : -1; const std::size_t nMemSize( @@ -1418,96 +1726,296 @@ BitmapDeviceSharedPtr createBitmapDeviceImpl( const basegfx::B2IVector& switch( nScanlineFormat ) { + // ---------------------------------------------------------------------- + // one bit formats + case Format::ONE_BIT_MSB_GRAY: { + return createPackedPixelRenderer< 1, + true, + boost::mpl::identity, + MaskAccessor >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + pFirstScanline, + MaskAccessor(), + pMem, + pPal ); + } + case Format::ONE_BIT_LSB_GRAY: + { + return createPackedPixelRenderer< 1, + false, + boost::mpl::identity, + MaskAccessor >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + pFirstScanline, + MaskAccessor(), + pMem, + pPal ); + } + case Format::ONE_BIT_MSB_PAL: + { + pPal = createStandardPalette(pPal,2); + return createPackedPixelRenderer< 1, + true, + PaletteAccessorSelector, + MaskAccessor >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + pFirstScanline, + NonStandardPaletteAccessor( &pPal->at(0), + pPal->size() ), + pMem, + pPal ); + } + case Format::ONE_BIT_LSB_PAL: + { + pPal = createStandardPalette(pPal,2); + return createPackedPixelRenderer< 1, + false, + PaletteAccessorSelector, + MaskAccessor >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + pFirstScanline, + NonStandardPaletteAccessor( &pPal->at(0), + pPal->size() ), + pMem, + pPal ); + } + + + // ---------------------------------------------------------------------- + // four bit formats + + case Format::FOUR_BIT_MSB_GRAY: + { + return createPackedPixelRenderer< 4, + true, + boost::mpl::identity, + MaskAccessor >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + pFirstScanline, + MaskAccessor(), + pMem, + pPal ); + } + case Format::FOUR_BIT_LSB_GRAY: + { + return createPackedPixelRenderer< 4, + false, + boost::mpl::identity, + MaskAccessor >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + pFirstScanline, + MaskAccessor(), + pMem, + pPal ); + } + case Format::FOUR_BIT_MSB_PAL: + { + pPal = createStandardPalette(pPal,16); + return createPackedPixelRenderer< 1, + true, + PaletteAccessorSelector, + MaskAccessor >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + pFirstScanline, + NonStandardPaletteAccessor( &pPal->at(0), + pPal->size() ), + pMem, + pPal ); + } + case Format::FOUR_BIT_LSB_PAL: + { + pPal = createStandardPalette(pPal,16); + return createPackedPixelRenderer< 1, + false, + PaletteAccessorSelector, + MaskAccessor >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + pFirstScanline, + NonStandardPaletteAccessor( &pPal->at(0), + pPal->size() ), + pMem, + pPal ); + } + + + // ---------------------------------------------------------------------- + // eight bit formats + + case Format::EIGHT_BIT_GRAY: + { return BitmapDeviceSharedPtr( - new OneBitMsbMaskRenderer( + new BitmapRenderer< AlphaMaskIterator, + AlphaMaskAccessor, + boost::mpl::identity >( rSize, bTopDown, nScanlineFormat, nScanlineStride, - MaskIterator(pFirstScanline, - nScanlineStride), - MaskIterator(pFirstScanline, - nScanlineStride) + AlphaMaskIterator(pFirstScanline, + nScanlineStride), + AlphaMaskIterator(pFirstScanline, + nScanlineStride) + vigra::Diff2D(rSize.getX(), rSize.getY()), - MaskAccessor(), + AlphaMaskAccessor(), pMem, pPal )); } - case Format::ONE_BIT_MSB_PAL: + case Format::EIGHT_BIT_PAL: { - if( !pPal ) - { - boost::shared_ptr< std::vector<Color> > pLocalPal( - new std::vector<Color>(2) ); - pLocalPal->at(0) = Color(0x00000000); - pLocalPal->at(1) = Color(0xFFFFFFFF); + pPal = createStandardPalette(pPal,256); + return BitmapDeviceSharedPtr( + new BitmapRenderer< AlphaMaskIterator, + AlphaMaskAccessor, + PaletteAccessorSelector >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + AlphaMaskIterator(pFirstScanline, + nScanlineStride), + AlphaMaskIterator(pFirstScanline, + nScanlineStride) + + vigra::Diff2D(rSize.getX(), + rSize.getY()), + StandardPaletteAccessor( &pPal->at(0), + pPal->size() ), + pMem, + pPal )); + } - pPal = pLocalPal; - } + // ---------------------------------------------------------------------- + // sixteen bit formats + + case Format::SIXTEEN_BIT_LSB_TC_MASK: + { return BitmapDeviceSharedPtr( - new OneBitMsbPaletteRenderer( + new BitmapRenderer< SixteenBitPixelIterator, + SixteenBitRawAccessor, + TrueColorLsbMaskAccessorSelector >( rSize, bTopDown, nScanlineFormat, nScanlineStride, - MaskIterator(pFirstScanline, - nScanlineStride), - MaskIterator(pFirstScanline, - nScanlineStride) + SixteenBitPixelIterator( + reinterpret_cast<sal_uInt16*>(pFirstScanline), + nScanlineStride), + SixteenBitPixelIterator( + reinterpret_cast<sal_uInt16*>(pFirstScanline), + nScanlineStride) + vigra::Diff2D(rSize.getX(), rSize.getY()), - PaletteAccessor( &pPal->at(0), - pPal->size() ), + SixteenBitLsbAccessor(), pMem, pPal )); } - case Format::EIGHT_BIT_GRAY: + case Format::SIXTEEN_BIT_MSB_TC_MASK: { return BitmapDeviceSharedPtr( - new EightBitGrayRenderer( + new BitmapRenderer< SixteenBitPixelIterator, + SixteenBitRawAccessor, + TrueColorMsbMaskAccessorSelector >( rSize, bTopDown, nScanlineFormat, nScanlineStride, - AlphaMaskIterator(pFirstScanline, - nScanlineStride), - AlphaMaskIterator(pFirstScanline, - nScanlineStride) + SixteenBitPixelIterator( + reinterpret_cast<sal_uInt16*>(pFirstScanline), + nScanlineStride), + SixteenBitPixelIterator( + reinterpret_cast<sal_uInt16*>(pFirstScanline), + nScanlineStride) + vigra::Diff2D(rSize.getX(), rSize.getY()), - AlphaMaskAccessor(), + SixteenBitMsbAccessor(), + pMem, + pPal )); + } + + // ---------------------------------------------------------------------- + // twentyfour bit formats + + case Format::TWENTYFOUR_BIT_TC_MASK: + { + return BitmapDeviceSharedPtr( + new BitmapRenderer< TwentyFourBitRGBIterator, + TwentyFourBitRGBAccessor, + boost::mpl::identity >( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + TwentyFourBitRGBIterator( + reinterpret_cast<TwentyFourBitPixelRGB*>(pFirstScanline), + nScanlineStride), + TwentyFourBitRGBIterator( + reinterpret_cast<TwentyFourBitPixelRGB*>(pFirstScanline), + nScanlineStride) + + vigra::Diff2D(rSize.getX(), + rSize.getY()), + TwentyFourBitRGBAccessor(), pMem, pPal )); } + + // ---------------------------------------------------------------------- + // thirtytwo bit formats + case Format::THIRTYTWO_BIT_TC_MASK: { return BitmapDeviceSharedPtr( - new ThirtyTwoBitTrueColorRenderer( + new BitmapRenderer< ThirtyTwoBitPixelIterator, + ThirtyTwoBitAccessor, + boost::mpl::identity >( rSize, bTopDown, nScanlineFormat, nScanlineStride, - ThirtyTwoBitPixelIterator(reinterpret_cast<Color*>(pFirstScanline), - nScanlineStride), - ThirtyTwoBitPixelIterator(reinterpret_cast<Color*>(pFirstScanline), - nScanlineStride) + ThirtyTwoBitPixelIterator( + reinterpret_cast<Color*>(pFirstScanline), + nScanlineStride), + ThirtyTwoBitPixelIterator( + reinterpret_cast<Color*>(pFirstScanline), + nScanlineStride) + vigra::Diff2D(rSize.getX(), rSize.getY()), ThirtyTwoBitAccessor(), pMem, pPal )); } - - default: - // TODO(F3): other formats not yet implemented - return BitmapDeviceSharedPtr(); } + + // TODO(F3): other formats not yet implemented + return BitmapDeviceSharedPtr(); } } // namespace diff --git a/basebmp/source/debug.cxx b/basebmp/source/debug.cxx index 19b799879d0a..8f3d1c5edcf4 100644 --- a/basebmp/source/debug.cxx +++ b/basebmp/source/debug.cxx @@ -2,9 +2,9 @@ * * $RCSfile: debug.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: thb $ $Date: 2006-06-07 14:27:36 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:41 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -87,10 +87,10 @@ namespace basebmp return "ONE_BIT_MSB_PAL"; case Format::ONE_BIT_LSB_PAL: return "ONE_BIT_LSB_PAL"; - case Format::TWO_BIT_MSB_PAL: - return "TWO_BIT_MSB_PAL"; - case Format::TWO_BIT_LSB_PAL: - return "TWO_BIT_LSB_PAL"; + case Format::FOUR_BIT_MSB_GRAY: + return "FOUR_BIT_MSB_GRAY"; + case Format::FOUR_BIT_LSB_GRAY: + return "FOUR_BIT_LSB_GRAY"; case Format::FOUR_BIT_MSB_PAL: return "FOUR_BIT_MSB_PAL"; case Format::FOUR_BIT_LSB_PAL: @@ -99,8 +99,10 @@ namespace basebmp return "EIGHT_BIT_PAL"; case Format::EIGHT_BIT_GRAY: return "EIGHT_BIT_GRAY"; - case Format::SIXTEEN_BIT_TC_MASK: - return "SIXTEEN_BIT_TC_MASK"; + case Format::SIXTEEN_BIT_LSB_TC_MASK: + return "SIXTEEN_BIT_LSB_TC_MASK"; + case Format::SIXTEEN_BIT_MSB_TC_MASK: + return "SIXTEEN_BIT_MSB_TC_MASK"; case Format::TWENTYFOUR_BIT_TC_MASK: return "TWENTYFOUR_BIT_TC_MASK"; case Format::THIRTYTWO_BIT_TC_MASK: diff --git a/basebmp/test/basictest.cxx b/basebmp/test/basictest.cxx index 8126dfd18f99..33209a81a534 100644 --- a/basebmp/test/basictest.cxx +++ b/basebmp/test/basictest.cxx @@ -4,9 +4,9 @@ * * $RCSfile: basictest.cxx,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: thb $ $Date: 2006-06-30 11:05:21 $ + * last change: $Author: thb $ $Date: 2006-07-06 10:00:41 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -179,6 +179,54 @@ public: pDevice->getPixel(aPt3) == aCol6); } + // 16bpp + { + pDevice = createBitmapDevice( aSize, + true, + Format::SIXTEEN_BIT_LSB_TC_MASK ); + const Color aCol7(0); + pDevice->clear( aCol7 ); + + const Color aCol4(0x00101010); + pDevice->setPixel( aPt, aCol4, DrawMode_PAINT ); + std::ofstream output("16bpp_test.dump"); + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #7", + pDevice->getPixel(aPt) == aCol4); + + const Color aCol5(0x00F0F0F0); + pDevice->setPixel( aPt2, aCol5, DrawMode_PAINT ); + debugDump( pDevice, output ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #8", + pDevice->getPixel(aPt2) == aCol5); + + const Color aCol6(0x00FFFFFF); + pDevice->setPixel( aPt3, aCol6, DrawMode_PAINT ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #9", + pDevice->getPixel(aPt3) != aCol7); + } + + // 24bpp + { + pDevice = createBitmapDevice( aSize, + true, + Format::TWENTYFOUR_BIT_TC_MASK ); + + const Color aCol4(0x01010101); + pDevice->setPixel( aPt, aCol4, DrawMode_PAINT ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #10", + pDevice->getPixel(aPt) == aCol4); + + const Color aCol5(0x0F0F0F0F); + pDevice->setPixel( aPt2, aCol5, DrawMode_PAINT ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #11", + pDevice->getPixel(aPt2) == aCol5); + + const Color aCol6(0xFFFFFFFF); + pDevice->setPixel( aPt3, aCol6, DrawMode_PAINT ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #12", + pDevice->getPixel(aPt3) == aCol6); + } + // 32bpp { pDevice = createBitmapDevice( aSize, @@ -187,17 +235,17 @@ public: const Color aCol4(0x01010101); pDevice->setPixel( aPt, aCol4, DrawMode_PAINT ); - CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #7", + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #13", pDevice->getPixel(aPt) == aCol4); const Color aCol5(0x0F0F0F0F); pDevice->setPixel( aPt2, aCol5, DrawMode_PAINT ); - CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #8", + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #14", pDevice->getPixel(aPt2) == aCol5); const Color aCol6(0xFFFFFFFF); pDevice->setPixel( aPt3, aCol6, DrawMode_PAINT ); - CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #9", + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #15", pDevice->getPixel(aPt3) == aCol6); } } |