Doxygen
Loading...
Searching...
No Matches
image.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2022 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#include <vector>
17#include <cmath>
18
19#include "image.h"
20#include "lodepng.h"
21#include "config.h"
22
23typedef unsigned char Byte;
24
25/** Helper struct representing a RGBA color */
33
34const int charSetWidth=80;
35const int charHeight=12;
36const int numChars=96;
37
38const unsigned short charPos[numChars] =
39 {
40 0, 5, 8, 13, 20, 27, 38, 47,
41 50, 54, 58, 65, 72, 76, 83, 87,
42 91, 98,105,112,119,126,133,140,
43 147,154,161,164,167,174,181,188,
44 195,207,216,224,233,242,250,258,
45 267,276,279,286,294,301,312,321,
46 331,339,349,357,365,372,380,389,
47 400,409,418,427,430,434,437,443,
48 450,453,460,467,474,481,488,492,
49 499,506,509,512,518,521,530,537,
50 544,551,557,562,568,571,578,585,
51 594,600,607,613,617,620,624,631
52 };
53
54const unsigned char charWidth[numChars] =
55 {
56 5, 3, 5, 7, 7,11, 9, 3,
57 4, 4, 7, 7, 4, 7, 4, 4,
58
59 7, 7, 7, 7, 7, 7, 7, 7,
60 7, 7, 3, 3, 7, 7, 7, 7,
61 12, 9, 8, 9, 9, 8, 8, 9,
62 9, 3, 7, 8, 7,11, 9,10,
63 8,10, 8, 8, 7, 8, 9,11,
64 9, 9, 9, 3, 4, 3, 6, 7,
65 3, 7, 7, 7, 7, 7, 4, 7,
66 7, 3, 3, 6, 3, 9, 7, 7,
67 7, 6, 5, 6, 3, 7, 7, 9,
68 6, 7, 6, 4, 3, 4, 7, 5
69 };
70
71const unsigned char fontRaw[charSetWidth*charHeight] = {
72 0x02, 0x50, 0x01, 0x06, 0x20, 0x60, 0xc6, 0x04, 0x00, 0x00, 0x00, 0x27,
73 0x04, 0x1c, 0x38, 0x11, 0xf1, 0xc7, 0xc7, 0x0e, 0x00, 0x00, 0x00, 0x03,
74 0x81, 0xf0, 0x10, 0x7c, 0x1e, 0x3e, 0x1f, 0x9f, 0x87, 0x88, 0x24, 0x09,
75 0x09, 0x02, 0x02, 0x41, 0x0f, 0x0f, 0x83, 0xc3, 0xe1, 0xe7, 0xf4, 0x24,
76 0x12, 0x22, 0x41, 0x20, 0x9f, 0xce, 0x30, 0x00, 0x10, 0x04, 0x00, 0x01,
77 0x00, 0x30, 0x08, 0x12, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
78 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x02, 0x51, 0x43, 0x89,
79 0x40, 0x90, 0x49, 0x15, 0x00, 0x00, 0x00, 0x28, 0x9c, 0x22, 0x44, 0x31,
80 0x02, 0x20, 0x48, 0x91, 0x00, 0x00, 0x00, 0x04, 0x46, 0x08, 0x28, 0x42,
81 0x21, 0x21, 0x10, 0x10, 0x08, 0x48, 0x24, 0x09, 0x11, 0x03, 0x06, 0x61,
82 0x10, 0x88, 0x44, 0x22, 0x12, 0x10, 0x84, 0x24, 0x12, 0x22, 0x22, 0x20,
83 0x80, 0x4a, 0x11, 0x00, 0x20, 0x04, 0x00, 0x01, 0x00, 0x40, 0x08, 0x00,
84 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
85 0x02, 0x22, 0x00, 0x00, 0x02, 0x51, 0x45, 0x49, 0x40, 0x90, 0x89, 0x0a,
86 0x00, 0x00, 0x00, 0x48, 0x84, 0x02, 0x04, 0x51, 0x02, 0x00, 0x88, 0x91,
87 0x00, 0x00, 0x00, 0x04, 0x44, 0xd4, 0x28, 0x42, 0x40, 0x20, 0x90, 0x10,
88 0x10, 0x08, 0x24, 0x09, 0x21, 0x03, 0x06, 0x51, 0x20, 0x48, 0x48, 0x12,
89 0x12, 0x00, 0x84, 0x22, 0x22, 0x22, 0x22, 0x11, 0x00, 0x89, 0x12, 0x80,
90 0x31, 0xc5, 0x87, 0x0d, 0x1c, 0xe3, 0x4b, 0x12, 0x49, 0x29, 0x16, 0x1c,
91 0x58, 0x69, 0x4c, 0xe8, 0x91, 0x44, 0x61, 0x44, 0xf2, 0x22, 0x00, 0x00,
92 0x02, 0x07, 0xe5, 0x06, 0x80, 0x60, 0x10, 0x95, 0x08, 0x00, 0x00, 0x48,
93 0x84, 0x04, 0x18, 0x51, 0xe2, 0xc0, 0x87, 0x11, 0x24, 0x18, 0x03, 0x00,
94 0x89, 0x24, 0x44, 0x42, 0x40, 0x20, 0x90, 0x10, 0x10, 0x08, 0x24, 0x09,
95 0x41, 0x02, 0x8a, 0x51, 0x20, 0x48, 0x48, 0x12, 0x11, 0x80, 0x84, 0x22,
96 0x21, 0x24, 0x14, 0x11, 0x01, 0x09, 0x14, 0x40, 0x02, 0x26, 0x48, 0x93,
97 0x22, 0x44, 0xcc, 0x92, 0x51, 0x36, 0x99, 0x22, 0x64, 0x99, 0x92, 0x48,
98 0x91, 0x44, 0x52, 0x44, 0x12, 0x22, 0x00, 0x00, 0x02, 0x01, 0x43, 0x80,
99 0x80, 0xa0, 0x10, 0x84, 0x08, 0x00, 0x00, 0x88, 0x84, 0x08, 0x04, 0x90,
100 0x13, 0x21, 0x08, 0x8f, 0x00, 0x61, 0xf0, 0xc0, 0x8a, 0x24, 0x44, 0x7c,
101 0x40, 0x20, 0x9f, 0x9f, 0x11, 0xcf, 0xe4, 0x09, 0xc1, 0x02, 0x8a, 0x49,
102 0x20, 0x4f, 0x88, 0x13, 0xe0, 0x60, 0x84, 0x22, 0x21, 0x54, 0x08, 0x0a,
103 0x02, 0x08, 0x90, 0x00, 0x00, 0x24, 0x48, 0x11, 0x22, 0x44, 0x48, 0x92,
104 0x61, 0x24, 0x91, 0x22, 0x44, 0x89, 0x10, 0x48, 0x91, 0x24, 0x8c, 0x44,
105 0x22, 0x22, 0x64, 0x00, 0x02, 0x07, 0xe1, 0x41, 0x31, 0x14, 0x10, 0x80,
106 0x3e, 0x07, 0xc0, 0x88, 0x84, 0x10, 0x05, 0x10, 0x12, 0x21, 0x08, 0x81,
107 0x01, 0x80, 0x00, 0x31, 0x0a, 0x24, 0x7c, 0x42, 0x40, 0x20, 0x90, 0x10,
108 0x10, 0x48, 0x24, 0x09, 0x21, 0x02, 0x52, 0x45, 0x20, 0x48, 0x08, 0x92,
109 0x20, 0x10, 0x84, 0x21, 0x41, 0x54, 0x14, 0x04, 0x04, 0x08, 0x90, 0x00,
110 0x01, 0xe4, 0x48, 0x11, 0x3e, 0x44, 0x48, 0x92, 0x61, 0x24, 0x91, 0x22,
111 0x44, 0x89, 0x0c, 0x48, 0x8a, 0x24, 0x8c, 0x48, 0x44, 0x21, 0x98, 0x00,
112 0x02, 0x02, 0x85, 0x41, 0x49, 0x08, 0x10, 0x80, 0x08, 0x00, 0x00, 0x88,
113 0x84, 0x20, 0x45, 0xf9, 0x12, 0x21, 0x08, 0x81, 0x00, 0x61, 0xf0, 0xc1,
114 0x0a, 0x68, 0x82, 0x42, 0x40, 0x20, 0x90, 0x10, 0x10, 0x48, 0x24, 0x89,
115 0x11, 0x02, 0x52, 0x45, 0x20, 0x48, 0x08, 0x52, 0x12, 0x10, 0x84, 0x21,
116 0x40, 0x88, 0x22, 0x04, 0x08, 0x08, 0x90, 0x00, 0x02, 0x24, 0x48, 0x11,
117 0x20, 0x44, 0x48, 0x92, 0x51, 0x24, 0x91, 0x22, 0x44, 0x89, 0x02, 0x48,
118 0x8a, 0x2a, 0x92, 0x28, 0x42, 0x22, 0x00, 0x00, 0x00, 0x02, 0x85, 0x41,
119 0x49, 0x18, 0x10, 0x80, 0x08, 0x00, 0x01, 0x08, 0x84, 0x20, 0x44, 0x11,
120 0x12, 0x22, 0x08, 0x91, 0x00, 0x18, 0x03, 0x00, 0x09, 0xb0, 0x82, 0x42,
121 0x21, 0x21, 0x10, 0x10, 0x08, 0xc8, 0x24, 0x89, 0x09, 0x02, 0x22, 0x43,
122 0x10, 0x88, 0x04, 0x22, 0x12, 0x10, 0x84, 0x20, 0x80, 0x88, 0x22, 0x04,
123 0x10, 0x08, 0x50, 0x00, 0x02, 0x26, 0x48, 0x93, 0x22, 0x44, 0xc8, 0x92,
124 0x49, 0x24, 0x91, 0x22, 0x64, 0x99, 0x12, 0x49, 0x84, 0x11, 0x21, 0x28,
125 0x82, 0x22, 0x00, 0x00, 0x02, 0x02, 0x83, 0x82, 0x30, 0xe4, 0x10, 0x80,
126 0x00, 0x20, 0x05, 0x07, 0x04, 0x3e, 0x38, 0x10, 0xe1, 0xc2, 0x07, 0x0e,
127 0x24, 0x00, 0x00, 0x01, 0x04, 0x00, 0x82, 0x7c, 0x1e, 0x3e, 0x1f, 0x90,
128 0x07, 0x48, 0x24, 0x71, 0x05, 0xf2, 0x22, 0x41, 0x0f, 0x08, 0x03, 0xd2,
129 0x11, 0xe0, 0x83, 0xc0, 0x80, 0x88, 0x41, 0x04, 0x1f, 0xc8, 0x50, 0x00,
130 0x01, 0xd5, 0x87, 0x0d, 0x1c, 0x43, 0x48, 0x92, 0x45, 0x24, 0x91, 0x1c,
131 0x58, 0x69, 0x0c, 0x66, 0x84, 0x11, 0x21, 0x10, 0xf2, 0x22, 0x00, 0x00,
132 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x20, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
134 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x10, 0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x09, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x08, 0x10, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x02,
144 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
145 0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00,
151 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xac, 0x00, 0x00
152};
153
154
156{
157 uint32_t width;
158 uint32_t height;
159 std::vector<uint8_t> data;
160 std::vector<Color> palette =
161 {
162 { 0xff, 0xff, 0xff, 0x00 },
163 { 0x00, 0x00, 0x00, 0xff },
164 { 0xff, 0xff, 0xc0, 0xff },
165 { 0x9f, 0x9f, 0x60, 0xff },
166 { 0xa7, 0x38, 0x30, 0xff },
167 { 0x29, 0x70, 0x18, 0xff },
168 { 0x97, 0xCC, 0xE8, 0xff },
169 { 0xe0, 0xe0, 0xe0, 0xff },
170 { 0xff, 0xff, 0xff, 0xff }
171 };
172};
173
174Image::Image(uint32_t w,uint32_t h) : p(std::make_unique<Private>())
175{
176 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
177 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
178 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
179
180 double red1=0.0 ,green1=0.0 ,blue1=0.0;
181 double red2=0.0, green2=0.0, blue2=0.0;
182
183 ColoredImage::hsl2rgb(hue/360.0, // hue
184 sat/255.0, // saturation
185 pow(235/255.0,gamma/100.0), // luma (gamma corrected)
186 &red1,&green1,&blue1
187 );
188
189 ColoredImage::hsl2rgb(hue/360.0, // hue
190 sat/255.0, // saturation
191 pow(138/255.0,gamma/100.0), // luma (gamma corrected)
192 &red2,&green2,&blue2
193 );
194
195 p->palette[2].red = static_cast<Byte>(red1 * 255.0);
196 p->palette[2].green = static_cast<Byte>(green1 * 255.0);
197 p->palette[2].blue = static_cast<Byte>(blue1 * 255.0);
198
199 p->palette[3].red = static_cast<Byte>(red2 * 255.0);
200 p->palette[3].green = static_cast<Byte>(green2 * 255.0);
201 p->palette[3].blue = static_cast<Byte>(blue2 * 255.0);
202
203 p->data.resize(w*h);
204 p->width = w;
205 p->height = h;
206}
207
208uint32_t Image::width() const { return p->width; }
209uint32_t Image::height() const { return p->height; }
210
211Image::~Image() = default;
212
213void Image::setPixel(uint32_t x,uint32_t y,uint8_t val)
214{
215 if (x<p->width && y<p->height) p->data[y*p->width+x] = val;
216}
217
218uint8_t Image::getPixel(uint32_t x,uint32_t y) const
219{
220 return (x<p->width && y<p->height) ? p->data[y*p->width+x] : 0;
221}
222
223void Image::writeChar(uint32_t x,uint32_t y,char c,uint8_t fg)
224{
225 if (c>=' ')
226 {
227 uint32_t ci=c-' ';
228 uint32_t rowOffset=0;
229 uint32_t cw = charWidth[ci];
230 uint32_t cp = charPos[ci];
231 for (uint32_t yf=0;yf<charHeight;yf++)
232 {
233 unsigned short bitPattern=0;
234 uint32_t bitsLeft=cw;
235 uint32_t byteOffset = rowOffset+(cp>>3);
236 uint32_t bitOffset = cp&7;
237 // get the bit pattern for row yf of the character from the font data
238 while (bitsLeft>0)
239 {
240 uint32_t bits=8-bitOffset;
241 if (bits>bitsLeft) bits=bitsLeft;
242 bitPattern<<=bits;
243 bitPattern|=((fontRaw[byteOffset]<<bitOffset)&0xff)>>(8-bits);
244 bitsLeft-=bits;
245 bitOffset=0;
246 byteOffset++;
247 }
248 if (cw>0 && cw<32)
249 {
250 uint32_t mask=(uint32_t)1<<(cw-1);
251 // draw character row yf
252 for (uint32_t xf=0;xf<cw;xf++)
253 {
254 setPixel(x+xf,y+yf,(bitPattern&mask) ? fg : getPixel(x+xf,y+yf));
255 mask>>=1;
256 }
257 rowOffset+=charSetWidth;
258 }
259 }
260 }
261}
262
263void Image::writeString(uint32_t x,uint32_t y,const QCString &s,uint8_t fg)
264{
265 if (!s.isEmpty())
266 {
267 const char *ps = s.data();
268 char c = 0;
269 while ((c=*ps++))
270 {
271 writeChar(x,y,c,fg);
272 x+=charWidth[c-' '];
273 }
274 }
275}
276
278{
279 uint32_t w=0;
280 if (!s.isEmpty())
281 {
282 const char *ps = s.data();
283 char c = 0;
284 while ((c=*ps++)) w+=charWidth[c-' '];
285 }
286 return w;
287}
288
289void Image::drawHorzLine(uint32_t y,uint32_t xs,uint32_t xe,uint8_t colIndex,uint32_t mask)
290{
291 uint32_t i=0,j=0;
292 for (uint32_t x=xs;x<=xe;x++,j++)
293 {
294 if (j&1) i++;
295 if (mask&(1<<(i&0x1f))) setPixel(x,y,colIndex);
296 }
297}
298
299void Image::drawHorzArrow(uint32_t y,uint32_t xs,uint32_t xe,uint8_t colIndex,uint32_t mask)
300{
301 drawHorzLine(y,xs,xe,colIndex,mask);
302 for (uint32_t i=0;i<6;i++)
303 {
304 uint32_t h=i>>1;
305 drawVertLine(xe-i,y-h,y+h,colIndex,0xffffffff);
306 }
307}
308
309void Image::drawVertLine(uint32_t x,uint32_t ys,uint32_t ye,uint8_t colIndex,uint32_t mask)
310{
311 uint32_t i=0;
312 for (uint32_t y=ys;y<=ye;y++,i++)
313 {
314 if (mask&(1<<(i&0x1f))) setPixel(x,y,colIndex);
315 }
316}
317
318void Image::drawVertArrow(uint32_t x,uint32_t ys,uint32_t ye,uint8_t colIndex,uint32_t mask)
319{
320 drawVertLine(x,ys,ye,colIndex,mask);
321 for (uint32_t i=0;i<6;i++)
322 {
323 uint32_t h=i>>1;
324 drawHorzLine(ys+i,x-h,x+h,colIndex,0xffffffff);
325 }
326}
327
328void Image::drawRect(uint32_t x,uint32_t y,uint32_t w,uint32_t h,uint8_t colIndex,uint32_t mask)
329{
330 drawHorzLine(y,x,x+w-1,colIndex,mask);
331 drawHorzLine(y+h-1,x,x+w-1,colIndex,mask);
332 drawVertLine(x,y,y+h-1,colIndex,mask);
333 drawVertLine(x+w-1,y,y+h-1,colIndex,mask);
334}
335
336void Image::fillRect(uint32_t x,uint32_t y,uint32_t width,uint32_t height,uint8_t colIndex,uint32_t mask)
337{
338 for (uint32_t yp=y,yi=0;yp<y+height;yp++,yi++)
339 for (uint32_t xp=x,xi=0;xp<x+width;xp++,xi++)
340 if (mask&(1<<((xi+yi)&0x1f)))
341 setPixel(xp,yp,colIndex);
342 else
343 setPixel(xp,yp,8);
344}
345
346bool Image::save(const QCString &fileName)
347{
348 uint8_t* buffer = nullptr;
349 size_t bufferSize = 0;
350 LodePNG_Encoder encoder;
351 LodePNG_Encoder_init(&encoder);
352 for (const auto &col : p->palette)
353 {
354 LodePNG_InfoColor_addPalette(&encoder.infoPng.color,
355 col.red,col.green,col.blue,col.alpha);
356 }
357 encoder.infoPng.color.colorType = 3;
358 encoder.infoRaw.color.colorType = 3;
359 LodePNG_encode(&encoder, &buffer, &bufferSize, &p->data[0], p->width, p->height);
360 LodePNG_saveFile(buffer, bufferSize, fileName.data());
361 free(buffer);
362 LodePNG_Encoder_cleanup(&encoder);
363 return TRUE;
364}
365
366//----------------------------------------------------------------
367
368void ColoredImage::hsl2rgb(double h,double s,double l,
369 double *pRed,double *pGreen,double *pBlue)
370{
371 double r = l; // default to gray
372 double g = l;
373 double b = l;
374 double v = (l <= 0.5) ? (l * (1.0 + s)) : (l + s - l * s);
375 if (v > 0)
376 {
377 double m = l + l - v;
378 double sv = ( v - m ) / v;
379 h *= 6.0;
380 int sextant = static_cast<int>(h);
381 double fract = h - sextant;
382 double vsf = v * sv * fract;
383 double mid1 = m + vsf;
384 double mid2 = v - vsf;
385 switch (sextant)
386 {
387 case 0:
388 r = v;
389 g = mid1;
390 b = m;
391 break;
392 case 1:
393 r = mid2;
394 g = v;
395 b = m;
396 break;
397 case 2:
398 r = m;
399 g = v;
400 b = mid1;
401 break;
402 case 3:
403 r = m;
404 g = mid2;
405 b = v;
406 break;
407 case 4:
408 r = mid1;
409 g = m;
410 b = v;
411 break;
412 case 5:
413 r = v;
414 g = m;
415 b = mid2;
416 break;
417 }
418 }
419 *pRed = r;
420 *pGreen = g;
421 *pBlue = b;
422}
423
425{
426 uint32_t width;
427 uint32_t height;
428 std::vector<uint8_t> data;
430};
431
432ColoredImage::ColoredImage(uint32_t width,uint32_t height,
433 const uint8_t *greyLevels,const uint8_t *alphaLevels,
434 int saturation,int hue,int gamma) : p(std::make_unique<Private>())
435{
436 p->hasAlpha = alphaLevels!=nullptr;
437 p->width = width;
438 p->height = height;
439 p->data.resize(width*height*4);
440 for (uint32_t i=0;i<width*height;i++)
441 {
442 double red=0.0, green=0.0, blue=0.0;
443 hsl2rgb(hue/360.0, // hue
444 saturation/255.0, // saturation
445 pow(greyLevels[i]/255.0,gamma/100.0), // luma (gamma corrected)
446 &red,&green,&blue);
447 Byte r = static_cast<Byte>(red *255.0);
448 Byte g = static_cast<Byte>(green*255.0);
449 Byte b = static_cast<Byte>(blue *255.0);
450 Byte a = alphaLevels ? alphaLevels[i] : 255;
451 p->data[i*4+0]=r;
452 p->data[i*4+1]=g;
453 p->data[i*4+2]=b;
454 p->data[i*4+3]=a;
455 }
456}
457
459
460bool ColoredImage::save(const QCString &fileName)
461{
462 uint8_t *buffer = nullptr;
463 size_t bufferSize = 0;
464 LodePNG_Encoder encoder;
465 LodePNG_Encoder_init(&encoder);
466 encoder.infoPng.color.colorType = p->hasAlpha ? 6 : 2; // 2=RGB 24 bit, 6=RGBA 32 bit
467 encoder.infoRaw.color.colorType = 6; // 6=RGBA 32 bit
468 LodePNG_encode(&encoder, &buffer, &bufferSize, &p->data[0], p->width, p->height);
469 LodePNG_saveFile(buffer, bufferSize, fileName.data());
470 LodePNG_Encoder_cleanup(&encoder);
471 free(buffer);
472 return TRUE;
473}
474
475
static void hsl2rgb(double h, double s, double l, double *pRed, double *pGreen, double *pBlue)
Definition image.cpp:368
ColoredImage(uint32_t width, uint32_t height, const uint8_t *greyLevels, const uint8_t *alphaLevels, int saturation, int hue, int gamma)
Definition image.cpp:432
std::unique_ptr< Private > p
Definition image.h:69
bool save(const QCString &fileName)
Definition image.cpp:460
void drawVertLine(uint32_t x, uint32_t ys, uint32_t ye, uint8_t colIndex, uint32_t mask)
Definition image.cpp:309
void setPixel(uint32_t x, uint32_t y, uint8_t val)
Definition image.cpp:213
std::unique_ptr< Private > p
Definition image.h:51
void drawHorzLine(uint32_t y, uint32_t xs, uint32_t xe, uint8_t colIndex, uint32_t mask)
Definition image.cpp:289
void drawVertArrow(uint32_t x, uint32_t ys, uint32_t ye, uint8_t colIndex, uint32_t mask)
Definition image.cpp:318
uint32_t width() const
Definition image.cpp:208
void fillRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint8_t colIndex, uint32_t mask)
Definition image.cpp:336
uint32_t height() const
Definition image.cpp:209
void drawHorzArrow(uint32_t y, uint32_t xs, uint32_t xe, uint8_t colIndex, uint32_t mask)
Definition image.cpp:299
void drawRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint8_t colIndex, uint32_t mask)
Definition image.cpp:328
void writeString(uint32_t x, uint32_t y, const QCString &s, uint8_t fg)
Definition image.cpp:263
bool save(const QCString &fileName)
Definition image.cpp:346
void writeChar(uint32_t x, uint32_t y, char c, uint8_t fg)
Definition image.cpp:223
uint8_t getPixel(uint32_t x, uint32_t y) const
Definition image.cpp:218
friend uint32_t stringLength(const QCString &s)
Definition image.cpp:277
Image(uint32_t w, uint32_t h)
Definition image.cpp:174
This is an alternative implementation of QCString.
Definition qcstring.h:101
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
#define Config_getInt(name)
Definition config.h:34
const unsigned short charPos[numChars]
Definition image.cpp:38
const unsigned char charWidth[numChars]
Definition image.cpp:54
const unsigned char fontRaw[charSetWidth *charHeight]
Definition image.cpp:71
const int numChars
Definition image.cpp:36
const int charHeight
Definition image.cpp:35
const int charSetWidth
Definition image.cpp:34
unsigned char Byte
Definition image.cpp:23
#define TRUE
Definition qcstring.h:37
Helper struct representing a RGBA color.
Definition image.cpp:27
Byte green
Definition image.cpp:29
Byte blue
Definition image.cpp:30
Byte alpha
Definition image.cpp:31
Byte red
Definition image.cpp:28
std::vector< uint8_t > data
Definition image.cpp:428
uint32_t width
Definition image.cpp:157
uint32_t height
Definition image.cpp:158
std::vector< uint8_t > data
Definition image.cpp:159
std::vector< Color > palette
Definition image.cpp:160