Skip to content
Snippets Groups Projects
CImg.h 2.76 MiB
Newer Older
  • Learn to ignore specific revisions
  • #ifndef CIMG_H
    #define CIMG_H
    
    
    4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
    /*
     #
     #  File            : CImg.h
     #                    ( C++ header file )
     #
     #  Description     : The C++ Template Image Processing Toolkit.
     #                    This file is the main component of the CImg Library project.
     #                    ( http://cimg.eu )
     #
     #  Project manager : David Tschumperle.
     #                    ( http://tschumperle.users.greyc.fr/ )
     #
     #                    A complete list of contributors is available in file 'README.txt'
     #                    distributed within the CImg package.
     #
     #  Licenses        : This file is 'dual-licensed', you have to choose one
     #                    of the two licenses below to apply.
     #
     #                    CeCILL-C
     #                    The CeCILL-C license is close to the GNU LGPL.
     #                    ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html )
     #
     #                or  CeCILL v2.0
     #                    The CeCILL license is compatible with the GNU GPL.
     #                    ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html )
     #
     #  This software is governed either by the CeCILL or the CeCILL-C license
     #  under French law and abiding by the rules of distribution of free software.
     #  You can  use, modify and or redistribute the software under the terms of
     #  the CeCILL or CeCILL-C licenses as circulated by CEA, CNRS and INRIA
     #  at the following URL: "http://www.cecill.info".
     #
     #  As a counterpart to the access to the source code and  rights to copy,
     #  modify and redistribute granted by the license, users are provided only
     #  with a limited warranty  and the software's author,  the holder of the
     #  economic rights,  and the successive licensors  have only  limited
     #  liability.
     #
     #  In this respect, the user's attention is drawn to the risks associated
     #  with loading,  using,  modifying and/or developing or reproducing the
     #  software by the user in light of its specific status of free software,
     #  that may mean  that it is complicated to manipulate,  and  that  also
     #  therefore means  that it is reserved for developers  and  experienced
     #  professionals having in-depth computer knowledge. Users are therefore
     #  encouraged to load and test the software's suitability as regards their
     #  requirements in conditions enabling the security of their systems and/or
     #  data to be ensured and,  more generally, to use and operate it in the
     #  same conditions as regards security.
     #
     #  The fact that you are presently reading this means that you have had
     #  knowledge of the CeCILL and CeCILL-C licenses and that you accept its terms.
     #
    */
    
    // Set version number of the library.
    #ifndef cimg_version
    #define cimg_version 200
    
    /*-----------------------------------------------------------
     #
     # Test and possibly auto-set CImg configuration variables
     # and include required headers.
     #
     # If you find that the default configuration variables are
     # not adapted to your system, you can override their values
     # before including the header file "CImg.h"
     # (use the #define directive).
     #
     ------------------------------------------------------------*/
    
    // Include standard C++ headers.
    // This is the minimal set of required headers to make CImg-based codes compile.
    #include <cstdio>
    #include <cstdlib>
    #include <cstdarg>
    #include <cstring>
    #include <cmath>
    #include <cfloat>
    #include <climits>
    #include <ctime>
    #include <exception>
    #include <algorithm>
    
    // Detect/configure OS variables.
    //
    // Define 'cimg_OS' to: '0' for an unknown OS (will try to minize library dependencies).
    //                      '1' for a Unix-like OS (Linux, Solaris, BSD, MacOSX, Irix, ...).
    //                      '2' for Microsoft Windows.
    //                      (auto-detection is performed if 'cimg_OS' is not set by the user).
    #ifndef cimg_OS
    #if defined(unix)        || defined(__unix)      || defined(__unix__) \
     || defined(linux)       || defined(__linux)     || defined(__linux__) \
     || defined(sun)         || defined(__sun) \
     || defined(BSD)         || defined(__OpenBSD__) || defined(__NetBSD__) \
     || defined(__FreeBSD__) || defined (__DragonFly__) \
     || defined(sgi)         || defined(__sgi) \
     || defined(__MACOSX__)  || defined(__APPLE__) \
     || defined(__CYGWIN__)
    #define cimg_OS 1
    #elif defined(_MSC_VER) || defined(WIN32)  || defined(_WIN32) || defined(__WIN32__) \
       || defined(WIN64)    || defined(_WIN64) || defined(__WIN64__)
    #define cimg_OS 2
    #else
    #define cimg_OS 0
    #endif
    #elif !(cimg_OS==0 || cimg_OS==1 || cimg_OS==2)
    #error CImg Library: Invalid configuration variable 'cimg_OS'.
    #error (correct values are '0 = unknown OS', '1 = Unix-like OS', '2 = Microsoft Windows').
    #endif
    #ifndef cimg_date
    #define cimg_date __DATE__
    #endif
    #ifndef cimg_time
    #define cimg_time __TIME__
    #endif
    
    // Disable silly warnings on some Microsoft VC++ compilers.
    #ifdef _MSC_VER
    #pragma warning(push)
    #pragma warning(disable:4127)
    #pragma warning(disable:4244)
    #pragma warning(disable:4311)
    #pragma warning(disable:4312)
    #pragma warning(disable:4512)
    #pragma warning(disable:4571)
    #pragma warning(disable:4640)
    #pragma warning(disable:4706)
    #pragma warning(disable:4710)
    #pragma warning(disable:4800)
    #pragma warning(disable:4804)
    #pragma warning(disable:4820)
    #pragma warning(disable:4996)
    #define _CRT_SECURE_NO_DEPRECATE 1
    #define _CRT_SECURE_NO_WARNINGS 1
    #define _CRT_NONSTDC_NO_DEPRECATE 1
    #endif
    
    // Define correct string functions for each compiler and OS.
    #if cimg_OS==2 && defined(_MSC_VER)
    #define cimg_sscanf std::sscanf
    #define cimg_sprintf std::sprintf
    #define cimg_snprintf cimg::_snprintf
    #define cimg_vsnprintf cimg::_vsnprintf
    #else
    #include <stdio.h>
    #if defined(__MACOSX__) || defined(__APPLE__)
    #define cimg_sscanf cimg::_sscanf
    #define cimg_sprintf cimg::_sprintf
    #define cimg_snprintf cimg::_snprintf
    #define cimg_vsnprintf cimg::_vsnprintf
    #else
    #define cimg_sscanf std::sscanf
    #define cimg_sprintf std::sprintf
    #define cimg_snprintf snprintf
    #define cimg_vsnprintf vsnprintf
    #endif
    #endif
    
    // Include OS-specific headers.
    #if cimg_OS==1
    #include <sys/types.h>
    #include <sys/time.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <dirent.h>
    #include <fnmatch.h>
    #elif cimg_OS==2
    #ifndef std_fopen
    #define std_fopen cimg::win_fopen
    #endif
    #ifndef NOMINMAX
    #define NOMINMAX
    #endif
    #ifndef WIN32_LEAN_AND_MEAN
    #define WIN32_LEAN_AND_MEAN
    #endif
    #include <windows.h>
    #ifndef _WIN32_IE
    #define _WIN32_IE 0x0400
    #endif
    #include <shlobj.h>
    #include <process.h>
    #include <io.h>
    #endif
    
    // Look for C++11 features.
    #ifndef cimg_use_cpp11
    #if __cplusplus>201100
    #define cimg_use_cpp11 1
    #else
    #define cimg_use_cpp11 0
    #endif
    #endif
    #if cimg_use_cpp11==1
    #include <initializer_list>
    #include <utility>
    #endif
    
    // Convenient macro to define pragma
    #ifdef _MSC_VER
    #define cimg_pragma(x) __pragma(x)
    #else
    #define cimg_pragma(x) _Pragma(#x)
    #endif
    
    // Define own types 'cimg_long/ulong' and 'cimg_int64/uint64' to ensure portability.
    // ( constrained to 'sizeof(cimg_ulong/cimg_long) = sizeof(void*)' and 'sizeof(cimg_int64/cimg_uint64)=8' ).
    #if cimg_OS==2
    
    #define cimg_uint64 unsigned __int64
    #define cimg_int64 __int64
    #define cimg_ulong UINT_PTR
    #define cimg_long INT_PTR
    #ifdef _MSC_VER
    #define cimg_fuint64 "%I64u"
    #define cimg_fint64 "%I64d"
    #else
    #define cimg_fuint64 "%llu"
    #define cimg_fint64 "%lld"
    #endif
    
    #else
    
    #if UINTPTR_MAX==0xffffffff || defined(__arm__) || defined(_M_ARM)
    #define cimg_uint64 unsigned long long
    #define cimg_int64 long long
    #define cimg_fuint64 "%llu"
    #define cimg_fint64 "%lld"
    #else
    #define cimg_uint64 unsigned long
    #define cimg_int64 long
    #define cimg_fuint64 "%lu"
    #define cimg_fint64 "%ld"
    #endif
    
    #if defined(__arm__) || defined(_M_ARM)
    #define cimg_ulong unsigned long long
    #define cimg_long long long
    #else
    #define cimg_ulong unsigned long
    #define cimg_long long
    #endif
    
    #endif
    
    // Configure filename separator.
    //
    // Filename separator is set by default to '/', except for Windows where it is '\'.
    #ifndef cimg_file_separator
    #if cimg_OS==2
    #define cimg_file_separator '\\'
    #else
    #define cimg_file_separator '/'
    #endif
    #endif
    
    // Configure verbosity of output messages.
    //
    // Define 'cimg_verbosity' to: '0' to hide library messages (quiet mode).
    //                             '1' to output library messages on the console.
    //                             '2' to output library messages on a basic dialog window (default behavior).
    //                             '3' to do as '1' + add extra warnings (may slow down the code!).
    //                             '4' to do as '2' + add extra warnings (may slow down the code!).
    //
    // Define 'cimg_strict_warnings' to replace warning messages by exception throwns.
    //
    // Define 'cimg_use_vt100' to allow output of color messages on VT100-compatible terminals.
    #ifndef cimg_verbosity
    #if cimg_OS==2
    #define cimg_verbosity 2
    #else
    #define cimg_verbosity 1
    #endif
    #elif !(cimg_verbosity==0 || cimg_verbosity==1 || cimg_verbosity==2 || cimg_verbosity==3 || cimg_verbosity==4)
    #error CImg Library: Configuration variable 'cimg_verbosity' is badly defined.
    #error (should be { 0=quiet | 1=console | 2=dialog | 3=console+warnings | 4=dialog+warnings }).
    #endif
    
    // Configure display framework.
    //
    // Define 'cimg_display' to: '0' to disable display capabilities.
    //                           '1' to use the X-Window framework (X11).
    //                           '2' to use the Microsoft GDI32 framework.
    #ifndef cimg_display
    #if cimg_OS==0
    #define cimg_display 0
    #elif cimg_OS==1
    #define cimg_display 1
    #elif cimg_OS==2
    #define cimg_display 2
    #endif
    #elif !(cimg_display==0 || cimg_display==1 || cimg_display==2)
    #error CImg Library: Configuration variable 'cimg_display' is badly defined.
    #error (should be { 0=none | 1=X-Window (X11) | 2=Microsoft GDI32 }).
    #endif
    
    // Configure the 'abort' signal handler (does nothing by default).
    // A typical signal handler can be defined in your own source like this:
    // #define cimg_abort_test() if (is_abort) throw CImgAbortException("")
    //
    // where 'is_abort' is a boolean variable defined somewhere in your code and reachable in the method.
    // 'cimg_abort_test2()' does the same but is called more often (in inner loops).
    #if defined(cimg_abort_test) && defined(cimg_use_openmp)
    
    // Define abort macros to be used with OpenMP.
    #ifndef cimg_abort_init
    #define cimg_abort_init bool cimg_abort_go = true; cimg::unused(cimg_abort_go)
    #endif
    #ifndef cimg_abort_try
    #define cimg_abort_try if (cimg_abort_go) try
    #endif
    #ifndef cimg_abort_catch
    #define cimg_abort_catch() catch (CImgAbortException&) { cimg_pragma(omp atomic) cimg_abort_go&=false; }
    #endif
    #ifdef cimg_abort_test2
    #ifndef cimg_abort_try2
    #define cimg_abort_try2 cimg_abort_try
    #endif
    #ifndef cimg_abort_catch2
    #define cimg_abort_catch2() cimg_abort_catch()
    #endif
    #ifndef cimg_abort_catch_fill
    #define cimg_abort_catch_fill() \
      catch (CImgException& e) { cimg_pragma(omp critical) CImg<charT>::string(e._message).move_to(is_error); \
                                 cimg_pragma(omp atomic) cimg_abort_go&=false; }
    #endif
    #endif
    
    #endif
    
    #ifndef cimg_abort_test
    #define cimg_abort_test()
    #endif
    #ifndef cimg_abort_test2
    #define cimg_abort_test2()
    #endif
    #ifndef cimg_abort_init
    #define cimg_abort_init
    #endif
    #ifndef cimg_abort_try
    #define cimg_abort_try
    #endif
    #ifndef cimg_abort_catch
    #define cimg_abort_catch()
    #endif
    #ifndef cimg_abort_try2
    #define cimg_abort_try2
    #endif
    #ifndef cimg_abort_catch2
    #define cimg_abort_catch2()
    #endif
    #ifndef cimg_abort_catch_fill
    #define cimg_abort_catch_fill()
    #endif
    #ifndef std_fopen
    #define std_fopen std::fopen
    #endif
    
    // Include display-specific headers.
    #if cimg_display==1
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>
    #include <X11/keysym.h>
    #include <pthread.h>
    #ifdef cimg_use_xshm
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <X11/extensions/XShm.h>
    #endif
    #ifdef cimg_use_xrandr
    #include <X11/extensions/Xrandr.h>
    #endif
    #endif
    #ifndef cimg_appname
    #define cimg_appname "CImg"
    #endif
    
    // Configure OpenMP support.
    // (http://www.openmp.org)
    //
    // Define 'cimg_use_openmp' to enable OpenMP support.
    //
    // OpenMP directives may be used in a (very) few CImg functions to get
    // advantages of multi-core CPUs.
    #ifdef cimg_use_openmp
    #include <omp.h>
    #define cimg_pragma_openmp(p) cimg_pragma(omp p)
    #else
    #define cimg_pragma_openmp(p)
    #endif
    
    // Configure OpenCV support.
    // (http://opencv.willowgarage.com/wiki/)
    //
    // Define 'cimg_use_opencv' to enable OpenCV support.
    //
    // OpenCV library may be used to access images from cameras
    // (see method 'CImg<T>::load_camera()').
    #ifdef cimg_use_opencv
    #ifdef True
    #undef True
    #define _cimg_redefine_True
    #endif
    #ifdef False
    #undef False
    #define _cimg_redefine_False
    #endif
    #include <cstddef>
    #include "cv.h"
    #include "highgui.h"
    #endif
    
    // Configure LibPNG support.
    // (http://www.libpng.org)
    //
    // Define 'cimg_use_png' to enable LibPNG support.
    //
    // PNG library may be used to get a native support of '.png' files.
    // (see methods 'CImg<T>::{load,save}_png()'.
    #ifdef cimg_use_png
    extern "C" {
    #include "png.h"
    }
    #endif
    
    // Configure LibJPEG support.
    // (http://en.wikipedia.org/wiki/Libjpeg)
    //
    // Define 'cimg_use_jpeg' to enable LibJPEG support.
    //
    // JPEG library may be used to get a native support of '.jpg' files.
    // (see methods 'CImg<T>::{load,save}_jpeg()').
    #ifdef cimg_use_jpeg
    extern "C" {
    #include "jpeglib.h"
    #include "setjmp.h"
    }
    #endif
    
    // Configure LibTIFF support.
    // (http://www.libtiff.org)
    //
    // Define 'cimg_use_tiff' to enable LibTIFF support.
    //
    // TIFF library may be used to get a native support of '.tif' files.
    // (see methods 'CImg[List]<T>::{load,save}_tiff()').
    #ifdef cimg_use_tiff
    extern "C" {
    #define uint64 uint64_hack_
    #define int64 int64_hack_
    #include "tiffio.h"
    #undef uint64
    #undef int64
    }
    #endif
    
    // Configure LibMINC2 support.
    // (http://en.wikibooks.org/wiki/MINC/Reference/MINC2.0_File_Format_Reference)
    //
    // Define 'cimg_use_minc2' to enable LibMINC2 support.
    //
    // MINC2 library may be used to get a native support of '.mnc' files.
    // (see methods 'CImg<T>::{load,save}_minc2()').
    #ifdef cimg_use_minc2
    #include "minc_io_simple_volume.h"
    #include "minc_1_simple.h"
    #include "minc_1_simple_rw.h"
    #endif
    
    // Configure Zlib support.
    // (http://www.zlib.net)
    //
    // Define 'cimg_use_zlib' to enable Zlib support.
    //
    // Zlib library may be used to allow compressed data in '.cimgz' files
    // (see methods 'CImg[List]<T>::{load,save}_cimg()').
    #ifdef cimg_use_zlib
    extern "C" {
    #include "zlib.h"
    }
    #endif
    
    // Configure libcurl support.
    // (http://curl.haxx.se/libcurl/)
    //
    // Define 'cimg_use_curl' to enable libcurl support.
    //
    // Libcurl may be used to get a native support of file downloading from the network.
    // (see method 'cimg::load_network()'.)
    #ifdef cimg_use_curl
    #include "curl/curl.h"
    #endif
    
    // Configure Magick++ support.
    // (http://www.imagemagick.org/Magick++)
    //
    // Define 'cimg_use_magick' to enable Magick++ support.
    //
    // Magick++ library may be used to get a native support of various image file formats.
    // (see methods 'CImg<T>::{load,save}()').
    #ifdef cimg_use_magick
    #include "Magick++.h"
    #endif
    
    // Configure FFTW3 support.
    // (http://www.fftw.org)
    //
    // Define 'cimg_use_fftw3' to enable libFFTW3 support.
    //
    // FFTW3 library may be used to efficiently compute the Fast Fourier Transform
    // of image data, without restriction on the image size.
    // (see method 'CImg[List]<T>::FFT()').
    #ifdef cimg_use_fftw3
    extern "C" {
    #include "fftw3.h"
    }
    #endif
    
    // Configure LibBoard support.
    // (http://libboard.sourceforge.net/)
    //
    // Define 'cimg_use_board' to enable Board support.
    //
    // Board library may be used to draw 3d objects in vector-graphics canvas
    // that can be saved as '.ps' or '.svg' files afterwards.
    // (see method 'CImg<T>::draw_object3d()').
    #ifdef cimg_use_board
    #ifdef None
    #undef None
    #define _cimg_redefine_None
    #endif
    #include "Board.h"
    #endif
    
    // Configure OpenEXR support.
    // (http://www.openexr.com/)
    //
    // Define 'cimg_use_openexr' to enable OpenEXR support.
    //
    // OpenEXR library may be used to get a native support of '.exr' files.
    // (see methods 'CImg<T>::{load,save}_exr()').
    #ifdef cimg_use_openexr
    #include "ImfRgbaFile.h"
    #include "ImfInputFile.h"
    #include "ImfChannelList.h"
    #include "ImfMatrixAttribute.h"
    #include "ImfArray.h"
    #endif
    
    // Configure TinyEXR support.
    // (https://github.com/syoyo/tinyexr)
    //
    // Define 'cimg_use_tinyexr' to enable TinyEXR support.
    //
    // TinyEXR is a small, single header-only library to load and save OpenEXR(.exr) images.
    #ifdef cimg_use_tinyexr
    #ifndef TINYEXR_IMPLEMENTATION
    #define TINYEXR_IMPLEMENTATION
    #endif
    #include "tinyexr.h"
    #endif
    
    // Lapack configuration.
    // (http://www.netlib.org/lapack)
    //
    // Define 'cimg_use_lapack' to enable LAPACK support.
    //
    // Lapack library may be used in several CImg methods to speed up
    // matrix computations (eigenvalues, inverse, ...).
    #ifdef cimg_use_lapack
    extern "C" {
      extern void sgetrf_(int*, int*, float*, int*, int*, int*);
      extern void sgetri_(int*, float*, int*, int*, float*, int*, int*);
      extern void sgetrs_(char*, int*, int*, float*, int*, int*, float*, int*, int*);
      extern void sgesvd_(char*, char*, int*, int*, float*, int*, float*, float*, int*, float*, int*, float*, int*, int*);
      extern void ssyev_(char*, char*, int*, float*, int*, float*, float*, int*, int*);
      extern void dgetrf_(int*, int*, double*, int*, int*, int*);
      extern void dgetri_(int*, double*, int*, int*, double*, int*, int*);
      extern void dgetrs_(char*, int*, int*, double*, int*, int*, double*, int*, int*);
      extern void dgesvd_(char*, char*, int*, int*, double*, int*, double*, double*,
                          int*, double*, int*, double*, int*, int*);
      extern void dsyev_(char*, char*, int*, double*, int*, double*, double*, int*, int*);
      extern void dgels_(char*, int*,int*,int*,double*,int*,double*,int*,double*,int*,int*);
      extern void sgels_(char*, int*,int*,int*,float*,int*,float*,int*,float*,int*,int*);
    }
    #endif
    
    // Check if min/max/PI macros are defined.
    //
    // CImg does not compile if macros 'min', 'max' or 'PI' are defined,
    // because it redefines functions min(), max() and const variable PI in the cimg:: namespace.
    // so it '#undef' these macros if necessary, and restore them to reasonable
    // values at the end of this file.
    #ifdef min
    #undef min
    #define _cimg_redefine_min
    #endif
    #ifdef max
    #undef max
    #define _cimg_redefine_max
    #endif
    #ifdef PI
    #undef PI
    #define _cimg_redefine_PI
    #endif
    
    // Define 'cimg_library' namespace suffix.
    //
    // You may want to add a suffix to the 'cimg_library' namespace, for instance if you need to work
    // with several versions of the library at the same time.
    #ifdef cimg_namespace_suffix
    #define __cimg_library_suffixed(s) cimg_library_##s
    #define _cimg_library_suffixed(s) __cimg_library_suffixed(s)
    #define cimg_library_suffixed _cimg_library_suffixed(cimg_namespace_suffix)
    #else
    #define cimg_library_suffixed cimg_library
    #endif
    
    /*------------------------------------------------------------------------------
      #
      # Define user-friendly macros.
      #
      # These CImg macros are prefixed by 'cimg_' and can be used safely in your own
      # code. They are useful to parse command line options, or to write image loops.
      #
      ------------------------------------------------------------------------------*/
    
    // Macros to define program usage, and retrieve command line arguments.
    #define cimg_usage(usage) cimg_library_suffixed::cimg::option((char*)0,argc,argv,(char*)0,usage,false)
    #define cimg_help(str) cimg_library_suffixed::cimg::option((char*)0,argc,argv,str,(char*)0)
    #define cimg_option(name,defaut,usage) cimg_library_suffixed::cimg::option(name,argc,argv,defaut,usage)
    
    // Macros to define and manipulate local neighborhoods.
    #define CImg_2x2(I,T) T I[4]; \
                          T& I##cc = I[0]; T& I##nc = I[1]; \
                          T& I##cn = I[2]; T& I##nn = I[3]; \
                          I##cc = I##nc = \
                          I##cn = I##nn = 0
    
    #define CImg_3x3(I,T) T I[9]; \
                          T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; \
                          T& I##pc = I[3]; T& I##cc = I[4]; T& I##nc = I[5]; \
                          T& I##pn = I[6]; T& I##cn = I[7]; T& I##nn = I[8]; \
                          I##pp = I##cp = I##np = \
                          I##pc = I##cc = I##nc = \
                          I##pn = I##cn = I##nn = 0
    
    #define CImg_4x4(I,T) T I[16]; \
                          T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; T& I##ap = I[3]; \
                          T& I##pc = I[4]; T& I##cc = I[5]; T& I##nc = I[6]; T& I##ac = I[7]; \
                          T& I##pn = I[8]; T& I##cn = I[9]; T& I##nn = I[10]; T& I##an = I[11]; \
                          T& I##pa = I[12]; T& I##ca = I[13]; T& I##na = I[14]; T& I##aa = I[15]; \
                          I##pp = I##cp = I##np = I##ap = \
                          I##pc = I##cc = I##nc = I##ac = \
                          I##pn = I##cn = I##nn = I##an = \
                          I##pa = I##ca = I##na = I##aa = 0
    
    #define CImg_5x5(I,T) T I[25]; \
                          T& I##bb = I[0]; T& I##pb = I[1]; T& I##cb = I[2]; T& I##nb = I[3]; T& I##ab = I[4]; \
                          T& I##bp = I[5]; T& I##pp = I[6]; T& I##cp = I[7]; T& I##np = I[8]; T& I##ap = I[9]; \
                          T& I##bc = I[10]; T& I##pc = I[11]; T& I##cc = I[12]; T& I##nc = I[13]; T& I##ac = I[14]; \
                          T& I##bn = I[15]; T& I##pn = I[16]; T& I##cn = I[17]; T& I##nn = I[18]; T& I##an = I[19]; \
                          T& I##ba = I[20]; T& I##pa = I[21]; T& I##ca = I[22]; T& I##na = I[23]; T& I##aa = I[24]; \
                          I##bb = I##pb = I##cb = I##nb = I##ab = \
                          I##bp = I##pp = I##cp = I##np = I##ap = \
                          I##bc = I##pc = I##cc = I##nc = I##ac = \
                          I##bn = I##pn = I##cn = I##nn = I##an = \
                          I##ba = I##pa = I##ca = I##na = I##aa = 0
    
    #define CImg_2x2x2(I,T) T I[8]; \
                          T& I##ccc = I[0]; T& I##ncc = I[1]; \
                          T& I##cnc = I[2]; T& I##nnc = I[3]; \
                          T& I##ccn = I[4]; T& I##ncn = I[5]; \
                          T& I##cnn = I[6]; T& I##nnn = I[7]; \
                          I##ccc = I##ncc = \
                          I##cnc = I##nnc = \
                          I##ccn = I##ncn = \
                          I##cnn = I##nnn = 0
    
    #define CImg_3x3x3(I,T) T I[27]; \
                          T& I##ppp = I[0]; T& I##cpp = I[1]; T& I##npp = I[2]; \
                          T& I##pcp = I[3]; T& I##ccp = I[4]; T& I##ncp = I[5]; \
                          T& I##pnp = I[6]; T& I##cnp = I[7]; T& I##nnp = I[8]; \
                          T& I##ppc = I[9]; T& I##cpc = I[10]; T& I##npc = I[11]; \
                          T& I##pcc = I[12]; T& I##ccc = I[13]; T& I##ncc = I[14]; \
                          T& I##pnc = I[15]; T& I##cnc = I[16]; T& I##nnc = I[17]; \
                          T& I##ppn = I[18]; T& I##cpn = I[19]; T& I##npn = I[20]; \
                          T& I##pcn = I[21]; T& I##ccn = I[22]; T& I##ncn = I[23]; \
                          T& I##pnn = I[24]; T& I##cnn = I[25]; T& I##nnn = I[26]; \
                          I##ppp = I##cpp = I##npp = \
                          I##pcp = I##ccp = I##ncp = \
                          I##pnp = I##cnp = I##nnp = \
                          I##ppc = I##cpc = I##npc = \
                          I##pcc = I##ccc = I##ncc = \
                          I##pnc = I##cnc = I##nnc = \
                          I##ppn = I##cpn = I##npn = \
                          I##pcn = I##ccn = I##ncn = \
                          I##pnn = I##cnn = I##nnn = 0
    
    #define cimg_get2x2(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(x,y,z,c), I[1] = (T)(img)(_n1##x,y,z,c), I[2] = (T)(img)(x,_n1##y,z,c), \
      I[3] = (T)(img)(_n1##x,_n1##y,z,c)
    
    #define cimg_get3x3(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(_p1##x,_p1##y,z,c), I[1] = (T)(img)(x,_p1##y,z,c), I[2] = (T)(img)(_n1##x,_p1##y,z,c), \
      I[3] = (T)(img)(_p1##x,y,z,c), I[4] = (T)(img)(x,y,z,c), I[5] = (T)(img)(_n1##x,y,z,c), \
      I[6] = (T)(img)(_p1##x,_n1##y,z,c), I[7] = (T)(img)(x,_n1##y,z,c), I[8] = (T)(img)(_n1##x,_n1##y,z,c)
    
    #define cimg_get4x4(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(_p1##x,_p1##y,z,c), I[1] = (T)(img)(x,_p1##y,z,c), I[2] = (T)(img)(_n1##x,_p1##y,z,c), \
      I[3] = (T)(img)(_n2##x,_p1##y,z,c), I[4] = (T)(img)(_p1##x,y,z,c), I[5] = (T)(img)(x,y,z,c), \
      I[6] = (T)(img)(_n1##x,y,z,c), I[7] = (T)(img)(_n2##x,y,z,c), I[8] = (T)(img)(_p1##x,_n1##y,z,c), \
      I[9] = (T)(img)(x,_n1##y,z,c), I[10] = (T)(img)(_n1##x,_n1##y,z,c), I[11] = (T)(img)(_n2##x,_n1##y,z,c), \
      I[12] = (T)(img)(_p1##x,_n2##y,z,c), I[13] = (T)(img)(x,_n2##y,z,c), I[14] = (T)(img)(_n1##x,_n2##y,z,c), \
      I[15] = (T)(img)(_n2##x,_n2##y,z,c)
    
    #define cimg_get5x5(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(_p2##x,_p2##y,z,c), I[1] = (T)(img)(_p1##x,_p2##y,z,c), I[2] = (T)(img)(x,_p2##y,z,c), \
      I[3] = (T)(img)(_n1##x,_p2##y,z,c), I[4] = (T)(img)(_n2##x,_p2##y,z,c), I[5] = (T)(img)(_p2##x,_p1##y,z,c), \
      I[6] = (T)(img)(_p1##x,_p1##y,z,c), I[7] = (T)(img)(x,_p1##y,z,c), I[8] = (T)(img)(_n1##x,_p1##y,z,c), \
      I[9] = (T)(img)(_n2##x,_p1##y,z,c), I[10] = (T)(img)(_p2##x,y,z,c), I[11] = (T)(img)(_p1##x,y,z,c), \
      I[12] = (T)(img)(x,y,z,c), I[13] = (T)(img)(_n1##x,y,z,c), I[14] = (T)(img)(_n2##x,y,z,c), \
      I[15] = (T)(img)(_p2##x,_n1##y,z,c), I[16] = (T)(img)(_p1##x,_n1##y,z,c), I[17] = (T)(img)(x,_n1##y,z,c), \
      I[18] = (T)(img)(_n1##x,_n1##y,z,c), I[19] = (T)(img)(_n2##x,_n1##y,z,c), I[20] = (T)(img)(_p2##x,_n2##y,z,c), \
      I[21] = (T)(img)(_p1##x,_n2##y,z,c), I[22] = (T)(img)(x,_n2##y,z,c), I[23] = (T)(img)(_n1##x,_n2##y,z,c), \
      I[24] = (T)(img)(_n2##x,_n2##y,z,c)
    
    #define cimg_get6x6(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(_p2##x,_p2##y,z,c), I[1] = (T)(img)(_p1##x,_p2##y,z,c), I[2] = (T)(img)(x,_p2##y,z,c), \
      I[3] = (T)(img)(_n1##x,_p2##y,z,c), I[4] = (T)(img)(_n2##x,_p2##y,z,c), I[5] = (T)(img)(_n3##x,_p2##y,z,c), \
      I[6] = (T)(img)(_p2##x,_p1##y,z,c), I[7] = (T)(img)(_p1##x,_p1##y,z,c), I[8] = (T)(img)(x,_p1##y,z,c), \
      I[9] = (T)(img)(_n1##x,_p1##y,z,c), I[10] = (T)(img)(_n2##x,_p1##y,z,c), I[11] = (T)(img)(_n3##x,_p1##y,z,c), \
      I[12] = (T)(img)(_p2##x,y,z,c), I[13] = (T)(img)(_p1##x,y,z,c), I[14] = (T)(img)(x,y,z,c), \
      I[15] = (T)(img)(_n1##x,y,z,c), I[16] = (T)(img)(_n2##x,y,z,c), I[17] = (T)(img)(_n3##x,y,z,c), \
      I[18] = (T)(img)(_p2##x,_n1##y,z,c), I[19] = (T)(img)(_p1##x,_n1##y,z,c), I[20] = (T)(img)(x,_n1##y,z,c), \
      I[21] = (T)(img)(_n1##x,_n1##y,z,c), I[22] = (T)(img)(_n2##x,_n1##y,z,c), I[23] = (T)(img)(_n3##x,_n1##y,z,c), \
      I[24] = (T)(img)(_p2##x,_n2##y,z,c), I[25] = (T)(img)(_p1##x,_n2##y,z,c), I[26] = (T)(img)(x,_n2##y,z,c), \
      I[27] = (T)(img)(_n1##x,_n2##y,z,c), I[28] = (T)(img)(_n2##x,_n2##y,z,c), I[29] = (T)(img)(_n3##x,_n2##y,z,c), \
      I[30] = (T)(img)(_p2##x,_n3##y,z,c), I[31] = (T)(img)(_p1##x,_n3##y,z,c), I[32] = (T)(img)(x,_n3##y,z,c), \
      I[33] = (T)(img)(_n1##x,_n3##y,z,c), I[34] = (T)(img)(_n2##x,_n3##y,z,c), I[35] = (T)(img)(_n3##x,_n3##y,z,c)
    
    #define cimg_get7x7(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(_p3##x,_p3##y,z,c), I[1] = (T)(img)(_p2##x,_p3##y,z,c), I[2] = (T)(img)(_p1##x,_p3##y,z,c), \
      I[3] = (T)(img)(x,_p3##y,z,c), I[4] = (T)(img)(_n1##x,_p3##y,z,c), I[5] = (T)(img)(_n2##x,_p3##y,z,c), \
      I[6] = (T)(img)(_n3##x,_p3##y,z,c), I[7] = (T)(img)(_p3##x,_p2##y,z,c), I[8] = (T)(img)(_p2##x,_p2##y,z,c), \
      I[9] = (T)(img)(_p1##x,_p2##y,z,c), I[10] = (T)(img)(x,_p2##y,z,c), I[11] = (T)(img)(_n1##x,_p2##y,z,c), \
      I[12] = (T)(img)(_n2##x,_p2##y,z,c), I[13] = (T)(img)(_n3##x,_p2##y,z,c), I[14] = (T)(img)(_p3##x,_p1##y,z,c), \
      I[15] = (T)(img)(_p2##x,_p1##y,z,c), I[16] = (T)(img)(_p1##x,_p1##y,z,c), I[17] = (T)(img)(x,_p1##y,z,c), \
      I[18] = (T)(img)(_n1##x,_p1##y,z,c), I[19] = (T)(img)(_n2##x,_p1##y,z,c), I[20] = (T)(img)(_n3##x,_p1##y,z,c), \
      I[21] = (T)(img)(_p3##x,y,z,c), I[22] = (T)(img)(_p2##x,y,z,c), I[23] = (T)(img)(_p1##x,y,z,c), \
      I[24] = (T)(img)(x,y,z,c), I[25] = (T)(img)(_n1##x,y,z,c), I[26] = (T)(img)(_n2##x,y,z,c), \
      I[27] = (T)(img)(_n3##x,y,z,c), I[28] = (T)(img)(_p3##x,_n1##y,z,c), I[29] = (T)(img)(_p2##x,_n1##y,z,c), \
      I[30] = (T)(img)(_p1##x,_n1##y,z,c), I[31] = (T)(img)(x,_n1##y,z,c), I[32] = (T)(img)(_n1##x,_n1##y,z,c), \
      I[33] = (T)(img)(_n2##x,_n1##y,z,c), I[34] = (T)(img)(_n3##x,_n1##y,z,c), I[35] = (T)(img)(_p3##x,_n2##y,z,c), \
      I[36] = (T)(img)(_p2##x,_n2##y,z,c), I[37] = (T)(img)(_p1##x,_n2##y,z,c), I[38] = (T)(img)(x,_n2##y,z,c), \
      I[39] = (T)(img)(_n1##x,_n2##y,z,c), I[40] = (T)(img)(_n2##x,_n2##y,z,c), I[41] = (T)(img)(_n3##x,_n2##y,z,c), \
      I[42] = (T)(img)(_p3##x,_n3##y,z,c), I[43] = (T)(img)(_p2##x,_n3##y,z,c), I[44] = (T)(img)(_p1##x,_n3##y,z,c), \
      I[45] = (T)(img)(x,_n3##y,z,c), I[46] = (T)(img)(_n1##x,_n3##y,z,c), I[47] = (T)(img)(_n2##x,_n3##y,z,c), \
      I[48] = (T)(img)(_n3##x,_n3##y,z,c)
    
    #define cimg_get8x8(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(_p3##x,_p3##y,z,c), I[1] = (T)(img)(_p2##x,_p3##y,z,c), I[2] = (T)(img)(_p1##x,_p3##y,z,c), \
      I[3] = (T)(img)(x,_p3##y,z,c), I[4] = (T)(img)(_n1##x,_p3##y,z,c), I[5] = (T)(img)(_n2##x,_p3##y,z,c), \
      I[6] = (T)(img)(_n3##x,_p3##y,z,c), I[7] = (T)(img)(_n4##x,_p3##y,z,c), I[8] = (T)(img)(_p3##x,_p2##y,z,c), \
      I[9] = (T)(img)(_p2##x,_p2##y,z,c), I[10] = (T)(img)(_p1##x,_p2##y,z,c), I[11] = (T)(img)(x,_p2##y,z,c), \
      I[12] = (T)(img)(_n1##x,_p2##y,z,c), I[13] = (T)(img)(_n2##x,_p2##y,z,c), I[14] = (T)(img)(_n3##x,_p2##y,z,c), \
      I[15] = (T)(img)(_n4##x,_p2##y,z,c), I[16] = (T)(img)(_p3##x,_p1##y,z,c), I[17] = (T)(img)(_p2##x,_p1##y,z,c), \
      I[18] = (T)(img)(_p1##x,_p1##y,z,c), I[19] = (T)(img)(x,_p1##y,z,c), I[20] = (T)(img)(_n1##x,_p1##y,z,c), \
      I[21] = (T)(img)(_n2##x,_p1##y,z,c), I[22] = (T)(img)(_n3##x,_p1##y,z,c), I[23] = (T)(img)(_n4##x,_p1##y,z,c), \
      I[24] = (T)(img)(_p3##x,y,z,c), I[25] = (T)(img)(_p2##x,y,z,c), I[26] = (T)(img)(_p1##x,y,z,c), \
      I[27] = (T)(img)(x,y,z,c), I[28] = (T)(img)(_n1##x,y,z,c), I[29] = (T)(img)(_n2##x,y,z,c), \
      I[30] = (T)(img)(_n3##x,y,z,c), I[31] = (T)(img)(_n4##x,y,z,c), I[32] = (T)(img)(_p3##x,_n1##y,z,c), \
      I[33] = (T)(img)(_p2##x,_n1##y,z,c), I[34] = (T)(img)(_p1##x,_n1##y,z,c), I[35] = (T)(img)(x,_n1##y,z,c), \
      I[36] = (T)(img)(_n1##x,_n1##y,z,c), I[37] = (T)(img)(_n2##x,_n1##y,z,c), I[38] = (T)(img)(_n3##x,_n1##y,z,c), \
      I[39] = (T)(img)(_n4##x,_n1##y,z,c), I[40] = (T)(img)(_p3##x,_n2##y,z,c), I[41] = (T)(img)(_p2##x,_n2##y,z,c), \
      I[42] = (T)(img)(_p1##x,_n2##y,z,c), I[43] = (T)(img)(x,_n2##y,z,c), I[44] = (T)(img)(_n1##x,_n2##y,z,c), \
      I[45] = (T)(img)(_n2##x,_n2##y,z,c), I[46] = (T)(img)(_n3##x,_n2##y,z,c), I[47] = (T)(img)(_n4##x,_n2##y,z,c), \
      I[48] = (T)(img)(_p3##x,_n3##y,z,c), I[49] = (T)(img)(_p2##x,_n3##y,z,c), I[50] = (T)(img)(_p1##x,_n3##y,z,c), \
      I[51] = (T)(img)(x,_n3##y,z,c), I[52] = (T)(img)(_n1##x,_n3##y,z,c), I[53] = (T)(img)(_n2##x,_n3##y,z,c), \
      I[54] = (T)(img)(_n3##x,_n3##y,z,c), I[55] = (T)(img)(_n4##x,_n3##y,z,c), I[56] = (T)(img)(_p3##x,_n4##y,z,c), \
      I[57] = (T)(img)(_p2##x,_n4##y,z,c), I[58] = (T)(img)(_p1##x,_n4##y,z,c), I[59] = (T)(img)(x,_n4##y,z,c), \
      I[60] = (T)(img)(_n1##x,_n4##y,z,c), I[61] = (T)(img)(_n2##x,_n4##y,z,c), I[62] = (T)(img)(_n3##x,_n4##y,z,c), \
      I[63] = (T)(img)(_n4##x,_n4##y,z,c);
    
    #define cimg_get9x9(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(_p4##x,_p4##y,z,c), I[1] = (T)(img)(_p3##x,_p4##y,z,c), I[2] = (T)(img)(_p2##x,_p4##y,z,c), \
      I[3] = (T)(img)(_p1##x,_p4##y,z,c), I[4] = (T)(img)(x,_p4##y,z,c), I[5] = (T)(img)(_n1##x,_p4##y,z,c), \
      I[6] = (T)(img)(_n2##x,_p4##y,z,c), I[7] = (T)(img)(_n3##x,_p4##y,z,c), I[8] = (T)(img)(_n4##x,_p4##y,z,c), \
      I[9] = (T)(img)(_p4##x,_p3##y,z,c), I[10] = (T)(img)(_p3##x,_p3##y,z,c), I[11] = (T)(img)(_p2##x,_p3##y,z,c), \
      I[12] = (T)(img)(_p1##x,_p3##y,z,c), I[13] = (T)(img)(x,_p3##y,z,c), I[14] = (T)(img)(_n1##x,_p3##y,z,c), \
      I[15] = (T)(img)(_n2##x,_p3##y,z,c), I[16] = (T)(img)(_n3##x,_p3##y,z,c), I[17] = (T)(img)(_n4##x,_p3##y,z,c), \
      I[18] = (T)(img)(_p4##x,_p2##y,z,c), I[19] = (T)(img)(_p3##x,_p2##y,z,c), I[20] = (T)(img)(_p2##x,_p2##y,z,c), \
      I[21] = (T)(img)(_p1##x,_p2##y,z,c), I[22] = (T)(img)(x,_p2##y,z,c), I[23] = (T)(img)(_n1##x,_p2##y,z,c), \
      I[24] = (T)(img)(_n2##x,_p2##y,z,c), I[25] = (T)(img)(_n3##x,_p2##y,z,c), I[26] = (T)(img)(_n4##x,_p2##y,z,c), \
      I[27] = (T)(img)(_p4##x,_p1##y,z,c), I[28] = (T)(img)(_p3##x,_p1##y,z,c), I[29] = (T)(img)(_p2##x,_p1##y,z,c), \
      I[30] = (T)(img)(_p1##x,_p1##y,z,c), I[31] = (T)(img)(x,_p1##y,z,c), I[32] = (T)(img)(_n1##x,_p1##y,z,c), \
      I[33] = (T)(img)(_n2##x,_p1##y,z,c), I[34] = (T)(img)(_n3##x,_p1##y,z,c), I[35] = (T)(img)(_n4##x,_p1##y,z,c), \
      I[36] = (T)(img)(_p4##x,y,z,c), I[37] = (T)(img)(_p3##x,y,z,c), I[38] = (T)(img)(_p2##x,y,z,c), \
      I[39] = (T)(img)(_p1##x,y,z,c), I[40] = (T)(img)(x,y,z,c), I[41] = (T)(img)(_n1##x,y,z,c), \
      I[42] = (T)(img)(_n2##x,y,z,c), I[43] = (T)(img)(_n3##x,y,z,c), I[44] = (T)(img)(_n4##x,y,z,c), \
      I[45] = (T)(img)(_p4##x,_n1##y,z,c), I[46] = (T)(img)(_p3##x,_n1##y,z,c), I[47] = (T)(img)(_p2##x,_n1##y,z,c), \
      I[48] = (T)(img)(_p1##x,_n1##y,z,c), I[49] = (T)(img)(x,_n1##y,z,c), I[50] = (T)(img)(_n1##x,_n1##y,z,c), \
      I[51] = (T)(img)(_n2##x,_n1##y,z,c), I[52] = (T)(img)(_n3##x,_n1##y,z,c), I[53] = (T)(img)(_n4##x,_n1##y,z,c), \
      I[54] = (T)(img)(_p4##x,_n2##y,z,c), I[55] = (T)(img)(_p3##x,_n2##y,z,c), I[56] = (T)(img)(_p2##x,_n2##y,z,c), \
      I[57] = (T)(img)(_p1##x,_n2##y,z,c), I[58] = (T)(img)(x,_n2##y,z,c), I[59] = (T)(img)(_n1##x,_n2##y,z,c), \
      I[60] = (T)(img)(_n2##x,_n2##y,z,c), I[61] = (T)(img)(_n3##x,_n2##y,z,c), I[62] = (T)(img)(_n4##x,_n2##y,z,c), \
      I[63] = (T)(img)(_p4##x,_n3##y,z,c), I[64] = (T)(img)(_p3##x,_n3##y,z,c), I[65] = (T)(img)(_p2##x,_n3##y,z,c), \
      I[66] = (T)(img)(_p1##x,_n3##y,z,c), I[67] = (T)(img)(x,_n3##y,z,c), I[68] = (T)(img)(_n1##x,_n3##y,z,c), \
      I[69] = (T)(img)(_n2##x,_n3##y,z,c), I[70] = (T)(img)(_n3##x,_n3##y,z,c), I[71] = (T)(img)(_n4##x,_n3##y,z,c), \
      I[72] = (T)(img)(_p4##x,_n4##y,z,c), I[73] = (T)(img)(_p3##x,_n4##y,z,c), I[74] = (T)(img)(_p2##x,_n4##y,z,c), \
      I[75] = (T)(img)(_p1##x,_n4##y,z,c), I[76] = (T)(img)(x,_n4##y,z,c), I[77] = (T)(img)(_n1##x,_n4##y,z,c), \
      I[78] = (T)(img)(_n2##x,_n4##y,z,c), I[79] = (T)(img)(_n3##x,_n4##y,z,c), I[80] = (T)(img)(_n4##x,_n4##y,z,c)
    
    #define cimg_get2x2x2(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(x,y,z,c), I[1] = (T)(img)(_n1##x,y,z,c), I[2] = (T)(img)(x,_n1##y,z,c), \
      I[3] = (T)(img)(_n1##x,_n1##y,z,c), I[4] = (T)(img)(x,y,_n1##z,c), I[5] = (T)(img)(_n1##x,y,_n1##z,c), \
      I[6] = (T)(img)(x,_n1##y,_n1##z,c), I[7] = (T)(img)(_n1##x,_n1##y,_n1##z,c)
    
    #define cimg_get3x3x3(img,x,y,z,c,I,T) \
      I[0] = (T)(img)(_p1##x,_p1##y,_p1##z,c), I[1] = (T)(img)(x,_p1##y,_p1##z,c), \
      I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c), I[3] = (T)(img)(_p1##x,y,_p1##z,c), I[4] = (T)(img)(x,y,_p1##z,c), \
      I[5] = (T)(img)(_n1##x,y,_p1##z,c), I[6] = (T)(img)(_p1##x,_n1##y,_p1##z,c), I[7] = (T)(img)(x,_n1##y,_p1##z,c), \
      I[8] = (T)(img)(_n1##x,_n1##y,_p1##z,c), I[9] = (T)(img)(_p1##x,_p1##y,z,c), I[10] = (T)(img)(x,_p1##y,z,c), \
      I[11] = (T)(img)(_n1##x,_p1##y,z,c), I[12] = (T)(img)(_p1##x,y,z,c), I[13] = (T)(img)(x,y,z,c), \
      I[14] = (T)(img)(_n1##x,y,z,c), I[15] = (T)(img)(_p1##x,_n1##y,z,c), I[16] = (T)(img)(x,_n1##y,z,c), \
      I[17] = (T)(img)(_n1##x,_n1##y,z,c), I[18] = (T)(img)(_p1##x,_p1##y,_n1##z,c), I[19] = (T)(img)(x,_p1##y,_n1##z,c), \
      I[20] = (T)(img)(_n1##x,_p1##y,_n1##z,c), I[21] = (T)(img)(_p1##x,y,_n1##z,c), I[22] = (T)(img)(x,y,_n1##z,c), \
      I[23] = (T)(img)(_n1##x,y,_n1##z,c), I[24] = (T)(img)(_p1##x,_n1##y,_n1##z,c), I[25] = (T)(img)(x,_n1##y,_n1##z,c), \
      I[26] = (T)(img)(_n1##x,_n1##y,_n1##z,c)
    
    // Macros to perform various image loops.
    //
    // These macros are simpler to use than loops with C++ iterators.
    #define cimg_for(img,ptrs,T_ptrs) \
      for (T_ptrs *ptrs = (img)._data, *_max##ptrs = (img)._data + (img).size(); ptrs<_max##ptrs; ++ptrs)
    #define cimg_rof(img,ptrs,T_ptrs) for (T_ptrs *ptrs = (img)._data + (img).size() - 1; ptrs>=(img)._data; --ptrs)
    #define cimg_foroff(img,off) for (cimg_ulong off = 0, _max##off = (img).size(); off<_max##off; ++off)
    
    #define cimg_for1(bound,i) for (int i = 0; i<(int)(bound); ++i)
    #define cimg_forX(img,x) cimg_for1((img)._width,x)
    #define cimg_forY(img,y) cimg_for1((img)._height,y)
    #define cimg_forZ(img,z) cimg_for1((img)._depth,z)
    #define cimg_forC(img,c) cimg_for1((img)._spectrum,c)
    #define cimg_forXY(img,x,y) cimg_forY(img,y) cimg_forX(img,x)
    #define cimg_forXZ(img,x,z) cimg_forZ(img,z) cimg_forX(img,x)
    #define cimg_forYZ(img,y,z) cimg_forZ(img,z) cimg_forY(img,y)
    #define cimg_forXC(img,x,c) cimg_forC(img,c) cimg_forX(img,x)
    #define cimg_forYC(img,y,c) cimg_forC(img,c) cimg_forY(img,y)
    #define cimg_forZC(img,z,c) cimg_forC(img,c) cimg_forZ(img,z)
    #define cimg_forXYZ(img,x,y,z) cimg_forZ(img,z) cimg_forXY(img,x,y)
    #define cimg_forXYC(img,x,y,c) cimg_forC(img,c) cimg_forXY(img,x,y)
    #define cimg_forXZC(img,x,z,c) cimg_forC(img,c) cimg_forXZ(img,x,z)
    #define cimg_forYZC(img,y,z,c) cimg_forC(img,c) cimg_forYZ(img,y,z)
    #define cimg_forXYZC(img,x,y,z,c) cimg_forC(img,c) cimg_forXYZ(img,x,y,z)
    
    #define cimg_rof1(bound,i) for (int i = (int)(bound) - 1; i>=0; --i)
    #define cimg_rofX(img,x) cimg_rof1((img)._width,x)
    #define cimg_rofY(img,y) cimg_rof1((img)._height,y)
    #define cimg_rofZ(img,z) cimg_rof1((img)._depth,z)
    #define cimg_rofC(img,c) cimg_rof1((img)._spectrum,c)
    #define cimg_rofXY(img,x,y) cimg_rofY(img,y) cimg_rofX(img,x)
    #define cimg_rofXZ(img,x,z) cimg_rofZ(img,z) cimg_rofX(img,x)
    #define cimg_rofYZ(img,y,z) cimg_rofZ(img,z) cimg_rofY(img,y)
    #define cimg_rofXC(img,x,c) cimg_rofC(img,c) cimg_rofX(img,x)
    #define cimg_rofYC(img,y,c) cimg_rofC(img,c) cimg_rofY(img,y)
    #define cimg_rofZC(img,z,c) cimg_rofC(img,c) cimg_rofZ(img,z)
    #define cimg_rofXYZ(img,x,y,z) cimg_rofZ(img,z) cimg_rofXY(img,x,y)
    #define cimg_rofXYC(img,x,y,c) cimg_rofC(img,c) cimg_rofXY(img,x,y)
    #define cimg_rofXZC(img,x,z,c) cimg_rofC(img,c) cimg_rofXZ(img,x,z)
    #define cimg_rofYZC(img,y,z,c) cimg_rofC(img,c) cimg_rofYZ(img,y,z)
    #define cimg_rofXYZC(img,x,y,z,c) cimg_rofC(img,c) cimg_rofXYZ(img,x,y,z)
    
    #define cimg_for_in1(bound,i0,i1,i) \
     for (int i = (int)(i0)<0?0:(int)(i0), _max##i = (int)(i1)<(int)(bound)?(int)(i1):(int)(bound) - 1; i<=_max##i; ++i)
    #define cimg_for_inX(img,x0,x1,x) cimg_for_in1((img)._width,x0,x1,x)
    #define cimg_for_inY(img,y0,y1,y) cimg_for_in1((img)._height,y0,y1,y)
    #define cimg_for_inZ(img,z0,z1,z) cimg_for_in1((img)._depth,z0,z1,z)
    #define cimg_for_inC(img,c0,c1,c) cimg_for_in1((img)._spectrum,c0,c1,c)
    #define cimg_for_inXY(img,x0,y0,x1,y1,x,y) cimg_for_inY(img,y0,y1,y) cimg_for_inX(img,x0,x1,x)
    #define cimg_for_inXZ(img,x0,z0,x1,z1,x,z) cimg_for_inZ(img,z0,z1,z) cimg_for_inX(img,x0,x1,x)
    #define cimg_for_inXC(img,x0,c0,x1,c1,x,c) cimg_for_inC(img,c0,c1,c) cimg_for_inX(img,x0,x1,x)
    #define cimg_for_inYZ(img,y0,z0,y1,z1,y,z) cimg_for_inZ(img,x0,z1,z) cimg_for_inY(img,y0,y1,y)
    #define cimg_for_inYC(img,y0,c0,y1,c1,y,c) cimg_for_inC(img,c0,c1,c) cimg_for_inY(img,y0,y1,y)
    #define cimg_for_inZC(img,z0,c0,z1,c1,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inZ(img,z0,z1,z)
    #define cimg_for_inXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_inZ(img,z0,z1,z) cimg_for_inXY(img,x0,y0,x1,y1,x,y)
    #define cimg_for_inXYC(img,x0,y0,c0,x1,y1,c1,x,y,c) cimg_for_inC(img,c0,c1,c) cimg_for_inXY(img,x0,y0,x1,y1,x,y)
    #define cimg_for_inXZC(img,x0,z0,c0,x1,z1,c1,x,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inXZ(img,x0,z0,x1,z1,x,z)
    #define cimg_for_inYZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inYZ(img,y0,z0,y1,z1,y,z)
    #define cimg_for_inXYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \
      cimg_for_inC(img,c0,c1,c) cimg_for_inXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
    #define cimg_for_insideX(img,x,n) cimg_for_inX(img,n,(img)._width - 1 - (n),x)
    #define cimg_for_insideY(img,y,n) cimg_for_inY(img,n,(img)._height - 1 - (n),y)
    #define cimg_for_insideZ(img,z,n) cimg_for_inZ(img,n,(img)._depth  - 1 - (n),z)
    #define cimg_for_insideC(img,c,n) cimg_for_inC(img,n,(img)._spectrum - 1 - (n),c)
    #define cimg_for_insideXY(img,x,y,n) cimg_for_inXY(img,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),x,y)
    #define cimg_for_insideXYZ(img,x,y,z,n) \
      cimg_for_inXYZ(img,n,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),(img)._depth - 1 - (n),x,y,z)
    #define cimg_for_insideXYZC(img,x,y,z,c,n) \
      cimg_for_inXYZ(img,n,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),(img)._depth - 1 - (n),x,y,z)
    
    #define cimg_for_out1(boundi,i0,i1,i) \
     for (int i = (int)(i0)>0?0:(int)(i1) + 1; i<(int)(boundi); ++i, i = i==(int)(i0)?(int)(i1) + 1:i)
    #define cimg_for_out2(boundi,boundj,i0,j0,i1,j1,i,j) \
     for (int j = 0; j<(int)(boundj); ++j) \
     for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j?0:(int)(i0)>0?0:(int)(i1) + 1; i<(int)(boundi); \
      ++i, i = _n1j?i:(i==(int)(i0)?(int)(i1) + 1:i))
    #define cimg_for_out3(boundi,boundj,boundk,i0,j0,k0,i1,j1,k1,i,j,k) \
     for (int k = 0; k<(int)(boundk); ++k) \
     for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \
     for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j || _n1k?0:(int)(i0)>0?0:(int)(i1) + 1; i<(int)(boundi); \
      ++i, i = _n1j || _n1k?i:(i==(int)(i0)?(int)(i1) + 1:i))
    #define cimg_for_out4(boundi,boundj,boundk,boundl,i0,j0,k0,l0,i1,j1,k1,l1,i,j,k,l) \
     for (int l = 0; l<(int)(boundl); ++l) \
     for (int _n1l = (int)(l<(int)(l0) || l>(int)(l1)), k = 0; k<(int)(boundk); ++k) \
     for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \
     for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j || _n1k || _n1l?0:(int)(i0)>0?0:(int)(i1) + 1; \
      i<(int)(boundi); ++i, i = _n1j || _n1k || _n1l?i:(i==(int)(i0)?(int)(i1) + 1:i))
    #define cimg_for_outX(img,x0,x1,x) cimg_for_out1((img)._width,x0,x1,x)
    #define cimg_for_outY(img,y0,y1,y) cimg_for_out1((img)._height,y0,y1,y)
    #define cimg_for_outZ(img,z0,z1,z) cimg_for_out1((img)._depth,z0,z1,z)
    #define cimg_for_outC(img,c0,c1,c) cimg_for_out1((img)._spectrum,c0,c1,c)
    #define cimg_for_outXY(img,x0,y0,x1,y1,x,y) cimg_for_out2((img)._width,(img)._height,x0,y0,x1,y1,x,y)
    #define cimg_for_outXZ(img,x0,z0,x1,z1,x,z) cimg_for_out2((img)._width,(img)._depth,x0,z0,x1,z1,x,z)
    #define cimg_for_outXC(img,x0,c0,x1,c1,x,c) cimg_for_out2((img)._width,(img)._spectrum,x0,c0,x1,c1,x,c)
    #define cimg_for_outYZ(img,y0,z0,y1,z1,y,z) cimg_for_out2((img)._height,(img)._depth,y0,z0,y1,z1,y,z)
    #define cimg_for_outYC(img,y0,c0,y1,c1,y,c) cimg_for_out2((img)._height,(img)._spectrum,y0,c0,y1,c1,y,c)
    #define cimg_for_outZC(img,z0,c0,z1,c1,z,c) cimg_for_out2((img)._depth,(img)._spectrum,z0,c0,z1,c1,z,c)
    #define cimg_for_outXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) \
      cimg_for_out3((img)._width,(img)._height,(img)._depth,x0,y0,z0,x1,y1,z1,x,y,z)
    #define cimg_for_outXYC(img,x0,y0,c0,x1,y1,c1,x,y,c) \
      cimg_for_out3((img)._width,(img)._height,(img)._spectrum,x0,y0,c0,x1,y1,c1,x,y,c)
    #define cimg_for_outXZC(img,x0,z0,c0,x1,z1,c1,x,z,c) \
      cimg_for_out3((img)._width,(img)._depth,(img)._spectrum,x0,z0,c0,x1,z1,c1,x,z,c)
    #define cimg_for_outYZC(img,y0,z0,c0,y1,z1,c1,y,z,c) \
      cimg_for_out3((img)._height,(img)._depth,(img)._spectrum,y0,z0,c0,y1,z1,c1,y,z,c)
    #define cimg_for_outXYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \
     cimg_for_out4((img)._width,(img)._height,(img)._depth,(img)._spectrum,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c)
    #define cimg_for_borderX(img,x,n) cimg_for_outX(img,n,(img)._width - 1 - (n),x)
    #define cimg_for_borderY(img,y,n) cimg_for_outY(img,n,(img)._height - 1 - (n),y)
    #define cimg_for_borderZ(img,z,n) cimg_for_outZ(img,n,(img)._depth - 1 - (n),z)
    #define cimg_for_borderC(img,c,n) cimg_for_outC(img,n,(img)._spectrum - 1 - (n),c)
    #define cimg_for_borderXY(img,x,y,n) cimg_for_outXY(img,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),x,y)
    #define cimg_for_borderXYZ(img,x,y,z,n) \
      cimg_for_outXYZ(img,n,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n),(img)._depth - 1 - (n),x,y,z)
    #define cimg_for_borderXYZC(img,x,y,z,c,n) \
     cimg_for_outXYZC(img,n,n,n,n,(img)._width - 1 - (n),(img)._height - 1 - (n), \
                      (img)._depth - 1 - (n),(img)._spectrum - 1 - (n),x,y,z,c)
    
    #define cimg_for_spiralXY(img,x,y) \
     for (int x = 0, y = 0, _n1##x = 1, _n1##y = (img).width()*(img).height(); _n1##y; \
          --_n1##y, _n1##x+=(_n1##x>>2) - ((!(_n1##x&3)?--y:((_n1##x&3)==1?(img)._width - 1 - ++x:\
          ((_n1##x&3)==2?(img)._height - 1 - ++y:--x))))?0:1)
    
    #define cimg_for_lineXY(x,y,x0,y0,x1,y1) \
     for (int x = (int)(x0), y = (int)(y0), _sx = 1, _sy = 1, _steep = 0, \
          _dx=(x1)>(x0)?(int)(x1) - (int)(x0):(_sx=-1,(int)(x0) - (int)(x1)), \
          _dy=(y1)>(y0)?(int)(y1) - (int)(y0):(_sy=-1,(int)(y0) - (int)(y1)), \
          _counter = _dx, \
          _err = _dx>_dy?(_dy>>1):((_steep=1),(_counter=_dy),(_dx>>1)); \
          _counter>=0; \
          --_counter, x+=_steep? \
          (y+=_sy,(_err-=_dx)<0?_err+=_dy,_sx:0): \
          (y+=(_err-=_dy)<0?_err+=_dx,_sy:0,_sx))
    
    #define cimg_for2(bound,i) \
     for (int i = 0, _n1##i = 1>=(bound)?(int)(bound) - 1:1; \
          _n1##i<(int)(bound) || i==--_n1##i; \
          ++i, ++_n1##i)
    #define cimg_for2X(img,x) cimg_for2((img)._width,x)
    #define cimg_for2Y(img,y) cimg_for2((img)._height,y)
    #define cimg_for2Z(img,z) cimg_for2((img)._depth,z)
    #define cimg_for2C(img,c) cimg_for2((img)._spectrum,c)
    #define cimg_for2XY(img,x,y) cimg_for2Y(img,y) cimg_for2X(img,x)
    #define cimg_for2XZ(img,x,z) cimg_for2Z(img,z) cimg_for2X(img,x)
    #define cimg_for2XC(img,x,c) cimg_for2C(img,c) cimg_for2X(img,x)
    #define cimg_for2YZ(img,y,z) cimg_for2Z(img,z) cimg_for2Y(img,y)
    #define cimg_for2YC(img,y,c) cimg_for2C(img,c) cimg_for2Y(img,y)
    #define cimg_for2ZC(img,z,c) cimg_for2C(img,c) cimg_for2Z(img,z)
    #define cimg_for2XYZ(img,x,y,z) cimg_for2Z(img,z) cimg_for2XY(img,x,y)
    #define cimg_for2XZC(img,x,z,c) cimg_for2C(img,c) cimg_for2XZ(img,x,z)
    #define cimg_for2YZC(img,y,z,c) cimg_for2C(img,c) cimg_for2YZ(img,y,z)
    #define cimg_for2XYZC(img,x,y,z,c) cimg_for2C(img,c) cimg_for2XYZ(img,x,y,z)
    
    #define cimg_for_in2(bound,i0,i1,i) \
     for (int i = (int)(i0)<0?0:(int)(i0), \
          _n1##i = i + 1>=(int)(bound)?(int)(bound) - 1:i + 1; \
          i<=(int)(i1) && (_n1##i<(int)(bound) || i==--_n1##i); \
          ++i, ++_n1##i)
    #define cimg_for_in2X(img,x0,x1,x) cimg_for_in2((img)._width,x0,x1,x)
    #define cimg_for_in2Y(img,y0,y1,y) cimg_for_in2((img)._height,y0,y1,y)
    #define cimg_for_in2Z(img,z0,z1,z) cimg_for_in2((img)._depth,z0,z1,z)
    #define cimg_for_in2C(img,c0,c1,c) cimg_for_in2((img)._spectrum,c0,c1,c)
    #define cimg_for_in2XY(img,x0,y0,x1,y1,x,y) cimg_for_in2Y(img,y0,y1,y) cimg_for_in2X(img,x0,x1,x)
    #define cimg_for_in2XZ(img,x0,z0,x1,z1,x,z) cimg_for_in2Z(img,z0,z1,z) cimg_for_in2X(img,x0,x1,x)
    #define cimg_for_in2XC(img,x0,c0,x1,c1,x,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2X(img,x0,x1,x)
    #define cimg_for_in2YZ(img,y0,z0,y1,z1,y,z) cimg_for_in2Z(img,z0,z1,z) cimg_for_in2Y(img,y0,y1,y)
    #define cimg_for_in2YC(img,y0,c0,y1,c1,y,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2Y(img,y0,y1,y)