1 /* -*- c++ -*-
2 gimp.h: Header for a Qt 3 plug-in for reading GIMP XCF image files
3 SPDX-FileCopyrightText: 2001 lignum Computing Inc. <allen@lignumcomputing.com>
4 SPDX-FileCopyrightText: 2004 Melchior FRANZ <mfranz@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8
9 #ifndef GIMP_H
10 #define GIMP_H
11
12 typedef unsigned char uchar;
13
14 /*
15 * These are the constants and functions I extracted from The GIMP source
16 * code. If the reader fails to work, this is probably the place to start
17 * looking for discontinuities.
18 */
19
20 // From GIMP "tile.h" v1.2
21
22 const uint TILE_WIDTH = 64; //!< Width of a tile in the XCF file.
23 const uint TILE_HEIGHT = 64; //!< Height of a tile in the XCF file.
24
25 // From GIMP "paint_funcs.c" v1.2
26
27 const int RANDOM_TABLE_SIZE = 4096; //!< Size of dissolve random number table.
28 const int RANDOM_SEED = 314159265; //!< Seed for dissolve random number table.
29 const double EPSILON = 0.0001; //!< Roundup in alpha blending.
30
31 // From GIMP "paint_funcs.h" v1.2
32
33 const uchar OPAQUE_OPACITY = 255; //!< Opaque value for 8-bit alpha component.
34
35 // From GIMP "apptypes.h" v1.2
36
37 //! Basic GIMP image type. QImage converter may produce a deeper image
38 //! than is specified here. For example, a grayscale image with an
39 //! alpha channel must (currently) use a 32-bit Qt image.
40
41 typedef enum {
42 RGB,
43 GRAY,
44 INDEXED,
45 } GimpImageBaseType;
46
47 // From GIMP "libgimp/gimpenums.h" v2.4
48
49 //! Effect to apply when layers are merged together.
50
51 typedef enum {
52 NORMAL_MODE,
53 DISSOLVE_MODE,
54 BEHIND_MODE,
55 MULTIPLY_MODE,
56 SCREEN_MODE,
57 OVERLAY_MODE,
58 DIFFERENCE_MODE,
59 ADDITION_MODE,
60 SUBTRACT_MODE,
61 DARKEN_ONLY_MODE,
62 LIGHTEN_ONLY_MODE,
63 HUE_MODE,
64 SATURATION_MODE,
65 COLOR_MODE,
66 VALUE_MODE,
67 DIVIDE_MODE,
68 DODGE_MODE,
69 BURN_MODE,
70 HARDLIGHT_MODE,
71 SOFTLIGHT_MODE,
72 GRAIN_EXTRACT_MODE,
73 GRAIN_MERGE_MODE
74 } LayerModeEffects;
75
76 // From GIMP "paint_funcs.c" v1.2
77
78 /*!
79 * Multiply two color components. Really expects the arguments to be
80 * 8-bit quantities.
81 * \param a first minuend.
82 * \param b second minuend.
83 * \return product of arguments.
84 */
INT_MULT(int a,int b)85 inline int INT_MULT(int a, int b)
86 {
87 int c = a * b + 0x80;
88 return ((c >> 8) + c) >> 8;
89 }
90
91 /*!
92 * Blend the two color components in the proportion alpha:
93 *
94 * result = alpha a + ( 1 - alpha ) b
95 *
96 * \param a first component.
97 * \param b second component.
98 * \param alpha blend proportion.
99 * \return blended color components.
100 */
101
INT_BLEND(int a,int b,int alpha)102 inline int INT_BLEND(int a, int b, int alpha)
103 {
104 return INT_MULT(a - b, alpha) + b;
105 }
106
107 // From GIMP "gimpcolorspace.c" v1.2
108
109 /*!
110 * Convert a color in RGB space to HSV space (Hue, Saturation, Value).
111 * \param red the red component (modified in place).
112 * \param green the green component (modified in place).
113 * \param blue the blue component (modified in place).
114 */
RGBTOHSV(uchar & red,uchar & green,uchar & blue)115 static void RGBTOHSV(uchar &red, uchar &green, uchar &blue)
116 {
117 int r, g, b;
118 double h, s, v;
119 int min, max;
120
121 h = 0.;
122
123 r = red;
124 g = green;
125 b = blue;
126
127 if (r > g) {
128 max = qMax(r, b);
129 min = qMin(g, b);
130 } else {
131 max = qMax(g, b);
132 min = qMin(r, b);
133 }
134
135 v = max;
136
137 if (max != 0) {
138 s = ((max - min) * 255) / (double)max;
139 } else {
140 s = 0;
141 }
142
143 if (s == 0) {
144 h = 0;
145 } else {
146 int delta = max - min;
147 if (r == max) {
148 h = (g - b) / (double)delta;
149 } else if (g == max) {
150 h = 2 + (b - r) / (double)delta;
151 } else if (b == max) {
152 h = 4 + (r - g) / (double)delta;
153 }
154 h *= 42.5;
155
156 if (h < 0) {
157 h += 255;
158 }
159 if (h > 255) {
160 h -= 255;
161 }
162 }
163
164 red = (uchar)h;
165 green = (uchar)s;
166 blue = (uchar)v;
167 }
168
169 /*!
170 * Convert a color in HSV space to RGB space.
171 * \param hue the hue component (modified in place).
172 * \param saturation the saturation component (modified in place).
173 * \param value the value component (modified in place).
174 */
HSVTORGB(uchar & hue,uchar & saturation,uchar & value)175 static void HSVTORGB(uchar &hue, uchar &saturation, uchar &value)
176 {
177 if (saturation == 0) {
178 hue = value;
179 saturation = value;
180 // value = value;
181 } else {
182 double h = hue * 6. / 255.;
183 double s = saturation / 255.;
184 double v = value / 255.;
185
186 double f = h - (int)h;
187 double p = v * (1. - s);
188 double q = v * (1. - (s * f));
189 double t = v * (1. - (s * (1. - f)));
190
191 // Worth a note here that gcc 2.96 will generate different results
192 // depending on optimization mode on i386.
193
194 switch ((int)h) {
195 case 0:
196 hue = (uchar)(v * 255);
197 saturation = (uchar)(t * 255);
198 value = (uchar)(p * 255);
199 break;
200 case 1:
201 hue = (uchar)(q * 255);
202 saturation = (uchar)(v * 255);
203 value = (uchar)(p * 255);
204 break;
205 case 2:
206 hue = (uchar)(p * 255);
207 saturation = (uchar)(v * 255);
208 value = (uchar)(t * 255);
209 break;
210 case 3:
211 hue = (uchar)(p * 255);
212 saturation = (uchar)(q * 255);
213 value = (uchar)(v * 255);
214 break;
215 case 4:
216 hue = (uchar)(t * 255);
217 saturation = (uchar)(p * 255);
218 value = (uchar)(v * 255);
219 break;
220 case 5:
221 hue = (uchar)(v * 255);
222 saturation = (uchar)(p * 255);
223 value = (uchar)(q * 255);
224 }
225 }
226 }
227
228 /*!
229 * Convert a color in RGB space to HLS space (Hue, Lightness, Saturation).
230 * \param red the red component (modified in place).
231 * \param green the green component (modified in place).
232 * \param blue the blue component (modified in place).
233 */
RGBTOHLS(uchar & red,uchar & green,uchar & blue)234 static void RGBTOHLS(uchar &red, uchar &green, uchar &blue)
235 {
236 int r = red;
237 int g = green;
238 int b = blue;
239
240 int min, max;
241
242 if (r > g) {
243 max = qMax(r, b);
244 min = qMin(g, b);
245 } else {
246 max = qMax(g, b);
247 min = qMin(r, b);
248 }
249
250 double h;
251 double l = (max + min) / 2.;
252 double s;
253
254 if (max == min) {
255 s = 0.;
256 h = 0.;
257 } else {
258 int delta = max - min;
259
260 if (l < 128) {
261 s = 255 * (double)delta / (double)(max + min);
262 } else {
263 s = 255 * (double)delta / (double)(511 - max - min);
264 }
265
266 if (r == max) {
267 h = (g - b) / (double)delta;
268 } else if (g == max) {
269 h = 2 + (b - r) / (double)delta;
270 } else {
271 h = 4 + (r - g) / (double)delta;
272 }
273
274 h *= 42.5;
275
276 if (h < 0) {
277 h += 255;
278 } else if (h > 255) {
279 h -= 255;
280 }
281 }
282
283 red = (uchar)h;
284 green = (uchar)l;
285 blue = (uchar)s;
286 }
287
288 /*!
289 * Implement the HLS "double hex-cone".
290 * \param n1 lightness fraction (?)
291 * \param n2 saturation fraction (?)
292 * \param hue hue "angle".
293 * \return HLS value.
294 */
HLSVALUE(double n1,double n2,double hue)295 static int HLSVALUE(double n1, double n2, double hue)
296 {
297 double value;
298
299 if (hue > 255) {
300 hue -= 255;
301 } else if (hue < 0) {
302 hue += 255;
303 }
304
305 if (hue < 42.5) {
306 value = n1 + (n2 - n1) * (hue / 42.5);
307 } else if (hue < 127.5) {
308 value = n2;
309 } else if (hue < 170) {
310 value = n1 + (n2 - n1) * ((170 - hue) / 42.5);
311 } else {
312 value = n1;
313 }
314
315 return (int)(value * 255);
316 }
317
318 /*!
319 * Convert a color in HLS space to RGB space.
320 * \param hue the hue component (modified in place).
321 * \param lightness the lightness component (modified in place).
322 * \param saturation the saturation component (modified in place).
323 */
HLSTORGB(uchar & hue,uchar & lightness,uchar & saturation)324 static void HLSTORGB(uchar &hue, uchar &lightness, uchar &saturation)
325 {
326 double h = hue;
327 double l = lightness;
328 double s = saturation;
329
330 if (s == 0) {
331 hue = (uchar)l;
332 lightness = (uchar)l;
333 saturation = (uchar)l;
334 } else {
335 double m1, m2;
336
337 if (l < 128) {
338 m2 = (l * (255 + s)) / 65025.;
339 } else {
340 m2 = (l + s - (l * s) / 255.) / 255.;
341 }
342
343 m1 = (l / 127.5) - m2;
344
345 hue = HLSVALUE(m1, m2, h + 85);
346 lightness = HLSVALUE(m1, m2, h);
347 saturation = HLSVALUE(m1, m2, h - 85);
348 }
349 }
350 #endif
351