1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX 25 #define INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX 26 27 #include <basebmp/colortraits.hxx> 28 #include <basebmp/accessortraits.hxx> 29 30 #include <vigra/numerictraits.hxx> 31 #include <vigra/metaprogramming.hxx> 32 33 #include <algorithm> 34 #include <functional> 35 36 namespace basebmp 37 { 38 39 /** Access pixel data via palette indirection 40 41 @tpl Accessor 42 Raw accessor, to be used to actually access the pixel values 43 44 @tpl ColorType 45 The color value type to use - e.g. the palette is an array of that 46 type 47 */ 48 template< class Accessor, typename ColorType > class PaletteImageAccessor 49 { 50 public: 51 typedef typename Accessor::value_type data_type; 52 typedef ColorType value_type; 53 54 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS 55 // making all members public, if no member template friends 56 private: 57 template<class A, typename C> friend class PaletteImageAccessor; 58 #endif 59 60 Accessor maAccessor; 61 const value_type* mpPalette; 62 std::size_t mnNumEntries; 63 64 public: PaletteImageAccessor()65 PaletteImageAccessor() : 66 maAccessor(), 67 mpPalette(0), 68 mnNumEntries(0) 69 {} 70 71 template< class A > explicit PaletteImageAccessor(PaletteImageAccessor<A,ColorType> const & rSrc)72 PaletteImageAccessor( PaletteImageAccessor<A,ColorType> const& rSrc ) : 73 maAccessor( rSrc.maAccessor ), 74 mpPalette( rSrc.mpPalette ), 75 mnNumEntries( rSrc.mnNumEntries ) 76 {} 77 PaletteImageAccessor(const value_type * pPalette,std::size_t numEntries)78 PaletteImageAccessor( const value_type* pPalette, 79 std::size_t numEntries ) : 80 maAccessor(), 81 mpPalette(pPalette), 82 mnNumEntries(numEntries) 83 {} 84 PaletteImageAccessor(T accessor,const value_type * pPalette,std::size_t numEntries)85 template< class T > PaletteImageAccessor( T accessor, 86 const value_type* pPalette, 87 std::size_t numEntries ) : 88 maAccessor(accessor), 89 mpPalette(pPalette), 90 mnNumEntries(numEntries) 91 {} 92 93 // ------------------------------------------------------- 94 getWrappedAccessor() const95 Accessor const& getWrappedAccessor() const { return maAccessor; } getWrappedAccessor()96 Accessor& getWrappedAccessor() { return maAccessor; } 97 98 // ------------------------------------------------------- 99 lookup(value_type const & v) const100 data_type lookup(value_type const& v) const 101 { 102 // TODO(P3): use table-based/octree approach here! 103 const value_type* best_entry; 104 const value_type* palette_end( mpPalette+mnNumEntries ); 105 if( (best_entry=std::find( mpPalette, palette_end, v)) != palette_end ) 106 return best_entry-mpPalette; 107 108 const value_type* curr_entry( mpPalette ); 109 best_entry = curr_entry; 110 while( curr_entry != palette_end ) 111 { 112 if( ColorTraits<value_type>::distance(*curr_entry, 113 *best_entry) 114 > ColorTraits<value_type>::distance(*curr_entry, 115 v) ) 116 { 117 best_entry = curr_entry; 118 } 119 120 ++curr_entry; 121 } 122 123 return best_entry-mpPalette; 124 } 125 126 // ------------------------------------------------------- 127 128 template< class Iterator > operator ()(Iterator const & i) const129 value_type operator()(Iterator const& i) const 130 { 131 return mpPalette[ maAccessor(i) ]; 132 } 133 134 template< class Iterator, class Difference > operator ()(Iterator const & i,Difference const & diff) const135 value_type operator()(Iterator const& i, Difference const& diff) const 136 { 137 return mpPalette[ maAccessor(i,diff) ]; 138 } 139 140 // ------------------------------------------------------- 141 142 template< typename V, class Iterator > set(V const & value,Iterator const & i) const143 void set(V const& value, Iterator const& i) const 144 { 145 maAccessor.set( 146 lookup( 147 vigra::detail::RequiresExplicitCast<value_type>::cast(value) ), 148 i ); 149 } 150 151 template< typename V, class Iterator, class Difference > set(V const & value,Iterator const & i,Difference const & diff) const152 void set(V const& value, Iterator const& i, Difference const& diff) const 153 { 154 maAccessor.set( 155 lookup( 156 vigra::detail::RequiresExplicitCast<value_type>::cast(value) ), 157 i, 158 diff ); 159 } 160 }; 161 162 } // namespace basebmp 163 164 #endif /* INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX */ 165