1 /* 2 * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 #ifndef KOCHANNELINFO_H_ 20 #define KOCHANNELINFO_H_ 21 22 #include <limits> 23 24 #include <QColor> 25 #include <QString> 26 #include <QList> 27 28 /** 29 * This class gives some basic information about a channel, 30 * that is, one of the components that makes up a particular 31 * pixel. 32 */ 33 class KoChannelInfo 34 { 35 public: 36 /** 37 * Used to represent a min and max range. 38 */ 39 struct DoubleRange 40 { 41 public: 42 double minVal, maxVal; 43 public: 44 /// creates an invalid range of 0,0 DoubleRangeDoubleRange45 DoubleRange(void) : minVal(0), maxVal(0) { } 46 /// creates DoubleRangeDoubleRange47 DoubleRange(qreal _minVal, qreal _maxVal) : minVal(_minVal), maxVal(_maxVal) { Q_ASSERT(minVal <= maxVal); } 48 /// true if this range is usable isValidDoubleRange49 bool isValid(void) const { return minVal < maxVal; } 50 }; 51 public: 52 /// enum to define the type of the channel 53 enum enumChannelType { 54 COLOR, ///< The channel represents a color 55 ALPHA ///< The channel represents the opacity of a pixel 56 //SUBSTANCE, ///< The channel represents a real-world substance like pigments or medium 57 //SUBSTRATE ///< The channel represents a real-world painting substrate like a canvas 58 }; 59 /// enum to define the value of the channel 60 enum enumChannelValueType { 61 UINT8, ///< use this for an unsigned integer 8bits channel 62 UINT16, ///< use this for an integer 16bits channel 63 UINT32, ///< use this for an unsigned integer 21bits channel 64 FLOAT16, ///< use this for a float 16bits channel 65 FLOAT32, ///< use this for a float 32bits channel 66 FLOAT64, ///< use this for a float 64bits channel 67 INT8, ///< use this for an integer 8bits channel 68 INT16, ///< use this for an integer 16bits channel 69 OTHER ///< Use this if the channel is neither an integer or a float 70 }; 71 72 public: KoChannelInfo()73 KoChannelInfo() { } 74 /** 75 * @param name of the channel 76 * @param npos position of the channel in the pixel (in bytes) 77 * @param displayPosition the position of the channel in the user-visible order 78 * @param channelType type of the channel 79 * @param channelValueType type of the numerical data used by the channel 80 * @param size number of bytes (not bits) of the channel (if -1, it is deduced from the channelType) 81 * @param color a color to represent that channel (for instance in an histogram) 82 * @param uiMinMax the reange 83 */ 84 KoChannelInfo(const QString & name, 85 qint32 npos, 86 qint32 displayPosition, 87 enumChannelType channelType, 88 enumChannelValueType channelValueType, 89 qint32 size = -1, 90 const QColor &color = QColor(0, 0, 0), 91 const DoubleRange &uiMinMax = DoubleRange()) m_name(name)92 : m_name(name) 93 , m_pos(npos) 94 , m_displayPosition(displayPosition) 95 , m_channelType(channelType) 96 , m_channelValueType(channelValueType) 97 , m_size(size) 98 , m_color(color) 99 , m_uiMinMax(uiMinMax) 100 { 101 switch(m_channelValueType) 102 { 103 case UINT8: 104 case INT8: 105 Q_ASSERT(m_size == -1 || m_size == 1); 106 m_size = 1; 107 break; 108 case UINT16: 109 case INT16: 110 Q_ASSERT(m_size == -1 || m_size == 2); 111 m_size = 2; 112 break; 113 case UINT32: 114 Q_ASSERT(m_size == -1 || m_size == 4); 115 m_size = 4; 116 break; 117 case FLOAT16: 118 Q_ASSERT(m_size == -1 || m_size == 2); 119 m_size = 2; 120 break; 121 case FLOAT32: 122 Q_ASSERT(m_size == -1 || m_size == 4); 123 m_size = 4; 124 break; 125 case FLOAT64: 126 Q_ASSERT(m_size == -1 || m_size == 8); 127 m_size = 8; 128 break; 129 case OTHER: 130 Q_ASSERT(m_size != -1); 131 } 132 if (!uiMinMax.isValid()) { 133 switch (m_channelValueType) { 134 case UINT8: 135 m_uiMinMax.minVal = std::numeric_limits<quint8>::min(); 136 m_uiMinMax.maxVal = std::numeric_limits<quint8>::max(); 137 break; 138 case INT8: 139 m_uiMinMax.minVal = std::numeric_limits<qint8>::min(); 140 m_uiMinMax.maxVal = std::numeric_limits<qint8>::max(); 141 break; 142 case UINT16: 143 m_uiMinMax.minVal = std::numeric_limits<quint16>::min(); 144 m_uiMinMax.maxVal = std::numeric_limits<quint16>::max(); 145 break; 146 case INT16: 147 m_uiMinMax.minVal = std::numeric_limits<qint16>::min(); 148 m_uiMinMax.maxVal = std::numeric_limits<qint16>::max(); 149 break; 150 case UINT32: 151 m_uiMinMax.minVal = std::numeric_limits<quint32>::min(); 152 m_uiMinMax.maxVal = std::numeric_limits<quint32>::max(); 153 break; 154 default: 155 // assume real otherwise, which is 0..1 by default 156 m_uiMinMax.minVal = 0.0; 157 m_uiMinMax.maxVal = 1.0; 158 break; 159 } 160 } 161 Q_ASSERT(m_uiMinMax.isValid()); 162 } 163 public: 164 165 /** 166 * converts the display position to the pixel-order index in the channels vector. 167 */ displayPositionToChannelIndex(int displayPosition,const QList<KoChannelInfo * > & channels)168 static int displayPositionToChannelIndex(int displayPosition, const QList<KoChannelInfo*> &channels) 169 { 170 for (int i = 0; i < channels.size(); ++i) { 171 if (channels.at(i)->displayPosition() == displayPosition) { 172 return i; 173 } 174 } 175 return -1; 176 } 177 displayOrderSorted(const QList<KoChannelInfo * > & channels)178 static QList<KoChannelInfo*> displayOrderSorted(const QList<KoChannelInfo*> &channels) 179 { 180 QList <KoChannelInfo*> sortedChannels; 181 for (int i = 0; i < channels.size(); ++i) { 182 foreach(KoChannelInfo* channel, channels) { 183 if (channel->displayPosition() == i) { 184 sortedChannels << channel; 185 break; 186 } 187 } 188 } 189 Q_ASSERT(channels.size() == sortedChannels.size()); 190 return sortedChannels; 191 } 192 193 /** 194 * User-friendly name for this channel for presentation purposes in the gui 195 */ name()196 inline QString name() const { 197 return m_name; 198 } 199 200 /** 201 * returns the position of the first byte of the channel in the pixel 202 */ pos()203 inline qint32 pos() const { 204 return m_pos; 205 } 206 207 /** 208 * @return the displayPosition of the channel in pixel 209 */ displayPosition()210 inline qint32 displayPosition() const { 211 return m_displayPosition; 212 } 213 214 /** 215 * returns the number of bytes this channel takes 216 */ size()217 inline qint32 size() const { 218 return m_size; 219 } 220 221 /** 222 * returns the type of the channel 223 */ channelType()224 inline enumChannelType channelType() const { 225 return m_channelType; 226 } 227 /** 228 * return the type of the value of the channel (float, uint8 or uint16) 229 */ channelValueType()230 inline enumChannelValueType channelValueType() const { 231 return m_channelValueType; 232 } 233 /** 234 * This is a color that can be used to represent this channel in histograms and so. 235 * By default this is black, so keep in mind that many channels might look the same 236 */ color()237 inline QColor color() const { 238 return m_color; 239 } 240 241 /** 242 * A channel is less than another channel if its pos is smaller. 243 */ 244 inline bool operator<(const KoChannelInfo & info) { 245 return m_pos < info.m_pos; 246 } 247 248 /** 249 * Gets the minimum value that this channel should have. 250 * This is suitable for UI use. 251 */ getUIMin(void)252 inline double getUIMin(void) const { 253 return m_uiMinMax.minVal; 254 } 255 256 /** 257 * Gets the minimum value that this channel should have. 258 * This is suitable for UI use. 259 */ getUIMax(void)260 inline double getUIMax(void) const { 261 return m_uiMinMax.maxVal; 262 } 263 264 private: 265 266 QString m_name; 267 qint32 m_pos; 268 qint32 m_displayPosition; 269 enumChannelType m_channelType; 270 enumChannelValueType m_channelValueType; 271 qint32 m_size; 272 QColor m_color; 273 DoubleRange m_uiMinMax; 274 275 }; 276 277 #endif // KOCHANNELINFO_H_ 278