diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox
index 7e469bf978..9833f556cc 100644
--- a/doc/dox/examples_and_tutorials.dox
+++ b/doc/dox/examples_and_tutorials.dox
@@ -101,6 +101,9 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
\image html imageplot_userpal_small.png
+ | \subpage JKQTPlotterImagePlotUserPalette
+ | `JKQTPColumnMathImage` user-defines palettes palettes from files
diff --git a/doc/dox/jkqtplotter.dox b/doc/dox/jkqtplotter.dox
index 13bd5e12b3..7e6da375e1 100644
--- a/doc/dox/jkqtplotter.dox
+++ b/doc/dox/jkqtplotter.dox
@@ -509,6 +509,9 @@ Examples:
\defgroup jkqtplotter_imagelots_tools Tool Functions & Classes for Image Drawing
\ingroup jkqtplotter_imagelots
+\defgroup jkqtplotter_imagelots_tools_LUTS Tool Functions to Build Lookup-Tables for Palettes
+\ingroup jkqtplotter_imagelots_tools
+
\defgroup jkqtplotter_imagelots_contour Contour Graphs (based on Image Data)
\ingroup jkqtplotter_imagelots
diff --git a/doc/images/JKQTPBuildColorPaletteLUTLinInterpolateSorted.cdr b/doc/images/JKQTPBuildColorPaletteLUTLinInterpolateSorted.cdr
new file mode 100644
index 0000000000..9140d9b51b
Binary files /dev/null and b/doc/images/JKQTPBuildColorPaletteLUTLinInterpolateSorted.cdr differ
diff --git a/doc/images/JKQTPBuildColorPaletteLUTLinInterpolateSorted.png b/doc/images/JKQTPBuildColorPaletteLUTLinInterpolateSorted.png
new file mode 100644
index 0000000000..bc2f789764
Binary files /dev/null and b/doc/images/JKQTPBuildColorPaletteLUTLinInterpolateSorted.png differ
diff --git a/doc/images/JKQTPBuildColorPaletteLUTSorted.cdr b/doc/images/JKQTPBuildColorPaletteLUTSorted.cdr
new file mode 100644
index 0000000000..83d63ce13a
Binary files /dev/null and b/doc/images/JKQTPBuildColorPaletteLUTSorted.cdr differ
diff --git a/doc/images/JKQTPBuildColorPaletteLUTSorted.png b/doc/images/JKQTPBuildColorPaletteLUTSorted.png
new file mode 100644
index 0000000000..2226bb1bf1
Binary files /dev/null and b/doc/images/JKQTPBuildColorPaletteLUTSorted.png differ
diff --git a/doc/images/palettes/palette_AFMhot.png b/doc/images/palettes/palette_AFMhot.png
index 0c63628b6f..1327a419ed 100644
Binary files a/doc/images/palettes/palette_AFMhot.png and b/doc/images/palettes/palette_AFMhot.png differ
diff --git a/doc/images/palettes/palette_BBlRdYe.png b/doc/images/palettes/palette_BBlRdYe.png
index 9462369a5c..35568d166e 100644
Binary files a/doc/images/palettes/palette_BBlRdYe.png and b/doc/images/palettes/palette_BBlRdYe.png differ
diff --git a/doc/images/palettes/palette_BWprint.png b/doc/images/palettes/palette_BWprint.png
index 2084a9e142..2962563fa8 100644
Binary files a/doc/images/palettes/palette_BWprint.png and b/doc/images/palettes/palette_BWprint.png differ
diff --git a/doc/images/palettes/palette_BlMaYe.png b/doc/images/palettes/palette_BlMaYe.png
index 83669e8ac2..c412ff18cf 100644
Binary files a/doc/images/palettes/palette_BlMaYe.png and b/doc/images/palettes/palette_BlMaYe.png differ
diff --git a/doc/images/palettes/palette_BlYe.png b/doc/images/palettes/palette_BlYe.png
index 9a5bacbfc3..e7ca107e5e 100644
Binary files a/doc/images/palettes/palette_BlYe.png and b/doc/images/palettes/palette_BlYe.png differ
diff --git a/doc/images/palettes/palette_BrBG.png b/doc/images/palettes/palette_BrBG.png
index 28bdcabd6f..1f336e7f1d 100644
Binary files a/doc/images/palettes/palette_BrBG.png and b/doc/images/palettes/palette_BrBG.png differ
diff --git a/doc/images/palettes/palette_GnRdVi.png b/doc/images/palettes/palette_GnRdVi.png
index c7544dfbed..873e0f04d8 100644
Binary files a/doc/images/palettes/palette_GnRdVi.png and b/doc/images/palettes/palette_GnRdVi.png differ
diff --git a/doc/images/palettes/palette_HSV.png b/doc/images/palettes/palette_HSV.png
index ae4949af4d..6a5c658325 100644
Binary files a/doc/images/palettes/palette_HSV.png and b/doc/images/palettes/palette_HSV.png differ
diff --git a/doc/images/palettes/palette_Matlab.png b/doc/images/palettes/palette_Matlab.png
index ac8f0a1050..f3bc790d33 100644
Binary files a/doc/images/palettes/palette_Matlab.png and b/doc/images/palettes/palette_Matlab.png differ
diff --git a/doc/images/palettes/palette_PuOr.png b/doc/images/palettes/palette_PuOr.png
index fabbe8223e..e6ef70e175 100644
Binary files a/doc/images/palettes/palette_PuOr.png and b/doc/images/palettes/palette_PuOr.png differ
diff --git a/doc/images/palettes/palette_RYGB.png b/doc/images/palettes/palette_RYGB.png
index 0eeb5733a0..3673599344 100644
Binary files a/doc/images/palettes/palette_RYGB.png and b/doc/images/palettes/palette_RYGB.png differ
diff --git a/doc/images/palettes/palette_YeBl.png b/doc/images/palettes/palette_YeBl.png
index bb403263a3..9d8f0e7df8 100644
Binary files a/doc/images/palettes/palette_YeBl.png and b/doc/images/palettes/palette_YeBl.png differ
diff --git a/doc/images/palettes/palette_YeGnBu.png b/doc/images/palettes/palette_YeGnBu.png
index 88cde329e2..2b97c32d09 100644
Binary files a/doc/images/palettes/palette_YeGnBu.png and b/doc/images/palettes/palette_YeGnBu.png differ
diff --git a/doc/images/palettes/palette_YeMaBl.png b/doc/images/palettes/palette_YeMaBl.png
index 03ac3ac7e4..66e45567c3 100644
Binary files a/doc/images/palettes/palette_YeMaBl.png and b/doc/images/palettes/palette_YeMaBl.png differ
diff --git a/doc/images/palettes/palette_autumn.png b/doc/images/palettes/palette_autumn.png
new file mode 100644
index 0000000000..303cf7ee84
Binary files /dev/null and b/doc/images/palettes/palette_autumn.png differ
diff --git a/doc/images/palettes/palette_blue.png b/doc/images/palettes/palette_blue.png
index 80be8563af..36a96c2ff0 100644
Binary files a/doc/images/palettes/palette_blue.png and b/doc/images/palettes/palette_blue.png differ
diff --git a/doc/images/palettes/palette_bluegreen.png b/doc/images/palettes/palette_bluegreen.png
index 5d5c6297c4..e621b72771 100644
Binary files a/doc/images/palettes/palette_bluegreen.png and b/doc/images/palettes/palette_bluegreen.png differ
diff --git a/doc/images/palettes/palette_bluegreenred.png b/doc/images/palettes/palette_bluegreenred.png
index 48b69565ee..f13e1af413 100644
Binary files a/doc/images/palettes/palette_bluegreenred.png and b/doc/images/palettes/palette_bluegreenred.png differ
diff --git a/doc/images/palettes/palette_bluered.png b/doc/images/palettes/palette_bluered.png
index 2a61656668..5c15976b6c 100644
Binary files a/doc/images/palettes/palette_bluered.png and b/doc/images/palettes/palette_bluered.png differ
diff --git a/doc/images/palettes/palette_bluewhitered.png b/doc/images/palettes/palette_bluewhitered.png
index 8080489bd6..e2b203f49a 100644
Binary files a/doc/images/palettes/palette_bluewhitered.png and b/doc/images/palettes/palette_bluewhitered.png differ
diff --git a/doc/images/palettes/palette_bone.png b/doc/images/palettes/palette_bone.png
new file mode 100644
index 0000000000..d38ba08744
Binary files /dev/null and b/doc/images/palettes/palette_bone.png differ
diff --git a/doc/images/palettes/palette_cool.png b/doc/images/palettes/palette_cool.png
new file mode 100644
index 0000000000..efd59a46e1
Binary files /dev/null and b/doc/images/palettes/palette_cool.png differ
diff --git a/doc/images/palettes/palette_copper.png b/doc/images/palettes/palette_copper.png
new file mode 100644
index 0000000000..f48153583d
Binary files /dev/null and b/doc/images/palettes/palette_copper.png differ
diff --git a/doc/images/palettes/palette_cyan.png b/doc/images/palettes/palette_cyan.png
index 3818cbefeb..04db7f9086 100644
Binary files a/doc/images/palettes/palette_cyan.png and b/doc/images/palettes/palette_cyan.png differ
diff --git a/doc/images/palettes/palette_cyanwhite.png b/doc/images/palettes/palette_cyanwhite.png
index 5343f05849..cef90025e2 100644
Binary files a/doc/images/palettes/palette_cyanwhite.png and b/doc/images/palettes/palette_cyanwhite.png differ
diff --git a/doc/images/palettes/palette_gray.png b/doc/images/palettes/palette_gray.png
index 0b879e6261..1b988b46e9 100644
Binary files a/doc/images/palettes/palette_gray.png and b/doc/images/palettes/palette_gray.png differ
diff --git a/doc/images/palettes/palette_green.png b/doc/images/palettes/palette_green.png
index cdb490c032..735b484493 100644
Binary files a/doc/images/palettes/palette_green.png and b/doc/images/palettes/palette_green.png differ
diff --git a/doc/images/palettes/palette_greenblue.png b/doc/images/palettes/palette_greenblue.png
index 4b16f64395..66ee04637f 100644
Binary files a/doc/images/palettes/palette_greenblue.png and b/doc/images/palettes/palette_greenblue.png differ
diff --git a/doc/images/palettes/palette_inferno.png b/doc/images/palettes/palette_inferno.png
new file mode 100644
index 0000000000..5b8165a8d1
Binary files /dev/null and b/doc/images/palettes/palette_inferno.png differ
diff --git a/doc/images/palettes/palette_invAFMhot.png b/doc/images/palettes/palette_invAFMhot.png
index 1e354b5264..e8e9ec19c8 100644
Binary files a/doc/images/palettes/palette_invAFMhot.png and b/doc/images/palettes/palette_invAFMhot.png differ
diff --git a/doc/images/palettes/palette_invBWprint.png b/doc/images/palettes/palette_invBWprint.png
index f39da8253d..279344670f 100644
Binary files a/doc/images/palettes/palette_invBWprint.png and b/doc/images/palettes/palette_invBWprint.png differ
diff --git a/doc/images/palettes/palette_invHSV.png b/doc/images/palettes/palette_invHSV.png
index e2dc3de763..9a261e7b6b 100644
Binary files a/doc/images/palettes/palette_invHSV.png and b/doc/images/palettes/palette_invHSV.png differ
diff --git a/doc/images/palettes/palette_invMatlab.png b/doc/images/palettes/palette_invMatlab.png
index 4e284646b9..ffbd573b31 100644
Binary files a/doc/images/palettes/palette_invMatlab.png and b/doc/images/palettes/palette_invMatlab.png differ
diff --git a/doc/images/palettes/palette_invRYGB.png b/doc/images/palettes/palette_invRYGB.png
index edf40c0fc7..e8b7ad1414 100644
Binary files a/doc/images/palettes/palette_invRYGB.png and b/doc/images/palettes/palette_invRYGB.png differ
diff --git a/doc/images/palettes/palette_invblue.png b/doc/images/palettes/palette_invblue.png
index 9deb7aca62..92029607c0 100644
Binary files a/doc/images/palettes/palette_invblue.png and b/doc/images/palettes/palette_invblue.png differ
diff --git a/doc/images/palettes/palette_invcyan.png b/doc/images/palettes/palette_invcyan.png
index f81793a2ee..608a9eff4a 100644
Binary files a/doc/images/palettes/palette_invcyan.png and b/doc/images/palettes/palette_invcyan.png differ
diff --git a/doc/images/palettes/palette_invgray.png b/doc/images/palettes/palette_invgray.png
index 1eef8e4982..686289367d 100644
Binary files a/doc/images/palettes/palette_invgray.png and b/doc/images/palettes/palette_invgray.png differ
diff --git a/doc/images/palettes/palette_invgreen.png b/doc/images/palettes/palette_invgreen.png
index 4f88ae48c8..0b01e5bc71 100644
Binary files a/doc/images/palettes/palette_invgreen.png and b/doc/images/palettes/palette_invgreen.png differ
diff --git a/doc/images/palettes/palette_invmagenta.png b/doc/images/palettes/palette_invmagenta.png
index f4345eb51b..67950d8b2f 100644
Binary files a/doc/images/palettes/palette_invmagenta.png and b/doc/images/palettes/palette_invmagenta.png differ
diff --git a/doc/images/palettes/palette_invocean.png b/doc/images/palettes/palette_invocean.png
index c53238236b..5d4889f937 100644
Binary files a/doc/images/palettes/palette_invocean.png and b/doc/images/palettes/palette_invocean.png differ
diff --git a/doc/images/palettes/palette_invrainbow.png b/doc/images/palettes/palette_invrainbow.png
index 4e2cb123d5..3d8b79669b 100644
Binary files a/doc/images/palettes/palette_invrainbow.png and b/doc/images/palettes/palette_invrainbow.png differ
diff --git a/doc/images/palettes/palette_invred.png b/doc/images/palettes/palette_invred.png
index 62287a59c1..a7b9f050b6 100644
Binary files a/doc/images/palettes/palette_invred.png and b/doc/images/palettes/palette_invred.png differ
diff --git a/doc/images/palettes/palette_invtrafficlight.png b/doc/images/palettes/palette_invtrafficlight.png
index ca438c2c20..af7a5d959e 100644
Binary files a/doc/images/palettes/palette_invtrafficlight.png and b/doc/images/palettes/palette_invtrafficlight.png differ
diff --git a/doc/images/palettes/palette_invyellow.png b/doc/images/palettes/palette_invyellow.png
index 99abeef587..5a25749a34 100644
Binary files a/doc/images/palettes/palette_invyellow.png and b/doc/images/palettes/palette_invyellow.png differ
diff --git a/doc/images/palettes/palette_magenta.png b/doc/images/palettes/palette_magenta.png
index 91d82e7e08..56051700da 100644
Binary files a/doc/images/palettes/palette_magenta.png and b/doc/images/palettes/palette_magenta.png differ
diff --git a/doc/images/palettes/palette_magentawhite.png b/doc/images/palettes/palette_magentawhite.png
index 85ee8cafe3..6119bda174 100644
Binary files a/doc/images/palettes/palette_magentawhite.png and b/doc/images/palettes/palette_magentawhite.png differ
diff --git a/doc/images/palettes/palette_magentayellow.png b/doc/images/palettes/palette_magentayellow.png
index 779a7ceca8..32446dc95a 100644
Binary files a/doc/images/palettes/palette_magentayellow.png and b/doc/images/palettes/palette_magentayellow.png differ
diff --git a/doc/images/palettes/palette_magma.png b/doc/images/palettes/palette_magma.png
new file mode 100644
index 0000000000..1c96eb9c6c
Binary files /dev/null and b/doc/images/palettes/palette_magma.png differ
diff --git a/doc/images/palettes/palette_ocean.png b/doc/images/palettes/palette_ocean.png
index 89c8ff64b8..060c35caf5 100644
Binary files a/doc/images/palettes/palette_ocean.png and b/doc/images/palettes/palette_ocean.png differ
diff --git a/doc/images/palettes/palette_plasma.png b/doc/images/palettes/palette_plasma.png
new file mode 100644
index 0000000000..447592112e
Binary files /dev/null and b/doc/images/palettes/palette_plasma.png differ
diff --git a/doc/images/palettes/palette_rainbow.png b/doc/images/palettes/palette_rainbow.png
index cc87320b82..5d9b9887db 100644
Binary files a/doc/images/palettes/palette_rainbow.png and b/doc/images/palettes/palette_rainbow.png differ
diff --git a/doc/images/palettes/palette_red.png b/doc/images/palettes/palette_red.png
index ba8fc16253..c1ec3a1a80 100644
Binary files a/doc/images/palettes/palette_red.png and b/doc/images/palettes/palette_red.png differ
diff --git a/doc/images/palettes/palette_redblue.png b/doc/images/palettes/palette_redblue.png
index 4bcbbc12f6..02c37f05f3 100644
Binary files a/doc/images/palettes/palette_redblue.png and b/doc/images/palettes/palette_redblue.png differ
diff --git a/doc/images/palettes/palette_redgreenblue.png b/doc/images/palettes/palette_redgreenblue.png
index 8247d4ef42..6846bcedc2 100644
Binary files a/doc/images/palettes/palette_redgreenblue.png and b/doc/images/palettes/palette_redgreenblue.png differ
diff --git a/doc/images/palettes/palette_redwhiteblue.png b/doc/images/palettes/palette_redwhiteblue.png
index bfcfb433fe..2ee2abafaf 100644
Binary files a/doc/images/palettes/palette_redwhiteblue.png and b/doc/images/palettes/palette_redwhiteblue.png differ
diff --git a/doc/images/palettes/palette_seismic.png b/doc/images/palettes/palette_seismic.png
new file mode 100644
index 0000000000..4cffa0be98
Binary files /dev/null and b/doc/images/palettes/palette_seismic.png differ
diff --git a/doc/images/palettes/palette_stepsBlGn.png b/doc/images/palettes/palette_stepsBlGn.png
index 22a2ef764c..3d06760191 100644
Binary files a/doc/images/palettes/palette_stepsBlGn.png and b/doc/images/palettes/palette_stepsBlGn.png differ
diff --git a/doc/images/palettes/palette_stepsBrBG.png b/doc/images/palettes/palette_stepsBrBG.png
index 55783cbbc5..a4c07f3971 100644
Binary files a/doc/images/palettes/palette_stepsBrBG.png and b/doc/images/palettes/palette_stepsBrBG.png differ
diff --git a/doc/images/palettes/palette_stepsGnBl.png b/doc/images/palettes/palette_stepsGnBl.png
index 0fdee278a1..6b2fdd8e30 100644
Binary files a/doc/images/palettes/palette_stepsGnBl.png and b/doc/images/palettes/palette_stepsGnBl.png differ
diff --git a/doc/images/palettes/palette_stepsPuOr.png b/doc/images/palettes/palette_stepsPuOr.png
index face322f03..0d84f84abf 100644
Binary files a/doc/images/palettes/palette_stepsPuOr.png and b/doc/images/palettes/palette_stepsPuOr.png differ
diff --git a/doc/images/palettes/palette_stepsYeGnBu.png b/doc/images/palettes/palette_stepsYeGnBu.png
index c66a0b03c2..0b7cb565af 100644
Binary files a/doc/images/palettes/palette_stepsYeGnBu.png and b/doc/images/palettes/palette_stepsYeGnBu.png differ
diff --git a/doc/images/palettes/palette_terrain.png b/doc/images/palettes/palette_terrain.png
new file mode 100644
index 0000000000..feb0ba208a
Binary files /dev/null and b/doc/images/palettes/palette_terrain.png differ
diff --git a/doc/images/palettes/palette_trafficlight.png b/doc/images/palettes/palette_trafficlight.png
index d8c22214d9..3341d04873 100644
Binary files a/doc/images/palettes/palette_trafficlight.png and b/doc/images/palettes/palette_trafficlight.png differ
diff --git a/doc/images/palettes/palette_viridis.png b/doc/images/palettes/palette_viridis.png
new file mode 100644
index 0000000000..7ea45f5adc
Binary files /dev/null and b/doc/images/palettes/palette_viridis.png differ
diff --git a/doc/images/palettes/palette_whitecyan.png b/doc/images/palettes/palette_whitecyan.png
index 584aee50f0..ed1a56a291 100644
Binary files a/doc/images/palettes/palette_whitecyan.png and b/doc/images/palettes/palette_whitecyan.png differ
diff --git a/doc/images/palettes/palette_whitemagenta.png b/doc/images/palettes/palette_whitemagenta.png
index 7906b06105..8f4ffefff5 100644
Binary files a/doc/images/palettes/palette_whitemagenta.png and b/doc/images/palettes/palette_whitemagenta.png differ
diff --git a/doc/images/palettes/palette_whiteyellow.png b/doc/images/palettes/palette_whiteyellow.png
index 6710920bbc..6619d5e83f 100644
Binary files a/doc/images/palettes/palette_whiteyellow.png and b/doc/images/palettes/palette_whiteyellow.png differ
diff --git a/doc/images/palettes/palette_yellow.png b/doc/images/palettes/palette_yellow.png
index 2a73c69ce1..cfc3966264 100644
Binary files a/doc/images/palettes/palette_yellow.png and b/doc/images/palettes/palette_yellow.png differ
diff --git a/doc/images/palettes/palette_yellowmagenta.png b/doc/images/palettes/palette_yellowmagenta.png
index 97f4923238..0cb0cee2c9 100644
Binary files a/doc/images/palettes/palette_yellowmagenta.png and b/doc/images/palettes/palette_yellowmagenta.png differ
diff --git a/doc/images/palettes/palette_yellowwhite.png b/doc/images/palettes/palette_yellowwhite.png
index 364174f8ea..df09f46e17 100644
Binary files a/doc/images/palettes/palette_yellowwhite.png and b/doc/images/palettes/palette_yellowwhite.png differ
diff --git a/doc/template_verbatimgraph.txt b/doc/template_verbatimgraph.txt
new file mode 100644
index 0000000000..36ec0b49fd
--- /dev/null
+++ b/doc/template_verbatimgraph.txt
@@ -0,0 +1,19 @@
+ \verbatim
+ colval
+ ^
+ |
+ 250 -
+ |
+ 200 -
+ |
+ 150 -
+ |
+ 100 -
+ |
+ 50 -
+ |
+ 0 -
+ |
+ ---|----|----|----|----|----|----|----|----|----|----|--> position
+ 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
+ \endverbatim
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 7223e7c7db..1e1c9adbf0 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -29,6 +29,7 @@ add_subdirectory(filledgraphs)
add_subdirectory(functionplot)
add_subdirectory(geometric)
add_subdirectory(imageplot)
+add_subdirectory(imageplot_userpal)
add_subdirectory(imageplot_modifier)
add_subdirectory(imageplot_nodatastore)
add_subdirectory(imageplot_opencv)
diff --git a/examples/README.md b/examples/README.md
index 47408179b2..9bbc0b546c 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -42,6 +42,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|:-------------:| ------------- | ------------- |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/rgbimageplot_qt_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/rgbimageplot_qt) | [`QImage` as a Graph](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/rgbimageplot_qt) | `JKQTPImage` `QImage` drawn onto a plot with arbitrary scaling inverted coordinate axes |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/imageplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot) | [Basic 1-channel Raw C Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot) | `JKQTPColumnMathImage` image data copied from C-style row-major array into a single column of the internal datastore Describes several options of the image plotting classes (different ways of color coding, what to do with data above/below the limits etc.) |
+| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/imageplot_userpal_program_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot_userpal) | [Image Plots with User-Defined Palettes](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot_userpal) | `JKQTPColumnMathImage` user-defines palettes palettes from files |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/imageplot_modifier_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot_modifier) | [Modifier-Feature of Image Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot_modifier) | `JKQTPColumnMathImage` image data copied from C-style row-major array into a single column of the internal datastore Image is modified by a second image to display two data dimensions at the same time |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/imageplot_nodatastore_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot_nodatastore) | [Basic 1-channel Raw C Image Plot without the internal datastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot_nodatastore) | `JKQTPMathImage` image data in a C-style row-major array, not using internal datastore |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/rgbimageplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/rgbimageplot) | [Simple 3-channel Math RGB/CMY Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/rgbimageplot) | `JKQTPColumnRGBMathImage` image data in a C-style row-major array, not using internal datastore RGB/CMY color compositing |
diff --git a/examples/imageplot_userpal/CMakeLists.txt b/examples/imageplot_userpal/CMakeLists.txt
new file mode 100644
index 0000000000..b5b800b322
--- /dev/null
+++ b/examples/imageplot_userpal/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 3.0)
+
+set(EXAMPLE_NAME imageplot_userpal)
+set(EXENAME jkqtptest_${EXAMPLE_NAME})
+
+message( STATUS ".. Building Example ${EXAMPLE_NAME}" )
+
+
+# Set up source files
+set(SOURCES ${EXAMPLE_NAME}.cpp)
+set(HEADERS )
+set(RESOURCES imageplot_userpal.qrc )
+set(UIS )
+
+add_executable(${EXENAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES} ${UIS})
+target_include_directories(${EXENAME} PRIVATE ../../lib)
+if(BUILD_STATIC_LIBS)
+ target_link_libraries(${EXENAME} JKQTPlotterLib)
+elseif(BUILD_SHARED_LIBS)
+ target_link_libraries(${EXENAME} JKQTPlotterSharedLib)
+endif()
+
+
+
+# Installation
+if(LIB_INSTALL)
+ install(TARGETS ${EXENAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+endif(LIB_INSTALL)
diff --git a/examples/imageplot_userpal/README.md b/examples/imageplot_userpal/README.md
new file mode 100644
index 0000000000..e724cd2daf
--- /dev/null
+++ b/examples/imageplot_userpal/README.md
@@ -0,0 +1,210 @@
+# Example (JKQTPlotter): Image Plots with Custom Palettes {#JKQTPlotterImagePlotUserPalette}
+
+This project (see `./examples/imageplot_userpal/`) demonstrates how to use user-defined color-palettes for image plots.
+The source code of the main application is (see [`imageplot_userpal.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot_userpal/imageplot_userpal.cpp)).
+
+# Build Palettes Programmatically
+
+JKQTPlotter comes with a large set of predefined color palettes, which are enumerated in `JKQTPMathImageColorPalette`.
+In addition you can build your own palettes as simple lookup-tables of type `JKQTPImageTools::LUTType` (which is a `QVector`) and register them in the system (using `JKQTPImageTools::registerPalette()`). There are several options available for building such a palette:
+1. you can simply define a palette from single colors:
+```.cpp
+ JKQTPImageTools::LUTType pal{
+ QColor("blue").rgb(),
+ QColor("green").rgb(),
+ QColor("white").rgb(),
+ QColor("yellow").rgb(),
+ QColor("red").rgb(),
+ QColor("red").rgb()
+ };
+```
+ Such a palette will have exactly as many entries, as you specified: ![palsimple](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/imageplot_userpal_palsimple.png)
+2. Alternatively you can build a palette from a set of colors with assocziated positions on the values axis (typically 0..1 as these are in any way later mapped to the actual data range):
+```.cpp
+ QList > palsteps2;
+ palsteps2<(0.00, QColor("blue").rgba());
+ palsteps2<(0.05, QColor("green").rgba());
+ palsteps2<(0.45, QColor("white").rgba());
+ palsteps2<(0.55, QColor("yellow").rgba());
+ palsteps2<(0.95, QColor("red").rgba());
+ palsteps2<(1.00, QColor("red").rgba());
+
+ pal=JKQTPBuildColorPaletteLUT(palsteps2, JKQTPImageTools::LUTSIZE);
+```
+ Such a palette will have `JKQTPImageTools::LUTSIZE (=255)` entries and the colors are not spaced equally: ![palsteps2](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/imageplot_userpal_palsteps2.png)
+3. The palettes so far had steps, but you can also give a series of nodes with positions (on the value axis) and RGB-colors there (e.g. `palsteps2` above) but then linearly interpolate between these by calling:
+```.cpp
+ pal=JKQTPBuildColorPaletteLUTLinInterpolate(palsteps2, JKQTPImageTools::LUTSIZE);
+```
+ The resulting LUT is then: ![imageplot_userpal_2_linear](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/imageplot_userpal_2_linear.png)
+4. Finally there is a second way of linear interpolation, where linear segments are given for the three color channels separately. To use such a definition, call `JKQTPBuildColorPaletteLUTLinSegments` instead (see documenttaion there).
+
+For each of these options, you finally call `JKQTPImageTools::registerPalette()` to make them known to the system:
+```.cpp
+ int userpalette_id=JKQTPImageTools::registerPalette("userpal_computer_readable_name", pal, QObject::tr("User Palette Human-Readable Name"));
+```
+This function returns an integer, which you can cast to a `JKQTPMathImageColorPalette` to use your new palette:
+```.cpp
+ JKQTPColumnMathImage* graph=new JKQTPColumnMathImage(plot);
+ // ...
+ graph->setPalette(static_cast(userpalette_id));
+```
+
+# Load Palettes from Files
+
+In addition to building palettes/LUTs programmatically, as shown above, you can simply load palettes from files using:
+```.cpp
+ JKQTPImageTools::registerPalettesFromFile(":/usercolorpalettes/palettes/All_idl_cmaps.xml");
+```
+
+This function may load different file formats (discriminated by the extension):
+1. XML-files (extension `.xml`) may contain one or more color palettes and should be formatted as follows:
+```.xml
+
+
+
+ ...
+
+```
+ or with several palettes in one file:
+```.xml
+
+
+
+
+ ...
+
+
+
+
+ ...
+
+ ...
+
+```
+
+2. CSV-files (extensions `.csv`, `.rgb`, `.pal`) are simply a list of 3 or 4 comma-separated values:
+```
+ red, green, blue
+ red, green, blue
+ ...
+```
+ or:
+```
+ scalar, red, green, blue
+ scalar, red, green, blue
+ ...
+```
+
+By default the palettes are simply read from the files as raw data. Alternatively you can linearly interpolate between the nodes in the file by calling
+```.cpp
+ JKQTPImageTools::registerPalettesFromFile(":/usercolorpalettes/palettes/All_idl_cmaps.xml", true);
+```
+
+Examples for such palette files can be found here: [/examples/imageplot_userpal/palettes/](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot_userpal/palettes/)
+
+# Main Program of the Example (GUI)
+
+The rest of the example program [`imageplot_userpal.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/imageplot_userpal/imageplot_userpal.cpp) just generates a 2D function plot as a color-map and displays it ...
+```.cpp
+ // 1. create a window containing a plotter and a combobox to select the color palette
+ // ... and get a pointer to the internal datastore (for convenience)
+ QWidget win;
+ QVBoxLayout* lay=new QVBoxLayout();
+ win.setLayout(lay);
+ JKQTPMathImageColorPaletteComboBox* cmbPalette=new JKQTPMathImageColorPaletteComboBox(&win);
+ lay->addWidget(cmbPalette);
+ JKQTPlotter* plot=new JKQTPlotter(&win);
+ lay->addWidget(plot);
+ JKQTPDatastore* ds=plot->getDatastore();
+
+ // 2. now we create data for the charts (taken from https://commons.wikimedia.org/wiki/File:Energiemix_Deutschland.svg)
+ const int NX=100; // image dimension in x-direction [pixels]
+ const int NY=NX; // image dimension in x-direction [pixels]
+ const double dx=0.6e-2; // size of a pixel in x-direction [micrometers]
+ const double dy=0.6e-2; // size of a pixel in x-direction [micrometers]
+
+ // 2.1 Parameters for airy disk plot (see https://en.wikipedia.org/wiki/Airy_disk)
+ double NA=1.1; // numerical aperture of lens
+ double wavelength=488e-3; // wavelength of the light [micrometers]
+
+ // 2.2 calculate image of airy disk in a row-major array and immediately store the values
+ // in a new image column cAiryDisk
+ size_t cAiryDisk=ds->addCalculatedImageColumn(NX, NY, [&](size_t ix, size_t iy)->double {
+ double x=static_cast(static_cast(ix)-NX/2)*dx;
+ double y=static_cast(static_cast(iy)-NY/2)*dy;
+ const double r=sqrt(x*x+y*y);
+ const double v=2.0*M_PI*NA*r/wavelength;
+ if (ix==NX/2 && iy==NY/2) return 1.0;
+ else return pow(2.0*j1(v)/v, 2);
+ }, "imagedata");
+
+
+
+
+ // 3. create a graph (JKQTPColumnMathImage) with the column created above as data
+ // The data is color-coded with the color-palette JKQTPMathImageMATLAB
+ // the converted range of data is determined automatically because setAutoImageRange(true)
+ JKQTPColumnMathImage* graph=new JKQTPColumnMathImage(plot);
+ graph->setTitle("default MATLAB palette");
+ // set the image column with the data
+ graph->setImageColumn(cAiryDisk);
+ // where does the image start in the plot, given in plot-axis-coordinates (bottom-left corner)
+ graph->setX(0);
+ graph->setY(0);
+ // width and height of the image in plot-axis-coordinates
+ graph->setWidth(1);
+ graph->setHeight(1);
+ // color-map is taken from cmbPalette
+ plot->connect(cmbPalette, &JKQTPMathImageColorPaletteComboBox::currentPaletteChanged,[&](JKQTPMathImageColorPalette p) { graph->setPalette(p); plot->redrawPlot(); });
+ cmbPalette->setCurrentColorPalette(graph->getPalette());
+
+
+ // 4. add the graphs to the plot, so it is actually displayed
+ plot->addGraph(graph);
+
+
+ // 5. fix axis and plot aspect ratio to 1
+ plot->getPlotter()->setMaintainAspectRatio(true);
+ plot->getPlotter()->setMaintainAxisAspectRatio(true);
+
+ // 6. autoscale the plot so the graph is contained
+ plot->zoomToFit();
+
+
+ // 8. show plotter and make it a decent size
+ win.show();
+ win.resize(500,550);
+ win.setWindowTitle("JKQTPColumnMathImage, User Palettes");
+```
+...along with a `JKQTPMathImageColorPaletteComboBox` to select a colormap and redraw the plot:
+```.cpp
+ JKQTPMathImageColorPaletteComboBox* cmbPalette=new JKQTPMathImageColorPaletteComboBox(&win);
+ // ...
+ plot->connect(cmbPalette, &JKQTPMathImageColorPaletteComboBox::currentPaletteChanged,[&](JKQTPMathImageColorPalette p) { graph->setPalette(p); plot->redrawPlot(); });
+ cmbPalette->setCurrentColorPalette(graph->getPalette());
+```
+
+It also adds two `QPushButton`s that allow to save the current or all registered color-palettes to small PNG-Files:
+```.cpp
+ QPushButton* btnSavePal=new QPushButton(QObject::tr("save current palette"), &win);
+ btnSavePal->connect(btnSavePal, &QPushButton::clicked, [&]() {
+ auto img=JKQTPImageTools::GetPaletteImage(cmbPalette->currentColorPalette(), JKQTPImageTools::LUTSIZE, 16);
+ img.save(JKQTPImageTools::JKQTPMathImageColorPalette2String(cmbPalette->currentColorPalette())+".png");
+ });
+ lay->addWidget(btnSavePal);
+ QPushButton* btnSaveAllPal=new QPushButton(QObject::tr("save all palettes"), &win);
+ btnSavePal->connect(btnSaveAllPal, &QPushButton::clicked, [&]() {
+ for (auto pn: JKQTPImageTools::getPredefinedPalettes()) {
+ auto p=JKQTPImageTools::String2JKQTPMathImageColorPalette(pn);
+ auto img=JKQTPImageTools::GetPaletteImage(p, JKQTPImageTools::LUTSIZE, 16);
+ img.save("palette_"+JKQTPImageTools::JKQTPMathImageColorPalette2String(p)+".png");
+ }
+ });
+ lay->addWidget(btnSaveAllPal);
+```
+
+The whole program looks like this:
+
+![imageplot_userpal_program](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/imageplot_userpal_program.png)
+
diff --git a/examples/imageplot_userpal/imageplot_userpal.cpp b/examples/imageplot_userpal/imageplot_userpal.cpp
new file mode 100644
index 0000000000..b8c28b4ca0
--- /dev/null
+++ b/examples/imageplot_userpal/imageplot_userpal.cpp
@@ -0,0 +1,173 @@
+/** \example imageplot_userpal.cpp
+ * Shows how to plot colored math images/matrices with JKQTPlotter, using user-defined image palettes
+ *
+ * \ref JKQTPlotterImagePlot
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "jkqtplotter/jkqtplotter.h"
+#include "jkqtplotter/graphs/jkqtpimage.h"
+#include "jkqtplotter/gui/jkqtpcomboboxes.h"
+#include "jkqtcommon/jkqtpbasicimagetools.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+
+int main(int argc, char* argv[])
+{
+ QApplication app(argc, argv);
+
+ // 0. tell the library where to find additional palettes.
+ // this needs to be done BEFORE first using JKQTPlotter
+ // 0.1 first we want to build a user-defined palette with five colors
+ // from a simple list of these colors:
+ JKQTPImageTools::LUTType pal{
+ QColor("blue").rgb(),
+ QColor("green").rgb(),
+ QColor("white").rgb(),
+ QColor("yellow").rgb(),
+ QColor("red").rgb(),
+ QColor("red").rgb()
+ };
+ JKQTPImageTools::registerPalette("userpal_list", pal, QObject::tr("User Palette simple list"));
+
+ // 0.2 first we want to build a user-defined palette with five colors
+ // the function JKQTPBuildColorPaletteLUT builds a full-sized palette
+ // with steps from the given 5 colors.
+ // Note that you need to double the last color in order to define its range's
+ // beginning and end
+ QList > palsteps1;
+ palsteps1<(0.0, QColor("blue").rgba());
+ palsteps1<(0.2, QColor("green").rgba());
+ palsteps1<(0.4, QColor("white").rgba());
+ palsteps1<(0.6, QColor("yellow").rgba());
+ palsteps1<(0.8, QColor("red").rgba());
+ palsteps1<(1.0, QColor("red").rgba());
+ JKQTPImageTools::registerPalette("userpal_1_steps", JKQTPBuildColorPaletteLUT(palsteps1), QObject::tr("User Palette 1, steps"));
+
+
+ // With the double value (first argument), you can determine where the next color
+ // band starts, with respect to the other colors. As an example, we make the central
+ // white band narrow, as well as the bands at the borders:
+ QList > palsteps2;
+ palsteps2<(0.00, QColor("blue").rgba());
+ palsteps2<(0.05, QColor("green").rgba());
+ palsteps2<(0.45, QColor("white").rgba());
+ palsteps2<(0.55, QColor("yellow").rgba());
+ palsteps2<(0.95, QColor("red").rgba());
+ palsteps2<(1.00, QColor("red").rgba());
+ int userpalette_id=JKQTPImageTools::registerPalette("userpal_2_steps", JKQTPBuildColorPaletteLUT(palsteps2), QObject::tr("User Palette 2, steps"));
+
+
+ // 0.2 If we use JKQTPBuildColorPaletteLUTLinInterpolate() instead of JKQTPBuildColorPaletteLUT(),
+ // the palettes will be smooth (linearly interpolated between the single given colors:
+ JKQTPImageTools::registerPalette("userpal_1_linear", JKQTPBuildColorPaletteLUTLinInterpolate(palsteps1), QObject::tr("User Palette 1, linear"));
+ JKQTPImageTools::registerPalette("userpal_2_linear", JKQTPBuildColorPaletteLUTLinInterpolate(palsteps2), QObject::tr("User Palette 2, linear"));
+
+ // 0.3 Now we load a whole set of additional palettes from an XML-file:
+ JKQTPImageTools::registerPalettesFromFile(":/usercolorpalettes/palettes/All_idl_cmaps.xml");
+ JKQTPImageTools::registerPalettesFromFile(":/usercolorpalettes/palettes/All_mpl_cmaps.xml");
+ JKQTPImageTools::registerPalettesFromFile(":/usercolorpalettes/palettes/CoolWarmUChar33.csv");
+ JKQTPImageTools::registerPalettesFromFile(":/usercolorpalettes/palettes/CoolWarmUChar257.csv");
+ JKQTPImageTools::registerPalettesFromFile(":/usercolorpalettes/palettes/NSW_Discrete_Z_ColorMap.xml");
+
+
+ // 1. create a window containing a plotter and a combobox to select the color palette
+ // ... and get a pointer to the internal datastore (for convenience)
+ QWidget win;
+ QVBoxLayout* lay=new QVBoxLayout();
+ win.setLayout(lay);
+ JKQTPMathImageColorPaletteComboBox* cmbPalette=new JKQTPMathImageColorPaletteComboBox(&win);
+ lay->addWidget(cmbPalette);
+ JKQTPlotter* plot=new JKQTPlotter(&win);
+ lay->addWidget(plot);
+ JKQTPDatastore* ds=plot->getDatastore();
+
+ // 2. now we create data for the charts (taken from https://commons.wikimedia.org/wiki/File:Energiemix_Deutschland.svg)
+ const int NX=100; // image dimension in x-direction [pixels]
+ const int NY=NX; // image dimension in x-direction [pixels]
+ const double dx=0.6e-2; // size of a pixel in x-direction [micrometers]
+ const double dy=0.6e-2; // size of a pixel in x-direction [micrometers]
+
+ // 2.1 Parameters for airy disk plot (see https://en.wikipedia.org/wiki/Airy_disk)
+ double NA=1.1; // numerical aperture of lens
+ double wavelength=488e-3; // wavelength of the light [micrometers]
+
+ // 2.2 calculate image of airy disk in a row-major array and immediately store the values
+ // in a new image column cAiryDisk
+ size_t cAiryDisk=ds->addCalculatedImageColumn(NX, NY, [&](size_t ix, size_t iy)->double {
+ double x=static_cast(static_cast(ix)-NX/2)*dx;
+ double y=static_cast(static_cast(iy)-NY/2)*dy;
+ const double r=sqrt(x*x+y*y);
+ const double v=2.0*M_PI*NA*r/wavelength;
+ if (ix==NX/2 && iy==NY/2) return 1.0;
+ else return pow(2.0*j1(v)/v, 2);
+ }, "imagedata");
+
+
+
+
+ // 3. create a graph (JKQTPColumnMathImage) with the column created above as data
+ // The data is color-coded with the color-palette JKQTPMathImageMATLAB
+ // the converted range of data is determined automatically because setAutoImageRange(true)
+ JKQTPColumnMathImage* graph=new JKQTPColumnMathImage(plot);
+ graph->setTitle("default MATLAB palette");
+ // set the image column with the data
+ graph->setImageColumn(cAiryDisk);
+ // where does the image start in the plot, given in plot-axis-coordinates (bottom-left corner)
+ graph->setX(0);
+ graph->setY(0);
+ // width and height of the image in plot-axis-coordinates
+ graph->setWidth(1);
+ graph->setHeight(1);
+ // color-map is taken from cmbPalette
+ plot->connect(cmbPalette, &JKQTPMathImageColorPaletteComboBox::currentPaletteChanged,[&](JKQTPMathImageColorPalette p) { graph->setPalette(p); plot->redrawPlot(); });
+ graph->setPalette(static_cast(userpalette_id));
+ cmbPalette->setCurrentColorPalette(graph->getPalette());
+
+
+ // 4. add the graphs to the plot, so it is actually displayed
+ plot->addGraph(graph);
+
+
+ // 5. fix axis and plot aspect ratio to 1
+ plot->getPlotter()->setMaintainAspectRatio(true);
+ plot->getPlotter()->setMaintainAxisAspectRatio(true);
+
+ // 6. autoscale the plot so the graph is contained
+ plot->zoomToFit();
+
+
+ // 7. Finally we add two buttons that save the current palette to a PNG-file and all loaded palettes:
+ QPushButton* btnSavePal=new QPushButton(QObject::tr("save current palette"), &win);
+ btnSavePal->connect(btnSavePal, &QPushButton::clicked, [&]() {
+ auto img=JKQTPImageTools::GetPaletteImage(cmbPalette->currentColorPalette(), JKQTPImageTools::LUTSIZE, 16);
+ img.save(JKQTPImageTools::JKQTPMathImageColorPalette2String(cmbPalette->currentColorPalette())+".png");
+ });
+ lay->addWidget(btnSavePal);
+ QPushButton* btnSaveAllPal=new QPushButton(QObject::tr("save all palettes"), &win);
+ btnSavePal->connect(btnSaveAllPal, &QPushButton::clicked, [&]() {
+ for (auto pn: JKQTPImageTools::getPredefinedPalettes()) {
+ auto p=JKQTPImageTools::String2JKQTPMathImageColorPalette(pn);
+ auto img=JKQTPImageTools::GetPaletteImage(p, JKQTPImageTools::LUTSIZE, 16);
+ img.save("palette_"+JKQTPImageTools::JKQTPMathImageColorPalette2String(p)+".png");
+ }
+ });
+ lay->addWidget(btnSaveAllPal);
+
+
+
+ // 8. show plotter and make it a decent size
+ win.show();
+ win.resize(500,550);
+ win.setWindowTitle("JKQTPColumnMathImage, USer Palettes");
+
+
+ return app.exec();
+}
diff --git a/examples/imageplot_userpal/imageplot_userpal.pro b/examples/imageplot_userpal/imageplot_userpal.pro
new file mode 100644
index 0000000000..35df32608b
--- /dev/null
+++ b/examples/imageplot_userpal/imageplot_userpal.pro
@@ -0,0 +1,27 @@
+# source code for this simple demo
+SOURCES = imageplot_userpal.cpp
+
+# configure Qt
+CONFIG += link_prl qt
+QT += core gui xml svg
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
+
+# output executable name
+TARGET = imageplot_userpal
+
+# include JKQTPlotter source code
+DEPENDPATH += ../../lib ../../qmake/staticlib/jkqtplotterlib
+INCLUDEPATH += ../../lib
+CONFIG (debug, debug|release) {
+ LIBS += -L../../qmake/staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
+} else {
+ LIBS += -L../../qmake/staticlib/jkqtplotterlib/release -ljkqtplotterlib
+}
+message("LIBS = $$LIBS")
+
+win32-msvc*: DEFINES += _USE_MATH_DEFINES
+win32-msvc*: DEFINES += NOMINMAX
+
+
+
+
diff --git a/examples/imageplot_userpal/imageplot_userpal.qrc b/examples/imageplot_userpal/imageplot_userpal.qrc
new file mode 100644
index 0000000000..4a46b408b7
--- /dev/null
+++ b/examples/imageplot_userpal/imageplot_userpal.qrc
@@ -0,0 +1,9 @@
+
+
+ palettes/All_idl_cmaps.xml
+ palettes/All_mpl_cmaps.xml
+ palettes/CoolWarmUChar33.csv
+ palettes/CoolWarmUChar257.csv
+ palettes/NSW_Discrete_Z_ColorMap.xml
+
+
diff --git a/examples/imageplot_userpal/imageplot_userpal_and_lib.pro b/examples/imageplot_userpal/imageplot_userpal_and_lib.pro
new file mode 100644
index 0000000000..cd086ab132
--- /dev/null
+++ b/examples/imageplot_userpal/imageplot_userpal_and_lib.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+
+SUBDIRS += jkqtplotterlib imageplot
+
+jkqtplotterlib.file = ../../qmake/staticlib/jkqtplotterlib/jkqtplotterlib.pro
+
+imageplot.file=$$PWD/imageplot.pro
+imageplot.depends = jkqtplotterlib
diff --git a/examples/imageplot_userpal/palettes/All_idl_cmaps.xml b/examples/imageplot_userpal/palettes/All_idl_cmaps.xml
new file mode 100644
index 0000000000..3df5a00bbe
--- /dev/null
+++ b/examples/imageplot_userpal/palettes/All_idl_cmaps.xml
@@ -0,0 +1,10581 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/imageplot_userpal/palettes/All_mpl_cmaps.xml b/examples/imageplot_userpal/palettes/All_mpl_cmaps.xml
new file mode 100644
index 0000000000..efc094000c
--- /dev/null
+++ b/examples/imageplot_userpal/palettes/All_mpl_cmaps.xml
@@ -0,0 +1,12903 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/imageplot_userpal/palettes/CoolWarmUChar257.csv b/examples/imageplot_userpal/palettes/CoolWarmUChar257.csv
new file mode 100644
index 0000000000..b1e2c5679b
--- /dev/null
+++ b/examples/imageplot_userpal/palettes/CoolWarmUChar257.csv
@@ -0,0 +1,258 @@
+Scalar,R,G,B
+0,59,76,192
+0.00390625,60,78,194
+0.0078125,61,80,195
+0.01171875,62,81,197
+0.015625,63,83,198
+0.01953125,64,85,200
+0.0234375,66,87,201
+0.02734375,67,88,203
+0.03125,68,90,204
+0.03515625,69,92,206
+0.0390625,70,93,207
+0.04296875,71,95,209
+0.046875,73,97,210
+0.05078125,74,99,211
+0.0546875,75,100,213
+0.05859375,76,102,214
+0.0625,77,104,215
+0.06640625,79,105,217
+0.0703125,80,107,218
+0.07421875,81,109,219
+0.078125,82,110,221
+0.08203125,84,112,222
+0.0859375,85,114,223
+0.08984375,86,115,224
+0.09375,87,117,225
+0.09765625,89,119,226
+0.1015625,90,120,228
+0.10546875,91,122,229
+0.109375,93,123,230
+0.11328125,94,125,231
+0.1171875,95,127,232
+0.12109375,96,128,233
+0.125,98,130,234
+0.12890625,99,131,235
+0.1328125,100,133,236
+0.13671875,102,135,237
+0.140625,103,136,238
+0.14453125,104,138,239
+0.1484375,106,139,239
+0.15234375,107,141,240
+0.15625,108,142,241
+0.16015625,110,144,242
+0.1640625,111,145,243
+0.16796875,112,147,243
+0.171875,114,148,244
+0.17578125,115,150,245
+0.1796875,116,151,246
+0.18359375,118,153,246
+0.1875,119,154,247
+0.19140625,120,156,247
+0.1953125,122,157,248
+0.19921875,123,158,249
+0.203125,124,160,249
+0.20703125,126,161,250
+0.2109375,127,163,250
+0.21484375,129,164,251
+0.21875,130,165,251
+0.22265625,131,167,252
+0.2265625,133,168,252
+0.23046875,134,169,252
+0.234375,135,171,253
+0.23828125,137,172,253
+0.2421875,138,173,253
+0.24609375,140,174,254
+0.25,141,176,254
+0.25390625,142,177,254
+0.2578125,144,178,254
+0.26171875,145,179,254
+0.265625,147,181,255
+0.26953125,148,182,255
+0.2734375,149,183,255
+0.27734375,151,184,255
+0.28125,152,185,255
+0.28515625,153,186,255
+0.2890625,155,187,255
+0.29296875,156,188,255
+0.296875,158,190,255
+0.30078125,159,191,255
+0.3046875,160,192,255
+0.30859375,162,193,255
+0.3125,163,194,255
+0.31640625,164,195,254
+0.3203125,166,196,254
+0.32421875,167,197,254
+0.328125,168,198,254
+0.33203125,170,199,253
+0.3359375,171,199,253
+0.33984375,172,200,253
+0.34375,174,201,253
+0.34765625,175,202,252
+0.3515625,176,203,252
+0.35546875,178,204,251
+0.359375,179,205,251
+0.36328125,180,205,251
+0.3671875,182,206,250
+0.37109375,183,207,250
+0.375,184,208,249
+0.37890625,185,208,248
+0.3828125,187,209,248
+0.38671875,188,210,247
+0.390625,189,210,247
+0.39453125,190,211,246
+0.3984375,192,212,245
+0.40234375,193,212,245
+0.40625,194,213,244
+0.41015625,195,213,243
+0.4140625,197,214,243
+0.41796875,198,214,242
+0.421875,199,215,241
+0.42578125,200,215,240
+0.4296875,201,216,239
+0.43359375,203,216,238
+0.4375,204,217,238
+0.44140625,205,217,237
+0.4453125,206,217,236
+0.44921875,207,218,235
+0.453125,208,218,234
+0.45703125,209,219,233
+0.4609375,210,219,232
+0.46484375,211,219,231
+0.46875,213,219,230
+0.47265625,214,220,229
+0.4765625,215,220,228
+0.48046875,216,220,227
+0.484375,217,220,225
+0.48828125,218,220,224
+0.4921875,219,220,223
+0.49609375,220,221,222
+0.5,221,221,221
+0.50390625,222,220,219
+0.5078125,223,220,218
+0.51171875,224,219,216
+0.515625,225,219,215
+0.51953125,226,218,214
+0.5234375,227,218,212
+0.52734375,228,217,211
+0.53125,229,216,209
+0.53515625,230,216,208
+0.5390625,231,215,206
+0.54296875,232,215,205
+0.546875,232,214,203
+0.55078125,233,213,202
+0.5546875,234,212,200
+0.55859375,235,212,199
+0.5625,236,211,197
+0.56640625,236,210,196
+0.5703125,237,209,194
+0.57421875,238,209,193
+0.578125,238,208,191
+0.58203125,239,207,190
+0.5859375,240,206,188
+0.58984375,240,205,187
+0.59375,241,204,185
+0.59765625,241,203,184
+0.6015625,242,202,182
+0.60546875,242,201,181
+0.609375,243,200,179
+0.61328125,243,199,178
+0.6171875,244,198,176
+0.62109375,244,197,174
+0.625,245,196,173
+0.62890625,245,195,171
+0.6328125,245,194,170
+0.63671875,245,193,168
+0.640625,246,192,167
+0.64453125,246,191,165
+0.6484375,246,190,163
+0.65234375,246,188,162
+0.65625,247,187,160
+0.66015625,247,186,159
+0.6640625,247,185,157
+0.66796875,247,184,156
+0.671875,247,182,154
+0.67578125,247,181,152
+0.6796875,247,180,151
+0.68359375,247,178,149
+0.6875,247,177,148
+0.69140625,247,176,146
+0.6953125,247,174,145
+0.69921875,247,173,143
+0.703125,247,172,141
+0.70703125,247,170,140
+0.7109375,247,169,138
+0.71484375,247,167,137
+0.71875,247,166,135
+0.72265625,246,164,134
+0.7265625,246,163,132
+0.73046875,246,161,131
+0.734375,246,160,129
+0.73828125,245,158,127
+0.7421875,245,157,126
+0.74609375,245,155,124
+0.75,244,154,123
+0.75390625,244,152,121
+0.7578125,244,151,120
+0.76171875,243,149,118
+0.765625,243,147,117
+0.76953125,242,146,115
+0.7734375,242,144,114
+0.77734375,241,142,112
+0.78125,241,141,111
+0.78515625,240,139,109
+0.7890625,240,137,108
+0.79296875,239,136,106
+0.796875,238,134,105
+0.80078125,238,132,103
+0.8046875,237,130,102
+0.80859375,236,129,100
+0.8125,236,127,99
+0.81640625,235,125,97
+0.8203125,234,123,96
+0.82421875,233,121,95
+0.828125,233,120,93
+0.83203125,232,118,92
+0.8359375,231,116,90
+0.83984375,230,114,89
+0.84375,229,112,88
+0.84765625,228,110,86
+0.8515625,227,108,85
+0.85546875,227,106,83
+0.859375,226,104,82
+0.86328125,225,102,81
+0.8671875,224,100,79
+0.87109375,223,98,78
+0.875,222,96,77
+0.87890625,221,94,75
+0.8828125,220,92,74
+0.88671875,218,90,73
+0.890625,217,88,71
+0.89453125,216,86,70
+0.8984375,215,84,69
+0.90234375,214,82,67
+0.90625,213,80,66
+0.91015625,212,78,65
+0.9140625,210,75,64
+0.91796875,209,73,62
+0.921875,208,71,61
+0.92578125,207,69,60
+0.9296875,205,66,59
+0.93359375,204,64,57
+0.9375,203,62,56
+0.94140625,202,59,55
+0.9453125,200,57,54
+0.94921875,199,54,53
+0.953125,198,51,52
+0.95703125,196,49,50
+0.9609375,195,46,49
+0.96484375,193,43,48
+0.96875,192,40,47
+0.97265625,190,37,46
+0.9765625,189,34,45
+0.98046875,188,30,44
+0.984375,186,26,43
+0.98828125,185,22,41
+0.9921875,183,17,40
+0.99609375,181,11,39
+1,180,4,38
\ No newline at end of file
diff --git a/examples/imageplot_userpal/palettes/CoolWarmUChar33.csv b/examples/imageplot_userpal/palettes/CoolWarmUChar33.csv
new file mode 100644
index 0000000000..5bc9c68283
--- /dev/null
+++ b/examples/imageplot_userpal/palettes/CoolWarmUChar33.csv
@@ -0,0 +1,34 @@
+Scalar,R,G,B
+0,59,76,192
+0.03125,68,90,204
+0.0625,77,104,215
+0.09375,87,117,225
+0.125,98,130,234
+0.15625,108,142,241
+0.1875,119,154,247
+0.21875,130,165,251
+0.25,141,176,254
+0.28125,152,185,255
+0.3125,163,194,255
+0.34375,174,201,253
+0.375,184,208,249
+0.40625,194,213,244
+0.4375,204,217,238
+0.46875,213,219,230
+0.5,221,221,221
+0.53125,229,216,209
+0.5625,236,211,197
+0.59375,241,204,185
+0.625,245,196,173
+0.65625,247,187,160
+0.6875,247,177,148
+0.71875,247,166,135
+0.75,244,154,123
+0.78125,241,141,111
+0.8125,236,127,99
+0.84375,229,112,88
+0.875,222,96,77
+0.90625,213,80,66
+0.9375,203,62,56
+0.96875,192,40,47
+1,180,4,38
\ No newline at end of file
diff --git a/examples/imageplot_userpal/palettes/NSW_Discrete_Z_ColorMap.xml b/examples/imageplot_userpal/palettes/NSW_Discrete_Z_ColorMap.xml
new file mode 100644
index 0000000000..79ebaae4d8
--- /dev/null
+++ b/examples/imageplot_userpal/palettes/NSW_Discrete_Z_ColorMap.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/jkqtcommon/CMakeLists.txt b/lib/jkqtcommon/CMakeLists.txt
index 42c9d64690..af14ab1a20 100644
--- a/lib/jkqtcommon/CMakeLists.txt
+++ b/lib/jkqtcommon/CMakeLists.txt
@@ -73,7 +73,7 @@ if(BUILD_SHARED_LIBS)
add_library(${libsh_name} SHARED ${SOURCES} ${HEADERS})
set_property(TARGET ${libsh_name} PROPERTY VERSION "${PROJECT_VERSION}")
set_property(TARGET ${libsh_name} PROPERTY OUTPUT_NAME "${libsh_name_decorated}")
- target_link_libraries(${libsh_name} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::PrintSupport)
+ target_link_libraries(${libsh_name} Qt5::Core Qt5::Gui Qt5::Xml Qt5::Widgets Qt5::PrintSupport)
target_compile_definitions(${libsh_name} PUBLIC JKQTCOMMON_LIB_IN_DLL)
target_compile_definitions(${libsh_name} PRIVATE JKQTCOMMON_LIB_EXPORT_LIBRARY)
set_property(TARGET ${libsh_name} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS "ON")
@@ -86,7 +86,7 @@ if(BUILD_STATIC_LIBS)
add_library(${lib_name} STATIC ${SOURCES} ${HEADERS})
set_property(TARGET ${lib_name} PROPERTY VERSION "${PROJECT_VERSION}")
set_property(TARGET ${lib_name} PROPERTY OUTPUT_NAME "${lib_name_decorated}")
- target_link_libraries(${lib_name} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::PrintSupport)
+ target_link_libraries(${lib_name} Qt5::Core Qt5::Gui Qt5::Xml Qt5::Widgets Qt5::PrintSupport)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${lib_name}Version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion )
diff --git a/lib/jkqtcommon/jkqtpbasicimagetools.cpp b/lib/jkqtcommon/jkqtpbasicimagetools.cpp
index af2fa32605..b6dc9dfbe2 100644
--- a/lib/jkqtcommon/jkqtpbasicimagetools.cpp
+++ b/lib/jkqtcommon/jkqtpbasicimagetools.cpp
@@ -30,1732 +30,2760 @@ const int JKQTPImageTools::PALETTE_ICON_WIDTH = 64;
const int JKQTPImageTools::PALETTE_IMAGEICON_HEIGHT = 64;
const int JKQTPImageTools::LUTSIZE = 256;
-QList JKQTPImageTools::global_jkqtpimagetools_lutstore = QList();
+QMap JKQTPImageTools::global_jkqtpimagetools_lutstore = JKQTPImageTools::getDefaultLUTs();
+int JKQTPImageTools::global_next_userpalette = JKQTPMathImageFIRST_REGISTERED_USER_PALETTE;
-bool JKQTPImagePlot_buildDefinedPaletteLessThan(const QPair &s1, const QPair &s2)
- {
- return s1.first > items, int lut_size) {
- qSort(items.begin(), items.end(), JKQTPImagePlot_buildDefinedPaletteLessThan);
+
+
+
+
+
+
+
+
+QMap JKQTPImageTools::getDefaultLUTs() {
+ QMap lutstore;
+
+ {
+ auto palette=JKQTPMathImageRED;
+ QString palN="red";
+ QString palNT=QObject::tr("red");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ plut[l]=qRgb(static_cast(255.0*v), 0, 0);
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageGREEN;
+ QString palN="green";
+ QString palNT=QObject::tr("green");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ plut[l]=qRgb(0, static_cast(255.0*v), 0);
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageBLUE;
+ QString palN="blue";
+ QString palNT=QObject::tr("blue");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ plut[l]=qRgb(0, 0, static_cast(255.0*v));
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageGRAY;
+ QString palN="gray";
+ QString palNT=QObject::tr("gray");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ plut[l]=qRgb(static_cast(255.0*v),
+ static_cast(255.0*v),
+ static_cast(255.0*v));
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageALPHA;
+ QString palN="alpha";
+ QString palNT=QObject::tr("alpha");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ plut[l]=qRgba(255,255,255,
+ static_cast(255.0*v));
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_ALPHA;
+ QString palN="invAlpha";
+ QString palNT=QObject::tr("inv. alpha");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ plut[l]=qRgba(255,255,255,
+ static_cast(255.0*v));
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTEDRED;
+ QString palN="invred";
+ QString palNT=QObject::tr("inv. red");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ plut[l]=qRgb(static_cast(255.0*(1.0-v)), 0, 0);
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTEDGREEN;
+ QString palN="invgreen";
+ QString palNT=QObject::tr("inv. green");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ plut[l]=qRgb(0, static_cast(255.0*(1.0-v)), 0);
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTEDBLUE;
+ QString palN="invblue";
+ QString palNT=QObject::tr("inv. blue");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ plut[l]=qRgb(0, 0, static_cast(255.0*(1.0-v)));
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTEDGRAY;
+ QString palN="invgray";
+ QString palNT=QObject::tr("inv. gray");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=1.0-(l/static_cast(JKQTPImageTools::LUTSIZE));
+ plut[l]=qRgb(static_cast(255.0*v),
+ static_cast(255.0*v),
+ static_cast(255.0*v));
+ }
+ plut[JKQTPImageTools::LUTSIZE+1]=plut[JKQTPImageTools::LUTSIZE];
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageMATLAB;
+ QString palN="Matlab";
+ QString palNT=QObject::tr("Matlab");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 382.5 - 1020.0 * std::abs(v - 0.75);
+ if (r > 255.0)
+ r = 255.0;
+ else if (r < 0.0)
+ r = 0.0;
+
+ double g = 382.5 - 1020.0 * std::abs(v - 0.5);
+ if (g > 255.0)
+ g = 255.0;
+ else if (g < 0.0)
+ g = 0.0;
+
+ double b = 382.5 - 1020.0 * std::abs(v - 0.25);
+ if (b > 255.0)
+ b = 255.0;
+ else if (b < 0.0)
+ b = 0.0;
+
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_MATLAB;
+ QString palN="invMatlab";
+ QString palNT=QObject::tr("inv. Matlab");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 382.5 - 1020.0 * std::abs(v - 0.75);
+ if (r > 255.0)
+ r = 255.0;
+ else if (r < 0.0)
+ r = 0.0;
+
+ double g = 382.5 - 1020.0 * std::abs(v - 0.5);
+ if (g > 255.0)
+ g = 255.0;
+ else if (g < 0.0)
+ g = 0.0;
+
+ double b = 382.5 - 1020.0 * std::abs(v - 0.25);
+ if (b > 255.0)
+ b = 255.0;
+ else if (b < 0.0)
+ b = 0.0;
+
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageRYGB;
+ QString palN="RYGB";
+ QString palNT=QObject::tr("RYGB");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 796.875*v - 199.21875;
+ if (r > 255.0)
+ r = 255.0;
+ else if (r < 0.0)
+ r = 0.0;
+
+ double g = 255.0 * std::sin(M_PI*v);
+
+ double b = 255.0 - 765.0 * v;
+ if (b < 0.0)
+ b = 0.0;
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_RYGB;
+ QString palN="invRYGB";
+ QString palNT=QObject::tr("inv. RYGB");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) {
+ for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 796.875*v - 199.21875;
+ if (r > 255.0)
+ r = 255.0;
+ else if (r < 0.0)
+ r = 0.0;
+
+ double g = 255.0 * std::sin(M_PI*v);
+
+ double b = 255.0 - 765.0 * v;
+ if (b < 0.0)
+ b = 0.0;
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageHSV;
+ QString palN="HSV";
+ QString palNT=QObject::tr("HSV");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ int h = static_cast(floor(6*v));
+ double f = 6*v-double(h);
+
+ switch (h)
+ {
+ case 0: plut[l]=qRgb(255, static_cast(255.0*f), 0); break;
+ case 1: plut[l]=qRgb(static_cast(255.0*(1-f)), 255, 0); break;
+ case 2: plut[l]=qRgb(0, 255, static_cast(255.0*f)); break;
+ case 3: plut[l]=qRgb(0, static_cast(255.0*(1-f)), 255); break;
+ case 4: plut[l]=qRgb(static_cast(255.0*f), 0, 255); break;
+ case 5: plut[l]=qRgb(255, 0, static_cast(255.0*(1-f))); break;
+ case 6: plut[l]=qRgb(255, static_cast(255.0*f), 0); break;
+ }
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_HSV;
+ QString palN="invHSV";
+ QString palNT=QObject::tr("inv. HSV");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ int h = static_cast(floor(6.0-6.0*v));
+ double f = 6.0-6.0*v-double(h);
+
+ switch (h)
+ {
+ case 0: plut[l]=qRgb(255, static_cast(255.0*f), 0); break;
+ case 1: plut[l]=qRgb(static_cast(255.0*(1-f)), 255, 0); break;
+ case 2: plut[l]=qRgb(0, 255, static_cast(255.0*f)); break;
+ case 3: plut[l]=qRgb(0, static_cast(255.0*(1-f)), 255); break;
+ case 4: plut[l]=qRgb(static_cast(255.0*f), 0, 255); break;
+ case 5: plut[l]=qRgb(255, 0, static_cast(255.0*(1-f))); break;
+ case 6: plut[l]=qRgb(255, static_cast(255.0*f), 0); break;
+ }
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageRAINBOW;
+ QString palN="rainbow";
+ QString palNT=QObject::tr("rainbow");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n";
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 255.0*std::abs(2.0*v-0.5);
+ if (r > 255.0)
+ r = 255.0;
+
+ double g = 255.0*sin(M_PI*v);
+
+ double b = 255.0*cos(0.5*M_PI*v);
+
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_RAINBOW;
+ QString palN="invrainbow";
+ QString palNT=QObject::tr("inv. rainbow");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n";
+ if (plut!=nullptr) {
+ for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 255.0*std::abs(2.0*v-0.5);
+ if (r > 255.0)
+ r = 255.0;
+
+ double g = 255.0*sin(M_PI*v);
+
+ double b = 255.0*cos(0.5*M_PI*v);
+
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageHOT;
+ QString palN="AFMhot";
+ QString palNT=QObject::tr("AFM hot");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 765.0*v;
+ if (r > 255.0)
+ r = 255.0;
+
+ double g = 765.0*v-255.0;
+ if (g > 255.0)
+ g = 255.0;
+ else if (g < 0.0)
+ g = 0.0;
+
+ double b = 765.0*v-510.0;
+ if (b < 0.0)
+ b = 0.0;
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_HOT;
+ QString palN="invAFMhot";
+ QString palNT=QObject::tr("inv. AFM hot");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 765.0*v;
+ if (r > 255.0)
+ r = 255.0;
+
+ double g = 765.0*v-255.0;
+ if (g > 255.0)
+ g = 255.0;
+ else if (g < 0.0)
+ g = 0.0;
+
+ double b = 765.0*v-510.0;
+ if (b < 0.0)
+ b = 0.0;
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageOCEAN;
+ QString palN="ocean";
+ QString palNT=QObject::tr("ocean");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 765.0*v-510.0;
+ if (r < 0.0)
+ r = 0.0;
+
+ double g = std::abs(382.5*v-127.5);
+
+ double b = 255.0*v;
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_OCEAN;
+ QString palN="invocean";
+ QString palNT=QObject::tr("inv. ocean");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=JKQTPImageTools::LUTSIZE; l>=0; l--) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 765.0*v-510.0;
+ if (r < 0.0)
+ r = 0.0;
+
+ double g = std::abs(382.5*v-127.5);
+
+ double b = 255.0*v;
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageBLUEMAGENTAYELLOW;
+ QString palN="BlMaYe";
+ QString palNT=QObject::tr("blue-magenta-yellow");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = (v/0.32-0.78125);
+ if (r < 0.0) r = 0.0;
+ if (r > 1.0) r = 1.0;
+
+ double g = 2.0*v-0.84;
+ if (g < 0.0) g = 0.0;
+ if (g > 1.0) g = 1.0;
+
+ double b = 4.0*v;
+ if (b>1 || b<0) b = -2.0*v+1.84;
+ if (b>1 || b<0) b = v/0.08-11.5;
+ if (b>1 || b<0) b=1;
+
+ if (b < 0.0) b = 0.0;
+ if (b > 1.0) b = 1.0;
+ plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_BLUEMAGENTAYELLOW;
+ QString palN="YeMaBl";
+ QString palNT=QObject::tr("yellow-magenta-blue");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data(); if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = (v/0.32-0.78125);
+ if (r < 0.0) r = 0.0;
+ if (r > 1.0) r = 1.0;
+
+ double g = 2.0*v-0.84;
+ if (g < 0.0) g = 0.0;
+ if (g > 1.0) g = 1.0;
+
+ double b = 4.0*v;
+ if (b>1 || b<0) b = -2.0*v+1.84;
+ if (b>1 || b<0) b = v/0.08-11.5;
+ if (b>1 || b<0) b=1;
+
+ if (b < 0.0) b = 0.0;
+ if (b > 1.0) b = 1.0;
+ plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageBLUEYELLOW;
+ QString palN="BlYe";
+ QString palNT=QObject::tr("blue-yellow");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = sqrt(sqrt(v));
+ if (r < 0.0) r = 0.0;
+ if (r > 1.0) r = 1.0;
+
+ double g = sin(M_PI/2.0*v);
+ if (g < 0.0) g = 0.0;
+ if (g > 1.0) g = 1.0;
+
+ double b = cos(M_PI/2.0*v);
+ if (b < 0.0) b = 0.0;
+ if (b > 1.0) b = 1.0;
+
+ plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_BLUEYELLOW;
+ QString palN="YeBl";
+ QString palNT=QObject::tr("yellow-blue");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = sqrt(sqrt(v));
+ if (r < 0.0) r = 0.0;
+ if (r > 1.0) r = 1.0;
+
+ double g = sin(M_PI/2.0*v);
+ if (g < 0.0) g = 0.0;
+ if (g > 1.0) g = 1.0;
+
+ double b = cos(M_PI/2.0*v);
+ if (b < 0.0) b = 0.0;
+ if (b > 1.0) b = 1.0;
+
+ plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageCYAN;
+ QString palN="cyan";
+ QString palNT=QObject::tr("cyan");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = v*0.5;
+ if (r < 0.0) r = 0.0;
+ if (r > 1.0) r = 1.0;
+
+ double g = v;
+ if (g < 0.0) g = 0.0;
+ if (g > 1.0) g = 1.0;
+
+ double b = v;
+ if (b < 0.0) b = 0.0;
+ if (b > 1.0) b = 1.0;
+ plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_CYAN;
+ QString palN="invcyan";
+ QString palNT=QObject::tr("inv. cyan");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = v*0.5;
+ if (r < 0.0) r = 0.0;
+ if (r > 1.0) r = 1.0;
+
+ double g = v;
+ if (g < 0.0) g = 0.0;
+ if (g > 1.0) g = 1.0;
+
+ double b = v;
+ if (b < 0.0) b = 0.0;
+ if (b > 1.0) b = 1.0;
+ plut[l]=qRgb(static_cast(255.0*r), static_cast(255.0*g), static_cast(255.0*b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageTRAFFICLIGHT;
+ QString palN="trafficlight";
+ QString palNT=QObject::tr("trafficlight");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=l/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = (v < 0.5) ? 128.0*sin(M_PI*(2.0*v-0.5))+128.0 : 255.0;
+ if (r > 255.0)
+ r = 255.0;
+
+ double g = (v < 0.5) ? 512.0*v+128.0 : 512.0-512.0*v;
+ if (g > 255.0)
+ g = 255.0;
+ plut[l]=qRgb(static_cast(r), static_cast(g), 0);
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageINVERTED_TRAFFICLIGHT;
+ QString palN="invtrafficlight";
+ QString palNT=QObject::tr("inv. trafficlight");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = (v < 0.5) ? 128.0*sin(M_PI*(2.0*v-0.5))+128.0 : 255.0;
+ if (r > 255.0)
+ r = 255.0;
+
+ double g = (v < 0.5) ? 512.0*v+128.0 : 512.0-512.0*v;
+ if (g > 255.0)
+ g = 255.0;
+ plut[l]=qRgb(static_cast(r), static_cast(g), 0);
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageBLUEWHITERED;
+ QString palN="bluewhitered";
+ QString palNT=QObject::tr("blue-white-red");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QList > lst;
+ lst<(8.0, 0xFFB2182B);
+ lst<(7.0, 0xFFD6604D);
+ lst<(6.0, 0xFFF4A582);
+ lst<(5.0, 0xFFFDDBC7);
+ lst<(4.0, 0xFFD1E5F0);
+ lst<(3.0, 0xFF92C5DE);
+ lst<(2.0, 0xFF4393C3);
+ lst<(1.0, 0xFF2166AC);
+
+ lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst, JKQTPImageTools::LUTSIZE+1);
+ }
+
+
+ {
+ auto palette=JKQTPMathImageREDWHITEBLUE;
+ QString palN="redwhiteblue";
+ QString palNT=QObject::tr("red-white-blue");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+
+ QList > lst;
+ lst<(0.0, 0xFFB2182B);
+ lst<(1.0, 0xFFD6604D);
+ lst<(2.0, 0xFFF4A582);
+ lst<(3.0, 0xFFFDDBC7);
+ lst<(4.0, 0xFFD1E5F0);
+ lst<(5.0, 0xFF92C5DE);
+ lst<(6.0, 0xFF4393C3);
+ lst<(7.0, 0xFF2166AC);
+
+ lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst, JKQTPImageTools::LUTSIZE+1);
+
+ }
+
+
+ {
+ auto palette=JKQTPMathImageBLACKBLUEREDYELLOW;
+ QString palN="BBlRdYe";
+ QString palNT=QObject::tr("black-blue-red-yellow");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n";
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=(l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 255.0*qBound(0.0,sqrt(v),1.0);
+ double g = 255.0*qBound(0.0,v*v*v,1.0);
+ double b = 255.0*qBound(0.0,sin(2.0*M_PI*v),1.0);
+
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageGREENREDVIOLET;
+ QString palN="GnRdVi";
+ QString palNT=QObject::tr("green-red-violet");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n";
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=(l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 255.0*qBound(0.0,v,1.0);
+ double g = 255.0*qBound(0.0,fabs(v-0.5),1.0);
+ double b = 255.0*qBound(0.0,v*v*v*v,1.0);
+
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageBLACKBLUEWHITEYELLOWWHITE;
+ QString palN="BWprint";
+ QString palNT=QObject::tr("black-blue-white-yellow-white");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data(); //std::cout<<"!!! creating rainbow lut\n";
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=(l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 255.0*qBound(0.0,v/0.32-0.78125,1.0);
+ double g = 255.0*qBound(0.0,v/0.32-0.78125,1.0);
+ double b = 255.0*qBound(0.0,(v<0.25)?4*v:(v<0.42)?1.0:(v<0.92)?-2.0*v+1.84:v/0.08-11.5,1.0);
+
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageWHITEYELLOWWHITEBLUEBLACK;
+ QString palN="invBWprint";
+ QString palNT=QObject::tr("white-yellow-white-blue-black");
+ lutstore[palette]=JKQTPImageTools::LUTData(QVector(JKQTPImageTools::LUTSIZE+1, 0), palN, palNT);
+ QRgb* plut=lutstore[palette].lut.data();
+ if (plut!=nullptr) {
+ for (int l=0; l<=JKQTPImageTools::LUTSIZE; l++) {
+ double v=(JKQTPImageTools::LUTSIZE-l)/static_cast(JKQTPImageTools::LUTSIZE);
+ double r = 255.0*qBound(0.0,v/0.32-0.78125,1.0);
+ double g = 255.0*qBound(0.0,v/0.32-0.78125,1.0);
+ double b = 255.0*qBound(0.0,(v<0.25)?4*v:(v<0.42)?1.0:(v<0.92)?-2.0*v+1.84:v/0.08-11.5,1.0);
+
+ plut[l]=qRgb(static_cast(r), static_cast(g), static_cast(b));
+ }
+ }
+ }
+
+
+ {
+ auto palette=JKQTPMathImageBR_GR;
+ QString palN="BrBG";
+ QString palNT=QObject::tr("BrBG");
+ lutstore[palette]=JKQTPImageTools::LUTData(palN, palNT);
+ QList > lst;
+ lst<(0.0, qRgb(0x8C, 0x51, 0x0A));
+ lst<(1.0, qRgb(0xBF, 0x81, 0x2D));
+ lst<(2.0, qRgb(0xDF, 0xC2, 0x7D));
+ lst<(3.0, 0xFFF6E8C3);
+ lst<(4.0, 0xFFC7EAE5);
+ lst<(5.0, 0xFF80CDC1);
+ lst<(6.0, 0xFF35978F);
+ lst<(7.0, 0xFF01665E);
+
+ lutstore[palette].lut=JKQTPBuildColorPaletteLUTLinInterpolate(lst);
+ }
+
+
+ {
+ auto palette=JKQTPMathImageBR_GR_STEP;
+ QString palN="stepsBrBG";
+ QString palNT=QObject::tr("steps: BrBG");
+ lutstore[palette]=JKQTPImageTools::LUTData( palN, palNT);
+
+ QList > lst;
+ lst<(0.0, qRgb(0x8C, 0x51, 0x0A));
+ lst<(1.0, qRgb(0xBF, 0x81, 0x2D));
+ lst<(2.0, qRgb(0xDF, 0xC2, 0x7D));
+ lst<(3.0, 0xFFF6E8C3);
+ lst<(4.0, 0xFFC7EAE5);
+ lst<(5.0, 0xFF80CDC1);
+ lst<(6.0, 0xFF35978F);
+ lst<(7.0, 0xFF01665E);
+
+ lutstore[palette].lut=JKQTPBuildColorPaletteLUT(lst);
+
+ }
+
+
+ {
+ auto palette=JKQTPMathImagePU_OR;
+ QString palN="PuOr";
+ QString palNT=QObject::tr("PuOr");
+ lutstore[palette]=JKQTPImageTools::LUTData(palN, palNT);
+ QList > lst;
+ lst<(0.0, 0xFFB35806);
+ lst<(1.0, 0xFFE08214);
+ lst<(2.0, 0xFFFDB863);
+ lst<(3.0, 0xFFFEE0B6);
+ lst<(4.0, 0xFFF7F7F7);
+ lst<(5.0, 0xFFD8DAEB);
+ lst< |