summaryrefslogtreecommitdiff
path: root/basebmp/inc/basebmp
diff options
context:
space:
mode:
Diffstat (limited to 'basebmp/inc/basebmp')
-rw-r--r--basebmp/inc/basebmp/accessor.hxx122
-rw-r--r--basebmp/inc/basebmp/accessoradapters.hxx529
-rw-r--r--basebmp/inc/basebmp/accessorfunctors.hxx190
-rw-r--r--basebmp/inc/basebmp/accessortraits.hxx133
-rw-r--r--basebmp/inc/basebmp/bitmapdevice.hxx695
-rw-r--r--basebmp/inc/basebmp/clippedlinerenderer.hxx415
-rw-r--r--basebmp/inc/basebmp/color.hxx102
-rw-r--r--basebmp/inc/basebmp/colorblendaccessoradapter.hxx151
-rw-r--r--basebmp/inc/basebmp/colormisc.hxx194
-rw-r--r--basebmp/inc/basebmp/colortraits.hxx153
-rw-r--r--basebmp/inc/basebmp/compositeiterator.hxx370
-rw-r--r--basebmp/inc/basebmp/debug.hxx53
-rw-r--r--basebmp/inc/basebmp/drawmodes.hxx58
-rw-r--r--basebmp/inc/basebmp/endian.hxx60
-rw-r--r--basebmp/inc/basebmp/fillimage.hxx72
-rw-r--r--basebmp/inc/basebmp/genericcolorimageaccessor.hxx85
-rw-r--r--basebmp/inc/basebmp/greylevelformats.hxx138
-rw-r--r--basebmp/inc/basebmp/iteratortraits.hxx58
-rw-r--r--basebmp/inc/basebmp/linerenderer.hxx184
-rw-r--r--basebmp/inc/basebmp/metafunctions.hxx225
-rw-r--r--basebmp/inc/basebmp/nonstandarditerator.hxx48
-rw-r--r--basebmp/inc/basebmp/packedpixeliterator.hxx680
-rw-r--r--basebmp/inc/basebmp/paletteformats.hxx150
-rw-r--r--basebmp/inc/basebmp/paletteimageaccessor.hxx171
-rw-r--r--basebmp/inc/basebmp/pixelformatadapters.hxx111
-rw-r--r--basebmp/inc/basebmp/pixeliterator.hxx358
-rw-r--r--basebmp/inc/basebmp/polypolygonrenderer.hxx369
-rw-r--r--basebmp/inc/basebmp/rgb24pixelformats.hxx101
-rw-r--r--basebmp/inc/basebmp/rgbmaskpixelformats.hxx292
-rw-r--r--basebmp/inc/basebmp/scaleimage.hxx198
-rw-r--r--basebmp/inc/basebmp/scanlineformats.hxx59
-rw-r--r--basebmp/inc/basebmp/stridedarrayiterator.hxx117
-rw-r--r--basebmp/inc/basebmp/tools.hxx94
-rw-r--r--basebmp/inc/basebmp/truecolormaskaccessor.hxx293
34 files changed, 7028 insertions, 0 deletions
diff --git a/basebmp/inc/basebmp/accessor.hxx b/basebmp/inc/basebmp/accessor.hxx
new file mode 100644
index 000000000000..9bf2d1b6d140
--- /dev/null
+++ b/basebmp/inc/basebmp/accessor.hxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_ACCESSOR_HXX
+#define INCLUDED_BASEBMP_ACCESSOR_HXX
+
+#include <vigra/numerictraits.hxx>
+
+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;
+ }
+
+ 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
+ {
+ return i.get(diff);
+ }
+
+ // -------------------------------------------------------
+
+ template< typename V, class Iterator >
+ void set(V const& value, Iterator const& i) const
+ {
+ i.set( 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.set( vigra::detail::RequiresExplicitCast<value_type>::cast(value),
+ diff );
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_ACCESSOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/accessoradapters.hxx b/basebmp/inc/basebmp/accessoradapters.hxx
new file mode 100644
index 000000000000..8fb801d7c8ca
--- /dev/null
+++ b/basebmp/inc/basebmp/accessoradapters.hxx
@@ -0,0 +1,529 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX
+#define INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX
+
+#include <vigra/numerictraits.hxx>
+
+namespace basebmp
+{
+
+/** Interpose given accessor's set and get methods with two unary
+ functors.
+
+ @tpl WrappedAccessor
+ Wrapped type must provide the usual get and set accessor methods,
+ with the usual signatures (see StandardAccessor for a conforming
+ example).
+
+ @tpl GetterFunctor
+ An Adaptable Unary Function (i.e. providing result_type and
+ argument_type typedefs)
+
+ @tpl SetterFunctor
+ An Adaptable Unary Function (i.e. providing result_type and
+ argument_type typedefs)
+ */
+template< class WrappedAccessor,
+ typename GetterFunctor,
+ typename SetterFunctor > class UnaryFunctionAccessorAdapter
+{
+public:
+ typedef typename GetterFunctor::result_type value_type;
+ typedef typename SetterFunctor::argument_type argument_type;
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+// making all members public, if no member template friends
+private:
+ template<class A, typename G, typename S> friend class UnaryFunctionAccessorAdapter;
+#endif
+
+ // we don't derive from wrapped type, to avoid ambiguities
+ // regarding templatized getter/setter methods.
+ WrappedAccessor maAccessor;
+ GetterFunctor maGetterFunctor;
+ SetterFunctor maSetterFunctor;
+
+public:
+ UnaryFunctionAccessorAdapter() :
+ maAccessor(),
+ maGetterFunctor(),
+ maSetterFunctor()
+ {}
+
+ template< class A > explicit
+ UnaryFunctionAccessorAdapter( UnaryFunctionAccessorAdapter< A,
+ GetterFunctor,
+ SetterFunctor > const& rSrc ) :
+ maAccessor( rSrc.maAccessor ),
+ maGetterFunctor( rSrc.maGetterFunctor ),
+ maSetterFunctor( rSrc.maSetterFunctor )
+ {}
+
+ template< class T > explicit UnaryFunctionAccessorAdapter( T const& accessor ) :
+ maAccessor( accessor ),
+ maGetterFunctor(),
+ maSetterFunctor()
+ {}
+
+ 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; }
+
+ // -------------------------------------------------------
+
+ value_type getter(typename GetterFunctor::argument_type v) const
+ {
+ return maGetterFunctor(v);
+ }
+ typename SetterFunctor::result_type setter(argument_type v) const
+ {
+ return maSetterFunctor(v);
+ }
+
+ // -------------------------------------------------------
+
+ 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
+ {
+ maAccessor.set(
+ maSetterFunctor(
+ vigra::detail::RequiresExplicitCast<argument_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(
+ maSetterFunctor(
+ vigra::detail::RequiresExplicitCast<argument_type>::cast(value) ),
+ i,
+ diff );
+ }
+
+};
+
+//-----------------------------------------------------------------------------
+
+/** Interpose given accessor's set methods with a binary function,
+ taking both old and new value.
+
+ The wrappee's getter methods kept 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, must provide a nested typedef value_type.
+
+ @tpl SetterFunctor
+ An adaptable binary function (i.e. providing nested typedefs for
+ result_type and first and second argument type)
+ */
+template< class WrappedAccessor,
+ typename SetterFunctor > class BinarySetterFunctionAccessorAdapter
+{
+public:
+ typedef typename WrappedAccessor::value_type value_type;
+ typedef typename SetterFunctor::second_argument_type argument_type;
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+// making all members public, if no member template friends
+private:
+ template<class A, typename S> friend class BinarySetterFunctionAccessorAdapter;
+#endif
+
+ WrappedAccessor maAccessor;
+ SetterFunctor maFunctor;
+
+public:
+ BinarySetterFunctionAccessorAdapter() :
+ maAccessor(),
+ maFunctor()
+ {}
+
+ template< class A > explicit
+ BinarySetterFunctionAccessorAdapter(
+ BinarySetterFunctionAccessorAdapter< A,
+ SetterFunctor > const& rSrc ) :
+ maAccessor( rSrc.maAccessor ),
+ maFunctor( rSrc.maFunctor )
+ {}
+
+ template< class T > explicit BinarySetterFunctionAccessorAdapter( T const& accessor ) :
+ maAccessor( accessor ),
+ maFunctor()
+ {}
+
+ template< class T > BinarySetterFunctionAccessorAdapter( T accessor,
+ SetterFunctor functor ) :
+ maAccessor( accessor ),
+ maFunctor( functor )
+ {}
+
+ // -------------------------------------------------------
+
+ WrappedAccessor const& getWrappedAccessor() const { return maAccessor; }
+ WrappedAccessor& getWrappedAccessor() { return maAccessor; }
+
+ // -------------------------------------------------------
+
+ typename SetterFunctor::result_type setter(
+ typename SetterFunctor::first_argument_type v1,
+ argument_type v2 ) const
+ {
+ return maSetterFunctor(v1,v2);
+ }
+
+ // -------------------------------------------------------
+
+ template< class Iterator >
+ value_type operator()(Iterator const& i) const
+ {
+ return maAccessor(i);
+ }
+
+ template< class Iterator, class Difference >
+ value_type operator()(Iterator const& i, Difference const& diff) const
+ {
+ 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<argument_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<argument_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. 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)
+
+ @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 nested typedef
+ value_type (the selection of WrappedAccessor1 as the provider for
+ that typedef is rather arbitrary. Could have been
+ WrappedAccessor2, too. So sue me)
+
+ @tpl Functor
+ An adaptable ternary function (i.e. providing nested typedefs for
+ result_type and first, second and third argument type)
+ */
+template< class WrappedAccessor1,
+ class WrappedAccessor2,
+ typename Functor > class TernarySetterFunctionAccessorAdapter
+{
+public:
+ typedef typename WrappedAccessor1::value_type value_type;
+ typedef typename Functor::third_argument_type argument_type;
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+// making all members public, if no member template friends
+private:
+ template<class A1, class A2, typename F> friend class TernarySetterFunctionAccessorAdapter;
+#endif
+
+ WrappedAccessor1 ma1stAccessor;
+ WrappedAccessor2 ma2ndAccessor;
+ Functor maFunctor;
+
+public:
+ TernarySetterFunctionAccessorAdapter() :
+ ma1stAccessor(),
+ ma2ndAccessor(),
+ maFunctor()
+ {}
+
+ template< class T > explicit TernarySetterFunctionAccessorAdapter( T const& accessor ) :
+ ma1stAccessor( accessor ),
+ ma2ndAccessor(),
+ maFunctor()
+ {}
+
+ template< class A1, class A2 > explicit
+ TernarySetterFunctionAccessorAdapter(
+ TernarySetterFunctionAccessorAdapter< A1,
+ A2,
+ Functor > const& rSrc ) :
+ ma1stAccessor( rSrc.ma1stAccessor ),
+ ma2ndAccessor( rSrc.ma2ndAccessor ),
+ maFunctor( rSrc.maFunctor )
+ {}
+
+ template< class T1, class T2 >
+ TernarySetterFunctionAccessorAdapter( T1 accessor1,
+ T2 accessor2 ) :
+ ma1stAccessor( accessor1 ),
+ ma2ndAccessor( accessor2 ),
+ maFunctor()
+ {}
+
+ template< class T1, class T2 >
+ TernarySetterFunctionAccessorAdapter( T1 accessor1,
+ T2 accessor2,
+ Functor func ) :
+ ma1stAccessor( accessor1 ),
+ ma2ndAccessor( accessor2 ),
+ maFunctor( func )
+ {}
+
+ // -------------------------------------------------------
+
+ WrappedAccessor1 const& get1stWrappedAccessor() const { return ma1stAccessor; }
+ WrappedAccessor1& get1stWrappedAccessor() { return ma1stAccessor; }
+
+ WrappedAccessor2 const& get2ndWrappedAccessor() const { return ma2ndAccessor; }
+ WrappedAccessor2& get2ndWrappedAccessor() { return ma2ndAccessor; }
+
+ // -------------------------------------------------------
+
+ typename Functor::result_type setter(
+ typename Functor::first_argument_type v1,
+ typename Functor::second_argument_type v2,
+ argument_type v3 ) const
+ {
+ return maSetterFunctor(v1,v2,v3);
+ }
+
+ // -------------------------------------------------------
+
+ template< class Iterator >
+ value_type operator()(Iterator const& i) const
+ {
+ return ma1stAccessor(i.first());
+ }
+
+ template< class Iterator, class Difference >
+ value_type operator()(Iterator const& i, Difference const& diff) const
+ {
+ return ma1stAccessor(i.second(),diff);
+ }
+
+ // -------------------------------------------------------
+
+ template< typename V, class Iterator >
+ void set(V const& value, Iterator const& i) const
+ {
+ ma1stAccessor.set(
+ maFunctor(ma1stAccessor(i.first()),
+ ma2ndAccessor(i.second()),
+ vigra::detail::RequiresExplicitCast<argument_type>::cast(value)),
+ i.first() );
+ }
+
+ template< typename V, class Iterator, class Difference >
+ void set(V const& value, Iterator const& i, Difference const& diff) const
+ {
+ ma1stAccessor.set(
+ maFunctor(ma1stAccessor(i.first(), diff),
+ ma2ndAccessor(i.second(),diff),
+ vigra::detail::RequiresExplicitCast<argument_type>::cast(value)),
+ i.first(),
+ diff );
+ }
+
+};
+
+//-----------------------------------------------------------------------------
+
+/** Access two distinct images simultaneously
+
+ Passed iterator must fulfill the CompositeIterator concept
+ (i.e. wrap the two image's iterators into one
+ CompositeIterator). The getter and setter methods expect and
+ return a pair of values, with types equal to the two accessors
+ value types
+
+ @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 nested typedef
+ value_type.
+
+ @tpl WrappedAccessor2
+ 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 nested typedef
+ value_type.
+ */
+template< class WrappedAccessor1,
+ class WrappedAccessor2 > class JoinImageAccessorAdapter
+{
+public:
+ // TODO(F3): Need numeric traits and a few free functions to
+ // actually calculate with a pair (semantic: apply every operation
+ // individually to the contained types)
+ typedef std::pair<typename WrappedAccessor1::value_type,
+ typename WrappedAccessor2::value_type> value_type;
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+// making all members public, if no member template friends
+private:
+ template<class A1, class A2> friend class JoinImageAccessorAdapter;
+#endif
+
+ WrappedAccessor1 ma1stAccessor;
+ WrappedAccessor2 ma2ndAccessor;
+
+public:
+ JoinImageAccessorAdapter() :
+ ma1stAccessor(),
+ ma2ndAccessor()
+ {}
+
+ template< class T > explicit JoinImageAccessorAdapter( T const& accessor ) :
+ ma1stAccessor( accessor ),
+ ma2ndAccessor()
+ {}
+
+ template< class A1, class A2 > explicit
+ JoinImageAccessorAdapter(
+ JoinImageAccessorAdapter< A1,
+ A2 > const& rSrc ) :
+ ma1stAccessor( rSrc.ma1stAccessor ),
+ ma2ndAccessor( rSrc.ma2ndAccessor )
+ {}
+
+ template< class T1, class T2 >
+ JoinImageAccessorAdapter( T1 accessor1,
+ T2 accessor2 ) :
+ ma1stAccessor( accessor1 ),
+ ma2ndAccessor( accessor2 )
+ {}
+
+ // -------------------------------------------------------
+
+ WrappedAccessor1 const& get1stWrappedAccessor() const { return ma1stAccessor; }
+ WrappedAccessor1& get1stWrappedAccessor() { return ma1stAccessor; }
+
+ WrappedAccessor2 const& get2ndWrappedAccessor() const { return ma2ndAccessor; }
+ WrappedAccessor2& get2ndWrappedAccessor() { return ma2ndAccessor; }
+
+ // -------------------------------------------------------
+
+ template< class Iterator >
+ value_type operator()(Iterator const& i) const
+ {
+ return std::make_pair(ma1stAccessor(i.first()),
+ ma2ndAccessor(i.second()));
+ }
+
+ template< class Iterator, class Difference >
+ value_type operator()(Iterator const& i, Difference const& diff) const
+ {
+ return std::make_pair(ma1stAccessor(i.first(),diff),
+ ma2ndAccessor(i.second(),diff));
+ }
+
+ // -------------------------------------------------------
+
+ template< typename V, class Iterator >
+ void set(V const& value, Iterator const& i) const
+ {
+ ma1stAccessor.set(
+ vigra::detail::RequiresExplicitCast<typename WrappedAccessor1::value_type>::cast(
+ value.first),
+ i.first() );
+ ma2ndAccessor.set(
+ vigra::detail::RequiresExplicitCast<typename WrappedAccessor2::value_type>::cast(
+ value.second),
+ i.second() );
+ }
+
+ template< typename V, class Iterator, class Difference >
+ void set(V const& value, Iterator const& i, Difference const& diff) const
+ {
+ ma1stAccessor.set(
+ vigra::detail::RequiresExplicitCast<typename WrappedAccessor1::value_type>::cast(
+ value.first),
+ i.first(),
+ diff );
+ ma2ndAccessor.set(
+ vigra::detail::RequiresExplicitCast<typename WrappedAccessor2::value_type>::cast(
+ value.second),
+ i.second(),
+ diff );
+ }
+
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/accessorfunctors.hxx b/basebmp/inc/basebmp/accessorfunctors.hxx
new file mode 100644
index 000000000000..1d5464ac0c2f
--- /dev/null
+++ b/basebmp/inc/basebmp/accessorfunctors.hxx
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_ACCESSORFUNCTORS_HXX
+#define INCLUDED_BASEBMP_ACCESSORFUNCTORS_HXX
+
+#include <osl/diagnose.h>
+#include <basebmp/metafunctions.hxx>
+
+#include <functional>
+
+namespace basebmp
+{
+
+// Some common accessor functors
+// ------------------------------------------------------------
+
+
+/// combine two values via XOR
+template< typename T > struct XorFunctor : public std::binary_function<T,T,T>
+{
+ T operator()( T v1, T v2 ) const { return v1 ^ v2; }
+};
+
+//-----------------------------------------------------------------------------
+
+/// Base class, passing on the arg types
+template< typename T, typename M > struct MaskFunctorBase :
+ public TernaryFunctorBase<T,M,T,T> {};
+
+
+/** Let a mask flag decide between two values
+
+ @tpl polarity
+ Mask polarity. When true, a false in the mask denotes
+ transparency, i.e. the original value will display. And vice
+ versa.
+ */
+template< typename T,
+ typename M,
+ bool polarity > struct GenericOutputMaskFunctor : public MaskFunctorBase<T,M>
+{
+ /// Ternary mask operation - selects v1 for !m == polarity, v2 otherwise
+ T operator()( T v1, M m, T v2 ) const
+ {
+ return !m == polarity ? v1 : v2;
+ }
+};
+
+/** Let a mask bit decide between two values (specialization for
+ integer mask types)
+ */
+template< typename T,
+ typename M,
+ bool polarity > struct IntegerOutputMaskFunctor;
+template< typename T,
+ typename M > struct IntegerOutputMaskFunctor<T,M,true> : public MaskFunctorBase<T,M>
+{
+ /** 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 IntegerOutputMaskFunctor<T,M,false> : public MaskFunctorBase<T,M>
+{
+ /** 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*mask + v2*(M)(1-mask);
+ }
+};
+
+/** Let a mask bit decide between two values (specialization for
+ binary-valued mask types)
+ */
+template< typename T, typename M, bool polarity > struct FastIntegerOutputMaskFunctor;
+template< typename T, typename M > struct FastIntegerOutputMaskFunctor<T,M,true> :
+ public MaskFunctorBase<T,M>
+{
+ /// 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;
+ }
+};
+template< typename T, typename M > struct FastIntegerOutputMaskFunctor<T,M,false> :
+ public MaskFunctorBase<T,M>
+{
+ /// 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 + v2*(M)(1-m);
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+/** Split a pair value from a JoinImageAccessorAdapter into its
+ individual values, and pass it on to a ternary functor
+
+ This wrapper is an adaptable binary functor, and can thus be used
+ with a BinarySetterFunctionAccessorAdapter. Useful e.g. for
+ out-of-image alpha channel, or a masked image.
+
+ @tpl Functor
+ An adaptable ternary functor (as can e.g. be passed to the
+ TernarySetterFunctionAccessorAdapter)
+ */
+template< typename Functor > struct BinaryFunctorSplittingWrapper :
+ public std::binary_function<typename Functor::first_argument_type,
+ std::pair<typename Functor::third_argument_type,
+ typename Functor::second_argument_type>,
+ typename Functor::result_type>
+{
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+// making all members public, if no member template friends
+private:
+ template<class A> friend struct BinaryFunctorSplittingWrapper;
+#endif
+ Functor maFunctor;
+
+public:
+ BinaryFunctorSplittingWrapper() : maFunctor() {}
+
+ template< class A > explicit
+ BinaryFunctorSplittingWrapper(
+ BinaryFunctorSplittingWrapper<A> const& src ) : maFunctor(src.maFunctor) {}
+
+ template< class F > explicit
+ BinaryFunctorSplittingWrapper( F const& func ) : maFunctor(func) {}
+
+ typename Functor::result_type operator()(
+ typename Functor::first_argument_type v1,
+ std::pair< typename Functor::third_argument_type,
+ typename Functor::second_argument_type > const& v2 ) const
+ {
+ return maFunctor( v1, v2.second, v2.first );
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_ACCESSORFUNCTORS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/accessortraits.hxx b/basebmp/inc/basebmp/accessortraits.hxx
new file mode 100644
index 000000000000..e54da3f3b5ea
--- /dev/null
+++ b/basebmp/inc/basebmp/accessortraits.hxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_ACCESSORTRAITS_HXX
+#define INCLUDED_BASEBMP_ACCESSORTRAITS_HXX
+
+#include <basebmp/accessorfunctors.hxx>
+#include <basebmp/accessoradapters.hxx>
+#include <basebmp/metafunctions.hxx>
+
+#include <functional>
+
+namespace basebmp
+{
+
+struct FastMask;
+struct NoFastMask;
+
+/// Metafunction to select output mask functor from iterator and mask value type
+template< typename T, typename M, bool polarity, typename DUMMY > struct outputMaskFunctorSelector : public
+ ifBothScalarIntegral< T, M,
+ IntegerOutputMaskFunctor< T, M, polarity >,
+ GenericOutputMaskFunctor< T, M, polarity > >
+{
+};
+template< typename T, typename M, bool polarity > struct outputMaskFunctorSelector< T, M, polarity, FastMask > : public
+ ifBothScalarIntegral< T, M,
+ FastIntegerOutputMaskFunctor< T, M, polarity >,
+ GenericOutputMaskFunctor< T, M, polarity > >
+{
+};
+
+/** 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,
+ bool polarity > struct maskedAccessorSelector
+{
+ typedef TernarySetterFunctionAccessorAdapter<
+ Accessor,
+ MaskAccessor,
+ typename outputMaskFunctorSelector<
+ typename Accessor::value_type,
+ typename MaskAccessor::value_type,
+ polarity,
+ 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,
+ bool polarity > struct masked_accessor :
+ public maskedAccessorSelector< Accessor,
+ MaskAccessor,
+ Iterator,
+ MaskIterator,
+ polarity >
+ {};
+
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_ACCESSORTRAITS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/bitmapdevice.hxx b/basebmp/inc/basebmp/bitmapdevice.hxx
new file mode 100644
index 000000000000..e026f3165fbb
--- /dev/null
+++ b/basebmp/inc/basebmp/bitmapdevice.hxx
@@ -0,0 +1,695 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_BITMAPDEVICE_HXX
+#define INCLUDED_BASEBMP_BITMAPDEVICE_HXX
+
+#include <sal/types.h>
+#include <basebmp/drawmodes.hxx>
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/noncopyable.hpp>
+#include <vector>
+
+namespace basegfx
+{
+ class B2IPoint;
+ class B2DPoint;
+ class B2IVector;
+ class B2IRange;
+ class B2DPolygon;
+ class B2DPolyPolygon;
+}
+
+namespace basebmp
+{
+
+// Temporary. Use like the tools color object
+class Color;
+typedef boost::shared_ptr< class BitmapDevice > BitmapDeviceSharedPtr;
+typedef boost::shared_array< sal_uInt8 > RawMemorySharedArray;
+typedef boost::shared_ptr< const std::vector<Color> > PaletteMemorySharedVector;
+
+struct ImplBitmapDevice;
+
+/** Definition of BitmapDevice interface
+
+ Use the createBitmapDevice() factory method to create instances.
+
+ Implementation note: the clip mask and bitmap parameter instances
+ of BitmapDevice that are passed to individual BitmapDevice
+ instances work best with 1 bit grey masks for the clip and a
+ format matching that of the target BitmapDevice for the other
+ parameters. The alpha mask passed to the drawMaskedColor() methods
+ works best when given as an eight bit grey bitmap. Everything else
+ is accepted, but potentially slow.
+ */
+class BitmapDevice : public boost::enable_shared_from_this<BitmapDevice>,
+ private boost::noncopyable
+{
+public:
+ /** Query size of device in pixel
+ */
+ basegfx::B2IVector getSize() const;
+
+ /** Query whether buffer starts with 0th scanline
+
+ @return true, if the buffer memory starts with the 0th
+ scanline, and false if it starts with the last one. The latter
+ is e.g. the typical scan line ordering for the Windows BMP
+ format.
+ */
+ bool isTopDown() const;
+
+ /** Query type of scanline memory format
+ */
+ sal_Int32 getScanlineFormat() const;
+
+ /** Query byte offset to get from scanline n to scanline n+1
+
+ @return the scanline stride in bytes. In the case of
+ isTopDown()==false, this offset will be negative.
+ */
+ sal_Int32 getScanlineStride() const;
+
+ /** Get pointer to frame buffer
+
+ @return a shared ptr to the bitmap buffer memory. As this is a
+ shared ptr, you can freely store and use the pointer, even
+ after this object has been deleted.
+ */
+ RawMemorySharedArray getBuffer() const;
+
+ /** Get pointer to palette
+
+ The returned pointer is const on purpose, since the
+ BitmapDevice might internally cache lookup information. Don't
+ modify the returned data, unless you want to enter the realm
+ of completely undefined behaviour.
+
+ @return shared pointer to vector of Color entries.
+ */
+ PaletteMemorySharedVector getPalette() const;
+
+ /** Query number of palette entries.
+
+ This is just a frontend for getPalette->size()
+ */
+ sal_Int32 getPaletteEntryCount() const;
+
+ /** Clear whole device with given color
+
+ This method works like a fill with the given color value,
+ resulting in a bitmap uniformly colored in fillColor.
+ */
+ void clear( Color fillColor );
+
+ /** Set given pixel to specified color
+
+ @param rPt
+ Pixel to set
+
+ @param pixelColor
+ Color value to set the pixel to
+
+ @param drawMode
+ Draw mode to use when changing the pixel value
+ */
+ void setPixel( const basegfx::B2IPoint& rPt,
+ Color pixelColor,
+ DrawMode drawMode );
+
+ /** Set given pixel to specified color
+
+ @param rPt
+ Pixel to set
+
+ @param pixelColor
+ Color value to set the pixel to
+
+ @param drawMode
+ Draw mode to use when changing the pixel value
+
+ @param rClip
+ Clip mask to use. If the clip mask is 1 at the given pixel
+ position, no change will take place.
+ */
+ void setPixel( const basegfx::B2IPoint& rPt,
+ Color pixelColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ /** Get color value at given pixel
+ */
+ Color getPixel( const basegfx::B2IPoint& rPt );
+
+ /** Get underlying pixel data value at given position
+
+ This method returns the raw pixel data. In the case of
+ paletted bitmaps, this is the palette index, not the final
+ color value.
+ */
+ sal_uInt32 getPixelData( const basegfx::B2IPoint& rPt );
+
+ /** Draw a line
+
+ @param rPt1
+ Start point of the line
+
+ @param rPt2
+ End point of the line. If the analytical line from rP1 to rPt2
+ (with the actual pixel positions assumed to be the center of
+ the pixel) is exactly in the middle between two pixel, this
+ method always selects the pixel closer to rPt1.
+
+ @param lineColor
+ Color value to draw the line with
+
+ @param drawMode
+ Draw mode to use when changing the pixel value
+ */
+ void drawLine( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode );
+
+ /** Draw a line
+
+ @param rPt1
+ Start point of the line
+
+ @param rPt2
+ End point of the line. If the analytical line from rP1 to rPt2
+ (with the actual pixel positions assumed to be the center of
+ the pixel) is exactly in the middle between two pixel, this
+ method always selects the pixel closer to rPt1.
+
+ @param lineColor
+ Color value to draw the line with
+
+ @param drawMode
+ Draw mode to use when changing the pixel value
+
+ @param rClip
+ Clip mask to use. Pixel where the corresponding clip mask
+ pixel is 1 will not be modified.
+ */
+ void drawLine( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ /** Draw a polygon
+
+ @param rPoly
+ Polygon to draw. Depending on the value returned by rPoly's
+ isClosed() method, the resulting line polygon will be drawn
+ closed or not.
+
+ @param lineColor
+ Color value to draw the polygon with
+
+ @param drawMode
+ Draw mode to use when changing pixel values
+ */
+ void drawPolygon( const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode );
+
+ /** Draw a polygon
+
+ @param rPoly
+ Polygon to draw. Depending on the value returned by rPoly's
+ isClosed() method, the resulting line polygon will be drawn
+ closed or not.
+
+ @param lineColor
+ Color value to draw the polygon with
+
+ @param drawMode
+ Draw mode to use when changing pixel values
+
+ @param rClip
+ Clip mask to use. Pixel where the corresponding clip mask
+ pixel is 1 will not be modified.
+ */
+ void drawPolygon( const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ /** Fill a poly-polygon
+
+ @param rPoly
+ Poly-polygon to fill. Regardless of the value returned by
+ rPoly's isClosed() method, the resulting filled poly-polygon
+ is always considered closed. As usual, when filling a shape,
+ the rightmost and bottommost pixel are not filled, compared to
+ the drawPolygon() method. For example, the rectangle
+ (0,0),(1,1) will have four pixel set, when drawn via
+ drawPolygon(), and only one pixel, when filled via
+ fillPolyPolygon().
+
+ @param fillColor
+ Color value to fill the poly-polygon with
+
+ @param drawMode
+ Draw mode to use when changing pixel values
+ */
+ void fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode );
+
+ /** Fill a poly-polygon
+
+ @param rPoly
+ Poly-polygon to fill. Regardless of the value returned by
+ rPoly's isClosed() method, the resulting filled poly-polygon
+ is always considered closed. As usual, when filling a shape,
+ the rightmost and bottommost pixel are not filled, compared to
+ the drawPolygon() method. For example, the rectangle
+ (0,0),(1,1) will have four pixel set, when drawn via
+ drawPolygon(), and only one pixel, when filled via
+ fillPolyPolygon().
+
+ @param fillColor
+ Color value to fill the poly-polygon with
+
+ @param drawMode
+ Draw mode to use when changing pixel values
+
+ @param rClip
+ Clip mask to use. Pixel where the corresponding clip mask
+ pixel is 1 will not be modified.
+ */
+ void fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ /** Draw another bitmap into this device
+
+ @param rSrcBitmap
+ Bitmap to render into this one. It is permitted that source
+ and destination bitmap are the same.
+
+ @param rSrcRect
+ Rectangle within the source bitmap to take the pixel from.
+
+ @param rDstRect
+ Rectangle in the destination bitmap to put the pixel
+ into. Source and destination rectangle are permitted to have
+ differing sizes; this method will scale the source pixel
+ accordingly. Please note that both source and destination
+ rectangle are interpreted excluding the rightmost pixel column
+ and the bottommost pixel row, this is much like polygon
+ filling. As a result, filling a given rectangle with
+ fillPolyPolygon(), and using the same rectangle as the
+ destination rectangle of this method, will affect exactly the
+ same set of pixel.
+
+ @param drawMode
+ Draw mode to use when changing pixel values
+ */
+ void drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode );
+
+ /** Draw another bitmap into this device
+
+ @param rSrcBitmap
+ Bitmap to render into this one. It is permitted that source
+ and destination bitmap are the same.
+
+ @param rSrcRect
+ Rectangle within the source bitmap to take the pixel from.
+
+ @param rDstRect
+ Rectangle in the destination bitmap to put the pixel
+ into. Source and destination rectangle are permitted to have
+ differing sizes; this method will scale the source pixel
+ accordingly. Please note that both source and destination
+ rectangle are interpreted excluding the rightmost pixel column
+ and the bottommost pixel row, this is much like polygon
+ filling. As a result, filling a given rectangle with
+ fillPolyPolygon(), and using the same rectangle as the
+ destination rectangle of this method, will affect exactly the
+ same set of pixel.
+
+ @param drawMode
+ Draw mode to use when changing pixel values
+
+ @param rClip
+ Clip mask to use. Pixel where the corresponding clip mask
+ pixel is 1 will not be modified.
+ */
+ void drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ /** Draw a color with an alpha-modulation bitmap into this device
+
+ This method takes a fixed color value, and an alpha mask. For
+ each pixel in the alpha mask, the given color value is blended
+ with the corresponding alpha value against the content of this
+ object.
+
+ @param aSrcColor
+ Color value to use for blending
+
+ @param rAlphaMask
+ Alpha mask to use for blending. It is permitted that alpha
+ mask and this bitmap are the same object.
+
+ @param rSrcRect
+ Rectangle within the alpha mask to take the pixel from.
+ Please note that the destination rectangle is interpreted
+ excluding the rightmost pixel column and the bottommost pixel
+ row, this is much like polygon filling. As a result, filling a
+ given rectangle with fillPolyPolygon(), and using the same
+ rectangle as the source rectangle of this method, will affect
+ exactly the same set of pixel.
+
+ @param rDstPoint
+ Destination point, where to start placing the pixel from the
+ source rectangle
+ */
+ void drawMaskedColor( Color aSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint );
+
+ /** Draw a color with an alpha-modulation bitmap into this device
+
+ This method takes a fixed color value, and an alpha mask. For
+ each pixel in the alpha mask, the given color value is blended
+ with the corresponding alpha value against the content of this
+ object.
+
+ @param aSrcColor
+ Color value to use for blending
+
+ @param rAlphaMask
+ Alpha mask to use for blending. It is permitted that alpha
+ mask and this bitmap are the same object.
+
+ @param rSrcRect
+ Rectangle within the alpha mask to take the pixel from.
+ Please note that the destination rectangle is interpreted
+ excluding the rightmost pixel column and the bottommost pixel
+ row, this is much like polygon filling. As a result, filling a
+ given rectangle with fillPolyPolygon(), and using the same
+ rectangle as the source rectangle of this method, will affect
+ exactly the same set of pixel.
+
+ @param rDstPoint
+ Destination point, where to start placing the pixel from the
+ source rectangle
+
+ @param rClip
+ Clip mask to use. Pixel where the corresponding clip mask
+ pixel is 1 will not be modified.
+ */
+ void drawMaskedColor( Color aSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint,
+ const BitmapDeviceSharedPtr& rClip );
+
+ /** Draw another bitmap through a mask into this device
+
+ This method renders a source bitmap into this device, much
+ like the drawBitmap() method. The only difference is the
+ additional mask parameter, which operates much like an
+ additional clip mask: pixel with value zero in this mask
+ result in destination pixel not being modified.
+
+ @param rSrcBitmap
+ Bitmap to render into this one. It is permitted that source
+ and destination bitmap are the same.
+
+ @param rMask
+ Bitmap to use as a mask. Pixel with value != zero in this mask
+ will result in destination pixel not being affected by the
+ blit operation.
+
+ @param rSrcRect
+ Rectangle within the source bitmap to take the pixel from.
+
+ @param rDstRect
+ Rectangle in the destination bitmap to put the pixel
+ into. Source and destination rectangle are permitted to have
+ differing sizes; this method will scale the source pixel
+ accordingly. Please note that both source and destination
+ rectangle are interpreted excluding the rightmost pixel column
+ and the bottommost pixel row, this is much like polygon
+ filling. As a result, filling a given rectangle with
+ fillPolyPolygon(), and using the same rectangle as the
+ destination rectangle of this method, will affect exactly the
+ same set of pixel.
+
+ @param drawMode
+ Draw mode to use when changing pixel values
+ */
+ void drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode );
+
+ /** Draw another bitmap through a mask into this device
+
+ This method renders a source bitmap into this device, much
+ like the drawBitmap() method. The only difference is the
+ additional mask parameter, which operates much like an
+ additional clip mask: pixel with value != zero in this mask
+ result in destination pixel not being modified.
+
+ @param rSrcBitmap
+ Bitmap to render into this one. It is permitted that source
+ and destination bitmap are the same.
+
+ @param rMask
+ Bitmap to use as a mask. Pixel with value != zero in this mask
+ will result in destination pixel not being affected by the
+ blit operation.
+
+ @param rSrcRect
+ Rectangle within the source bitmap to take the pixel from.
+
+ @param rDstRect
+ Rectangle in the destination bitmap to put the pixel
+ into. Source and destination rectangle are permitted to have
+ differing sizes; this method will scale the source pixel
+ accordingly. Please note that both source and destination
+ rectangle are interpreted excluding the rightmost pixel column
+ and the bottommost pixel row, this is much like polygon
+ filling. As a result, filling a given rectangle with
+ fillPolyPolygon(), and using the same rectangle as the
+ destination rectangle of this method, will affect exactly the
+ same set of pixel.
+
+ @param drawMode
+ Draw mode to use when changing pixel values
+
+ @param rClip
+ Clip mask to use. Pixel where the corresponding clip mask
+ pixel is 1 will not be modified.
+ */
+ void drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+protected:
+ BitmapDevice( const basegfx::B2IRange& rBounds,
+ sal_Int32 nScanlineFormat,
+ sal_Int32 nScanlineStride,
+ sal_uInt8* pFirstScanline,
+ const RawMemorySharedArray& rMem,
+ const PaletteMemorySharedVector& rPalette );
+
+ virtual ~BitmapDevice();
+
+private:
+ virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const = 0;
+ virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const = 0;
+ virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const = 0;
+
+ virtual void clear_i( Color fillColor,
+ const basegfx::B2IRange& rBounds ) = 0;
+
+ virtual void setPixel_i( const basegfx::B2IPoint& rPt,
+ Color lineColor,
+ DrawMode drawMode ) = 0;
+ virtual void setPixel_i( const basegfx::B2IPoint& rPt,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ virtual Color getPixel_i( const basegfx::B2IPoint& rPt ) = 0;
+
+ virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt ) = 0;
+
+ virtual void drawLine_i( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ const basegfx::B2IRange& rBounds,
+ Color lineColor,
+ DrawMode drawMode ) = 0;
+ virtual void drawLine_i( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ const basegfx::B2IRange& rBounds,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ virtual void drawPolygon_i( const basegfx::B2DPolygon& rPoly,
+ const basegfx::B2IRange& rBounds,
+ Color lineColor,
+ DrawMode drawMode ) = 0;
+ virtual void drawPolygon_i( const basegfx::B2DPolygon& rPoly,
+ const basegfx::B2IRange& rBounds,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ virtual void fillPolyPolygon_i( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode,
+ const basegfx::B2IRange& rBounds ) = 0;
+ virtual void fillPolyPolygon_i( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode,
+ const basegfx::B2IRange& rBounds,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ // must work with *this == rSrcBitmap!
+ virtual void drawBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode ) = 0;
+ virtual void drawBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ // must work with *this == rSrcBitmap!
+ virtual void drawMaskedColor_i( Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint ) = 0;
+ virtual void drawMaskedColor_i( Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ // must work with *this == rSrcBitmap!
+ virtual void drawMaskedBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode ) = 0;
+ virtual void drawMaskedBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ BitmapDeviceSharedPtr getGenericRenderer() const;
+
+ boost::scoped_ptr< ImplBitmapDevice > mpImpl;
+};
+
+/** Factory method to create a BitmapDevice for given scanline format
+ */
+BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
+ bool bTopDown,
+ sal_Int32 nScanlineFormat );
+
+/** Factory method to create a BitmapDevice for given scanline format
+ with the given palette
+
+ Note: the provided palette must have sufficient size, to satisfy
+ lookups for the whole range of pixel values from the specified
+ format.
+ */
+BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
+ bool bTopDown,
+ sal_Int32 nScanlineFormat,
+ const PaletteMemorySharedVector& rPalette );
+
+/** Factory method to create a BitmapDevice for given scanline format
+ from the given piece of raw memory and palette
+
+ Note: the provided memory must have sufficient size, to store the
+ image of the specified area and format.
+ */
+BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
+ bool bTopDown,
+ sal_Int32 nScanlineFormat,
+ const RawMemorySharedArray& rMem,
+ const PaletteMemorySharedVector& rPalette );
+
+
+/** Factory method to retrieve a subsetted BitmapDevice to the same
+ memory.
+
+ This method creates a second bitmap device instance, which renders
+ to the same memory as the original, but to a limited, rectangular
+ area. Useful to implement rectangular clips (usually faster than
+ setting up a 1bpp clip mask).
+ */
+BitmapDeviceSharedPtr subsetBitmapDevice( const BitmapDeviceSharedPtr& rProto,
+ const basegfx::B2IRange& rSubset );
+
+/** Factory method to clone a BitmapDevice from a given prototype.
+
+ All attributes (like scanline format and top-down state) are
+ copied, only the size can be varied. Note that the prototype's
+ bitmap content is <em>not</em> copied, only a palette (if any).
+ */
+BitmapDeviceSharedPtr cloneBitmapDevice( const basegfx::B2IVector& rSize,
+ const BitmapDeviceSharedPtr& rProto );
+
+}
+
+#endif /* INCLUDED_BASEBMP_BITMAPDEVICE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/clippedlinerenderer.hxx b/basebmp/inc/basebmp/clippedlinerenderer.hxx
new file mode 100644
index 000000000000..e023581416d6
--- /dev/null
+++ b/basebmp/inc/basebmp/clippedlinerenderer.hxx
@@ -0,0 +1,415 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_CLIPPEDLINERENDERER_HXX
+#define INCLUDED_BASEBMP_CLIPPEDLINERENDERER_HXX
+
+#include <basegfx/tools/rectcliptools.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+#include <basegfx/range/b2irange.hxx>
+
+#include <vigra/diff2d.hxx>
+#include <vigra/iteratortraits.hxx>
+
+namespace basebmp
+{
+
+// factored-out bresenham setup code, which is used from two different
+// places in renderClippedLine() below. Admittedly messy for the long
+// parameter list...
+inline bool prepareClip( sal_Int32 a1,
+ sal_Int32 a2,
+ sal_Int32 b1,
+ sal_Int32 da,
+ sal_Int32 db,
+ sal_Int32& o_as,
+ sal_Int32& o_bs,
+ int sa,
+ int sb,
+ sal_Int32& io_rem,
+ int& o_n,
+ sal_uInt32 clipCode1,
+ sal_uInt32 clipCount1,
+ sal_uInt32 clipCode2,
+ sal_uInt32 clipCount2,
+ sal_Int32 aMin,
+ sal_uInt32 aMinFlag,
+ sal_Int32 aMax,
+ sal_uInt32 aMaxFlag,
+ sal_Int32 bMin,
+ sal_uInt32 bMinFlag,
+ sal_Int32 bMax,
+ sal_uInt32 bMaxFlag,
+ bool bRoundTowardsPt2 )
+{
+ int ca(0), cb(0);
+ if( clipCode1 )
+ {
+ if( clipCode1 & aMinFlag )
+ {
+ ca = 2*db*(aMin - a1);
+ o_as = aMin;
+ }
+ else if( clipCode1 & aMaxFlag )
+ {
+ ca = 2*db*(a1 - aMax);
+ o_as = aMax;
+ }
+
+ if( clipCode1 & bMinFlag )
+ {
+ cb = 2*da*(bMin - b1);
+ o_bs = bMin;
+ }
+ else if( clipCode1 & bMaxFlag )
+ {
+ cb = 2*da*(b1 - bMax);
+ o_bs = bMax;
+ }
+
+ if( clipCount1 == 2 )
+ clipCode1 &= (ca + da < cb + !bRoundTowardsPt2) ? ~(aMinFlag|aMaxFlag) : ~(bMinFlag|bMaxFlag);
+
+ if( clipCode1 & (aMinFlag|aMaxFlag) )
+ {
+ cb = (ca + da - !bRoundTowardsPt2) / (2*da);
+
+ if( sb >= 0 )
+ {
+ o_bs = b1 + cb;
+ if( o_bs > bMax )
+ return false;
+ }
+ else
+ {
+ o_bs = b1 - cb;
+ if( o_bs < bMin )
+ return false;
+ }
+
+ io_rem += ca - 2*da*cb;
+ }
+ else
+ {
+ ca = (cb - da + 2*db - bRoundTowardsPt2) / (2*db);
+ if( sa >= 0 )
+ {
+ o_as = a1 + ca;
+ if( o_as > aMax )
+ return false;
+ }
+ else
+ {
+ o_as = a1 - ca;
+ if( o_as < aMin )
+ return false;
+ }
+
+ io_rem += 2*db*ca - cb;
+ }
+ }
+ else
+ {
+ o_as = a1; o_bs = b1;
+ }
+
+ bool bRetVal = false;
+ if( clipCode2 )
+ {
+ if( clipCount2 == 2 )
+ {
+ ca = 2*db*((clipCode2 & aMinFlag) ? a1 - aMin : aMax - a1);
+ cb = 2*da*((clipCode2 & bMinFlag) ? b1 - bMin : bMax - b1);
+ clipCode2 &= (cb + da < ca + bRoundTowardsPt2) ? ~(aMinFlag|aMaxFlag) : ~(bMinFlag|bMaxFlag);
+ }
+
+ if( clipCode2 & (aMinFlag|aMaxFlag) )
+ o_n = (clipCode2 & aMinFlag) ? o_as - aMin : aMax - o_as;
+ else
+ {
+ o_n = (clipCode2 & bMinFlag) ? o_bs - bMin : bMax - o_bs;
+ bRetVal = true;
+ }
+ }
+ else
+ o_n = (a2 >= o_as) ? a2 - o_as : o_as - a2;
+
+ return bRetVal;
+}
+
+
+/** Render line to image iterators, clip against given rectangle
+
+ This method renders a line from aPt1 to aPt2, clipped against
+ rClipRect (the clipping will take place pixel-perfect, i.e. as if
+ the original bresenham-rendered line would have been clipped each
+ pixel individually. No slight shifts compared to unclipped lines).
+
+ @param aPt1
+ Start point of the line
+
+ @param aPt2
+ End point of the line
+
+ @param rClipRect
+ Rectangle to clip against
+
+ @param color
+ Color value to render the line with
+
+ @param begin
+ left-top image iterator
+
+ @param end
+ right-bottom image iterator
+
+ @param acc
+ Image accessor
+
+ @param bRoundTowardsPt2
+ Rounding mode to use. Giving false here results in line pixel tend
+ towards pt1, i.e. when a pixel exactly hits the middle between two
+ pixel, the pixel closer to pt1 will be chosen. Giving true here
+ makes renderClippedLine() choose pt2 in those cases.
+ */
+template< class Iterator, class Accessor >
+void renderClippedLine( basegfx::B2IPoint aPt1,
+ basegfx::B2IPoint aPt2,
+ const basegfx::B2IRange& rClipRect,
+ typename Accessor::value_type color,
+ Iterator begin,
+ Accessor acc,
+ bool bRoundTowardsPt2=false )
+{
+ // Algorithm according to Steven Eker's 'Pixel-perfect line clipping',
+ // Graphics Gems V, pp. 314-322
+ sal_uInt32 clipCode1 = basegfx::tools::getCohenSutherlandClipFlags(aPt1,
+ rClipRect);
+ sal_uInt32 clipCode2 = basegfx::tools::getCohenSutherlandClipFlags(aPt2,
+ rClipRect);
+
+ if( clipCode1 & clipCode2 )
+ return; // line fully clipped away
+
+ sal_uInt32 clipCount1 = basegfx::tools::getNumberOfClipPlanes(clipCode1);
+ sal_uInt32 clipCount2 = basegfx::tools::getNumberOfClipPlanes(clipCode2);
+
+ if( (clipCode1 != 0 && clipCode2 == 0)
+ || (clipCount1 == 2 && clipCount2 == 1) )
+ {
+ std::swap(clipCount2,clipCount1);
+ std::swap(clipCode2,clipCode1);
+ std::swap(aPt1,aPt2);
+ bRoundTowardsPt2 = !bRoundTowardsPt2;
+ }
+
+ const sal_Int32 x1 = aPt1.getX();
+ const sal_Int32 x2 = aPt2.getX();
+ const sal_Int32 y1 = aPt1.getY();
+ const sal_Int32 y2 = aPt2.getY();
+
+ // TODO(E1): This might overflow
+ sal_Int32 adx = x2 - x1;
+ int sx = 1;
+ if( adx < 0 )
+ {
+ adx *= -1;
+ sx = -1;
+ }
+
+ // TODO(E1): This might overflow
+ sal_Int32 ady = y2 - y1;
+ int sy = 1;
+ if( ady < 0 )
+ {
+ ady *= -1;
+ sy = -1;
+ }
+
+ int n = 0;
+ sal_Int32 xs = x1;
+ sal_Int32 ys = y1;
+ if( adx >= ady )
+ {
+ // semi-horizontal line
+ sal_Int32 rem = 2*ady - adx - !bRoundTowardsPt2;
+
+ const bool bUseAlternateBresenham(
+ prepareClip(x1, x2, y1, adx, ady, xs, ys, sx, sy,
+ rem, n, clipCode1, clipCount1, clipCode2, clipCount2,
+ rClipRect.getMinX(), basegfx::tools::RectClipFlags::LEFT,
+ rClipRect.getMaxX(), basegfx::tools::RectClipFlags::RIGHT,
+ rClipRect.getMinY(), basegfx::tools::RectClipFlags::TOP,
+ rClipRect.getMaxY(), basegfx::tools::RectClipFlags::BOTTOM,
+ bRoundTowardsPt2 ));
+
+ Iterator currIter( begin + vigra::Diff2D(0,ys) );
+ typename vigra::IteratorTraits<Iterator>::row_iterator
+ rowIter( currIter.rowIterator() + xs );
+
+ adx *= 2;
+ ady *= 2;
+
+ if( bUseAlternateBresenham )
+ {
+ while(true)
+ {
+ acc.set(color, rowIter);
+
+ if( rem >= 0 )
+ {
+ if( --n < 0 )
+ break;
+
+ ys += sy;
+ xs += sx;
+ rem -= adx;
+
+ currIter.y += sy;
+ rowIter = currIter.rowIterator() + xs;
+ }
+ else
+ {
+ xs += sx;
+ rowIter += sx;
+ }
+
+ rem += ady;
+ }
+ }
+ else
+ {
+ while(true)
+ {
+ acc.set(color, rowIter);
+
+ if( --n < 0 )
+ break;
+
+ if( rem >= 0 )
+ {
+ ys += sy;
+ xs += sx;
+ rem -= adx;
+
+ currIter.y += sy;
+ rowIter = currIter.rowIterator() + xs;
+ }
+ else
+ {
+ xs += sx;
+ rowIter += sx;
+ }
+
+ rem += ady;
+ }
+ }
+ }
+ else
+ {
+ // semi-vertical line
+ sal_Int32 rem = 2*adx - ady - !bRoundTowardsPt2;
+
+ const bool bUseAlternateBresenham(
+ prepareClip(y1, y2, x1, ady, adx, ys, xs, sy, sx,
+ rem, n, clipCode1, clipCount1, clipCode2, clipCount2,
+ rClipRect.getMinY(), basegfx::tools::RectClipFlags::TOP,
+ rClipRect.getMaxY(), basegfx::tools::RectClipFlags::BOTTOM,
+ rClipRect.getMinX(), basegfx::tools::RectClipFlags::LEFT,
+ rClipRect.getMaxX(), basegfx::tools::RectClipFlags::RIGHT,
+ bRoundTowardsPt2 ));
+
+ Iterator currIter( begin + vigra::Diff2D(xs,0) );
+ typename vigra::IteratorTraits<Iterator>::column_iterator
+ colIter( currIter.columnIterator() + ys );
+
+ adx *= 2;
+ ady *= 2;
+
+ if( bUseAlternateBresenham )
+ {
+ while(true)
+ {
+ acc.set(color, colIter);
+
+ if( rem >= 0 )
+ {
+ if( --n < 0 )
+ break;
+
+ xs += sx;
+ ys += sy;
+ rem -= ady;
+
+ currIter.x += sx;
+ colIter = currIter.columnIterator() + ys;
+ }
+ else
+ {
+ ys += sy;
+ colIter += sy;
+ }
+
+ rem += adx;
+ }
+ }
+ else
+ {
+ while(true)
+ {
+ acc.set(color, colIter);
+
+ if( --n < 0 )
+ break;
+
+ if( rem >= 0 )
+ {
+ xs += sx;
+ ys += sy;
+ rem -= ady;
+
+ currIter.x += sx;
+ colIter = currIter.columnIterator() + ys;
+ }
+ else
+ {
+ ys += sy;
+ colIter += sy;
+ }
+
+ rem += adx;
+ }
+ }
+ }
+}
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_CLIPPEDLINERENDERER_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/color.hxx b/basebmp/inc/basebmp/color.hxx
new file mode 100644
index 000000000000..1bd70198a280
--- /dev/null
+++ b/basebmp/inc/basebmp/color.hxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_COLOR_HXX
+#define INCLUDED_BASEBMP_COLOR_HXX
+
+#include <sal/types.h>
+#include <rtl/math.hxx>
+
+namespace basebmp
+{
+
+class Color
+{
+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 ) :
+ mnColor( ((sal_uInt32)nRed << 16) | ((sal_uInt32)nGreen << 8) | nBlue )
+ {}
+
+ void setRed( sal_uInt8 nRed ) { mnColor &= ~0x00FF0000UL; mnColor |= (sal_uInt32)nRed << 16; }
+ void setGreen( sal_uInt8 nGreen ) { mnColor &= ~0x0000FF00UL; mnColor |= (sal_uInt32)nGreen << 8; }
+ void setBlue( sal_uInt8 nBlue ) { mnColor &= ~0x000000FFUL; mnColor |= nBlue; }
+
+ void setGrey( sal_uInt8 nGreyVal ) { mnColor = (sal_uInt32)nGreyVal << 16 | (sal_uInt32)nGreyVal << 8 | nGreyVal; }
+
+ sal_uInt8 getRed() const { return 0xFF & (sal_uInt8)(mnColor >> 16); }
+ sal_uInt8 getGreen() const { return 0xFF & (sal_uInt8)(mnColor >> 8); }
+ sal_uInt8 getBlue() const { return 0xFF & (sal_uInt8)mnColor; }
+
+ sal_uInt8 getGreyscale() const { return (sal_uInt8)((getBlue()*28UL +
+ getGreen()*151 +
+ getRed()*77) / 256); }
+
+ sal_uInt32 toInt32() const { return mnColor; }
+
+ bool operator!() const { return mnColor == 0; }
+ Color operator&( sal_uInt32 nMask ) const { return Color(mnColor & nMask); }
+ Color operator^( Color col ) const { return Color(col.getRed()^getRed(),
+ col.getGreen()^getGreen(),
+ col.getBlue()^getBlue()); }
+ Color operator-( Color col ) const { return Color((sal_uInt8)abs((int)getRed()-col.getRed()),
+ (sal_uInt8)abs((int)getGreen()-col.getGreen()),
+ (sal_uInt8)abs((int)getBlue()-col.getBlue())); }
+ Color operator+( Color col ) const { return Color(getRed()+col.getRed(),
+ getGreen()+col.getGreen(),
+ getBlue()+col.getBlue()); }
+ Color operator*( Color col ) const { return Color((sal_uInt8)((sal_uInt32)col.getRed()*getRed()/SAL_MAX_UINT8),
+ (sal_uInt8)((sal_uInt32)col.getGreen()*getGreen()/SAL_MAX_UINT8),
+ (sal_uInt8)((sal_uInt32)col.getBlue()*getBlue()/SAL_MAX_UINT8)); }
+ Color operator*( sal_uInt8 n ) const { return Color((sal_uInt8)((sal_uInt32)n*getRed()/SAL_MAX_UINT8),
+ (sal_uInt8)((sal_uInt32)n*getGreen()/SAL_MAX_UINT8),
+ (sal_uInt8)((sal_uInt32)n*getBlue()/SAL_MAX_UINT8)); }
+ Color operator*( double n ) const { return Color((sal_uInt8)(n*getRed()+.5),
+ (sal_uInt8)(n*getGreen()+.5),
+ (sal_uInt8)(n*getBlue()+.5)); }
+ bool operator==( const Color& rhs ) const { return (getRed()==rhs.getRed() &&
+ getGreen()==rhs.getGreen() &&
+ getBlue()==rhs.getBlue()); }
+ bool operator!=( const Color& rhs ) const { return !(*this==rhs); }
+ double magnitude() const { return sqrt((double)getRed()*getRed()
+ + getGreen()*getGreen()
+ + getBlue()*getBlue()); }
+};
+
+} // namespace vigra
+
+#endif /* INCLUDED_BASEBMP_COLOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/colorblendaccessoradapter.hxx b/basebmp/inc/basebmp/colorblendaccessoradapter.hxx
new file mode 100644
index 000000000000..4bb913500bd9
--- /dev/null
+++ b/basebmp/inc/basebmp/colorblendaccessoradapter.hxx
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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 other
+ sensible default behaviour for these methods.
+ */
+template< class WrappedAccessor,
+ typename AlphaType,
+ bool polarity > 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,polarity>::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 */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/colormisc.hxx b/basebmp/inc/basebmp/colormisc.hxx
new file mode 100644
index 000000000000..96a312c251ae
--- /dev/null
+++ b/basebmp/inc/basebmp/colormisc.hxx
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_COLORMISC_HXX
+#define INCLUDED_BASEBMP_COLORMISC_HXX
+
+#include <osl/diagnose.h>
+#include <basebmp/color.hxx>
+#include <basebmp/colortraits.hxx>
+#include <basebmp/accessortraits.hxx>
+#include <vigra/mathutil.hxx>
+
+// Contents of this header moved out of color.hxx, as it is not useful
+// for the general public (drags in vigra and other template
+// functionality, that shouldn't be necessary for the ordinary client
+// of BitmapDevice etc.)
+
+namespace basebmp
+{
+
+template< bool polarity > struct ColorBitmaskOutputMaskFunctor;
+template<> struct ColorBitmaskOutputMaskFunctor<true> : MaskFunctorBase<Color,sal_uInt8>
+{
+ 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);
+ }
+};
+template<> struct ColorBitmaskOutputMaskFunctor<false> : MaskFunctorBase<Color,sal_uInt8>
+{
+ Color operator()( Color v1, sal_uInt8 m, Color v2 ) const
+ {
+ OSL_ASSERT(m<=1);
+
+ return Color(v1.toInt32()*m + v2.toInt32()*(sal_uInt8)(1-m));
+ }
+};
+
+/// Specialized output mask functor for Color value type
+template<bool polarity> struct outputMaskFunctorSelector< Color, sal_uInt8, polarity, FastMask >
+{
+ typedef ColorBitmaskOutputMaskFunctor<polarity> type;
+};
+
+template< bool polarity > struct ColorBlendFunctor8
+ : public TernaryFunctorBase<sal_uInt8,Color,Color,Color>
+{
+ Color operator()( sal_uInt8 alpha,
+ Color v1,
+ Color v2 ) const
+ {
+ alpha = polarity ? alpha : 255 - alpha;
+
+ const sal_uInt8 v1_red( v1.getRed() );
+ const sal_uInt8 v1_green( v1.getGreen() );
+ const sal_uInt8 v1_blue( v1.getBlue() );
+
+ // using '>> 8' instead of '/ 0x100' is ill-advised (shifted
+ // value might be negative). Better rely on decent optimizer
+ // here...
+ return Color(((((sal_Int32)v2.getRed() - v1_red)*alpha) / 0x100) + v1_red,
+ ((((sal_Int32)v2.getGreen() - v1_green)*alpha) / 0x100) + v1_green,
+ ((((sal_Int32)v2.getBlue() - v1_blue)*alpha) / 0x100) + v1_blue);
+ }
+};
+
+template< bool polarity > struct ColorBlendFunctor32
+ : public TernaryFunctorBase<Color,Color,Color,Color>
+{
+ Color operator()( Color input,
+ Color v1,
+ Color v2 ) const
+ {
+ sal_uInt8 alpha = input.getGreyscale();
+ alpha = polarity ? alpha : 255 - alpha;
+
+ const sal_uInt8 v1_red( v1.getRed() );
+ const sal_uInt8 v1_green( v1.getGreen() );
+ const sal_uInt8 v1_blue( v1.getBlue() );
+
+ // using '>> 8' instead of '/ 0x100' is ill-advised (shifted
+ // value might be negative). Better rely on decent optimizer
+ // here...
+ return Color(((((sal_Int32)v2.getRed() - v1_red)*alpha) / 0x100) + v1_red,
+ ((((sal_Int32)v2.getGreen() - v1_green)*alpha) / 0x100) + v1_green,
+ ((((sal_Int32)v2.getBlue() - v1_blue)*alpha) / 0x100) + v1_blue);
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+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, bool polarity > struct blend_functor;
+
+ /// Calculate normalized distance between color c1 and c2
+ static inline double distance( const Color& c1,
+ const Color& c2 )
+ {
+ return (c1 - c2).magnitude();
+ }
+
+ static inline component_type toGreyscale( const Color& c )
+ {
+ return c.getGreyscale();
+ }
+
+ static inline Color fromGreyscale( component_type c )
+ {
+ return Color(c,c,c);
+ }
+};
+
+/// The version for plain 8 bit alpha
+template<bool polarity> struct ColorTraits< Color >::blend_functor< sal_uInt8, polarity >
+{
+ typedef ColorBlendFunctor8<polarity> type;
+};
+
+/// The version taking grey value of a Color
+template<bool polarity> struct ColorTraits< Color >::blend_functor< Color, polarity >
+{
+ typedef ColorBlendFunctor32<polarity> type;
+};
+
+} // namespace basebmp
+
+namespace vigra
+{
+
+template<>
+struct NumericTraits<basebmp::Color>
+{
+ typedef basebmp::Color Type;
+ typedef basebmp::Color Promote;
+ typedef basebmp::Color RealPromote;
+ typedef std::complex<basebmp::Color> ComplexPromote;
+ typedef sal_uInt8 ValueType;
+
+ typedef VigraTrueType isIntegral;
+ typedef VigraFalseType isScalar;
+ typedef VigraTrueType isSigned;
+ typedef VigraTrueType isOrdered;
+ typedef VigraFalseType isComplex;
+
+ static Type zero() { return Type(); }
+ static Type one() { return Type(0x01010101); }
+ static Type nonZero() { return Type(0x01010101); }
+
+ static Promote toPromote(const Type& v) { return v; }
+ static RealPromote toRealPromote(const Type& v) { return v; }
+ static Type fromPromote(const Promote& v) { return v; }
+ static Type fromRealPromote(const RealPromote& v) { return v; }
+};
+
+} // namespace vigra
+
+#endif /* INCLUDED_BASEBMP_COLORMISC_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/colortraits.hxx b/basebmp/inc/basebmp/colortraits.hxx
new file mode 100644
index 000000000000..ba6a4cfeee27
--- /dev/null
+++ b/basebmp/inc/basebmp/colortraits.hxx
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_COLORTRAITS_HXX
+#define INCLUDED_BASEBMP_COLORTRAITS_HXX
+
+#include <basebmp/accessoradapters.hxx>
+#include <basebmp/metafunctions.hxx>
+
+#include <vigra/mathutil.hxx>
+
+namespace basebmp
+{
+
+/** Functor template, to calculate alpha blending between two
+ values. Float case.
+
+ @tpl polarity
+ When true, 0 means fully transparent, and 1 fully opaque. And vice
+ versa.
+ */
+template< typename ValueType,
+ typename AlphaType,
+ bool polarity > struct BlendFunctor;
+template< typename ValueType,
+ typename AlphaType > struct BlendFunctor<ValueType,AlphaType,true>
+ : public TernaryFunctorBase<AlphaType,ValueType,ValueType,ValueType>
+{
+ 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 BlendFunctor<ValueType,AlphaType,false>
+ : public TernaryFunctorBase<AlphaType,ValueType,ValueType,ValueType>
+{
+ ValueType operator()( AlphaType alpha,
+ ValueType v1,
+ ValueType v2 ) const
+ {
+ const typename vigra::NumericTraits<AlphaType>::RealPromote fAlpha(
+ vigra::NumericTraits<AlphaType>::toRealPromote(alpha));
+ return fAlpha*v1 + (vigra::NumericTraits<AlphaType>::one()-fAlpha)*v2;
+ }
+};
+
+/** Functor template, to calculate alpha blending between two
+ values. Integer case.
+
+ @tpl polarity
+ When true, 0 means fully transparent, and 1 fully opaque. And vice
+ versa.
+ */
+template< typename ValueType,
+ typename AlphaType,
+ bool polarity > struct IntegerBlendFunctor;
+template< typename ValueType,
+ typename AlphaType > struct IntegerBlendFunctor<ValueType,AlphaType,true>
+ : public TernaryFunctorBase<AlphaType,ValueType,ValueType,ValueType>
+{
+ 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 ValueType,
+ typename AlphaType > struct IntegerBlendFunctor<ValueType,AlphaType,false>
+ : public TernaryFunctorBase<AlphaType,ValueType,ValueType,ValueType>
+{
+ ValueType operator()( AlphaType alpha,
+ ValueType v1,
+ ValueType v2 ) const
+ {
+ return (alpha*v1 +
+ vigra::NumericTraits<AlphaType>::toPromote(
+ vigra::NumericTraits<AlphaType>::max()-alpha)*v2) /
+ vigra::NumericTraits<AlphaType>::max();
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+template< typename ColorType > struct ColorTraits
+{
+ /// Metafunction to select blend functor from color and alpha type
+ template< typename AlphaType, bool polarity > struct blend_functor : public
+ ifScalarIntegral< AlphaType,
+ IntegerBlendFunctor< ColorType, AlphaType, polarity >,
+ BlendFunctor< ColorType, AlphaType, polarity > > {};
+
+ /// @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 inline vigra::NormTraits<ColorType> distance( ColorType c1,
+ ColorType c2 )
+ {
+ return vigra::norm(c1 - c2);
+ }
+
+ static inline component_type toGreyscale( ColorType c )
+ {
+ return c;
+ }
+
+ static inline ColorType fromGreyscale( component_type c )
+ {
+ return c;
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_COLORTRAITS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/compositeiterator.hxx b/basebmp/inc/basebmp/compositeiterator.hxx
new file mode 100644
index 000000000000..e64cf0d8c093
--- /dev/null
+++ b/basebmp/inc/basebmp/compositeiterator.hxx
@@ -0,0 +1,370 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX
+#define INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX
+
+#include <sal/types.h>
+#include <osl/diagnose.h>
+
+#include <basebmp/nonstandarditerator.hxx>
+#include <vigra/tuple.hxx>
+#include <vigra/iteratortraits.hxx>
+
+
+namespace basebmp
+{
+
+namespace detail
+{
+ template< typename T1, typename T2 > class ArithmeticProxy
+ {
+ public:
+ ArithmeticProxy(T1& val1, T2& val2) :
+ mpVal1( &val1 ),
+ mpVal2( &val2 )
+ {}
+
+ void operator++() { ++(*mpVal1); ++(*mpVal2); }
+ void operator++(int) { (*mpVal1)++; (*mpVal2)++; }
+ void operator--() { --(*mpVal1); --(*mpVal2); }
+ void operator--(int) { (*mpVal1)--; (*mpVal2)--; }
+ void operator+=(int d) {*mpVal1+=d; *mpVal2+=d; }
+ void operator-=(int d) {*mpVal1-=d; *mpVal2-=d; }
+
+ bool operator==(ArithmeticProxy const & rhs) const
+ { return *mpVal1==*rhs.mpVal1 && *mpVal2==*rhs.mpVal2; }
+
+ bool operator!=(ArithmeticProxy const & rhs) const
+ { return *mpVal1!=*rhs.mpVal1 || *mpVal2!=*rhs.mpVal2; }
+
+ bool operator<(ArithmeticProxy const & rhs) const
+ { return *mpVal1<*rhs.mpVal1 && *mpVal2<*rhs.mpVal2; }
+
+ bool operator<=(ArithmeticProxy const & rhs) const
+ { return *mpVal1<=*rhs.mpVal1 && *mpVal2<=*rhs.mpVal2; }
+
+ bool operator>(ArithmeticProxy const & rhs) const
+ { return *mpVal1>*rhs.mpVal1 && *mpVal2>*rhs.mpVal2; }
+
+ bool operator>=(ArithmeticProxy const & rhs) const
+ { return *mpVal1>=*rhs.mpVal1 && *mpVal2>=*rhs.mpVal2; }
+
+ int operator-(ArithmeticProxy const & rhs) const
+ { return *mpVal1 - *rhs.mpVal1; }
+
+ private:
+ T1* mpVal1;
+ T2* mpVal2;
+ };
+
+ template< typename Iterator1,
+ typename Iterator2,
+ typename ValueType,
+ typename DifferenceType,
+ typename IteratorCategory,
+ class Derived >
+ class CompositeIteratorBase : public NonStandardIterator
+ {
+ public:
+ typedef Iterator1 iterator1_type;
+ typedef Iterator2 iterator2_type;
+ typedef ValueType value_type;
+ typedef DifferenceType difference_type;
+ typedef IteratorCategory iterator_category;
+
+ protected:
+ iterator1_type maIter1;
+ iterator2_type maIter2;
+
+ private:
+ bool equal(CompositeIteratorBase const & rhs) const
+ {
+ return (maIter1 == rhs.maIter1) && (maIter2 == rhs.maIter2);
+ }
+
+ public:
+ CompositeIteratorBase() :
+ maIter1(),
+ maIter2()
+ {}
+
+ CompositeIteratorBase( const iterator1_type& rIter1, const iterator2_type& rIter2 ) :
+ maIter1( rIter1 ),
+ maIter2( rIter2 )
+ {}
+
+ bool operator==(Derived const & rhs) const
+ {
+ return equal(rhs);
+ }
+
+ bool operator!=(Derived const & rhs) const
+ {
+ return !equal(rhs);
+ }
+
+ difference_type operator-(Derived const & rhs) const
+ {
+ OSL_ASSERT( maIter1 - rhs.maIter1 == maIter2 - rhs.maIter2 );
+ return maIter1 - rhs.maIter1;
+ }
+
+ Derived & operator+=(difference_type const & s)
+ {
+ maIter1 += s;
+ maIter2 += s;
+ return static_cast<Derived&>(*this);
+ }
+
+ Derived & operator-=(difference_type const & s)
+ {
+ maIter1 -= s;
+ maIter2 -= s;
+ return static_cast<Derived&>(*this);
+ }
+
+ Derived operator+(difference_type const & s) const
+ {
+ Derived ret(static_cast<Derived const&>(*this));
+ ret += s;
+ return ret;
+ }
+
+ Derived operator-(difference_type const & s) const
+ {
+ Derived ret(static_cast<Derived const&>(*this));
+ ret -= s;
+ return ret;
+ }
+
+ Derived& operator++()
+ {
+ ++maIter1;
+ ++maIter2;
+ return static_cast<Derived&>(*this);
+ }
+
+ Derived& operator--()
+ {
+ --maIter1;
+ --maIter2;
+ return static_cast<Derived&>(*this);
+ }
+
+ Derived operator++(int)
+ {
+ Derived ret(static_cast<Derived const&>(*this));
+ ++maIter1;
+ ++maIter2;
+ return ret;
+ }
+
+ Derived operator--(int)
+ {
+ Derived ret(static_cast<Derived const&>(*this));
+ --maIter1;
+ --maIter2;
+ return ret;
+ }
+
+ value_type get() const
+ {
+ return value_type(maIter1.get(),
+ maIter2.get());
+ }
+
+ value_type get(difference_type const & d) const
+ {
+ return value_type(maIter1.get(d),
+ maIter2.get(d));
+ }
+
+ void set( value_type v ) const
+ {
+ maIter1.set(v);
+ maIter2.set(v);
+ }
+
+ void set( value_type v, difference_type const & d ) const
+ {
+ maIter1.set(v,d);
+ maIter2.set(v,d);
+ }
+
+ const iterator1_type& first() const { return maIter1; }
+ iterator1_type& first() { return maIter1; }
+
+ const iterator2_type& second() const { return maIter2; }
+ iterator2_type& second() { return maIter2; }
+ };
+}
+
+/** Provide the composition of two 1D image iterators
+
+ Use this template to compose two iterators into one (e.g. image
+ and mask). Operations are transitive, e.g. operator== only returns
+ true, if both wrapped iterator operator== have yielded true.
+
+ Note that both iterators must have compatible difference types. To
+ avoid funny effects, iterator ranges given by a CompositeIterator
+ should consist of wrapped iterators of similar range
+ */
+template< typename Iterator1,
+ typename Iterator2,
+ typename ValueType,
+ typename DifferenceType,
+ typename IteratorCategory >
+class CompositeIterator1D :
+ public detail::CompositeIteratorBase< Iterator1,
+ Iterator2,
+ ValueType,
+ DifferenceType,
+ IteratorCategory,
+ CompositeIterator1D<Iterator1,
+ Iterator2,
+ ValueType,
+ DifferenceType,
+ IteratorCategory> >
+{
+ typedef detail::CompositeIteratorBase< Iterator1,
+ Iterator2,
+ ValueType,
+ DifferenceType,
+ IteratorCategory,
+ CompositeIterator1D<Iterator1,
+ Iterator2,
+ ValueType,
+ DifferenceType,
+ IteratorCategory> > base_type;
+public:
+ CompositeIterator1D() :
+ base_type()
+ {}
+
+ CompositeIterator1D( const Iterator1& rIter1,
+ const Iterator2& rIter2 ) :
+ base_type( rIter1, rIter2 )
+ {}
+};
+
+/** Provide the composition of two 2D image iterators
+
+ Use this template to compose two iterators into one (e.g. image
+ and mask). Operations are transitive, e.g. operator== only returns
+ true, if both wrapped iterator operator== have yielded true.
+
+ Note that both iterators must have compatible difference types. To
+ avoid funny effects, iterator ranges given by a CompositeIterator
+ should consist of wrapped iterators of similar range
+ */
+template< typename Iterator1, typename Iterator2 > class CompositeIterator2D :
+ public detail::CompositeIteratorBase< Iterator1,
+ Iterator2,
+ std::pair<
+ typename vigra::IteratorTraits<Iterator1>::value_type,
+ typename vigra::IteratorTraits<Iterator2>::value_type >,
+ typename vigra::IteratorTraits<Iterator1>::difference_type,
+ typename vigra::IteratorTraits<Iterator1>::iterator_category,
+ CompositeIterator2D<Iterator1, Iterator2> >
+{
+ typedef detail::CompositeIteratorBase< Iterator1,
+ Iterator2,
+ std::pair<
+ typename vigra::IteratorTraits<Iterator1>::value_type,
+ typename vigra::IteratorTraits<Iterator2>::value_type >,
+ typename vigra::IteratorTraits<Iterator1>::difference_type,
+ typename vigra::IteratorTraits<Iterator1>::iterator_category,
+ CompositeIterator2D<Iterator1, Iterator2> > base_type;
+public:
+ typedef CompositeIterator1D< typename Iterator1::row_iterator,
+ typename Iterator2::row_iterator,
+ typename base_type::value_type,
+ int,
+ typename base_type::iterator_category > row_iterator;
+ typedef CompositeIterator1D< typename Iterator1::column_iterator,
+ typename Iterator2::column_iterator,
+ typename base_type::value_type,
+ int,
+ typename base_type::iterator_category > column_iterator;
+
+ typedef detail::ArithmeticProxy< typename Iterator1::MoveX,
+ typename Iterator2::MoveX > MoveX;
+ typedef detail::ArithmeticProxy< typename Iterator1::MoveY,
+ typename Iterator2::MoveY > MoveY;
+
+ MoveX x;
+ MoveY y;
+
+ CompositeIterator2D() :
+ base_type(),
+ x(this->maIter1.x,this->maIter2.x),
+ y(this->maIter1.y,this->maIter2.y)
+ {}
+
+ CompositeIterator2D( const Iterator1& rIter1, const Iterator2& rIter2 ) :
+ base_type( rIter1, rIter2 ),
+ x(this->maIter1.x,this->maIter2.x),
+ y(this->maIter1.y,this->maIter2.y)
+ {}
+
+ CompositeIterator2D( const CompositeIterator2D& rOld ) :
+ base_type(rOld),
+ x(this->maIter1.x,this->maIter2.x),
+ y(this->maIter1.y,this->maIter2.y)
+ {}
+
+ CompositeIterator2D& operator=( const CompositeIterator2D& rNew )
+ {
+ this->maIter1 = rNew.maIter1;
+ this->maIter2 = rNew.maIter2;
+
+ x = MoveX(this->maIter1.x,
+ this->maIter2.x);
+ y = MoveY(this->maIter1.y,
+ this->maIter2.y);
+ }
+
+ row_iterator rowIterator() const
+ {
+ return row_iterator(this->maIter1.rowIterator(),
+ this->maIter2.rowIterator());
+ }
+
+ column_iterator columnIterator() const
+ {
+ return column_iterator(this->maIter1.columnIterator(),
+ this->maIter2.columnIterator());
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/debug.hxx b/basebmp/inc/basebmp/debug.hxx
new file mode 100644
index 000000000000..c5660b9a6a74
--- /dev/null
+++ b/basebmp/inc/basebmp/debug.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_DEBUG_HXX
+#define INCLUDED_BASEBMP_DEBUG_HXX
+
+#include <iostream>
+#include <boost/shared_ptr.hpp>
+
+namespace basebmp
+{
+ class BitmapDevice;
+
+ /** Dump content of BitmapDevice to given output stream.
+
+ @param rDevice
+ Device whose content should be dumped.
+
+ @param rOutputStream
+ Stream to write output to.
+ */
+ void debugDump( const boost::shared_ptr< BitmapDevice >& rDevice,
+ ::std::ostream& rOutputStream );
+}
+
+#endif /* INCLUDED_BASEBMP_DEBUG_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/drawmodes.hxx b/basebmp/inc/basebmp/drawmodes.hxx
new file mode 100644
index 000000000000..7e59f81b6140
--- /dev/null
+++ b/basebmp/inc/basebmp/drawmodes.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_DRAWMODES_HXX
+#define INCLUDED_BASEBMP_DRAWMODES_HXX
+
+/* Definition of Draw modes */
+
+namespace basebmp
+{
+ enum DrawMode
+ {
+ /** Default draw mode, which simply renders pixel in the
+ requested color
+ */
+ DrawMode_PAINT,
+
+ /** XOR draw mode, which XORs each existing pixel value with
+ the new color.
+
+ The result of this XOR operation strongly depends on the
+ underlying pixel format, as it is defined by the bitwise
+ XOR of the (potentially palette-looked-up) color value and
+ the existing pixel content (being it true color or a
+ palette index).
+ */
+ DrawMode_XOR
+ };
+}
+
+#endif /* INCLUDED_BASEBMP_DRAWMODES_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/endian.hxx b/basebmp/inc/basebmp/endian.hxx
new file mode 100644
index 000000000000..03a0dbeb9fbf
--- /dev/null
+++ b/basebmp/inc/basebmp/endian.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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 */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/fillimage.hxx b/basebmp/inc/basebmp/fillimage.hxx
new file mode 100644
index 000000000000..d3809ecc0b6e
--- /dev/null
+++ b/basebmp/inc/basebmp/fillimage.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_FILLIMAGE_HXX
+#define INCLUDED_BASEBMP_FILLIMAGE_HXX
+
+#include <vigra/tuple.hxx>
+#include <vigra/iteratortraits.hxx>
+
+namespace basebmp
+{
+
+template< class DestIterator, class DestAccessor, typename T >
+void fillImage( DestIterator begin,
+ DestIterator end,
+ DestAccessor ad,
+ T fillVal )
+{
+ const int width ( end.x - begin.x );
+ const int height( end.y - begin.y );
+
+ for( int y=0; y<height; ++y, ++begin.y )
+ {
+ typename vigra::IteratorTraits<DestIterator>::row_iterator
+ rowIter( begin.rowIterator() );
+ const typename vigra::IteratorTraits<DestIterator>::row_iterator
+ rowEnd( rowIter + width );
+
+ // TODO(P2): Provide specialized span fill methods on the
+ // iterator/accessor
+ while( rowIter != rowEnd )
+ ad.set(fillVal, rowIter++);
+ }
+}
+
+template< class DestIterator, class DestAccessor, typename T >
+inline void fillImage( vigra::triple<DestIterator,DestIterator,DestAccessor> const& src,
+ T fillVal )
+{
+ fillImage(src.first,src.second,src.third,fillVal);
+}
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_FILLIMAGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/genericcolorimageaccessor.hxx b/basebmp/inc/basebmp/genericcolorimageaccessor.hxx
new file mode 100644
index 000000000000..2fada3948faf
--- /dev/null
+++ b/basebmp/inc/basebmp/genericcolorimageaccessor.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_GENERICCOLORIMAGEACCESSOR_HXX
+#define INCLUDED_BASEBMP_GENERICCOLORIMAGEACCESSOR_HXX
+
+#include <basebmp/color.hxx>
+#include <basebmp/bitmapdevice.hxx>
+
+namespace basebmp
+{
+ /** Access a BitmapDevice generically
+
+ This accessor deals with an opaque BitmapDevice generically,
+ via getPixel()/setPixel() at the published interface.
+ */
+ class GenericColorImageAccessor
+ {
+ BitmapDeviceSharedPtr mpDevice;
+ DrawMode meDrawMode;
+
+ public:
+ typedef Color value_type;
+
+ explicit GenericColorImageAccessor( BitmapDeviceSharedPtr const& rTarget ) :
+ mpDevice(rTarget),
+ meDrawMode(DrawMode_PAINT)
+ {}
+
+ GenericColorImageAccessor( BitmapDeviceSharedPtr const& rTarget,
+ DrawMode eDrawMode ) :
+ mpDevice(rTarget),
+ meDrawMode(eDrawMode)
+ {}
+
+ template< typename Iterator >
+ Color operator()( Iterator const& i ) const
+ { return mpDevice->getPixel( basegfx::B2IPoint( i->x,i->y ) ); }
+
+ template< typename Iterator, typename Difference >
+ Color operator()( Iterator const& i, Difference const& diff) const
+ { return mpDevice->getPixel( basegfx::B2IPoint( i[diff]->x,
+ i[diff]->y ) ); }
+
+ template< typename Iterator >
+ void set(Color const& value, Iterator const& i) const
+ { return mpDevice->setPixel( basegfx::B2IPoint( i->x,i->y ),
+ value, meDrawMode ); }
+
+ template< class Iterator, class Difference >
+ void set(value_type const& value, Iterator const& i, Difference const& diff) const
+ { return mpDevice->setPixel( basegfx::B2IPoint( i[diff]->x,
+ i[diff]->y ),
+ value, meDrawMode ); }
+ };
+}
+
+#endif /* INCLUDED_BASEBMP_GENERICCOLORIMAGEACCESSOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/greylevelformats.hxx b/basebmp/inc/basebmp/greylevelformats.hxx
new file mode 100644
index 000000000000..111fcc7e12fd
--- /dev/null
+++ b/basebmp/inc/basebmp/greylevelformats.hxx
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_GREYLEVELFORMATS_HXX
+#define INCLUDED_BASEBMP_GREYLEVELFORMATS_HXX
+
+#include <basebmp/color.hxx>
+#include <basebmp/colortraits.hxx>
+#include <basebmp/accessor.hxx>
+#include <basebmp/pixeliterator.hxx>
+#include <basebmp/packedpixeliterator.hxx>
+#include <basebmp/pixelformatadapters.hxx>
+#include <basebmp/metafunctions.hxx>
+
+#include <vigra/numerictraits.hxx>
+#include <vigra/metaprogramming.hxx>
+
+#include <functional>
+
+namespace basebmp
+{
+
+template< typename PixelType,
+ typename ColorType,
+ int UsedRange > struct GreylevelGetter :
+ public std::unary_function<PixelType, ColorType>
+{
+ ColorType operator()( PixelType const& c ) const
+ {
+ return ColorTraits<ColorType>::fromGreyscale(
+ vigra::NumericTraits<PixelType>::toPromote(c) *
+ vigra::NumericTraits<PixelType>::maxConst / UsedRange );
+ }
+};
+
+template< typename PixelType,
+ typename ColorType,
+ int UsedRange > struct GreylevelSetter :
+ public std::unary_function<ColorType, PixelType>
+{
+ PixelType operator()( ColorType const& c ) const
+ {
+ return vigra::NumericTraits<PixelType>::toPromote(
+ ColorTraits<ColorType>::toGreyscale(c)) *
+ UsedRange /
+ vigra::NumericTraits<PixelType>::maxConst;
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+template< class Iterator,
+ class Accessor,
+ int UsedRange > struct PixelFormatTraitsTemplate_Greylevel
+{
+ typedef typename Iterator::value_type pixel_type;
+
+ typedef GreylevelGetter<pixel_type,
+ Color,
+ UsedRange> getter_type;
+ typedef GreylevelSetter<pixel_type,
+ Color,
+ UsedRange> setter_type;
+
+ typedef Iterator iterator_type;
+ typedef Accessor raw_accessor_type;
+ typedef AccessorSelector<
+ getter_type,
+ setter_type > accessor_selector;
+};
+
+template< int BitsPerPixel,
+ bool MsbFirst > struct PixelFormatTraitsTemplate_PackedGreylevel :
+ public PixelFormatTraitsTemplate_Greylevel<
+ PackedPixelIterator< sal_uInt8,
+ BitsPerPixel,
+ true >,
+ NonStandardAccessor< sal_uInt8 >,
+ (1UL << BitsPerPixel)-1 >
+{};
+
+//-----------------------------------------------------------------------------
+
+// 1bpp MSB
+typedef PixelFormatTraitsTemplate_PackedGreylevel<1, true> PixelFormatTraits_GREY1_MSB;
+
+// 1bpp LSB
+typedef PixelFormatTraitsTemplate_PackedGreylevel<1, false> PixelFormatTraits_GREY1_LSB;
+BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_GREY1_MSB::getter_type,
+ PixelFormatTraits_GREY1_MSB::setter_type);
+
+
+// 4bpp MSB
+typedef PixelFormatTraitsTemplate_PackedGreylevel<4, true> PixelFormatTraits_GREY4_MSB;
+
+// 4bpp LSB
+typedef PixelFormatTraitsTemplate_PackedGreylevel<4, false> PixelFormatTraits_GREY4_LSB;
+BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_GREY4_MSB::getter_type,
+ PixelFormatTraits_GREY4_MSB::setter_type);
+
+// 8bpp
+typedef PixelFormatTraitsTemplate_Greylevel<
+ PixelIterator< sal_uInt8 >,
+ StandardAccessor< sal_uInt8 >,
+ 255 > PixelFormatTraits_GREY8;
+BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_GREY8::getter_type,
+ PixelFormatTraits_GREY8::setter_type);
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_GREYLEVELFORMATS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/iteratortraits.hxx b/basebmp/inc/basebmp/iteratortraits.hxx
new file mode 100644
index 000000000000..ac76a3ebf783
--- /dev/null
+++ b/basebmp/inc/basebmp/iteratortraits.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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 */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/linerenderer.hxx b/basebmp/inc/basebmp/linerenderer.hxx
new file mode 100644
index 000000000000..5e3d4df30b88
--- /dev/null
+++ b/basebmp/inc/basebmp/linerenderer.hxx
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_LINERENDERER_HXX
+#define INCLUDED_BASEBMP_LINERENDERER_HXX
+
+#include <basegfx/point/b2ipoint.hxx>
+
+#include <vigra/diff2d.hxx>
+#include <vigra/iteratortraits.hxx>
+
+
+/* Scan-converting lines */
+
+namespace basebmp
+{
+
+/** Render line with Bresenham
+
+ This function renders the line given by rPt1 and rPt2 using the
+ Bresenham algorithm with the specified color value. Make sure rPt1
+ and rPt1 are valid coordinates in the image given by begin and
+ end, since no clipping takes place.
+
+ @param aPt1
+ Start point of the line
+
+ @param aPt2
+ End point of the line
+
+ @param color
+ Color value to render the line with
+
+ @param begin
+ left-top image iterator
+
+ @param end
+ right-bottom image iterator
+
+ @param acc
+ Image accessor
+
+ @param bRoundTowardsPt2
+ Rounding mode to use. Giving false here results in line pixel tend
+ towards pt1, i.e. when a pixel exactly hits the middle between two
+ pixel, the pixel closer to pt1 will be chosen. Giving true here
+ makes renderClippedLine() choose pt2 in those cases.
+ */
+template< class Iterator, class Accessor >
+void renderLine( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ typename Accessor::value_type color,
+ Iterator begin,
+ Accessor acc,
+ bool bRoundTowardsPt2=false )
+{
+ // code inspired by Paul Heckbert's Digital Line Drawing
+ // (Graphics Gems, Academic Press 1990)
+ const sal_Int32 x1 = rPt1.getX();
+ const sal_Int32 x2 = rPt2.getX();
+ const sal_Int32 y1 = rPt1.getY();
+ const sal_Int32 y2 = rPt2.getY();
+
+ // TODO(E1): This might overflow
+ sal_Int32 adx = x2 - x1;
+ int sx = 1;
+ if( adx < 0 )
+ {
+ adx *= -1;
+ sx = -1;
+ }
+
+ // TODO(E1): This might overflow
+ sal_Int32 ady = y2 - y1;
+ int sy = 1;
+ if( ady < 0 )
+ {
+ ady *= -1;
+ sy = -1;
+ }
+
+ // TODO(P3): handle horizontal and vertical lines specially
+ sal_Int32 xs = x1;
+ sal_Int32 ys = y1;
+ if( adx >= ady )
+ {
+ // semi-horizontal line
+ sal_Int32 rem = 2*ady - adx - !bRoundTowardsPt2;
+ adx *= 2;
+ ady *= 2;
+
+ Iterator currIter( begin + vigra::Diff2D(0,ys) );
+ typename vigra::IteratorTraits<Iterator>::row_iterator
+ rowIter( currIter.rowIterator() + xs );
+ while(true)
+ {
+ acc.set(color, rowIter);
+
+ if( xs == x2 )
+ return;
+
+ if( rem >= 0 )
+ {
+ ys += sy;
+ xs += sx;
+ currIter.y += sy;
+ rowIter = currIter.rowIterator() + xs;
+ rem -= adx;
+ }
+ else
+ {
+ xs += sx;
+ rowIter += sx;
+ }
+
+ rem += ady;
+ }
+ }
+ else
+ {
+ // semi-vertical line
+ sal_Int32 rem = 2*adx - ady - !bRoundTowardsPt2;
+ adx *= 2;
+ ady *= 2;
+
+ Iterator currIter( begin + vigra::Diff2D(xs,0) );
+ typename vigra::IteratorTraits<Iterator>::column_iterator
+ colIter( currIter.columnIterator() + ys );
+ while(true)
+ {
+ acc.set(color, colIter);
+
+ if( ys == y2 )
+ return;
+
+ if( rem >= 0 )
+ {
+ xs += sx;
+ ys += sy;
+ currIter.x += sx;
+ colIter = currIter.columnIterator() + ys;
+ rem -= ady;
+ }
+ else
+ {
+ ys += sy;
+ colIter += sy;
+ }
+
+ rem += adx;
+ }
+ }
+}
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_LINERENDERER_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/metafunctions.hxx b/basebmp/inc/basebmp/metafunctions.hxx
new file mode 100644
index 000000000000..642a98a70680
--- /dev/null
+++ b/basebmp/inc/basebmp/metafunctions.hxx
@@ -0,0 +1,225 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_METAFUNCTIONS_HXX
+#define INCLUDED_BASEBMP_METAFUNCTIONS_HXX
+
+#include <boost/mpl/integral_c.hpp>
+#include <vigra/metaprogramming.hxx>
+#include <vigra/numerictraits.hxx>
+
+namespace basebmp
+{
+
+// TODO(Q3): move to generic place (o3tl?)
+
+/** 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;
+};
+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
+{
+ typedef T type;
+};
+template <typename T> struct remove_const<const T>
+{
+ typedef T type;
+};
+
+//--------------------------------------------------------------
+
+/// Base class for an adaptable ternary functor
+template< typename A1, typename A2, typename A3, typename R > struct TernaryFunctorBase
+{
+ typedef A1 first_argument_type;
+ typedef A2 second_argument_type;
+ typedef A3 third_argument_type;
+ typedef R result_type;
+};
+
+//--------------------------------------------------------------
+
+/** template meta function: ensure that given integer type is unsigned
+
+ If given integer type is already unsigned, return as-is -
+ otherwise, convert to unsigned type of same or greater range.
+ */
+template< typename T > struct make_unsigned;
+
+#define BASEBMP_MAKE_UNSIGNED(T,U) \
+ template<> struct make_unsigned<T> { \
+ typedef U type; \
+ };
+
+BASEBMP_MAKE_UNSIGNED(signed char,unsigned char)
+BASEBMP_MAKE_UNSIGNED(unsigned char,unsigned char)
+BASEBMP_MAKE_UNSIGNED(short,unsigned short)
+BASEBMP_MAKE_UNSIGNED(unsigned short,unsigned short)
+BASEBMP_MAKE_UNSIGNED(int,unsigned int)
+BASEBMP_MAKE_UNSIGNED(unsigned int,unsigned int)
+BASEBMP_MAKE_UNSIGNED(long,unsigned long)
+BASEBMP_MAKE_UNSIGNED(unsigned long,unsigned long)
+
+#undef BASEBMP_MAKE_UNSIGNED
+
+/// cast integer to unsigned type of similar size
+template< typename T > inline typename make_unsigned<T>::type unsigned_cast( T value )
+{
+ 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 )
+{
+ return x < 0;
+}
+
+/// Overload for ints (branch-free)
+inline bool is_negative( int x )
+{
+ // force logic shift (result for signed shift right is undefined)
+ 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
+{
+ typedef
+ typename vigra::If<
+ typename vigra::NumericTraits< T >::isIntegral,
+ typename vigra::If<
+ typename vigra::NumericTraits< T >::isScalar,
+ trueCase,
+ falseCase >::type,
+ falseCase >::type type;
+};
+
+/// Results in VigraTrueType, if T is of non-integer type and scalar
+template< typename T, typename trueCase, typename falseCase >
+struct ifScalarNonIntegral
+{
+ typedef
+ typename vigra::If<
+ typename vigra::NumericTraits< T >::isIntegral,
+ falseCase,
+ typename vigra::If<
+ typename vigra::NumericTraits< T >::isScalar,
+ trueCase,
+ falseCase >::type >::type type;
+};
+
+/// Results in VigraTrueType, if both T1 and T2 are of integer type and scalar
+template< typename T1, typename T2, typename trueCase, typename falseCase >
+struct ifBothScalarIntegral
+{
+ typedef
+ typename ifScalarIntegral<
+ T1,
+ typename ifScalarIntegral<
+ T2,
+ trueCase,
+ falseCase >::type,
+ falseCase >::type type;
+};
+
+//--------------------------------------------------------------
+
+/// Count number of trailing zeros
+template< unsigned 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< unsigned int val > struct bitcount
+{
+ enum { next = val >> 1 };
+ enum { value = bitcount<next>::value + (val & 1) };
+};
+
+template<> struct bitcount<0>
+{
+ enum { value = 0 };
+};
+
+//--------------------------------------------------------------
+
+/// 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);
+}
+
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_METAFUNCTIONS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/nonstandarditerator.hxx b/basebmp/inc/basebmp/nonstandarditerator.hxx
new file mode 100644
index 000000000000..090d15d41025
--- /dev/null
+++ b/basebmp/inc/basebmp/nonstandarditerator.hxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_NONSTANDARDITERATOR_HXX
+#define INCLUDED_BASEBMP_NONSTANDARDITERATOR_HXX
+
+#include <vigra/metaprogramming.hxx>
+
+namespace basebmp
+{
+ /// Base class defining pointer and reference types as VigraFalseType
+ struct NonStandardIterator
+ {
+ typedef vigra::VigraFalseType reference;
+ typedef vigra::VigraFalseType index_reference;
+ typedef vigra::VigraFalseType pointer;
+ };
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_NONSTANDARDITERATOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/packedpixeliterator.hxx b/basebmp/inc/basebmp/packedpixeliterator.hxx
new file mode 100644
index 000000000000..b98c8c8f9670
--- /dev/null
+++ b/basebmp/inc/basebmp/packedpixeliterator.hxx
@@ -0,0 +1,680 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_PACKEDPIXELITERATOR_HXX
+#define INCLUDED_BASEBMP_PACKEDPIXELITERATOR_HXX
+
+#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>
+#include <vigra/diff2d.hxx>
+
+namespace basebmp
+{
+
+/// Get bitmask for data at given intra-word position, for given bit depth
+template< typename value_type,
+ int bits_per_pixel,
+ bool MsbFirst,
+ typename difference_type >
+inline value_type get_mask( difference_type d )
+{
+ BOOST_STATIC_ASSERT(bits_per_pixel > 0);
+ BOOST_STATIC_ASSERT(sizeof(value_type)*8 % bits_per_pixel == 0);
+ BOOST_STATIC_ASSERT(sizeof(value_type)*8 / bits_per_pixel > 1);
+ BOOST_STATIC_ASSERT(vigra::TypeTraits<value_type>::isPOD::asBool);
+
+ const unsigned int nIntraWordPositions( sizeof(value_type)*8 / bits_per_pixel );
+
+ // create bits_per_pixel 1s shift to intra-word position
+ return ((~(~0 << bits_per_pixel)) << bits_per_pixel*(MsbFirst ?
+ (nIntraWordPositions-1 - (d % nIntraWordPositions)) :
+ (d % nIntraWordPositions)));
+}
+
+template< int num_intraword_positions, int bits_per_pixel, bool MsbFirst, typename difference_type > inline difference_type get_shift( difference_type remainder )
+{
+ return bits_per_pixel*(MsbFirst ?
+ (num_intraword_positions - 1 - remainder) :
+ remainder);
+}
+
+template< typename Valuetype,
+ int bits_per_pixel,
+ bool MsbFirst > class PackedPixelColumnIterator : public NonStandardIterator
+{
+public:
+ // no reference, no index_reference type here
+ typedef Valuetype value_type;
+ typedef int difference_type;
+ typedef image_traverser_tag iterator_category;
+
+ typedef typename remove_const<value_type>::type mask_type;
+ typedef value_type* pointer;
+ typedef StridedArrayIterator< value_type > MoveY;
+
+ enum {
+ /** The number of pixel within a single value_type value
+ */
+ num_intraword_positions=sizeof(value_type)*8/bits_per_pixel,
+ /** Bit mask for one pixel (least significant bits)
+ */
+ bit_mask=~(~0 << bits_per_pixel)
+ };
+
+private:
+ MoveY y;
+ mask_type mask_;
+ difference_type shift_;
+
+ void inc()
+ {
+ ++y;
+ }
+
+ void dec()
+ {
+ --y;
+ }
+
+ bool equal( PackedPixelColumnIterator const & rhs ) const
+ {
+ return rhs.y == y;
+ }
+
+ bool less( PackedPixelColumnIterator const & rhs ) const
+ {
+ return y < rhs.y;
+ }
+
+public:
+ PackedPixelColumnIterator() :
+ y(0),
+ mask_( get_mask<value_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
+ shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst, difference_type>(0) )
+ {}
+
+ PackedPixelColumnIterator( const MoveY& base, difference_type remainder ) :
+ y(base),
+ mask_( get_mask<value_type, bits_per_pixel, MsbFirst>(remainder) ),
+ shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder) )
+ {}
+
+ PackedPixelColumnIterator& operator+=( difference_type d )
+ {
+ y += d;
+ return *this;
+ }
+
+ PackedPixelColumnIterator& operator-=( difference_type d )
+ {
+ y -= d;
+ return *this;
+ }
+
+ PackedPixelColumnIterator operator+( difference_type d )
+ {
+ PackedPixelColumnIterator res(*this);
+ res += d;
+ return res;
+ }
+
+ PackedPixelColumnIterator operator-( difference_type d )
+ {
+ PackedPixelColumnIterator res(*this);
+ res -= d;
+ return res;
+ }
+
+ PackedPixelColumnIterator& operator++()
+ {
+ inc();
+ return *this;
+ }
+
+ PackedPixelColumnIterator& operator--()
+ {
+ dec();
+ return *this;
+ }
+
+ PackedPixelColumnIterator operator++(int)
+ {
+ PackedPixelColumnIterator res(*this);
+ inc();
+ return res;
+ }
+
+ PackedPixelColumnIterator operator--(int)
+ {
+ PackedPixelColumnIterator res(*this);
+ dec();
+ return res;
+ }
+
+ bool operator==(PackedPixelColumnIterator const & rhs) const
+ {
+ return equal( rhs );
+ }
+
+ bool operator!=(PackedPixelColumnIterator const & rhs) const
+ {
+ return !equal( rhs );
+ }
+
+ bool operator<(PackedPixelColumnIterator const & rhs) const
+ {
+ return less(rhs);
+ }
+
+ bool operator<=(PackedPixelColumnIterator const & rhs) const
+ {
+ return !rhs.less(*this);
+ }
+
+ bool operator>(PackedPixelColumnIterator const & rhs) const
+ {
+ return rhs.less(*this);
+ }
+
+ bool operator>=(PackedPixelColumnIterator const & rhs) const
+ {
+ return !less(rhs);
+ }
+
+ difference_type operator-(PackedPixelColumnIterator const & rhs) const
+ {
+ return y - rhs.y;
+ }
+
+ value_type get() const
+ {
+ return unsigned_cast<value_type>(*y() & mask_) >> shift_;
+ }
+
+ value_type get(difference_type d) const
+ {
+ return unsigned_cast<value_type>(*y(d) & mask_) >> shift_;
+ }
+
+ void set( value_type v ) const
+ {
+ const value_type pixel_value( (v << shift_) & mask_ );
+ *y() = (*y() & ~mask_) | pixel_value;
+ }
+
+ void set( value_type v, difference_type d ) const
+ {
+ const value_type pixel_value( (v << shift_) & mask_ );
+ *y(d) = (*y(d) & ~mask_) | pixel_value;
+ }
+};
+
+template< typename Valuetype,
+ int bits_per_pixel,
+ bool MsbFirst > class PackedPixelRowIterator : public NonStandardIterator
+{
+public:
+ // no reference, no index_reference type here
+ typedef Valuetype value_type;
+ typedef int difference_type;
+ typedef image_traverser_tag iterator_category;
+
+ typedef typename remove_const<value_type>::type mask_type;
+ typedef value_type* pointer;
+
+ enum {
+ /** The number of pixel within a single value_type value
+ */
+ num_intraword_positions=sizeof(value_type)*8/bits_per_pixel,
+ /** Bit mask for one pixel (least significant bits)
+ */
+ bit_mask=~(~0 << bits_per_pixel)
+ };
+
+private:
+ pointer data_;
+ mask_type mask_;
+ difference_type remainder_;
+
+ void update_mask()
+ {
+ mask_ = get_mask<value_type, bits_per_pixel, MsbFirst>(remainder_);
+ }
+
+ void inc()
+ {
+ const difference_type newValue( remainder_ + 1 );
+ const difference_type data_offset( newValue / num_intraword_positions );
+
+ data_ += data_offset;
+ remainder_ = newValue % num_intraword_positions;
+
+ const mask_type shifted_mask(
+ MsbFirst ?
+ unsigned_cast<mask_type>(mask_) >> bits_per_pixel :
+ mask_ << bits_per_pixel );
+
+ // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
+ mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
+ bit_mask << bits_per_pixel*(num_intraword_positions-1) :
+ bit_mask);
+ }
+
+ void dec()
+ {
+ const difference_type newValue( remainder_ - 1 );
+ const bool isNegative( is_negative(newValue) );
+ const difference_type newRemainder( newValue % num_intraword_positions );
+
+ // calc data_ += newValue / num_intraword_positions;
+ // remainder_ = newRemainder;
+ // for newValue >= 0, and
+ // data_ += newValue / num_intraword_positions - 1;
+ // remainder_ = num_intraword_positions - newRemainder;
+ // (to force remainder_ to be positive).
+ // This is branch-free, if is_negative() is branch-free
+ const difference_type data_offset( newValue / num_intraword_positions - isNegative );
+ data_ += data_offset;
+ remainder_ = newRemainder + isNegative*num_intraword_positions;
+
+ const mask_type shifted_mask(
+ MsbFirst ?
+ mask_ << bits_per_pixel :
+ unsigned_cast<mask_type>(mask_) >> bits_per_pixel );
+
+ // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
+ mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
+ bit_mask :
+ bit_mask << bits_per_pixel*(num_intraword_positions-1));
+ }
+
+ bool equal( PackedPixelRowIterator const & rhs ) const
+ {
+ return rhs.data_ == data_ && rhs.remainder_ == remainder_;
+ }
+
+ bool less( PackedPixelRowIterator const & rhs ) const
+ {
+ return data_ == rhs.data_ ?
+ (remainder_ < rhs.remainder_) :
+ (data_ < rhs.data_);
+ }
+
+public:
+ PackedPixelRowIterator() :
+ data_(0),
+ mask_( get_mask<value_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
+ remainder_(0)
+ {}
+
+ explicit PackedPixelRowIterator( pointer base, int x ) :
+ data_(base),
+ mask_(0),
+ remainder_(x % num_intraword_positions)
+ {
+ update_mask();
+ }
+
+ PackedPixelRowIterator& operator+=( difference_type d )
+ {
+ const difference_type newValue( remainder_ + d );
+ const bool isNegative( is_negative(newValue) );
+ const difference_type newRemainder( newValue % num_intraword_positions );
+
+ // calc data_ += newValue / num_intraword_positions;
+ // remainder_ = newRemainder;
+ // for newValue >= 0, and
+ // data_ += newValue / num_intraword_positions - 1;
+ // remainder_ = newRemainder + num_intraword_positions;
+ // (to force remainder_ to be positive).
+ // This is branch-free, if is_negative() is branch-free
+ data_ += newValue / num_intraword_positions - isNegative;
+ remainder_ = newRemainder + isNegative*num_intraword_positions;
+ update_mask();
+
+ return *this;
+ }
+
+ PackedPixelRowIterator& operator-=( difference_type d )
+ {
+ // forward to operator+= - which has to cope with negative
+ // values, anyway.
+ return *this += -d;
+ }
+
+ PackedPixelRowIterator operator+( difference_type d )
+ {
+ PackedPixelRowIterator res(*this);
+ res += d;
+ return res;
+ }
+
+ PackedPixelRowIterator operator-( difference_type d )
+ {
+ PackedPixelRowIterator res(*this);
+ res -= d;
+ return res;
+ }
+
+ PackedPixelRowIterator& operator++()
+ {
+ inc();
+ return *this;
+ }
+
+ PackedPixelRowIterator& operator--()
+ {
+ dec();
+ return *this;
+ }
+
+ PackedPixelRowIterator operator++(int)
+ {
+ PackedPixelRowIterator res(*this);
+ inc();
+ return res;
+ }
+
+ PackedPixelRowIterator operator--(int)
+ {
+ PackedPixelRowIterator res(*this);
+ dec();
+ return res;
+ }
+
+ bool operator==(PackedPixelRowIterator const & rhs) const
+ {
+ return equal( rhs );
+ }
+
+ bool operator!=(PackedPixelRowIterator const & rhs) const
+ {
+ return !equal( rhs );
+ }
+
+ bool operator<(PackedPixelRowIterator const & rhs) const
+ {
+ return less(rhs);
+ }
+
+ bool operator<=(PackedPixelRowIterator const & rhs) const
+ {
+ return !rhs.less(*this);
+ }
+
+ bool operator>(PackedPixelRowIterator const & rhs) const
+ {
+ return rhs.less(*this);
+ }
+
+ bool operator>=(PackedPixelRowIterator const & rhs) const
+ {
+ return !less(rhs);
+ }
+
+ difference_type operator-(PackedPixelRowIterator const & rhs) const
+ {
+ return (data_ - rhs.data_)*num_intraword_positions + (remainder_ - rhs.remainder_);
+ }
+
+ value_type get() const
+ {
+ return unsigned_cast<value_type>(*data_ & mask_) >>
+ get_shift<num_intraword_positions,
+ bits_per_pixel,
+ MsbFirst>(remainder_);
+ }
+
+ value_type get(difference_type d) const
+ {
+ PackedPixelRowIterator tmp(*this);
+ tmp += d;
+ return tmp.get();
+ }
+
+ void set( value_type v ) const
+ {
+ const value_type pixel_value(
+ (v <<
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_))
+ & mask_ );
+ *data_ = (*data_ & ~mask_) | pixel_value;
+ }
+
+ void set( value_type v, difference_type d ) const
+ {
+ PackedPixelRowIterator tmp(*this);
+ tmp += d;
+ tmp.set(v);
+ }
+};
+
+/** 2D image iterator for packed pixel formats
+
+ This iterator can be used for image formats that pack more than
+ one pixel into an machine data type (like one bit per pixel, eight
+ of which packed into one char)
+ */
+template< typename Valuetype,
+ int bits_per_pixel,
+ bool MsbFirst > class PackedPixelIterator : public NonStandardIterator
+{
+public:
+ // no reference, no index_reference type here
+ typedef Valuetype value_type;
+ typedef vigra::Diff2D difference_type;
+ typedef image_traverser_tag iterator_category;
+ typedef PackedPixelRowIterator<value_type,
+ bits_per_pixel,
+ MsbFirst> row_iterator;
+ typedef PackedPixelColumnIterator<value_type,
+ bits_per_pixel,
+ MsbFirst> column_iterator;
+
+ typedef value_type* pointer;
+ typedef int MoveX;
+ typedef StridedArrayIterator< value_type > MoveY;
+
+ enum {
+ /** The number of pixel within a single value_type value
+ */
+ num_intraword_positions=sizeof(value_type)*8/bits_per_pixel,
+ /** Bit mask for one pixel (least significant bits)
+ */
+ bit_mask=~(~0 << bits_per_pixel)
+ };
+
+ // TODO(F2): direction of iteration (ImageIterator can be made to
+ // run backwards)
+
+private:
+ pointer current() const
+ {
+ return y() + (x / num_intraword_positions);
+ }
+
+ pointer current(int dx, int dy) const
+ {
+ return y(dy) + ((x+dx)/num_intraword_positions);
+ }
+
+ bool equal(PackedPixelIterator const & rhs) const
+ {
+ return (x == rhs.x) && (y == rhs.y);
+ }
+
+public:
+ PackedPixelIterator() :
+ x(0),
+ y(0)
+ {}
+
+ PackedPixelIterator(pointer base, int ystride) :
+ x(0),
+ y(ystride,base)
+ {}
+
+ bool operator==(PackedPixelIterator const & rhs) const
+ {
+ return equal(rhs);
+ }
+
+ bool operator!=(PackedPixelIterator const & rhs) const
+ {
+ return !equal(rhs);
+ }
+
+ difference_type operator-(PackedPixelIterator const & rhs) const
+ {
+ return difference_type(x - rhs.x, y - rhs.y);
+ }
+
+ MoveX x;
+ MoveY y;
+
+ PackedPixelIterator & operator+=(difference_type const & s)
+ {
+ x += s.x;
+ y += s.y;
+ return *this;
+ }
+
+ PackedPixelIterator & operator-=(difference_type const & s)
+ {
+ x -= s.x;
+ y -= s.y;
+ return *this;
+ }
+
+ PackedPixelIterator operator+(difference_type const & s) const
+ {
+ PackedPixelIterator ret(*this);
+ ret += s;
+ return ret;
+ }
+
+ PackedPixelIterator operator-(difference_type const & s) const
+ {
+ PackedPixelIterator ret(*this);
+ ret -= s;
+ return ret;
+ }
+
+ row_iterator rowIterator() const
+ {
+ return row_iterator(current(),x);
+ }
+
+ column_iterator columnIterator() const
+ {
+ return column_iterator(MoveY(y,
+ x / num_intraword_positions),
+ x % num_intraword_positions);
+ }
+
+ value_type get() const
+ {
+ const int remainder( x % num_intraword_positions );
+
+ return (unsigned_cast<value_type>(*current() &
+ get_mask<value_type, bits_per_pixel, MsbFirst>(remainder))
+ >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder));
+ }
+
+ value_type get(difference_type const & d) const
+ {
+ const int remainder( x(d.x) % num_intraword_positions );
+
+ return (unsigned_cast<value_type>(*current(d.x,d.y) &
+ get_mask<value_type, bits_per_pixel, MsbFirst>(remainder))
+ >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder));
+ }
+
+ void set( value_type v ) const
+ {
+ const int remainder( x % num_intraword_positions );
+ const int mask( get_mask<value_type, bits_per_pixel, MsbFirst>(remainder) );
+ const value_type pixel_value(
+ (v <<
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
+ & mask );
+ pointer p = current();
+ *p = (*p & ~mask) | pixel_value;
+ }
+
+ void set( value_type v, difference_type const & d ) const
+ {
+ const int remainder( (x + d.x) % num_intraword_positions );
+ const int mask( get_mask<value_type, bits_per_pixel, MsbFirst>(remainder) );
+ const value_type pixel_value(
+ (v <<
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
+ & mask );
+ pointer p = current(d.x,d.y);
+ *p = (*p & ~mask) | pixel_value;
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+// 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 polarity,
+ bool MsbFirst > struct maskedAccessorSelector< Accessor,
+ MaskAccessor,
+ Iterator,
+ PackedPixelIterator< typename MaskAccessor::value_type,
+ 1,
+ MsbFirst >,
+ polarity >
+{
+ typedef TernarySetterFunctionAccessorAdapter<
+ Accessor,
+ MaskAccessor,
+ typename outputMaskFunctorSelector<
+ typename Accessor::value_type,
+ typename MaskAccessor::value_type,
+ polarity,
+ FastMask>::type >
+ type;
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_PACKEDPIXELITERATOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/paletteformats.hxx b/basebmp/inc/basebmp/paletteformats.hxx
new file mode 100644
index 000000000000..f138549462fe
--- /dev/null
+++ b/basebmp/inc/basebmp/paletteformats.hxx
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_PACKEDPIXELFORMATS_HXX
+#define INCLUDED_BASEBMP_PACKEDPIXELFORMATS_HXX
+
+#include <basebmp/color.hxx>
+#include <basebmp/colortraits.hxx>
+#include <basebmp/accessor.hxx>
+#include <basebmp/pixeliterator.hxx>
+#include <basebmp/packedpixeliterator.hxx>
+#include <basebmp/pixelformatadapters.hxx>
+#include <basebmp/paletteimageaccessor.hxx>
+#include <basebmp/metafunctions.hxx>
+
+#include <vigra/numerictraits.hxx>
+#include <vigra/metaprogramming.hxx>
+
+#include <functional>
+
+namespace basebmp
+{
+
+//-----------------------------------------------------------------------------
+
+/** Lookup index value for given color value in a PaletteImageAccessor
+ */
+template< class Accessor > struct ColorLookup
+{
+ typename Accessor::data_type operator()( const Accessor& acc,
+ typename Accessor::value_type v ) const
+ {
+ return acc.lookup(v);
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+// partial specialization of AccessorTraits for PaletteAccessor
+template< class Accessor, typename ColorType > struct AccessorTraits<
+ PaletteImageAccessor< Accessor, ColorType > >
+{
+ /// 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;
+ };
+};
+
+//-----------------------------------------------------------------------------
+
+template< typename ColorType > struct PaletteAccessorSelector
+{
+ template< class Accessor > struct wrap_accessor
+ {
+ typedef PaletteImageAccessor< Accessor, ColorType > type;
+ };
+};
+
+//-----------------------------------------------------------------------------
+
+template< class Iterator,
+ class Accessor > struct PixelFormatTraitsTemplate_Palette
+{
+ typedef typename Iterator::value_type pixel_type;
+ typedef Iterator iterator_type;
+ typedef Accessor raw_accessor_type;
+ typedef PaletteAccessorSelector<Color> accessor_selector;
+};
+
+template< int BitsPerPixel,
+ bool MsbFirst > struct PixelFormatTraitsTemplate_PackedPalette :
+ public PixelFormatTraitsTemplate_Palette<
+ PackedPixelIterator< sal_uInt8,
+ BitsPerPixel,
+ MsbFirst >,
+ NonStandardAccessor< sal_uInt8 > >
+{};
+
+//-----------------------------------------------------------------------------
+
+// 1bpp MSB
+typedef PixelFormatTraitsTemplate_PackedPalette<1, true> PixelFormatTraits_PAL1_MSB;
+
+// 1bpp LSB
+typedef PixelFormatTraitsTemplate_PackedPalette<1, false> PixelFormatTraits_PAL1_LSB;
+
+// 4bpp MSB
+typedef PixelFormatTraitsTemplate_PackedPalette<4, true> PixelFormatTraits_PAL4_MSB;
+
+// 4bpp LSB
+typedef PixelFormatTraitsTemplate_PackedPalette<4, false> PixelFormatTraits_PAL4_LSB;
+
+// 8bpp
+typedef PixelFormatTraitsTemplate_Palette<
+ PixelIterator< sal_uInt8 >,
+ StandardAccessor< sal_uInt8 > > PixelFormatTraits_PAL8;
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_PACKEDPIXELFORMATS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/paletteimageaccessor.hxx b/basebmp/inc/basebmp/paletteimageaccessor.hxx
new file mode 100644
index 000000000000..35a14d16dd36
--- /dev/null
+++ b/basebmp/inc/basebmp/paletteimageaccessor.hxx
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX
+#define INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX
+
+#include <basebmp/colortraits.hxx>
+#include <basebmp/accessortraits.hxx>
+
+#include <vigra/numerictraits.hxx>
+#include <vigra/metaprogramming.hxx>
+
+#include <algorithm>
+#include <functional>
+
+namespace basebmp
+{
+
+/** 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< class Accessor, typename ColorType > class PaletteImageAccessor
+{
+public:
+ 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:
+ template<class A, typename C> friend class PaletteImageAccessor;
+#endif
+
+ 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)
+ {}
+
+ // -------------------------------------------------------
+
+ 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( 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( ColorTraits<value_type>::distance(*curr_entry,
+ *best_entry)
+ > ColorTraits<value_type>::distance(*curr_entry,
+ v) )
+ {
+ best_entry = curr_entry;
+ }
+
+ ++curr_entry;
+ }
+
+ return best_entry-mpPalette;
+ }
+
+ // -------------------------------------------------------
+
+ template< class Iterator >
+ 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 mpPalette[ maAccessor(i,diff) ];
+ }
+
+ // -------------------------------------------------------
+
+ template< typename V, class Iterator >
+ void set(V const& value, Iterator const& i) const
+ {
+ 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
+ {
+ maAccessor.set(
+ lookup(
+ vigra::detail::RequiresExplicitCast<value_type>::cast(value) ),
+ i,
+ diff );
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/pixelformatadapters.hxx b/basebmp/inc/basebmp/pixelformatadapters.hxx
new file mode 100644
index 000000000000..6ebf531fbbb4
--- /dev/null
+++ b/basebmp/inc/basebmp/pixelformatadapters.hxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_PIXELFORMATADAPTERS_HXX
+#define INCLUDED_BASEBMP_PIXELFORMATADAPTERS_HXX
+
+#include <basebmp/accessortraits.hxx>
+#include <basebmp/accessoradapters.hxx>
+
+#include <vigra/metaprogramming.hxx>
+
+namespace basebmp
+{
+
+// convenience functionality, providing everything necessary for a new
+// pixel format. simply plug in two conversion functors from/to a
+// common color format.
+
+/** Accessor selection metafunction, used to wrap a given accessor
+ with one converting between the pixel and color types
+
+ Use the nested template's typedef type, to retrieve an
+ AccessorAdapter which operates on a pixel value accessor, and
+ provides color values to the outside.
+
+ Nested like this, to avoid template template parameters at other
+ places: an instantiated version of AccessorSelector can be passed
+ to other templates, which in turn can invoke the nested meta
+ function.
+ */
+template< typename Getter,
+ typename Setter > struct AccessorSelector
+{
+ template< typename Accessor > struct wrap_accessor
+ {
+ typedef UnaryFunctionAccessorAdapter< Accessor,
+ Getter,
+ Setter > type;
+ };
+};
+
+//-----------------------------------------------------------------------------
+
+/** Convert color value to pixel data type
+ */
+template< class Accessor, typename DataType > struct ColorConvert
+{
+ DataType operator()( const Accessor& acc,
+ typename Accessor::value_type v ) const
+ {
+ return acc.setter(v);
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+/** Macro generates partial specialization for color-conversion
+ UnaryFunctionAccessorAdapter, and the given getter/setter functors
+ */
+#define BASEBMP_SPECIALIZE_ACCESSORTRAITS(Getter,Setter) \
+template< class Accessor > struct AccessorTraits< \
+ UnaryFunctionAccessorAdapter< Accessor, \
+ Getter, \
+ Setter > > \
+{ \
+ typedef typename Accessor::value_type data_type; \
+ typedef UnaryFunctionAccessorAdapter< \
+ Accessor, \
+ Getter, \
+ Setter > accessor_type; \
+ typedef typename accessor_type::value_type value_type; \
+ typedef ColorConvert< accessor_type, \
+ data_type > color_lookup; \
+ typedef Accessor raw_accessor; \
+ typedef vigra::VigraFalseType xor_accessor; \
+ template< class MaskAccessor, \
+ class Iterator, \
+ class MaskIterator > struct masked_accessor\
+ { typedef vigra::VigraFalseType type; }; \
+}
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_PIXELFORMATADAPTERS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/pixeliterator.hxx b/basebmp/inc/basebmp/pixeliterator.hxx
new file mode 100644
index 000000000000..6e5ca4394a01
--- /dev/null
+++ b/basebmp/inc/basebmp/pixeliterator.hxx
@@ -0,0 +1,358 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_PIXELITERATOR_HXX
+#define INCLUDED_BASEBMP_PIXELITERATOR_HXX
+
+#include <basebmp/metafunctions.hxx>
+#include <basebmp/stridedarrayiterator.hxx>
+
+#include <vigra/metaprogramming.hxx>
+#include <vigra/diff2d.hxx>
+
+namespace basebmp
+{
+
+template< typename Valuetype > class PixelColumnIterator
+{
+public:
+ typedef Valuetype value_type;
+ typedef Valuetype& reference;
+ typedef reference index_reference;
+ typedef Valuetype* pointer;
+ typedef int difference_type;
+ typedef image_traverser_tag iterator_category;
+
+ typedef StridedArrayIterator< value_type > MoveY;
+
+private:
+ MoveY y;
+
+ bool equal( PixelColumnIterator const & rhs ) const
+ {
+ return rhs.y == y;
+ }
+
+ bool less( PixelColumnIterator const & rhs ) const
+ {
+ return y < rhs.y;
+ }
+
+public:
+ PixelColumnIterator() :
+ y(0)
+ {}
+
+ explicit PixelColumnIterator( const MoveY& pos ) :
+ y(pos)
+ {}
+
+ PixelColumnIterator( const MoveY& pos, int x ) :
+ y(pos,x)
+ {}
+
+ PixelColumnIterator& operator+=( difference_type d )
+ {
+ y += d;
+ return *this;
+ }
+
+ PixelColumnIterator& operator-=( difference_type d )
+ {
+ y -= d;
+ return *this;
+ }
+
+ PixelColumnIterator operator+( difference_type d )
+ {
+ PixelColumnIterator res(*this);
+ res += d;
+ return res;
+ }
+
+ PixelColumnIterator operator-( difference_type d )
+ {
+ PixelColumnIterator res(*this);
+ res -= d;
+ return res;
+ }
+
+ PixelColumnIterator& operator++()
+ {
+ ++y;
+ return *this;
+ }
+
+ PixelColumnIterator& operator--()
+ {
+ --y;
+ return *this;
+ }
+
+ PixelColumnIterator operator++(int)
+ {
+ PixelColumnIterator res(*this);
+ ++y;
+ return res;
+ }
+
+ PixelColumnIterator operator--(int)
+ {
+ PixelColumnIterator res(*this);
+ --y;
+ return res;
+ }
+
+ bool operator==(PixelColumnIterator const & rhs) const
+ {
+ return equal( rhs );
+ }
+
+ bool operator!=(PixelColumnIterator const & rhs) const
+ {
+ return !equal( rhs );
+ }
+
+ bool operator<(PixelColumnIterator const & rhs) const
+ {
+ return less(rhs);
+ }
+
+ bool operator<=(PixelColumnIterator const & rhs) const
+ {
+ return !rhs.less(*this);
+ }
+
+ bool operator>(PixelColumnIterator const & rhs) const
+ {
+ return rhs.less(*this);
+ }
+
+ bool operator>=(PixelColumnIterator const & rhs) const
+ {
+ return !less(rhs);
+ }
+
+ difference_type operator-(PixelColumnIterator const & rhs) const
+ {
+ return y - rhs.y;
+ }
+
+ value_type get() const
+ {
+ return *y();
+ }
+
+ value_type get(difference_type d) const
+ {
+ return *y(d);
+ }
+
+ void set( value_type v ) const
+ {
+ *y() = v;
+ }
+
+ void set( value_type v, difference_type d ) const
+ {
+ *y(d) = v;
+ }
+
+ reference operator*() const
+ {
+ return *y();
+ }
+
+ pointer operator->() const
+ {
+ return y();
+ }
+
+ reference operator[](difference_type d) const
+ {
+ return *y(d);
+ }
+
+ reference operator()(int dy) const
+ {
+ return *y(dy);
+ }
+};
+
+template< typename Valuetype > class PixelIterator
+{
+public:
+ typedef Valuetype value_type;
+ typedef Valuetype& reference;
+ typedef reference index_reference;
+ typedef Valuetype* pointer;
+ typedef vigra::Diff2D difference_type;
+ typedef image_traverser_tag iterator_category;
+ typedef pointer row_iterator;
+ typedef PixelColumnIterator<value_type> column_iterator;
+
+ typedef int MoveX;
+ typedef StridedArrayIterator< value_type > MoveY;
+
+ // TODO(F2): direction of iteration (ImageIterator can be made to
+ // run backwards)
+
+private:
+ bool equal(PixelIterator const & rhs) const
+ {
+ return (x == rhs.x) && (y == rhs.y);
+ }
+
+ pointer current() const
+ {
+ return y() + x;
+ }
+
+ pointer current(int dx, int dy) const
+ {
+ return y(dy) + x+dx;
+ }
+
+public:
+ PixelIterator() :
+ x(0),
+ y(0)
+ {}
+
+ PixelIterator(pointer base, int ystride) :
+ x(0),
+ y(ystride,base)
+ {}
+
+ bool operator==(PixelIterator const & rhs) const
+ {
+ return equal(rhs);
+ }
+
+ bool operator!=(PixelIterator const & rhs) const
+ {
+ return !equal(rhs);
+ }
+
+ difference_type operator-(PixelIterator const & rhs) const
+ {
+ return difference_type(x - rhs.x, y - rhs.y);
+ }
+
+ MoveX x;
+ MoveY y;
+
+ PixelIterator & operator+=(difference_type const & s)
+ {
+ x += s.x;
+ y += s.y;
+ return *this;
+ }
+
+ PixelIterator & operator-=(difference_type const & s)
+ {
+ x -= s.x;
+ y -= s.y;
+ return *this;
+ }
+
+ PixelIterator operator+(difference_type const & s) const
+ {
+ PixelIterator ret(*this);
+ ret += s;
+ return ret;
+ }
+
+ PixelIterator operator-(difference_type const & s) const
+ {
+ PixelIterator ret(*this);
+ ret -= s;
+ return ret;
+ }
+
+ row_iterator rowIterator() const
+ {
+ return row_iterator(y()+x);
+ }
+
+ column_iterator columnIterator() const
+ {
+ return column_iterator(y,x);
+ }
+
+ value_type get() const
+ {
+ return *current();
+ }
+
+ value_type get(difference_type const & d) const
+ {
+ return *current(d.y, d.x);
+ }
+
+ void set( value_type v ) const
+ {
+ *current() = v;
+ }
+
+ void set( value_type v, difference_type const & d ) const
+ {
+ *current(d.y,d.x) = v;
+ }
+
+ reference operator*() const
+ {
+ return *current();
+ }
+
+ pointer operator->() const
+ {
+ return current();
+ }
+
+ reference operator[]( const vigra::Diff2D& d ) const
+ {
+ return *current(d.x,d.y);
+ }
+
+ reference operator()(int dx, int dy) const
+ {
+ return *current(dx,dy);
+ }
+
+ pointer operator[](int dy) const
+ {
+ return y(dy) + x;
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_PIXELITERATOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/polypolygonrenderer.hxx b/basebmp/inc/basebmp/polypolygonrenderer.hxx
new file mode 100644
index 000000000000..6a7c391f31d0
--- /dev/null
+++ b/basebmp/inc/basebmp/polypolygonrenderer.hxx
@@ -0,0 +1,369 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_POLYPOLYGONRENDERER_HXX
+#define INCLUDED_BASEBMP_POLYPOLYGONRENDERER_HXX
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/range/b2irange.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/polygon/b2dpolypolygonfillrule.hxx>
+#include <basegfx/numeric/ftools.hxx>
+
+#include <vigra/diff2d.hxx>
+#include <vigra/iteratortraits.hxx>
+
+#include <vector>
+
+
+namespace basebmp
+{
+ namespace detail
+ {
+ /// convert int32 to 32:32 fixed point
+ inline sal_Int64 toFractional( sal_Int32 v ) { return (sal_Int64)v << 32; }
+ /// convert double to 32:32 fixed point
+ inline sal_Int64 toFractional( double v ) { return (sal_Int64)(v*SAL_MAX_UINT32 + (v < 0.0 ? -0.5 : 0.5 )); }
+ /// convert 32:32 fixed point to int32 (truncate)
+ inline sal_Int32 toInteger( sal_Int64 v ) { return (sal_Int32)(v < 0 ? ~((~v) >> 32) : v >> 32); }
+ /// convert 32:32 fixed point to int32 (properly rounded)
+ inline sal_Int32 toRoundedInteger( sal_Int64 v ) { return toInteger(v) + (sal_Int32)((v&0x80000000) >> 31); }
+
+ /** internal vertex store -
+
+ Different from B2DPoint, since we don't need floating
+ point coords, but orientation of vertex and y counter
+ */
+ struct Vertex
+ {
+ sal_Int32 mnYCounter;
+ sal_Int64 mnX;
+ sal_Int64 mnXDelta;
+
+ bool mbDownwards; // needed for nonzero winding rule
+ // fills
+
+ Vertex() :
+ mnYCounter(0),
+ mnX(0),
+ mnXDelta(0),
+ mbDownwards(true)
+ {}
+ Vertex( basegfx::B2DPoint const& rPt1,
+ basegfx::B2DPoint const& rPt2,
+ bool bDownwards ) :
+ mnYCounter( basegfx::fround(rPt2.getY()) -
+ basegfx::fround(rPt1.getY()) ),
+ mnX( toFractional( basegfx::fround(rPt1.getX()) )),
+ mnXDelta( toFractional(
+ ((rPt2.getX() - rPt1.getX()) /
+ (double)mnYCounter) )),
+ mbDownwards(bDownwards)
+ {}
+ };
+
+ typedef std::vector< std::vector<Vertex> > VectorOfVectorOfVertices;
+ typedef std::vector< Vertex* > VectorOfVertexPtr;
+
+ /// non-templated setup of GET
+ sal_uInt32 setupGlobalEdgeTable( VectorOfVectorOfVertices& rGET,
+ basegfx::B2DPolyPolygon const& rPoly,
+ sal_Int32 nMinY );
+ /// sort rAETSrc, copy not-yet-ended edges over to rAETDest
+ void sortAET( VectorOfVertexPtr& rAETSrc,
+ VectorOfVertexPtr& rAETDest );
+
+ /// For the STL algorithms
+ struct RasterConvertVertexComparator
+ {
+ RasterConvertVertexComparator() {}
+
+ bool operator()( const Vertex& rLHS,
+ const Vertex& rRHS ) const
+ {
+ return rLHS.mnX < rRHS.mnX;
+ }
+
+ bool operator()( const Vertex* pLHS,
+ const Vertex* pRHS ) const
+ {
+ return pLHS->mnX < pRHS->mnX;
+ }
+ };
+
+ } // namespace detail
+
+
+ /** Raster-convert a poly-polygon.
+
+ This algorithm does not perform antialiasing, and thus
+ internally works with integer vertex coordinates.
+
+ @param begin
+ Left, top edge of the destination bitmap. This position is
+ considered (0,0) relative to all polygon vertices
+
+ @param ad
+ Accessor to set pixel values
+
+ @param fillColor
+ Color to use for filling
+
+ @param rClipRect
+ Clipping rectangle, relative to the begin iterator. No pixel outside
+ this clip rect will be modified.
+
+ @param rPoly
+ Polygon to fill
+ */
+ template< class DestIterator, class DestAccessor, typename T >
+ void renderClippedPolyPolygon( DestIterator begin,
+ DestAccessor ad,
+ T fillColor,
+ const basegfx::B2IRange& rClipRect,
+ basegfx::B2DPolyPolygon const& rPoly,
+ basegfx::FillRule eFillRule )
+ {
+ const sal_Int32 nClipX1( std::max((sal_Int32)0,rClipRect.getMinX()) );
+ const sal_Int32 nClipX2( rClipRect.getMaxX() );
+ const sal_Int32 nClipY1( std::max((sal_Int32)0,rClipRect.getMinY()) );
+ const sal_Int32 nClipY2( rClipRect.getMaxY() );
+ const sal_Int64 nClipX1_frac( detail::toFractional(nClipX1) );
+ const sal_Int64 nClipX2_frac( detail::toFractional(nClipX2) );
+
+ basegfx::B2DRange const aPolyBounds( basegfx::tools::getRange(rPoly) );
+
+ const sal_Int32 nMinY( basegfx::fround(aPolyBounds.getMinY()) );
+ const sal_Int32 nMaxY(
+ std::min(
+ nClipY2-1,
+ basegfx::fround(aPolyBounds.getMaxY())));
+
+ if( nMinY > nMaxY )
+ return; // really, nothing to do then.
+
+ detail::VectorOfVectorOfVertices aGET; // the Global Edge Table
+ aGET.resize( nMaxY - nMinY + 1 );
+
+ sal_uInt32 const nVertexCount(
+ detail::setupGlobalEdgeTable( aGET, rPoly, nMinY ) );
+
+
+ // Perform actual scan conversion
+ //----------------------------------------------------------------------
+
+ if( aGET.empty() )
+ return;
+
+ detail::VectorOfVertexPtr aAET1; // the Active Edge Table
+ detail::VectorOfVertexPtr aAET2;
+ detail::VectorOfVertexPtr* pAET = &aAET1;
+ detail::VectorOfVertexPtr* pAETOther = &aAET2;
+ aAET1.reserve( nVertexCount );
+ aAET2.reserve( nVertexCount );
+
+ // current scanline - initially, points to first scanline
+ // within the clip rect, or to the polygon's first scanline
+ // (whichever is greater)
+ DestIterator aScanline( begin +
+ vigra::Diff2D(
+ 0,
+ std::max(nMinY,
+ nClipY1)) );
+ detail::RasterConvertVertexComparator aComp;
+
+
+ // now process each of the nMaxY - nMinY + 1 scanlines
+ // ------------------------------------------------------------
+
+ for( sal_Int32 y=nMinY; y <= nMaxY; ++y )
+ {
+ if( !aGET[y-nMinY].empty() )
+ {
+ // merge AET with current scanline's new vertices (both
+ // are already correctly sorted)
+ detail::VectorOfVectorOfVertices::value_type::iterator vertex=aGET[y-nMinY].begin();
+ detail::VectorOfVectorOfVertices::value_type::iterator const end=aGET[y-nMinY].end();
+ while( vertex != end )
+ {
+ // find insertion pos by binary search, and put ptr
+ // into active edge vector
+ pAET->insert( std::lower_bound( pAET->begin(),
+ pAET->end(),
+ &(*vertex),
+ aComp ),
+ &(*vertex) );
+
+ ++vertex;
+ }
+ }
+
+ // with less than two active edges, no fill visible
+ if( pAET->size() >= 2 )
+ {
+ typename vigra::IteratorTraits<DestIterator>::row_iterator
+ rowIter( aScanline.rowIterator() );
+
+ // process each span in current scanline, with
+ // even-odd fill rule
+ detail::VectorOfVertexPtr::iterator currVertex( pAET->begin() );
+ detail::VectorOfVertexPtr::iterator const lastVertex( pAET->end()-1 );
+ sal_uInt32 nCrossedEdges(0);
+ sal_Int32 nWindingNumber(0);
+ while( currVertex != lastVertex )
+ {
+ // TODO(P1): might be worth a try to extend the
+ // size()==2 case also to the actual filling
+ // here. YMMV.
+ detail::Vertex& rV1( **currVertex );
+ detail::Vertex const& rV2( **++currVertex );
+
+ nWindingNumber += -1 + 2*rV1.mbDownwards;
+
+ // calc fill status for both rules. might save a
+ // few percent runtime to specialize here...
+ const bool bEvenOddFill(
+ eFillRule == basegfx::FillRule_EVEN_ODD && !(nCrossedEdges & 0x01) );
+ const bool bNonZeroWindingFill(
+ eFillRule == basegfx::FillRule_NONZERO_WINDING_NUMBER && nWindingNumber != 0 );
+
+ // is span visible?
+ if( (bEvenOddFill || bNonZeroWindingFill) &&
+ y >= nClipY1 &&
+ rV1.mnX < nClipX2_frac &&
+ rV2.mnX > nClipX1_frac )
+ {
+ // clip span to horizontal bounds
+ sal_Int32 const nStartX(
+ std::max( nClipX1,
+ std::min( nClipX2-1,
+ detail::toRoundedInteger(rV1.mnX) )));
+ sal_Int32 const nEndX(
+ std::max( nClipX1,
+ std::min( nClipX2,
+ detail::toRoundedInteger(rV2.mnX) )));
+
+ typename vigra::IteratorTraits<DestIterator>::row_iterator
+ currPix( rowIter + nStartX);
+ typename vigra::IteratorTraits<DestIterator>::row_iterator
+ rowEnd( rowIter + nEndX );
+
+ // TODO(P2): Provide specialized span fill methods on the
+ // iterator/accessor
+ while( currPix != rowEnd )
+ ad.set(fillColor, currPix++);
+ }
+
+ // step vertices
+ rV1.mnX += rV1.mnXDelta;
+ --rV1.mnYCounter;
+
+ ++nCrossedEdges;
+ }
+
+ // step vertex also for the last one
+ detail::Vertex& rLastV( **currVertex );
+ rLastV.mnX += rLastV.mnXDelta;
+ --rLastV.mnYCounter;
+
+
+ // prune AET from ended edges, and keep it sorted
+ // ---------------------------------------------------------
+
+ pAETOther->clear();
+ if( pAET->size() == 2 )
+ {
+ // the case of exactly two active edges is both
+ // sufficiently common (all 'simple' polygons have
+ // it), and further more would complicate the
+ // generic case below (which works with a sliding
+ // triple of vertices).
+ if( !aComp(*(*pAET)[0], *(*pAET)[1]) )
+ std::swap(*(*pAET)[0], *(*pAET)[1]);
+
+ if( (*pAET)[0]->mnYCounter > 0 )
+ pAETOther->push_back( (*pAET)[0] );
+ if( (*pAET)[1]->mnYCounter > 0 )
+ pAETOther->push_back( (*pAET)[1] );
+ }
+ else
+ {
+ bool bFallbackTaken(false);
+ currVertex = pAET->begin();
+ detail::VectorOfVertexPtr::iterator prevVertex( currVertex );
+ while( currVertex != lastVertex )
+ {
+ // try to get away with one linear swoop and
+ // simple neighbor swapping. this is an
+ // overwhelmingly common case - polygons with
+ // excessively crisscrossing edges (which on
+ // top of that cross more than one other edge
+ // per scanline) are seldom. And even if we
+ // get such a beast here, this extra loop has
+ // still only linear cost
+ if( aComp(**(currVertex+1),**currVertex) )
+ {
+ std::swap(*currVertex, *(currVertex+1));
+
+ if( aComp(**currVertex,**prevVertex) )
+ {
+ // one swap was not sufficient -
+ // fallback to generic sort algo, then
+ detail::sortAET(*pAET, *pAETOther);
+ bFallbackTaken = true;
+ break;
+ }
+ }
+
+ if( (*currVertex)->mnYCounter > 0 )
+ pAETOther->push_back( *currVertex );
+
+ prevVertex = currVertex++;
+ }
+
+ // don't forget to add last vertex (loop above
+ // only deals with n-1 vertices)
+ if( !bFallbackTaken && (*currVertex)->mnYCounter > 0 )
+ pAETOther->push_back( *currVertex );
+ }
+
+ std::swap( pAET, pAETOther );
+ }
+
+ if( y >= nClipY1 )
+ ++aScanline.y;
+ }
+ }
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_POLYPOLYGONRENDERER_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/rgb24pixelformats.hxx b/basebmp/inc/basebmp/rgb24pixelformats.hxx
new file mode 100644
index 000000000000..91d374efd7e9
--- /dev/null
+++ b/basebmp/inc/basebmp/rgb24pixelformats.hxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_RGB24PIXELFORMATS_HXX
+#define INCLUDED_BASEBMP_RGB24PIXELFORMATS_HXX
+
+#include <basebmp/color.hxx>
+#include <basebmp/accessor.hxx>
+#include <basebmp/pixeliterator.hxx>
+#include <basebmp/pixelformatadapters.hxx>
+
+#include <vigra/rgbvalue.hxx>
+
+#include <functional>
+
+namespace basebmp
+{
+
+template< typename PixelType, typename ColorType > struct RGBValueGetter :
+ public std::unary_function<PixelType, ColorType>
+{
+ ColorType operator()( PixelType const& c ) const
+ {
+ return ColorType(c.red(),c.green(),c.blue());
+ }
+};
+
+template< typename PixelType, typename ColorType > struct RGBValueSetter :
+ public std::unary_function<ColorType, PixelType>
+{
+ PixelType operator()( ColorType const& c ) const
+ {
+ PixelType res;
+ res.setRed(c.getRed());
+ res.setGreen(c.getGreen());
+ res.setBlue(c.getBlue());
+ return res;
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+template< typename PixelType > struct PixelFormatTraitsTemplate_RGBValue
+{
+ typedef PixelType pixel_type;
+
+ typedef RGBValueGetter<pixel_type,
+ Color> getter_type;
+ typedef RGBValueSetter<pixel_type,
+ Color> setter_type;
+
+ typedef PixelIterator<pixel_type> iterator_type;
+ typedef StandardAccessor<pixel_type> raw_accessor_type;
+ typedef AccessorSelector<
+ getter_type, setter_type> accessor_selector;
+};
+
+//-----------------------------------------------------------------------------
+
+// 24bpp RGB
+typedef PixelFormatTraitsTemplate_RGBValue<
+ vigra::RGBValue<sal_uInt8> > PixelFormatTraits_RGB24;
+BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB24::getter_type,
+ PixelFormatTraits_RGB24::setter_type);
+
+// 24bpp BGR
+typedef PixelFormatTraitsTemplate_RGBValue<
+ vigra::RGBValue<sal_uInt8,2,1,0> > PixelFormatTraits_BGR24;
+BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_BGR24::getter_type,
+ PixelFormatTraits_BGR24::setter_type);
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_RGB24PIXELFORMATS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/rgbmaskpixelformats.hxx b/basebmp/inc/basebmp/rgbmaskpixelformats.hxx
new file mode 100644
index 000000000000..47f7c2bf6199
--- /dev/null
+++ b/basebmp/inc/basebmp/rgbmaskpixelformats.hxx
@@ -0,0 +1,292 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX
+#define INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX
+
+#include <basebmp/color.hxx>
+#include <basebmp/colortraits.hxx>
+#include <basebmp/accessor.hxx>
+#include <basebmp/pixeliterator.hxx>
+#include <basebmp/pixelformatadapters.hxx>
+#include <basebmp/metafunctions.hxx>
+#include <basebmp/endian.hxx>
+
+#include <vigra/numerictraits.hxx>
+#include <vigra/metaprogramming.hxx>
+
+#include <functional>
+
+namespace basebmp
+{
+
+/** Base class operating on RGB truecolor mask pixel
+
+ Use this template, if you have an (integer) pixel type, and three
+ bitmasks denoting where the channel bits are.
+
+ @tpl PixelType
+ Input pixel type to operate on
+
+ @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 on.
+ */
+template< typename PixelType,
+ typename ColorType,
+ unsigned int RedMask,
+ unsigned int GreenMask,
+ unsigned int BlueMask,
+ bool SwapBytes > struct RGBMaskFunctorBase
+{
+ typedef PixelType pixel_type;
+ typedef ColorType color_type;
+ typedef typename make_unsigned<pixel_type>::type unsigned_pixel_type;
+ typedef typename ColorTraits<ColorType>::component_type component_type;
+
+ // 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
+ };
+};
+
+template< typename PixelType,
+ typename ColorType,
+ unsigned int RedMask,
+ unsigned int GreenMask,
+ unsigned int BlueMask,
+ bool SwapBytes > struct RGBMaskGetter :
+ public RGBMaskFunctorBase<PixelType,
+ ColorType,
+ RedMask,
+ GreenMask,
+ BlueMask,
+ SwapBytes>,
+ public std::unary_function<PixelType, ColorType>
+{
+ typedef RGBMaskFunctorBase<PixelType,
+ ColorType,
+ RedMask,
+ GreenMask,
+ BlueMask,
+ SwapBytes> base_type;
+
+ ColorType operator()( PixelType v ) const
+ {
+ v = SwapBytes ? byteSwap(v) : v;
+
+ const typename base_type::unsigned_pixel_type red (v & RedMask);
+ const typename base_type::unsigned_pixel_type green(v & GreenMask);
+ const typename base_type::unsigned_pixel_type blue (v & BlueMask);
+
+ // shift color nibbles to right-aligend position. ORing it
+ // channel value shifted twice the number of channel bits, to
+ // spread the value into the component_type range
+ ColorType res( (shiftRight(red,
+ base_type::red_shift-8*
+ (signed)sizeof(typename base_type::component_type)+
+ base_type::red_bits)) |
+ (shiftRight(red,
+ base_type::red_shift-8*
+ (signed)sizeof(typename base_type::component_type)+
+ 2*base_type::red_bits)),
+
+ (shiftRight(green,
+ base_type::green_shift-8*
+ (signed)sizeof(typename base_type::component_type)+
+ base_type::green_bits)) |
+ (shiftRight(green,
+ base_type::green_shift-8*
+ (signed)sizeof(typename base_type::component_type)+
+ 2*base_type::green_bits)),
+
+ (shiftRight(blue,
+ base_type::blue_shift-8*
+ (signed)sizeof(typename base_type::component_type)+
+ base_type::blue_bits)) |
+ (shiftRight(blue,
+ base_type::blue_shift-8*
+ (signed)sizeof(typename base_type::component_type)+
+ 2*base_type::blue_bits)) );
+ return res;
+ }
+};
+
+template< typename PixelType,
+ typename ColorType,
+ unsigned int RedMask,
+ unsigned int GreenMask,
+ unsigned int BlueMask,
+ bool SwapBytes > struct RGBMaskSetter :
+ public RGBMaskFunctorBase<PixelType,
+ ColorType,
+ RedMask,
+ GreenMask,
+ BlueMask,
+ SwapBytes>,
+ public std::unary_function<ColorType, PixelType>
+{
+ typedef RGBMaskFunctorBase<PixelType,
+ ColorType,
+ RedMask,
+ GreenMask,
+ BlueMask,
+ SwapBytes> base_type;
+
+ PixelType operator()( ColorType const& c ) const
+ {
+ const typename base_type::unsigned_pixel_type red (c.getRed());
+ const typename base_type::unsigned_pixel_type green(c.getGreen());
+ const typename base_type::unsigned_pixel_type blue (c.getBlue());
+
+ typename base_type::unsigned_pixel_type res(
+ (shiftLeft(red,
+ base_type::red_shift-8*
+ (signed)sizeof(typename base_type::component_type)+
+ base_type::red_bits) & RedMask) |
+ (shiftLeft(green,
+ base_type::green_shift-8*
+ (signed)sizeof(typename base_type::component_type)+
+ base_type::green_bits) & GreenMask) |
+ (shiftLeft(blue,
+ base_type::blue_shift-8*
+ (signed)sizeof(typename base_type::component_type)+
+ base_type::blue_bits) & BlueMask) );
+
+ return SwapBytes ? byteSwap(res) : res;
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+template< typename PixelType,
+ unsigned int RedMask,
+ unsigned int GreenMask,
+ unsigned int BlueMask,
+ bool SwapBytes > struct PixelFormatTraitsTemplate_RGBMask
+{
+ typedef PixelType pixel_type;
+
+ typedef RGBMaskGetter<pixel_type,
+ Color,
+ RedMask,
+ GreenMask,
+ BlueMask,
+ SwapBytes> getter_type;
+ typedef RGBMaskSetter<pixel_type,
+ Color,
+ RedMask,
+ GreenMask,
+ BlueMask,
+ SwapBytes> setter_type;
+
+ typedef PixelIterator<pixel_type> iterator_type;
+ typedef StandardAccessor<pixel_type> raw_accessor_type;
+ typedef AccessorSelector<
+ getter_type, setter_type> accessor_selector;
+};
+
+//-----------------------------------------------------------------------------
+
+#ifdef OSL_LITENDIAN
+# define BASEBMP_TRUECOLORMASK_LSB_SWAP false
+# define BASEBMP_TRUECOLORMASK_MSB_SWAP true
+#else
+# ifdef OSL_BIGENDIAN
+# define BASEBMP_TRUECOLORMASK_LSB_SWAP true
+# define BASEBMP_TRUECOLORMASK_MSB_SWAP false
+# else
+# error Undetermined endianness!
+# endif
+#endif
+
+//-----------------------------------------------------------------------------
+
+// 16bpp MSB RGB
+typedef PixelFormatTraitsTemplate_RGBMask<
+ sal_uInt16,
+ 0xF800,
+ 0x07E0,
+ 0x001F,
+ BASEBMP_TRUECOLORMASK_MSB_SWAP > PixelFormatTraits_RGB16_565_MSB;
+BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB16_565_MSB::getter_type,
+ PixelFormatTraits_RGB16_565_MSB::setter_type);
+
+// 16bpp LSB RGB
+typedef PixelFormatTraitsTemplate_RGBMask<
+ sal_uInt16,
+ 0xF800,
+ 0x07E0,
+ 0x001F,
+ BASEBMP_TRUECOLORMASK_LSB_SWAP > PixelFormatTraits_RGB16_565_LSB;
+BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB16_565_LSB::getter_type,
+ PixelFormatTraits_RGB16_565_LSB::setter_type);
+
+// 32bpp endian-sensitive RGB
+typedef PixelFormatTraitsTemplate_RGBMask<
+ sal_uInt32,
+ 0xFF0000,
+ 0x00FF00,
+ 0x0000FF,
+ BASEBMP_TRUECOLORMASK_LSB_SWAP > PixelFormatTraits_RGB32_888;
+BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_RGB32_888::getter_type,
+ PixelFormatTraits_RGB32_888::setter_type);
+
+// 32bpp endian-sensitive BGR
+typedef PixelFormatTraitsTemplate_RGBMask<
+ sal_uInt32,
+ 0xFF0000,
+ 0x00FF00,
+ 0x0000FF,
+ BASEBMP_TRUECOLORMASK_MSB_SWAP > PixelFormatTraits_BGR32_888;
+BASEBMP_SPECIALIZE_ACCESSORTRAITS(PixelFormatTraits_BGR32_888::getter_type,
+ PixelFormatTraits_BGR32_888::setter_type);
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_RGBMASKPIXELFORMATS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/scaleimage.hxx b/basebmp/inc/basebmp/scaleimage.hxx
new file mode 100644
index 000000000000..a8fd83e2cd94
--- /dev/null
+++ b/basebmp/inc/basebmp/scaleimage.hxx
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_SCALEIMAGE_HXX
+#define INCLUDED_BASEBMP_SCALEIMAGE_HXX
+
+#include <osl/diagnose.h>
+
+#include <vigra/tuple.hxx>
+#include <vigra/copyimage.hxx>
+#include <vigra/basicimage.hxx>
+#include <vigra/iteratortraits.hxx>
+
+namespace basebmp
+{
+
+template< class SourceIter, class SourceAcc,
+ class DestIter, class DestAcc >
+void scaleLine( SourceIter s_begin,
+ SourceIter s_end,
+ SourceAcc s_acc,
+ DestIter d_begin,
+ DestIter d_end,
+ DestAcc d_acc )
+{
+ const int src_width = s_end - s_begin;
+ const int dest_width = d_end - d_begin;
+
+ OSL_ASSERT( src_width > 0 && dest_width > 0 );
+
+ if( src_width >= dest_width )
+ {
+ // shrink
+ int rem = 0;
+ while( s_begin != s_end )
+ {
+ if( rem >= 0 )
+ {
+ d_acc.set( s_acc(s_begin), d_begin );
+
+ rem -= src_width;
+ ++d_begin;
+ }
+
+ rem += dest_width;
+ ++s_begin;
+ }
+ }
+ else
+ {
+ // enlarge
+ int rem = -dest_width;
+ while( d_begin != d_end )
+ {
+ if( rem >= 0 )
+ {
+ rem -= dest_width;
+ ++s_begin;
+ }
+
+ d_acc.set( s_acc(s_begin), d_begin );
+
+ rem += src_width;
+ ++d_begin;
+ }
+ }
+}
+
+/** Scale an image using zero order interpolation (pixel replication)
+
+ Source and destination range must be at least one pixel wide and
+ high.
+
+ @param s_begin
+ Start iterator for source image
+
+ @param s_end
+ End iterator for source image
+
+ @param s_acc
+ Source accessor
+
+ @param d_begin
+ Start iterator for destination image
+
+ @param d_end
+ End iterator for destination image
+
+ @param d_acc
+ Destination accessor
+
+ @param bMustCopy
+ When true, scaleImage always copies source, even when doing 1:1
+ copy
+ */
+template< class SourceIter, class SourceAcc,
+ class DestIter, class DestAcc >
+void scaleImage( SourceIter s_begin,
+ SourceIter s_end,
+ SourceAcc s_acc,
+ DestIter d_begin,
+ DestIter d_end,
+ DestAcc d_acc,
+ bool bMustCopy=false )
+{
+ const int src_width ( s_end.x - s_begin.x );
+ const int src_height( s_end.y - s_begin.y );
+
+ const int dest_width ( d_end.x - d_begin.x );
+ const int dest_height( d_end.y - d_begin.y );
+
+ if( !bMustCopy &&
+ src_width == dest_width &&
+ src_height == dest_height )
+ {
+ // no scaling involved, can simply copy
+ vigra::copyImage( s_begin, s_end, s_acc,
+ d_begin, d_acc );
+ return;
+ }
+
+ typedef vigra::BasicImage<typename SourceAcc::value_type> TmpImage;
+ typedef typename TmpImage::traverser TmpImageIter;
+
+ TmpImage tmp_image(src_width,
+ dest_height);
+ TmpImageIter t_begin = tmp_image.upperLeft();
+
+ // scale in y direction
+ for( int x=0; x<src_width; ++x, ++s_begin.x, ++t_begin.x )
+ {
+ typename SourceIter::column_iterator s_cbegin = s_begin.columnIterator();
+ typename TmpImageIter::column_iterator t_cbegin = t_begin.columnIterator();
+
+ scaleLine(s_cbegin, s_cbegin+src_height, s_acc,
+ t_cbegin, t_cbegin+dest_height, tmp_image.accessor());
+ }
+
+ t_begin = tmp_image.upperLeft();
+
+ // scale in x direction
+ for( int y=0; y<dest_height; ++y, ++d_begin.y, ++t_begin.y )
+ {
+ typename DestIter::row_iterator d_rbegin = d_begin.rowIterator();
+ typename TmpImageIter::row_iterator t_rbegin = t_begin.rowIterator();
+
+ scaleLine(t_rbegin, t_rbegin+src_width, tmp_image.accessor(),
+ d_rbegin, d_rbegin+dest_width, d_acc);
+ }
+}
+
+/** Scale an image, range tuple version
+
+ @param bMustCopy
+ When true, scaleImage always copies source, even when doing 1:1
+ copy
+ */
+template< class SourceIter, class SourceAcc,
+ class DestIter, class DestAcc >
+inline void scaleImage( vigra::triple<SourceIter,SourceIter,SourceAcc> const& src,
+ vigra::triple<DestIter,DestIter,DestAcc> const& dst,
+ bool bMustCopy=false )
+{
+ scaleImage(src.first,src.second,src.third,
+ dst.first,dst.second,dst.third,
+ bMustCopy);
+}
+
+}
+
+#endif /* INCLUDED_BASEBMP_SCALEIMAGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/scanlineformats.hxx b/basebmp/inc/basebmp/scanlineformats.hxx
new file mode 100644
index 000000000000..ee466f21b5c9
--- /dev/null
+++ b/basebmp/inc/basebmp/scanlineformats.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_SCANLINEFORMATS_HXX
+#define INCLUDED_BASEBMP_SCANLINEFORMATS_HXX
+
+#include <sal/types.h>
+
+/* Definition of Scanline formats */
+
+namespace basebmp { namespace Format
+{
+ static const sal_Int32 NONE = 0;
+ static const sal_Int32 ONE_BIT_MSB_GREY = (sal_Int32)0x01;
+ static const sal_Int32 ONE_BIT_LSB_GREY = (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 FOUR_BIT_MSB_GREY = (sal_Int32)0x05;
+ static const sal_Int32 FOUR_BIT_LSB_GREY = (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_GREY = (sal_Int32)0x0A;
+ 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 THIRTYTWO_BIT_TC_MASK_ARGB = (sal_Int32)0x0F;
+ static const sal_Int32 MAX = (sal_Int32)0x0F;
+} }
+
+#endif /* INCLUDED_BASEBMP_SCANLINEFORMATS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/stridedarrayiterator.hxx b/basebmp/inc/basebmp/stridedarrayiterator.hxx
new file mode 100644
index 000000000000..422269cb70e4
--- /dev/null
+++ b/basebmp/inc/basebmp/stridedarrayiterator.hxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_STRIDEDARRAYITERATOR_HXX
+#define INCLUDED_BASEBMP_STRIDEDARRAYITERATOR_HXX
+
+#include <basebmp/metafunctions.hxx>
+
+namespace basebmp
+{
+
+/** Like vigra::StridedArrayIterator
+
+ Changed semantics re. DirectionSelector<StridedArrayTag>: stride
+ now counts in <em>raw</em> bytes
+
+ Adapts given ptr, in a way that iterator increments move forward
+ in strided steps. Stride can, by the way, also be negative
+ */
+template< typename T > class StridedArrayIterator
+{
+public:
+ typedef typename clone_const<T, unsigned char>::type internal_type;
+
+ /** Create iterator
+
+ @param stride
+
+ Stride in bytes. Given value should better match memory layout
+ of T, as memory gets reinterpret-casted.
+ */
+ explicit StridedArrayIterator(int stride, T* ptr = 0) :
+ stride_(stride),
+ current_(reinterpret_cast<internal_type*>(ptr))
+ {}
+
+ /** Copy from other StridedArrayIterator, plus given offset
+
+ @param offset
+ Offset in bytes
+ */
+ StridedArrayIterator( StridedArrayIterator const& rSrc,
+ int offset ) :
+ stride_(rSrc.stride_),
+ current_(reinterpret_cast<internal_type*>(
+ reinterpret_cast<T*>(rSrc.current_)+offset))
+ {}
+
+ void operator++() {current_ += stride_; }
+ void operator++(int) {current_ += stride_; }
+ void operator--() {current_ -= stride_; }
+ void operator--(int) {current_ -= stride_; }
+ void operator+=(int dy) {current_ += dy*stride_; }
+ void operator-=(int dy) {current_ -= dy*stride_; }
+
+ int operator-(StridedArrayIterator const & rhs) const
+ { return (current_ - rhs.current_) / stride_; }
+
+ bool operator==(StridedArrayIterator const & rhs) const
+ { return current_ == rhs.current_; }
+
+ bool operator!=(StridedArrayIterator const & rhs) const
+ { return current_ != rhs.current_; }
+
+ bool operator<(StridedArrayIterator const & rhs) const
+ { return *this - rhs < 0; }
+
+ bool operator<=(StridedArrayIterator const & rhs) const
+ { return *this - rhs <= 0; }
+
+ bool operator>(StridedArrayIterator const & rhs) const
+ { return *this - rhs > 0; }
+
+ bool operator>=(StridedArrayIterator const & rhs) const
+ { return *this - rhs >= 0; }
+
+ T* operator()() const
+ { return reinterpret_cast<T*>(current_); }
+
+ T* operator()(int d) const
+ { return reinterpret_cast<T*>(current_ + d*stride_); }
+
+private:
+ int stride_;
+ internal_type* current_;
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_STRIDEDARRAYITERATOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/tools.hxx b/basebmp/inc/basebmp/tools.hxx
new file mode 100644
index 000000000000..0b5fcb87a693
--- /dev/null
+++ b/basebmp/inc/basebmp/tools.hxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_TOOLS_HXX
+#define INCLUDED_BASEBMP_TOOLS_HXX
+
+#include <basegfx/range/b2irange.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+#include <vigra/tuple.hxx>
+#include <vigra/diff2d.hxx>
+
+namespace basebmp
+{
+ inline vigra::Diff2D topLeft( const basegfx::B2IRange& rRange )
+ { return vigra::Diff2D(rRange.getMinX(),rRange.getMinY()); }
+
+ inline vigra::Diff2D bottomRight( const basegfx::B2IRange& rRange )
+ { return vigra::Diff2D(rRange.getMaxX(),rRange.getMaxY()); }
+
+ template< class Iterator, class Accessor >
+ inline vigra::triple<Iterator,Iterator,Accessor>
+ destIterRange(Iterator const& begin,
+ Accessor const& accessor,
+ const basegfx::B2IRange& rRange)
+ {
+ return vigra::triple<Iterator,Iterator,Accessor>(
+ begin + topLeft(rRange),
+ begin + bottomRight(rRange),
+ accessor);
+ }
+
+ template< class Iterator, class Accessor >
+ inline vigra::triple<Iterator,Iterator,Accessor>
+ srcIterRange(Iterator const& begin,
+ Accessor const& accessor,
+ const basegfx::B2IRange& rRange)
+ {
+ return vigra::triple<Iterator,Iterator,Accessor>(
+ begin + topLeft(rRange),
+ begin + bottomRight(rRange),
+ accessor);
+ }
+
+ template< class Iterator, class Accessor >
+ inline vigra::pair<Iterator,Accessor>
+ srcIter(Iterator const& begin,
+ Accessor const& accessor,
+ const basegfx::B2IPoint& rPt)
+ {
+ return vigra::pair<Iterator,Accessor>(
+ begin + vigra::Diff2D(rPt.getX(),rPt.getY()),
+ accessor);
+ }
+
+ template< class Iterator, class Accessor >
+ inline vigra::pair<Iterator,Accessor>
+ destIter(Iterator const& begin,
+ Accessor const& accessor,
+ const basegfx::B2IPoint& rPt)
+ {
+ return vigra::pair<Iterator,Accessor>(
+ begin + vigra::Diff2D(rPt.getX(),rPt.getY()),
+ accessor);
+ }
+}
+
+#endif /* INCLUDED_BASEBMP_TOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basebmp/inc/basebmp/truecolormaskaccessor.hxx b/basebmp/inc/basebmp/truecolormaskaccessor.hxx
new file mode 100644
index 000000000000..79693a7b0ebb
--- /dev/null
+++ b/basebmp/inc/basebmp/truecolormaskaccessor.hxx
@@ -0,0 +1,293 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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 */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */