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