File indexing completed on 2024-05-12 07:49:37
0001 /* -*- c++ -*- 0002 gimp.h: Header for a Qt 3 plug-in for reading GIMP XCF image files 0003 SPDX-FileCopyrightText: 2001 lignum Computing Inc. <allen@lignumcomputing.com> 0004 SPDX-FileCopyrightText: 2004 Melchior FRANZ <mfranz@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 0009 #ifndef GIMP_H 0010 #define GIMP_H 0011 0012 typedef unsigned char uchar; 0013 0014 /* 0015 * These are the constants and functions I extracted from The GIMP source 0016 * code. If the reader fails to work, this is probably the place to start 0017 * looking for discontinuities. 0018 */ 0019 0020 // From GIMP "tile.h" v1.2 0021 0022 const uint TILE_WIDTH = 64; //!< Width of a tile in the XCF file. 0023 const uint TILE_HEIGHT = 64; //!< Height of a tile in the XCF file. 0024 0025 // From GIMP "paint_funcs.c" v1.2 0026 0027 const int RANDOM_TABLE_SIZE = 4096; //!< Size of dissolve random number table. 0028 const int RANDOM_SEED = 314159265; //!< Seed for dissolve random number table. 0029 const double EPSILON = 0.0001; //!< Roundup in alpha blending. 0030 0031 // From GIMP "paint_funcs.h" v1.2 0032 0033 const uchar OPAQUE_OPACITY = 255; //!< Opaque value for 8-bit alpha component. 0034 0035 // From GIMP "apptypes.h" v1.2 0036 0037 //! Basic GIMP image type. QImage converter may produce a deeper image 0038 //! than is specified here. For example, a grayscale image with an 0039 //! alpha channel must (currently) use a 32-bit Qt image. 0040 0041 typedef enum { 0042 RGB, 0043 GRAY, 0044 INDEXED, 0045 } GimpImageBaseType; 0046 0047 // From GIMP "libgimp/gimpenums.h" v2.4 0048 0049 // From GIMP "paint_funcs.c" v1.2 0050 0051 /*! 0052 * Multiply two color components. Really expects the arguments to be 0053 * 8-bit quantities. 0054 * \param a first minuend. 0055 * \param b second minuend. 0056 * \return product of arguments. 0057 */ 0058 inline int INT_MULT(int a, int b) 0059 { 0060 int c = a * b + 0x80; 0061 return ((c >> 8) + c) >> 8; 0062 } 0063 0064 /*! 0065 * Blend the two color components in the proportion alpha: 0066 * 0067 * result = alpha a + ( 1 - alpha ) b 0068 * 0069 * \param a first component. 0070 * \param b second component. 0071 * \param alpha blend proportion. 0072 * \return blended color components. 0073 */ 0074 0075 inline int INT_BLEND(int a, int b, int alpha) 0076 { 0077 return INT_MULT(a - b, alpha) + b; 0078 } 0079 0080 // From GIMP "gimpcolorspace.c" v1.2 0081 0082 /*! 0083 * Convert a color in RGB space to HSV space (Hue, Saturation, Value). 0084 * \param red the red component (modified in place). 0085 * \param green the green component (modified in place). 0086 * \param blue the blue component (modified in place). 0087 */ 0088 static void RGBTOHSV(uchar &red, uchar &green, uchar &blue) 0089 { 0090 int r, g, b; 0091 double h, s, v; 0092 int min, max; 0093 0094 h = 0.; 0095 0096 r = red; 0097 g = green; 0098 b = blue; 0099 0100 if (r > g) { 0101 max = qMax(r, b); 0102 min = qMin(g, b); 0103 } else { 0104 max = qMax(g, b); 0105 min = qMin(r, b); 0106 } 0107 0108 v = max; 0109 0110 if (max != 0) { 0111 s = ((max - min) * 255) / (double)max; 0112 } else { 0113 s = 0; 0114 } 0115 0116 if (s == 0) { 0117 h = 0; 0118 } else { 0119 int delta = max - min; 0120 if (r == max) { 0121 h = (g - b) / (double)delta; 0122 } else if (g == max) { 0123 h = 2 + (b - r) / (double)delta; 0124 } else if (b == max) { 0125 h = 4 + (r - g) / (double)delta; 0126 } 0127 h *= 42.5; 0128 0129 if (h < 0) { 0130 h += 255; 0131 } 0132 if (h > 255) { 0133 h -= 255; 0134 } 0135 } 0136 0137 red = (uchar)h; 0138 green = (uchar)s; 0139 blue = (uchar)v; 0140 } 0141 0142 /*! 0143 * Convert a color in HSV space to RGB space. 0144 * \param hue the hue component (modified in place). 0145 * \param saturation the saturation component (modified in place). 0146 * \param value the value component (modified in place). 0147 */ 0148 static void HSVTORGB(uchar &hue, uchar &saturation, uchar &value) 0149 { 0150 if (saturation == 0) { 0151 hue = value; 0152 saturation = value; 0153 // value = value; 0154 } else { 0155 double h = hue * 6. / 255.; 0156 double s = saturation / 255.; 0157 double v = value / 255.; 0158 0159 double f = h - (int)h; 0160 double p = v * (1. - s); 0161 double q = v * (1. - (s * f)); 0162 double t = v * (1. - (s * (1. - f))); 0163 0164 // Worth a note here that gcc 2.96 will generate different results 0165 // depending on optimization mode on i386. 0166 0167 switch ((int)h) { 0168 case 0: 0169 hue = (uchar)(v * 255); 0170 saturation = (uchar)(t * 255); 0171 value = (uchar)(p * 255); 0172 break; 0173 case 1: 0174 hue = (uchar)(q * 255); 0175 saturation = (uchar)(v * 255); 0176 value = (uchar)(p * 255); 0177 break; 0178 case 2: 0179 hue = (uchar)(p * 255); 0180 saturation = (uchar)(v * 255); 0181 value = (uchar)(t * 255); 0182 break; 0183 case 3: 0184 hue = (uchar)(p * 255); 0185 saturation = (uchar)(q * 255); 0186 value = (uchar)(v * 255); 0187 break; 0188 case 4: 0189 hue = (uchar)(t * 255); 0190 saturation = (uchar)(p * 255); 0191 value = (uchar)(v * 255); 0192 break; 0193 case 5: 0194 hue = (uchar)(v * 255); 0195 saturation = (uchar)(p * 255); 0196 value = (uchar)(q * 255); 0197 } 0198 } 0199 } 0200 0201 /*! 0202 * Convert a color in RGB space to HLS space (Hue, Lightness, Saturation). 0203 * \param red the red component (modified in place). 0204 * \param green the green component (modified in place). 0205 * \param blue the blue component (modified in place). 0206 */ 0207 static void RGBTOHLS(uchar &red, uchar &green, uchar &blue) 0208 { 0209 int r = red; 0210 int g = green; 0211 int b = blue; 0212 0213 int min, max; 0214 0215 if (r > g) { 0216 max = qMax(r, b); 0217 min = qMin(g, b); 0218 } else { 0219 max = qMax(g, b); 0220 min = qMin(r, b); 0221 } 0222 0223 double h; 0224 double l = (max + min) / 2.; 0225 double s; 0226 0227 if (max == min) { 0228 s = 0.; 0229 h = 0.; 0230 } else { 0231 int delta = max - min; 0232 0233 if (l < 128) { 0234 s = 255 * (double)delta / (double)(max + min); 0235 } else { 0236 s = 255 * (double)delta / (double)(511 - max - min); 0237 } 0238 0239 if (r == max) { 0240 h = (g - b) / (double)delta; 0241 } else if (g == max) { 0242 h = 2 + (b - r) / (double)delta; 0243 } else { 0244 h = 4 + (r - g) / (double)delta; 0245 } 0246 0247 h *= 42.5; 0248 0249 if (h < 0) { 0250 h += 255; 0251 } else if (h > 255) { 0252 h -= 255; 0253 } 0254 } 0255 0256 red = (uchar)h; 0257 green = (uchar)l; 0258 blue = (uchar)s; 0259 } 0260 0261 /*! 0262 * Implement the HLS "double hex-cone". 0263 * \param n1 lightness fraction (?) 0264 * \param n2 saturation fraction (?) 0265 * \param hue hue "angle". 0266 * \return HLS value. 0267 */ 0268 static int HLSVALUE(double n1, double n2, double hue) 0269 { 0270 double value; 0271 0272 if (hue > 255) { 0273 hue -= 255; 0274 } else if (hue < 0) { 0275 hue += 255; 0276 } 0277 0278 if (hue < 42.5) { 0279 value = n1 + (n2 - n1) * (hue / 42.5); 0280 } else if (hue < 127.5) { 0281 value = n2; 0282 } else if (hue < 170) { 0283 value = n1 + (n2 - n1) * ((170 - hue) / 42.5); 0284 } else { 0285 value = n1; 0286 } 0287 0288 return (int)(value * 255); 0289 } 0290 0291 /*! 0292 * Convert a color in HLS space to RGB space. 0293 * \param hue the hue component (modified in place). 0294 * \param lightness the lightness component (modified in place). 0295 * \param saturation the saturation component (modified in place). 0296 */ 0297 static void HLSTORGB(uchar &hue, uchar &lightness, uchar &saturation) 0298 { 0299 double h = hue; 0300 double l = lightness; 0301 double s = saturation; 0302 0303 if (s == 0) { 0304 hue = (uchar)l; 0305 lightness = (uchar)l; 0306 saturation = (uchar)l; 0307 } else { 0308 double m1, m2; 0309 0310 if (l < 128) { 0311 m2 = (l * (255 + s)) / 65025.; 0312 } else { 0313 m2 = (l + s - (l * s) / 255.) / 255.; 0314 } 0315 0316 m1 = (l / 127.5) - m2; 0317 0318 hue = HLSVALUE(m1, m2, h + 85); 0319 lightness = HLSVALUE(m1, m2, h); 0320 saturation = HLSVALUE(m1, m2, h - 85); 0321 } 0322 } 0323 #endif