311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.2)
2 | project(src)
3 |
4 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}")
5 | set(Boost_INCLUDE_DIR /cygdrive/c/boost)
6 | set(Boost_LIBRARY_DIR /cygdrive/c/boost/stage/lib)
7 | set(CMAKE_BUILD_TYPE Release)
8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fopenmp -O3")
9 |
10 | find_package(OpenMP)
11 | find_package(Boost 1.56 COMPONENTS program_options REQUIRED)
12 | include_directories(${Boost_INCLUDE_DIR})
13 | link_directories(${Boost_LIBRARY_DIR})
14 |
15 | set(SOURCE_FILES
16 | stdafx.cpp
17 | imagegen.cpp
18 | lodepng.cpp
19 | RandomFunction.hpp
20 | )
21 |
22 | add_executable(ImageGenCygwin ${SOURCE_FILES})
23 | target_link_libraries(ImageGenCygwin ${Boost_LIBRARIES})
--------------------------------------------------------------------------------
/src/Coloring.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "PolynomialColoring.h"
--------------------------------------------------------------------------------
/src/ColoringAlgorithm.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | struct ColoringAlgorithm
4 | {
5 | protected:
6 | ~ColoringAlgorithm() { }
7 |
8 | public:
9 | virtual void Value(const float input, float &r, float &g, float &b) const = 0;
10 | };
11 |
12 | struct NoColoring : ColoringAlgorithm
13 | {
14 | protected:
15 | ~NoColoring() { }
16 |
17 | public:
18 | explicit NoColoring(int _) {}
19 | virtual void Value(const float input, float &r, float &g, float &b) const override
20 | {
21 | r = g = b = input;
22 | }
23 | };
--------------------------------------------------------------------------------
/src/ImageGen.exe.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/ImageGen.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | MPI Debug
10 | x64
11 |
12 |
13 | MPI Release
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {3C1AC435-F600-4901-8BFA-687666D1EAEC}
23 | Win32Proj
24 | BlackAndWhite
25 | ImageGen
26 |
27 |
28 |
29 | Application
30 | true
31 | Intel C++ Compiler XE 15.0
32 | MultiByte
33 | Sequential
34 | false
35 |
36 |
37 | Application
38 | true
39 | Intel C++ Compiler XE 15.0
40 | MultiByte
41 | Sequential
42 | false
43 |
44 |
45 | Application
46 | false
47 | Intel C++ Compiler XE 15.0
48 | true
49 | MultiByte
50 | Parallel
51 | false
52 |
53 |
54 | Application
55 | false
56 | Intel C++ Compiler XE 15.0
57 | true
58 | MultiByte
59 | Parallel
60 | false
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | true
80 | $(ProjectDir)
81 |
82 |
83 | true
84 | $(ProjectDir)
85 |
86 |
87 | false
88 | $(ProjectDir)
89 |
90 |
91 | false
92 | $(ProjectDir)
93 |
94 |
95 |
96 | Create
97 | Level3
98 | Disabled
99 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
100 | $(SolutionDir)..\include\lodepng;c:\boost;C:\Program Files (x86)\intel\Composer XE 2015\mkl\include;%(AdditionalIncludeDirectories)
101 | StreamingSIMDExtensions3
102 | GenerateParallelCode
103 | true
104 | false
105 |
106 |
107 | Console
108 | true
109 | c:\boost\stage\lib;C:\Program Files (x86)\intel\Composer XE 2015\mkl\lib\intel64;C:\Program Files (x86)\Intel\Composer XE 2015\compiler\lib\intel64;%(AdditionalLibraryDirectories)
110 |
111 |
112 |
113 |
114 | Create
115 | Level3
116 | Disabled
117 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
118 | $(SolutionDir)..\include\lodepng;c:\boost;C:\Program Files (x86)\intel\Composer XE 2015\mkl\include;%(AdditionalIncludeDirectories)
119 | StreamingSIMDExtensions3
120 | GenerateParallelCode
121 | true
122 | false
123 |
124 |
125 | Console
126 | true
127 | c:\boost\stage\lib;C:\Program Files (x86)\intel\Composer XE 2015\mkl\lib\intel64;C:\Program Files (x86)\Intel\Composer XE 2015\compiler\lib\intel64;%(AdditionalLibraryDirectories)
128 | impi.lib;impicxx.lib;%(AdditionalDependencies)
129 |
130 |
131 |
132 |
133 | Level3
134 | Create
135 | MaxSpeedHighLevel
136 | true
137 | true
138 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
139 | $(SolutionDir)..\include\lodepng;c:\boost;C:\Program Files (x86)\intel\Composer XE 2015\mkl\include;%(AdditionalIncludeDirectories)
140 | StreamingSIMDExtensions3
141 | AnySuitable
142 | Speed
143 | true
144 | true
145 |
146 |
147 | true
148 | true
149 | true
150 | GenerateParallelCode
151 | true
152 | false
153 | NoIPO
154 | SSE41
155 | HOST
156 | AssemblyAndSourceCode
157 |
158 |
159 | Console
160 | true
161 | true
162 | true
163 | c:\boost\stage\lib;C:\Program Files (x86)\intel\Composer XE 2015\mkl\lib\intel64;C:\Program Files (x86)\Intel\Composer XE 2015\compiler\lib\intel64;%(AdditionalLibraryDirectories)
164 |
165 |
166 |
167 |
168 | Level3
169 | Create
170 | MaxSpeedHighLevel
171 | true
172 | true
173 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
174 | $(SolutionDir)..\include\lodepng;c:\boost;C:\Program Files (x86)\intel\Composer XE 2015\mkl\include;%(AdditionalIncludeDirectories)
175 | StreamingSIMDExtensions3
176 | AnySuitable
177 | Speed
178 | true
179 | true
180 |
181 |
182 | true
183 | true
184 | true
185 | GenerateParallelCode
186 | true
187 | false
188 | NoIPO
189 | SSE41
190 | HOST
191 | AssemblyAndSourceCode
192 |
193 |
194 | Console
195 | true
196 | true
197 | true
198 | c:\boost\stage\lib;C:\Program Files (x86)\intel\Composer XE 2015\mkl\lib\intel64;C:\Program Files (x86)\Intel\Composer XE 2015\compiler\lib\intel64;%(AdditionalLibraryDirectories)
199 | impi.lib;impicxx.lib;%(AdditionalDependencies)
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 | Use
213 | Use
214 |
215 |
216 | Use
217 | Use
218 |
219 |
220 | Create
221 | Create
222 | Create
223 | Create
224 |
225 |
226 |
227 |
228 |
229 |
--------------------------------------------------------------------------------
/src/ImageGen.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {0930e3db-8b05-4ba1-a88b-4bffa074a45c}
14 |
15 |
16 |
17 |
18 | Header Files
19 |
20 |
21 | Coloring
22 |
23 |
24 | Coloring
25 |
26 |
27 | Header Files
28 |
29 |
30 | Header Files
31 |
32 |
33 | Header Files
34 |
35 |
36 |
37 |
38 | Source Files
39 |
40 |
41 | Source Files
42 |
43 |
44 | Source Files
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/ImageGenerator.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.31101.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageGen", "ImageGen.vcxproj", "{3C1AC435-F600-4901-8BFA-687666D1EAEC}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | MPI Debug|x64 = MPI Debug|x64
12 | MPI Release|x64 = MPI Release|x64
13 | Release|x64 = Release|x64
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {3C1AC435-F600-4901-8BFA-687666D1EAEC}.Debug|x64.ActiveCfg = Debug|x64
17 | {3C1AC435-F600-4901-8BFA-687666D1EAEC}.Debug|x64.Build.0 = Debug|x64
18 | {3C1AC435-F600-4901-8BFA-687666D1EAEC}.MPI Debug|x64.ActiveCfg = MPI Debug|x64
19 | {3C1AC435-F600-4901-8BFA-687666D1EAEC}.MPI Debug|x64.Build.0 = MPI Debug|x64
20 | {3C1AC435-F600-4901-8BFA-687666D1EAEC}.MPI Release|x64.ActiveCfg = MPI Release|x64
21 | {3C1AC435-F600-4901-8BFA-687666D1EAEC}.MPI Release|x64.Build.0 = MPI Release|x64
22 | {3C1AC435-F600-4901-8BFA-687666D1EAEC}.Release|x64.ActiveCfg = Release|x64
23 | {3C1AC435-F600-4901-8BFA-687666D1EAEC}.Release|x64.Build.0 = Release|x64
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/src/PolynomialColoring.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ColoringAlgorithm.h"
4 | #include
5 |
6 | struct PolynomialColoring : ColoringAlgorithm
7 | {
8 | uint8_t terms;
9 | float *r, *g, *b;
10 |
11 | explicit PolynomialColoring(const uint8_t terms) : terms(terms)
12 | {
13 | r = new float[terms];
14 | g = new float[terms];
15 | b = new float[terms];
16 | for (size_t i = 0; i < terms; ++i)
17 | {
18 | r[i] = randfloat;
19 | g[i] = randfloat;
20 | b[i] = randfloat;
21 | }
22 | }
23 |
24 |
25 |
26 | virtual void Value(const float input, float &r, float &g, float &b) const override
27 | {
28 | r += tools::evaluate_polynomial(this->r, input, terms);
29 | g += tools::evaluate_polynomial(this->g, input, terms);
30 | b += tools::evaluate_polynomial(this->b, input, terms);
31 | }
32 |
33 | virtual ~PolynomialColoring()
34 | {
35 | delete[] r;
36 | delete[] g;
37 | delete[] b;
38 | }
39 | };
--------------------------------------------------------------------------------
/src/RandomFunction.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "functions.h"
4 |
5 | #define randfloat ((float)rand() / (float)RAND_MAX)
6 | #define randfloat2 ((2*randfloat) - 1.f)
7 |
8 | #define UNARY 0
9 | #define BINARY 1
10 | #define TERMINALINDEX 2
11 | #define TERMINALVALUE 3
12 |
13 | class RandomFunction
14 | {
15 | int type;
16 | int index;
17 | float value;
18 | RandomFunction *lhs;
19 | RandomFunction *rhs;
20 | size_t unaryFunctionCount;
21 | size_t binaryFunctionCount;
22 | bool vectorize;
23 | public:
24 | RandomFunction(const int count, const int depth, const bool vectorize)
25 | {
26 | unaryFunctionCount = vectorize ? unaryVectorFunctions.size() : unaryFunctions.size();
27 | binaryFunctionCount = vectorize ? binaryVectorFunctions.size() : binaryFunctions.size();
28 |
29 | lhs = nullptr;
30 | rhs = nullptr;
31 | int r = rand() % 100;
32 | if (depth < 2)
33 | {
34 | if (r < 10)
35 | {
36 | value = randfloat2;
37 | type = TERMINALVALUE;
38 | }
39 | else
40 | {
41 | index = rand() % count;
42 | type = TERMINALINDEX;
43 | }
44 | }
45 | else
46 | {
47 | if (r < 2)
48 | {
49 | index = rand() % count;
50 | type = TERMINALINDEX;
51 | }
52 | else if(r > 50 && depth < 4 )
53 | {
54 | do {
55 | delete lhs;
56 | lhs = new RandomFunction(count, depth - 1, vectorize);
57 | type = UNARY;
58 | index = rand() % unaryFunctionCount;
59 | } while (lhs->type == TERMINALVALUE);
60 | }
61 | else
62 | {
63 | do {
64 | delete lhs;
65 | delete rhs;
66 | lhs = new RandomFunction(count, depth - 1, vectorize);
67 | rhs = new RandomFunction(count, depth - 1, vectorize);
68 | } while ((*lhs == *rhs) ||
69 | (lhs->type == TERMINALVALUE && rhs->type == TERMINALVALUE));
70 | type = BINARY;
71 | index = rand() % binaryFunctionCount;
72 | }
73 | }
74 | }
75 |
76 | ~RandomFunction()
77 | {
78 | delete lhs;
79 | delete rhs;
80 | }
81 |
82 | bool operator==(const RandomFunction& other)
83 | {
84 | if (type != other.type) return false;
85 |
86 | switch (type)
87 | {
88 | case UNARY:
89 | return index == other.index && *lhs == *other.lhs;
90 | case BINARY:
91 | return index == other.index && *lhs == *other.lhs && *rhs == *other.rhs;
92 | case TERMINALVALUE:
93 | return value == other.value;
94 | case TERMINALINDEX:
95 | return index == other.index;
96 | }
97 | return false;
98 | }
99 |
100 | float Eval(const float input) const
101 | {
102 | vector d;
103 | d.push_back(input);
104 | return Eval(d);
105 | }
106 |
107 | float Eval(const float x, const float y) const
108 | {
109 | vector d;
110 | d.push_back(x);
111 | d.push_back(y);
112 | return Eval(d);
113 | }
114 |
115 | friend ostream& operator<<(ostream& os, const RandomFunction& f)
116 | {
117 | switch (f.type)
118 | {
119 | case UNARY:
120 | os << "U" << f.index << "(" << *f.lhs << ")";
121 | break;
122 | case BINARY:
123 | os << "B" << f.index << "(" << *f.lhs << "," << *f.rhs << ")";
124 | break;
125 | case TERMINALVALUE:
126 | os << f.value;
127 | break;
128 | case TERMINALINDEX:
129 | switch (f.index)
130 | {
131 | case 0: os << "x"; break;
132 | case 1: os << "y"; break;
133 | }
134 | }
135 | return os;
136 | }
137 |
138 | void Eval(const int w, const int h, const float* x, const float* y,
139 | float* result, const bool vectorize) const
140 | {
141 | if (vectorize)
142 | EvalVector(w, h, x, y, result);
143 | else {
144 | //#pragma omp parallel for
145 | for (size_t j = 0; j < h; ++j)
146 | {
147 | //#pragma omp parallel for
148 | for (size_t i = 0; i < w; ++i)
149 | {
150 | result[j*w + i] = Eval(x[i], y[j]);
151 | }
152 | }
153 | }
154 | }
155 |
156 | private:
157 | void EvalVector(const int w, const int h, const float* x,
158 | const float* y, float* result) const
159 | {
160 | int count = w * h;
161 |
162 | // construct a mesh grid of x and y values
163 | float *xx = new float[count];
164 | float *yy = new float[count];
165 | for (int i = 0; i < h; ++i)
166 | {
167 | for (int j = 0; j < w; ++j)
168 | {
169 | int pos = w*i + j;
170 | xx[pos] = x[j];
171 | yy[pos] = y[i];
172 | }
173 | }
174 |
175 | EvalVector(&count, xx, yy, result);
176 |
177 | delete[] xx;
178 | delete[] yy;
179 | }
180 |
181 | // assume # of dimensions == 2
182 | void EvalVector(const int* count, const float* x, const float* y, float* result) const
183 | {
184 | float *xx = new float[*count];
185 | float *yy = new float[*count];
186 | switch (type)
187 | {
188 | case UNARY:
189 | lhs->EvalVector(count, x, y, xx);
190 | unaryVectorFunctions[index](count, xx, result);
191 | break;
192 | case BINARY:
193 | lhs->EvalVector(count, x, y, xx);
194 | rhs->EvalVector(count, x, y, yy);
195 | binaryVectorFunctions[index](count, xx, yy, result);
196 | break;
197 | case TERMINALVALUE:
198 | for (size_t i = 0; i < *count; ++i)
199 | result[i] = value;
200 | break;
201 | case TERMINALINDEX:
202 | for (size_t i = 0; i < *count; ++i)
203 | result[i] = index == 0 ? x[i] : y[i];
204 | break;
205 | }
206 | delete[] xx;
207 | delete[] yy;
208 | }
209 |
210 | float Eval(const vector& params) const
211 | {
212 | float result = 0;
213 | switch (type)
214 | {
215 | case UNARY:
216 | result = unaryFunctions[index](lhs->Eval(params));
217 | break;
218 | case BINARY:
219 | result = binaryFunctions[index](lhs->Eval(params), rhs->Eval(params));
220 | break;
221 | case TERMINALVALUE:
222 | result = value;
223 | break;
224 | case TERMINALINDEX:
225 | result = params[index];
226 | break;
227 | }
228 | return result;
229 | }
230 | };
--------------------------------------------------------------------------------
/src/functions.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | typedef function unaryFunction;
4 | typedef function binaryFunction;
5 |
6 | inline vector initUnaryFunctions()
7 | {
8 | vector result {
9 | sinf, cosf, expf,
10 | logf,
11 | sinhf, coshf, tanhf,
12 | fabsf
13 | };
14 | result.push_back([](float x) { return -x; });
15 | result.push_back([](float x) { return x*x; });
16 | result.push_back([](float x) { return x*x*x; });
17 | return result;
18 | }
19 |
20 | inline vector> initBinaryFunctions()
21 | {
22 | vector result;
23 | result.push_back([](const float a, const float b) { return a + b; });
24 | result.push_back([](const float a, const float b) { return a - b; });
25 | result.push_back([](const float a, const float b) { return a * b; });
26 |
27 | //result.push_back([](float a, float b) { return a / b; });
28 | result.push_back([](const float a, const float b) { return sin(a*b); });
29 | //result.push_back([](float a, float b) { return cos(a*b); });
30 | //result.push_back([](float a, float b) { return tanh(a*b); });
31 | //result.push_back([](float a, float b) { return powf(a,b); });
32 | //result.push_back([](float a, float b) { return std::max(a,b); });
33 | //result.push_back([](float a, float b) { return std::min(a,b); });
34 | return result;
35 | }
36 |
37 | const vector unaryFunctions = initUnaryFunctions();
38 | const vector binaryFunctions = initBinaryFunctions();
39 |
40 | typedef function unaryVectorFunction;
41 | typedef function binaryVectorFunction;
42 |
43 | #ifdef USEMKL
44 |
45 | inline vector initUnaryVectorFunctions()
46 | {
47 | vector result;
48 | result.push_back(vssin);
49 | result.push_back(vscos);
50 | result.push_back(vsexp);
51 | //result.push_back(vslog10);
52 | result.push_back(vssinh);
53 | result.push_back(vscosh);
54 | result.push_back(vstanh);
55 | result.push_back(vsabs);
56 | //result.push_back(vssqrt);
57 | //result.push_back(vstanh);
58 | return result;
59 | }
60 |
61 | inline vector initBinaryVectorFunctions()
62 | {
63 | vector result;
64 | result.push_back(vsadd);
65 | result.push_back(vssub);
66 | result.push_back(vsmul);
67 |
68 | // this is what a compound function (in this case, sin(a*b) looks like)
69 | result.push_back([](const int* n, const float* a, const float* b, float* c)
70 | {
71 | float* temp = new float[*n];
72 | vsmul(n, a, b, temp);
73 | vssin(n, temp, c);
74 | delete[] temp;
75 | });
76 |
77 | return result;
78 | }
79 |
80 | #endif
81 |
82 | const vector unaryVectorFunctions
83 | #ifdef USEMKL
84 | = initUnaryVectorFunctions()
85 | #endif
86 | ;
87 | const vector binaryVectorFunctions
88 | #ifdef USEMKL
89 | = initBinaryVectorFunctions()
90 | #endif
91 | ;
--------------------------------------------------------------------------------
/src/imagegen.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "RandomFunction.hpp"
3 | #include "Coloring.h"
4 | namespace po = boost::program_options;
5 |
6 | void linspace(const float start, const float end,
7 | const int count, float* result)
8 | {
9 | float dx = (end - start) / (count - 1);
10 | for (size_t i = 0; i < count; ++i)
11 | {
12 | result[i] = start + dx*i;
13 | }
14 | }
15 |
16 | float poly(const float x, const float *const args)
17 | {
18 | return x*(args[0] * x + args[1]) + args[2];
19 | }
20 |
21 | // returns true if normalization succeeded and false if it failed
22 | bool normalizeImage(float *image, const size_t pixelCount)
23 | {
24 | vector r(pixelCount);
25 | vector g(pixelCount);
26 | vector b(pixelCount);
27 |
28 | accumulator_set> accR, accG, accB;
30 |
31 | for (size_t i = 0; i < pixelCount; i++)
32 | {
33 | accR(image[i * 3 + 0]);
34 | accG(image[i * 3 + 1]);
35 | accB(image[i * 3 + 2]);
36 | }
37 |
38 | float meanR = mean(accR), meanG = mean(accG), meanB = mean(accB);
39 | float varR = variance(accR), varG = variance(accG), varB = variance(accB);
40 | float minR = boost::accumulators::min(accR), minG = boost::accumulators::min(accG), minB = boost::accumulators::min(accB);
41 | float maxR = boost::accumulators::max(accR), maxG = boost::accumulators::max(accG), maxB = boost::accumulators::max(accB);
42 |
43 | float rangeR = maxR - minR;
44 | float rangeG = maxG - minG;
45 | float rangeB = maxB - minB;
46 |
47 | cout << "mean: " << meanR << " " << meanG << " " << meanB << endl;
48 | cout << "var : " << varR << " " << varG << " " << varB << endl;
49 | cout << "min : " << minR << " " << minG << " " << minB << endl;
50 | cout << "max : " << maxR << " " << maxG << " " << maxB << endl;
51 |
52 | float all[] = { meanR, meanG, meanB, varR, varG, varB };
53 | for (auto x : all)
54 | if (std::isnan(x) || std::isinf(x)) return false;
55 |
56 | // now transform the image
57 | for (size_t i = 0; i < pixelCount; i++)
58 | {
59 | image[i * 3 + 0] = (image[i * 3 + 0] - meanR) / (varR / 3);
60 | image[i * 3 + 1] = (image[i * 3 + 1] - meanG) / (varG / 3);
61 | image[i * 3 + 2] = (image[i * 3 + 2] - meanB) / (varB / 3);
62 | }
63 |
64 | // postprocessing, you really feel like it
65 | /*for (size_t i = 0; i < pixelCount*3; i++)
66 | {
67 | image[i] *= image[i];
68 | }*/
69 |
70 | return true;
71 | }
72 |
73 | inline uint8_t constrain(float x)
74 | {
75 | return fmaxf(0.f, fminf(x, 255.f));
76 | }
77 |
78 | int equivalence_check()
79 | {
80 | assert(unaryFunctions.size() == unaryVectorFunctions.size());
81 | assert(binaryFunctions.size() == binaryVectorFunctions.size());
82 |
83 | // ensure that scalar and vector random functions are equivalent
84 | constexpr int count = 101;
85 | float f[count];
86 | linspace(-M_PI, M_PI, count, f);
87 | float result[count*count], result2[count*count];
88 |
89 | RandomFunction rf(2, 8, false);
90 | rf.Eval(count, count, f, f, result, false);
91 | rf.Eval(count, count, f, f, result2, true);
92 |
93 | for (size_t i = 0; i < count; i++)
94 | {
95 | if (result[i] != result2[i])
96 | {
97 | cout << "failed at " << i << " difference = " << abs(result[i]-result2[i]) << endl;
98 | }
99 | }
100 | return 0;
101 | }
102 |
103 | static random_device rd{};
104 |
105 | struct image_rendering_options
106 | {
107 | float xmin = -M_PI;
108 | float xmax = M_PI;
109 | float ymin = -M_PI;
110 | float ymax = M_PI;
111 | const unsigned int dimensions = 2;
112 | unsigned int iterations = 2;
113 | unsigned int depth = 6;
114 | boost::optional seed;
115 | int w = 1024;
116 | int h = 1024;
117 | int threads = 1;
118 | unsigned int images_to_generate = 1; // per process
119 |
120 | friend class boost::serialization::access;
121 |
122 | template
123 | inline void serialize(Ar& ar, const unsigned int fv)
124 | {
125 | ar & xmin;
126 | ar & xmax;
127 | ar & ymin;
128 | ar & ymax;
129 | ar & dimensions;
130 | ar & iterations;
131 | ar & depth;
132 | ar & seed;
133 | ar & w;
134 | ar & h;
135 | ar & threads;
136 | ar & images_to_generate;
137 | }
138 | };
139 |
140 | image_rendering_options parse_options(int ac, char* av[])
141 | {
142 | vector renderTimes; // not here
143 |
144 | image_rendering_options iro;
145 |
146 | po::options_description desc("generator options");
147 | desc.add_options()
148 | ("help", "show some help")
149 | ("n", po::value(&iro.images_to_generate), "number of images to generate")
150 | ("i", po::value(&iro.iterations), "number of iterations")
151 | ("d", po::value(&iro.depth), "function depth")
152 | ("z", po::value(), "size of image to generate (w/h)")
153 | ("f", po::value>(), "frame (xmin xmax ymin ymax) in which to generate")
154 | ("s", po::value(), "rng seed")
155 | ("t", po::value(&iro.threads), "number of threads");
156 |
157 | po::variables_map vm;
158 | try
159 | {
160 | po::store(po::parse_command_line(ac, av, desc,
161 | po::command_line_style::unix_style ^ po::command_line_style::allow_short), vm);
162 | }
163 | catch (const exception& e)
164 | {
165 | cout << "Cannot parse command-line arguments: " << e.what() << endl;
166 | throw;
167 | }
168 | po::notify(vm);
169 |
170 | if (vm.count("z")) iro.w = iro.h = vm["z"].as();
171 |
172 | if (vm.count("t"))
173 | {
174 | //omp_set_num_threads(threads);
175 | // this is now specified later
176 | }
177 |
178 | if (vm.count("f"))
179 | {
180 | auto vals = vm["f"].as>();
181 | if (vals.size() == 4)
182 | {
183 | iro.xmin = vals[0];
184 | iro.xmax = vals[1];
185 | iro.ymin = vals[2];
186 | iro.ymax = vals[3];
187 | }
188 | }
189 |
190 | if (vm.count("help"))
191 | {
192 | cout << desc << endl;
193 | iro.images_to_generate = 0;
194 | }
195 |
196 | // the seed is used to initialize the RNG
197 | if (vm.count("s"))
198 | {
199 | iro.seed = (unsigned)boost::lexical_cast(vm["s"].as());
200 | }
201 |
202 | return iro;
203 | }
204 |
205 | void render(image_rendering_options& iro) {
206 | vector renderTimes;
207 |
208 |
209 | //#pragma omp parallel for
210 | for (int i = 0; i < iro.images_to_generate; ++i) {
211 | everything:
212 | auto seed = iro.seed.is_initialized() ? iro.seed.value() : rd();
213 | srand(seed);
214 |
215 | sanity:
216 | #ifdef USEMKL // does vector routine checks
217 | equivalence_check();
218 | //return;
219 | #endif
220 |
221 | cout << endl << "Render started with seed " << seed << endl;
222 | auto start_time = high_resolution_clock::now();
223 | RandomFunction rf(iro.dimensions, iro.depth, false);
224 |
225 | auto w = iro.w;
226 | auto h = iro.h;
227 |
228 | float *x = new float[w];
229 | float *y = new float[h];
230 | linspace(iro.xmin, iro.xmax, w, x);
231 | linspace(iro.ymin, iro.ymax, h, y);
232 |
233 | cout << rf << endl;
234 | float *f = new float[w * h];
235 |
236 | uint8_t *image = new uint8_t[w * h * 3];
237 | float *intermediate = new float[w * h * 3];
238 | memset(image, 0, w * h * 3 * sizeof(uint8_t));
239 |
240 | int it_count = iro.iterations;
241 | while (it_count-- > 0) {
242 | rf.Eval(w, h, x, y, f, false);
243 |
244 | PolynomialColoring ca(3);
245 |
246 | // prepare intermediate values
247 | for (size_t j = 0; j < h; ++j) {
248 | for (size_t i = 0; i < w; ++i) {
249 | int k = j * w + i;
250 | int k3 = 3 * k;
251 | ca.Value(f[k], intermediate[k3], intermediate[k3 + 1], intermediate[k3 + 2]);
252 | }
253 | }
254 | };
255 |
256 | cout << "Calculations done." << endl;
257 |
258 | // normalize intermediate values using chosen algos
259 | if (!normalizeImage(intermediate, w * h)) {
260 | cout << "Generation failed, re-doing this!" << endl;
261 | // if this fails, try again with same params
262 | goto everything;
263 | }
264 |
265 | for (size_t j = 0; j < h; ++j) {
266 | for (size_t i = 0; i < w; ++i) {
267 | int k = j * w + i;
268 | int k3 = 3 * k;
269 | image[k3 + 0] = constrain(128.f * (intermediate[k3 + 0] + 1.f));
270 | image[k3 + 1] = constrain(128.f * (intermediate[k3 + 1] + 1.f));
271 | image[k3 + 2] = constrain(128.f * (intermediate[k3 + 2] + 1.f));
272 | }
273 | }
274 |
275 | // send the image over to the recipient
276 | auto filename = string("./samples/") + boost::lexical_cast(seed) + ".png";
277 | lodepng_encode24_file(filename.c_str(), image, w, h);
278 |
279 | delete[] image;
280 | delete[] intermediate;
281 | delete[] f;
282 | delete[] x;
283 | delete[] y;
284 |
285 | auto end_time = high_resolution_clock::now();
286 | auto duration = duration_cast(end_time - start_time).count();
287 | renderTimes.push_back(duration);
288 | cout << "Render took " << duration << "msec." << endl;
289 | }
290 |
291 | // compute average render time
292 | double sum = 0.0;
293 | uint32_t renderCount = renderTimes.size();
294 | for (auto t : renderTimes) sum += t;
295 | cout << "Average rendering time is " << (sum / renderCount) << "msec." << endl;
296 | }
297 |
298 | int main(int ac, char* av[])
299 | {
300 | auto options = parse_options(ac, av);
301 | options.images_to_generate = 50;
302 |
303 | render(options);
304 |
305 | return 0;
306 | }
--------------------------------------------------------------------------------
/src/lodepng.h:
--------------------------------------------------------------------------------
1 | /*
2 | LodePNG version 20130128
3 |
4 | Copyright (c) 2005-2013 Lode Vandevenne
5 |
6 | This software is provided 'as-is', without any express or implied
7 | warranty. In no event will the authors be held liable for any damages
8 | arising from the use of this software.
9 |
10 | Permission is granted to anyone to use this software for any purpose,
11 | including commercial applications, and to alter it and redistribute it
12 | freely, subject to the following restrictions:
13 |
14 | 1. The origin of this software must not be misrepresented; you must not
15 | claim that you wrote the original software. If you use this software
16 | in a product, an acknowledgment in the product documentation would be
17 | appreciated but is not required.
18 |
19 | 2. Altered source versions must be plainly marked as such, and must not be
20 | misrepresented as being the original software.
21 |
22 | 3. This notice may not be removed or altered from any source
23 | distribution.
24 | */
25 |
26 | #ifndef LODEPNG_H
27 | #define LODEPNG_H
28 |
29 | /*
30 | The following #defines are used to create code sections. They can be disabled
31 | to disable code sections, which can give faster compile time and smaller binary.
32 | The "NO_COMPILE" defines are designed to be used to pass as defines to the
33 | compiler command to disable them without modifying this header, e.g.
34 | -DLODEPNG_NO_COMPILE_ZLIB for gcc.
35 | */
36 | /*deflate & zlib. If disabled, you must specify alternative zlib functions in
37 | the custom_zlib field of the compress and decompress settings*/
38 | #ifndef LODEPNG_NO_COMPILE_ZLIB
39 | #define LODEPNG_COMPILE_ZLIB
40 | #endif
41 | /*png encoder and png decoder*/
42 | #ifndef LODEPNG_NO_COMPILE_PNG
43 | #define LODEPNG_COMPILE_PNG
44 | #endif
45 | /*deflate&zlib decoder and png decoder*/
46 | #ifndef LODEPNG_NO_COMPILE_DECODER
47 | #define LODEPNG_COMPILE_DECODER
48 | #endif
49 | /*deflate&zlib encoder and png encoder*/
50 | #ifndef LODEPNG_NO_COMPILE_ENCODER
51 | #define LODEPNG_COMPILE_ENCODER
52 | #endif
53 | /*the optional built in harddisk file loading and saving functions*/
54 | #ifndef LODEPNG_NO_COMPILE_DISK
55 | #define LODEPNG_COMPILE_DISK
56 | #endif
57 | /*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/
58 | #ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS
59 | #define LODEPNG_COMPILE_ANCILLARY_CHUNKS
60 | #endif
61 | /*ability to convert error numerical codes to English text string*/
62 | #ifndef LODEPNG_NO_COMPILE_ERROR_TEXT
63 | #define LODEPNG_COMPILE_ERROR_TEXT
64 | #endif
65 | /*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/
66 | #ifdef __cplusplus
67 | #ifndef LODEPNG_NO_COMPILE_CPP
68 | #define LODEPNG_COMPILE_CPP
69 | #endif
70 | #endif
71 |
72 | #ifdef LODEPNG_COMPILE_PNG
73 | /*The PNG color types (also used for raw).*/
74 | typedef enum LodePNGColorType
75 | {
76 | LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/
77 | LCT_RGB = 2, /*RGB: 8,16 bit*/
78 | LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/
79 | LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/
80 | LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/
81 | } LodePNGColorType;
82 |
83 | #ifdef LODEPNG_COMPILE_DECODER
84 | /*
85 | Converts PNG data in memory to raw pixel data.
86 | out: Output parameter. Pointer to buffer that will contain the raw pixel data.
87 | After decoding, its size is w * h * (bytes per pixel) bytes larger than
88 | initially. Bytes per pixel depends on colortype and bitdepth.
89 | Must be freed after usage with free(*out).
90 | Note: for 16-bit per channel colors, uses big endian format like PNG does.
91 | w: Output parameter. Pointer to width of pixel data.
92 | h: Output parameter. Pointer to height of pixel data.
93 | in: Memory buffer with the PNG file.
94 | insize: size of the in buffer.
95 | colortype: the desired color type for the raw output image. See explanation on PNG color types.
96 | bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types.
97 | Return value: LodePNG error code (0 means no error).
98 | */
99 | unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h,
100 | const unsigned char* in, size_t insize,
101 | LodePNGColorType colortype, unsigned bitdepth);
102 |
103 | /*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/
104 | unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h,
105 | const unsigned char* in, size_t insize);
106 |
107 | /*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/
108 | unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h,
109 | const unsigned char* in, size_t insize);
110 |
111 | #ifdef LODEPNG_COMPILE_DISK
112 | /*
113 | Load PNG from disk, from file with given name.
114 | Same as the other decode functions, but instead takes a filename as input.
115 | */
116 | unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h,
117 | const char* filename,
118 | LodePNGColorType colortype, unsigned bitdepth);
119 |
120 | /*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/
121 | unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h,
122 | const char* filename);
123 |
124 | /*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/
125 | unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h,
126 | const char* filename);
127 | #endif /*LODEPNG_COMPILE_DISK*/
128 | #endif /*LODEPNG_COMPILE_DECODER*/
129 |
130 |
131 | #ifdef LODEPNG_COMPILE_ENCODER
132 | /*
133 | Converts raw pixel data into a PNG image in memory. The colortype and bitdepth
134 | of the output PNG image cannot be chosen, they are automatically determined
135 | by the colortype, bitdepth and content of the input pixel data.
136 | Note: for 16-bit per channel colors, needs big endian format like PNG does.
137 | out: Output parameter. Pointer to buffer that will contain the PNG image data.
138 | Must be freed after usage with free(*out).
139 | outsize: Output parameter. Pointer to the size in bytes of the out buffer.
140 | image: The raw pixel data to encode. The size of this buffer should be
141 | w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth.
142 | w: width of the raw pixel data in pixels.
143 | h: height of the raw pixel data in pixels.
144 | colortype: the color type of the raw input image. See explanation on PNG color types.
145 | bitdepth: the bit depth of the raw input image. See explanation on PNG color types.
146 | Return value: LodePNG error code (0 means no error).
147 | */
148 | unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize,
149 | const unsigned char* image, unsigned w, unsigned h,
150 | LodePNGColorType colortype, unsigned bitdepth);
151 |
152 | /*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/
153 | unsigned lodepng_encode32(unsigned char** out, size_t* outsize,
154 | const unsigned char* image, unsigned w, unsigned h);
155 |
156 | /*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/
157 | unsigned lodepng_encode24(unsigned char** out, size_t* outsize,
158 | const unsigned char* image, unsigned w, unsigned h);
159 |
160 | #ifdef LODEPNG_COMPILE_DISK
161 | /*
162 | Converts raw pixel data into a PNG file on disk.
163 | Same as the other encode functions, but instead takes a filename as output.
164 | NOTE: This overwrites existing files without warning!
165 | */
166 | unsigned lodepng_encode_file(const char* filename,
167 | const unsigned char* image, unsigned w, unsigned h,
168 | LodePNGColorType colortype, unsigned bitdepth);
169 |
170 | /*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/
171 | unsigned lodepng_encode32_file(const char* filename,
172 | const unsigned char* image, unsigned w, unsigned h);
173 |
174 | /*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/
175 | unsigned lodepng_encode24_file(const char* filename,
176 | const unsigned char* image, unsigned w, unsigned h);
177 | #endif /*LODEPNG_COMPILE_DISK*/
178 | #endif /*LODEPNG_COMPILE_ENCODER*/
179 |
180 |
181 | #ifdef LODEPNG_COMPILE_CPP
182 | namespace lodepng
183 | {
184 | #ifdef LODEPNG_COMPILE_DECODER
185 | /*Same as lodepng_decode_memory, but decodes to an std::vector.*/
186 | unsigned decode(std::vector& out, unsigned& w, unsigned& h,
187 | const unsigned char* in, size_t insize,
188 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
189 | unsigned decode(std::vector& out, unsigned& w, unsigned& h,
190 | const std::vector& in,
191 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
192 | #ifdef LODEPNG_COMPILE_DISK
193 | /*
194 | Converts PNG file from disk to raw pixel data in memory.
195 | Same as the other decode functions, but instead takes a filename as input.
196 | */
197 | unsigned decode(std::vector& out, unsigned& w, unsigned& h,
198 | const std::string& filename,
199 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
200 | #endif //LODEPNG_COMPILE_DISK
201 | #endif //LODEPNG_COMPILE_DECODER
202 |
203 | #ifdef LODEPNG_COMPILE_ENCODER
204 | /*Same as lodepng_encode_memory, but encodes to an std::vector.*/
205 | unsigned encode(std::vector& out,
206 | const unsigned char* in, unsigned w, unsigned h,
207 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
208 | unsigned encode(std::vector& out,
209 | const std::vector& in, unsigned w, unsigned h,
210 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
211 | #ifdef LODEPNG_COMPILE_DISK
212 | /*
213 | Converts 32-bit RGBA raw pixel data into a PNG file on disk.
214 | Same as the other encode functions, but instead takes a filename as output.
215 | NOTE: This overwrites existing files without warning!
216 | */
217 | unsigned encode(const std::string& filename,
218 | const unsigned char* in, unsigned w, unsigned h,
219 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
220 | unsigned encode(const std::string& filename,
221 | const std::vector& in, unsigned w, unsigned h,
222 | LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8);
223 | #endif //LODEPNG_COMPILE_DISK
224 | #endif //LODEPNG_COMPILE_ENCODER
225 | } //namespace lodepng
226 | #endif /*LODEPNG_COMPILE_CPP*/
227 | #endif /*LODEPNG_COMPILE_PNG*/
228 |
229 | #ifdef LODEPNG_COMPILE_ERROR_TEXT
230 | /*Returns an English description of the numerical error code.*/
231 | const char* lodepng_error_text(unsigned code);
232 | #endif /*LODEPNG_COMPILE_ERROR_TEXT*/
233 |
234 | #ifdef LODEPNG_COMPILE_DECODER
235 | /*Settings for zlib decompression*/
236 | typedef struct LodePNGDecompressSettings LodePNGDecompressSettings;
237 | struct LodePNGDecompressSettings
238 | {
239 | unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
240 |
241 | /*use custom zlib decoder instead of built in one (default: null)*/
242 | unsigned (*custom_zlib)(unsigned char**, size_t*,
243 | const unsigned char*, size_t,
244 | const LodePNGDecompressSettings*);
245 | /*use custom deflate decoder instead of built in one (default: null)
246 | if custom_zlib is used, custom_deflate is ignored since only the built in
247 | zlib function will call custom_deflate*/
248 | unsigned (*custom_inflate)(unsigned char**, size_t*,
249 | const unsigned char*, size_t,
250 | const LodePNGDecompressSettings*);
251 |
252 | void* custom_context; /*optional custom settings for custom functions*/
253 | };
254 |
255 | extern const LodePNGDecompressSettings lodepng_default_decompress_settings;
256 | void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings);
257 | #endif /*LODEPNG_COMPILE_DECODER*/
258 |
259 | #ifdef LODEPNG_COMPILE_ENCODER
260 | /*
261 | Settings for zlib compression. Tweaking these settings tweaks the balance
262 | between speed and compression ratio.
263 | */
264 | typedef struct LodePNGCompressSettings LodePNGCompressSettings;
265 | struct LodePNGCompressSettings /*deflate = compress*/
266 | {
267 | /*LZ77 related settings*/
268 | unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/
269 | unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/
270 | unsigned windowsize; /*the maximum is 32768, higher gives more compression but is slower. Typical value: 2048.*/
271 | unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/
272 | unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/
273 | unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/
274 |
275 | /*use custom zlib encoder instead of built in one (default: null)*/
276 | unsigned (*custom_zlib)(unsigned char**, size_t*,
277 | const unsigned char*, size_t,
278 | const LodePNGCompressSettings*);
279 | /*use custom deflate encoder instead of built in one (default: null)
280 | if custom_zlib is used, custom_deflate is ignored since only the built in
281 | zlib function will call custom_deflate*/
282 | unsigned (*custom_deflate)(unsigned char**, size_t*,
283 | const unsigned char*, size_t,
284 | const LodePNGCompressSettings*);
285 |
286 | void* custom_context; /*optional custom settings for custom functions*/
287 | };
288 |
289 | extern const LodePNGCompressSettings lodepng_default_compress_settings;
290 | void lodepng_compress_settings_init(LodePNGCompressSettings* settings);
291 | #endif /*LODEPNG_COMPILE_ENCODER*/
292 |
293 | #ifdef LODEPNG_COMPILE_PNG
294 | /*
295 | Color mode of an image. Contains all information required to decode the pixel
296 | bits to RGBA colors. This information is the same as used in the PNG file
297 | format, and is used both for PNG and raw image data in LodePNG.
298 | */
299 | typedef struct LodePNGColorMode
300 | {
301 | /*header (IHDR)*/
302 | LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/
303 | unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/
304 |
305 | /*
306 | palette (PLTE and tRNS)
307 |
308 | Dynamically allocated with the colors of the palette, including alpha.
309 | When encoding a PNG, to store your colors in the palette of the LodePNGColorMode, first use
310 | lodepng_palette_clear, then for each color use lodepng_palette_add.
311 | If you encode an image without alpha with palette, don't forget to put value 255 in each A byte of the palette.
312 |
313 | When decoding, by default you can ignore this palette, since LodePNG already
314 | fills the palette colors in the pixels of the raw RGBA output.
315 |
316 | The palette is only supported for color type 3.
317 | */
318 | unsigned char* palette; /*palette in RGBARGBA... order*/
319 | size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/
320 |
321 | /*
322 | transparent color key (tRNS)
323 |
324 | This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit.
325 | For greyscale PNGs, r, g and b will all 3 be set to the same.
326 |
327 | When decoding, by default you can ignore this information, since LodePNG sets
328 | pixels with this key to transparent already in the raw RGBA output.
329 |
330 | The color key is only supported for color types 0 and 2.
331 | */
332 | unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/
333 | unsigned key_r; /*red/greyscale component of color key*/
334 | unsigned key_g; /*green component of color key*/
335 | unsigned key_b; /*blue component of color key*/
336 | } LodePNGColorMode;
337 |
338 | /*init, cleanup and copy functions to use with this struct*/
339 | void lodepng_color_mode_init(LodePNGColorMode* info);
340 | void lodepng_color_mode_cleanup(LodePNGColorMode* info);
341 | /*return value is error code (0 means no error)*/
342 | unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source);
343 |
344 | void lodepng_palette_clear(LodePNGColorMode* info);
345 | /*add 1 color to the palette*/
346 | unsigned lodepng_palette_add(LodePNGColorMode* info,
347 | unsigned char r, unsigned char g, unsigned char b, unsigned char a);
348 |
349 | /*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/
350 | unsigned lodepng_get_bpp(const LodePNGColorMode* info);
351 | /*get the amount of color channels used, based on colortype in the struct.
352 | If a palette is used, it counts as 1 channel.*/
353 | unsigned lodepng_get_channels(const LodePNGColorMode* info);
354 | /*is it a greyscale type? (only colortype 0 or 4)*/
355 | unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info);
356 | /*has it got an alpha channel? (only colortype 2 or 6)*/
357 | unsigned lodepng_is_alpha_type(const LodePNGColorMode* info);
358 | /*has it got a palette? (only colortype 3)*/
359 | unsigned lodepng_is_palette_type(const LodePNGColorMode* info);
360 | /*only returns true if there is a palette and there is a value in the palette with alpha < 255.
361 | Loops through the palette to check this.*/
362 | unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info);
363 | /*
364 | Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image.
365 | Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels).
366 | Returns false if the image can only have opaque pixels.
367 | In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values,
368 | or if "key_defined" is true.
369 | */
370 | unsigned lodepng_can_have_alpha(const LodePNGColorMode* info);
371 | /*Returns the byte size of a raw image buffer with given width, height and color mode*/
372 | size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color);
373 |
374 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
375 | /*The information of a Time chunk in PNG.*/
376 | typedef struct LodePNGTime
377 | {
378 | unsigned year; /*2 bytes used (0-65535)*/
379 | unsigned month; /*1-12*/
380 | unsigned day; /*1-31*/
381 | unsigned hour; /*0-23*/
382 | unsigned minute; /*0-59*/
383 | unsigned second; /*0-60 (to allow for leap seconds)*/
384 | } LodePNGTime;
385 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
386 |
387 | /*Information about the PNG image, except pixels, width and height.*/
388 | typedef struct LodePNGInfo
389 | {
390 | /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/
391 | unsigned compression_method;/*compression method of the original file. Always 0.*/
392 | unsigned filter_method; /*filter method of the original file*/
393 | unsigned interlace_method; /*interlace method of the original file*/
394 | LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/
395 |
396 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
397 | /*
398 | suggested background color chunk (bKGD)
399 | This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit.
400 |
401 | For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding
402 | the encoder writes the red one. For palette PNGs: When decoding, the RGB value
403 | will be stored, not a palette index. But when encoding, specify the index of
404 | the palette in background_r, the other two are then ignored.
405 |
406 | The decoder does not use this background color to edit the color of pixels.
407 | */
408 | unsigned background_defined; /*is a suggested background color given?*/
409 | unsigned background_r; /*red component of suggested background color*/
410 | unsigned background_g; /*green component of suggested background color*/
411 | unsigned background_b; /*blue component of suggested background color*/
412 |
413 | /*
414 | non-international text chunks (tEXt and zTXt)
415 |
416 | The char** arrays each contain num strings. The actual messages are in
417 | text_strings, while text_keys are keywords that give a short description what
418 | the actual text represents, e.g. Title, Author, Description, or anything else.
419 |
420 | A keyword is minimum 1 character and maximum 79 characters long. It's
421 | discouraged to use a single line length longer than 79 characters for texts.
422 |
423 | Don't allocate these text buffers yourself. Use the init/cleanup functions
424 | correctly and use lodepng_add_text and lodepng_clear_text.
425 | */
426 | size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/
427 | char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/
428 | char** text_strings; /*the actual text*/
429 |
430 | /*
431 | international text chunks (iTXt)
432 | Similar to the non-international text chunks, but with additional strings
433 | "langtags" and "transkeys".
434 | */
435 | size_t itext_num; /*the amount of international texts in this PNG*/
436 | char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/
437 | char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/
438 | char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/
439 | char** itext_strings; /*the actual international text - UTF-8 string*/
440 |
441 | /*time chunk (tIME)*/
442 | unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/
443 | LodePNGTime time;
444 |
445 | /*phys chunk (pHYs)*/
446 | unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/
447 | unsigned phys_x; /*pixels per unit in x direction*/
448 | unsigned phys_y; /*pixels per unit in y direction*/
449 | unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
450 |
451 | /*
452 | unknown chunks
453 | There are 3 buffers, one for each position in the PNG where unknown chunks can appear
454 | each buffer contains all unknown chunks for that position consecutively
455 | The 3 buffers are the unknown chunks between certain critical chunks:
456 | 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND
457 | Do not allocate or traverse this data yourself. Use the chunk traversing functions declared
458 | later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct.
459 | */
460 | unsigned char* unknown_chunks_data[3];
461 | size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/
462 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
463 | } LodePNGInfo;
464 |
465 | /*init, cleanup and copy functions to use with this struct*/
466 | void lodepng_info_init(LodePNGInfo* info);
467 | void lodepng_info_cleanup(LodePNGInfo* info);
468 | /*return value is error code (0 means no error)*/
469 | unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source);
470 |
471 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
472 | void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
473 | unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/
474 |
475 | void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
476 | unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
477 | const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
478 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
479 |
480 | /*
481 | Converts raw buffer from one color type to another color type, based on
482 | LodePNGColorMode structs to describe the input and output color type.
483 | See the reference manual at the end of this header file to see which color conversions are supported.
484 | return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported)
485 | The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel
486 | of the output color type (lodepng_get_bpp)
487 | Note: for 16-bit per channel colors, uses big endian format like PNG does.
488 | */
489 | unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
490 | LodePNGColorMode* mode_out, LodePNGColorMode* mode_in,
491 | unsigned w, unsigned h);
492 |
493 |
494 | #ifdef LODEPNG_COMPILE_DECODER
495 | /*
496 | Settings for the decoder. This contains settings for the PNG and the Zlib
497 | decoder, but not the Info settings from the Info structs.
498 | */
499 | typedef struct LodePNGDecoderSettings
500 | {
501 | LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
502 |
503 | unsigned ignore_crc; /*ignore CRC checksums*/
504 | unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
505 |
506 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
507 | unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/
508 | /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/
509 | unsigned remember_unknown_chunks;
510 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
511 | } LodePNGDecoderSettings;
512 |
513 | void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings);
514 | #endif /*LODEPNG_COMPILE_DECODER*/
515 |
516 | #ifdef LODEPNG_COMPILE_ENCODER
517 | /*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/
518 | typedef enum LodePNGFilterStrategy
519 | {
520 | /*every filter at zero*/
521 | LFS_ZERO,
522 | /*Use filter that gives minumum sum, as described in the official PNG filter heuristic.*/
523 | LFS_MINSUM,
524 | /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending
525 | on the image, this is better or worse than minsum.*/
526 | LFS_ENTROPY,
527 | /*
528 | Brute-force-search PNG filters by compressing each filter for each scanline.
529 | Experimental, very slow, and only rarely gives better compression than MINSUM.
530 | */
531 | LFS_BRUTE_FORCE,
532 | /*use predefined_filters buffer: you specify the filter type for each scanline*/
533 | LFS_PREDEFINED
534 | } LodePNGFilterStrategy;
535 |
536 | /*automatically use color type with less bits per pixel if losslessly possible. Default: LAC_AUTO*/
537 | typedef enum LodePNGAutoConvert
538 | {
539 | LAC_NO, /*use color type user requested*/
540 | LAC_ALPHA, /*use color type user requested, but if only opaque pixels and RGBA or grey+alpha, use RGB or grey*/
541 | LAC_AUTO, /*use PNG color type that can losslessly represent the uncompressed image the smallest possible*/
542 | /*
543 | like AUTO, but do not choose 1, 2 or 4 bit per pixel types.
544 | sometimes a PNG image compresses worse if less than 8 bits per pixels.
545 | */
546 | LAC_AUTO_NO_NIBBLES,
547 | /*
548 | like AUTO, but never choose palette color type. For small images, encoding
549 | the palette may take more bytes than what is gained. Note that AUTO also
550 | already prevents encoding the palette for extremely small images, but that may
551 | not be sufficient because due to the compression it cannot predict when to
552 | switch.
553 | */
554 | LAC_AUTO_NO_PALETTE,
555 | LAC_AUTO_NO_NIBBLES_NO_PALETTE
556 | } LodePNGAutoConvert;
557 |
558 |
559 | /*Settings for the encoder.*/
560 | typedef struct LodePNGEncoderSettings
561 | {
562 | LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/
563 |
564 | LodePNGAutoConvert auto_convert; /*how to automatically choose output PNG color type, if at all*/
565 |
566 | /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than
567 | 8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to
568 | completely follow the official PNG heuristic, filter_palette_zero must be true and
569 | filter_strategy must be LFS_MINSUM*/
570 | unsigned filter_palette_zero;
571 | /*Which filter strategy to use when not using zeroes due to filter_palette_zero.
572 | Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/
573 | LodePNGFilterStrategy filter_strategy;
574 | /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with
575 | the same length as the amount of scanlines in the image, and each value must <= 5. You
576 | have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero
577 | must be set to 0 to ensure this is also used on palette or low bitdepth images.*/
578 | unsigned char* predefined_filters;
579 |
580 | /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette).
581 | If colortype is 3, PLTE is _always_ created.*/
582 | unsigned force_palette;
583 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
584 | /*add LodePNG identifier and version as a text chunk, for debugging*/
585 | unsigned add_id;
586 | /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/
587 | unsigned text_compression;
588 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
589 | } LodePNGEncoderSettings;
590 |
591 | void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings);
592 | #endif /*LODEPNG_COMPILE_ENCODER*/
593 |
594 |
595 | #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER)
596 | /*The settings, state and information for extended encoding and decoding.*/
597 | typedef struct LodePNGState
598 | {
599 | #ifdef LODEPNG_COMPILE_DECODER
600 | LodePNGDecoderSettings decoder; /*the decoding settings*/
601 | #endif /*LODEPNG_COMPILE_DECODER*/
602 | #ifdef LODEPNG_COMPILE_ENCODER
603 | LodePNGEncoderSettings encoder; /*the encoding settings*/
604 | #endif /*LODEPNG_COMPILE_ENCODER*/
605 | LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/
606 | LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/
607 | unsigned error;
608 | #ifdef LODEPNG_COMPILE_CPP
609 | //For the lodepng::State subclass.
610 | virtual ~LodePNGState(){}
611 | #endif
612 | } LodePNGState;
613 |
614 | /*init, cleanup and copy functions to use with this struct*/
615 | void lodepng_state_init(LodePNGState* state);
616 | void lodepng_state_cleanup(LodePNGState* state);
617 | void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source);
618 | #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */
619 |
620 | #ifdef LODEPNG_COMPILE_DECODER
621 | /*
622 | Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and
623 | getting much more information about the PNG image and color mode.
624 | */
625 | unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
626 | LodePNGState* state,
627 | const unsigned char* in, size_t insize);
628 |
629 | /*
630 | Read the PNG header, but not the actual data. This returns only the information
631 | that is in the header chunk of the PNG, such as width, height and color type. The
632 | information is placed in the info_png field of the LodePNGState.
633 | */
634 | unsigned lodepng_inspect(unsigned* w, unsigned* h,
635 | LodePNGState* state,
636 | const unsigned char* in, size_t insize);
637 | #endif /*LODEPNG_COMPILE_DECODER*/
638 |
639 |
640 | #ifdef LODEPNG_COMPILE_ENCODER
641 | /*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/
642 | unsigned lodepng_encode(unsigned char** out, size_t* outsize,
643 | const unsigned char* image, unsigned w, unsigned h,
644 | LodePNGState* state);
645 | #endif /*LODEPNG_COMPILE_ENCODER*/
646 |
647 | /*
648 | The lodepng_chunk functions are normally not needed, except to traverse the
649 | unknown chunks stored in the LodePNGInfo struct, or add new ones to it.
650 | It also allows traversing the chunks of an encoded PNG file yourself.
651 |
652 | PNG standard chunk naming conventions:
653 | First byte: uppercase = critical, lowercase = ancillary
654 | Second byte: uppercase = public, lowercase = private
655 | Third byte: must be uppercase
656 | Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
657 | */
658 |
659 | /*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/
660 | unsigned lodepng_chunk_length(const unsigned char* chunk);
661 |
662 | /*puts the 4-byte type in null terminated string*/
663 | void lodepng_chunk_type(char type[5], const unsigned char* chunk);
664 |
665 | /*check if the type is the given type*/
666 | unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type);
667 |
668 | /*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/
669 | unsigned char lodepng_chunk_ancillary(const unsigned char* chunk);
670 |
671 | /*0: public, 1: private (see PNG standard)*/
672 | unsigned char lodepng_chunk_private(const unsigned char* chunk);
673 |
674 | /*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/
675 | unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk);
676 |
677 | /*get pointer to the data of the chunk, where the input points to the header of the chunk*/
678 | unsigned char* lodepng_chunk_data(unsigned char* chunk);
679 | const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk);
680 |
681 | /*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/
682 | unsigned lodepng_chunk_check_crc(const unsigned char* chunk);
683 |
684 | /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/
685 | void lodepng_chunk_generate_crc(unsigned char* chunk);
686 |
687 | /*iterate to next chunks. don't use on IEND chunk, as there is no next chunk then*/
688 | unsigned char* lodepng_chunk_next(unsigned char* chunk);
689 | const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk);
690 |
691 | /*
692 | Appends chunk to the data in out. The given chunk should already have its chunk header.
693 | The out variable and outlength are updated to reflect the new reallocated buffer.
694 | Returns error code (0 if it went ok)
695 | */
696 | unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk);
697 |
698 | /*
699 | Appends new chunk to out. The chunk to append is given by giving its length, type
700 | and data separately. The type is a 4-letter string.
701 | The out variable and outlength are updated to reflect the new reallocated buffer.
702 | Returne error code (0 if it went ok)
703 | */
704 | unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length,
705 | const char* type, const unsigned char* data);
706 |
707 |
708 | /*Calculate CRC32 of buffer*/
709 | unsigned lodepng_crc32(const unsigned char* buf, size_t len);
710 | #endif /*LODEPNG_COMPILE_PNG*/
711 |
712 |
713 | #ifdef LODEPNG_COMPILE_ZLIB
714 | /*
715 | This zlib part can be used independently to zlib compress and decompress a
716 | buffer. It cannot be used to create gzip files however, and it only supports the
717 | part of zlib that is required for PNG, it does not support dictionaries.
718 | */
719 |
720 | #ifdef LODEPNG_COMPILE_DECODER
721 | /*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/
722 | unsigned lodepng_inflate(unsigned char** out, size_t* outsize,
723 | const unsigned char* in, size_t insize,
724 | const LodePNGDecompressSettings* settings);
725 |
726 | /*
727 | Decompresses Zlib data. Reallocates the out buffer and appends the data. The
728 | data must be according to the zlib specification.
729 | Either, *out must be NULL and *outsize must be 0, or, *out must be a valid
730 | buffer and *outsize its size in bytes. out must be freed by user after usage.
731 | */
732 | unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize,
733 | const unsigned char* in, size_t insize,
734 | const LodePNGDecompressSettings* settings);
735 | #endif /*LODEPNG_COMPILE_DECODER*/
736 |
737 | #ifdef LODEPNG_COMPILE_ENCODER
738 | /*
739 | Compresses data with Zlib. Reallocates the out buffer and appends the data.
740 | Zlib adds a small header and trailer around the deflate data.
741 | The data is output in the format of the zlib specification.
742 | Either, *out must be NULL and *outsize must be 0, or, *out must be a valid
743 | buffer and *outsize its size in bytes. out must be freed by user after usage.
744 | */
745 | unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize,
746 | const unsigned char* in, size_t insize,
747 | const LodePNGCompressSettings* settings);
748 |
749 | /*
750 | Find length-limited Huffman code for given frequencies. This function is in the
751 | public interface only for tests, it's used internally by lodepng_deflate.
752 | */
753 | unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies,
754 | size_t numcodes, unsigned maxbitlen);
755 |
756 | /*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/
757 | unsigned lodepng_deflate(unsigned char** out, size_t* outsize,
758 | const unsigned char* in, size_t insize,
759 | const LodePNGCompressSettings* settings);
760 |
761 | #endif /*LODEPNG_COMPILE_ENCODER*/
762 | #endif /*LODEPNG_COMPILE_ZLIB*/
763 |
764 | #ifdef LODEPNG_COMPILE_DISK
765 | /*
766 | Load a file from disk into buffer. The function allocates the out buffer, and
767 | after usage you should free it.
768 | out: output parameter, contains pointer to loaded buffer.
769 | outsize: output parameter, size of the allocated out buffer
770 | filename: the path to the file to load
771 | return value: error code (0 means ok)
772 | */
773 | unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename);
774 |
775 | /*
776 | Save a file from buffer to disk. Warning, if it exists, this function overwrites
777 | the file without warning!
778 | buffer: the buffer to write
779 | buffersize: size of the buffer to write
780 | filename: the path to the file to save to
781 | return value: error code (0 means ok)
782 | */
783 | unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename);
784 | #endif /*LODEPNG_COMPILE_DISK*/
785 |
786 | #ifdef LODEPNG_COMPILE_CPP
787 | //The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers.
788 | namespace lodepng
789 | {
790 | #ifdef LODEPNG_COMPILE_PNG
791 | class State : public LodePNGState
792 | {
793 | public:
794 | State();
795 | State(const State& other);
796 | virtual ~State();
797 | State& operator=(const State& other);
798 | };
799 |
800 | #ifdef LODEPNG_COMPILE_DECODER
801 | //Same as other lodepng::decode, but using a State for more settings and information.
802 | unsigned decode(std::vector& out, unsigned& w, unsigned& h,
803 | State& state,
804 | const unsigned char* in, size_t insize);
805 | unsigned decode(std::vector& out, unsigned& w, unsigned& h,
806 | State& state,
807 | const std::vector& in);
808 | #endif /*LODEPNG_COMPILE_DECODER*/
809 |
810 | #ifdef LODEPNG_COMPILE_ENCODER
811 | //Same as other lodepng::encode, but using a State for more settings and information.
812 | unsigned encode(std::vector& out,
813 | const unsigned char* in, unsigned w, unsigned h,
814 | State& state);
815 | unsigned encode(std::vector& out,
816 | const std::vector& in, unsigned w, unsigned h,
817 | State& state);
818 | #endif /*LODEPNG_COMPILE_ENCODER*/
819 |
820 | #ifdef LODEPNG_COMPILE_DISK
821 | /*
822 | Load a file from disk into an std::vector. If the vector is empty, then either
823 | the file doesn't exist or is an empty file.
824 | */
825 | void load_file(std::vector& buffer, const std::string& filename);
826 |
827 | /*
828 | Save the binary data in an std::vector to a file on disk. The file is overwritten
829 | without warning.
830 | */
831 | void save_file(const std::vector& buffer, const std::string& filename);
832 | #endif //LODEPNG_COMPILE_DISK
833 | #endif //LODEPNG_COMPILE_PNG
834 |
835 | #ifdef LODEPNG_COMPILE_ZLIB
836 | #ifdef LODEPNG_COMPILE_DECODER
837 | //Zlib-decompress an unsigned char buffer
838 | unsigned decompress(std::vector& out, const unsigned char* in, size_t insize,
839 | const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings);
840 |
841 | //Zlib-decompress an std::vector
842 | unsigned decompress(std::vector& out, const std::vector& in,
843 | const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings);
844 | #endif //LODEPNG_COMPILE_DECODER
845 |
846 | #ifdef LODEPNG_COMPILE_ENCODER
847 | //Zlib-compress an unsigned char buffer
848 | unsigned compress(std::vector& out, const unsigned char* in, size_t insize,
849 | const LodePNGCompressSettings& settings = lodepng_default_compress_settings);
850 |
851 | //Zlib-compress an std::vector
852 | unsigned compress(std::vector& out, const std::vector& in,
853 | const LodePNGCompressSettings& settings = lodepng_default_compress_settings);
854 | #endif //LODEPNG_COMPILE_ENCODER
855 | #endif //LODEPNG_COMPILE_ZLIB
856 | } //namespace lodepng
857 | #endif /*LODEPNG_COMPILE_CPP*/
858 |
859 | /*
860 | TODO:
861 | [.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often
862 | [.] check compatibility with vareous compilers - done but needs to be redone for every newer version
863 | [X] converting color to 16-bit per channel types
864 | [ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values)
865 | [ ] make sure encoder generates no chunks with size > (2^31)-1
866 | [ ] partial decoding (stream processing)
867 | [X] let the "isFullyOpaque" function check color keys and transparent palettes too
868 | [X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl"
869 | [ ] don't stop decoding on errors like 69, 57, 58 (make warnings)
870 | [ ] make option to choose if the raw image with non multiple of 8 bits per scanline should have padding bits or not
871 | [ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes
872 | */
873 |
874 | #endif /*LODEPNG_H inclusion guard*/
875 |
876 | /*
877 | LodePNG Documentation
878 | ---------------------
879 |
880 | 0. table of contents
881 | --------------------
882 |
883 | 1. about
884 | 1.1. supported features
885 | 1.2. features not supported
886 | 2. C and C++ version
887 | 3. security
888 | 4. decoding
889 | 5. encoding
890 | 6. color conversions
891 | 6.1. PNG color types
892 | 6.2. color conversions
893 | 6.3. padding bits
894 | 6.4. A note about 16-bits per channel and endianness
895 | 7. error values
896 | 8. chunks and PNG editing
897 | 9. compiler support
898 | 10. examples
899 | 10.1. decoder C++ example
900 | 10.2. decoder C example
901 | 11. changes
902 | 12. contact information
903 |
904 |
905 | 1. about
906 | --------
907 |
908 | PNG is a file format to store raster images losslessly with good compression,
909 | supporting different color types and alpha channel.
910 |
911 | LodePNG is a PNG codec according to the Portable Network Graphics (PNG)
912 | Specification (Second Edition) - W3C Recommendation 10 November 2003.
913 |
914 | The specifications used are:
915 |
916 | *) Portable Network Graphics (PNG) Specification (Second Edition):
917 | http://www.w3.org/TR/2003/REC-PNG-20031110
918 | *) RFC 1950 ZLIB Compressed Data Format version 3.3:
919 | http://www.gzip.org/zlib/rfc-zlib.html
920 | *) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3:
921 | http://www.gzip.org/zlib/rfc-deflate.html
922 |
923 | The most recent version of LodePNG can currently be found at
924 | http://lodev.org/lodepng/
925 |
926 | LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds
927 | extra functionality.
928 |
929 | LodePNG exists out of two files:
930 | -lodepng.h: the header file for both C and C++
931 | -lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage
932 |
933 | If you want to start using LodePNG right away without reading this doc, get the
934 | examples from the LodePNG website to see how to use it in code, or check the
935 | smaller examples in chapter 13 here.
936 |
937 | LodePNG is simple but only supports the basic requirements. To achieve
938 | simplicity, the following design choices were made: There are no dependencies
939 | on any external library. There are functions to decode and encode a PNG with
940 | a single function call, and extended versions of these functions taking a
941 | LodePNGState struct allowing to specify or get more information. By default
942 | the colors of the raw image are always RGB or RGBA, no matter what color type
943 | the PNG file uses. To read and write files, there are simple functions to
944 | convert the files to/from buffers in memory.
945 |
946 | This all makes LodePNG suitable for loading textures in games, demos and small
947 | programs, ... It's less suitable for full fledged image editors, loading PNGs
948 | over network (it requires all the image data to be available before decoding can
949 | begin), life-critical systems, ...
950 |
951 | 1.1. supported features
952 | -----------------------
953 |
954 | The following features are supported by the decoder:
955 |
956 | *) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image,
957 | or the same color type as the PNG
958 | *) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image
959 | *) Adam7 interlace and deinterlace for any color type
960 | *) loading the image from harddisk or decoding it from a buffer from other sources than harddisk
961 | *) support for alpha channels, including RGBA color model, translucent palettes and color keying
962 | *) zlib decompression (inflate)
963 | *) zlib compression (deflate)
964 | *) CRC32 and ADLER32 checksums
965 | *) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks.
966 | *) the following chunks are supported (generated/interpreted) by both encoder and decoder:
967 | IHDR: header information
968 | PLTE: color palette
969 | IDAT: pixel data
970 | IEND: the final chunk
971 | tRNS: transparency for palettized images
972 | tEXt: textual information
973 | zTXt: compressed textual information
974 | iTXt: international textual information
975 | bKGD: suggested background color
976 | pHYs: physical dimensions
977 | tIME: modification time
978 |
979 | 1.2. features not supported
980 | ---------------------------
981 |
982 | The following features are _not_ supported:
983 |
984 | *) some features needed to make a conformant PNG-Editor might be still missing.
985 | *) partial loading/stream processing. All data must be available and is processed in one call.
986 | *) The following public chunks are not supported but treated as unknown chunks by LodePNG
987 | cHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT
988 | Some of these are not supported on purpose: LodePNG wants to provide the RGB values
989 | stored in the pixels, not values modified by system dependent gamma or color models.
990 |
991 |
992 | 2. C and C++ version
993 | --------------------
994 |
995 | The C version uses buffers allocated with alloc that you need to free()
996 | yourself. You need to use init and cleanup functions for each struct whenever
997 | using a struct from the C version to avoid exploits and memory leaks.
998 |
999 | The C++ version has extra functions with std::vectors in the interface and the
1000 | lodepng::State class which is a LodePNGState with constructor and destructor.
1001 |
1002 | These files work without modification for both C and C++ compilers because all
1003 | the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers
1004 | ignore it, and the C code is made to compile both with strict ISO C90 and C++.
1005 |
1006 | To use the C++ version, you need to rename the source file to lodepng.cpp
1007 | (instead of lodepng.c), and compile it with a C++ compiler.
1008 |
1009 | To use the C version, you need to rename the source file to lodepng.c (instead
1010 | of lodepng.cpp), and compile it with a C compiler.
1011 |
1012 |
1013 | 3. Security
1014 | -----------
1015 |
1016 | Even if carefully designed, it's always possible that LodePNG contains possible
1017 | exploits. If you discover one, please let me know, and it will be fixed.
1018 |
1019 | When using LodePNG, care has to be taken with the C version of LodePNG, as well
1020 | as the C-style structs when working with C++. The following conventions are used
1021 | for all C-style structs:
1022 |
1023 | -if a struct has a corresponding init function, always call the init function when making a new one
1024 | -if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks
1025 | -if a struct has a corresponding copy function, use the copy function instead of "=".
1026 | The destination must also be inited already.
1027 |
1028 |
1029 | 4. Decoding
1030 | -----------
1031 |
1032 | Decoding converts a PNG compressed image to a raw pixel buffer.
1033 |
1034 | Most documentation on using the decoder is at its declarations in the header
1035 | above. For C, simple decoding can be done with functions such as
1036 | lodepng_decode32, and more advanced decoding can be done with the struct
1037 | LodePNGState and lodepng_decode. For C++, all decoding can be done with the
1038 | various lodepng::decode functions, and lodepng::State can be used for advanced
1039 | features.
1040 |
1041 | When using the LodePNGState, it uses the following fields for decoding:
1042 | *) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here
1043 | *) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get
1044 | *) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use
1045 |
1046 | LodePNGInfo info_png
1047 | --------------------
1048 |
1049 | After decoding, this contains extra information of the PNG image, except the actual
1050 | pixels, width and height because these are already gotten directly from the decoder
1051 | functions.
1052 |
1053 | It contains for example the original color type of the PNG image, text comments,
1054 | suggested background color, etc... More details about the LodePNGInfo struct are
1055 | at its declaration documentation.
1056 |
1057 | LodePNGColorMode info_raw
1058 | -------------------------
1059 |
1060 | When decoding, here you can specify which color type you want
1061 | the resulting raw image to be. If this is different from the colortype of the
1062 | PNG, then the decoder will automatically convert the result. This conversion
1063 | always works, except if you want it to convert a color PNG to greyscale or to
1064 | a palette with missing colors.
1065 |
1066 | By default, 32-bit color is used for the result.
1067 |
1068 | LodePNGDecoderSettings decoder
1069 | ------------------------------
1070 |
1071 | The settings can be used to ignore the errors created by invalid CRC and Adler32
1072 | chunks, and to disable the decoding of tEXt chunks.
1073 |
1074 | There's also a setting color_convert, true by default. If false, no conversion
1075 | is done, the resulting data will be as it was in the PNG (after decompression)
1076 | and you'll have to puzzle the colors of the pixels together yourself using the
1077 | color type information in the LodePNGInfo.
1078 |
1079 |
1080 | 5. Encoding
1081 | -----------
1082 |
1083 | Encoding converts a raw pixel buffer to a PNG compressed image.
1084 |
1085 | Most documentation on using the encoder is at its declarations in the header
1086 | above. For C, simple encoding can be done with functions such as
1087 | lodepng_encode32, and more advanced decoding can be done with the struct
1088 | LodePNGState and lodepng_encode. For C++, all encoding can be done with the
1089 | various lodepng::encode functions, and lodepng::State can be used for advanced
1090 | features.
1091 |
1092 | Like the decoder, the encoder can also give errors. However it gives less errors
1093 | since the encoder input is trusted, the decoder input (a PNG image that could
1094 | be forged by anyone) is not trusted.
1095 |
1096 | When using the LodePNGState, it uses the following fields for encoding:
1097 | *) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be.
1098 | *) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has
1099 | *) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use
1100 |
1101 | LodePNGInfo info_png
1102 | --------------------
1103 |
1104 | When encoding, you use this the opposite way as when decoding: for encoding,
1105 | you fill in the values you want the PNG to have before encoding. By default it's
1106 | not needed to specify a color type for the PNG since it's automatically chosen,
1107 | but it's possible to choose it yourself given the right settings.
1108 |
1109 | The encoder will not always exactly match the LodePNGInfo struct you give,
1110 | it tries as close as possible. Some things are ignored by the encoder. The
1111 | encoder uses, for example, the following settings from it when applicable:
1112 | colortype and bitdepth, text chunks, time chunk, the color key, the palette, the
1113 | background color, the interlace method, unknown chunks, ...
1114 |
1115 | When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk.
1116 | If the palette contains any colors for which the alpha channel is not 255 (so
1117 | there are translucent colors in the palette), it'll add a tRNS chunk.
1118 |
1119 | LodePNGColorMode info_raw
1120 | -------------------------
1121 |
1122 | You specify the color type of the raw image that you give to the input here,
1123 | including a possible transparent color key and palette you happen to be using in
1124 | your raw image data.
1125 |
1126 | By default, 32-bit color is assumed, meaning your input has to be in RGBA
1127 | format with 4 bytes (unsigned chars) per pixel.
1128 |
1129 | LodePNGEncoderSettings encoder
1130 | ------------------------------
1131 |
1132 | The following settings are supported (some are in sub-structs):
1133 | *) auto_convert: when this option is enabled, the encoder will
1134 | automatically choose the smallest possible color mode (including color key) that
1135 | can encode the colors of all pixels without information loss.
1136 | *) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree,
1137 | 2 = dynamic huffman tree (best compression). Should be 2 for proper
1138 | compression.
1139 | *) use_lz77: whether or not to use LZ77 for compressed block types. Should be
1140 | true for proper compression.
1141 | *) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value
1142 | 2048 by default, but can be set to 32768 for better, but slow, compression.
1143 | *) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE
1144 | chunk if force_palette is true. This can used as suggested palette to convert
1145 | to by viewers that don't support more than 256 colors (if those still exist)
1146 | *) add_id: add text chunk "Encoder: LodePNG " to the image.
1147 | *) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks.
1148 | zTXt chunks use zlib compression on the text. This gives a smaller result on
1149 | large texts but a larger result on small texts (such as a single program name).
1150 | It's all tEXt or all zTXt though, there's no separate setting per text yet.
1151 |
1152 |
1153 | 6. color conversions
1154 | --------------------
1155 |
1156 | An important thing to note about LodePNG, is that the color type of the PNG, and
1157 | the color type of the raw image, are completely independent. By default, when
1158 | you decode a PNG, you get the result as a raw image in the color type you want,
1159 | no matter whether the PNG was encoded with a palette, greyscale or RGBA color.
1160 | And if you encode an image, by default LodePNG will automatically choose the PNG
1161 | color type that gives good compression based on the values of colors and amount
1162 | of colors in the image. It can be configured to let you control it instead as
1163 | well, though.
1164 |
1165 | To be able to do this, LodePNG does conversions from one color mode to another.
1166 | It can convert from almost any color type to any other color type, except the
1167 | following conversions: RGB to greyscale is not supported, and converting to a
1168 | palette when the palette doesn't have a required color is not supported. This is
1169 | not supported on purpose: this is information loss which requires a color
1170 | reduction algorithm that is beyong the scope of a PNG encoder (yes, RGB to grey
1171 | is easy, but there are multiple ways if you want to give some channels more
1172 | weight).
1173 |
1174 | By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB
1175 | color, no matter what color type the PNG has. And by default when encoding,
1176 | LodePNG automatically picks the best color model for the output PNG, and expects
1177 | the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control
1178 | the color format of the images yourself, you can skip this chapter.
1179 |
1180 | 6.1. PNG color types
1181 | --------------------
1182 |
1183 | A PNG image can have many color types, ranging from 1-bit color to 64-bit color,
1184 | as well as palettized color modes. After the zlib decompression and unfiltering
1185 | in the PNG image is done, the raw pixel data will have that color type and thus
1186 | a certain amount of bits per pixel. If you want the output raw image after
1187 | decoding to have another color type, a conversion is done by LodePNG.
1188 |
1189 | The PNG specification gives the following color types:
1190 |
1191 | 0: greyscale, bit depths 1, 2, 4, 8, 16
1192 | 2: RGB, bit depths 8 and 16
1193 | 3: palette, bit depths 1, 2, 4 and 8
1194 | 4: greyscale with alpha, bit depths 8 and 16
1195 | 6: RGBA, bit depths 8 and 16
1196 |
1197 | Bit depth is the amount of bits per pixel per color channel. So the total amount
1198 | of bits per pixel is: amount of channels * bitdepth.
1199 |
1200 | 6.2. color conversions
1201 | ----------------------
1202 |
1203 | As explained in the sections about the encoder and decoder, you can specify
1204 | color types and bit depths in info_png and info_raw to change the default
1205 | behaviour.
1206 |
1207 | If, when decoding, you want the raw image to be something else than the default,
1208 | you need to set the color type and bit depth you want in the LodePNGColorMode,
1209 | or the parameters of the simple function of LodePNG you're using.
1210 |
1211 | If, when encoding, you use another color type than the default in the input
1212 | image, you need to specify its color type and bit depth in the LodePNGColorMode
1213 | of the raw image, or use the parameters of the simplefunction of LodePNG you're
1214 | using.
1215 |
1216 | If, when encoding, you don't want LodePNG to choose the output PNG color type
1217 | but control it yourself, you need to set auto_convert in the encoder settings
1218 | to LAC_NONE, and specify the color type you want in the LodePNGInfo of the
1219 | encoder.
1220 |
1221 | If you do any of the above, LodePNG may need to do a color conversion, which
1222 | follows the rules below, and may sometimes not be allowed.
1223 |
1224 | To avoid some confusion:
1225 | -the decoder converts from PNG to raw image
1226 | -the encoder converts from raw image to PNG
1227 | -the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image
1228 | -the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG
1229 | -when encoding, the color type in LodePNGInfo is ignored if auto_convert
1230 | is enabled, it is automatically generated instead
1231 | -when decoding, the color type in LodePNGInfo is set by the decoder to that of the original
1232 | PNG image, but it can be ignored since the raw image has the color type you requested instead
1233 | -if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion
1234 | between the color types is done if the color types are supported. If it is not
1235 | supported, an error is returned. If the types are the same, no conversion is done.
1236 | -even though some conversions aren't supported, LodePNG supports loading PNGs from any
1237 | colortype and saving PNGs to any colortype, sometimes it just requires preparing
1238 | the raw image correctly before encoding.
1239 | -both encoder and decoder use the same color converter.
1240 |
1241 | Non supported color conversions:
1242 | -color to greyscale: no error is thrown, but the result will look ugly because
1243 | only the red channel is taken
1244 | -anything, to palette when that palette does not have that color in it: in this
1245 | case an error is thrown
1246 |
1247 | Supported color conversions:
1248 | -anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA
1249 | -any grey or grey+alpha, to grey or grey+alpha
1250 | -anything to a palette, as long as the palette has the requested colors in it
1251 | -removing alpha channel
1252 | -higher to smaller bitdepth, and vice versa
1253 |
1254 | If you want no color conversion to be done:
1255 | -In the encoder, you can make it save a PNG with any color type by giving the
1256 | raw color mode and LodePNGInfo the same color mode, and setting auto_convert to
1257 | LAC_NO.
1258 | -In the decoder, you can make it store the pixel data in the same color type
1259 | as the PNG has, by setting the color_convert setting to false. Settings in
1260 | info_raw are then ignored.
1261 |
1262 | The function lodepng_convert does the color conversion. It is available in the
1263 | interface but normally isn't needed since the encoder and decoder already call
1264 | it.
1265 |
1266 | 6.3. padding bits
1267 | -----------------
1268 |
1269 | In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines
1270 | have a bit amount that isn't a multiple of 8, then padding bits are used so that each
1271 | scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output.
1272 | The raw input image you give to the encoder, and the raw output image you get from the decoder
1273 | will NOT have these padding bits, e.g. in the case of a 1-bit image with a width
1274 | of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte,
1275 | not the first bit of a new byte.
1276 |
1277 | 6.4. A note about 16-bits per channel and endianness
1278 | ----------------------------------------------------
1279 |
1280 | LodePNG uses unsigned char arrays for 16-bit per channel colors too, just like
1281 | for any other color format. The 16-bit values are stored in big endian (most
1282 | significant byte first) in these arrays. This is the opposite order of the
1283 | little endian used by x86 CPU's.
1284 |
1285 | LodePNG always uses big endian because the PNG file format does so internally.
1286 | Conversions to other formats than PNG uses internally are not supported by
1287 | LodePNG on purpose, there are myriads of formats, including endianness of 16-bit
1288 | colors, the order in which you store R, G, B and A, and so on. Supporting and
1289 | converting to/from all that is outside the scope of LodePNG.
1290 |
1291 | This may mean that, depending on your use case, you may want to convert the big
1292 | endian output of LodePNG to little endian with a for loop. This is certainly not
1293 | always needed, many applications and libraries support big endian 16-bit colors
1294 | anyway, but it means you cannot simply cast the unsigned char* buffer to an
1295 | unsigned short* buffer on x86 CPUs.
1296 |
1297 |
1298 | 7. error values
1299 | ---------------
1300 |
1301 | All functions in LodePNG that return an error code, return 0 if everything went
1302 | OK, or a non-zero code if there was an error.
1303 |
1304 | The meaning of the LodePNG error values can be retrieved with the function
1305 | lodepng_error_text: given the numerical error code, it returns a description
1306 | of the error in English as a string.
1307 |
1308 | Check the implementation of lodepng_error_text to see the meaning of each code.
1309 |
1310 |
1311 | 8. chunks and PNG editing
1312 | -------------------------
1313 |
1314 | If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG
1315 | editor that should follow the rules about handling of unknown chunks, or if your
1316 | program is able to read other types of chunks than the ones handled by LodePNG,
1317 | then that's possible with the chunk functions of LodePNG.
1318 |
1319 | A PNG chunk has the following layout:
1320 |
1321 | 4 bytes length
1322 | 4 bytes type name
1323 | length bytes data
1324 | 4 bytes CRC
1325 |
1326 | 8.1. iterating through chunks
1327 | -----------------------------
1328 |
1329 | If you have a buffer containing the PNG image data, then the first chunk (the
1330 | IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the
1331 | signature of the PNG and are not part of a chunk. But if you start at byte 8
1332 | then you have a chunk, and can check the following things of it.
1333 |
1334 | NOTE: none of these functions check for memory buffer boundaries. To avoid
1335 | exploits, always make sure the buffer contains all the data of the chunks.
1336 | When using lodepng_chunk_next, make sure the returned value is within the
1337 | allocated memory.
1338 |
1339 | unsigned lodepng_chunk_length(const unsigned char* chunk):
1340 |
1341 | Get the length of the chunk's data. The total chunk length is this length + 12.
1342 |
1343 | void lodepng_chunk_type(char type[5], const unsigned char* chunk):
1344 | unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type):
1345 |
1346 | Get the type of the chunk or compare if it's a certain type
1347 |
1348 | unsigned char lodepng_chunk_critical(const unsigned char* chunk):
1349 | unsigned char lodepng_chunk_private(const unsigned char* chunk):
1350 | unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk):
1351 |
1352 | Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are).
1353 | Check if the chunk is private (public chunks are part of the standard, private ones not).
1354 | Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical
1355 | chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your
1356 | program doesn't handle that type of unknown chunk.
1357 |
1358 | unsigned char* lodepng_chunk_data(unsigned char* chunk):
1359 | const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk):
1360 |
1361 | Get a pointer to the start of the data of the chunk.
1362 |
1363 | unsigned lodepng_chunk_check_crc(const unsigned char* chunk):
1364 | void lodepng_chunk_generate_crc(unsigned char* chunk):
1365 |
1366 | Check if the crc is correct or generate a correct one.
1367 |
1368 | unsigned char* lodepng_chunk_next(unsigned char* chunk):
1369 | const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk):
1370 |
1371 | Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these
1372 | functions do no boundary checking of the allocated data whatsoever, so make sure there is enough
1373 | data available in the buffer to be able to go to the next chunk.
1374 |
1375 | unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk):
1376 | unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length,
1377 | const char* type, const unsigned char* data):
1378 |
1379 | These functions are used to create new chunks that are appended to the data in *out that has
1380 | length *outlength. The append function appends an existing chunk to the new data. The create
1381 | function creates a new chunk with the given parameters and appends it. Type is the 4-letter
1382 | name of the chunk.
1383 |
1384 | 8.2. chunks in info_png
1385 | -----------------------
1386 |
1387 | The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3
1388 | buffers (each with size) to contain 3 types of unknown chunks:
1389 | the ones that come before the PLTE chunk, the ones that come between the PLTE
1390 | and the IDAT chunks, and the ones that come after the IDAT chunks.
1391 | It's necessary to make the distionction between these 3 cases because the PNG
1392 | standard forces to keep the ordering of unknown chunks compared to the critical
1393 | chunks, but does not force any other ordering rules.
1394 |
1395 | info_png.unknown_chunks_data[0] is the chunks before PLTE
1396 | info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT
1397 | info_png.unknown_chunks_data[2] is the chunks after IDAT
1398 |
1399 | The chunks in these 3 buffers can be iterated through and read by using the same
1400 | way described in the previous subchapter.
1401 |
1402 | When using the decoder to decode a PNG, you can make it store all unknown chunks
1403 | if you set the option settings.remember_unknown_chunks to 1. By default, this
1404 | option is off (0).
1405 |
1406 | The encoder will always encode unknown chunks that are stored in the info_png.
1407 | If you need it to add a particular chunk that isn't known by LodePNG, you can
1408 | use lodepng_chunk_append or lodepng_chunk_create to the chunk data in
1409 | info_png.unknown_chunks_data[x].
1410 |
1411 | Chunks that are known by LodePNG should not be added in that way. E.g. to make
1412 | LodePNG add a bKGD chunk, set background_defined to true and add the correct
1413 | parameters there instead.
1414 |
1415 |
1416 | 9. compiler support
1417 | -------------------
1418 |
1419 | No libraries other than the current standard C library are needed to compile
1420 | LodePNG. For the C++ version, only the standard C++ library is needed on top.
1421 | Add the files lodepng.c(pp) and lodepng.h to your project, include
1422 | lodepng.h where needed, and your program can read/write PNG files.
1423 |
1424 | If performance is important, use optimization when compiling! For both the
1425 | encoder and decoder, this makes a large difference.
1426 |
1427 | Make sure that LodePNG is compiled with the same compiler of the same version
1428 | and with the same settings as the rest of the program, or the interfaces with
1429 | std::vectors and std::strings in C++ can be incompatible.
1430 |
1431 | CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets.
1432 |
1433 | *) gcc and g++
1434 |
1435 | LodePNG is developed in gcc so this compiler is natively supported. It gives no
1436 | warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++
1437 | version 4.7.1 on Linux, 32-bit and 64-bit.
1438 |
1439 | *) Mingw
1440 |
1441 | The Mingw compiler (a port of gcc) for Windows is fully supported by LodePNG.
1442 |
1443 | *) Visual Studio 2005 and up, Visual C++ Express Edition 2005 and up
1444 |
1445 | Visual Studio may give warnings about 'fopen' being deprecated. A multiplatform library
1446 | can't support the proposed Visual Studio alternative however, so LodePNG keeps using
1447 | fopen. If you don't want to see the deprecated warnings, put this on top of lodepng.h
1448 | before the inclusions:
1449 | #define _CRT_SECURE_NO_DEPRECATE
1450 |
1451 | With warning level 4 (W4), there may be a lot of warnings about possible loss of data
1452 | due to integer conversions. I'm not planning to resolve these warnings. The gcc compiler
1453 | doesn't give those even with strict warning flags. With warning level 3 in VS 2008
1454 | Express Edition, LodePNG is, other than the fopen warnings, warning-free again since
1455 | version 20120923.
1456 |
1457 | Visual Studio may want "stdafx.h" files to be included in each source file. That
1458 | is not standard C++ and will not be added to the stock LodePNG. Try to find a
1459 | setting to disable it for this source file.
1460 |
1461 | *) Visual Studio 6.0
1462 |
1463 | LodePNG support for Visual Studio 6.0 is not guaranteed because VS6 doesn't
1464 | follow the C++ standard correctly.
1465 |
1466 | *) Comeau C/C++
1467 |
1468 | Vesion 20070107 compiles without problems on the Comeau C/C++ Online Test Drive
1469 | at http://www.comeaucomputing.com/tryitout in both C90 and C++ mode.
1470 |
1471 | *) Compilers on Macintosh
1472 |
1473 | LodePNG has been reported to work both with the gcc and LLVM for Macintosh, both
1474 | for C and C++.
1475 |
1476 | *) Other Compilers
1477 |
1478 | If you encounter problems on other compilers, feel free to let me know and I may
1479 | try to fix it if the compiler is modern standards complient.
1480 |
1481 |
1482 | 10. examples
1483 | ------------
1484 |
1485 | This decoder example shows the most basic usage of LodePNG. More complex
1486 | examples can be found on the LodePNG website.
1487 |
1488 | 10.1. decoder C++ example
1489 | -------------------------
1490 |
1491 | #include "lodepng.h"
1492 | #include
1493 |
1494 | int main(int argc, char *argv[])
1495 | {
1496 | const char* filename = argc > 1 ? argv[1] : "test.png";
1497 |
1498 | //load and decode
1499 | std::vector image;
1500 | unsigned width, height;
1501 | unsigned error = lodepng::decode(image, width, height, filename);
1502 |
1503 | //if there's an error, display it
1504 | if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
1505 |
1506 | //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ...
1507 | }
1508 |
1509 | 10.2. decoder C example
1510 | -----------------------
1511 |
1512 | #include "lodepng.h"
1513 |
1514 | int main(int argc, char *argv[])
1515 | {
1516 | unsigned error;
1517 | unsigned char* image;
1518 | size_t width, height;
1519 | const char* filename = argc > 1 ? argv[1] : "test.png";
1520 |
1521 | error = lodepng_decode32_file(&image, &width, &height, filename);
1522 |
1523 | if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error));
1524 |
1525 | / * use image here * /
1526 |
1527 | free(image);
1528 | return 0;
1529 | }
1530 |
1531 |
1532 | 11. changes
1533 | -----------
1534 |
1535 | The version number of LodePNG is the date of the change given in the format
1536 | yyyymmdd.
1537 |
1538 | Some changes aren't backwards compatible. Those are indicated with a (!)
1539 | symbol.
1540 |
1541 | *) 28 jan 2013: Bugfix with color key.
1542 | *) 27 okt 2012: Tweaks in text chunk keyword length error handling.
1543 | *) 8 okt 2012 (!): Added new filter strategy (entropy) and new auto color mode.
1544 | (no palette). Better deflate tree encoding. New compression tweak settings.
1545 | Faster color conversions while decoding. Some internal cleanups.
1546 | *) 23 sep 2012: Reduced warnings in Visual Studio a little bit.
1547 | *) 1 sep 2012 (!): Removed #define's for giving custom (de)compression functions
1548 | and made it work with function pointers instead.
1549 | *) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc
1550 | and free functions and toggle #defines from compiler flags. Small fixes.
1551 | *) 6 may 2012 (!): Made plugging in custom zlib/deflate functions more flexible.
1552 | *) 22 apr 2012 (!): Made interface more consistent, renaming a lot. Removed
1553 | redundant C++ codec classes. Reduced amount of structs. Everything changed,
1554 | but it is cleaner now imho and functionality remains the same. Also fixed
1555 | several bugs and shrinked the implementation code. Made new samples.
1556 | *) 6 nov 2011 (!): By default, the encoder now automatically chooses the best
1557 | PNG color model and bit depth, based on the amount and type of colors of the
1558 | raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color.
1559 | *) 9 okt 2011: simpler hash chain implementation for the encoder.
1560 | *) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching.
1561 | *) 23 aug 2011: tweaked the zlib compression parameters after benchmarking.
1562 | A bug with the PNG filtertype heuristic was fixed, so that it chooses much
1563 | better ones (it's quite significant). A setting to do an experimental, slow,
1564 | brute force search for PNG filter types is added.
1565 | *) 17 aug 2011 (!): changed some C zlib related function names.
1566 | *) 16 aug 2011: made the code less wide (max 120 characters per line).
1567 | *) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors.
1568 | *) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled.
1569 | *) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman
1570 | to optimize long sequences of zeros.
1571 | *) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and
1572 | LodePNG_InfoColor_canHaveAlpha functions for convenience.
1573 | *) 7 nov 2010: added LodePNG_error_text function to get error code description.
1574 | *) 30 okt 2010: made decoding slightly faster
1575 | *) 26 okt 2010: (!) changed some C function and struct names (more consistent).
1576 | Reorganized the documentation and the declaration order in the header.
1577 | *) 08 aug 2010: only changed some comments and external samples.
1578 | *) 05 jul 2010: fixed bug thanks to warnings in the new gcc version.
1579 | *) 14 mar 2010: fixed bug where too much memory was allocated for char buffers.
1580 | *) 02 sep 2008: fixed bug where it could create empty tree that linux apps could
1581 | read by ignoring the problem but windows apps couldn't.
1582 | *) 06 jun 2008: added more error checks for out of memory cases.
1583 | *) 26 apr 2008: added a few more checks here and there to ensure more safety.
1584 | *) 06 mar 2008: crash with encoding of strings fixed
1585 | *) 02 feb 2008: support for international text chunks added (iTXt)
1586 | *) 23 jan 2008: small cleanups, and #defines to divide code in sections
1587 | *) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor.
1588 | *) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder.
1589 | *) 17 jan 2008: ability to encode and decode compressed zTXt chunks added
1590 | Also vareous fixes, such as in the deflate and the padding bits code.
1591 | *) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved
1592 | filtering code of encoder.
1593 | *) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A
1594 | C++ wrapper around this provides an interface almost identical to before.
1595 | Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code
1596 | are together in these files but it works both for C and C++ compilers.
1597 | *) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks
1598 | *) 30 aug 2007: bug fixed which makes this Borland C++ compatible
1599 | *) 09 aug 2007: some VS2005 warnings removed again
1600 | *) 21 jul 2007: deflate code placed in new namespace separate from zlib code
1601 | *) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images
1602 | *) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing
1603 | invalid std::vector element [0] fixed, and level 3 and 4 warnings removed
1604 | *) 02 jun 2007: made the encoder add a tag with version by default
1605 | *) 27 may 2007: zlib and png code separated (but still in the same file),
1606 | simple encoder/decoder functions added for more simple usage cases
1607 | *) 19 may 2007: minor fixes, some code cleaning, new error added (error 69),
1608 | moved some examples from here to lodepng_examples.cpp
1609 | *) 12 may 2007: palette decoding bug fixed
1610 | *) 24 apr 2007: changed the license from BSD to the zlib license
1611 | *) 11 mar 2007: very simple addition: ability to encode bKGD chunks.
1612 | *) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding
1613 | palettized PNG images. Plus little interface change with palette and texts.
1614 | *) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes.
1615 | Fixed a bug where the end code of a block had length 0 in the Huffman tree.
1616 | *) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented
1617 | and supported by the encoder, resulting in smaller PNGs at the output.
1618 | *) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone.
1619 | *) 24 jan 2007: gave encoder an error interface. Added color conversion from any
1620 | greyscale type to 8-bit greyscale with or without alpha.
1621 | *) 21 jan 2007: (!) Totally changed the interface. It allows more color types
1622 | to convert to and is more uniform. See the manual for how it works now.
1623 | *) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days:
1624 | encode/decode custom tEXt chunks, separate classes for zlib & deflate, and
1625 | at last made the decoder give errors for incorrect Adler32 or Crc.
1626 | *) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel.
1627 | *) 29 dec 2006: Added support for encoding images without alpha channel, and
1628 | cleaned out code as well as making certain parts faster.
1629 | *) 28 dec 2006: Added "Settings" to the encoder.
1630 | *) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now.
1631 | Removed some code duplication in the decoder. Fixed little bug in an example.
1632 | *) 09 dec 2006: (!) Placed output parameters of public functions as first parameter.
1633 | Fixed a bug of the decoder with 16-bit per color.
1634 | *) 15 okt 2006: Changed documentation structure
1635 | *) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the
1636 | given image buffer, however for now it's not compressed.
1637 | *) 08 sep 2006: (!) Changed to interface with a Decoder class
1638 | *) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different
1639 | way. Renamed decodePNG to decodePNGGeneric.
1640 | *) 29 jul 2006: (!) Changed the interface: image info is now returned as a
1641 | struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy.
1642 | *) 28 jul 2006: Cleaned the code and added new error checks.
1643 | Corrected terminology "deflate" into "inflate".
1644 | *) 23 jun 2006: Added SDL example in the documentation in the header, this
1645 | example allows easy debugging by displaying the PNG and its transparency.
1646 | *) 22 jun 2006: (!) Changed way to obtain error value. Added
1647 | loadFile function for convenience. Made decodePNG32 faster.
1648 | *) 21 jun 2006: (!) Changed type of info vector to unsigned.
1649 | Changed position of palette in info vector. Fixed an important bug that
1650 | happened on PNGs with an uncompressed block.
1651 | *) 16 jun 2006: Internally changed unsigned into unsigned where
1652 | needed, and performed some optimizations.
1653 | *) 07 jun 2006: (!) Renamed functions to decodePNG and placed them
1654 | in LodePNG namespace. Changed the order of the parameters. Rewrote the
1655 | documentation in the header. Renamed files to lodepng.cpp and lodepng.h
1656 | *) 22 apr 2006: Optimized and improved some code
1657 | *) 07 sep 2005: (!) Changed to std::vector interface
1658 | *) 12 aug 2005: Initial release (C++, decoder only)
1659 |
1660 |
1661 | 12. contact information
1662 | -----------------------
1663 |
1664 | Feel free to contact me with suggestions, problems, comments, ... concerning
1665 | LodePNG. If you encounter a PNG image that doesn't work properly with this
1666 | decoder, feel free to send it and I'll use it to find and fix the problem.
1667 |
1668 | My email address is (puzzle the account and domain together with an @ symbol):
1669 | Domain: gmail dot com.
1670 | Account: lode dot vandevenne.
1671 |
1672 |
1673 | Copyright (c) 2005-2012 Lode Vandevenne
1674 | */
1675 |
--------------------------------------------------------------------------------
/src/pngwriter.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nesteruk/ImageGenerator/51534b8280f5aaea013c92d86eabd39023bf2a36/src/pngwriter.h
--------------------------------------------------------------------------------
/src/stdafx.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 |
--------------------------------------------------------------------------------
/src/stdafx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define _USE_MATH_DEFINES
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | using namespace std;
15 | using namespace chrono;
16 |
17 | // M_PI... not on GCC, apparently
18 | #ifndef M_PI
19 | constexpr auto M_PI = 3.14159265358979323846;
20 | #endif
21 |
22 | #include "lodepng.h"
23 |
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | //#include
32 | #include
33 | #include
34 | using namespace boost::accumulators;
35 | using namespace boost::math;
36 |
37 | #ifdef USEMKL
38 | #include
39 | #endif
40 | #include
41 | //#include
--------------------------------------------------------------------------------