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