00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef cimg_version
00043 #define cimg_version 127
00044
00045
00046 #if defined(_MSC_VER) && _MSC_VER<1300
00047 #define cimg_use_visualcpp6
00048 #endif
00049
00050
00051 #if defined(_MSC_VER) && _MSC_VER>=1300
00052 #define _CRT_SECURE_NO_DEPRECATE 1
00053 #define _CRT_NONSTDC_NO_DEPRECATE 1
00054 #endif
00055
00056
00057 #include <cstdio>
00058 #include <cstdlib>
00059 #include <cstdarg>
00060 #include <cstring>
00061 #include <cmath>
00062 #include <ctime>
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #ifndef cimg_OS
00076
00077 #if defined(unix) || defined(__unix) || defined(__unix__) \
00078 || defined(linux) || defined(__linux) || defined(__linux__) \
00079 || defined(sun) || defined(__sun) \
00080 || defined(BSD) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined __DragonFly__ \
00081 || defined(__MACOSX__) || defined(__APPLE__) \
00082 || defined(sgi) || defined(__sgi) \
00083 || defined(__CYGWIN__)
00084 #define cimg_OS 1
00085 #ifndef cimg_display_type
00086 #define cimg_display_type 1
00087 #endif
00088 #ifndef cimg_color_terminal
00089 #define cimg_color_terminal
00090 #endif
00091
00092 #elif defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
00093 || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
00094 #define cimg_OS 2
00095 #ifndef cimg_display_type
00096 #define cimg_display_type 2
00097 #endif
00098
00099 #else
00100 #define cimg_OS 0
00101 #ifndef cimg_display_type
00102 #define cimg_display_type 0
00103 #endif
00104 #endif
00105 #endif
00106
00107
00108
00109
00110
00111
00112
00113 #ifndef cimg_debug
00114 #define cimg_debug 2
00115 #endif
00116
00117
00118 #if cimg_OS==1
00119 #include <sys/time.h>
00120 #include <unistd.h>
00121 #elif cimg_OS==2
00122 #include <windows.h>
00123 #ifndef _WIN32_IE
00124 #define _WIN32_IE 0x0400
00125 #endif
00126 #include <shlobj.h>
00127 #ifdef cimg_use_visualcpp6
00128 #define std
00129 #endif
00130 #endif
00131
00132
00133 #ifdef PI
00134 #error -------------------------------------------------------------------------------
00135 #error The macro value 'PI' has been defined prior to the #include "CImg.h" directive.
00136 #error The CImg Library does not compile with such a macro value defined.
00137 #error Please (re)define this macro *after* including "CImg.h" if really necessary.
00138 #error Following error messages are most probably related to this problem.
00139 #error -------------------------------------------------------------------------------
00140 #endif
00141 #ifdef min
00142 #undef min
00143 #define cimg_redefine_min
00144 #endif
00145 #ifdef max
00146 #undef max
00147 #define cimg_redefine_max
00148 #endif
00149
00150
00151 #if cimg_display_type==1
00152 #include <X11/Xlib.h>
00153 #include <X11/Xutil.h>
00154 #include <X11/keysym.h>
00155 #include <pthread.h>
00156 #ifdef cimg_use_xshm
00157 #include <sys/ipc.h>
00158 #include <sys/shm.h>
00159 #include <X11/extensions/XShm.h>
00160 #endif
00161 #ifdef cimg_use_xrandr
00162 #include <X11/extensions/Xrandr.h>
00163 #endif
00164 #endif
00165
00166
00167
00168
00169
00170
00171
00172
00173 #ifdef cimg_use_png
00174 extern "C" {
00175 #include "png.h"
00176 }
00177 #endif
00178 #ifdef cimg_use_jpeg
00179 extern "C" {
00180 #include "jpeglib.h"
00181 }
00182 #endif
00183 #ifdef cimg_use_tiff
00184 extern "C" {
00185 #include "tiffio.h"
00186 }
00187 #endif
00188 #ifdef cimg_use_magick
00189 #include "Magick++.h"
00190 #endif
00191 #ifdef cimg_use_fftw3
00192 extern "C" {
00193 #include "fftw3.h"
00194 }
00195 #endif
00196 #ifdef cimg_use_lapack
00197 extern "C" {
00198 extern void sgetrf_(int*, int*, float*, int*, int*, int*);
00199 extern void sgetri_(int*, float*, int*, int*, float*, int*, int*);
00200 extern void sgetrs_(char*, int*, int*, float*, int*, int*, float*, int*, int*);
00201 extern void sgesvd_(char*, char*, int*, int*, float*, int*, float*, float*, int*, float*, int*, float*, int*, int*);
00202 extern void ssyev_(char*, char*, int*, float*, int*, float*, float*, int*, int*);
00203 extern void dgetrf_(int*, int*, double*, int*, int*, int*);
00204 extern void dgetri_(int*, double*, int*, int*, double*, int*, int*);
00205 extern void dgetrs_(char*, int*, int*, double*, int*, int*, double*, int*, int*);
00206 extern void dgesvd_(char*, char*, int*, int*, double*, int*, double*, double*, int*, double*, int*, double*, int*, int*);
00207 extern void dsyev_(char*, char*, int*, double*, int*, double*, double*, int*, int*);
00208 }
00209 #endif
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 #define cimg_usage(usage) cimg_library::cimg::option((char*)0,argc,argv,(char*)0,usage)
00224 #define cimg_help(str) cimg_library::cimg::option((char*)0,argc,argv,str,(char*)0)
00225 #define cimg_option(name,defaut,usage) cimg_library::cimg::option(name,argc,argv,defaut,usage)
00226 #define cimg_argument(pos) cimg_library::cimg::argument(pos,argc,argv)
00227 #define cimg_argument1(pos,s0) cimg_library::cimg::argument(pos,argc,argv,1,s0)
00228 #define cimg_argument2(pos,s0,s1) cimg_library::cimg::argument(pos,argc,argv,2,s0,s1)
00229 #define cimg_argument3(pos,s0,s1,s2) cimg_library::cimg::argument(pos,argc,argv,3,s0,s1,s2)
00230 #define cimg_argument4(pos,s0,s1,s2,s3) cimg_library::cimg::argument(pos,argc,argv,4,s0,s1,s2,s3)
00231 #define cimg_argument5(pos,s0,s1,s2,s3,s4) cimg_library::cimg::argument(pos,argc,argv,5,s0,s1,s2,s3,s4)
00232 #define cimg_argument6(pos,s0,s1,s2,s3,s4,s5) cimg_library::cimg::argument(pos,argc,argv,6,s0,s1,s2,s3,s4,s5)
00233 #define cimg_argument7(pos,s0,s1,s2,s3,s4,s5,s6) cimg_library::cimg::argument(pos,argc,argv,7,s0,s1,s2,s3,s4,s5,s6)
00234 #define cimg_argument8(pos,s0,s1,s2,s3,s4,s5,s6,s7) cimg_library::cimg::argument(pos,argc,argv,8,s0,s1,s2,s3,s4,s5,s6,s7)
00235 #define cimg_argument9(pos,s0,s1,s2,s3,s4,s5,s6,s7,s8) cimg_library::cimg::argument(pos,argc,argv,9,s0,s1,s2,s3,s4,s5,s6,s7,s8)
00236
00237
00238
00239 #define CImg_2x2(I,T) T I[4]; \
00240 T& I##cc = I[0]; T& I##nc = I[1]; \
00241 T& I##cn = I[2]; T& I##nn = I[3]; \
00242 I##cc = I##nc = \
00243 I##cn = I##nn = 0
00244
00245 #define CImg_3x3(I,T) T I[9]; \
00246 T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; \
00247 T& I##pc = I[3]; T& I##cc = I[4]; T& I##nc = I[5]; \
00248 T& I##pn = I[6]; T& I##cn = I[7]; T& I##nn = I[8]; \
00249 I##pp = I##cp = I##np = \
00250 I##pc = I##cc = I##nc = \
00251 I##pn = I##cn = I##nn = 0
00252
00253
00254 #define CImg_4x4(I,T) T I[16]; \
00255 T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; T& I##ap = I[3]; \
00256 T& I##pc = I[4]; T& I##cc = I[5]; T& I##nc = I[6]; T& I##ac = I[7]; \
00257 T& I##pn = I[8]; T& I##cn = I[9]; T& I##nn = I[10]; T& I##an = I[11]; \
00258 T& I##pa = I[12]; T& I##ca = I[13]; T& I##na = I[14]; T& I##aa = I[15]; \
00259 I##pp = I##cp = I##np = I##ap = \
00260 I##pc = I##cc = I##nc = I##ac = \
00261 I##pn = I##cn = I##nn = I##an = \
00262 I##pa = I##ca = I##na = I##aa = 0
00263
00264 #define CImg_5x5(I,T) T I[25]; \
00265 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]; \
00266 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]; \
00267 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]; \
00268 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]; \
00269 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]; \
00270 I##bb = I##pb = I##cb = I##nb = I##ab = \
00271 I##bp = I##pp = I##cp = I##np = I##ap = \
00272 I##bc = I##pc = I##cc = I##nc = I##ac = \
00273 I##bn = I##pn = I##cn = I##nn = I##an = \
00274 I##ba = I##pa = I##ca = I##na = I##aa = 0
00275
00276 #define CImg_2x2x2(I,T) T I[8]; \
00277 T& I##ccc = I[0]; T& I##ncc = I[1]; \
00278 T& I##cnc = I[2]; T& I##nnc = I[3]; \
00279 T& I##ccn = I[4]; T& I##ncn = I[5]; \
00280 T& I##cnn = I[6]; T& I##nnn = I[7]; \
00281 I##ccc = I##ncc = \
00282 I##cnc = I##nnc = \
00283 I##ccn = I##ncn = \
00284 I##cnn = I##nnn = 0
00285
00286 #define CImg_3x3x3(I,T) T I[27]; \
00287 T& I##ppp = I[0]; T& I##cpp = I[1]; T& I##npp = I[2]; \
00288 T& I##pcp = I[3]; T& I##ccp = I[4]; T& I##ncp = I[5]; \
00289 T& I##pnp = I[6]; T& I##cnp = I[7]; T& I##nnp = I[8]; \
00290 T& I##ppc = I[9]; T& I##cpc = I[10]; T& I##npc = I[11]; \
00291 T& I##pcc = I[12]; T& I##ccc = I[13]; T& I##ncc = I[14]; \
00292 T& I##pnc = I[15]; T& I##cnc = I[16]; T& I##nnc = I[17]; \
00293 T& I##ppn = I[18]; T& I##cpn = I[19]; T& I##npn = I[20]; \
00294 T& I##pcn = I[21]; T& I##ccn = I[22]; T& I##ncn = I[23]; \
00295 T& I##pnn = I[24]; T& I##cnn = I[25]; T& I##nnn = I[26]; \
00296 I##ppp = I##cpp = I##npp = \
00297 I##pcp = I##ccp = I##ncp = \
00298 I##pnp = I##cnp = I##nnp = \
00299 I##ppc = I##cpc = I##npc = \
00300 I##pcc = I##ccc = I##ncc = \
00301 I##pnc = I##cnc = I##nnc = \
00302 I##ppn = I##cpn = I##npn = \
00303 I##pcn = I##ccn = I##ncn = \
00304 I##pnn = I##cnn = I##nnn = 0
00305
00306 #define cimg_get2x2(img,x,y,z,v,I) \
00307 I[0] = (img)(x, y,z,v), I[1] = (img)(_n1##x, y,z,v), \
00308 I[2] = (img)(x,_n1##y,z,v), I[3] = (img)(_n1##x,_n1##y,z,v)
00309
00310 #define cimg_get3x3(img,x,y,z,v,I) \
00311 I[0] = (img)(_p1##x,_p1##y,z,v), I[1] = (img)(x,_p1##y,z,v), I[2] = (img)(_n1##x,_p1##y,z,v), \
00312 I[3] = (img)(_p1##x, y,z,v), I[4] = (img)(x, y,z,v), I[5] = (img)(_n1##x, y,z,v), \
00313 I[6] = (img)(_p1##x,_n1##y,z,v), I[7] = (img)(x,_n1##y,z,v), I[8] = (img)(_n1##x,_n1##y,z,v)
00314
00315 #define cimg_get4x4(img,x,y,z,v,I) \
00316 I[0] = (img)(_p1##x,_p1##y,z,v), I[1] = (img)(x,_p1##y,z,v), I[2] = (img)(_n1##x,_p1##y,z,v), I[3] = (img)(_n2##x,_p1##y,z,v), \
00317 I[4] = (img)(_p1##x, y,z,v), I[5] = (img)(x, y,z,v), I[6] = (img)(_n1##x, y,z,v), I[7] = (img)(_n2##x, y,z,v), \
00318 I[8] = (img)(_p1##x,_n1##y,z,v), I[9] = (img)(x,_n1##y,z,v), I[10] = (img)(_n1##x,_n1##y,z,v), I[11] = (img)(_n2##x,_n1##y,z,v), \
00319 I[12] = (img)(_p1##x,_n2##y,z,v), I[13] = (img)(x,_n2##y,z,v), I[14] = (img)(_n1##x,_n2##y,z,v), I[15] = (img)(_n2##x,_n2##y,z,v)
00320
00321 #define cimg_get5x5(img,x,y,z,v,I) \
00322 I[0] = (img)(_p2##x,_p2##y,z,v), I[1] = (img)(_p1##x,_p2##y,z,v), I[2] = (img)(x,_p2##y,z,v), I[3] = (img)(_n1##x,_p2##y,z,v), I[4] = (img)(_n2##x,_p2##y,z,v), \
00323 I[5] = (img)(_p2##x,_p1##y,z,v), I[6] = (img)(_p1##x,_p1##y,z,v), I[7] = (img)(x,_p1##y,z,v), I[8] = (img)(_n1##x,_p1##y,z,v), I[9] = (img)(_n2##x,_p1##y,z,v), \
00324 I[10] = (img)(_p2##x, y,z,v), I[11] = (img)(_p1##x, y,z,v), I[12] = (img)(x, y,z,v), I[13] = (img)(_n1##x, y,z,v), I[14] = (img)(_n2##x, y,z,v), \
00325 I[15] = (img)(_p2##x,_n1##y,z,v), I[16] = (img)(_p1##x,_n1##y,z,v), I[17] = (img)(x,_n1##y,z,v), I[18] = (img)(_n1##x,_n1##y,z,v), I[19] = (img)(_n2##x,_n1##y,z,v), \
00326 I[20] = (img)(_p2##x,_n2##y,z,v), I[21] = (img)(_p1##x,_n2##y,z,v), I[22] = (img)(x,_n2##y,z,v), I[23] = (img)(_n1##x,_n2##y,z,v), I[24] = (img)(_n2##x,_n2##y,z,v)
00327 #define cimg_get6x6(img,x,y,z,v,I) \
00328 I[0] = (img)(_p2##x,_p2##y,z,v), I[1] = (img)(_p1##x,_p2##y,z,v), I[2] = (img)(x,_p2##y,z,v), I[3] = (img)(_n1##x,_p2##y,z,v), I[4] = (img)(_n2##x,_p2##y,z,v), I[5] = (img)(_n3##x,_p2##y,z,v), \
00329 I[6] = (img)(_p2##x,_p1##y,z,v), I[7] = (img)(_p1##x,_p1##y,z,v), I[8] = (img)(x,_p1##y,z,v), I[9] = (img)(_n1##x,_p1##y,z,v), I[10] = (img)(_n2##x,_p1##y,z,v), I[11] = (img)(_n3##x,_p1##y,z,v), \
00330 I[12] = (img)(_p2##x,y,z,v), I[13] = (img)(_p1##x,y,z,v), I[14] = (img)(x,y,z,v), I[15] = (img)(_n1##x,y,z,v), I[16] = (img)(_n2##x,y,z,v), I[17] = (img)(_n3##x,y,z,v), \
00331 I[18] = (img)(_p2##x,_n1##y,z,v), I[19] = (img)(_p1##x,_n1##y,z,v), I[20] = (img)(x,_n1##y,z,v), I[21] = (img)(_n1##x,_n1##y,z,v), I[22] = (img)(_n2##x,_n1##y,z,v), I[23] = (img)(_n3##x,_n1##y,z,v), \
00332 I[24] = (img)(_p2##x,_n2##y,z,v), I[25] = (img)(_p1##x,_n2##y,z,v), I[26] = (img)(x,_n2##y,z,v), I[27] = (img)(_n1##x,_n2##y,z,v), I[28] = (img)(_n2##x,_n2##y,z,v), I[29] = (img)(_n3##x,_n2##y,z,v), \
00333 I[30] = (img)(_p2##x,_n3##y,z,v), I[31] = (img)(_p1##x,_n3##y,z,v), I[32] = (img)(x,_n3##y,z,v), I[33] = (img)(_n1##x,_n3##y,z,v), I[34] = (img)(_n2##x,_n3##y,z,v), I[35] = (img)(_n3##x,_n3##y,z,v);
00334
00335 #define cimg_get7x7(img,x,y,z,v,I) \
00336 I[0] = (img)(_p3##x,_p3##y,z,v), I[1] = (img)(_p2##x,_p3##y,z,v), I[2] = (img)(_p1##x,_p3##y,z,v), I[3] = (img)(x,_p3##y,z,v), I[4] = (img)(_n1##x,_p3##y,z,v), I[5] = (img)(_n2##x,_p3##y,z,v), I[6] = (img)(_n3##x,_p3##y,z,v), \
00337 I[7] = (img)(_p3##x,_p2##y,z,v), I[8] = (img)(_p2##x,_p2##y,z,v), I[9] = (img)(_p1##x,_p2##y,z,v), I[10] = (img)(x,_p2##y,z,v), I[11] = (img)(_n1##x,_p2##y,z,v), I[12] = (img)(_n2##x,_p2##y,z,v), I[13] = (img)(_n3##x,_p2##y,z,v), \
00338 I[14] = (img)(_p3##x,_p1##y,z,v), I[15] = (img)(_p2##x,_p1##y,z,v), I[16] = (img)(_p1##x,_p1##y,z,v), I[17] = (img)(x,_p1##y,z,v), I[18] = (img)(_n1##x,_p1##y,z,v), I[19] = (img)(_n2##x,_p1##y,z,v), I[20] = (img)(_n3##x,_p1##y,z,v), \
00339 I[21] = (img)(_p3##x,y,z,v), I[22] = (img)(_p2##x,y,z,v), I[23] = (img)(_p1##x,y,z,v), I[24] = (img)(x,y,z,v), I[25] = (img)(_n1##x,y,z,v), I[26] = (img)(_n2##x,y,z,v), I[27] = (img)(_n3##x,y,z,v), \
00340 I[28] = (img)(_p3##x,_n1##y,z,v), I[29] = (img)(_p2##x,_n1##y,z,v), I[30] = (img)(_p1##x,_n1##y,z,v), I[31] = (img)(x,_n1##y,z,v), I[32] = (img)(_n1##x,_n1##y,z,v), I[33] = (img)(_n2##x,_n1##y,z,v), I[34] = (img)(_n3##x,_n1##y,z,v), \
00341 I[35] = (img)(_p3##x,_n2##y,z,v), I[36] = (img)(_p2##x,_n2##y,z,v), I[37] = (img)(_p1##x,_n2##y,z,v), I[38] = (img)(x,_n2##y,z,v), I[39] = (img)(_n1##x,_n2##y,z,v), I[40] = (img)(_n2##x,_n2##y,z,v), I[41] = (img)(_n3##x,_n2##y,z,v), \
00342 I[42] = (img)(_p3##x,_n3##y,z,v), I[43] = (img)(_p2##x,_n3##y,z,v), I[44] = (img)(_p1##x,_n3##y,z,v), I[45] = (img)(x,_n3##y,z,v), I[46] = (img)(_n1##x,_n3##y,z,v), I[47] = (img)(_n2##x,_n3##y,z,v), I[48] = (img)(_n3##x,_n3##y,z,v);
00343
00344 #define cimg_get2x2x2(img,x,y,z,v,I) \
00345 I[0] = (img)(x, y, z,v), I[1] = (img)(_n1##x, y, z,v), \
00346 I[2] = (img)(x,_n1##y, z,v), I[3] = (img)(_n1##x,_n1##y, z,v), \
00347 I[4] = (img)(x, y,_n1##z,v), I[5] = (img)(_n1##x, y,_n1##z,v), \
00348 I[6] = (img)(x,_n1##y,_n1##z,v), I[7] = (img)(_n1##x,_n1##y,_n1##z,v)
00349
00350 #define cimg_get3x3x3(img,x,y,z,v,I) \
00351 I[0] = (img)(_p1##x,_p1##y,_p1##z,v), I[1] = (img)(x,_p1##y,_p1##z,v), I[2] = (img)(_n1##x,_p1##y,_p1##z,v), \
00352 I[3] = (img)(_p1##x, y,_p1##z,v), I[4] = (img)(x, y,_p1##z,v), I[5] = (img)(_n1##x, y,_p1##z,v), \
00353 I[6] = (img)(_p1##x,_n1##y,_p1##z,v), I[7] = (img)(x,_n1##y,_p1##z,v), I[8] = (img)(_n1##x,_n1##y,_p1##z,v), \
00354 I[9] = (img)(_p1##x,_p1##y, z,v), I[10] = (img)(x,_p1##y, z,v), I[11] = (img)(_n1##x,_p1##y, z,v), \
00355 I[12] = (img)(_p1##x, y, z,v), I[13] = (img)(x, y, z,v), I[14] = (img)(_n1##x, y, z,v), \
00356 I[15] = (img)(_p1##x,_n1##y, z,v), I[16] = (img)(x,_n1##y, z,v), I[17] = (img)(_n1##x,_n1##y, z,v), \
00357 I[18] = (img)(_p1##x,_p1##y,_n1##z,v), I[19] = (img)(x,_p1##y,_n1##z,v), I[20] = (img)(_n1##x,_p1##y,_n1##z,v), \
00358 I[21] = (img)(_p1##x, y,_n1##z,v), I[22] = (img)(x, y,_n1##z,v), I[23] = (img)(_n1##x, y,_n1##z,v), \
00359 I[24] = (img)(_p1##x,_n1##y,_n1##z,v), I[25] = (img)(x,_n1##y,_n1##z,v), I[26] = (img)(_n1##x,_n1##y,_n1##z,v)
00360
00361
00362
00363
00364 #define cimg_for(img,ptr,T_ptr) for (T_ptr *ptr = (img).data + (img).size(); (ptr--)>(img).data; )
00365 #define cimg_foroff(img,off) for (unsigned int off = 0; off<(img).size(); ++off)
00366 #define cimglist_for(list,l) for (unsigned int l=0; l<(list).size; ++l)
00367 #define cimglist_apply(list,fn) cimglist_for(list,__##fn) (list)[__##fn].fn
00368
00369 #define cimg_for1(bound,i) for (int i = 0; i<(int)(bound); ++i)
00370 #define cimg_forX(img,x) cimg_for1((img).width,x)
00371 #define cimg_forY(img,y) cimg_for1((img).height,y)
00372 #define cimg_forZ(img,z) cimg_for1((img).depth,z)
00373 #define cimg_forV(img,v) cimg_for1((img).dim,v)
00374 #define cimg_forXY(img,x,y) cimg_forY(img,y) cimg_forX(img,x)
00375 #define cimg_forXZ(img,x,z) cimg_forZ(img,z) cimg_forX(img,x)
00376 #define cimg_forYZ(img,y,z) cimg_forZ(img,z) cimg_forY(img,y)
00377 #define cimg_forXV(img,x,v) cimg_forV(img,v) cimg_forX(img,x)
00378 #define cimg_forYV(img,y,v) cimg_forV(img,v) cimg_forY(img,y)
00379 #define cimg_forZV(img,z,v) cimg_forV(img,v) cimg_forZ(img,z)
00380 #define cimg_forXYZ(img,x,y,z) cimg_forZ(img,z) cimg_forXY(img,x,y)
00381 #define cimg_forXYV(img,x,y,v) cimg_forV(img,v) cimg_forXY(img,x,y)
00382 #define cimg_forXZV(img,x,z,v) cimg_forV(img,v) cimg_forXZ(img,x,z)
00383 #define cimg_forYZV(img,y,z,v) cimg_forV(img,v) cimg_forYZ(img,y,z)
00384 #define cimg_forXYZV(img,x,y,z,v) cimg_forV(img,v) cimg_forXYZ(img,x,y,z)
00385
00386 #define cimg_for_in1(bound,i0,i1,i) \
00387 for (int i = (int)(i0)<0?0:(int)(i0), _max##i = (int)(i1)<(int)(bound)?(int)(i1):(int)(bound)-1; i<=_max##i; ++i)
00388 #define cimg_for_inX(img,x0,x1,x) cimg_for_in1((img).width,x0,x1,x)
00389 #define cimg_for_inY(img,y0,y1,y) cimg_for_in1((img).height,y0,y1,y)
00390 #define cimg_for_inZ(img,z0,z1,z) cimg_for_in1((img).depth,z0,z1,z)
00391 #define cimg_for_inV(img,v0,v1,v) cimg_for_in1((img).dim,v0,v1,v)
00392 #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)
00393 #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)
00394 #define cimg_for_inXV(img,x0,v0,x1,v1,x,v) cimg_for_inV(img,v0,v1,v) cimg_for_inX(img,x0,x1,x)
00395 #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)
00396 #define cimg_for_inYV(img,y0,v0,y1,v1,y,v) cimg_for_inV(img,v0,v1,v) cimg_for_inY(img,y0,y1,y)
00397 #define cimg_for_inZV(img,z0,v0,z1,v1,z,v) cimg_for_inV(img,v0,v1,v) cimg_for_inZ(img,z0,z1,z)
00398 #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)
00399 #define cimg_for_inXYV(img,x0,y0,v0,x1,y1,v1,x,y,v) cimg_for_inV(img,v0,v1,v) cimg_for_inXY(img,x0,y0,x1,y1,x,y)
00400 #define cimg_for_inXZV(img,x0,z0,v0,x1,z1,v1,x,z,v) cimg_for_inV(img,v0,v1,v) cimg_for_inXZ(img,x0,z0,x1,z1,x,z)
00401 #define cimg_for_inYZV(img,y0,z0,v0,y1,z1,v1,y,z,v) cimg_for_inV(img,v0,v1,v) cimg_for_inYZ(img,y0,z0,y1,z1,y,z)
00402 #define cimg_for_inXYZV(img,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) cimg_for_inV(img,v0,v1,v) cimg_for_inXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
00403 #define cimg_for_insideX(img,x,n) cimg_for_inX(img,n,(img).width-1-(n),x)
00404 #define cimg_for_insideY(img,y,n) cimg_for_inY(img,n,(img).height-1-(n),y)
00405 #define cimg_for_insideZ(img,z,n) cimg_for_inZ(img,n,(img).depth-1-(n),z)
00406 #define cimg_for_insideV(img,v,n) cimg_for_inV(img,n,(img).dim-1-(n),v)
00407 #define cimg_for_insideXY(img,x,y,n) cimg_for_inXY(img,n,n,(img).width-1-(n),(img).height-1-(n),x,y)
00408 #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)
00409 #define cimg_for_insideXYZV(img,x,y,z,v,n) cimg_for_inXYZ(img,n,n,n,(img).width-1-(n),(img).height-1-(n),(img).depth-1-(n),x,y,z)
00410
00411 #define cimg_for_out1(boundi,i0,i1,i) \
00412 for (int i = (int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); ++i, i = i==(int)(i0)?(int)(i1)+1:i)
00413 #define cimg_for_out2(boundi,boundj,i0,j0,i1,j1,i,j) \
00414 for (int j = 0; j<(int)(boundj); ++j) \
00415 for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j?0:(int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); \
00416 ++i, i = _n1j?i:(i==(int)(i0)?(int)(i1)+1:i))
00417 #define cimg_for_out3(boundi,boundj,boundk,i0,j0,k0,i1,j1,k1,i,j,k) \
00418 for (int k = 0; k<(int)(boundk); ++k) \
00419 for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \
00420 for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j || _n1k?0:(int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); \
00421 ++i, i = _n1j || _n1k?i:(i==(int)(i0)?(int)(i1)+1:i))
00422 #define cimg_for_out4(boundi,boundj,boundk,boundl,i0,j0,k0,l0,i1,j1,k1,l1,i,j,k,l) \
00423 for (int l = 0; l<(int)(boundl); ++l) \
00424 for (int _n1l = (int)(l<(int)(l0) || l>(int)(l1)), k = 0; k<(int)(boundk); ++k) \
00425 for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \
00426 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); \
00427 ++i, i = _n1j || _n1k || _n1l?i:(i==(int)(i0)?(int)(i1)+1:i))
00428 #define cimg_for_outX(img,x0,x1,x) cimg_for_out1((img).width,x0,x1,x)
00429 #define cimg_for_outY(img,y0,y1,y) cimg_for_out1((img).height,y0,y1,y)
00430 #define cimg_for_outZ(img,z0,z1,z) cimg_for_out1((img).depth,z0,z1,z)
00431 #define cimg_for_outV(img,v0,v1,v) cimg_for_out1((img).dim,v0,v1,v)
00432 #define cimg_for_outXY(img,x0,y0,x1,y1,x,y) cimg_for_out2((img).width,(img).height,x0,y0,x1,y1,x,y)
00433 #define cimg_for_outXZ(img,x0,z0,x1,z1,x,z) cimg_for_out2((img).width,(img).depth,x0,z0,x1,z1,x,z)
00434 #define cimg_for_outXV(img,x0,v0,x1,v1,x,v) cimg_for_out2((img).width,(img).dim,x0,v0,x1,v1,x,v)
00435 #define cimg_for_outYZ(img,y0,z0,y1,z1,y,z) cimg_for_out2((img).height,(img).depth,y0,z0,y1,z1,y,z)
00436 #define cimg_for_outYV(img,y0,v0,y1,v1,y,v) cimg_for_out2((img).height,(img).dim,y0,v0,y1,v1,y,v)
00437 #define cimg_for_outZV(img,z0,v0,z1,v1,z,v) cimg_for_out2((img).depth,(img).dim,z0,v0,z1,v1,z,v)
00438 #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)
00439 #define cimg_for_outXYV(img,x0,y0,v0,x1,y1,v1,x,y,v) cimg_for_out3((img).width,(img).height,(img).dim,x0,y0,v0,x1,y1,v1,x,y,v)
00440 #define cimg_for_outXZV(img,x0,z0,v0,x1,z1,v1,x,z,v) cimg_for_out3((img).width,(img).depth,(img).dim,x0,z0,v0,x1,z1,v1,x,z,v)
00441 #define cimg_for_outYZV(img,y0,z0,v0,y1,z1,v1,y,z,v) cimg_for_out3((img).height,(img).depth,(img).dim,y0,z0,v0,y1,z1,v1,y,z,v)
00442 #define cimg_for_outXYZV(img,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) \
00443 cimg_for_out4((img).width,(img).height,(img).depth,(img).dim,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v)
00444 #define cimg_for_borderX(img,x,n) cimg_for_outX(img,n,(img).width-1-(n),x)
00445 #define cimg_for_borderY(img,y,n) cimg_for_outY(img,n,(img).height-1-(n),y)
00446 #define cimg_for_borderZ(img,z,n) cimg_for_outZ(img,n,(img).depth-1-(n),z)
00447 #define cimg_for_borderV(img,v,n) cimg_for_outV(img,n,(img).dim-1-(n),v)
00448 #define cimg_for_borderXY(img,x,y,n) cimg_for_outXY(img,n,n,(img).width-1-(n),(img).height-1-(n),x,y)
00449 #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)
00450 #define cimg_for_borderXYZV(img,x,y,z,v,n) \
00451 cimg_for_outXYZV(img,n,n,n,n,(img).width-1-(n),(img).height-1-(n),(img).depth-1-(n),(img).dim-1-(n),x,y,z,v)
00452
00453 #define cimg_for_spiralXY(img,x,y) \
00454 for (int x = 0, y = 0, _n1##x = 1, _n1##y = (int)((img).width*(img).height); _n1##y; \
00455 --_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)
00456
00457 #define cimg_for_lineXY(x,y,x0,y0,x1,y1) \
00458 for (int x = (int)(x0), y = (int)(y0), _sx = 1, _sy = 1, _steep = 0, \
00459 _dx=(x1)>(x0)?(int)(x1)-(int)(x0):(_sx=-1,(int)(x0)-(int)(x1)), \
00460 _dy=(y1)>(y0)?(int)(y1)-(int)(y0):(_sy=-1,(int)(y0)-(int)(y1)), \
00461 _counter = _dx, \
00462 _err = _dx>_dy?(_dy>>1):((_steep=1),(_counter=_dy),(_dx>>1)); \
00463 _counter>=0; \
00464 --_counter, x+=_steep? \
00465 (y+=_sy,(_err-=_dx)<0?_err+=_dy,_sx:0): \
00466 (y+=(_err-=_dy)<0?_err+=_dx,_sy:0,_sx))
00467
00468 #define cimg_for2(bound,i) \
00469 for (int i = 0, _n1##i = 1>=(bound)?(int)(bound)-1:1; \
00470 _n1##i<(int)(bound) || i==--_n1##i; \
00471 ++i, ++_n1##i)
00472 #define cimg_for2X(img,x) cimg_for2((img).width,x)
00473 #define cimg_for2Y(img,y) cimg_for2((img).height,y)
00474 #define cimg_for2Z(img,z) cimg_for2((img).depth,z)
00475 #define cimg_for2V(img,v) cimg_for2((img).dim,v)
00476 #define cimg_for2XY(img,x,y) cimg_for2Y(img,y) cimg_for2X(img,x)
00477 #define cimg_for2XZ(img,x,z) cimg_for2Z(img,z) cimg_for2X(img,x)
00478 #define cimg_for2XV(img,x,v) cimg_for2V(img,v) cimg_for2X(img,x)
00479 #define cimg_for2YZ(img,y,z) cimg_for2Z(img,z) cimg_for2Y(img,y)
00480 #define cimg_for2YV(img,y,v) cimg_for2V(img,v) cimg_for2Y(img,y)
00481 #define cimg_for2ZV(img,z,v) cimg_for2V(img,v) cimg_for2Z(img,z)
00482 #define cimg_for2XYZ(img,x,y,z) cimg_for2Z(img,z) cimg_for2XY(img,x,y)
00483 #define cimg_for2XZV(img,x,z,v) cimg_for2V(img,v) cimg_for2XZ(img,x,z)
00484 #define cimg_for2YZV(img,y,z,v) cimg_for2V(img,v) cimg_for2YZ(img,y,z)
00485 #define cimg_for2XYZV(img,x,y,z,v) cimg_for2V(img,v) cimg_for2XYZ(img,x,y,z)
00486
00487 #define cimg_for_in2(bound,i0,i1,i) \
00488 for (int i = (int)(i0)<0?0:(int)(i0), \
00489 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1; \
00490 i<=(int)(i1) && (_n1##i<(int)(bound) || i==--_n1##i); \
00491 ++i, ++_n1##i)
00492 #define cimg_for_in2X(img,x0,x1,x) cimg_for_in2((img).width,x0,x1,x)
00493 #define cimg_for_in2Y(img,y0,y1,y) cimg_for_in2((img).height,y0,y1,y)
00494 #define cimg_for_in2Z(img,z0,z1,z) cimg_for_in2((img).depth,z0,z1,z)
00495 #define cimg_for_in2V(img,v0,v1,v) cimg_for_in2((img).dim,v0,v1,v)
00496 #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)
00497 #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)
00498 #define cimg_for_in2XV(img,x0,v0,x1,v1,x,v) cimg_for_in2V(img,v0,v1,v) cimg_for_in2X(img,x0,x1,x)
00499 #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)
00500 #define cimg_for_in2YV(img,y0,v0,y1,v1,y,v) cimg_for_in2V(img,v0,v1,v) cimg_for_in2Y(img,y0,y1,y)
00501 #define cimg_for_in2ZV(img,z0,v0,z1,v1,z,v) cimg_for_in2V(img,v0,v1,v) cimg_for_in2Z(img,z0,z1,z)
00502 #define cimg_for_in2XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in2Z(img,z0,z1,z) cimg_for_in2XY(img,x0,y0,x1,y1,x,y)
00503 #define cimg_for_in2XZV(img,x0,z0,v0,x1,y1,v1,x,z,v) cimg_for_in2V(img,v0,v1,v) cimg_for_in2XZ(img,x0,y0,x1,y1,x,z)
00504 #define cimg_for_in2YZV(img,y0,z0,v0,y1,z1,v1,y,z,v) cimg_for_in2V(img,v0,v1,v) cimg_for_in2YZ(img,y0,z0,y1,z1,y,z)
00505 #define cimg_for_in2XYZV(img,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) cimg_for_in2V(img,v0,v1,v) cimg_for_in2XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
00506
00507 #define cimg_for3(bound,i) \
00508 for (int i = 0, _p1##i = 0, \
00509 _n1##i = 1>=(bound)?(int)(bound)-1:1; \
00510 _n1##i<(int)(bound) || i==--_n1##i; \
00511 _p1##i = i++, ++_n1##i)
00512 #define cimg_for3X(img,x) cimg_for3((img).width,x)
00513 #define cimg_for3Y(img,y) cimg_for3((img).height,y)
00514 #define cimg_for3Z(img,z) cimg_for3((img).depth,z)
00515 #define cimg_for3V(img,v) cimg_for3((img).dim,v)
00516 #define cimg_for3XY(img,x,y) cimg_for3Y(img,y) cimg_for3X(img,x)
00517 #define cimg_for3XZ(img,x,z) cimg_for3Z(img,z) cimg_for3X(img,x)
00518 #define cimg_for3XV(img,x,v) cimg_for3V(img,v) cimg_for3X(img,x)
00519 #define cimg_for3YZ(img,y,z) cimg_for3Z(img,z) cimg_for3Y(img,y)
00520 #define cimg_for3YV(img,y,v) cimg_for3V(img,v) cimg_for3Y(img,y)
00521 #define cimg_for3ZV(img,z,v) cimg_for3V(img,v) cimg_for3Z(img,z)
00522 #define cimg_for3XYZ(img,x,y,z) cimg_for3Z(img,z) cimg_for3XY(img,x,y)
00523 #define cimg_for3XZV(img,x,z,v) cimg_for3V(img,v) cimg_for3XZ(img,x,z)
00524 #define cimg_for3YZV(img,y,z,v) cimg_for3V(img,v) cimg_for3YZ(img,y,z)
00525 #define cimg_for3XYZV(img,x,y,z,v) cimg_for3V(img,v) cimg_for3XYZ(img,x,y,z)
00526
00527 #define cimg_for_in3(bound,i0,i1,i) \
00528 for (int i = (int)(i0)<0?0:(int)(i0), \
00529 _p1##i = i-1<0?0:i-1, \
00530 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1; \
00531 i<=(int)(i1) && (_n1##i<(int)(bound) || i==--_n1##i); \
00532 _p1##i = i++, ++_n1##i)
00533 #define cimg_for_in3X(img,x0,x1,x) cimg_for_in3((img).width,x0,x1,x)
00534 #define cimg_for_in3Y(img,y0,y1,y) cimg_for_in3((img).height,y0,y1,y)
00535 #define cimg_for_in3Z(img,z0,z1,z) cimg_for_in3((img).depth,z0,z1,z)
00536 #define cimg_for_in3V(img,v0,v1,v) cimg_for_in3((img).dim,v0,v1,v)
00537 #define cimg_for_in3XY(img,x0,y0,x1,y1,x,y) cimg_for_in3Y(img,y0,y1,y) cimg_for_in3X(img,x0,x1,x)
00538 #define cimg_for_in3XZ(img,x0,z0,x1,z1,x,z) cimg_for_in3Z(img,z0,z1,z) cimg_for_in3X(img,x0,x1,x)
00539 #define cimg_for_in3XV(img,x0,v0,x1,v1,x,v) cimg_for_in3V(img,v0,v1,v) cimg_for_in3X(img,x0,x1,x)
00540 #define cimg_for_in3YZ(img,y0,z0,y1,z1,y,z) cimg_for_in3Z(img,z0,z1,z) cimg_for_in3Y(img,y0,y1,y)
00541 #define cimg_for_in3YV(img,y0,v0,y1,v1,y,v) cimg_for_in3V(img,v0,v1,v) cimg_for_in3Y(img,y0,y1,y)
00542 #define cimg_for_in3ZV(img,z0,v0,z1,v1,z,v) cimg_for_in3V(img,v0,v1,v) cimg_for_in3Z(img,z0,z1,z)
00543 #define cimg_for_in3XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in3Z(img,z0,z1,z) cimg_for_in3XY(img,x0,y0,x1,y1,x,y)
00544 #define cimg_for_in3XZV(img,x0,z0,v0,x1,y1,v1,x,z,v) cimg_for_in3V(img,v0,v1,v) cimg_for_in3XZ(img,x0,y0,x1,y1,x,z)
00545 #define cimg_for_in3YZV(img,y0,z0,v0,y1,z1,v1,y,z,v) cimg_for_in3V(img,v0,v1,v) cimg_for_in3YZ(img,y0,z0,y1,z1,y,z)
00546 #define cimg_for_in3XYZV(img,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) cimg_for_in3V(img,v0,v1,v) cimg_for_in3XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
00547
00548 #define cimg_for4(bound,i) \
00549 for (int i = 0, _p1##i = 0, _n1##i = 1>=(bound)?(int)(bound)-1:1, \
00550 _n2##i = 2>=(bound)?(int)(bound)-1:2; \
00551 _n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i); \
00552 _p1##i = i++, ++_n1##i, ++_n2##i)
00553 #define cimg_for4X(img,x) cimg_for4((img).width,x)
00554 #define cimg_for4Y(img,y) cimg_for4((img).height,y)
00555 #define cimg_for4Z(img,z) cimg_for4((img).depth,z)
00556 #define cimg_for4V(img,v) cimg_for4((img).dim,v)
00557 #define cimg_for4XY(img,x,y) cimg_for4Y(img,y) cimg_for4X(img,x)
00558 #define cimg_for4XZ(img,x,z) cimg_for4Z(img,z) cimg_for4X(img,x)
00559 #define cimg_for4XV(img,x,v) cimg_for4V(img,v) cimg_for4X(img,x)
00560 #define cimg_for4YZ(img,y,z) cimg_for4Z(img,z) cimg_for4Y(img,y)
00561 #define cimg_for4YV(img,y,v) cimg_for4V(img,v) cimg_for4Y(img,y)
00562 #define cimg_for4ZV(img,z,v) cimg_for4V(img,v) cimg_for4Z(img,z)
00563 #define cimg_for4XYZ(img,x,y,z) cimg_for4Z(img,z) cimg_for4XY(img,x,y)
00564 #define cimg_for4XZV(img,x,z,v) cimg_for4V(img,v) cimg_for4XZ(img,x,z)
00565 #define cimg_for4YZV(img,y,z,v) cimg_for4V(img,v) cimg_for4YZ(img,y,z)
00566 #define cimg_for4XYZV(img,x,y,z,v) cimg_for4V(img,v) cimg_for4XYZ(img,x,y,z)
00567
00568 #define cimg_for_in4(bound,i0,i1,i) \
00569 for (int i = (int)(i0)<0?0:(int)(i0), \
00570 _p1##i = i-1<0?0:i-1, \
00571 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
00572 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2; \
00573 i<=(int)(i1) && (_n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i)); \
00574 _p1##i = i++, ++_n1##i, ++_n2##i)
00575 #define cimg_for_in4X(img,x0,x1,x) cimg_for_in4((img).width,x0,x1,x)
00576 #define cimg_for_in4Y(img,y0,y1,y) cimg_for_in4((img).height,y0,y1,y)
00577 #define cimg_for_in4Z(img,z0,z1,z) cimg_for_in4((img).depth,z0,z1,z)
00578 #define cimg_for_in4V(img,v0,v1,v) cimg_for_in4((img).dim,v0,v1,v)
00579 #define cimg_for_in4XY(img,x0,y0,x1,y1,x,y) cimg_for_in4Y(img,y0,y1,y) cimg_for_in4X(img,x0,x1,x)
00580 #define cimg_for_in4XZ(img,x0,z0,x1,z1,x,z) cimg_for_in4Z(img,z0,z1,z) cimg_for_in4X(img,x0,x1,x)
00581 #define cimg_for_in4XV(img,x0,v0,x1,v1,x,v) cimg_for_in4V(img,v0,v1,v) cimg_for_in4X(img,x0,x1,x)
00582 #define cimg_for_in4YZ(img,y0,z0,y1,z1,y,z) cimg_for_in4Z(img,z0,z1,z) cimg_for_in4Y(img,y0,y1,y)
00583 #define cimg_for_in4YV(img,y0,v0,y1,v1,y,v) cimg_for_in4V(img,v0,v1,v) cimg_for_in4Y(img,y0,y1,y)
00584 #define cimg_for_in4ZV(img,z0,v0,z1,v1,z,v) cimg_for_in4V(img,v0,v1,v) cimg_for_in4Z(img,z0,z1,z)
00585 #define cimg_for_in4XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in4Z(img,z0,z1,z) cimg_for_in4XY(img,x0,y0,x1,y1,x,y)
00586 #define cimg_for_in4XZV(img,x0,z0,v0,x1,y1,v1,x,z,v) cimg_for_in4V(img,v0,v1,v) cimg_for_in4XZ(img,x0,y0,x1,y1,x,z)
00587 #define cimg_for_in4YZV(img,y0,z0,v0,y1,z1,v1,y,z,v) cimg_for_in4V(img,v0,v1,v) cimg_for_in4YZ(img,y0,z0,y1,z1,y,z)
00588 #define cimg_for_in4XYZV(img,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) cimg_for_in4V(img,v0,v1,v) cimg_for_in4XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
00589
00590 #define cimg_for5(bound,i) \
00591 for (int i = 0, _p2##i = 0, _p1##i = 0, \
00592 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
00593 _n2##i = 2>=(bound)?(int)(bound)-1:2; \
00594 _n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i); \
00595 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i)
00596 #define cimg_for5X(img,x) cimg_for5((img).width,x)
00597 #define cimg_for5Y(img,y) cimg_for5((img).height,y)
00598 #define cimg_for5Z(img,z) cimg_for5((img).depth,z)
00599 #define cimg_for5V(img,v) cimg_for5((img).dim,v)
00600 #define cimg_for5XY(img,x,y) cimg_for5Y(img,y) cimg_for5X(img,x)
00601 #define cimg_for5XZ(img,x,z) cimg_for5Z(img,z) cimg_for5X(img,x)
00602 #define cimg_for5XV(img,x,v) cimg_for5V(img,v) cimg_for5X(img,x)
00603 #define cimg_for5YZ(img,y,z) cimg_for5Z(img,z) cimg_for5Y(img,y)
00604 #define cimg_for5YV(img,y,v) cimg_for5V(img,v) cimg_for5Y(img,y)
00605 #define cimg_for5ZV(img,z,v) cimg_for5V(img,v) cimg_for5Z(img,z)
00606 #define cimg_for5XYZ(img,x,y,z) cimg_for5Z(img,z) cimg_for5XY(img,x,y)
00607 #define cimg_for5XZV(img,x,z,v) cimg_for5V(img,v) cimg_for5XZ(img,x,z)
00608 #define cimg_for5YZV(img,y,z,v) cimg_for5V(img,v) cimg_for5YZ(img,y,z)
00609 #define cimg_for5XYZV(img,x,y,z,v) cimg_for5V(img,v) cimg_for5XYZ(img,x,y,z)
00610
00611 #define cimg_for_in5(bound,i0,i1,i) \
00612 for (int i = (int)(i0)<0?0:(int)(i0), \
00613 _p2##i = i-2<0?0:i-2, \
00614 _p1##i = i-1<0?0:i-1, \
00615 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
00616 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2; \
00617 i<=(int)(i1) && (_n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i)); \
00618 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i)
00619 #define cimg_for_in5X(img,x0,x1,x) cimg_for_in5((img).width,x0,x1,x)
00620 #define cimg_for_in5Y(img,y0,y1,y) cimg_for_in5((img).height,y0,y1,y)
00621 #define cimg_for_in5Z(img,z0,z1,z) cimg_for_in5((img).depth,z0,z1,z)
00622 #define cimg_for_in5V(img,v0,v1,v) cimg_for_in5((img).dim,v0,v1,v)
00623 #define cimg_for_in5XY(img,x0,y0,x1,y1,x,y) cimg_for_in5Y(img,y0,y1,y) cimg_for_in5X(img,x0,x1,x)
00624 #define cimg_for_in5XZ(img,x0,z0,x1,z1,x,z) cimg_for_in5Z(img,z0,z1,z) cimg_for_in5X(img,x0,x1,x)
00625 #define cimg_for_in5XV(img,x0,v0,x1,v1,x,v) cimg_for_in5V(img,v0,v1,v) cimg_for_in5X(img,x0,x1,x)
00626 #define cimg_for_in5YZ(img,y0,z0,y1,z1,y,z) cimg_for_in5Z(img,z0,z1,z) cimg_for_in5Y(img,y0,y1,y)
00627 #define cimg_for_in5YV(img,y0,v0,y1,v1,y,v) cimg_for_in5V(img,v0,v1,v) cimg_for_in5Y(img,y0,y1,y)
00628 #define cimg_for_in5ZV(img,z0,v0,z1,v1,z,v) cimg_for_in5V(img,v0,v1,v) cimg_for_in5Z(img,z0,z1,z)
00629 #define cimg_for_in5XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in5Z(img,z0,z1,z) cimg_for_in5XY(img,x0,y0,x1,y1,x,y)
00630 #define cimg_for_in5XZV(img,x0,z0,v0,x1,y1,v1,x,z,v) cimg_for_in5V(img,v0,v1,v) cimg_for_in5XZ(img,x0,y0,x1,y1,x,z)
00631 #define cimg_for_in5YZV(img,y0,z0,v0,y1,z1,v1,y,z,v) cimg_for_in5V(img,v0,v1,v) cimg_for_in5YZ(img,y0,z0,y1,z1,y,z)
00632 #define cimg_for_in5XYZV(img,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) cimg_for_in5V(img,v0,v1,v) cimg_for_in5XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
00633
00634 #define cimg_for6(bound,i) \
00635 for (int i = 0, _p2##i = 0, _p1##i = 0, \
00636 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
00637 _n2##i = 2>=(bound)?(int)(bound)-1:2, \
00638 _n3##i = 3>=(bound)?(int)(bound)-1:3; \
00639 _n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i); \
00640 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
00641 #define cimg_for6X(img,x) cimg_for6((img).width,x)
00642 #define cimg_for6Y(img,y) cimg_for6((img).height,y)
00643 #define cimg_for6Z(img,z) cimg_for6((img).depth,z)
00644 #define cimg_for6V(img,v) cimg_for6((img).dim,v)
00645 #define cimg_for6XY(img,x,y) cimg_for6Y(img,y) cimg_for6X(img,x)
00646 #define cimg_for6XZ(img,x,z) cimg_for6Z(img,z) cimg_for6X(img,x)
00647 #define cimg_for6XV(img,x,v) cimg_for6V(img,v) cimg_for6X(img,x)
00648 #define cimg_for6YZ(img,y,z) cimg_for6Z(img,z) cimg_for6Y(img,y)
00649 #define cimg_for6YV(img,y,v) cimg_for6V(img,v) cimg_for6Y(img,y)
00650 #define cimg_for6ZV(img,z,v) cimg_for6V(img,v) cimg_for6Z(img,z)
00651 #define cimg_for6XYZ(img,x,y,z) cimg_for6Z(img,z) cimg_for6XY(img,x,y)
00652 #define cimg_for6XZV(img,x,z,v) cimg_for6V(img,v) cimg_for6XZ(img,x,z)
00653 #define cimg_for6YZV(img,y,z,v) cimg_for6V(img,v) cimg_for6YZ(img,y,z)
00654 #define cimg_for6XYZV(img,x,y,z,v) cimg_for6V(img,v) cimg_for6XYZ(img,x,y,z)
00655
00656 #define cimg_for_in6(bound,i0,i1,i) \
00657 for (int i = (int)(i0)<0?0:(int)(i0), \
00658 _p2##i = i-2<0?0:i-2, \
00659 _p1##i = i-1<0?0:i-1, \
00660 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
00661 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2, \
00662 _n3##i = i+3>=(int)(bound)?(int)(bound)-1:i+3; \
00663 i<=(int)(i1) && (_n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i)); \
00664 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
00665 #define cimg_for_in6X(img,x0,x1,x) cimg_for_in6((img).width,x0,x1,x)
00666 #define cimg_for_in6Y(img,y0,y1,y) cimg_for_in6((img).height,y0,y1,y)
00667 #define cimg_for_in6Z(img,z0,z1,z) cimg_for_in6((img).depth,z0,z1,z)
00668 #define cimg_for_in6V(img,v0,v1,v) cimg_for_in6((img).dim,v0,v1,v)
00669 #define cimg_for_in6XY(img,x0,y0,x1,y1,x,y) cimg_for_in6Y(img,y0,y1,y) cimg_for_in6X(img,x0,x1,x)
00670 #define cimg_for_in6XZ(img,x0,z0,x1,z1,x,z) cimg_for_in6Z(img,z0,z1,z) cimg_for_in6X(img,x0,x1,x)
00671 #define cimg_for_in6XV(img,x0,v0,x1,v1,x,v) cimg_for_in6V(img,v0,v1,v) cimg_for_in6X(img,x0,x1,x)
00672 #define cimg_for_in6YZ(img,y0,z0,y1,z1,y,z) cimg_for_in6Z(img,z0,z1,z) cimg_for_in6Y(img,y0,y1,y)
00673 #define cimg_for_in6YV(img,y0,v0,y1,v1,y,v) cimg_for_in6V(img,v0,v1,v) cimg_for_in6Y(img,y0,y1,y)
00674 #define cimg_for_in6ZV(img,z0,v0,z1,v1,z,v) cimg_for_in6V(img,v0,v1,v) cimg_for_in6Z(img,z0,z1,z)
00675 #define cimg_for_in6XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in6Z(img,z0,z1,z) cimg_for_in6XY(img,x0,y0,x1,y1,x,y)
00676 #define cimg_for_in6XZV(img,x0,z0,v0,x1,y1,v1,x,z,v) cimg_for_in6V(img,v0,v1,v) cimg_for_in6XZ(img,x0,y0,x1,y1,x,z)
00677 #define cimg_for_in6YZV(img,y0,z0,v0,y1,z1,v1,y,z,v) cimg_for_in6V(img,v0,v1,v) cimg_for_in6YZ(img,y0,z0,y1,z1,y,z)
00678 #define cimg_for_in6XYZV(img,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) cimg_for_in6V(img,v0,v1,v) cimg_for_in6XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
00679
00680 #define cimg_for7(bound,i) \
00681 for (int i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \
00682 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
00683 _n2##i = 2>=(bound)?(int)(bound)-1:2, \
00684 _n3##i = 3>=(bound)?(int)(bound)-1:3; \
00685 _n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i); \
00686 _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
00687 #define cimg_for7X(img,x) cimg_for7((img).width,x)
00688 #define cimg_for7Y(img,y) cimg_for7((img).height,y)
00689 #define cimg_for7Z(img,z) cimg_for7((img).depth,z)
00690 #define cimg_for7V(img,v) cimg_for7((img).dim,v)
00691 #define cimg_for7XY(img,x,y) cimg_for7Y(img,y) cimg_for7X(img,x)
00692 #define cimg_for7XZ(img,x,z) cimg_for7Z(img,z) cimg_for7X(img,x)
00693 #define cimg_for7XV(img,x,v) cimg_for7V(img,v) cimg_for7X(img,x)
00694 #define cimg_for7YZ(img,y,z) cimg_for7Z(img,z) cimg_for7Y(img,y)
00695 #define cimg_for7YV(img,y,v) cimg_for7V(img,v) cimg_for7Y(img,y)
00696 #define cimg_for7ZV(img,z,v) cimg_for7V(img,v) cimg_for7Z(img,z)
00697 #define cimg_for7XYZ(img,x,y,z) cimg_for7Z(img,z) cimg_for7XY(img,x,y)
00698 #define cimg_for7XZV(img,x,z,v) cimg_for7V(img,v) cimg_for7XZ(img,x,z)
00699 #define cimg_for7YZV(img,y,z,v) cimg_for7V(img,v) cimg_for7YZ(img,y,z)
00700 #define cimg_for7XYZV(img,x,y,z,v) cimg_for7V(img,v) cimg_for7XYZ(img,x,y,z)
00701
00702 #define cimg_for_in7(bound,i0,i1,i) \
00703 for (int i = (int)(i0)<0?0:(int)(i0), \
00704 _p3##i = i-3<0?0:i-3, \
00705 _p2##i = i-2<0?0:i-2, \
00706 _p1##i = i-1<0?0:i-1, \
00707 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
00708 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2, \
00709 _n3##i = i+3>=(int)(bound)?(int)(bound)-1:i+3; \
00710 i<=(int)(i1) && (_n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i)); \
00711 _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
00712 #define cimg_for_in7X(img,x0,x1,x) cimg_for_in7((img).width,x0,x1,x)
00713 #define cimg_for_in7Y(img,y0,y1,y) cimg_for_in7((img).height,y0,y1,y)
00714 #define cimg_for_in7Z(img,z0,z1,z) cimg_for_in7((img).depth,z0,z1,z)
00715 #define cimg_for_in7V(img,v0,v1,v) cimg_for_in7((img).dim,v0,v1,v)
00716 #define cimg_for_in7XY(img,x0,y0,x1,y1,x,y) cimg_for_in7Y(img,y0,y1,y) cimg_for_in7X(img,x0,x1,x)
00717 #define cimg_for_in7XZ(img,x0,z0,x1,z1,x,z) cimg_for_in7Z(img,z0,z1,z) cimg_for_in7X(img,x0,x1,x)
00718 #define cimg_for_in7XV(img,x0,v0,x1,v1,x,v) cimg_for_in7V(img,v0,v1,v) cimg_for_in7X(img,x0,x1,x)
00719 #define cimg_for_in7YZ(img,y0,z0,y1,z1,y,z) cimg_for_in7Z(img,z0,z1,z) cimg_for_in7Y(img,y0,y1,y)
00720 #define cimg_for_in7YV(img,y0,v0,y1,v1,y,v) cimg_for_in7V(img,v0,v1,v) cimg_for_in7Y(img,y0,y1,y)
00721 #define cimg_for_in7ZV(img,z0,v0,z1,v1,z,v) cimg_for_in7V(img,v0,v1,v) cimg_for_in7Z(img,z0,z1,z)
00722 #define cimg_for_in7XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in7Z(img,z0,z1,z) cimg_for_in7XY(img,x0,y0,x1,y1,x,y)
00723 #define cimg_for_in7XZV(img,x0,z0,v0,x1,y1,v1,x,z,v) cimg_for_in7V(img,v0,v1,v) cimg_for_in7XZ(img,x0,y0,x1,y1,x,z)
00724 #define cimg_for_in7YZV(img,y0,z0,v0,y1,z1,v1,y,z,v) cimg_for_in7V(img,v0,v1,v) cimg_for_in7YZ(img,y0,z0,y1,z1,y,z)
00725 #define cimg_for_in7XYZV(img,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) cimg_for_in7V(img,v0,v1,v) cimg_for_in7XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
00726
00727 #define cimg_for2x2(img,x,y,z,v,I) \
00728 cimg_for2((img).height,y) for (int x = 0, \
00729 _n1##x = (int)( \
00730 (I[0] = (img)(0,y,z,v)), \
00731 (I[2] = (img)(0,_n1##y,z,v)), \
00732 1>=(img).width?(int)((img).width)-1:1); \
00733 (_n1##x<(int)((img).width) && ( \
00734 (I[1] = (img)(_n1##x,y,z,v)), \
00735 (I[3] = (img)(_n1##x,_n1##y,z,v)),1)) || \
00736 x==--_n1##x; \
00737 I[0] = I[1], \
00738 I[2] = I[3], \
00739 ++x, ++_n1##x)
00740
00741 #define cimg_for_in2x2(img,x0,y0,x1,y1,x,y,z,v,I) \
00742 cimg_for_in2((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
00743 _n1##x = (int)( \
00744 (I[0] = (img)(x,y,z,v)), \
00745 (I[2] = (img)(x,_n1##y,z,v)), \
00746 x+1>=(int)(img).width?(int)((img).width)-1:x+1); \
00747 x<=(int)(x1) && ((_n1##x<(int)((img).width) && ( \
00748 (I[1] = (img)(_n1##x,y,z,v)), \
00749 (I[3] = (img)(_n1##x,_n1##y,z,v)),1)) || \
00750 x==--_n1##x); \
00751 I[0] = I[1], \
00752 I[2] = I[3], \
00753 ++x, ++_n1##x)
00754
00755 #define cimg_for3x3(img,x,y,z,v,I) \
00756 cimg_for3((img).height,y) for (int x = 0, \
00757 _p1##x = 0, \
00758 _n1##x = (int)( \
00759 (I[0] = I[1] = (img)(0,_p1##y,z,v)), \
00760 (I[3] = I[4] = (img)(0,y,z,v)), \
00761 (I[6] = I[7] = (img)(0,_n1##y,z,v)), \
00762 1>=(img).width?(int)((img).width)-1:1); \
00763 (_n1##x<(int)((img).width) && ( \
00764 (I[2] = (img)(_n1##x,_p1##y,z,v)), \
00765 (I[5] = (img)(_n1##x,y,z,v)), \
00766 (I[8] = (img)(_n1##x,_n1##y,z,v)),1)) || \
00767 x==--_n1##x; \
00768 I[0] = I[1], I[1] = I[2], \
00769 I[3] = I[4], I[4] = I[5], \
00770 I[6] = I[7], I[7] = I[8], \
00771 _p1##x = x++, ++_n1##x)
00772
00773 #define cimg_for_in3x3(img,x0,y0,x1,y1,x,y,z,v,I) \
00774 cimg_for_in3((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
00775 _p1##x = x-1<0?0:x-1, \
00776 _n1##x = (int)( \
00777 (I[0] = (img)(_p1##x,_p1##y,z,v)), \
00778 (I[3] = (img)(_p1##x,y,z,v)), \
00779 (I[6] = (img)(_p1##x,_n1##y,z,v)), \
00780 (I[1] = (img)(x,_p1##y,z,v)), \
00781 (I[4] = (img)(x,y,z,v)), \
00782 (I[7] = (img)(x,_n1##y,z,v)), \
00783 x+1>=(int)(img).width?(int)((img).width)-1:x+1); \
00784 x<=(int)(x1) && ((_n1##x<(int)((img).width) && ( \
00785 (I[2] = (img)(_n1##x,_p1##y,z,v)), \
00786 (I[5] = (img)(_n1##x,y,z,v)), \
00787 (I[8] = (img)(_n1##x,_n1##y,z,v)),1)) || \
00788 x==--_n1##x); \
00789 I[0] = I[1], I[1] = I[2], \
00790 I[3] = I[4], I[4] = I[5], \
00791 I[6] = I[7], I[7] = I[8], \
00792 _p1##x = x++, ++_n1##x)
00793
00794 #define cimg_for4x4(img,x,y,z,v,I) \
00795 cimg_for4((img).height,y) for (int x = 0, \
00796 _p1##x = 0, \
00797 _n1##x = 1>=(img).width?(int)((img).width)-1:1, \
00798 _n2##x = (int)( \
00799 (I[0] = I[1] = (img)(0,_p1##y,z,v)), \
00800 (I[4] = I[5] = (img)(0,y,z,v)), \
00801 (I[8] = I[9] = (img)(0,_n1##y,z,v)), \
00802 (I[12] = I[13] = (img)(0,_n2##y,z,v)), \
00803 (I[2] = (img)(_n1##x,_p1##y,z,v)), \
00804 (I[6] = (img)(_n1##x,y,z,v)), \
00805 (I[10] = (img)(_n1##x,_n1##y,z,v)), \
00806 (I[14] = (img)(_n1##x,_n2##y,z,v)), \
00807 2>=(img).width?(int)((img).width)-1:2); \
00808 (_n2##x<(int)((img).width) && ( \
00809 (I[3] = (img)(_n2##x,_p1##y,z,v)), \
00810 (I[7] = (img)(_n2##x,y,z,v)), \
00811 (I[11] = (img)(_n2##x,_n1##y,z,v)), \
00812 (I[15] = (img)(_n2##x,_n2##y,z,v)),1)) || \
00813 _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \
00814 I[0] = I[1], I[1] = I[2], I[2] = I[3], \
00815 I[4] = I[5], I[5] = I[6], I[6] = I[7], \
00816 I[8] = I[9], I[9] = I[10], I[10] = I[11], \
00817 I[12] = I[13], I[13] = I[14], I[14] = I[15], \
00818 _p1##x = x++, ++_n1##x, ++_n2##x)
00819
00820 #define cimg_for_in4x4(img,x0,y0,x1,y1,x,y,z,v,I) \
00821 cimg_for_in4((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
00822 _p1##x = x-1<0?0:x-1, \
00823 _n1##x = x+1>=(int)(img).width?(int)((img).width)-1:x+1, \
00824 _n2##x = (int)( \
00825 (I[0] = (img)(_p1##x,_p1##y,z,v)), \
00826 (I[4] = (img)(_p1##x,y,z,v)), \
00827 (I[8] = (img)(_p1##x,_n1##y,z,v)), \
00828 (I[12] = (img)(_p1##x,_n2##y,z,v)), \
00829 (I[1] = (img)(x,_p1##y,z,v)), \
00830 (I[5] = (img)(x,y,z,v)), \
00831 (I[9] = (img)(x,_n1##y,z,v)), \
00832 (I[13] = (img)(x,_n2##y,z,v)), \
00833 (I[2] = (img)(_n1##x,_p1##y,z,v)), \
00834 (I[6] = (img)(_n1##x,y,z,v)), \
00835 (I[10] = (img)(_n1##x,_n1##y,z,v)), \
00836 (I[14] = (img)(_n1##x,_n2##y,z,v)), \
00837 x+2>=(int)(img).width?(int)((img).width)-1:x+2); \
00838 x<=(int)(x1) && ((_n2##x<(int)((img).width) && ( \
00839 (I[3] = (img)(_n2##x,_p1##y,z,v)), \
00840 (I[7] = (img)(_n2##x,y,z,v)), \
00841 (I[11] = (img)(_n2##x,_n1##y,z,v)), \
00842 (I[15] = (img)(_n2##x,_n2##y,z,v)),1)) || \
00843 _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \
00844 I[0] = I[1], I[1] = I[2], I[2] = I[3], \
00845 I[4] = I[5], I[5] = I[6], I[6] = I[7], \
00846 I[8] = I[9], I[9] = I[10], I[10] = I[11], \
00847 I[12] = I[13], I[13] = I[14], I[14] = I[15], \
00848 _p1##x = x++, ++_n1##x, ++_n2##x)
00849
00850 #define cimg_for5x5(img,x,y,z,v,I) \
00851 cimg_for5((img).height,y) for (int x = 0, \
00852 _p2##x = 0, _p1##x = 0, \
00853 _n1##x = 1>=(img).width?(int)((img).width)-1:1, \
00854 _n2##x = (int)( \
00855 (I[0] = I[1] = I[2] = (img)(0,_p2##y,z,v)), \
00856 (I[5] = I[6] = I[7] = (img)(0,_p1##y,z,v)), \
00857 (I[10] = I[11] = I[12] = (img)(0,y,z,v)), \
00858 (I[15] = I[16] = I[17] = (img)(0,_n1##y,z,v)), \
00859 (I[20] = I[21] = I[22] = (img)(0,_n2##y,z,v)), \
00860 (I[3] = (img)(_n1##x,_p2##y,z,v)), \
00861 (I[8] = (img)(_n1##x,_p1##y,z,v)), \
00862 (I[13] = (img)(_n1##x,y,z,v)), \
00863 (I[18] = (img)(_n1##x,_n1##y,z,v)), \
00864 (I[23] = (img)(_n1##x,_n2##y,z,v)), \
00865 2>=(img).width?(int)((img).width)-1:2); \
00866 (_n2##x<(int)((img).width) && ( \
00867 (I[4] = (img)(_n2##x,_p2##y,z,v)), \
00868 (I[9] = (img)(_n2##x,_p1##y,z,v)), \
00869 (I[14] = (img)(_n2##x,y,z,v)), \
00870 (I[19] = (img)(_n2##x,_n1##y,z,v)), \
00871 (I[24] = (img)(_n2##x,_n2##y,z,v)),1)) || \
00872 _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \
00873 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \
00874 I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \
00875 I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \
00876 I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \
00877 I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \
00878 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x)
00879
00880 #define cimg_for_in5x5(img,x0,y0,x1,y1,x,y,z,v,I) \
00881 cimg_for_in5((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
00882 _p2##x = x-2<0?0:x-2, \
00883 _p1##x = x-1<0?0:x-1, \
00884 _n1##x = x+1>=(int)(img).width?(int)((img).width)-1:x+1, \
00885 _n2##x = (int)( \
00886 (I[0] = (img)(_p2##x,_p2##y,z,v)), \
00887 (I[5] = (img)(_p2##x,_p1##y,z,v)), \
00888 (I[10] = (img)(_p2##x,y,z,v)), \
00889 (I[15] = (img)(_p2##x,_n1##y,z,v)), \
00890 (I[20] = (img)(_p2##x,_n2##y,z,v)), \
00891 (I[1] = (img)(_p1##x,_p2##y,z,v)), \
00892 (I[6] = (img)(_p1##x,_p1##y,z,v)), \
00893 (I[11] = (img)(_p1##x,y,z,v)), \
00894 (I[16] = (img)(_p1##x,_n1##y,z,v)), \
00895 (I[21] = (img)(_p1##x,_n2##y,z,v)), \
00896 (I[2] = (img)(x,_p2##y,z,v)), \
00897 (I[7] = (img)(x,_p1##y,z,v)), \
00898 (I[12] = (img)(x,y,z,v)), \
00899 (I[17] = (img)(x,_n1##y,z,v)), \
00900 (I[22] = (img)(x,_n2##y,z,v)), \
00901 (I[3] = (img)(_n1##x,_p2##y,z,v)), \
00902 (I[8] = (img)(_n1##x,_p1##y,z,v)), \
00903 (I[13] = (img)(_n1##x,y,z,v)), \
00904 (I[18] = (img)(_n1##x,_n1##y,z,v)), \
00905 (I[23] = (img)(_n1##x,_n2##y,z,v)), \
00906 x+2>=(int)(img).width?(int)((img).width)-1:x+2); \
00907 x<=(int)(x1) && ((_n2##x<(int)((img).width) && ( \
00908 (I[4] = (img)(_n2##x,_p2##y,z,v)), \
00909 (I[9] = (img)(_n2##x,_p1##y,z,v)), \
00910 (I[14] = (img)(_n2##x,y,z,v)), \
00911 (I[19] = (img)(_n2##x,_n1##y,z,v)), \
00912 (I[24] = (img)(_n2##x,_n2##y,z,v)),1)) || \
00913 _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \
00914 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \
00915 I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \
00916 I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \
00917 I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \
00918 I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \
00919 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x)
00920
00921 #define cimg_for6x6(img,x,y,z,v,I) \
00922 cimg_for6((img).height,y) for (int x = 0, \
00923 _p2##x = 0, _p1##x = 0, \
00924 _n1##x = 1>=(img).width?(int)((img).width)-1:1, \
00925 _n2##x = 2>=(img).width?(int)((img).width)-1:2, \
00926 _n3##x = (int)( \
00927 (I[0] = I[1] = I[2] = (img)(0,_p2##y,z,v)), \
00928 (I[6] = I[7] = I[8] = (img)(0,_p1##y,z,v)), \
00929 (I[12] = I[13] = I[14] = (img)(0,y,z,v)), \
00930 (I[18] = I[19] = I[20] = (img)(0,_n1##y,z,v)), \
00931 (I[24] = I[25] = I[26] = (img)(0,_n2##y,z,v)), \
00932 (I[30] = I[31] = I[32] = (img)(0,_n3##y,z,v)), \
00933 (I[3] = (img)(_n1##x,_p2##y,z,v)), \
00934 (I[9] = (img)(_n1##x,_p1##y,z,v)), \
00935 (I[15] = (img)(_n1##x,y,z,v)), \
00936 (I[21] = (img)(_n1##x,_n1##y,z,v)), \
00937 (I[27] = (img)(_n1##x,_n2##y,z,v)), \
00938 (I[33] = (img)(_n1##x,_n3##y,z,v)), \
00939 (I[4] = (img)(_n2##x,_p2##y,z,v)), \
00940 (I[10] = (img)(_n2##x,_p1##y,z,v)), \
00941 (I[16] = (img)(_n2##x,y,z,v)), \
00942 (I[22] = (img)(_n2##x,_n1##y,z,v)), \
00943 (I[28] = (img)(_n2##x,_n2##y,z,v)), \
00944 (I[34] = (img)(_n2##x,_n3##y,z,v)), \
00945 3>=(img).width?(int)((img).width)-1:3); \
00946 (_n3##x<(int)((img).width) && ( \
00947 (I[5] = (img)(_n3##x,_p2##y,z,v)), \
00948 (I[11] = (img)(_n3##x,_p1##y,z,v)), \
00949 (I[17] = (img)(_n3##x,y,z,v)), \
00950 (I[23] = (img)(_n3##x,_n1##y,z,v)), \
00951 (I[29] = (img)(_n3##x,_n2##y,z,v)), \
00952 (I[35] = (img)(_n3##x,_n3##y,z,v)),1)) || \
00953 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3## x = _n2##x = --_n1##x); \
00954 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \
00955 I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \
00956 I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \
00957 I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \
00958 I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \
00959 I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \
00960 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
00961
00962 #define cimg_for_in6x6(img,x0,y0,x1,y1,x,y,z,v,I) \
00963 cimg_for_in6((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)x0, \
00964 _p2##x = x-2<0?0:x-2, \
00965 _p1##x = x-1<0?0:x-1, \
00966 _n1##x = x+1>=(int)(img).width?(int)((img).width)-1:x+1, \
00967 _n2##x = x+2>=(int)(img).width?(int)((img).width)-1:x+2, \
00968 _n3##x = (int)( \
00969 (I[0] = (img)(_p2##x,_p2##y,z,v)), \
00970 (I[6] = (img)(_p2##x,_p1##y,z,v)), \
00971 (I[12] = (img)(_p2##x,y,z,v)), \
00972 (I[18] = (img)(_p2##x,_n1##y,z,v)), \
00973 (I[24] = (img)(_p2##x,_n2##y,z,v)), \
00974 (I[30] = (img)(_p2##x,_n3##y,z,v)), \
00975 (I[1] = (img)(_p1##x,_p2##y,z,v)), \
00976 (I[7] = (img)(_p1##x,_p1##y,z,v)), \
00977 (I[13] = (img)(_p1##x,y,z,v)), \
00978 (I[19] = (img)(_p1##x,_n1##y,z,v)), \
00979 (I[25] = (img)(_p1##x,_n2##y,z,v)), \
00980 (I[31] = (img)(_p1##x,_n3##y,z,v)), \
00981 (I[2] = (img)(x,_p2##y,z,v)), \
00982 (I[8] = (img)(x,_p1##y,z,v)), \
00983 (I[14] = (img)(x,y,z,v)), \
00984 (I[20] = (img)(x,_n1##y,z,v)), \
00985 (I[26] = (img)(x,_n2##y,z,v)), \
00986 (I[32] = (img)(x,_n3##y,z,v)), \
00987 (I[3] = (img)(_n1##x,_p2##y,z,v)), \
00988 (I[9] = (img)(_n1##x,_p1##y,z,v)), \
00989 (I[15] = (img)(_n1##x,y,z,v)), \
00990 (I[21] = (img)(_n1##x,_n1##y,z,v)), \
00991 (I[27] = (img)(_n1##x,_n2##y,z,v)), \
00992 (I[33] = (img)(_n1##x,_n3##y,z,v)), \
00993 (I[4] = (img)(_n2##x,_p2##y,z,v)), \
00994 (I[10] = (img)(_n2##x,_p1##y,z,v)), \
00995 (I[16] = (img)(_n2##x,y,z,v)), \
00996 (I[22] = (img)(_n2##x,_n1##y,z,v)), \
00997 (I[28] = (img)(_n2##x,_n2##y,z,v)), \
00998 (I[34] = (img)(_n2##x,_n3##y,z,v)), \
00999 x+3>=(int)(img).width?(int)((img).width)-1:x+3); \
01000 x<=(int)(x1) && ((_n3##x<(int)((img).width) && ( \
01001 (I[5] = (img)(_n3##x,_p2##y,z,v)), \
01002 (I[11] = (img)(_n3##x,_p1##y,z,v)), \
01003 (I[17] = (img)(_n3##x,y,z,v)), \
01004 (I[23] = (img)(_n3##x,_n1##y,z,v)), \
01005 (I[29] = (img)(_n3##x,_n2##y,z,v)), \
01006 (I[35] = (img)(_n3##x,_n3##y,z,v)),1)) || \
01007 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3## x = _n2##x = --_n1##x)); \
01008 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \
01009 I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \
01010 I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \
01011 I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \
01012 I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \
01013 I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \
01014 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
01015
01016 #define cimg_for7x7(img,x,y,z,v,I) \
01017 cimg_for7((img).height,y) for (int x = 0, \
01018 _p3##x = 0, _p2##x = 0, _p1##x = 0, \
01019 _n1##x = 1>=(img).width?(int)((img).width)-1:1, \
01020 _n2##x = 2>=(img).width?(int)((img).width)-1:2, \
01021 _n3##x = (int)( \
01022 (I[0] = I[1] = I[2] = I[3] = (img)(0,_p3##y,z,v)), \
01023 (I[7] = I[8] = I[9] = I[10] = (img)(0,_p2##y,z,v)), \
01024 (I[14] = I[15] = I[16] = I[17] = (img)(0,_p1##y,z,v)), \
01025 (I[21] = I[22] = I[23] = I[24] = (img)(0,y,z,v)), \
01026 (I[28] = I[29] = I[30] = I[31] = (img)(0,_n1##y,z,v)), \
01027 (I[35] = I[36] = I[37] = I[38] = (img)(0,_n2##y,z,v)), \
01028 (I[42] = I[43] = I[44] = I[45] = (img)(0,_n3##y,z,v)), \
01029 (I[4] = (img)(_n1##x,_p3##y,z,v)), \
01030 (I[11] = (img)(_n1##x,_p2##y,z,v)), \
01031 (I[18] = (img)(_n1##x,_p1##y,z,v)), \
01032 (I[25] = (img)(_n1##x,y,z,v)), \
01033 (I[32] = (img)(_n1##x,_n1##y,z,v)), \
01034 (I[39] = (img)(_n1##x,_n2##y,z,v)), \
01035 (I[46] = (img)(_n1##x,_n3##y,z,v)), \
01036 (I[5] = (img)(_n2##x,_p3##y,z,v)), \
01037 (I[12] = (img)(_n2##x,_p2##y,z,v)), \
01038 (I[19] = (img)(_n2##x,_p1##y,z,v)), \
01039 (I[26] = (img)(_n2##x,y,z,v)), \
01040 (I[33] = (img)(_n2##x,_n1##y,z,v)), \
01041 (I[40] = (img)(_n2##x,_n2##y,z,v)), \
01042 (I[47] = (img)(_n2##x,_n3##y,z,v)), \
01043 3>=(img).width?(int)((img).width)-1:3); \
01044 (_n3##x<(int)((img).width) && ( \
01045 (I[6] = (img)(_n3##x,_p3##y,z,v)), \
01046 (I[13] = (img)(_n3##x,_p2##y,z,v)), \
01047 (I[20] = (img)(_n3##x,_p1##y,z,v)), \
01048 (I[27] = (img)(_n3##x,y,z,v)), \
01049 (I[34] = (img)(_n3##x,_n1##y,z,v)), \
01050 (I[41] = (img)(_n3##x,_n2##y,z,v)), \
01051 (I[48] = (img)(_n3##x,_n3##y,z,v)),1)) || \
01052 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x); \
01053 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \
01054 I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \
01055 I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \
01056 I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \
01057 I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \
01058 I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \
01059 I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \
01060 _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
01061
01062 #define cimg_for_in7x7(img,x0,y0,x1,y1,x,y,z,v,I) \
01063 cimg_for_in7((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
01064 _p3##x = x-3<0?0:x-3, \
01065 _p2##x = x-2<0?0:x-2, \
01066 _p1##x = x-1<0?0:x-1, \
01067 _n1##x = x+1>=(int)(img).width?(int)((img).width)-1:x+1, \
01068 _n2##x = x+2>=(int)(img).width?(int)((img).width)-1:x+2, \
01069 _n3##x = (int)( \
01070 (I[0] = (img)(_p3##x,_p3##y,z,v)), \
01071 (I[7] = (img)(_p3##x,_p2##y,z,v)), \
01072 (I[14] = (img)(_p3##x,_p1##y,z,v)), \
01073 (I[21] = (img)(_p3##x,y,z,v)), \
01074 (I[28] = (img)(_p3##x,_n1##y,z,v)), \
01075 (I[35] = (img)(_p3##x,_n2##y,z,v)), \
01076 (I[42] = (img)(_p3##x,_n3##y,z,v)), \
01077 (I[1] = (img)(_p2##x,_p3##y,z,v)), \
01078 (I[8] = (img)(_p2##x,_p2##y,z,v)), \
01079 (I[15] = (img)(_p2##x,_p1##y,z,v)), \
01080 (I[22] = (img)(_p2##x,y,z,v)), \
01081 (I[29] = (img)(_p2##x,_n1##y,z,v)), \
01082 (I[36] = (img)(_p2##x,_n2##y,z,v)), \
01083 (I[43] = (img)(_p2##x,_n3##y,z,v)), \
01084 (I[2] = (img)(_p1##x,_p3##y,z,v)), \
01085 (I[9] = (img)(_p1##x,_p2##y,z,v)), \
01086 (I[16] = (img)(_p1##x,_p1##y,z,v)), \
01087 (I[23] = (img)(_p1##x,y,z,v)), \
01088 (I[30] = (img)(_p1##x,_n1##y,z,v)), \
01089 (I[37] = (img)(_p1##x,_n2##y,z,v)), \
01090 (I[44] = (img)(_p1##x,_n3##y,z,v)), \
01091 (I[3] = (img)(x,_p3##y,z,v)), \
01092 (I[10] = (img)(x,_p2##y,z,v)), \
01093 (I[17] = (img)(x,_p1##y,z,v)), \
01094 (I[24] = (img)(x,y,z,v)), \
01095 (I[31] = (img)(x,_n1##y,z,v)), \
01096 (I[38] = (img)(x,_n2##y,z,v)), \
01097 (I[45] = (img)(x,_n3##y,z,v)), \
01098 (I[4] = (img)(_n1##x,_p3##y,z,v)), \
01099 (I[11] = (img)(_n1##x,_p2##y,z,v)), \
01100 (I[18] = (img)(_n1##x,_p1##y,z,v)), \
01101 (I[25] = (img)(_n1##x,y,z,v)), \
01102 (I[32] = (img)(_n1##x,_n1##y,z,v)), \
01103 (I[39] = (img)(_n1##x,_n2##y,z,v)), \
01104 (I[46] = (img)(_n1##x,_n3##y,z,v)), \
01105 (I[5] = (img)(_n2##x,_p3##y,z,v)), \
01106 (I[12] = (img)(_n2##x,_p2##y,z,v)), \
01107 (I[19] = (img)(_n2##x,_p1##y,z,v)), \
01108 (I[26] = (img)(_n2##x,y,z,v)), \
01109 (I[33] = (img)(_n2##x,_n1##y,z,v)), \
01110 (I[40] = (img)(_n2##x,_n2##y,z,v)), \
01111 (I[47] = (img)(_n2##x,_n3##y,z,v)), \
01112 x+3>=(int)(img).width?(int)((img).width)-1:x+3); \
01113 x<=(int)(x1) && ((_n3##x<(int)((img).width) && ( \
01114 (I[6] = (img)(_n3##x,_p3##y,z,v)), \
01115 (I[13] = (img)(_n3##x,_p2##y,z,v)), \
01116 (I[20] = (img)(_n3##x,_p1##y,z,v)), \
01117 (I[27] = (img)(_n3##x,y,z,v)), \
01118 (I[34] = (img)(_n3##x,_n1##y,z,v)), \
01119 (I[41] = (img)(_n3##x,_n2##y,z,v)), \
01120 (I[48] = (img)(_n3##x,_n3##y,z,v)),1)) || \
01121 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x)); \
01122 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \
01123 I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \
01124 I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \
01125 I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \
01126 I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \
01127 I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \
01128 I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \
01129 _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
01130
01131 #define cimg_for2x2x2(img,x,y,z,v,I) \
01132 cimg_for2((img).depth,z) cimg_for2((img).height,y) for (int x = 0, \
01133 _n1##x = (int)( \
01134 (I[0] = (img)(0,y,z,v)), \
01135 (I[2] = (img)(0,_n1##y,z,v)), \
01136 (I[4] = (img)(0,y,_n1##z,v)), \
01137 (I[6] = (img)(0,_n1##y,_n1##z,v)), \
01138 1>=(img).width?(int)((img).width)-1:1); \
01139 (_n1##x<(int)((img).width) && ( \
01140 (I[1] = (img)(_n1##x,y,z,v)), \
01141 (I[3] = (img)(_n1##x,_n1##y,z,v)), \
01142 (I[5] = (img)(_n1##x,y,_n1##z,v)), \
01143 (I[7] = (img)(_n1##x,_n1##y,_n1##z,v)),1)) || \
01144 x==--_n1##x; \
01145 I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], \
01146 ++x, ++_n1##x)
01147
01148 #define cimg_for_in2x2x2(img,x0,y0,z0,x1,y1,z1,x,y,z,v,I) \
01149 cimg_for_in2((img).depth,z0,z1,z) cimg_for_in2((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
01150 _n1##x = (int)( \
01151 (I[0] = (img)(x,y,z,v)), \
01152 (I[2] = (img)(x,_n1##y,z,v)), \
01153 (I[4] = (img)(x,y,_n1##z,v)), \
01154 (I[6] = (img)(x,_n1##y,_n1##z,v)), \
01155 x+1>=(int)(img).width?(int)((img).width)-1:x+1); \
01156 x<=(int)(x1) && ((_n1##x<(int)((img).width) && ( \
01157 (I[1] = (img)(_n1##x,y,z,v)), \
01158 (I[3] = (img)(_n1##x,_n1##y,z,v)), \
01159 (I[5] = (img)(_n1##x,y,_n1##z,v)), \
01160 (I[7] = (img)(_n1##x,_n1##y,_n1##z,v)),1)) || \
01161 x==--_n1##x); \
01162 I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], \
01163 ++x, ++_n1##x)
01164
01165 #define cimg_for3x3x3(img,x,y,z,v,I) \
01166 cimg_for3((img).depth,z) cimg_for3((img).height,y) for (int x = 0, \
01167 _p1##x = 0, \
01168 _n1##x = (int)( \
01169 (I[0] = I[1] = (img)(0,_p1##y,_p1##z,v)), \
01170 (I[3] = I[4] = (img)(0,y,_p1##z,v)), \
01171 (I[6] = I[7] = (img)(0,_n1##y,_p1##z,v)), \
01172 (I[9] = I[10] = (img)(0,_p1##y,z,v)), \
01173 (I[12] = I[13] = (img)(0,y,z,v)), \
01174 (I[15] = I[16] = (img)(0,_n1##y,z,v)), \
01175 (I[18] = I[19] = (img)(0,_p1##y,_n1##z,v)), \
01176 (I[21] = I[22] = (img)(0,y,_n1##z,v)), \
01177 (I[24] = I[25] = (img)(0,_n1##y,_n1##z,v)), \
01178 1>=(img).width?(int)((img).width)-1:1); \
01179 (_n1##x<(int)((img).width) && ( \
01180 (I[2] = (img)(_n1##x,_p1##y,_p1##z,v)), \
01181 (I[5] = (img)(_n1##x,y,_p1##z,v)), \
01182 (I[8] = (img)(_n1##x,_n1##y,_p1##z,v)), \
01183 (I[11] = (img)(_n1##x,_p1##y,z,v)), \
01184 (I[14] = (img)(_n1##x,y,z,v)), \
01185 (I[17] = (img)(_n1##x,_n1##y,z,v)), \
01186 (I[20] = (img)(_n1##x,_p1##y,_n1##z,v)), \
01187 (I[23] = (img)(_n1##x,y,_n1##z,v)), \
01188 (I[26] = (img)(_n1##x,_n1##y,_n1##z,v)),1)) || \
01189 x==--_n1##x; \
01190 I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], \
01191 I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], \
01192 I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], \
01193 _p1##x = x++, ++_n1##x)
01194
01195 #define cimg_for_in3x3x3(img,x0,y0,z0,x1,y1,z1,x,y,z,v,I) \
01196 cimg_for_in3((img).depth,z0,z1,z) cimg_for_in3((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
01197 _p1##x = x-1<0?0:x-1, \
01198 _n1##x = (int)( \
01199 (I[0] = (img)(_p1##x,_p1##y,_p1##z,v)), \
01200 (I[3] = (img)(_p1##x,y,_p1##z,v)), \
01201 (I[6] = (img)(_p1##x,_n1##y,_p1##z,v)), \
01202 (I[9] = (img)(_p1##x,_p1##y,z,v)), \
01203 (I[12] = (img)(_p1##x,y,z,v)), \
01204 (I[15] = (img)(_p1##x,_n1##y,z,v)), \
01205 (I[18] = (img)(_p1##x,_p1##y,_n1##z,v)), \
01206 (I[21] = (img)(_p1##x,y,_n1##z,v)), \
01207 (I[24] = (img)(_p1##x,_n1##y,_n1##z,v)), \
01208 (I[1] = (img)(x,_p1##y,_p1##z,v)), \
01209 (I[4] = (img)(x,y,_p1##z,v)), \
01210 (I[7] = (img)(x,_n1##y,_p1##z,v)), \
01211 (I[10] = (img)(x,_p1##y,z,v)), \
01212 (I[13] = (img)(x,y,z,v)), \
01213 (I[16] = (img)(x,_n1##y,z,v)), \
01214 (I[19] = (img)(x,_p1##y,_n1##z,v)), \
01215 (I[22] = (img)(x,y,_n1##z,v)), \
01216 (I[25] = (img)(x,_n1##y,_n1##z,v)), \
01217 x+1>=(int)(img).width?(int)((img).width)-1:x+1); \
01218 x<=(int)(x1) && ((_n1##x<(int)((img).width) && ( \
01219 (I[2] = (img)(_n1##x,_p1##y,_p1##z,v)), \
01220 (I[5] = (img)(_n1##x,y,_p1##z,v)), \
01221 (I[8] = (img)(_n1##x,_n1##y,_p1##z,v)), \
01222 (I[11] = (img)(_n1##x,_p1##y,z,v)), \
01223 (I[14] = (img)(_n1##x,y,z,v)), \
01224 (I[17] = (img)(_n1##x,_n1##y,z,v)), \
01225 (I[20] = (img)(_n1##x,_p1##y,_n1##z,v)), \
01226 (I[23] = (img)(_n1##x,y,_n1##z,v)), \
01227 (I[26] = (img)(_n1##x,_n1##y,_n1##z,v)),1)) || \
01228 x==--_n1##x); \
01229 I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], \
01230 I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], \
01231 I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], \
01232 _p1##x = x++, ++_n1##x)
01233
01234 #define _CImg_stdarg(img,a0,a1,N,t) \
01235 { unsigned int _siz = (unsigned int)N; \
01236 if (_siz--) { \
01237 va_list ap; \
01238 va_start(ap,a1); \
01239 T *ptrd = (img).data; \
01240 *(ptrd++) = (T)a0; \
01241 if (_siz--) { \
01242 *(ptrd++) = (T)a1; \
01243 for (; _siz; --_siz) *(ptrd++) = (T)va_arg(ap,t); \
01244 } \
01245 va_end(ap); \
01246 }}
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01259
01270 namespace cimg_library {
01271
01272
01273 template<typename T=float> struct CImg;
01274 template<typename T=float> struct CImgList;
01275 struct CImgDisplay;
01276 struct CImgException;
01277
01278 namespace cimg {
01279
01280
01281 inline void info();
01282
01283 inline unsigned int& exception_mode();
01284
01285 inline int dialog(const char *title, const char *msg, const char *button1_txt="OK",
01286 const char *button2_txt=0, const char *button3_txt=0,
01287 const char *button4_txt=0, const char *button5_txt=0,
01288 const char *button6_txt=0, const bool centering=false);
01289
01290 template<typename tfunc, typename tp, typename tf>
01291 inline void marching_cubes(const tfunc& func, const float isovalue,
01292 const float x0, const float y0, const float z0,
01293 const float x1, const float y1, const float z1,
01294 const float resx, const float resy, const float resz,
01295 CImgList<tp>& points, CImgList<tf>& primitives,
01296 const bool invert_faces=false);
01297
01298 template<typename tfunc, typename tp, typename tf>
01299 inline void marching_squares(const tfunc& func, const float isovalue,
01300 const float x0, const float y0,
01301 const float x1, const float y1,
01302 const float resx, const float resy,
01303 CImgList<tp>& points, CImgList<tf>& primitives);
01304 }
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317 #define cimg_exception_err(etype,disp_flag) \
01318 std::va_list ap; \
01319 va_start(ap,format); \
01320 std::vsprintf(message,format,ap); \
01321 va_end(ap); \
01322 if (cimg::exception_mode()>=1) { \
01323 if (cimg::exception_mode()>=2 && disp_flag) { \
01324 try { cimg::dialog(etype,message,"Abort"); } \
01325 catch (CImgException&) { std::fprintf(stderr,"\n# %s :\n%s\n\n",etype,message); } \
01326 } else std::fprintf(stderr,"\n# %s :\n%s\n\n",etype,message); \
01327 } \
01328 if (cimg::exception_mode()>=3) cimg_library::cimg::info(); \
01329
01330
01331
01395 struct CImgException {
01396 char message[1024];
01397 CImgException() { message[0]='\0'; }
01398 CImgException(const char *format,...) { cimg_exception_err("CImgException",true); }
01399 };
01400
01401
01402
01403 struct CImgInstanceException : public CImgException {
01404 CImgInstanceException(const char *format,...) { cimg_exception_err("CImgInstanceException",true); }
01405 };
01406
01407
01408
01409 struct CImgArgumentException : public CImgException {
01410 CImgArgumentException(const char *format,...) { cimg_exception_err("CImgArgumentException",true); }
01411 };
01412
01413
01414
01415 struct CImgIOException : public CImgException {
01416 CImgIOException(const char *format,...) { cimg_exception_err("CImgIOException",true); }
01417 };
01418
01419
01420
01421 struct CImgDisplayException : public CImgException {
01422 CImgDisplayException(const char *format,...) { cimg_exception_err("CImgDisplayException",false); }
01423 };
01424
01425
01426
01427 struct CImgWarningException : public CImgException {
01428 CImgWarningException(const char *format,...) { cimg_exception_err("CImgWarningException",false); }
01429 };
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01442
01449 namespace cimg {
01450
01451
01452 template<typename T> struct type {
01453 static const char* string() {
01454 static const char* s[] = { "unknown", "unknown8", "unknown16", "unknown24",
01455 "unknown32", "unknown40", "unknown48", "unknown56",
01456 "unknown64", "unknown72", "unknown80", "unknown88",
01457 "unknown96", "unknown104", "unknown112", "unknown120",
01458 "unknown128" };
01459 return s[(sizeof(T)<17)?sizeof(T):0];
01460 }
01461 static bool is_float() { return false; }
01462 static T min() { return (T)-1>0?(T)0:(T)-1<<(8*sizeof(T)-1); }
01463 static T max() { return (T)-1>0?(T)-1:~((T)-1<<(8*sizeof(T)-1)); }
01464 static const char* format() { return "%s"; }
01465 static const char* format(const T val) { static const char *s = "unknown"; return s; }
01466 };
01467
01468 template<> struct type<bool> {
01469 static const char* string() { static const char *const s = "bool"; return s; }
01470 static bool is_float() { return false; }
01471 static bool min() { return false; }
01472 static bool max() { return true; }
01473 static const char* format() { return "%s"; }
01474 static const char* format(const bool val) { static const char* s[] = { "false", "true" }; return s[val?1:0]; }
01475 };
01476
01477 template<> struct type<unsigned char> {
01478 static const char* string() { static const char *const s = "unsigned char"; return s; }
01479 static bool is_float() { return false; }
01480 static unsigned char min() { return 0; }
01481 static unsigned char max() { return (unsigned char)~0U; }
01482 static const char* format() { return "%u"; }
01483 static const unsigned int format(const unsigned char val) { return (unsigned int)val; }
01484 };
01485
01486 template<> struct type<char> {
01487 static const char* string() { static const char *const s = "char"; return s; }
01488 static bool is_float() { return false; }
01489 static char min() { return (char)(-1L<<(8*sizeof(char)-1)); }
01490 static char max() { return ~((char)(-1L<<(8*sizeof(char)-1))); }
01491 static const char* format() { return "%d"; }
01492 static const int format(const char val) { return (int)val; }
01493 };
01494
01495 template<> struct type<unsigned short> {
01496 static const char* string() { static const char *const s = "unsigned short"; return s; }
01497 static bool is_float() { return false; }
01498 static unsigned short min() { return 0; }
01499 static unsigned short max() { return (unsigned short)~0U; }
01500 static const char* format() { return "%u"; }
01501 static const unsigned int format(const unsigned short val) { return (unsigned int)val; }
01502 };
01503
01504 template<> struct type<short> {
01505 static const char* string() { static const char *const s = "short"; return s; }
01506 static bool is_float() { return false; }
01507 static short min() { return (short)(-1L<<(8*sizeof(short)-1)); }
01508 static short max() { return ~((short)(-1L<<(8*sizeof(short)-1))); }
01509 static const char* format() { return "%d"; }
01510 static const int format(const short val) { return (int)val; }
01511 };
01512
01513 template<> struct type<unsigned int> {
01514 static const char* string() { static const char *const s = "unsigned int"; return s; }
01515 static bool is_float() { return false; }
01516 static unsigned int min() { return 0; }
01517 static unsigned int max() { return (unsigned int)~0U; }
01518 static const char* format() { return "%u"; }
01519 static const unsigned int format(const unsigned int val) { return val; }
01520 };
01521
01522 template<> struct type<int> {
01523 static const char* string() { static const char *const s = "int"; return s; }
01524 static bool is_float() { return false; }
01525 static int min() { return (int)(-1L<<(8*sizeof(int)-1)); }
01526 static int max() { return ~((int)(-1L<<(8*sizeof(int)-1))); }
01527 static const char* format() { return "%d"; }
01528 static const int format(const int val) { return val; }
01529 };
01530
01531 template<> struct type<unsigned long> {
01532 static const char* string() { static const char *const s = "unsigned long"; return s; }
01533 static bool is_float() { return false; }
01534 static unsigned long min() { return 0; }
01535 static unsigned long max() { return (unsigned long)~0UL; }
01536 static const char* format() { return "%lu"; }
01537 static const unsigned long format(const unsigned long val) { return val; }
01538 };
01539
01540 template<> struct type<long> {
01541 static const char* string() { static const char *const s = "long"; return s; }
01542 static bool is_float() { return false; }
01543 static long min() { return (long)(-1L<<(8*sizeof(long)-1)); }
01544 static long max() { return ~((long)(-1L<<(8*sizeof(long)-1))); }
01545 static const char* format() { return "%ld"; }
01546 static const long format(const long val) { return val; }
01547 };
01548
01549 template<> struct type<float> {
01550 static const char* string() { static const char *const s = "float"; return s; }
01551 static bool is_float() { return true; }
01552 static float min() { return -3.4E38f; }
01553 static float max() { return 3.4E38f; }
01554 static const char* format() { return "%g"; }
01555 static const double format(const float val) { return (double)val; }
01556 };
01557
01558 template<> struct type<double> {
01559 static const char* string() { static const char *const s = "double"; return s; }
01560 static bool is_float() { return true; }
01561 static double min() { return -1.7E308; }
01562 static double max() { return 1.7E308; }
01563 static const char* format() { return "%g"; }
01564 static const double format(const double val) { return val; }
01565 };
01566
01567 template<typename T, typename t> struct superset { typedef T type; };
01568 template<> struct superset<bool,unsigned char> { typedef unsigned char type; };
01569 template<> struct superset<bool,char> { typedef char type; };
01570 template<> struct superset<bool,unsigned short> { typedef unsigned short type; };
01571 template<> struct superset<bool,short> { typedef short type; };
01572 template<> struct superset<bool,unsigned int> { typedef unsigned int type; };
01573 template<> struct superset<bool,int> { typedef int type; };
01574 template<> struct superset<bool,unsigned long> { typedef unsigned long type; };
01575 template<> struct superset<bool,long> { typedef long type; };
01576 template<> struct superset<bool,float> { typedef float type; };
01577 template<> struct superset<bool,double> { typedef double type; };
01578 template<> struct superset<unsigned char,char> { typedef short type; };
01579 template<> struct superset<unsigned char,unsigned short> { typedef unsigned short type; };
01580 template<> struct superset<unsigned char,short> { typedef short type; };
01581 template<> struct superset<unsigned char,unsigned int> { typedef unsigned int type; };
01582 template<> struct superset<unsigned char,int> { typedef int type; };
01583 template<> struct superset<unsigned char,unsigned long> { typedef unsigned long type; };
01584 template<> struct superset<unsigned char,long> { typedef long type; };
01585 template<> struct superset<unsigned char,float> { typedef float type; };
01586 template<> struct superset<unsigned char,double> { typedef double type; };
01587 template<> struct superset<char,unsigned char> { typedef short type; };
01588 template<> struct superset<char,unsigned short> { typedef int type; };
01589 template<> struct superset<char,short> { typedef short type; };
01590 template<> struct superset<char,unsigned int> { typedef long type; };
01591 template<> struct superset<char,int> { typedef int type; };
01592 template<> struct superset<char,unsigned long> { typedef long type; };
01593 template<> struct superset<char,long> { typedef long type; };
01594 template<> struct superset<char,float> { typedef float type; };
01595 template<> struct superset<char,double> { typedef double type; };
01596 template<> struct superset<unsigned short,char> { typedef int type; };
01597 template<> struct superset<unsigned short,short> { typedef int type; };
01598 template<> struct superset<unsigned short,unsigned int> { typedef unsigned int type; };
01599 template<> struct superset<unsigned short,int> { typedef int type; };
01600 template<> struct superset<unsigned short,unsigned long> { typedef unsigned long type; };
01601 template<> struct superset<unsigned short,long> { typedef long type; };
01602 template<> struct superset<unsigned short,float> { typedef float type; };
01603 template<> struct superset<unsigned short,double> { typedef double type; };
01604 template<> struct superset<short,unsigned short> { typedef int type; };
01605 template<> struct superset<short,unsigned int> { typedef long type; };
01606 template<> struct superset<short,int> { typedef int type; };
01607 template<> struct superset<short,unsigned long> { typedef long type; };
01608 template<> struct superset<short,long> { typedef long type; };
01609 template<> struct superset<short,float> { typedef float type; };
01610 template<> struct superset<short,double> { typedef double type; };
01611 template<> struct superset<unsigned int,char> { typedef long type; };
01612 template<> struct superset<unsigned int,short> { typedef long type; };
01613 template<> struct superset<unsigned int,int> { typedef long type; };
01614 template<> struct superset<unsigned int,unsigned long> { typedef unsigned long type; };
01615 template<> struct superset<unsigned int,long> { typedef long type; };
01616 template<> struct superset<unsigned int,float> { typedef float type; };
01617 template<> struct superset<unsigned int,double> { typedef double type; };
01618 template<> struct superset<int,unsigned int> { typedef long type; };
01619 template<> struct superset<int,unsigned long> { typedef long type; };
01620 template<> struct superset<int,long> { typedef long type; };
01621 template<> struct superset<int,float> { typedef float type; };
01622 template<> struct superset<int,double> { typedef double type; };
01623 template<> struct superset<unsigned long,char> { typedef long type; };
01624 template<> struct superset<unsigned long,short> { typedef long type; };
01625 template<> struct superset<unsigned long,int> { typedef long type; };
01626 template<> struct superset<unsigned long,long> { typedef long type; };
01627 template<> struct superset<unsigned long,float> { typedef float type; };
01628 template<> struct superset<unsigned long,double> { typedef double type; };
01629 template<> struct superset<long,float> { typedef float type; };
01630 template<> struct superset<long,double> { typedef double type; };
01631 template<> struct superset<float,double> { typedef double type; };
01632
01633 template<typename t1, typename t2, typename t3> struct superset2 {
01634 typedef typename superset<t1, typename superset<t2,t3>::type>::type type;
01635 };
01636
01637 template<typename t1, typename t2> struct last { typedef t2 type; };
01638
01639
01640 #if cimg_display_type==1
01641 struct X11info {
01642 volatile unsigned int nb_wins;
01643 pthread_mutex_t* mutex;
01644 pthread_t* event_thread;
01645 CImgDisplay* wins[1024];
01646 Display* display;
01647 unsigned int nb_bits;
01648 GC* gc;
01649 bool blue_first;
01650 bool byte_order;
01651 bool shm_enabled;
01652 #ifdef cimg_use_xrandr
01653 XRRScreenSize *resolutions;
01654 Rotation curr_rotation;
01655 unsigned int curr_resolution;
01656 unsigned int nb_resolutions;
01657 #endif
01658 X11info():nb_wins(0),mutex(0),event_thread(0),display(0),
01659 nb_bits(0),gc(0),blue_first(false),byte_order(false),shm_enabled(false) {
01660 #ifdef cimg_use_xrandr
01661 resolutions = 0;
01662 curr_rotation = 0;
01663 curr_resolution = nb_resolutions = 0;
01664 #endif
01665 }
01666 };
01667 #if defined(cimg_module)
01668 X11info& X11attr();
01669 #elif defined(cimg_main)
01670 X11info& X11attr() { static X11info val; return val; }
01671 #else
01672 inline X11info& X11attr() { static X11info val; return val; }
01673 #endif
01674
01675 #elif cimg_display_type==2
01676 struct Win32info {
01677 HANDLE wait_event;
01678 Win32info() { wait_event = CreateEvent(0,FALSE,FALSE,0); }
01679 };
01680 #if defined(cimg_module)
01681 Win32info& Win32attr();
01682 #elif defined(cimg_main)
01683 Win32info& Win32attr() { static Win32info val; return val; }
01684 #else
01685 inline Win32info& Win32attr() { static Win32info val; return val; }
01686 #endif
01687 #endif
01688
01689 inline unsigned int& exception_mode() { static unsigned int mode = cimg_debug; return mode; }
01690
01691 #ifdef cimg_color_terminal
01692 const char t_normal[] = { 0x1b,'[','0',';','0',';','0','m','\0' };
01693 const char t_red[] = { 0x1b,'[','4',';','3','1',';','5','9','m','\0' };
01694 const char t_bold[] = { 0x1b,'[','1','m','\0' };
01695 const char t_purple[] = { 0x1b,'[','0',';','3','5',';','5','9','m','\0' };
01696 #else
01697 const char t_normal[] = { '\0' };
01698 const char *const t_red = cimg::t_normal, *const t_bold = cimg::t_normal, *const t_purple = cimg::t_normal;
01699 #endif
01700
01701 #if cimg_display_type==1
01702
01703 const unsigned int keyESC = XK_Escape;
01704 const unsigned int keyF1 = XK_F1;
01705 const unsigned int keyF2 = XK_F2;
01706 const unsigned int keyF3 = XK_F3;
01707 const unsigned int keyF4 = XK_F4;
01708 const unsigned int keyF5 = XK_F5;
01709 const unsigned int keyF6 = XK_F6;
01710 const unsigned int keyF7 = XK_F7;
01711 const unsigned int keyF8 = XK_F8;
01712 const unsigned int keyF9 = XK_F9;
01713 const unsigned int keyF10 = XK_F10;
01714 const unsigned int keyF11 = XK_F11;
01715 const unsigned int keyF12 = XK_F12;
01716 const unsigned int keyPAUSE = XK_Pause;
01717 const unsigned int key1 = XK_1;
01718 const unsigned int key2 = XK_2;
01719 const unsigned int key3 = XK_3;
01720 const unsigned int key4 = XK_4;
01721 const unsigned int key5 = XK_5;
01722 const unsigned int key6 = XK_6;
01723 const unsigned int key7 = XK_7;
01724 const unsigned int key8 = XK_8;
01725 const unsigned int key9 = XK_9;
01726 const unsigned int key0 = XK_0;
01727 const unsigned int keyBACKSPACE = XK_BackSpace;
01728 const unsigned int keyINSERT = XK_Insert;
01729 const unsigned int keyHOME = XK_Home;
01730 const unsigned int keyPAGEUP = XK_Page_Up;
01731 const unsigned int keyTAB = XK_Tab;
01732 const unsigned int keyQ = XK_q;
01733 const unsigned int keyW = XK_w;
01734 const unsigned int keyE = XK_e;
01735 const unsigned int keyR = XK_r;
01736 const unsigned int keyT = XK_t;
01737 const unsigned int keyY = XK_y;
01738 const unsigned int keyU = XK_u;
01739 const unsigned int keyI = XK_i;
01740 const unsigned int keyO = XK_o;
01741 const unsigned int keyP = XK_p;
01742 const unsigned int keyDELETE = XK_Delete;
01743 const unsigned int keyEND = XK_End;
01744 const unsigned int keyPAGEDOWN = XK_Page_Down;
01745 const unsigned int keyCAPSLOCK = XK_Caps_Lock;
01746 const unsigned int keyA = XK_a;
01747 const unsigned int keyS = XK_s;
01748 const unsigned int keyD = XK_d;
01749 const unsigned int keyF = XK_f;
01750 const unsigned int keyG = XK_g;
01751 const unsigned int keyH = XK_h;
01752 const unsigned int keyJ = XK_j;
01753 const unsigned int keyK = XK_k;
01754 const unsigned int keyL = XK_l;
01755 const unsigned int keyENTER = XK_Return;
01756 const unsigned int keySHIFTLEFT = XK_Shift_L;
01757 const unsigned int keyZ = XK_z;
01758 const unsigned int keyX = XK_x;
01759 const unsigned int keyC = XK_c;
01760 const unsigned int keyV = XK_v;
01761 const unsigned int keyB = XK_b;
01762 const unsigned int keyN = XK_n;
01763 const unsigned int keyM = XK_m;
01764 const unsigned int keySHIFTRIGHT = XK_Shift_R;
01765 const unsigned int keyARROWUP = XK_Up;
01766 const unsigned int keyCTRLLEFT = XK_Control_L;
01767 const unsigned int keyAPPLEFT = XK_Super_L;
01768 const unsigned int keySPACE = XK_space;
01769 const unsigned int keyALTGR = XK_Alt_R;
01770 const unsigned int keyAPPRIGHT = XK_Super_R;
01771 const unsigned int keyMENU = XK_Menu;
01772 const unsigned int keyCTRLRIGHT = XK_Control_R;
01773 const unsigned int keyARROWLEFT = XK_Left;
01774 const unsigned int keyARROWDOWN = XK_Down;
01775 const unsigned int keyARROWRIGHT = XK_Right;
01776 const unsigned int keyPAD0 = XK_KP_0;
01777 const unsigned int keyPAD1 = XK_KP_1;
01778 const unsigned int keyPAD2 = XK_KP_2;
01779 const unsigned int keyPAD3 = XK_KP_3;
01780 const unsigned int keyPAD4 = XK_KP_4;
01781 const unsigned int keyPAD5 = XK_KP_5;
01782 const unsigned int keyPAD6 = XK_KP_6;
01783 const unsigned int keyPAD7 = XK_KP_7;
01784 const unsigned int keyPAD8 = XK_KP_8;
01785 const unsigned int keyPAD9 = XK_KP_9;
01786 const unsigned int keyPADADD = XK_KP_Add;
01787 const unsigned int keyPADSUB = XK_KP_Subtract;
01788 const unsigned int keyPADMUL = XK_KP_Multiply;
01789 const unsigned int keyPADDIV = XK_KP_Divide;
01790
01791 #elif (cimg_display_type==2 && cimg_OS==2)
01792
01793 const unsigned int keyESC = VK_ESCAPE;
01794 const unsigned int keyF1 = VK_F1;
01795 const unsigned int keyF2 = VK_F2;
01796 const unsigned int keyF3 = VK_F3;
01797 const unsigned int keyF4 = VK_F4;
01798 const unsigned int keyF5 = VK_F5;
01799 const unsigned int keyF6 = VK_F6;
01800 const unsigned int keyF7 = VK_F7;
01801 const unsigned int keyF8 = VK_F8;
01802 const unsigned int keyF9 = VK_F9;
01803 const unsigned int keyF10 = VK_F10;
01804 const unsigned int keyF11 = VK_F11;
01805 const unsigned int keyF12 = VK_F12;
01806 const unsigned int keyPAUSE = VK_PAUSE;
01807 const unsigned int key1 = '1';
01808 const unsigned int key2 = '2';
01809 const unsigned int key3 = '3';
01810 const unsigned int key4 = '4';
01811 const unsigned int key5 = '5';
01812 const unsigned int key6 = '6';
01813 const unsigned int key7 = '7';
01814 const unsigned int key8 = '8';
01815 const unsigned int key9 = '9';
01816 const unsigned int key0 = '0';
01817 const unsigned int keyBACKSPACE = VK_BACK;
01818 const unsigned int keyINSERT = VK_INSERT;
01819 const unsigned int keyHOME = VK_HOME;
01820 const unsigned int keyPAGEUP = VK_PRIOR;
01821 const unsigned int keyTAB = VK_TAB;
01822 const unsigned int keyQ = 'Q';
01823 const unsigned int keyW = 'W';
01824 const unsigned int keyE = 'E';
01825 const unsigned int keyR = 'R';
01826 const unsigned int keyT = 'T';
01827 const unsigned int keyY = 'Y';
01828 const unsigned int keyU = 'U';
01829 const unsigned int keyI = 'I';
01830 const unsigned int keyO = 'O';
01831 const unsigned int keyP = 'P';
01832 const unsigned int keyDELETE = VK_DELETE;
01833 const unsigned int keyEND = VK_END;
01834 const unsigned int keyPAGEDOWN = VK_NEXT;
01835 const unsigned int keyCAPSLOCK = VK_CAPITAL;
01836 const unsigned int keyA = 'A';
01837 const unsigned int keyS = 'S';
01838 const unsigned int keyD = 'D';
01839 const unsigned int keyF = 'F';
01840 const unsigned int keyG = 'G';
01841 const unsigned int keyH = 'H';
01842 const unsigned int keyJ = 'J';
01843 const unsigned int keyK = 'K';
01844 const unsigned int keyL = 'L';
01845 const unsigned int keyENTER = VK_RETURN;
01846 const unsigned int keySHIFTLEFT = VK_SHIFT;
01847 const unsigned int keyZ = 'Z';
01848 const unsigned int keyX = 'X';
01849 const unsigned int keyC = 'C';
01850 const unsigned int keyV = 'V';
01851 const unsigned int keyB = 'B';
01852 const unsigned int keyN = 'N';
01853 const unsigned int keyM = 'M';
01854 const unsigned int keySHIFTRIGHT = VK_SHIFT;
01855 const unsigned int keyARROWUP = VK_UP;
01856 const unsigned int keyCTRLLEFT = VK_CONTROL;
01857 const unsigned int keyAPPLEFT = VK_LWIN;
01858 const unsigned int keySPACE = VK_SPACE;
01859 const unsigned int keyALTGR = VK_CONTROL;
01860 const unsigned int keyAPPRIGHT = VK_RWIN;
01861 const unsigned int keyMENU = VK_APPS;
01862 const unsigned int keyCTRLRIGHT = VK_CONTROL;
01863 const unsigned int keyARROWLEFT = VK_LEFT;
01864 const unsigned int keyARROWDOWN = VK_DOWN;
01865 const unsigned int keyARROWRIGHT = VK_RIGHT;
01866 const unsigned int keyPAD0 = 0x60;
01867 const unsigned int keyPAD1 = 0x61;
01868 const unsigned int keyPAD2 = 0x62;
01869 const unsigned int keyPAD3 = 0x63;
01870 const unsigned int keyPAD4 = 0x64;
01871 const unsigned int keyPAD5 = 0x65;
01872 const unsigned int keyPAD6 = 0x66;
01873 const unsigned int keyPAD7 = 0x67;
01874 const unsigned int keyPAD8 = 0x68;
01875 const unsigned int keyPAD9 = 0x69;
01876 const unsigned int keyPADADD = VK_ADD;
01877 const unsigned int keyPADSUB = VK_SUBTRACT;
01878 const unsigned int keyPADMUL = VK_MULTIPLY;
01879 const unsigned int keyPADDIV = VK_DIVIDE;
01880 #else
01881
01882 const unsigned int keyESC = 1U;
01883 const unsigned int keyF1 = 2U;
01884 const unsigned int keyF2 = 3U;
01885 const unsigned int keyF3 = 4U;
01886 const unsigned int keyF4 = 5U;
01887 const unsigned int keyF5 = 6U;
01888 const unsigned int keyF6 = 7U;
01889 const unsigned int keyF7 = 8U;
01890 const unsigned int keyF8 = 9U;
01891 const unsigned int keyF9 = 10U;
01892 const unsigned int keyF10 = 11U;
01893 const unsigned int keyF11 = 12U;
01894 const unsigned int keyF12 = 13U;
01895 const unsigned int keyPAUSE = 14U;
01896 const unsigned int key1 = 15U;
01897 const unsigned int key2 = 16U;
01898 const unsigned int key3 = 17U;
01899 const unsigned int key4 = 18U;
01900 const unsigned int key5 = 19U;
01901 const unsigned int key6 = 20U;
01902 const unsigned int key7 = 21U;
01903 const unsigned int key8 = 22U;
01904 const unsigned int key9 = 23U;
01905 const unsigned int key0 = 24U;
01906 const unsigned int keyBACKSPACE = 25U;
01907 const unsigned int keyINSERT = 26U;
01908 const unsigned int keyHOME = 27U;
01909 const unsigned int keyPAGEUP = 28U;
01910 const unsigned int keyTAB = 29U;
01911 const unsigned int keyQ = 30U;
01912 const unsigned int keyW = 31U;
01913 const unsigned int keyE = 32U;
01914 const unsigned int keyR = 33U;
01915 const unsigned int keyT = 34U;
01916 const unsigned int keyY = 35U;
01917 const unsigned int keyU = 36U;
01918 const unsigned int keyI = 37U;
01919 const unsigned int keyO = 38U;
01920 const unsigned int keyP = 39U;
01921 const unsigned int keyDELETE = 40U;
01922 const unsigned int keyEND = 41U;
01923 const unsigned int keyPAGEDOWN = 42U;
01924 const unsigned int keyCAPSLOCK = 43U;
01925 const unsigned int keyA = 44U;
01926 const unsigned int keyS = 45U;
01927 const unsigned int keyD = 46U;
01928 const unsigned int keyF = 47U;
01929 const unsigned int keyG = 48U;
01930 const unsigned int keyH = 49U;
01931 const unsigned int keyJ = 50U;
01932 const unsigned int keyK = 51U;
01933 const unsigned int keyL = 52U;
01934 const unsigned int keyENTER = 53U;
01935 const unsigned int keySHIFTLEFT = 54U;
01936 const unsigned int keyZ = 55U;
01937 const unsigned int keyX = 56U;
01938 const unsigned int keyC = 57U;
01939 const unsigned int keyV = 58U;
01940 const unsigned int keyB = 59U;
01941 const unsigned int keyN = 60U;
01942 const unsigned int keyM = 61U;
01943 const unsigned int keySHIFTRIGHT = 62U;
01944 const unsigned int keyARROWUP = 63U;
01945 const unsigned int keyCTRLLEFT = 64U;
01946 const unsigned int keyAPPLEFT = 65U;
01947 const unsigned int keySPACE = 66U;
01948 const unsigned int keyALTGR = 67U;
01949 const unsigned int keyAPPRIGHT = 68U;
01950 const unsigned int keyMENU = 69U;
01951 const unsigned int keyCTRLRIGHT = 70U;
01952 const unsigned int keyARROWLEFT = 71U;
01953 const unsigned int keyARROWDOWN = 72U;
01954 const unsigned int keyARROWRIGHT = 73U;
01955 const unsigned int keyPAD0 = 74U;
01956 const unsigned int keyPAD1 = 75U;
01957 const unsigned int keyPAD2 = 76U;
01958 const unsigned int keyPAD3 = 77U;
01959 const unsigned int keyPAD4 = 78U;
01960 const unsigned int keyPAD5 = 79U;
01961 const unsigned int keyPAD6 = 80U;
01962 const unsigned int keyPAD7 = 81U;
01963 const unsigned int keyPAD8 = 82U;
01964 const unsigned int keyPAD9 = 83U;
01965 const unsigned int keyPADADD = 84U;
01966 const unsigned int keyPADSUB = 85U;
01967 const unsigned int keyPADMUL = 86U;
01968 const unsigned int keyPADDIV = 87U;
01969 #endif
01970
01971 const double PI = 3.14159265358979323846;
01972
01973
01974 const unsigned int font7x11[7*11*256/32] = {
01975 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01976 0x0,0x0,0x0,0x0,0x0,0x0,0x90,0x0,0x7f0000,0x40000,0x0,0x0,0x4010c0a4,0x82000040,0x11848402,0x18480050,0x80430292,0x8023,0x9008000,
01977 0x40218140,0x4000040,0x21800402,0x18000051,0x1060500,0x8083,0x10000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x24002,0x4031,0x80000000,0x10000,
01978 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x81c0400,0x40020000,0x80070080,0x40440e00,0x0,0x0,0x1,0x88180000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01979 0x0,0x200000,0x0,0x0,0x80000,0x0,0x0,0x20212140,0x5000020,0x22400204,0x240000a0,0x40848500,0x4044,0x80010038,0x20424285,0xa000020,
01980 0x42428204,0x2428e0a0,0x82090a14,0x4104,0x85022014,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10240a7,0x88484040,0x40800000,0x270c3,0x87811e0e,
01981 0x7c70e000,0x78,0x3c23c1ef,0x1f3e1e89,0xf1c44819,0xa23cf0f3,0xc3cff120,0xc18307f4,0x4040400,0x20000,0x80080080,0x40200,0x0,
01982 0x40000,0x2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8188,0x50603800,0xf3c00000,0x1c004003,0xc700003e,0x18180,0xc993880,0x10204081,
01983 0x2071ef9,0xf3e7cf9f,0x3e7c7911,0xe3c78f1e,0x7d1224,0x48906048,0x0,0x4000000,0x0,0x9000,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,
01984 0x0,0x10240aa,0x14944080,0x23610000,0x68940,0x40831010,0x8891306,0x802044,0x44522208,0x90202088,0x40448819,0xb242890a,0x24011111,
01985 0x49448814,0x4040a00,0xe2c3c7,0x8e3f3cb9,0xc1c44216,0xee38b0f2,0xe78f9120,0xc18507e2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01986 0x101c207,0x88a04001,0x9c00000,0x2200a041,0x8200113a,0x8240,0x50a3110,0x2850a142,0x850c2081,0x2040204,0x8104592,0x142850a1,
01987 0x42cd1224,0x4888bc48,0x70e1c387,0xe3b3c70,0xe1c38e1c,0x38707171,0xc3870e1c,0x10791224,0x48906c41,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01988 0x10003ee,0x15140080,0x21810000,0x48840,0x40851020,0x8911306,0x31fd804,0x9c522408,0x90204088,0x4045081a,0xba42890a,0x24011111,
01989 0x49285024,0x2041b00,0x132408,0x910844c8,0x4044821b,0x7244c913,0x24041111,0x49488822,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01990 0x28204,0x85006001,0x6a414000,0x3a004043,0xc700113a,0x8245,0x50a3a00,0x2850a142,0x850c4081,0x2040204,0x81045d2,0x142850a1,
01991 0x24951224,0x48852250,0x8102040,0x81054089,0x12244204,0x8108992,0x24489122,0x991224,0x4888b222,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01992 0x1000143,0xa988080,0x2147c01f,0x88840,0x83091c2c,0x1070f000,0xc000608,0xa48bc408,0x9e3c46f8,0x40460816,0xaa42f10b,0xc3811111,
01993 0x35102044,0x1041100,0xf22408,0x9f084488,0x40470212,0x62448912,0x6041111,0x55308846,0x8061c80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01994 0x1028704,0x8f805801,0x4be28fdf,0x220001f0,0x111a,0x60000182,0x82c5c710,0x44891224,0x489640f1,0xe3c78204,0x810e552,0x142850a1,
01995 0x18a51224,0x48822250,0x78f1e3c7,0x8f1f40f9,0xf3e7c204,0x8108912,0x24489122,0x7ea91224,0x4888a222,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01996 0x10007e2,0x85648080,0x20010000,0x88841,0x8f8232,0x20881000,0xc1fc610,0xbefa2408,0x90204288,0x40450816,0xa642810a,0x4041110a,
01997 0x36282084,0x1042080,0x1122408,0x90084488,0x40450212,0x62448912,0x184110a,0x55305082,0x8042700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01998 0x1028207,0x82004801,0x68050040,0x1c000040,0x110a,0x60000001,0x45484d10,0x7cf9f3e7,0xcf944081,0x2040204,0x8104532,0x142850a1,
01999 0x18a51224,0x48822248,0x89122448,0x91244081,0x2040204,0x8108912,0x24489122,0xc91224,0x48852214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x282,
02000 0x89630080,0x20010c00,0x30108842,0x810222,0x20882306,0x3001800,0x408a2208,0x90202288,0x40448814,0xa642810a,0x2041110a,0x26442104,
02001 0x840000,0x1122408,0x90084488,0x40448212,0x62448912,0x84130a,0x36485102,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x101c208,0x4f802801,
02002 0x8028040,0x40,0x130a,0x2,0x85e897a0,0x44891224,0x489c2081,0x2040204,0x8104532,0x142850a1,0x24cd1224,0x48823c44,0x89122448,
02003 0x91244081,0x2040204,0x8108912,0x24489122,0xc93264,0xc9852214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100028f,0x109f0080,0x20010c00,
02004 0x303071f3,0xc7011c1c,0x4071c306,0x802010,0x3907c1ef,0x1f201e89,0xf3844f90,0xa23c80f2,0x17810e04,0x228223f4,0x840000,0xfbc3c7,
02005 0x8f083c88,0x40444212,0x6238f0f2,0x7039d04,0x228423e2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1008780,0x2201800,0xf0014000,0x1f0,
02006 0x1d0a,0x5,0x851e140,0x83060c18,0x30671ef9,0xf3e7cf9f,0x3e7c7911,0xe3c78f1e,0x42f8e1c3,0x8702205c,0x7cf9f3e7,0xcf9b3c78,0xf1e3c204,
02007 0x8107111,0xc3870e1c,0x10f1d3a7,0x4e823c08,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x40,0x40000400,0x200000,0x0,0x2,0x0,0x0,0x0,0x0,0x18,
02008 0x0,0x4,0x44007f,0x0,0x400,0x400000,0x8010,0x0,0x6002,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x200800,0x0,0x0,0x100a,
02009 0x400000,0x44,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x0,0x62018,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x31,0x80000800,
02010 0x400000,0x0,0x4,0x0,0x0,0x0,0x0,0xc,0x0,0x7,0x3c0000,0x0,0x3800,0x3800000,0x8010,0x0,0x1c001,0x881c0000,0x0,0x0,0x0,0x0,0x0,0x0,
02011 0x0,0x0,0x207000,0x0,0x0,0x100a,0xc00000,0x3c,0x0,0xc00,0x0,0x0,0x0,0x0,0x0,0x0,0x1800,0x0,0x0,0x0,0x0,0x1c2070
02012 };
02013
02014
02015 const unsigned int font10x13[256*10*13/32] = {
02016 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02017 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80100c0,
02018 0x68000300,0x801,0xc00010,0x100c000,0x68100,0x100c0680,0x2,0x403000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02019 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02020 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x4020120,
02021 0x58120480,0x402,0x1205008,0x2012050,0x58080,0x20120581,0x40000001,0x804812,0x2000000,0x0,0x300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02022 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x140,0x80000,0x200402,0x800000,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02023 0x0,0x7010,0x7000000,0x8000200,0x20000,0xc0002000,0x8008,0x0,0x0,0x0,0x0,0x808,0x4000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02024 0x0,0x0,0x80000000,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x480,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x80100c0,0x68000480,0x1001,
02025 0xc00010,0x1018000,0x68100,0x100c0680,0x4,0x403000,0x1020000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140,0x28081883,0x200801,
02026 0x2a00000,0x10,0x1c0201c0,0x70040f80,0xc0f81c07,0x0,0x70,0x3e0303c0,0x3c3c0f83,0xe03c2107,0xe08810,0x18c31070,0x3c0703c0,
02027 0x783e0842,0x22222208,0x83e04010,0x1008000,0x4000200,0x20001,0x2002,0x408008,0x0,0x0,0x100000,0x0,0x1008,0x2000000,0x0,0x0,0x0,
02028 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20080,0x38000880,0x8078140f,0x81c00000,0x3e000,0xc020180,0x60080001,0xe0000002,0xc00042,0x108e2010,
02029 0xc0300c0,0x300c0303,0xf83c3e0f,0x83e0f81c,0x701c070,0x3c0c41c0,0x701c0701,0xc0001d08,0x42108421,0x8820088,0x4020120,0x58140480,
02030 0x802,0x1205008,0x3014050,0xc058080,0x20120581,0x40000002,0x804814,0x2020050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140,
02031 0x281e2484,0x80200801,0x1c02000,0x10,0x22060220,0x880c0801,0x82208,0x80000001,0x20008,0x41030220,0x40220802,0x402102,0x209010,
02032 0x18c31088,0x22088220,0x80080842,0x22222208,0x80204010,0x1014000,0x200,0x20001,0x2000,0x8008,0x0,0x0,0x100000,0x0,0x1008,
02033 0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40000500,0x80800010,0x40200000,0x41000,0x12020040,0x10000003,0xa0000006,
02034 0x12000c4,0x31014000,0xc0300c0,0x300c0302,0x80402008,0x2008008,0x2008020,0x220c4220,0x88220882,0x20002208,0x42108421,0x8820088,
02035 0x0,0x300,0x0,0x0,0x0,0x14000000,0x0,0x200200,0x0,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xfc282504,0x80001000,
02036 0x82a02000,0x20,0x22020020,0x8140802,0x102208,0x80801006,0x18008,0x9c848220,0x80210802,0x802102,0x20a010,0x15429104,0x22104220,
02037 0x80080842,0x22221405,0x404008,0x1022000,0x703c0,0x381e0701,0xc0783c02,0xc09008,0x1d83c070,0x3c078140,0x381c0882,0x21242208,
02038 0x81e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0,0x40220500,0x80800027,0x20e02800,0x9c800,0x12020040,
02039 0x20000883,0xa0200002,0x120a044,0x11064010,0x12048120,0x48120484,0x80802008,0x2008008,0x2008020,0x210a4411,0x4411044,0x10884508,
02040 0x42108421,0x503c0b0,0x1c0701c0,0x701c0707,0x70381c07,0x1c07008,0x2008020,0x20f01c0,0x701c0701,0xc0201c08,0x82208822,0x883c088,
02041 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x50281903,0x20001000,0x80802000,0x20,0x22020040,0x30240f03,0xc0101c08,0x80801018,
02042 0x1fc06010,0xa48483c0,0x80210f03,0xe0803f02,0x20c010,0x15429104,0x22104220,0x70080841,0x41540805,0x804008,0x1041000,0x8220,
02043 0x40220881,0x882202,0x40a008,0x12422088,0x22088180,0x40100882,0x21241408,0x80201008,0x2031000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02044 0x0,0x20280,0x401c0200,0x700028,0x21205000,0x92800,0xc1fc080,0x10000883,0xa0200002,0x1205049,0x12c19010,0x12048120,0x48120484,
02045 0xf0803c0f,0x3c0f008,0x2008020,0x790a4411,0x4411044,0x10504908,0x42108421,0x5022088,0x2008020,0x8020080,0x88402208,0x82208808,
02046 0x2008020,0x1e088220,0x88220882,0x20002608,0x82208822,0x8822088,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x501c0264,
02047 0xa0001000,0x8001fc00,0x7000020,0x22020080,0x83e0082,0x20202207,0x80000020,0x1020,0xa4848220,0x80210802,0x9c2102,0x20c010,
02048 0x12425104,0x3c1043c0,0x8080841,0x41540802,0x804008,0x1000000,0x78220,0x40220f81,0x882202,0x40c008,0x12422088,0x22088100,
02049 0x60100881,0x41540805,0x406008,0x1849000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0xf0140200,0x880028,0x20e0a03f,0x709c800,
02050 0x201c0,0x60000881,0xa0000007,0xc0284b,0x122eb020,0x12048120,0x48120487,0x80802008,0x2008008,0x2008020,0x21094411,0x4411044,
02051 0x10204908,0x42108421,0x2022088,0x1e0781e0,0x781e0787,0xf8403e0f,0x83e0f808,0x2008020,0x22088220,0x88220882,0x21fc2a08,0x82208822,
02052 0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0xf80a0294,0x40001000,0x80002000,0x20,0x22020100,0x8040082,0x20202200,
02053 0x80000018,0x1fc06020,0xa48fc220,0x80210802,0x842102,0x20a010,0x12425104,0x20104240,0x8080841,0x41541402,0x1004008,0x1000000,
02054 0x88220,0x40220801,0x882202,0x40a008,0x12422088,0x22088100,0x18100881,0x41540805,0x801008,0x2046000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02055 0x0,0x0,0x0,0x20280,0x401c0f80,0x80880028,0x20005001,0x94800,0x20000,0x880,0xa0000000,0x5015,0x4215040,0x3f0fc3f0,0xfc3f0fc8,
02056 0x80802008,0x2008008,0x2008020,0x21094411,0x4411044,0x10505108,0x42108421,0x203c088,0x22088220,0x88220888,0x80402008,0x2008008,
02057 0x2008020,0x22088220,0x88220882,0x20002a08,0x82208822,0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa00a0494,0x60001000,
02058 0x80002004,0x8020,0x22020200,0x88040882,0x20402201,0x801006,0x18000,0x9f084220,0x40220802,0x442102,0x209010,0x10423088,0x20088220,
02059 0x8080840,0x80882202,0x2004008,0x1000000,0x88220,0x40220881,0x882202,0x409008,0x12422088,0x22088100,0x8100880,0x80881402,
02060 0x1001008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0x40220200,0x80700027,0x20002801,0x92800,0x1fc000,0x980,
02061 0xa0000000,0xa017,0x84417840,0x21084210,0x84210848,0x80402008,0x2008008,0x2008020,0x2208c220,0x88220882,0x20882208,0x42108421,
02062 0x2020088,0x22088220,0x88220888,0xc8402208,0x82208808,0x2008020,0x22088220,0x88220882,0x20203208,0x82208822,0x2022020,0x0,0x0,0x0,
02063 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xa03c0463,0x90000801,0x2004,0x8040,0x1c0703e0,0x70040701,0xc0401c06,0x801001,0x20020,
02064 0x400843c0,0x3c3c0f82,0x3c2107,0x1c0881e,0x10423070,0x20070210,0xf0080780,0x80882202,0x3e04004,0x1000000,0x783c0,0x381e0701,
02065 0x782202,0x408808,0x12422070,0x3c078100,0x700c0780,0x80882202,0x1e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0,
02066 0xf8000200,0x80080010,0x40000001,0x41000,0x0,0xe80,0xa0000000,0x21,0x8e21038,0x21084210,0x84210848,0xf83c3e0f,0x83e0f81c,
02067 0x701c070,0x3c08c1c0,0x701c0701,0xc0005c07,0x81e0781e,0x20200b0,0x1e0781e0,0x781e0787,0x30381c07,0x1c07008,0x2008020,0x1c0881c0,
02068 0x701c0701,0xc0201c07,0x81e0781e,0x203c020,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,0x801,0x4,0x40,0x0,0x0,0x0,0x1000,
02069 0x0,0x3c000000,0x0,0x0,0x0,0x0,0x10000,0x0,0x0,0x4004,0x1000000,0x0,0x0,0x80000,0x400000,0x0,0x20008000,0x0,0x4,0x1008,0x2000000,
02070 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x8008000f,0x80000000,0x3e000,0x0,0x800,0xa0000400,0x0,0x0,0x0,0x0,0x80000,0x0,
02071 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100000,0x0,0x0,0x0,0x0,0x2000,0x0,0x4020040,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,
02072 0x402,0x8,0x40,0x0,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x0,0x7004,0x70000fc,0x0,0x0,0x700000,0x800000,0x0,0x20008000,
02073 0x0,0x4,0x808,0x4000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x80f00000,0x0,0x0,0x0,0x800,0xa0001800,0x0,0x0,0x0,0x0,
02074 0x300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x4020040
02075 };
02076
02077
02078 const unsigned int font8x17[8*17*256/32] = {
02079 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02080 0x0,0x0,0x0,0x2400,0x2400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20081834,0x1c0000,0x20081800,0x20081800,0x342008,
02081 0x18340000,0x200818,0x80000,0x0,0x180000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4200000,0x0,0x0,
02082 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x380000,0x4000,0x2000c00,0x40100840,0x70000000,0x0,0x0,0x1c,0x10700000,0x7,0x0,
02083 0x1800,0x1800,0x0,0x0,0x0,0x14,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1010242c,0x14140000,0x10102414,0x10102414,0x2c1010,0x242c1400,
02084 0x101024,0x14100038,0x0,0x240000,0x0,0x0,0x30000000,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x12,0x0,0x8100000,0x0,
02085 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x80000,0x10004000,0x2001000,0x40000040,0x10000000,0x0,0x0,0x10,0x10100000,0x4,
02086 0x0,0x18000000,0x0,0x0,0x0,0x34002400,0x2400,0x0,0x0,0x0,0x3c,0x0,0x8000000,0x0,0x60607800,0x0,0x140000,0x0,0x0,0x0,0x0,0x0,
02087 0x44,0x10081834,0x240000,0x10081800,0x10081800,0x1c341008,0x18340000,0x100818,0x84000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102812,
02088 0x8601c10,0x8100800,0x2,0x1c383e3e,0x67e1e7f,0x3e3c0000,0x38,0x1e087e1e,0x7c7f7f1e,0x417c1c42,0x4063611c,0x7e1c7e3e,0xfe414181,
02089 0x63827f10,0x40081000,0x8004000,0x2001000,0x40000040,0x10000000,0x0,0x10000000,0x10,0x10100000,0x3c000008,0x0,0x24003e00,
02090 0x3f007f00,0x0,0x0,0x2ce91800,0x1882,0x10101c,0xc2103c,0x143c3c00,0x3c00,0x18003c3c,0x10001f00,0x181c00,0x20200810,0x8080808,
02091 0x8083e1e,0x7f7f7f7f,0x7c7c7c7c,0x7c611c1c,0x1c1c1c00,0x1e414141,0x41824044,0x810242c,0x14180000,0x8102414,0x8102414,0x382c0810,
02092 0x242c1400,0x81024,0x14104014,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102816,0x3e902010,0x10084910,0x4,0x22084343,0xa402102,0x41620000,
02093 0x44,0x33144121,0x42404021,0x41100444,0x40636122,0x43224361,0x10416381,0x22440310,0x20082800,0x4000,0x2001000,0x40000040,
02094 0x10000000,0x0,0x10000000,0x10,0x10100000,0x24000008,0x0,0x606100,0x68000300,0x8106c,0x34000000,0x4f0000,0x44,0x101020,0x441040,
02095 0x420200,0x4200,0x24000404,0x7d00,0x82200,0x20203010,0x14141414,0x14082821,0x40404040,0x10101010,0x42612222,0x22222200,0x23414141,
02096 0x41447e48,0x0,0x0,0x0,0x0,0x4000000,0x18,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10287f,0x49902010,0x10083e10,0x4,0x41080101,
02097 0x1a404002,0x41411818,0x1004004,0x21144140,0x41404040,0x41100448,0x40555141,0x41414140,0x10412281,0x14280610,0x20084400,0x1c7c1c,
02098 0x3e3c7c3a,0x5c703844,0x107f5c3c,0x7c3e3c3c,0x7e424281,0x66427e10,0x10100000,0x40100008,0x1010,0xa04000,0x48100610,0x100c3024,
02099 0x24000000,0x4f3c00,0x2c107e28,0x3820,0x42281060,0x9d1e12,0xbd00,0x24100818,0x427d00,0x82248,0x20200800,0x14141414,0x14142840,
02100 0x40404040,0x10101010,0x41514141,0x41414142,0x43414141,0x41284350,0x1c1c1c1c,0x1c1c6c1c,0x3c3c3c3c,0x70707070,0x3c5c3c3c,
02101 0x3c3c3c18,0x3e424242,0x42427c42,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102824,0x48623010,0x10081c10,0x8,0x41080103,0x127c5e04,
02102 0x41411818,0xe7f3808,0x4f144140,0x41404040,0x41100450,0x40555141,0x41414160,0x1041225a,0x1c280410,0x1008c600,0x226622,0x66661066,
02103 0x62100848,0x10496266,0x66663242,0x10426681,0x24220260,0x100c0000,0xf8280008,0x1010,0x606000,0x48280428,0x28042014,0x48000000,
02104 0x494200,0x52280228,0x105420,0x3cee1058,0xa12236,0xa500,0x18101004,0x427d00,0x8226c,0x76767e10,0x14141414,0x14142840,0x40404040,
02105 0x10101010,0x41514141,0x41414124,0x45414141,0x41284150,0x22222222,0x22221222,0x66666666,0x10101010,0x66626666,0x66666600,
02106 0x66424242,0x42226622,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100024,0x381c4900,0x10086bfe,0x8,0x4908021c,0x22036304,0x3e630000,
02107 0x70000710,0x51227e40,0x417f7f43,0x7f100470,0x40554941,0x43417e3e,0x1041225a,0x8100810,0x10080000,0x24240,0x42421042,0x42100850,
02108 0x10494242,0x42422040,0x1042245a,0x18240410,0x10103900,0x407c003e,0x1818,0x1c3e10,0x4f7c087c,0x7c002010,0x48000000,0x4008,
02109 0x527c0410,0x105078,0x2410104c,0xa13e6c,0x7f00b900,0xfe3c3c,0x421d18,0x1c1c36,0x38383810,0x22222222,0x22144e40,0x7f7f7f7f,
02110 0x10101010,0xf1494141,0x41414118,0x49414141,0x4110435c,0x2020202,0x2021240,0x42424242,0x10101010,0x42424242,0x424242ff,0x4e424242,
02111 0x42244224,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000fe,0xe664d00,0x10080810,0x380010,0x41080c03,0x42014108,0x633d0000,0x70000710,
02112 0x51224140,0x41404041,0x41100448,0x40494541,0x7e414203,0x1041145a,0x14101010,0x10080000,0x3e4240,0x427e1042,0x42100870,0x10494242,
02113 0x4242203c,0x1042245a,0x18241810,0x10104600,0xf8f60008,0x1010,0x600320,0x48f610f6,0xf6000000,0x187eff,0x3c04,0x5ef61810,0x105020,
02114 0x24fe0064,0x9d006c,0x138ad00,0x100000,0x420518,0x36,0xc0c0c020,0x22222222,0x22224840,0x40404040,0x10101010,0x41454141,0x41414118,
02115 0x51414141,0x41107e46,0x3e3e3e3e,0x3e3e7e40,0x7e7e7e7e,0x10101010,0x42424242,0x42424200,0x5a424242,0x42244224,0x0,0x0,0x0,
02116 0x0,0x0,0x0,0x0,0x0,0x28,0x9094500,0x10080010,0x10,0x41081801,0x7f014118,0x41010000,0xe7f3800,0x513e4140,0x41404041,0x41100444,
02117 0x40414541,0x40414101,0x10411466,0x36103010,0x8080000,0x424240,0x42401042,0x42100848,0x10494242,0x42422002,0x10423c5a,0x18142010,
02118 0x10100000,0x407c0010,0x1010,0x260140,0x487c307c,0x7c000000,0x180000,0x202,0x507c2010,0x105020,0x3c10003c,0x423e36,0x1004200,
02119 0x100000,0x420500,0x3e6c,0x41e0440,0x3e3e3e3e,0x3e3e7840,0x40404040,0x10101010,0x41454141,0x41414124,0x61414141,0x41104042,
02120 0x42424242,0x42425040,0x40404040,0x10101010,0x42424242,0x42424218,0x72424242,0x42144214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100048,
02121 0x49096200,0x8100010,0x18001810,0x22082043,0x2432310,0x61421818,0x1004010,0x4f634121,0x42404021,0x41104444,0x40414322,0x40234143,
02122 0x10411466,0x22106010,0x8080000,0x466622,0x66621066,0x42100844,0x10494266,0x66662042,0x10461824,0x24184010,0x10100000,0x24381010,
02123 0x34001018,0xda4320,0x68386038,0x38000000,0x0,0x4204,0x50384010,0x105420,0x4210100c,0x3c0012,0x3c00,0x0,0x460500,0x48,0xc020c44,
02124 0x63636363,0x63228821,0x40404040,0x10101010,0x42432222,0x22222242,0x62414141,0x41104042,0x46464646,0x46465022,0x62626262,
02125 0x10101010,0x66426666,0x66666618,0x66464646,0x46186618,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100048,0x3e063d00,0x8100000,0x18001820,
02126 0x1c3e7f3e,0x23c1e20,0x3e3c1818,0x10,0x20417e1e,0x7c7f401e,0x417c3842,0x7f41431c,0x401e40be,0x103e0866,0x41107f10,0x4080000,
02127 0x3a5c1c,0x3a3c103a,0x427c0842,0xe49423c,0x7c3e203c,0xe3a1824,0x66087e10,0x10100000,0x3c103010,0x245a1010,0x5a3e10,0x3f107f10,
02128 0x10000000,0x0,0x3c08,0x2e107e10,0x1038fc,0x101004,0x0,0x0,0xfe0000,0x7f0500,0x0,0x14041438,0x41414141,0x41418e1e,0x7f7f7f7f,
02129 0x7c7c7c7c,0x7c431c1c,0x1c1c1c00,0xbc3e3e3e,0x3e10405c,0x3a3a3a3a,0x3a3a6e1c,0x3c3c3c3c,0x7c7c7c7c,0x3c423c3c,0x3c3c3c00,
02130 0x7c3a3a3a,0x3a087c08,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x4200000,0x10000020,0x0,0x0,0x10,0x0,0x30000000,0x0,
02131 0x0,0x0,0x60000,0x0,0x1c,0x4380000,0x0,0x2,0x800,0x0,0x40020000,0x0,0x8000c,0x10600000,0x2010,0x48000000,0x240000,0x0,0x0,
02132 0x0,0x0,0x0,0x1000,0x1078,0x0,0x0,0x0,0x400500,0x0,0x1e081e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02133 0x84008,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x0,0x20000040,0x0,0x0,0x20,0x0,0x1e000000,0x0,0x0,0x0,0x20000,0x0,
02134 0x0,0x2000000,0x0,0x26,0x800,0x0,0x40020000,0x0,0x100000,0x10000000,0x2030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x1000,0x0,
02135 0x0,0x0,0x400000,0x8000000,0x41e0400,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x104010,0x0,0x0,0x0,0x0,
02136 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x0,0x1c,0x7000,0x0,0x40020000,0x0,0x300000,
02137 0x0,0xe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x0,0x0,0x0,0x400000,0x38000000,0x0,0x0,0x1c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02138 0x1c,0x0,0x0,0x0,0x0,0x0,0x304030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02139 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02140 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02141 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02142 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
02143
02144
02145 const unsigned int font10x19[10*19*256/32] = {
02146 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02147 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3600000,0x36000,0x0,0x0,0x0,0x0,0x6c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02148 0x0,0x180181c0,0xe81b0300,0x1801,0x81c06c18,0x181c06c,0xe8180,0x181c0e81,0xb0000006,0x60701b,0x1800000,0x0,0x0,0x0,0x0,0x0,
02149 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02150 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00000,0x1c000,0x0,0x0,0x0,0x0,0x6c,0x0,0x0,0x0,0x0,
02151 0x0,0x0,0x0,0x0,0x0,0x0,0xc030360,0xb81b0480,0xc03,0x3606c0c,0x303606c,0xb80c0,0x30360b81,0xb0000003,0xc0d81b,0x3000000,0x0,
02152 0x300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02153 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x0,0x0,0x2200000,
02154 0x22000,0x0,0x0,0x0,0x0,0x0,0x0,0x30000,0x0,0xe0,0x38078000,0x0,0x480,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3000c080,0x480,0x3000,
02155 0xc0800030,0xc08000,0x300,0xc080000,0xc,0x302000,0xc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x41c01,0xe020060c,
02156 0x800000,0x4,0x1e0703e0,0xf8060fc1,0xe1fe1e07,0x80000000,0x78,0x307e0,0x3c7c1fe7,0xf83c408f,0x80f10440,0x18660878,0x7e0787e0,
02157 0x78ff9024,0xa0140a0,0x27f83840,0x700e000,0x18000400,0x8000,0x70004002,0x410078,0x0,0x0,0x0,0x0,0x1808,0xc000000,0xf000000,
02158 0xe000000,0x1400,0x1e0001f,0x8007f800,0x0,0x0,0x3a3b,0x61400000,0x14202,0x20000,0x38002020,0x3c1b00,0x3e00000,0xf8,0x1c0001c0,
02159 0x78060001,0xf800000e,0x1e00020,0x8004020,0xc0300c0,0x300c0301,0xf83c7f9f,0xe7f9fe3e,0xf83e0f8,0x7c1821e0,0x781e0781,0xe0001f10,
02160 0x24090240,0xa02400f8,0x18018140,0xe81b0480,0x1801,0x81406c18,0x181406c,0x190e8180,0x18140e81,0xb0000006,0x60501b,0x184006c,
02161 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x26042202,0x200c06,0x800000,0x8,0x210d0611,0x40e0803,0x10026188,0x40000000,
02162 0x8c,0xf030418,0xc6431004,0xc64082,0x110840,0x18660884,0x41084410,0x8c081024,0xa012110,0x40082020,0x101b000,0xc000400,0x8000,
02163 0x80004002,0x410008,0x0,0x0,0x100000,0x0,0x2008,0x2000000,0x18800000,0x10000000,0x2200,0x2300024,0x800,0x0,0x0,0x2e13,0x60800000,
02164 0x8104,0x20040,0x64001040,0x80401b07,0x80100000,0x1e000,0x22000020,0x40c0003,0xc8000002,0x3300020,0x8004020,0xc0300c0,0x300c0301,
02165 0x40c64010,0x4010008,0x2008020,0x43182210,0x84210842,0x10002190,0x24090240,0x9044018c,0xc030220,0xb81b0300,0xc03,0x2206c0c,
02166 0x302206c,0x1e0b80c0,0x30220b81,0xb0000003,0xc0881b,0x304006c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x241f2202,
02167 0x200802,0x4900000,0x8,0x21010408,0x20a0802,0x44090,0x20000000,0x4,0x11878408,0x80411004,0x804082,0x111040,0x1ce50986,0x40986409,
02168 0x81022,0x12012108,0x80102020,0x1031800,0x400,0x8000,0x80004000,0x10008,0x0,0x0,0x100000,0x0,0x2008,0x2000000,0x10000000,
02169 0x10000000,0x18,0x4000044,0x1000,0x30180,0xd81b0000,0x13,0xe0000000,0x88,0x40,0x400018c0,0x80400018,0x61f00000,0x61800,0x22020020,
02170 0x4000007,0xc8000002,0x2100020,0x8038000,0x1e0781e0,0x781e0301,0x40804010,0x4010008,0x2008020,0x41142619,0x86619866,0x18002190,
02171 0x24090240,0x8887e104,0x0,0x0,0x0,0x0,0x0,0x2000000,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x2434a202,
02172 0x200802,0x3e00000,0x10,0x40810008,0x21a0804,0x44090,0x20000000,0x80040004,0x20848409,0x409004,0x1004082,0x112040,0x14a50902,
02173 0x40902409,0x81022,0x11321208,0x80202010,0x1060c00,0x7c5e0,0x781e8783,0xf07a5f0e,0x1c10808,0xfc5f078,0x5e07a170,0x7c7e1024,
02174 0xa016190,0x27f82008,0x2000000,0x20000000,0x10000000,0x80200024,0x4000044,0x2000,0x18180,0xc8320000,0x12,0xa1f00037,0x7f888,
02175 0x1e0,0x40410880,0x80600017,0xa2100000,0x5e800,0x22020040,0x38001027,0xc8000002,0x2100020,0x8004020,0x12048120,0x48120482,
02176 0x41004010,0x4010008,0x2008020,0x40942409,0x2409024,0x9044390,0x24090240,0x88841918,0x1f07c1f0,0x7c1f07c3,0x70781e07,0x81e07838,
02177 0xe0380e0,0x1f17c1e0,0x781e0781,0xe0001f90,0x24090240,0x9025e102,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0xff241c41,
02178 0x1001,0x1c02000,0x10,0x40810008,0x6120f85,0xe0086190,0x20c03007,0x8007800c,0x27848419,0x409004,0x1004082,0x114040,0x14a48902,
02179 0x40902409,0x81022,0x11321205,0x602010,0x1000000,0x86610,0x84218840,0x80866182,0x411008,0x9261884,0x61086189,0x82101022,0x12012108,
02180 0x40082008,0x2000000,0x20030000,0x20000000,0x80200024,0x4000044,0x3006030,0xc018100,0x4c260000,0x12,0x26080048,0x83000850,
02181 0x20250,0x403e0500,0x8078002c,0x12302200,0x92400,0x1c0200c0,0x4001027,0xc8000002,0x3308820,0x8004020,0x12048120,0x48120482,
02182 0x41004010,0x4010008,0x2008020,0x40922409,0x2409024,0x8884690,0x24090240,0x85040920,0x21886218,0x86218860,0x88842108,0x42108408,
02183 0x2008020,0x21186210,0x84210842,0x10302190,0x24090240,0x88461084,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x4c240182,
02184 0x80001001,0x6b02000,0x20,0x4c810010,0x78220846,0x10081e10,0x20c0301c,0x1fe0e018,0x4d8487e1,0x409fe7,0xf9007f82,0x11a040,
02185 0x13248902,0x41102418,0xe0081022,0x11320c05,0x402008,0x1000000,0x2409,0x409020,0x81024082,0x412008,0x9240902,0x40902101,0x101022,
02186 0x11321208,0x40102008,0x2000000,0x7e0c8000,0xfc000003,0xf0fc0018,0x43802047,0x8c8040c8,0x32008300,0x44240000,0x0,0x4000048,
02187 0x8c801050,0x20440,0x40221dc0,0x808c0028,0x11d0667f,0x8009c400,0x1fc180,0x4001023,0xc8300002,0x1e0ccfb,0x3ec7b020,0x12048120,
02188 0x48120482,0x79007f9f,0xe7f9fe08,0x2008020,0xf0922409,0x2409024,0x8504490,0x24090240,0x85040920,0x802008,0x2008020,0x89004090,
02189 0x24090208,0x2008020,0x40902409,0x2409024,0x8304390,0x24090240,0x88440884,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,
02190 0x481c0606,0xc8001001,0x802000,0x20,0x4c810020,0x4220024,0x8102108,0x60000070,0x3820,0x48884419,0x409004,0x10e4082,0x112040,
02191 0x13244902,0x7e1027e0,0x3c081021,0x21320c02,0x802008,0x1000000,0x7e409,0x409020,0x81024082,0x414008,0x9240902,0x40902101,
02192 0x80101022,0x11320c08,0x40202008,0x2038800,0x200bc000,0x20000000,0x80200003,0x80f04044,0xbc080bc,0x2f000200,0x0,0x0,0x6001048,
02193 0x8bc02020,0x20441,0xf8220200,0x80820028,0x1000cc00,0x80094400,0x201e0,0x78001021,0xc830000f,0x8000663c,0xf03c0c0,0x21084210,
02194 0x84210846,0x41004010,0x4010008,0x2008020,0x40912409,0x2409024,0x8204890,0x24090240,0x82040930,0x1f87e1f8,0x7e1f87e0,0x89004090,
02195 0x24090208,0x2008020,0x40902409,0x2409024,0x8004690,0x24090240,0x88440884,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,
02196 0x480719c4,0x48001001,0x81fc00,0x7800020,0x40810040,0x2420024,0x8104087,0xa0000070,0x3820,0x48884409,0x409004,0x1024082,0x111040,
02197 0x13244902,0x40102410,0x2081021,0x214a1202,0x1802008,0x1000000,0x182409,0x409fe0,0x81024082,0x41a008,0x9240902,0x40902100,
02198 0xf8101021,0x214a0c04,0x80c0c008,0x1847000,0x7c1ee000,0x20000000,0x8020000c,0x8c044,0x1ee181ee,0x7b800000,0x707,0xf3ff0000,
02199 0x3e0084f,0x9ee0c020,0x20440,0x40221fc0,0xc2002c,0x13f11000,0x87892400,0x20000,0x1020,0x48000000,0x3f011c6,0x31cc6180,0x21084210,
02200 0x84210844,0x41004010,0x4010008,0x2008020,0x40912409,0x2409024,0x8505090,0x24090240,0x8204191c,0x60982609,0x82609823,0xf9007f9f,
02201 0xe7f9fe08,0x2008020,0x40902409,0x2409024,0x9fe4c90,0x24090240,0x84840848,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xfe048224,
02202 0x28001001,0x2000,0x40,0x40810080,0x27f8024,0x8104080,0x2000001c,0x1fe0e020,0x488fc409,0x409004,0x1024082,0x110840,0x10242902,
02203 0x40102408,0x2081021,0x214a1202,0x1002004,0x1000000,0x102409,0x409000,0x81024082,0x411008,0x9240902,0x40902100,0x6101021,
02204 0x214a0c04,0x81002008,0x2000000,0x201dc000,0x20000000,0x80200000,0x98044,0x1dc101dc,0x77000000,0x700,0x0,0x180448,0x1dc10020,
02205 0x20440,0x403e0200,0x620017,0xa000cc00,0x80052800,0x20000,0x1020,0x48000000,0x6606,0x206100,0x3f0fc3f0,0xfc3f0fc7,0xc1004010,
02206 0x4010008,0x2008020,0x4090a409,0x2409024,0x8886090,0x24090240,0x8207e106,0x40902409,0x2409024,0x81004010,0x4010008,0x2008020,
02207 0x40902409,0x2409024,0x8005890,0x24090240,0x84840848,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x98048224,0x30001001,0x2000,
02208 0x40,0x21010100,0x2020024,0x8204080,0x40000007,0x80078000,0x48884408,0x80411004,0x824082,0x110840,0x10242986,0x40086409,0x2081021,
02209 0xe14a2102,0x2002004,0x1000000,0x106409,0x409000,0x81024082,0x410808,0x9240902,0x40902100,0x2101021,0x214a1202,0x82002008,
02210 0x2000000,0x300f8000,0x20000000,0x80fc001d,0xe4088044,0xf8200f8,0x3e000000,0x300,0x0,0x80c48,0xf820020,0x20640,0x40410200,
02211 0x803c0018,0x60006600,0x61800,0x0,0x1020,0x48000000,0xcc0a,0x20a100,0x21084210,0x84210844,0x40804010,0x4010008,0x2008020,
02212 0x4110a619,0x86619866,0x19046110,0x24090240,0x82040102,0x41906419,0x6419064,0x81004010,0x4010008,0x2008020,0x40902409,0x2409024,
02213 0x8307090,0x24090240,0x82840828,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x90248222,0x30000802,0x200c,0xc080,0x21010301,
02214 0x4021042,0x10202108,0xc0c03000,0x80040020,0x4d902418,0xc6431004,0xc24082,0x6210440,0x10241884,0x40084409,0x86080840,0xc0842102,
02215 0x4002002,0x1000000,0x18e610,0x84218820,0x80864082,0x410408,0x9240884,0x61086101,0x6101860,0xc0842103,0x4002008,0x2000000,
02216 0x10850180,0x20330000,0x80200013,0x26184024,0x5040050,0x14000000,0x0,0x0,0x4180848,0x85040020,0x20350,0x40000200,0x800c0007,
02217 0x80002200,0x1e000,0x0,0x1860,0x48000000,0x880a,0x40a188,0x40902409,0x2409028,0x40c64010,0x4010008,0x2008020,0x43106210,0x84210842,
02218 0x10006108,0x42108421,0x2040102,0x6398e639,0x8e6398e4,0x88842088,0x22088208,0x2008020,0x21102210,0x84210842,0x10306118,0x66198661,
02219 0x83061030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0x901f01c1,0xe8000802,0xc,0xc080,0x1e07c7f8,0xf8020f81,0xe0401e07,
02220 0x80c03000,0x20,0x279027e0,0x3c7c1fe4,0x3c408f,0x83c1027f,0x90241878,0x4007c404,0xf8080780,0xc0844082,0x7f82002,0x1000000,
02221 0xfa5e0,0x781e87c0,0x807a409f,0xc0410207,0x9240878,0x5e07a100,0xf80e0fa0,0xc0846183,0x7f82008,0x2000000,0xf020100,0x40321360,
02222 0x80200014,0xa3e0201f,0x8207f820,0x8000000,0x0,0x0,0x3e01037,0x207f820,0x201e1,0xfc000200,0x80040000,0x0,0x0,0x1fc000,0x17b0,
02223 0x48000000,0x12,0xc120f0,0x40902409,0x2409028,0x783c7f9f,0xe7f9fe3e,0xf83e0f8,0x7c1061e0,0x781e0781,0xe000be07,0x81e0781e,
02224 0x204017c,0x3e8fa3e8,0xfa3e8fa3,0x70781f07,0xc1f07c7f,0x1fc7f1fc,0x1e1021e0,0x781e0781,0xe0007e0f,0xa3e8fa3e,0x8305e030,0x0,
02225 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000,0xc06,0xc,0x100,0x0,0x0,0x0,0x3000,0x0,0x20000000,0x0,0x0,0x0,0x0,0xc000,
02226 0x0,0x0,0x2001,0x1000000,0x0,0x0,0x20000,0x400000,0x0,0x40002000,0x0,0x1,0x2008,0x2000000,0x100,0x40240000,0x80200008,0x40000000,
02227 0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x80040000,0x0,0x0,0x0,0x1000,0x48000000,0x1f,0x181f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02228 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1040010,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000,0x60c,0x18,0x0,
02229 0x0,0x0,0x0,0x6000,0x0,0x10000000,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x3800,0x7000000,0x0,0x0,0x840000,0x400000,0x0,0x40002000,
02230 0x0,0x2,0x2008,0x2000000,0x200,0x40440000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x80780000,0x0,0x0,0x0,0x1000,0x48000400,
02231 0x2,0x1e02000,0x0,0x0,0x80000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,0x0,0x0,0x0,0x0,0x0,0x0,0x2040020,0x0,0x0,0x0,0x0,
02232 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x4000,0x0,0xf000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02233 0x780000,0x3800000,0x0,0x40002000,0x0,0xe,0x1808,0xc000000,0x3,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000,
02234 0x0,0x0,0x0,0x1000,0x1c00,0x0,0x0,0x0,0x0,0x380000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x380000,0x0,0x0,0x0,0x0,0x0,0x0,0xe0400e0,
02235 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3fc,
02236 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02237 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
02238
02239
02240 const unsigned int font12x24[12*24*256/32] = {
02241 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02242 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x19,0x80000000,0x198000,0x0,0x0,0x0,0x0,
02243 0x0,0x198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc001806,0xc81980,0x60000000,0xc001806,0x1980c00,0x18060198,0xc80c,
02244 0x180600,0xc8198000,0xc001,0x80601980,0x18000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02245 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02246 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x0,0xf0000,0x0,0x0,0x0,0x0,0x0,0x198,0x0,0x0,0x0,0x0,0x0,0x0,
02247 0x0,0x0,0x0,0x0,0x0,0x0,0x600300f,0x1301980,0x90000000,0x600300f,0x1980600,0x300f0198,0x13006,0x300f01,0x30198000,0x6003,
02248 0xf01980,0x30000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02249 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02250 0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x0,0x60000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7007,0x3c0000,0x3006019,
02251 0x80000000,0x90000000,0x3006019,0x80000300,0x60198000,0x3,0x601980,0x0,0x3006,0x1980000,0x60000000,0x0,0x0,0xe0000000,0x0,
02252 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02253 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000000,
02254 0x0,0x0,0x0,0x0,0x0,0xc800019,0x80000000,0x198000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x1001,0x420000,0x0,0x0,0x90000000,
02255 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000c06,0xc80001,0x10000000,0x18000c06,0x1800,0xc060000,0xc818,0xc0600,0xc8000000,
02256 0x18000,0xc0600000,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80660207,0x800f8060,0x300c004,0x0,0x6,
02257 0xe00703f,0x3f00383,0xf80f07fc,0x1f01f000,0x0,0xf8,0x607f,0x7c7e07,0xfe7fe0f8,0x6063fc1f,0x86066007,0xe7060f0,0x7f80f07f,
02258 0x81f8fff6,0x6606c03,0x70ee077f,0xe0786000,0xf0070000,0xc000060,0xc0,0x3e000,0x60006003,0x600fc00,0x0,0x0,0x0,0x0,0x0,0x3c0603,
02259 0xc0000000,0x7800000,0xf0000,0x0,0xf00001f,0x80001fe0,0x7fe000,0x0,0x0,0x0,0x168fe609,0x0,0x90e07,0x6000,0x3c000e,0x70000f8,
02260 0x1980001f,0x0,0x1f8,0xf00000f,0xf00180,0xfe000,0xe00e,0x1001,0x20060,0x6006006,0x600600,0x600fe07c,0x7fe7fe7f,0xe7fe3fc3,
02261 0xfc3fc3fc,0x7e07060f,0xf00f00,0xf00f0000,0xf360660,0x6606606e,0x76001e0,0xc00180f,0x1681981,0x10000000,0xc00180f,0x1980c00,
02262 0x180f0198,0x3801680c,0x180f01,0x68198000,0xc001,0x80f01980,0x18600198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,
02263 0x8044020c,0xc01f8060,0x2004004,0x0,0xc,0x3f81f07f,0x87f80383,0xf81f87fc,0x3f83f800,0x0,0x1fc,0x780607f,0x81fe7f87,0xfe7fe1fc,
02264 0x6063fc1f,0x860c6007,0xe7061f8,0x7fc1f87f,0xc3fcfff6,0x6606c03,0x30c6067f,0xe0783000,0xf00d8000,0x6000060,0xc0,0x7e000,0x60006003,
02265 0x600fc00,0x0,0x0,0xc00,0x0,0x0,0x7c0603,0xe0000000,0xfc00000,0x1f0000,0x0,0x900003f,0xc0003fe0,0x7fe000,0x0,0x0,0x0,0x1302660f,
02266 0x0,0xf0606,0x6004,0x7e0006,0x60601f8,0x19800001,0x80000000,0x1f8,0x19800010,0x81080300,0x3f2000,0x2011,0x1001,0x1c0060,0x6006006,
02267 0x600600,0x601fe1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f87061f,0x81f81f81,0xf81f8000,0x3fa60660,0x66066066,0x66003f0,0x6003009,
02268 0x1301981,0x10000000,0x6003009,0x1980600,0x30090198,0x1f013006,0x300901,0x30198000,0x6003,0x901980,0x30600198,0x0,0x0,0x0,
02269 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc0f8c,0xc0180060,0x6006044,0x40000000,0xc,0x3181b041,0xc41c0783,0x388018,
02270 0x71c71800,0x0,0x106,0x18c0f061,0xc38261c6,0x600384,0x60606001,0x86186007,0xe78630c,0x60e30c60,0xe7040606,0x630cc03,0x39c30c00,
02271 0xc0603000,0x3018c000,0x3000060,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600,0x60000000,0x18400000,0x180000,
02272 0x0,0x19800070,0x40003600,0xc000,0x0,0x0,0x0,0x25a06,0x0,0x6030c,0x4,0xe20007,0xe060180,0xf000,0x80000000,0xf0000,0x10800000,
02273 0x80080600,0x7f2000,0x2020,0x80001001,0x20000,0xf00f00f,0xf00f00,0x601b0382,0x60060060,0x6000600,0x60060060,0x61c78630,0xc30c30c3,
02274 0xc30c000,0x30e60660,0x66066063,0xc600738,0x3006019,0x80000000,0xe0000000,0x3006019,0x80000300,0x60198000,0x3e000003,0x601980,
02275 0x0,0x3006,0x1980000,0x60600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc1fcc,0xc0180060,0x6006035,0x80000000,
02276 0x18,0x71c03000,0xc00c0583,0x300018,0x60c60c00,0x0,0x6,0x3060f060,0xc30060c6,0x600300,0x60606001,0x86306007,0x9e78670e,0x60670e60,
02277 0x66000606,0x630c606,0x19830c01,0xc0601800,0x30306000,0x60,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600,
02278 0x60000000,0x18000000,0x300000,0x0,0x78060,0x6600,0x1c000,0x300c,0x39819c0,0x0,0x25a00,0x0,0x30c,0x4,0xc00003,0xc060180,0x30c1f,
02279 0x80000000,0x30c000,0x10800001,0x80700000,0x7f2000,0x2020,0x80001001,0x20060,0xf00f00f,0xf00f00,0xf01b0300,0x60060060,0x6000600,
02280 0x60060060,0x60c78670,0xe70e70e7,0xe70e000,0x70c60660,0x66066063,0xc7f8618,0x0,0x0,0x0,0x0,0x0,0x0,0x7000000,0x0,0x0,0x0,
02281 0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x87ff3a4c,0xc0180060,0x400600e,0x600000,0x18,0x60c03000,
02282 0xc00c0d83,0x700018,0x60c60c00,0x20,0x400006,0x3060f060,0xc6006066,0x600600,0x60606001,0x86606006,0x966c6606,0x60660660,0x66000606,
02283 0x630c666,0xf019801,0x80601800,0x30603000,0x1f06f,0xf01ec0,0xf03fe1ec,0x6703e01f,0x61c0c06,0xdc6701f0,0x6f01ec0c,0xe1f87fc6,
02284 0xc60cc03,0x71c60c7f,0xc0600600,0x60000000,0x30000000,0x300000,0x40040,0x88060,0x6600,0x18000,0x300c,0x1981980,0x0,0x2421f,
02285 0x80003ce0,0x7fc198,0x601f,0xc02021,0x980600c0,0x40230,0x80000000,0x402000,0x19806003,0x80006,0xc7f2000,0x2020,0x80001001,
02286 0x420060,0xf00f00f,0xf00f00,0xf01b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x6606208,0x60e60660,0x66066061,
02287 0x987fc670,0x1f01f01f,0x1f01f01,0xf039c0f0,0xf00f00f,0xf03e03,0xe03e03e0,0x1f06701f,0x1f01f01,0xf01f0060,0x1e660c60,0xc60c60c6,
02288 0xc6f060c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x7ff3207,0x8c0c0000,0xc00300e,0x600000,0x30,0x60c03000,
02289 0xc01c0983,0xf0600030,0x31860c06,0x6001e0,0x78000e,0x23e1f861,0xc6006066,0x600600,0x60606001,0x86c06006,0x966c6606,0x60660660,
02290 0xe7000606,0x630c666,0xf01f803,0x600c00,0x30000000,0x3f87f,0x83f83fc3,0xf83fe3fc,0x7f83e01f,0x6380c07,0xfe7f83f8,0x7f83fc0d,
02291 0xf3fc7fc6,0xc71cc03,0x3183187f,0xc0600600,0x60000000,0xff806000,0x300000,0x40040,0x88070,0x6600,0x60030060,0x6001818,0x1883180,
02292 0x0,0x2423f,0xc0007ff0,0x607fc1f8,0x603f,0x80c01fc1,0xf80601e0,0x5f220,0x80420000,0x5f2000,0xf006006,0x80006,0xc7f2000,0x2020,
02293 0x82107c07,0xc03c0060,0x1f81f81f,0x81f81f80,0xf03b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x660671c,0x61660660,
02294 0x66066061,0xf860e6c0,0x3f83f83f,0x83f83f83,0xf87fe3f8,0x3f83f83f,0x83f83e03,0xe03e03e0,0x3f87f83f,0x83f83f83,0xf83f8060,
02295 0x3fc60c60,0xc60c60c3,0x187f8318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x883200,0x300c0000,0xc003035,0x80600000,
02296 0x30,0x66c03001,0xc0f81983,0xf86f0030,0x1f071c06,0x600787,0xfe1e001c,0x6261987f,0x86006067,0xfe7fc600,0x7fe06001,0x87c06006,
02297 0xf6646606,0x60e6067f,0xc3e00606,0x61986f6,0x600f007,0x600c00,0x30000000,0x21c71,0x830831c3,0x1c06031c,0x71c06003,0x6700c06,
02298 0x6671c318,0x71831c0f,0x16040c06,0xc318606,0x1b031803,0x80600600,0x60000000,0x30009000,0x300000,0x40040,0x7003e,0x67e0,0x90070090,
02299 0x9001818,0x8c3100,0x0,0x60,0x4000e730,0x900380f0,0x6034,0x80c018c7,0xfe060338,0xb0121,0x80c60000,0x909000,0x6008,0x1080006,
02300 0xc3f2000,0x2011,0x3180060,0x60060e0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0x60664660,0x66066066,
02301 0x66063b8,0x62660660,0x66066060,0xf06066c0,0x21c21c21,0xc21c21c2,0x1c466308,0x31c31c31,0xc31c0600,0x60060060,0x31871c31,0x83183183,
02302 0x18318000,0x71860c60,0xc60c60c3,0x18718318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1981a00,0xe03e0000,0xc003044,
02303 0x40600000,0x60,0x66c03001,0x80f03182,0x1c7f8030,0x3f83fc06,0x601e07,0xfe078038,0x6661987f,0x86006067,0xfe7fc61e,0x7fe06001,
02304 0x87e06006,0x66666606,0x7fc6067f,0x81f80606,0x61986f6,0x6006006,0x600600,0x30000000,0xc60,0xc60060c6,0xc06060c,0x60c06003,
02305 0x6e00c06,0x6660c60c,0x60c60c0e,0x6000c06,0xc318666,0x1f031803,0x600600,0x603c2000,0x30016800,0x1fe0000,0x1f81f8,0x1c1f,0x804067e1,
02306 0x68060168,0x16800810,0xc42300,0x0,0x60,0x20c331,0x68030060,0x6064,0x3fc1040,0xf006031c,0xa011e,0x818c7fe0,0x909000,0x7fe1f,
02307 0x80f00006,0xc0f2060,0xf80e,0x18c0780,0x780781c0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0xfc666660,
02308 0x66066066,0x66061f0,0x66660660,0x66066060,0x606066e0,0xc00c00,0xc00c00c0,0xc066600,0x60c60c60,0xc60c0600,0x60060060,0x60c60c60,
02309 0xc60c60c6,0xc60c000,0x61c60c60,0xc60c60c3,0x1860c318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1980f81,0x80373000,
02310 0xc003004,0x7fe0001,0xf0000060,0x60c03003,0x183180,0xc71c060,0x3181ec00,0x7000,0xe070,0x66619860,0xc6006066,0x60061e,0x60606001,
02311 0x87606006,0x66626606,0x7f860661,0xc01c0606,0x6198696,0xf00600e,0x600600,0x30000000,0x1fc60,0xc60060c7,0xfc06060c,0x60c06003,
02312 0x7c00c06,0x6660c60c,0x60c60c0c,0x7f00c06,0xc3b8666,0xe01b007,0x3c00600,0x3c7fe000,0xff03ec00,0x1fe0000,0x40040,0xe001,0xc0806603,
02313 0xec0e03ec,0x3ec00010,0x0,0x60000000,0x7f,0x10c3f3,0xec070060,0x6064,0x3fc1040,0x6000030c,0xa0100,0x3187fe1,0xf09f1000,0x7fe00,
02314 0x6,0xc012060,0x0,0xc63c03,0xc03c0380,0x19819819,0x81981981,0x98330600,0x60060060,0x6000600,0x60060060,0xfc662660,0x66066066,
02315 0x66060e0,0x6c660660,0x66066060,0x6060e630,0x1fc1fc1f,0xc1fc1fc1,0xfc3fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6,
02316 0xc60c7fe,0x62c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe02c6,0x3c633000,0xc003004,
02317 0x7fe0001,0xf00000c0,0x60c03006,0xc6180,0xc60c060,0x60c00c00,0x7000,0xe060,0x66639c60,0x66006066,0x600606,0x60606001,0x86306006,
02318 0x66636606,0x60060660,0xc0060606,0x61f8696,0xf00600c,0x600300,0x30000000,0x3fc60,0xc60060c7,0xfc06060c,0x60c06003,0x7c00c06,
02319 0x6660c60c,0x60c60c0c,0x1f80c06,0xc1b0666,0xe01b00e,0x3c00600,0x3c43c000,0x3007de00,0x600000,0x40040,0x30000,0x61006607,0xde0c07de,
02320 0x7de00000,0x0,0xf07fefff,0x1f,0x8008c3f7,0xde0e0060,0x6064,0xc01047,0xfe00018c,0xb013f,0x86300061,0xf0911000,0x6000,0x6,
02321 0xc012060,0x3f,0x8063c0cc,0x3cc0c700,0x39c39c39,0xc39c39c1,0x98630600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066,
02322 0x66061f0,0x78660660,0x66066060,0x607fc618,0x3fc3fc3f,0xc3fc3fc3,0xfc7fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6,
02323 0xc60c7fe,0x64c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe0260,0x6661b000,0xc003000,
02324 0x600000,0xc0,0x60c0300c,0xc7fe0,0xc60c060,0x60c01c00,0x1e07,0xfe078060,0x6663fc60,0x66006066,0x600606,0x60606001,0x86386006,
02325 0x6636606,0x60060660,0xe0060606,0x60f039c,0x1b806018,0x600300,0x30000000,0x70c60,0xc60060c6,0x6060c,0x60c06003,0x7600c06,
02326 0x6660c60c,0x60c60c0c,0x1c0c06,0xc1b03fc,0xe01f01c,0xe00600,0x70000000,0x3007fc00,0x600000,0x40040,0x0,0x62006607,0xfc1807fc,
02327 0x7fc00000,0x0,0xf0000000,0x1,0xc004c307,0xfc1c0060,0x6064,0xc018c0,0x600000d8,0x5f200,0x3180060,0x50a000,0x6000,0x6,0xc012000,
02328 0x0,0xc601c0,0x4201c600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066,0x66063b8,
02329 0x70660660,0x66066060,0x607f860c,0x70c70c70,0xc70c70c7,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000,
02330 0x68c60c60,0xc60c60c1,0xf060c1f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3300260,0x6661e000,0xc003000,0x600000,
02331 0x180,0x71c03018,0xc7fe0,0xc60c0c0,0x60c01800,0x787,0xfe1e0060,0x6663fc60,0x630060c6,0x600306,0x60606001,0x86186006,0x661e70e,
02332 0x60070c60,0x60060606,0x60f039c,0x19806038,0x600180,0x30000000,0x60c60,0xc60060c6,0x6060c,0x60c06003,0x6700c06,0x6660c60c,
02333 0x60c60c0c,0xc0c06,0xc1b039c,0x1f00e018,0x600600,0x60000000,0x1803f800,0x600000,0x40040,0x39e00,0x63006603,0xf83803f8,0x3f800000,
02334 0x0,0x60000000,0x0,0xc00cc303,0xf8180060,0x6064,0xc01fc0,0x60060070,0x40200,0x18c0060,0x402000,0x6000,0x6,0xc012000,0x0,0x18c0140,
02335 0x2014600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0300,0x60060060,0x6000600,0x60060060,0x60c61e70,0xe70e70e7,0xe70e71c,0x60e60660,0x66066060,
02336 0x6060060c,0x60c60c60,0xc60c60c6,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000,0x70c60c60,0xc60c60c0,
02337 0xe060c0e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x33022e0,0x6670c000,0xc003000,0x600600,0x60180,0x31803030,
02338 0x41c0184,0x1831c0c0,0x71c23806,0x6001e0,0x780000,0x62630c60,0xe38261c6,0x600386,0x60606043,0x860c6006,0x661e30c,0x60030c60,
02339 0x740e0607,0xe0f039c,0x31c06030,0x600180,0x30000000,0x61c71,0x830831c3,0x406031c,0x60c06003,0x6300c06,0x6660c318,0x71831c0c,
02340 0x41c0c07,0x1c0e039c,0x1b00e030,0x600600,0x60000000,0x1c41b00e,0x601cc0,0x401f8,0x45240,0xe1803601,0xb03001b0,0x1b000000,
02341 0x0,0x0,0x41,0xc008e711,0xb0300060,0x6034,0x80c02020,0x60060030,0x30c00,0xc60000,0x30c000,0x0,0x7,0x1c012000,0x0,0x3180240,
02342 0x6024608,0x30c30c30,0xc30c30c3,0xc630382,0x60060060,0x6000600,0x60060060,0x61c61e30,0xc30c30c3,0xc30c208,0x70c70e70,0xe70e70e0,
02343 0x6060068c,0x61c61c61,0xc61c61c6,0x1cc62308,0x30430430,0x43040600,0x60060060,0x31860c31,0x83183183,0x18318060,0x31c71c71,
02344 0xc71c71c0,0xe07180e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2203fc0,0x663f6000,0x6006000,0x600600,0x60300,
02345 0x3f81fe7f,0xc7f80187,0xf83f80c0,0x3f83f006,0x600020,0x400060,0x33e6067f,0xc1fe7f87,0xfe6001fe,0x6063fc7f,0x60e7fe6,0x660e3f8,
02346 0x6001f860,0x37fc0603,0xfc06030c,0x30c0607f,0xe06000c0,0x30000000,0x7fc7f,0x83f83fc3,0xfc0603fc,0x60c7fe03,0x61807c6,0x6660c3f8,
02347 0x7f83fc0c,0x7f80fc3,0xfc0e039c,0x3180607f,0xc0600600,0x60000000,0xfc0e00c,0x601986,0x66040040,0x4527f,0xc0803fe0,0xe07fe0e0,
02348 0xe000000,0x0,0x0,0x7f,0x80107ff0,0xe07fc060,0x603f,0x83fe0000,0x60060018,0xf000,0x420000,0xf0000,0x7fe00,0x7,0xfe012000,
02349 0x0,0x2100640,0xc0643f8,0x60660660,0x66066067,0xec3e1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f860e3f,0x83f83f83,0xf83f8000,
02350 0x5fc3fc3f,0xc3fc3fc0,0x606006fc,0x7fc7fc7f,0xc7fc7fc7,0xfcffe3f8,0x3fc3fc3f,0xc3fc7fe7,0xfe7fe7fe,0x3f860c3f,0x83f83f83,
02351 0xf83f8060,0x7f83fc3f,0xc3fc3fc0,0x607f8060,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2201f80,0x3c1e7000,0x6006000,
02352 0x600,0x60300,0xe01fe7f,0xc3f00183,0xe01f0180,0x1f01e006,0x600000,0x60,0x3006067f,0x807c7e07,0xfe6000f8,0x6063fc3e,0x6067fe6,
02353 0x660e0f0,0x6000f060,0x3bf80601,0xf806030c,0x60e0607f,0xe06000c0,0x30000000,0x1ec6f,0xf01ec0,0xf80601ec,0x60c7fe03,0x61c03c6,
02354 0x6660c1f0,0x6f01ec0c,0x3f007c1,0xcc0e030c,0x71c0c07f,0xc0600600,0x60000000,0x7804018,0xe01186,0x66040040,0x39e3f,0x80401fe0,
02355 0x407fe040,0x4000000,0x0,0x0,0x3f,0x203ce0,0x407fc060,0x601f,0x3fe0000,0x60060018,0x0,0x0,0x0,0x7fe00,0x6,0xe6012000,0x0,
02356 0x7e0,0x1807e1f0,0x60660660,0x66066066,0x6c3e07c,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7e060e0f,0xf00f00,0xf00f0000,0x8f01f81f,
02357 0x81f81f80,0x60600670,0x1ec1ec1e,0xc1ec1ec1,0xec79c0f0,0xf80f80f,0x80f87fe7,0xfe7fe7fe,0x1f060c1f,0x1f01f01,0xf01f0000,0x4f01cc1c,
02358 0xc1cc1cc0,0xc06f00c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x6006000,0x600,0x600,0x0,0x0,0x0,0x0,
02359 0x600000,0x0,0x18000000,0x0,0x0,0x0,0x0,0x0,0x1800,0x0,0x0,0x0,0x600060,0x30000000,0x0,0x0,0xc,0x3,0x0,0x0,0x60000c00,0x0,
02360 0x0,0xc000,0x600600,0x60000000,0x18,0xc03100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f8,0x0,0x0,0x0,0x0,0x6,
02361 0x12000,0x2000000,0x40,0x20004000,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02362 0x0,0xc06000c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x2004000,0xc00,0x0,0x0,0x0,0x0,0x0,0xc00000,
02363 0x0,0x1c000000,0x0,0x0,0x0,0x0,0x0,0xc00,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x21c,0x3,0x0,0x0,0x60000c00,0x0,0x0,0xc000,
02364 0x7c0603,0xe0000000,0x10,0xc02300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f0,0x0,0x0,0x0,0x0,0x6,0x12000,0x1000000,
02365 0x40,0x7e004000,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc06000c0,0x0,
02366 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x300c000,0xc00,0x0,0x0,0x0,0x0,0x0,0xc00000,0x0,0x7800000,0x0,
02367 0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x3f8,0x3e,0x0,0x0,0x60000c00,0x0,0x0,0x38000,0x3c0603,0xc0000000,
02368 0x10,0xfc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x60000,0x0,0x0,0x0,0x0,0x6,0x0,0x1000000,0x0,0x0,0x0,0x0,
02369 0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x80600380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02370 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffc,0x0,
02371 0x0,0x1f0,0x3c,0x0,0x0,0x60000c00,0x0,0x0,0x38000,0x600,0x0,0x0,0xf000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02372 0x0,0x0,0x0,0x0,0x0,0x6,0x0,0xe000000,0x0,0x0,0x0,0x0,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x0,0x0,0x0,0x0,
02373 0x0,0x0,0x0,0x3,0x80600380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02374 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02375 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02376 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
02377
02378
02379 const unsigned int font16x32[16*32*256/32] = {
02380 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02381 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02382 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc300000,0x0,0xc300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02383 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70000e0,0x3c00730,0xe7001c0,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0x730,0x70000e0,0x3c00730,
02384 0xe700000,0x700,0xe003c0,0xe7000e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02385 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02386 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02387 0x0,0x0,0x6600000,0x0,0x6600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02388 0x0,0x0,0x18001c0,0x6600ff0,0xe7003e0,0x0,0x18001c0,0x6600e70,0x18001c0,0x6600e70,0xff0,0x18001c0,0x6600ff0,0xe700000,0x180,
02389 0x1c00660,0xe7001c0,0x0,0x0,0x0,0x380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02390 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02391 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,
02392 0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00380,
02393 0xc300ce0,0xe700630,0x0,0x1c00380,0xc300e70,0x1c00380,0xc300e70,0xce0,0x1c00380,0xc300ce0,0xe700000,0x1c0,0x3800c30,0xe700380,
02394 0x0,0x0,0x0,0x7c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02395 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02396 0x0,0x0,0x0,0x0,0xe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x0,
02397 0x0,0x0,0x0,0x0,0x0,0xc300000,0x0,0xc300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x700000,0x0,0x0,0x0,0x7c007c00,0x3e000000,
02398 0x0,0x0,0x630,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe000070,0x1800000,0xc60,0x0,0xe000070,0x1800000,0xe000070,
02399 0x1800000,0x0,0xe000070,0x1800000,0x0,0xe00,0x700180,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02400 0x0,0x0,0x0,0x800000,0x0,0x600600,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02401 0x0,0x0,0x3f0,0xfc0,0x0,0x7000000,0x38000000,0x1c0000,0xfc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,
02402 0x1801f00,0x0,0x0,0x1c,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7300000,0x6600000,0x0,0x6600000,0x0,0x0,0x0,0x0,0xe700000,
02403 0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0x0,0xc000c00,0x43800000,0x0,0x0,0x630,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02404 0xf80,0x70000e0,0x3c00730,0xe700c60,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0xe000730,0x70000e0,0x3c00730,0xe700000,0x700,
02405 0xe003c0,0xe7000e0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300000,0x803c00,0x7c00180,
02406 0xc00300,0x1000000,0x0,0x1c,0x3c007c0,0xfc007e0,0xe01ff8,0x3f03ffc,0x7e007c0,0x0,0x0,0x7c0,0x1c0,0x7f8003f0,0x7f007ff8,0x7ff803f0,
02407 0x70381ffc,0xff0700e,0x7000783c,0x783807c0,0x7fc007c0,0x7fc00fc0,0x7fff7038,0x700ee007,0x780f780f,0x7ffc03f0,0x70000fc0,0x3c00000,
02408 0x3000000,0x38000000,0x1c0000,0x1fc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x1801f80,0x0,0x1f80000,
02409 0x7e,0x0,0x0,0x2400000,0xfc00000,0x7ff0000,0x7ffc0000,0x0,0x0,0x0,0x0,0xf30fb0c,0x2400000,0x0,0x240780f,0x1c0,0xfc,0x780f,
02410 0x18003f0,0xe700000,0x7c00000,0x0,0xff0,0x3c00000,0x78007c0,0xc00000,0xff80000,0xf80,0x7c00000,0xc000c00,0x18001c0,0x1c001c0,
02411 0x1c001c0,0x1c003e0,0x7fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007838,0x7c007c0,0x7c007c0,0x7c00000,0x7c67038,
02412 0x70387038,0x7038780f,0x70001fe0,0x30000c0,0x2400f30,0xe700c60,0x0,0x30000c0,0x2400e70,0x30000c0,0x2400e70,0xf700f30,0x30000c0,
02413 0x2400f30,0xe700000,0x300,0xc00240,0xe7000c0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,
02414 0x630018c,0x807e00,0xfe00180,0xc00300,0x1000000,0x0,0x38,0xff01fc0,0x3ff01ff0,0x1e01ff8,0x7f83ffc,0x1ff80ff0,0x0,0x0,0xff0,
02415 0x1f003e0,0x7fe00ff8,0x7fc07ff8,0x7ff80ff8,0x70381ffc,0xff0701c,0x7000783c,0x78381ff0,0x7fe01ff0,0x7fe01ff0,0x7fff7038,0x781ee007,
02416 0x3c1e380e,0x7ffc0380,0x380001c0,0x3c00000,0x1800000,0x38000000,0x1c0000,0x3c00000,0x380001c0,0xe01c00,0x3800000,0x0,0x0,
02417 0x0,0x7000000,0x0,0x0,0x1e0,0x18003c0,0x0,0x3fc0000,0x70,0x0,0x0,0x6600000,0x1ff00000,0x1fff0000,0x7ffc0000,0x0,0x0,0x0,0x0,
02418 0xcf0239c,0x3c00000,0x0,0x3c0380e,0x1c0,0x2001fe,0x380e,0x18007f8,0xe700000,0x8600000,0x0,0xff0,0x7e00000,0x8c00870,0x1800000,
02419 0x1ff80000,0x180,0xc600000,0xc000c00,0x38001c0,0x3e003e0,0x3e003e0,0x3e001c0,0x7fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,
02420 0x7fc07838,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x1fec7038,0x70387038,0x7038380e,0x70003ce0,0x1800180,0x6600cf0,0xe7007c0,0x0,
02421 0x1800180,0x6600e70,0x1800180,0x6600e70,0x7c00cf0,0x1800180,0x6600cf0,0xe700000,0x180,0x1800660,0xe700180,0x38000e70,0x0,
02422 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630030c,0x3f0e700,0x1e200180,0x1800180,0x21100000,0x0,
02423 0x38,0x1e7819c0,0x38781038,0x1e01c00,0xf080038,0x1c381c38,0x0,0x0,0x1878,0x7fc03e0,0x70e01e18,0x70e07000,0x70001e18,0x703801c0,
02424 0x707038,0x70007c7c,0x7c381c70,0x70701c70,0x70703830,0x1c07038,0x381ce007,0x1c1c3c1e,0x3c0380,0x380001c0,0x7e00000,0xc00000,
02425 0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0,0x70c0000,0xe0,
02426 0x0,0x0,0xc300000,0x38300000,0x3c700000,0x3c0000,0x0,0x0,0x0,0x0,0xce022f4,0x1800000,0x0,0x1803c1e,0x1c0,0x2003c2,0x3c1e,
02427 0x1800e08,0x7e0,0x300000,0x0,0x7e00000,0xe700000,0x600030,0x3000000,0x3f980000,0x180,0x18200000,0xc000c00,0x1e0001c0,0x3e003e0,
02428 0x3e003e0,0x3e003e0,0xfe01e18,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70e07c38,0x1c701c70,0x1c701c70,0x1c700000,0x3c787038,
02429 0x70387038,0x70383c1e,0x70003870,0xc00300,0xc300ce0,0x380,0x0,0xc00300,0xc300000,0xc00300,0xc300000,0xfc00ce0,0xc00300,0xc300ce0,
02430 0x0,0xc0,0x3000c30,0x300,0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630031c,0xff8c300,
02431 0x1c000180,0x1800180,0x39380000,0x0,0x70,0x1c3801c0,0x203c001c,0x3e01c00,0x1c000038,0x381c3838,0x0,0x0,0x1038,0xe0e03e0,0x70703c08,
02432 0x70707000,0x70003808,0x703801c0,0x707070,0x70007c7c,0x7c383838,0x70383838,0x70387010,0x1c07038,0x381c700e,0x1e3c1c1c,0x780380,
02433 0x1c0001c0,0xe700000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,
02434 0x0,0xe000000,0xe0,0x0,0x1000100,0x3800,0x70100000,0x38700000,0x780000,0x1c0,0x7801ce0,0xe380000,0x0,0x2264,0x0,0x0,0x1c1c,
02435 0x0,0x200780,0x1c1c,0x1800c00,0x1818,0x7f00000,0x0,0x18180000,0xc300000,0x600070,0x0,0x7f980000,0x180,0x18300000,0xc000c00,
02436 0x3000000,0x3e003e0,0x3e003e0,0x3e003e0,0xee03c08,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838,
02437 0x38380000,0x38387038,0x70387038,0x70381c1c,0x7fc03870,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xbc00000,0x0,0x0,0x0,0x0,0x0,0x0,
02438 0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0xe88c300,0x1c000180,0x38001c0,
02439 0xfe00180,0x0,0x70,0x1c3801c0,0x1c001c,0x6e01c00,0x1c000078,0x381c3818,0x0,0x40000,0x40000038,0x1c0607e0,0x70703800,0x70707000,
02440 0x70003800,0x703801c0,0x7070e0,0x70007c7c,0x7c383838,0x70383838,0x70387000,0x1c07038,0x381c700e,0xf780e38,0x700380,0x1c0001c0,
02441 0x1c380000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0,
02442 0xe000000,0xe0,0x0,0x1000100,0x4400,0x70000000,0x38700000,0x700000,0xe0,0x7001c70,0xe380000,0x0,0x2264,0x0,0x0,0xe38,0x0,
02443 0x200700,0xe38,0x1800c00,0x300c,0xc300000,0x0,0x300c0000,0xc300180,0x6003c0,0x0,0x7f980000,0x180,0x18300000,0xc000c00,0x1800000,
02444 0x7e007e0,0x7e007e0,0x7e003e0,0xee03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838,0x38380000,
02445 0x38387038,0x70387038,0x70380e38,0x7ff039f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e00000,0x0,0x0,0x0,0x40000,0x0,0x0,0x38000000,
02446 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0x1c80e700,0x1c000180,0x38001c0,0x3800180,
02447 0x0,0xe0,0x381c01c0,0x1c001c,0x6e01c00,0x38000070,0x381c381c,0x0,0x3c0000,0x78000078,0x38030770,0x70707800,0x70387000,0x70007000,
02448 0x703801c0,0x7071c0,0x7000745c,0x7638701c,0x7038701c,0x70387000,0x1c07038,0x1c38718e,0x7700f78,0xf00380,0xe0001c0,0x381c0000,
02449 0x7e0,0x39e003e0,0x79c03f0,0x3ffc079c,0x39e01fc0,0xfe01c1e,0x3807778,0x39e007e0,0x39e0079c,0x73c07e0,0x7ff83838,0x701ce007,
02450 0x783c701c,0x1ffc01c0,0x18001c0,0x0,0x1c000100,0xe0,0x0,0x1000100,0x4200,0x70000000,0x70700100,0xf00100,0x10000e0,0x7000c70,
02451 0xc700000,0x0,0x2204,0x7e00000,0x1e380100,0x1ffc0f78,0x0,0xf80700,0xf78,0x1800e00,0x63e6,0x18300000,0x0,0x6fe60000,0xe700180,
02452 0xc00060,0x3838,0x7f980000,0x180,0x18300000,0xc000c00,0x18001c0,0x7700770,0x7700770,0x77007f0,0xee07800,0x70007000,0x70007000,
02453 0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1008,0x707c7038,0x70387038,0x70380f78,0x707039c0,0x7e007e0,0x7e007e0,
02454 0x7e007e0,0x1f3c03e0,0x3f003f0,0x3f003f0,0x1fc01fc0,0x1fc01fc0,0x7f039e0,0x7e007e0,0x7e007e0,0x7e00380,0x7ce3838,0x38383838,
02455 0x3838701c,0x39e0701c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6307fff,0x1c807e0c,0xe000180,
02456 0x30000c0,0x3800180,0x0,0xe0,0x381c01c0,0x1c001c,0xce01fe0,0x38000070,0x381c381c,0x3800380,0xfc0000,0x7e0000f0,0x30030770,
02457 0x70707000,0x70387000,0x70007000,0x703801c0,0x707380,0x700076dc,0x7638701c,0x7038701c,0x70387800,0x1c07038,0x1c3873ce,0x7f00770,
02458 0xe00380,0xe0001c0,0x700e0000,0x1ff8,0x3ff00ff0,0xffc0ff8,0x3ffc0ffc,0x3bf01fc0,0xfe01c3c,0x3807f78,0x3bf00ff0,0x3ff00ffc,
02459 0x77e0ff0,0x7ff83838,0x3838e007,0x3c783838,0x1ffc01c0,0x18001c0,0x0,0x7ff00380,0x1e0,0x0,0x1000100,0x4200,0x78000000,0x70700380,
02460 0xe00380,0x3800060,0xe000e30,0x1c600000,0x0,0x2204,0xff00000,0x7f7c0380,0x1ffc0770,0x1c0,0x3fc0700,0x18040770,0x1800780,0x4e12,
02461 0x18300104,0x0,0x4c320000,0x7e00180,0x1c00030,0x3838,0x7f980000,0x180,0x18302080,0xc000c00,0x18001c0,0x7700770,0x7700770,
02462 0x7700770,0x1ee07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c381c,0x705c7038,0x70387038,
02463 0x70380770,0x70383b80,0x1ff81ff8,0x1ff81ff8,0x1ff81ff8,0x3fbe0ff0,0xff80ff8,0xff80ff8,0x1fc01fc0,0x1fc01fc0,0xff83bf0,0xff00ff0,
02464 0xff00ff0,0xff00380,0xffc3838,0x38383838,0x38383838,0x3ff03838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02465 0x0,0x1c0,0x7fff,0x1c803c38,0xf000000,0x70000e0,0xfe00180,0x0,0x1c0,0x381c01c0,0x3c0078,0xce01ff0,0x39e000f0,0x1c38381c,0x3800380,
02466 0x3e07ffc,0xf8001f0,0x307b0770,0x70e07000,0x70387000,0x70007000,0x703801c0,0x707700,0x700076dc,0x7638701c,0x7038701c,0x70387e00,
02467 0x1c07038,0x1c3873ce,0x3e007f0,0x1e00380,0x70001c0,0x0,0x1038,0x3c381e18,0x1c7c1e3c,0x3801e3c,0x3c7801c0,0xe01c78,0x380739c,
02468 0x3c781c38,0x3c381c3c,0x7c21e10,0x7003838,0x3838700e,0x1ef03838,0x3c01c0,0x18001c0,0x0,0x7fe007c0,0x1c0,0x0,0x1000100,0x6400,
02469 0x7e000000,0x707007c0,0x1e007c0,0x7c00070,0xe000638,0x18600000,0x0,0x0,0x1e100000,0x73ce07c0,0x3c07f0,0x1c0,0x7240700,0x1ddc3ffe,
02470 0x1800de0,0x8c01,0x1870030c,0x0,0x8c310000,0x3c00180,0x3800030,0x3838,0x7f980000,0x180,0x183030c0,0xc000c00,0x430001c0,0x7700770,
02471 0x7700770,0x7700770,0x1ce07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1c38,0x70dc7038,
02472 0x70387038,0x703807f0,0x70383b80,0x10381038,0x10381038,0x10381038,0x21e71e18,0x1e3c1e3c,0x1e3c1e3c,0x1c001c0,0x1c001c0,0x1e383c78,
02473 0x1c381c38,0x1c381c38,0x1c380380,0x1c383838,0x38383838,0x38383838,0x3c383838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02474 0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0x1e8000e0,0x1f000000,0x70000e0,0x39380180,0x0,0x1c0,0x3b9c01c0,0x3c07f0,0x18e01078,0x3bf800e0,
02475 0x7e0383c,0x3800380,0x1f807ffc,0x3f001c0,0x61ff0e38,0x7fc07000,0x70387ff0,0x7ff07000,0x7ff801c0,0x707f00,0x7000729c,0x7338701c,
02476 0x7070701c,0x70703fc0,0x1c07038,0x1e7873ce,0x1c003e0,0x3c00380,0x70001c0,0x0,0x1c,0x3c381c00,0x1c3c1c1c,0x3801c3c,0x383801c0,
02477 0xe01cf0,0x380739c,0x38381c38,0x3c381c3c,0x7801c00,0x7003838,0x3838700e,0xfe03c78,0x7801c0,0x18001c0,0x0,0x1c000c20,0xff8,
02478 0x0,0x1ff01ff0,0x3818,0x3fc00100,0x707e0c20,0x3c00c20,0xc200030,0xc000618,0x18c00000,0x0,0x0,0x1c000080,0xe1ce0c20,0x7803e0,
02479 0x1c0,0xe200700,0xff83ffe,0x1801878,0x9801,0x1cf0071c,0x7ffc0000,0x8c310000,0x7ffe,0x7000030,0x3838,0x3f980380,0x180,0xc6038e0,
02480 0x7f9c7f9c,0x3e1c01c0,0xe380e38,0xe380e38,0xe380f78,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0,0x1c001c0,0xfe387338,0x701c701c,
02481 0x701c701c,0x701c0e70,0x719c7038,0x70387038,0x703803e0,0x70383b80,0x1c001c,0x1c001c,0x1c001c,0xe71c00,0x1c1c1c1c,0x1c1c1c1c,
02482 0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380000,0x3c383838,0x38383838,0x38383c78,0x3c383c78,0x0,0x0,0x0,0x0,
02483 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0xf800380,0x3f830000,0x70000e0,0x31080180,0x0,0x380,0x3b9c01c0,
02484 0x7807e0,0x38e00038,0x3c3800e0,0xff01c3c,0x3800380,0x7c000000,0x7c03c0,0x61870e38,0x7fc07000,0x70387ff0,0x7ff070fc,0x7ff801c0,
02485 0x707f80,0x7000739c,0x7338701c,0x7ff0701c,0x7fe00ff0,0x1c07038,0xe7073ce,0x1c003e0,0x3800380,0x38001c0,0x0,0x1c,0x381c3800,
02486 0x381c380e,0x380381c,0x383801c0,0xe01de0,0x380739c,0x3838381c,0x381c381c,0x7001e00,0x7003838,0x1c70718e,0x7e01c70,0xf00380,
02487 0x18001e0,0x1e000000,0x1c001bb0,0xff8,0x0,0x1000100,0xe0,0xff00300,0x707e1bb0,0x3801bb0,0x1bb00010,0x8000308,0x30c00000,0x0,
02488 0x0,0x1e0000c0,0xe1ce1bb0,0xf003e0,0x1c0,0x1c203ff8,0x63003e0,0x180181c,0x9801,0xfb00e38,0x7ffc0000,0x8fc10000,0x7ffe,0xe000860,
02489 0x3838,0x1f980380,0x180,0x7c01c70,0x1f001f0,0x1f003c0,0xe380e38,0xe380e38,0xe380e38,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0,
02490 0x1c001c0,0xfe387338,0x701c701c,0x701c701c,0x701c07e0,0x731c7038,0x70387038,0x703803e0,0x70383980,0x1c001c,0x1c001c,0x1c001c,
02491 0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x387c3838,0x38383838,0x38381c70,
02492 0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc30,0x7f00e00,0x33c30000,0x70000e0,0x1007ffe,
02493 0x0,0x380,0x3b9c01c0,0xf00078,0x30e0001c,0x3c1c01c0,0x1c381fdc,0x0,0x70000000,0x1c0380,0x63030e38,0x70707000,0x70387000,0x700070fc,
02494 0x703801c0,0x707b80,0x7000739c,0x7338701c,0x7fc0701c,0x7fc001f0,0x1c07038,0xe703e5c,0x3e001c0,0x7800380,0x38001c0,0x0,0x7fc,
02495 0x381c3800,0x381c380e,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7001fc0,0x7003838,0x1c70718e,0x7c01c70,
02496 0xe01f00,0x180007c,0x7f8c0000,0x7fc03fb8,0x1c0,0x0,0x1000100,0x700,0x1f00600,0x70703fb8,0x7803fb8,0x3fb80000,0x8000000,0x180,
02497 0x0,0x0,0x1fc00060,0xe1ce3fb8,0xe001c0,0x1c0,0x1c203ff8,0xc1801c0,0x180c,0x9801,0x1c70,0xc0000,0x8cc10000,0x180,0xfe007c0,
02498 0x3838,0x7980380,0xff0,0xe38,0x3e003e00,0x3e000380,0xe380e38,0xe380e38,0xe380e38,0x38e07000,0x70007000,0x70007000,0x1c001c0,
02499 0x1c001c0,0x70387338,0x701c701c,0x701c701c,0x701c03c0,0x731c7038,0x70387038,0x703801c0,0x703838e0,0x7fc07fc,0x7fc07fc,0x7fc07fc,
02500 0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x38dc3838,0x38383838,0x38381c70,
02501 0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc60,0xf83878,0x71e30000,0x70000e0,0x1007ffe,
02502 0x7f0,0x380,0x381c01c0,0x1e0003c,0x60e0001c,0x381c01c0,0x381c079c,0x0,0x7c000000,0x7c0380,0x63031c1c,0x70307000,0x70387000,
02503 0x7000701c,0x703801c0,0x7071c0,0x7000739c,0x71b8701c,0x7000701c,0x71e00078,0x1c07038,0xe703e7c,0x7e001c0,0xf000380,0x38001c0,
02504 0x0,0x1ffc,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fc0,0x380739c,0x3838381c,0x381c381c,0x7000ff0,0x7003838,0x1ef03bdc,
02505 0x3800ee0,0x1e01f00,0x180007c,0x61fc0000,0x7fc07f3c,0x1c0,0x0,0x1000100,0x1800,0x780c00,0x70707f3c,0xf007f3c,0x7f3c0000,0x0,
02506 0x3c0,0x3ffcffff,0x0,0xff00030,0xe1fe7f3c,0x1e001c0,0x1c0,0x1c200700,0xc183ffe,0xe0c,0x9801,0x1ff038e0,0xc07f0,0x8c610000,
02507 0x180,0x0,0x3838,0x1980380,0x0,0x1ff0071c,0xe000e000,0xe0000f80,0x1c1c1c1c,0x1c1c1c1c,0x1c1c1e38,0x38e07000,0x70007000,0x70007000,
02508 0x1c001c0,0x1c001c0,0x703871b8,0x701c701c,0x701c701c,0x701c03c0,0x761c7038,0x70387038,0x703801c0,0x70703870,0x1ffc1ffc,0x1ffc1ffc,
02509 0x1ffc1ffc,0xfff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x389c3838,0x38383838,
02510 0x38380ee0,0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xfffc,0xbc60fc,0x70e30000,0x70000e0,
02511 0x180,0x7f0,0x700,0x381c01c0,0x3e0001c,0x7ffc001c,0x381c03c0,0x381c001c,0x0,0x1f807ffc,0x3f00380,0x63031ffc,0x70387000,0x70387000,
02512 0x7000701c,0x703801c0,0x7071e0,0x7000701c,0x71b8701c,0x7000701c,0x70f00038,0x1c07038,0x7e03e7c,0x77001c0,0xe000380,0x1c001c0,
02513 0x0,0x3c1c,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x70003f8,0x7003838,0xee03bdc,
02514 0x3c00ee0,0x3c00380,0x18000e0,0xf00000,0x1c007e7c,0x3c0,0x0,0x1000100,0x0,0x381800,0x70707e7c,0xe007e7c,0x7e7c0000,0x0,0x7c0,
02515 0x0,0x0,0x3f80018,0xe1fe7e7c,0x3c001c0,0x1c0,0x1c200700,0xc183ffe,0xf0c,0x8c01,0x38e0,0xc07f0,0x8c710000,0x180,0x0,0x3838,
02516 0x1980000,0x0,0x71c,0x7000f0,0x700f00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x3fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
02517 0x703871b8,0x701c701c,0x701c701c,0x701c07e0,0x7c1c7038,0x70387038,0x703801c0,0x7ff03838,0x3c1c3c1c,0x3c1c3c1c,0x3c1c3c1c,
02518 0x3fff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x391c3838,0x38383838,0x38380ee0,
02519 0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfffc,0x9c01ce,0x70f60000,0x70000e0,0x180,
02520 0x0,0x700,0x381c01c0,0x780001c,0x7ffc001c,0x381c0380,0x381c003c,0x0,0x3e07ffc,0xf800380,0x63031ffc,0x70387000,0x70387000,
02521 0x7000701c,0x703801c0,0x7070f0,0x7000701c,0x71b8701c,0x7000701c,0x70700038,0x1c07038,0x7e03e7c,0xf7801c0,0x1e000380,0x1c001c0,
02522 0x0,0x381c,0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7000078,0x7003838,0xee03a5c,
02523 0x7c00fe0,0x78001c0,0x18001c0,0x0,0x1c003ef8,0x380,0x0,0x1000100,0x810,0x383000,0x70703ef8,0x1e003ef8,0x3ef80000,0x0,0x7c0,
02524 0x0,0x0,0x78000c,0xe1c03ef8,0x78001c0,0x1c0,0x1c200700,0x63001c0,0x18003f8,0x4e12,0x1c70,0xc0000,0x4c320000,0x180,0x0,0x3838,
02525 0x1980000,0x0,0xe38,0x700118,0x701e00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x7fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
02526 0x703871b8,0x701c701c,0x701c701c,0x701c0e70,0x7c1c7038,0x70387038,0x703801c0,0x7fc0381c,0x381c381c,0x381c381c,0x381c381c,
02527 0x78e03800,0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x3b1c3838,0x38383838,0x38380fe0,
02528 0x381c0fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1860,0x9c0186,0x707e0000,0x30000c0,0x180,
02529 0x0,0xe00,0x183801c0,0xf00001c,0xe0001c,0x181c0380,0x381c0038,0x0,0xfc0000,0x7e000000,0x61873c1e,0x70383800,0x70707000,0x7000381c,
02530 0x703801c0,0x707070,0x7000701c,0x70f83838,0x70003838,0x70780038,0x1c07038,0x7e03c3c,0xe3801c0,0x1c000380,0xe001c0,0x0,0x381c,
02531 0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01ef0,0x380739c,0x3838381c,0x381c381c,0x7000038,0x7003838,0xfe03e7c,0xfe007c0,
02532 0x70001c0,0x18001c0,0x0,0xe001ff0,0x380,0x0,0x1000100,0x162c,0x381800,0x30701ff0,0x1c001ff0,0x1ff00000,0x0,0x3c0,0x0,0x0,
02533 0x380018,0xe1c01ff0,0x70001c0,0x1c0,0x1c200700,0xff801c0,0x18000f0,0x63e6,0xe38,0x0,0x6c3e0000,0x0,0x0,0x3838,0x1980000,0x0,
02534 0x1c70,0xf0000c,0xf01c00,0x3c1e3c1e,0x3c1e3c1e,0x3c1e3c1c,0x70e03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x707070f8,
02535 0x38383838,0x38383838,0x38381c38,0x38387038,0x70387038,0x703801c0,0x7000381c,0x381c381c,0x381c381c,0x381c381c,0x70e03800,
02536 0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0380,0x3e1c3838,0x38383838,0x383807c0,0x381c07c0,
02537 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18c0,0x9c0186,0x783c0000,0x38001c0,0x180,0x3800000,
02538 0x3800e00,0x1c3801c0,0x1e00003c,0xe00038,0x1c1c0780,0x381c0038,0x3800380,0x3c0000,0x78000000,0x61ff380e,0x70383808,0x70707000,
02539 0x7000381c,0x703801c0,0x40707078,0x7000701c,0x70f83838,0x70003838,0x70384038,0x1c07038,0x7e03c3c,0x1e3c01c0,0x3c000380,0xe001c0,
02540 0x0,0x383c,0x3c381c00,0x1c3c1c00,0x3801c3c,0x383801c0,0xe01c78,0x380739c,0x38381c38,0x3c381c3c,0x7000038,0x7003878,0x7c01e78,
02541 0x1ef007c0,0xf0001c0,0x18001c0,0x0,0xe000ee0,0x7800380,0xe380000,0x1001ff0,0x2242,0x40380c00,0x38700ee0,0x3c000ee0,0xee00000,
02542 0x0,0x0,0x0,0x0,0x380030,0xe1c00ee0,0xf0001c0,0x1c0,0xe200700,0xdd801c0,0x1800038,0x300c,0x71c,0x0,0x300c0000,0x0,0x0,0x3838,
02543 0x1980000,0x0,0x38e0,0xb0000c,0xb01c08,0x380e380e,0x380e380e,0x380e380e,0x70e03808,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
02544 0x707070f8,0x38383838,0x38383838,0x3838381c,0x38387038,0x70387038,0x703801c0,0x7000381c,0x383c383c,0x383c383c,0x383c383c,
02545 0x70e01c00,0x1c001c00,0x1c001c00,0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383878,0x38783878,0x387807c0,
02546 0x3c3807c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x18c0,0x10b801ce,0x3c3e0000,0x38001c0,0x180,
02547 0x3800000,0x3801c00,0x1e7801c0,0x3c002078,0xe02078,0x1c380700,0x1c3810f0,0x3800380,0x40000,0x40000380,0x307b380e,0x70701e18,
02548 0x70e07000,0x70001c1c,0x703801c0,0x60e0703c,0x7000701c,0x70f83c78,0x70003c70,0x703c70f0,0x1c03870,0x3c01c3c,0x3c1c01c0,0x78000380,
02549 0x7001c0,0x0,0x3c7c,0x3c381e18,0x1c7c1e0c,0x3801c3c,0x383801c0,0xe01c38,0x3c0739c,0x38381c38,0x3c381c3c,0x7001078,0x7803c78,
02550 0x7c01c38,0x1c780380,0x1e0001c0,0x18001c0,0x0,0x70c06c0,0x7000380,0xe300000,0x1000100,0x2142,0x70f00600,0x3c7006c0,0x780006c0,
02551 0x6c00000,0x0,0x0,0x0,0x0,0x10780060,0x73e206c0,0x1e0001c0,0x1c0,0x7240700,0x180c01c0,0x1800018,0x1818,0x30c,0x0,0x18180000,
02552 0x0,0x0,0x3c78,0x1980000,0x0,0x30c0,0x130000c,0x1301c18,0x380e380e,0x380e380e,0x380e380e,0x70e01e18,0x70007000,0x70007000,
02553 0x1c001c0,0x1c001c0,0x70e070f8,0x3c783c78,0x3c783c78,0x3c781008,0x7c783870,0x38703870,0x387001c0,0x70003a3c,0x3c7c3c7c,0x3c7c3c7c,
02554 0x3c7c3c7c,0x79f11e18,0x1e0c1e0c,0x1e0c1e0c,0x1c001c0,0x1c001c0,0x1c783838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383c78,0x3c783c78,
02555 0x3c780380,0x3c380380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x38c0,0x1ff800fc,0x1fee0000,
02556 0x1800180,0x180,0x3800000,0x3801c00,0xff01ffc,0x3ffc3ff0,0xe03ff0,0xff00700,0x1ff81fe0,0x3800380,0x0,0x380,0x3000780f,0x7ff00ff8,
02557 0x7fc07ff8,0x70000ffc,0x70381ffc,0x7fe0701c,0x7ff8701c,0x70781ff0,0x70001ff0,0x701c7ff0,0x1c01fe0,0x3c01c38,0x380e01c0,0x7ffc0380,
02558 0x7001c0,0x0,0x1fdc,0x3ff00ff0,0xffc0ffc,0x3800fdc,0x38383ffe,0xe01c3c,0x1fc739c,0x38380ff0,0x3ff00ffc,0x7001ff0,0x3f81fb8,
02559 0x7c01c38,0x3c3c0380,0x1ffc01c0,0x18001c0,0x0,0x3fc0380,0x7000380,0xc70718c,0x1000100,0x2244,0x7ff00200,0x1fff0380,0x7ffc0380,
02560 0x3800000,0x0,0x0,0x0,0x0,0x1ff000c0,0x7f7e0380,0x1ffc01c0,0x1c0,0x3fc3ffe,0x1c0,0x1800018,0x7e0,0x104,0x0,0x7e00000,0x7ffe,
02561 0x0,0x3fde,0x1980000,0x0,0x2080,0x3300018,0x3300ff0,0x780f780f,0x780f780f,0x780f780e,0xf0fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,
02562 0x1ffc1ffc,0x7fc07078,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x7ff01fe0,0x1fe01fe0,0x1fe001c0,0x70003bf8,0x1fdc1fdc,0x1fdc1fdc,
02563 0x1fdc1fdc,0x3fbf0ff0,0xffc0ffc,0xffc0ffc,0x3ffe3ffe,0x3ffe3ffe,0xff03838,0xff00ff0,0xff00ff0,0xff00000,0x3ff01fb8,0x1fb81fb8,
02564 0x1fb80380,0x3ff00380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x31c0,0x7e00078,0x7cf0000,0x1800180,
02565 0x0,0x3800000,0x3803800,0x3c01ffc,0x3ffc0fe0,0xe01fc0,0x3e00e00,0x7e00f80,0x3800380,0x0,0x380,0x18007007,0x7fc003f0,0x7f007ff8,
02566 0x700003f0,0x70381ffc,0x3f80701e,0x7ff8701c,0x707807c0,0x700007c0,0x701e1fc0,0x1c00fc0,0x3c01818,0x780f01c0,0x7ffc0380,0x3801c0,
02567 0x0,0xf9c,0x39e003e0,0x79c03f0,0x380079c,0x38383ffe,0xe01c1e,0x7c739c,0x383807e0,0x39e0079c,0x7000fc0,0x1f80f38,0x3801c38,
02568 0x781e0380,0x1ffc01c0,0x18001c0,0x0,0x1f80100,0xe000700,0x1c60718c,0x1000100,0x1e3c,0x1fc00100,0x7ff0100,0x7ffc0100,0x1000000,
02569 0x0,0x0,0x0,0x0,0xfc00080,0x3e3c0100,0x1ffc01c0,0x1c0,0xf83ffe,0x1c0,0x1800838,0x0,0x0,0x0,0x0,0x7ffe,0x0,0x3b9e,0x1980000,
02570 0x0,0x0,0x2300038,0x23003e0,0x70077007,0x70077007,0x70077007,0xe0fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007078,
02571 0x7c007c0,0x7c007c0,0x7c00000,0xc7c00fc0,0xfc00fc0,0xfc001c0,0x700039f0,0xf9c0f9c,0xf9c0f9c,0xf9c0f9c,0x1f1e03e0,0x3f003f0,
02572 0x3f003f0,0x3ffe3ffe,0x3ffe3ffe,0x7e03838,0x7e007e0,0x7e007e0,0x7e00000,0x63e00f38,0xf380f38,0xf380380,0x39e00380,0x0,0x0,
02573 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,0x0,0xc00300,0x0,0x3000000,0x3800,0x0,0x0,0x0,0x0,
02574 0x0,0x300,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x0,0x0,0x0,0x0,0x380,0x3801c0,0x0,0x0,0x0,0x0,0x1c,0x0,0xe00000,
02575 0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1c0,0x18001c0,0x0,0x0,0xe000700,0x18600000,0x1000100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02576 0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800ff0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0x1800000,0x0,0x6300070,0x6300000,0x0,
02577 0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000000,
02578 0x0,0x700,0x38000700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,0x0,0xc00300,0x0,0x7000000,
02579 0x7000,0x0,0x0,0x0,0x0,0x0,0x700,0x0,0x0,0xf040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78,0x0,0x0,0x0,0x0,0x3f0,0x1c0fc0,0x0,0x0,
02580 0x0,0x0,0x1c,0x0,0xe00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1e0,0x18003c0,0x0,0x0,0xc000700,0x18c00000,0x1000000,0x0,
02581 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x18007e0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0xc00000,
02582 0x0,0x7f800e0,0x7f80000,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,
02583 0x0,0x0,0x0,0x0,0x0,0x0,0x700,0x38000700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,
02584 0x0,0x600600,0x0,0x6000000,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x7fc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,
02585 0x3f0,0xfc0,0x0,0x0,0x0,0x0,0x838,0x0,0x1e00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0xf00,0xfc,0x1801f80,0x0,0x0,0x8008e00,0x30c00000,
02586 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0xc00000,
02587 0x0,0x3001c0,0x300000,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,
02588 0x0,0x0,0x0,0x0,0x0,0xf00,0x38000f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,0x0,
02589 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02590 0x0,0x0,0xff0,0x0,0x1fc00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x3e00,0x7c,0x1801f00,0x0,0x0,0x800fe00,0x0,0x0,0x0,0x0,0x0,0x0,
02591 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x7c00000,0x0,0x3001fc,0x300000,
02592 0x0,0x0,0x0,0x3e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02593 0x3e00,0x38003e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02594 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfff8,0x0,0x0,0x0,0x7e0,0x0,0x1f000000,
02595 0x0,0x0,0x3800001c,0x0,0x0,0x0,0x3c00,0x0,0x1800000,0x0,0x0,0x7800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02596 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x7800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02597 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00,0x38003c00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02598 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02599 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x0,0x0,
02600 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02601 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02602 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02603 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02604 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02605 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02606 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02607 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02608 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02609 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02610 0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
02611
02612
02613 const unsigned int font19x38[19*38*256/32] = {
02614 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02615 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02616 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c380000,0x0,0x1c380,0x0,0x0,0x0,0x0,0x0,
02617 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800007,0x3c003,0x86000000,
02618 0x1e00000,0x3,0x80000700,0x3c00000,0x380000,0x70003c00,0x0,0xe1800e,0x1c00,0xf000e18,0x0,0x0,0x700000e0,0x780000,0x7000,0x0,
02619 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02620 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02621 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02622 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe700000,0x0,0xe700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02623 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0000e,0x7e003,0xe60071c0,0x7f80000,0x1,0xc0000e00,0x7e0038e,0x1c0000,
02624 0xe0007e00,0x38e00000,0xf98007,0x3800,0x1f800f98,0x1c70000,0x0,0x380001c0,0xfc0071,0xc000e000,0x0,0x0,0x0,0x0,0x3e00000,0x0,
02625 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02626 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02627 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02628 0x0,0x0,0x0,0x7e00000,0x0,0x7e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02629 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0001c,0xe7006,0x7c0071c0,0xe180000,0x0,0xe0001c00,0xe70038e,0xe0001,0xc000e700,0x38e00000,
02630 0x19f0003,0x80007000,0x39c019f0,0x1c70000,0x0,0x1c000380,0x1ce0071,0xc001c000,0x0,0x0,0x0,0x0,0x7f00000,0x0,0x0,0x0,0x0,0x0,
02631 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02632 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02633 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,
02634 0x0,0x3c00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02635 0x0,0x0,0x700038,0x1c3806,0x3c0071c0,0xc0c0000,0x0,0x70003800,0x1c38038e,0x70003,0x8001c380,0x38e00000,0x18f0001,0xc000e000,
02636 0x70e018f0,0x1c70000,0x0,0xe000700,0x3870071,0xc0038000,0x0,0x0,0x0,0x0,0xe380000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02637 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02638 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02639 0xe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60000000,0x0,0x0,
02640 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c38,0x0,0x1,0xc3800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00000,0x0,0x0,0x0,
02641 0x0,0x0,0x0,0x0,0x0,0x0,0xc0c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe000003,0x80018000,0x0,0xc180000,
02642 0xe,0x380,0x1800000,0xe00000,0x38001800,0x0,0x38,0xe00,0x6000000,0x0,0x1,0xc0000070,0x300000,0x3800,0x0,0x0,0x0,0x0,0x0,0x0,
02643 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02644 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7000000,0x0,0x0,0x0,0x0,0x0,0x0,
02645 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78c00,0xc30,
02646 0x0,0x0,0xc3000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800000,0x0,0x0,0x0,0xe0,0x1c000f,0xc0000000,0x0,0x0,
02647 0x0,0xc0c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7000007,0x3c003,0xc6000000,0xc180000,0x7,0x700,
02648 0x3c00000,0x700000,0x70003c00,0x0,0xf1801c,0x1c00,0xf000f18,0x0,0x0,0xe00000e0,0x780000,0x7000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02649 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x1c007000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02650 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe0000,0xfe000,0x0,0x3800000,0x700000,0x38,
02651 0x7,0xe000001c,0x1c00,0x1c00700,0x7fc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf800e,0x3e0000,0x0,0x0,0x0,0x1e00000,0x0,0x1,
02652 0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7cc00,0x660,0x0,0x0,0x66000000,0x0,0x0,0x0,0x0,0x7,0x1c000000,0x0,0x0,0x0,0x3fe00000,
02653 0x0,0x0,0x7000000,0x0,0x0,0x0,0x3e0,0x7c001f,0xe0000000,0x0,0x0,0x0,0xe1c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02654 0x0,0x0,0x0,0x1f80,0x380000e,0x7e007,0xe60071c0,0xc180000,0x3,0x80000e00,0x7e0038e,0x380000,0xe0007e00,0x38e00f00,0x1f9800e,
02655 0x3800,0x1f801f98,0x1c70000,0x0,0x700001c0,0xfc0071,0xc000e007,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02656 0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0x61c00600,0x1e00007e,0x70000,0x18003000,0x1800000,0x0,0x0,0x1c01f0,0x7e003f,0xc003f800,
02657 0x1e03ffc,0x7f01ff,0xfc03f000,0x7e000000,0x0,0x0,0xfc0,0x1e,0x7fe000,0x7e03fe00,0x3fff07ff,0xe007e038,0x383ffe0,0xff81c01,
02658 0xe1c000f8,0xf8f00e0,0xfc01ffc,0x3f00ff,0xc000fe07,0xfffc7007,0x1c007700,0x73c01ef,0x78ffff,0xfe0380,0xfe000,0x38000000,0x1800000,
02659 0x700000,0x38,0x1f,0xe000001c,0x1c00,0x1c00700,0x7fc0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x3f800e,0x3f8000,0x0,0xfc0000,
02660 0x0,0x7f00000,0x0,0x1,0x98000000,0x7f00000,0x3ffe00,0xffff0,0x0,0x0,0x0,0x0,0x0,0xcf81f,0xee3807e0,0x0,0x0,0x7e03c01e,0x1c,
02661 0x0,0x1f800000,0xf0078038,0xfc007,0x1c000000,0xfe00000,0x0,0x0,0x3fe000f0,0xf,0xc001f800,0x6000000,0xffc000,0x0,0x1c0007e0,
02662 0x360,0x6c0010,0x70000700,0xf0001e,0x3c000,0x78000f00,0x7f800ff,0xf007e01f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83fc0,
02663 0x7807007,0xe000fc00,0x1f8003f0,0x7e0000,0x1f867,0x70e00e,0x1c01c380,0x38f00787,0x3fe0,0x180000c,0x66006,0x7c0071c0,0xe380000,
02664 0x1,0x80000c00,0x660038e,0x180000,0xc0006600,0x38e0078e,0x19f0006,0x3000,0x198019f0,0x1c70000,0x0,0x30000180,0xcc0071,0xc000c007,
02665 0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0x61800600,0x7f8001ff,0x70000,
02666 0x38003800,0x1800000,0x0,0x0,0x3807fc,0x1fe00ff,0xf00ffe00,0x3e03ffc,0xff81ff,0xfc07fc01,0xff800000,0x0,0x0,0x3fe0,0xfe001e,
02667 0x7ff801,0xff83ff80,0x3fff07ff,0xe01ff838,0x383ffe0,0xff81c03,0xc1c000f8,0xf8f80e0,0x3ff01fff,0xffc0ff,0xf003ff87,0xfffc7007,
02668 0x1e00f700,0x71c03c7,0x70ffff,0xfe01c0,0xfe000,0x7c000000,0xc00000,0x700000,0x38,0x3f,0xe000001c,0x1c00,0x1c00700,0x7fc0000,
02669 0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x3f800e,0x3f8000,0x0,0x3fe0000,0x0,0xff00000,0x0,0x3,0xc000000,0x1ffc0000,0xfffe00,
02670 0xffff0,0x0,0x0,0x0,0x0,0x0,0xc781f,0xee3803c0,0x0,0x0,0x3c01c01c,0x1c,0xc000,0x7fc00000,0x70070038,0x3fe007,0x1c000000,0x1ff80000,
02671 0x0,0x0,0x3fe003fc,0x1f,0xe003fc00,0xc000000,0x3ffc000,0x0,0x7c000ff0,0x60,0xc0000,0x30000700,0xf0001e,0x3c000,0x78000f00,
02672 0x3f000ff,0xf01ff81f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ff8,0x7c0701f,0xf803ff00,0x7fe00ffc,0x1ff8000,0x7fe67,
02673 0x70e00e,0x1c01c380,0x38700707,0x7ff0,0xc00018,0xc3006,0x3c0071c0,0x7f00000,0x0,0xc0001800,0xc30038e,0xc0001,0x8000c300,0x38e003fc,
02674 0x18f0003,0x6000,0x30c018f0,0x1c70000,0x0,0x18000300,0x1860071,0xc0018007,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02675 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xe1801fc0,0x618001ff,0x70000,0x30001800,0x21840000,0x0,0x0,0x380ffe,0x1fe00ff,
02676 0xfc0fff00,0x3e03ffc,0x1ff81ff,0xfc0ffe03,0xffc00000,0x0,0x0,0x7ff0,0x3ff803f,0x7ffc03,0xffc3ffc0,0x3fff07ff,0xe03ffc38,0x383ffe0,
02677 0xff81c07,0x81c000f8,0xf8f80e0,0x7ff81fff,0x81ffe0ff,0xf80fff87,0xfffc7007,0xe00e700,0x70e0387,0x80f0ffff,0xe001c0,0xe000,
02678 0xfe000000,0xe00000,0x700000,0x38,0x3c,0x1c,0x1c00,0x1c00700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x78000e,0x3c000,
02679 0x0,0x7ff0000,0x0,0xf100000,0x0,0x7,0xe000000,0x7ffc0000,0x1fffe00,0xffff0,0x0,0x0,0x0,0x0,0x0,0x3,0xf780180,0x0,0x0,0x1801e03c,
02680 0x1c,0xc000,0xffc00000,0x780f0038,0x786000,0x7f00,0x18380000,0x0,0xfe00,0x30c,0x10,0x70020e00,0x1c000000,0x7f8c000,0x0,0x6c001c38,
02681 0x60,0xc0000,0x70000700,0x1f8003f,0x7e000,0xfc001f80,0x3f000ff,0xf03ffc1f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ffc,
02682 0x7c0703f,0xfc07ff80,0xfff01ffe,0x3ffc000,0xffec7,0x70e00e,0x1c01c380,0x38780f07,0xf070,0xe00038,0x1c3800,0x0,0x3e00000,0x0,
02683 0xe0003800,0x1c380000,0xe0003,0x8001c380,0x3e0,0x3,0x8000e000,0x70e00000,0x0,0x0,0x1c000700,0x3870000,0x38007,0x0,0x0,0x0,
02684 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xe3807ff0,0xc0c003c1,0x70000,0x70001c00,
02685 0x718e0000,0x0,0x0,0x700f1e,0x1ce00c0,0x3c0c0f80,0x7e03800,0x3e08000,0x381e0f03,0xc1e00000,0x0,0x0,0x7078,0x783c03f,0x701e07,
02686 0xc1c383e0,0x38000700,0x7c1c38,0x3801c00,0x381c0f,0x1c000fc,0x1f8f80e0,0x78781c07,0x81e1e0e0,0x780f0180,0xe007007,0xe00e380,
02687 0xe0f0783,0x80e0000e,0xe000e0,0xe001,0xef000000,0x0,0x700000,0x38,0x38,0x1c,0x0,0x700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,
02688 0x0,0x0,0x0,0x70000e,0x1c000,0x0,0xf830000,0x0,0x1e000000,0x0,0x0,0x10000,0x780c0000,0x3e38000,0xe0,0x0,0x0,0x0,0x0,0x0,0x3,
02689 0xd580000,0x0,0x0,0xe038,0x1c,0xc000,0xf0400000,0x380e0038,0x702000,0x1ffc0,0xc0000,0x0,0x3ff80,0x606,0x0,0x30000600,0x0,
02690 0x7f8c000,0x0,0xc001818,0x60,0xc0003,0xe0000700,0x1f8003f,0x7e000,0xfc001f80,0x73801ee,0x7c1c1c,0x38000,0x70000e00,0xe0001,
02691 0xc0003800,0x700383e,0x7c0703c,0x3c078780,0xf0f01e1e,0x3c3c000,0xf0f87,0x70e00e,0x1c01c380,0x38380e07,0xe038,0x0,0x0,0x0,
02692 0x0,0x0,0x0,0x0,0x0,0x0,0xff0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02693 0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xc380fff0,0xc0c00380,0x70000,0x70001c00,0x3dbc0070,0x0,0x0,0x701e0f,0xe0000,0x1e000380,
02694 0x6e03800,0x7800000,0x781c0707,0x80e00000,0x0,0x0,0x4038,0xe00c03f,0x700e07,0x4380f0,0x38000700,0x700438,0x3801c00,0x381c0e,
02695 0x1c000ec,0x1b8fc0e0,0xf03c1c03,0xc3c0f0e0,0x3c1e0000,0xe007007,0xe00e380,0xe070703,0xc1e0001e,0xe000e0,0xe001,0xc7000000,
02696 0x0,0x700000,0x38,0x38,0x1c,0x0,0x700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x70000e,0x1c000,0x0,0xe010000,0x0,
02697 0x1c000000,0x10,0x20000,0x6c000,0xf0000000,0x3838000,0x1e0,0x0,0xf000f,0xf1e00,0x78f00000,0x0,0x3,0xdd80000,0x0,0x0,0xf078,
02698 0x0,0xc001,0xe0000000,0x1c1c0038,0x700000,0x3c1e0,0xc0000,0x0,0x783c0,0x606,0x0,0x30000e00,0x0,0xff8c000,0x0,0xc00300c,0x60,
02699 0xc0003,0xe0000000,0x1f8003f,0x7e000,0xfc001f80,0x73801ce,0x70041c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700380f,0x7e07078,
02700 0x1e0f03c1,0xe0783c0f,0x781e000,0x1c0787,0x70e00e,0x1c01c380,0x383c1e07,0xff00e038,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x878,
02701 0x0,0x0,0x0,0x7,0x80000080,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,
02702 0x1c7000,0xc301e630,0xc0c00380,0x70000,0xe0000e00,0xff00070,0x0,0x0,0xe01c07,0xe0000,0xe000380,0xce03800,0x7000000,0x701c0707,
02703 0x600000,0x0,0x4000010,0x38,0x1c00e07f,0x80700e0e,0x38070,0x38000700,0xe00038,0x3801c00,0x381c1c,0x1c000ec,0x1b8ec0e0,0xe01c1c01,
02704 0xc38070e0,0x1c1c0000,0xe007007,0x701c380,0xe078e01,0xc1c0003c,0xe00070,0xe003,0x83800000,0x7f,0x71f000,0x3e003e38,0x3f007ff,
02705 0xe01f1c1c,0x7801fc00,0x3fc00701,0xe01c0077,0x8f071e00,0xf801c7c,0x7c700e,0x3e01fc03,0xfff8380e,0xe007700,0x73c0787,0x387ffc,
02706 0x70000e,0x1c000,0x0,0xe000000,0x0,0x1c000000,0x10,0x20000,0xc2000,0xe0000000,0x3838000,0x3c0,0x0,0xf000f,0x78e00,0x70e00000,
02707 0x0,0x3,0xc980fe0,0x1f0,0xf8000007,0xffc07070,0x0,0x3f801,0xc0000000,0x1e3c0038,0x700000,0x70070,0x7fc0000,0x0,0xe00e0,0x606,
02708 0x1c0000,0x70007c00,0x380e,0xff8c000,0x0,0xc00300c,0x60,0xc0000,0x70000000,0x3fc007f,0x800ff001,0xfe003fc0,0x73801ce,0xe0001c,
02709 0x38000,0x70000e00,0xe0001,0xc0003800,0x7003807,0x7607070,0xe0e01c1,0xc0383807,0x700e000,0x1c0387,0x70e00e,0x1c01c380,0x381c1c07,
02710 0xffc0e0f8,0x3f8007f,0xfe001,0xfc003f80,0x7f007e3,0xe003e001,0xf8003f00,0x7e000fc,0xfe001f,0xc003f800,0x7f00003c,0x38f0007,
02711 0xc000f800,0x1f0003e0,0x7c0007,0x8003f0c3,0x80e0701c,0xe0381c0,0x70700387,0x1f01c00e,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02712 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c701f,0xfff1c600,0xc0c00380,0x70000,0xe0000e00,0x3c00070,0x0,0x0,0xe03c07,
02713 0x800e0000,0xe000380,0x1ce03800,0x7000000,0x701c0707,0x7003c0,0x780000,0x3c00001e,0x38,0x18006073,0x80700e0e,0x38070,0x38000700,
02714 0xe00038,0x3801c00,0x381c38,0x1c000ee,0x3b8ee0e1,0xe01e1c01,0xc78078e0,0x1c1c0000,0xe007007,0x701c387,0xe03de00,0xe3800038,
02715 0xe00070,0xe007,0x1c00000,0x1ff,0xc077f801,0xff807fb8,0xff807ff,0xe03fdc1d,0xfc01fc00,0x3fc00703,0xc01c007f,0xdf877f00,0x3fe01dfe,
02716 0xff700e,0xff07ff03,0xfff8380e,0x700f700,0x71e0f03,0x80707ffc,0x70000e,0x1c000,0x0,0x1c000008,0x0,0x1c000000,0x10,0x20000,
02717 0x82000,0xe0000000,0x7038000,0x80000380,0x2000040,0x7000e,0x38700,0xf1e00000,0x0,0x3,0xc183ff8,0x3fd,0xfc008007,0xffc038e0,
02718 0x0,0xffc01,0xc0008008,0xe380038,0x380000,0xe3e38,0x1ffc0040,0x80000000,0x1cfc70,0x606,0x1c0000,0xe0007c00,0x380e,0xff8c000,
02719 0x0,0xc00300c,0x8100060,0xc0000,0x30000700,0x39c0073,0x800e7001,0xce0039c0,0x73801ce,0xe0001c,0x38000,0x70000e00,0xe0001,
02720 0xc0003800,0x7003807,0x77070f0,0xf1e01e3,0xc03c7807,0x8f00f080,0x83c0787,0x70e00e,0x1c01c380,0x380e3807,0xffe0e1c0,0xffe01ff,
02721 0xc03ff807,0xff00ffe0,0x1ffc0ff7,0xf01ff807,0xfc00ff80,0x1ff003fe,0xfe001f,0xc003f800,0x7f0003fc,0x3bf801f,0xf003fe00,0x7fc00ff8,
02722 0x1ff0007,0x8007fd83,0x80e0701c,0xe0381c0,0x70380707,0x7f80e01c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02723 0x0,0x0,0x0,0x0,0x1c,0x1c701f,0xfff1c600,0x618081c0,0x70000,0xe0000e00,0x3c00070,0x0,0x0,0xe03803,0x800e0000,0xe000380,0x18e03800,
02724 0xf000000,0xf01c0707,0x7003c0,0x780000,0xfc00001f,0x80000078,0x301e6073,0x80700e1c,0x38038,0x38000700,0x1c00038,0x3801c00,
02725 0x381c70,0x1c000e6,0x338ee0e1,0xc00e1c01,0xc70038e0,0x1c1c0000,0xe007007,0x701c387,0xe01dc00,0xf7800078,0xe00070,0xe00e,0xe00000,
02726 0x3ff,0xe07ffc03,0xffc0fff8,0x1ffc07ff,0xe07ffc1d,0xfe01fc00,0x3fc00707,0x801c007f,0xdf877f80,0x7ff01fff,0x1fff00e,0xff07ff03,
02727 0xfff8380e,0x700e380,0xe0e0e03,0x80707ffc,0x70000e,0x1c000,0x0,0x7ffc001c,0x0,0x1c000000,0x10,0x20000,0x82000,0xe0000000,
02728 0x7038001,0xc0000780,0x70000e0,0x3800e,0x38700,0xe1c00000,0x0,0x3,0xc183ff8,0x7ff,0xfc01c007,0xffc03de0,0x0,0x1ffc01,0xc001c01c,
02729 0xf780038,0x3c0000,0xcff18,0x380c00c1,0x80000000,0x18fe30,0x30c,0x1c0001,0xc0000e00,0x380e,0xff8c000,0x0,0xc00300c,0xc180060,
02730 0xc0000,0x30000700,0x39c0073,0x800e7001,0xce0039c0,0xe1c038e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x877070e0,
02731 0x71c00e3,0x801c7003,0x8e0071c0,0x1c380fc7,0x70e00e,0x1c01c380,0x380f7807,0x1e0e380,0x1fff03ff,0xe07ffc0f,0xff81fff0,0x3ffe0fff,
02732 0xf03ffc0f,0xfe01ffc0,0x3ff807ff,0xfe001f,0xc003f800,0x7f0007fe,0x3bfc03f,0xf807ff00,0xffe01ffc,0x3ff8007,0x800fff83,0x80e0701c,
02733 0xe0381c0,0x70380707,0xffc0e01c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c701f,
02734 0xfff1c600,0x7f8381e0,0x70000,0xc0000600,0xff00070,0x0,0x0,0x1c03803,0x800e0000,0xe000f00,0x38e03fe0,0xe000000,0xe00e0e07,
02735 0x7003c0,0x780007,0xf0ffff87,0xf00000f0,0x307fe0f3,0xc0703c1c,0x38038,0x38000700,0x1c00038,0x3801c00,0x381ce0,0x1c000e6,0x338e70e1,
02736 0xc00e1c01,0xc70038e0,0x3c1e0000,0xe007007,0x783c38f,0x8e01fc00,0x770000f0,0xe00038,0xe01c,0x700000,0x381,0xe07c1e07,0xc0c1e0f8,
02737 0x3c1e0038,0xf07c1f,0xe001c00,0x1c0070f,0x1c0079,0xf3c7c380,0xf0781f07,0x83c1f00f,0xc10f0300,0x1c00380e,0x700e380,0xe0f1e03,
02738 0xc0f00078,0x70000e,0x1c000,0x0,0xfff8003e,0x0,0x3c000000,0x10,0x20000,0xc6000,0xf0000000,0x7038003,0xe0000f00,0xf8001f0,
02739 0x3801c,0x18300,0xe1800000,0x0,0x3,0xc187818,0x70f,0x9e03e000,0x7801dc0,0x1c,0x3cc401,0xc000efb8,0x7f7f0038,0x3f0000,0x1ce11c,
02740 0x300c01c3,0x80000000,0x38c638,0x3fc,0x1c0003,0x80000600,0x380e,0xff8c000,0x0,0xc00300c,0xe1c0060,0xc0010,0x70000700,0x79e00f3,
02741 0xc01e7803,0xcf0079e0,0xe1c038e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x873870e0,0x71c00e3,0x801c7003,
02742 0x8e0070e0,0x38381dc7,0x70e00e,0x1c01c380,0x38077007,0xf0e700,0x1c0f0381,0xe0703c0e,0x781c0f0,0x381e083e,0x787c0c1e,0xf03c1e0,
02743 0x783c0f07,0x800e0001,0xc0003800,0x7000fff,0x3e1c078,0x3c0f0781,0xe0f03c1e,0x783c000,0x1e0f03,0x80e0701c,0xe0381c0,0x70380f07,
02744 0xc1e0e03c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1,0x8701c600,0x1e0f01e0,0x1,
02745 0xc0000700,0x3dbc0070,0x0,0x0,0x1c03803,0x800e0000,0x1e01fe00,0x70e03ff8,0xe3e0001,0xe007fc07,0x80f003c0,0x78001f,0xc0ffff81,
02746 0xfc0001e0,0x30e1e0e1,0xc07ff81c,0x38038,0x3ffe07ff,0xc1c0003f,0xff801c00,0x381de0,0x1c000e7,0x738e70e1,0xc00e1c03,0xc70038e0,
02747 0x780f8000,0xe007007,0x383838d,0x8e00f800,0x7f0000e0,0xe00038,0xe000,0x0,0x200,0xf0780e07,0x8041c078,0x380e0038,0xe03c1e,
02748 0xf001c00,0x1c0071e,0x1c0070,0xe1c783c0,0xe0381e03,0x8380f00f,0xe0000,0x1c00380e,0x381c380,0xe07bc01,0xc0e00078,0x70000e,
02749 0x1c000,0x0,0x1c000061,0x0,0x38000000,0x10,0x20000,0x7c000,0x7c000000,0x703fc06,0x10000e00,0x18400308,0x1801c,0x1c381,0xc3800000,
02750 0x0,0x0,0x7000,0xe0f,0xe061000,0x7801fc0,0x1c,0x38c001,0xc0007ff0,0x7fff0038,0x77c000,0x19c00c,0x301c0387,0x0,0x30c618,0xf0,
02751 0x1c0007,0x600,0x380e,0x7f8c007,0x80000000,0xc001818,0x70e03fc,0x387f871f,0xe0e00700,0x70e00e1,0xc01c3803,0x870070e0,0xe1c038f,
02752 0xe1c0001f,0xff03ffe0,0x7ffc0fff,0x800e0001,0xc0003800,0x7003803,0x873870e0,0x71c00e3,0x801c7003,0x8e007070,0x703839c7,0x70e00e,
02753 0x1c01c380,0x3807f007,0x70e700,0x10078200,0xf0401e08,0x3c10078,0x200f001c,0x3878041c,0x70380e0,0x701c0e03,0x800e0001,0xc0003800,
02754 0x7001e0f,0x3c1e070,0x1c0e0381,0xc070380e,0x701c000,0x1c0f03,0x80e0701c,0xe0381c0,0x701c0e07,0x80e07038,0x0,0x0,0x0,0x0,0x0,
02755 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0x8600e600,0x7803f0,0x1,0xc0000700,0x718e0070,0x0,0x0,0x38038c3,
02756 0x800e0000,0x3c01f800,0x60e03ffc,0xeff8001,0xc001f003,0xc1f003c0,0x7800fe,0xffff80,0x3f8003c0,0x60c0e0e1,0xc07fe01c,0x38038,
02757 0x3ffe07ff,0xc1c07e3f,0xff801c00,0x381fe0,0x1c000e3,0x638e30e1,0xc00e1c07,0x870038ff,0xf00ff800,0xe007007,0x38381cd,0x9c007000,
02758 0x3e0001e0,0xe0001c,0xe000,0x0,0x0,0x70780f0f,0x3c078,0x70070038,0x1e03c1c,0x7001c00,0x1c0073c,0x1c0070,0xe1c701c1,0xe03c1e03,
02759 0xc780f00f,0xe0000,0x1c00380e,0x381c387,0xe03f801,0xc0e000f0,0x70000e,0x1c007,0xe0100000,0x1c0000cd,0x80000003,0xffc00000,
02760 0x3ff,0x807ff000,0xe0,0x7fc00060,0x703fc0c,0xd8001e00,0x3360066c,0x1c018,0xc181,0x83000000,0x0,0x0,0x7000,0x300e07,0xe0cd800,
02761 0xf000f80,0x1c,0x78c00f,0xff0038e0,0x3e00038,0xe1e000,0x19800c,0x383c070e,0x7fffc00,0x30fc18,0x0,0xffff80e,0x20e00,0x380e,
02762 0x7f8c007,0x80000000,0xc001c38,0x38703ff,0xf87fff0f,0xcfe00f00,0x70e00e1,0xc01c3803,0x870070e0,0x1e1e078f,0xe1c0001f,0xff03ffe0,
02763 0x7ffc0fff,0x800e0001,0xc0003800,0x700ff83,0x871870e0,0x71c00e3,0x801c7003,0x8e007038,0xe03871c7,0x70e00e,0x1c01c380,0x3803e007,
02764 0x70e700,0x38000,0x70000e00,0x1c00038,0x7001c,0x38f00038,0x3870070,0xe00e1c01,0xc00e0001,0xc0003800,0x7001c07,0x380e0f0,0x1e1e03c3,
02765 0xc078780f,0xf01e000,0x3c0f03,0x80e0701c,0xe0381c0,0x701c0e07,0x80f07038,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02766 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0x8600ff00,0x1e00778,0x38000001,0xc0000700,0x21843fff,0xe0000000,0x0,0x38039e3,0x800e0000,
02767 0x7c01fe00,0xe0e0203e,0xeffc001,0xc00ffe03,0xff700000,0x7f0,0x0,0x7f00380,0x618060e1,0xc07ffc1c,0x38038,0x3ffe07ff,0xc1c07e3f,
02768 0xff801c00,0x381ff0,0x1c000e3,0x638e38e1,0xc00e1fff,0x870038ff,0xc003fe00,0xe007007,0x38381cd,0x9c00f800,0x3e0003c0,0xe0001c,
02769 0xe000,0x0,0x0,0x7070070e,0x38038,0x70070038,0x1c01c1c,0x7001c00,0x1c00778,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0xfc000,
02770 0x1c00380e,0x381c3c7,0x1e01f001,0xe1e001e0,0xf0000e,0x1e01f,0xf8300000,0x1c00019c,0xc0000003,0xffc00000,0x10,0x20000,0x700,
02771 0x1ff000c0,0x703fc19,0xcc003c00,0x67300ce6,0xc038,0xc181,0x83000000,0x0,0x0,0x7e00,0x180e07,0xe19cc00,0x1e000f80,0x1c,0x70c00f,
02772 0xff007070,0x3e00038,0xe0f000,0x19800c,0x1fec0e1c,0x7fffc00,0x30f818,0x0,0xffff81f,0xf003fc00,0x380e,0x3f8c007,0x80000000,
02773 0x7f800ff0,0x1c3803f,0xe007fc00,0xff800e00,0x70e00e1,0xc01c3803,0x870070e0,0x1c0e070f,0xe1c0001f,0xff03ffe0,0x7ffc0fff,0x800e0001,
02774 0xc0003800,0x700ff83,0x871c70e0,0x71c00e3,0x801c7003,0x8e00701d,0xc038e1c7,0x70e00e,0x1c01c380,0x3803e007,0x70e3c0,0x38000,
02775 0x70000e00,0x1c00038,0x7001c,0x38e00038,0x3870070,0xe00e1c01,0xc00e0001,0xc0003800,0x7003c07,0x8380e0e0,0xe1c01c3,0x80387007,
02776 0xe00e1ff,0xfe381b83,0x80e0701c,0xe0381c0,0x701e1e07,0x707878,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02777 0x0,0x0,0x0,0x0,0x1c,0x3,0xe007fe0,0x7800e3c,0x38000001,0xc0000700,0x1803fff,0xe0000000,0x0,0x70039c3,0x800e0000,0xf8000f80,
02778 0xc0e0000e,0xf83c003,0xc01e0f01,0xff700000,0x7c0,0x0,0x1f00780,0x618061c0,0xe0701e1c,0x38038,0x38000700,0x1c07e38,0x3801c00,
02779 0x381e78,0x1c000e3,0xe38e18e1,0xc00e1fff,0x70038ff,0xe0007f80,0xe007007,0x1c701dd,0x9c00f800,0x1c000780,0xe0000e,0xe000,0x0,
02780 0x7f,0xf070070e,0x38038,0x7fff0038,0x1c01c1c,0x7001c00,0x1c007f8,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x7fc00,0x1c00380e,
02781 0x1c381c7,0x1c01f000,0xe1c001c0,0xfe0000e,0xfe1f,0xfff00000,0x7ff003fc,0xe0000003,0xffc00000,0x10,0x20000,0x3800,0x3fc0180,
02782 0x703803f,0xce007800,0xff381fe7,0x30,0x0,0xc0,0x0,0x0,0x3fe0,0xc0e07,0xfe3fce00,0x1c000700,0x1c,0x70c00f,0xff006030,0x1c00000,
02783 0xe07800,0x19800c,0xfcc1c38,0x7fffc00,0x30d818,0x0,0xffff81f,0xf001f800,0x380e,0xf8c007,0x80000000,0x7f8007e0,0xe1c3fe,0x7fc00f,
02784 0xf8001e00,0xe0701c0,0xe0381c07,0x380e070,0x1c0e070e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700ff83,0x870c70e0,
02785 0x71c00e3,0x801c7003,0x8e00700f,0x8038c1c7,0x70e00e,0x1c01c380,0x3801c007,0xf0e3e0,0x3ff807f,0xf00ffe01,0xffc03ff8,0x7ff03ff,
02786 0xf8e0003f,0xff87fff0,0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e1ff,0xfe383383,0x80e0701c,
02787 0xe0381c0,0x700e1c07,0x703870,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0xc000ff0,
02788 0x3c1e1c1c,0x38000001,0xc0000700,0x1803fff,0xe0000007,0xf8000000,0x7003803,0x800e0001,0xf0000381,0xc0e00007,0xf01e003,0x801c0700,
02789 0x7c700000,0x7c0,0x0,0x1f00700,0x618061c0,0xe0700e1c,0x38038,0x38000700,0x1c00e38,0x3801c00,0x381e38,0x1c000e1,0xc38e1ce1,
02790 0xc00e1ffc,0x70038e0,0xf0000780,0xe007007,0x1c701dd,0xdc01fc00,0x1c000780,0xe0000e,0xe000,0x0,0x1ff,0xf070070e,0x38038,0x7fff0038,
02791 0x1c01c1c,0x7001c00,0x1c007f8,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x3ff00,0x1c00380e,0x1c381cd,0x9c00e000,0xe1c003c0,
02792 0xf80000e,0x3e18,0x3ff00000,0xffe007fd,0xf0000000,0x38000000,0x10,0x20000,0x1c000,0x3c0300,0x703807f,0xdf007801,0xff7c3fef,
02793 0x80000000,0x0,0x3e0,0x7ffe7ff,0xff000000,0x1ff8,0x60e07,0xfe7fdf00,0x3c000700,0x1c,0x70c001,0xc0006030,0x7fff0000,0xf03800,
02794 0x19800c,0x1c38,0x1c07,0xf830cc18,0x0,0x1c0000,0x0,0x380e,0x18c007,0x80000000,0x0,0xe1cfe0,0x1fc003f,0x80003c00,0xe0701c0,
02795 0xe0381c07,0x380e070,0x1c0e070e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x870e70e0,0x71c00e3,0x801c7003,
02796 0x8e007007,0x3981c7,0x70e00e,0x1c01c380,0x3801c007,0x1e0e0f8,0xfff81ff,0xf03ffe07,0xffc0fff8,0x1fff07ff,0xf8e0003f,0xff87fff0,
02797 0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e1ff,0xfe386383,0x80e0701c,0xe0381c0,0x700e1c07,
02798 0x703870,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x7f,0xffc00678,0x707f9c1e,0x38000001,
02799 0xc0000700,0x70,0x7,0xf8000000,0xe003803,0x800e0003,0xe00001c3,0x80e00007,0xe00e007,0x80380380,0x700000,0x7f0,0x0,0x7f00700,
02800 0x618061ff,0xe070071c,0x38038,0x38000700,0x1c00e38,0x3801c00,0x381c3c,0x1c000e1,0xc38e1ce1,0xc00e1c00,0x70038e0,0x700003c0,
02801 0xe007007,0x1c701d8,0xdc03dc00,0x1c000f00,0xe00007,0xe000,0x0,0x3ff,0xf070070e,0x38038,0x7fff0038,0x1c01c1c,0x7001c00,0x1c007fc,
02802 0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x3f00,0x1c00380e,0x1c381cd,0x9c01f000,0x73800780,0xfe0000e,0xfe10,0x7c00000,0x1c000ffb,
02803 0xf8000000,0x38000000,0x10,0x20000,0x20000,0x1e0700,0x70380ff,0xbf80f003,0xfefe7fdf,0xc0000000,0x0,0x3f0,0x7ffe7ff,0xff000000,
02804 0x1f8,0x30e07,0xfeffbf80,0x78000700,0x1c,0x70c001,0xc0006030,0x7fff0000,0x783800,0x1ce11c,0xe1c,0x1c07,0xf838ce38,0x0,0x1c0000,
02805 0x0,0x380e,0x18c000,0x0,0x0,0x1c38c00,0x1800030,0x7800,0xfff01ff,0xe03ffc07,0xff80fff0,0x3fff0ffe,0x1c0001c,0x38000,0x70000e00,
02806 0xe0001,0xc0003800,0x7003803,0x870e70e0,0x71c00e3,0x801c7003,0x8e00700f,0x803b81c7,0x70e00e,0x1c01c380,0x3801c007,0xffe0e03c,
02807 0x1fff83ff,0xf07ffe0f,0xffc1fff8,0x3fff0fff,0xf8e0003f,0xff87fff0,0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,
02808 0x80387007,0xe00e000,0x38c383,0x80e0701c,0xe0381c0,0x70073807,0x701ce0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02809 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f,0xffc0063c,0x40619c0f,0x30000001,0xc0000700,0x70,0x7,0xf8000000,0xe003803,0x800e0007,0xc00001c3,
02810 0xfffc0007,0xe00e007,0x380380,0xf00000,0xfe,0xffff80,0x3f800700,0x618063ff,0xf070071c,0x38038,0x38000700,0x1c00e38,0x3801c00,
02811 0x381c1e,0x1c000e0,0x38e0ee1,0xc00e1c00,0x70038e0,0x380001c0,0xe007007,0x1ef01d8,0xdc038e00,0x1c001e00,0xe00007,0xe000,0x0,
02812 0x7c0,0x7070070e,0x38038,0x70000038,0x1c01c1c,0x7001c00,0x1c0079e,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x780,0x1c00380e,
02813 0xe701cd,0x9c01f000,0x73800f00,0xe0000e,0xe000,0x0,0x1c0007f7,0xf0000000,0x70000000,0x10,0x20000,0x0,0xe0e00,0x703807f,0x7f01e001,
02814 0xfdfc3fbf,0x80000000,0x0,0x7f0,0x0,0x0,0x3c,0x18e07,0x7f7f00,0xf0000700,0x1c,0x70c001,0xc0007070,0x1c00000,0x3e7000,0xcff18,
02815 0x3ffc070e,0x1c07,0xf818c630,0x0,0x1c0000,0x0,0x380e,0x18c000,0x0,0x3ffc,0x3870000,0xe000fc00,0x380f000,0x1fff83ff,0xf07ffe0f,
02816 0xffc1fff8,0x3fff0ffe,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x870770e0,0x71c00e3,0x801c7003,0x8e00701d,
02817 0xc03f01c7,0x70e00e,0x1c01c380,0x3801c007,0xffc0e01c,0x3e0387c0,0x70f80e1f,0x1c3e038,0x7c071e1c,0xe00038,0x70000,0xe0001c00,
02818 0xe0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e000,0x398383,0x80e0701c,0xe0381c0,0x70073807,0x701ce0,
02819 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f,0xffc0061c,0xc0dc07,0xf0000001,0xc0000700,
02820 0x70,0x0,0x0,0x1c003c07,0x800e000f,0x1c3,0xfffc0007,0xe00e007,0x380380,0xe00000,0x1f,0xc0ffff81,0xfc000700,0x618063ff,0xf070070e,
02821 0x38070,0x38000700,0xe00e38,0x3801c00,0x381c0e,0x1c000e0,0x38e0ee1,0xe01e1c00,0x78078e0,0x380001c0,0xe007007,0xee01f8,0xfc078f00,
02822 0x1c001c00,0xe00003,0x8000e000,0x0,0x700,0x7070070e,0x38038,0x70000038,0x1c01c1c,0x7001c00,0x1c0070e,0x1c0070,0xe1c701c1,
02823 0xc01c1c01,0xc700700e,0x380,0x1c00380e,0xe700ed,0xb803f800,0x77800f00,0x70000e,0x1c000,0x0,0xe0003f7,0xe0000000,0x70000000,
02824 0x10,0x20000,0x1c0e0,0xe1c00,0x703803f,0x7e01c000,0xfdf81fbf,0x0,0x0,0x3f0,0x0,0x0,0x1c,0x1ce07,0x3f7e00,0xf0000700,0x1c,
02825 0x70c001,0xc00038e0,0x1c00038,0xf7000,0xe3e38,0x3ffc0387,0x1c00,0x1cc770,0x0,0x1c0000,0x0,0x380e,0x18c000,0x0,0x3ffc,0x70e0001,
02826 0xe001fe00,0x780e000,0x1fff83ff,0xf07ffe0f,0xffc1fff8,0x3fff0ffe,0xe0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003807,
02827 0x70770f0,0xf1e01e3,0xc03c7807,0x8f00f038,0xe03e03c7,0x70e00e,0x1c01c380,0x3801c007,0xff00e00e,0x38038700,0x70e00e1c,0x1c38038,
02828 0x70071c1c,0xe00038,0x70000,0xe0001c00,0xe0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e000,0x3b0383,0x80e0701c,
02829 0xe0381c0,0x70077807,0x701de0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1c00061c,
02830 0xc0de03,0xe0000001,0xc0000700,0x70,0x0,0x0,0x1c001c07,0xe001e,0x1c3,0xfffc0007,0x600e00e,0x380380,0xe00000,0x7,0xf0ffff87,
02831 0xf0000000,0x60c0e380,0x7070070e,0x38070,0x38000700,0xe00e38,0x3801c00,0x381c0f,0x1c000e0,0x38e06e0,0xe01c1c00,0x38070e0,
02832 0x1c0001c0,0xe007007,0xee00f8,0xf80f0700,0x1c003c00,0xe00003,0x8000e000,0x0,0x700,0x70780f0f,0x3c078,0x70000038,0x1e03c1c,
02833 0x7001c00,0x1c0070f,0x1c0070,0xe1c701c1,0xe03c1e03,0xc780f00e,0x380,0x1c00380e,0xe700f8,0xf807bc00,0x3f001e00,0x70000e,0x1c000,
02834 0x0,0xe0001ff,0xc0000000,0x70000000,0x10,0x20000,0x33110,0xe0e00,0x383801f,0xfc03c000,0x7ff00ffe,0x0,0x0,0x3e0,0x0,0x0,0x1c,
02835 0x38e07,0x1ffc01,0xe0000700,0x1c,0x78c001,0xc0007ff0,0x1c00038,0x7c000,0x70070,0x1c3,0x80001c00,0xe00e0,0x0,0x1c0000,0x0,
02836 0x380e,0x18c000,0x0,0x0,0xe1c0001,0xe0010700,0x780e000,0x1c038380,0x70700e0e,0x1c1c038,0x78070e0e,0xe0001c,0x38000,0x70000e00,
02837 0xe0001,0xc0003800,0x7003807,0x7037070,0xe0e01c1,0xc0383807,0x700e070,0x701c0387,0x70e00e,0x1c01c380,0x3801c007,0xe00e,0x38038700,
02838 0x70e00e1c,0x1c38038,0x70071c1c,0xf00038,0x70000,0xe0001c00,0xe0001,0xc0003800,0x7003c07,0x8380e0f0,0x1e1e03c3,0xc078780f,
02839 0xf01e007,0x803e0783,0x80e0701c,0xe0381c0,0x7003f007,0x80f00fc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02840 0x0,0x0,0x0,0x0,0x0,0x6,0x1800061c,0xc0de01,0xc0000000,0xc0000e00,0x70,0xf0000,0x3c00,0x38001c0f,0xe003c,0x3c0,0xe0000e,0x701e00e,
02841 0x3c0780,0x1e003c0,0x780000,0xfc00001f,0x80000000,0x60e1e780,0x78700f07,0x4380f0,0x38000700,0xf00e38,0x3801c00,0xc0781c07,
02842 0x81c000e0,0x38e07e0,0xe03c1c00,0x380f0e0,0x1e0003c0,0xe00780f,0xee00f0,0x780e0780,0x1c007800,0xe00001,0xc000e000,0x0,0x700,
02843 0xf0780e07,0x8041c078,0x38020038,0xe03c1c,0x7001c00,0x1c00707,0x801c0070,0xe1c701c0,0xe0381e03,0x8380f00e,0x80380,0x1c003c1e,
02844 0x7e00f8,0xf80f1e00,0x3f003c00,0x70000e,0x1c000,0x0,0xf0100f7,0x80078000,0x700078f0,0x10,0x7ff000,0x61208,0x1e0700,0x383800f,
02845 0x78078000,0x3de007bc,0x0,0x0,0x0,0x0,0x0,0x401c,0x70e0f,0xf7803,0xc0000700,0x1c,0x38c001,0xc000efb8,0x1c00038,0x1e000,0x3c1e0,
02846 0xc1,0x80000000,0x783c0,0x0,0x0,0x0,0x3c1e,0x18c000,0x0,0x0,0xc180003,0x60000300,0xd80e010,0x3c03c780,0x78f00f1e,0x1e3c03c,
02847 0x70039c0e,0x70041c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700380f,0x703f070,0x1e0e03c1,0xc078380f,0x701e0e0,0x381c0787,
02848 0x80f0f01e,0x1e03c3c0,0x7801c007,0xe00e,0x38078700,0xf0e01e1c,0x3c38078,0x700f1c1c,0x78041c,0x1038020,0x70040e00,0x800e0001,
02849 0xc0003800,0x7001c07,0x380e070,0x1c0e0381,0xc070380e,0x701c007,0x801e0703,0xc1e0783c,0xf0781e0,0xf003f007,0x80e00fc0,0x0,
02850 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xe,0x1801867c,0xc0cf83,0xe0000000,0xe0000e00,
02851 0x70,0xf0000,0x3c00,0x38000f1e,0xe0070,0x180780,0xe0603e,0x783c01e,0x1e0f01,0x7c003c0,0x780000,0x3c00001e,0x700,0x307fe700,
02852 0x38701e07,0xc1c383e0,0x38000700,0x7c1e38,0x3801c00,0xe0f01c03,0x81c000e0,0x38e03e0,0x78781c00,0x1e1e0e0,0xe180780,0xe003c1e,
02853 0x7c00f0,0x781e03c0,0x1c007000,0xe00001,0xc000e000,0x0,0x783,0xf07c1e07,0xc0c1e0f8,0x3e0e0038,0xf07c1c,0x7001c00,0x1c00703,
02854 0xc01e0070,0xe1c701c0,0xf0781f07,0x83c1f00e,0xe0f80,0x1e003c3e,0x7e00f8,0xf80e0e00,0x3f003800,0x70000e,0x1c000,0x0,0x7830077,
02855 0xf0000,0x700078f0,0x10,0x20000,0x41208,0xc03c0380,0x3c38007,0x70070000,0x1dc003b8,0x0,0x0,0x0,0x0,0x0,0x707c,0x6070f,0x86077003,
02856 0x80000700,0x1c,0x3ec401,0xc001c01c,0x1c00038,0xf000,0x1ffc0,0x40,0x80000000,0x3ff80,0x0,0x0,0x0,0x3e3e,0x18c000,0x0,0x0,
02857 0x8100006,0x60000300,0x1980f070,0x3801c700,0x38e0071c,0xe3801c,0x70039c0e,0x7c1c1c,0x38000,0x70000e00,0xe0001,0xc0003800,
02858 0x700383e,0x701f03c,0x3c078780,0xf0f01e1e,0x3c3c1c0,0x1c3f0f03,0xc1e0783c,0xf0781e0,0xf001c007,0xe81e,0x3c1f8783,0xf0f07e1e,
02859 0xfc3c1f8,0x783f1e3e,0x187c0c1f,0x703e0e0,0x7c1c0f83,0x800e0001,0xc0003800,0x7001e0f,0x380e078,0x3c0f0781,0xe0f03c1e,0x783c007,
02860 0x801e0f03,0xc3e0787c,0xf0f81e1,0xf003f007,0xc1e00fc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02861 0x0,0x0,0x1c,0xe,0x3801fff8,0x6187ff,0xe0000000,0xe0000e00,0x70,0xf0000,0x3c00,0x38000ffe,0x1fff0ff,0xfe1fff80,0xe07ffc,0x3ffc01c,
02862 0x1fff01,0xff8003c0,0x780000,0x4000010,0x700,0x301e6700,0x387ffe03,0xffc3ffc0,0x3fff0700,0x3ffe38,0x383ffe0,0xfff01c03,0xc1fff8e0,
02863 0x38e03e0,0x7ff81c00,0x1ffe0e0,0xf1fff80,0xe003ffe,0x7c00f0,0x781c01c0,0x1c00ffff,0xe00001,0xc000e000,0x0,0x3ff,0x707ffc03,
02864 0xffc0fff8,0x1ffe0038,0x7ffc1c,0x707fff0,0x1c00701,0xc00ff070,0xe1c701c0,0x7ff01fff,0x1fff00e,0xfff00,0xff81fee,0x7e00f0,
02865 0x781e0f00,0x1e007ffc,0x70000e,0x1c000,0x0,0x3ff003e,0xf0000,0xe00070e0,0x60830010,0x20000,0x41208,0xfffc01c0,0x1fffe03,0xe00ffff0,
02866 0xf8001f0,0x0,0x0,0x0,0x0,0x0,0x7ff8,0xc07fd,0xfe03e007,0xffc00700,0x1c,0x1ffc1f,0xffc08008,0x1c00038,0x7000,0x7f00,0x0,0x0,
02867 0xfe00,0x0,0xffff800,0x0,0x3ff7,0x8018c000,0x0,0x0,0x6,0x60000700,0x19807ff0,0x3801c700,0x38e0071c,0xe3801c,0x70039c0f,0xf03ffc1f,
02868 0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ffc,0x701f03f,0xfc07ff80,0xfff01ffe,0x3ffc080,0x83fff03,0xffe07ffc,0xfff81ff,
02869 0xf001c007,0xeffc,0x1ffb83ff,0x707fee0f,0xfdc1ffb8,0x3ff70ff7,0xf83ffc0f,0xff01ffe0,0x3ffc07ff,0x83fff87f,0xff0fffe1,0xfffc0ffe,
02870 0x380e03f,0xf807ff00,0xffe01ffc,0x3ff8007,0x803ffe01,0xfee03fdc,0x7fb80ff,0x7001e007,0xffc00780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02871 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xc,0x3801fff0,0x7f83fe,0x70000000,0xe0000e00,0x0,0xf0000,0x3c00,0x700007fc,
02872 0x1fff0ff,0xfe1ffe00,0xe07ff8,0x1ff801c,0xffe01,0xff0003c0,0x780000,0x0,0x700,0x38000f00,0x3c7ffc01,0xff83ff80,0x3fff0700,
02873 0x1ffc38,0x383ffe0,0x7fe01c01,0xe1fff8e0,0x38e03e0,0x3ff01c00,0xffc0e0,0x71fff00,0xe001ffc,0x7c00f0,0x783c01e0,0x1c00ffff,
02874 0xe00000,0xe000e000,0x0,0x1ff,0x7077f801,0xff807fb8,0xffc0038,0x3fdc1c,0x707fff0,0x1c00701,0xe007f070,0xe1c701c0,0x3fe01dfe,
02875 0xff700e,0x7fe00,0xff80fee,0x3c0070,0x703c0780,0x1e007ffc,0x70000e,0x1c000,0x0,0x1fe001c,0xe0000,0xe000e1c0,0x71c78010,0x20000,
02876 0x21318,0xfff800c0,0xfffe01,0xc00ffff0,0x70000e0,0x0,0x0,0x0,0x0,0x0,0x3ff0,0x1803fd,0xfe01c007,0xffc00700,0x1c,0xffc1f,0xffc00000,
02877 0x1c00038,0x7000,0x0,0x0,0x0,0x0,0x0,0xffff800,0x0,0x3ff7,0x8018c000,0x0,0x0,0xc,0x60000e00,0x31803fe0,0x7801ef00,0x3de007bc,
02878 0xf7801e,0xf003fc0f,0xf01ff81f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ff8,0x701f01f,0xf803ff00,0x7fe00ffc,0x1ff8000,
02879 0x67fe01,0xffc03ff8,0x7ff00ff,0xe001c007,0xeff8,0xffb81ff,0x703fee07,0xfdc0ffb8,0x1ff70ff7,0xf81ff807,0xfe00ffc0,0x1ff803ff,
02880 0x3fff87f,0xff0fffe1,0xfffc07fc,0x380e01f,0xf003fe00,0x7fc00ff8,0x1ff0000,0x37fc00,0xfee01fdc,0x3fb807f,0x7001e007,0x7f800780,
02881 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xc,0x30007fc0,0x1e00f8,0x78000000,0x70001c00,
02882 0x0,0xe0000,0x3c00,0x700001f0,0x1fff0ff,0xfe07f800,0xe01fe0,0x7e0038,0x3f800,0xfc0003c0,0x700000,0x0,0x700,0x18000e00,0x1c7ff000,
02883 0x7e03fe00,0x3fff0700,0x7f038,0x383ffe0,0x1f801c00,0xf1fff8e0,0x38e01e0,0xfc01c00,0x3f80e0,0x787fc00,0xe0007f0,0x7c00f0,0x387800f0,
02884 0x1c00ffff,0xe00000,0xe000e000,0x0,0xfc,0x7071f000,0x3f003e38,0x3f00038,0x1f1c1c,0x707fff0,0x1c00700,0xf003f070,0xe1c701c0,
02885 0x1f801c7c,0x7c700e,0x1f800,0x3f8078e,0x3c0070,0x707803c0,0x1c007ffc,0x70000e,0x1c000,0x0,0x7c0008,0x1e0000,0xe000e1c0,0x71c30010,
02886 0x20000,0x1e1f0,0x3fe00020,0x3ffe00,0x800ffff0,0x2000040,0x0,0x0,0x0,0x0,0x0,0xfc0,0x3001f0,0x78008007,0xffc00700,0x1c,0x3f81f,
02887 0xffc00000,0x1c00038,0x407000,0x0,0x0,0x0,0x0,0x0,0xffff800,0x0,0x39c7,0x18c000,0x0,0x0,0x18,0x60001c00,0x61801f80,0x7000ee00,
02888 0x1dc003b8,0x77000e,0xe001f80f,0xf007e01f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83fc0,0x700f007,0xe000fc00,0x1f8003f0,
02889 0x7e0000,0xe1f800,0x7f000fe0,0x1fc003f,0x8001c007,0xe7f0,0x7e380fc,0x701f8e03,0xf1c07e38,0xfc703c1,0xe003f001,0xf8003f00,
02890 0x7e000fc,0x3fff87f,0xff0fffe1,0xfffc03f8,0x380e00f,0xc001f800,0x3f0007e0,0xfc0000,0x61f800,0x78e00f1c,0x1e3803c,0x7001c007,
02891 0x1f000700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x70001c00,0x0,
02892 0x1c0000,0x0,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,
02893 0x0,0x0,0x0,0x0,0xe00000,0x7000e000,0x0,0x0,0x0,0x0,0x0,0x1c00,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x1c000000,
02894 0x70000e,0x1c000,0x0,0x0,0x1c0000,0xe000c180,0x10,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,
02895 0x0,0x38,0x70e000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x2000,0x0,0x1f,0xf8003800,0x7fe00000,0x0,0x0,0x0,0x0,0x4000,
02896 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,
02897 0x0,0x0,0x1c007,0x700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x30001800,
02898 0x0,0x1c0000,0x0,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0xe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e000,
02899 0x0,0x0,0x0,0x0,0x0,0xe00000,0x7000e000,0x0,0x0,0x0,0x0,0x0,0x1c00,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x1c000000,
02900 0x70000e,0x1c000,0x0,0x0,0x1c0001,0xe001c380,0x10,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,
02901 0x0,0x38,0x7fe000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x3000,0x0,0x1f,0xf8007000,0x7fe00000,0x0,0x0,0x0,0x0,0x6000,
02902 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02903 0x0,0x1c007,0x700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x38003800,
02904 0x0,0x380000,0x1,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00000,0x0,0x0,0x3c18000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf000,
02905 0x0,0x0,0x0,0x0,0x0,0xfe0000,0x380fe000,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x38000000,
02906 0x78000e,0x3c000,0x0,0x0,0x180001,0xc0018300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,
02907 0x38,0x1f8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x1800,0x0,0x0,0x6000e000,0x1800000,0x0,0x0,0x0,0x0,0x3000,0x0,
02908 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02909 0x38007,0xe00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x18003000,
02910 0x0,0x300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x1ff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,
02911 0x0,0x0,0x0,0xfe0000,0xfe000,0x0,0x0,0x0,0x0,0x0,0x607800,0x0,0x3c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x78000000,
02912 0x3f800e,0x3f8000,0x0,0x0,0x300043,0xc0018200,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,
02913 0x0,0x38,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x11800,0x0,0x0,0x6001ff00,0x1800000,0x0,0x0,0x0,0x0,0x23000,0x0,0x0,
02914 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x23000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78007,
02915 0x1e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x1c007000,0x0,0x0,
02916 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe0000,
02917 0xfe000,0x0,0x0,0x0,0x0,0x0,0x7ff000,0x0,0x7f800000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xf8000000,0x3f800e,0x3f8000,0x0,
02918 0x0,0x10007f,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x38,0x0,0x0,0x0,0x0,
02919 0x0,0x0,0x0,0x0,0x3800,0x0,0x1f800,0x0,0x0,0x6001ff00,0x1800000,0x0,0x0,0x0,0x0,0x3f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02920 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f8007,0xfe00,0x0,0x0,0x0,0x0,
02921 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02922 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fff8,0x0,0x0,0x0,0x0,0x7fe000,0x0,
02923 0x7f000000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xf0000000,0xf800e,0x3e0000,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02924 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x1f000,0x0,0x0,0x0,0x0,0x0,
02925 0x0,0x0,0x0,0x3e000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e000,0x0,0x0,0x0,0x0,0x0,0x0,
02926 0x0,0x0,0x0,0x0,0x0,0x0,0x3f0007,0xfc00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02927 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02928 0x0,0x0,0x0,0x0,0x7fff8,0x0,0x0,0x0,0x0,0x1fc000,0x0,0x7e000000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xc0000000,0xe,0x0,
02929 0x0,0x0,0x3e,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02930 0x0,0x0,0x3800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02931 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c0007,0xf000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02932 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02933 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02934 0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02935 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02936 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
02937
02938
02939 const unsigned int font29x57[29*57*256/32] = {
02940 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02941 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02942 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02943 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02944 0x0,0x781e00,0x0,0x0,0x7,0x81e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02945 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c0000,0xf8000,0x7e00000,0x0,0x7,
02946 0xc0000000,0x0,0x7c00,0xf80,0x7e000,0x0,0x7c00000,0xf80000,0x7e000000,0x0,0x0,0x1f00,0x3e0,0x1f800,0x0,0x0,0x0,0x3,0xe0000000,
02947 0x7c00003f,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02948 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02949 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02950 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02951 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02952 0x0,0x0,0x0,0x0,0x0,0x0,0x3c3c00,0x0,0x0,0x3,0xc3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,
02953 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0000,
02954 0x1f0000,0x7e00000,0xf838001f,0xf80001f,0xf0000000,0x0,0x3e00,0x1f00,0x7e000,0x3e1f000,0x3e00000,0x1f00000,0x7e00003e,0x1f000000,
02955 0x3e0,0xe0000f80,0x7c0,0x1f800,0x3e0e00,0x7c3e000,0x0,0x1,0xf0000000,0xf800003f,0x1f0f,0x800001f0,0x0,0x0,0x0,0x0,0x0,0x0,
02956 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02957 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02958 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02959 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02960 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e7800,0x0,0x0,
02961 0x1,0xe7800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02962 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0000,0x1e0000,0xff00001,0xfe38001f,0xf80003f,
02963 0xf8000000,0x0,0x1e00,0x1e00,0xff000,0x3e1f000,0x1e00000,0x1e00000,0xff00003e,0x1f000000,0x7f8,0xe0000780,0x780,0x3fc00,0x7f8e00,
02964 0x7c3e000,0x0,0x0,0xf0000000,0xf000007f,0x80001f0f,0x800001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02965 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02966 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02967 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02968 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02969 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xef000,0x0,0x0,0x0,0xef000000,0x0,0x0,0x0,0x0,0x0,0x0,
02970 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02971 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000,0x3c0000,0x1e780003,0xfff8001f,0xf80003c,0x78000000,0x0,0xf00,0x3c00,0x1e7800,
02972 0x3e1f000,0xf00000,0x3c00001,0xe780003e,0x1f000000,0xfff,0xe00003c0,0xf00,0x79e00,0xfffe00,0x7c3e000,0x0,0x0,0x78000001,0xe00000f3,
02973 0xc0001f0f,0x800003c0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02974 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02975 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02976 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02977 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02978 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7e000,0x0,0x0,0x0,0x7e000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02979 0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02980 0x0,0x78000,0x780000,0x3c3c0003,0x8ff0001f,0xf800078,0x3c000000,0x0,0x780,0x7800,0x3c3c00,0x3e1f000,0x780000,0x7800003,0xc3c0003e,
02981 0x1f000000,0xe3f,0xc00001e0,0x1e00,0xf0f00,0xe3fc00,0x7c3e000,0x0,0x0,0x3c000003,0xc00001e1,0xe0001f0f,0x80000780,0x0,0x0,
02982 0x0,0x0,0x0,0x0,0x1f,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02983 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02984 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02985 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02986 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02987 0x0,0x7e000,0x0,0x0,0x0,0x7e000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,
02988 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc00,0x7e000,0xfe000,0x0,0x3c000,0xf00000,0x781e0003,
02989 0x83e0001f,0xf800070,0x1c000000,0x0,0x3c0,0xf000,0x781e00,0x3e1f000,0x3c0000,0xf000007,0x81e0003e,0x1f000000,0xe0f,0x800000f0,
02990 0x3c00,0x1e0780,0xe0f800,0x7c3e000,0x0,0x0,0x1e000007,0x800003c0,0xf0001f0f,0x80000f00,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf8000000,
02991 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02992 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02993 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02994 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02995 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02996 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02997 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3fc00,0x1fe000,0x3ff800,0x0,0x0,0x0,0x0,0x0,0x70,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02998 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x78000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02999 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03000 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03001 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03002 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03003 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03004 0x0,0x0,0x78,0xf000000,0x0,0x0,0x780f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c0,
03005 0x0,0x0,0x0,0x0,0x0,0x0,0x3fc00,0x1fe000,0x3ffc00,0x0,0x0,0x0,0x0,0x0,0x70,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03006 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00000,0x3e000,0x3e00000,0x0,0x78,0x3c000000,0x0,0x1f000,0x3e0,
03007 0x3e000,0x0,0x1f000000,0x3e0000,0x3e000000,0x0,0x0,0x7c00,0xf8,0xf800,0x0,0x0,0x0,0xf,0x80000000,0x1f00001f,0x0,0x3e,0x0,
03008 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03009 0x0,0x0,0x0,0x30000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03010 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80000,
03011 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03012 0x0,0x0,0x0,0x0,0xf80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x781c0000,0x38,0xe000000,0x0,0x0,0x380e0,0x0,
03013 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80,0x0,0x0,0x0,0x0,0x0,0x0,0x39c00,0x1ce000,0x303e00,
03014 0x0,0x0,0x0,0x0,0x0,0x78,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,
03015 0x0,0x0,0xf80000,0x7c000,0x3e00000,0xf0380000,0x70,0x1c000000,0x0,0xf800,0x7c0,0x3e000,0x0,0xf800000,0x7c0000,0x3e000000,
03016 0x0,0x3c0,0xe0003e00,0x1f0,0xf800,0x3c0e00,0x0,0x0,0x7,0xc0000000,0x3e00001f,0x0,0x7c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03017 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0xff,0x0,
03018 0xf8,0xf8000,0x1c000,0x0,0x0,0x0,0x0,0x1f,0xc0000000,0x1ff8,0xff00,0x0,0x0,0x3fe000,0x0,0x1fc00001,0xfe000000,0x0,0x0,0x0,
03019 0x0,0x7f800,0x0,0x0,0x0,0xff00000,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xf8000000,0xfe,0x0,0x7f80,0x0,0x0,0x0,0x0,0x0,
03020 0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x780000,0x1,0xe0000000,0x0,0x780000,0x3,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,
03021 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc0000f0,0x3f000,0x0,0x0,0x3fc00,0x0,0x0,0x1fc000,0x0,0x0,0x0,0x1fc0,
03022 0x0,0xff000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe1c0000,0x1c,0x1c000000,0x0,0x0,0x1c1c0,0x0,0x0,0x0,0x0,0x1fe0000,
03023 0x0,0x0,0x1ff,0x1f0f8,0x0,0xff000,0x0,0x0,0x0,0x3f,0xff00000f,0x80000000,0xfe0,0x3f80,0xf00,0x0,0x0,0x0,0x1,0xf8000003,0xe0000000,
03024 0x1c00,0xe000,0xe00,0x0,0x0,0x0,0x0,0x0,0x3c,0x78000000,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000,
03025 0x7f0000,0x0,0x1fc07000,0x0,0x0,0x0,0x0,0x0,0x3f800,0x780000,0x78000,0x7f00001,0xfc38001f,0xf800070,0x1c000000,0x0,0x7800,
03026 0x780,0x7f000,0x3e1f000,0x7800000,0x780000,0x7f00003e,0x1f0003f0,0x7f0,0xe0001e00,0x1e0,0x1fc00,0x7f0e00,0x7c3e000,0x0,0x3,
03027 0xc0000000,0x3c00003f,0x80001f0f,0x80000078,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03028 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x1e078000,0x30000000,0x3ff,0xc00001e0,0xf0,
03029 0x78000,0x1c000,0x0,0x0,0x0,0x0,0x1e0007f,0xf000007e,0x1ffff,0x7ffe0,0x1f80,0x3ffff80,0xfff803,0xfffff800,0xfff80007,0xff800000,
03030 0x0,0x0,0x0,0x0,0x1ffe00,0x0,0xfe0003,0xfff80000,0x3ffe01ff,0xe00003ff,0xffe01fff,0xff0003ff,0xe01e0007,0x803ffff0,0xfff80,
03031 0x3c000fc0,0x7800001f,0x8003f07e,0x1e000f,0xfe0007ff,0xf00003ff,0x8007ffe0,0x1fff8,0x7fffffe,0xf0003c1,0xe000079e,0xf1f,0x1f3e0,
03032 0x1f01ff,0xfff8003f,0xf003c000,0x7fe0,0x3f00,0x0,0x3c0000,0x1,0xe0000000,0x0,0x780000,0xf,0xfe000000,0x78000,0x3c00,0xf000,
03033 0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xfc0000f0,0x3fe00,0x0,0x0,0xfff00,0x0,0x0,0x3fe000,
03034 0x0,0x0,0x0,0x1dc0,0x0,0x3fff00,0x0,0x3ffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff1c07ff,0x3c0f001e,0x3c000000,
03035 0x0,0x0,0x1e3c0,0xf80007c,0x0,0x780000,0x0,0xfff8000,0x3e00,0x1f00000,0x7ff,0xc001f0f8,0x0,0x3ffc00,0x0,0x0,0x0,0x3f,0xff00003f,
03036 0xe0000000,0x3ff8,0xffe0,0x1e00,0x0,0xfffc00,0x0,0x7,0xf800000f,0xf8000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000,
03037 0x3f800001,0xfc00003f,0xf80000ff,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc,
03038 0xfc00,0x3c001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x0,0x7ff8f0f0,0x3c0780,0x1e03c00,0xf01e000,0x783e0001,0xf01e0000,0xffe00,
03039 0x3c0000,0xf0000,0x7700001,0xfe38001f,0xf800070,0x1c000000,0x0,0x3c00,0xf00,0x77000,0x3e1f000,0x3c00000,0xf00000,0x7700003e,
03040 0x1f0000f8,0xc0007f8,0xe0000f00,0x3c0,0x1dc00,0x7f8e00,0x7c3e000,0x0,0x1,0xe0000000,0x7800003b,0x80001f0f,0x800000f0,0x1e0000,
03041 0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03042 0x0,0x0,0x780000,0x3c1e0000,0x1e070000,0x300001f0,0x7ff,0xc00001e0,0x1e0,0x7c000,0x1c000,0x0,0x0,0x0,0x0,0x3c000ff,0xf80007fe,
03043 0x3ffff,0x801ffff8,0x1f80,0x3ffff80,0x3fff803,0xfffff801,0xfffc000f,0xffc00000,0x0,0x0,0x0,0x0,0x7fff80,0x0,0xfe0003,0xffff0000,
03044 0xffff01ff,0xfc0003ff,0xffe01fff,0xff000fff,0xf01e0007,0x803ffff0,0xfff80,0x3c001f80,0x7800001f,0xc007f07e,0x1e001f,0xff0007ff,
03045 0xfc0007ff,0xc007fffc,0x3fffc,0x7fffffe,0xf0003c1,0xf0000f9e,0xf0f,0x8003e1e0,0x1e01ff,0xfff8003f,0xf001e000,0x7fe0,0x3f00,
03046 0x0,0x1e0000,0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,
03047 0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x1fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x3de0,0x0,0x7fff80,0x0,0xfffff80,
03048 0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe7bc07ff,0x3e1f000f,0x78000000,0x0,0x0,0xf780,0x7800078,0x0,0x780000,0x180000,
03049 0x1fff8000,0x1e00,0x1e0003c,0xfff,0xc001f0f8,0x0,0x7ffe00,0x0,0x0,0x0,0x3f,0xff00007f,0xf0000000,0x3ffc,0xfff0,0x3c00,0x0,
03050 0x7fffc00,0x0,0x7,0xf800003f,0xfe000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xe00001ff,
03051 0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000fc00,0x3c003ffe,0x1fff0,
03052 0xfff80,0x7ffc00,0x3ffe000,0x0,0xfffce0f0,0x3c0780,0x1e03c00,0xf01e000,0x781e0001,0xe01e0000,0x3fff00,0x1e0000,0x1e0000,0xf780003,
03053 0xcf78001f,0xf800078,0x3c000000,0x0,0x1e00,0x1e00,0xf7800,0x3e1f000,0x1e00000,0x1e00000,0xf780003e,0x1f0000fc,0x7c000f3d,
03054 0xe0000780,0x780,0x3de00,0xf3de00,0x7c3e000,0x0,0x0,0xf0000000,0xf000007b,0xc0001f0f,0x800001e0,0x1e0000,0x3e1f00,0x0,0x0,
03055 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,
03056 0x3c1e0000,0x1e0f0000,0x300007fc,0xfff,0xc00001e0,0x1e0,0x3c000,0x1c000,0x0,0x0,0x0,0x0,0x3c001ff,0xfc001ffe,0x3ffff,0xc01ffffc,
03057 0x3f80,0x3ffff80,0x7fff803,0xfffff803,0xfffe001f,0xffe00000,0x0,0x0,0x0,0x0,0xffff80,0x7f800,0xfe0003,0xffff8001,0xffff01ff,
03058 0xff0003ff,0xffe01fff,0xff001fff,0xf01e0007,0x803ffff0,0xfff80,0x3c003f00,0x7800001f,0xc007f07f,0x1e003f,0xff8007ff,0xff000fff,
03059 0xe007ffff,0x7fffc,0x7fffffe,0xf0003c0,0xf0000f1e,0xf07,0x8003c1f0,0x3e01ff,0xfff8003f,0xf001e000,0x7fe0,0x7f80,0x0,0xe0000,
03060 0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,
03061 0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x3fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x78f0,0x0,0xffff80,0x0,0x3fffff80,0x1f,
03062 0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc7f80070,0x3e1f0007,0x70000000,0x0,0x0,0x7700,0x7c000f8,0x0,0x780000,0x180000,
03063 0x3fff8000,0x1f00,0x3e0003c,0x1f03,0xc001f0f8,0x0,0x703f00,0x0,0x0,0x0,0x3f,0xff0000f0,0xf8000000,0x303e,0xc0f8,0x7800,0x0,
03064 0xffffc00,0x0,0x7,0x3800003e,0x3e000000,0x1c00,0xe000,0x3c00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00000f,0xe00001ff,
03065 0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000fe00,0x3c007fff,0x3fff8,
03066 0x1fffc0,0xfffe00,0x7fff000,0x1,0xffffc0f0,0x3c0780,0x1e03c00,0xf01e000,0x781f0003,0xe01e0000,0x3fff80,0xe0000,0x3c0000,0x1e3c0003,
03067 0x8ff0001f,0xf80003c,0x78000000,0x0,0xe00,0x3c00,0x1e3c00,0x3e1f000,0xe00000,0x3c00001,0xe3c0003e,0x1f00007f,0xf8000e3f,0xc0000380,
03068 0xf00,0x78f00,0xe3fc00,0x7c3e000,0x0,0x0,0x70000001,0xe00000f1,0xe0001f0f,0x800003c0,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,
03069 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c0f0000,
03070 0x30000ffe,0xf80,0xc00001e0,0x3c0,0x1e000,0x101c040,0x0,0x0,0x0,0x0,0x78003f0,0x7e001ffe,0x3f807,0xe01f00fe,0x3f80,0x3ffff80,
03071 0x7e01803,0xfffff007,0xe03f003f,0x3f00000,0x0,0x0,0x0,0x0,0xfc0fc0,0x3ffe00,0xfe0003,0xffffc003,0xf81f01ff,0xff8003ff,0xffe01fff,
03072 0xff003f01,0xf01e0007,0x803ffff0,0xfff80,0x3c007e00,0x7800001f,0xc007f07f,0x1e007e,0xfc007ff,0xff801f83,0xf007ffff,0x800fc07c,
03073 0x7fffffe,0xf0003c0,0xf0000f0f,0x1e07,0xc007c0f8,0x7c01ff,0xfff8003c,0xf000,0x1e0,0xffc0,0x0,0xf0000,0x1,0xe0000000,0x0,0x780000,
03074 0x3e,0x0,0x78000,0x3c00,0xf000,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0x800000f0,0x1f80,
03075 0x0,0x0,0x7e0780,0x0,0x0,0x1f82000,0x0,0x0,0x0,0x7070,0x0,0x1f80f80,0x0,0x7fffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,
03076 0x0,0x1,0xc3f80070,0x3f3f0007,0xf0000000,0x0,0x0,0x7f00,0x3e001f0,0x0,0x780000,0x180000,0x7f018000,0xf80,0x7c0003c,0x3e00,
03077 0x4001f0f8,0xfe00,0x400f00,0x0,0x0,0x0,0x7f000000,0xe0,0x38000000,0x1e,0x38,0x7800,0x0,0x1ffe1c00,0x0,0x0,0x38000078,0xf000000,
03078 0x1c00,0xe000,0x7f800,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xf00001ff,0xffc03f81,0xf007ffff,0xc03ffffe,
03079 0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf800fe00,0x3c00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800,
03080 0x3,0xf07fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x780f8007,0xc01e0000,0x7e0fc0,0xf0000,0x3c0000,0x1c1c0003,0x87f0001f,0xf80003f,
03081 0xf8000000,0x0,0xf00,0x3c00,0x1c1c00,0x3e1f000,0xf00000,0x3c00001,0xc1c0003e,0x1f00003f,0xc0000e1f,0xc00003c0,0xf00,0x70700,
03082 0xe1fc00,0x7c3e000,0x0,0x0,0x78000001,0xe00000e0,0xe0001f0f,0x800003c0,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03083 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c0f0001,0xff801e0f,
03084 0x1f00,0x1e0,0x3c0,0x1e000,0x3c1c1e0,0x0,0x0,0x0,0x0,0x78007c0,0x1f001f9e,0x3c001,0xf010003e,0x7780,0x3c00000,0xf800000,0xf007,
03085 0xc01f007c,0x1f80000,0x0,0x0,0x0,0x0,0xe003e0,0x7fff00,0x1ef0003,0xc007e007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x301e0007,
03086 0x80007800,0x780,0x3c00fc00,0x7800001f,0xe00ff07f,0x1e00f8,0x3e00780,0x1fc03e00,0xf807801f,0xc01f001c,0xf000,0xf0003c0,0xf0000f0f,
03087 0x1e03,0xc00f8078,0x780000,0xf0003c,0xf000,0x1e0,0x1f3e0,0x0,0x78000,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,
03088 0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0xf0,0xf80,0x0,0x0,0xf80180,0x0,0x0,0x1e00000,
03089 0x0,0x0,0x0,0xe038,0x0,0x3e00380,0x0,0xfe0f0000,0x0,0xf0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc0f00070,0x3b370003,0xe0000000,
03090 0x0,0x0,0x3e00,0x1e001e0,0x0,0x780000,0x180000,0x7c000000,0x780,0x780003c,0x3c00,0x0,0x7ffc0,0x780,0x0,0x0,0x3,0xffe00000,
03091 0x1c0,0x3c000000,0xe,0x38,0xf000,0x0,0x3ffe1c00,0x0,0x0,0x38000078,0xf000000,0x1c00,0xe000,0x7f000,0xf000,0x3de000,0x1ef0000,
03092 0xf780000,0x7bc00003,0xde00001e,0xf00003e7,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
03093 0xe0001e03,0xfc00fe00,0x3c01f007,0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x7,0xc01f80f0,0x3c0780,0x1e03c00,0xf01e000,0x78078007,
03094 0x801e0000,0x7803c0,0x78000,0x780000,0x380e0003,0x81e00000,0x1f,0xf0000000,0x0,0x780,0x7800,0x380e00,0x0,0x780000,0x7800003,
03095 0x80e00000,0x1ff,0x80000e07,0x800001e0,0x1e00,0xe0380,0xe07800,0x0,0x0,0x0,0x3c000003,0xc00001c0,0x70000000,0x780,0x1e0000,
03096 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03097 0x780000,0x3c1e0000,0x3c0e0007,0xfff01c07,0x1e00,0x1e0,0x780,0xf000,0x3e1c3e0,0x0,0x0,0x0,0x0,0xf0007c0,0x1f00181e,0x20000,
03098 0xf000001f,0xf780,0x3c00000,0x1f000000,0x1f00f,0x800f8078,0xf80000,0x0,0x0,0x0,0x0,0x8003e0,0x1fc0f80,0x1ef0003,0xc001e007,
03099 0x800101e0,0x7e003c0,0x1e00,0x7800,0x101e0007,0x80007800,0x780,0x3c00f800,0x7800001e,0xe00ef07f,0x801e00f0,0x1e00780,0x7c03c00,
03100 0x78078007,0xc01e0004,0xf000,0xf0003c0,0x78001e0f,0x1e03,0xe00f807c,0xf80000,0x1f0003c,0x7800,0x1e0,0x3e1f0,0x0,0x3c000,0x1,
03101 0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,
03102 0x1e,0xf0,0x780,0x0,0x0,0x1f00080,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x1e03c,0x0,0x3c00080,0x0,0xf80f0000,0x0,0x1f0000,0x0,0x0,
03103 0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x3bf70003,0xe0000000,0x0,0x0,0x3e00,0x1f003e0,0x0,0x780000,0x180000,0x78000000,0x7c0,0xf80003c,
03104 0x3c00,0x0,0x1f01f0,0x780,0x0,0x0,0xf,0x80f80000,0x1c0,0x1c000000,0xe,0x38,0x1e000,0x0,0x7ffe1c00,0x0,0x0,0x380000f0,0x7800000,
03105 0x1c00,0xe000,0x7fc00,0xf000,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x80007800,0x10078000,0x3c0000,
03106 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00ff00,0x3c01e003,0xc00f001e,0x7800f0,0x3c00780,0x1e003c00,
03107 0x7,0x800f00f0,0x3c0780,0x1e03c00,0xf01e000,0x7807c00f,0x801e0000,0xf803c0,0x3c000,0xf00000,0x780f0000,0x0,0x7,0xc0000000,
03108 0x0,0x3c0,0xf000,0x780f00,0x0,0x3c0000,0xf000007,0x80f00000,0x7ff,0xc0000000,0xf0,0x3c00,0x1e03c0,0x0,0x0,0x0,0x0,0x1e000007,
03109 0x800003c0,0x78000000,0xf00,0x1e0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03110 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c1e001f,0xfff03803,0x80001e00,0x1e0,0x780,0xf000,0xf9cf80,
03111 0x0,0x0,0x0,0x0,0xf000780,0xf00001e,0x0,0xf800000f,0xe780,0x3c00000,0x1e000000,0x1e00f,0x78078,0x7c0000,0x0,0x0,0x0,0x0,0x1e0,
03112 0x3f003c0,0x1ef0003,0xc000f00f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780,0x3c01f000,0x7800001e,0xe00ef07f,
03113 0x801e01f0,0x1e00780,0x3c07c00,0x78078003,0xc03e0000,0xf000,0xf0003c0,0x78001e0f,0x1e01,0xf01f003c,0xf00000,0x3e0003c,0x7800,
03114 0x1e0,0x7c0f8,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,
03115 0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,0x0,0x0,0x3c00000,0x0,0x8,0x40,0x0,0x7e0000,0x7c00000,0x1,0xf00f0000,
03116 0x0,0x3e0000,0x0,0x3f,0xfc0,0xfc3f0,0xfc3f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0,0xf003c0,0x0,0x0,0x180000,0xf8000000,
03117 0x3c0,0xf00003c,0x3c00,0x0,0x3c0078,0x7ff80,0x0,0x0,0x1e,0x3c0000,0x1c0,0x1c000000,0xe,0xf0,0x0,0x0,0x7ffe1c00,0x0,0x0,0x380000f0,
03118 0x7800000,0x1c00,0xe000,0x3c00,0x0,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x8000f800,0x78000,0x3c0000,
03119 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00ff00,0x3c03e003,0xc01f001e,0xf800f0,0x7c00780,0x3e003c00,
03120 0xf,0x800f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803c00f,0x1fffc0,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03121 0x0,0x0,0x307,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03122 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x781e003f,0xfff03803,
03123 0x80001e00,0x1e0,0xf80,0xf000,0x3dde00,0x0,0x0,0x0,0x0,0xf000f00,0x780001e,0x0,0x7800000f,0x1e780,0x3c00000,0x3e000000,0x3e00f,
03124 0x780f0,0x7c0000,0x0,0x0,0x0,0x0,0x1e0,0x7c001e0,0x3ef8003,0xc000f00f,0x1e0,0xf003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780,
03125 0x3c03e000,0x7800001e,0xf01ef07b,0xc01e01e0,0xf00780,0x3e07800,0x3c078003,0xe03c0000,0xf000,0xf0003c0,0x78001e0f,0x1e00,0xf01e003e,
03126 0x1f00000,0x3c0003c,0x7800,0x1e0,0x78078,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,
03127 0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,0x0,0x0,0x3c00000,0x0,0x18,0xc0,0x0,
03128 0xe70000,0x7800000,0x1,0xe00f0000,0x0,0x3c0000,0x0,0x3f,0xfc0,0xfc1f0,0x1f83f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0,
03129 0xf807c0,0x0,0x0,0x180000,0xf0000000,0x3e0,0x1f00003c,0x3e00,0x0,0x70001c,0x3fff80,0x0,0x0,0x38,0xe0000,0x1c0,0x1c000078,
03130 0x1c,0x1fe0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x7df000,0x3ef8000,0x1f7c0000,0xfbe00007,
03131 0xdf00003c,0x780003c7,0x8000f000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f780,
03132 0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0xf80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803e01f,0x1ffff8,0xf001e0,
03133 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x0,0x0,0x0,0x1e0000,
03134 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03135 0x780000,0x3c1e0000,0x781e003e,0x30703803,0x80001e00,0x1e0,0xf00,0x7800,0xff800,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e,
03136 0x0,0x7800000f,0x3c780,0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x2000000,0x800000,0x1e0,0x78000e0,0x3c78003,
03137 0xc000f01e,0x1e0,0xf803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x701cf07b,0xc01e01e0,0xf00780,0x1e07800,
03138 0x3c078001,0xe03c0000,0xf000,0xf0003c0,0x7c003e0f,0x1e00,0xf83e001e,0x1e00000,0x7c0003c,0x3c00,0x1e0,0xf807c,0x0,0x0,0x1fe0001,
03139 0xe1fc0000,0x7f00003,0xf8780007,0xf000003c,0x7f0,0x783f0,0x0,0x0,0x7800000,0x1e00000,0x3e0f8000,0xfc00007,0xf8000007,0xf00001fc,
03140 0xf,0xc0003fc0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x3c00000,0x0,0x0,0x3c00000,0x0,0x18,0xc0,0x0,0x1818000,
03141 0x7800000,0x1,0xe00f0000,0x0,0x7c0000,0x0,0x1f,0x80001f80,0x7c1f8,0x1f83e0,0x0,0x0,0x0,0x70,0x38c70007,0xf8000000,0x7f03,
03142 0xf0000000,0x0,0x780780,0x0,0x0,0xfe0000,0xf0000000,0x1e0,0x1e00003c,0x3f00,0x0,0xe07f0e,0x7fff80,0x0,0x0,0x70,0x70000,0x1c0,
03143 0x1c000078,0x3c,0x1fc0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x78f000,0x3c78000,0x1e3c0000,
03144 0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,
03145 0xf80f780,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0x1f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801e01e,0x1ffffc,
03146 0xf007e0,0x3fc000,0x1fe0000,0xff00000,0x7f800003,0xfc00001f,0xe0000fc0,0xfc00007f,0xfe0,0x7f00,0x3f800,0x1fc000,0x0,0x0,0x0,
03147 0x1,0xf000001f,0x80000ff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x1f80000,0x1fc1e000,0x0,0x0,0x0,0x0,0x1e1fc0,0x0,0x0,0x0,0x0,
03148 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,
03149 0x781c007c,0x30003803,0x80001f00,0x1e0,0xf00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e,0x0,0x7800000f,0x3c780,
03150 0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x1e000000,0xf00000,0x3e0,0xf0000e0,0x3c78003,0xc000f01e,0x1e0,0x7803c0,
03151 0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c0f8000,0x7800001e,0x701cf079,0xe01e01e0,0xf00780,0x1e07800,0x3c078001,0xe03c0000,
03152 0xf000,0xf0003c0,0x3c003c0f,0x3e00,0x787c001f,0x3e00000,0xf80003c,0x3c00,0x1e0,0x1f003e,0x0,0x0,0x1fffc001,0xe7ff0000,0x3ffe000f,
03153 0xfe78003f,0xfc001fff,0xfe001ffc,0xf0078ffc,0x1ffc00,0x7ff000,0x7800f80,0x1e0000f,0x7f1fc01e,0x3ff0001f,0xfe00079f,0xfc0007ff,
03154 0x3c003c7f,0xf001fff8,0x1fffff0,0x3c003c0,0xf0000f1e,0xf1f,0x7c1f0,0x1f00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3c00000,0x100000,
03155 0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7800000,0x1,0xe00f0000,0x1000000,0xf80000,0x40000002,0xf,0x80001f00,0x7e0f8,0x1f07c0,
03156 0x0,0x0,0x0,0x70,0x38c7003f,0xff000000,0xff8f,0xf8000100,0xffffe,0x7c0f80,0x0,0x0,0x3ffc000,0xf0000020,0x1001f0,0x3c00003c,
03157 0x1f80,0x0,0x1c3ffc7,0x7c0780,0x0,0x0,0xe3,0xff038000,0xe0,0x38000078,0x78,0x1ff0,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0,
03158 0x7800000,0x1c00,0xe000,0xe00,0xf000,0x78f000,0x3c78000,0x1e3c0000,0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000,
03159 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,
03160 0x4000200f,0x3f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801f03e,0x1ffffe,0xf01fe0,0x3fff800,0x1fffc000,0xfffe0007,0xfff0003f,
03161 0xff8001ff,0xfc003ff3,0xfe0003ff,0xe0007ff8,0x3ffc0,0x1ffe00,0xfff000,0x3ff80001,0xffc0000f,0xfe00007f,0xf000003f,0xf8003c7f,
03162 0xe0003ffc,0x1ffe0,0xfff00,0x7ff800,0x3ffc000,0x1f80000,0xfff1c03c,0x3c01e0,0x1e00f00,0xf007800,0x781f0001,0xf01e7ff0,0x7c0007c,
03163 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,
03164 0x3c1e003f,0xfffff078,0x30003803,0x80000f00,0x1e0,0x1f00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x3c000f00,0x780001e,0x0,0x7800000f,
03165 0x78780,0x3c00000,0x3c000000,0x7c00f,0x780f0,0x3c0007,0xe000003f,0x0,0xfe000000,0xfe0000,0x3c0,0x1f000070,0x7c7c003,0xc000f01e,
03166 0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c1f0000,0x7800001e,0x783cf079,0xe01e03c0,0xf00780,0x1e0f000,0x3c078001,
03167 0xe03c0000,0xf000,0xf0003c0,0x3c003c07,0x81f03c00,0x7c7c000f,0x87c00000,0xf00003c,0x1e00,0x1e0,0x3e001f,0x0,0x0,0x3fffe001,
03168 0xefff8000,0x7fff001f,0xff78007f,0xfe001fff,0xfe003ffe,0xf0079ffe,0x1ffc00,0x7ff000,0x7801f00,0x1e0000f,0xffbfe01e,0x7ff8003f,
03169 0xff0007bf,0xfe000fff,0xbc003cff,0xf803fffc,0x1fffff0,0x3c003c0,0x78001e1e,0xf0f,0x800f80f0,0x1e00ff,0xffe0001e,0xf0,0x780,
03170 0x0,0x0,0x3c00000,0x380000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1008000,0x7800000,0x3,0xe00f0000,0x3800000,0xf00000,0xe0000007,
03171 0xf,0x80001f00,0x3e0f8,0x1e07c0,0x0,0x0,0x0,0x70,0x3807007f,0xff800000,0x1ffdf,0xfc000380,0xffffe,0x3e1f00,0x0,0x0,0xfffe000,
03172 0xf0000030,0x3800f8,0x7c00003c,0xfc0,0x0,0x18780c3,0xf00780,0x80100,0x0,0xc3,0xffc18000,0xf0,0x78000078,0xf0,0xf0,0x0,0x3c003c0,
03173 0xfffe1c00,0x0,0x0,0x380000f0,0x7800801,0x1c00,0xe000,0x1e00,0xf000,0xf8f800,0x7c7c000,0x3e3e0001,0xf1f0000f,0x8f80007c,0x7c000787,
03174 0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078001,0xe03c000f,
03175 0x1e00078,0xf0003c0,0x78001e00,0xe000701f,0x3fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x7800f87c,0x1e007f,0xf07e00,0x7fffc00,0x3fffe001,
03176 0xffff000f,0xfff8007f,0xffc003ff,0xfe007ff7,0xff0007ff,0xf000fffc,0x7ffe0,0x3fff00,0x1fff800,0x3ff80001,0xffc0000f,0xfe00007f,
03177 0xf00000ff,0xf8003cff,0xf0007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x1f80001,0xfffb803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001,
03178 0xe01efff8,0x3c00078,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03179 0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e003f,0xfffff078,0x30001c07,0xf80,0x1e0,0x1e00,0x3c00,0xff800,0x1e0000,0x0,0x0,0x0,0x3c001e00,
03180 0x3c0001e,0x0,0x7800001e,0x70780,0x3c00000,0x78000000,0x78007,0x800f00f0,0x3e0007,0xe000003f,0x3,0xfe000000,0xff8000,0x7c0,
03181 0x1e000070,0x783c003,0xc001f01e,0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c3e0000,0x7800001e,0x3838f079,
03182 0xe01e03c0,0x780780,0x1e0f000,0x1e078001,0xe03c0000,0xf000,0xf0003c0,0x3c007c07,0x81f03c00,0x3ef80007,0x87800000,0x1f00003c,
03183 0x1e00,0x1e0,0x7c000f,0x80000000,0x0,0x3ffff001,0xffffc000,0xffff003f,0xff7800ff,0xff001fff,0xfe007ffe,0xf007bffe,0x1ffc00,
03184 0x7ff000,0x7803e00,0x1e0000f,0xffffe01e,0xfff8007f,0xff8007ff,0xff001fff,0xbc003dff,0xf807fffc,0x1fffff0,0x3c003c0,0x78001e0f,
03185 0x1e07,0xc01f00f0,0x1e00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7c00000,0x7c0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1018000,0x7800000,
03186 0x3,0xc00f0000,0x7c00000,0x1f00001,0xf000000f,0x80000007,0xc0003e00,0x1e07c,0x3e0780,0x0,0x0,0x0,0x70,0x380700ff,0xff800000,
03187 0x3ffff,0xfe0007c0,0xffffe,0x1e1e00,0x0,0x780000,0x1fffe000,0xf0000078,0x7c0078,0x7800003c,0xff0,0x0,0x38e0003,0x80f00780,
03188 0x180300,0x0,0x1c3,0x81e1c000,0x7f,0xf0000078,0x1e0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800c01,0x80001c00,
03189 0xe000,0x603e00,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x7800078,0x3c000f87,0x8001e000,0x78000,0x3c0000,0x1e00000,
03190 0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f01,0xf000f81e,
03191 0x7bc0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007878,0x1e001f,0xf0f800,0x7fffe00,0x3ffff001,0xffff800f,0xfffc007f,0xffe003ff,
03192 0xff007fff,0xff800fff,0xf001fffe,0xffff0,0x7fff80,0x3fffc00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00001ff,0xfc003dff,0xf000ffff,
03193 0x7fff8,0x3fffc0,0x1fffe00,0xffff000,0x1f80003,0xffff803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001,0xe01ffffc,0x3c00078,0x0,
03194 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,
03195 0x3c1e003f,0xfffff078,0x30001e0f,0x300780,0x1e0,0x1e00,0x3c00,0x3dde00,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf800003e,
03196 0xf0780,0x3dfc000,0x783f8000,0xf8007,0xc01f00f0,0x3e0007,0xe000003f,0x1f,0xfc000000,0x7ff000,0xf80,0x3e007c70,0x783c003,0xc001e03c,
03197 0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007,0x80007800,0x780,0x3c7c0000,0x7800001e,0x3878f078,0xf01e03c0,0x780780,0x1e0f000,0x1e078001,
03198 0xe03e0000,0xf000,0xf0003c0,0x1e007807,0x83f03c00,0x3ef00007,0xcf800000,0x3e00003c,0xf00,0x1e0,0xf80007,0xc0000000,0x0,0x3e01f801,
03199 0xfe07e001,0xf80f007e,0x7f801f8,0x1f801fff,0xfe00fc0f,0xf007f83f,0x1ffc00,0x7ff000,0x7807c00,0x1e0000f,0x87e1e01f,0xe0fc00fc,
03200 0xfc007f8,0x1f803f03,0xfc003df0,0x3807e03c,0x1fffff0,0x3c003c0,0x78003e0f,0x1e03,0xe03e00f8,0x3e00ff,0xffe0001e,0xf0,0x780,
03201 0x0,0x0,0x7800000,0xfe0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7c00000,0x3,0xc00f0000,0xfe00000,0x3e00003,0xf800001f,
03202 0xc0000007,0xc0003e00,0x1e03c,0x3c0f80,0x0,0x0,0x0,0x70,0x380700fc,0x7800000,0x7c1fe,0x3e000fe0,0xffffe,0x1f3e00,0x0,0x780000,
03203 0x3f98e000,0xf000003c,0xfcf8007c,0xf800003c,0x3ffc,0x0,0x31c0001,0x80f00f80,0x380700,0x0,0x183,0x80e0c000,0x3f,0xe0000078,
03204 0x3c0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x38000078,0xf000e01,0xc003ffe0,0x1fff00,0x7ffc00,0xf000,0xf07800,0x783c000,0x3c1e0001,
03205 0xe0f0000f,0x7800078,0x3c000f07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,
03206 0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf801f01e,0xf3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007cf8,
03207 0x1e000f,0x80f0f000,0x7c03f00,0x3e01f801,0xf00fc00f,0x807e007c,0x3f003e0,0x1f80707f,0x8f801f80,0xf003f03f,0x1f81f8,0xfc0fc0,
03208 0x7e07e00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00003ff,0xfc003fc1,0xf801f81f,0x800fc0fc,0x7e07e0,0x3f03f00,0x1f81f800,0x1f80007,
03209 0xe07f003c,0x3c01e0,0x1e00f00,0xf007800,0x780f8003,0xe01fe07e,0x3e000f8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03210 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3f,0xfffff078,0x30000ffe,0x1f007c0,0x0,0x1e00,
03211 0x3c00,0xf9cf80,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf00000fc,0x1e0780,0x3fff800,0x78ffe000,0xf0003,0xe03e00f0,
03212 0x3e0007,0xe000003f,0x7f,0xe01fffff,0xf00ffc00,0x1f80,0x3c01ff70,0x783c003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007,
03213 0x80007800,0x780,0x3cfc0000,0x7800001e,0x3c78f078,0xf01e03c0,0x780780,0x3e0f000,0x1e078003,0xc01f0000,0xf000,0xf0003c0,0x1e007807,
03214 0x83f83c00,0x1ff00003,0xcf000000,0x3e00003c,0xf00,0x1e0,0x0,0x0,0x0,0x20007801,0xfc03e003,0xe003007c,0x3f803e0,0x7c0003c,
03215 0xf807,0xf007e00f,0x3c00,0xf000,0x780f800,0x1e0000f,0x87e1f01f,0x803c00f8,0x7c007f0,0xf803e01,0xfc003f80,0x80f8004,0x3c000,
03216 0x3c003c0,0x3c003c0f,0x1e03,0xe03e0078,0x3c0000,0x7c0001e,0xf0,0x780,0x0,0x0,0x3ffff800,0x1ff0000,0x0,0x7800000,0x0,0x18,
03217 0xc0,0x0,0x1818000,0x3e00000,0x3,0xc00f0000,0x1ff00000,0x3e00007,0xfc00003f,0xe0000003,0xc0003c00,0xf03c,0x3c0f00,0x0,0x0,
03218 0x0,0x70,0x380701f0,0x800000,0x780fc,0x1e001ff0,0x7c,0xf3c00,0x0,0x780000,0x7e182000,0xf000001f,0xfff00ffc,0xffc0003c,0x3cfe,
03219 0x0,0x31c0001,0x80f01f80,0x780f00,0x0,0x183,0x80e0c000,0xf,0x80000078,0x780,0x38,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x38000078,
03220 0xf000f01,0xe003ffe0,0x1fff00,0x7ff800,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x78000f8,0x3e000f07,0x8003c000,0x78000,
03221 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,
03222 0x78000f00,0x7c03e01e,0x1e3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78003cf0,0x1e0007,0x80f1e000,0x4000f00,0x20007801,0x3c008,
03223 0x1e0040,0xf00200,0x780403f,0x7803e00,0x3007c00f,0x803e007c,0x1f003e0,0xf801f00,0x780000,0x3c00000,0x1e000000,0xf00007f0,
03224 0x3e003f00,0x7801f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e003c,0x3c01e0,0x1e00f00,0xf007800,0x78078003,
03225 0xc01fc03e,0x1e000f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03226 0x0,0x0,0x0,0x0,0x0,0x780000,0x0,0xf078007c,0x300007fc,0x7e00fe0,0x0,0x1e00,0x3c00,0x3e1c3e0,0x1e0000,0x0,0x0,0x0,0xf0001e00,
03227 0x3c0001e,0x1,0xf000fff8,0x1e0780,0x3fffe00,0x79fff000,0x1f0001,0xfffc00f0,0x7e0007,0xe000003f,0x3ff,0x801fffff,0xf003ff80,
03228 0x3f00,0x3c03fff0,0xf01e003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3df80000,0x7800001e,
03229 0x1c70f078,0x781e03c0,0x780780,0x3c0f000,0x1e078007,0xc01f8000,0xf000,0xf0003c0,0x1e007807,0x83f83c00,0xfe00003,0xff000000,
03230 0x7c00003c,0x780,0x1e0,0x0,0x0,0x0,0x7c01,0xf801f007,0xc00100f8,0x1f803c0,0x3c0003c,0x1f003,0xf007c00f,0x80003c00,0xf000,
03231 0x783f000,0x1e0000f,0x3c0f01f,0x3e01f0,0x3e007e0,0x7c07c00,0xfc003f00,0xf0000,0x3c000,0x3c003c0,0x3c003c0f,0x1e01,0xf07c007c,
03232 0x7c0000,0xfc0001e,0xf0,0x780,0x0,0x0,0x3ffff000,0x3838000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0xff0000,0x3f00000,0x3,0xc00fff00,
03233 0x38380000,0x7c0000e,0xe000070,0x70000001,0xe0003c00,0xf01e,0x780e00,0x0,0x0,0x0,0x0,0x1e0,0x0,0x780f8,0xf003838,0xfc,0xffc00,
03234 0x0,0x780000,0x7c180000,0xf000000f,0xffe00fff,0xffc0003c,0x783f,0x80000000,0x6380000,0xc0f83f80,0xf81f00,0x0,0x303,0x80e06000,
03235 0x0,0x78,0xf00,0x78,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x3800003c,0x3e000f81,0xf003ffe0,0x1fff00,0x1fc000,0xf000,0x1e03c00,
03236 0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e000f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,
03237 0x3c000001,0xe0001e00,0x3c0f0f0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3e07c01e,0x1e3c0f0,0x3c0780,0x1e03c00,
03238 0xf01e000,0x78003ff0,0x1e0007,0x80f1e000,0xf80,0x7c00,0x3e000,0x1f0000,0xf80000,0x7c0001e,0x3c07c00,0x10078007,0x803c003c,
03239 0x1e001e0,0xf000f00,0x780000,0x3c00000,0x1e000000,0xf00007c0,0x1e003e00,0x7c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00,
03240 0xf,0x801f003c,0x3c01e0,0x1e00f00,0xf007800,0x7807c007,0xc01f801f,0x1f001f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03241 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x0,0xe078003c,0x300001f0,0x3f801ff0,0x0,
03242 0x3c00,0x1e00,0x3c1c1e0,0x1e0000,0x0,0x0,0x0,0xf0001e0f,0x3c0001e,0x3,0xe000fff0,0x3c0780,0x3ffff00,0x7bfff800,0x1e0000,0x7ff00078,
03243 0x7e0007,0xe000003f,0x1ffc,0x1fffff,0xf0007ff0,0x7e00,0x3c07c3f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,
03244 0x1fffff,0x80007800,0x780,0x3ffc0000,0x7800001e,0x1ef0f078,0x781e03c0,0x780780,0x7c0f000,0x1e07801f,0x800ff000,0xf000,0xf0003c0,
03245 0xf00f807,0x83b83c00,0xfc00001,0xfe000000,0xf800003c,0x780,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0xc00000f0,0xf80780,0x3c0003c,
03246 0x1e001,0xf007c007,0x80003c00,0xf000,0x787e000,0x1e0000f,0x3c0f01f,0x1e01e0,0x1e007c0,0x3c07800,0x7c003f00,0xf0000,0x3c000,
03247 0x3c003c0,0x3e007c07,0x80003c00,0xf8f8003c,0x780000,0xf80001e,0xf0,0x780,0x0,0x0,0x7ffff000,0x601c000,0x3,0xffff0000,0x0,
03248 0xfff,0xf8007fff,0xc0000000,0x7e003c,0x1fe0000,0xc0003,0xc00fff00,0x601c0000,0xf800018,0x70000c0,0x38000001,0xe0007800,0x701e,
03249 0x701e00,0x0,0x0,0x0,0x0,0x1e0,0x6,0x700f8,0xf00601c,0xf8,0x7f800,0x0,0x780000,0xf8180000,0xf000000f,0x87c00fff,0xffc0003c,
03250 0xf01f,0xc0000000,0x6380000,0xc07ff780,0x1f03e03,0xfffffe00,0x303,0x81c06000,0x0,0x1ffff,0xfe001e00,0x180f8,0x0,0x3c003c0,
03251 0x3ffe1c00,0x3f00000,0x0,0x3800003f,0xfe0007c0,0xf8000000,0x18000000,0xc0000006,0x1f000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e,
03252 0x3c000f0,0x1e001f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f0f0,
03253 0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f0f801e,0x3c3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007,
03254 0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07c00,0xf0007,0x8078003c,0x3c001e0,0x1e000f00,0x780000,0x3c00000,
03255 0x1e000000,0xf0000f80,0x1f003e00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0xf,0x3f003c,0x3c01e0,0x1e00f00,0xf007800,
03256 0x7803c007,0x801f000f,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03257 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe078003f,0xb0000000,0xfc003cf0,0x0,0x3c00,0x1e00,0x101c040,0x1e0000,0x0,0x0,0x1,
03258 0xe0001e1f,0x83c0001e,0x7,0xe000fff0,0x3c0780,0x3c03f80,0x7fc0fc00,0x1e0000,0xfff80078,0xfe0007,0xe000003f,0x7fe0,0x1fffff,
03259 0xf0000ffc,0xfc00,0x780f81f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3ffc0000,
03260 0x7800001e,0x1ef0f078,0x3c1e03c0,0x780780,0x1fc0f000,0x1e07ffff,0x7ff00,0xf000,0xf0003c0,0xf00f007,0xc3b87c00,0x7c00001,0xfe000000,
03261 0xf800003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0x800000f0,0xf80780,0x1e0003c,0x1e001,0xf0078007,0x80003c00,0xf000,0x78fc000,
03262 0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,0x3c07800,0x7c003e00,0xf0000,0x3c000,0x3c003c0,0x1e007807,0x80003c00,0x7df0003c,0x780000,
03263 0x1f00001e,0xf0,0x780,0x0,0x0,0x7800000,0xe7ce000,0x3,0xffff0000,0x0,0xfff,0xf8007fff,0xc0000000,0x1f0,0xffe000,0x1c0003,
03264 0xc00fff00,0xe7ce0000,0xf800039,0xf38001cf,0x9c000000,0xe0007800,0x780e,0x701c00,0x0,0x0,0x0,0x0,0x1e0,0x7,0xf0078,0xf00e7ce,
03265 0x1f0,0x7f800,0x0,0x780000,0xf0180000,0xf000000e,0x1c0001f,0xe000003c,0xf007,0xe0000000,0x6380000,0xc03fe780,0x3e07c03,0xfffffe00,
03266 0x303,0xffc06000,0x0,0x1ffff,0xfe003ffe,0x1fff0,0x0,0x3c003c0,0x1ffe1c00,0x3f00000,0x7,0xffc0001f,0xfc0003e0,0x7c000001,0xfc00000f,
03267 0xe000007f,0x1e000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,
03268 0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e,
03269 0x783c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007,0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07800,
03270 0xf0003,0xc078001e,0x3c000f0,0x1e000780,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c03c003,0xc01e001e,0xf000f0,
03271 0x7800780,0x3c003c00,0xf,0x7f003c,0x3c01e0,0x1e00f00,0xf007800,0x7803c007,0x801f000f,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03272 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe070001f,0xf8000007,
03273 0xf0007cf8,0x7800000,0x3c00,0x1e00,0x1c000,0x1e0000,0x0,0x0,0x1,0xe0001e1f,0x83c0001e,0xf,0xc000fff8,0x780780,0x2000f80,0x7f803e00,
03274 0x3e0003,0xfffe007c,0x1fe0000,0x0,0x3ff00,0x0,0x1ff,0x8001f000,0x780f00f0,0x1f00f003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff,
03275 0xfe03c00f,0xf81fffff,0x80007800,0x780,0x3ffe0000,0x7800001e,0xee0f078,0x3c1e03c0,0x7807ff,0xff80f000,0x1e07fffe,0x3ffe0,
03276 0xf000,0xf0003c0,0xf00f003,0xc7bc7800,0xfc00000,0xfc000001,0xf000003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xe000f80f,0x800001e0,
03277 0xf80f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x79f8000,0x1e0000f,0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003e00,
03278 0xf0000,0x3c000,0x3c003c0,0x1e007807,0x81e03c00,0x7df0003e,0xf80000,0x3e00003e,0xf0,0x7c0,0xfc000,0x80000000,0x7800000,0x1e7cf000,
03279 0x3,0xffff0000,0x0,0x18,0xc0,0x0,0xf80,0x7ffc00,0x380003,0xc00fff01,0xe7cf0000,0x1f000079,0xf3c003cf,0x9e000000,0xe0007000,
03280 0x380e,0xe01c00,0x0,0x0,0x0,0x0,0x1e0,0x3,0x800f0078,0xf01e7cf,0x3e0,0x3f000,0x0,0x780000,0xf018001f,0xfff8001e,0x1e0000f,
03281 0xc000003c,0xf003,0xe0000000,0x6380000,0xc00fc780,0x7c0f803,0xfffffe00,0x303,0xfe006000,0x0,0x1ffff,0xfe003ffe,0x1ffe0,0x0,
03282 0x3c003c0,0xffe1c00,0x3f00000,0x7,0xffc00007,0xf00001f0,0x3e00001f,0xfc0000ff,0xe00007ff,0x3e000,0x3e01e00,0x1f00f000,0xf8078007,
03283 0xc03c003e,0x1e001e0,0xf001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,
03284 0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000fc0,
03285 0x1e0007,0x80f1f000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c0f800,0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000,
03286 0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1e,0xf7803c,0x3c01e0,0x1e00f00,
03287 0xf007800,0x7803e00f,0x801e000f,0x80f803e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03288 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe0f0000f,0xff00001f,0x8000f87c,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,
03289 0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x1f,0x800000fe,0xf00780,0x7c0,0x7f001e00,0x3c0007,0xe03f003f,0x3fe0000,0x0,0x3fc00,0x0,
03290 0x7f,0x8001e000,0x781f00f0,0x1e00f003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3f9f0000,0x7800001e,
03291 0xfe0f078,0x3c1e03c0,0x7807ff,0xff00f000,0x1e07fff8,0xfff8,0xf000,0xf0003c0,0xf81f003,0xc7bc7800,0xfe00000,0x78000003,0xe000003c,
03292 0x1e0,0x1e0,0x0,0x0,0x0,0x1fffc01,0xe000780f,0x1e0,0x780f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7bf0000,0x1e0000f,
03293 0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xf8000,0x3c000,0x3c003c0,0x1f00f807,0x81f03c00,0x3fe0001e,0xf00000,0x7c00007c,
03294 0xf0,0x3e0,0x3ff801,0x80000000,0x7800000,0x3cfcf800,0x3,0xffff0000,0x0,0x18,0xc0,0x0,0x7c00,0x1fff00,0x700003,0xc00f0003,
03295 0xcfcf8000,0x3e0000f3,0xf3e0079f,0x9f000000,0xf000,0x1000,0x0,0x0,0x0,0x0,0x0,0x1f0,0x1,0xc00f0078,0xf03cfcf,0x800007c0,0x1e000,
03296 0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x8000003c,0xf001,0xf0000000,0x6380000,0xc0000000,0xf81f003,0xfffffe00,0x303,
03297 0x87006000,0x0,0x1ffff,0xfe003ffe,0x7f00,0x0,0x3c003c0,0x3fe1c00,0x3f00000,0x7,0xffc00000,0xf8,0x1f0001ff,0xf0000fff,0x80007ffc,
03298 0xfc000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf001e07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,
03299 0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3fc001e,0x1e03c0f0,0x3c0780,
03300 0x1e03c00,0xf01e000,0x78000780,0x1e0007,0x80f0fc00,0x3fff80,0x1fffc00,0xfffe000,0x7fff0003,0xfff8001f,0xffc0001e,0x3c0f000,
03301 0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000,0x3c00000,0x1e000000,0xf0001e00,0xf803c00,0x3c078001,0xe03c000f,0x1e00078,
03302 0xf0003c0,0x78001e07,0xfffffe1e,0x1e7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801e00f,0x1e0007,0x807803c0,0x0,0x0,0x0,0x0,0x0,
03303 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3,0xc0f00007,
03304 0xffc0007e,0xf03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x3f,0x3e,0xf00780,0x3c0,0x7e001e00,
03305 0x7c000f,0x800f001f,0xffde0000,0x0,0x3e000,0x0,0xf,0x8003e000,0x781e0070,0x1e00f003,0xc001f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,
03306 0xf81e0007,0x80007800,0x780,0x3f1f0000,0x7800001e,0x7c0f078,0x1e1e03c0,0x7807ff,0xfc00f000,0x1e07fffe,0xffc,0xf000,0xf0003c0,
03307 0x781e003,0xc71c7800,0x1ff00000,0x78000003,0xe000003c,0x1e0,0x1e0,0x0,0x0,0x0,0xffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,
03308 0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7f000,0x3c000,
03309 0x3c003c0,0xf00f007,0xc1f07c00,0x1fc0001f,0x1f00000,0xfc000ff8,0xf0,0x1ff,0xfffe07,0x80000000,0x7800000,0x7ffcfc00,0x0,0xf000000,
03310 0x0,0x18,0xc0,0x0,0x3e000,0x1ff80,0xe00003,0xc00f0007,0xffcfc000,0x3e0001ff,0xf3f00fff,0x9f800000,0x6000,0x0,0x0,0x7c000,
03311 0x0,0x0,0x0,0xfe,0x0,0xe00f007f,0xff07ffcf,0xc0000fc0,0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x80000000,0xf800,
03312 0xf0000000,0x6380000,0xc0000000,0x1f03c000,0x1e00,0x303,0x83806000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xfe1c00,0x3f00000,0x0,
03313 0x0,0x3c,0xf801fff,0xfff8,0x7ffc0,0x1f8000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf003c07,0x8003c000,0x78000,
03314 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,
03315 0x78000f00,0x1f8001e,0x1e03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e000f,0x80f0ff00,0x1ffff80,0xffffc00,0x7fffe003,
03316 0xffff001f,0xfff800ff,0xffc007ff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,
03317 0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x3c7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801f01f,
03318 0x1e0007,0x807c07c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03319 0x0,0x0,0x0,0x0,0x780000,0x3,0xc0f00000,0xfff003f0,0x1f00f03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x7ff80000,0x3,
03320 0xc0001e0f,0x3c0001e,0x7e,0x1f,0x1e00780,0x3e0,0x7e000f00,0x78000f,0x7800f,0xff9e0000,0x0,0x3fc00,0x0,0x7f,0x8003c000,0x781e0070,
03321 0x3e00f803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3e0f8000,0x7800001e,0x7c0f078,0x1e1e03c0,
03322 0x7807ff,0xf000f000,0x1e07807f,0xfe,0xf000,0xf0003c0,0x781e003,0xc71c7800,0x3ef00000,0x78000007,0xc000003c,0x1e0,0x1e0,0x0,
03323 0x0,0x0,0x1ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e,
03324 0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7ff80,0x3c000,0x3c003c0,0xf00f003,0xc1f07800,0x1fc0000f,0x1e00000,0xf8000ff0,0xf0,
03325 0xff,0xffffff,0x80000000,0x3fffc000,0xfff9fe00,0x0,0xf000000,0x0,0x18,0xc0,0x0,0x1f0000,0x1fc0,0x1c00003,0xc00f000f,0xff9fe000,
03326 0x7c0003ff,0xe7f81fff,0x3fc00000,0x0,0x0,0x0,0xfe000,0x1ffffc0f,0xfffffc00,0x0,0xff,0xf0000000,0x700f007f,0xff0fff9f,0xe0000f80,
03327 0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00fff,0xffc00000,0xf800,0xf0000000,0x6380000,0xc0ffff80,0x3e078000,0x1e00,0x7ff80303,
03328 0x83c06000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000,0x0,0x7f,0xff00001e,0x7c1fff0,0xfff80,0x7ffc00,0x3f0000,0x7c01f00,
03329 0x3e00f801,0xf007c00f,0x803e007c,0x1f003e0,0xf803c07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
03330 0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f8001e,0x3c03c0f0,0x3c0780,0x1e03c00,0xf01e000,
03331 0x78000780,0x1e001f,0xf07f80,0x3ffff80,0x1ffffc00,0xffffe007,0xffff003f,0xfff801ff,0xffc03fff,0xffc0f000,0x1fffff,0xc0fffffe,
03332 0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,
03333 0xfffffe1e,0x787803c,0x3c01e0,0x1e00f00,0xf007800,0x7800f01e,0x1e0007,0x803c0780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03334 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x3ff80fc0,0x7fc1e01f,
03335 0x7800000,0x3c00,0x1e00,0x0,0x7fffff80,0x0,0x7ff80000,0x7,0x80001e00,0x3c0001e,0xfc,0xf,0x1e00780,0x1e0,0x7c000f00,0x78000f,
03336 0x78007,0xff1e0000,0x0,0x3ff00,0x0,0x1ff,0x8003c000,0x781e0070,0x3c007803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007,
03337 0x80007800,0x780,0x3c07c000,0x7800001e,0x7c0f078,0xf1e03c0,0x780780,0xf000,0x1e07801f,0x3e,0xf000,0xf0003c0,0x781e003,0xcf1c7800,
03338 0x3cf80000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0,0x0,0x0,0x3ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,
03339 0x80003c00,0xf000,0x7ff8000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3fff0,0x3c000,0x3c003c0,0xf81f003,
03340 0xc3b87800,0xf80000f,0x1e00001,0xf0000ff0,0xf0,0xff,0xf03fff,0x80000000,0x3fff8001,0xfff1ff00,0x0,0xf000000,0x0,0x18,0xc0,
03341 0x0,0x380000,0x7c0,0x3c00003,0xc00f001f,0xff1ff000,0xf80007ff,0xc7fc3ffe,0x3fe00000,0x0,0x0,0x0,0x1ff000,0x7ffffe1f,0xffffff00,
03342 0x0,0x7f,0xfe000000,0x780f007f,0xff1fff1f,0xf0001f00,0x1e000,0x0,0x780001,0xe0180000,0xf000001c,0xe00fff,0xffc00000,0x7c00,
03343 0xf0000000,0x31c0001,0x80ffff80,0x3e078000,0x1e00,0x7ff80183,0x81c0c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000,
03344 0x0,0x7f,0xff00001e,0x7c7ff03,0xc03ff8fe,0x1ffc0f0,0x7e0000,0x7800f00,0x3c007801,0xe003c00f,0x1e0078,0xf003c0,0x7803c07,0x8003c000,
03345 0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c,
03346 0xf0001e0,0x78000f00,0x3fc001e,0x7803c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e007f,0xf03fe0,0x7ffff80,0x3ffffc01,
03347 0xffffe00f,0xffff007f,0xfff803ff,0xffc07fff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,
03348 0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x707803c,0x3c01e0,0x1e00f00,0xf007800,
03349 0x7800f01e,0x1e0007,0x803c0780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03350 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x30f81f00,0xffe1e00f,0x87800000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000,
03351 0x7,0x80001e00,0x3c0001e,0x1f8,0x7,0x83c00780,0x1e0,0x7c000f00,0xf8001e,0x3c001,0xfc1e0000,0x0,0x7fe0,0x0,0xffc,0x3c000,0x781e0070,
03352 0x3ffff803,0xc000783c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x380f078,0xf1e03c0,
03353 0x780780,0xf000,0x1e07800f,0x8000001e,0xf000,0xf0003c0,0x3c3c003,0xcf1e7800,0x7c780000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0,
03354 0x0,0x0,0x7f003c01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7f7c000,0x1e0000f,0x3c0f01e,
03355 0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfff8,0x3c000,0x3c003c0,0x781e003,0xc3b87800,0x1fc00007,0x83e00003,0xe0000ff8,0xf0,
03356 0x1ff,0xc007fe,0x0,0x7fff8001,0xffe3ff00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x3c0,0x7800003,0xc00f001f,0xfe3ff000,0xf80007ff,
03357 0x8ffc3ffc,0x7fe00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x1f,0xff000000,0x3c0f007f,0xff1ffe3f,0xf0003e00,0x1e000,0x0,0x780001,
03358 0xe0180000,0xf000001e,0x1e00fff,0xffc00000,0x3f00,0xf0000000,0x31c0001,0x80ffff80,0x1f03c000,0x1e00,0x7ff80183,0x81c0c000,
03359 0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x7f,0xff00003c,0xf87f007,0xc03f83ff,0x81fc01f0,0x7c0000,0x7ffff00,0x3ffff801,
03360 0xffffc00f,0xfffe007f,0xfff003ff,0xff807fff,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
03361 0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf003c0f0,0x3c0780,0x1e03c00,0xf01e000,
03362 0x78000780,0x1ffffe,0xf00ff0,0xfe00780,0x7f003c03,0xf801e01f,0xc00f00fe,0x7807f0,0x3c0ffff,0xffc0f000,0x1fffff,0xc0fffffe,
03363 0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,
03364 0x1e,0xf07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783e,0x1e0007,0x801e0f80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03365 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x307c0801,0xe1f1e00f,0x87000000,
03366 0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000,0xf,0x1e00,0x3c0001e,0x3f0,0x7,0x83fffffc,0x1e0,0x7c000f00,0xf0001e,0x3c000,0x3e0000,
03367 0x0,0x1ffc,0x1fffff,0xf0007ff0,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x3c000,0x781e0007,0x80007800,
03368 0x780,0x3c03e000,0x7800001e,0xf078,0x79e03c0,0x780780,0xf000,0x1e078007,0x8000000f,0xf000,0xf0003c0,0x3c3c001,0xee0ef000,
03369 0xf87c0000,0x7800001f,0x3c,0x78,0x1e0,0x0,0x0,0x0,0x7c003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00,
03370 0xf000,0x7e3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x1ffc,0x3c000,0x3c003c0,0x781e003,0xe3b8f800,
03371 0x1fc00007,0x83c00007,0xc00000fc,0xf0,0x3e0,0x8001f8,0x0,0x7800000,0xffc7fe00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0,
03372 0xf000003,0xc00f000f,0xfc7fe001,0xf00003ff,0x1ff81ff8,0xffc00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x3,0xff800000,0x1e0f0078,
03373 0xffc7f,0xe0007c00,0x1e000,0x0,0x780001,0xe0180000,0xf000000e,0x1c00007,0x80000000,0x1f81,0xe0000000,0x38e0003,0x80000000,
03374 0xf81f000,0x1e00,0x7ff801c3,0x80e1c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf8,0x1f070007,0xc03803ff,0xc1c001f0,
03375 0xf80000,0xfffff00,0x7ffff803,0xffffc01f,0xfffe00ff,0xfff007ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,
03376 0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f00f,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e,0xf003c0f0,
03377 0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1ffffc,0xf003f8,0xf800780,0x7c003c03,0xe001e01f,0xf00f8,0x7807c0,0x3c0fc1e,0xf000,
03378 0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,
03379 0xf0003c0,0x78001e00,0x1e,0x1e07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783c,0x1e0007,0x801e0f00,0x0,0x0,0x0,0x0,0x0,0x0,
03380 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xffff8000,0x303c0001,
03381 0xc071e007,0xcf000000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0xf,0xf00,0x780001e,0x7e0,0x7,0x83fffffc,0x1e0,0x7c000f00,0x1f0001e,
03382 0x3c000,0x3c0000,0x0,0x3ff,0x801fffff,0xf003ff80,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007,
03383 0x80007800,0x780,0x3c01f000,0x7800001e,0xf078,0x79e03c0,0xf00780,0xf000,0x3e078007,0xc000000f,0xf000,0xf0003c0,0x3c3c001,
03384 0xee0ef000,0xf03e0000,0x7800003e,0x3c,0x78,0x1e0,0x0,0x0,0x0,0xf8003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,
03385 0x80003c00,0xf000,0x7c3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfc,0x3c000,0x3c003c0,0x3c3e001,0xe7b8f000,
03386 0x3fe00007,0xc7c0000f,0xc000003e,0xf0,0x7c0,0x0,0x0,0x7c00000,0x7fcffc00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0,0x1e000003,
03387 0xc00f0007,0xfcffc003,0xe00001ff,0x3ff00ff9,0xff800000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x1f800000,0xf0f0078,0x7fcff,
03388 0xc000fc00,0x1e000,0x0,0x780001,0xe0180000,0xf000000f,0x87c00007,0x80000000,0xfe3,0xe0000000,0x18780c3,0x0,0x7c0f800,0x1e00,
03389 0xc3,0x80e18000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x1f0,0x3e00000f,0xc0000303,0xe00003f0,0xf00000,0xfffff80,
03390 0x7ffffc03,0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,
03391 0x3c000001,0xe0001e00,0x780f00f,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1f0f801f,0xe00780f0,0x3c0780,0x1e03c00,
03392 0xf01e000,0x78000780,0x1ffff8,0xf000f8,0x1f000780,0xf8003c07,0xc001e03e,0xf01f0,0x780f80,0x3c1f01e,0xf000,0x1e0000,0xf00000,
03393 0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,
03394 0x1e,0x3c07803c,0x3c01e0,0x1e00f00,0xf007800,0x78007c7c,0x1e0007,0x801f1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03395 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x81c00000,0x303c0003,0x8039e003,0xef000000,
03396 0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0xfc0,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000,
03397 0x0,0x7f,0xe01fffff,0xf00ffc00,0x3c000,0x781f00f0,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007,0x80007800,
03398 0x780,0x3c01f000,0x7800001e,0xf078,0x7de01e0,0xf00780,0x7800,0x3c078003,0xc000000f,0xf000,0xf0003c0,0x3e7c001,0xee0ef001,
03399 0xf01e0000,0x7800003e,0x3c,0x3c,0x1e0,0x0,0x0,0x0,0xf0003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00,
03400 0xf000,0x781f000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0x7df00003,
03401 0xc780000f,0x8000003e,0xf0,0x780,0x0,0x0,0x3c00000,0x3fcff800,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x1f00fc,0x1e0,0x1e000001,
03402 0xe00f0003,0xfcff8003,0xe00000ff,0x3fe007f9,0xff000000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x7c00000,0xf0f0078,0x3fcff,0x8000f800,
03403 0x1e000,0x0,0x780001,0xe0180000,0xf000001f,0xffe00007,0x8000003c,0x7ff,0xc0000000,0x1c3ffc7,0x0,0x3e07c00,0x1e00,0xe3,0x80738000,
03404 0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x3e0,0x7c00001d,0xc0000001,0xe0000770,0x1f00000,0xfffff80,0x7ffffc03,
03405 0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
03406 0xe0001e00,0x780f00f,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0x3e07c01f,0xc00780f0,0x3c0780,0x1e03c00,0xf01e000,
03407 0x78000780,0x1fffc0,0xf0007c,0x1e000780,0xf0003c07,0x8001e03c,0xf01e0,0x780f00,0x3c1e01e,0xf000,0x1e0000,0xf00000,0x7800000,
03408 0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1e,0x7807803c,
03409 0x3c01e0,0x1e00f00,0xf007800,0x78003c78,0x1e0007,0x800f1e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03410 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x83c00000,0x303c0003,0x8039e001,0xee000000,0x1e00,0x3c00,
03411 0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0x1f80,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000,0x0,0x1f,0xfc1fffff,
03412 0xf07ff000,0x0,0x780f00f0,0x78003c03,0xc000781e,0x1e0,0xf803c0,0x1e00,0x1e000,0x781e0007,0x80007800,0x780,0x3c00f800,0x7800001e,
03413 0xf078,0x3de01e0,0xf00780,0x7800,0x3c078003,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfe0ff003,0xe01f0000,0x7800007c,0x3c,0x3c,
03414 0x1e0,0x0,0x0,0x0,0xf0007c01,0xe000f80f,0x800001e0,0xf80f00,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x780f800,0x1e0000f,
03415 0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003c00,0x1e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0xf8f80003,0xe780001f,0x1e,
03416 0xf0,0x780,0x0,0x0,0x3c00000,0x1ffff000,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x3bc1de,0x1e0,0xf000001,0xe00f0001,0xffff0007,0xc000007f,
03417 0xffc003ff,0xfe000000,0x0,0x0,0x0,0xfe000,0x0,0x0,0x0,0x0,0x3c00000,0x1e0f0078,0x1ffff,0x1f000,0x1e000,0x0,0x780000,0xf0180000,
03418 0xf000001f,0xfff00007,0x8000003c,0x1ff,0x80000000,0xe0ff0e,0x0,0x1f03e00,0x1e00,0x70,0x70000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,
03419 0xe1c00,0x0,0x0,0x0,0x7c0,0xf8000019,0xc0000000,0xe0000670,0x1e00000,0xf000780,0x78003c03,0xc001e01e,0xf00f0,0x780780,0x3c0f807,
03420 0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf80f007,0xbc03c001,0xe01e000f,
03421 0xf00078,0x78003c0,0x3c001e00,0x7c03e00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,
03422 0xf0007c07,0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0xf800,0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,
03423 0xf0001e00,0x7803c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1f8001f,0xf00f803c,0x3c01e0,0x1e00f00,0xf007800,
03424 0x78003e78,0x1e000f,0x800f9e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03425 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x3c00000,0x303c0003,0x8039f001,0xfe000000,0x1e00,0x3c00,0x0,0x1e0000,0x0,0x0,0x3c,0xf00,
03426 0x780001e,0x3f00,0x7,0x80000780,0x3e0,0x3e000f00,0x3c0001e,0x3c000,0x7c0000,0x0,0x3,0xfe000000,0xff8000,0x0,0x3c0f81f0,0xf0001e03,
03427 0xc000780f,0x1e0,0xf003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x780,0x3c007c00,0x7800001e,0xf078,0x3de01e0,0xf00780,0x7800,
03428 0x3c078001,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfc07f003,0xe00f0000,0x78000078,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01,
03429 0xf000f007,0x800000f0,0xf80780,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,
03430 0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78001,0xe71df000,0xf8f80001,0xef80003e,0x1e,0xf0,0x780,0x0,0x0,0x3c00000,
03431 0xfffe000,0x0,0x3e000000,0x0,0x18,0x7fff,0xc0000000,0x60c306,0x1e0,0x7800001,0xe00f0000,0xfffe0007,0x8000003f,0xff8001ff,
03432 0xfc000000,0x0,0x0,0x0,0x7c000,0x0,0x0,0x0,0x0,0x3c00000,0x3c0f0078,0xfffe,0x3e000,0x1e000,0x0,0x780000,0xf0180000,0xf000003c,
03433 0xfcf80007,0x8000003c,0x7f,0x0,0x70001c,0x0,0xf81f00,0x0,0x38,0xe0000,0x0,0x0,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf81,
03434 0xf0000039,0xc0000000,0xe0000e70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,0x8000f000,0x78000,
03435 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f007,0xbc03c001,0xe01e000f,0xf00078,0x78003c0,
03436 0x3c001e00,0xf801f00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07,0x8003e03c,
03437 0x1f01e0,0xf80f00,0x7c1e01e,0x7800,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00,
03438 0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xe00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef8,0x1f000f,
03439 0x7be00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03440 0x0,0x0,0xf,0x3c00000,0x307c0003,0x8038f000,0xfc000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e00003c,0x780,0xf00001e,
03441 0x7e00,0xf,0x80000780,0x3c0,0x3e001e00,0x3c0001f,0x7c000,0x780007,0xe000003f,0x0,0xfe000000,0xfe0000,0x0,0x3c07c3f0,0xf0001e03,
03442 0xc000f80f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x4000f80,0x3c003c00,0x7800001e,0xf078,0x1fe01f0,0x1f00780,
03443 0x7c00,0x7c078001,0xf000001f,0xf000,0xf0003c0,0x1e78001,0xfc07f007,0xc00f8000,0x780000f8,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01,
03444 0xf000f007,0xc00000f0,0xf80780,0x3c,0x1f003,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,
03445 0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78000,0xfe0fe001,0xf07c0001,0xef00007c,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,
03446 0x7cfc000,0xfc00000,0x3c00000f,0xc3f00000,0x18,0x7fff,0xc0000000,0x406303,0x3e0,0x3c00001,0xf00f0000,0x7cfc000f,0x8000001f,
03447 0x3f0000f9,0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x780700f8,0x7cfc,0x7c000,0x1e000,0x0,0x780000,0xf8180000,
03448 0xf0000070,0x3c0007,0x8000003c,0x3f,0x80000000,0x3c0078,0x0,0x780f00,0x0,0x1e,0x3c0000,0x0,0x0,0x0,0x0,0x0,0x3e007c0,0xe1c00,
03449 0x0,0x0,0x0,0xf01,0xe0000071,0xc0000000,0xe0001c70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,
03450 0x8000f800,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00f003,0xfc03e003,0xe01f001f,
03451 0xf800f8,0x7c007c0,0x3e003e01,0xf000f80f,0xf00f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07,
03452 0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0x7c00,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00,
03453 0xf003c00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xc00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef0,
03454 0x1f000f,0x7bc00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03455 0x0,0x0,0x0,0x0,0x780000,0xf,0x3800040,0x30780003,0x8038f800,0x78000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078,
03456 0x780,0x1f00001e,0xfc00,0x20001f,0x780,0x80007c0,0x1f001e00,0x7c0000f,0x78000,0xf80007,0xe000003f,0x0,0x1e000000,0xf00000,
03457 0x3c000,0x3c03fff0,0xf0001e03,0xc001f007,0x800101e0,0x7e003c0,0x1e00,0x7800,0x781e0007,0x80007800,0x6000f00,0x3c003e00,0x7800001e,
03458 0xf078,0x1fe00f0,0x1e00780,0x3c00,0x78078000,0xf020001e,0xf000,0x7800780,0xff0001,0xfc07f00f,0x8007c000,0x780001f0,0x3c,0xf,
03459 0x1e0,0x0,0x0,0x0,0xf800fc01,0xf801f007,0xc00100f8,0x1f807c0,0x40003c,0xf807,0xf0078007,0x80003c00,0xf000,0x7803e00,0x1f0000f,
03460 0x3c0f01e,0x1e01f0,0x3e007e0,0x7c07c00,0xfc003c00,0x1e,0x3e000,0x3e007c0,0x1ff8000,0xfe0fe003,0xe03e0001,0xff0000fc,0x1e,
03461 0xf0,0x780,0x0,0x0,0x1f00080,0x3cf8000,0xfc00000,0x3c00001f,0x83f00000,0x18,0xc0,0x0,0xc06203,0x40003c0,0x1c00000,0xf80f0000,
03462 0x3cf8001f,0xf,0x3e000079,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x700780fc,0x3cf8,0xfc000,0x1e000,0x0,0x780000,
03463 0x7c180000,0xf0000020,0x100007,0x8000003c,0xf,0x80000000,0x1f01f0,0x0,0x380700,0x0,0xf,0x80f80000,0x0,0x0,0x0,0x0,0x0,0x3e007c0,
03464 0xe1c00,0x0,0x0,0x0,0xe01,0xc0000071,0xc0000001,0xc0001c70,0x1e00040,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,
03465 0x80007800,0x10078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00f003,0xfc01e003,0xc00f001e,
03466 0x7800f0,0x3c00780,0x1e003c00,0xe000700f,0x800f0078,0x7803c0,0x3c01e00,0x1e00f000,0xf0000780,0x1e0000,0xf0003c,0x1f001f80,
03467 0xf800fc07,0xc007e03e,0x3f01f0,0x1f80f80,0xfc1e01f,0x7c00,0x100f8000,0x807c0004,0x3e00020,0x1f000100,0x780000,0x3c00000,0x1e000000,
03468 0xf0000f80,0x1f003c00,0x3c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00,0x1f8000f,0x801f003e,0x7c01f0,0x3e00f80,0x1f007c00,
03469 0xf8001ff0,0x1f801f,0x7fc00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03470 0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0xf,0x7800078,0x31f80001,0xc070fc00,0xfc000000,0x1e00,0x7c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078,
03471 0x7c0,0x1f00001e,0x1f000,0x38003f,0x780,0xe000f80,0x1f803e00,0x780000f,0x800f8000,0x1f00007,0xe000003f,0x0,0x2000000,0x800000,
03472 0x3c000,0x3e01ff71,0xf0001f03,0xc007f007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x781e0007,0x80007800,0x7801f00,0x3c001f00,0x7800001e,
03473 0xf078,0xfe00f8,0x3e00780,0x3e00,0xf8078000,0xf838003e,0xf000,0x7c00f80,0xff0000,0xfc07e00f,0x8003c000,0x780001e0,0x3c,0xf,
03474 0x1e0,0x0,0x0,0x0,0xf801fc01,0xfc03e003,0xe003007c,0x3f803e0,0x1c0003c,0xfc0f,0xf0078007,0x80003c00,0xf000,0x7801f00,0xf8000f,
03475 0x3c0f01e,0x1e00f8,0x7c007f0,0xf803e01,0xfc003c00,0x8003e,0x1f000,0x1e00fc0,0xff0000,0xfe0fe007,0xc01f0000,0xfe0000f8,0x1e,
03476 0xf0,0x780,0x0,0x0,0xf80180,0x1cf0000,0x1f800000,0x3c00001f,0x83e00000,0x18,0xc0,0x0,0xc06203,0x70007c0,0xe00000,0x7e0f0000,
03477 0x1cf0001e,0x7,0x3c000039,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x7c00000,0xe00780fc,0x2001cf0,0xf8000,0x1e000,0x0,
03478 0x780000,0x7e182000,0xf0000000,0x7,0x8000003c,0x7,0xc0000000,0x7ffc0,0x0,0x180300,0x0,0x3,0xffe00000,0x0,0x0,0x0,0x0,0x0,
03479 0x3f00fc0,0xe1c00,0x0,0x0,0x0,0xc01,0x800000e1,0xc0000003,0xc0003870,0x1f001c0,0x3e0003e1,0xf0001f0f,0x8000f87c,0x7c3e0,0x3e1f00,
03480 0x1f1e007,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e03,0xfc00f001,0xfc01f007,
03481 0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x4000201f,0xc01f007c,0xf803e0,0x7c01f00,0x3e00f801,0xf0000780,0x1e0000,0xf0007c,
03482 0x1f003f80,0xf801fc07,0xc00fe03e,0x7f01f0,0x3f80f80,0x1fc1f03f,0x803e00,0x3007c003,0x803e001c,0x1f000e0,0xf800700,0x780000,
03483 0x3c00000,0x1e000000,0xf00007c0,0x3e003c00,0x3c01f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e001e,0xfc00f0,
03484 0x7e00780,0x3f003c01,0xf8000fe0,0x1fc03e,0x3f800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03485 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x780007f,0xfff00001,0xe0f07f03,0xfe000000,0xf00,0x7800,0x0,
03486 0x1e0000,0xfc0000,0x0,0x7e0000f0,0x3f0,0x7e000fff,0xfc03ffff,0xf83f00fe,0x780,0xfc03f80,0xfc0fc00,0xf800007,0xe03f0018,0x7e00007,
03487 0xe000003f,0x0,0x0,0x0,0x3c000,0x1e007c71,0xe0000f03,0xffffe003,0xf01f01ff,0xff8003ff,0xffe01e00,0x3f01,0xf81e0007,0x803ffff0,
03488 0x7e03f00,0x3c000f00,0x7ffffe1e,0xf078,0xfe007e,0xfc00780,0x1f83,0xf0078000,0x783f00fe,0xf000,0x3f03f00,0xff0000,0xfc07e01f,
03489 0x3e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7e07fc01,0xfe07e001,0xf80f007e,0x7f801f8,0xfc0003c,0x7ffe,0xf0078007,
03490 0x807ffffe,0xf000,0x7801f00,0xfff00f,0x3c0f01e,0x1e00fc,0xfc007f8,0x1f803f03,0xfc003c00,0xf80fc,0x1fff0,0x1f83fc0,0xff0000,
03491 0xfc07e007,0xc01f0000,0xfe0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfe0780,0xfe0000,0x1f000000,0x3c00001f,0x7c00e03,0x81c00018,
03492 0xc0,0x0,0x406203,0x7e01fc0,0x700000,0x7fffff80,0xfe0003f,0xffffc003,0xf800001f,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0,
03493 0x1f800001,0xc007c1fe,0x6000fe0,0x1ffffe,0x1e000,0x0,0x780000,0x3f98e03f,0xffff8000,0x7,0x8000003c,0x7,0xc0000000,0xfe00,
03494 0x0,0x80100,0x0,0x0,0x7f000000,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3f83fe8,0xe1c00,0x0,0x0,0x0,0x801,0xc1,0xc0000007,0x80003070,
03495 0xfc0fc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc03f01,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,
03496 0xffff001f,0xfff800ff,0xffc01fff,0xf800f001,0xfc00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800,0x1f,0xf07e003f,0x3f001f8,
03497 0x1f800fc0,0xfc007e07,0xe0000780,0x1e0000,0xf301f8,0xfc0ff80,0x7e07fc03,0xf03fe01f,0x81ff00fc,0xff807e0,0x7fc0f87f,0x81801f80,
03498 0xf003f01f,0x801f80fc,0xfc07e0,0x7e03f00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff807e0,0x7e003c00,0x3c01f81f,0x800fc0fc,0x7e07e0,
03499 0x3f03f00,0x1f81f800,0x1f8000f,0xe07e001f,0x83fc00fc,0x1fe007e0,0xff003f07,0xf8000fe0,0x1fe07e,0x3f800,0x0,0x0,0x0,0x0,0x0,
03500 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x780007f,
03501 0xffe00000,0xffe03fff,0xdf000000,0xf00,0x7800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0x1ff,0xfc000fff,0xfc03ffff,0xf83ffffc,0x780,
03502 0xfffff00,0x7fff800,0xf000007,0xffff001f,0xffe00007,0xe000003f,0x0,0x0,0x0,0x3c000,0x1e000001,0xe0000f03,0xffffc001,0xffff01ff,
03503 0xff0003ff,0xffe01e00,0x1fff,0xf81e0007,0x803ffff0,0x7fffe00,0x3c000f80,0x7ffffe1e,0xf078,0xfe003f,0xff800780,0xfff,0xf0078000,
03504 0x7c3ffffc,0xf000,0x3ffff00,0xff0000,0xf803e01e,0x1e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7fffbc01,0xffffc000,
03505 0xffff003f,0xfff800ff,0xffc0003c,0x3ffe,0xf0078007,0x807ffffe,0xf000,0x7800f80,0x7ff00f,0x3c0f01e,0x1e007f,0xff8007ff,0xff001fff,
03506 0xbc003c00,0xffffc,0x1fff0,0x1fffbc0,0xff0000,0x7c07c00f,0x800f8000,0x7e0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7fff80,0x7c0000,
03507 0x1f000000,0x3c00001e,0x7c00f07,0xc1e00018,0xc0,0x0,0x60e303,0x7ffff80,0x380000,0x3fffff80,0x7c0003f,0xffffc001,0xf000000f,
03508 0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff800003,0x8003ffff,0xfe0007c0,0x1ffffe,0x1e000,0x0,0x780000,0x1fffe03f,0xffff8000,
03509 0x7,0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3fffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x1c1,
03510 0xc000000f,0x7070,0x7fffc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0,
03511 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000f001,0xfc007fff,0x3fff8,0x1fffc0,0xfffe00,0x7fff000,0x3b,0xfffc003f,
03512 0xfff001ff,0xff800fff,0xfc007fff,0xe0000780,0x1e0000,0xf3fff8,0xffff780,0x7fffbc03,0xfffde01f,0xffef00ff,0xff7807ff,0xfbc0ffff,
03513 0xff800fff,0xf001ffff,0x800ffffc,0x7fffe0,0x3ffff00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff803ff,0xfc003c00,0x3c00ffff,0x7fff8,
03514 0x3fffc0,0x1fffe00,0xffff000,0x1f,0xfffc001f,0xffbc00ff,0xfde007ff,0xef003fff,0x780007e0,0x1ffffc,0x1f800,0x0,0x0,0x0,0x0,
03515 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x700003f,
03516 0xffc00000,0x7fc01fff,0x9f800000,0xf80,0xf800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0xff,0xf8000fff,0xfc03ffff,0xf83ffff8,0x780,
03517 0xffffe00,0x7fff000,0xf000003,0xfffe001f,0xffc00007,0xe000003f,0x0,0x0,0x0,0x3c000,0xf000003,0xe0000f83,0xffff0000,0xffff01ff,
03518 0xfc0003ff,0xffe01e00,0xfff,0xf01e0007,0x803ffff0,0x7fffc00,0x3c0007c0,0x7ffffe1e,0xf078,0x7e003f,0xff000780,0x7ff,0xe0078000,
03519 0x3c3ffff8,0xf000,0x1fffe00,0x7e0000,0xf803e03e,0x1f000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x3fff3c01,0xefff8000,
03520 0x7ffe001f,0xff78007f,0xff80003c,0x1ffc,0xf0078007,0x807ffffe,0xf000,0x78007c0,0x3ff00f,0x3c0f01e,0x1e003f,0xff0007bf,0xfe000fff,
03521 0xbc003c00,0xffff8,0xfff0,0xfff3c0,0x7e0000,0x7c07c01f,0x7c000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3fff80,0x380000,
03522 0x3e000000,0x7c00003e,0x7801f07,0xc1e00018,0xc0,0x0,0x39c1ce,0x7ffff00,0x1c0000,0xfffff80,0x380003f,0xffffc000,0xe0000007,
03523 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff000007,0x1ffcf,0xfe000380,0x1ffffe,0x1e000,0x0,0x780000,0xfffe03f,0xffff8000,0x7,
03524 0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x381,
03525 0xc000001e,0xe070,0x7fff80,0x7c0001f3,0xe0000f9f,0x7cf8,0x3e7c0,0x1f3e00,0xfbe007,0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0,
03526 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000f000,0xfc007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x79,0xfff8001f,
03527 0xffe000ff,0xff0007ff,0xf8003fff,0xc0000780,0x1e0000,0xf3fff0,0x7ffe780,0x3fff3c01,0xfff9e00f,0xffcf007f,0xfe7803ff,0xf3c07ff3,
03528 0xff8007ff,0xe000ffff,0x7fff8,0x3fffc0,0x1fffe00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff801ff,0xf8003c00,0x3c007ffe,0x3fff0,
03529 0x1fff80,0xfffc00,0x7ffe000,0x1d,0xfff8000f,0xff3c007f,0xf9e003ff,0xcf001ffe,0x780007c0,0x1efff8,0x1f000,0x0,0x0,0x0,0x0,
03530 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0xf000003,
03531 0xfe000000,0x1f000fff,0xfc00000,0x780,0xf000,0x0,0x0,0xf80000,0x0,0x7e0001e0,0x7f,0xf0000fff,0xfc03ffff,0xf81ffff0,0x780,
03532 0x7fff800,0x1ffe000,0x1f000000,0xfff8001f,0xff000007,0xe000003e,0x0,0x0,0x0,0x3c000,0xf800003,0xc0000783,0xfff80000,0x3ffe01ff,
03533 0xe00003ff,0xffe01e00,0x7ff,0xc01e0007,0x803ffff0,0x3fff800,0x3c0003c0,0x7ffffe1e,0xf078,0x7e000f,0xfe000780,0x3ff,0xc0078000,
03534 0x3e1fffe0,0xf000,0x7ff800,0x7e0000,0xf803e07c,0xf800,0x780003ff,0xfffc003c,0x3,0xc00001e0,0x0,0x0,0x0,0xffe3c01,0xe7ff0000,
03535 0x3ffc000f,0xfe78003f,0xfe00003c,0x7f0,0xf0078007,0x807ffffe,0xf000,0x78003e0,0xff00f,0x3c0f01e,0x1e001f,0xfe00079f,0xfc0007ff,
03536 0x3c003c00,0x7ffe0,0x1ff0,0x7fe3c0,0x7e0000,0x7c07c03e,0x3e000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfff00,0x100000,
03537 0x3e000000,0x7800003c,0xf800f07,0xc1e00018,0xc0,0x0,0x1f80fc,0x3fffc00,0xc0000,0x3ffff80,0x100003f,0xffffc000,0x40000002,
03538 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xfc000006,0xff87,0xfc000100,0x1ffffe,0x1e000,0x0,0x780000,0x3ffc03f,0xffff8000,0x7,
03539 0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dff9f8,0xe1c00,0x0,0x0,0x0,0x0,0x3ff,
03540 0xf800003c,0xfffe,0x1ffe00,0x780000f3,0xc000079e,0x3cf0,0x1e780,0xf3c00,0x7bc007,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0,
03541 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc,0xf000,0xfc001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x70,0xfff00007,
03542 0xff80003f,0xfc0001ff,0xe0000fff,0x780,0x1e0000,0xf3ffe0,0x1ffc780,0xffe3c00,0x7ff1e003,0xff8f001f,0xfc7800ff,0xe3c03fe1,
03543 0xff0003ff,0xc0007ffc,0x3ffe0,0x1fff00,0xfff800,0xfffffc07,0xffffe03f,0xffff01ff,0xfff800ff,0xf0003c00,0x3c003ffc,0x1ffe0,
03544 0xfff00,0x7ff800,0x3ffc000,0x38,0xfff00007,0xfe3c003f,0xf1e001ff,0x8f000ffc,0x780007c0,0x1e7ff0,0x1f000,0x0,0x0,0x0,0x0,0x0,
03545 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,
03546 0x1fc,0x0,0x780,0xf000,0x0,0x0,0x1f80000,0x0,0x1e0,0x1f,0xc0000000,0x0,0x1ff80,0x0,0xffc000,0x7f8000,0x0,0x3fe00007,0xfc000000,
03547 0x7e,0x0,0x0,0x0,0x0,0x7c00000,0x0,0x0,0xff00000,0x0,0x0,0xfe,0x0,0x0,0x3fc000,0x0,0x0,0x0,0x3,0xf8000000,0xff,0xc0000000,
03548 0x1ff00,0x0,0x1fe000,0x0,0x0,0x0,0x0,0x3c,0x3,0xc00001e0,0x0,0x0,0x0,0x3f80000,0x1fc0000,0x7f00003,0xf8000007,0xf0000000,
03549 0x0,0xf0000000,0x0,0xf000,0x0,0x0,0x0,0x7,0xf8000787,0xf00001fc,0x3c000000,0x7f80,0x0,0x1f8000,0x0,0x0,0x0,0x7c000000,0x1e,
03550 0xf0,0x780,0x0,0x0,0x3fc00,0x0,0x3c000000,0x7800003c,0xf000601,0xc00018,0xc0,0x0,0x0,0x3fe000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03551 0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xf0000000,0x7e03,0xf0000000,0x0,0x0,0x0,0x0,0xfe0000,0x0,0x0,0x3c,0x2007,0x80000000,0x0,0x0,
03552 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c7e0f0,0xe1c00,0x0,0x3800000,0x0,0x0,0x3ff,0xf8000078,0xfffe,0x7f800,0x0,0x0,0x0,0x0,
03553 0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000,0x7f0000,0x70,0x3fc00001,0xfe00000f,0xf000007f,
03554 0x800003fc,0x0,0x0,0xff00,0x7f0000,0x3f80000,0x1fc00000,0xfe000007,0xf000003f,0x80001f80,0xfc00007f,0xfe0,0x7f00,0x3f800,
03555 0x1fc000,0x0,0x0,0x0,0x3f,0xc0000000,0xff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x78,0x3fc00001,0xf800000f,0xc000007e,0x3f0,0x7c0,
03556 0x1e1fc0,0x1f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03557 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x3c0,0x1e000,0x0,0x0,0x1f00000,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03558 0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0x3e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xe0000000,0x0,0x0,0x0,
03559 0x0,0x0,0x0,0x0,0x3c,0x1,0xe00001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,
03560 0x0,0x0,0x0,0x0,0x0,0x0,0x78000000,0x1e,0xf0,0x780,0x0,0x0,0x0,0x0,0x3c000000,0x78000078,0xf000000,0x18,0xc0,0x0,0x0,0x0,
03561 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x3c0f,0x80000000,
03562 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0x1800000,0x0,0x0,0x3ff,0xf80000f0,0xfffe,0x0,0x0,0x0,0x0,
03563 0x0,0x0,0x0,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03564 0x0,0x0,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x780,0x1e0000,0x1e000,0x0,0x0,0x0,
03565 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,
03566 0x0,0x0,0x3c0,0x1e000,0x0,0x0,0x1f00000,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0x1f80000,
03567 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x1,0xe00001e0,0x0,
03568 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe0000000,0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0xf8000000,
03569 0x1f,0xf0,0xf80,0x0,0x0,0x0,0x0,0x78000000,0xf8000078,0x1e000000,0x8,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03570 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x3fff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03571 0x0,0x3c00000,0xe1c00,0x0,0x1c00000,0x0,0x0,0x1,0xc00001e0,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03572 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03573 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80,0x1e0000,0x3e000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03574 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x1e0,0x3c000,0x0,0x0,0x1f00000,
03575 0x0,0x780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0xfe0100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03576 0x0,0x0,0x0,0x0,0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0xf0007fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe0000000,
03577 0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x1f,0x800000f0,0x1f80,0x0,0x0,0x0,0x0,
03578 0x78000000,0xf0000070,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03579 0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x3ffe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0xe00000,
03580 0x0,0x0,0x1,0xc00003ff,0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03581 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03582 0x0,0x0,0x0,0xf00,0x1e0000,0x3c000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03583 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x1e0,0x7c000,0x0,0x0,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03584 0x0,0x0,0x0,0x0,0x0,0x78,0x0,0x0,0x0,0x0,0x7fff80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78000000,
03585 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4003,0xe0000000,0x0,0x1f000,0x0,0x0,
03586 0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x1,0xf0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0x70000001,0xf00000e0,
03587 0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,
03588 0x0,0x0,0x3c,0xff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0xe00000,0x0,0x0,0x1,0xc00003ff,
03589 0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03590 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00,0x1e0000,
03591 0x7c000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03592 0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0xf0,0x78000,0x0,0x0,0x3e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,
03593 0x0,0x0,0x0,0x1fff80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,
03594 0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780f,0xc0000000,0x0,0x3e000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,
03595 0x0,0x0,0x0,0x0,0x3,0xe0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0xf0000103,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03596 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,
03597 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x21e00000,0x0,0x0,0x1,0xc00003ff,0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10f,
03598 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10f,0x0,
03599 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e00,0x1e0000,0xf8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03600 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,
03601 0xf8,0xf8000,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x1fe00,0x0,0x0,0x0,0x0,
03602 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,
03603 0x0,0x0,0x7fff,0xc0000000,0x0,0x3ffe000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0xe0000000,0x7,0xfc0000f0,
03604 0x3fe00,0x0,0x0,0x0,0x0,0x600001ff,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03605 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,
03606 0x3fe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03607 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03608 0x0,0x0,0x0,0x0,0x7fe00,0x1e0000,0x1ff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03609 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03610 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03611 0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fff,0x80000000,0x0,0x3ffc000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,
03612 0x0,0x0,0x0,0x0,0x7f,0xc0000000,0x0,0xfc0000f0,0x3f000,0x0,0x0,0x0,0x0,0x1ff,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03613 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03614 0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x3fc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fe,0x0,0x0,0x0,0x0,0x0,
03615 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fe,0x0,0x0,0x0,0x0,0x0,0x0,
03616 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fc00,0x1e0000,0x1ff0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03617 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03618 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03619 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x3ffe,0x0,0x0,0x3ff8000,0x0,0x0,0x0,
03620 0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0x80000000,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x80000000,0x0,0x0,0x0,0x0,
03621 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03622 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x3f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fc,0x0,
03623 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fc,0x0,0x0,
03624 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f800,0x1e0000,0x1fe0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03625 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03626 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03627 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f8,0x0,0x0,0x3fe0000,
03628 0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7e,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,
03629 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03630 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03631 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03632 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7e000,0x1e0000,0x1f80000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03633 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03634 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03635 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03636 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03637 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03638 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03639 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03640 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03641 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03642 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03643 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,
03644 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03645 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03646 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03647 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
03648
03649
03650 const unsigned char logo40x38[4576] = {
03651 177,200,200,200,3,123,123,0,36,200,200,200,1,123,123,0,2,255,255,0,1,189,189,189,1,0,0,0,34,200,200,200,
03652 1,123,123,0,4,255,255,0,1,189,189,189,1,0,0,0,1,123,123,123,32,200,200,200,1,123,123,0,5,255,255,0,1,0,0,
03653 0,2,123,123,123,30,200,200,200,1,123,123,0,6,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,29,200,200,200,
03654 1,123,123,0,7,255,255,0,1,0,0,0,2,123,123,123,28,200,200,200,1,123,123,0,8,255,255,0,1,189,189,189,1,0,0,0,
03655 2,123,123,123,27,200,200,200,1,123,123,0,9,255,255,0,1,0,0,0,2,123,123,123,26,200,200,200,1,123,123,0,10,255,
03656 255,0,1,189,189,189,1,0,0,0,2,123,123,123,25,200,200,200,1,123,123,0,3,255,255,0,1,189,189,189,3,0,0,0,1,189,
03657 189,189,3,255,255,0,1,0,0,0,2,123,123,123,24,200,200,200,1,123,123,0,4,255,255,0,5,0,0,0,3,255,255,0,1,189,
03658 189,189,1,0,0,0,2,123,123,123,23,200,200,200,1,123,123,0,4,255,255,0,5,0,0,0,4,255,255,0,1,0,0,0,2,123,123,123,
03659 22,200,200,200,1,123,123,0,5,255,255,0,5,0,0,0,4,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,21,200,200,200,
03660 1,123,123,0,5,255,255,0,5,0,0,0,5,255,255,0,1,0,0,0,2,123,123,123,20,200,200,200,1,123,123,0,6,255,255,0,5,0,0,
03661 0,5,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,19,200,200,200,1,123,123,0,6,255,255,0,1,123,123,0,3,0,0,0,1,
03662 123,123,0,6,255,255,0,1,0,0,0,2,123,123,123,18,200,200,200,1,123,123,0,7,255,255,0,1,189,189,189,3,0,0,0,1,189,
03663 189,189,6,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,17,200,200,200,1,123,123,0,8,255,255,0,3,0,0,0,8,255,255,
03664 0,1,0,0,0,2,123,123,123,16,200,200,200,1,123,123,0,9,255,255,0,1,123,123,0,1,0,0,0,1,123,123,0,8,255,255,0,1,189,
03665 189,189,1,0,0,0,2,123,123,123,15,200,200,200,1,123,123,0,9,255,255,0,1,189,189,189,1,0,0,0,1,189,189,189,9,255,255,
03666 0,1,0,0,0,2,123,123,123,14,200,200,200,1,123,123,0,11,255,255,0,1,0,0,0,10,255,255,0,1,189,189,189,1,0,0,0,2,123,
03667 123,123,13,200,200,200,1,123,123,0,23,255,255,0,1,0,0,0,2,123,123,123,12,200,200,200,1,123,123,0,11,255,255,0,1,189,
03668 189,189,2,0,0,0,1,189,189,189,9,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,11,200,200,200,1,123,123,0,11,255,255,
03669 0,4,0,0,0,10,255,255,0,1,0,0,0,2,123,123,123,10,200,200,200,1,123,123,0,12,255,255,0,4,0,0,0,10,255,255,0,1,189,189,
03670 189,1,0,0,0,2,123,123,123,9,200,200,200,1,123,123,0,12,255,255,0,1,189,189,189,2,0,0,0,1,189,189,189,11,255,255,0,1,
03671 0,0,0,2,123,123,123,9,200,200,200,1,123,123,0,27,255,255,0,1,0,0,0,3,123,123,123,8,200,200,200,1,123,123,0,26,255,
03672 255,0,1,189,189,189,1,0,0,0,3,123,123,123,9,200,200,200,1,123,123,0,24,255,255,0,1,189,189,189,1,0,0,0,4,123,123,
03673 123,10,200,200,200,1,123,123,0,24,0,0,0,5,123,123,123,12,200,200,200,27,123,123,123,14,200,200,200,25,123,123,123,86,
03674 200,200,200,91,49,124,118,124,71,32,124,95,49,56,114,52,82,121,0};
03675
03676
03677 inline void warn(const char *format,...) {
03678 if (cimg::exception_mode()>=1) {
03679 char message[8192];
03680 std::va_list ap;
03681 va_start(ap,format);
03682 std::vsprintf(message,format,ap);
03683 va_end(ap);
03684 #ifdef cimg_strict_warnings
03685 throw CImgWarningException(message);
03686 #else
03687 std::fprintf(stderr,"\n<CImg Warning> %s\n",message);
03688 #endif
03689 }
03690 }
03691
03692 inline int xln(const int x) {
03693 return x>0?(int)(1+std::log10((double)x)):1;
03694 }
03695
03696 inline char uncase(const char x) {
03697 return (char)((x<'A'||x>'Z')?x:x-'A'+'a');
03698 }
03699
03700 inline float atof(const char *str) {
03701 float x = 0,y = 1;
03702 if (!str) return 0; else { std::sscanf(str,"%g/%g",&x,&y); return x/y; }
03703 }
03704
03705 inline int strlen(const char *s) {
03706 if (s) { int k; for (k=0; s[k]; ++k) ; return k; }
03707 return -1;
03708 }
03709
03710 inline int strncmp(const char *s1, const char *s2, const int l) {
03711 if (s1 && s2) { int n = 0; for (int k=0; k<l; ++k) n+=std::abs(s1[k] - s2[k]); return n; }
03712 return 0;
03713 }
03714
03715 inline int strncasecmp(const char *s1, const char *s2, const int l) {
03716 if (s1 && s2) { int n = 0; for (int k=0; k<l; ++k) n+=std::abs(uncase(s1[k])-uncase(s2[k])); return n; }
03717 return 0;
03718 }
03719
03720 inline int strcmp(const char *s1, const char *s2) {
03721 const int l1 = cimg::strlen(s1), l2 = cimg::strlen(s2);
03722 return cimg::strncmp(s1,s2,1+(l1<l2?l1:l2));
03723 }
03724
03725 inline int strcasecmp(const char *s1, const char *s2) {
03726 const int l1 = cimg::strlen(s1), l2 = cimg::strlen(s2);
03727 return cimg::strncasecmp(s1,s2,1+(l1<l2?l1:l2));
03728 }
03729
03730 inline int strfind(const char *s, const char c) {
03731 if (s) {
03732 int l; for (l=cimg::strlen(s); l>=0 && s[l]!=c; --l) ;
03733 return l;
03734 }
03735 return -1;
03736 }
03737
03738 inline const char* basename(const char *s) {
03739 return (cimg_OS!=2)?(s?s+1+cimg::strfind(s,'/'):0):(s?s+1+cimg::strfind(s,'\\'):0);
03740 }
03741
03743 inline bool endian() {
03744 const int x=1;
03745 return ((unsigned char*)&x)[0]?false:true;
03746 }
03747
03749 inline unsigned long time() {
03750 #if cimg_OS==1
03751 struct timeval st_time;
03752 gettimeofday(&st_time,0);
03753 return (unsigned long)(st_time.tv_usec/1000 + st_time.tv_sec*1000);
03754 #elif cimg_OS==2
03755 static SYSTEMTIME st_time;
03756 GetSystemTime(&st_time);
03757 return (unsigned long)(st_time.wMilliseconds + 1000*(st_time.wSecond + 60*(st_time.wMinute + 60*st_time.wHour)));
03758 #else
03759 return 0;
03760 #endif
03761 }
03762
03764
03769 inline void sleep(const unsigned int milliseconds) {
03770 #if cimg_OS==1
03771 struct timespec tv;
03772 tv.tv_sec = milliseconds/1000;
03773 tv.tv_nsec = (milliseconds%1000)*1000000;
03774 nanosleep(&tv,0);
03775 #elif cimg_OS==2
03776 Sleep(milliseconds);
03777 #endif
03778 }
03779
03780 inline unsigned int wait(const unsigned int milliseconds, unsigned long& timer) {
03781 if (!timer) timer = cimg::time();
03782 const unsigned long current_time = cimg::time();
03783 if (current_time>=timer+milliseconds) { timer = current_time; return 0; }
03784 const unsigned long time_diff = timer + milliseconds - current_time;
03785 timer = current_time + time_diff;
03786 cimg::sleep(time_diff);
03787 return (unsigned int)time_diff;
03788 }
03789
03791
03796 inline unsigned int wait(const unsigned int milliseconds) {
03797 static unsigned long timer = 0;
03798 if (!timer) timer = cimg::time();
03799 return wait(milliseconds,timer);
03800 }
03801
03802
03803
03804 inline void srand() {
03805 static bool first_time = true;
03806 if (first_time) {
03807 std::srand(cimg::time());
03808 unsigned char *const rand_mem = new unsigned char[1+std::rand()%2048];
03809 std::srand((unsigned int)(std::rand() + (unsigned long)rand_mem));
03810 delete[] rand_mem;
03811 first_time = false;
03812 }
03813 }
03814
03815 inline const char *const filenamerand() {
03816 static char id[9] = { 0,0,0,0,0,0,0,0,0 };
03817 cimg::srand();
03818 for (unsigned int k=0; k<8; k++) {
03819 const int v = (int)std::rand()%3;
03820 id[k] = v==0?('0'+(std::rand()%10)):(v==1?('a'+(std::rand()%26)):('A'+(std::rand()%26)));
03821 }
03822 return id;
03823 }
03824
03825 inline void system(const char *command, const char *module_name=0) {
03826 #if cimg_OS==2
03827 PROCESS_INFORMATION pi;
03828 STARTUPINFO si;
03829 std::memset(&pi, 0, sizeof(PROCESS_INFORMATION));
03830 std::memset(&si, 0, sizeof(STARTUPINFO));
03831 GetStartupInfo(&si);
03832 si.cb = sizeof(si);
03833 si.wShowWindow = SW_HIDE;
03834 si.dwFlags |= SW_HIDE;
03835 const BOOL res = CreateProcess((LPCTSTR)module_name,(LPTSTR)command,0,0,FALSE,0,0,0,&si,&pi);
03836 if (res) {
03837 WaitForSingleObject(pi.hProcess, INFINITE);
03838 CloseHandle(pi.hThread);
03839 CloseHandle(pi.hProcess);
03840 } else
03841 #endif
03842 std::system(command);
03843 command = module_name = 0;
03844 }
03845
03846
03847 #if cimg_OS==2
03848 inline void winformat_string(char *const s) {
03849 if (s && s[0]) {
03850 char *const ns = new char[MAX_PATH];
03851 if (GetShortPathNameA(s,ns,MAX_PATH)) std::strcpy(s,ns);
03852 }
03853 }
03854 #else
03855 inline void winformat_string(char *const) {}
03856 #endif
03857
03858
03863 #if cimg_OS==2
03864 inline const char* programfiles_path() {
03865 static char *st_programfiles_path = 0;
03866 if (!st_programfiles_path) {
03867 st_programfiles_path = new char[MAX_PATH];
03868 std::memset(st_programfiles_path,0,MAX_PATH);
03869
03870 #if !defined(__INTEL_COMPILER)
03871 if (!SHGetSpecialFolderPathA(0,st_programfiles_path,0x0026,false)) {
03872 const char *pfPath = getenv("PROGRAMFILES");
03873 if (pfPath) std::strcpy(st_programfiles_path,pfPath);
03874 else std::strcpy(st_programfiles_path,"C:\\PROGRA~1");
03875 }
03876 #else
03877 std::strcpy(st_programfiles_path,"C:\\PROGRA~1");
03878 #endif
03879 }
03880 return st_programfiles_path;
03881 }
03882 #endif
03883
03885
03906 inline const char* imagemagick_path() {
03907 static char *st_imagemagick_path = 0;
03908 if (!st_imagemagick_path) {
03909 st_imagemagick_path = new char[1024];
03910 std::memset(st_imagemagick_path,0,1024);
03911 bool path_found = false;
03912 std::FILE *file = 0;
03913 #ifdef cimg_imagemagick_path
03914 std::strncpy(st_imagemagick_path,cimg_imagemagick_path,1023);
03915 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03916 #endif
03917 #if cimg_OS==2
03918 const char *pf_path = programfiles_path();
03919 if (!path_found) {
03920 std::sprintf(st_imagemagick_path,".\\convert.exe");
03921 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03922 }
03923 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03924 std::sprintf(st_imagemagick_path,"%s\\IMAGEM~1.%u-Q\\convert.exe",pf_path,k);
03925 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03926 }}
03927 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03928 std::sprintf(st_imagemagick_path,"%s\\IMAGEM~1.%u\\convert.exe",pf_path,k);
03929 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03930 }}
03931 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03932 std::sprintf(st_imagemagick_path,"%s\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",pf_path,k);
03933 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03934 }}
03935 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03936 std::sprintf(st_imagemagick_path,"%s\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",pf_path,k);
03937 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03938 }}
03939 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03940 std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u-Q\\convert.exe",k);
03941 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03942 }}
03943 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03944 std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u\\convert.exe",k);
03945 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03946 }}
03947 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03948 std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",k);
03949 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03950 }}
03951 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03952 std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",k);
03953 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03954 }}
03955 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03956 std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u-Q\\convert.exe",k);
03957 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03958 }}
03959 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03960 std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u\\convert.exe",k);
03961 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03962 }}
03963 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03964 std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",k);
03965 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03966 }}
03967 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03968 std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",k);
03969 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03970 }}
03971 if (!path_found) std::strcpy(st_imagemagick_path,"convert.exe");
03972 #else
03973 if (!path_found) {
03974 std::sprintf(st_imagemagick_path,"./convert");
03975 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03976 }
03977 if (!path_found) std::strcpy(st_imagemagick_path,"convert");
03978 #endif
03979 winformat_string(st_imagemagick_path);
03980 }
03981 return st_imagemagick_path;
03982 }
03983
03985
04006 inline const char* graphicsmagick_path() {
04007 static char *st_graphicsmagick_path = 0;
04008 if (!st_graphicsmagick_path) {
04009 st_graphicsmagick_path = new char[1024];
04010 std::memset(st_graphicsmagick_path,0,1024);
04011 bool path_found = false;
04012 std::FILE *file = 0;
04013 #ifdef cimg_graphicsmagick_path
04014 std::strcpy(st_graphicsmagick_path,cimg_graphicsmagick_path);
04015 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04016 #endif
04017 #if cimg_OS==2
04018 const char* pf_path = programfiles_path();
04019 if (!path_found) {
04020 std::sprintf(st_graphicsmagick_path,".\\gm.exe");
04021 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04022 }
04023 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04024 std::sprintf(st_graphicsmagick_path,"%s\\GRAPHI~1.%u-Q\\gm.exe",pf_path,k);
04025 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04026 }}
04027 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04028 std::sprintf(st_graphicsmagick_path,"%s\\GRAPHI~1.%u\\gm.exe",pf_path,k);
04029 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04030 }}
04031 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04032 std::sprintf(st_graphicsmagick_path,"%s\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",pf_path,k);
04033 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04034 }}
04035 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04036 std::sprintf(st_graphicsmagick_path,"%s\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",pf_path,k);
04037 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04038 }}
04039 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04040 std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u-Q\\gm.exe",k);
04041 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04042 }}
04043 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04044 std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u\\gm.exe",k);
04045 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04046 }}
04047 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04048 std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",k);
04049 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04050 }}
04051 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04052 std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",k);
04053 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04054 }}
04055 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04056 std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u-Q\\gm.exe",k);
04057 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04058 }}
04059 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04060 std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u\\gm.exe",k);
04061 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04062 }}
04063 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04064 std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",k);
04065 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04066 }}
04067 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04068 std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",k);
04069 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04070 }}
04071 if (!path_found) std::strcpy(st_graphicsmagick_path,"gm.exe");
04072 #else
04073 if (!path_found) {
04074 std::sprintf(st_graphicsmagick_path,"./gm");
04075 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04076 }
04077 if (!path_found) std::strcpy(st_graphicsmagick_path,"gm");
04078 #endif
04079 winformat_string(st_graphicsmagick_path);
04080 }
04081 return st_graphicsmagick_path;
04082 }
04083
04085
04106 inline const char* medcon_path() {
04107 static char *st_medcon_path = 0;
04108 if (!st_medcon_path) {
04109 st_medcon_path = new char[1024];
04110 std::memset(st_medcon_path,0,1024);
04111 bool path_found = false;
04112 std::FILE *file = 0;
04113 #ifdef cimg_medcon_path
04114 std::strcpy(st_medcon_path,cimg_medcon_path);
04115 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04116 #endif
04117 #if cimg_OS==2
04118 const char* pf_path = programfiles_path();
04119 if (!path_found) {
04120 std::sprintf(st_medcon_path,".\\medcon.bat");
04121 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04122 }
04123 if (!path_found) {
04124 std::sprintf(st_medcon_path,".\\medcon.exe");
04125 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04126 }
04127 if (!path_found) {
04128 std::sprintf(st_medcon_path,"%s\\XMedCon\\bin\\medcon.bat",pf_path);
04129 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04130 }
04131 if (!path_found) {
04132 std::sprintf(st_medcon_path,"%s\\XMedCon\\bin\\medcon.exe",pf_path);
04133 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04134 }
04135 if (!path_found) std::strcpy(st_medcon_path,"medcon.bat");
04136 #else
04137 if (!path_found) {
04138 std::sprintf(st_medcon_path,"./medcon");
04139 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04140 }
04141 if (!path_found) std::strcpy(st_medcon_path,"medcon");
04142 #endif
04143 winformat_string(st_medcon_path);
04144 }
04145 return st_medcon_path;
04146 }
04147
04149
04169 inline const char* temporary_path() {
04170
04171 #define cimg_test_temporary_path(p) \
04172 if (!path_found) { \
04173 std::sprintf(st_temporary_path,"%s",p); \
04174 std::sprintf(tmp,"%s%s%s",st_temporary_path,cimg_OS==2?"\\":"/",filetmp); \
04175 if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; } \
04176 }
04177
04178 static char *st_temporary_path = 0;
04179 if (!st_temporary_path) {
04180 st_temporary_path = new char[1024];
04181 std::memset(st_temporary_path,0,1024);
04182 bool path_found = false;
04183 char tmp[1024], filetmp[512];
04184 std::FILE *file = 0;
04185 std::sprintf(filetmp,"%s.tmp",cimg::filenamerand());
04186 #ifdef cimg_temporary_path
04187 cimg_test_temporary_path(cimg_temporary_path);
04188 #endif
04189 char *tmpPath = getenv("TMP");
04190 if (tmpPath==NULL) { tmpPath = getenv("TEMP"); winformat_string(tmpPath); }
04191 if (tmpPath!=NULL) cimg_test_temporary_path(tmpPath);
04192 #if cimg_OS==2
04193 cimg_test_temporary_path("C:\\WINNT\\Temp");
04194 cimg_test_temporary_path("C:\\WINDOWS\\Temp");
04195 cimg_test_temporary_path("C:\\Temp");
04196 cimg_test_temporary_path("C:");
04197 cimg_test_temporary_path("D:\\WINNT\\Temp");
04198 cimg_test_temporary_path("D:\\WINDOWS\\Temp");
04199 cimg_test_temporary_path("D:\\Temp");
04200 cimg_test_temporary_path("D:");
04201 #else
04202 cimg_test_temporary_path("/tmp");
04203 cimg_test_temporary_path("/var/tmp");
04204 #endif
04205 if (!path_found) {
04206 st_temporary_path[0]='\0';
04207 std::strcpy(tmp,filetmp);
04208 if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; }
04209 }
04210 if (!path_found)
04211 throw CImgIOException("cimg::temporary_path() : Unable to find a temporary path accessible for writing\n"
04212 "you have to set the macro 'cimg_temporary_path' to a valid path where you have writing access :\n"
04213 "#define cimg_temporary_path \"path\" (before including 'CImg.h')");
04214 }
04215 return st_temporary_path;
04216 }
04217
04218 inline const char *filename_split(const char *const filename, char *const body=0) {
04219 if (!filename) { if (body) body[0]='\0'; return 0; }
04220 int l = cimg::strfind(filename,'.');
04221 if (l>=0) { if (body) { std::strncpy(body,filename,l); body[l]='\0'; }}
04222 else { if (body) std::strcpy(body,filename); l=(int)std::strlen(filename)-1; }
04223 return filename+l+1;
04224 }
04225
04226 inline char* filename_number(const char *const filename, const int number, const unsigned int n, char *const string) {
04227 if (!filename) { if (string) string[0]='\0'; return 0; }
04228 char format[1024],body[1024];
04229 const char *ext = cimg::filename_split(filename,body);
04230 if (n>0) std::sprintf(format,"%s_%%.%ud.%s",body,n,ext);
04231 else std::sprintf(format,"%s_%%d.%s",body,ext);
04232 std::sprintf(string,format,number);
04233 return string;
04234 }
04235
04236 inline std::FILE *fopen(const char *const path, const char *const mode) {
04237 if(!path || !mode)
04238 throw CImgArgumentException("cimg::fopen() : File '%s' cannot be opened with mode '%s'.",
04239 path?path:"(null)",mode?mode:"(null)");
04240 if (path[0]=='-') return (mode[0]=='r')?stdin:stdout;
04241 std::FILE *dest = std::fopen(path,mode);
04242 if (!dest)
04243 throw CImgIOException("cimg::fopen() : File '%s' cannot be opened%s",
04244 path,mode[0]=='r'?" for reading.":(mode[0]=='w'?" for writing.":"."),path);
04245 return dest;
04246 }
04247
04248 inline int fclose(std::FILE *file) {
04249 if (!file) warn("cimg::fclose() : Can't close (null) file");
04250 if (!file || file==stdin || file==stdout) return 0;
04251 const int errn = std::fclose(file);
04252 if (errn!=0) warn("cimg::fclose() : Error %d during file closing",errn);
04253 return errn;
04254 }
04255
04256 template<typename T> inline int fread(T *const ptr, const unsigned int nmemb, std::FILE *stream) {
04257 if (!ptr || nmemb<=0 || !stream)
04258 throw CImgArgumentException("cimg::fread() : Can't read %u x %u bytes of file pointer '%p' in buffer '%p'",
04259 nmemb,sizeof(T),stream,ptr);
04260 const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
04261 unsigned int toread = nmemb, alread = 0, ltoread = 0, lalread = 0;
04262 do {
04263 ltoread = (toread*sizeof(T))<wlimitT?toread:wlimit;
04264 lalread = (unsigned int)std::fread((void*)(ptr+alread),sizeof(T),ltoread,stream);
04265 alread+=lalread;
04266 toread-=lalread;
04267 } while (ltoread==lalread && toread>0);
04268 if (toread>0) warn("cimg::fread() : File reading problems, only %u/%u elements read",alread,nmemb);
04269 return alread;
04270 }
04271
04272 template<typename T> inline int fwrite(const T *ptr, const unsigned int nmemb, std::FILE *stream) {
04273 if (!ptr || !stream)
04274 throw CImgArgumentException("cimg::fwrite() : Can't write %u x %u bytes of file pointer '%p' from buffer '%p'",
04275 nmemb,sizeof(T),stream,ptr);
04276 if (nmemb<=0) return 0;
04277 const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
04278 unsigned int towrite = nmemb, alwrite = 0, ltowrite = 0, lalwrite = 0;
04279 do {
04280 ltowrite = (towrite*sizeof(T))<wlimitT?towrite:wlimit;
04281 lalwrite = (unsigned int)std::fwrite((void*)(ptr+alwrite),sizeof(T),ltowrite,stream);
04282 alwrite+=lalwrite;
04283 towrite-=lalwrite;
04284 } while (ltowrite==lalwrite && towrite>0);
04285 if (towrite>0) warn("cimg::fwrite() : File writing problems, only %u/%u elements written",alwrite,nmemb);
04286 return alwrite;
04287 }
04288
04289
04290 template<typename T> inline void swap(T& a, T& b) { T t = a; a = b; b = t; }
04291
04292 template<typename T1, typename T2> inline void swap(T1& a1, T1& b1, T2& a2, T2& b2) {
04293 cimg::swap(a1,b1); cimg::swap(a2,b2);
04294 }
04295
04296 template<typename T1, typename T2, typename T3> inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3) {
04297 cimg::swap(a1,b1,a2,b2); cimg::swap(a3,b3);
04298 }
04299
04300 template<typename T1, typename T2, typename T3, typename T4>
04301 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4) {
04302 cimg::swap(a1,b1,a2,b2,a3,b3); cimg::swap(a4,b4);
04303 }
04304
04305 template<typename T1, typename T2, typename T3, typename T4, typename T5>
04306 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5) {
04307 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4); cimg::swap(a5,b5);
04308 }
04309
04310 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
04311 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5, T6& a6, T6& b6) {
04312 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5); cimg::swap(a6,b6);
04313 }
04314
04315 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
04316 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5, T6& a6, T6& b6,
04317 T7& a7, T7& b7) {
04318 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6); cimg::swap(a7,b7);
04319 }
04320
04321 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
04322 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5, T6& a6, T6& b6,
04323 T7& a7, T7& b7, T8& a8, T8& b8) {
04324 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6,a7,b7); cimg::swap(a8,b8);
04325 }
04326
04327 template<typename T> inline void endian_swap(T* const buffer, const unsigned int size) {
04328 switch (sizeof(T)) {
04329 case 1: break;
04330 case 2: {
04331 for (unsigned short *ptr = (unsigned short*)buffer+size; ptr>(unsigned short*)buffer; ) {
04332 const unsigned short val = *(--ptr);
04333 *ptr = (unsigned short)((val>>8)|((val<<8)));
04334 }
04335 } break;
04336 case 4: {
04337 for (unsigned int *ptr = (unsigned int*)buffer+size; ptr>(unsigned int*)buffer; ) {
04338 const unsigned int val = *(--ptr);
04339 *ptr = (val>>24)|((val>>8)&0xff00)|((val<<8)&0xff0000)|(val<<24);
04340 }
04341 } break;
04342 default: {
04343 for (T* ptr = buffer+size; ptr>buffer; ) {
04344 unsigned char *pb = (unsigned char*)(--ptr), *pe = pb + sizeof(T);
04345 for (int i=0; i<(int)sizeof(T)/2; ++i) cimg::swap(*(pb++),*(--pe));
04346 } break;
04347 }
04348 }
04349 }
04350
04351 template<typename T> inline T& endian_swap(T& a) {
04352 endian_swap(&a,1);
04353 return a;
04354 }
04355
04356 inline const char* option(const char *const name, const int argc, char **argv,
04357 const char *defaut, const char *const usage=0) {
04358 static bool first = true, visu = false;
04359 const char *res = 0;
04360 if (first) {
04361 first=false;
04362 visu = (cimg::option("-h",argc,argv,(char*)0)!=0);
04363 visu |= (cimg::option("-help",argc,argv,(char*)0)!=0);
04364 visu |= (cimg::option("--help",argc,argv,(char*)0)!=0);
04365 }
04366 if (!name && visu) {
04367 if (usage) {
04368 std::fprintf(stderr,"\n %s%s%s",cimg::t_red,cimg::basename(argv[0]),cimg::t_normal);
04369 std::fprintf(stderr," : %s",usage);
04370 std::fprintf(stderr," (%s, %s)\n\n",__DATE__,__TIME__);
04371 }
04372 if (defaut) std::fprintf(stderr,"%s\n",defaut);
04373 }
04374 if (name) {
04375 if (argc>0) {
04376 int k = 0,i;
04377 while (k<argc && cimg::strcmp(argv[k],name)) ++k;
04378 i=k;
04379 res=(k++==argc?defaut:(k==argc?argv[--k]:argv[k]));
04380 } else res = defaut;
04381 if (visu && usage) std::fprintf(stderr," %s%-8s%s = %-12s : %s%s%s\n",
04382 cimg::t_bold,name,cimg::t_normal,res?res:"0",cimg::t_purple,usage,cimg::t_normal);
04383 }
04384 return res;
04385 }
04386
04387 inline bool option(const char *const name, const int argc, char **argv,
04388 const bool defaut, const char *const usage=0) {
04389 const char *s = cimg::option(name,argc,argv,(char*)0);
04390 const bool res = s?(cimg::strcasecmp(s,"false") && cimg::strcasecmp(s,"off") && cimg::strcasecmp(s,"0")):defaut;
04391 cimg::option(name,0,0,res?"true":"false",usage);
04392 return res;
04393 }
04394
04395 inline int option(const char *const name, const int argc, char **argv,
04396 const int defaut, const char *const usage=0) {
04397 const char *s = cimg::option(name,argc,argv,(char*)0);
04398 const int res = s?std::atoi(s):defaut;
04399 char tmp[256];
04400 std::sprintf(tmp,"%d",res);
04401 cimg::option(name,0,0,tmp,usage);
04402 return res;
04403 }
04404
04405 inline char option(const char *const name, const int argc, char **argv,
04406 const char defaut, const char *const usage=0) {
04407 const char *s = cimg::option(name,argc,argv,(char*)0);
04408 const char res = s?s[0]:defaut;
04409 char tmp[8];
04410 tmp[0] = res;
04411 tmp[1] ='\0';
04412 cimg::option(name,0,0,tmp,usage);
04413 return res;
04414 }
04415
04416 inline float option(const char *const name, const int argc, char **argv,
04417 const float defaut, const char *const usage=0) {
04418 const char *s = cimg::option(name,argc,argv,(char*)0);
04419 const float res = s?cimg::atof(s):defaut;
04420 char tmp[256];
04421 std::sprintf(tmp,"%g",res);
04422 cimg::option(name,0,0,tmp,usage);
04423 return res;
04424 }
04425
04426 inline double option(const char *const name, const int argc, char **argv,
04427 const double defaut, const char *const usage=0) {
04428 const char *s = cimg::option(name,argc,argv,(char*)0);
04429 const double res = s?cimg::atof(s):defaut;
04430 char tmp[256];
04431 std::sprintf(tmp,"%g",res);
04432 cimg::option(name,0,0,tmp,usage);
04433 return res;
04434 }
04435
04436 inline const char* argument(const unsigned int nb, const int argc, char **argv, const unsigned int nb_singles=0, ...) {
04437 for (int k=1, pos=0; k<argc;) {
04438 const char *const item = argv[k];
04439 bool option = (*item=='-'), single_option = false;
04440 if (option) {
04441 va_list ap;
04442 va_start(ap,nb_singles);
04443 for (unsigned int i=0; i<nb_singles; ++i) if (!cimg::strcasecmp(item,va_arg(ap,char*))) { single_option = true; break; }
04444 va_end(ap);
04445 }
04446 if (option) { ++k; if (!single_option) ++k; }
04447 else { if (pos++==(int)nb) return item; else ++k; }
04448 }
04449 return 0;
04450 }
04451
04452 template<typename T> inline const T rol(const T a, const unsigned int n=1) {
04453 return n?(T)((a<<n)|(a>>((sizeof(T)<<3)-n))):a;
04454 }
04455
04456 template<typename T> inline const T ror(const T a, const unsigned int n=1) {
04457 return n?(T)((a>>n)|(a<<((sizeof(T)<<3)-n))):a;
04458 }
04459
04461 template<typename T> inline T abs(const T a) {
04462 return a>=0?a:-a;
04463 }
04464
04465 inline bool abs(const bool a) {
04466 return a;
04467 }
04468
04469 inline unsigned char abs(const unsigned char a) {
04470 return a;
04471 }
04472
04473 inline unsigned short abs(const unsigned short a) {
04474 return a;
04475 }
04476
04477 inline unsigned int abs(const unsigned int a) {
04478 return a;
04479 }
04480
04481 inline unsigned long abs(const unsigned long a) {
04482 return a;
04483 }
04484
04485 inline double abs(const double a) {
04486 return std::fabs(a);
04487 }
04488
04489 inline float abs(const float a) {
04490 return (float)std::fabs((double)a);
04491 }
04492
04493 inline int abs(const int a) {
04494 return std::abs(a);
04495 }
04496
04497 template<typename T> inline T sqr(const T val) {
04498 return val*val;
04499 }
04500
04502 template<typename T> inline T min(const T a, const T b) {
04503 return a<=b?a:b;
04504 }
04505
04507 template<typename T> inline T min(const T a, const T b, const T c) {
04508 return cimg::min(cimg::min(a,b),c);
04509 }
04510
04512 template<typename T> inline T min(const T a, const T b, const T c, const T d) {
04513 return cimg::min(cimg::min(a,b,c),d);
04514 }
04515
04517 template<typename T> inline T max(const T a, const T b) {
04518 return a>=b?a:b;
04519 }
04520
04522 template<typename T> inline T max(const T a, const T b, const T c) {
04523 return cimg::max(cimg::max(a,b),c);
04524 }
04525
04527 template<typename T> inline T max(const T a, const T b, const T c, const T d) {
04528 return cimg::max(cimg::max(a,b,c),d);
04529 }
04530
04532 template<typename T> inline T sign(const T x) {
04533 return (x<0)?(T)(-1):(x==0?(T)0:(T)1);
04534 }
04535
04537 template<typename T> inline unsigned long nearest_pow2(const T x) {
04538 unsigned long i=1;
04539 while (x>i) i<<=1;
04540 return i;
04541 }
04542
04544
04547 template<typename T> inline T mod(const T& x, const T& m) {
04548 const double dx = (double)x, dm = (double)m;
04549 if (x<0) { return (T)(dm+dx+dm*std::floor(-dx/dm)); }
04550 return (T)(dx-dm*std::floor(dx/dm));
04551 }
04552
04553 inline int mod(const char x, const char m) {
04554 return x>=0?x%m:(x%m?m+x%m:0);
04555 }
04556
04557 inline int mod(const short x, const short m) {
04558 return x>=0?x%m:(x%m?m+x%m:0);
04559 }
04560
04561 inline int mod(const int x, const int m) {
04562 return x>=0?x%m:(x%m?m+x%m:0);
04563 }
04564
04565 inline int mod(const long x, const long m) {
04566 return x>=0?x%m:(x%m?m+x%m:0);
04567 }
04568
04569 inline int mod(const unsigned char x, const unsigned char m) {
04570 return x%m;
04571 }
04572
04573 inline int mod(const unsigned short x, const unsigned short m) {
04574 return x%m;
04575 }
04576
04577 inline int mod(const unsigned int x, const unsigned int m) {
04578 return x%m;
04579 }
04580
04581 inline int mod(const unsigned long x, const unsigned long m) {
04582 return x%m;
04583 }
04584
04586
04591 template<typename T> inline T minmod(const T a, const T b) {
04592 return a*b<=0?0:(a>0?(a<b?a:b):(a<b?b:a));
04593 }
04594
04596 inline double rand() {
04597 return (double)std::rand()/RAND_MAX;
04598 }
04599
04601 inline double crand() {
04602 return 1-2*cimg::rand();
04603 }
04604
04606 inline double grand() {
04607 double x1, w;
04608 do {
04609 const double x2 = 2*cimg::rand()-1.0;
04610 x1 = 2*cimg::rand()-1.0;
04611 w = x1*x1 + x2*x2;
04612 } while (w<=0 || w>=1.0);
04613 return x1*std::sqrt((-2*std::log(w))/w);
04614 }
04615
04617 inline double round(const double x, const double y, const unsigned int round_type=0) {
04618 if (y<=0) return x;
04619 const double delta = cimg::mod(x,y);
04620 if (delta==0.0) return x;
04621 const double
04622 backward = x-delta,
04623 forward = backward+y;
04624 return round_type==1?backward:(round_type==2?forward:(2*delta<y?backward:forward));
04625 }
04626
04627 inline double pythagore(double a, double b) {
04628 const double absa = cimg::abs(a), absb = cimg::abs(b);
04629 if (absa>absb) { const double tmp = absb/absa; return absa*std::sqrt(1.0+tmp*tmp); }
04630 else { const double tmp = absa/absb; return (absb==0?0:absb*std::sqrt(1.0+tmp*tmp)); }
04631 }
04632
04634
04637 inline void info() {
04638 char tmp[1024] = { 0 };
04639 std::fprintf(stderr,"\n %sCImg Library %u.%u.%u%s, compiled %s ( %s ) with the following flags :\n\n",
04640 cimg::t_red,cimg_version/100,(cimg_version%100)/10,cimg_version%10,cimg::t_normal,__DATE__,__TIME__);
04641
04642 std::fprintf(stderr," > CPU endianness : %s%s Endian%s\n",
04643 cimg::t_bold,
04644 cimg::endian()?"Big":"Little",
04645 cimg::t_normal);
04646
04647 std::fprintf(stderr," > Operating System : %s%-13s%s %s('cimg_OS'=%d)%s\n",
04648 cimg::t_bold,
04649 cimg_OS==1?"Unix":(cimg_OS==2?"Windows":"Unknow"),
04650 cimg::t_normal,cimg::t_purple,
04651 cimg_OS,
04652 cimg::t_normal);
04653
04654 #ifdef cimg_use_visualcpp6
04655 std::fprintf(stderr," > Using Visual C++ 6.0 : %s%-13s%s %s('cimg_use_visualcpp6' defined)%s\n",
04656 cimg::t_bold,"Yes",cimg::t_normal,cimg::t_purple,cimg::t_normal);
04657 #endif
04658
04659 std::fprintf(stderr," > Display type : %s%-13s%s %s('cimg_display_type'=%d)%s\n",
04660 cimg::t_bold,
04661 cimg_display_type==0?"No display":(cimg_display_type==1?"X11":(cimg_display_type==2?"Windows GDI":"Unknow")),
04662 cimg::t_normal,cimg::t_purple,
04663 cimg_display_type,
04664 cimg::t_normal);
04665
04666 std::fprintf(stderr," > Color terminal : %s%-13s%s %s('cimg_color_terminal' %s)%s\n",
04667 cimg::t_bold,
04668 #ifdef cimg_color_terminal
04669 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04670 #else
04671 "No",cimg::t_normal,cimg::t_purple,"undefined",
04672 #endif
04673 cimg::t_normal);
04674
04675 std::fprintf(stderr," > Debug messages : %s%-13s%s %s('cimg_debug'=%d)%s\n",
04676 cimg::t_bold,
04677 cimg_debug==0?"No":(cimg_debug==1 || cimg_debug==2?"Yes":(cimg_debug==3?"Yes+":"Unknown")),
04678 cimg::t_normal,cimg::t_purple,
04679 cimg_debug,
04680 cimg::t_normal);
04681
04682 #if cimg_display_type==1
04683 std::fprintf(stderr," > Using XShm for X11 : %s%-13s%s %s('cimg_use_xshm' %s)%s\n",
04684 cimg::t_bold,
04685 #ifdef cimg_use_xshm
04686 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04687 #else
04688 "No",cimg::t_normal,cimg::t_purple,"undefined",
04689 #endif
04690 cimg::t_normal);
04691
04692 std::fprintf(stderr," > Using XRand for X11 : %s%-13s%s %s('cimg_use_xrandr' %s)%s\n",
04693 cimg::t_bold,
04694 #ifdef cimg_use_xrandr
04695 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04696 #else
04697 "No",cimg::t_normal,cimg::t_purple,"undefined",
04698 #endif
04699 cimg::t_normal);
04700 #endif
04701
04702 std::fprintf(stderr," > Using PNG library : %s%-13s%s %s('cimg_use_png' %s)%s\n",
04703 cimg::t_bold,
04704 #ifdef cimg_use_png
04705 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04706 #else
04707 "No",cimg::t_normal,cimg::t_purple,"undefined",
04708 #endif
04709 cimg::t_normal);
04710 std::fprintf(stderr," > Using JPEG library : %s%-13s%s %s('cimg_use_jpeg' %s)%s\n",
04711 cimg::t_bold,
04712 #ifdef cimg_use_jpeg
04713 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04714 #else
04715 "No",cimg::t_normal,cimg::t_purple,"undefined",
04716 #endif
04717 cimg::t_normal);
04718
04719 std::fprintf(stderr," > Using TIFF library : %s%-13s%s %s('cimg_use_tiff' %s)%s\n",
04720 cimg::t_bold,
04721 #ifdef cimg_use_tiff
04722 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04723 #else
04724 "No",cimg::t_normal,cimg::t_purple,"undefined",
04725 #endif
04726 cimg::t_normal);
04727
04728 std::fprintf(stderr," > Using Magick++ library : %s%-13s%s %s('cimg_use_magick' %s)%s\n",
04729 cimg::t_bold,
04730 #ifdef cimg_use_magick
04731 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04732 #else
04733 "No",cimg::t_normal,cimg::t_purple,"undefined",
04734 #endif
04735 cimg::t_normal);
04736
04737 std::fprintf(stderr," > Using FFTW3 library : %s%-13s%s %s('cimg_use_fftw3' %s)%s\n",
04738 cimg::t_bold,
04739 #ifdef cimg_use_fftw3
04740 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04741 #else
04742 "No",cimg::t_normal,cimg::t_purple,"undefined",
04743 #endif
04744 cimg::t_normal);
04745
04746 std::fprintf(stderr," > Using LAPACK library : %s%-13s%s %s('cimg_use_lapack' %s)%s\n",
04747 cimg::t_bold,
04748 #ifdef cimg_use_lapack
04749 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04750 #else
04751 "No",cimg::t_normal,cimg::t_purple,"undefined",
04752 #endif
04753 cimg::t_normal);
04754
04755 std::sprintf(tmp,"\"%.1020s\"",cimg::imagemagick_path());
04756 std::fprintf(stderr," > Path of ImageMagick : %s%-13s%s %s('cimg_imagemagick_path'%s)%s\n",
04757 cimg::t_bold,
04758 tmp,
04759 cimg::t_normal,
04760 #ifdef cimg_imagemagick_path
04761 cimg::t_purple,"=\""cimg_imagemagick_path"\"",
04762 #else
04763 cimg::t_purple," undefined",
04764 #endif
04765 cimg::t_normal);
04766
04767 std::sprintf(tmp,"\"%.1020s\"",cimg::graphicsmagick_path());
04768 std::fprintf(stderr," > Path of GraphicsMagick : %s%-13s%s %s('cimg_graphicsmagick_path'%s)%s\n",
04769 cimg::t_bold,
04770 tmp,
04771 cimg::t_normal,
04772 #ifdef cimg_graphicsmagick_path
04773 cimg::t_purple,"=\""cimg_graphicsmagick_path"\"",
04774 #else
04775 cimg::t_purple," undefined",
04776 #endif
04777 cimg::t_normal);
04778
04779 std::sprintf(tmp,"\"%.1020s\"",cimg::medcon_path());
04780 std::fprintf(stderr," > Path of 'medcon' : %s%-13s%s %s('cimg_medcon_path'%s)%s\n",
04781 cimg::t_bold,
04782 tmp,
04783 cimg::t_normal,
04784 #ifdef cimg_medcon_path
04785 cimg::t_purple,"=\""cimg_medcon_path"\"",
04786 #else
04787 cimg::t_purple," undefined",
04788 #endif
04789 cimg::t_normal);
04790
04791 std::sprintf(tmp,"\"%.1020s\"",cimg::temporary_path());
04792 std::fprintf(stderr," > Temporary path : %s%-13s%s %s('cimg_temporary_path'%s)%s\n",
04793 cimg::t_bold,
04794 tmp,
04795 cimg::t_normal,
04796 #ifdef cimg_temporary_path
04797 cimg::t_purple,"=\""cimg_temporary_path"\"",
04798 #else
04799 cimg::t_purple," undefined",
04800 #endif
04801 cimg::t_normal);
04802
04803 std::fprintf(stderr,"\n");
04804 }
04805
04806 #ifdef cimg_use_lapack
04807 template<typename T> inline void getrf(int &N, T *lapA, int *IPIV, int &INFO) {
04808 dgetrf_(&N,&N,lapA,&N,IPIV,&INFO);
04809 }
04810
04811 inline void getrf(int &N, float *lapA, int *IPIV, int &INFO) {
04812 sgetrf_(&N,&N,lapA,&N,IPIV,&INFO);
04813 }
04814
04815 template<typename T> inline void getri(int &N, T *lapA, int *IPIV, T* WORK, int &LWORK, int &INFO) {
04816 dgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO);
04817 }
04818
04819 inline void getri(int &N, float *lapA, int *IPIV, float* WORK, int &LWORK, int &INFO) {
04820 sgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO);
04821 }
04822
04823 template<typename T> inline void gesvd(char &JOB, int &M, int &N, T *lapA, int &MN,
04824 T *lapS, T *lapU, T *lapV, T *WORK, int &LWORK, int &INFO) {
04825 dgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO);
04826 }
04827
04828 inline void gesvd(char &JOB, int &M, int &N, float *lapA, int &MN,
04829 float *lapS, float *lapU, float *lapV, float *WORK, int &LWORK, int &INFO) {
04830 sgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO);
04831 }
04832
04833 template<typename T> inline void getrs(char &TRANS, int &N, T *lapA, int *IPIV, T *lapB, int &INFO) {
04834 int one = 1;
04835 dgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO);
04836 }
04837
04838 inline void getrs(char &TRANS, int &N, float *lapA, int *IPIV, float *lapB, int &INFO) {
04839 int one = 1;
04840 sgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO);
04841 }
04842
04843 template<typename T> inline void syev(char &JOB, char &UPLO, int &N, T *lapA, T *lapW, T *WORK, int &LWORK, int &INFO) {
04844 dsyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO);
04845 }
04846
04847 inline void syev(char &JOB, char &UPLO, int &N, float *lapA, float *lapW, float *WORK, int &LWORK, int &INFO) {
04848 ssyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO);
04849 }
04850 #endif
04851
04852
04853 }
04854
04855
04856
04857
04858
04859
04860
04861
04862
04863
04864
04865
04866
04867 #ifdef cimg_use_visualcpp6
04868 template<typename t> inline CImg<t> operator+(const CImg<t>& img, const t val) {
04869 return CImg<t>(img,false)+=val;
04870 }
04871 #else
04872 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator+(const CImg<t1>& img, const t2 val) {
04873 typedef typename cimg::superset<t1,t2>::type restype;
04874 return CImg<restype>(img,false)+=val;
04875 }
04876 #endif
04877
04878 #ifdef cimg_use_visualcpp6
04879 template<typename t> inline CImg<t> operator+(const t val, const CImg<t>& img) {
04880 return img+val;
04881 }
04882 #else
04883 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator+(const t1 val, const CImg<t2>& img) {
04884 return img+val;
04885 }
04886 #endif
04887
04888 #ifdef cimg_use_visualcpp6
04889 template<typename t> inline CImgList<t> operator+(const CImgList<t>& list, const t val) {
04890 return CImgList<t>(list)+=val;
04891 }
04892 #else
04893 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const CImgList<t1>& list, const t2 val) {
04894 typedef typename cimg::superset<t1,t2>::type restype;
04895 return CImgList<restype>(list)+=val;
04896 }
04897 #endif
04898
04899 #ifdef cimg_use_visualcpp6
04900 template<typename t> inline CImgList<t> operator+(const t val, const CImgList<t>& list) {
04901 return list+val;
04902 }
04903 #else
04904 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const t1 val, const CImgList<t2>& list) {
04905 return list+val;
04906 }
04907 #endif
04908
04909 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator+(const CImg<t1>& img1, const CImg<t2>& img2) {
04910 typedef typename cimg::superset<t1,t2>::type restype;
04911 return CImg<restype>(img1,false)+=img2;
04912 }
04913
04914 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const CImg<t1>& img, const CImgList<t2>& list) {
04915 typedef typename cimg::superset<t1,t2>::type restype;
04916 return CImgList<restype>(list)+=img;
04917 }
04918
04919 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const CImgList<t1>& list, const CImg<t2>& img) {
04920 return img+list;
04921 }
04922
04923 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const CImgList<t1>& list1, const CImgList<t2>& list2) {
04924 typedef typename cimg::superset<t1,t2>::type restype;
04925 return CImgList<restype>(list1)+=list2;
04926 }
04927
04928 #ifdef cimg_use_visualcpp6
04929 template<typename t> inline CImg<t> operator-(const CImg<t>& img, const t val) {
04930 return CImg<t>(img,false)-=val;
04931 }
04932 #else
04933 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator-(const CImg<t1>& img, const t2 val) {
04934 typedef typename cimg::superset<t1,t2>::type restype;
04935 return CImg<restype>(img,false)-=val;
04936 }
04937 #endif
04938
04939 #ifdef cimg_use_visualcpp6
04940 template<typename t> inline CImg<t> operator-(const t val, const CImg<t>& img) {
04941 return CImg<t>(img.width,img.height,img.depth,img.dim,val)-=img;
04942 }
04943 #else
04944 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator-(const t1 val, const CImg<t2>& img) {
04945 typedef typename cimg::superset<t1,t2>::type restype;
04946 return CImg<restype>(img.width,img.height,img.depth,img.dim,(restype)val)-=img;
04947 }
04948 #endif
04949
04950 #ifdef cimg_use_visualcpp6
04951 template<typename t> inline CImgList<t> operator-(const CImgList<t>& list, const t val) {
04952 return CImgList<t>(list)-=val;
04953 }
04954 #else
04955 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const CImgList<t1>& list, const t2 val) {
04956 typedef typename cimg::superset<t1,t2>::type restype;
04957 return CImgList<restype>(list)-=val;
04958 }
04959 #endif
04960
04961 #ifdef cimg_use_visualcpp6
04962 template<typename t> inline CImgList<double> operator-(const t val, const CImgList<t>& list) {
04963 CImgList<t> res(list.size);
04964 cimglist_for(res,l) res[l] = val-list[l];
04965 return res;
04966 }
04967 #else
04968 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const t1 val, const CImgList<t2>& list) {
04969 typedef typename cimg::superset<t1,t2>::type restype;
04970 CImgList<restype> res(list.size);
04971 cimglist_for(res,l) res[l] = val-list[l];
04972 return res;
04973 }
04974 #endif
04975
04976 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator-(const CImg<t1>& img1, const CImg<t2>& img2) {
04977 typedef typename cimg::superset<t1,t2>::type restype;
04978 return CImg<restype>(img1,false)-=img2;
04979 }
04980
04981 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const CImg<t1>& img, const CImgList<t2>& list) {
04982 typedef typename cimg::superset<t1,t2>::type restype;
04983 CImgList<restype> res(list.size);
04984 cimglist_for(res,l) res[l] = img-list[l];
04985 return res;
04986 }
04987
04988 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const CImgList<t1>& list, const CImg<t2>& img) {
04989 typedef typename cimg::superset<t1,t2>::type restype;
04990 return CImgList<restype>(list)-=img;
04991 }
04992
04993 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const CImgList<t1>& list1, const CImgList<t2>& list2) {
04994 typedef typename cimg::superset<t1,t2>::type restype;
04995 return CImgList<restype>(list1)-=list2;
04996 }
04997
04998 #ifdef cimg_use_visualcpp6
04999 template<typename t> inline CImg<t> operator*(const CImg<t>& img, const double val) {
05000 return CImg<t>(img,false)*=val;
05001 }
05002 #else
05003 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator*(const CImg<t1>& img, const t2 val) {
05004 typedef typename cimg::superset<t1,t2>::type restype;
05005 return CImg<restype>(img,false)*=val;
05006 }
05007 #endif
05008
05009 #ifdef cimg_use_visualcpp6
05010 template<typename t> inline CImg<t> operator*(const double val, const CImg<t>& img) {
05011 return img*val;
05012 }
05013 #else
05014 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator*(const t1 val, const CImg<t2>& img) {
05015 return img*val;
05016 }
05017 #endif
05018
05019 #ifdef cimg_use_visualcpp6
05020 template<typename t> inline CImgList<t> operator*(const CImgList<t>& list, const double val) {
05021 return CImgList<t>(list)*=val;
05022 }
05023 #else
05024 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const CImgList<t1>& list, const t2 val) {
05025 typedef typename cimg::superset<t1,t2>::type restype;
05026 return CImgList<restype>(list)*=val;
05027 }
05028 #endif
05029
05030 #ifdef cimg_use_visualcpp6
05031 template<typename t> inline CImgList<t> operator*(const double val, const CImgList<t>& list) {
05032 return list*val;
05033 }
05034 #else
05035 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const t1 val, const CImgList<t2>& list) {
05036 return list*val;
05037 }
05038 #endif
05039
05040 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator*(const CImg<t1>& img1, const CImg<t2>& img2) {
05041 typedef typename cimg::superset<t1,t2>::type restype;
05042 if (img1.width!=img2.height)
05043 throw CImgArgumentException("operator*() : can't multiply a matrix (%ux%u) by a matrix (%ux%u)",
05044 img1.width,img1.height,img2.width,img2.height);
05045 CImg<restype> res(img2.width,img1.height);
05046 restype val;
05047 cimg_forXY(res,i,j) { val = 0; cimg_forX(img1,k) val+=img1(k,j)*img2(i,k); res(i,j) = val; }
05048 return res;
05049 }
05050
05051 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const CImg<t1>& img, const CImgList<t2>& list) {
05052 typedef typename cimg::superset<t1,t2>::type restype;
05053 CImgList<restype> res(list.size);
05054 cimglist_for(res,l) res[l] = img*list[l];
05055 return res;
05056 }
05057
05058 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const CImgList<t1>& list, const CImg<t2>& img) {
05059 typedef typename cimg::superset<t1,t2>::type restype;
05060 CImgList<restype> res(list.size);
05061 cimglist_for(res,l) res[l] = list[l]*img;
05062 return res;
05063 }
05064
05065 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const CImgList<t1>& list1, const CImgList<t2>& list2) {
05066 typedef typename cimg::superset<t1,t2>::type restype;
05067 CImgList<restype> res(cimg::min(list1.size,list2.size));
05068 cimglist_for(res,l) res[l] = list1[l]*list2[l];
05069 return res;
05070 }
05071
05072 #ifdef cimg_use_visualcpp6
05073 template<typename t> inline CImg<t> operator/(const CImg<t>& img, const double val) {
05074 return CImg<t>(img,false)/=val;
05075 }
05076 #else
05077 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator/(const CImg<t1>& img, const t2 val) {
05078 typedef typename cimg::superset<t1,t2>::type restype;
05079 return CImg<restype>(img,false)/=val;
05080 }
05081 #endif
05082
05083 #ifdef cimg_use_visualcpp6
05084 template<typename t> inline CImg<t> operator/(const double val, CImg<t>& img) {
05085 return val*img.get_inverse();
05086 }
05087 #else
05088 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator/(const t1 val, CImg<t2>& img) {
05089 return val*img.get_inverse();
05090 }
05091 #endif
05092
05093 #ifdef cimg_use_visualcpp6
05094 template<typename t> inline CImgList<t> operator/(const CImgList<t>& list, const double val) {
05095 return CImgList<t>(list)/=val;
05096 }
05097 #else
05098 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator/(const CImgList<t1>& list, const t2 val) {
05099 typedef typename cimg::superset<t1,t2>::type restype;
05100 return CImgList<restype>(list)/=val;
05101 }
05102 #endif
05103
05104 #ifdef cimg_use_visualcpp6
05105 template<typename t> inline CImgList<t> operator/(const double val, const CImgList<t>& list) {
05106 CImgList<t> res(list.size);
05107 cimglist_for(res,l) res[l] = val/list[l];
05108 return res;
05109 }
05110 #else
05111 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator/(const t1 val, const CImgList<t2>& list) {
05112 typedef typename cimg::superset<t1,t2>::type restype;
05113 CImgList<restype> res(list.size);
05114 cimglist_for(res,l) res[l] = val/list[l];
05115 return res;
05116 }
05117 #endif
05118
05119 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator/(const CImg<t1>& img1, const CImg<t2>& img2) {
05120 typedef typename cimg::superset<t1,t2>::type restype;
05121 return CImg<restype>(img1,false)*=img2.get_inverse();
05122 }
05123
05124 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator/(const CImg<t1>& img, const CImgList<t2>& list) {
05125 typedef typename cimg::superset<t1,t2>::type restype;
05126 CImgList<restype> res(list.size);
05127 cimglist_for(res,l) res[l] = img/list[l];
05128 return res;
05129 }
05130
05131 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator/(const CImgList<t1>& list, const CImg<t2>& img) {
05132 typedef typename cimg::superset<t1,t2>::type restype;
05133 return CImgList<restype>(list)/=img;
05134 }
05135
05136 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator/(const CImgList<t1>& list1, const CImgList<t2>& list2) {
05137 typedef typename cimg::superset<t1,t2>::type restype;
05138 return CImgList<restype>(list1)/=list2;
05139 }
05140
05141
05142
05143
05144
05145
05146
05147
05148
05149
05150
05151
05152
05153 template<typename T, typename t> inline CImg<T> apply(const CImg<T>& instance, t& func) {
05154 return instance.get_apply(func);
05155 }
05156
05157 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> mul(const CImg<T>& instance, const CImg<t>& img) {
05158 return instance.get_mul(img);
05159 }
05160
05161 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> div(const CImg<T>& instance, const CImg<t>& img) {
05162 return instance.get_div(img);
05163 }
05164
05165 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> max(const CImg<T>& instance, const CImg<t>& img) {
05166 return instance.get_max(img);
05167 }
05168
05169 template<typename T> inline CImg<T> max(const CImg<T>& instance, const T val) {
05170 return instance.get_max(val);
05171 }
05172
05173 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> min(const CImg<T>& instance, const CImg<t>& img) {
05174 return instance.get_min(img);
05175 }
05176
05177 template<typename T> inline CImg<typename cimg::last<T,double>::type> stats(const CImg<T>& instance) {
05178 return instance.get_stats();
05179 }
05180
05181 template<typename T> inline CImg<T> min(const CImg<T>& instance, const T val) {
05182 return instance.get_min(val);
05183 }
05184
05185 template<typename T> inline CImg<typename cimg::superset<T,float>::type> sqr(const CImg<T>& instance) {
05186 return instance.get_sqr();
05187 }
05188
05189 template<typename T> inline CImg<typename cimg::superset<T,float>::type> sqrt(const CImg<T>& instance) {
05190 return instance.get_sqrt();
05191 }
05192
05193 template<typename T> inline CImg<typename cimg::superset<T,float>::type> exp(const CImg<T>& instance) {
05194 return instance.get_exp();
05195 }
05196
05197 template<typename T> inline CImg<typename cimg::superset<T,float>::type> log(const CImg<T>& instance) {
05198 return instance.get_log();
05199 }
05200
05201 template<typename T> inline CImg<typename cimg::superset<T,float>::type> log10(const CImg<T>& instance) {
05202 return instance.get_log10();
05203 }
05204
05205 template<typename T> inline CImg<typename cimg::superset<T,float>::type> pow(const CImg<T>& instance, const double p) {
05206 return instance.get_pow(p);
05207 }
05208
05209 template<typename T, typename t> inline CImg<typename cimg::superset<T,float>::type> pow(const CImg<T>& instance, const CImg<t>& img) {
05210 return instance.get_pow(img);
05211 }
05212
05213 template<typename T> inline CImg<typename cimg::superset<T,float>::type> abs(const CImg<T>& instance) {
05214 return instance.get_abs();
05215 }
05216
05217 template<typename T> inline CImg<typename cimg::superset<T,float>::type> cos(const CImg<T>& instance) {
05218 return instance.get_cos();
05219 }
05220
05221 template<typename T> inline CImg<typename cimg::superset<T,float>::type> sin(const CImg<T>& instance) {
05222 return instance.get_sin();
05223 }
05224
05225 template<typename T> inline CImg<typename cimg::superset<T,float>::type> tan(const CImg<T>& instance) {
05226 return instance.get_tan();
05227 }
05228
05229 template<typename T> inline CImg<typename cimg::superset<T,float>::type> acos(const CImg<T>& instance) {
05230 return instance.get_acos();
05231 }
05232
05233 template<typename T> inline CImg<typename cimg::superset<T,float>::type> asin(const CImg<T>& instance) {
05234 return instance.get_asin();
05235 }
05236
05237 template<typename T> inline CImg<typename cimg::superset<T,float>::type> atan(const CImg<T>& instance) {
05238 return instance.get_atan();
05239 }
05240
05241 template<typename T> inline CImg<T> round(const CImg<T>& instance, const float x, const unsigned int round_type=0) {
05242 return instance.get_round(x,round_type);
05243 }
05244
05245 template<typename T> inline CImg<T> rand(const CImg<T>& instance, const T val_min, const T val_max) {
05246 return instance.get_rand(val_min,val_max);
05247 }
05248
05249 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val) {
05250 return instance.get_fill(val);
05251 }
05252
05253 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1) {
05254 return instance.get_fill(val0,val1);
05255 }
05256
05257 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2) {
05258 return instance.get_fill(val0,val1,val2);
05259 }
05260
05261 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3) {
05262 return instance.get_fill(val0,val1,val2,val3);
05263 }
05264
05265 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05266 const T val4) {
05267 return instance.get_fill(val0,val1,val2,val3,val4);
05268 }
05269
05270 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05271 const T val4, const T val5) {
05272 return instance.get_fill(val0,val1,val2,val3,val4,val5);
05273 }
05274
05275 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05276 const T val4, const T val5, const T val6) {
05277 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6);
05278 }
05279
05280 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05281 const T val4, const T val5, const T val6, const T val7) {
05282 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7);
05283 }
05284
05285 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05286 const T val4, const T val5, const T val6, const T val7, const T val8) {
05287 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8);
05288 }
05289
05290 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05291 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9) {
05292 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9);
05293 }
05294
05295 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05296 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05297 const T val10) {
05298 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10);
05299 }
05300
05301 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05302 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05303 const T val10, const T val11) {
05304 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11);
05305 }
05306
05307 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05308 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05309 const T val10, const T val11, const T val12) {
05310 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12);
05311 }
05312
05313 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05314 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05315 const T val10, const T val11, const T val12, const T val13) {
05316 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13);
05317 }
05318
05319 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05320 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05321 const T val10, const T val11, const T val12, const T val13, const T val14) {
05322 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14);
05323 }
05324
05325 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05326 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05327 const T val10, const T val11, const T val12, const T val13, const T val14, const T val15) {
05328 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14,val15);
05329 }
05330
05331 template<typename T, int N> inline CImg<T> fill(const CImg<T>& instance, const int val0, ...) {
05332 CImg<T> res(instance,false);
05333 va_list ap;
05334 va_start(ap,val0);
05335 res.template _fill<N,int>(val0,ap);
05336 va_end(ap);
05337 return res;
05338 }
05339
05340 template<typename T, int N> inline CImg<T> fill(const CImg<T>& instance, const double val0, ...) {
05341 CImg<T> res(instance,false);
05342 va_list ap;
05343 va_start(ap,val0);
05344 res.template _fill<N,double>(val0,ap);
05345 va_end(ap);
05346 return res;
05347 }
05348
05349 template<typename T> inline CImg<T> normalize(const CImg<T>& instance, const T a, const T b) {
05350 return instance.get_normalize(a,b);
05351 }
05352
05353 template<typename T> inline CImg<T> cut(const CImg<T>& instance, const T a, const T b) {
05354 return instance.get_cut(a,b);
05355 }
05356
05357 template<typename T> inline CImg<T> quantize(const CImg<T>& instance, const unsigned int n=256, const bool keep_range=true) {
05358 return instance.get_quantize(n,keep_range);
05359 }
05360
05361 template<typename T> inline CImg<T> threshold(const CImg<T>& instance, const T thres) {
05362 return instance.get_threshold(thres);
05363 }
05364
05365 template<typename T> inline CImg<T> rotate(const CImg<T>& instance, const float angle, const unsigned int cond=3) {
05366 return instance.get_rotate(angle,cond);
05367 }
05368
05369 template<typename T> inline CImg<T> rotate(const CImg<T>& instance, const float angle, const float cx, const float cy,
05370 const float zoom=1, const unsigned int cond=3) {
05371 return instance.get_rotate(angle,cx,cy,zoom,cond);
05372 }
05373
05374 template<typename T> inline CImg<T> resize(const CImg<T>& instance,
05375 const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100,
05376 const int interp=1, const int border_condition=-1, const bool center=false) {
05377 return instance.get_resize(pdx,pdy,pdz,pdv,interp,border_condition,center);
05378 }
05379
05380 template<typename T, typename t> inline CImg<T> resize(const CImg<T>& instance, const CImg<t>& src,
05381 const int interp=1, const int border_condition=-1,
05382 const bool center=false) {
05383 return instance.get_resize(src,interp,border_condition,center);
05384 }
05385
05386 template<typename T> inline CImg<T> resize(const CImg<T>& instance, const CImgDisplay& disp,
05387 const int interp=1, const int border_condition=-1, const bool center=false) {
05388 return instance.get_resize(disp,interp,border_condition,center);
05389 }
05390
05391 template<typename T> inline CImg<T> permute_axes(const CImg<T>& instance, const char *permut="vxyz") {
05392 return instance.get_permute_axes(instance,permut);
05393 }
05394
05395 template<typename T> inline CImg<T> resize_halfXY(const CImg<T>& instance) {
05396 return instance.get_resize_halfXY();
05397 }
05398
05399 template<typename T> inline CImg<T> crop(const CImg<T>& instance, const int x0, const int y0, const int z0, const int v0,
05400 const int x1, const int y1, const int z1, const int v1,
05401 const bool border_condition=false) {
05402 return instance.get_crop(x0,y0,z0,v0,x1,y1,z1,v1,border_condition);
05403 }
05404
05405 template<typename T> inline CImg<T> crop(const CImg<T>& instance, const int x0, const int y0, const int z0,
05406 const int x1, const int y1, const int z1,
05407 const bool border_condition=false) {
05408 return instance.get_crop(x0,y0,z0,x1,y1,z1,border_condition);
05409 }
05410
05411 template<typename T> inline CImg<T> crop(const CImg<T>& instance, const int x0, const int y0,
05412 const int x1, const int y1,
05413 const bool border_condition=false) {
05414 return instance.get_crop(x0,y0,x1,y1,border_condition);
05415 }
05416
05417 template<typename T> inline CImg<T> crop(const CImg<T>& instance, const int x0, const int x1,
05418 const bool border_condition=false) {
05419 return instance.get_crop(x0,x1,border_condition);
05420 }
05421
05422 template<typename T> inline CImg<T> columns(const CImg<T>& instance, const unsigned int x0, const unsigned int x1) {
05423 return instance.get_columns(x0,x1);
05424 }
05425
05426 template<typename T> inline CImg<T> column(const CImg<T>& instance, const unsigned int x0) {
05427 return instance.get_column(x0);
05428 }
05429
05430 template<typename T> inline CImg<T> lines(const CImg<T>& instance, const unsigned int y0, const unsigned int y1) {
05431 return instance.get_lines(y0,y1);
05432 }
05433
05434 template<typename T> inline CImg<T> line(const CImg<T>& instance, const unsigned int y0) {
05435 return instance.get_line(y0);
05436 }
05437
05438 template<typename T> inline CImg<T> slices(const CImg<T>& instance, const unsigned int z0, const unsigned int z1) {
05439 return instance.get_slices(z0,z1);
05440 }
05441
05442 template<typename T> inline CImg<T> slice(const CImg<T>& instance, const unsigned int z0) {
05443 return instance.get_slice(z0);
05444 }
05445
05446 template<typename T> inline CImg<T> channels(const CImg<T>& instance, const unsigned int v0, const unsigned int v1) {
05447 return instance.get_channels(v0,v1);
05448 }
05449
05450 template<typename T> inline CImg<T> channel(const CImg<T>& instance, const unsigned int v0) {
05451 return instance.get_channel(v0);
05452 }
05453
05454 template<typename T> inline CImg<T> shared_points(CImg<T>& instance, const unsigned int x0, const unsigned int x1,
05455 const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) {
05456 return instance.get_shared_points(x0,x1,y0,z0,v0);
05457 }
05458
05459 template<typename T> inline CImg<T> shared_points(const CImg<T>& instance, const unsigned int x0, const unsigned int x1,
05460 const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) {
05461 return instance.get_shared_points(x0,x1,y0,z0,v0);
05462 }
05463
05464 template<typename T> inline CImg<T> shared_lines(CImg<T>& instance, const unsigned int y0, const unsigned int y1,
05465 const unsigned int z0=0, const unsigned int v0=0) {
05466 return instance.get_shared_lines(y0,y1,z0,v0);
05467 }
05468
05469 template<typename T> inline CImg<T> shared_lines(const CImg<T>& instance, const unsigned int y0, const unsigned int y1,
05470 const unsigned int z0=0, const unsigned int v0=0) {
05471 return instance.get_shared_lines(y0,y1,z0,v0);
05472 }
05473
05474 template<typename T> inline CImg<T> shared_line(CImg<T>& instance,
05475 const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) {
05476 return instance.get_shared_line(y0,z0,v0);
05477 }
05478
05479 template<typename T> inline CImg<T> shared_line(const CImg<T>& instance,
05480 const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) {
05481 return instance.get_shared_line(y0,z0,v0);
05482 }
05483
05484 template<typename T> inline CImg<T> shared_planes(CImg<T>& instance,
05485 const unsigned int z0, const unsigned int z1, const unsigned int v0=0) {
05486 return instance.get_shared_planes(z0,z1,v0);
05487 }
05488
05489 template<typename T> inline CImg<T> shared_planes(const CImg<T>& instance,
05490 const unsigned int z0, const unsigned int z1, const unsigned int v0=0) {
05491 return instance.get_shared_planes(z0,z1,v0);
05492 }
05493
05494 template<typename T> inline CImg<T> shared_plane(CImg<T>& instance, const unsigned int z0, const unsigned int v0=0) {
05495 return instance.get_shared_plane(z0,v0);
05496 }
05497
05498 template<typename T> inline CImg<T> shared_plane(const CImg<T>& instance, const unsigned int z0, const unsigned int v0=0) {
05499 return instance.get_shared_plane(z0,v0);
05500 }
05501
05502 template<typename T> inline CImg<T> shared_channels(CImg<T>& instance, const unsigned int v0, const unsigned int v1) {
05503 return instance.get_shared_channels(v0,v1);
05504 }
05505
05506 template<typename T> inline CImg<T> shared_channels(const CImg<T>& instance, const unsigned int v0, const unsigned int v1) {
05507 return instance.get_shared_channels(v0,v1);
05508 }
05509
05510 template<typename T> inline CImg<T> shared_channel(CImg<T>& instance, const unsigned int v0) {
05511 return instance.get_shared_channel(v0);
05512 }
05513
05514 template<typename T> inline CImg<T> shared_channel(const CImg<T>& instance, const unsigned int v0) {
05515 return instance.get_shared_channel(v0);
05516 }
05517
05518 template<typename T> inline CImg<T> shared(CImg<T>& instance) {
05519 return instance.get_shared();
05520 }
05521
05522 template<typename T> inline CImg<T> shared(const CImg<T>& instance) {
05523 return instance.get_shared();
05524 }
05525
05526 template<typename T> inline CImg<T> mirror(const CImg<T>& instance, const char axe='x') {
05527 return instance.get_mirror(axe);
05528 }
05529
05530 template<typename T> inline CImg<T> translate(const CImg<T>& instance, const int deltax, const int deltay=0, const int deltaz=0,
05531 const int deltav=0, const int border_condition=0) {
05532 return instance.get_translate(deltax,deltay,deltaz,deltav,border_condition);
05533 }
05534
05535 template<typename T> inline CImg<T> projections2d(const CImg<T>& instance,
05536 const unsigned int x0, const unsigned int y0, const unsigned int z0,
05537 const int dx=-100, const int dy=-100, const int dz=-100) {
05538 return instance.get_projections2d(x0,y0,z0,dx,dy,dz);
05539 }
05540
05541 template<typename T> inline CImg<typename cimg::last<T,float>::type>
05542 histogram(const CImg<T>& instance, const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) {
05543 return instance.get_histogram(nblevels,val_min,val_max);
05544 }
05545
05546 template<typename T> inline CImg<T> equalize_histogram(const CImg<T>& instance,
05547 const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) {
05548 return instance.get_equalize_histogram(nblevels,val_min,val_max);
05549 }
05550
05551 template<typename T> inline CImg<typename cimg::last<T,unsigned int>::type> label_regions(const CImg<T>& instance) {
05552 return instance.get_label_regions();
05553 }
05554
05555 template<typename T> inline CImg<typename cimg::superset<T,float>::type> norm_pointwise(const CImg<T>& instance, int norm_type=2) {
05556 return instance.get_norm_pointwise(norm_type);
05557 }
05558
05559 template<typename T> inline CImg<typename cimg::superset<T,float>::type> orientation_pointwise(const CImg<T>& instance) {
05560 return instance.get_orientation_pointwise();
05561 }
05562
05563 template<typename T> inline CImgList<T> split(const CImg<T>& instance, const char axe='x', const unsigned int nb=0) {
05564 return instance.get_split(axe,nb);
05565 }
05566
05567 template<typename T> inline CImg<T> append(const CImg<T>& instance, const CImg<T>& img, const char axis='x', const char align='c') {
05568 return instance.get_append(img,axis,align);
05569 }
05570
05571 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> gradientXY(const CImg<T>& instance, const int scheme=0) {
05572 return instance.get_gradientXY(scheme);
05573 }
05574
05575 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> gradientXYZ(const CImg<T>& instance, const int scheme=0) {
05576 return instance.get_gradientXYZ(scheme);
05577 }
05578
05579 template<typename T> inline CImg<typename cimg::superset<T,float>::type> structure_tensorXY(const CImg<T>& instance, const int scheme=1) {
05580 return instance.get_structure_tensorXY(scheme);
05581 }
05582
05583 template<typename T> inline CImg<typename cimg::superset<T,float>::type> structure_tensorXYZ(const CImg<T>& instance, const int scheme=1) {
05584 return instance.get_structure_tensorXYZ(scheme);
05585 }
05586
05587 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05588 distance_function(const CImg<T>& instance, const unsigned int nb_iter=100, const float band_size=0.0f, const float precision=0.5f) {
05589 return instance.get_distance_function(nb_iter,band_size,precision);
05590 }
05591
05592 template<typename T, typename t> inline CImg<typename cimg::superset<T,float>::type>
05593 dijkstra(const CImg<T>& instance, const unsigned int starting_node, const unsigned int ending_node, CImg<t>& previous) {
05594 return instance.get_dijkstra(starting_node,ending_node,previous);
05595 }
05596
05597 template<typename T, typename t> inline CImg<typename cimg::superset<T,float>::type>
05598 dijkstra(const CImg<T>& instance, const unsigned int starting_node, const unsigned int ending_node=~0U) {
05599 return instance.get_dijkstra(starting_node,ending_node);
05600 }
05601
05602 template<typename T, typename t> inline CImg<t> RGBtoLUT(const CImg<T>& instance, const CImg<t>& palette,
05603 const bool dithering=true, const bool indexing=false) {
05604 return instance.get_RGBtoLUT(palette,dithering,indexing);
05605 }
05606
05607 template<typename T> inline CImg<T> RGBtoLUT(const CImg<T>& instance, const bool dithering=true, const bool indexing=false) {
05608 return instance.get_RGBtoLUT(dithering,indexing);
05609 }
05610
05611 template<typename T, typename t> inline CImg<t> LUTtoRGB(const CImg<T>& instance, const CImg<t>& palette) {
05612 return instance.get_LUTtoRGB(palette);
05613 }
05614
05615 template<typename T> inline CImg<T> LUTtoRGB(const CImg<T>& instance) {
05616 return instance.get_LUTtoRGB();
05617 }
05618
05619 template<typename T> inline CImg<typename cimg::superset<T,float>::type> RGBtoHSV(const CImg<T>& instance) {
05620 return instance.get_RGBtoHSV();
05621 }
05622
05623 template<typename T> inline CImg<T> HSVtoRGB(const CImg<T>& instance) {
05624 return instance.get_HSVtoRGB();
05625 }
05626
05627 template<typename T> inline CImg<typename cimg::superset<T,float>::type> RGBtoHSL(const CImg<T>& instance) {
05628 return instance.get_RGBtoHSL();
05629 }
05630
05631 template<typename T> inline CImg<T> HSLtoRGB(const CImg<T>& instance) {
05632 return instance.get_HSLtoRGB();
05633 }
05634
05635 template<typename T> inline CImg<T> RGBtoYCbCr(const CImg<T>& instance) {
05636 return instance.get_RGBtoYCbCr();
05637 }
05638
05639 template<typename T> inline CImg<T> YCbCrtoRGB(const CImg<T>& instance) {
05640 return instance.get_YCbCrtoRGB();
05641 }
05642
05643 template<typename T> inline CImg<typename cimg::superset<T,float>::type> RGBtoYUV(const CImg<T>& instance) {
05644 return instance.get_RGBtoYUV();
05645 }
05646
05647 template<typename T> inline CImg<T> YUVtoRGB(const CImg<T>& instance) {
05648 return instance.get_YUVtoRGB();
05649 }
05650
05651 template<typename T> inline CImg<typename cimg::superset<T,float>::type> RGBtoXYZ(const CImg<T>& instance) {
05652 return instance.get_RGBtoXYZ();
05653 }
05654
05655 template<typename T> inline CImg<T> XYZtoRGB(const CImg<T>& instance) {
05656 return instance.get_XYZtoRGB();
05657 }
05658
05659 template<typename T> inline CImg<T> XYZtoLab(const CImg<T>& instance) {
05660 return instance.get_XYZtoLab();
05661 }
05662
05663 template<typename T> inline CImg<T> LabtoXYZ(const CImg<T>& instance) {
05664 return instance.get_LabtoXYZ();
05665 }
05666
05667 template<typename T> inline CImg<T> XYZtoxyY(const CImg<T>& instance) {
05668 return instance.get_XYZtoxyY();
05669 }
05670
05671 template<typename T> inline CImg<T> xyYtoXYZ(const CImg<T>& instance) {
05672 return instance.get_xyYtoXYZ();
05673 }
05674
05675 template<typename T> inline CImg<T> RGBtoLab(const CImg<T>& instance) {
05676 return instance.get_RGBtoLab();
05677 }
05678
05679 template<typename T> inline CImg<T> LabtoRGB(const CImg<T>& instance) {
05680 return instance.get_LabtoRGB();
05681 }
05682
05683 template<typename T> inline CImg<T> RGBtoxyY(const CImg<T>& instance) {
05684 return instance.get_RGBtoxyY();
05685 }
05686
05687 template<typename T> inline CImg<T> xyYtoRGB(const CImg<T>& instance) {
05688 return instance.get_xyYtoRGB();
05689 }
05690
05691 template<typename T> inline CImg<T> RGBtoBayer(const CImg<T>& instance, const bool even_mode=true) {
05692 return instance.get_RGBtoBayer(even_mode);
05693 }
05694
05695 template<typename T> inline CImg<T> BayertoRGB(const CImg<T>& instance, const unsigned int interpolation_type=3, const bool even_mode=true) {
05696 return instance.get_BayertoRGB(interpolation_type,even_mode);
05697 }
05698
05699 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type>
05700 correlate(const CImg<T>& instance, const CImg<t>& mask, const unsigned int cond=1, const bool weighted_correl=false) {
05701 return instance.get_correlate(mask,cond,weighted_correl);
05702 }
05703
05704 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type>
05705 convolve(const CImg<T>& instance, const CImg<t>& mask, const unsigned int cond=1, const bool weighted_convol=false) {
05706 return instance.get_convolve(mask,cond,weighted_convol);
05707 }
05708
05709 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type>
05710 erode(const CImg<T>& instance, const CImg<t>& mask, const unsigned int cond=1, const bool weighted_erosion=false) {
05711 return instance.get_erode(mask,cond,weighted_erosion);
05712 }
05713
05714 template<typename T> inline CImg<T> erode(const CImg<T>& instance, const unsigned int n, const unsigned int cond=1) {
05715 return instance.get_erode(n,cond);
05716 }
05717
05718 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type>
05719 dilate(const CImg<T>& instance, const CImg<t>& mask, const unsigned int cond=1, const bool weighted_dilatation=false) {
05720 return instance.get_dilate(mask,cond,weighted_dilatation);
05721 }
05722
05723 template<typename T> inline CImg<T> dilate(const CImg<T>& instance, const unsigned int n, const unsigned int cond=1) {
05724 return instance.get_dilate(n,cond);
05725 }
05726
05727 template<typename T> inline CImg<T> noise(const CImg<T>& instance, const double sigma=-20, const unsigned int ntype=0) {
05728 return instance.get_noise(sigma,ntype);
05729 }
05730
05731 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05732 deriche(const CImg<T>& instance, const float sigma, const int order=0, const char axe='x', const bool cond=true) {
05733 return instance.get_deriche(sigma,order,axe,cond);
05734 }
05735
05736 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05737 blur(const CImg<T>& instance, const float sigmax, const float sigmay, const float sigmaz, const bool cond=true) {
05738 return instance.get_blur(sigmax,sigmay,sigmaz,cond);
05739 }
05740
05741 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05742 blur(const CImg<T>& instance, const float sigma, const bool cond=true) {
05743 return instance.get_blur(sigma,cond);
05744 }
05745
05746 template<typename T, typename t> inline CImg<T> blur_anisotropic(const CImg<T>& instance, const CImg<t>& G, const float amplitude=60.0f,
05747 const float dl=0.8f, const float da=30.0f,
05748 const float gauss_prec=2.0f, const unsigned int interpolation=0,
05749 const bool fast_approx=true) {
05750 return instance.get_blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
05751 }
05752
05753 template<typename T, typename tm> inline CImg<T> blur_anisotropic(const CImg<T>& instance, const CImg<tm>& mask,
05754 const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
05755 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
05756 const float da=30.0f, const float gauss_prec=2.0f,
05757 const unsigned int interpolation=0, const bool fast_approx=true,
05758 const float geom_factor=1.0f) {
05759 return instance.get_blur_anisotropic(mask,amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
05760 }
05761
05762 template<typename T> inline CImg<T> blur_anisotropic(const CImg<T>& instance, const float amplitude, const float sharpness=0.7f,
05763 const float anisotropy=0.3f,
05764 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
05765 const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0,
05766 const bool fast_approx=true, const float geom_factor=1.0f) {
05767 return instance.get_blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
05768 }
05769
05770 template<typename T> inline CImg<T> blur_bilateral(const CImg<T>& instance,
05771 const float sigmax, const float sigmay, const float sigmaz, const float sigmar,
05772 const int bgridx, const int bgridy, const int bgridz, const int bgridr,
05773 const bool interpolation=true) {
05774 return instance.get_blur_bilateral(sigmax,sigmay,sigmaz,sigmar,bgridx,bgridy,bgridz,bgridr,interpolation);
05775 }
05776
05777 template<typename T> inline CImg<T> blur_bilateral(const CImg<T>& instance,
05778 const float sigmas, const float sigmar, const int bgrids=-33, const int bgridr=32,
05779 const bool interpolation=true) {
05780 return instance.get_blur_bilateral(sigmas,sigmar,bgrids,bgridr,interpolation);
05781 }
05782
05783 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> FFT(const CImg<T>& instance, const char axe, const bool inverse=false) {
05784 return instance.get_FFT(axe,inverse);
05785 }
05786
05787 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> FFT(const CImg<T>& instance, const bool inverse=false) {
05788 return instance.get_FFT(inverse);
05789 }
05790
05791 template<typename T> inline CImg<T> blur_median(const CImg<T>& instance, const unsigned int n=3) {
05792 return instance.get_blur_median(n);
05793 }
05794
05795 template<typename T> inline CImg<T> sharpen(const CImg<T>& instance, const float amplitude=50.0f, const float edge=1.0f,
05796 const float alpha=0.0f, const float sigma=0.0f) {
05797 return instance.get_sharpen(amplitude,edge,alpha,sigma);
05798 }
05799
05800 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05801 haar(const CImg<T>& instance, const char axis, const bool inverse=false, const unsigned int nb_scales=1) {
05802 return instance.get_haar(axis,inverse,nb_scales);
05803 }
05804
05805 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05806 haar(const CImg<T>& instance, const bool inverse=false, const unsigned int nb_scales=1) {
05807 return instance.get_haar(inverse,nb_scales);
05808 }
05809
05810 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05811 displacement_field(const CImg<T>& instance, const CImg<T>& reference,
05812 const float smooth=0.1f, const float precision=1e-6f,
05813 const unsigned int nb_scale=0,
05814 const unsigned int itermax=10000) {
05815 return instance.get_displacement_field(reference,smooth,precision,nb_scale,itermax);
05816 }
05817
05818 template<typename T> inline CImg<T> matrix(const CImg<T>& instance) {
05819 return instance.get_matrix();
05820 }
05821
05822 template<typename T> inline CImg<T> tensor(const CImg<T>& instance) {
05823 return instance.get_tensor();
05824 }
05825
05826 template<typename T> inline CImg<T> unroll(const CImg<T>& instance, const char axe='x') {
05827 return instance.get_unroll(axe);
05828 }
05829
05830 template<typename T> inline CImg<T> diagonal(const CImg<T>& instance) {
05831 return instance.get_diagonal();
05832 }
05833
05834 template<typename T> inline CImg<T> identity_matrix(const CImg<T>& instance) {
05835 return instance.get_identity_matrix();
05836 }
05837
05838 template<typename T> inline CImg<T> sequence(const CImg<T>& instance, const T a0, const T a1) {
05839 return instance.get_sequence(a0,a1);
05840 }
05841
05842 template<typename T> inline CImg<T> vector_at(const CImg<T>& instance, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) {
05843 return instance.get_vector_at(x,y,z);
05844 }
05845
05846 template<typename T> inline CImg<T> matrix_at(const CImg<T>& instance, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) {
05847 return instance.get_matrix_at(x,y,z);
05848 }
05849
05850 template<typename T> inline CImg<T> tensor_at(const CImg<T>& instance, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) {
05851 return instance.get_tensor_at(x,y,z);
05852 }
05853
05854 template<typename T> inline CImg<T> transpose(const CImg<T>& instance) {
05855 return instance.get_transpose();
05856 }
05857
05858 template<typename T> inline CImg<typename cimg::superset<T,float>::type> inverse(const CImg<T>& instance, const bool use_LU=true) {
05859 return instance.get_inverse(use_LU);
05860 }
05861
05862 template<typename T> inline CImg<typename cimg::superset<T,float>::type> pseudoinverse(const CImg<T>& instance) {
05863 return instance.get_pseudoinverse();
05864 }
05865
05866 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> cross(const CImg<T>& instance, const CImg<t>& img) {
05867 return instance.get_cross(img);
05868 }
05869
05870 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> SVD(const CImg<T>& instance, const bool sorting=true) {
05871 return instance.get_SVD(sorting);
05872 }
05873
05874 template<typename T, typename t> inline CImg<typename cimg::superset2<T,t,float>::type> solve(const CImg<T>& instance, const CImg<t>& A) {
05875 return instance.get_solve(A);
05876 }
05877
05878 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> eigen(const CImg<T>& instance) {
05879 return instance.get_eigen();
05880 }
05881
05882 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> symmetric_eigen(const CImg<T>& instance) {
05883 return instance.get_symmetric_eigen();
05884 }
05885
05886 template<typename T, typename t> inline CImg<T> sort(const CImg<T>& instance, CImg<t>& permutations, const bool increasing=true) {
05887 return instance.get_sort(permutations,increasing);
05888 }
05889
05890 template<typename T> inline CImg<T> sort(const CImg<T>& instance, const bool increasing=true) {
05891 return instance.get_sort(increasing);
05892 }
05893
05894 template<typename T, typename t> inline CImg<T> permute(const CImg<T>& instance, const CImg<t>& permutation) {
05895 return instance.get_permute(permutation);
05896 }
05897
05898 template<typename T> inline CImg<typename cimg::last<T,int>::type>
05899 coordinates(const CImg<T>& instance, const int coords_type, CImgDisplay &disp,
05900 unsigned int *const XYZ=0, const unsigned char *const color=0) {
05901 return instance.get_coordinates(coords_type,disp,XYZ,color);
05902 }
05903
05904 template<typename T, typename t> inline CImgList<typename cimg::superset<T,t>::type>
05905 insert(const CImgList<T>& instance, const CImg<t>& img, const unsigned int pos=~0U, const bool shared=false) {
05906 return instance.get_insert(img,pos,shared);
05907 }
05908
05909 template<typename T, typename t> inline CImgList<typename cimg::superset<T,t>::type>
05910 insert(const CImgList<T>& instance, const unsigned int n, const CImg<t>& img,
05911 const unsigned int pos=~0U, const bool shared=false) {
05912 return instance.get_insert(n,img,pos,shared);
05913 }
05914
05915 template<typename T, typename t> inline CImgList<typename cimg::superset<T,t>::type>
05916 insert(const CImgList<T>& instance, const CImgList<t>& list, const unsigned int pos=~0U, int shared=0) {
05917 return instance.get_insert(list,pos,shared);
05918 }
05919
05920 template<typename T, typename t> inline CImgList<typename cimg::superset<T,t>::type>
05921 insert(const CImgList<T>& instance, const unsigned int n, const CImgList<t>& list, const unsigned int pos=~0U, const int shared=0) {
05922 return instance.insert(n,list,pos,shared);
05923 }
05924
05925 template<typename T> inline CImgList<T> remove(const CImgList<T>& instance, const unsigned int pos) {
05926 return instance.get_remove(pos);
05927 }
05928
05929 template<typename T> inline CImgList<T> remove(const CImgList<T>& instance) {
05930 return instance.get_remove();
05931 }
05932
05933 template<typename T> inline CImgList<T> reverse(const CImgList<T>& instance) {
05934 return instance.get_reverse();
05935 }
05936
05937 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05938 const bool shared=false) {
05939 return instance.get_crop(i0,i1,shared);
05940 }
05941
05942 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05943 const int x0, const int y0, const int z0, const int v0,
05944 const int x1, const int y1, const int z1, const int v1) {
05945 return instance.get_crop(i0,i1,x0,y0,z0,v0,x1,y1,z1,v1);
05946 }
05947
05948 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05949 const int x0, const int y0, const int z0,
05950 const int x1, const int y1, const int z1) {
05951 return instance.get_crop(i0,i1,x0,y0,z0,x1,y1,z1);
05952 }
05953
05954 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05955 const int x0, const int y0,
05956 const int x1, const int y1) {
05957 return instance.get_crop(i0,i1,x0,y0,x1,y1);
05958 }
05959
05960 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05961 const int x0, const int x1) {
05962 return instance.get_crop(i0,i1,x0,x1);
05963 }
05964
05965 template<typename T> inline CImgList<typename cimg::superset<T,float>::type>
05966 FFT(const CImgList<T>& instance, const char axe, const bool inverse=false) {
05967 return instance.get_FFT(axe,inverse);
05968 }
05969
05970 template<typename T> inline CImgList<typename cimg::superset<T,float>::type>
05971 FFT(const CImgList<T>& instance, const bool inverse=false) {
05972 return instance.get_FFT(inverse);
05973 }
05974
05975 template<typename T> inline CImgList<T> split(const CImgList<T>& instance, const char axe='x') {
05976 return instance.get_split(axe);
05977 }
05978
05979 template<typename T> inline CImg<T> append(const CImgList<T>& instance, const char axe='x', const char align='c') {
05980 return instance.get_append(axe,align);
05981 }
05982
05983 template<typename T> inline CImgList<T> crop_font(const CImgList<T>& instance) {
05984 return instance.get_crop_font();
05985 }
05986
05987
05988
05989
05990
05991
05992
05993
05994
05995
05996
05997
05998
06000
06008 struct CImgDisplay {
06009
06011 unsigned int width;
06012
06014 unsigned int height;
06015
06017 unsigned int normalization;
06018
06020 unsigned int events;
06021
06023 char* title;
06024
06026 volatile int window_x;
06027
06029 volatile int window_y;
06030
06032 volatile unsigned int window_width;
06033
06035 volatile unsigned int window_height;
06036
06038 volatile int mouse_x;
06039
06041 volatile int mouse_y;
06042
06044 volatile unsigned int buttons[512];
06045 volatile unsigned int& button;
06046
06048 volatile int wheel;
06049
06051 volatile unsigned int& key;
06052 volatile unsigned int keys[512];
06053
06055 volatile unsigned int& released_key;
06056 volatile unsigned int released_keys[512];
06057
06059 volatile bool is_closed;
06060
06062 volatile bool is_resized;
06063
06065 volatile bool is_moved;
06066
06068 volatile bool is_event;
06069
06071 bool is_fullscreen;
06072
06073 float fps_fps, min, max;
06074 unsigned long timer, fps_frames, fps_timer;
06075
06076 #ifdef cimgdisplay_plugin
06077 #include cimgdisplay_plugin
06078 #endif
06079
06081 CImgDisplay():
06082 width(0),height(0),normalization(0),events(0),title(0),
06083 window_x(0),window_y(0),window_width(0),window_height(0),
06084 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06085 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),
06086 min(0),max(0) {}
06087
06089
06098 CImgDisplay(const unsigned int dimw, const unsigned int dimh, const char *title=0,
06099 const unsigned int normalization_type=3, const unsigned int events_type=3,
06100 const bool fullscreen_flag=false, const bool closed_flag=false):
06101 width(0),height(0),normalization(0),events(0),title(0),
06102 window_x(0),window_y(0),window_width(0),window_height(0),
06103 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06104 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),
06105 min(0),max(0) {
06106 assign(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06107 }
06108
06110
06117 template<typename T>
06118 CImgDisplay(const CImg<T>& img, const char *title=0,
06119 const unsigned int normalization_type=3, const unsigned int events_type=3,
06120 const bool fullscreen_flag=false, const bool closed_flag=false):
06121 width(0),height(0),normalization(0),events(0),title(0),
06122 window_x(0),window_y(0),window_width(0),window_height(0),
06123 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06124 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),min(0),max(0) {
06125 assign(img,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06126 }
06127
06129
06136 template<typename T>
06137 CImgDisplay(const CImgList<T>& list, const char *title=0,
06138 const unsigned int normalization_type=3, const unsigned int events_type=3,
06139 const bool fullscreen_flag=false, const bool closed_flag=false):
06140 width(0),height(0),normalization(0),events(0),title(0),
06141 window_x(0),window_y(0),window_width(0),window_height(0),
06142 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06143 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),min(0),max(0) {
06144 assign(list,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06145 }
06146
06148
06151 CImgDisplay(const CImgDisplay& disp):
06152 width(0),height(0),normalization(0),events(0),title(0),
06153 window_x(0),window_y(0),window_width(0),window_height(0),
06154 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06155 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),min(0),max(0) {
06156 assign(disp);
06157 }
06158
06160 ~CImgDisplay() {
06161 assign();
06162 }
06163
06165 CImgDisplay& operator=(const CImgDisplay& disp) {
06166 return assign(disp);
06167 }
06168
06170 bool is_empty() const {
06171 return (!width || !height);
06172 }
06173
06175 operator bool() const {
06176 return !is_empty();
06177 }
06178
06180 int dimx() const {
06181 return (int)width;
06182 }
06183
06185 int dimy() const {
06186 return (int)height;
06187 }
06188
06190 int window_dimx() const {
06191 return (int)window_width;
06192 }
06193
06195 int window_dimy() const {
06196 return (int)window_height;
06197 }
06198
06200 int window_posx() const {
06201 return window_x;
06202 }
06203
06205 int window_posy() const {
06206 return window_y;
06207 }
06208
06210
06212 CImgDisplay& wait(const unsigned int milliseconds) {
06213 cimg::wait(milliseconds, timer);
06214 return *this;
06215 }
06216
06218 CImgDisplay& wait() {
06219 if (!is_empty()) wait(*this);
06220 return *this;
06221 }
06222
06224 static void wait(CImgDisplay& disp1) {
06225 disp1.is_event = 0;
06226 while (!disp1.is_event) wait_all();
06227 }
06228
06230 static void wait(CImgDisplay& disp1, CImgDisplay& disp2) {
06231 disp1.is_event = disp2.is_event = 0;
06232 while (!disp1.is_event && !disp2.is_event) wait_all();
06233 }
06234
06236 static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3) {
06237 disp1.is_event = disp2.is_event = disp3.is_event = 0;
06238 while (!disp1.is_event && !disp2.is_event && !disp3.is_event) wait_all();
06239 }
06240
06242 static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4) {
06243 disp1.is_event = disp2.is_event = disp3.is_event = disp4.is_event = 0;
06244 while (!disp1.is_event && !disp2.is_event && !disp3.is_event && !disp4.is_event) wait_all();
06245 }
06246
06248 float frames_per_second() {
06249 if (!fps_timer) fps_timer = cimg::time();
06250 const float delta = (cimg::time()-fps_timer)/1000.0f;
06251 ++fps_frames;
06252 if (delta>=1.0f) {
06253 fps_fps = fps_frames/delta;
06254 fps_frames = 0;
06255 fps_timer = cimg::time();
06256 }
06257 return fps_fps;
06258 }
06259
06261
06270 template<typename T> CImgDisplay& display(const CImgList<T>& list, const char axe='x', const char align='c') {
06271 return display(list.get_append(axe,align));
06272 }
06273
06275 template<typename T> CImgDisplay& operator<<(const CImg<T>& img) {
06276 return display(img);
06277 }
06278
06280 template<typename T> CImgDisplay& operator<<(const CImgList<T>& list) {
06281 return display(list);
06282 }
06283
06285
06289 template<typename T> CImgDisplay& resize(const CImg<T>& img, const bool redraw=true) {
06290 return resize(img.width,img.height,redraw);
06291 }
06292
06294 CImgDisplay& resize(const CImgDisplay& disp, const bool redraw=true) {
06295 return resize(disp.width,disp.height,redraw);
06296 }
06297
06299 CImgDisplay& resize(const bool redraw=true) {
06300 resize(window_width,window_height,redraw);
06301 return *this;
06302 }
06303
06305 template<typename tp, typename tf, typename tc, typename to>
06306 CImgDisplay& display_object3d(const tp& points, const CImgList<tf>& primitives,
06307 const CImgList<tc>& colors, const to& opacities,
06308 const bool centering=true,
06309 const int render_static=4, const int render_motion=1,
06310 const bool double_sided=false,
06311 const float focale=500.0f, const float ambient_light=0.05f,
06312 const bool display_axes=true, float *const pose_matrix=0) {
06313 CImg<tc>(width,height,1,3,0).display_object3d(points,primitives,colors,opacities,*this,
06314 centering,render_static,render_motion,
06315 double_sided,focale,ambient_light,
06316 display_axes,pose_matrix);
06317 return *this;
06318 }
06319
06321 template<typename tp, typename tf, typename tc>
06322 CImgDisplay& display_object3d(const tp& points, const CImgList<tf>& primitives,
06323 const CImgList<tc>& colors,
06324 const bool centering=true,
06325 const int render_static=4, const int render_motion=1,
06326 const bool double_sided=false,
06327 const float focale=500.0f, const float ambient_light=0.05f,
06328 const bool display_axes=true,
06329 float *const pose_matrix=0,
06330 const float opacity=1.0f) {
06331 typedef typename cimg::superset<tc,float>::type to;
06332 CImg<tc>(width,height,1,3,0).display_object3d(points,primitives,colors,
06333 CImg<to>::vector((to)opacity),
06334 *this,centering,render_static,render_motion,
06335 double_sided,focale,ambient_light,display_axes,pose_matrix);
06336 return *this;
06337 }
06338
06340 CImgDisplay& toggle_fullscreen() {
06341 return assign(width,height,title,normalization,events,!is_fullscreen,is_closed);
06342 }
06343
06344
06345 template<typename t, typename T> static void _render_resize(const T *ptrs, const unsigned int ws, const unsigned int hs,
06346 t *ptrd, const unsigned int wd, const unsigned int hd) {
06347 unsigned int *const offx = new unsigned int[wd], *const offy = new unsigned int[hd+1], *poffx, *poffy;
06348 float s, curr, old;
06349 s = (float)ws/wd;
06350 poffx = offx; curr = 0; for (unsigned int x=0; x<wd; ++x) { old=curr; curr+=s; *(poffx++) = (unsigned int)curr-(unsigned int)old; }
06351 s = (float)hs/hd;
06352 poffy = offy; curr = 0; for (unsigned int y=0; y<hd; ++y) { old=curr; curr+=s; *(poffy++) = ws*((unsigned int)curr-(unsigned int)old); }
06353 *poffy = 0;
06354 poffy = offy;
06355 {for (unsigned int y=0; y<hd; ) {
06356 const T *ptr = ptrs;
06357 poffx = offx;
06358 for (unsigned int x=0; x<wd; ++x) { *(ptrd++) = *ptr; ptr+=*(poffx++); }
06359 ++y;
06360 unsigned int dy=*(poffy++);
06361 for (;!dy && y<hd; std::memcpy(ptrd, ptrd-wd, sizeof(t)*wd), ++y, ptrd+=wd, dy=*(poffy++));
06362 ptrs+=dy;
06363 }}
06364 delete[] offx; delete[] offy;
06365 }
06366
06368 CImgDisplay& flush() {
06369 std::memset((void*)buttons,0,512*sizeof(unsigned int));
06370 std::memset((void*)keys,0,512*sizeof(unsigned int));
06371 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
06372 mouse_x = mouse_y = -1;
06373 return *this;
06374 }
06375
06377 bool is_key(const bool remove=false) {
06378 for (unsigned int *ptrs=(unsigned int*)keys+512-1; ptrs>=keys; --ptrs) if (*ptrs) { if (remove) *ptrs = 0; return true; }
06379 return false;
06380 }
06381
06383 bool is_key(const unsigned int key1, const bool remove) {
06384 for (unsigned int *ptrs=(unsigned int*)keys+512-1; ptrs>=keys; --ptrs) if (*ptrs==key1) { if (remove) *ptrs = 0; return true; }
06385 return false;
06386 }
06387
06389 bool is_key(const unsigned int key1, const unsigned int key2, const bool remove) {
06390 const unsigned int seq[] = { key1, key2 };
06391 return is_key(seq,2,remove);
06392 }
06393
06395 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3, const bool remove) {
06396 const unsigned int seq[] = { key1, key2, key3 };
06397 return is_key(seq,3,remove);
06398 }
06399
06401 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06402 const unsigned int key4, const bool remove) {
06403 const unsigned int seq[] = { key1, key2, key3, key4 };
06404 return is_key(seq,4,remove);
06405 }
06406
06408 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06409 const unsigned int key4, const unsigned int key5, const bool remove) {
06410 const unsigned int seq[] = { key1, key2, key3, key4, key5 };
06411 return is_key(seq,5,remove);
06412 }
06413
06415 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06416 const unsigned int key4, const unsigned int key5, const unsigned int key6, const bool remove) {
06417 const unsigned int seq[] = { key1, key2, key3, key4, key5, key6 };
06418 return is_key(seq,6,remove);
06419 }
06420
06422 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06423 const unsigned int key4, const unsigned int key5, const unsigned int key6,
06424 const unsigned int key7, const bool remove) {
06425 const unsigned int seq[] = { key1, key2, key3, key4, key5, key6, key7 };
06426 return is_key(seq,7,remove);
06427 }
06428
06430 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06431 const unsigned int key4, const unsigned int key5, const unsigned int key6,
06432 const unsigned int key7, const unsigned int key8, const bool remove) {
06433 const unsigned int seq[] = { key1, key2, key3, key4, key5, key6, key7, key8 };
06434 return is_key(seq,8,remove);
06435 }
06436
06438 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06439 const unsigned int key4, const unsigned int key5, const unsigned int key6,
06440 const unsigned int key7, const unsigned int key8, const unsigned int key9, const bool remove) {
06441 const unsigned int seq[] = { key1, key2, key3, key4, key5, key6, key7, key8, key9 };
06442 return is_key(seq,9,remove);
06443 }
06444
06446 bool is_key(const unsigned int *const keyseq, const unsigned int N, const bool remove=true) {
06447 if (keyseq && N) {
06448 const unsigned int *const ps_end = keyseq+N-1, k = *ps_end, *const pk_end = (unsigned int*)keys+1+512-N;
06449 for (unsigned int *pk = (unsigned int*)keys; pk<pk_end; ) {
06450 if (*(pk++)==k) {
06451 bool res = true;
06452 const unsigned int *ps = ps_end, *pk2 = pk;
06453 for (unsigned int i=1; i<N; ++i) res = (*(--ps)==*(pk2++));
06454 if (res) {
06455 if (remove) std::memset((void*)(pk-1),0,sizeof(unsigned int)*N);
06456 return true;
06457 }
06458 }
06459 }
06460 }
06461 return false;
06462 }
06463
06464
06465
06466 #if cimg_display_type==0
06467
06469 static int screen_dimx() {
06470 return 0;
06471 }
06472
06474 static int screen_dimy() {
06475 return 0;
06476 }
06477
06479 CImgDisplay& assign() {
06480 return *this;
06481 }
06482
06484 CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0,
06485 const unsigned int normalization_type=3, const unsigned int events_type=3,
06486 const bool fullscreen_flag=false, const bool closed_flag=false) {
06487 throw CImgDisplayException("CImgDisplay() : Display has been required but is not available (cimg_display_type=0)");
06488 fps_timer = 0*(unsigned long)(dimw + dimh + title + normalization_type + events_type + (int)fullscreen_flag + (int)closed_flag);
06489 return *this;
06490 }
06491
06493 template<typename T> CImgDisplay& assign(const CImg<T>& img, const char *title=0,
06494 const unsigned int normalization_type=3, const unsigned int events_type=3,
06495 const bool fullscreen_flag=false, const bool closed_flag=false) {
06496 fps_timer = 0*(unsigned long)(img.width + title + normalization_type + events_type + (int)fullscreen_flag + (int)closed_flag);
06497 return assign(0,0);
06498 }
06499
06501 template<typename T> CImgDisplay& assign(const CImgList<T>& list, const char *title=0,
06502 const unsigned int normalization_type=3, const unsigned int events_type=3,
06503 const bool fullscreen_flag=false, const bool closed_flag=false) {
06504 fps_timer = 0*(unsigned long)(list.size + title + normalization_type + events_type + (int)fullscreen_flag + (int)closed_flag);
06505 return assign(0,0);
06506 }
06507
06509 CImgDisplay& assign(const CImgDisplay &disp) {
06510 return assign(disp.width,disp.height);
06511 }
06512
06514 template<typename T> CImgDisplay& display(const CImg<T>& img) {
06515 fps_timer = 0*img.width;
06516 return *this;
06517 }
06518
06520 CImgDisplay& resize(const int width, const int height, const bool redraw=true) {
06521 fps_timer = 0*width*height*(int)redraw;
06522 return *this;
06523 }
06524
06526 CImgDisplay& move(const int posx, const int posy) {
06527 fps_timer = 0*posx*posy;
06528 return *this;
06529 }
06530
06532 CImgDisplay& set_mouse(const int posx, const int posy) {
06533 fps_timer = 0*posx*posy;
06534 return *this;
06535 }
06536
06538 CImgDisplay& hide_mouse() {
06539 return *this;
06540 }
06541
06543 CImgDisplay& show_mouse() {
06544 return *this;
06545 }
06546
06548 static void wait_all() {}
06549
06551 CImgDisplay& show() {
06552 return *this;
06553 }
06554
06556 CImgDisplay& close() {
06557 return *this;
06558 }
06559
06561 CImgDisplay& set_title(const char *format,...) {
06562 fps_timer = 0*(unsigned long)format;
06563 return *this;
06564 }
06565
06567 CImgDisplay& paint() {
06568 return *this;
06569 }
06570
06572 template<typename T> CImgDisplay& render(const CImg<T>& img) {
06573 fps_timer = 0*img.width;
06574 return *this;
06575 }
06576
06578 template<typename T> const CImgDisplay& snapshot(CImg<T>& img) const {
06579 img.assign(width,height,1,3,0);
06580 return *this;
06581 }
06582
06583
06584
06585 #elif cimg_display_type==1
06586 void *data;
06587 Window window;
06588 Window background_window;
06589 XImage *image;
06590 Colormap colormap;
06591 Atom wm_delete_window, wm_delete_protocol;
06592 #ifdef cimg_use_xshm
06593 XShmSegmentInfo *shminfo;
06594 #endif
06595
06596 static int screen_dimx() {
06597 int res = 0;
06598 if (!cimg::X11attr().display) {
06599 Display *disp = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0"));
06600 if (!disp) throw CImgDisplayException("CImgDisplay::screen_dimx() : Can't open X11 display");
06601 res = DisplayWidth(disp,DefaultScreen(disp));
06602 XCloseDisplay(disp);
06603 } else {
06604 #ifdef cimg_use_xrandr
06605 if (cimg::X11attr().resolutions && cimg::X11attr().curr_resolution)
06606 res = cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].width;
06607 else
06608 #endif
06609 res = DisplayWidth(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
06610 }
06611 return res;
06612 }
06613
06614 static int screen_dimy() {
06615 int res = 0;
06616 if (!cimg::X11attr().display) {
06617 Display *disp = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0"));
06618 if (!disp) throw CImgDisplayException("CImgDisplay::screen_dimy() : Can't open X11 display");
06619 res = DisplayHeight(disp,DefaultScreen(disp));
06620 XCloseDisplay(disp);
06621 } else {
06622 #ifdef cimg_use_xrandr
06623 if (cimg::X11attr().resolutions && cimg::X11attr().curr_resolution)
06624 res = cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].height; else
06625 #endif
06626 res = DisplayHeight(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
06627 }
06628 return res;
06629 }
06630
06631 CImgDisplay& assign() {
06632 if (!is_empty()) {
06633 pthread_mutex_lock(cimg::X11attr().mutex);
06634
06635
06636 unsigned int i;
06637 for (i=0; i<cimg::X11attr().nb_wins && cimg::X11attr().wins[i]!=this; ++i);
06638 for (; i<cimg::X11attr().nb_wins-1; ++i) cimg::X11attr().wins[i]=cimg::X11attr().wins[i+1];
06639 --cimg::X11attr().nb_wins;
06640
06641
06642 if (is_fullscreen) _desinit_fullscreen();
06643 XDestroyWindow(cimg::X11attr().display,window);
06644 window = 0;
06645 #ifdef cimg_use_xshm
06646 if (shminfo) {
06647 XShmDetach(cimg::X11attr().display, shminfo);
06648 XDestroyImage(image);
06649 shmdt(shminfo->shmaddr);
06650 shmctl(shminfo->shmid,IPC_RMID,0);
06651 delete shminfo;
06652 shminfo = 0;
06653 } else
06654 #endif
06655 XDestroyImage(image);
06656 data = 0;
06657 image = 0;
06658 if (cimg::X11attr().nb_bits==8) XFreeColormap(cimg::X11attr().display,colormap);
06659 colormap = 0;
06660 XSync(cimg::X11attr().display, False);
06661
06662
06663 if (title) delete[] title;
06664 width = height = normalization = events = 0;
06665 is_fullscreen = false; is_resized = false; is_moved = false; is_event = false;
06666 is_closed = true;
06667 title = 0;
06668 window_x = window_y = window_width = window_height = mouse_x = mouse_y = wheel = 0;
06669 std::memset((void*)buttons,0,512*sizeof(unsigned int));
06670 std::memset((void*)keys,0,512*sizeof(unsigned int));
06671 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
06672 min = max = 0;
06673
06674
06675 if (!cimg::X11attr().nb_wins) {
06676
06677
06678 pthread_cancel(*cimg::X11attr().event_thread);
06679 pthread_mutex_unlock(cimg::X11attr().mutex);
06680 pthread_join(*cimg::X11attr().event_thread,0);
06681 delete cimg::X11attr().event_thread;
06682 cimg::X11attr().event_thread = 0;
06683 pthread_mutex_destroy(cimg::X11attr().mutex);
06684 delete cimg::X11attr().mutex;
06685 cimg::X11attr().mutex = 0;
06686 XSync(cimg::X11attr().display, False);
06687 XCloseDisplay(cimg::X11attr().display);
06688 cimg::X11attr().display = 0;
06689 delete cimg::X11attr().gc;
06690 cimg::X11attr().gc = 0;
06691 } else pthread_mutex_unlock(cimg::X11attr().mutex);
06692 }
06693 return *this;
06694 }
06695
06696 CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0,
06697 const unsigned int normalization_type=3, const unsigned int events_type=3,
06698 const bool fullscreen_flag=false, const bool closed_flag=false) {
06699 if (!dimw || !dimh) return assign();
06700 _assign(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06701 min = max = 0;
06702 std::memset(data,0,(cimg::X11attr().nb_bits==8?sizeof(unsigned char):
06703 (cimg::X11attr().nb_bits==16?sizeof(unsigned short):sizeof(unsigned int)))*width*height);
06704 return paint();
06705 }
06706
06707 template<typename T> CImgDisplay& assign(const CImg<T>& img, const char *title=0,
06708 const unsigned int normalization_type=3, const unsigned int events_type=3,
06709 const bool fullscreen_flag=false, const bool closed_flag=false) {
06710 if (!img) return assign();
06711 CImg<T> tmp;
06712 const CImg<T>& nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
06713 _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06714 if (normalization==2) min = (float)nimg.minmax(max);
06715 return render(nimg).paint();
06716 }
06717
06718 template<typename T> CImgDisplay& assign(const CImgList<T>& list, const char *title=0,
06719 const unsigned int normalization_type=3, const unsigned int events_type=3,
06720 const bool fullscreen_flag=false, const bool closed_flag=false) {
06721 if (!list) return assign();
06722 CImg<T> tmp;
06723 const CImg<T> img = list.get_append('x','p'),
06724 &nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
06725 _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06726 if (normalization==2) min = (float)nimg.minmax(max);
06727 return render(nimg).paint();
06728 }
06729
06730 CImgDisplay& assign(const CImgDisplay& win) {
06731 if (!win) return assign();
06732 _assign(win.width,win.height,win.title,win.normalization,win.events,win.is_fullscreen,win.is_closed);
06733 std::memcpy(data,win.data,(cimg::X11attr().nb_bits==8?sizeof(unsigned char):
06734 cimg::X11attr().nb_bits==16?sizeof(unsigned short):
06735 sizeof(unsigned int))*width*height);
06736 return paint();
06737 }
06738
06739 template<typename T> CImgDisplay& display(const CImg<T>& img) {
06740 if (is_empty()) assign(img.width,img.height);
06741 return render(img).paint(false);
06742 }
06743
06744 CImgDisplay& resize(const int nwidth, const int nheight, const bool redraw=true) {
06745 if (!nwidth || !nheight) return assign();
06746 if (is_empty()) return assign(cimg::max(nwidth,0),cimg::max(nheight,0));
06747 const unsigned int
06748 tmpdimx = (nwidth>0)?nwidth:(-nwidth*width/100),
06749 tmpdimy = (nheight>0)?nheight:(-nheight*height/100),
06750 dimx = cimg::min(tmpdimx?tmpdimx:1,(unsigned int)screen_dimx()),
06751 dimy = cimg::min(tmpdimy?tmpdimy:1,(unsigned int)screen_dimy());
06752 const bool
06753 is_disp_different = (width!=dimx || height!=dimy),
06754 is_win_different = (window_width!=dimx || window_height!=dimy);
06755 if (is_disp_different || is_win_different) {
06756 pthread_mutex_lock(cimg::X11attr().mutex);
06757 XResizeWindow(cimg::X11attr().display,window,dimx,dimy);
06758 window_width = dimx;
06759 window_height = dimy;
06760 is_resized = false;
06761 if (is_disp_different) {
06762 switch (cimg::X11attr().nb_bits) {
06763 case 8: { unsigned char foo = 0; _resize(foo,dimx,dimy,redraw); } break;
06764 case 16: { unsigned short foo = 0; _resize(foo,dimx,dimy,redraw); } break;
06765 default: { unsigned int foo = 0; _resize(foo,dimx,dimy,redraw); } break;
06766 }
06767 width = dimx;
06768 height = dimy;
06769 }
06770 pthread_mutex_unlock(cimg::X11attr().mutex);
06771 if (is_fullscreen) move((screen_dimx()-width)/2,(screen_dimy()-height)/2);
06772 if (redraw) return paint();
06773 }
06774 return *this;
06775 }
06776
06777 CImgDisplay& move(const int posx, const int posy) {
06778 if (is_empty()) return *this;
06779 show();
06780 pthread_mutex_lock(cimg::X11attr().mutex);
06781 XMoveWindow(cimg::X11attr().display,window,posx,posy);
06782 is_moved = false;
06783 window_x = posx;
06784 window_y = posy;
06785 pthread_mutex_unlock(cimg::X11attr().mutex);
06786 return paint();
06787 }
06788
06789 CImgDisplay& set_mouse(const int posx, const int posy) {
06790 if (!is_closed && posx>=0 && posy>=0) {
06791 pthread_mutex_lock(cimg::X11attr().mutex);
06792 XWarpPointer(cimg::X11attr().display,None,window,0,0,0,0,posx,posy);
06793 is_moved = false;
06794 mouse_x = posx;
06795 mouse_y = posy;
06796 XSync(cimg::X11attr().display, False);
06797 pthread_mutex_unlock(cimg::X11attr().mutex);
06798 }
06799 return *this;
06800 }
06801
06802 CImgDisplay& hide_mouse() {
06803 if (cimg::X11attr().display) {
06804 pthread_mutex_lock(cimg::X11attr().mutex);
06805 const char pix_data[8] = { 0 };
06806 XColor col;
06807 col.red = col.green = col.blue = 0;
06808 Pixmap pix = XCreateBitmapFromData(cimg::X11attr().display,window,pix_data,8,8);
06809 Cursor cur = XCreatePixmapCursor(cimg::X11attr().display,pix,pix,&col,&col,0,0);
06810 XFreePixmap(cimg::X11attr().display,pix);
06811 XDefineCursor(cimg::X11attr().display,window,cur);
06812 pthread_mutex_unlock(cimg::X11attr().mutex);
06813 }
06814 return *this;
06815 }
06816
06817 CImgDisplay& show_mouse() {
06818 if (cimg::X11attr().display) {
06819 pthread_mutex_lock(cimg::X11attr().mutex);
06820 XDefineCursor(cimg::X11attr().display,window,None);
06821 pthread_mutex_unlock(cimg::X11attr().mutex);
06822 }
06823 return *this;
06824 }
06825
06826 static void wait_all() {
06827 if (cimg::X11attr().display) {
06828 pthread_mutex_lock(cimg::X11attr().mutex);
06829 bool flag = true;
06830 XEvent event;
06831 while (flag) {
06832 for (unsigned int i=0; i<cimg::X11attr().nb_wins; ++i) {
06833 cimg::X11attr().wins[i]->is_event = false;
06834 const unsigned int xevent_type = (cimg::X11attr().wins[i]->events)&3;
06835 const unsigned int emask =
06836 ((xevent_type>=1)?ExposureMask|StructureNotifyMask:0)|
06837 ((xevent_type>=2)?ButtonPressMask|KeyPressMask|PointerMotionMask|LeaveWindowMask:0)|
06838 ((xevent_type>=3)?ButtonReleaseMask|KeyReleaseMask:0);
06839 XSelectInput(cimg::X11attr().display,cimg::X11attr().wins[i]->window,emask);
06840 }
06841 XNextEvent(cimg::X11attr().display, &event);
06842 for (unsigned int i=0; i<cimg::X11attr().nb_wins; ++i)
06843 if (!cimg::X11attr().wins[i]->is_closed && event.xany.window==cimg::X11attr().wins[i]->window) {
06844 cimg::X11attr().wins[i]->_handle_events(&event);
06845 if (cimg::X11attr().wins[i]->is_event) flag = false;
06846 }
06847 }
06848 pthread_mutex_unlock(cimg::X11attr().mutex);
06849 }
06850 }
06851
06852 CImgDisplay& show() {
06853 if (is_empty()) return *this;
06854 if (is_closed) {
06855 pthread_mutex_lock(cimg::X11attr().mutex);
06856 if (is_fullscreen) _init_fullscreen();
06857 _map_window();
06858 is_closed = false;
06859 pthread_mutex_unlock(cimg::X11attr().mutex);
06860 }
06861 return paint();
06862 }
06863
06864 CImgDisplay& close() {
06865 if (is_empty()) return *this;
06866 if (!is_closed) {
06867 pthread_mutex_lock(cimg::X11attr().mutex);
06868 if (is_fullscreen) _desinit_fullscreen();
06869 XUnmapWindow(cimg::X11attr().display,window);
06870 window_x = window_y = -1;
06871 is_closed = true;
06872 pthread_mutex_unlock(cimg::X11attr().mutex);
06873 }
06874 return *this;
06875 }
06876
06877 CImgDisplay& set_title(const char *format,...) {
06878 if (is_empty()) return *this;
06879 char tmp[1024] = {0};
06880 va_list ap;
06881 va_start(ap, format);
06882 std::vsprintf(tmp,format,ap);
06883 va_end(ap);
06884 if (title) delete[] title;
06885 const int s = cimg::strlen(tmp)+1;
06886 title = new char[s];
06887 std::memcpy(title,tmp,s*sizeof(char));
06888 pthread_mutex_lock(cimg::X11attr().mutex);
06889 XStoreName(cimg::X11attr().display,window,tmp);
06890 pthread_mutex_unlock(cimg::X11attr().mutex);
06891 return *this;
06892 }
06893
06894 CImgDisplay& paint(const bool wait_expose=true) {
06895 if (is_empty()) return *this;
06896 pthread_mutex_lock(cimg::X11attr().mutex);
06897 _paint(wait_expose);
06898 pthread_mutex_unlock(cimg::X11attr().mutex);
06899 return *this;
06900 }
06901
06902 template<typename T> CImgDisplay& render(const CImg<T>& img, const bool flag8=false) {
06903 if (is_empty()) return *this;
06904 if (!img)
06905 throw CImgArgumentException("CImgDisplay::_render_image() : Specified input image (%u,%u,%u,%u,%p) is empty.",
06906 img.width,img.height,img.depth,img.dim,img.data);
06907 if (img.depth!=1) return render(img.get_projections2d(img.width/2,img.height/2,img.depth/2));
06908 if (cimg::X11attr().nb_bits==8 && (img.width!=width || img.height!=height)) return render(img.get_resize(width,height,1,-100,1));
06909 if (cimg::X11attr().nb_bits==8 && !flag8 && img.dim==3) return render(img.get_RGBtoLUT(true),true);
06910
06911 const unsigned int xymax = img.width*img.height;
06912 const T
06913 *data1 = img.data,
06914 *data2 = (img.dim>=2)?img.ptr(0,0,0,1):data1,
06915 *data3 = (img.dim>=3)?img.ptr(0,0,0,2):data1;
06916 if (cimg::X11attr().blue_first) cimg::swap(data1,data3);
06917 pthread_mutex_lock(cimg::X11attr().mutex);
06918
06919 if (!normalization || (normalization==3 && cimg::type<T>::string()==cimg::type<unsigned char>::string())) {
06920 min = max = 0;
06921 switch (cimg::X11attr().nb_bits) {
06922 case 8: {
06923 _set_colormap(colormap,img.dim);
06924 unsigned char *const ndata = (img.width==width && img.height==height)?(unsigned char*)data:new unsigned char[img.width*img.height];
06925 unsigned char *ptrd = (unsigned char*)ndata;
06926 switch (img.dim) {
06927 case 1: for (unsigned int xy=0; xy<xymax; ++xy) (*ptrd++) = (unsigned char)*(data1++);
06928 break;
06929 case 2: for (unsigned int xy=0; xy<xymax; ++xy) {
06930 const unsigned char R = (unsigned char)*(data1++), G = (unsigned char)*(data2++);
06931 (*ptrd++) = (R&0xf0)|(G>>4);
06932 } break;
06933 default: for (unsigned int xy=0; xy<xymax; ++xy) {
06934 const unsigned char R = (unsigned char)*(data1++), G = (unsigned char)*(data2++), B = (unsigned char)*(data3++);
06935 (*ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6);
06936 } break;
06937 }
06938 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned char*)data,width,height); delete[] ndata; }
06939 } break;
06940 case 16: {
06941 unsigned short *const ndata = (img.width==width && img.height==height)?(unsigned short*)data:new unsigned short[img.width*img.height];
06942 unsigned char *ptrd = (unsigned char*)ndata;
06943 const unsigned int M = 248;
06944 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
06945 const unsigned char G = (unsigned char)*(data2++)>>2;
06946 *(ptrd++) = ((unsigned char)*(data1++)&M) | (G>>3);
06947 *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3);
06948 } else for (unsigned int xy=0; xy<xymax; ++xy) {
06949 const unsigned char G = (unsigned char)*(data2++)>>2;
06950 *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3);
06951 *(ptrd++) = ((unsigned char)*(data1++)&M) | (G>>3);
06952 }
06953 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned short*)data,width,height); delete[] ndata; }
06954 } break;
06955 default: {
06956 unsigned int *const ndata = (img.width==width && img.height==height)?(unsigned int*)data:new unsigned int[img.width*img.height];
06957 unsigned char *ptrd = (unsigned char*)ndata;
06958 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
06959 *(ptrd++) = 0;
06960 *(ptrd++) = (unsigned char)*(data1++);
06961 *(ptrd++) = (unsigned char)*(data2++);
06962 *(ptrd++) = (unsigned char)*(data3++);
06963 } else for (unsigned int xy=0; xy<xymax; ++xy) {
06964 *(ptrd++) = (unsigned char)*(data3++);
06965 *(ptrd++) = (unsigned char)*(data2++);
06966 *(ptrd++) = (unsigned char)*(data1++);
06967 *(ptrd++) = 0;
06968 }
06969 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned int*)data,width,height); delete[] ndata; }
06970 } break;
06971 };
06972 } else {
06973 if (normalization==3) {
06974 if (cimg::type<T>::is_float()) min = (float)img.minmax(max);
06975 else { min = (float)cimg::type<T>::min(); max = (float)cimg::type<T>::max(); }
06976 } else if ((min>max) || normalization==1) min = (float)img.minmax(max);
06977 const float delta = max-min, mm = delta?delta:1.0f;
06978 switch (cimg::X11attr().nb_bits) {
06979 case 8: {
06980 _set_colormap(colormap,img.dim);
06981 unsigned char *const ndata = (img.width==width && img.height==height)?(unsigned char*)data:new unsigned char[img.width*img.height];
06982 unsigned char *ptrd = (unsigned char*)ndata;
06983 switch (img.dim) {
06984 case 1: for (unsigned int xy=0; xy<xymax; ++xy) {
06985 const unsigned char R = (unsigned char)(255*(*(data1++)-min)/mm);
06986 *(ptrd++) = R;
06987 } break;
06988 case 2: for (unsigned int xy=0; xy<xymax; ++xy) {
06989 const unsigned char
06990 R = (unsigned char)(255*(*(data1++)-min)/mm),
06991 G = (unsigned char)(255*(*(data2++)-min)/mm);
06992 (*ptrd++) = (R&0xf0) | (G>>4);
06993 } break;
06994 default:
06995 for (unsigned int xy=0; xy<xymax; ++xy) {
06996 const unsigned char
06997 R = (unsigned char)(255*(*(data1++)-min)/mm),
06998 G = (unsigned char)(255*(*(data2++)-min)/mm),
06999 B = (unsigned char)(255*(*(data3++)-min)/mm);
07000 *(ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6);
07001 } break;
07002 }
07003 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned char*)data,width,height); delete[] ndata; }
07004 } break;
07005 case 16: {
07006 unsigned short *const ndata = (img.width==width && img.height==height)?(unsigned short*)data:new unsigned short[img.width*img.height];
07007 unsigned char *ptrd = (unsigned char*)ndata;
07008 const unsigned int M = 248;
07009 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
07010 const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2;
07011 *(ptrd++) = ((unsigned char)(255*(*(data1++)-min)/mm)&M) | (G>>3);
07012 *(ptrd++) = (G<<5) | ((unsigned char)(255*(*(data3++)-min)/mm)>>3);
07013 } else for (unsigned int xy=0; xy<xymax; ++xy) {
07014 const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2;
07015 *(ptrd++) = (G<<5) | ((unsigned char)(255*(*(data3++)-min)/mm)>>3);
07016 *(ptrd++) = ((unsigned char)(255*(*(data1++)-min)/mm)&M) | (G>>3);
07017 }
07018 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned short*)data,width,height); delete[] ndata; }
07019 } break;
07020 default: {
07021 unsigned int *const ndata = (img.width==width && img.height==height)?(unsigned int*)data:new unsigned int[img.width*img.height];
07022 unsigned char *ptrd = (unsigned char*)ndata;
07023 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
07024 (*ptrd++) = 0;
07025 (*ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm);
07026 (*ptrd++) = (unsigned char)(255*(*(data2++)-min)/mm);
07027 (*ptrd++) = (unsigned char)(255*(*(data3++)-min)/mm);
07028 } else for (unsigned int xy=0; xy<xymax; ++xy) {
07029 (*ptrd++) = (unsigned char)(255*(*(data3++)-min)/mm);
07030 (*ptrd++) = (unsigned char)(255*(*(data2++)-min)/mm);
07031 (*ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm);
07032 (*ptrd++) = 0;
07033 }
07034 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned int*)data,width,height); delete[] ndata; }
07035 } break;
07036 }
07037 }
07038 pthread_mutex_unlock(cimg::X11attr().mutex);
07039 return *this;
07040 }
07041
07042 template<typename T> const CImgDisplay& snapshot(CImg<T>& img) const {
07043 if (is_empty()) img.assign();
07044 else {
07045 img.assign(width,height,1,3);
07046 const unsigned int xymax = width*height;
07047 T
07048 *data1 = img.ptr(0,0,0,0),
07049 *data2 = img.ptr(0,0,0,1),
07050 *data3 = img.ptr(0,0,0,2);
07051 if (cimg::X11attr().blue_first) cimg::swap(data1,data3);
07052 switch (cimg::X11attr().nb_bits) {
07053 case 8: {
07054 unsigned char *ptrs = (unsigned char*)data;
07055 for (unsigned int xy=0; xy<xymax; ++xy) {
07056 const unsigned char val = *(ptrs++);
07057 *(data1++) = val&0xe0;
07058 *(data2++) = (val&0x1c)<<3;
07059 *(data3++) = val<<6;
07060 }
07061 } break;
07062 case 16: {
07063 unsigned char *ptrs = (unsigned char*)data;
07064 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
07065 const unsigned char val0 = *(ptrs++), val1 = *(ptrs++);
07066 *(data1++) = val0&0xf8;
07067 *(data2++) = (val0<<5) | ((val1&0xe0)>>5);
07068 *(data3++) = val1<<3;
07069 } else for (unsigned int xy=0; xy<xymax; ++xy) {
07070 const unsigned short val0 = *(ptrs++), val1 = *(ptrs++);
07071 *(data1++) = val1&0xf8;
07072 *(data2++) = (val1<<5) | ((val0&0xe0)>>5);
07073 *(data3++) = val0<<3;
07074 }
07075 } break;
07076 default: {
07077 unsigned char *ptrs = (unsigned char*)data;
07078 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
07079 ++ptrs;
07080 *(data1++) = *(ptrs++);
07081 *(data2++) = *(ptrs++);
07082 *(data3++) = *(ptrs++);
07083 } else for (unsigned int xy=0; xy<xymax; ++xy) {
07084 *(data3++) = *(ptrs++);
07085 *(data2++) = *(ptrs++);
07086 *(data1++) = *(ptrs++);
07087 ++ptrs;
07088 }
07089 } break;
07090 }
07091 }
07092 return *this;
07093 }
07094
07095 static int _assign_xshm(Display *dpy, XErrorEvent *error) {
07096 dpy = 0; error = 0;
07097 cimg::X11attr().shm_enabled = false;
07098 return 0;
07099 }
07100
07101 void _assign(const unsigned int dimw, const unsigned int dimh, const char *ptitle=0,
07102 const unsigned int normalization_type=3, const unsigned int events_type=3,
07103 const bool fullscreen_flag=false, const bool closed_flag=false) {
07104
07105
07106 const int s = cimg::strlen(ptitle)+1;
07107 char *tmp_title = s?new char[s]:0;
07108 if (s) std::memcpy(tmp_title,ptitle,s*sizeof(char));
07109
07110
07111 if (!is_empty()) assign();
07112
07113
07114 if (!cimg::X11attr().display) {
07115 cimg::X11attr().nb_wins = 0;
07116 cimg::X11attr().mutex = new pthread_mutex_t;
07117 pthread_mutex_init(cimg::X11attr().mutex,0);
07118
07119 cimg::X11attr().display = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0"));
07120 if (!cimg::X11attr().display)
07121 throw CImgDisplayException("CImgDisplay::_create_window() : Can't open X11 display");
07122 cimg::X11attr().nb_bits = DefaultDepth(cimg::X11attr().display, DefaultScreen(cimg::X11attr().display));
07123 if (cimg::X11attr().nb_bits!=8 && cimg::X11attr().nb_bits!=16 && cimg::X11attr().nb_bits!=24 && cimg::X11attr().nb_bits!=32)
07124 throw CImgDisplayException("CImgDisplay::_create_window() : %u bits mode is not supported "
07125 "(only 8, 16, 24 and 32 bits modes are supported)",cimg::X11attr().nb_bits);
07126 cimg::X11attr().gc = new GC;
07127 *cimg::X11attr().gc = DefaultGC(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
07128 Visual *visual = DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
07129 XVisualInfo vtemplate;
07130 vtemplate.visualid = XVisualIDFromVisual(visual);
07131 int nb_visuals;
07132 XVisualInfo *vinfo = XGetVisualInfo(cimg::X11attr().display,VisualIDMask,&vtemplate,&nb_visuals);
07133 if (vinfo && vinfo->red_mask<vinfo->blue_mask) cimg::X11attr().blue_first = true;
07134 cimg::X11attr().byte_order = ImageByteOrder(cimg::X11attr().display);
07135 XFree(vinfo);
07136 pthread_mutex_lock(cimg::X11attr().mutex);
07137 cimg::X11attr().event_thread = new pthread_t;
07138 pthread_create(cimg::X11attr().event_thread,0,_events_thread,0);
07139 } else pthread_mutex_lock(cimg::X11attr().mutex);
07140
07141
07142 width = cimg::min(dimw,(unsigned int)screen_dimx());
07143 height = cimg::min(dimh,(unsigned int)screen_dimy());
07144 normalization = normalization_type%4;
07145 events = events_type%4;
07146 is_fullscreen = fullscreen_flag;
07147 title = tmp_title;
07148 window_x = window_y = wheel = 0;
07149 mouse_x = mouse_y = -1;
07150 std::memset((void*)buttons,0,512*sizeof(unsigned int));
07151 std::memset((void*)keys,0,512*sizeof(unsigned int));
07152 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
07153 is_resized = is_moved = is_event = false;
07154 is_closed = closed_flag;
07155 fps_timer = fps_frames = timer = 0;
07156 fps_fps = 0;
07157
07158
07159 if (is_fullscreen) {
07160 _init_fullscreen();
07161 const unsigned int sx = screen_dimx(), sy = screen_dimy();
07162 XSetWindowAttributes winattr;
07163 winattr.override_redirect = True;
07164 window = XCreateWindow(cimg::X11attr().display,
07165 RootWindow(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07166 (sx-width)/2,(sy-height)/2,
07167 width,height,0,0,InputOutput,CopyFromParent,CWOverrideRedirect,&winattr);
07168 } else
07169 window = XCreateSimpleWindow(cimg::X11attr().display,
07170 RootWindow(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07171 0,0,width,height,2,0,0x0L);
07172 XStoreName(cimg::X11attr().display,window,title?title:" ");
07173 if (cimg::X11attr().nb_bits==8) {
07174 colormap = XCreateColormap(cimg::X11attr().display,window,DefaultVisual(cimg::X11attr().display,
07175 DefaultScreen(cimg::X11attr().display)),AllocAll);
07176 _set_colormap(colormap,3);
07177 XSetWindowColormap(cimg::X11attr().display,window,colormap);
07178 }
07179 window_width = width;
07180 window_height = height;
07181
07182
07183 const unsigned int bufsize = width*height*(cimg::X11attr().nb_bits==8?1:(cimg::X11attr().nb_bits==16?2:4));
07184 #ifdef cimg_use_xshm
07185 shminfo = 0;
07186 if (XShmQueryExtension(cimg::X11attr().display)) {
07187 shminfo = new XShmSegmentInfo;
07188 image = XShmCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07189 cimg::X11attr().nb_bits,ZPixmap,0,shminfo,width,height);
07190 if (!image) {
07191 delete shminfo;
07192 shminfo = 0;
07193 } else {
07194 shminfo->shmid = shmget(IPC_PRIVATE, bufsize, IPC_CREAT | 0777);
07195 if (shminfo->shmid==-1) {
07196 XDestroyImage(image);
07197 delete shminfo;
07198 shminfo = 0;
07199 } else {
07200 shminfo->shmaddr = image->data = (char*)(data = shmat(shminfo->shmid,0,0));
07201 if (shminfo->shmaddr==(char*)-1) {
07202 shmctl(shminfo->shmid,IPC_RMID,0);
07203 XDestroyImage(image);
07204 delete shminfo;
07205 shminfo = 0;
07206 } else {
07207 shminfo->readOnly = False;
07208 cimg::X11attr().shm_enabled = true;
07209 XErrorHandler oldXErrorHandler = XSetErrorHandler(_assign_xshm);
07210 XShmAttach(cimg::X11attr().display, shminfo);
07211 XSync(cimg::X11attr().display, False);
07212 XSetErrorHandler(oldXErrorHandler);
07213 if (!cimg::X11attr().shm_enabled) {
07214 shmdt(shminfo->shmaddr);
07215 shmctl(shminfo->shmid,IPC_RMID,0);
07216 XDestroyImage(image);
07217 delete shminfo;
07218 shminfo = 0;
07219 }
07220 }
07221 }
07222 }
07223 }
07224 if (!shminfo)
07225 #endif
07226 {
07227 data = std::malloc(bufsize);
07228 image = XCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07229 cimg::X11attr().nb_bits,ZPixmap,0,(char*)data,width,height,8,0);
07230 }
07231
07232 if (!is_closed) _map_window(); else { window_x = window_y = cimg::type<int>::min(); }
07233
07234 if (events) {
07235 wm_delete_window = XInternAtom(cimg::X11attr().display, "WM_DELETE_WINDOW", False);
07236 wm_delete_protocol = XInternAtom(cimg::X11attr().display, "WM_PROTOCOLS", False);
07237 XSetWMProtocols(cimg::X11attr().display, window, &wm_delete_window, 1);
07238 if (is_fullscreen) XGrabKeyboard(cimg::X11attr().display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
07239 }
07240 cimg::X11attr().wins[cimg::X11attr().nb_wins++]=this;
07241 pthread_mutex_unlock(cimg::X11attr().mutex);
07242 }
07243
07244 void _map_window() {
07245 XWindowAttributes attr;
07246 XEvent event;
07247 XSelectInput(cimg::X11attr().display,window,ExposureMask | StructureNotifyMask);
07248 bool exposed = false, mapped = false;
07249 XMapRaised(cimg::X11attr().display,window);
07250 XSync(cimg::X11attr().display,False);
07251 do {
07252 XWindowEvent(cimg::X11attr().display,window,StructureNotifyMask | ExposureMask,&event);
07253 switch (event.type) {
07254 case MapNotify: mapped = true; break;
07255 case Expose: exposed = true; break;
07256 default: XSync(cimg::X11attr().display, False); cimg::sleep(10);
07257 }
07258 } while (!(exposed && mapped));
07259 do {
07260 XGetWindowAttributes(cimg::X11attr().display, window, &attr);
07261 if (attr.map_state!=IsViewable) { XSync(cimg::X11attr().display,False); cimg::sleep(10); }
07262 } while (attr.map_state != IsViewable);
07263 window_x = attr.x;
07264 window_y = attr.y;
07265 }
07266
07267 void _set_colormap(Colormap& colormap, const unsigned int dim) {
07268 XColor palette[256];
07269 switch (dim) {
07270 case 1:
07271 for (unsigned int index=0; index<256; ++index) {
07272 palette[index].pixel = index;
07273 palette[index].red = palette[index].green = palette[index].blue = (unsigned short)(index<<8);
07274 palette[index].flags = DoRed | DoGreen | DoBlue;
07275 }
07276 break;
07277 case 2:
07278 for (unsigned int index=0, r=8; r<256; r+=16)
07279 for (unsigned int g=8; g<256; g+=16) {
07280 palette[index].pixel = index;
07281 palette[index].red = palette[index].blue = (unsigned short)(r<<8);
07282 palette[index].green = (unsigned short)(g<<8);
07283 palette[index++].flags = DoRed | DoGreen | DoBlue;
07284 }
07285 break;
07286 default:
07287 for (unsigned int index=0, r=16; r<256; r+=32)
07288 for (unsigned int g=16; g<256; g+=32)
07289 for (unsigned int b=32; b<256; b+=64) {
07290 palette[index].pixel = index;
07291 palette[index].red = (unsigned short)(r<<8);
07292 palette[index].green = (unsigned short)(g<<8);
07293 palette[index].blue = (unsigned short)(b<<8);
07294 palette[index++].flags = DoRed | DoGreen | DoBlue;
07295 }
07296 break;
07297 }
07298 XStoreColors(cimg::X11attr().display,colormap,palette,256);
07299 }
07300
07301 void _paint(const bool wait_expose=true) {
07302 if (!is_closed) {
07303 if (wait_expose) {
07304 static XEvent event;
07305 event.xexpose.type = Expose;
07306 event.xexpose.serial = 0;
07307 event.xexpose.send_event = True;
07308 event.xexpose.display = cimg::X11attr().display;
07309 event.xexpose.window = window;
07310 event.xexpose.x = 0;
07311 event.xexpose.y = 0;
07312 event.xexpose.width = dimx();
07313 event.xexpose.height = dimy();
07314 event.xexpose.count = 0;
07315 XSendEvent(cimg::X11attr().display, window, False, 0, &event);
07316 } else {
07317 #ifdef cimg_use_xshm
07318 if (shminfo) XShmPutImage(cimg::X11attr().display,window,*cimg::X11attr().gc,image,0,0,0,0,width,height,False);
07319 else
07320 #endif
07321 XPutImage(cimg::X11attr().display,window,*cimg::X11attr().gc,image,0,0,0,0,width,height);
07322 XSync(cimg::X11attr().display, False);
07323 }
07324 }
07325 }
07326
07327 template<typename T> void _resize(T foo, const unsigned int ndimx, const unsigned int ndimy, const bool redraw) {
07328 foo = 0;
07329 #ifdef cimg_use_xshm
07330 if (shminfo) {
07331 XShmSegmentInfo *nshminfo = new XShmSegmentInfo;
07332 XImage *nimage = XShmCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07333 cimg::X11attr().nb_bits,ZPixmap,0,nshminfo,ndimx,ndimy);
07334 if (!nimage) {
07335 delete nshminfo;
07336 return;
07337 } else {
07338 nshminfo->shmid = shmget(IPC_PRIVATE, ndimx*ndimy*sizeof(T), IPC_CREAT | 0777);
07339 if (nshminfo->shmid==-1) {
07340 XDestroyImage(nimage);
07341 delete nshminfo;
07342 return;
07343 } else {
07344 nshminfo->shmaddr = nimage->data = (char*)shmat(nshminfo->shmid,0,0);
07345 if (nshminfo->shmaddr==(char*)-1) {
07346 shmctl(nshminfo->shmid,IPC_RMID,0);
07347 XDestroyImage(nimage);
07348 delete nshminfo;
07349 return;
07350 } else {
07351 nshminfo->readOnly = False;
07352 cimg::X11attr().shm_enabled = true;
07353 XErrorHandler oldXErrorHandler = XSetErrorHandler(_assign_xshm);
07354 XShmAttach(cimg::X11attr().display, nshminfo);
07355 XSync(cimg::X11attr().display, False);
07356 XSetErrorHandler(oldXErrorHandler);
07357 if (!cimg::X11attr().shm_enabled) {
07358 shmdt(nshminfo->shmaddr);
07359 shmctl(nshminfo->shmid,IPC_RMID,0);
07360 XDestroyImage(nimage);
07361 delete nshminfo;
07362 return;
07363 } else {
07364 T *const ndata = (T*)nimage->data;
07365 if (redraw) _render_resize((T*)data,width,height,ndata,ndimx,ndimy);
07366 else std::memset(ndata,0,sizeof(T)*ndimx*ndimy);
07367 XShmDetach(cimg::X11attr().display, shminfo);
07368 XDestroyImage(image);
07369 shmdt(shminfo->shmaddr);
07370 shmctl(shminfo->shmid,IPC_RMID,0);
07371 delete shminfo;
07372 shminfo = nshminfo;
07373 image = nimage;
07374 data = (void*)ndata;
07375 }
07376 }
07377 }
07378 }
07379 } else
07380 #endif
07381 {
07382 T *ndata = (T*)std::malloc(ndimx*ndimy*sizeof(T));
07383 if (redraw) _render_resize((T*)data,width,height,ndata,ndimx,ndimy);
07384 else std::memset(ndata,0,sizeof(T)*ndimx*ndimy);
07385 data = (void*)ndata;
07386 XDestroyImage(image);
07387 image = XCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07388 cimg::X11attr().nb_bits,ZPixmap,0,(char*)data,ndimx,ndimy,8,0);
07389 }
07390 }
07391
07392 void _init_fullscreen() {
07393 background_window = 0;
07394 if (is_fullscreen && !is_closed) {
07395 #ifdef cimg_use_xrandr
07396 int foo;
07397 if (XRRQueryExtension(cimg::X11attr().display,&foo,&foo)) {
07398 XRRRotations(cimg::X11attr().display, DefaultScreen(cimg::X11attr().display), &cimg::X11attr().curr_rotation);
07399 if (!cimg::X11attr().resolutions) {
07400 cimg::X11attr().resolutions = XRRSizes(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display),&foo);
07401 cimg::X11attr().nb_resolutions = (unsigned int)foo;
07402 }
07403 if (cimg::X11attr().resolutions) {
07404 cimg::X11attr().curr_resolution = 0;
07405 for (unsigned int i=0; i<cimg::X11attr().nb_resolutions; ++i) {
07406 const unsigned int
07407 nw = (unsigned int)(cimg::X11attr().resolutions[i].width),
07408 nh = (unsigned int)(cimg::X11attr().resolutions[i].height);
07409 if (nw>=width && nh>=height &&
07410 nw<=(unsigned int)(cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].width) &&
07411 nh<=(unsigned int)(cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].height))
07412 cimg::X11attr().curr_resolution = i;
07413 }
07414 if (cimg::X11attr().curr_resolution>0) {
07415 XRRScreenConfiguration *config = XRRGetScreenInfo(cimg::X11attr().display, DefaultRootWindow(cimg::X11attr().display));
07416 XRRSetScreenConfig(cimg::X11attr().display, config, DefaultRootWindow(cimg::X11attr().display),
07417 cimg::X11attr().curr_resolution, cimg::X11attr().curr_rotation, CurrentTime);
07418 XRRFreeScreenConfigInfo(config);
07419 XSync(cimg::X11attr().display, False);
07420 }
07421 }
07422 }
07423 if (!cimg::X11attr().resolutions) cimg::warn("CImgDisplay::_create_window() : Xrandr extension is not supported by the X server.");
07424 #endif
07425 const unsigned int sx = screen_dimx(), sy = screen_dimy();
07426 XSetWindowAttributes winattr;
07427 winattr.override_redirect = True;
07428 if (sx!=width || sy!=height) {
07429 background_window = XCreateWindow(cimg::X11attr().display,
07430 RootWindow(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),0,0,
07431 sx,sy,0,0,InputOutput,CopyFromParent,CWOverrideRedirect,&winattr);
07432 const unsigned int bufsize = sx*sy*(cimg::X11attr().nb_bits==8?1:(cimg::X11attr().nb_bits==16?2:4));
07433 void *background_data = std::malloc(bufsize);
07434 std::memset(background_data,0,bufsize);
07435 XImage *background_image = XCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07436 cimg::X11attr().nb_bits,ZPixmap,0,(char*)background_data,sx,sy,8,0);
07437 XEvent event;
07438 XSelectInput(cimg::X11attr().display,background_window,StructureNotifyMask);
07439 XMapRaised(cimg::X11attr().display,background_window);
07440 do XWindowEvent(cimg::X11attr().display,background_window,StructureNotifyMask,&event);
07441 while (event.type!=MapNotify);
07442 #ifdef cimg_use_xshm
07443 if (shminfo) XShmPutImage(cimg::X11attr().display,background_window,*cimg::X11attr().gc,background_image,0,0,0,0,sx,sy,False);
07444 else
07445 #endif
07446 XPutImage(cimg::X11attr().display,background_window,*cimg::X11attr().gc,background_image,0,0,0,0,sx,sy);
07447 XWindowAttributes attr;
07448 XGetWindowAttributes(cimg::X11attr().display, background_window, &attr);
07449 while (attr.map_state != IsViewable) XSync(cimg::X11attr().display, False);
07450 XDestroyImage(background_image);
07451 }
07452 }
07453 }
07454
07455 void _desinit_fullscreen() {
07456 if (is_fullscreen) {
07457 XUngrabKeyboard(cimg::X11attr().display,CurrentTime);
07458 #ifdef cimg_use_xrandr
07459 if (cimg::X11attr().resolutions && cimg::X11attr().curr_resolution) {
07460 XRRScreenConfiguration *config = XRRGetScreenInfo(cimg::X11attr().display, DefaultRootWindow(cimg::X11attr().display));
07461 XRRSetScreenConfig(cimg::X11attr().display, config, DefaultRootWindow(cimg::X11attr().display),
07462 0, cimg::X11attr().curr_rotation, CurrentTime);
07463 XRRFreeScreenConfigInfo(config);
07464 XSync(cimg::X11attr().display, False);
07465 cimg::X11attr().curr_resolution = 0;
07466 }
07467 #endif
07468 if (background_window) XDestroyWindow(cimg::X11attr().display,background_window);
07469 background_window = 0;
07470 is_fullscreen = false;
07471 }
07472 }
07473
07474 void _handle_events(const XEvent *const pevent) {
07475 XEvent event=*pevent;
07476 switch (event.type) {
07477 case ClientMessage:
07478 if ((int)event.xclient.message_type==(int)wm_delete_protocol &&
07479 (int)event.xclient.data.l[0]==(int)wm_delete_window) {
07480 XUnmapWindow(cimg::X11attr().display,window);
07481 mouse_x = mouse_y = -1;
07482 if (button) {
07483 std::memmove((void*)(buttons+1),(void*)buttons,512-1);
07484 button = 0;
07485 }
07486 if (key) {
07487 std::memmove((void*)(keys+1),(void*)keys,512-1);
07488 key = 0;
07489 }
07490 if (released_key) {
07491 std::memmove((void*)(released_keys+1),(void*)released_keys,512-1);
07492 released_key = 0;
07493 }
07494 is_closed = is_event = true;
07495 }
07496 break;
07497 case ConfigureNotify: {
07498 while (XCheckWindowEvent(cimg::X11attr().display,window,StructureNotifyMask,&event));
07499 const unsigned int
07500 nw = event.xconfigure.width,
07501 nh = event.xconfigure.height;
07502 const int
07503 nx = event.xconfigure.x,
07504 ny = event.xconfigure.y;
07505 if (nw && nh && (nw!=window_width || nh!=window_height)) {
07506 window_width = nw;
07507 window_height = nh;
07508 mouse_x = mouse_y = -1;
07509 XResizeWindow(cimg::X11attr().display,window,window_width,window_height);
07510 is_resized = is_event = true;
07511 }
07512 if (nx!=window_x || ny!=window_y) {
07513 window_x = nx;
07514 window_y = ny;
07515 is_moved = is_event = true;
07516 }
07517 } break;
07518 case Expose: {
07519 while (XCheckWindowEvent(cimg::X11attr().display,window,ExposureMask,&event));
07520 _paint(false);
07521 if (is_fullscreen) {
07522 XWindowAttributes attr;
07523 XGetWindowAttributes(cimg::X11attr().display, window, &attr);
07524 while (attr.map_state != IsViewable) XSync(cimg::X11attr().display, False);
07525 XSetInputFocus(cimg::X11attr().display, window, RevertToParent, CurrentTime);
07526 }
07527 } break;
07528 case ButtonPress: {
07529 do {
07530 switch (event.xbutton.button) {
07531 case 1: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button|=1; is_event = true; break;
07532 case 2: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button|=4; is_event = true; break;
07533 case 3: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button|=2; is_event = true; break;
07534 default: break;
07535 }
07536 } while (XCheckWindowEvent(cimg::X11attr().display,window,ButtonPressMask,&event));
07537 } break;
07538 case ButtonRelease: {
07539 do {
07540 switch (event.xbutton.button) {
07541 case 1: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button&=~1U; is_event = true; break;
07542 case 2: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button&=~4U; is_event = true; break;
07543 case 3: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button&=~2U; is_event = true; break;
07544 case 4: ++wheel; is_event = true; break;
07545 case 5: --wheel; is_event = true; break;
07546 default: break;
07547 }
07548 } while (XCheckWindowEvent(cimg::X11attr().display,window,ButtonReleaseMask,&event));
07549 } break;
07550 case KeyPress: {
07551 char tmp;
07552 KeySym ksym;
07553 XLookupString(&event.xkey,&tmp,1,&ksym,0);
07554 if (key) std::memmove((void*)(keys+1),(void*)keys,512-1);
07555 key = (unsigned int)ksym;
07556 if (released_key) {
07557 std::memmove((void*)(released_keys+1),(void*)released_keys,512-1);
07558 released_key = 0;
07559 }
07560 is_event = true;
07561 } break;
07562 case KeyRelease: {
07563 char tmp;
07564 KeySym ksym;
07565 XLookupString(&event.xkey,&tmp,1,&ksym,0);
07566 if (key) {
07567 std::memmove((void*)(keys+1),(void*)keys,512-1);
07568 key = 0;
07569 }
07570 if (released_key) std::memmove((void*)(released_keys+1),(void*)released_keys,512-1);
07571 released_key = (unsigned int)ksym;
07572 is_event = true;
07573 } break;
07574 case LeaveNotify:
07575 while (XCheckWindowEvent(cimg::X11attr().display,window,LeaveWindowMask,&event));
07576 mouse_x = mouse_y =-1;
07577 is_event = true;
07578 break;
07579 case MotionNotify:
07580 while (XCheckWindowEvent(cimg::X11attr().display,window,PointerMotionMask,&event));
07581 mouse_x = event.xmotion.x;
07582 mouse_y = event.xmotion.y;
07583 if (mouse_x<0 || mouse_y<0 || mouse_x>=dimx() || mouse_y>=dimy()) mouse_x = mouse_y = -1;
07584 is_event = true;
07585 break;
07586 }
07587 }
07588
07589 static void* _events_thread(void *arg) {
07590 arg = 0;
07591 XEvent event;
07592 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,0);
07593 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
07594 for (;;) {
07595 pthread_mutex_lock(cimg::X11attr().mutex);
07596 for (unsigned int i=0; i<cimg::X11attr().nb_wins; ++i) {
07597 const unsigned int xevent_type = (cimg::X11attr().wins[i]->events)&3;
07598 const unsigned int emask =
07599 ((xevent_type>=1)?ExposureMask|StructureNotifyMask:0)|
07600 ((xevent_type>=2)?ButtonPressMask|KeyPressMask|PointerMotionMask|LeaveWindowMask:0)|
07601 ((xevent_type>=3)?ButtonReleaseMask|KeyReleaseMask:0);
07602 XSelectInput(cimg::X11attr().display,cimg::X11attr().wins[i]->window,emask);
07603 }
07604 bool event_flag = XCheckTypedEvent(cimg::X11attr().display, ClientMessage, &event);
07605 if (!event_flag) event_flag = XCheckMaskEvent(cimg::X11attr().display,
07606 ExposureMask|StructureNotifyMask|ButtonPressMask|
07607 KeyPressMask|PointerMotionMask|LeaveWindowMask|ButtonReleaseMask|
07608 KeyReleaseMask,&event);
07609 if (event_flag) {
07610 for (unsigned int i=0; i<cimg::X11attr().nb_wins; ++i)
07611 if (!cimg::X11attr().wins[i]->is_closed && event.xany.window==cimg::X11attr().wins[i]->window)
07612 cimg::X11attr().wins[i]->_handle_events(&event);
07613 }
07614 pthread_mutex_unlock(cimg::X11attr().mutex);
07615 pthread_testcancel();
07616 cimg::sleep(7);
07617 }
07618 return 0;
07619 }
07620
07621
07622
07623 #elif cimg_display_type==2
07624 CLIENTCREATESTRUCT ccs;
07625 BITMAPINFO bmi;
07626 unsigned int *data;
07627 DEVMODE curr_mode;
07628 HWND window;
07629 HWND background_window;
07630 HDC hdc;
07631 HANDLE thread;
07632 HANDLE created;
07633 HANDLE mutex;
07634 bool visible_cursor;
07635
07636 static int screen_dimx() {
07637 DEVMODE mode;
07638 mode.dmSize = sizeof(DEVMODE);
07639 mode.dmDriverExtra = 0;
07640 EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode);
07641 return mode.dmPelsWidth;
07642 }
07643
07644 static int screen_dimy() {
07645 DEVMODE mode;
07646 mode.dmSize = sizeof(DEVMODE);
07647 mode.dmDriverExtra = 0;
07648 EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode);
07649 return mode.dmPelsHeight;
07650 }
07651
07652 CImgDisplay& assign() {
07653 if (!is_empty()) {
07654 DestroyWindow(window);
07655 if (events) TerminateThread(thread,0);
07656 if (data) delete[] data;
07657 if (title) delete[] title;
07658 if (is_fullscreen) _desinit_fullscreen();
07659 width = height = normalization = events = 0;
07660 is_fullscreen = is_resized = is_moved = is_event = false;
07661 is_closed = true;
07662 title = 0;
07663 window_x = window_y = window_width = window_height = mouse_x = mouse_y = wheel = 0;
07664 std::memset((void*)buttons,0,512*sizeof(unsigned int));
07665 std::memset((void*)keys,0,512*sizeof(unsigned int));
07666 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
07667 min = max = 0;
07668 }
07669 return *this;
07670 }
07671
07672 CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0,
07673 const unsigned int normalization_type=3, const unsigned int events_type=3,
07674 const bool fullscreen_flag=false, const bool closed_flag=false) {
07675 if (!dimw || !dimh) return assign();
07676 _assign(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag);
07677 min = max = 0;
07678 std::memset(data,0,sizeof(unsigned int)*width*height);
07679 return paint();
07680 }
07681
07682 template<typename T> CImgDisplay& assign(const CImg<T>& img, const char *title=0,
07683 const unsigned int normalization_type=3, const unsigned int events_type=3,
07684 const bool fullscreen_flag=false, const bool closed_flag=false) {
07685 if (!img) return assign();
07686 CImg<T> tmp;
07687 const CImg<T>& nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
07688 _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
07689 if (normalization==2) min = (float)nimg.minmax(max);
07690 return display(nimg);
07691 }
07692
07693 template<typename T> CImgDisplay& assign(const CImgList<T>& list, const char *title=0,
07694 const unsigned int normalization_type=3, const unsigned int events_type=3,
07695 const bool fullscreen_flag=false, const bool closed_flag=false) {
07696 if (!list) return assign();
07697 CImg<T> tmp;
07698 const CImg<T> img = list.get_append('x','p'),
07699 &nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
07700 _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
07701 if (normalization==2) min = (float)nimg.minmax(max);
07702 return display(nimg);
07703 }
07704
07705 CImgDisplay& assign(const CImgDisplay& win) {
07706 if (!win) return assign();
07707 _assign(win.width,win.height,win.title,win.normalization,win.events,win.is_fullscreen,win.is_closed);
07708 std::memcpy(data,win.data,sizeof(unsigned int)*width*height);
07709 return paint();
07710 }
07711
07712 template<typename T> CImgDisplay& display(const CImg<T>& img) {
07713 if (is_empty()) assign(img.width,img.height);
07714 return render(img).paint();
07715 }
07716
07717 CImgDisplay& resize(const int nwidth, const int nheight, const bool redraw=true) {
07718 if (!nwidth || !nheight) return assign();
07719 if (is_empty()) return assign(cimg::max(nwidth,0),cimg::max(nheight,0));
07720 const unsigned int
07721 tmpdimx=(nwidth>0)?nwidth:(-nwidth*width/100),
07722 tmpdimy=(nheight>0)?nheight:(-nheight*height/100),
07723 dimx = cimg::min(tmpdimx?tmpdimx:1,(unsigned int)screen_dimx()),
07724 dimy = cimg::min(tmpdimy?tmpdimy:1,(unsigned int)screen_dimy());
07725 const bool
07726 is_disp_different = (width!=dimx || height!=dimy),
07727 is_win_different = (window_width!=dimx || window_height!=dimy);
07728
07729 if (is_disp_different || is_win_different) {
07730 RECT rect; rect.left = rect.top = 0; rect.right = dimx-1; rect.bottom = dimy-1;
07731 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
07732 const int cwidth = rect.right-rect.left+1, cheight = rect.bottom-rect.top+1;
07733 SetWindowPos(window,0,0,0,cwidth,cheight,SWP_NOMOVE | SWP_NOZORDER | SWP_NOCOPYBITS);
07734 window_width = dimx;
07735 window_height = dimy;
07736 is_resized = false;
07737 if (is_disp_different) {
07738 unsigned int *ndata = new unsigned int[dimx*dimy];
07739 if (redraw) _render_resize(data,width,height,ndata,dimx,dimy);
07740 else std::memset(ndata,0x80,sizeof(unsigned int)*dimx*dimy);
07741 delete[] data;
07742 data = ndata;
07743 bmi.bmiHeader.biWidth = dimx;
07744 bmi.bmiHeader.biHeight = -(int)dimy;
07745 width = dimx;
07746 height = dimy;
07747 }
07748 if (is_fullscreen) move((screen_dimx()-width)/2,(screen_dimy()-height)/2);
07749 if (redraw) return paint();
07750 }
07751 return *this;
07752 }
07753
07754 CImgDisplay& move(const int posx, const int posy) {
07755 if (is_empty()) return *this;
07756 if (!is_fullscreen) {
07757 RECT rect; rect.left = rect.top = 0; rect.right=window_width-1; rect.bottom=window_height-1;
07758 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
07759 const int border1 = (rect.right-rect.left+1-width)/2, border2 = rect.bottom-rect.top+1-height-border1;
07760 SetWindowPos(window,0,posx-border1,posy-border2,0,0,SWP_NOSIZE | SWP_NOZORDER);
07761 } else SetWindowPos(window,0,posx,posy,0,0,SWP_NOSIZE | SWP_NOZORDER);
07762 window_x = posx;
07763 window_y = posy;
07764 is_moved = false;
07765 return show();
07766 }
07767
07768 CImgDisplay& set_mouse(const int posx, const int posy) {
07769 if (!is_closed && posx>=0 && posy>=0) {
07770 _update_window_pos();
07771 const int res = (int)SetCursorPos(window_x+posx,window_y+posy);
07772 if (res) { mouse_x = posx; mouse_y = posy; }
07773 }
07774 return *this;
07775 }
07776
07777 CImgDisplay& hide_mouse() {
07778 if (is_empty()) return *this;
07779 visible_cursor = false;
07780 ShowCursor(FALSE);
07781 SendMessage(window,WM_SETCURSOR,0,0);
07782 return *this;
07783 }
07784
07785 CImgDisplay& show_mouse() {
07786 if (is_empty()) return *this;
07787 visible_cursor = true;
07788 ShowCursor(TRUE);
07789 SendMessage(window,WM_SETCURSOR,0,0);
07790 return *this;
07791 }
07792
07793 static void wait_all() {
07794 WaitForSingleObject(cimg::Win32attr().wait_event,INFINITE);
07795 }
07796
07797 CImgDisplay& show() {
07798 if (is_empty()) return *this;
07799 if (is_closed) {
07800 is_closed = false;
07801 if (is_fullscreen) _init_fullscreen();
07802 ShowWindow(window,SW_SHOW);
07803 _update_window_pos();
07804 }
07805 return paint();
07806 }
07807
07808 CImgDisplay& close() {
07809 if (is_empty()) return *this;
07810 if (!is_closed && !is_fullscreen) {
07811 if (is_fullscreen) _desinit_fullscreen();
07812 ShowWindow(window,SW_HIDE);
07813 is_closed = true;
07814 window_x = window_y = 0;
07815 }
07816 return *this;
07817 }
07818
07819 CImgDisplay& set_title(const char *format,...) {
07820 if (is_empty()) return *this;
07821 char tmp[1024] = {0};
07822 va_list ap;
07823 va_start(ap, format);
07824 std::vsprintf(tmp,format,ap);
07825 va_end(ap);
07826 if (title) delete[] title;
07827 const int s = cimg::strlen(tmp)+1;
07828 title = new char[s];
07829 std::memcpy(title,tmp,s*sizeof(char));
07830 SetWindowTextA(window, tmp);
07831 return *this;
07832 }
07833
07834 CImgDisplay& paint() {
07835 if (!is_closed) {
07836 WaitForSingleObject(mutex,INFINITE);
07837 SetDIBitsToDevice(hdc,0,0,width,height,0,0,0,height,data,&bmi,DIB_RGB_COLORS);
07838 ReleaseMutex(mutex);
07839 }
07840 return *this;
07841 }
07842
07843 template<typename T> CImgDisplay& render(const CImg<T>& img) {
07844 if (is_empty()) return *this;
07845 if (!img)
07846 throw CImgArgumentException("CImgDisplay::_render_image() : Specified input image (%u,%u,%u,%u,%p) is empty.",
07847 img.width,img.height,img.depth,img.dim,img.data);
07848 if (img.depth!=1) return render(img.get_projections2d(img.width/2,img.height/2,img.depth/2));
07849
07850 const T
07851 *data1 = img.data,
07852 *data2 = (img.dim>=2)?img.ptr(0,0,0,1):data1,
07853 *data3 = (img.dim>=3)?img.ptr(0,0,0,2):data1;
07854
07855 WaitForSingleObject(mutex,INFINITE);
07856 unsigned int
07857 *const ndata = (img.width==width && img.height==height)?data:new unsigned int[img.width*img.height],
07858 *ptrd = ndata;
07859
07860 if (!normalization || (normalization==3 && cimg::type<T>::string()==cimg::type<unsigned char>::string())) {
07861 min = max = 0;
07862 for (unsigned int xy = img.width*img.height; xy>0; --xy)
07863 *(ptrd++) = ((unsigned char)*(data1++)<<16) | ((unsigned char)*(data2++)<<8) | (unsigned char)*(data3++);
07864 } else {
07865 if (normalization==3) {
07866 if (cimg::type<T>::is_float()) min = (float)img.minmax(max);
07867 else { min = (float)cimg::type<T>::min(); max = (float)cimg::type<T>::max(); }
07868 } else if ((min>max) || normalization==1) min = (float)img.minmax(max);
07869 const float delta = max-min, mm = delta?delta:1.0f;
07870 for (unsigned int xy = img.width*img.height; xy>0; --xy) {
07871 const unsigned char
07872 R = (unsigned char)(255*(*(data1++)-min)/mm),
07873 G = (unsigned char)(255*(*(data2++)-min)/mm),
07874 B = (unsigned char)(255*(*(data3++)-min)/mm);
07875 *(ptrd++) = (R<<16) | (G<<8) | (B);
07876 }
07877 }
07878 if (ndata!=data) { _render_resize(ndata,img.width,img.height,data,width,height); delete[] ndata; }
07879 ReleaseMutex(mutex);
07880 return *this;
07881 }
07882
07883 template<typename T> const CImgDisplay& snapshot(CImg<T>& img) const {
07884 if (is_empty()) img.assign();
07885 else {
07886 img.assign(width,height,1,3);
07887 T
07888 *data1 = img.ptr(0,0,0,0),
07889 *data2 = img.ptr(0,0,0,1),
07890 *data3 = img.ptr(0,0,0,2);
07891 unsigned int *ptrs = data;
07892 for (unsigned int xy = img.width*img.height; xy>0; --xy) {
07893 const unsigned int val = *(ptrs++);
07894 *(data1++) = (unsigned char)(val>>16);
07895 *(data2++) = (unsigned char)((val>>8)&0xFF);
07896 *(data3++) = (unsigned char)(val&0xFF);
07897 }
07898 }
07899 return *this;
07900 }
07901
07902 CImgDisplay& _assign(const unsigned int dimw, const unsigned int dimh, const char *ptitle=0,
07903 const unsigned int normalization_type=3, const unsigned int events_type=3,
07904 const bool fullscreen_flag=false, const bool closed_flag=false) {
07905
07906
07907 const int s = cimg::strlen(ptitle)+1;
07908 char *tmp_title = s?new char[s]:0;
07909 if (s) std::memcpy(tmp_title,ptitle,s*sizeof(char));
07910
07911
07912 if (!is_empty()) assign();
07913
07914
07915 width = cimg::min(dimw,(unsigned int)screen_dimx());
07916 height = cimg::min(dimh,(unsigned int)screen_dimy());
07917 normalization = normalization_type%4;
07918 events = events_type%4;
07919 is_fullscreen = fullscreen_flag;
07920 title = tmp_title;
07921 window_x = window_y = wheel = 0;
07922 mouse_x = mouse_y = -1;
07923 std::memset((void*)buttons,0,512*sizeof(unsigned int));
07924 std::memset((void*)keys,0,512*sizeof(unsigned int));
07925 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
07926 is_resized = is_moved = is_event = false;
07927 is_closed = closed_flag;
07928 fps_timer = fps_frames = timer = 0;
07929 fps_fps = 0;
07930 visible_cursor = true;
07931
07932 if (is_fullscreen) _init_fullscreen();
07933
07934
07935 void *arg = (void*)(new void*[2]);
07936 ((void**)arg)[0]=(void*)this;
07937 ((void**)arg)[1]=(void*)title;
07938 if (events) {
07939 unsigned long ThreadID = 0;
07940 mutex = CreateMutex(0,FALSE,0);
07941 created = CreateEvent(0,FALSE,FALSE,0);
07942 thread = CreateThread(0,0,_events_thread,arg,0,&ThreadID);
07943 WaitForSingleObject(created,INFINITE);
07944 } else _events_thread(arg);
07945
07946 return *this;
07947 }
07948
07949 static LRESULT APIENTRY _handle_events(HWND window,UINT msg,WPARAM wParam,LPARAM lParam) {
07950 #ifdef _WIN64
07951 CImgDisplay* disp = (CImgDisplay*)GetWindowLongPtr(window,GWLP_USERDATA);
07952 #else
07953 CImgDisplay* disp = (CImgDisplay*)GetWindowLong(window,GWL_USERDATA);
07954 #endif
07955 MSG st_msg;
07956
07957 switch(msg) {
07958 case WM_CLOSE:
07959 disp->mouse_x = disp->mouse_y = -1;
07960 disp->window_x = disp->window_y = 0;
07961 if (disp->button) {
07962 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
07963 disp->button = 0;
07964 }
07965 if (disp->key) {
07966 std::memmove((void*)(disp->keys+1),(void*)disp->keys,512-1);
07967 disp->key = 0;
07968 }
07969 if (disp->released_key) {
07970 std::memmove((void*)(disp->released_keys+1),(void*)disp->released_keys,512-1);
07971 disp->released_key = 0;
07972 }
07973 disp->is_closed = true;
07974 ReleaseMutex(disp->mutex);
07975 ShowWindow(disp->window,SW_HIDE);
07976 disp->is_event = true;
07977 SetEvent(cimg::Win32attr().wait_event);
07978 return 0;
07979 case WM_SIZE: {
07980 while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE));
07981 WaitForSingleObject(disp->mutex,INFINITE);
07982 const unsigned int nw = LOWORD(lParam),nh = HIWORD(lParam);
07983 if (nw && nh && (nw!=disp->width || nh!=disp->height)) {
07984 disp->window_width = nw;
07985 disp->window_height = nh;
07986 disp->mouse_x = disp->mouse_y = -1;
07987 disp->is_resized = disp->is_event = true;
07988 SetEvent(cimg::Win32attr().wait_event);
07989 }
07990 ReleaseMutex(disp->mutex);
07991 } break;
07992 case WM_MOVE: {
07993 while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE));
07994 WaitForSingleObject(disp->mutex,INFINITE);
07995 const int nx = (int)(short)(LOWORD(lParam)), ny = (int)(short)(HIWORD(lParam));
07996 if (nx!=disp->window_x || ny!=disp->window_y) {
07997 disp->window_x = nx;
07998 disp->window_y = ny;
07999 disp->is_moved = disp->is_event = true;
08000 SetEvent(cimg::Win32attr().wait_event);
08001 }
08002 ReleaseMutex(disp->mutex);
08003 } break;
08004 case WM_PAINT:
08005 disp->paint();
08006 break;
08007 }
08008 if (disp->events>=2) switch(msg) {
08009 case WM_KEYDOWN:
08010 if (disp->key) std::memmove((void*)(disp->keys+1),(void*)disp->keys,512-1);
08011 disp->key = (int)wParam;
08012 if (disp->released_key) {
08013 std::memmove((void*)(disp->released_keys+1),(void*)disp->released_keys,512-1);
08014 disp->released_key = 0;
08015 }
08016 disp->is_event = true;
08017 SetEvent(cimg::Win32attr().wait_event);
08018 break;
08019 case WM_MOUSEMOVE: {
08020 while (PeekMessage(&st_msg,window,WM_MOUSEMOVE,WM_MOUSEMOVE,PM_REMOVE));
08021 disp->mouse_x = LOWORD(lParam);
08022 disp->mouse_y = HIWORD(lParam);
08023 if (disp->mouse_x<0 || disp->mouse_y<0 || disp->mouse_x>=disp->dimx() || disp->mouse_y>=disp->dimy())
08024 disp->mouse_x=disp->mouse_y=-1;
08025 disp->is_event = true;
08026 SetEvent(cimg::Win32attr().wait_event);
08027 } break;
08028 case WM_LBUTTONDOWN:
08029 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08030 disp->button|=1U;
08031 disp->is_event = true;
08032 SetEvent(cimg::Win32attr().wait_event);
08033 break;
08034 case WM_RBUTTONDOWN:
08035 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08036 disp->button|=2U;
08037 disp->is_event = true;
08038 SetEvent(cimg::Win32attr().wait_event);
08039 break;
08040 case WM_MBUTTONDOWN:
08041 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08042 disp->button|=4U;
08043 disp->is_event = true;
08044 SetEvent(cimg::Win32attr().wait_event);
08045 break;
08046 case 0x020A:
08047 disp->wheel+=(int)((short)HIWORD(wParam))/120;
08048 disp->is_event = true;
08049 SetEvent(cimg::Win32attr().wait_event);
08050 }
08051
08052 if (disp->events>=3) switch(msg) {
08053 case WM_KEYUP:
08054 if (disp->key) {
08055 std::memmove((void*)(disp->keys+1),(void*)disp->keys,512-1);
08056 disp->key = 0;
08057 }
08058 if (disp->released_key) std::memmove((void*)(disp->released_keys+1),(void*)disp->released_keys,512-1);
08059 disp->released_key = (int)wParam;
08060 disp->is_event = true;
08061 SetEvent(cimg::Win32attr().wait_event);
08062 break;
08063 case WM_LBUTTONUP:
08064 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08065 disp->button&=~1U;
08066 disp->is_event = true;
08067 SetEvent(cimg::Win32attr().wait_event);
08068 break;
08069 case WM_RBUTTONUP:
08070 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08071 disp->button&=~2U;
08072 disp->is_event = true;
08073 SetEvent(cimg::Win32attr().wait_event);
08074 break;
08075 case WM_MBUTTONUP:
08076 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08077 disp->button&=~4U;
08078 disp->is_event = true;
08079 SetEvent(cimg::Win32attr().wait_event);
08080 break;
08081 case WM_SETCURSOR:
08082 if (disp->visible_cursor) ShowCursor(TRUE);
08083 else ShowCursor(FALSE);
08084 break;
08085 }
08086 return DefWindowProc(window,msg,wParam,lParam);
08087 }
08088
08089 static DWORD WINAPI _events_thread(void* arg) {
08090 CImgDisplay *disp = (CImgDisplay*)(((void**)arg)[0]);
08091 const char *title = (const char*)(((void**)arg)[1]);
08092 MSG msg;
08093 delete[] (void**)arg;
08094 disp->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
08095 disp->bmi.bmiHeader.biWidth = disp->width;
08096 disp->bmi.bmiHeader.biHeight = -(int)disp->height;
08097 disp->bmi.bmiHeader.biPlanes = 1;
08098 disp->bmi.bmiHeader.biBitCount = 32;
08099 disp->bmi.bmiHeader.biCompression = BI_RGB;
08100 disp->bmi.bmiHeader.biSizeImage = 0;
08101 disp->bmi.bmiHeader.biXPelsPerMeter = 1;
08102 disp->bmi.bmiHeader.biYPelsPerMeter = 1;
08103 disp->bmi.bmiHeader.biClrUsed = 0;
08104 disp->bmi.bmiHeader.biClrImportant = 0;
08105 disp->data = new unsigned int[disp->width*disp->height];
08106 if (!disp->is_fullscreen) {
08107 RECT rect;
08108 rect.left = rect.top = 0; rect.right = disp->width-1; rect.bottom = disp->height-1;
08109 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
08110 const int border1 = (rect.right-rect.left+1-disp->width)/2, border2 = rect.bottom-rect.top+1-disp->height-border1;
08111 disp->window = CreateWindowA("MDICLIENT",title?title:" ",
08112 WS_OVERLAPPEDWINDOW | (disp->is_closed?0:WS_VISIBLE), CW_USEDEFAULT,CW_USEDEFAULT,
08113 disp->width + 2*border1, disp->height + border1 + border2,
08114 0,0,0,&(disp->ccs));
08115 if (!disp->is_closed) {
08116 GetWindowRect(disp->window,&rect);
08117 disp->window_x = rect.left + border1;
08118 disp->window_y = rect.top + border2;
08119 } else disp->window_x = disp->window_y = 0;
08120 } else {
08121 const unsigned int sx = screen_dimx(), sy = screen_dimy();
08122 disp->window = CreateWindowA("MDICLIENT",title?title:" ",
08123 WS_POPUP | (disp->is_closed?0:WS_VISIBLE), (sx-disp->width)/2, (sy-disp->height)/2,
08124 disp->width,disp->height,0,0,0,&(disp->ccs));
08125 disp->window_x = disp->window_y = 0;
08126 }
08127 SetForegroundWindow(disp->window);
08128 disp->hdc = GetDC(disp->window);
08129 disp->window_width = disp->width;
08130 disp->window_height = disp->height;
08131 disp->mouse_x = disp->mouse_y = -1;
08132 disp->wheel = 0;
08133 std::memset((void*)disp->buttons,0,512*sizeof(unsigned int));
08134 std::memset((void*)disp->keys,0,512*sizeof(unsigned int));
08135 std::memset((void*)disp->released_keys,0,512*sizeof(unsigned int));
08136 disp->is_resized = disp->is_moved = disp->is_event = false;
08137 if (disp->events) {
08138 #ifdef _WIN64
08139 SetWindowLongPtr(disp->window,GWLP_USERDATA,(LONG_PTR)disp);
08140 SetWindowLongPtr(disp->window,GWLP_WNDPROC,(LONG_PTR)_handle_events);
08141 #else
08142 SetWindowLong(disp->window,GWL_USERDATA,(LONG)disp);
08143 SetWindowLong(disp->window,GWL_WNDPROC,(LONG)_handle_events);
08144 #endif
08145 SetEvent(disp->created);
08146 while (GetMessage(&msg,0,0,0)) DispatchMessage(&msg);
08147 }
08148 return 0;
08149 }
08150
08151 void _init_fullscreen() {
08152 background_window = 0;
08153 if (is_fullscreen && !is_closed) {
08154 DEVMODE mode;
08155 unsigned int imode = 0, ibest = 0, bestbpp = 0, bw = ~0U, bh = ~0U;
08156 for (mode.dmSize = sizeof(DEVMODE), mode.dmDriverExtra = 0; EnumDisplaySettings(0,imode,&mode); ++imode) {
08157 const unsigned int nw = mode.dmPelsWidth, nh = mode.dmPelsHeight;
08158 if (nw>=width && nh>=height && mode.dmBitsPerPel>=bestbpp && nw<=bw && nh<=bh) {
08159 bestbpp = mode.dmBitsPerPel;
08160 ibest = imode;
08161 bw = nw; bh = nh;
08162 }
08163 }
08164 if (bestbpp) {
08165 curr_mode.dmSize = sizeof(DEVMODE); curr_mode.dmDriverExtra = 0;
08166 EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&curr_mode);
08167 EnumDisplaySettings(0,ibest,&mode);
08168 ChangeDisplaySettings(&mode,0);
08169 } else curr_mode.dmSize = 0;
08170
08171 const unsigned int sx = screen_dimx(), sy = screen_dimy();
08172 if (sx!=width || sy!=height) {
08173 CLIENTCREATESTRUCT background_ccs;
08174 background_window = CreateWindowA("MDICLIENT"," ",WS_POPUP | WS_VISIBLE, 0,0,sx,sy,0,0,0,&background_ccs);
08175 SetForegroundWindow(background_window);
08176 }
08177 } else curr_mode.dmSize = 0;
08178 }
08179
08180 void _desinit_fullscreen() {
08181 if (is_fullscreen) {
08182 if (background_window) DestroyWindow(background_window);
08183 background_window = 0;
08184 if (curr_mode.dmSize) ChangeDisplaySettings(&curr_mode,0);
08185 is_fullscreen = false;
08186 }
08187 }
08188
08189 CImgDisplay& _update_window_pos() {
08190 if (!is_closed) {
08191 RECT rect;
08192 rect.left = rect.top = 0; rect.right = width-1; rect.bottom = height-1;
08193 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
08194 const int border1 = (rect.right-rect.left+1-width)/2, border2 = rect.bottom-rect.top+1-height-border1;
08195 GetWindowRect(window,&rect);
08196 window_x = rect.left + border1;
08197 window_y = rect.top + border2;
08198 } else window_x = window_y = -1;
08199 return *this;
08200 }
08201
08202 #endif
08203
08204 };
08205
08206
08207
08208
08209
08210
08211
08212
08213
08214
08215
08216
08217
08219
08310 template<typename T> struct CImg {
08311
08313
08320 unsigned int width;
08321
08323
08331 unsigned int height;
08332
08334
08342 unsigned int depth;
08343
08345
08353 unsigned int dim;
08354
08356 bool is_shared;
08357
08359 T *data;
08360
08362
08367 typedef T* iterator;
08368
08370
08375 typedef const T* const_iterator;
08376
08378 typedef T value_type;
08379
08381
08382
08384
08385
08386 #ifdef cimg_plugin
08387 #include cimg_plugin
08388 #endif
08389
08390
08391
08392
08394
08395
08396
08398
08406 CImg():
08407 width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {}
08408
08410
08419 ~CImg() {
08420 if (data && !is_shared) delete[] data;
08421 }
08422
08424
08433 CImg<T>& assign() {
08434 if (data && !is_shared) delete[] data;
08435 width = height = depth = dim = 0; is_shared = false; data = 0;
08436 return *this;
08437 }
08438
08440
08445 CImg<T>& clear() {
08446 return assign();
08447 }
08448
08450
08466 explicit CImg(const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1):
08467 is_shared(false) {
08468 const unsigned long siz = dx*dy*dz*dv;
08469 if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new T[siz]; }
08470 else { width = height = depth = dim = 0; data = 0; }
08471 }
08472
08474
08490 CImg<T>& assign(const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) {
08491 const unsigned long siz = dx*dy*dz*dv;
08492 if (!siz) return assign();
08493 const unsigned long curr_siz = size();
08494 if (is_shared) {
08495 if (siz>curr_siz)
08496 throw CImgArgumentException("CImg<%s>::assign() : Cannot assign image (%u,%u,%u,%u) to shared instance image (%u,%u,%u,%u,%p).",
08497 pixel_type(),dx,dy,dz,dv,width,height,depth,dim,data);
08498 } else {
08499 if (siz!=curr_siz) { if (data) delete[] data; data = new T[siz]; }
08500 width = dx; height = dy; depth = dz; dim = dv;
08501 }
08502 return *this;
08503 }
08504
08506
08518 CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const T val):
08519 is_shared(false) {
08520 const unsigned long siz = dx*dy*dz*dv;
08521 if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new T[siz]; fill(val); }
08522 else { width = height = depth = dim = 0; data = 0; }
08523 }
08524
08526
08538 CImg<T>& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const T val) {
08539 return assign(dx,dy,dz,dv).fill(val);
08540 }
08541
08543
08547 template<typename t> CImg(const t *const data_buffer, const unsigned int dx, const unsigned int dy=1,
08548 const unsigned int dz=1, const unsigned int dv=1, const bool shared=false):is_shared(false) {
08549 if (shared) throw CImgArgumentException("CImg<%s>::CImg() : Cannot construct a shared copy from a (%s*) buffer "
08550 "(different pixel types).",pixel_type(),CImg<t>::pixel_type());
08551 const unsigned long siz = dx*dy*dz*dv;
08552 if (data_buffer && siz) {
08553 width = dx; height = dy; depth = dz; dim = dv; data = new T[siz];
08554 const t *ptrs = data_buffer + siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
08555 } else { width = height = depth = dim = 0; data = 0; }
08556 }
08557
08558 #ifdef cimg_use_visualcpp6
08559 CImg(const T *const data_buffer, const unsigned int dx, const unsigned int dy,
08560 const unsigned int dz, const unsigned int dv, const bool shared) {
08561 #else
08562 CImg(const T *const data_buffer, const unsigned int dx, const unsigned int dy=1,
08563 const unsigned int dz=1, const unsigned int dv=1, const bool shared=false) {
08564 #endif
08565 const unsigned long siz = dx*dy*dz*dv;
08566 if (data_buffer && siz) {
08567 width = dx; height = dy; depth = dz; dim = dv; is_shared = shared;
08568 if (is_shared) data = const_cast<T*>(data_buffer);
08569 else { data = new T[siz]; std::memcpy(data,data_buffer,siz*sizeof(T)); }
08570 } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
08571 }
08572
08574 #ifdef cimg_use_visualcpp6
08575 template<typename t> CImg<T>& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy,
08576 const unsigned int dz, const unsigned int dv) {
08577 #else
08578 template<typename t> CImg<T>& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy=1,
08579 const unsigned int dz=1, const unsigned int dv=1) {
08580 #endif
08581 const unsigned long siz = dx*dy*dz*dv;
08582 if (!data_buffer || !siz) return assign();
08583 assign(dx,dy,dz,dv);
08584 const t *ptrs = data_buffer + siz;
08585 cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
08586 return *this;
08587 }
08588
08589 CImg<T>& assign(const T *const data_buffer, const unsigned int dx, const unsigned int dy=1,
08590 const unsigned int dz=1, const unsigned int dv=1) {
08591 const unsigned long siz = dx*dy*dz*dv;
08592 if (!data_buffer || !siz) return assign();
08593 const unsigned long curr_siz = size();
08594 if (data_buffer==data && siz==curr_siz) return assign(dx,dy,dz,dv);
08595 if (is_shared || data_buffer+siz<data || data_buffer>=data+size()) {
08596 assign(dx,dy,dz,dv);
08597 if (is_shared) std::memmove(data,data_buffer,siz*sizeof(T));
08598 else std::memcpy(data,data_buffer,siz*sizeof(T));
08599 } else {
08600 T *new_data = new T[siz];
08601 std::memcpy(new_data,data_buffer,siz*sizeof(T));
08602 delete[] data; data = new_data; width = dx; height = dy; depth = dz; dim = dv;
08603 }
08604 return *this;
08605 }
08606
08608 template<typename t> CImg<T>& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy,
08609 const unsigned int dz, const unsigned int dv, const bool shared) {
08610 if (shared) throw CImgArgumentException("CImg<%s>::assign() : Cannot construct a shared copy from a (%s*) buffer "
08611 "(different pixel types).",pixel_type(),CImg<t>::pixel_type());
08612 return assign().assign(data_buffer,dx,dy,dz,dv);
08613 }
08614
08615 CImg<T>& assign(const T *const data_buffer, const unsigned int dx, const unsigned int dy,
08616 const unsigned int dz, const unsigned int dv, const bool shared) {
08617 if (!shared) return assign(data_buffer,dx,dy,dz,dv);
08618 const unsigned long siz = dx*dy*dz*dv;
08619 if (!data_buffer || !siz)
08620 throw CImgArgumentException("CImg<%s>::assign() : Cannot construct a shared copy of an empty image.",pixel_type());
08621 if (!is_shared) {
08622 if (data_buffer+siz<data || data_buffer>=data+size()) assign();
08623 else cimg::warn("CImg<%s>::assign() : Create shared version of previous parts of the instance image, possible memory leaks !",
08624 pixel_type());
08625 }
08626 width = dx; height = dy; depth = dz; dim = dv; is_shared = true;
08627 data = const_cast<T*>(data_buffer);
08628 return *this;
08629 }
08630
08632
08650 template<typename t> CImg(const CImg<t>& img):is_shared(false) {
08651 const unsigned int siz = img.size();
08652 if (img.data && siz) {
08653 width = img.width; height = img.height; depth = img.depth; dim = img.dim; data = new T[siz];
08654 const t *ptrs = img.data + siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
08655 } else { width = height = depth = dim = 0; data = 0; }
08656 }
08657
08658 CImg(const CImg<T>& img) {
08659 const unsigned int siz = img.size();
08660 if (img.data && siz) {
08661 width = img.width; height = img.height; depth = img.depth; dim = img.dim; is_shared = img.is_shared;
08662 if (is_shared) data = const_cast<T*>(img.data);
08663 else { data = new T[siz]; std::memcpy(data,img.data,siz*sizeof(T)); }
08664 } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
08665 }
08666
08668
08678 template<typename t> CImg<T>& assign(const CImg<t>& img) {
08679 return assign(img.data,img.width,img.height,img.depth,img.dim);
08680 }
08681
08683
08697 template<typename t> CImg(const CImg<t>& img, const bool shared):is_shared(false) {
08698 if (shared) throw CImgArgumentException("CImg<%s>::CImg() : Cannot construct a shared copy from a CImg<%s> image "
08699 "(different pixel types).",pixel_type(),CImg<t>::pixel_type());
08700 const unsigned int siz = img.size();
08701 if (img.data && siz) {
08702 width = img.width; height = img.height; depth = img.depth; dim = img.dim; data = new T[siz];
08703 const t *ptrs = img.data+siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
08704 } else { width = height = depth = dim = 0; data = 0; }
08705 }
08706
08707 CImg(const CImg<T>& img, const bool shared) {
08708 const unsigned int siz = img.size();
08709 if (img.data && siz) {
08710 width = img.width; height = img.height; depth = img.depth; dim = img.dim; is_shared = shared;
08711 if (is_shared) data = const_cast<T*>(img.data);
08712 else { data = new T[siz]; std::memcpy(data,img.data,siz*sizeof(T)); }
08713 } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
08714 }
08715
08717
08730 template<typename t> CImg<T>& assign(const CImg<t>& img, const bool shared) {
08731 return assign(img.data,img.width,img.height,img.depth,img.dim,shared);
08732 }
08733
08735 CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv,
08736 const int val0, const int val1, ...):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08737 assign(dx,dy,dz,dv);
08738 _CImg_stdarg(*this,val0,val1,dx*dy*dz*dv,int);
08739 }
08740
08742 CImg<T>& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv,
08743 const int val0, const int val1, ...) {
08744 assign(dx,dy,dz,dv);
08745 _CImg_stdarg(*this,val0,val1,dx*dy*dz*dv,int);
08746 return *this;
08747 }
08748
08750 CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv,
08751 const double val0, const double val1, ...):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08752 assign(dx,dy,dz,dv);
08753 _CImg_stdarg(*this,val0,val1,dx*dy*dz*dv,double);
08754 }
08755
08757 CImg<T>& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv,
08758 const double val0, const double val1, ...) {
08759 assign(dx,dy,dz,dv);
08760 _CImg_stdarg(*this,val0,val1,dx*dy*dz*dv,double);
08761 return *this;
08762 }
08763
08765 template<typename t> CImg(const CImg<t>& img, const char *const dimensions):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08766 assign(img,dimensions);
08767 }
08768
08770 template<typename t> CImg<T>& assign(const CImg<t>& img, const char *const dimensions) {
08771 if (dimensions) {
08772 unsigned int siz[4] = { 0,1,1,1 };
08773 const char *s = dimensions;
08774 char tmp[256] = { 0 }, c = 0;
08775 int val = 0;
08776 for (unsigned int k=0; k<4; ++k) {
08777 const int err = std::sscanf(s,"%[-0-9]%c",tmp,&c);
08778 if (err>=1) {
08779 const int err = std::sscanf(s,"%d",&val);
08780 if (err==1) {
08781 int val2 = val<0?-val:(c=='%'?val:-1);
08782 if (val2>=0) {
08783 val = (int)((k==0?img.width:(k==1?img.height:(k==2?img.depth:img.dim)))*val2/100);
08784 if (c!='%' && !val) val = 1;
08785 }
08786 siz[k] = val;
08787 }
08788 s+=cimg::strlen(tmp);
08789 if (c=='%') ++s;
08790 }
08791 if (!err) {
08792 if (!cimg::strncasecmp(s,"x",1)) { ++s; siz[k] = img.width; }
08793 else if (!cimg::strncasecmp(s,"y",1)) { ++s; siz[k] = img.height; }
08794 else if (!cimg::strncasecmp(s,"z",1)) { ++s; siz[k] = img.depth; }
08795 else if (!cimg::strncasecmp(s,"v",1)) { ++s; siz[k] = img.dim; }
08796 else if (!cimg::strncasecmp(s,"dx",2)) { s+=2; siz[k] = img.width; }
08797 else if (!cimg::strncasecmp(s,"dy",2)) { s+=2; siz[k] = img.height; }
08798 else if (!cimg::strncasecmp(s,"dz",2)) { s+=2; siz[k] = img.depth; }
08799 else if (!cimg::strncasecmp(s,"dv",2)) { s+=2; siz[k] = img.dim; }
08800 else if (!cimg::strncasecmp(s,"dimx",4)) { s+=4; siz[k] = img.width; }
08801 else if (!cimg::strncasecmp(s,"dimy",4)) { s+=4; siz[k] = img.height; }
08802 else if (!cimg::strncasecmp(s,"dimz",4)) { s+=4; siz[k] = img.depth; }
08803 else if (!cimg::strncasecmp(s,"dimv",4)) { s+=4; siz[k] = img.dim; }
08804 else if (!cimg::strncasecmp(s,"width",5)) { s+=5; siz[k] = img.width; }
08805 else if (!cimg::strncasecmp(s,"height",6)) { s+=6; siz[k] = img.height; }
08806 else if (!cimg::strncasecmp(s,"depth",5)) { s+=5; siz[k] = img.depth; }
08807 else if (!cimg::strncasecmp(s,"dim",3)) { s+=3; siz[k] = img.dim; }
08808 else { ++s; --k; }
08809 }
08810 }
08811 return assign(siz[0],siz[1],siz[2],siz[3]);
08812 }
08813 return assign();
08814 }
08815
08817 template<typename t> CImg(const CImg<t>& img, const char *const dimensions, const T val):
08818 width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08819 assign(img,dimensions).fill(val);
08820 }
08821
08823 template<typename t> CImg<T>& assign(const CImg<t>& img, const char *const dimensions, const T val) {
08824 return assign(img,dimensions).fill(val);
08825 }
08826
08828
08839 CImg(const char *const filename):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08840 assign(filename);
08841 }
08842
08844
08853 CImg<T>& assign(const char *const filename) {
08854 return load(filename);
08855 }
08856
08858 CImg(const CImgDisplay &disp):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08859 disp.snapshot(*this);
08860 }
08861
08863 CImg<T>& assign(const CImgDisplay &disp) {
08864 disp.snapshot(*this);
08865 return *this;
08866 }
08867
08868
08869 CImg<T>& swap(CImg<T>& img) {
08870 cimg::swap(width,img.width);
08871 cimg::swap(height,img.height);
08872 cimg::swap(depth,img.depth);
08873 cimg::swap(dim,img.dim);
08874 cimg::swap(data,img.data);
08875 cimg::swap(is_shared,img.is_shared);
08876 return img;
08877 }
08878
08879
08880 #ifndef cimg_use_visualcpp6
08881 CImg<T>& assign_to(CImg<T>& img) {
08882 if (is_shared || img.is_shared) return img.assign(*this);
08883 cimg::swap(width,img.width);
08884 cimg::swap(height,img.height);
08885 cimg::swap(depth,img.depth);
08886 cimg::swap(dim,img.dim);
08887 cimg::swap(data,img.data);
08888 return img;
08889 }
08890 #endif
08891
08892 template<typename t> CImg<t>& assign_to(CImg<t>& img) {
08893 return img.assign(*this);
08894 }
08895
08897
08898
08900
08901
08902
08904
08909 static const char* pixel_type() {
08910 return cimg::type<T>::string();
08911 }
08912
08914
08924 unsigned long size() const {
08925 return width*height*depth*dim;
08926 }
08927
08929
08932 int dimx() const {
08933 return (int)width;
08934 }
08935
08937
08940 int dimy() const {
08941 return (int)height;
08942 }
08943
08945
08948 int dimz() const {
08949 return (int)depth;
08950 }
08951
08953
08956 int dimv() const {
08957 return (int)dim;
08958 }
08959
08961 template<typename t> bool is_sameX(const CImg<t>& img) const {
08962 return (width==img.width);
08963 }
08964
08966 bool is_sameX(const CImgDisplay& disp) const {
08967 return (width==disp.width);
08968 }
08969
08971 template<typename t> bool is_sameY(const CImg<t>& img) const {
08972 return (height==img.height);
08973 }
08974
08976 bool is_sameY(const CImgDisplay& disp) const {
08977 return (height==disp.height);
08978 }
08979
08981 template<typename t> bool is_sameZ(const CImg<t>& img) const {
08982 return (depth==img.depth);
08983 }
08984
08986 template<typename t> bool is_sameV(const CImg<t>& img) const {
08987 return (dim==img.dim);
08988 }
08989
08991 template<typename t> bool is_sameXY(const CImg<t>& img) const {
08992 return (is_sameX(img) && is_sameY(img));
08993 }
08994
08996 bool is_sameXY(const CImgDisplay& disp) const {
08997 return (is_sameX(disp) && is_sameY(disp));
08998 }
08999
09001 template<typename t> bool is_sameXZ(const CImg<t>& img) const {
09002 return (is_sameX(img) && is_sameZ(img));
09003 }
09004
09006 template<typename t> bool is_sameXV(const CImg<t>& img) const {
09007 return (is_sameX(img) && is_sameV(img));
09008 }
09009
09011 template<typename t> bool is_sameYZ(const CImg<t>& img) const {
09012 return (is_sameY(img) && is_sameZ(img));
09013 }
09014
09016 template<typename t> bool is_sameYV(const CImg<t>& img) const {
09017 return (is_sameY(img) && is_sameV(img));
09018 }
09019
09021 template<typename t> bool is_sameZV(const CImg<t>& img) const {
09022 return (is_sameZ(img) && is_sameV(img));
09023 }
09024
09026 template<typename t> bool is_sameXYZ(const CImg<t>& img) const {
09027 return (is_sameXY(img) && is_sameZ(img));
09028 }
09029
09031 template<typename t> bool is_sameXYV(const CImg<t>& img) const {
09032 return (is_sameXY(img) && is_sameZ(img));
09033 }
09034
09036 template<typename t> bool is_sameXZV(const CImg<t>& img) const {
09037 return (is_sameXY(img) && is_sameZ(img));
09038 }
09039
09041 template<typename t> bool is_sameYZV(const CImg<t>& img) const {
09042 return (is_sameXY(img) && is_sameZ(img));
09043 }
09044
09046 template<typename t> bool is_sameXYZV(const CImg<t>& img) const {
09047 return (is_sameXYZ(img) && is_sameV(img));
09048 }
09049
09051 bool contains(const int x, const int y=0, const int z=0, const int v=0) const {
09052 return data && x>=0 && x<dimx() && y>=0 && y<dimy() && z>=0 && z<dimz() && v>=0 && v<dimv();
09053 }
09054
09056 template<typename t> bool contains(const T& pixel, t& x, t& y, t& z, t& v) const {
09057 const T *ptr = &pixel;
09058 unsigned long off = (unsigned long)(ptr-data);
09059 const unsigned long whz = width*height*depth, wh = width*height;
09060 v = (t)(off/whz); off%=whz; z =(t)(off/wh); off%=wh; y = (t)(off/width); x = (t)(off%width);
09061 return contains(x,y,z,v);
09062 }
09063
09065 template<typename t> bool contains(const T& pixel, t& x, t& y, t& z) const {
09066 t v;
09067 return contains(pixel,x,y,z,v);
09068 }
09069
09071 template<typename t> bool contains(const T& pixel, t& x, t& y) const {
09072 t z,v;
09073 return contains(pixel,x,y,z,v);
09074 }
09075
09077 template<typename t> bool contains(const T& pixel, t& x) const {
09078 t y,z,v;
09079 return contains(pixel,x,y,z,v);
09080 }
09081
09083 template<typename t> bool contains(const T& pixel) const {
09084 t x,y,z,v;
09085 return contains(pixel,x,y,z,v);
09086 }
09087
09089
09092 template<typename t> bool is_overlapping(const CImg<t>& img) const {
09093 const unsigned long csiz = size(), isiz = img.size();
09094 return !((void*)(data+csiz)<=(void*)img.data || (void*)data>=(void*)(img.data+isiz));
09095 }
09096
09098 bool is_empty() const {
09099 return !(data && width && height && depth && dim);
09100 }
09101
09103 operator bool() const {
09104 return !is_empty();
09105 }
09106
09108
09124 long offset(const int x=0, const int y=0, const int z=0, const int v=0) const {
09125 return x + y*width + z*width*height + v*width*height*depth;
09126 }
09127
09129
09147 T* ptr(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) {
09148 const long off = offset(x,y,z,v);
09149 #if cimg_debug>=3
09150 if (off<0 || off>=(long)size()) {
09151 cimg::warn("CImg<%s>::ptr() : Asked for a pointer at coordinates (%u,%u,%u,%u) (offset=%u), "
09152 "outside image range (%u,%u,%u,%u) (size=%u)",
09153 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09154 return data;
09155 }
09156 #endif
09157 return data+off;
09158 }
09159
09160 const T* ptr(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const {
09161 const long off = offset(x,y,z,v);
09162 #if cimg_debug>=3
09163 if (off<0 || off>=(long)size()) {
09164 cimg::warn("CImg<%s>::ptr() : Trying to get a pointer at (%u,%u,%u,%u) (offset=%u) which is"
09165 "outside the data of the image (%u,%u,%u,%u) (size=%u)",
09166 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09167 return data;
09168 }
09169 #endif
09170 return data+off;
09171 }
09172
09174 iterator begin() {
09175 return data;
09176 }
09177
09178 const_iterator begin() const {
09179 return data;
09180 }
09181
09183 iterator end() {
09184 return data + size();
09185 }
09186
09187 const_iterator end() const {
09188 return data + size();
09189 }
09190
09192
09214 T& operator()(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) {
09215 const long off = offset(x,y,z,v);
09216 #if cimg_debug>=3
09217 if (!data || off>=(long)size()) {
09218 cimg::warn("CImg<%s>::operator() : Pixel access requested at (%u,%u,%u,%u) (offset=%u) "
09219 "outside the image range (%u,%u,%u,%u) (size=%u)",
09220 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09221 return *data;
09222 }
09223 #endif
09224 return data[off];
09225 }
09226
09227 const T& operator()(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const {
09228 const long off = offset(x,y,z,v);
09229 #if cimg_debug>=3
09230 if (!data || off>=(long)size()) {
09231 cimg::warn("CImg<%s>::operator() : Pixel access requested at (%u,%u,%u,%u) (offset=%u) "
09232 "outside the image range (%u,%u,%u,%u) (size=%u)",
09233 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09234 return *data;
09235 }
09236 #endif
09237 return data[off];
09238 }
09239
09241 T& at(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) {
09242 const long off = offset(x,y,z,v);
09243 if (!data || off>=(long)size())
09244 throw CImgArgumentException("CImg<%s>::at() : Pixel access requested at (%u,%u,%u,%u) (offset=%u) "
09245 "outside the image range (%u,%u,%u,%u) (size=%u)",
09246 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09247 return data[off];
09248 }
09249
09250 const T& at(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const {
09251 const long off = offset(x,y,z,v);
09252 if (!data || off>=(long)size())
09253 throw CImgArgumentException("CImg<%s>::at() : Pixel access requested at (%u,%u,%u,%u) (offset=%u) "
09254 "outside the image range (%u,%u,%u,%u) (size=%u)",
09255 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09256 return data[off];
09257 }
09258
09260
09277 T& operator[](const unsigned long off) {
09278 return operator()(off);
09279 }
09280
09281 const T& operator[](const unsigned long off) const {
09282 return operator()(off);
09283 }
09284
09286 T& back() {
09287 return operator()(size()-1);
09288 }
09289
09290 const T& back() const {
09291 return operator()(size()-1);
09292 }
09293
09295 T& front() {
09296 return *data;
09297 }
09298
09299 const T& front() const {
09300 return *data;
09301 }
09302
09304
09326 T pix1d(const int x, const int y, const int z, const int v, const T out_val) const {
09327 return (x<0 || x>=dimx())?out_val:(*this)(x,y,z,v);
09328 }
09329
09330 const T& pix1d(const int x, const int y=0, const int z=0, const int v=0) const {
09331 return (*this)(x<0?0:(x>=dimx()?dimx()-1:x),y,z,v);
09332 }
09333
09335 T pix2d(const int x, const int y, const int z, const int v, const T out_val) const {
09336 return (x<0 || y<0 || x>=dimx() || y>=dimy())?out_val:(*this)(x,y,z,v);
09337 }
09338
09339 const T& pix2d(const int x, const int y, const int z=0, const int v=0) const {
09340 return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),z,v);
09341 }
09342
09344 T pix3d(const int x, const int y, const int z, const int v, const T out_val) const {
09345 return (x<0 || y<0 || z<0 || x>=dimx() || y>=dimy() || z>=dimz())?out_val:(*this)(x,y,z,v);
09346 }
09347
09348 const T& pix3d(const int x, const int y, const int z, const int v=0) const {
09349 return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),
09350 z<0?0:(z>=dimz()?dimz()-1:z),v);
09351 }
09352
09354 T pix4d(const int x, const int y, const int z, const int v, const T out_val) const {
09355 return (x<0 || y<0 || z<0 || v<0 || x>=dimx() || y>=dimy() || z>=dimz() || v>=dimv())?out_val:(*this)(x,y,z,v);
09356 }
09357
09358 T pix4d(const int x, const int y, const int z, const int v) const {
09359 return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),
09360 z<0?0:(z>=dimz()?dimz()-1:z), v<0?0:(v>=dimv()?dimv()-1:v));
09361 }
09362
09364
09369 typename cimg::superset<T,float>::type linear_pix1d(const float fx, const int y, const int z, const int v,
09370 const T out_val) const {
09371 typedef typename cimg::superset<T,float>::type ftype;
09372 const int
09373 x = (int)fx-(fx>=0?0:1), nx = x+1;
09374 const float
09375 dx = fx-x;
09376 const ftype
09377 Ic = (ftype)pix1d(x,y,z,v,out_val), In = (ftype)pix2d(nx,y,z,v,out_val);
09378 return Ic + dx*(In-Ic);
09379 }
09380
09381 typename cimg::superset<T,float>::type linear_pix1d(const float fx, const int y=0, const int z=0, const int v=0) const {
09382 typedef typename cimg::superset<T,float>::type ftype;
09383 const float
09384 nfx = fx<0?0:(fx>width-1?width-1:fx);
09385 const unsigned int
09386 x = (unsigned int)nfx;
09387 const float
09388 dx = nfx-x;
09389 const unsigned int
09390 nx = dx>0?x+1:x;
09391 const ftype
09392 Ic = (ftype)(*this)(x,y,z,v), In = (ftype)(*this)(nx,y,z,v);
09393 return Ic + dx*(In-Ic);
09394 }
09395
09397
09402 typename cimg::superset<T,float>::type linear_pix2d(const float fx, const float fy, const int z, const int v,
09403 const T out_val) const {
09404 typedef typename cimg::superset<T,float>::type ftype;
09405 const int
09406 x = (int)fx-(fx>=0?0:1), nx = x+1,
09407 y = (int)fy-(fy>=0?0:1), ny = y+1;
09408 const float
09409 dx = fx-x,
09410 dy = fy-y;
09411 const ftype
09412 Icc = (ftype)pix2d(x,y,z,v,out_val), Inc = (ftype)pix2d(nx,y,z,v,out_val),
09413 Icn = (ftype)pix2d(x,ny,z,v,out_val), Inn = (ftype)pix2d(nx,ny,z,v,out_val);
09414 return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc);
09415 }
09416
09417 typename cimg::superset<T,float>::type linear_pix2d(const float fx, const float fy, const int z=0, const int v=0) const {
09418 typedef typename cimg::superset<T,float>::type ftype;
09419 const float
09420 nfx = fx<0?0:(fx>width-1?width-1:fx),
09421 nfy = fy<0?0:(fy>height-1?height-1:fy);
09422 const unsigned int
09423 x = (unsigned int)nfx,
09424 y = (unsigned int)nfy;
09425 const float
09426 dx = nfx-x,
09427 dy = nfy-y;
09428 const unsigned int
09429 nx = dx>0?x+1:x,
09430 ny = dy>0?y+1:y;
09431 const ftype
09432 Icc = (ftype)(*this)(x,y,z,v), Inc = (ftype)(*this)(nx,y,z,v),
09433 Icn = (ftype)(*this)(x,ny,z,v), Inn = (ftype)(*this)(nx,ny,z,v);
09434 return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc);
09435 }
09436
09438
09443 typename cimg::superset<T,float>::type linear_pix3d(const float fx, const float fy, const float fz, const int v,
09444 const T out_val) const {
09445 typedef typename cimg::superset<T,float>::type ftype;
09446 const int
09447 x = (int)fx-(fx>=0?0:1), nx = x+1,
09448 y = (int)fy-(fy>=0?0:1), ny = y+1,
09449 z = (int)fz-(fz>=0?0:1), nz = z+1;
09450 const float
09451 dx = fx-x,
09452 dy = fy-y,
09453 dz = fz-z;
09454 const ftype
09455 Iccc = (ftype)pix3d(x,y,z,v,out_val), Incc = (ftype)pix3d(nx,y,z,v,out_val),
09456 Icnc = (ftype)pix3d(x,ny,z,v,out_val), Innc = (ftype)pix3d(nx,ny,z,v,out_val),
09457 Iccn = (ftype)pix3d(x,y,nz,v,out_val), Incn = (ftype)pix3d(nx,y,nz,v,out_val),
09458 Icnn = (ftype)pix3d(x,ny,nz,v,out_val), Innn = (ftype)pix3d(nx,ny,nz,v,out_val);
09459 return Iccc +
09460 dx*(Incc-Iccc +
09461 dy*(Iccc+Innc-Icnc-Incc +
09462 dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) +
09463 dz*(Iccc+Incn-Iccn-Incc)) +
09464 dy*(Icnc-Iccc +
09465 dz*(Iccc+Icnn-Iccn-Icnc)) +
09466 dz*(Iccn-Iccc);
09467 }
09468
09469 typename cimg::superset<T,float>::type linear_pix3d(const float fx, const float fy=0, const float fz=0, const int v=0) const {
09470 typedef typename cimg::superset<T,float>::type ftype;
09471 const float
09472 nfx = fx<0?0:(fx>width-1?width-1:fx),
09473 nfy = fy<0?0:(fy>height-1?height-1:fy),
09474 nfz = fz<0?0:(fz>depth-1?depth-1:fz);
09475 const unsigned int
09476 x = (unsigned int)nfx,
09477 y = (unsigned int)nfy,
09478 z = (unsigned int)nfz;
09479 const float
09480 dx = nfx-x,
09481 dy = nfy-y,
09482 dz = nfz-z;
09483 const unsigned int
09484 nx = dx>0?x+1:x,
09485 ny = dy>0?y+1:y,
09486 nz = dz>0?z+1:z;
09487 const ftype
09488 Iccc = (ftype)(*this)(x,y,z,v), Incc = (ftype)(*this)(nx,y,z,v),
09489 Icnc = (ftype)(*this)(x,ny,z,v), Innc = (ftype)(*this)(nx,ny,z,v),
09490 Iccn = (ftype)(*this)(x,y,nz,v), Incn = (ftype)(*this)(nx,y,nz,v),
09491 Icnn = (ftype)(*this)(x,ny,nz,v), Innn = (ftype)(*this)(nx,ny,nz,v);
09492 return Iccc +
09493 dx*(Incc-Iccc +
09494 dy*(Iccc+Innc-Icnc-Incc +
09495 dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) +
09496 dz*(Iccc+Incn-Iccn-Incc)) +
09497 dy*(Icnc-Iccc +
09498 dz*(Iccc+Icnn-Iccn-Icnc)) +
09499 dz*(Iccn-Iccc);
09500 }
09501
09503
09527 typename cimg::superset<T,float>::type linear_pix4d(const float fx, const float fy, const float fz, const float fv,
09528 const T out_val) const {
09529 typedef typename cimg::superset<T,float>::type ftype;
09530 const int
09531 x = (int)fx-(fx>=0?0:1), nx = x+1,
09532 y = (int)fy-(fy>=0?0:1), ny = y+1,
09533 z = (int)fz-(fz>=0?0:1), nz = z+1,
09534 v = (int)fv-(fv>=0?0:1), nv = v+1;
09535 const float
09536 dx = fx-x,
09537 dy = fy-y,
09538 dz = fz-z,
09539 dv = fv-v;
09540 const ftype
09541 Icccc = (ftype)pix4d(x,y,z,v,out_val), Inccc = (ftype)pix4d(nx,y,z,v,out_val),
09542 Icncc = (ftype)pix4d(x,ny,z,v,out_val), Inncc = (ftype)pix4d(nx,ny,z,v,out_val),
09543 Iccnc = (ftype)pix4d(x,y,nz,v,out_val), Incnc = (ftype)pix4d(nx,y,nz,v,out_val),
09544 Icnnc = (ftype)pix4d(x,ny,nz,v,out_val), Innnc = (ftype)pix4d(nx,ny,nz,v,out_val),
09545 Icccn = (ftype)pix4d(x,y,z,nv,out_val), Inccn = (ftype)pix4d(nx,y,z,nv,out_val),
09546 Icncn = (ftype)pix4d(x,ny,z,nv,out_val), Inncn = (ftype)pix4d(nx,ny,z,nv,out_val),
09547 Iccnn = (ftype)pix4d(x,y,nz,nv,out_val), Incnn = (ftype)pix4d(nx,y,nz,nv,out_val),
09548 Icnnn = (ftype)pix4d(x,ny,nz,nv,out_val), Innnn = (ftype)pix4d(nx,ny,nz,nv,out_val);
09549 return Icccc +
09550 dx*(Inccc-Icccc +
09551 dy*(Icccc+Inncc-Icncc-Inccc +
09552 dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc +
09553 dv*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) +
09554 dv*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) +
09555 dz*(Icccc+Incnc-Iccnc-Inccc +
09556 dv*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) +
09557 dv*(Icccc+Inccn-Inccc-Icccn)) +
09558 dy*(Icncc-Icccc +
09559 dz*(Icccc+Icnnc-Iccnc-Icncc +
09560 dv*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) +
09561 dv*(Icccc+Icncn-Icncc-Icccn)) +
09562 dz*(Iccnc-Icccc +
09563 dv*(Icccc+Iccnn-Iccnc-Icccn)) +
09564 dv*(Icccn-Icccc);
09565 }
09566
09567 typename cimg::superset<T,float>::type linear_pix4d(const float fx, const float fy=0, const float fz=0, const float fv=0) const {
09568 typedef typename cimg::superset<T,float>::type ftype;
09569 const float
09570 nfx = fx<0?0:(fx>width-1?width-1:fx),
09571 nfy = fy<0?0:(fy>height-1?height-1:fy),
09572 nfz = fz<0?0:(fz>depth-1?depth-1:fz),
09573 nfv = fv<0?0:(fv>dim-1?dim-1:fv);
09574 const unsigned int
09575 x = (unsigned int)nfx,
09576 y = (unsigned int)nfy,
09577 z = (unsigned int)nfz,
09578 v = (unsigned int)nfv;
09579 const float
09580 dx = nfx-x,
09581 dy = nfy-y,
09582 dz = nfz-z,
09583 dv = nfv-v;
09584 const unsigned int
09585 nx = dx>0?x+1:x,
09586 ny = dy>0?y+1:y,
09587 nz = dz>0?z+1:z,
09588 nv = dv>0?v+1:v;
09589 const ftype
09590 Icccc = (ftype)(*this)(x,y,z,v), Inccc = (ftype)(*this)(nx,y,z,v),
09591 Icncc = (ftype)(*this)(x,ny,z,v), Inncc = (ftype)(*this)(nx,ny,z,v),
09592 Iccnc = (ftype)(*this)(x,y,nz,v), Incnc = (ftype)(*this)(nx,y,nz,v),
09593 Icnnc = (ftype)(*this)(x,ny,nz,v), Innnc = (ftype)(*this)(nx,ny,nz,v),
09594 Icccn = (ftype)(*this)(x,y,z,nv), Inccn = (ftype)(*this)(nx,y,z,nv),
09595 Icncn = (ftype)(*this)(x,ny,z,nv), Inncn = (ftype)(*this)(nx,ny,z,nv),
09596 Iccnn = (ftype)(*this)(x,y,nz,nv), Incnn = (ftype)(*this)(nx,y,nz,nv),
09597 Icnnn = (ftype)(*this)(x,ny,nz,nv), Innnn = (ftype)(*this)(nx,ny,nz,nv);
09598 return Icccc +
09599 dx*(Inccc-Icccc +
09600 dy*(Icccc+Inncc-Icncc-Inccc +
09601 dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc +
09602 dv*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) +
09603 dv*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) +
09604 dz*(Icccc+Incnc-Iccnc-Inccc +
09605 dv*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) +
09606 dv*(Icccc+Inccn-Inccc-Icccn)) +
09607 dy*(Icncc-Icccc +
09608 dz*(Icccc+Icnnc-Iccnc-Icncc +
09609 dv*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) +
09610 dv*(Icccc+Icncn-Icncc-Icccn)) +
09611 dz*(Iccnc-Icccc +
09612 dv*(Icccc+Iccnn-Iccnc-Icccn)) +
09613 dv*(Icccn-Icccc);
09614 }
09615
09617
09622 typename cimg::superset<T,float>::type cubic_pix1d(const float fx, const int y, const int z, const int v,
09623 const T out_val) const {
09624 typedef typename cimg::superset<T,float>::type ftype;
09625 const int
09626 x = (int)fx-(fx>=0?0:1), px = x-1, nx = x+1, ax = x+2;
09627 const float
09628 dx = fx-x;
09629 const ftype
09630 Ip = (ftype)pix1d(px,y,z,v,out_val), Ic = (ftype)pix1d(x,y,z,v,out_val),
09631 In = (ftype)pix1d(nx,y,z,v,out_val), Ia = (ftype)pix1d(ax,y,z,v,out_val),
09632 valm = cimg::min(Ip,In,Ic,Ia), valM = cimg::max(Ip,In,Ic,Ia),
09633 u0 = Ic - Ip,
09634 u1 = Ia - In,
09635 a = 2*(Ic-In) + u0 + u1,
09636 b = 3*(In-Ic) - 2*u0 - u1,
09637 val = a*dx*dx*dx + b*dx*dx + u0*dx + Ic;
09638 return val<valm?valm:(val>valM?valM:val);
09639 }
09640
09641 typename cimg::superset<T,float>::type cubic_pix1d(const float fx, const int y=0, const int z=0, const int v=0) const {
09642 typedef typename cimg::superset<T,float>::type ftype;
09643 const float
09644 nfx = fx<0?0:(fx>width-1?width-1:fx);
09645 const int
09646 x = (int)nfx;
09647 const float
09648 dx = nfx-x;
09649 const int
09650 px = x-1<0?0:x-1, nx = dx>0?x+1:x, ax = x+2>=dimx()?dimx()-1:x+2;
09651 const ftype
09652 Ip = (ftype)(*this)(px,y,z,v), Ic = (ftype)(*this)(x,y,z,v),
09653 In = (ftype)(*this)(nx,y,z,v), Ia = (ftype)(*this)(ax,y,z,v),
09654 valm = cimg::min(Ip,In,Ic,Ia), valM = cimg::max(Ip,In,Ic,Ia),
09655 u0 = Ic - Ip,
09656 u1 = Ia - In,
09657 a = 2*(Ic-In) + u0 + u1,
09658 b = 3*(In-Ic) - 2*u0 - u1,
09659 val = a*dx*dx*dx + b*dx*dx + u0*dx + Ic;
09660 return val<valm?valm:(val>valM?valM:val);
09661 }
09662
09664
09678 typename cimg::superset<T,float>::type cubic_pix2d(const float fx, const float fy, const int z, const int v,
09679 const T out_val) const {
09680 typedef typename cimg::superset<T,float>::type ftype;
09681 const int
09682 x = (int)fx-(fx>=0?0:1), px = x-1, nx = x+1, ax = x+2,
09683 y = (int)fy-(fy>=0?0:1), py = y-1, ny = y+1, ay = y+2;
09684 const float
09685 dx = fx-x, dx2 = dx*dx, dx3 = dx2*dx,
09686 dy = fy-y;
09687 const ftype
09688 Ipp = (ftype)pix2d(px,py,z,v,out_val), Icp = (ftype)pix2d(x,py,z,v,out_val),
09689 Inp = (ftype)pix2d(nx,py,z,v,out_val), Iap = (ftype)pix2d(ax,py,z,v,out_val),
09690 Ipc = (ftype)pix2d(px,y,z,v,out_val), Icc = (ftype)pix2d(x,y,z,v,out_val),
09691 Inc = (ftype)pix2d(nx,y,z,v,out_val), Iac = (ftype)pix2d(ax,y,z,v,out_val),
09692 Ipn = (ftype)pix2d(px,ny,z,v,out_val), Icn = (ftype)pix2d(x,ny,z,v,out_val),
09693 Inn = (ftype)pix2d(nx,ny,z,v,out_val), Ian = (ftype)pix2d(ax,ny,z,v,out_val),
09694 Ipa = (ftype)pix2d(px,ay,z,v,out_val), Ica = (ftype)pix2d(x,ay,z,v,out_val),
09695 Ina = (ftype)pix2d(nx,ay,z,v,out_val), Iaa = (ftype)pix2d(ax,ay,z,v,out_val),
09696 valm = cimg::min(cimg::min(Ipp,Icp,Inp,Iap),cimg::min(Ipc,Icc,Inc,Iac),cimg::min(Ipn,Icn,Inn,Ian),cimg::min(Ipa,Ica,Ina,Iaa)),
09697 valM = cimg::max(cimg::max(Ipp,Icp,Inp,Iap),cimg::max(Ipc,Icc,Inc,Iac),cimg::max(Ipn,Icn,Inn,Ian),cimg::max(Ipa,Ica,Ina,Iaa)),
09698 u0p = Icp - Ipp,
09699 u1p = Iap - Inp,
09700 ap = 2*(Icp-Inp) + u0p + u1p,
09701 bp = 3*(Inp-Icp) - 2*u0p - u1p,
09702 u0c = Icc - Ipc,
09703 u1c = Iac - Inc,
09704 ac = 2*(Icc-Inc) + u0c + u1c,
09705 bc = 3*(Inc-Icc) - 2*u0c - u1c,
09706 u0n = Icn - Ipn,
09707 u1n = Ian - Inn,
09708 an = 2*(Icn-Inn) + u0n + u1n,
09709 bn = 3*(Inn-Icn) - 2*u0n - u1n,
09710 u0a = Ica - Ipa,
09711 u1a = Iaa - Ina,
09712 aa = 2*(Ica-Ina) + u0a + u1a,
09713 ba = 3*(Ina-Ica) - 2*u0a - u1a,
09714 valp = ap*dx3 + bp*dx2 + u0p*dx + Icp,
09715 valc = ac*dx3 + bc*dx2 + u0c*dx + Icc,
09716 valn = an*dx3 + bn*dx2 + u0n*dx + Icn,
09717 vala = aa*dx3 + ba*dx2 + u0a*dx + Ica,
09718 u0 = valc - valp,
09719 u1 = vala - valn,
09720 a = 2*(valc-valn) + u0 + u1,
09721 b = 3*(valn-valc) - 2*u0 - u1,
09722 val = a*dy*dy*dy + b*dy*dy + u0*dy + valc;
09723 return val<valm?valm:(val>valM?valM:val);
09724 }
09725
09726 typename cimg::superset<T,float>::type cubic_pix2d(const float fx, const float fy, const int z=0, const int v=0) const {
09727 typedef typename cimg::superset<T,float>::type ftype;
09728 const float
09729 nfx = fx<0?0:(fx>width-1?width-1:fx),
09730 nfy = fy<0?0:(fy>height-1?height-1:fy);
09731 const int
09732 x = (int)nfx,
09733 y = (int)nfy;
09734 const float
09735 dx = nfx-x, dx2 = dx*dx, dx3 = dx2*dx,
09736 dy = nfy-y;
09737 const int
09738 px = x-1<0?0:x-1, nx = dx>0?x+1:x, ax = x+2>=dimx()?dimx()-1:x+2,
09739 py = y-1<0?0:y-1, ny = dy>0?y+1:y, ay = y+2>=dimy()?dimy()-1:y+2;
09740 const ftype
09741 Ipp = (ftype)(*this)(px,py,z,v), Icp = (ftype)(*this)(x,py,z,v),
09742 Inp = (ftype)(*this)(nx,py,z,v), Iap = (ftype)(*this)(ax,py,z,v),
09743 Ipc = (ftype)(*this)(px,y,z,v), Icc = (ftype)(*this)(x,y,z,v),
09744 Inc = (ftype)(*this)(nx,y,z,v), Iac = (ftype)(*this)(ax,y,z,v),
09745 Ipn = (ftype)(*this)(px,ny,z,v), Icn = (ftype)(*this)(x,ny,z,v),
09746 Inn = (ftype)(*this)(nx,ny,z,v), Ian = (ftype)(*this)(ax,ny,z,v),
09747 Ipa = (ftype)(*this)(px,ay,z,v), Ica = (ftype)(*this)(x,ay,z,v),
09748 Ina = (ftype)(*this)(nx,ay,z,v), Iaa = (ftype)(*this)(ax,ay,z,v),
09749 valm = cimg::min(cimg::min(Ipp,Icp,Inp,Iap),cimg::min(Ipc,Icc,Inc,Iac),cimg::min(Ipn,Icn,Inn,Ian),cimg::min(Ipa,Ica,Ina,Iaa)),
09750 valM = cimg::max(cimg::max(Ipp,Icp,Inp,Iap),cimg::max(Ipc,Icc,Inc,Iac),cimg::max(Ipn,Icn,Inn,Ian),cimg::max(Ipa,Ica,Ina,Iaa)),
09751 u0p = Icp - Ipp,
09752 u1p = Iap - Inp,
09753 ap = 2*(Icp-Inp) + u0p + u1p,
09754 bp = 3*(Inp-Icp) - 2*u0p - u1p,
09755 u0c = Icc - Ipc,
09756 u1c = Iac - Inc,
09757 ac = 2*(Icc-Inc) + u0c + u1c,
09758 bc = 3*(Inc-Icc) - 2*u0c - u1c,
09759 u0n = Icn - Ipn,
09760 u1n = Ian - Inn,
09761 an = 2*(Icn-Inn) + u0n + u1n,
09762 bn = 3*(Inn-Icn) - 2*u0n - u1n,
09763 u0a = Ica - Ipa,
09764 u1a = Iaa - Ina,
09765 aa = 2*(Ica-Ina) + u0a + u1a,
09766 ba = 3*(Ina-Ica) - 2*u0a - u1a,
09767 valp = ap*dx3 + bp*dx2 + u0p*dx + Icp,
09768 valc = ac*dx3 + bc*dx2 + u0c*dx + Icc,
09769 valn = an*dx3 + bn*dx2 + u0n*dx + Icn,
09770 vala = aa*dx3 + ba*dx2 + u0a*dx + Ica,
09771 u0 = valc - valp,
09772 u1 = vala - valn,
09773 a = 2*(valc-valn) + u0 + u1,
09774 b = 3*(valn-valc) - 2*u0 - u1,
09775 val = a*dy*dy*dy + b*dy*dy + u0*dy + valc;
09776 return val<valm?valm:(val>valM?valM:val);
09777 }
09778
09780 const T& max() const {
09781 if (is_empty()) throw CImgInstanceException("CImg<%s>::max() : Instance image is empty.",pixel_type());
09782 const T *ptrmax = data;
09783 T max_value = *ptrmax;
09784 cimg_for(*this,ptr,T) if ((*ptr)>max_value) max_value = *(ptrmax=ptr);
09785 return *ptrmax;
09786 }
09787
09789 T& max() {
09790 if (is_empty()) throw CImgInstanceException("CImg<%s>::max() : Instance image is empty.",pixel_type());
09791 T *ptrmax = data;
09792 T max_value = *ptrmax;
09793 cimg_for(*this,ptr,T) if ((*ptr)>max_value) max_value = *(ptrmax=ptr);
09794 return *ptrmax;
09795 }
09796
09798 const T& min() const {
09799 if (is_empty()) throw CImgInstanceException("CImg<%s>::min() : Instance image is empty.",pixel_type());
09800 const T *ptrmin = data;
09801 T min_value = *ptrmin;
09802 cimg_for(*this,ptr,T) if ((*ptr)<min_value) min_value = *(ptrmin=ptr);
09803 return *ptrmin;
09804 }
09805
09807 T& min() {
09808 if (is_empty()) throw CImgInstanceException("CImg<%s>::min() : Instance image is empty.",pixel_type());
09809 T *ptrmin = data;
09810 T min_value = *ptrmin;
09811 cimg_for(*this,ptr,T) if ((*ptr)<min_value) min_value = *(ptrmin=ptr);
09812 return *ptrmin;
09813 }
09814
09816 template<typename t> const T& minmax(t& max_val) const {
09817 if (is_empty()) throw CImgInstanceException("CImg<%s>::minmax() : Instance image is empty.",pixel_type());
09818 const T *ptrmin = data;
09819 T min_value = *ptrmin, max_value = min_value;
09820 cimg_for(*this,ptr,T) {
09821 const T val = *ptr;
09822 if (val<min_value) { min_value = val; ptrmin = ptr; }
09823 if (val>max_value) max_value = val;
09824 }
09825 max_val = (t)max_value;
09826 return *ptrmin;
09827 }
09828
09830 template<typename t> T& minmax(t& max_val) {
09831 if (is_empty()) throw CImgInstanceException("CImg<%s>::minmax() : Instance image is empty.",pixel_type());
09832 T *ptrmin = data;
09833 T min_value = *ptrmin, max_value = min_value;
09834 cimg_for(*this,ptr,T) {
09835 const T val = *ptr;
09836 if (val<min_value) { min_value = val; ptrmin = ptr; }
09837 if (val>max_value) max_value = val;
09838 }
09839 max_val = (t)max_value;
09840 return *ptrmin;
09841 }
09842
09844 template<typename t> const T& maxmin(t& min_val) const {
09845 if (is_empty()) throw CImgInstanceException("CImg<%s>::maxmin() : Instance image is empty.",pixel_type());
09846 const T *ptrmax = data;
09847 T max_value = *ptrmax, min_value = max_value;
09848 cimg_for(*this,ptr,T) {
09849 const T val = *ptr;
09850 if (val>max_value) { max_value = val; ptrmax = ptr; }
09851 if (val<min_value) min_value = val;
09852 }
09853 min_val = (t)min_value;
09854 return *ptrmax;
09855 }
09856
09858 template<typename t> T& maxmin(t& min_val) {
09859 if (is_empty()) throw CImgInstanceException("CImg<%s>::maxmin() : Instance image is empty.",pixel_type());
09860 T *ptrmax = data;
09861 T max_value = *ptrmax, min_value = max_value;
09862 cimg_for(*this,ptr,T) {
09863 const T val = *ptr;
09864 if (val>max_value) { max_value = val; ptrmax = ptr; }
09865 if (val<min_value) min_value = val;
09866 }
09867 min_val = (t)min_value;
09868 return *ptrmax;
09869 }
09870
09872 double mean() const {
09873 if (is_empty()) throw CImgInstanceException("CImg<%s>::mean() : Instance image is empty.",pixel_type());
09874 double val = 0;
09875 cimg_for(*this,ptr,T) val+=(double)*ptr;
09876 return val/size();
09877 }
09878
09880 template<typename t> double variancemean(const unsigned int variance_method, t& mean) const {
09881 if (is_empty())
09882 throw CImgInstanceException("CImg<%s>::variance() : Instance image is empty.",pixel_type());
09883 double variance = 0, average = 0;
09884 const unsigned int siz = size();
09885 switch (variance_method) {
09886 case 3: {
09887 CImg<double> buf(*this);
09888 const unsigned int siz2 = siz>>1;
09889 { cimg_for(buf,ptrs,double) { const double val = *ptrs; (*ptrs)*=val; average+=val; }}
09890 buf.sort();
09891 double a = 0;
09892 const double *ptrs = buf.ptr();
09893 for (unsigned int j=0; j<siz2; ++j) a+=(*ptrs++);
09894 const double sig = 2.6477*std::sqrt(a/siz2);
09895 variance = sig*sig;
09896 } break;
09897 case 2: {
09898 CImg<double> buf(*this);
09899 buf.sort();
09900 const unsigned int siz2 = siz>>1;
09901 const double med_i = buf[siz2];
09902 cimg_for(buf,ptrs,double) { const double val = *ptrs; *ptrs = cimg::abs(val-med_i); average+=val; }
09903 buf.sort();
09904 const double sig = 1.4828*buf[siz2];
09905 variance = sig*sig;
09906 } break;
09907 case 1: {
09908 double S = 0, S2 = 0;
09909 cimg_for(*this,ptr,T) { const double val = (double)*ptr; S+=val; S2+=val*val; }
09910 variance = siz>1?(S2 - S*S/siz)/(siz-1):0;
09911 average = S;
09912 } break;
09913 default:{
09914 double S = 0, S2 = 0;
09915 cimg_for(*this,ptr,T) { const double val = (double)*ptr; S+=val; S2+=val*val; }
09916 variance = (S2 - S*S/siz)/siz;
09917 average = S;
09918 } break;
09919 }
09920 mean = (t)(average/siz);
09921 return variance;
09922 }
09923
09925 double variance(const unsigned int variance_method=0) const {
09926 double foo;
09927 return variancemean(variance_method,foo);
09928 }
09929
09931 template<typename t> double MSE(const CImg<t>& img) const {
09932 if (img.size()!=size())
09933 throw CImgArgumentException("CImg<%s>::MSE() : Instance image (%u,%u,%u,%u) and given image (%u,%u,%u,%u) have different dimensions.",
09934 pixel_type(),width,height,depth,dim,img.width,img.height,img.depth,img.dim);
09935
09936 double vMSE = 0;
09937 const t* ptr2 = img.end();
09938 cimg_for(*this,ptr1,T) {
09939 const double diff = (double)*ptr1 - (double)*(--ptr2);
09940 vMSE += diff*diff;
09941 }
09942 vMSE/=img.size();
09943 return vMSE;
09944 }
09945
09947 template<typename t> double PSNR(const CImg<t>& img, const double valmax=255.0) const {
09948 const double vMSE = std::sqrt(MSE(img));
09949 return (vMSE!=0)?(20*std::log10(valmax/vMSE)):(cimg::type<double>::max());
09950 }
09951
09953 double trace() const {
09954 if (is_empty())
09955 throw CImgInstanceException("CImg<%s>::trace() : Instance matrix (%u,%u,%u,%u,%p) is empty.",
09956 pixel_type(),width,height,depth,dim,data);
09957 double res = 0;
09958 cimg_forX(*this,k) res+=(*this)(k,k);
09959 return res;
09960 }
09961
09963 T median() const {
09964 const unsigned int s = size();
09965 const T res = kth_smallest(s>>1);
09966 return (s%2)?res:((res+kth_smallest((s>>1)-1))/2);
09967 }
09968
09970 template<typename t> double dot(const CImg<t>& img) const {
09971 if (is_empty())
09972 throw CImgInstanceException("CImg<%s>::dot() : Instance object (%u,%u,%u,%u,%p) is empty.",
09973 pixel_type(),width,height,depth,dim,data);
09974 if (!img)
09975 throw CImgArgumentException("CImg<%s>::trace() : Specified argument (%u,%u,%u,%u,%p) is empty.",
09976 pixel_type(),img.width,img.height,img.depth,img.dim,img.data);
09977 const unsigned long nb = cimg::min(size(),img.size());
09978 double res = 0;
09979 for (unsigned long off=0; off<nb; ++off) res+=(double)data[off]*(double)img[off];
09980 return res;
09981 }
09982
09984 double det() const {
09985 if (is_empty() || width!=height || depth!=1 || dim!=1)
09986 throw CImgInstanceException("CImg<%s>::det() : Instance matrix (%u,%u,%u,%u,%p) is not square or is empty.",
09987 pixel_type(),width,height,depth,dim,data);
09988 switch (width) {
09989 case 1: return (*this)(0,0);
09990 case 2: return (*this)(0,0)*(*this)(1,1)-(*this)(0,1)*(*this)(1,0);
09991 case 3: {
09992 const double
09993 a = data[0], d = data[1], g = data[2],
09994 b = data[3], e = data[4], h = data[5],
09995 c = data[6], f = data[7], i = data[8];
09996 return i*a*e-a*h*f-i*b*d+b*g*f+c*d*h-c*g*e;
09997 }
09998 default: {
09999 typedef typename cimg::superset<T,float>::type ftype;
10000 CImg<ftype> lu(*this);
10001 CImg<unsigned int> indx;
10002 bool d;
10003 lu._LU(indx,d);
10004 double res = d?1.0:-1.0;
10005 cimg_forX(lu,i) res*=lu(i,i);
10006 return res;
10007 }
10008 }
10009 return 0;
10010 }
10011
10013 double norm(const int norm_type=2) const {
10014 if (is_empty())
10015 throw CImgInstanceException("CImg<%s>::norm() : Instance object (%u,%u,%u,%u,%p) is empty.",
10016 pixel_type(),width,height,depth,dim,data);
10017 double res = 0;
10018 switch (norm_type) {
10019 case -1: {
10020 cimg_foroff(*this,off) {
10021 const double tmp = cimg::abs((double)data[off]);
10022 if (tmp>res) res = tmp;
10023 }
10024 return res;
10025 } break;
10026 case 1 : {
10027 cimg_foroff(*this,off) res+=cimg::abs((double)data[off]);
10028 return res;
10029 } break;
10030 default: { return std::sqrt(dot(*this)); }
10031 }
10032 return 0;
10033 }
10034
10036 double sum() const {
10037 if (is_empty())
10038 throw CImgInstanceException("CImg<%s>::sum() : Instance object (%u,%u,%u,%u,%p) is empty.",
10039 pixel_type(),width,height,depth,dim,data);
10040 double res = 0;
10041 cimg_for(*this,ptr,T) res+=*ptr;
10042 return res;
10043 }
10044
10046
10047 const T kth_smallest(const unsigned int k) const {
10048 if (is_empty())
10049 throw CImgInstanceException("CImg<%s>::kth_smallest() : Instance image (%u,%u,%u,%u,%p) is empty.",
10050 pixel_type(),width,height,depth,dim,data);
10051 CImg<T> arr(*this);
10052 unsigned long l = 0, ir = size()-1;
10053 for (;;) {
10054 if (ir<=l+1) {
10055 if (ir==l+1 && arr[ir]<arr[l]) cimg::swap(arr[l],arr[ir]);
10056 return arr[k];
10057 } else {
10058 const unsigned long mid = (l+ir)>>1;
10059 cimg::swap(arr[mid],arr[l+1]);
10060 if (arr[l]>arr[ir]) cimg::swap(arr[l],arr[ir]);
10061 if (arr[l+1]>arr[ir]) cimg::swap(arr[l+1],arr[ir]);
10062 if (arr[l]>arr[l+1]) cimg::swap(arr[l],arr[l+1]);
10063 unsigned long i = l+1, j = ir;
10064 const T pivot = arr[l+1];
10065 for (;;) {
10066 do ++i; while (arr[i]<pivot);
10067 do --j; while (arr[j]>pivot);
10068 if (j<i) break;
10069 cimg::swap(arr[i],arr[j]);
10070 }
10071 arr[l+1] = arr[j];
10072 arr[j] = pivot;
10073 if (j>=k) ir=j-1;
10074 if (j<=k) l=i;
10075 }
10076 }
10077 return 0;
10078 }
10079
10081
10098 const CImg<T>& print(const char *title=0, const int print_flag=1) const {
10099 typedef typename cimg::last<T,double>::type cdouble;
10100 static CImg<cdouble> st;
10101 if (print_flag>=0) {
10102 std::fprintf(stderr,"%-8s(this=%p): { size=(%u,%u,%u,%u), data=(%s*)%p (%s)",
10103 title?title:"CImg",(void*)this,
10104 width,height,depth,dim,pixel_type(),(void*)data,
10105 is_shared?"shared":"not shared");
10106 if (is_empty()) { std::fprintf(stderr,", [Undefined pixel data] }\n"); return *this; }
10107 if (print_flag>=1) {
10108 st = get_stats();
10109 int xm, ym, zm, vm, xM, yM, zM, vM;
10110 contains(data[(int)st(4)],xm,ym,zm,vm);
10111 contains(data[(int)st(5)],xM,yM,zM,vM);
10112 std::fprintf(stderr,", min=%g, mean=%g [std=%g], max=%g, pmin=(%d,%d,%d,%d), pmax=(%d,%d,%d,%d)",
10113 st[0],st[2],std::sqrt(st[3]),st[1],xm,ym,zm,vm,xM,yM,zM,vM);
10114 }
10115 if (print_flag>=2 || size()<=16) {
10116 std::fprintf(stderr," }\n%s = [ ",title?title:"data");
10117 cimg_forXYZV(*this,x,y,z,k) {
10118 std::fprintf(stderr,cimg::type<T>::format(),cimg::type<T>::format((*this)(x,y,z,k)));
10119 std::fprintf(stderr,"%s",((x+1)*(y+1)*(z+1)*(k+1)==(int)size()?" ]\n":(((x+1)%width==0)?" ; ":" ")));
10120 }
10121 } else std::fprintf(stderr," }\n");
10122 }
10123 return *this;
10124 }
10125
10127 const CImg<T>& print(const int print_flag) const {
10128 return print(0,print_flag);
10129 }
10130
10132
10133
10135
10136
10137
10139
10146 template<typename t> CImg<T>& operator=(const CImg<t>& img) {
10147 return assign(img);
10148 }
10149
10150 CImg<T>& operator=(const CImg<T>& img) {
10151 return assign(img);
10152 }
10153
10155
10168 CImg<T>& operator=(const T *buf) {
10169 return assign(buf,width,height,depth,dim);
10170 }
10171
10173 CImg<T>& operator=(const T val) {
10174 return fill(val);
10175 }
10176
10178
10182 CImg<T> operator+() const {
10183 return CImg<T>(*this,false);
10184 }
10185
10187 #ifdef cimg_use_visualcpp6
10188 CImg<T>& operator+=(const T val) {
10189 #else
10190 template<typename t> CImg<T>& operator+=(const t val) {
10191 #endif
10192 cimg_for(*this,ptr,T) (*ptr) = (T)((*ptr)+val);
10193 return *this;
10194 }
10195
10197 template<typename t> CImg<T>& operator+=(const CImg<t>& img) {
10198 if (is_overlapping(img)) return *this+=+img;
10199 const unsigned int smin = cimg::min(size(),img.size());
10200 t *ptrs = img.data + smin;
10201 for (T *ptrd = data + smin; ptrd>data; --ptrd, (*ptrd)=(T)((*ptrd)+(*(--ptrs))));
10202 return *this;
10203 }
10204
10206 CImg<T>& operator++() {
10207 cimg_for(*this,ptr,T) ++(*ptr);
10208 return *this;
10209 }
10210
10212 CImg<T> operator++(int) {
10213 CImg<T> copy(*this,false);
10214 ++*this;
10215 return copy;
10216 }
10217
10219 CImg<T> operator-() const {
10220 return CImg<T>(width,height,depth,dim,0)-=*this;
10221 }
10222
10224 #ifdef cimg_use_visualcpp6
10225 CImg<T>& operator-=(const T val) {
10226 #else
10227 template<typename t> CImg<T>& operator-=(const t val) {
10228 #endif
10229 cimg_for(*this,ptr,T) (*ptr) = (T)((*ptr)-val);
10230 return *this;
10231 }
10232
10234 template<typename t> CImg<T>& operator-=(const CImg<t>& img) {
10235 if (is_overlapping(img)) return *this-=+img;
10236 const unsigned int smin = cimg::min(size(),img.size());
10237 t *ptrs = img.data+smin;
10238 for (T *ptrd = data+smin; ptrd>data; --ptrd, (*ptrd) = (T)((*ptrd)-(*(--ptrs))));
10239 return *this;
10240 }
10241
10243 CImg<T>& operator--() {
10244 cimg_for(*this,ptr,T) *ptr = *ptr-(T)1;
10245 return *this;
10246 }
10247
10249 CImg<T> operator--(int) {
10250 CImg<T> copy(*this,false);
10251 --*this;
10252 return copy;
10253 }
10254
10256 #ifdef cimg_use_visualcpp6
10257 CImg<T>& operator*=(const double val) {
10258 #else
10259 template<typename t> CImg<T>& operator*=(const t val) {
10260 #endif
10261 cimg_for(*this,ptr,T) (*ptr) = (T)((*ptr)*val);
10262 return *this;
10263 }
10264
10266 template<typename t> CImg<T>& operator*=(const CImg<t>& img) {
10267 return ((*this)*img).assign_to(*this);
10268 }
10269
10271 #ifdef cimg_use_visualcpp6
10272 CImg<T>& operator/=(const double val) {
10273 #else
10274 template<typename t> CImg<T>& operator/=(const t val) {
10275 #endif
10276 cimg_for(*this,ptr,T) (*ptr) = (T)((*ptr)/val);
10277 return *this;
10278 }
10279
10281 template<typename t> CImg<T>& operator/=(const CImg<t>& img) {
10282 return assign(*this*img.get_inverse());
10283 }
10284
10286 template<typename t> CImg<typename cimg::superset<T,t>::type> operator%(const CImg<t>& img) const {
10287 typedef typename cimg::superset<T,t>::type restype;
10288 return CImg<restype>(*this,false)%=img;
10289 }
10290
10292 CImg<T> operator%(const T val) const {
10293 return (+*this)%=val;
10294 }
10295
10297 CImg<T>& operator%=(const T val) {
10298 cimg_for(*this,ptr,T) (*ptr) = (T)cimg::mod(*ptr,val);
10299 return *this;
10300 }
10301
10303 template<typename t> CImg<T>& operator%=(const CImg<t>& img) {
10304 if (is_overlapping(img)) return *this%=+img;
10305 typedef typename cimg::superset<T,t>::type btype;
10306 const unsigned int smin = cimg::min(size(),img.size());
10307 const t *ptrs = img.data + smin;
10308 for (T *ptrd = data + smin; ptrd>data; ) {
10309 T& val = *(--ptrd);
10310 val = (T)cimg::mod((btype)val,(btype)*(--ptrs));
10311 }
10312 return *this;
10313 }
10314
10316 template<typename t> CImg<typename cimg::superset<T,t>::type> operator&(const CImg<t>& img) const {
10317 typedef typename cimg::superset<T,t>::type restype;
10318 return CImg<restype>(*this,false)&=img;
10319 }
10320
10322 CImg<T> operator&(const T val) const {
10323 return (+*this)&=val;
10324 }
10325
10327 template<typename t> CImg<T>& operator&=(const CImg<t>& img) {
10328 if (is_overlapping(img)) return *this&=+img;
10329 const unsigned int smin = cimg::min(size(),img.size());
10330 const t *ptrs = img.data + smin;
10331 for (T *ptrd = data + smin; ptrd>data; ) {
10332 T& val = *(--ptrd);
10333 val = (T)((unsigned long)val & (unsigned long)*(--ptrs));
10334 }
10335 return *this;
10336 }
10337
10339 CImg<T>& operator&=(const T val) {
10340 cimg_for(*this,ptr,T) *ptr = (T)((unsigned long)*ptr & (unsigned long)val);
10341 return *this;
10342 }
10343
10345 template<typename t> CImg<typename cimg::superset<T,t>::type> operator|(const CImg<t>& img) const {
10346 typedef typename cimg::superset<T,t>::type restype;
10347 return CImg<restype>(*this,false)|=img;
10348 }
10349
10351 CImg<T> operator|(const T val) const {
10352 return (+*this)|=val;
10353 }
10354
10356 template<typename t> CImg<T>& operator|=(const CImg<t>& img) {
10357 if (is_overlapping(img)) return *this|=+img;
10358 const unsigned int smin = cimg::min(size(),img.size());
10359 const t *ptrs = img.data + smin;
10360 for (T *ptrd = data + smin; ptrd>data; ) {
10361 T& val = *(--ptrd);
10362 val = (T)((unsigned long)val | (unsigned long)*(--ptrs));
10363 }
10364 return *this;
10365 }
10366
10368 CImg<T>& operator|=(const T val) {
10369 cimg_for(*this,ptr,T) *ptr = (T)((unsigned long)*ptr | (unsigned long)val);
10370 return *this;
10371 }
10372
10374 template<typename t> CImg<typename cimg::superset<T,t>::type> operator^(const CImg<t>& img) const {
10375 typedef typename cimg::superset<T,t>::type restype;
10376 return CImg<restype>(*this,false)^=img;
10377 }
10378
10380 CImg<T> operator^(const T val) const {
10381 return (+*this)^=val;
10382 }
10383
10385 template<typename t> CImg<T>& operator^=(const CImg<t>& img) {
10386 if (is_overlapping(img)) return *this^=+img;
10387 const unsigned int smin = cimg::min(size(),img.size());
10388 const t *ptrs = img.data + smin;
10389 for (T *ptrd = data+smin; ptrd>data; ) {
10390 T& val = *(--ptrd);
10391 val =(T)((unsigned long)val ^ (unsigned long)*(--ptrs));
10392 }
10393 return *this;
10394 }
10395
10397 CImg<T>& operator^=(const T val) {
10398 cimg_for(*this,ptr,T) *ptr = (T)((unsigned long)*ptr ^ (unsigned long)val);
10399 return *this;
10400 }
10401
10403 CImg<T> operator~() const {
10404 CImg<T> res(width,height,depth,dim);
10405 const T *ptrs = end();
10406 cimg_for(res,ptrd,T) *ptrd = (T)~(unsigned long)*(--ptrs);
10407 return res;
10408 }
10409
10411 CImg<T>& operator<<=(const int n) {
10412 cimg_for(*this,ptr,T) *ptr = (T)(((long)*ptr)<<n);
10413 return *this;
10414 }
10415
10417 CImg<T> operator<<(const int n) const {
10418 return (+*this)<<=n;
10419 }
10420
10422 CImg<T>& operator>>=(const int n) {
10423 cimg_for(*this,ptr,T) *ptr = (T)(((long)*ptr)>>n);
10424 return *this;
10425 }
10426
10428 CImg<T> operator>>(const int n) const {
10429 return (+*this)>>=n;
10430 }
10431
10433 template<typename t> bool operator==(const CImg<t>& img) const {
10434 const unsigned int siz = size();
10435 bool vequal = true;
10436 if (siz!=img.size()) return false;
10437 t *ptrs=img.data+siz;
10438 for (T *ptrd=data+siz; vequal && ptrd>data; vequal=vequal&&((*(--ptrd))==(*(--ptrs))));
10439 return vequal;
10440 }
10441
10443 template<typename t> bool operator!=(const CImg<t>& img) const {
10444 return !((*this)==img);
10445 }
10446
10448 template<typename t> CImgList<typename cimg::superset<T,t>::type> operator<<(const CImg<t>& img) const {
10449 typedef typename cimg::superset<T,t>::type restype;
10450 return CImgList<restype>(*this,img);
10451 }
10452
10454 template<typename t> CImgList<typename cimg::superset<T,t>::type> operator<<(const CImgList<t>& list) const {
10455 typedef typename cimg::superset<T,t>::type restype;
10456 return CImgList<restype>(list).insert(*this,0);
10457 }
10458
10460 template<typename t> CImgList<typename cimg::superset<T,t>::type> operator>>(const CImg<t>& img) const {
10461 return (*this)<<img;
10462 }
10463
10465 template<typename t> CImgList<t>& operator>>(const CImgList<t>& list) const {
10466 return list.insert(*this,0);
10467 }
10468
10470 const CImg<T>& operator>>(CImgDisplay& disp) const {
10471 return display(disp);
10472 }
10473
10475
10476
10478
10479
10480
10482 template<typename t> CImg<T> get_apply(t& func) const {
10483 return (+*this).apply(func);
10484 }
10485
10487 template<typename t> CImg<T>& apply(t& func) {
10488 cimg_for(*this,ptr,T) *ptr = func(*ptr);
10489 return *this;
10490 }
10491
10493 template<typename t> CImg<typename cimg::superset<T,t>::type> get_mul(const CImg<t>& img) const {
10494 typedef typename cimg::superset<T,t>::type restype;
10495 return CImg<restype>(*this,false).mul(img);
10496 }
10497
10499 template<typename t> CImg<T>& mul(const CImg<t>& img) {
10500 if (is_overlapping(img)) return mul(+img);
10501 t *ptrs = img.data;
10502 T *ptrf = data + cimg::min(size(),img.size());
10503 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = (T)(*ptrd*(*(ptrs++)));
10504 return *this;
10505 }
10506
10508 template<typename t> CImg<typename cimg::superset<T,t>::type> get_div(const CImg<t>& img) const {
10509 typedef typename cimg::superset<T,t>::type restype;
10510 return CImg<restype>(*this,false).div(img);
10511 }
10512
10514 template<typename t> CImg<T>& div(const CImg<t>& img) {
10515 if (is_overlapping(img)) return div(+img);
10516 t *ptrs = img.data;
10517 T *ptrf = data + cimg::min(size(),img.size());
10518 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = (T)(*ptrd/(*(ptrs++)));
10519 return *this;
10520 }
10521
10523 template<typename t> CImg<typename cimg::superset<T,t>::type> get_max(const CImg<t>& img) const {
10524 typedef typename cimg::superset<T,t>::type restype;
10525 return CImg<restype>(*this,false).max(img);
10526 }
10527
10529 template<typename t> CImg<T>& max(const CImg<t>& img) {
10530 if (is_overlapping(img)) return max(+img);
10531 t *ptrs = img.data;
10532 T *ptrf = data + cimg::min(size(),img.size());
10533 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = cimg::max((T)*(ptrs++),*ptrd);
10534 return *this;
10535 }
10536
10538 CImg<T> get_max(const T val) const {
10539 return (+*this).max(val);
10540 }
10541
10543 CImg<T>& max(const T val) {
10544 cimg_for(*this,ptr,T) (*ptr) = cimg::max(*ptr,val);
10545 return *this;
10546 }
10547
10549 template<typename t> CImg<typename cimg::superset<T,t>::type> get_min(const CImg<t>& img) const {
10550 typedef typename cimg::superset<T,t>::type restype;
10551 return CImg<restype>(*this,false).min(img);
10552 }
10553
10555 template<typename t> CImg<T>& min(const CImg<t>& img) {
10556 if (is_overlapping(img)) return min(+img);
10557 t *ptrs = img.data;
10558 T *ptrf = data + cimg::min(size(),img.size());
10559 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = cimg::min((T)*(ptrs++),*ptrd);
10560 return *this;
10561 }
10562
10564 CImg<T> get_min(const T val) const {
10565 return (+*this).min(val);
10566 }
10567
10569 CImg<T>& min(const T val) {
10570 cimg_for(*this,ptr,T) (*ptr) = cimg::min(*ptr,val);
10571 return *this;
10572 }
10573
10575 CImg<typename cimg::last<T,double>::type> get_stats() const {
10576 typedef typename cimg::last<T,double>::type restype;
10577 return CImg<restype>(*this).stats();
10578 }
10579
10581 CImg<T>& stats() {
10582 if (is_empty())
10583 throw CImgInstanceException("CImg<%s>::stats() : Instance image is empty.",pixel_type());
10584 const unsigned long siz = size();
10585 const T *pm = data, *pM = pm;
10586 double S = 0, S2 = 0;
10587 T m = *pm, M = m;
10588 cimg_for(*this,ptr,T) {
10589 const T val = *ptr;
10590 const double fval = (double)val;
10591 if (val<m) { m = val; pm = ptr; }
10592 if (val>M) { M = val; pM = ptr; }
10593 S+=fval;
10594 S2+=fval*fval;
10595 }
10596 return assign(1,6).fill((T)m,(T)M,(T)(S/siz),(T)((S2-S*S/siz)/siz),(T)(pm-data),(T)(pM-data));
10597 }
10598
10600 CImg<typename cimg::superset<T,float>::type> get_sqr() const {
10601 typedef typename cimg::superset<T,float>::type restype;
10602 return CImg<restype>(*this,false).sqr();
10603 }
10604
10606 CImg<T>& sqr() {
10607 cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = (T)(val*val); };
10608 return *this;
10609 }
10610
10612 CImg<typename cimg::superset<T,float>::type> get_sqrt() const {
10613 typedef typename cimg::superset<T,float>::type restype;
10614 return CImg<restype>(*this,false).sqrt();
10615 }
10616
10618 CImg<T>& sqrt() {
10619 cimg_for(*this,ptr,T) (*ptr) = (T)std::sqrt((double)(*ptr));
10620 return *this;
10621 }
10622
10624 CImg<typename cimg::superset<T,float>::type> get_exp() const {
10625 typedef typename cimg::superset<T,float>::type restype;
10626 return CImg<restype>(*this,false).exp();
10627 }
10628
10630 CImg<T>& exp() {
10631 cimg_for(*this,ptr,T) (*ptr) = (T)std::exp((double)(*ptr));
10632 return *this;
10633 }
10634
10636 CImg<typename cimg::superset<T,float>::type> get_log() const {
10637 typedef typename cimg::superset<T,float>::type restype;
10638 return CImg<restype>(*this,false).log();
10639 }
10640
10642 CImg<T>& log() {
10643 cimg_for(*this,ptr,T) (*ptr) = (T)std::log((double)(*ptr));
10644 return *this;
10645 }
10646
10648 CImg<typename cimg::superset<T,float>::type> get_log10() const {
10649 typedef typename cimg::superset<T,float>::type restype;
10650 return CImg<restype>(*this,false).log10();
10651 }
10652
10654 CImg<T>& log10() {
10655 cimg_for(*this,ptr,T) (*ptr) = (T)std::log10((double)(*ptr));
10656 return *this;
10657 }
10658
10660 CImg<typename cimg::superset<T,float>::type> get_pow(const double p) const {
10661 typedef typename cimg::superset<T,float>::type restype;
10662 return CImg<restype>(*this,false).pow(p);
10663 }
10664
10666 CImg<T>& pow(const double p) {
10667 if (p==0) return fill(1);
10668 if (p==0.5) { cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = (T)std::sqrt((double)val); } return *this; }
10669 if (p==1) return *this;
10670 if (p==2) { cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = val*val; } return *this; }
10671 if (p==3) { cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = val*val*val; } return *this; }
10672 if (p==4) { cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = val*val*val*val; } return *this; }
10673 cimg_for(*this,ptr,T) (*ptr) = (T)std::pow((double)(*ptr),p);
10674 return *this;
10675 }
10676
10678 template<typename t> CImg<typename cimg::superset<T,float>::type> get_pow(const CImg<t>& img) const {
10679 typedef typename cimg::superset<T,float>::type restype;
10680 return CImg<restype>(*this,false).pow(img);
10681 }
10682
10684 template<typename t> CImg<T>& pow(const CImg<t>& img) {
10685 if (is_overlapping(img)) return pow(+img);
10686 t *ptrs = img.data;
10687 T *ptrf = data + cimg::min(size(),img.size());
10688 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = (T)std::pow((double)*ptrd,(double)(*(ptrs++)));
10689 return *this;
10690 }
10691
10693 CImg<typename cimg::superset<T,float>::type> get_abs() const {
10694 typedef typename cimg::superset<T,float>::type restype;
10695 return CImg<restype>(*this,false).abs();
10696 }
10697
10699 CImg<T>& abs() {
10700 cimg_for(*this,ptr,T) (*ptr) = cimg::abs(*ptr);
10701 return *this;
10702 }
10703
10705 CImg<typename cimg::superset<T,float>::type> get_cos() const {
10706 typedef typename cimg::superset<T,float>::type restype;
10707 return CImg<restype>(*this,false).cos();
10708 }
10709
10711 CImg<T>& cos() {
10712 cimg_for(*this,ptr,T) (*ptr) = (T)std::cos((double)(*ptr));
10713 return *this;
10714 }
10715
10717 CImg<typename cimg::superset<T,float>::type> get_sin() const {
10718 typedef typename cimg::superset<T,float>::type restype;
10719 return CImg<restype>(*this,false).sin();
10720 }
10721
10723 CImg<T>& sin() {
10724 cimg_for(*this,ptr,T) (*ptr) = (T)std::sin((double)(*ptr));
10725 return *this;
10726 }
10727
10729 CImg<typename cimg::superset<T,float>::type> get_tan() const {
10730 typedef typename cimg::superset<T,float>::type restype;
10731 return CImg<restype>(*this,false).tan();
10732 }
10733
10735 CImg<T>& tan() {
10736 cimg_for(*this,ptr,T) (*ptr) = (T)std::tan((double)(*ptr));
10737 return *this;
10738 }
10739
10741 CImg<typename cimg::superset<T,float>::type> get_acos() const {
10742 typedef typename cimg::superset<T,float>::type restype;
10743 return CImg<restype>(*this,false).acos();
10744 }
10745
10747 CImg<T>& acos() {
10748 cimg_for(*this,ptr,T) (*ptr) = (T)std::acos((double)(*ptr));
10749 return *this;
10750 }
10751
10753 CImg<typename cimg::superset<T,float>::type> get_asin() const {
10754 typedef typename cimg::superset<T,float>::type restype;
10755 return CImg<restype>(*this,false).asin();
10756 }
10757
10759 CImg<T>& asin() {
10760 cimg_for(*this,ptr,T) (*ptr) = (T)std::asin((double)(*ptr));
10761 return *this;
10762 }
10763
10765 CImg<typename cimg::superset<T,float>::type> get_atan() const {
10766 typedef typename cimg::superset<T,float>::type restype;
10767 return CImg<restype>(*this,false).atan();
10768 }
10769
10771 CImg<T>& atan() {
10772 cimg_for(*this,ptr,T) (*ptr) = (T)std::atan((double)(*ptr));
10773 return *this;
10774 }
10775
10777
10781 CImg<T> get_round(const float x, const unsigned int round_type=0) const {
10782 return (+*this).round(x,round_type);
10783 }
10784
10786 CImg<T>& round(const float x, const unsigned int round_type=0) {
10787 cimg_for(*this,ptr,T) (*ptr) = (T)cimg::round(*ptr,x,round_type);
10788 return *this;
10789 }
10790
10792 CImg<T> get_rand(const T val_min, const T val_max) const {
10793 return (+*this).rand(val_min,val_max);
10794 }
10795
10797 CImg<T>& rand(const T val_min, const T val_max) {
10798 const float delta = (float)val_max - (float)val_min;
10799 cimg_for(*this,ptr,T) *ptr = (T)(val_min + cimg::rand()*delta);
10800 return *this;
10801 }
10802
10804
10805
10807
10808
10809
10811
10816 CImg<T> get_fill(const T val) const {
10817 return CImg<T>(width,height,depth,dim).fill(val);
10818 }
10819
10821 CImg<T>& fill(const T val) {
10822 if (!is_empty()) {
10823 if (val && sizeof(T)!=1) cimg_for(*this,ptr,T) *ptr = val;
10824 else std::memset(data,(int)val,size()*sizeof(T));
10825 }
10826 return *this;
10827 }
10828
10830 CImg<T> get_fill(const T val0, const T val1) const {
10831 return CImg<T>(width,height,depth,dim).fill(val0,val1);
10832 }
10833
10835 CImg<T>& fill(const T val0, const T val1) {
10836 if (!is_empty()) {
10837 T *ptr, *ptr_end = end()-1;
10838 for (ptr=data; ptr<ptr_end; ) { *(ptr++) = val0; *(ptr++) = val1; }
10839 if (ptr!=ptr_end+1) *(ptr++) = val0;
10840 }
10841 return *this;
10842 }
10843
10845 CImg<T> get_fill(const T val0, const T val1, const T val2) const {
10846 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2);
10847 }
10848
10850 CImg<T>& fill(const T val0, const T val1, const T val2) {
10851 if (!is_empty()) {
10852 T *ptr, *ptr_end = end()-2;
10853 for (ptr=data; ptr<ptr_end; ) { *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; }
10854 ptr_end+=2;
10855 switch (ptr_end-ptr) {
10856 case 2: *(--ptr_end) = val1;
10857 case 1: *(--ptr_end) = val0;
10858 }
10859 }
10860 return *this;
10861 }
10862
10864 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3) const {
10865 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3);
10866 }
10867
10869 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3) {
10870 if (!is_empty()) {
10871 T *ptr, *ptr_end = end()-3;
10872 for (ptr=data; ptr<ptr_end; ) { *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; }
10873 ptr_end+=3;
10874 switch (ptr_end-ptr) {
10875 case 3: *(--ptr_end) = val2;
10876 case 2: *(--ptr_end) = val1;
10877 case 1: *(--ptr_end) = val0;
10878 }
10879 }
10880 return *this;
10881 }
10882
10884 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4) const {
10885 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4);
10886 }
10887
10889 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4) {
10890 if (!is_empty()) {
10891 T *ptr, *ptr_end = end()-4;
10892 for (ptr=data; ptr<ptr_end; ) { *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; }
10893 ptr_end+=4;
10894 switch (ptr_end-ptr) {
10895 case 4: *(--ptr_end) = val3;
10896 case 3: *(--ptr_end) = val2;
10897 case 2: *(--ptr_end) = val1;
10898 case 1: *(--ptr_end) = val0;
10899 }
10900 }
10901 return *this;
10902 }
10903
10905 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5) const {
10906 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5);
10907 }
10908
10910 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5) {
10911 if (!is_empty()) {
10912 T *ptr, *ptr_end = end()-5;
10913 for (ptr=data; ptr<ptr_end; ) {
10914 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
10915 }
10916 ptr_end+=5;
10917 switch (ptr_end-ptr) {
10918 case 5: *(--ptr_end) = val4;
10919 case 4: *(--ptr_end) = val3;
10920 case 3: *(--ptr_end) = val2;
10921 case 2: *(--ptr_end) = val1;
10922 case 1: *(--ptr_end) = val0;
10923 }
10924 }
10925 return *this;
10926 }
10927
10929 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6) const {
10930 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6);
10931 }
10932
10934 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6) {
10935 if (!is_empty()) {
10936 T *ptr, *ptr_end = end()-6;
10937 for (ptr=data; ptr<ptr_end; ) {
10938 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5; *(ptr++) = val6;
10939 }
10940 ptr_end+=6;
10941 switch (ptr_end-ptr) {
10942 case 6: *(--ptr_end) = val5;
10943 case 5: *(--ptr_end) = val4;
10944 case 4: *(--ptr_end) = val3;
10945 case 3: *(--ptr_end) = val2;
10946 case 2: *(--ptr_end) = val1;
10947 case 1: *(--ptr_end) = val0;
10948 }
10949 }
10950 return *this;
10951 }
10952
10954 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
10955 const T val7) const {
10956 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7);
10957 }
10958
10960 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
10961 const T val7) {
10962 if (!is_empty()) {
10963 T *ptr, *ptr_end = end()-7;
10964 for (ptr=data; ptr<ptr_end; ) {
10965 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3;
10966 *(ptr++) = val4; *(ptr++) = val5; *(ptr++) = val6; *(ptr++) = val7;
10967 }
10968 ptr_end+=7;
10969 switch (ptr_end-ptr) {
10970 case 7: *(--ptr_end) = val6;
10971 case 6: *(--ptr_end) = val5;
10972 case 5: *(--ptr_end) = val4;
10973 case 4: *(--ptr_end) = val3;
10974 case 3: *(--ptr_end) = val2;
10975 case 2: *(--ptr_end) = val1;
10976 case 1: *(--ptr_end) = val0;
10977 }
10978 }
10979 return *this;
10980 }
10981
10983 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
10984 const T val7, const T val8) const {
10985 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8);
10986 }
10987
10989 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
10990 const T val7, const T val8) {
10991 if (!is_empty()) {
10992 T *ptr, *ptr_end = end()-8;
10993 for (ptr=data; ptr<ptr_end; ) {
10994 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2;
10995 *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
10996 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8;
10997 }
10998 ptr_end+=8;
10999 switch (ptr_end-ptr) {
11000 case 8: *(--ptr_end) = val7;
11001 case 7: *(--ptr_end) = val6;
11002 case 6: *(--ptr_end) = val5;
11003 case 5: *(--ptr_end) = val4;
11004 case 4: *(--ptr_end) = val3;
11005 case 3: *(--ptr_end) = val2;
11006 case 2: *(--ptr_end) = val1;
11007 case 1: *(--ptr_end) = val0;
11008 }
11009 }
11010 return *this;
11011 }
11012
11014 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11015 const T val7, const T val8, const T val9) const {
11016 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9);
11017 }
11018
11020 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11021 const T val7, const T val8, const T val9) {
11022 if (!is_empty()) {
11023 T *ptr, *ptr_end = end()-9;
11024 for (ptr=data; ptr<ptr_end; ) {
11025 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4;
11026 *(ptr++) = val5; *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9;
11027 }
11028 ptr_end+=9;
11029 switch (ptr_end-ptr) {
11030 case 9: *(--ptr_end) = val8;
11031 case 8: *(--ptr_end) = val7;
11032 case 7: *(--ptr_end) = val6;
11033 case 6: *(--ptr_end) = val5;
11034 case 5: *(--ptr_end) = val4;
11035 case 4: *(--ptr_end) = val3;
11036 case 3: *(--ptr_end) = val2;
11037 case 2: *(--ptr_end) = val1;
11038 case 1: *(--ptr_end) = val0;
11039 }
11040 }
11041 return *this;
11042 }
11043
11045 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11046 const T val7, const T val8, const T val9, const T val10) const {
11047 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10);
11048 }
11049
11051 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11052 const T val7, const T val8, const T val9, const T val10) {
11053 if (!is_empty()) {
11054 T *ptr, *ptr_end = end()-10;
11055 for (ptr=data; ptr<ptr_end; ) {
11056 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4;
11057 *(ptr++) = val5; *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9;
11058 *(ptr++) = val10;
11059 }
11060 ptr_end+=10;
11061 switch (ptr_end-ptr) {
11062 case 10: *(--ptr_end) = val9;
11063 case 9: *(--ptr_end) = val8;
11064 case 8: *(--ptr_end) = val7;
11065 case 7: *(--ptr_end) = val6;
11066 case 6: *(--ptr_end) = val5;
11067 case 5: *(--ptr_end) = val4;
11068 case 4: *(--ptr_end) = val3;
11069 case 3: *(--ptr_end) = val2;
11070 case 2: *(--ptr_end) = val1;
11071 case 1: *(--ptr_end) = val0;
11072 }
11073 }
11074 return *this;
11075 }
11076
11078 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11079 const T val7, const T val8, const T val9, const T val10, const T val11) const {
11080 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11);
11081 }
11082
11084 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11085 const T val7, const T val8, const T val9, const T val10, const T val11) {
11086 if (!is_empty()) {
11087 T *ptr, *ptr_end = end()-11;
11088 for (ptr=data; ptr<ptr_end; ) {
11089 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11090 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11091 }
11092 ptr_end+=11;
11093 switch (ptr_end-ptr) {
11094 case 11: *(--ptr_end) = val10;
11095 case 10: *(--ptr_end) = val9;
11096 case 9: *(--ptr_end) = val8;
11097 case 8: *(--ptr_end) = val7;
11098 case 7: *(--ptr_end) = val6;
11099 case 6: *(--ptr_end) = val5;
11100 case 5: *(--ptr_end) = val4;
11101 case 4: *(--ptr_end) = val3;
11102 case 3: *(--ptr_end) = val2;
11103 case 2: *(--ptr_end) = val1;
11104 case 1: *(--ptr_end) = val0;
11105 }
11106 }
11107 return *this;
11108 }
11109
11111 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11112 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12) const {
11113 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12);
11114 }
11115
11117 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11118 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12) {
11119 if (!is_empty()) {
11120 T *ptr, *ptr_end = end()-12;
11121 for (ptr=data; ptr<ptr_end; ) {
11122 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11123 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11124 *(ptr++) = val12;
11125 }
11126 ptr_end+=12;
11127 switch (ptr_end-ptr) {
11128 case 12: *(--ptr_end) = val11;
11129 case 11: *(--ptr_end) = val10;
11130 case 10: *(--ptr_end) = val9;
11131 case 9: *(--ptr_end) = val8;
11132 case 8: *(--ptr_end) = val7;
11133 case 7: *(--ptr_end) = val6;
11134 case 6: *(--ptr_end) = val5;
11135 case 5: *(--ptr_end) = val4;
11136 case 4: *(--ptr_end) = val3;
11137 case 3: *(--ptr_end) = val2;
11138 case 2: *(--ptr_end) = val1;
11139 case 1: *(--ptr_end) = val0;
11140 }
11141 }
11142 return *this;
11143 }
11144
11146 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11147 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11148 const T val13) const {
11149 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13);
11150 }
11151
11153 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11154 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11155 const T val13) {
11156 if (!is_empty()) {
11157 T *ptr, *ptr_end = end()-13;
11158 for (ptr=data; ptr<ptr_end; ) {
11159 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11160 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11161 *(ptr++) = val12; *(ptr++) = val13;
11162 }
11163 ptr_end+=13;
11164 switch (ptr_end-ptr) {
11165 case 13: *(--ptr_end) = val12;
11166 case 12: *(--ptr_end) = val11;
11167 case 11: *(--ptr_end) = val10;
11168 case 10: *(--ptr_end) = val9;
11169 case 9: *(--ptr_end) = val8;
11170 case 8: *(--ptr_end) = val7;
11171 case 7: *(--ptr_end) = val6;
11172 case 6: *(--ptr_end) = val5;
11173 case 5: *(--ptr_end) = val4;
11174 case 4: *(--ptr_end) = val3;
11175 case 3: *(--ptr_end) = val2;
11176 case 2: *(--ptr_end) = val1;
11177 case 1: *(--ptr_end) = val0;
11178 }
11179 }
11180 return *this;
11181 }
11182
11184 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11185 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11186 const T val13, const T val14) const {
11187 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14);
11188 }
11189
11191 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11192 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11193 const T val13, const T val14) {
11194 if (!is_empty()) {
11195 T *ptr, *ptr_end = end()-14;
11196 for (ptr=data; ptr<ptr_end; ) {
11197 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11198 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11199 *(ptr++) = val12; *(ptr++) = val13; *(ptr++) = val14;
11200 }
11201 ptr_end+=14;
11202 switch (ptr_end-ptr) {
11203 case 14: *(--ptr_end) = val13;
11204 case 13: *(--ptr_end) = val12;
11205 case 12: *(--ptr_end) = val11;
11206 case 11: *(--ptr_end) = val10;
11207 case 10: *(--ptr_end) = val9;
11208 case 9: *(--ptr_end) = val8;
11209 case 8: *(--ptr_end) = val7;
11210 case 7: *(--ptr_end) = val6;
11211 case 6: *(--ptr_end) = val5;
11212 case 5: *(--ptr_end) = val4;
11213 case 4: *(--ptr_end) = val3;
11214 case 3: *(--ptr_end) = val2;
11215 case 2: *(--ptr_end) = val1;
11216 case 1: *(--ptr_end) = val0;
11217 }
11218 }
11219 return *this;
11220 }
11221
11223 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11224 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11225 const T val13, const T val14, const T val15) const {
11226 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14,val15);
11227 }
11228
11230 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11231 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11232 const T val13, const T val14, const T val15) {
11233 if (!is_empty()) {
11234 T *ptr, *ptr_end = end()-15;
11235 for (ptr=data; ptr<ptr_end; ) {
11236 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11237 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11238 *(ptr++) = val12; *(ptr++) = val13; *(ptr++) = val14; *(ptr++) = val15;
11239 }
11240 ptr_end+=15;
11241 switch (ptr_end-ptr) {
11242 case 15: *(--ptr_end) = val14;
11243 case 14: *(--ptr_end) = val13;
11244 case 13: *(--ptr_end) = val12;
11245 case 12: *(--ptr_end) = val11;
11246 case 11: *(--ptr_end) = val10;
11247 case 10: *(--ptr_end) = val9;
11248 case 9: *(--ptr_end) = val8;
11249 case 8: *(--ptr_end) = val7;
11250 case 7: *(--ptr_end) = val6;
11251 case 6: *(--ptr_end) = val5;
11252 case 5: *(--ptr_end) = val4;
11253 case 4: *(--ptr_end) = val3;
11254 case 3: *(--ptr_end) = val2;
11255 case 2: *(--ptr_end) = val1;
11256 case 1: *(--ptr_end) = val0;
11257 }
11258 }
11259 return *this;
11260 }
11261
11263 template<int N> CImg<T> get_fill(const int val0, ...) const {
11264 CImg<T> res(*this,false);
11265 va_list ap;
11266 va_start(ap,val0);
11267 res._fill<N,int>(val0,ap);
11268 va_end(ap);
11269 return res;
11270 }
11271
11273 template<int N> CImg<T>& fill(const int val0, ...) {
11274 va_list ap;
11275 va_start(ap,val0);
11276 _fill<N,int>(val0,ap);
11277 va_end(ap);
11278 return *this;
11279 }
11280
11282 template<int N> CImg<T> get_fill(const double val0, ...) const {
11283 CImg<T> res(*this,false);
11284 va_list ap;
11285 va_start(ap,val0);
11286 res._fill<N,double>(val0,ap);
11287 va_end(ap);
11288 return res;
11289 }
11290
11292 template<int N> CImg<T>& fill(const double val0, ...) {
11293 va_list ap;
11294 va_start(ap,val0);
11295 _fill<N,double>(val0,ap);
11296 va_end(ap);
11297 return *this;
11298 }
11299
11300 template<int N, typename t> CImg<T>& _fill(const t val0, va_list &ap) {
11301 if (N>0 && !is_empty()) {
11302 CImg<T> vals(N);
11303 T *ptrs = vals.data;
11304 *(ptrs++) = (T)val0;
11305 for (int i=1; i<N; ++i) *(ptrs++) = (T)va_arg(ap,t);
11306 ptrs-=N;
11307 T *ptr, *ptr_end = end()+1-N;
11308 for (ptr=data; ptr<ptr_end; ) { ptrs = vals.data; for (int i=0; i<N; ++i) *(ptr++) = *(ptrs++); }
11309 ptr_end+=N-1;
11310 ptrs = vals.data;
11311 for (int i = ptr_end-ptr; i>0; --i) *(ptr++) = *(ptrs++);
11312 }
11313 return *this;
11314 }
11315
11317 CImg<T>& fillV(const unsigned int x, const unsigned int y, const unsigned int z, const int a0, ...) {
11318
11319 #define _cimg_fillv(x,y,z,a0,t) if (x<width && y<height && z<depth) { \
11320 va_list ap; va_start(ap,a0); \
11321 const unsigned int whz = width*height*depth; \
11322 T *ptrd = ptr(x,y,z,0); *ptrd = (T)a0; \
11323 for (unsigned int k=1; k<dim; ++k) { ptrd+=whz; *ptrd = (T)va_arg(ap,t); } \
11324 va_end(ap); }
11325 _cimg_fillv(x,y,z,a0,int);
11326 return *this;
11327 }
11328
11330 CImg<T>& fillV(const unsigned int x, const unsigned int y, const unsigned int z, const double a0, ...) {
11331 _cimg_fillv(x,y,z,a0,double);
11332 return *this;
11333 }
11334
11336 CImg<T>& fillZV(const unsigned int x, const unsigned int y, const int a0, ...) {
11337
11338 #define _cimg_fillzv(x,y,a0,t) if (x<width && y<height) { \
11339 va_list ap; va_start(ap,a0); \
11340 const unsigned int wh = width*height, zd = depth*dim; \
11341 T *ptrd = ptr(x,y,0,0); *ptrd = (T)a0; \
11342 for (unsigned int k=1; k<zd; ++k) { ptrd+=wh; *ptrd = (T)va_arg(ap,t); } \
11343 va_end(ap); }
11344 _cimg_fillzv(x,y,a0,int);
11345 return *this;
11346 }
11347
11349 CImg<T>& fillZV(const unsigned int x, const unsigned int y, const double a0, ...) {
11350 _cimg_fillzv(x,y,a0,double);
11351 return *this;
11352 }
11353
11355 CImg<T>& fillYZV(const unsigned int x, const int a0, ...) {
11356 #define _cimg_fillyzv(x,a0,t) if (x<width) { \
11357 va_list ap; va_start(ap,a0); \
11358 const unsigned int hzd = height*depth*dim; \
11359 T *ptrd = ptr(x,0,0,0); *ptrd = (T)a0; \
11360 for (unsigned int k=1; k<hzd; ++k) { ptrd+=width; *ptrd = (T)va_arg(ap,t); } \
11361 va_end(ap); \
11362 }
11363 _cimg_fillyzv(x,a0,int);
11364 return *this;
11365 }
11366
11368 CImg<T>& fillYZV(const unsigned int x, const double a0, ...) {
11369 _cimg_fillyzv(x,a0,double);
11370 return *this;
11371 }
11372
11374
11378 CImg<T> get_normalize(const T a, const T b) const {
11379 return (+*this).normalize(a,b);
11380 }
11381
11383 CImg<T>& normalize(const T a, const T b) {
11384 if (!is_empty()) {
11385 typedef typename cimg::superset<T,float>::type ftype;
11386 T m, M = maxmin(m);
11387 const ftype fm = (ftype)m, fM = (ftype)M;
11388 if (m==M) return fill(0);
11389 if (m!=a || M!=b) cimg_for(*this,ptr,T) *ptr = (T)((*ptr-fm)/(fM-fm)*(b-a)+a);
11390 }
11391 return *this;
11392 }
11393
11395
11399 CImg<T> get_cut(const T a, const T b) const {
11400 return (+*this).cut(a,b);
11401 }
11402
11404 CImg<T>& cut(const T a, const T b) {
11405 if (!is_empty())
11406 cimg_for(*this,ptr,T) *ptr = (*ptr<a)?a:((*ptr>b)?b:*ptr);
11407 return *this;
11408 }
11409
11411
11415 CImg<T> get_quantize(const unsigned int n=256, const bool keep_range=true) const {
11416 return (+*this).quantize(n,keep_range);
11417 }
11418
11420 CImg<T>& quantize(const unsigned int n=256, const bool keep_range=true) {
11421 if (!is_empty()) {
11422 if (!n) throw CImgArgumentException("CImg<%s>::quantize() : Cannot quantize image to 0 values.",
11423 pixel_type());
11424 typedef typename cimg::superset<T,float>::type ftype;
11425 ftype m, M = (ftype)maxmin(m), range = M - m;
11426 if (range>0) {
11427 if (keep_range) cimg_for(*this,ptr,T) {
11428 const unsigned int val = (unsigned int)((*ptr-m)*n/range);
11429 *ptr = (T)(m + cimg::min(val,n-1)*range/n);
11430 } else cimg_for(*this,ptr,T) {
11431 const unsigned int val = (unsigned int)((*ptr-m)*n/range);
11432 *ptr = (T)cimg::min(val,n-1);
11433 }
11434 }
11435 }
11436 return *this;
11437 }
11438
11440
11443 CImg<T> get_threshold(const T thres) const {
11444 return (+*this).threshold(thres);
11445 }
11446
11448 CImg<T>& threshold(const T thres) {
11449 if (!is_empty()) cimg_for(*this,ptr,T) *ptr = *ptr<=thres?(T)0:(T)1;
11450 return *this;
11451 }
11452
11454
11462 CImg<T> get_rotate(const float angle, const unsigned int cond=3) const {
11463 if (is_empty()) return CImg<T>();
11464 CImg<T> dest;
11465 const float nangle = cimg::mod(angle,360.0f), rad = (float)((nangle*cimg::PI)/180.0),
11466 ca=(float)std::cos(rad), sa=(float)std::sin(rad);
11467 if (cond!=1 && cimg::mod(nangle,90.0f)==0) {
11468 const int wm1 = dimx()-1, hm1 = dimy()-1;
11469 const int iangle = (int)nangle/90;
11470 switch (iangle) {
11471 case 1: {
11472 dest.assign(height,width,depth,dim);
11473 cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(y,hm1-x,z,v);
11474 } break;
11475 case 2: {
11476 dest.assign(width,height,depth,dim);
11477 cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(wm1-x,hm1-y,z,v);
11478 } break;
11479 case 3: {
11480 dest.assign(height,width,depth,dim);
11481 cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(wm1-y,x,z,v);
11482 } break;
11483 default:
11484 return *this;
11485 }
11486 } else {
11487 const float
11488 ux = (float)(cimg::abs(width*ca)), uy = (float)(cimg::abs(width*sa)),
11489 vx = (float)(cimg::abs(height*sa)), vy = (float)(cimg::abs(height*ca)),
11490 w2 = 0.5f*width, h2 = 0.5f*height,
11491 dw2 = 0.5f*(ux+vx), dh2 = 0.5f*(uy+vy);
11492 dest.assign((int)(ux+vx), (int)(uy+vy),depth,dim);
11493 switch (cond) {
11494 case 0: {
11495 cimg_forXY(dest,x,y)
11496 cimg_forZV(*this,z,v)
11497 dest(x,y,z,v) = pix2d((int)(w2 + (x-dw2)*ca + (y-dh2)*sa),(int)(h2 - (x-dw2)*sa + (y-dh2)*ca),z,v,0);
11498 } break;
11499 case 1: {
11500 cimg_forXY(dest,x,y)
11501 cimg_forZV(*this,z,v)
11502 dest(x,y,z,v) = (*this)(cimg::mod((int)(w2 + (x-dw2)*ca + (y-dh2)*sa),dimx()),
11503 cimg::mod((int)(h2 - (x-dw2)*sa + (y-dh2)*ca),dimy()),z,v);
11504 } break;
11505 case 2: {
11506 cimg_forXY(dest,x,y) {
11507 const float X = w2 + (x-dw2)*ca + (y-dh2)*sa, Y = h2 - (x-dw2)*sa + (y-dh2)*ca;
11508 cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)linear_pix2d(X,Y,z,v,0);
11509 }
11510 } break;
11511 default: {
11512 cimg_forXY(dest,x,y) {
11513 const float X = w2 + (x-dw2)*ca + (y-dh2)*sa, Y = h2 - (x-dw2)*sa + (y-dh2)*ca;
11514 cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)cubic_pix2d(X,Y,z,v,0);
11515 }
11516 } break;
11517 }
11518 }
11519 return dest;
11520 }
11521
11523 CImg<T>& rotate(const float angle, const unsigned int cond=3) {
11524 return get_rotate(angle,cond).assign_to(*this);
11525 }
11526
11528
11539 CImg<T> get_rotate(const float angle, const float cx, const float cy, const float zoom=1, const unsigned int cond=3) const {
11540 if (is_empty()) return CImg<T>();
11541 CImg<T> dest(width,height,depth,dim);
11542 const float nangle = cimg::mod(angle,360.0f), rad = (float)((nangle*cimg::PI)/180.0),
11543 ca=(float)std::cos(rad)/zoom, sa=(float)std::sin(rad)/zoom;
11544 if (cond!=1 && zoom==1 && cimg::mod(nangle,90.0f)==0) {
11545 const int iangle = (int)nangle/90;
11546 switch (iangle) {
11547 case 1: {
11548 dest.fill(0);
11549 const unsigned int
11550 xmin = cimg::max(0,(dimx()-dimy())/2), xmax = cimg::min(width,xmin+height),
11551 ymin = cimg::max(0,(dimy()-dimx())/2), ymax = cimg::min(height,ymin+width),
11552 xoff = xmin + cimg::min(0,(dimx()-dimy())/2),
11553 yoff = ymin + cimg::min(0,(dimy()-dimx())/2);
11554 cimg_forZV(dest,z,v) for (unsigned int y=ymin; y<ymax; ++y) for (unsigned int x=xmin; x<xmax; ++x)
11555 dest(x,y,z,v) = (*this)(y-yoff,height-1-x+xoff,z,v);
11556 } break;
11557 case 2: {
11558 cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(width-1-x,height-1-y,z,v);
11559 } break;
11560 case 3: {
11561 dest.fill(0);
11562 const unsigned int
11563 xmin = cimg::max(0,(dimx()-dimy())/2), xmax = cimg::min(width,xmin+height),
11564 ymin = cimg::max(0,(dimy()-dimx())/2), ymax = cimg::min(height,ymin+width),
11565 xoff = xmin + cimg::min(0,(dimx()-dimy())/2),
11566 yoff = ymin + cimg::min(0,(dimy()-dimx())/2);
11567 cimg_forZV(dest,z,v) for (unsigned int y=ymin; y<ymax; ++y) for (unsigned int x=xmin; x<xmax; ++x)
11568 dest(x,y,z,v) = (*this)(width-1-y+yoff,x-xoff,z,v);
11569 } break;
11570 default:
11571 return *this;
11572 }
11573 } else
11574 switch (cond) {
11575 case 0: {
11576 cimg_forXY(dest,x,y)
11577 cimg_forZV(*this,z,v)
11578 dest(x,y,z,v) = pix2d((int)(cx + (x-cx)*ca + (y-cy)*sa),(int)(cy - (x-cx)*sa + (y-cy)*ca),z,v,0);
11579 } break;
11580 case 1: {
11581 cimg_forXY(dest,x,y)
11582 cimg_forZV(*this,z,v)
11583 dest(x,y,z,v) = (*this)(cimg::mod((int)(cx + (x-cx)*ca + (y-cy)*sa),dimx()),
11584 cimg::mod((int)(cy - (x-cx)*sa + (y-cy)*ca),dimy()),z,v);
11585 } break;
11586 case 2: {
11587 cimg_forXY(dest,x,y) {
11588 const float X = cx + (x-cx)*ca + (y-cy)*sa, Y = cy - (x-cx)*sa + (y-cy)*ca;
11589 cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)linear_pix2d(X,Y,z,v,0);
11590 }
11591 } break;
11592 default: {
11593 cimg_forXY(dest,x,y) {
11594 const float X = cx + (x-cx)*ca + (y-cy)*sa, Y = cy - (x-cx)*sa + (y-cy)*ca;
11595 cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)cubic_pix2d(X,Y,z,v,0);
11596 }
11597 } break;
11598 }
11599 return dest;
11600 }
11601
11603 CImg<T>& rotate(const float angle, const float cx, const float cy, const float zoom=1, const unsigned int cond=3) {
11604 return get_rotate(angle,cx,cy,zoom,cond).assign_to(*this);
11605 }
11606
11608
11625 CImg<T> get_resize(const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100,
11626 const int interp=1, const int border_condition=-1, const bool center=false) const {
11627 if (!pdx || !pdy || !pdz || !pdv) return CImg<T>();
11628 const unsigned int
11629 tdx = pdx<0?-pdx*width/100:pdx,
11630 tdy = pdy<0?-pdy*height/100:pdy,
11631 tdz = pdz<0?-pdz*depth/100:pdz,
11632 tdv = pdv<0?-pdv*dim/100:pdv,
11633 dx = tdx?tdx:1,
11634 dy = tdy?tdy:1,
11635 dz = tdz?tdz:1,
11636 dv = tdv?tdv:1;
11637 if (width==dx && height==dy && depth==dz && dim==dv) return *this;
11638 if (is_empty()) return CImg<T>(dx,dy,dz,dv,0);
11639
11640 CImg<T> res;
11641
11642 switch (interp) {
11643 case -1:
11644 std::memcpy(res.assign(dx,dy,dz,dv,0).data,data,sizeof(T)*cimg::min(size(),(long unsigned int)dx*dy*dz*dv));
11645 break;
11646
11647 case 0: {
11648 const unsigned int bx = width-1, by = height-1, bz = depth-1, bv = dim-1;
11649 res.assign(dx,dy,dz,dv);
11650 switch (border_condition) {
11651 case 1: {
11652 if (center) {
11653 const int
11654 x0 = (res.dimx()-dimx())/2,
11655 y0 = (res.dimy()-dimy())/2,
11656 z0 = (res.dimz()-dimz())/2,
11657 v0 = (res.dimv()-dimv())/2,
11658 x1 = x0 + (int)bx,
11659 y1 = y0 + (int)by,
11660 z1 = z0 + (int)bz,
11661 v1 = v0 + (int)bv;
11662 res.draw_image(*this,x0,y0,z0,v0);
11663 cimg_for_outXYZV(res,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) res(x,y,z,v) = pix4d(x-x0,y-y0,z-z0,v-v0);
11664 } else {
11665 res.draw_image(*this,0,0,0,0);
11666 cimg_for_outXYZV(res,0,0,0,0,bx,by,bz,bv,x,y,z,v) res(x,y,z,v) = pix4d(x,y,z,v);
11667 }
11668 } break;
11669 case 2 : {
11670 const int
11671 x0 = (res.dimx()-dimx())/2,
11672 y0 = (res.dimy()-dimy())/2,
11673 z0 = (res.dimz()-dimz())/2,
11674 v0 = (res.dimv()-dimv())/2,
11675 nx0 = x0>0?x0-(1+x0/width)*width:x0,
11676 ny0 = y0>0?y0-(1+y0/height)*height:y0,
11677 nz0 = z0>0?z0-(1+z0/depth)*depth:z0,
11678 nv0 = v0>0?v0-(1+v0/dim)*dim:v0;
11679 for (int k=nv0; k<(int)dv; k+=dimv())
11680 for (int z=nz0; z<(int)dz; z+=dimz())
11681 for (int y=ny0; y<(int)dy; y+=dimy())
11682 for (int x=nx0; x<(int)dx; x+=dimx()) res.draw_image(*this,x,y,z,k);
11683 } break;
11684 default: {
11685 res.fill(0);
11686 if (center) res.draw_image(*this,(res.dimx()-dimx())/2,(res.dimy()-dimy())/2,(res.dimz()-dimz())/2,(res.dimv()-dimv())/2);
11687 else res.draw_image(*this,0,0,0,0);
11688 } break;
11689 }
11690 } break;
11691
11692 case 1: {
11693 res.assign(dx,dy,dz,dv);
11694 unsigned int
11695 *const offx = new unsigned int[dx],
11696 *const offy = new unsigned int[dy+1],
11697 *const offz = new unsigned int[dz+1],
11698 *const offv = new unsigned int[dv+1],
11699 *poffx, *poffy, *poffz, *poffv,
11700 curr, old;
11701 const unsigned int wh = width*height, whd = width*height*depth, rwh = dx*dy, rwhd = dx*dy*dz;
11702 poffx = offx; curr = 0; { cimg_forX(res,x) { old=curr; curr=(x+1)*width/dx; *(poffx++) = (unsigned int)curr-(unsigned int)old; }}
11703 poffy = offy; curr = 0; { cimg_forY(res,y) { old=curr; curr=(y+1)*height/dy; *(poffy++) = width*((unsigned int)curr-(unsigned int)old); }} *poffy=0;
11704 poffz = offz; curr = 0; { cimg_forZ(res,z) { old=curr; curr=(z+1)*depth/dz; *(poffz++) = wh*((unsigned int)curr-(unsigned int)old); }} *poffz=0;
11705 poffv = offv; curr = 0; { cimg_forV(res,k) { old=curr; curr=(k+1)*dim/dv; *(poffv++) = whd*((unsigned int)curr-(unsigned int)old); }} *poffv=0;
11706 T *ptrd = res.data;
11707 const T* ptrv = data;
11708 poffv = offv;
11709 for (unsigned int k=0; k<dv; ) {
11710 const T *ptrz = ptrv;
11711 poffz = offz;
11712 for (unsigned int z=0; z<dz; ) {
11713 const T *ptry = ptrz;
11714 poffy = offy;
11715 for (unsigned int y=0; y<dy; ) {
11716 const T *ptrx = ptry;
11717 poffx = offx;
11718 cimg_forX(res,x) { *(ptrd++) = *ptrx; ptrx+=*(poffx++); }
11719 ++y;
11720 unsigned int dy = *(poffy++);
11721 for (;!dy && y<dy; std::memcpy(ptrd, ptrd-dx, sizeof(T)*dx), ++y, ptrd+=dx, dy=*(poffy++));
11722 ptry+=dy;
11723 }
11724 ++z;
11725 unsigned int dz = *(poffz++);
11726 for (;!dz && z<dz; std::memcpy(ptrd, ptrd-rwh, sizeof(T)*rwh), ++z, ptrd+=rwh, dz=*(poffz++));
11727 ptrz+=dz;
11728 }
11729 ++k;
11730 unsigned int dv = *(poffv++);
11731 for (;!dv && k<dv; std::memcpy(ptrd, ptrd-rwhd, sizeof(T)*rwhd), ++k, ptrd+=rwhd, dv=*(poffv++));
11732 ptrv+=dv;
11733 }
11734 delete[] offx; delete[] offy; delete[] offz; delete[] offv;
11735 } break;
11736
11737 case 2: {
11738 typedef typename cimg::superset<T,float>::type ftype;
11739 bool instance_first = true;
11740 if (dx!=width) {
11741 CImg<ftype> tmp(dx,height,depth,dim,0);
11742 for (unsigned int a=width*dx, b=width, c=dx, s=0, t=0; a; ) {
11743 const unsigned int d = cimg::min(b,c);
11744 a-=d; b-=d; c-=d;
11745 cimg_forYZV(tmp,y,z,v) tmp(t,y,z,v)+=(ftype)(*this)(s,y,z,v)*d;
11746 if (!b) { cimg_forYZV(tmp,y,z,v) tmp(t,y,z,v)/=width; ++t; b = width; }
11747 if (!c) { ++s; c = dx; }
11748 }
11749 tmp.assign_to(res);
11750 instance_first = false;
11751 }
11752 if (dy!=height) {
11753 CImg<ftype> tmp(dx,dy,depth,dim,0);
11754 for (unsigned int a=height*dy, b=height, c=dy, s=0, t=0; a; ) {
11755 const unsigned int d = cimg::min(b,c);
11756 a-=d; b-=d; c-=d;
11757 if (instance_first) cimg_forXZV(tmp,x,z,v) tmp(x,t,z,v)+=(ftype)(*this)(x,s,z,v)*d;
11758 else cimg_forXZV(tmp,x,z,v) tmp(x,t,z,v)+=(ftype)res(x,s,z,v)*d;
11759 if (!b) { cimg_forXZV(tmp,x,z,v) tmp(x,t,z,v)/=height; ++t; b = height; }
11760 if (!c) { ++s; c = dy; }
11761 }
11762 tmp.assign_to(res);
11763 instance_first = false;
11764 }
11765 if (dz!=depth) {
11766 CImg<ftype> tmp(dx,dy,dz,dim,0);
11767 for (unsigned int a=depth*dz, b=depth, c=dz, s=0, t=0; a; ) {
11768 const unsigned int d = cimg::min(b,c);
11769 a-=d; b-=d; c-=d;
11770 if (instance_first) cimg_forXYV(tmp,x,y,v) tmp(x,y,t,v)+=(ftype)(*this)(x,y,s,v)*d;
11771 else cimg_forXYV(tmp,x,y,v) tmp(x,y,t,v)+=(ftype)res(x,y,s,v)*d;
11772 if (!b) { cimg_forXYV(tmp,x,y,v) tmp(x,y,t,v)/=depth; ++t; b = depth; }
11773 if (!c) { ++s; c = dz; }
11774 }
11775 tmp.assign_to(res);
11776 instance_first = false;
11777 }
11778 if (dv!=dim) {
11779 CImg<ftype> tmp(dx,dy,dz,dv,0);
11780 for (unsigned int a=dim*dv, b=dim, c=dv, s=0, t=0; a; ) {
11781 const unsigned int d = cimg::min(b,c);
11782 a-=d; b-=d; c-=d;
11783 if (instance_first) cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)+=(ftype)(*this)(x,y,z,s)*d;
11784 else cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)+=(ftype)res(x,y,z,s)*d;
11785 if (!b) { cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)/=dim; ++t; b = dim; }
11786 if (!c) { ++s; c = dv; }
11787 }
11788 tmp.assign_to(res);
11789 instance_first = false;
11790 }
11791 } break;
11792
11793 case 3: {
11794 const unsigned int dimmax = cimg::max(dx,dy,dz,dv);
11795 const float
11796 sx = (border_condition<0 && dx>width )?(dx>1?(width-1.0f)/(dx-1) :0):(float)width/dx,
11797 sy = (border_condition<0 && dy>height)?(dy>1?(height-1.0f)/(dy-1):0):(float)height/dy,
11798 sz = (border_condition<0 && dz>depth )?(dz>1?(depth-1.0f)/(dz-1) :0):(float)depth/dz,
11799 sv = (border_condition<0 && dv>dim )?(dv>1?(dim-1.0f)/(dv-1) :0):(float)dim/dv;
11800
11801 unsigned int *const off = new unsigned int[dimmax], *poff;
11802 float *const foff = new float[dimmax], *pfoff, old, curr;
11803 CImg<T> resx, resy, resz, resv;
11804 T *ptrd;
11805
11806 if (dx!=width) {
11807 if (width==1) resx = get_resize(dx,height,depth,dim,1,0);
11808 else {
11809 resx.assign(dx,height,depth,dim);
11810 curr = old = 0; poff = off; pfoff = foff;
11811 cimg_forX(resx,x) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sx; *(poff++) = (unsigned int)curr-(unsigned int)old; }
11812 ptrd = resx.data;
11813 const T *ptrs0 = data;
11814 cimg_forYZV(resx,y,z,k) {
11815 poff = off; pfoff = foff;
11816 const T *ptrs = ptrs0, *const ptrsmax = ptrs0 + (width-1);
11817 cimg_forX(resx,x) {
11818 const float alpha = *(pfoff++);
11819 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+1):(border_condition?val1:0);
11820 *(ptrd++) = (T)((1-alpha)*val1 + alpha*val2);
11821 ptrs+=*(poff++);
11822 }
11823 ptrs0+=width;
11824 }
11825 }
11826 } else resx.assign(*this,true);
11827
11828 if (dy!=height) {
11829 if (height==1) resy = resx.get_resize(dx,dy,depth,dim,1,0);
11830 else {
11831 resy.assign(dx,dy,depth,dim);
11832 curr = old = 0; poff = off; pfoff = foff;
11833 cimg_forY(resy,y) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sy; *(poff++) = dx*((unsigned int)curr-(unsigned int)old); }
11834 cimg_forXZV(resy,x,z,k) {
11835 ptrd = resy.ptr(x,0,z,k);
11836 const T *ptrs = resx.ptr(x,0,z,k), *const ptrsmax = ptrs + (height-1)*dx;
11837 poff = off; pfoff = foff;
11838 cimg_forY(resy,y) {
11839 const float alpha = *(pfoff++);
11840 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+dx):(border_condition?val1:0);
11841 *ptrd = (T)((1-alpha)*val1 + alpha*val2);
11842 ptrd+=dx;
11843 ptrs+=*(poff++);
11844 }
11845 }
11846 }
11847 resx.assign();
11848 } else resy.assign(resx,true);
11849
11850 if (dz!=depth) {
11851 if (depth==1) resz = resy.get_resize(dx,dy,dz,dim,1,0);
11852 else {
11853 const unsigned int wh = dx*dy;
11854 resz.assign(dx,dy,dz,dim);
11855 curr = old = 0; poff = off; pfoff = foff;
11856 cimg_forZ(resz,z) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sz; *(poff++) = wh*((unsigned int)curr-(unsigned int)old); }
11857 cimg_forXYV(resz,x,y,k) {
11858 ptrd = resz.ptr(x,y,0,k);
11859 const T *ptrs = resy.ptr(x,y,0,k), *const ptrsmax = ptrs + (depth-1)*wh;
11860 poff = off; pfoff = foff;
11861 cimg_forZ(resz,z) {
11862 const float alpha = *(pfoff++);
11863 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+wh):(border_condition?val1:0);
11864 *ptrd = (T)((1-alpha)*val1 + alpha*val2);
11865 ptrd+=wh;
11866 ptrs+=*(poff++);
11867 }
11868 }
11869 }
11870 resy.assign();
11871 } else resz.assign(resy,true);
11872
11873 if (dv!=dim) {
11874 if (dim==1) resv = resz.get_resize(dx,dy,dz,dv,1,0);
11875 else {
11876 const unsigned int whd = dx*dy*dz;
11877 resv.assign(dx,dy,dz,dv);
11878 curr = old = 0; poff = off; pfoff = foff;
11879 cimg_forV(resv,k) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sv; *(poff++) = whd*((unsigned int)curr-(unsigned int)old); }
11880 cimg_forXYZ(resv,x,y,z) {
11881 ptrd = resv.ptr(x,y,z,0);
11882 const T *ptrs = resz.ptr(x,y,z,0), *const ptrsmax = ptrs + (dim-1)*whd;
11883 poff = off; pfoff = foff;
11884 cimg_forV(resv,k) {
11885 const float alpha = *(pfoff++);
11886 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+whd):(border_condition?val1:0);
11887 *ptrd = (T)((1-alpha)*val1 + alpha*val2);
11888 ptrd+=whd;
11889 ptrs+=*(poff++);
11890 }
11891 }
11892 }
11893 resz.assign();
11894 } else resv.assign(resz,true);
11895
11896 delete[] off; delete[] foff;
11897 return resv.is_shared?(resz.is_shared?(resy.is_shared?(resx.is_shared?(+(*this)):resx):resy):resz):resv;
11898 } break;
11899
11900 case 4: {
11901 res.assign(dx,dy,dz,dv,0);
11902 cimg_forXYZV(*this,x,y,z,k) res(x*dx/width,y*dy/height,z*dz/depth,k*dv/dim) = (*this)(x,y,z,k);
11903 } break;
11904
11905 case 5: {
11906 typedef typename cimg::superset<T,float>::type ftype;
11907 const float
11908 sx = (border_condition<0 && dx>width )?(dx>1?(width-1.0f)/(dx-1) :0):(float)width/dx,
11909 sy = (border_condition<0 && dy>height)?(dy>1?(height-1.0f)/(dy-1):0):(float)height/dy,
11910 sz = (border_condition<0 && dz>depth )?(dz>1?(depth-1.0f)/(dz-1) :0):(float)depth/dz,
11911 sv = (border_condition<0 && dv>dim )?(dv>1?(dim-1.0f)/(dv-1) :0):(float)dim/dv;
11912 res.assign(dx,dy,dz,dv);
11913 T *ptrd = res.ptr();
11914 float cx, cy, cz, ck = 0;
11915 cimg_forV(res,k) { cz = 0;
11916 cimg_forZ(res,z) { cy = 0;
11917 cimg_forY(res,y) { cx = 0;
11918 cimg_forX(res,x) {
11919 *(ptrd++) = (T)(border_condition?cubic_pix2d(cx,cy,(int)cz,(int)ck):cubic_pix2d(cx,cy,(int)cz,(int)ck,0));
11920 cx+=sx;
11921 } cy+=sy;
11922 } cz+=sz;
11923 } ck+=sv;
11924 }
11925 } break;
11926
11927 default:
11928 throw CImgArgumentException("CImg<%s>::resize() : Invalid interpolation method : %d specified.",
11929 pixel_type(),interp);
11930 }
11931 return res;
11932 }
11933
11935 CImg<T>& resize(const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100,
11936 const int interp=1, const int border_condition=-1, const bool center=false) {
11937 if (!pdx || !pdy || !pdz || !pdv) return assign();
11938 const unsigned int
11939 dx = pdx<0?-pdx*width/100:pdx,
11940 dy = pdy<0?-pdy*height/100:pdy,
11941 dz = pdz<0?-pdz*depth/100:pdz,
11942 dv = pdv<0?-pdv*dim/100:pdv;
11943 if (width==dx && height==dy && depth==dz && dim==dv) return *this;
11944 if (interp==-1 && dx*dy*dz*dv==size()) {
11945 width = dx; height = dy; depth = dz; dim = dv;
11946 return *this;
11947 }
11948 return get_resize(dx,dy,dz,dv,interp,border_condition,center).assign_to(*this);
11949 }
11950
11952
11965 template<typename t> CImg<T> get_resize(const CImg<t>& src, const int interp=1,
11966 const int border_condition=-1, const bool center=false) const {
11967 return get_resize(src.width,src.height,src.depth,src.dim,interp,border_condition,center);
11968 }
11969
11971 template<typename t> CImg<T>& resize(const CImg<t>& src, const int interp=1,
11972 const int border_condition=-1, const bool center=false) {
11973 return resize(src.width,src.height,src.depth,src.dim,interp,border_condition,center);
11974 }
11975
11977
11990 CImg<T> get_resize(const CImgDisplay& disp, const int interp=1,
11991 const int border_condition=-1, const bool center=false) const {
11992 return get_resize(disp.width,disp.height,depth,dim,interp,border_condition,center);
11993 }
11994
11996 CImg<T>& resize(const CImgDisplay& disp, const int interp=1,
11997 const int border_condition=-1, const bool center=false) {
11998 return resize(disp.width,disp.height,depth,dim,interp,border_condition,center);
11999 }
12000
12002
12006 CImg<T> get_permute_axes(const char *permut="vxyz") const {
12007 if (is_empty() || !permut) return (+*this);
12008 CImg<T> res;
12009 const T* ptr = data;
12010 if (!cimg::strncasecmp(permut,"xyzv",4)) return (+*this);
12011 if (!cimg::strncasecmp(permut,"xyvz",4)) { res.assign(width,height,dim,depth); cimg_forXYZV(*this,x,y,z,v) res(x,y,v,z) = *(ptr++); return res; }
12012 if (!cimg::strncasecmp(permut,"xzyv",4)) { res.assign(width,depth,height,dim); cimg_forXYZV(*this,x,y,z,v) res(x,z,y,v) = *(ptr++); return res; }
12013 if (!cimg::strncasecmp(permut,"xzvy",4)) { res.assign(width,depth,dim,height); cimg_forXYZV(*this,x,y,z,v) res(x,z,v,y) = *(ptr++); return res; }
12014 if (!cimg::strncasecmp(permut,"xvyz",4)) { res.assign(width,dim,height,depth); cimg_forXYZV(*this,x,y,z,v) res(x,v,y,z) = *(ptr++); return res; }
12015 if (!cimg::strncasecmp(permut,"xvzy",4)) { res.assign(width,dim,depth,height); cimg_forXYZV(*this,x,y,z,v) res(x,v,z,y) = *(ptr++); return res; }
12016 if (!cimg::strncasecmp(permut,"yxzv",4)) { res.assign(height,width,depth,dim); cimg_forXYZV(*this,x,y,z,v) res(y,x,z,v) = *(ptr++); return res; }
12017 if (!cimg::strncasecmp(permut,"yxvz",4)) { res.assign(height,width,dim,depth); cimg_forXYZV(*this,x,y,z,v) res(y,x,v,z) = *(ptr++); return res; }
12018 if (!cimg::strncasecmp(permut,"yzxv",4)) { res.assign(height,depth,width,dim); cimg_forXYZV(*this,x,y,z,v) res(y,z,x,v) = *(ptr++); return res; }
12019 if (!cimg::strncasecmp(permut,"yzvx",4)) { res.assign(height,depth,dim,width); cimg_forXYZV(*this,x,y,z,v) res(y,z,v,x) = *(ptr++); return res; }
12020 if (!cimg::strncasecmp(permut,"yvxz",4)) { res.assign(height,dim,width,depth); cimg_forXYZV(*this,x,y,z,v) res(y,v,x,z) = *(ptr++); return res; }
12021 if (!cimg::strncasecmp(permut,"yvzx",4)) { res.assign(height,dim,depth,width); cimg_forXYZV(*this,x,y,z,v) res(y,v,z,x) = *(ptr++); return res; }
12022 if (!cimg::strncasecmp(permut,"zxyv",4)) { res.assign(depth,width,height,dim); cimg_forXYZV(*this,x,y,z,v) res(z,x,y,v) = *(ptr++); return res; }
12023 if (!cimg::strncasecmp(permut,"zxvy",4)) { res.assign(depth,width,dim,height); cimg_forXYZV(*this,x,y,z,v) res(z,x,v,y) = *(ptr++); return res; }
12024 if (!cimg::strncasecmp(permut,"zyxv",4)) { res.assign(depth,height,width,dim); cimg_forXYZV(*this,x,y,z,v) res(z,y,x,v) = *(ptr++); return res; }
12025 if (!cimg::strncasecmp(permut,"zyvx",4)) { res.assign(depth,height,dim,width); cimg_forXYZV(*this,x,y,z,v) res(z,y,v,x) = *(ptr++); return res; }
12026 if (!cimg::strncasecmp(permut,"zvxy",4)) { res.assign(depth,dim,width,height); cimg_forXYZV(*this,x,y,z,v) res(z,v,x,y) = *(ptr++); return res; }
12027 if (!cimg::strncasecmp(permut,"zvyx",4)) { res.assign(depth,dim,height,width); cimg_forXYZV(*this,x,y,z,v) res(z,v,y,x) = *(ptr++); return res; }
12028 if (!cimg::strncasecmp(permut,"vxyz",4)) { res.assign(dim,width,height,depth); cimg_forXYZV(*this,x,y,z,v) res(v,x,y,z) = *(ptr++); return res; }
12029 if (!cimg::strncasecmp(permut,"vxzy",4)) { res.assign(dim,width,depth,height); cimg_forXYZV(*this,x,y,z,v) res(v,x,z,y) = *(ptr++); return res; }
12030 if (!cimg::strncasecmp(permut,"vyxz",4)) { res.assign(dim,height,width,depth); cimg_forXYZV(*this,x,y,z,v) res(v,y,x,z) = *(ptr++); return res; }
12031 if (!cimg::strncasecmp(permut,"vyzx",4)) { res.assign(dim,height,depth,width); cimg_forXYZV(*this,x,y,z,v) res(v,y,z,x) = *(ptr++); return res; }
12032 if (!cimg::strncasecmp(permut,"vzxy",4)) { res.assign(dim,depth,width,height); cimg_forXYZV(*this,x,y,z,v) res(v,z,x,y) = *(ptr++); return res; }
12033 if (!cimg::strncasecmp(permut,"vzyx",4)) { res.assign(dim,depth,height,width); cimg_forXYZV(*this,x,y,z,v) res(v,z,y,x) = *(ptr++); return res; }
12034 throw CImgArgumentException("CImg<%s>::permute_axes() : Invalid input permutation '%s'.",pixel_type(),permut);
12035 return res;
12036 }
12037
12039 CImg<T>& permute_axes(const char *order="vxyz") {
12040 return get_permute_axes(order).assign_to(*this);
12041 }
12042
12044 CImg<T> get_resize_halfXY() const {
12045 typedef typename cimg::superset<T,float>::type ftype;
12046 if (is_empty()) return CImg<T>();
12047 const ftype mask[9] = { 0.07842776544f, 0.1231940459f, 0.07842776544f,
12048 0.1231940459f, 0.1935127547f, 0.1231940459f,
12049 0.07842776544f, 0.1231940459f, 0.07842776544f };
12050 ftype I[9] = { 0 };
12051 CImg<T> dest(width/2,height/2,depth,dim);
12052 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I)
12053 if (x%2 && y%2) dest(x/2,y/2,z,k) = (T)
12054 (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] +
12055 I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] +
12056 I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]);
12057 return dest;
12058 }
12059
12061 CImg<T>& resize_halfXY() {
12062 return get_resize_halfXY().assign_to(*this);
12063 }
12064
12066 CImg<T> get_mirror(const char axe='x') const {
12067 return (+*this).mirror(axe);
12068 }
12069
12071 CImg<T>& mirror(const char axe='x') {
12072 if (!is_empty()) {
12073 T *pf, *pb, *buf = 0;
12074 switch (cimg::uncase(axe)) {
12075 case 'x': {
12076 pf = data; pb = ptr(width-1);
12077 for (unsigned int yzv=0; yzv<height*depth*dim; ++yzv) {
12078 for (unsigned int x=0; x<width/2; ++x) { const T val = *pf; *(pf++) = *pb; *(pb--) = val; }
12079 pf+=width-width/2;
12080 pb+=width+width/2;
12081 }
12082 } break;
12083 case 'y': {
12084 buf = new T[width];
12085 pf = data; pb = ptr(0,height-1);
12086 for (unsigned int zv=0; zv<depth*dim; ++zv) {
12087 for (unsigned int y=0; y<height/2; ++y) {
12088 std::memcpy(buf,pf,width*sizeof(T));
12089 std::memcpy(pf,pb,width*sizeof(T));
12090 std::memcpy(pb,buf,width*sizeof(T));
12091 pf+=width;
12092 pb-=width;
12093 }
12094 pf+=width*(height-height/2);
12095 pb+=width*(height+height/2);
12096 }
12097 } break;
12098 case 'z': {
12099 buf = new T[width*height];
12100 pf = data; pb = ptr(0,0,depth-1);
12101 cimg_forV(*this,v) {
12102 for (unsigned int z=0; z<depth/2; ++z) {
12103 std::memcpy(buf,pf,width*height*sizeof(T));
12104 std::memcpy(pf,pb,width*height*sizeof(T));
12105 std::memcpy(pb,buf,width*height*sizeof(T));
12106 pf+=width*height;
12107 pb-=width*height;
12108 }
12109 pf+=width*height*(depth-depth/2);
12110 pb+=width*height*(depth+depth/2);
12111 }
12112 } break;
12113 case 'v': {
12114 buf = new T[width*height*depth];
12115 pf = data; pb = ptr(0,0,0,dim-1);
12116 for (unsigned int v=0; v<dim/2; ++v) {
12117 std::memcpy(buf,pf,width*height*depth*sizeof(T));
12118 std::memcpy(pf,pb,width*height*depth*sizeof(T));
12119 std::memcpy(pb,buf,width*height*depth*sizeof(T));
12120 pf+=width*height*depth;
12121 pb-=width*height*depth;
12122 }
12123 } break;
12124 default:
12125 throw CImgArgumentException("CImg<%s>::mirror() : unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe);
12126 }
12127 if (buf) delete[] buf;
12128 }
12129 return *this;
12130 }
12131
12133
12145 CImg<T> get_translate(const int deltax, const int deltay=0, const int deltaz=0, const int deltav=0,
12146 const int border_condition=0) const {
12147 return (+*this).translate(deltax,deltay,deltaz,deltav,border_condition);
12148 }
12149
12151 CImg<T>& translate(const int deltax, const int deltay=0, const int deltaz=0, const int deltav=0,
12152 const int border_condition=0) {
12153 if (!is_empty()) {
12154
12155 if (deltax)
12156 switch (border_condition) {
12157 case 0:
12158 if (cimg::abs(deltax)>=dimx()) return fill(0);
12159 if (deltax>0) cimg_forYZV(*this,y,z,k) {
12160 std::memmove(ptr(0,y,z,k),ptr(deltax,y,z,k),(width-deltax)*sizeof(T));
12161 std::memset(ptr(width-deltax,y,z,k),0,deltax*sizeof(T));
12162 } else cimg_forYZV(*this,y,z,k) {
12163 std::memmove(ptr(-deltax,y,z,k),ptr(0,y,z,k),(width+deltax)*sizeof(T));
12164 std::memset(ptr(0,y,z,k),0,-deltax*sizeof(T));
12165 }
12166 break;
12167 case 1:
12168 if (deltax>0) {
12169 const int ndeltax = (deltax>=dimx())?width-1:deltax;
12170 if (!ndeltax) return *this;
12171 cimg_forYZV(*this,y,z,k) {
12172 std::memmove(ptr(0,y,z,k),ptr(ndeltax,y,z,k),(width-ndeltax)*sizeof(T));
12173 T *ptrd = ptr(width-1,y,z,k);
12174 const T val = *ptrd;
12175 for (int l=0; l<ndeltax-1; ++l) *(--ptrd) = val;
12176 }
12177 } else {
12178 const int ndeltax = (-deltax>=dimx())?width-1:-deltax;
12179 if (!ndeltax) return *this;
12180 cimg_forYZV(*this,y,z,k) {
12181 std::memmove(ptr(ndeltax,y,z,k),ptr(0,y,z,k),(width-ndeltax)*sizeof(T));
12182 T *ptrd = ptr(0,y,z,k);
12183 const T val = *ptrd;
12184 for (int l=0; l<ndeltax-1; ++l) *(++ptrd) = val;
12185 }
12186 }
12187 break;
12188 case 2: {
12189 const int ml = cimg::mod(deltax,dimx()), ndeltax = (ml<=dimx()/2)?ml:(ml-dimx());
12190 if (!ndeltax) return *this;
12191 T* buf = new T[cimg::abs(ndeltax)];
12192 if (ndeltax>0) cimg_forYZV(*this,y,z,k) {
12193 std::memcpy(buf,ptr(0,y,z,k),ndeltax*sizeof(T));
12194 std::memmove(ptr(0,y,z,k),ptr(ndeltax,y,z,k),(width-ndeltax)*sizeof(T));
12195 std::memcpy(ptr(width-ndeltax,y,z,k),buf,ndeltax*sizeof(T));
12196 } else cimg_forYZV(*this,y,z,k) {
12197 std::memcpy(buf,ptr(width+ndeltax,y,z,k),-ndeltax*sizeof(T));
12198 std::memmove(ptr(-ndeltax,y,z,k),ptr(0,y,z,k),(width+ndeltax)*sizeof(T));
12199 std::memcpy(ptr(0,y,z,k),buf,-ndeltax*sizeof(T));
12200 }
12201 delete[] buf;
12202 } break;
12203 }
12204
12205 if (deltay)
12206 switch (border_condition) {
12207 case 0:
12208 if (cimg::abs(deltay)>=dimy()) return fill(0);
12209 if (deltay>0) cimg_forZV(*this,z,k) {
12210 std::memmove(ptr(0,0,z,k),ptr(0,deltay,z,k),width*(height-deltay)*sizeof(T));
12211 std::memset(ptr(0,height-deltay,z,k),0,width*deltay*sizeof(T));
12212 } else cimg_forZV(*this,z,k) {
12213 std::memmove(ptr(0,-deltay,z,k),ptr(0,0,z,k),width*(height+deltay)*sizeof(T));
12214 std::memset(ptr(0,0,z,k),0,-deltay*width*sizeof(T));
12215 }
12216 break;
12217 case 1:
12218 if (deltay>0) {
12219 const int ndeltay = (deltay>=dimy())?height-1:deltay;
12220 if (!ndeltay) return *this;
12221 cimg_forZV(*this,z,k) {
12222 std::memmove(ptr(0,0,z,k),ptr(0,ndeltay,z,k),width*(height-ndeltay)*sizeof(T));
12223 T *ptrd = ptr(0,height-ndeltay,z,k), *ptrs = ptr(0,height-1,z,k);
12224 for (int l=0; l<ndeltay-1; ++l) { std::memcpy(ptrd,ptrs,width*sizeof(T)); ptrd+=width; }
12225 }
12226 } else {
12227 const int ndeltay = (-deltay>=dimy())?height-1:-deltay;
12228 if (!ndeltay) return *this;
12229 cimg_forZV(*this,z,k) {
12230 std::memmove(ptr(0,ndeltay,z,k),ptr(0,0,z,k),width*(height-ndeltay)*sizeof(T));
12231 T *ptrd = ptr(0,1,z,k), *ptrs = ptr(0,0,z,k);
12232 for (int l=0; l<ndeltay-1; ++l) { std::memcpy(ptrd,ptrs,width*sizeof(T)); ptrd+=width; }
12233 }
12234 }
12235 break;
12236 case 2: {
12237 const int ml = cimg::mod(deltay,dimy()), ndeltay = (ml<=dimy()/2)?ml:(ml-dimy());
12238 if (!ndeltay) return *this;
12239 T* buf = new T[width*cimg::abs(ndeltay)];
12240 if (ndeltay>0) cimg_forZV(*this,z,k) {
12241 std::memcpy(buf,ptr(0,0,z,k),width*ndeltay*sizeof(T));
12242 std::memmove(ptr(0,0,z,k),ptr(0,ndeltay,z,k),width*(height-ndeltay)*sizeof(T));
12243 std::memcpy(ptr(0,height-ndeltay,z,k),buf,width*ndeltay*sizeof(T));
12244 } else cimg_forZV(*this,z,k) {
12245 std::memcpy(buf,ptr(0,height+ndeltay,z,k),-ndeltay*width*sizeof(T));
12246 std::memmove(ptr(0,-ndeltay,z,k),ptr(0,0,z,k),width*(height+ndeltay)*sizeof(T));
12247 std::memcpy(ptr(0,0,z,k),buf,-ndeltay*width*sizeof(T));
12248 }
12249 delete[] buf;
12250 } break;
12251 }
12252
12253 if (deltaz)
12254 switch (border_condition) {
12255 case 0:
12256 if (cimg::abs(deltaz)>=dimz()) return fill(0);
12257 if (deltaz>0) cimg_forV(*this,k) {
12258 std::memmove(ptr(0,0,0,k),ptr(0,0,deltaz,k),width*height*(depth-deltaz)*sizeof(T));
12259 std::memset(ptr(0,0,depth-deltaz,k),0,width*height*deltaz*sizeof(T));
12260 } else cimg_forV(*this,k) {
12261 std::memmove(ptr(0,0,-deltaz,k),ptr(0,0,0,k),width*height*(depth+deltaz)*sizeof(T));
12262 std::memset(ptr(0,0,0,k),0,-deltaz*width*height*sizeof(T));
12263 }
12264 break;
12265 case 1:
12266 if (deltaz>0) {
12267 const int ndeltaz = (deltaz>=dimz())?depth-1:deltaz;
12268 if (!ndeltaz) return *this;
12269 cimg_forV(*this,k) {
12270 std::memmove(ptr(0,0,0,k),ptr(0,0,ndeltaz,k),width*height*(depth-ndeltaz)*sizeof(T));
12271 T *ptrd = ptr(0,0,depth-ndeltaz,k), *ptrs = ptr(0,0,depth-1,k);
12272 for (int l=0; l<ndeltaz-1; ++l) { std::memcpy(ptrd,ptrs,width*height*sizeof(T)); ptrd+=width*height; }
12273 }
12274 } else {
12275 const int ndeltaz = (-deltaz>=dimz())?depth-1:-deltaz;
12276 if (!ndeltaz) return *this;
12277 cimg_forV(*this,k) {
12278 std::memmove(ptr(0,0,ndeltaz,k),ptr(0,0,0,k),width*height*(depth-ndeltaz)*sizeof(T));
12279 T *ptrd = ptr(0,0,1,k), *ptrs = ptr(0,0,0,k);
12280 for (int l=0; l<ndeltaz-1; ++l) { std::memcpy(ptrd,ptrs,width*height*sizeof(T)); ptrd+=width*height; }
12281 }
12282 }
12283 break;
12284 case 2: {
12285 const int ml = cimg::mod(deltaz,dimz()), ndeltaz = (ml<=dimz()/2)?ml:(ml-dimz());
12286 if (!ndeltaz) return *this;
12287 T* buf = new T[width*height*cimg::abs(ndeltaz)];
12288 if (ndeltaz>0) cimg_forV(*this,k) {
12289 std::memcpy(buf,ptr(0,0,0,k),width*height*ndeltaz*sizeof(T));
12290 std::memmove(ptr(0,0,0,k),ptr(0,0,ndeltaz,k),width*height*(depth-ndeltaz)*sizeof(T));
12291 std::memcpy(ptr(0,0,depth-ndeltaz,k),buf,width*height*ndeltaz*sizeof(T));
12292 } else cimg_forV(*this,k) {
12293 std::memcpy(buf,ptr(0,0,depth+ndeltaz,k),-ndeltaz*width*height*sizeof(T));
12294 std::memmove(ptr(0,0,-ndeltaz,k),ptr(0,0,0,k),width*height*(depth+ndeltaz)*sizeof(T));
12295 std::memcpy(ptr(0,0,0,k),buf,-ndeltaz*width*height*sizeof(T));
12296 }
12297 delete[] buf;
12298 } break;
12299 }
12300
12301 if (deltav)
12302 switch (border_condition) {
12303 case 0:
12304 if (cimg::abs(deltav)>=dimv()) return fill(0);
12305 if (deltav>0) {
12306 std::memmove(data,ptr(0,0,0,deltav),width*height*depth*(dim-deltav)*sizeof(T));
12307 std::memset(ptr(0,0,0,dim-deltav),0,width*height*depth*deltav*sizeof(T));
12308 } else cimg_forV(*this,k) {
12309 std::memmove(ptr(0,0,0,-deltav),data,width*height*depth*(dim+deltav)*sizeof(T));
12310 std::memset(data,0,-deltav*width*height*depth*sizeof(T));
12311 }
12312 break;
12313 case 1:
12314 if (deltav>0) {
12315 const int ndeltav = (deltav>=dimv())?dim-1:deltav;
12316 if (!ndeltav) return *this;
12317 std::memmove(data,ptr(0,0,0,ndeltav),width*height*depth*(dim-ndeltav)*sizeof(T));
12318 T *ptrd = ptr(0,0,0,dim-ndeltav), *ptrs = ptr(0,0,0,dim-1);
12319 for (int l=0; l<ndeltav-1; ++l) { std::memcpy(ptrd,ptrs,width*height*depth*sizeof(T)); ptrd+=width*height*depth; }
12320 } else {
12321 const int ndeltav = (-deltav>=dimv())?dim-1:-deltav;
12322 if (!ndeltav) return *this;
12323 std::memmove(ptr(0,0,0,ndeltav),data,width*height*depth*(dim-ndeltav)*sizeof(T));
12324 T *ptrd = ptr(0,0,0,1);
12325 for (int l=0; l<ndeltav-1; ++l) { std::memcpy(ptrd,data,width*height*depth*sizeof(T)); ptrd+=width*height*depth; }
12326 }
12327 break;
12328 case 2: {
12329 const int ml = cimg::mod(deltav,dimv()), ndeltav = (ml<=dimv()/2)?ml:(ml-dimv());
12330 if (!ndeltav) return *this;
12331 T* buf = new T[width*height*depth*cimg::abs(ndeltav)];
12332 if (ndeltav>0) {
12333 std::memcpy(buf,data,width*height*depth*ndeltav*sizeof(T));
12334 std::memmove(data,ptr(0,0,0,ndeltav),width*height*depth*(dim-ndeltav)*sizeof(T));
12335 std::memcpy(ptr(0,0,0,dim-ndeltav),buf,width*height*depth*ndeltav*sizeof(T));
12336 } else {
12337 std::memcpy(buf,ptr(0,0,0,dim+ndeltav),-ndeltav*width*height*depth*sizeof(T));
12338 std::memmove(ptr(0,0,0,-ndeltav),data,width*height*depth*(dim+ndeltav)*sizeof(T));
12339 std::memcpy(data,buf,-ndeltav*width*height*depth*sizeof(T));
12340 }
12341 delete[] buf;
12342 } break;
12343 }
12344 }
12345 return *this;
12346 }
12347
12349
12360 CImg<T> get_crop(const int x0, const int y0, const int z0, const int v0,
12361 const int x1, const int y1, const int z1, const int v1,
12362 const bool border_condition=false) const {
12363 if (is_empty()) return *this;
12364 const int
12365 nx0 = x0<x1?x0:x1, nx1 = x0^x1^nx0,
12366 ny0 = y0<y1?y0:y1, ny1 = y0^y1^ny0,
12367 nz0 = z0<z1?z0:z1, nz1 = z0^z1^nz0,
12368 nv0 = v0<v1?v0:v1, nv1 = v0^v1^nv0;
12369 CImg<T> dest(1U+nx1-nx0,1U+ny1-ny0,1U+nz1-nz0,1U+nv1-nv0);
12370 if (nx0<0 || nx1>=dimx() || ny0<0 || ny1>=dimy() || nz0<0 || nz1>=dimz() || nv0<0 || nv1>=dimv()) {
12371 if (border_condition) cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = pix4d(nx0+x,ny0+y,nz0+z,nv0+v);
12372 else dest.fill(0).draw_image(*this,-nx0,-ny0,-nz0,-nv0);
12373 } else dest.draw_image(*this,-nx0,-ny0,-nz0,-nv0);
12374 return dest;
12375 }
12376
12378 CImg<T>& crop(const int x0, const int y0, const int z0, const int v0,
12379 const int x1, const int y1, const int z1, const int v1,
12380 const bool border_condition=false) {
12381 return get_crop(x0,y0,z0,v0,x1,y1,z1,v1,border_condition).assign_to(*this);
12382 }
12383
12385
12395 CImg<T> get_crop(const int x0, const int y0, const int z0,
12396 const int x1, const int y1, const int z1,
12397 const bool border_condition=false) const {
12398 return get_crop(x0,y0,z0,0,x1,y1,z1,dim-1,border_condition);
12399 }
12400
12402 CImg<T>& crop(const int x0, const int y0, const int z0,
12403 const int x1, const int y1, const int z1,
12404 const bool border_condition=false) {
12405 return crop(x0,y0,z0,0,x1,y1,z1,dim-1,border_condition);
12406 }
12407
12409
12417 CImg<T> get_crop(const int x0, const int y0,
12418 const int x1, const int y1,
12419 const bool border_condition=false) const {
12420 return get_crop(x0,y0,0,0,x1,y1,depth-1,dim-1,border_condition);
12421 }
12422
12424 CImg<T>& crop(const int x0, const int y0,
12425 const int x1, const int y1,
12426 const bool border_condition=false) {
12427 return crop(x0,y0,0,0,x1,y1,depth-1,dim-1,border_condition);
12428 }
12429
12431
12437 CImg<T> get_crop(const int x0, const int x1, const bool border_condition=false) const {
12438 return get_crop(x0,0,0,0,x1,height-1,depth-1,dim-1,border_condition);
12439 }
12440
12442 CImg<T>& crop(const int x0, const int x1, const bool border_condition=false) {
12443 return crop(x0,0,0,0,x1,height-1,depth-1,dim-1,border_condition);
12444 }
12445
12447 CImg<T> get_columns(const unsigned int x0, const unsigned int x1) const {
12448 return get_crop((int)x0,0,0,0,(int)x1,dimy()-1,dimz()-1,dimv()-1);
12449 }
12450
12452 CImg<T>& columns(const unsigned int x0, const unsigned int x1) {
12453 return get_columns(x0,x1).assign_to(*this);
12454 }
12455
12457 CImg<T> get_column(const unsigned int x0) const {
12458 return get_columns(x0,x0);
12459 }
12460
12462 CImg<T>& column(const unsigned int x0) {
12463 return columns(x0,x0);
12464 }
12465
12467 CImg<T> get_lines(const unsigned int y0, const unsigned int y1) const {
12468 return get_crop(0,(int)y0,0,0,dimx()-1,(int)y1,dimz()-1,dimv()-1);
12469 }
12470
12472 CImg<T>& lines(const unsigned int y0, const unsigned int y1) {
12473 return get_lines(y0,y1).assign_to(*this);
12474 }
12475
12477 CImg<T> get_line(const unsigned int y0) const {
12478 return get_lines(y0,y0);
12479 }
12480
12482 CImg<T>& line(const unsigned int y0) {
12483 return lines(y0,y0);
12484 }
12485
12487 CImg<T> get_slices(const unsigned int z0, const unsigned int z1) const {
12488 return get_crop(0,0,(int)z0,0,dimx()-1,dimy()-1,(int)z1,dimv()-1);
12489 }
12490
12492 CImg<T>& slices(const unsigned int z0, const unsigned int z1) {
12493 return get_slices(z0,z1).assign_to(*this);
12494 }
12495
12497 CImg<T> get_slice(const unsigned int z0) const {
12498 return get_slices(z0,z0);
12499 }
12500
12502 CImg<T>& slice(const unsigned int z0) {
12503 return slices(z0,z0);
12504 }
12505
12507 CImg<T> get_channels(const unsigned int v0, const unsigned int v1) const {
12508 return get_crop(0,0,0,(int)v0,dimx()-1,dimy()-1,dimz()-1,(int)v1);
12509 }
12510
12512 CImg<T>& channels(const unsigned int v0, const unsigned int v1) {
12513 return get_channels(v0,v1).assign_to(*this);
12514 }
12515
12517 CImg<T> get_channel(const unsigned int v0) const {
12518 return get_channels(v0,v0);
12519 }
12520
12522 CImg<T>& channel(const unsigned int v0) {
12523 return channels(v0,v0);
12524 }
12525
12527 CImg<T> get_shared_points(const unsigned int x0, const unsigned int x1,
12528 const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) {
12529 const unsigned long beg = offset(x0,y0,z0,v0), end = offset(x1,y0,z0,v0);
12530 if (beg>end || beg>=size() || end>=size())
12531 throw CImgArgumentException("CImg<%s>::get_shared_points() : Cannot return a shared-memory subset (%u->%u,%u,%u,%u) from "
12532 "a (%u,%u,%u,%u) image.",pixel_type(),x0,x1,y0,z0,v0,width,height,depth,dim);
12533 return CImg<T>(data+beg,x1-x0+1,1,1,1,true);
12534 }
12535
12537 const CImg<T> get_shared_points(const unsigned int x0, const unsigned int x1,
12538 const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) const {
12539 const unsigned long beg = offset(x0,y0,z0,v0), end = offset(x1,y0,z0,v0);
12540 if (beg>end || beg>=size() || end>=size())
12541 throw CImgArgumentException("CImg<%s>::get_shared_points() : Cannot return a shared-memory subset (%u->%u,%u,%u,%u) from "
12542 "a (%u,%u,%u,%u) image.",pixel_type(),x0,x1,y0,z0,v0,width,height,depth,dim);
12543 return CImg<T>(data+beg,x1-x0+1,1,1,1,true);
12544 }
12545
12547 CImg<T> get_shared_lines(const unsigned int y0, const unsigned int y1,
12548 const unsigned int z0=0, const unsigned int v0=0) {
12549 const unsigned long beg = offset(0,y0,z0,v0), end = offset(0,y1,z0,v0);
12550 if (beg>end || beg>=size() || end>=size())
12551 throw CImgArgumentException("CImg<%s>::get_shared_lines() : Cannot return a shared-memory subset (0->%u,%u->%u,%u,%u) from "
12552 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,y0,y1,z0,v0,width,height,depth,dim);
12553 return CImg<T>(data+beg,width,y1-y0+1,1,1,true);
12554 }
12555
12557 const CImg<T> get_shared_lines(const unsigned int y0, const unsigned int y1,
12558 const unsigned int z0=0, const unsigned int v0=0) const {
12559 const unsigned long beg = offset(0,y0,z0,v0), end = offset(0,y1,z0,v0);
12560 if (beg>end || beg>=size() || end>=size())
12561 throw CImgArgumentException("CImg<%s>::get_shared_lines() : Cannot return a shared-memory subset (0->%u,%u->%u,%u,%u) from "
12562 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,y0,y1,z0,v0,width,height,depth,dim);
12563 return CImg<T>(data+beg,width,y1-y0+1,1,1,true);
12564 }
12565
12567 CImg<T> get_shared_line(const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) {
12568 return get_shared_lines(y0,y0,z0,v0);
12569 }
12570
12572 const CImg<T> get_shared_line(const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) const {
12573 return get_shared_lines(y0,y0,z0,v0);
12574 }
12575
12577 CImg<T> get_shared_planes(const unsigned int z0, const unsigned int z1, const unsigned int v0=0) {
12578 const unsigned long beg = offset(0,0,z0,v0), end = offset(0,0,z1,v0);
12579 if (beg>end || beg>=size() || end>=size())
12580 throw CImgArgumentException("CImg<%s>::get_shared_planes() : Cannot return a shared-memory subset (0->%u,0->%u,%u->%u,%u) from "
12581 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,z0,z1,v0,width,height,depth,dim);
12582 return CImg<T>(data+beg,width,height,z1-z0+1,1,true);
12583 }
12584
12586 const CImg<T> get_shared_planes(const unsigned int z0, const unsigned int z1, const unsigned int v0=0) const {
12587 const unsigned long beg = offset(0,0,z0,v0), end = offset(0,0,z1,v0);
12588 if (beg>end || beg>=size() || end>=size())
12589 throw CImgArgumentException("CImg<%s>::get_shared_planes() : Cannot return a shared-memory subset (0->%u,0->%u,%u->%u,%u) from "
12590 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,z0,z1,v0,width,height,depth,dim);
12591 return CImg<T>(data+beg,width,height,z1-z0+1,1,true);
12592 }
12593
12595 CImg<T> get_shared_plane(const unsigned int z0, const unsigned int v0=0) {
12596 return get_shared_planes(z0,z0,v0);
12597 }
12598
12600 const CImg<T> get_shared_plane(const unsigned int z0, const unsigned int v0=0) const {
12601 return get_shared_planes(z0,z0,v0);
12602 }
12603
12605 CImg<T> get_shared_channels(const unsigned int v0, const unsigned int v1) {
12606 const unsigned long beg = offset(0,0,0,v0), end = offset(0,0,0,v1);
12607 if (beg>end || beg>=size() || end>=size())
12608 throw CImgArgumentException("CImg<%s>::get_shared_channels() : Cannot return a shared-memory subset (0->%u,0->%u,0->%u,%u->%u) from "
12609 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,depth-1,v0,v1,width,height,depth,dim);
12610 return CImg<T>(data+beg,width,height,depth,v1-v0+1,true);
12611 }
12612
12614 const CImg<T> get_shared_channels(const unsigned int v0, const unsigned int v1) const {
12615 const unsigned long beg = offset(0,0,0,v0), end = offset(0,0,0,v1);
12616 if (beg>end || beg>=size() || end>=size())
12617 throw CImgArgumentException("CImg<%s>::get_shared_channels() : Cannot return a shared-memory subset (0->%u,0->%u,0->%u,%u->%u) from "
12618 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,depth-1,v0,v1,width,height,depth,dim);
12619 return CImg<T>(data+beg,width,height,depth,v1-v0+1,true);
12620 }
12621
12623 CImg<T> get_shared_channel(const unsigned int v0) {
12624 return get_shared_channels(v0,v0);
12625 }
12626
12628 const CImg<T> get_shared_channel(const unsigned int v0) const {
12629 return get_shared_channels(v0,v0);
12630 }
12631
12633 CImg<T> get_shared() {
12634 return CImg<T>(data,width,height,depth,dim,true);
12635 }
12636
12638 const CImg<T> get_shared() const {
12639 return CImg<T>(data,width,height,depth,dim,true);
12640 }
12641
12643 CImg<T> get_projections2d(const unsigned int x0, const unsigned int y0, const unsigned int z0,
12644 const int dx=-100, const int dy=-100, const int dz=-100) const {
12645 if (is_empty()) return CImg<T>();
12646 const unsigned int
12647 nx0 = (x0>=width)?width-1:x0,
12648 ny0 = (y0>=height)?height-1:y0,
12649 nz0 = (z0>=depth)?depth-1:z0;
12650 CImg<T>
12651 imgxy(width,height,1,dim),
12652 imgzy(depth,height,1,dim),
12653 imgxz(width,depth,1,dim);
12654 { cimg_forXYV(*this,x,y,k) imgxy(x,y,k) = (*this)(x,y,nz0,k); }
12655 { cimg_forYZV(*this,y,z,k) imgzy(z,y,k) = (*this)(nx0,y,z,k); }
12656 { cimg_forXZV(*this,x,z,k) imgxz(x,z,k) = (*this)(x,ny0,z,k); }
12657 imgxy.resize(dx,dy,1,dim,1);
12658 imgzy.resize(dz,dy,1,dim,1);
12659 imgxz.resize(dx,dz,1,dim,1);
12660 return CImg<T>(imgxy.width+imgzy.width,imgxy.height+imgxz.height,1,dim,0).
12661 draw_image(imgxy,0,0).
12662 draw_image(imgzy,imgxy.width,0).
12663 draw_image(imgxz,0,imgxy.height);
12664 }
12665
12667 CImg<T>& projections2d(const unsigned int x0, const unsigned int y0, const unsigned int z0,
12668 const int dx=-100, const int dy=-100, const int dz=-100) {
12669 return get_projections2d(x0,y0,z0,dx,dy,dz).assign_to(*this);
12670 }
12671
12673
12691 CImg<typename cimg::last<T,float>::type> get_histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) const {
12692 typedef typename cimg::last<T,float>::type ftype;
12693 if (is_empty()) return CImg<ftype>();
12694 if (!nblevels)
12695 throw CImgArgumentException("CImg<%s>::get_histogram() : Can't compute an histogram with 0 levels",
12696 pixel_type());
12697 T vmin = val_min, vmax = val_max;
12698 CImg<ftype> res(nblevels,1,1,1,0);
12699 if (vmin>=vmax && vmin==0) vmin = minmax(vmax);
12700 if (vmin<vmax) cimg_for(*this,ptr,T) {
12701 const int pos = (int)((*ptr-vmin)*(nblevels-1)/(vmax-vmin));
12702 if (pos>=0 && pos<(int)nblevels) ++res[pos];
12703 } else res[0]+=size();
12704 return res;
12705 }
12706
12708 CImg<T>& histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) {
12709 return get_histogram(nblevels,val_min,val_max).assign_to(*this);
12710 }
12711
12713
12727 CImg<T> get_equalize_histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) const {
12728 return (+*this).equalize_histogram(nblevels,val_min,val_max);
12729 }
12730
12732 CImg<T>& equalize_histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) {
12733 if (!is_empty()) {
12734 T vmin = val_min, vmax = val_max;
12735 if (vmin==vmax && vmin==0) vmin = minmax(vmax);
12736 if (vmin<vmax) {
12737 CImg<float> hist = get_histogram(nblevels,vmin,vmax);
12738 float cumul = 0;
12739 cimg_forX(hist,pos) { cumul+=hist[pos]; hist[pos]=cumul; }
12740 cimg_for(*this,ptr,T) {
12741 const int pos = (unsigned int)((*ptr-vmin)*(nblevels-1)/(vmax-vmin));
12742 if (pos>=0 && pos<(int)nblevels) *ptr = (T)(vmin + (vmax-vmin)*hist[pos]/size());
12743 }
12744 }
12745 }
12746 return *this;
12747 }
12748
12750 CImg<typename cimg::last<T,unsigned int>::type> get_label_regions() const {
12751
12752 #define _cimg_get_label_test(p,q) { \
12753 flag = true; \
12754 const T *ptr1 = ptr(x,y) + siz, *ptr2 = ptr(p,q) + siz; \
12755 for (unsigned int i = dim; flag && i; --i) { ptr1-=wh; ptr2-=wh; flag = (*ptr1==*ptr2); } \
12756 }
12757
12758 if (depth>1)
12759 throw CImgInstanceException("CImg<%s>::label_regions() : Instance image must be a 2D image");
12760 typedef typename cimg::last<T,unsigned int>::type uitype;
12761 CImg<uitype> res(width,height,depth,1,0);
12762 unsigned int label = 1;
12763 const unsigned int wh = width*height, siz = width*height*dim;
12764 const int W1 = dimx()-1, H1 = dimy()-1;
12765 bool flag;
12766 cimg_forXY(*this,x,y) {
12767 bool done = false;
12768 if (y) {
12769 _cimg_get_label_test(x,y-1);
12770 if (flag) {
12771 const unsigned int lab = (res(x,y) = res(x,y-1));
12772 done = true;
12773 if (x && res(x-1,y)!=lab) {
12774 _cimg_get_label_test(x-1,y);
12775 if (flag) {
12776 const unsigned int lold = res(x-1,y), *const cptr = res.ptr(x,y);
12777 for (unsigned int *ptr = res.ptr(); ptr<cptr; ++ptr) if (*ptr==lold) *ptr = lab;
12778 }
12779 }
12780 }
12781 }
12782 if (x && !done) { _cimg_get_label_test(x-1,y); if (flag) { res(x,y) = res(x-1,y); done = true; }}
12783 if (!done) res(x,y) = label++;
12784 }
12785 for (int y=H1; y>=0; --y) for (int x=W1; x>=0; --x) {
12786 bool done = false;
12787 if (y<H1) {
12788 _cimg_get_label_test(x,y+1);
12789 if (flag) {
12790 const unsigned int lab = (res(x,y) = res(x,y+1));
12791 done = true;
12792 if (x<W1 && res(x+1,y)!=lab) {
12793 _cimg_get_label_test(x+1,y);
12794 if (flag) {
12795 const unsigned int lold = res(x+1,y), *const cptr = res.ptr(x,y);
12796 for (unsigned int *ptr = res.ptr()+res.size()-1; ptr>cptr; --ptr) if (*ptr==lold) *ptr = lab;
12797 }
12798 }
12799 }
12800 }
12801 if (x<W1 && !done) { _cimg_get_label_test(x+1,y); if (flag) res(x,y) = res(x+1,y); done = true; }
12802 }
12803 const unsigned int lab0 = res.max()+1;
12804 label = lab0;
12805 cimg_foroff(res,off) {
12806 const unsigned int lab = res[off];
12807 if (lab<lab0) { cimg_for(res,ptr,unsigned int) if (*ptr==lab) *ptr = label; ++label; }
12808 }
12809 return (res-=lab0);
12810 }
12811
12813 CImg<T>& label_regions() {
12814 return get_label_regions().assign_to(*this);
12815 }
12816
12818
12826 CImg<typename cimg::superset<T,float>::type> get_norm_pointwise(int norm_type=2) const {
12827 typedef typename cimg::superset<T,float>::type restype;
12828 if (is_empty()) return CImg<restype>();
12829 CImg<restype> res(width,height,depth);
12830 switch(norm_type) {
12831 case -1: {
12832 cimg_forXYZ(*this,x,y,z) {
12833 restype n = 0; cimg_forV(*this,v) {
12834 const restype tmp = (restype)cimg::abs((*this)(x,y,z,v));
12835 if (tmp>n) n=tmp; res(x,y,z) = n;
12836 }
12837 }
12838 } break;
12839 case 1: {
12840 cimg_forXYZ(*this,x,y,z) {
12841 restype n = 0; cimg_forV(*this,v) n+=cimg::abs((*this)(x,y,z,v)); res(x,y,z) = n;
12842 }
12843 } break;
12844 default: {
12845 cimg_forXYZ(*this,x,y,z) {
12846 restype n = 0; cimg_forV(*this,v) n+=(*this)(x,y,z,v)*(*this)(x,y,z,v); res(x,y,z) = (restype)std::sqrt((double)n);
12847 }
12848 } break;
12849 }
12850 return res;
12851 }
12852
12854 CImg<T>& norm_pointwise(int norm_type=2) {
12855 return get_norm_pointwise(norm_type).assign_to(*this);
12856 }
12857
12859
12865 CImg<typename cimg::superset<T,float>::type> get_orientation_pointwise() const {
12866 typedef typename cimg::superset<T,float>::type restype;
12867 if (is_empty()) return CImg<restype>();
12868 return CImg<restype>(*this,false).orientation_pointwise();
12869 }
12870
12872 CImg<T>& orientation_pointwise() {
12873 cimg_forXYZ(*this,x,y,z) {
12874 float n = 0.0f;
12875 cimg_forV(*this,v) n+=(float)((*this)(x,y,z,v)*(*this)(x,y,z,v));
12876 n = (float)std::sqrt(n);
12877 if (n>0) cimg_forV(*this,v) (*this)(x,y,z,v) = (T)((*this)(x,y,z,v)/n);
12878 else cimg_forV(*this,v) (*this)(x,y,z,v) = 0;
12879 }
12880 return *this;
12881 }
12882
12884 CImgList<T> get_split(const char axe='x', const unsigned int nb=0) const {
12885 if (is_empty()) return CImgList<T>();
12886 CImgList<T> res;
12887 switch (cimg::uncase(axe)) {
12888 case 'x': {
12889 if (nb>width)
12890 throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'x' into %u images.",
12891 pixel_type(),width,height,depth,dim,data,nb);
12892 res.assign(nb?nb:width);
12893 const unsigned int delta = width/res.size + ((width%res.size)?1:0);
12894 unsigned int l,x;
12895 for (l=0, x=0; l<res.size-1; ++l, x+=delta) res[l] = get_crop(x,0,0,0,x+delta-1,height-1,depth-1,dim-1);
12896 res[res.size-1] = get_crop(x,0,0,0,width-1,height-1,depth-1,dim-1);
12897 } break;
12898 case 'y': {
12899 if (nb>height)
12900 throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'y' into %u images.",
12901 pixel_type(),width,height,depth,dim,data,nb);
12902 res.assign(nb?nb:height);
12903 const unsigned int delta = height/res.size + ((height%res.size)?1:0);
12904 unsigned int l,x;
12905 for (l=0, x=0; l<res.size-1; ++l, x+=delta) res[l] = get_crop(0,x,0,0,width-1,x+delta-1,depth-1,dim-1);
12906 res[res.size-1] = get_crop(0,x,0,0,width-1,height-1,depth-1,dim-1);
12907 } break;
12908 case 'z': {
12909 if (nb>depth)
12910 throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'z' into %u images.",
12911 pixel_type(),width,height,depth,dim,data,nb);
12912 res.assign(nb?nb:depth);
12913 const unsigned int delta = depth/res.size + ((depth%res.size)?1:0);
12914 unsigned int l,x;
12915 for (l=0, x=0; l<res.size-1; ++l, x+=delta) res[l] = get_crop(0,0,x,0,width-1,height-1,x+delta-1,dim-1);
12916 res[res.size-1] = get_crop(0,0,x,0,width-1,height-1,depth-1,dim-1);
12917 } break;
12918 case 'v': {
12919 if (nb>dim)
12920 throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'v' into %u images.",
12921 pixel_type(),width,height,depth,dim,data,nb);
12922 res.assign(nb?nb:dim);
12923 const unsigned int delta = dim/res.size + ((dim%res.size)?1:0);
12924 unsigned int l,x;
12925 for (l=0, x=0; l<res.size-1; ++l, x+=delta) res[l] = get_crop(0,0,0,x,width-1,height-1,depth-1,x+delta-1);
12926 res[res.size-1] = get_crop(0,0,0,x,width-1,height-1,depth-1,dim-1);
12927 } break;
12928 default:
12929 throw CImgArgumentException("CImg<%s>::get_split() : Unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe);
12930 break;
12931 }
12932 return res;
12933 }
12934
12936 CImg<T> get_append(const CImg<T>& img, const char axis='x', const char align='c') const {
12937 if (!img) return *this;
12938 if (is_empty()) return img;
12939 CImgList<T> temp(2);
12940 temp[0].width = width; temp[0].height = height; temp[0].depth = depth;
12941 temp[0].dim = dim; temp[0].data = data;
12942 temp[1].width = img.width; temp[1].height = img.height; temp[1].depth = img.depth;
12943 temp[1].dim = img.dim; temp[1].data = img.data;
12944 const CImg<T> res = temp.get_append(axis,align);
12945 temp[0].width = temp[0].height = temp[0].depth = temp[0].dim = 0; temp[0].data = 0;
12946 temp[1].width = temp[1].height = temp[1].depth = temp[1].dim = 0; temp[1].data = 0;
12947 return res;
12948 }
12949
12951 CImg<T>& append(const CImg<T>& img, const char axis='x', const char align='c') {
12952 if (!img) return *this;
12953 if (is_empty()) return (*this=img);
12954 return get_append(img,axis,align).assign_to(*this);
12955 }
12956
12958
12967 CImgList<typename cimg::superset<T,float>::type> get_gradientXY(const int scheme=0) const {
12968 typedef typename cimg::superset<T,float>::type restype;
12969 if (is_empty()) return CImgList<restype>(2);
12970 CImgList<restype> res(2,width,height,depth,dim);
12971 switch(scheme) {
12972 case -1: {
12973 CImg_3x3(I,restype);
12974 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) { res[0](x,y,z,k) = Icc-Ipc; res[1](x,y,z,k) = Icc-Icp; }
12975 } break;
12976 case 1: {
12977 CImg_2x2(I,restype);
12978 cimg_forZV(*this,z,k) cimg_for2x2(*this,x,y,z,k,I) { res[0](x,y,0,k) = Inc-Icc; res[1](x,y,z,k) = Icn-Icc; }
12979 } break;
12980 case 2: {
12981 CImg_3x3(I,restype);
12982 const float a = 1, b = 2;
12983 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
12984 res[0](x,y,z,k) = -a*Ipp-b*Ipc-a*Ipn+a*Inp+b*Inc+a*Inn;
12985 res[1](x,y,z,k) = -a*Ipp-b*Icp-a*Inp+a*Ipn+b*Icn+a*Inn;
12986 }
12987 } break;
12988 case 3: {
12989 CImg_3x3(I,restype);
12990 const float a = (float)(0.25*(2-std::sqrt(2.0))), b = (float)(0.5f*(std::sqrt(2.0)-1));
12991 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
12992 res[0](x,y,z,k) = -a*Ipp-b*Ipc-a*Ipn+a*Inp+b*Inc+a*Inn;
12993 res[1](x,y,z,k) = -a*Ipp-b*Icp-a*Inp+a*Ipn+b*Icn+a*Inn;
12994 }
12995 } break;
12996 case 4: {
12997 res[0] = get_deriche(0,1,'x');
12998 res[1] = get_deriche(0,1,'y');
12999 } break;
13000 default: {
13001 CImg_3x3(I,restype);
13002 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
13003 res[0](x,y,z,k) = 0.5f*(Inc-Ipc);
13004 res[1](x,y,z,k) = 0.5f*(Icn-Icp);
13005 }
13006 } break;
13007 }
13008 return res;
13009 }
13010
13012
13015 CImgList<typename cimg::superset<T,float>::type> get_gradientXYZ(const int scheme=0) const {
13016 typedef typename cimg::superset<T,float>::type restype;
13017 if (is_empty()) return CImgList<restype>(3);
13018 CImgList<restype> res(3,width,height,depth,dim);
13019 CImg_3x3x3(I,restype);
13020 switch(scheme) {
13021 case -1: {
13022 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13023 res[0](x,y,z,k) = Iccc-Ipcc;
13024 res[1](x,y,z,k) = Iccc-Icpc;
13025 res[2](x,y,z,k) = Iccc-Iccp;
13026 }
13027 } break;
13028 case 1: {
13029 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13030 res[0](x,y,z,k) = Incc-Iccc;
13031 res[1](x,y,z,k) = Icnc-Iccc;
13032 res[2](x,y,z,k) = Iccn-Iccc;
13033 }
13034 } break;
13035 case 4: {
13036 res[0] = get_deriche(0,1,'x');
13037 res[1] = get_deriche(0,1,'y');
13038 res[2] = get_deriche(0,1,'z');
13039 } break;
13040 default: {
13041 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13042 res[0](x,y,z,k) = 0.5f*(Incc-Ipcc);
13043 res[1](x,y,z,k) = 0.5f*(Icnc-Icpc);
13044 res[2](x,y,z,k) = 0.5f*(Iccn-Iccp);
13045 }
13046 } break;
13047 }
13048 return res;
13049 }
13050
13052 CImg<typename cimg::superset<T,float>::type> get_structure_tensorXY(const int scheme=1) const {
13053 typedef typename cimg::superset<T,float>::type restype;
13054 if (is_empty()) return CImg<restype>();
13055 CImg<restype> res(width,height,depth,3,0);
13056 CImg_3x3(I,restype);
13057 switch (scheme) {
13058 case 0: {
13059 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,0,k,I) {
13060 const restype
13061 ix = 0.5f*(Inc-Ipc),
13062 iy = 0.5f*(Icn-Icp);
13063 res(x,y,z,0)+=ix*ix;
13064 res(x,y,z,1)+=ix*iy;
13065 res(x,y,z,2)+=iy*iy;
13066 }
13067 } break;
13068 default: {
13069 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,0,k,I) {
13070 const restype
13071 ixf = Inc-Icc, ixb = Icc-Ipc,
13072 iyf = Icn-Icc, iyb = Icc-Icp;
13073 res(x,y,z,0) += 0.5f*(ixf*ixf+ixb*ixb);
13074 res(x,y,z,1) += 0.25f*(ixf*iyf+ixf*iyb+ixb*iyf+ixb*iyb);
13075 res(x,y,z,2) += 0.5f*(iyf*iyf+iyb*iyb);
13076 }
13077 } break;
13078 }
13079 return res;
13080 }
13081
13083 CImg<T>& structure_tensorXY(const int scheme=1) {
13084 return get_structure_tensorXY(scheme).assign_to(*this);
13085 }
13086
13088 CImg<typename cimg::superset<T,float>::type> get_structure_tensorXYZ(const int scheme=1) const {
13089 typedef typename cimg::superset<T,float>::type restype;
13090 if (is_empty()) return CImg<restype>();
13091 CImg<restype> res(width,height,depth,6,0);
13092 CImg_3x3x3(I,restype);
13093 switch (scheme) {
13094 case 0: {
13095 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13096 const restype
13097 ix = 0.5f*(Incc-Ipcc),
13098 iy = 0.5f*(Icnc-Icpc),
13099 iz = 0.5f*(Iccn-Iccp);
13100 res(x,y,z,0)+=ix*ix;
13101 res(x,y,z,1)+=ix*iy;
13102 res(x,y,z,2)+=ix*iz;
13103 res(x,y,z,3)+=iy*iy;
13104 res(x,y,z,4)+=iy*iz;
13105 res(x,y,z,5)+=iz*iz;
13106 }
13107 } break;
13108 default: {
13109 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13110 const restype
13111 ixf = Incc-Iccc, ixb = Iccc-Ipcc,
13112 iyf = Icnc-Iccc, iyb = Iccc-Icpc,
13113 izf = Iccn-Iccc, izb = Iccc-Iccp;
13114 res(x,y,z,0) += 0.5f*(ixf*ixf + ixb*ixb);
13115 res(x,y,z,1) += 0.25f*(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb);
13116 res(x,y,z,2) += 0.25f*(ixf*izf + ixf*izb + ixb*izf + ixb*izb);
13117 res(x,y,z,3) += 0.5f*(iyf*iyf + iyb*iyb);
13118 res(x,y,z,4) += 0.25f*(iyf*izf + iyf*izb + iyb*izf + iyb*izb);
13119 res(x,y,z,5) += 0.5f*(izf*izf + izb*izb);
13120 }
13121 } break;
13122 }
13123 return res;
13124 }
13125
13127 CImg<T>& structure_tensorXYZ(const int scheme=1) {
13128 return get_structure_tensorXYZ(scheme).assign_to(*this);
13129 }
13130
13132
13135 CImgList<typename cimg::superset<T,float>::type> get_hessianXY() {
13136 typedef typename cimg::superset<T,float>::type ftype;
13137 if (is_empty()) return CImgList<ftype>(3);
13138 CImgList<ftype> res(3,width,height,depth,dim);
13139 CImg_3x3(I,ftype);
13140 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
13141 res[0](x,y,z,k) = Ipc + Inc - 2*Icc;
13142 res[1](x,y,z,k) = 0.25f*(Ipp + Inn - Ipn - Inp);
13143 res[2](x,y,z,k) = Icp + Icn - 2*Icc;
13144 }
13145 return res;
13146 }
13147
13149
13152 CImgList<typename cimg::superset<T,float>::type> get_hessianXYZ() {
13153 typedef typename cimg::superset<T,float>::type ftype;
13154 if (is_empty()) return CImgList<ftype>(6);
13155 CImgList<ftype> res(6,width,height,depth,dim);
13156 CImg_3x3x3(I,ftype);
13157 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13158 res[0](x,y,z,k) = Ipcc + Incc - 2*Iccc;
13159 res[1](x,y,z,k) = 0.25f*(Ippc + Innc - Ipnc - Inpc);
13160 res[2](x,y,z,k) = 0.25f*(Ipcp + Incn - Ipcn - Incp);
13161 res[3](x,y,z,k) = Icpc + Icnc - 2*Iccc;
13162 res[4](x,y,z,k) = 0.25f*(Icpp + Icnn - Icpn - Icnp);
13163 res[5](x,y,z,k) = Iccn + Iccp - 2*Iccc;
13164 }
13165 return res;
13166 }
13167
13169 CImg<typename cimg::superset<T,float>::type> get_distance_function(const unsigned int nb_iter=100, const float band_size=0.0f, const float precision=0.5f) const {
13170 typedef typename cimg::superset<T,float>::type ftype;
13171 return CImg<ftype>(*this,false).distance_function(nb_iter,band_size,precision);
13172 }
13173
13175 CImg<T>& distance_function(const unsigned int nb_iter=100, const float band_size=0.0f, const float precision=0.5f) {
13176 typedef typename cimg::superset<T,float>::type ftype;
13177 if (is_empty()) return *this;
13178 CImg<ftype> veloc(*this);
13179 for (unsigned int iter=0; iter<nb_iter; ++iter) {
13180
13181 if (depth>1) {
13182 CImg_3x3x3(I,ftype);
13183 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) if (band_size<=0 || cimg::abs(Iccc)<band_size) {
13184 const ftype
13185 gx = 0.5f*(Incc-Ipcc),
13186 gy = 0.5f*(Icnc-Icpc),
13187 gz = 0.5f*(Iccn-Iccp),
13188 sgn = -cimg::sign(Iccc),
13189 ix = gx*sgn>0?Incc-Iccc:Iccc-Ipcc,
13190 iy = gy*sgn>0?Icnc-Iccc:Iccc-Icpc,
13191 iz = gz*sgn>0?Iccn-Iccc:Iccc-Iccp,
13192 ng = 1e-5f+(ftype)std::sqrt(gx*gx+gy*gy+gz*gz),
13193 ngx = gx/ng,
13194 ngy = gy/ng,
13195 ngz = gz/ng;
13196 veloc(x,y,z,k) = sgn*(ngx*ix+ngy*iy+ngz*iz-1);
13197 }
13198 } else {
13199 CImg_3x3(I,ftype);
13200 cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) if (band_size<=0 || cimg::abs(Icc)<band_size) {
13201 const ftype
13202 gx = 0.5f*(Inc-Ipc),
13203 gy = 0.5f*(Icn-Icp),
13204 sgn = -cimg::sign(Icc),
13205 ix = gx*sgn>0?Inc-Icc:Icc-Ipc,
13206 iy = gy*sgn>0?Icn-Icc:Icc-Icp,
13207 ng = 1e-5f+(ftype)std::sqrt(gx*gx+gy*gy),
13208 ngx = gx/ng,
13209 ngy = gy/ng;
13210 veloc(x,y,k) = sgn*(ngx*ix+ngy*iy-1);
13211 }
13212 }
13213 float m, M = (float)veloc.maxmin(m), xdt = precision/(float)cimg::max(cimg::abs(m),cimg::abs(M));
13214 *this+=(veloc*=xdt);
13215 }
13216 return *this;
13217 }
13218
13220
13228 template<typename tf, typename t>
13229 static CImg<T> get_dijkstra(const tf& distance, const unsigned int nb_nodes,
13230 const unsigned int starting_node, const unsigned int ending_node,
13231 CImg<t>& previous) {
13232
13233 CImg<T> dist(1,nb_nodes,1,1,cimg::type<T>::max());
13234 dist(starting_node) = 0;
13235 previous.assign(1,nb_nodes,1,1,(t)-1);
13236 previous(starting_node) = (t)starting_node;
13237 typedef typename cimg::last<T,unsigned int>::type uitype;
13238 CImg<uitype> Q(nb_nodes);
13239 cimg_forX(Q,u) Q(u) = u;
13240 cimg::swap(Q(starting_node),Q(0));
13241 unsigned int sizeQ = nb_nodes;
13242 while (sizeQ) {
13243
13244 const unsigned int umin = Q(0);
13245 if (umin==ending_node) sizeQ = 0;
13246 else {
13247 const T dmin = dist(umin);
13248 const T infty = cimg::type<T>::max();
13249 for (unsigned int q=1; q<sizeQ; ++q) {
13250 const unsigned int v = Q(q);
13251 const T d = (T)distance(v,umin);
13252 if (d<infty) {
13253 const T alt = dmin + d;
13254 if (alt<dist(v)) {
13255 dist(v) = alt;
13256 previous(v) = (t)umin;
13257 const T distpos = dist(Q(q));
13258 for (unsigned int pos = q, par = 0; pos && distpos<dist(Q(par=(pos+1)/2-1)); pos=par) cimg::swap(Q(pos),Q(par));
13259 }
13260 }
13261 }
13262
13263 Q(0) = Q(--sizeQ);
13264 const T distpos = dist(Q(0));
13265 for (unsigned int pos = 0, left = 0, right = 0;
13266 ((right=2*(pos+1),(left=right-1))<sizeQ && distpos>dist(Q(left))) || (right<sizeQ && distpos>dist(Q(right)));) {
13267 if (right<sizeQ) {
13268 if (dist(Q(left))<dist(Q(right))) { cimg::swap(Q(pos),Q(left)); pos = left; }
13269 else { cimg::swap(Q(pos),Q(right)); pos = right; }
13270 } else { cimg::swap(Q(pos),Q(left)); pos = left; }
13271 }
13272 }
13273 }
13274 return dist;
13275 }
13276
13277 template<typename tf, typename t>
13278 static CImg<T> get_dijkstra(const tf& distance, const unsigned int nb_nodes,
13279 const unsigned int starting_node, const unsigned int ending_node=~0U) {
13280 typedef typename cimg::last<T,unsigned int>::type uitype;
13281 CImg<uitype> foo;
13282 return get_dijkstra(distance,nb_nodes,starting_node,ending_node,foo);
13283 }
13284
13286
13292 template<typename t> CImg<T> get_dijkstra(const unsigned int starting_node, const unsigned int ending_node, CImg<t>& previous) const {
13293 if (width!=height || depth!=1 || dim!=1)
13294 throw CImgInstanceException("CImg<%s>::dijkstra() : Instance image (%u,%u,%u,%u,%p) is not a graph adjacency matrix",
13295 pixel_type(),width,height,depth,dim,data);
13296 return CImg<T>::get_dijkstra(*this,width,starting_node,ending_node,previous);
13297 }
13298
13299
13300 template<typename t> CImg<T>& dijkstra(const unsigned int starting_node, const unsigned int ending_node, CImg<t>& previous) {
13301 return get_dijkstra(starting_node,ending_node,previous).assign_to(*this);
13302 }
13303
13305 CImg<typename cimg::superset<T,float>::type> get_dijkstra(const unsigned int starting_node, const unsigned int ending_node=~0U) const {
13306 typedef typename cimg::last<T,unsigned int>::type uitype;
13307 CImg<uitype> foo;
13308 return get_dijkstra(starting_node,ending_node,foo);
13309 }
13310
13311
13312 CImg<T>& dijkstra(const unsigned int starting_node, const unsigned int ending_node=~0U) {
13313 return get_dijkstra(starting_node,ending_node).assign_to(*this);
13314 }
13315
13317
13318
13320
13321
13322
13323 struct _marching_squares_func {
13324 const CImg<T>& ref;
13325 _marching_squares_func(const CImg<T>& pref):ref(pref) {}
13326 float operator()(const float x, const float y) const {
13327 return (float)ref((int)x,(int)y);
13328 }
13329 };
13330
13331 struct _marching_cubes_func {
13332 const CImg<T>& ref;
13333 _marching_cubes_func(const CImg<T>& pref):ref(pref) {}
13334 float operator()(const float x, const float y, const float z) const {
13335 return (float)ref((int)x,(int)y,(int)z);
13336 }
13337 };
13338
13339 struct _marching_squares_func_float {
13340 const CImg<T>& ref;
13341 _marching_squares_func_float(const CImg<T>& pref):ref(pref) {}
13342 float operator()(const float x, const float y) const {
13343 return (float)ref.linear_pix2d(x,y);
13344 }
13345 };
13346
13347 struct _marching_cubes_func_float {
13348 const CImg<T>& ref;
13349 _marching_cubes_func_float(const CImg<T>& pref):ref(pref) {}
13350 float operator()(const float x, const float y, const float z) const {
13351 return (float)ref.linear_pix3d(x,y,z);
13352 }
13353 };
13354
13356 template<typename tp, typename tf>
13357 const CImg<T>& marching_squares(const float isovalue, CImgList<tp>& points, CImgList<tf>& primitives) const {
13358 if (height<=1 || depth>1 || dim>1)
13359 throw CImgInstanceException("CImg<%s>::marching_squares() : Instance image (%u,%u,%u,%u,%p) is not a 2D scalar image.",
13360 pixel_type(),width,height,depth,dim,data);
13361 const _marching_squares_func func(*this);
13362 cimg::marching_squares(func,isovalue,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,1.0f,1.0f,points,primitives);
13363 return *this;
13364 }
13365
13367
13370 template<typename tp, typename tf>
13371 const CImg<T>& marching_squares(const float isovalue,
13372 const float resx, const float resy,
13373 CImgList<tp>& points, CImgList<tf>& primitives) const {
13374 if (height<=1 || depth>1 || dim>1)
13375 throw CImgInstanceException("CImg<%s>::marching_squares() : Instance image (%u,%u,%u,%u,%p) is not a 2D scalar image.",
13376 pixel_type(),width,height,depth,dim,data);
13377 const _marching_squares_func_float func(*this);
13378 cimg::marching_squares(func,isovalue,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,resx,resy,points,primitives);
13379 return *this;
13380 }
13381
13383 template<typename tp, typename tf>
13384 const CImg<T>& marching_cubes(const float isovalue, CImgList<tp>& points, CImgList<tf>& primitives,
13385 const bool invert_faces = false) const {
13386 if (depth<=1 || dim>1)
13387 throw CImgInstanceException("CImg<%s>::marching_cubes() : Instance image (%u,%u,%u,%u,%p) is not a 3D scalar image.",
13388 pixel_type(),width,height,depth,dim,data);
13389 const _marching_cubes_func func(*this);
13390 cimg::marching_cubes(func,isovalue,0.0f,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,dimz()-1.0f,
13391 1.0f,1.0f,1.0f,points,primitives,invert_faces);
13392 return *this;
13393 }
13394
13396
13399 template<typename tp, typename tf>
13400 const CImg<T>& marching_cubes(const float isovalue,
13401 const float resx, const float resy, const float resz,
13402 CImgList<tp>& points, CImgList<tf>& primitives,
13403 const bool invert_faces = false) const {
13404 if (depth<=1 || dim>1)
13405 throw CImgInstanceException("CImg<%s>::marching_cubes() : Instance image (%u,%u,%u,%u,%p) is not a 3D scalar image.",
13406 pixel_type(),width,height,depth,dim,data);
13407 const _marching_cubes_func_float func(*this);
13408 cimg::marching_cubes(func,isovalue,0.0f,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,dimz()-1.0f,
13409 resx,resy,resz,points,primitives,invert_faces);
13410 return *this;
13411 }
13412
13414
13415
13417
13418
13419
13421
13427 static CImg<T> get_default_LUT8() {
13428 static CImg<T> palette;
13429 if (!palette) {
13430 palette.assign(1,256,1,3);
13431 for (unsigned int index=0, r=16; r<256; r+=32)
13432 for (unsigned int g=16; g<256; g+=32)
13433 for (unsigned int b=32; b<256; b+=64) {
13434 palette(0,index,0) = (T)r;
13435 palette(0,index,1) = (T)g;
13436 palette(0,index++,2) = (T)b;
13437 }
13438 }
13439 return palette;
13440 }
13441
13443 static CImg<T> get_rainbow_LUT8() {
13444 static CImg<T> palette;
13445 if (!palette) {
13446 typedef typename cimg::superset<T,int>::type itype;
13447 CImg<itype> tmp(1,256,1,3,255);
13448 tmp.get_shared_channel(0).sequence(0,359);
13449 tmp.HSVtoRGB();
13450 palette = tmp;
13451 }
13452 return palette;
13453 }
13454
13456 static CImg<T> get_cluster_LUT8() {
13457 static const unsigned char pal[] =
13458 { 217,62,88,75,1,237,240,12,56,160,165,116,1,1,204,2,15,248,148,185,133,141,46,246,222,116,16,5,207,226,
13459 17,114,247,1,214,53,238,0,95,55,233,235,109,0,17,54,33,0,90,30,3,0,94,27,19,0,68,212,166,130,0,15,7,119,
13460 238,2,246,198,0,3,16,10,13,2,25,28,12,6,2,99,18,141,30,4,3,140,12,4,30,233,7,10,0,136,35,160,168,184,20,
13461 233,0,1,242,83,90,56,180,44,41,0,6,19,207,5,31,214,4,35,153,180,75,21,76,16,202,218,22,17,2,136,71,74,
13462 81,251,244,148,222,17,0,234,24,0,200,16,239,15,225,102,230,186,58,230,110,12,0,7,129,249,22,241,37,219,
13463 1,3,254,210,3,212,113,131,197,162,123,252,90,96,209,60,0,17,0,180,249,12,112,165,43,27,229,77,40,195,12,
13464 87,1,210,148,47,80,5,9,1,137,2,40,57,205,244,40,8,252,98,0,40,43,206,31,187,0,180,1,69,70,227,131,108,0,
13465 223,94,228,35,248,243,4,16,0,34,24,2,9,35,73,91,12,199,51,1,249,12,103,131,20,224,2,70,32,
13466 233,1,165,3,8,154,246,233,196,5,0,6,183,227,247,195,208,36,0,0,226,160,210,198,69,153,210,1,23,8,192,2,4,
13467 137,1,0,52,2,249,241,129,0,0,234,7,238,71,7,32,15,157,157,252,158,2,250,6,13,30,11,162,0,199,21,11,27,224,
13468 4,157,20,181,111,187,218,3,0,11,158,230,196,34,223,22,248,135,254,210,157,219,0,117,239,3,255,4,227,5,247,
13469 11,4,3,188,111,11,105,195,2,0,14,1,21,219,192,0,183,191,113,241,1,12,17,248,0,48,7,19,1,254,212,0,239,246,
13470 0,23,0,250,165,194,194,17,3,253,0,24,6,0,141,167,221,24,212,2,235,243,0,0,205,1,251,133,204,28,4,6,1,10,
13471 141,21,74,12,236,254,228,19,1,0,214,1,186,13,13,6,13,16,27,209,6,216,11,207,251,59,32,9,155,23,19,235,143,
13472 116,6,213,6,75,159,23,6,0,228,4,10,245,249,1,7,44,234,4,102,174,0,19,239,103,16,15,18,8,214,22,4,47,244,
13473 255,8,0,251,173,1,212,252,250,251,252,6,0,29,29,222,233,246,5,149,0,182,180,13,151,0,203,183,0,35,149,0,
13474 235,246,254,78,9,17,203,73,11,195,0,3,5,44,0,0,237,5,106,6,130,16,214,20,168,247,168,4,207,11,5,1,232,251,
13475 129,210,116,231,217,223,214,27,45,38,4,177,186,249,7,215,172,16,214,27,249,230,236,2,34,216,217,0,175,30,
13476 243,225,244,182,20,212,2,226,21,255,20,0,2,13,62,13,191,14,76,64,20,121,4,118,0,216,1,147,0,2,210,1,215,
13477 95,210,236,225,184,46,0,248,24,11,1,9,141,250,243,9,221,233,160,11,147,2,55,8,23,12,253,9,0,54,0,231,6,3,
13478 141,8,2,246,9,180,5,11,8,227,8,43,110,242,1,130,5,97,36,10,6,219,86,133,11,108,6,1,5,244,67,19,28,0,174,
13479 154,16,127,149,252,188,196,196,228,244,9,249,0,0,0,37,170,32,250,0,73,255,23,3,224,234,38,195,198,0,255,87,
13480 33,221,174,31,3,0,189,228,6,153,14,144,14,108,197,0,9,206,245,254,3,16,253,178,248,0,95,125,8,0,3,168,21,
13481 23,168,19,50,240,244,185,0,1,144,10,168,31,82,1,13 };
13482 static const CImg<T> palette(pal,256,1,1,3,false);
13483 return palette;
13484 }
13485
13487
13495 template<typename t> CImg<t> get_RGBtoLUT(const CImg<t>& palette, const bool dithering=true, const bool indexing=false) const {
13496 if (is_empty()) return CImg<t>();
13497 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoLUT() : Input image dimension is dim=%u, "
13498 "should be a (R,G,B) image.",pixel_type(),dim);
13499 if (palette.data && palette.dim!=3)
13500 throw CImgArgumentException("CImg<%s>::RGBtoLUT() : Given palette dimension is dim=%u, "
13501 "should be a (R,G,B) palette",pixel_type(),palette.dim);
13502 CImg<t> res(width,height,depth,indexing?1:3), pal = palette.data?palette:CImg<t>::get_default_LUT8();
13503 float *line1 = new float[3*width], *line2 = new float[3*width], *pline1 = line1, *pline2 = line2;
13504 cimg_forZ(*this,z) {
13505 float *ptr = pline2; cimg_forX(*this,x) { *(ptr++) = (*this)(x,0,z,0); *(ptr++) = (*this)(x,0,z,1); *(ptr++) = (*this)(x,0,z,2); }
13506 cimg_forY(*this,y) {
13507 cimg::swap(pline1,pline2);
13508 if (y<dimy()-1) {
13509 const int ny = y+1;
13510 float *ptr = pline2; cimg_forX(*this,x) { *(ptr++) = (*this)(x,ny,z,0); *(ptr++) = (*this)(x,ny,z,1); *(ptr++) = (*this)(x,ny,z,2); }
13511 }
13512 float *ptr1=pline1, *ptr2=pline2;
13513 cimg_forX(*this,x) {
13514 float R = *(ptr1++), G = *(ptr1++), B = *(ptr1++);
13515 R = R<0?0:(R>255?255:R); G = G<0?0:(G>255?255:G); B = B<0?0:(B>255?255:B);
13516 int best_index = 0;
13517 t Rbest = 0, Gbest = 0, Bbest = 0;
13518 if (palette.data) {
13519 float min = cimg::type<float>::max();
13520 cimg_forX(palette,off) {
13521 const t Rp = palette(off,0), Gp = palette(off,1), Bp = palette(off,2);
13522 const float error = (float)((Rp-R)*(Rp-R) + (Gp-G)*(Gp-G) + (Bp-B)*(Bp-B));
13523 if (error<min) { min=error; best_index=off; Rbest=Rp; Gbest=Gp; Bbest=Bp; }
13524 }
13525 } else {
13526 Rbest = (t)((unsigned char)R&0xe0); Gbest = (t)((unsigned char)G&0xe0); Bbest = (t)((unsigned char)B&0xc0);
13527 best_index = (unsigned char)Rbest | ((unsigned char)Gbest>>3) | ((unsigned char)Bbest>>6);
13528 }
13529 if (indexing) res(x,y,z) = best_index;
13530 else { res(x,y,z,0) = Rbest; res(x,y,z,1) = Gbest; res(x,y,z,2) = Bbest; }
13531 if (dithering) {
13532 const float dR = (float)(R-Rbest), dG = (float)(G-Gbest), dB = (float)(B-Bbest);
13533 if (x<dimx()-1) { *(ptr1++)+= dR*7/16; *(ptr1++)+= dG*7/16; *(ptr1++)+= dB*7/16; ptr1-=3; }
13534 if (y<dimy()-1) {
13535 *(ptr2++)+= dR*5/16; *(ptr2++)+= dG*5/16; *ptr2+= dB*5/16; ptr2-=2;
13536 if (x>0) { *(--ptr2)+= dB*3/16; *(--ptr2)+= dG*3/16; *(--ptr2)+= dR*3/16; ptr2+=3; }
13537 if (x<dimx()-1) { ptr2+=3; *(ptr2++)+= dR/16; *(ptr2++)+= dG/16; *ptr2+= dB/16; ptr2-=5; }
13538 }
13539 }
13540 ptr2+=3;
13541 }
13542 }
13543 }
13544 delete[] line1; delete[] line2;
13545 return res;
13546 }
13547
13549 CImg<T>& RGBtoLUT(const CImg<T>& palette, const bool dithering=true, const bool indexing=false) {
13550 return get_RGBtoLUT(palette,dithering,indexing).assign_to(*this);
13551 }
13552
13554
13557 CImg<T> get_RGBtoLUT(const bool dithering=true, const bool indexing=false) const {
13558 CImg<T> foo;
13559 return get_RGBtoLUT(foo,dithering,indexing);
13560 }
13561
13563 CImg<T>& RGBtoLUT(const bool dithering=true, const bool indexing=false) {
13564 CImg<T> foo;
13565 return get_RGBtoLUT(foo,dithering,indexing).assign_to(*this);
13566 }
13567
13569 template<typename t> CImg<t> get_LUTtoRGB(const CImg<t>& palette) const {
13570 if (is_empty()) return CImg<t>();
13571 if (dim!=1) throw CImgInstanceException("CImg<%s>::LUTtoRGB() : Input image dimension is dim=%u, "
13572 "should be a LUT image",pixel_type(),dim);
13573 if (palette.data && palette.dim!=3)
13574 throw CImgArgumentException("CImg<%s>::LUTtoRGB() : Given palette dimension is dim=%u, "
13575 "should be a (R,G,B) palette",pixel_type(),palette.dim);
13576 CImg<t> res(width,height,depth,3);
13577 CImg<t> pal = palette.data?palette:CImg<t>::get_default_LUT8();
13578 cimg_forXYZ(*this,x,y,z) {
13579 const unsigned int index = (unsigned int)(*this)(x,y,z);
13580 res(x,y,z,0) = pal(index,0);
13581 res(x,y,z,1) = pal(index,1);
13582 res(x,y,z,2) = pal(index,2);
13583 }
13584 return res;
13585 }
13586
13588 CImg<T>& LUTtoRGB(const CImg<T>& palette) {
13589 return get_LUTtoRGB(palette).assign_to(*this);
13590 }
13591
13593 CImg<T> get_LUTtoRGB() const {
13594 CImg<T> foo;
13595 return get_LUTtoRGB(foo);
13596 }
13597
13599 CImg<T>& LUTtoRGB() {
13600 CImg<T> foo;
13601 return get_LUTtoRGB(foo).assign_to(*this);
13602 }
13603
13605 CImg<typename cimg::superset<T,float>::type> get_RGBtoHSV() const {
13606 typedef typename cimg::superset<T,float>::type ftype;
13607 return CImg<ftype>(*this).RGBtoHSV();
13608 }
13609
13611 CImg<T>& RGBtoHSV() {
13612 if (!is_empty()) {
13613 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoHSV() : Input image dimension is dim=%u, "
13614 "should be a (R,G,B) image.",pixel_type(),dim);
13615 cimg_forXYZ(*this,x,y,z) {
13616 const float
13617 R = (float)((*this)(x,y,z,0)/255.0f),
13618 G = (float)((*this)(x,y,z,1)/255.0f),
13619 B = (float)((*this)(x,y,z,2)/255.0f);
13620 const float m = cimg::min(R,G,B), M = cimg::max(R,G,B);
13621 float H = 0, S = 0;
13622 if (M!=m) {
13623 const float
13624 f = (R==m)?(G-B):((G==m)?(B-R):(R-G)),
13625 i = (R==m)?3.0f:((G==m)?5.0f:1.0f);
13626 H = (i-f/(M-m));
13627 if (H>=6.0f) H-=6.0f;
13628 H*=60;
13629 S = (M-m)/M;
13630 }
13631 (*this)(x,y,z,0) = (T)H;
13632 (*this)(x,y,z,1) = (T)S;
13633 (*this)(x,y,z,2) = (T)M;
13634 }
13635 }
13636 return *this;
13637 }
13638
13640 CImg<T> get_HSVtoRGB() const {
13641 return (+*this).HSVtoRGB();
13642 }
13643
13645 CImg<T>& HSVtoRGB() {
13646 if (!is_empty()) {
13647 if (dim!=3) throw CImgInstanceException("CImg<%s>::HSVtoRGB() : Input image dimension is dim=%u, "
13648 "should be a (H,S,V) image",pixel_type(),dim);
13649 cimg_forXYZ(*this,x,y,z) {
13650 float
13651 H = (float)((*this)(x,y,z,0)),
13652 S = (float)((*this)(x,y,z,1)),
13653 V = (float)((*this)(x,y,z,2));
13654 float R = 0, G = 0, B = 0;
13655 if (H<0) R = G = B = V;
13656 else {
13657 H/=60.0f;
13658 const int i = (int)std::floor(H);
13659 const float
13660 f = (i&1)?(H-i):(1.0f-H+i),
13661 m = V*(1.0f-S),
13662 n = V*(1.0f-S*f);
13663 switch(i) {
13664 case 6:
13665 case 0: R = V; G = n; B = m; break;
13666 case 1: R = n; G = V; B = m; break;
13667 case 2: R = m; G = V; B = n; break;
13668 case 3: R = m; G = n; B = V; break;
13669 case 4: R = n; G = m; B = V; break;
13670 case 5: R = V; G = m; B = n; break;
13671 }
13672 }
13673 (*this)(x,y,z,0) = (T)(R*255.0f);
13674 (*this)(x,y,z,1) = (T)(G*255.0f);
13675 (*this)(x,y,z,2) = (T)(B*255.0f);
13676 }
13677 }
13678 return *this;
13679 }
13680
13682 CImg<typename cimg::superset<T,float>::type> get_RGBtoHSL() const {
13683 typedef typename cimg::superset<T,float>::type ftype;
13684 return CImg<ftype>(*this).RGBtoHSL();
13685 }
13686
13688 CImg<T>& RGBtoHSL() {
13689 if (!is_empty()) {
13690 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoHSL() : Input image dimension is dim=%u, "
13691 "should be a (R,G,B) image.",pixel_type(),dim);
13692 cimg_forXYZ(*this,x,y,z) {
13693 const float
13694 R = (float)((*this)(x,y,z,0)/255.0f),
13695 G = (float)((*this)(x,y,z,1)/255.0f),
13696 B = (float)((*this)(x,y,z,2)/255.0f);
13697 const float m = cimg::min(R,G,B), M = cimg::max(R,G,B), L = 0.5f*(m+M);
13698 float H = 0, S = 0;
13699 if (M==m || L==0) H = S = 0;
13700 else {
13701 const float
13702 f = (R==m)?(G-B):((G==m)?(B-R):(R-G)),
13703 i = (R==m)?3.0f:((G==m)?5.0f:1.0f);
13704 H = (i-f/(M-m));
13705 if (H>=6.0f) H-=6.0f;
13706 H*=60;
13707 S = (L<=0.5f)?((M-m)/(M+m)):((M-m)/(2-M-m));
13708 }
13709 (*this)(x,y,z,0) = (T)H;
13710 (*this)(x,y,z,1) = (T)S;
13711 (*this)(x,y,z,2) = (T)L;
13712 }
13713 }
13714 return *this;
13715 }
13716
13718 CImg<T> get_RGBtoYCbCr() const {
13719 return (+*this).RGBtoYCbCr();
13720 }
13721
13723 CImg<T>& RGBtoYCbCr() {
13724 if (!is_empty()) {
13725 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoYCbCr() : Input image dimension is dim=%u, "
13726 "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
13727 cimg_forXYZ(*this,x,y,z) {
13728 const int
13729 R = (int)((*this)(x,y,z,0)),
13730 G = (int)((*this)(x,y,z,1)),
13731 B = (int)((*this)(x,y,z,2));
13732 const int
13733 Y = ((66*R+129*G+25*B+128)>>8) + 16,
13734 Cb = ((-38*R-74*G+112*B+128)>>8) + 128,
13735 Cr = ((112*R-94*G-18*B+128)>>8) + 128;
13736 (*this)(x,y,z,0) = (T)(Y<0?0:(Y>255?255:Y));
13737 (*this)(x,y,z,1) = (T)(Cb<0?0:(Cb>255?255:Cb));
13738 (*this)(x,y,z,2) = (T)(Cr<0?0:(Cr>255?255:Cr));
13739 }
13740 }
13741 return *this;
13742 }
13743
13745 CImg<T> get_YCbCrtoRGB() const {
13746 return (+*this).YCbCrtoRGB();
13747 }
13748
13750 CImg<T>& YCbCrtoRGB() {
13751 if (!is_empty()) {
13752 if (dim!=3) throw CImgInstanceException("CImg<%s>::YCbCrtoRGB() : Input image dimension is dim=%u, "
13753 "should be a (Y,Cb,Cr)_8 image (dim=3)",pixel_type(),dim);
13754 cimg_forXYZ(*this,x,y,z) {
13755 const int
13756 Y = (int)((*this)(x, y, z, 0)-16),
13757 Cb = (int)((*this)(x, y, z, 1)-128),
13758 Cr = (int)((*this)(x, y, z, 2)-128);
13759 const int
13760 R = ((298*Y + 409*Cr + 128) >> 8 ),
13761 G = ((298*Y - 100*Cb - 208*Cr + 128) >> 8 ),
13762 B = ((298*Y + 516*Cb + 128) >> 8 );
13763 (*this)(x,y,z,0) = (T)(R<0?0:(R>255?255:R));
13764 (*this)(x,y,z,1) = (T)(G<0?0:(G>255?255:G));
13765 (*this)(x,y,z,2) = (T)(B<0?0:(B>255?255:B));
13766 }
13767 }
13768 return *this;
13769 }
13770
13772 CImg<typename cimg::superset<T,float>::type> get_RGBtoYUV() const {
13773 typedef typename cimg::superset<T,float>::type restype;
13774 return CImg<restype>(*this,false).RGBtoYUV();
13775 }
13776
13778 CImg<T>& RGBtoYUV() {
13779 if (!is_empty()) {
13780 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoYUV() : Input image dimension is dim=%u, "
13781 "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
13782 cimg_forXYZ(*this,x,y,z) {
13783 const float
13784 R = (*this)(x,y,z,0)/255.0f,
13785 G = (*this)(x,y,z,1)/255.0f,
13786 B = (*this)(x,y,z,2)/255.0f,
13787 Y = (T)(0.299*R + 0.587*G + 0.114*B);
13788 (*this)(x,y,z,0) = (T)Y;
13789 (*this)(x,y,z,1) = (T)(0.492*(B-Y));
13790 (*this)(x,y,z,2) = (T)(0.877*(R-Y));
13791 }
13792 }
13793 return *this;
13794 }
13795
13797 CImg<T> get_YUVtoRGB() const {
13798 return (+*this).YUVtoRGB();
13799 }
13800
13802 CImg<T>& YUVtoRGB() {
13803 if (!is_empty()) {
13804 if (dim!=3) throw CImgInstanceException("CImg<%s>::YUVtoRGB() : Input image dimension is dim=%u, "
13805 "should be a (Y,U,V) image (dim=3)",pixel_type(),dim);
13806 cimg_forXYZ(*this,x,y,z) {
13807 const T Y = (*this)(x,y,z,0), U = (*this)(x,y,z,1), V = (*this)(x,y,z,2);
13808 (*this)(x,y,z,0) = (T)((Y + 1.140*V)*255.0f);
13809 (*this)(x,y,z,1) = (T)((Y - 0.395*U - 0.581*V)*255.0f);
13810 (*this)(x,y,z,2) = (T)((Y + 2.032*U)*255.0f);
13811 }
13812 }
13813 return *this;
13814 }
13815
13817 CImg<typename cimg::superset<T,float>::type> get_RGBtoXYZ() const {
13818 typedef typename cimg::superset<T,float>::type restype;
13819 return CImg<restype>(*this,false).RGBtoXYZ();
13820 }
13821
13823 CImg<T>& RGBtoXYZ() {
13824 if (!is_empty()) {
13825 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoXYZ() : Input image dimension is dim=%u, "
13826 "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
13827 cimg_forXYZ(*this,x,y,z) {
13828 const float
13829 R = (float)((*this)(x,y,z,0)/255.0f),
13830 G = (float)((*this)(x,y,z,1)/255.0f),
13831 B = (float)((*this)(x,y,z,2)/255.0f);
13832 (*this)(x,y,z,0) = (T)(0.412453*R + 0.357580*G + 0.180423*B);
13833 (*this)(x,y,z,1) = (T)(0.212671*R + 0.715160*G + 0.072169*B);
13834 (*this)(x,y,z,2) = (T)(0.019334*R + 0.119193*G + 0.950227*B);
13835 }
13836 }
13837 return *this;
13838 }
13839
13841 CImg<T> get_XYZtoRGB() const {
13842 return (+*this).XYZtoRGB();
13843 }
13844
13846 CImg<T>& XYZtoRGB() {
13847 if (!is_empty()) {
13848 if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoRGB() : Input image dimension is dim=%u, "
13849 "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
13850 cimg_forXYZ(*this,x,y,z) {
13851 const float
13852 X = (float)(255.0f*(*this)(x,y,z,0)),
13853 Y = (float)(255.0f*(*this)(x,y,z,1)),
13854 Z = (float)(255.0f*(*this)(x,y,z,2));
13855 (*this)(x,y,z,0) = (T)(3.240479*X - 1.537150*Y - 0.498535*Z);
13856 (*this)(x,y,z,1) = (T)(-0.969256*X + 1.875992*Y + 0.041556*Z);
13857 (*this)(x,y,z,2) = (T)(0.055648*X - 0.204043*Y + 1.057311*Z);
13858 }
13859 }
13860 return *this;
13861 }
13862
13864 CImg<T> get_XYZtoLab() const {
13865 return (+*this).XYZtoLab();
13866 }
13867
13869 CImg<T>& XYZtoLab() {
13870 #define cimg_Labf(x) ((x)>=0.008856?(std::pow(x,1/3.0)):(7.787*(x)+16.0/116.0))
13871 if (!is_empty()) {
13872 if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoLab() : Input image dimension is dim=%u, "
13873 "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
13874 const double
13875 Xn = 0.412453 + 0.357580 + 0.180423,
13876 Yn = 0.212671 + 0.715160 + 0.072169,
13877 Zn = 0.019334 + 0.119193 + 0.950227;
13878 cimg_forXYZ(*this,x,y,z) {
13879 const T X = (*this)(x,y,z,0), Y = (*this)(x,y,z,1), Z = (*this)(x,y,z,2);
13880 const double
13881 XXn = X/Xn, YYn = Y/Yn, ZZn = Z/Zn,
13882 fX = cimg_Labf(XXn), fY = cimg_Labf(YYn), fZ = cimg_Labf(ZZn);
13883 (*this)(x,y,z,0) = (T)(116*fY-16);
13884 (*this)(x,y,z,1) = (T)(500*(fX-fY));
13885 (*this)(x,y,z,2) = (T)(200*(fY-fZ));
13886 }
13887 }
13888 return *this;
13889 }
13890
13892 CImg<T> get_LabtoXYZ() const {
13893 return (+*this).LabtoXYZ();
13894 }
13895
13897 CImg<T>& LabtoXYZ() {
13898 #define cimg_Labfi(x) ((x)>=0.206893?((x)*(x)*(x)):(((x)-16.0/116.0)/7.787))
13899 if (!is_empty()) {
13900 if (dim!=3) throw CImgInstanceException("CImg<%s>::LabtoXYZ() : Input image dimension is dim=%u, "
13901 "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
13902 const double
13903 Xn = 0.412453 + 0.357580 + 0.180423,
13904 Yn = 0.212671 + 0.715160 + 0.072169,
13905 Zn = 0.019334 + 0.119193 + 0.950227;
13906 cimg_forXYZ(*this,x,y,z) {
13907 const T L = (*this)(x,y,z,0), a = (*this)(x,y,z,1), b = (*this)(x,y,z,2);
13908 const double
13909 cY = (L+16)/116.0,
13910 Y = Yn*cimg_Labfi(cY),
13911 pY = std::pow(Y/Yn,1.0/3),
13912 cX = a/500+pY,
13913 X = Xn*cX*cX*cX,
13914 cZ = pY-b/200,
13915 Z = Zn*cZ*cZ*cZ;
13916 (*this)(x,y,z,0) = (T)(X);
13917 (*this)(x,y,z,1) = (T)(Y);
13918 (*this)(x,y,z,2) = (T)(Z);
13919 }
13920 }
13921 return *this;
13922 }
13923
13925 CImg<T> get_XYZtoxyY() const {
13926 return (+*this).XYZtoxyY();
13927 }
13928
13930 CImg<T>& XYZtoxyY() {
13931 if (!is_empty()) {
13932 if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoxyY() : Input image dimension is dim=%u, "
13933 "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
13934 cimg_forXYZ(*this,x,y,z) {
13935 const T X = (*this)(x,y,z,0), Y = (*this)(x,y,z,1), Z = (*this)(x,y,z,2), sum = (X+Y+Z), nsum = sum>0?sum:1;
13936 (*this)(x,y,z,0) = X/nsum;
13937 (*this)(x,y,z,1) = Y/nsum;
13938 (*this)(x,y,z,2) = Y;
13939 }
13940 }
13941 return *this;
13942 }
13943
13945 CImg<T> get_xyYtoXYZ() const {
13946 return (+*this).xyYtoXYZ();
13947 }
13948
13950 CImg<T>& xyYtoXYZ() {
13951 if (!is_empty()) {
13952 if (dim!=3) throw CImgInstanceException("CImg<%s>::xyYtoXYZ() : Input image dimension is dim=%u, "
13953 "should be a (x,y,Y) image (dim=3)",pixel_type(),dim);
13954 cimg_forXYZ(*this,x,y,z) {
13955 const T px = (*this)(x,y,z,0), py = (*this)(x,y,z,1), Y = (*this)(x,y,z,2), ny = py>0?py:1;
13956 (*this)(x,y,z,0) = (T)(px*Y/ny);
13957 (*this)(x,y,z,1) = Y;
13958 (*this)(x,y,z,2) = (T)((1-px-py)*Y/ny);
13959 }
13960 }
13961 return *this;
13962 }
13963
13965 CImg<T> get_RGBtoLab() const {
13966 return (+*this).RGBtoLab();
13967 }
13968
13970 CImg<T>& RGBtoLab() {
13971 return RGBtoXYZ().XYZtoLab();
13972 }
13973
13975 CImg<T> get_LabtoRGB() const {
13976 return (+*this).LabtoRGB();
13977 }
13978
13980 CImg<T>& LabtoRGB() {
13981 return LabtoXYZ().XYZtoRGB();
13982 }
13983
13985 CImg<T> get_RGBtoxyY() const {
13986 return (+*this).RGBtoxyY();
13987 }
13988
13990 CImg<T>& RGBtoxyY() {
13991 return RGBtoXYZ().XYZtoxyY();
13992 }
13993
13995 CImg<T> get_xyYtoRGB() const {
13996 return (+*this).xyYtoRGB();
13997 }
13998
14000 CImg<T>& xyYtoRGB() {
14001 return xyYtoXYZ().XYZtoRGB();
14002 }
14003
14005
14008 CImg<T> get_RGBtoBayer() const {
14009 if (is_empty()) return *this;
14010 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoBayer() : Input image dimension is dim=%u, "
14011 "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
14012 CImg<T> res(width,height,depth,1);
14013 const T
14014 *pR = ptr(0,0,0,0),
14015 *pG = ptr(0,0,0,1),
14016 *pB = ptr(0,0,0,2);
14017 T *ptrd = res.data;
14018 cimg_forXYZ(*this,x,y,z) {
14019 if (y%2) {
14020 if (x%2) *(ptrd++) = *pB;
14021 else *(ptrd++) = *pG;
14022 } else {
14023 if (x%2) *(ptrd++) = *pG;
14024 else *(ptrd++) = *pR;
14025 }
14026 ++pR; ++pG; ++pB;
14027 }
14028 return res;
14029 }
14030
14031
14032 CImg<T>& RGBtoBayer() {
14033 return get_RGBtoBayer().assign_to(*this);
14034 }
14035
14037 CImg<T> get_BayertoRGB(const unsigned int interpolation_type=3) const {
14038 if (is_empty()) return *this;
14039 if (dim!=1) throw CImgInstanceException("CImg<%s>::BayertoRGB() : Input image dimension is dim=%u, "
14040 "should be a Bayer image (dim=1)",pixel_type(),dim);
14041 CImg<T> res(width,height,depth,3);
14042 CImg_3x3(I,T);
14043 T
14044 *pR = res.ptr(0,0,0,0),
14045 *pG = res.ptr(0,0,0,1),
14046 *pB = res.ptr(0,0,0,2);
14047 switch(interpolation_type) {
14048 case 3: {
14049 CImg_3x3(R,T);
14050 CImg_3x3(G,T);
14051 CImg_3x3(B,T);
14052 cimg_forXYZ(*this,x,y,z) {
14053 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<dimx()-1?x+1:x-1, _n1y = y<dimy()-1?y+1:y-1;
14054 cimg_get3x3(*this,x,y,z,0,I);
14055 if (y%2) {
14056 if (x%2) {
14057 const float alpha = cimg::sqr(Inc-Ipc), beta = cimg::sqr(Icn-Icp), cx = 1/(1+alpha), cy = 1/(1+beta);
14058 *pG = (T)((cx*(Inc+Ipc) + cy*(Icn+Icp))/(2*(cx+cy)));
14059 } else *pG = Icc;
14060 } else {
14061 if (x%2) *pG = Icc;
14062 else {
14063 const float alpha = cimg::sqr(Inc-Ipc), beta = cimg::sqr(Icn-Icp), cx = 1/(1+alpha), cy = 1/(1+beta);
14064 *pG = (T)((cx*(Inc+Ipc) + cy*(Icn+Icp))/(2*(cx+cy)));
14065 }
14066 }
14067 ++pG;
14068 }
14069 cimg_forXYZ(*this,x,y,z) {
14070 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<dimx()-1?x+1:x-1, _n1y = y<dimy()-1?y+1:y-1;
14071 cimg_get3x3(*this,x,y,z,0,I);
14072 cimg_get3x3(res,x,y,z,1,G);
14073 if (y%2) {
14074 if (x%2) *pB = Icc;
14075 else { *pR = (T)((Icn+Icp)/2); *pB = (T)((Inc+Ipc)/2); }
14076 } else {
14077 if (x%2) { *pR = (T)((Inc+Ipc)/2); *pB = (T)((Icn+Icp)/2); }
14078 else *pR = Icc;
14079 }
14080 ++pR; ++pB;
14081 }
14082 pR = res.ptr(0,0,0,0);
14083 pG = res.ptr(0,0,0,1);
14084 pB = res.ptr(0,0,0,2);
14085 cimg_forXYZ(*this,x,y,z) {
14086 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<dimx()-1?x+1:x-1, _n1y = y<dimy()-1?y+1:y-1;
14087 cimg_get3x3(res,x,y,z,0,R);
14088 cimg_get3x3(res,x,y,z,1,G);
14089 cimg_get3x3(res,x,y,z,2,B);
14090 if (y%2) {
14091 if (x%2) {
14092 const float alpha = cimg::sqr(Rnc-Rpc), beta = cimg::sqr(Rcn-Rcp), cx = 1/(1+alpha), cy = 1/(1+beta);
14093 *pR = (T)((cx*(Rnc+Rpc) + cy*(Rcn+Rcp))/(2*(cx+cy)));
14094 }
14095 } else {
14096 if (!(x%2)) {
14097 const float alpha = cimg::sqr(Bnc-Bpc), beta = cimg::sqr(Bcn-Bcp), cx = 1/(1+alpha), cy = 1/(1+beta);
14098 *pB = (T)((cx*(Bnc+Bpc) + cy*(Bcn+Bcp))/(2*(cx+cy)));
14099 }
14100 }
14101 ++pR; ++pG; ++pB;
14102 }
14103 } break;
14104 case 2: {
14105 cimg_forXYZ(*this,x,y,z) {
14106 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<dimx()-1?x+1:x-1, _n1y = y<dimy()-1?y+1:y-1;
14107 cimg_get3x3(*this,x,y,z,0,I);
14108 if (y%2) {
14109 if (x%2) { *pR = (Ipp+Inn+Ipn+Inp)/4; *pG = (Inc+Ipc+Icn+Icp)/4; *pB = Icc; }
14110 else { *pR = (Icp+Icn)/2; *pG = Icc; *pB = (Inc+Ipc)/2; }
14111 } else {
14112 if (x%2) { *pR = (Ipc+Inc)/2; *pG = Icc; *pB = (Icn+Icp)/2; }
14113 else { *pR = Icc; *pG = (Inc+Ipc+Icn+Icp)/4; *pB = (Ipp+Inn+Ipn+Inp)/4; }
14114 }
14115 ++pR; ++pG; ++pB;
14116 }
14117 } break;
14118 case 1: {
14119 cimg_forXYZ(*this,x,y,z) {
14120 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<dimx()-1?x+1:x-1, _n1y = y<dimy()-1?y+1:y-1;
14121 cimg_get3x3(*this,x,y,z,0,I);
14122 if (y%2) {
14123 if (x%2) { *pR = cimg::min(Ipp,Inn,Ipn,Inp); *pG = cimg::min(Inc,Ipc,Icn,Icp); *pB = Icc; }
14124 else { *pR = cimg::min(Icn,Icp); *pG = Icc; *pB = cimg::min(Inc,Ipc); }
14125 } else {
14126 if (x%2) { *pR = cimg::min(Inc,Ipc); *pG = Icc; *pB = cimg::min(Icn,Icp); }
14127 else { *pR = Icc; *pG = cimg::min(Inc,Ipc,Icn,Icp); *pB = cimg::min(Ipp,Inn,Ipn,Inp); }
14128 }
14129 ++pR; ++pG; ++pB;
14130 }
14131 } break;
14132 default: {
14133 const T *ptrs = data;
14134 res.fill(0);
14135 cimg_forXYZ(*this,x,y,z) {
14136 const T val = *(ptrs++);
14137 if (y%2) { if (x%2) *pB = val; else *pG = val; } else { if (x%2) *pG = val; else *pR = val; }
14138 ++pR; ++pG; ++pB;
14139 }
14140 } break;
14141 }
14142 return res;
14143 }
14144
14145
14146 CImg<T>& BayertoRGB(const unsigned int interpolation_type=3) {
14147 return get_BayertoRGB(interpolation_type).assign_to(*this);
14148 }
14149
14151
14152
14154
14155
14156
14157
14158
14159 template<typename tc>
14160 CImg<T>& _draw_scanline(const int x0, const int x1, const int y, const tc *const color,
14161 const float opacity=1.0f, const float brightness=1.0f, const bool init=false) {
14162 static const T maxval = cimg::type<T>::max(), minval = cimg::type<T>::min();
14163 static float nopacity = 0, copacity = 0;
14164 static unsigned int whz = 0;
14165 static const tc *col = 0;
14166 if (init) {
14167 nopacity = cimg::abs(opacity);
14168 copacity = 1.0f - cimg::max(opacity,0.0f);
14169 whz = width*height*depth;
14170 } else {
14171 const int nx0 = x0>0?x0:0, nx1 = x1<dimx()?x1:dimx()-1, dx = nx1 - nx0;
14172 if (dx>=0) {
14173 col = color;
14174 const unsigned int off = whz-dx-1;
14175 T *ptrd = ptr(nx0,y);
14176 if (opacity>=1) {
14177 if (brightness==1.0f) {
14178 if (sizeof(T)!=1) cimg_forV(*this,k) {
14179 const T val = (T)*(col++);
14180 for (int x=dx; x>=0; --x) *(ptrd++) = val;
14181 ptrd+=off;
14182 } else cimg_forV(*this,k) {
14183 const T val = (T)*(col++);
14184 std::memset(ptrd,(int)val,dx+1);
14185 ptrd+=whz;
14186 }
14187 } else {
14188 if (brightness>1.0f) {
14189 if (sizeof(T)!=1) cimg_forV(*this,k) {
14190 const float tval = (float)(*(col++)*brightness);
14191 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
14192 for (int x=dx; x>=0; --x) *(ptrd++) = val;
14193 ptrd+=off;
14194 } else cimg_forV(*this,k) {
14195 const float tval = (float)(*(col++)*brightness);
14196 const T val = tval<(float)maxval?(T)tval:maxval;
14197 std::memset(ptrd,(int)val,dx+1);
14198 ptrd+=whz;
14199 }
14200 } else {
14201 if (sizeof(T)!=1) cimg_forV(*this,k) {
14202 const T val = (T)(*(col++)*brightness);
14203 for (int x=dx; x>=0; --x) *(ptrd++) = val;
14204 ptrd+=off;
14205 } else cimg_forV(*this,k) {
14206 const T val = (T)(*(col++)*brightness);
14207 std::memset(ptrd,(int)val,dx+1);
14208 ptrd+=whz;
14209 }
14210 }
14211 }
14212 } else {
14213 if (brightness==1.0f) {
14214 cimg_forV(*this,k) {
14215 const T val = (T)*(col++);
14216 for (int x=dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; }
14217 ptrd+=off;
14218 }
14219 } else {
14220 if (brightness>1.0f) {
14221 cimg_forV(*this,k) {
14222 const float tval = (float)(*(col++)*brightness);
14223 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
14224 for (int x=dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; }
14225 ptrd+=off;
14226 }
14227 } else {
14228 cimg_forV(*this,k) {
14229 const T val = (T)(*(col++)*brightness);
14230 for (int x=dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; }
14231 ptrd+=off;
14232 }
14233 }
14234 }
14235 }
14236 }
14237 }
14238 return *this;
14239 }
14240
14241 template<typename tc>
14242 CImg<T>& _draw_scanline(const tc *const color, const float opacity=1.0f) {
14243 return _draw_scanline(0,0,0,color,opacity,1.0f,true);
14244 }
14245
14247
14263 template<typename tc>
14264 CImg<T>& draw_point(const int x0, const int y0, const tc *const color, const float opacity=1.0f) {
14265 return draw_point(x0,y0,0,color,opacity);
14266 }
14267
14268 template<typename tc>
14269 CImg<T>& draw_point(const int x0, const int y0, const CImg<tc>& color, const float opacity=1.0f) {
14270 return draw_point(x0,y0,color.data,opacity);
14271 }
14272
14274
14278 template<typename tc>
14279 CImg<T>& draw_point(const int x0, const int y0, const int z0, const tc *const color, const float opacity=1.0f) {
14280 if (!is_empty()) {
14281 if (!color) throw CImgArgumentException("CImg<%s>::draw_point() : Specified color is (null)",pixel_type());
14282 if (x0>=0 && y0>=0 && z0>=0 && x0<dimx() && y0<dimy() && z0<dimz()) {
14283 const tc *col = color;
14284 const unsigned int whz = width*height*depth;
14285 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
14286 T *ptrd = ptr(x0,y0,z0,0);
14287 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=whz; }
14288 else cimg_forV(*this,k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; }
14289 }
14290 }
14291 return *this;
14292 }
14293
14294 template<typename tc>
14295 CImg<T>& draw_point(const int x0, const int y0, const int z0, const CImg<tc>& color, const float opacity=1.0f) {
14296 return draw_point(x0,y0,z0,color.data,opacity);
14297 }
14298
14299
14300 template<typename t, typename tc>
14301 CImg<T>& _draw_point(const t& points, const tc *const color,
14302 const float opacity, const unsigned int W, const unsigned int H) {
14303 if (points && W && H>1) {
14304 if (H==2) for (unsigned int i=0; i<W; ++i) {
14305 const int x = (int)points(i,0), y = (int)points(i,1);
14306 draw_point(x,y,color,opacity);
14307 } else for (unsigned int i=0; i<W; ++i) {
14308 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
14309 draw_point(x,y,z,color,opacity);
14310 }
14311 }
14312 return *this;
14313 }
14314
14316
14336 template<typename t, typename tc>
14337 CImg<T>& draw_point(const CImgList<t>& points, const tc *const color, const float opacity=1.0f) {
14338 unsigned int H = ~0U; cimglist_for(points,p) H = cimg::min(H,(unsigned int)(points[p].size()));
14339 return _draw_point(points,color,opacity,points.size,H);
14340 }
14341
14342 template<typename t, typename tc>
14343 CImg<T>& draw_point(const CImgList<t>& points, const CImg<tc>& color, const float opacity=1.0f) {
14344 return draw_point(points,color.data,opacity);
14345 }
14346
14348
14353 template<typename t, typename tc>
14354 CImg<T>& draw_point(const CImg<t>& points, const tc *const color, const float opacity=1.0f) {
14355 return _draw_point(points,color,opacity,points.width,points.height);
14356 }
14357
14358 template<typename t, typename tc>
14359 CImg<T>& draw_point(const CImg<t>& points, const CImg<tc>& color, const float opacity=1.0f) {
14360 return draw_point(points,color.data,opacity);
14361 }
14362
14364
14384 template<typename tc>
14385 CImg<T>& draw_line(const int x0, const int y0, const int x1, const int y1,
14386 const tc *const color, const float opacity=1.0f,
14387 const unsigned int pattern=~0U, const bool init_hatch=true) {
14388 if (!is_empty()) {
14389 if (!color) throw CImgArgumentException("CImg<%s>::draw_line() : Specified color is (null)",pixel_type());
14390 static unsigned int hatch = ~0U-(~0U>>1);
14391 if (init_hatch) hatch = ~0U-(~0U>>1);
14392 const tc* col = color;
14393 const bool xdir = x0<x1, ydir = y0<y1;
14394 int
14395 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
14396 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1,
14397 &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
14398 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1,
14399 &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0;
14400 if (xright<0 || xleft>=dimx()) return *this;
14401 if (xleft<0) { yleft-=xleft*(yright-yleft)/(xright-xleft); xleft = 0; }
14402 if (xright>=dimx()) { yright-=(xright-dimx())*(yright-yleft)/(xright-xleft); xright = dimx()-1; }
14403 if (ydown<0 || yup>=dimy()) return *this;
14404 if (yup<0) { xup-=yup*(xdown-xup)/(ydown-yup); yup = 0; }
14405 if (ydown>=dimy()) { xdown-=(ydown-dimy())*(xdown-xup)/(ydown-yup); ydown = dimy()-1; }
14406 T *ptrd0 = ptr(nx0,ny0,0,0);
14407 int dx = xright-xleft, dy = ydown-yup;
14408 const bool steep = dy>dx;
14409 if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
14410 const int
14411 offx = (nx0<nx1?1:-1)*(steep?width:1),
14412 offy = (ny0<ny1?1:-1)*(steep?1:width),
14413 wh = width*height;
14414 if (opacity>=1) {
14415 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14416 T *ptrd = ptrd0;
14417 if (pattern&hatch) { cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=wh; } col-=dim; }
14418 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14419 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14420 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14421 T *ptrd = ptrd0;
14422 cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=wh; } col-=dim;
14423 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14424 }
14425 } else {
14426 const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f);
14427 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14428 T *ptrd = ptrd0;
14429 if (pattern&hatch) { cimg_forV(*this,k) { const tc& c = *(col++); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } col-=dim; }
14430 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14431 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14432 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14433 T *ptrd = ptrd0;
14434 cimg_forV(*this,k) { const tc& c = *(col++); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } col-=dim;
14435 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14436 }
14437 }
14438 }
14439 return *this;
14440 }
14441
14442 template<typename tc>
14443 CImg<T>& draw_line(const int x0, const int y0, const int x1, const int y1,
14444 const CImg<tc>& color, const float opacity=1.0f,
14445 const unsigned int pattern=~0U, const bool init_hatch=true) {
14446 return draw_line(x0,y0,x1,y1,color.data,opacity,pattern,init_hatch);
14447 }
14448
14450
14454 template<typename tc>
14455 CImg<T>& draw_line(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1,
14456 const tc *const color, const float opacity=1.0f,
14457 const unsigned int pattern=~0U, const bool init_hatch=true) {
14458 if (!is_empty()) {
14459 if (!color) throw CImgArgumentException("CImg<%s>::draw_line() : Specified color is (null)",pixel_type());
14460 static unsigned int hatch = ~0U-(~0U>>1);
14461 if (init_hatch) hatch = ~0U-(~0U>>1);
14462 const tc *col = color;
14463 int nx0 = x0, ny0 = y0, nz0 = z0, nx1 = x1, ny1 = y1, nz1 = z1;
14464 if (nx0>nx1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
14465 if (nx1<0 || nx0>=dimx()) return *this;
14466 if (nx0<0) { const int D=1+nx1-nx0; ny0-=nx0*(1+ny1-ny0)/D; nz0-=nx0*(1+nz1-nz0)/D; nx0 = 0; }
14467 if (nx1>=dimx()) { const int d=nx1-dimx(), D=1+nx1-nx0; ny1+=d*(1+ny0-ny1)/D; nz1+=d*(1+nz0-nz1)/D; nx1 = dimx()-1; }
14468 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
14469 if (ny1<0 || ny0>=dimy()) return *this;
14470 if (ny0<0) { const int D=1+ny1-ny0; nx0-=ny0*(1+nx1-nx0)/D; nz0-=ny0*(1+nz1-nz0)/D; ny0 = 0; }
14471 if (ny1>=dimy()) { const int d=ny1-dimy(), D=1+ny1-ny0; nx1+=d*(1+nx0-nx1)/D; nz1+=d*(1+nz0-nz1)/D; ny1 = dimy()-1; }
14472 if (nz0>nz1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
14473 if (nz1<0 || nz0>=dimz()) return *this;
14474 if (nz0<0) { const int D=1+nz1-nz0; nx0-=nz0*(1+nx1-nx0)/D; ny0-=nz0*(1+ny1-ny0)/D; nz0 = 0; }
14475 if (nz1>=dimz()) { const int d=nz1-dimz(), D=1+nz1-nz0; nx1+=d*(1+nx0-nx1)/D; ny1+=d*(1+ny0-ny1)/D; nz1 = dimz()-1; }
14476 const unsigned int dmax = cimg::max(cimg::abs(nx1-nx0),cimg::abs(ny1-ny0),nz1-nz0), whz = width*height*depth;
14477 const float px = (nx1-nx0)/(float)dmax, py = (ny1-ny0)/(float)dmax, pz = (nz1-nz0)/(float)dmax;
14478 float x = (float)nx0, y = (float)ny0, z = (float)nz0;
14479 if (opacity>=1) for (unsigned int t=0; t<=dmax; ++t) {
14480 if (!(~pattern) || (~pattern && pattern&hatch)) {
14481 T* ptrd = ptr((unsigned int)x,(unsigned int)y,(unsigned int)z,0);
14482 cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=whz; }
14483 col-=dim;
14484 }
14485 x+=px; y+=py; z+=pz; if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1));
14486 } else {
14487 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
14488 for (unsigned int t=0; t<=dmax; ++t) {
14489 if (!(~pattern) || (~pattern && pattern&hatch)) {
14490 T* ptrd = ptr((unsigned int)x,(unsigned int)y,(unsigned int)z,0);
14491 cimg_forV(*this,k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; }
14492 col-=dim;
14493 }
14494 x+=px; y+=py; z+=pz; if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1));
14495 }
14496 }
14497 }
14498 return *this;
14499 }
14500
14501 template<typename tc>
14502 CImg<T>& draw_line(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1,
14503 const CImg<tc>& color, const float opacity=1.0f,
14504 const unsigned int pattern=~0U, const bool init_hatch=true) {
14505 return draw_line(x0,y0,z0,x1,y1,z1,color.data,opacity,pattern,init_hatch);
14506 }
14507
14509
14532 template<typename t>
14533 CImg<T>& draw_line(const int x0, const int y0, const int x1, const int y1,
14534 const CImg<t>& texture,
14535 const int tx0, const int ty0, const int tx1, const int ty1,
14536 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14537 if (!is_empty()) {
14538 if (!texture || texture.dim<dim)
14539 throw CImgArgumentException("CImg<%s>::draw_line() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
14540 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
14541 if (is_overlapping(texture)) return draw_line(x0,y0,x1,y1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);
14542 static unsigned int hatch = ~0U-(~0U>>1);
14543 if (init_hatch) hatch = ~0U-(~0U>>1);
14544 const bool xdir = x0<x1, ydir = y0<y1;
14545 int
14546 dtx = tx1-tx0, dty = ty1-ty0,
14547 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
14548 tnx0 = tx0, tnx1 = tx1, tny0 = ty0, tny1 = ty1,
14549 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1, &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
14550 &txleft = xdir?tnx0:tnx1, &tyleft = xdir?tny0:tny1, &txright = xdir?tnx1:tnx0, &tyright = xdir?tny1:tny0,
14551 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1, &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0,
14552 &txup = ydir?tnx0:tnx1, &tyup = ydir?tny0:tny1, &txdown = ydir?tnx1:tnx0, &tydown = ydir?tny1:tny0;
14553 if (xright<0 || xleft>=dimx()) return *this;
14554 if (xleft<0) {
14555 const int D = xright-xleft;
14556 yleft-=xleft*(yright-yleft)/D;
14557 txleft-=xleft*(txright-txleft)/D;
14558 tyleft-=xleft*(tyright-tyleft)/D;
14559 xleft = 0;
14560 }
14561 if (xright>=dimx()) {
14562 const int d = xright-dimx(), D = xright-xleft;
14563 yright-=d*(yright-yleft)/D;
14564 txright-=d*(txright-txleft)/D;
14565 tyright-=d*(tyright-tyleft)/D;
14566 xright = dimx()-1;
14567 }
14568 if (ydown<0 || yup>=dimy()) return *this;
14569 if (yup<0) {
14570 const int D = ydown-yup;
14571 xup-=yup*(xdown-xup)/D;
14572 txup-=yup*(txdown-txup)/D;
14573 tyup-=yup*(tydown-tyup)/D;
14574 yup = 0;
14575 }
14576 if (ydown>=dimy()) {
14577 const int d = ydown-dimy(), D = ydown-yup;
14578 xdown-=d*(xdown-xup)/D;
14579 txdown-=d*(txdown-txup)/D;
14580 tydown-=d*(tydown-tyup)/D;
14581 ydown = dimy()-1;
14582 }
14583 T *ptrd0 = ptr(nx0,ny0,0,0);
14584 int dx = xright-xleft, dy = ydown-yup;
14585 const bool steep = dy>dx;
14586 if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
14587 const int
14588 offx = (nx0<nx1?1:-1)*(steep?width:1),
14589 offy = (ny0<ny1?1:-1)*(steep?1:width),
14590 wh = width*height,
14591 ndx = dx>0?dx:1;
14592 if (opacity>=1) {
14593 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14594 T *ptrd = ptrd0;
14595 if (pattern&hatch) {
14596 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
14597 cimg_forV(*this,k) { *ptrd = texture(tx,ty,0,k); ptrd+=wh; }
14598 }
14599 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14600 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14601 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14602 T *ptrd = ptrd0;
14603 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
14604 cimg_forV(*this,k) { *ptrd = texture(tx,ty,0,k); ptrd+=wh; }
14605 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14606 }
14607 } else {
14608 const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f);
14609 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14610 T *ptrd = ptrd0;
14611 if (pattern&hatch) {
14612 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
14613 cimg_forV(*this,k) { const T c = (T)texture(tx,ty,0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; }
14614 }
14615 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14616 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14617 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14618 T *ptrd = ptrd0;
14619 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
14620 cimg_forV(*this,k) { const T c = (T)texture(tx,ty,0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; }
14621 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14622 }
14623 }
14624 }
14625 return *this;
14626 }
14627
14629 template<typename t>
14630 CImg<T>& draw_line(const int x0, const int y0, const float z0, const int x1, const int y1, const float z1,
14631 const CImg<t>& texture,
14632 const int tx0, const int ty0, const int tx1, const int ty1,
14633 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14634 if (!is_empty() && z0>0 && z1>0) {
14635 if (!texture || texture.dim<dim)
14636 throw CImgArgumentException("CImg<%s>::draw_line() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
14637 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
14638 if (is_overlapping(texture)) return draw_line(x0,y0,z0,x1,y1,z1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);
14639 static unsigned int hatch = ~0U-(~0U>>1);
14640 if (init_hatch) hatch = ~0U-(~0U>>1);
14641 const bool xdir = x0<x1, ydir = y0<y1;
14642 int
14643 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
14644 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1,
14645 &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
14646 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1,
14647 &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0;
14648 float
14649 Tx0 = tx0/z0, Tx1 = tx1/z1,
14650 Ty0 = ty0/z0, Ty1 = ty1/z1,
14651 Z0 = 1.0f/z0, Z1 = 1.0f/z1,
14652 dz = Z1-Z0, dtx = Tx1-Tx0, dty = Ty1-Ty0,
14653 tnx0 = Tx0, tnx1 = Tx1, tny0 = Ty0, tny1 = Ty1, nz0 = Z0, nz1 = Z1,
14654 &zleft = xdir?nz0:nz1, &txleft = xdir?tnx0:tnx1, &tyleft = xdir?tny0:tny1,
14655 &zright = xdir?nz1:nz0, &txright = xdir?tnx1:tnx0, &tyright = xdir?tny1:tny0,
14656 &zup = ydir?nz0:nz1, &txup = ydir?tnx0:tnx1, &tyup = ydir?tny0:tny1,
14657 &zdown = ydir?nz1:nz0, &txdown = ydir?tnx1:tnx0, &tydown = ydir?tny1:tny0;
14658
14659 if (xright<0 || xleft>=dimx()) return *this;
14660 if (xleft<0) {
14661 const int D = xright-xleft;
14662 yleft-=xleft*(yright-yleft)/D;
14663 zleft-=xleft*(zright-zleft)/D;
14664 txleft-=xleft*(txright-txleft)/D;
14665 tyleft-=xleft*(tyright-tyleft)/D;
14666 xleft = 0;
14667 }
14668 if (xright>=dimx()) {
14669 const int d = xright-dimx(), D = xright-xleft;
14670 yright-=d*(yright-yleft)/D;
14671 zright-=d*(zright-zleft)/D;
14672 txright-=d*(txright-txleft)/D;
14673 tyright-=d*(tyright-tyleft)/D;
14674 xright = dimx()-1;
14675 }
14676 if (ydown<0 || yup>=dimy()) return *this;
14677 if (yup<0) {
14678 const int D = ydown-yup;
14679 xup-=yup*(xdown-xup)/D;
14680 zup-=yup*(zdown-zup)/D;
14681 txup-=yup*(txdown-txup)/D;
14682 tyup-=yup*(tydown-tyup)/D;
14683 yup = 0;
14684 }
14685 if (ydown>=dimy()) {
14686 const int d = ydown-dimy(), D = ydown-yup;
14687 xdown-=d*(xdown-xup)/D;
14688 zdown-=d*(zdown-zup)/D;
14689 txdown-=d*(txdown-txup)/D;
14690 tydown-=d*(tydown-tyup)/D;
14691 ydown = dimy()-1;
14692 }
14693 T *ptrd0 = ptr(nx0,ny0,0,0);
14694 int dx = xright-xleft, dy = ydown-yup;
14695 const bool steep = dy>dx;
14696 if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
14697 const int
14698 offx = (nx0<nx1?1:-1)*(steep?width:1),
14699 offy = (ny0<ny1?1:-1)*(steep?1:width),
14700 wh = width*height,
14701 ndx = dx>0?dx:1;
14702 if (opacity>=1) {
14703 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14704 T *ptrd = ptrd0;
14705 if (pattern&hatch) {
14706 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
14707 cimg_forV(*this,k) { *ptrd = texture((int)(tx/z),(int)(ty/z),0,k); ptrd+=wh; }
14708 }
14709 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14710 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14711 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14712 T *ptrd = ptrd0;
14713 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
14714 cimg_forV(*this,k) { *ptrd = texture((int)(tx/z),(int)(ty/z),0,k); ptrd+=wh; }
14715 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14716 }
14717 } else {
14718 const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f);
14719 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14720 T *ptrd = ptrd0;
14721 if (pattern&hatch) {
14722 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
14723 cimg_forV(*this,k) { const T c = (T)texture((int)(tx/z),(int)(ty/z),0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; }
14724 }
14725 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14726 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14727 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14728 T *ptrd = ptrd0;
14729 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
14730 cimg_forV(*this,k) { const T c = (T)texture((int)(tx/z),(int)(ty/z),0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; }
14731 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14732 }
14733 }
14734 }
14735 return *this;
14736 }
14737
14738
14739 template<typename t, typename tc>
14740 CImg<T>& _draw_line(const t& points, const tc *const color,
14741 const float opacity, const unsigned int pattern, const bool init_hatch,
14742 const unsigned int W, const unsigned int H) {
14743 bool ninit_hatch = init_hatch;
14744 if (points && W>1 && H>1) {
14745 if (H==2) {
14746 const int x0 = (int)points(0,0), y0 = (int)points(0,1);
14747 int ox = x0, oy = y0;
14748 for (unsigned int i=1; i<W; ++i) {
14749 const int x = (int)points(i,0), y = (int)points(i,1);
14750 draw_line(ox,oy,x,y,color,opacity,pattern,ninit_hatch);
14751 ninit_hatch = false;
14752 ox = x; oy = y;
14753 }
14754 } else {
14755 const int x0 = (int)points(0,0), y0 = (int)points(0,1), z0 = (int)points(0,2);
14756 int ox = x0, oy = y0, oz = z0;
14757 for (unsigned int i=1; i<W; ++i) {
14758 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
14759 draw_line(ox,oy,oz,x,y,z,color,opacity,pattern,ninit_hatch);
14760 ninit_hatch = false;
14761 ox = x; oy = y; oz = z;
14762 }
14763 }
14764 }
14765 return *this;
14766 }
14767
14769
14791 template<typename t, typename tc>
14792 CImg<T>& draw_line(const CImgList<t>& points, const tc *const color,
14793 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14794 unsigned int H = ~0U; cimglist_for(points,p) H = cimg::min(H,(unsigned int)(points[p].size()));
14795 return _draw_line(points,color,opacity,pattern,init_hatch,points.size,H);
14796 }
14797
14798 template<typename t, typename tc>
14799 CImg<T>& draw_line(const CImgList<t>& points, const CImg<tc>& color,
14800 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14801 return draw_line(points,color.data,opacity,pattern,init_hatch);
14802 }
14803
14805
14810 template<typename t, typename tc>
14811 CImg<T>& draw_line(const CImg<t>& points, const tc *const color,
14812 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14813 return _draw_line(points,color,opacity,pattern,init_hatch,points.width,points.height);
14814 }
14815
14816 template<typename t, typename tc>
14817 CImg<T>& draw_line(const CImg<t>& points, const CImg<tc>& color,
14818 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14819 return draw_line(points,color.data,opacity,pattern,init_hatch);
14820 }
14821
14822
14823 template<typename t, typename tc>
14824 CImg<T>& _draw_polygon(const t& points, const tc *const color, const float opacity, const unsigned int N) {
14825 if (!is_empty() && N>2) {
14826 if (!color) throw CImgArgumentException("CImg<%s>::draw_polygon() : Specified color is (null).",pixel_type());
14827 _draw_scanline(color,opacity);
14828 int xmin = (int)(~0U>>1), xmax = 0, ymin = (int)(~0U>>1), ymax = 0;
14829 { for (unsigned int p=0; p<N; ++p) {
14830 const int x = (int)points(p,0), y = (int)points(p,1);
14831 if (x<xmin) xmin = x;
14832 if (x>xmax) xmax = x;
14833 if (y<ymin) ymin = y;
14834 if (y>ymax) ymax = y;
14835 }}
14836 if (xmax<0 || xmin>=dimx() || ymax<0 || ymin>=dimx()) return *this;
14837 const unsigned int
14838 nymin = ymin<0?0:(unsigned int)ymin,
14839 nymax = ymax>=dimy()?height-1:(unsigned int)ymax,
14840 dy = 1 + nymax - nymin;
14841 typedef typename cimg::last<T,int>::type cint;
14842 CImg<cint> X(1+N,dy,1,2,0), done(N,2,1,1,0), tmp;
14843 int ox = (int)points(0,0), oy = (int)points(0,1), op = 0;
14844 for (unsigned int p=1; p<=N; ++p) {
14845 const int cp = p!=N?p:0, cx = (int)points(cp,0), cy = (int)points(cp,1),
14846 y0 = oy-nymin, y1 = cy-nymin, dir = (y1>y0?0:1);
14847 for (int x=ox, y=y0, _sx=1, _sy=1,
14848 _dx = cx>ox?cx-ox:((_sx=-1),ox-cx),
14849 _dy = y1>y0?y1-y0:((_sy=-1),y0-y1),
14850 _counter = ((_dx-=_dy?_dy*(_dx/_dy):0),_dy),
14851 _err = _dx>>1,
14852 _rx = _dy?(cx-ox)/_dy:0;
14853 _counter>0;
14854 --_counter, y+=_sy, x+=_rx + ((_err-=_dx)<0?_err+=_dy,_sx:0))
14855 if (y>=0 && y<=(int)dy && y!=y0) X(++X(0,y,dir),y,dir) = x;
14856 if (!done(op,dir)) { X(++X(0,y0,dir),y0,dir) = ox; ++done(op,dir); }
14857 if (!done(cp,dir)) { X(++X(0,y1,dir),y1,dir) = cx; ++done(cp,dir); }
14858 ox = cx; oy = cy; op = cp;
14859 }
14860 for (int y=0; y<(int)dy; ++y) {
14861 tmp.assign(X.ptr(1,y,0),X(0,y,0),1,1,1,true).sort();
14862 tmp.assign(X.ptr(1,y,1),X(0,y,1),1,1,1,true).sort();
14863 for (int i=X(0,y,0); i>=1; --i) {
14864 const int xb = X(i,y,0), xe = X(i,y,1);
14865 if (xe>xb) _draw_scanline(xb,xe,nymin+y,color,opacity);
14866 else _draw_scanline(xe,xb,nymin+y,color,opacity);
14867 }
14868 }
14869 }
14870 return *this;
14871 }
14872
14874 template<typename t, typename tc>
14875 CImg<T>& draw_polygon(const CImgList<t>& points, const tc *const color, const float opacity=1.0f) {
14876 return _draw_polygon(points,color,opacity,points.size);
14877 }
14878
14879 template<typename t, typename tc>
14880 CImg<T>& draw_polygon(const CImgList<t>& points, const CImg<tc>& color, const float opacity=1.0f) {
14881 return draw_polygon(points,color.data,opacity);
14882 }
14883
14885 template<typename t, typename tc>
14886 CImg<T>& draw_polygon(const CImg<t>& points, const tc *const color, const float opacity=1.0f) {
14887 return _draw_polygon(points,color,opacity,points.width);
14888 }
14889
14890 template<typename t, typename tc>
14891 CImg<T>& draw_polygon(const CImg<t>& points, const CImg<tc>& color, const float opacity=1.0f) {
14892 return draw_polygon(points,color.data,opacity);
14893 }
14894
14895
14896 template<typename t, typename tc>
14897 CImg<T>& _draw_polygon(const t& points, const tc *const color,
14898 const float opacity, const unsigned int pattern,
14899 const unsigned int W, const unsigned int H) {
14900 bool ninit_hatch = true;
14901 if (points && W>2 && H>1) {
14902 if (H==2) {
14903 const int x0 = (int)points(0,0), y0 = (int)points(0,1);
14904 int ox = x0, oy = y0;
14905 for (unsigned int i=1; i<W; ++i) {
14906 const int x = (int)points(i,0), y = (int)points(i,1);
14907 draw_line(ox,oy,x,y,color,opacity,pattern,ninit_hatch);
14908 ninit_hatch = false;
14909 ox = x; oy = y;
14910 }
14911 draw_line(ox,oy,x0,y0,color,opacity,pattern,false);
14912 } else {
14913 const int x0 = (int)points(0,0), y0 = (int)points(0,1), z0 = (int)points(0,2);
14914 int ox = x0, oy = y0, oz = z0;
14915 for (unsigned int i=1; i<W; ++i) {
14916 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
14917 draw_line(ox,oy,oz,x,y,z,color,opacity,pattern,ninit_hatch);
14918 ninit_hatch = false;
14919 ox = x; oy = y; oz = z;
14920 }
14921 draw_line(ox,oy,oz,x0,y0,z0,color,opacity,pattern,false);
14922 }
14923 }
14924 return *this;
14925 }
14926
14927
14928 template<typename t, typename tc>
14929 CImg<T>& draw_polygon(const CImgList<t>& points, const tc *const color,
14930 const float opacity, const unsigned int pattern) {
14931 unsigned int H = ~0U; cimglist_for(points,p) H = cimg::min(H,(unsigned int)(points[p].size()));
14932 return _draw_polygon(points,color,opacity,pattern,points.size,H);
14933 }
14934
14935 template<typename t, typename tc>
14936 CImg<T>& draw_polygon(const CImgList<t>& points, const CImg<tc>& color,
14937 const float opacity, const unsigned int pattern) {
14938 return draw_polygon(points,color.data,opacity,pattern);
14939 }
14940
14941
14942 template<typename t, typename tc>
14943 CImg<T>& draw_polygon(const CImg<t>& points, const tc *const color,
14944 const float opacity, const unsigned int pattern) {
14945 return _draw_polygon(points,color,opacity,pattern,points.width,points.height);
14946 }
14947
14948 template<typename t, typename tc>
14949 CImg<T>& draw_polygon(const CImg<t>& points, const CImg<tc>& color,
14950 const float opacity, const unsigned int pattern) {
14951 return draw_polygon(points,color.data,opacity,pattern);
14952 }
14953
14955
14986 template<typename tc>
14987 CImg<T>& draw_spline(const int x0, const int y0, const float u0, const float v0,
14988 const int x1, const int y1, const float u1, const float v1,
14989 const tc *const color,
14990 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
14991 const bool init_hatch=true) {
14992 if (!is_empty()) {
14993 if (!color) throw CImgArgumentException("CImg<%s>::draw_spline() : Specified color is (null)",pixel_type());
14994 bool ninit_hatch = init_hatch;
14995 const float
14996 dx = (float)(x1-x0),
14997 dy = (float)(y1-y0),
14998 dmax = cimg::max(cimg::abs(dx),cimg::abs(dy)),
14999 ax = -2*dx + u0 + u1,
15000 bx = 3*dx - 2*u0 - u1,
15001 ay = -2*dy + v0 + v1,
15002 by = 3*dy - 2*v0 - v1,
15003 xprecision = dmax>0?precision/dmax:1.0f,
15004 tmax = 1.0f + (dmax>0?xprecision:0.0f);
15005 int ox = x0, oy = y0;
15006 for (float t=0.0f; t<tmax; t+=xprecision) {
15007 const float
15008 t2 = t*t,
15009 t3 = t2*t;
15010 const int
15011 nx = (int)(ax*t3 + bx*t2 + u0*t + x0),
15012 ny = (int)(ay*t3 + by*t2 + v0*t + y0);
15013 draw_line(ox,oy,nx,ny,color,opacity,pattern,ninit_hatch);
15014 ninit_hatch = false;
15015 ox = nx; oy = ny;
15016 }
15017 }
15018 return *this;
15019 }
15020
15021 template<typename tc>
15022 CImg<T>& draw_spline(const int x0, const int y0, const float u0, const float v0,
15023 const int x1, const int y1, const float u1, const float v1,
15024 const CImg<tc>& color,
15025 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
15026 const bool init_hatch=true) {
15027 return draw_spline(x0,y0,u0,v0,x1,y1,u1,v1,color.data,precision,opacity,pattern,init_hatch);
15028 }
15029
15031
15035 template<typename tc>
15036 CImg<T>& draw_spline(const int x0, const int y0, const int z0, const float u0, const float v0, const float w0,
15037 const int x1, const int y1, const int z1, const float u1, const float v1, const float w1,
15038 const tc *const color,
15039 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
15040 const bool init_hatch=true) {
15041 if (!is_empty()) {
15042 if (!color) throw CImgArgumentException("CImg<%s>::draw_spline() : Specified color is (null)",pixel_type());
15043 bool ninit_hatch = init_hatch;
15044 const float
15045 dx = (float)(x1-x0),
15046 dy = (float)(y1-y0),
15047 dz = (float)(z1-z0),
15048 dmax = cimg::max(cimg::abs(dx),cimg::abs(dy),cimg::abs(dz)),
15049 ax = -2*dx + u0 + u1,
15050 bx = 3*dx - 2*u0 - u1,
15051 ay = -2*dy + v0 + v1,
15052 by = 3*dy - 2*v0 - v1,
15053 az = -2*dz + w0 + w1,
15054 bz = 3*dz - 2*w0 - w1,
15055 xprecision = dmax>0?precision/dmax:1.0f,
15056 tmax = 1.0f + (dmax>0?xprecision:0.0f);
15057 int ox = x0, oy = y0, oz = z0;
15058 for (float t=0.0f; t<tmax; t+=xprecision) {
15059 const float
15060 t2 = t*t,
15061 t3 = t2*t;
15062 const int
15063 nx = (int)(ax*t3 + bx*t2 + u0*t + x0),
15064 ny = (int)(ay*t3 + by*t2 + v0*t + y0),
15065 nz = (int)(az*t3 + bz*t2 + w0*t + z0);
15066 draw_line(ox,oy,oz,nx,ny,nz,color,opacity,pattern,ninit_hatch);
15067 ninit_hatch = false;
15068 ox = nx; oy = ny; oz = nz;
15069 }
15070 }
15071 return *this;
15072 }
15073
15074 template<typename tc>
15075 CImg<T>& draw_spline(const int x0, const int y0, const int z0, const float u0, const float v0, const float w0,
15076 const int x1, const int y1, const int z1, const float u1, const float v1, const float w1,
15077 const CImg<tc>& color,
15078 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
15079 const bool init_hatch=true) {
15080 return draw_spline(x0,y0,z0,u0,v0,w0,x1,y1,z1,u1,v1,w1,color.data,precision,opacity,pattern,init_hatch);
15081 }
15082
15084
15103 template<typename t>
15104 CImg<T>& draw_spline(const int x0, const int y0, const float u0, const float v0,
15105 const int x1, const int y1, const float u1, const float v1,
15106 const CImg<t>& texture,
15107 const int tx0, const int ty0, const int tx1, const int ty1,
15108 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
15109 const bool init_hatch=true) {
15110 if (!is_empty()) {
15111 if (!texture || texture.dim<dim)
15112 throw CImgArgumentException("CImg<%s>::draw_line() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
15113 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
15114 if (is_overlapping(texture)) return draw_spline(x0,y0,u0,v0,x1,y1,u1,v1,+texture,tx0,ty0,tx1,ty1,precision,opacity,pattern,init_hatch);
15115 bool ninit_hatch = true;
15116 const float
15117 dx = (float)(x1-x0),
15118 dy = (float)(y1-y0),
15119 dmax = cimg::max(cimg::abs(dx),cimg::abs(dy)),
15120 ax = -2*dx + u0 + u1,
15121 bx = 3*dx - 2*u0 - u1,
15122 ay = -2*dy + v0 + v1,
15123 by = 3*dy - 2*v0 - v1,
15124 xprecision = dmax>0?precision/dmax:1.0f,
15125 tmax = 1.0f + (dmax>0?xprecision:0.0f);
15126 int ox = x0, oy = y0, otx = tx0, oty = ty0;
15127 for (float t1=0.0f; t1<tmax; t1+=xprecision) {
15128 const float
15129 t2 = t1*t1,
15130 t3 = t2*t1;
15131 const int
15132 nx = (int)(ax*t3 + bx*t2 + u0*t1 + x0),
15133 ny = (int)(ay*t3 + by*t2 + v0*t1 + y0),
15134 ntx = tx0 + (int)((tx1-tx0)*t1/tmax),
15135 nty = ty0 + (int)((ty1-ty0)*t1/tmax);
15136 draw_line(ox,oy,nx,ny,texture,otx,oty,ntx,nty,opacity,pattern,ninit_hatch);
15137 ninit_hatch = false;
15138 ox = nx; oy = ny; otx = ntx; oty = nty;
15139 }
15140 }
15141 return *this;
15142 }
15143
15144
15145 template<typename tp, typename tt, typename tc>
15146 CImg<T>& _draw_spline(const tp& points, const tt& tangents,
15147 const tc *const color, const bool close_set,
15148 const float precision, const float opacity, const unsigned int pattern, const bool init_hatch,
15149 const unsigned int W, const unsigned int H) {
15150 bool ninit_hatch = init_hatch;
15151 if (points && tangents && W>1 && H>1) {
15152 if (H==2) {
15153 const int x0 = (int)points(0,0), y0 = (int)points(0,1);
15154 const float u0 = (float)tangents(0,0), v0 = (float)tangents(0,1);
15155 int ox = x0, oy = y0;
15156 float ou = u0, ov = v0;
15157 for (unsigned int i=1; i<W; ++i) {
15158 const int x = (int)points(i,0), y = (int)points(i,1);
15159 const float u = (float)tangents(i,0), v = (float)tangents(i,1);
15160 draw_spline(ox,oy,ou,ov,x,y,u,v,color,precision,opacity,pattern,ninit_hatch);
15161 ninit_hatch = false;
15162 ox = x; oy = y; ou = u; ov = v;
15163 }
15164 if (close_set) draw_spline(ox,oy,ou,ov,x0,y0,u0,v0,color,precision,opacity,pattern,false);
15165 } else {
15166 const int x0 = (int)points(0,0), y0 = (int)points(0,1), z0 = (int)points(0,2);
15167 const float u0 = (float)tangents(0,0), v0 = (float)tangents(0,1), w0 = (float)tangents(0,2);
15168 int ox = x0, oy = y0, oz = z0;
15169 float ou = u0, ov = v0, ow = w0;
15170 for (unsigned int i=1; i<W; ++i) {
15171 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
15172 const float u = (float)tangents(i,0), v = (float)tangents(i,1), w = (float)tangents(i,2);
15173 draw_spline(ox,oy,oz,ou,ov,ow,x,y,z,u,v,w,color,opacity,pattern,ninit_hatch);
15174 ninit_hatch = false;
15175 ox = x; oy = y; oz = z; ou = u; ov = v; ow = w;
15176 }
15177 if (close_set) draw_spline(ox,oy,oz,ou,ov,ow,x0,y0,z0,u0,v0,w0,color,precision,opacity,pattern,false);
15178 }
15179 }
15180 return *this;
15181 }
15182
15183 template<typename tp, typename tc>
15184 CImg<T>& _draw_spline(const tp& points,
15185 const tc *const color, const bool close_set,
15186 const float precision, const float opacity, const unsigned int pattern, const bool init_hatch,
15187 const unsigned int W, const unsigned int H) {
15188 typedef typename cimg::superset<T,float>::type ftype;
15189 CImg<ftype> tangents;
15190 if (points && W>1 && H>1) {
15191 if (H==2) {
15192 tangents.assign(W,H);
15193 for (unsigned int p=0; p<W; ++p) {
15194 const unsigned int
15195 p0 = close_set?(p+W-1)%W:(p?p-1:0),
15196 p1 = close_set?(p+1)%W:(p+1<W?p+1:p);
15197 const float
15198 x = (float)points(p,0),
15199 y = (float)points(p,1),
15200 x0 = (float)points(p0,0),
15201 y0 = (float)points(p0,1),
15202 x1 = (float)points(p1,0),
15203 y1 = (float)points(p1,1),
15204 u0 = x-x0,
15205 v0 = y-y0,
15206 n0 = 1e-8f + (float)std::sqrt(u0*u0+v0*v0),
15207 u1 = x1-x,
15208 v1 = y1-y,
15209 n1 = 1e-8f + (float)std::sqrt(u1*u1+v1*v1),
15210 u = u0/n0 + u1/n1,
15211 v = v0/n0 + v1/n1,
15212 n = 1e-8f + (float)std::sqrt(u*u+v*v),
15213 fact = 0.5f*(n0 + n1);
15214 tangents(p,0) = (ftype)(fact*u/n);
15215 tangents(p,1) = (ftype)(fact*v/n);
15216 }
15217 } else {
15218 tangents.assign(W,H);
15219 for (unsigned int p=0; p<W; ++p) {
15220 const unsigned int
15221 p0 = close_set?(p+W-1)%W:(p?p-1:0),
15222 p1 = close_set?(p+1)%W:(p+1<W?p+1:p);
15223 const float
15224 x = (float)points(p,0),
15225 y = (float)points(p,1),
15226 z = (float)points(p,2),
15227 x0 = (float)points(p0,0),
15228 y0 = (float)points(p0,1),
15229 z0 = (float)points(p0,2),
15230 x1 = (float)points(p1,0),
15231 y1 = (float)points(p1,1),
15232 z1 = (float)points(p1,2),
15233 u0 = x-x0,
15234 v0 = y-y0,
15235 w0 = z-z0,
15236 n0 = 1e-8f + (float)std::sqrt(u0*u0+v0*v0+w0*w0),
15237 u1 = x1-x,
15238 v1 = y1-y,
15239 w1 = z1-z,
15240 n1 = 1e-8f + (float)std::sqrt(u1*u1+v1*v1+w1*w1),
15241 u = u0/n0 + u1/n1,
15242 v = v0/n0 + v1/n1,
15243 w = w0/n0 + w1/n1,
15244 n = 1e-8f + (float)std::sqrt(u*u+v*v+w*w),
15245 fact = 0.5f*(n0 + n1);
15246 tangents(p,0) = (ftype)(fact*u/n);
15247 tangents(p,1) = (ftype)(fact*v/n);
15248 tangents(p,2) = (ftype)(fact*w/n);
15249 }
15250 }
15251 _draw_spline(points,tangents,color,close_set,precision,opacity,pattern,init_hatch,W,H);
15252 }
15253 return *this;
15254 }
15255
15257 template<typename tp, typename tt, typename tc>
15258 CImg<T>& draw_spline(const CImgList<tp>& points, const CImgList<tt>& tangents,
15259 const tc *const color, const bool close_set=false,
15260 const float precision=4.0f, const float opacity=1.0f,
15261 const unsigned int pattern=~0U, const bool init_hatch=true) {
15262 unsigned int H = ~0U; cimglist_for(points,p) H = cimg::min(H,(unsigned int)(points[p].size()),(unsigned int)(tangents[p].size()));
15263 return _draw_spline(points,tangents,color,close_set,precision,opacity,pattern,init_hatch,points.size,H);
15264 }
15265
15266 template<typename tp, typename tt, typename tc>
15267 CImg<T>& draw_spline(const CImgList<tp>& points, const CImgList<tt>& tangents,
15268 const CImg<tc>& color, const bool close_set=false,
15269 const float precision=4.0f, const float opacity=1.0f,
15270 const unsigned int pattern=~0U, const bool init_hatch=true) {
15271 return draw_spline(points,tangents,color.data,close_set,precision,opacity,pattern,init_hatch);
15272 }
15273
15275 template<typename tp, typename tt, typename tc>
15276 CImg<T>& draw_spline(const CImg<tp>& points, const CImg<tt>& tangents,
15277 const tc *const color, const bool close_set=false,
15278 const float precision=4.0f, const float opacity=1.0f,
15279 const unsigned int pattern=~0U, const bool init_hatch=true) {
15280 return _draw_spline(points,tangents,color,close_set,precision,opacity,pattern,init_hatch,points.width,points.height);
15281 }
15282
15283 template<typename tp, typename tt, typename tc>
15284 CImg<T>& draw_spline(const CImg<tp>& points, const CImg<tt>& tangents,
15285 const CImg<tc>& color, const bool close_set=false,
15286 const float precision=4.0f, const float opacity=1.0f,
15287 const unsigned int pattern=~0U, const bool init_hatch=true) {
15288 return draw_spline(points,tangents,color.data,close_set,precision,opacity,pattern,init_hatch);
15289 }
15290
15292 template<typename t, typename tc>
15293 CImg<T>& draw_spline(const CImgList<t>& points, const tc *const color,
15294 const bool close_set=false, const float precision=4.0f, const float opacity=1.0f,
15295 const unsigned int pattern=~0U, const bool init_hatch=true) {
15296 unsigned int H = ~0U;
15297 cimglist_for(points,p) {
15298 const unsigned int s = points[p].size();
15299 if (s<H) H = s;
15300 }
15301 return _draw_spline(points,color,close_set,precision,opacity,pattern,init_hatch,points.size,H);
15302 }
15303
15304 template<typename t, typename tc>
15305 CImg<T>& draw_spline(const CImgList<t>& points, CImg<tc>& color,
15306 const bool close_set=false, const float precision=4.0f, const float opacity=1.0f,
15307 const unsigned int pattern=~0U, const bool init_hatch=true) {
15308 return draw_spline(points,color.data,close_set,precision,opacity,pattern,init_hatch);
15309 }
15310
15312 template<typename t, typename tc>
15313 CImg<T>& draw_spline(const CImg<t>& points, const tc *const color,
15314 const bool close_set=false, const float precision=4.0f, const float opacity=1.0f,
15315 const unsigned int pattern=~0U, const bool init_hatch=true) {
15316 return _draw_spline(points,color,close_set,precision,opacity,pattern,init_hatch,points.width,points.height);
15317 }
15318
15319 template<typename t, typename tc>
15320 CImg<T>& draw_spline(const CImg<t>& points, const CImg<tc>& color,
15321 const bool close_set=false, const float precision=4.0f, const float opacity=1.0f,
15322 const unsigned int pattern=~0U, const bool init_hatch=true) {
15323 return draw_spline(points,color.data,close_set,precision,opacity,pattern,init_hatch);
15324 }
15325
15327
15340 template<typename tc>
15341 CImg<T>& draw_arrow(const int x0, const int y0, const int x1, const int y1,
15342 const tc *const color,
15343 const float angle=30, const float length=-10,
15344 const float opacity=1.0f, const unsigned int pattern=~0U) {
15345 if (!is_empty()) {
15346 const float u = (float)(x0-x1), v = (float)(y0-y1), sq = u*u+v*v,
15347 deg = (float)(angle*cimg::PI/180), ang = (sq>0)?(float)std::atan2(v,u):0.0f,
15348 l = (length>=0)?length:-length*(float)std::sqrt(sq)/100;
15349 if (sq>0) {
15350 const double cl = std::cos(ang-deg), sl = std::sin(ang-deg), cr = std::cos(ang+deg), sr = std::sin(ang+deg);
15351 const int
15352 xl = x1+(int)(l*cl), yl = y1+(int)(l*sl),
15353 xr = x1+(int)(l*cr), yr = y1+(int)(l*sr),
15354 xc = x1+(int)((l+1)*(cl+cr))/2, yc = y1+(int)((l+1)*(sl+sr))/2;
15355 draw_line(x0,y0,xc,yc,color,opacity,pattern).draw_triangle(x1,y1,xl,yl,xr,yr,color,opacity);
15356 } else draw_point(x0,y0,color,opacity);
15357 }
15358 return *this;
15359 }
15360
15361 template<typename tc>
15362 CImg<T>& draw_arrow(const int x0, const int y0, const int x1, const int y1,
15363 const CImg<tc>& color,
15364 const float angle=30, const float length=-10,
15365 const float opacity=1.0f, const unsigned int pattern=~0U) {
15366 return draw_arrow(x0,y0,x1,y1,color.data,angle,length,opacity,pattern);
15367 }
15368
15370
15380 template<typename t>
15381 CImg<T>& draw_image(const CImg<t>& sprite,
15382 const int x0, const int y0=0, const int z0=0, const int v0=0,
15383 const float opacity=1.0f) {
15384 if (!is_empty()) {
15385 if (!sprite)
15386 throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
15387 pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
15388 if (is_overlapping(sprite)) return draw_image(+sprite,x0,y0,z0,v0,opacity);
15389 const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0);
15390 const int
15391 lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0),
15392 lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0),
15393 lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0),
15394 lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0);
15395 const t
15396 *ptrs = sprite.data -
15397 (bx?x0:0) -
15398 (by?y0*sprite.dimx():0) -
15399 (bz?z0*sprite.dimx()*sprite.dimy():0) -
15400 (bv?v0*sprite.dimx()*sprite.dimy()*sprite.dimz():0);
15401 const unsigned int
15402 offX = width-lX, soffX = sprite.width-lX,
15403 offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY),
15404 offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ);
15405 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
15406 T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
15407 if (lX>0 && lY>0 && lZ>0 && lV>0)
15408 for (int v=0; v<lV; ++v) {
15409 for (int z=0; z<lZ; ++z) {
15410 for (int y=0; y<lY; ++y) {
15411 if (opacity>=1) for (int x=0; x<lX; ++x) *(ptrd++) = (T)*(ptrs++);
15412 else for (int x=0; x<lX; ++x) { *ptrd = (T)(nopacity*(*(ptrs++)) + *ptrd*copacity); ++ptrd; }
15413 ptrd+=offX; ptrs+=soffX;
15414 }
15415 ptrd+=offY; ptrs+=soffY;
15416 }
15417 ptrd+=offZ; ptrs+=soffZ;
15418 }
15419 }
15420 return *this;
15421 }
15422
15423 #ifndef cimg_use_visualcpp6
15424 CImg<T>& draw_image(const CImg<T>& sprite,
15425 const int x0, const int y0=0, const int z0=0, const int v0=0,
15426 const float opacity=1.0f) {
15427 if (!is_empty()) {
15428 if (!sprite)
15429 throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
15430 pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
15431 if (is_overlapping(sprite)) return draw_image(+sprite,x0,y0,z0,v0,opacity);
15432 const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0);
15433 const int
15434 lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0),
15435 lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0),
15436 lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0),
15437 lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0);
15438 const T
15439 *ptrs = sprite.data -
15440 (bx?x0:0) -
15441 (by?y0*sprite.dimx():0) -
15442 (bz?z0*sprite.dimx()*sprite.dimy():0) -
15443 (bv?v0*sprite.dimx()*sprite.dimy()*sprite.dimz():0);
15444 const unsigned int
15445 offX = width-lX, soffX = sprite.width-lX,
15446 offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY),
15447 offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ),
15448 slX = lX*sizeof(T);
15449 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
15450 T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
15451 if (lX>0 && lY>0 && lZ>0 && lV>0)
15452 for (int v=0; v<lV; ++v) {
15453 for (int z=0; z<lZ; ++z) {
15454 if (opacity>=1) for (int y=0; y<lY; ++y) { std::memcpy(ptrd,ptrs,slX); ptrd+=width; ptrs+=sprite.width; }
15455 else for (int y=0; y<lY; ++y) {
15456 for (int x=0; x<lX; ++x) { *ptrd = (T)(nopacity*(*(ptrs++)) + *ptrd*copacity); ++ptrd; }
15457 ptrd+=offX; ptrs+=soffX;
15458 }
15459 ptrd+=offY; ptrs+=soffY;
15460 }
15461 ptrd+=offZ; ptrs+=soffZ;
15462 }
15463 }
15464 return *this;
15465 }
15466 #endif
15467
15469
15483 template<typename ti, typename tm>
15484 CImg<T>& draw_image(const CImg<ti>& sprite, const CImg<tm>& mask,
15485 const int x0, const int y0=0, const int z0=0, const int v0=0,
15486 const float mask_valmax=1.0f, const float opacity=1.0f) {
15487 if (!is_empty()) {
15488 if (!sprite)
15489 throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
15490 pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
15491 if (!mask)
15492 throw CImgArgumentException("CImg<%s>::draw_image() : Specified mask image (%u,%u,%u,%u,%p) is empty.",
15493 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
15494 if (is_overlapping(sprite)) return draw_image(+sprite,mask,x0,y0,z0,v0,mask_valmax,opacity);
15495 if (is_overlapping(mask)) return draw_image(sprite,+mask,x0,y0,z0,v0,mask_valmax,opacity);
15496 if (mask.width!=sprite.width || mask.height!=sprite.height || mask.depth!=sprite.depth)
15497 throw CImgArgumentException("CImg<%s>::draw_image() : Mask dimension is (%u,%u,%u,%u), while sprite is (%u,%u,%u,%u)",
15498 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,sprite.width,sprite.height,sprite.depth,sprite.dim);
15499 const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0);
15500 const int
15501 lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0),
15502 lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0),
15503 lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0),
15504 lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0);
15505 const int
15506 coff = -(bx?x0:0)-(by?y0*mask.dimx():0)-(bz?z0*mask.dimx()*mask.dimy():0)-(bv?v0*mask.dimx()*mask.dimy()*mask.dimz():0),
15507 ssize = mask.dimx()*mask.dimy()*mask.dimz();
15508 const ti *ptrs = sprite.data + coff;
15509 const tm *ptrm = mask.data + coff;
15510 const unsigned int
15511 offX = width-lX, soffX = sprite.width-lX,
15512 offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY),
15513 offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ);
15514 T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
15515 if (lX>0 && lY>0 && lZ>0 && lV>0)
15516 for (int v=0; v<lV; ++v) {
15517 ptrm = mask.data + (ptrm - mask.data)%ssize;
15518 for (int z=0; z<lZ; ++z) {
15519 for (int y=0; y<lY; ++y) {
15520 for (int x=0; x<lX; ++x) {
15521 const float mopacity = *(ptrm++)*opacity,
15522 nopacity = cimg::abs(mopacity), copacity = mask_valmax-cimg::max(mopacity,0.0f);
15523 *ptrd = (T)((nopacity*(*(ptrs++)) + *ptrd*copacity)/mask_valmax);
15524 ++ptrd;
15525 }
15526 ptrd+=offX; ptrs+=soffX; ptrm+=soffX;
15527 }
15528 ptrd+=offY; ptrs+=soffY; ptrm+=soffY;
15529 }
15530 ptrd+=offZ; ptrs+=soffZ; ptrm+=soffZ;
15531 }
15532 }
15533 return *this;
15534 }
15535
15537
15551 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0, const int v0,
15552 const int x1, const int y1, const int z1, const int v1,
15553 const T val, const float opacity=1.0f) {
15554 if (!is_empty()) {
15555 const bool bx=(x0<x1), by=(y0<y1), bz=(z0<z1), bv=(v0<v1);
15556 const int nx0=bx?x0:x1, nx1=bx?x1:x0, ny0=by?y0:y1, ny1=by?y1:y0, nz0=bz?z0:z1, nz1=bz?z1:z0, nv0=bv?v0:v1, nv1=bv?v1:v0;
15557 const int
15558 lX = (1+nx1-nx0) + (nx1>=dimx()?dimx()-1-nx1:0) + (nx0<0?nx0:0),
15559 lY = (1+ny1-ny0) + (ny1>=dimy()?dimy()-1-ny1:0) + (ny0<0?ny0:0),
15560 lZ = (1+nz1-nz0) + (nz1>=dimz()?dimz()-1-nz1:0) + (nz0<0?nz0:0),
15561 lV = (1+nv1-nv0) + (nv1>=dimv()?dimv()-1-nv1:0) + (nv0<0?nv0:0);
15562 const unsigned int offX = width-lX, offY = width*(height-lY), offZ = width*height*(depth-lZ);
15563 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
15564 T *ptrd = ptr(nx0<0?0:nx0,ny0<0?0:ny0,nz0<0?0:nz0,nv0<0?0:nv0);
15565 if (lX>0 && lY>0 && lZ>0 && lV>0)
15566 for (int v=0; v<lV; ++v) {
15567 for (int z=0; z<lZ; ++z) {
15568 for (int y=0; y<lY; ++y) {
15569 if (opacity>=1) {
15570 if (sizeof(T)!=1) { for (int x=0; x<lX; ++x) *(ptrd++) = val; ptrd+=offX; }
15571 else { std::memset(ptrd,(int)val,lX); ptrd+=width; }
15572 } else { for (int x=0; x<lX; ++x) { *ptrd = (T)(nopacity*val + *ptrd*copacity); ++ptrd; } ptrd+=offX; }
15573 }
15574 ptrd+=offY;
15575 }
15576 ptrd+=offZ;
15577 }
15578 }
15579 return *this;
15580 }
15581
15583
15595 template<typename tc>
15596 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0,
15597 const int x1, const int y1, const int z1,
15598 const tc *const color, const float opacity=1.0f) {
15599 if (!color) throw CImgArgumentException("CImg<%s>::draw_rectangle : specified color is (null)",pixel_type());
15600 cimg_forV(*this,k) draw_rectangle(x0,y0,z0,k,x1,y1,z1,k,color[k],opacity);
15601 return *this;
15602 }
15603
15604 template<typename tc>
15605 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0,
15606 const int x1, const int y1, const int z1,
15607 const CImg<tc>& color, const float opacity=1.0f) {
15608 return draw_rectangle(x0,y0,z0,x1,y1,z1,color.data,opacity);
15609 }
15610
15612 template<typename tc>
15613 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0,
15614 const int x1, const int y1, const int z1,
15615 const tc *const color, const float opacity, const unsigned int pattern) {
15616 return draw_line(x0,y0,z0,x1,y0,z0,color,opacity,pattern,true).
15617 draw_line(x1,y0,z0,x1,y1,z0,color,opacity,pattern,false).
15618 draw_line(x1,y1,z0,x0,y1,z0,color,opacity,pattern,false).
15619 draw_line(x0,y1,z0,x0,y0,z0,color,opacity,pattern,false).
15620 draw_line(x0,y0,z1,x1,y0,z1,color,opacity,pattern,true).
15621 draw_line(x1,y0,z1,x1,y1,z1,color,opacity,pattern,false).
15622 draw_line(x1,y1,z1,x0,y1,z1,color,opacity,pattern,false).
15623 draw_line(x0,y1,z1,x0,y0,z1,color,opacity,pattern,false).
15624 draw_line(x0,y0,z0,x0,y0,z1,color,opacity,pattern,true).
15625 draw_line(x1,y0,z0,x1,y0,z1,color,opacity,pattern,true).
15626 draw_line(x1,y1,z0,x1,y1,z1,color,opacity,pattern,true).
15627 draw_line(x0,y1,z0,x0,y1,z1,color,opacity,pattern,true);
15628 }
15629
15630 template<typename tc>
15631 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0,
15632 const int x1, const int y1, const int z1,
15633 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
15634 return draw_rectangle(x0,y0,z0,x1,y1,z1,color.data,opacity,pattern);
15635 }
15636
15638
15648 template<typename tc>
15649 CImg<T>& draw_rectangle(const int x0, const int y0, const int x1, const int y1,
15650 const tc *const color, const float opacity=1.0f) {
15651 return draw_rectangle(x0,y0,0,x1,y1,depth-1,color,opacity);
15652 }
15653
15654 template<typename tc>
15655 CImg<T>& draw_rectangle(const int x0, const int y0, const int x1, const int y1,
15656 const CImg<tc>& color, const float opacity=1.0f) {
15657 return draw_rectangle(x0,y0,x1,y1,color.data,opacity);
15658 }
15659
15661 template<typename tc>
15662 CImg<T>& draw_rectangle(const int x0, const int y0, const int x1, const int y1,
15663 const tc *const color, const float opacity, const unsigned int pattern) {
15664 return draw_line(x0,y0,x1,y0,color,opacity,pattern,true).
15665 draw_line(x1,y0,x1,y1,color,opacity,pattern,false).
15666 draw_line(x1,y1,x0,y1,color,opacity,pattern,false).
15667 draw_line(x0,y1,x0,y0,color,opacity,pattern,false);
15668 }
15669
15670 template<typename tc>
15671 CImg<T>& draw_rectangle(const int x0, const int y0, const int x1, const int y1,
15672 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
15673 return draw_rectangle(x0,y0,x1,y1,color.data,opacity,pattern);
15674 }
15675
15676
15677 #define _cimg_for_triangle1(img,xl,xr,y,x0,y0,x1,y1,x2,y2) \
15678 for (int y = y0<0?0:y0, \
15679 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15680 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15681 _sxn=1, \
15682 _sxr=1, \
15683 _sxl=1, \
15684 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
15685 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
15686 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
15687 _dyn = y2-y1, \
15688 _dyr = y2-y0, \
15689 _dyl = y1-y0, \
15690 _counter = (_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15691 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15692 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15693 cimg::min((int)(img).height-y-1,y2-y)), \
15694 _errn = _dyn/2, \
15695 _errr = _dyr/2, \
15696 _errl = _dyl/2, \
15697 _rxn = _dyn?(x2-x1)/_dyn:0, \
15698 _rxr = _dyr?(x2-x0)/_dyr:0, \
15699 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
15700 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn); \
15701 _counter>=0; --_counter, ++y, \
15702 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
15703 xl+=(y!=y1)?_rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0): \
15704 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
15705
15706 #define _cimg_for_triangle2(img,xl,cl,xr,cr,y,x0,y0,c0,x1,y1,c1,x2,y2,c2) \
15707 for (int y = y0<0?0:y0, \
15708 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15709 cr = y0>=0?c0:(c0-y0*(c2-c0)/(y2-y0)), \
15710 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15711 cl = y1>=0?(y0>=0?(y0==y1?c1:c0):(c0-y0*(c1-c0)/(y1-y0))):(c1-y1*(c2-c1)/(y2-y1)), \
15712 _sxn=1, _scn=1, \
15713 _sxr=1, _scr=1, \
15714 _sxl=1, _scl=1, \
15715 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
15716 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
15717 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
15718 _dcn = c2>c1?c2-c1:(_scn=-1,c1-c2), \
15719 _dcr = c2>c0?c2-c0:(_scr=-1,c0-c2), \
15720 _dcl = c1>c0?c1-c0:(_scl=-1,c0-c1), \
15721 _dyn = y2-y1, \
15722 _dyr = y2-y0, \
15723 _dyl = y1-y0, \
15724 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15725 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15726 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15727 _dcn-=_dyn?_dyn*(_dcn/_dyn):0, \
15728 _dcr-=_dyr?_dyr*(_dcr/_dyr):0, \
15729 _dcl-=_dyl?_dyl*(_dcl/_dyl):0, \
15730 cimg::min((int)(img).height-y-1,y2-y)), \
15731 _errn = _dyn/2, _errcn = _errn, \
15732 _errr = _dyr/2, _errcr = _errr, \
15733 _errl = _dyl/2, _errcl = _errl, \
15734 _rxn = _dyn?(x2-x1)/_dyn:0, \
15735 _rcn = _dyn?(c2-c1)/_dyn:0, \
15736 _rxr = _dyr?(x2-x0)/_dyr:0, \
15737 _rcr = _dyr?(c2-c0)/_dyr:0, \
15738 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
15739 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
15740 _rcl = (y0!=y1 && y1>0)?(_dyl?(c1-c0)/_dyl:0): \
15741 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ); \
15742 _counter>=0; --_counter, ++y, \
15743 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
15744 cr+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), \
15745 xl+=(y!=y1)?(cl+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), \
15746 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
15747 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cl=c1, \
15748 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
15749
15750 #define _cimg_for_triangle3(img,xl,txl,tyl,xr,txr,tyr,y,x0,y0,tx0,ty0,x1,y1,tx1,ty1,x2,y2,tx2,ty2) \
15751 for (int y = y0<0?0:y0, \
15752 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15753 txr = y0>=0?tx0:(tx0-y0*(tx2-tx0)/(y2-y0)), \
15754 tyr = y0>=0?ty0:(ty0-y0*(ty2-ty0)/(y2-y0)), \
15755 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15756 txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0-y0*(tx1-tx0)/(y1-y0))):(tx1-y1*(tx2-tx1)/(y2-y1)), \
15757 tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0-y0*(ty1-ty0)/(y1-y0))):(ty1-y1*(ty2-ty1)/(y2-y1)), \
15758 _sxn=1, _stxn=1, _styn=1, \
15759 _sxr=1, _stxr=1, _styr=1, \
15760 _sxl=1, _stxl=1, _styl=1, \
15761 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
15762 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
15763 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
15764 _dtxn = tx2>tx1?tx2-tx1:(_stxn=-1,tx1-tx2), \
15765 _dtxr = tx2>tx0?tx2-tx0:(_stxr=-1,tx0-tx2), \
15766 _dtxl = tx1>tx0?tx1-tx0:(_stxl=-1,tx0-tx1), \
15767 _dtyn = ty2>ty1?ty2-ty1:(_styn=-1,ty1-ty2), \
15768 _dtyr = ty2>ty0?ty2-ty0:(_styr=-1,ty0-ty2), \
15769 _dtyl = ty1>ty0?ty1-ty0:(_styl=-1,ty0-ty1), \
15770 _dyn = y2-y1, \
15771 _dyr = y2-y0, \
15772 _dyl = y1-y0, \
15773 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15774 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15775 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15776 _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \
15777 _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \
15778 _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \
15779 _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \
15780 _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \
15781 _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \
15782 cimg::min((int)(img).height-y-1,y2-y)), \
15783 _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, \
15784 _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, \
15785 _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, \
15786 _rxn = _dyn?(x2-x1)/_dyn:0, \
15787 _rtxn = _dyn?(tx2-tx1)/_dyn:0, \
15788 _rtyn = _dyn?(ty2-ty1)/_dyn:0, \
15789 _rxr = _dyr?(x2-x0)/_dyr:0, \
15790 _rtxr = _dyr?(tx2-tx0)/_dyr:0, \
15791 _rtyr = _dyr?(ty2-ty0)/_dyr:0, \
15792 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
15793 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
15794 _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1-tx0)/_dyl:0): \
15795 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \
15796 _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1-ty0)/_dyl:0): \
15797 (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); \
15798 _counter>=0; --_counter, ++y, \
15799 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
15800 txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \
15801 tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \
15802 xl+=(y!=y1)?(txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \
15803 tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \
15804 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
15805 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \
15806 _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1,\
15807 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
15808
15809 #define _cimg_for_triangle4(img,xl,cl,txl,tyl,xr,cr,txr,tyr,y,x0,y0,c0,tx0,ty0,x1,y1,c1,tx1,ty1,x2,y2,c2,tx2,ty2) \
15810 for (int y = y0<0?0:y0, \
15811 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15812 cr = y0>=0?c0:(c0-y0*(c2-c0)/(y2-y0)), \
15813 txr = y0>=0?tx0:(tx0-y0*(tx2-tx0)/(y2-y0)), \
15814 tyr = y0>=0?ty0:(ty0-y0*(ty2-ty0)/(y2-y0)), \
15815 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15816 cl = y1>=0?(y0>=0?(y0==y1?c1:c0):(c0-y0*(c1-c0)/(y1-y0))):(c1-y1*(c2-c1)/(y2-y1)), \
15817 txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0-y0*(tx1-tx0)/(y1-y0))):(tx1-y1*(tx2-tx1)/(y2-y1)), \
15818 tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0-y0*(ty1-ty0)/(y1-y0))):(ty1-y1*(ty2-ty1)/(y2-y1)), \
15819 _sxn=1, _scn=1, _stxn=1, _styn=1, \
15820 _sxr=1, _scr=1, _stxr=1, _styr=1, \
15821 _sxl=1, _scl=1, _stxl=1, _styl=1, \
15822 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
15823 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
15824 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
15825 _dcn = c2>c1?c2-c1:(_scn=-1,c1-c2), \
15826 _dcr = c2>c0?c2-c0:(_scr=-1,c0-c2), \
15827 _dcl = c1>c0?c1-c0:(_scl=-1,c0-c1), \
15828 _dtxn = tx2>tx1?tx2-tx1:(_stxn=-1,tx1-tx2), \
15829 _dtxr = tx2>tx0?tx2-tx0:(_stxr=-1,tx0-tx2), \
15830 _dtxl = tx1>tx0?tx1-tx0:(_stxl=-1,tx0-tx1), \
15831 _dtyn = ty2>ty1?ty2-ty1:(_styn=-1,ty1-ty2), \
15832 _dtyr = ty2>ty0?ty2-ty0:(_styr=-1,ty0-ty2), \
15833 _dtyl = ty1>ty0?ty1-ty0:(_styl=-1,ty0-ty1), \
15834 _dyn = y2-y1, \
15835 _dyr = y2-y0, \
15836 _dyl = y1-y0, \
15837 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15838 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15839 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15840 _dcn-=_dyn?_dyn*(_dcn/_dyn):0, \
15841 _dcr-=_dyr?_dyr*(_dcr/_dyr):0, \
15842 _dcl-=_dyl?_dyl*(_dcl/_dyl):0, \
15843 _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \
15844 _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \
15845 _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \
15846 _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \
15847 _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \
15848 _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \
15849 cimg::min((int)(img).height-y-1,y2-y)), \
15850 _errn = _dyn/2, _errcn = _errn, _errtxn = _errn, _errtyn = _errn, \
15851 _errr = _dyr/2, _errcr = _errr, _errtxr = _errr, _errtyr = _errr, \
15852 _errl = _dyl/2, _errcl = _errl, _errtxl = _errl, _errtyl = _errl, \
15853 _rxn = _dyn?(x2-x1)/_dyn:0, \
15854 _rcn = _dyn?(c2-c1)/_dyn:0, \
15855 _rtxn = _dyn?(tx2-tx1)/_dyn:0, \
15856 _rtyn = _dyn?(ty2-ty1)/_dyn:0, \
15857 _rxr = _dyr?(x2-x0)/_dyr:0, \
15858 _rcr = _dyr?(c2-c0)/_dyr:0, \
15859 _rtxr = _dyr?(tx2-tx0)/_dyr:0, \
15860 _rtyr = _dyr?(ty2-ty0)/_dyr:0, \
15861 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
15862 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
15863 _rcl = (y0!=y1 && y1>0)?(_dyl?(c1-c0)/_dyl:0): \
15864 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ), \
15865 _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1-tx0)/_dyl:0): \
15866 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \
15867 _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1-ty0)/_dyl:0): \
15868 (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); \
15869 _counter>=0; --_counter, ++y, \
15870 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
15871 cr+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), \
15872 txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \
15873 tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \
15874 xl+=(y!=y1)?(cl+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), \
15875 txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \
15876 tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \
15877 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
15878 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cl=c1, \
15879 _errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \
15880 _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1, \
15881 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
15882
15883 #define _cimg_for_triangle5(img,xl,txl,tyl,lxl,lyl,xr,txr,tyr,lxr,lyr,y,x0,y0,tx0,ty0,lx0,ly0,x1,y1,tx1,ty1,lx1,ly1,x2,y2,tx2,ty2,lx2,ly2) \
15884 for (int y = y0<0?0:y0, \
15885 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15886 txr = y0>=0?tx0:(tx0-y0*(tx2-tx0)/(y2-y0)), \
15887 tyr = y0>=0?ty0:(ty0-y0*(ty2-ty0)/(y2-y0)), \
15888 lxr = y0>=0?lx0:(lx0-y0*(lx2-lx0)/(y2-y0)), \
15889 lyr = y0>=0?ly0:(ly0-y0*(ly2-ly0)/(y2-y0)), \
15890 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15891 txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0-y0*(tx1-tx0)/(y1-y0))):(tx1-y1*(tx2-tx1)/(y2-y1)), \
15892 tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0-y0*(ty1-ty0)/(y1-y0))):(ty1-y1*(ty2-ty1)/(y2-y1)), \
15893 lxl = y1>=0?(y0>=0?(y0==y1?lx1:lx0):(lx0-y0*(lx1-lx0)/(y1-y0))):(lx1-y1*(lx2-lx1)/(y2-y1)), \
15894 lyl = y1>=0?(y0>=0?(y0==y1?ly1:ly0):(ly0-y0*(ly1-ly0)/(y1-y0))):(ly1-y1*(ly2-ly1)/(y2-y1)), \
15895 _sxn=1, _stxn=1, _styn=1, _slxn=1, _slyn=1, \
15896 _sxr=1, _stxr=1, _styr=1, _slxr=1, _slyr=1, \
15897 _sxl=1, _stxl=1, _styl=1, _slxl=1, _slyl=1, \
15898 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), _dyn = y2-y1, \
15899 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), _dyr = y2-y0, \
15900 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), _dyl = y1-y0, \
15901 _dtxn = tx2>tx1?tx2-tx1:(_stxn=-1,tx1-tx2), \
15902 _dtxr = tx2>tx0?tx2-tx0:(_stxr=-1,tx0-tx2), \
15903 _dtxl = tx1>tx0?tx1-tx0:(_stxl=-1,tx0-tx1), \
15904 _dtyn = ty2>ty1?ty2-ty1:(_styn=-1,ty1-ty2), \
15905 _dtyr = ty2>ty0?ty2-ty0:(_styr=-1,ty0-ty2), \
15906 _dtyl = ty1>ty0?ty1-ty0:(_styl=-1,ty0-ty1), \
15907 _dlxn = lx2>lx1?lx2-lx1:(_slxn=-1,lx1-lx2), \
15908 _dlxr = lx2>lx0?lx2-lx0:(_slxr=-1,lx0-lx2), \
15909 _dlxl = lx1>lx0?lx1-lx0:(_slxl=-1,lx0-lx1), \
15910 _dlyn = ly2>ly1?ly2-ly1:(_slyn=-1,ly1-ly2), \
15911 _dlyr = ly2>ly0?ly2-ly0:(_slyr=-1,ly0-ly2), \
15912 _dlyl = ly1>ly0?ly1-ly0:(_slyl=-1,ly0-ly1), \
15913 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15914 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15915 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15916 _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \
15917 _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \
15918 _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \
15919 _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \
15920 _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \
15921 _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \
15922 _dlxn-=_dyn?_dyn*(_dlxn/_dyn):0, \
15923 _dlxr-=_dyr?_dyr*(_dlxr/_dyr):0, \
15924 _dlxl-=_dyl?_dyl*(_dlxl/_dyl):0, \
15925 _dlyn-=_dyn?_dyn*(_dlyn/_dyn):0, \
15926 _dlyr-=_dyr?_dyr*(_dlyr/_dyr):0, \
15927 _dlyl-=_dyl?_dyl*(_dlyl/_dyl):0, \
15928 cimg::min((int)(img).height-y-1,y2-y)), \
15929 _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, _errlxn = _errn, _errlyn = _errn, \
15930 _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, _errlxr = _errr, _errlyr = _errr, \
15931 _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, _errlxl = _errl, _errlyl = _errl, \
15932 _rxn = _dyn?(x2-x1)/_dyn:0, \
15933 _rtxn = _dyn?(tx2-tx1)/_dyn:0, \
15934 _rtyn = _dyn?(ty2-ty1)/_dyn:0, \
15935 _rlxn = _dyn?(lx2-lx1)/_dyn:0, \
15936 _rlyn = _dyn?(ly2-ly1)/_dyn:0, \
15937 _rxr = _dyr?(x2-x0)/_dyr:0, \
15938 _rtxr = _dyr?(tx2-tx0)/_dyr:0, \
15939 _rtyr = _dyr?(ty2-ty0)/_dyr:0, \
15940 _rlxr = _dyr?(lx2-lx0)/_dyr:0, \
15941 _rlyr = _dyr?(ly2-ly0)/_dyr:0, \
15942 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
15943 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
15944 _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1-tx0)/_dyl:0): \
15945 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \
15946 _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1-ty0)/_dyl:0): \
15947 (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ), \
15948 _rlxl = (y0!=y1 && y1>0)?(_dyl?(lx1-lx0)/_dyl:0): \
15949 (_errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxn ), \
15950 _rlyl = (y0!=y1 && y1>0)?(_dyl?(ly1-ly0)/_dyl:0): \
15951 (_errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyn ); \
15952 _counter>=0; --_counter, ++y, \
15953 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
15954 txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \
15955 tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \
15956 lxr+=_rlxr+((_errlxr-=_dlxr)<0?_errlxr+=_dyr,_slxr:0), \
15957 lyr+=_rlyr+((_errlyr-=_dlyr)<0?_errlyr+=_dyr,_slyr:0), \
15958 xl+=(y!=y1)?(txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \
15959 tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \
15960 lxl+=_rlxl+((_errlxl-=_dlxl)<0?(_errlxl+=_dyl,_slxl):0), \
15961 lyl+=_rlyl+((_errlyl-=_dlyl)<0?(_errlyl+=_dyl,_slyl):0), \
15962 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
15963 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \
15964 _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1, \
15965 _errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxl=_rlxn, lxl=lx1, \
15966 _errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyl=_rlyn, lyl=ly1, \
15967 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
15968
15969
15970 template<typename tc>
15971 CImg<T>& _draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
15972 const tc *const color, const float opacity, const float brightness) {
15973 _draw_scanline(color,opacity);
15974 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2;
15975 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1);
15976 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2);
15977 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2);
15978 if (ny0<dimy() && ny2>=0) {
15979 if ((nx1-nx0)*(ny2-ny0)-(nx2-nx0)*(ny1-ny0)<0)
15980 _cimg_for_triangle1(*this,xl,xr,y,nx0,ny0,nx1,ny1,nx2,ny2) _draw_scanline(xl,xr,y,color,opacity,brightness);
15981 else
15982 _cimg_for_triangle1(*this,xl,xr,y,nx0,ny0,nx1,ny1,nx2,ny2) _draw_scanline(xr,xl,y,color,opacity,brightness);
15983 }
15984 return *this;
15985 }
15986
15988 template<typename tc>
15989 CImg<T>& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
15990 const tc *const color, const float opacity=1.0f) {
15991 if (!is_empty()) {
15992 if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type());
15993 _draw_triangle(x0,y0,x1,y1,x2,y2,color,opacity,1.0f);
15994 }
15995 return *this;
15996 }
15997
15998 template<typename tc>
15999 CImg<T>& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
16000 const CImg<tc>& color, const float opacity=1.0f) {
16001 return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opacity);
16002 }
16003
16005 template<typename tc>
16006 CImg<T>& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
16007 const tc *const color, const float opacity, const unsigned int pattern) {
16008 if (!is_empty()) {
16009 if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type());
16010 draw_line(x0,y0,x1,y1,color,opacity,pattern,true).
16011 draw_line(x1,y1,x2,y2,color,opacity,pattern,false).
16012 draw_line(x2,y2,x0,y0,color,opacity,pattern,false);
16013 }
16014 return *this;
16015 }
16016
16017 template<typename tc>
16018 CImg<T>& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
16019 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
16020 return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opacity,pattern);
16021 }
16022
16024
16038 template<typename tc>
16039 CImg<T>& draw_triangle(const int x0, const int y0,
16040 const int x1, const int y1,
16041 const int x2, const int y2,
16042 const tc *const color,
16043 const float c0,
16044 const float c1,
16045 const float c2,
16046 const float opacity=1.0f) {
16047 if (!is_empty()) {
16048 if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type());
16049 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16050 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16051 const int whz = width*height*depth, offx = dim*whz-1;
16052 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16053 nc0 = (int)(c0*256), nc1 = (int)(c1*256), nc2 = (int)(c2*256);
16054 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nc0,nc1);
16055 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nc0,nc2);
16056 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nc1,nc2);
16057 if (ny0<dimy() && ny2>=0) {
16058 _cimg_for_triangle2(*this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) {
16059 int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0;
16060 if (xright<xleft) cimg::swap(xleft,xright,cleft,cright);
16061 const int
16062 dx = xright-xleft,
16063 dc = cright>cleft?cright-cleft:cleft-cright,
16064 rc = dx?(cright-cleft)/dx:0,
16065 sc = cright>cleft?1:-1,
16066 ndc = dc-(dx?dx*(dc/dx):0);
16067 int errc = dx>>1;
16068 if (xleft<0 && dx) cleft-=xleft*(cright-cleft)/dx;
16069 if (xleft<0) xleft=0;
16070 if (xright>=dimx()-1) xright=dimx()-1;
16071 T* ptrd = ptr(xleft,y,0,0);
16072 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16073 const tc *col = color;
16074 cimg_forV(*this,k) {
16075 const float tval = (float)((cleft**(col++))/256);
16076 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16077 *ptrd = val;
16078 ptrd+=whz;
16079 }
16080 ptrd-=offx;
16081 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16082 } else for (int x=xleft; x<=xright; ++x) {
16083 const tc *col = color;
16084 cimg_forV(*this,k) {
16085 const float tval = (float)((cleft**(col++))/256);
16086 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16087 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16088 ptrd+=whz;
16089 }
16090 ptrd-=offx;
16091 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16092 }
16093 }
16094 }
16095 }
16096 return *this;
16097 }
16098
16099 template<typename tc>
16100 CImg<T>& draw_triangle(const int x0, const int y0,
16101 const int x1, const int y1,
16102 const int x2, const int y2,
16103 const CImg<tc>& color,
16104 const float c0,
16105 const float c1,
16106 const float c2,
16107 const float opacity=1.0f) {
16108 return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,c0,c1,c2,opacity);
16109 }
16110
16112
16130 template<typename t> CImg<T>& draw_triangle(const int x0, const int y0,
16131 const int x1, const int y1,
16132 const int x2, const int y2,
16133 const CImg<t>& texture,
16134 const int tx0, const int ty0,
16135 const int tx1, const int ty1,
16136 const int tx2, const int ty2,
16137 const float opacity=1.0f,
16138 const float brightness=1.0f) {
16139 if (!is_empty()) {
16140 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16141 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16142 if (is_overlapping(texture)) return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness);
16143 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16144 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16145 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16146 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16147 ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2;
16148 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1);
16149 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2);
16150 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2);
16151 if (ny0<dimy() && ny2>=0) {
16152 _cimg_for_triangle3(*this,xleft0,txleft0,tyleft0,xright0,txright0,tyright0,y,
16153 nx0,ny0,ntx0,nty0,nx1,ny1,ntx1,nty1,nx2,ny2,ntx2,nty2) {
16154 int
16155 xleft = xleft0, xright = xright0,
16156 txleft = txleft0, txright = txright0,
16157 tyleft = tyleft0, tyright = tyright0;
16158 if (xright<xleft) cimg::swap(xleft,xright,txleft,txright,tyleft,tyright);
16159 const int
16160 dx = xright-xleft,
16161 dtx = txright>txleft?txright-txleft:txleft-txright,
16162 dty = tyright>tyleft?tyright-tyleft:tyleft-tyright,
16163 rtx = dx?(txright-txleft)/dx:0,
16164 rty = dx?(tyright-tyleft)/dx:0,
16165 stx = txright>txleft?1:-1,
16166 sty = tyright>tyleft?1:-1,
16167 ndtx = dtx-(dx?dx*(dtx/dx):0),
16168 ndty = dty-(dx?dx*(dty/dx):0);
16169 int errtx = dx>>1, errty = errtx;
16170 if (xleft<0 && dx) {
16171 txleft-=xleft*(txright-txleft)/dx;
16172 tyleft-=xleft*(tyright-tyleft)/dx;
16173 }
16174 if (xleft<0) xleft=0;
16175 if (xright>=dimx()-1) xright=dimx()-1;
16176 T* ptrd = ptr(xleft,y,0,0);
16177 if (opacity>=1) {
16178 if (brightness<=1) for (int x=xleft; x<=xright; ++x) {
16179 const t *col = texture.ptr(txleft,tyleft);
16180 cimg_forV(*this,k) {
16181 *ptrd = (T)(brightness**col);
16182 ptrd+=whz; col+=twhz;
16183 }
16184 ptrd-=offx;
16185 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16186 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16187 } else for (int x=xleft; x<=xright; ++x) {
16188 const t *col = texture.ptr(txleft,tyleft);
16189 cimg_forV(*this,k) {
16190 const float tval = (float)(brightness**col);
16191 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16192 *ptrd = val;
16193 ptrd+=whz; col+=twhz;
16194 }
16195 ptrd-=offx;
16196 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16197 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16198 }
16199 } else {
16200 if (brightness<=1) for (int x=xleft; x<=xright; ++x) {
16201 const t *col = texture.ptr(txleft,tyleft);
16202 cimg_forV(*this,k) {
16203 *ptrd = (T)(nopacity*brightness**col + *ptrd*copacity);
16204 ptrd+=whz; col+=twhz;
16205 }
16206 ptrd-=offx;
16207 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16208 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16209 } else for (int x=xleft; x<=xright; ++x) {
16210 const t *col = texture.ptr(txleft,tyleft);
16211 cimg_forV(*this,k) {
16212 const float tval = (float)(brightness**col);
16213 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16214 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16215 ptrd+=whz; col+=twhz;
16216 }
16217 ptrd-=offx;
16218 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16219 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16220 }
16221 }
16222 }
16223 }
16224 }
16225 return *this;
16226 }
16227
16229 template<typename t> CImg<T>& draw_triangle(const int x0, const int y0, const float z0,
16230 const int x1, const int y1, const float z1,
16231 const int x2, const int y2, const float z2,
16232 const CImg<t>& texture,
16233 const int tx0, const int ty0,
16234 const int tx1, const int ty1,
16235 const int tx2, const int ty2,
16236 const float opacity=1.0f,
16237 const float brightness=1.0f) {
16238 if (!is_empty() && z0>0 && z1>0 && z2>0) {
16239 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16240 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16241 if (is_overlapping(texture)) return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness);
16242 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16243 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16244 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16245 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2;
16246 float
16247 ntx0 = tx0/z0, nty0 = ty0/z0,
16248 ntx1 = tx1/z1, nty1 = ty1/z1,
16249 ntx2 = tx2/z2, nty2 = ty2/z2,
16250 nz0 = 1.0f/z0, nz1 = 1.0f/z1, nz2 = 1.0f/z2;
16251 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1);
16252 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2);
16253 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2);
16254 if (ny0<dimy() && ny2>=0) {
16255 float
16256 ptxl = (ntx1-ntx0)/(ny1-ny0),
16257 ptxr = (ntx2-ntx0)/(ny2-ny0),
16258 ptxn = (ntx2-ntx1)/(ny2-ny1),
16259 ptyl = (nty1-nty0)/(ny1-ny0),
16260 ptyr = (nty2-nty0)/(ny2-ny0),
16261 ptyn = (nty2-nty1)/(ny2-ny1),
16262 pzl = (nz1-nz0)/(ny1-ny0),
16263 pzr = (nz2-nz0)/(ny2-ny0),
16264 pzn = (nz2-nz1)/(ny2-ny1),
16265 zr = ny0>=0?nz0:(nz0-ny0*(nz2-nz0)/(ny2-ny0)),
16266 txr = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)),
16267 tyr = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)),
16268 zl = ny1>=0?(ny0>=0?nz0:(nz0-ny0*(nz1-nz0)/(ny1-ny0))):(pzl=pzn,(nz1-ny1*(nz2-nz1)/(ny2-ny1))),
16269 txl = ny1>=0?(ny0>=0?ntx0:(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ptxl=ptxn,(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1))),
16270 tyl = ny1>=0?(ny0>=0?nty0:(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(ptyl=ptyn,(nty1-ny1*(nty2-nty1)/(ny2-ny1)));
16271 _cimg_for_triangle1(*this,xleft0,xright0,y,nx0,ny0,nx1,ny1,nx2,ny2) {
16272 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
16273 int xleft = xleft0, xright = xright0;
16274 float
16275 zleft = zl, zright = zr,
16276 txleft = txl, txright = txr,
16277 tyleft = tyl, tyright = tyr;
16278 if (xright<xleft) cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright);
16279 const int dx = xright-xleft;
16280 const float
16281 pentez = (zright-zleft)/dx,
16282 pentetx = (txright-txleft)/dx,
16283 pentety = (tyright-tyleft)/dx;
16284 if (xleft<0 && dx) {
16285 zleft-=xleft*(zright-zleft)/dx;
16286 txleft-=xleft*(txright-txleft)/dx;
16287 tyleft-=xleft*(tyright-tyleft)/dx;
16288 }
16289 if (xleft<0) xleft=0;
16290 if (xright>=dimx()-1) xright=dimx()-1;
16291 T* ptrd = ptr(xleft,y,0,0);
16292 if (opacity>=1) {
16293 if (brightness<=1) for (int x=xleft; x<=xright; ++x) {
16294 const float invz = 1.0f/zleft;
16295 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16296 cimg_forV(*this,k) {
16297 *ptrd = (T)(brightness**col);
16298 ptrd+=whz; col+=twhz;
16299 }
16300 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16301 } else for (int x=xleft; x<=xright; ++x) {
16302 const float invz = 1.0f/zleft;
16303 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16304 cimg_forV(*this,k) {
16305 const float tval = (float)(brightness**col);
16306 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16307 *ptrd = val;
16308 ptrd+=whz; col+=twhz;
16309 }
16310 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16311 }
16312 } else {
16313 if (brightness<=1) for (int x=xleft; x<=xright; ++x) {
16314 const float invz = 1.0f/zleft;
16315 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16316 cimg_forV(*this,k) {
16317 *ptrd = (T)(nopacity*brightness**col + *ptrd*copacity);
16318 ptrd+=whz; col+=twhz;
16319 }
16320 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16321 } else for (int x=xleft; x<=xright; ++x) {
16322 const float invz = 1.0f/zleft;
16323 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16324 cimg_forV(*this,k) {
16325 const float tval = (float)(brightness**col);
16326 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16327 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16328 ptrd+=whz; col+=twhz;
16329 }
16330 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16331 }
16332 }
16333 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
16334 }
16335 }
16336 }
16337 return *this;
16338 }
16339
16341
16359 template<typename tc, typename t>
16360 CImg<T>& draw_triangle(const int x0, const int y0,
16361 const int x1, const int y1,
16362 const int x2, const int y2,
16363 const tc *const color,
16364 const CImg<t>& light,
16365 const int lx0, const int ly0,
16366 const int lx1, const int ly1,
16367 const int lx2, const int ly2,
16368 const float opacity=1.0f) {
16369 if (!is_empty()) {
16370 if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type());
16371 if (!light) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.",
16372 pixel_type(),light.width,light.height,light.depth,light.dim,light.data);
16373 if (is_overlapping(light)) return draw_triangle(x0,y0,x1,y1,x2,y2,color,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
16374 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16375 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16376 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16377 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
16378 const int whz = width*height*depth, offx = dim*whz-1;
16379 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nlx0,nlx1,nly0,nly1);
16380 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nlx0,nlx2,nly0,nly2);
16381 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nlx1,nlx2,nly1,nly2);
16382 if (ny0<dimy() && ny2>=0) {
16383 _cimg_for_triangle3(*this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y,
16384 nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) {
16385 int
16386 xleft = xleft0, xright = xright0,
16387 lxleft = lxleft0, lxright = lxright0,
16388 lyleft = lyleft0, lyright = lyright0;
16389 if (xright<xleft) cimg::swap(xleft,xright,lxleft,lxright,lyleft,lyright);
16390 const int
16391 dx = xright-xleft,
16392 dlx = lxright>lxleft?lxright-lxleft:lxleft-lxright,
16393 dly = lyright>lyleft?lyright-lyleft:lyleft-lyright,
16394 rlx = dx?(lxright-lxleft)/dx:0,
16395 rly = dx?(lyright-lyleft)/dx:0,
16396 slx = lxright>lxleft?1:-1,
16397 sly = lyright>lyleft?1:-1,
16398 ndlx = dlx-(dx?dx*(dlx/dx):0),
16399 ndly = dly-(dx?dx*(dly/dx):0);
16400 int errlx = dx>>1, errly = errlx;
16401 if (xleft<0 && dx) {
16402 lxleft-=xleft*(lxright-lxleft)/dx;
16403 lyleft-=xleft*(lyright-lyleft)/dx;
16404 }
16405 if (xleft<0) xleft=0;
16406 if (xright>=dimx()-1) xright=dimx()-1;
16407 T* ptrd = ptr(xleft,y,0,0);
16408 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16409 const t lightness = light(lxleft,lyleft);
16410 const tc *col = color;
16411 cimg_forV(*this,k) {
16412 const float tval = (float)(*(col++)*lightness);
16413 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16414 *ptrd = val;
16415 ptrd+=whz;
16416 }
16417 ptrd-=offx;
16418 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16419 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16420 } else for (int x=xleft; x<=xright; ++x) {
16421 const t lightness = light(lxleft,lyleft);
16422 const tc *col = color;
16423 cimg_forV(*this,k) {
16424 const float tval = (float)(*(col++)*lightness);
16425 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16426 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16427 ptrd+=whz;
16428 }
16429 ptrd-=offx;
16430 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16431 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16432 }
16433 }
16434 }
16435 }
16436 return *this;
16437 }
16438
16439 template<typename tc, typename t>
16440 CImg<T>& draw_triangle(const int x0, const int y0,
16441 const int x1, const int y1,
16442 const int x2, const int y2,
16443 const CImg<tc>& color,
16444 const CImg<t>& light,
16445 const int lx0, const int ly0,
16446 const int lx1, const int ly1,
16447 const int lx2, const int ly2,
16448 const float opacity=1.0f) {
16449 return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
16450 }
16451
16453
16473 template<typename t> CImg<T>& draw_triangle(const int x0, const int y0,
16474 const int x1, const int y1,
16475 const int x2, const int y2,
16476 const CImg<t>& texture,
16477 const int tx0, const int ty0,
16478 const int tx1, const int ty1,
16479 const int tx2, const int ty2,
16480 const float c0,
16481 const float c1,
16482 const float c2,
16483 const float opacity=1) {
16484 if (!is_empty()) {
16485 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16486 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16487 if (is_overlapping(texture)) return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,c0,c1,c2,opacity);
16488 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16489 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16490 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16491 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16492 ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2,
16493 nc0 = (int)(c0*256), nc1 = (int)(c1*256), nc2 = (int)(c2*256);
16494 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nc0,nc1);
16495 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nc0,nc2);
16496 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nc1,nc2);
16497 if (ny0<dimy() && ny2>=0) {
16498 _cimg_for_triangle4(*this,xleft0,cleft0,txleft0,tyleft0,xright0,cright0,txright0,tyright0,y,
16499 nx0,ny0,nc0,ntx0,nty0,nx1,ny1,nc1,ntx1,nty1,nx2,ny2,nc2,ntx2,nty2) {
16500 int
16501 xleft = xleft0, xright = xright0,
16502 cleft = cleft0, cright = cright0,
16503 txleft = txleft0, txright = txright0,
16504 tyleft = tyleft0, tyright = tyright0;
16505 if (xright<xleft) cimg::swap(xleft,xright,cleft,cright,txleft,txright,tyleft,tyright);
16506 const int
16507 dx = xright-xleft,
16508 dc = cright>cleft?cright-cleft:cleft-cright,
16509 dtx = txright>txleft?txright-txleft:txleft-txright,
16510 dty = tyright>tyleft?tyright-tyleft:tyleft-tyright,
16511 rc = dx?(cright-cleft)/dx:0,
16512 rtx = dx?(txright-txleft)/dx:0,
16513 rty = dx?(tyright-tyleft)/dx:0,
16514 sc = cright>cleft?1:-1,
16515 stx = txright>txleft?1:-1,
16516 sty = tyright>tyleft?1:-1,
16517 ndc = dc-(dx?dx*(dc/dx):0),
16518 ndtx = dtx-(dx?dx*(dtx/dx):0),
16519 ndty = dty-(dx?dx*(dty/dx):0);
16520 int errc = dx>>1, errtx = errc, errty = errc;
16521 if (xleft<0 && dx) {
16522 cleft-=xleft*(cright-cleft)/dx;
16523 txleft-=xleft*(txright-txleft)/dx;
16524 tyleft-=xleft*(tyright-tyleft)/dx;
16525 }
16526 if (xleft<0) xleft=0;
16527 if (xright>=dimx()-1) xright=dimx()-1;
16528 T* ptrd = ptr(xleft,y,0,0);
16529 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16530 const t *col = texture.ptr(txleft,tyleft);
16531 cimg_forV(*this,k) {
16532 const float tval = (float)(cleft**col/256);
16533 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16534 *ptrd = (T)val;
16535 ptrd+=whz; col+=twhz;
16536 }
16537 ptrd-=offx;
16538 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16539 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16540 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16541 } else for (int x=xleft; x<=xright; ++x) {
16542 const t *col = texture.ptr(txleft,tyleft);
16543 cimg_forV(*this,k) {
16544 const float tval = (float)(cleft**col/256);
16545 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16546 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16547 ptrd+=whz; col+=twhz;
16548 }
16549 ptrd-=offx;
16550 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16551 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16552 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16553 }
16554 }
16555 }
16556 }
16557 return *this;
16558 }
16559
16561 template<typename t> CImg<T>& draw_triangle(const int x0, const int y0, const float z0,
16562 const int x1, const int y1, const float z1,
16563 const int x2, const int y2, const float z2,
16564 const CImg<t>& texture,
16565 const int tx0, const int ty0,
16566 const int tx1, const int ty1,
16567 const int tx2, const int ty2,
16568 const float c0,
16569 const float c1,
16570 const float c2,
16571 const float opacity=1.0f) {
16572 if (!is_empty() && z0>0 && z1>0 && z2>0) {
16573 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16574 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16575 if (is_overlapping(texture)) return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,c0,c1,c2,opacity);
16576 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16577 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16578 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16579 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16580 nc0 = (int)(c0*256), nc1 = (int)(c1*256), nc2 = (int)(c2*256);
16581 float
16582 ntx0 = tx0/z0, nty0 = ty0/z0,
16583 ntx1 = tx1/z1, nty1 = ty1/z1,
16584 ntx2 = tx2/z2, nty2 = ty2/z2,
16585 nz0 = 1.0f/z0, nz1 = 1.0f/z1, nz2 = 1.0f/z2;
16586 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1,nc0,nc1);
16587 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2,nc0,nc2);
16588 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2,nc1,nc2);
16589 if (ny0<dimy() && ny2>=0) {
16590 float
16591 ptxl = (ntx1-ntx0)/(ny1-ny0),
16592 ptxr = (ntx2-ntx0)/(ny2-ny0),
16593 ptxn = (ntx2-ntx1)/(ny2-ny1),
16594 ptyl = (nty1-nty0)/(ny1-ny0),
16595 ptyr = (nty2-nty0)/(ny2-ny0),
16596 ptyn = (nty2-nty1)/(ny2-ny1),
16597 pzl = (nz1-nz0)/(ny1-ny0),
16598 pzr = (nz2-nz0)/(ny2-ny0),
16599 pzn = (nz2-nz1)/(ny2-ny1),
16600 zr = ny0>=0?nz0:(nz0-ny0*(nz2-nz0)/(ny2-ny0)),
16601 txr = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)),
16602 tyr = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)),
16603 zl = ny1>=0?(ny0>=0?nz0:(nz0-ny0*(nz1-nz0)/(ny1-ny0))):(pzl=pzn,(nz1-ny1*(nz2-nz1)/(ny2-ny1))),
16604 txl = ny1>=0?(ny0>=0?ntx0:(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ptxl=ptxn,(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1))),
16605 tyl = ny1>=0?(ny0>=0?nty0:(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(ptyl=ptyn,(nty1-ny1*(nty2-nty1)/(ny2-ny1)));
16606 _cimg_for_triangle2(*this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) {
16607 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
16608 int
16609 xleft = xleft0, xright = xright0,
16610 cleft = cleft0, cright = cright0;
16611 float
16612 zleft = zl, zright = zr,
16613 txleft = txl, txright = txr,
16614 tyleft = tyl, tyright = tyr;
16615 if (xright<xleft) cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright,cleft,cright);
16616 const int
16617 dx = xright-xleft,
16618 dc = cright>cleft?cright-cleft:cleft-cright,
16619 rc = dx?(cright-cleft)/dx:0,
16620 sc = cright>cleft?1:-1,
16621 ndc = dc-(dx?dx*(dc/dx):0);
16622 const float
16623 pentez = (zright-zleft)/dx,
16624 pentetx = (txright-txleft)/dx,
16625 pentety = (tyright-tyleft)/dx;
16626 int errc = dx>>1;
16627 if (xleft<0 && dx) {
16628 cleft-=xleft*(cright-cleft)/dx;
16629 zleft-=xleft*(zright-zleft)/dx;
16630 txleft-=xleft*(txright-txleft)/dx;
16631 tyleft-=xleft*(tyright-tyleft)/dx;
16632 }
16633 if (xleft<0) xleft=0;
16634 if (xright>=dimx()-1) xright=dimx()-1;
16635 T* ptrd = ptr(xleft,y,0,0);
16636 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16637 const float invz = 1.0f/zleft;
16638 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16639 cimg_forV(*this,k) {
16640 const float tval = (float)(cleft**col/256);
16641 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16642 *ptrd = val;
16643 ptrd+=whz; col+=twhz;
16644 }
16645 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16646 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16647 } else for (int x=xleft; x<=xright; ++x) {
16648 const float invz = 1.0f/zleft;
16649 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16650 cimg_forV(*this,k) {
16651 const float tval = (float)(cleft**col/256);
16652 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16653 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16654 ptrd+=whz; col+=twhz;
16655 }
16656 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16657 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16658 }
16659 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
16660 }
16661 }
16662 }
16663 return *this;
16664 }
16665
16667
16691 template<typename t, typename tl> CImg<T>& draw_triangle(const int x0, const int y0,
16692 const int x1, const int y1,
16693 const int x2, const int y2,
16694 const CImg<t>& texture,
16695 const int tx0, const int ty0,
16696 const int tx1, const int ty1,
16697 const int tx2, const int ty2,
16698 const CImg<tl>& light,
16699 const int lx0, const int ly0,
16700 const int lx1, const int ly1,
16701 const int lx2, const int ly2,
16702 const float opacity=1.0f) {
16703 if (!is_empty()) {
16704 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16705 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16706 if (!light) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.",
16707 pixel_type(),light.width,light.height,light.depth,light.dim,light.data);
16708 if (is_overlapping(texture)) return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
16709 if (is_overlapping(light)) return draw_triangle(x0,y0,x1,y1,x2,y2,texture,tx0,ty0,tx1,ty1,tx2,ty2,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
16710 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16711 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16712 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16713 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16714 ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2,
16715 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
16716 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1);
16717 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2);
16718 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2);
16719 if (ny0<dimy() && ny2>=0) {
16720 _cimg_for_triangle5(*this,xleft0,lxleft0,lyleft0,txleft0,tyleft0,xright0,lxright0,lyright0,txright0,tyright0,y,
16721 nx0,ny0,nlx0,nly0,ntx0,nty0,nx1,ny1,nlx1,nly1,ntx1,nty1,nx2,ny2,nlx2,nly2,ntx2,nty2) {
16722 int
16723 xleft = xleft0, xright = xright0,
16724 lxleft = lxleft0, lxright = lxright0,
16725 lyleft = lyleft0, lyright = lyright0,
16726 txleft = txleft0, txright = txright0,
16727 tyleft = tyleft0, tyright = tyright0;
16728 if (xright<xleft) cimg::swap(xleft,xright,lxleft,lxright,lyleft,lyright,txleft,txright,tyleft,tyright);
16729 const int
16730 dx = xright-xleft,
16731 dlx = lxright>lxleft?lxright-lxleft:lxleft-lxright,
16732 dly = lyright>lyleft?lyright-lyleft:lyleft-lyright,
16733 dtx = txright>txleft?txright-txleft:txleft-txright,
16734 dty = tyright>tyleft?tyright-tyleft:tyleft-tyright,
16735 rlx = dx?(lxright-lxleft)/dx:0,
16736 rly = dx?(lyright-lyleft)/dx:0,
16737 rtx = dx?(txright-txleft)/dx:0,
16738 rty = dx?(tyright-tyleft)/dx:0,
16739 slx = lxright>lxleft?1:-1,
16740 sly = lyright>lyleft?1:-1,
16741 stx = txright>txleft?1:-1,
16742 sty = tyright>tyleft?1:-1,
16743 ndlx = dlx-(dx?dx*(dlx/dx):0),
16744 ndly = dly-(dx?dx*(dly/dx):0),
16745 ndtx = dtx-(dx?dx*(dtx/dx):0),
16746 ndty = dty-(dx?dx*(dty/dx):0);
16747 int errlx = dx>>1, errly = errlx, errtx = errlx, errty = errlx;
16748 if (xleft<0 && dx) {
16749 lxleft-=xleft*(lxright-lxleft)/dx;
16750 lyleft-=xleft*(lyright-lyleft)/dx;
16751 txleft-=xleft*(txright-txleft)/dx;
16752 tyleft-=xleft*(tyright-tyleft)/dx;
16753 }
16754 if (xleft<0) xleft=0;
16755 if (xright>=dimx()-1) xright=dimx()-1;
16756 T* ptrd = ptr(xleft,y,0,0);
16757 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16758 const tl lightness = light(lxleft,lyleft);
16759 const t *col = texture.ptr(txleft,tyleft);
16760 cimg_forV(*this,k) {
16761 const float tval = (float)(lightness**col);
16762 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16763 *ptrd = (T)val;
16764 ptrd+=whz; col+=twhz;
16765 }
16766 ptrd-=offx;
16767 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16768 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16769 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16770 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16771 } else for (int x=xleft; x<=xright; ++x) {
16772 const tl lightness = light(lxleft,lyleft);
16773 const t *col = texture.ptr(txleft,tyleft);
16774 cimg_forV(*this,k) {
16775 const float tval = (float)(lightness**col);
16776 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16777 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16778 ptrd+=whz; col+=twhz;
16779 }
16780 ptrd-=offx;
16781 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16782 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16783 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16784 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16785 }
16786 }
16787 }
16788 }
16789 return *this;
16790 }
16791
16793 template<typename t, typename tl> CImg<T>& draw_triangle(const int x0, const int y0, const float z0,
16794 const int x1, const int y1, const float z1,
16795 const int x2, const int y2, const float z2,
16796 const CImg<t>& texture,
16797 const int tx0, const int ty0,
16798 const int tx1, const int ty1,
16799 const int tx2, const int ty2,
16800 const CImg<tl>& light,
16801 const int lx0, const int ly0,
16802 const int lx1, const int ly1,
16803 const int lx2, const int ly2,
16804 const float opacity=1.0f) {
16805 if (!is_empty() && z0>0 && z1>0 && z2>0) {
16806 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16807 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16808 if (!light) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.",
16809 pixel_type(),light.width,light.height,light.depth,light.dim,light.data);
16810 if (is_overlapping(texture)) return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
16811 if (is_overlapping(light)) return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,texture,tx0,ty0,tx1,ty1,tx2,ty2,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
16812 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16813 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16814 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16815 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16816 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
16817 float
16818 ntx0 = tx0/z0, nty0 = ty0/z0,
16819 ntx1 = tx1/z1, nty1 = ty1/z1,
16820 ntx2 = tx2/z2, nty2 = ty2/z2,
16821 nz0 = 1.0f/z0, nz1 = 1.0f/z1, nz2 = 1.0f/z2;
16822 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1,nz0,nz1);
16823 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2,nz0,nz2);
16824 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2,nz1,nz2);
16825 if (ny0<dimy() && ny2>=0) {
16826 float
16827 ptxl = (ntx1-ntx0)/(ny1-ny0),
16828 ptxr = (ntx2-ntx0)/(ny2-ny0),
16829 ptxn = (ntx2-ntx1)/(ny2-ny1),
16830 ptyl = (nty1-nty0)/(ny1-ny0),
16831 ptyr = (nty2-nty0)/(ny2-ny0),
16832 ptyn = (nty2-nty1)/(ny2-ny1),
16833 pzl = (nz1-nz0)/(ny1-ny0),
16834 pzr = (nz2-nz0)/(ny2-ny0),
16835 pzn = (nz2-nz1)/(ny2-ny1),
16836 zr = ny0>=0?nz0:(nz0-ny0*(nz2-nz0)/(ny2-ny0)),
16837 txr = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)),
16838 tyr = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)),
16839 zl = ny1>=0?(ny0>=0?nz0:(nz0-ny0*(nz1-nz0)/(ny1-ny0))):(pzl=pzn,(nz1-ny1*(nz2-nz1)/(ny2-ny1))),
16840 txl = ny1>=0?(ny0>=0?ntx0:(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ptxl=ptxn,(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1))),
16841 tyl = ny1>=0?(ny0>=0?nty0:(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(ptyl=ptyn,(nty1-ny1*(nty2-nty1)/(ny2-ny1)));
16842 _cimg_for_triangle3(*this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y,
16843 nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) {
16844 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
16845 int
16846 xleft = xleft0, xright = xright0,
16847 lxleft = lxleft0, lxright = lxright0,
16848 lyleft = lyleft0, lyright = lyright0;
16849 float
16850 zleft = zl, zright = zr,
16851 txleft = txl, txright = txr,
16852 tyleft = tyl, tyright = tyr;
16853 if (xright<xleft) cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright,lxleft,lxright,lyleft,lyright);
16854 const int
16855 dx = xright-xleft,
16856 dlx = lxright>lxleft?lxright-lxleft:lxleft-lxright,
16857 dly = lyright>lyleft?lyright-lyleft:lyleft-lyright,
16858 rlx = dx?(lxright-lxleft)/dx:0,
16859 rly = dx?(lyright-lyleft)/dx:0,
16860 slx = lxright>lxleft?1:-1,
16861 sly = lyright>lyleft?1:-1,
16862 ndlx = dlx-(dx?dx*(dlx/dx):0),
16863 ndly = dly-(dx?dx*(dly/dx):0);
16864 const float
16865 pentez = (zright-zleft)/dx,
16866 pentetx = (txright-txleft)/dx,
16867 pentety = (tyright-tyleft)/dx;
16868 int errlx = dx>>1, errly = errlx;
16869 if (xleft<0 && dx) {
16870 zleft-=xleft*(zright-zleft)/dx;
16871 lxleft-=xleft*(lxright-lxleft)/dx;
16872 lyleft-=xleft*(lyright-lyleft)/dx;
16873 txleft-=xleft*(txright-txleft)/dx;
16874 tyleft-=xleft*(tyright-tyleft)/dx;
16875 }
16876 if (xleft<0) xleft=0;
16877 if (xright>=dimx()-1) xright=dimx()-1;
16878 T* ptrd = ptr(xleft,y,0,0);
16879 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16880 const float invz = 1.0f/zleft;
16881 const tl lightness = light(lxleft,lyleft);
16882 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16883 cimg_forV(*this,k) {
16884 const float tval = (float)(lightness**col);
16885 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16886 *ptrd = val;
16887 ptrd+=whz; col+=twhz;
16888 }
16889 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16890 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16891 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16892 } else for (int x=xleft; x<=xright; ++x) {
16893 const float invz = 1.0f/zleft;
16894 const tl lightness = light(lxleft,lyleft);
16895 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16896 cimg_forV(*this,k) {
16897 const float tval = (float)(lightness**col);
16898 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16899 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16900 ptrd+=whz; col+=twhz;
16901 }
16902 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16903 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16904 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16905 }
16906 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
16907 }
16908 }
16909 }
16910 return *this;
16911 }
16912
16913
16914 template<typename tc>
16915 CImg<T>& _draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
16916 const tc *const color, const float opacity, const unsigned int pattern) {
16917 if (!is_empty()) {
16918 if (!color) throw CImgArgumentException("CImg<%s>::draw_ellipse : Specified color is (null).",pixel_type());
16919 _draw_scanline(color,opacity);
16920 const float
16921 nr1 = cimg::abs(r1), nr2 = cimg::abs(r2),
16922 norm = (float)std::sqrt(ru*ru+rv*rv),
16923 u = norm>0?ru/norm:1,
16924 v = norm>0?rv/norm:0,
16925 rmax = cimg::max(nr1,nr2),
16926 l1 = (float)std::pow(rmax/(nr1>0?nr1:1e-6),2),
16927 l2 = (float)std::pow(rmax/(nr2>0?nr2:1e-6),2),
16928 a = l1*u*u + l2*v*v,
16929 b = u*v*(l1-l2),
16930 c = l1*v*v + l2*u*u;
16931 const int
16932 yb = (int)std::sqrt(a*rmax*rmax/(a*c-b*b)),
16933 tymin = y0-yb,
16934 tymax = y0+yb,
16935 ymin = tymin<0?0:tymin,
16936 ymax = tymax>=dimy()?height-1:tymax;
16937 int oxmin = 0, oxmax = 0;
16938 bool first_line = true;
16939 for (int y=ymin; y<=ymax; ++y) {
16940 const float
16941 Y = y-y0 + (y<y0?0.5f:-0.5f),
16942 delta = b*b*Y*Y-a*(c*Y*Y-rmax*rmax),
16943 sdelta = delta>0?(float)std::sqrt(delta)/a:0.0f,
16944 bY = b*Y/a,
16945 fxmin = x0-0.5f-bY-sdelta,
16946 fxmax = x0+0.5f-bY+sdelta;
16947 const int xmin = (int)fxmin, xmax = (int)fxmax;
16948 if (!pattern) _draw_scanline(xmin,xmax,y,color,opacity);
16949 else {
16950 if (first_line) {
16951 if (y0-yb>=0) _draw_scanline(xmin,xmax,y,color,opacity);
16952 else draw_point(xmin,y,color,opacity).draw_point(xmax,y,color,opacity);
16953 first_line = false;
16954 } else {
16955 if (xmin<oxmin) _draw_scanline(xmin,oxmin-1,y,color,opacity);
16956 else _draw_scanline(oxmin+(oxmin==xmin?0:1),xmin,y,color,opacity);
16957 if (xmax<oxmax) _draw_scanline(xmax,oxmax-1,y,color,opacity);
16958 else _draw_scanline(oxmax+(oxmax==xmax?0:1),xmax,y,color,opacity);
16959 if (y==tymax) _draw_scanline(xmin+1,xmax-1,y,color,opacity);
16960 }
16961 }
16962 oxmin = xmin; oxmax = xmax;
16963 }
16964 }
16965 return *this;
16966 }
16967
16969
16980 template<typename tc>
16981 CImg<T>& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
16982 const tc *const color, const float opacity, const unsigned int pattern) {
16983 if (pattern) _draw_ellipse(x0,y0,r1,r2,ru,rv,color,opacity,pattern);
16984 return *this;
16985 }
16986
16987 template<typename tc>
16988 CImg<T>& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
16989 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
16990 return draw_ellipse(x0,y0,r1,r2,ru,rv,color.data,opacity,pattern);
16991 }
16992
16994
17004 template<typename tc>
17005 CImg<T>& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
17006 const tc *const color, const float opacity=1.0f) {
17007 return _draw_ellipse(x0,y0,r1,r2,ru,rv,color,opacity,0U);
17008 }
17009
17010 template<typename tc>
17011 CImg<T>& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
17012 const CImg<tc>& color, const float opacity=1.0f) {
17013 return draw_ellipse(x0,y0,r1,r2,ru,rv,color.data,opacity);
17014 }
17015
17017
17024 template<typename t, typename tc>
17025 CImg<T>& draw_ellipse(const int x0, const int y0, const CImg<t> &tensor,
17026 const tc *const color, const float opacity=1.0f) {
17027 CImgList<t> eig = tensor.get_symmetric_eigen();
17028 const CImg<t> &val = eig[0], &vec = eig[1];
17029 return draw_ellipse(x0,y0,val(0),val(1),vec(0,0),vec(0,1),color,opacity);
17030 }
17031
17032 template<typename t, typename tc>
17033 CImg<T>& draw_ellipse(const int x0, const int y0, const CImg<t> &tensor,
17034 const CImg<tc>& color, const float opacity=1.0f) {
17035 return draw_ellipse(x0,y0,tensor,color.data,opacity);
17036 }
17037
17039
17047 template<typename t, typename tc>
17048 CImg<T>& draw_ellipse(const int x0, const int y0, const CImg<t> &tensor,
17049 const tc *const color, const float opacity, const unsigned int pattern) {
17050 CImgList<t> eig = tensor.get_symmetric_eigen();
17051 const CImg<t> &val = eig[0], &vec = eig[1];
17052 return draw_ellipse(x0,y0,val(0),val(1),vec(0,0),vec(0,1),color,opacity,pattern);
17053 }
17054
17055 template<typename t, typename tc>
17056 CImg<T>& draw_ellipse(const int x0, const int y0, const CImg<t> &tensor,
17057 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
17058 return draw_ellipse(x0,y0,tensor,color.data,opacity,pattern);
17059 }
17060
17062
17071 template<typename tc>
17072 CImg<T>& draw_circle(const int x0, const int y0, int radius, const tc *const color, const float opacity=1.0f) {
17073 if (!is_empty()) {
17074 if (!color) throw CImgArgumentException("CImg<%s>::draw_circle : Specified color is (null).",pixel_type());
17075 _draw_scanline(color,opacity);
17076 if (radius<0 || x0-radius>=dimx() || y0+radius<0 || y0-radius>=dimy()) return *this;
17077 if (y0>=0 && y0<dimy()) _draw_scanline(x0-radius,x0+radius,y0,color,opacity);
17078 for (int f=1-radius, ddFx=0, ddFy=-(radius<<1), x=0, y=radius; x<y; ) {
17079 if (f>=0) {
17080 const int x1 = x0-x, x2 = x0+x, y1 = y0-y, y2 = y0+y;
17081 if (y1>=0 && y1<dimy()) _draw_scanline(x1,x2,y1,color,opacity);
17082 if (y2>=0 && y2<dimy()) _draw_scanline(x1,x2,y2,color,opacity);
17083 f+=(ddFy+=2); --y;
17084 }
17085 const bool no_diag = y!=(x++);
17086 ++(f+=(ddFx+=2));
17087 const int x1 = x0-y, x2 = x0+y, y1 = y0-x, y2 = y0+x;
17088 if (no_diag) {
17089 if (y1>=0 && y1<dimy()) _draw_scanline(x1,x2,y1,color,opacity);
17090 if (y2>=0 && y2<dimy()) _draw_scanline(x1,x2,y2,color,opacity);
17091 }
17092 }
17093 }
17094 return *this;
17095 }
17096
17097 template<typename tc>
17098 CImg<T>& draw_circle(const int x0, const int y0, int radius, const CImg<tc>& color, const float opacity=1.0f) {
17099 return draw_circle(x0,y0,radius,color.data,opacity);
17100 }
17101
17103
17110 template<typename tc>
17111 CImg<T>& draw_circle(const int x0, const int y0, int radius, const tc *const color, const float opacity, const unsigned int) {
17112 if (!is_empty()) {
17113 if (!color) throw CImgArgumentException("CImg<%s>::draw_circle : Specified color is (null).",pixel_type());
17114 if (radius<0 || x0-radius>=dimx() || y0+radius<0 || y0-radius>=dimy()) return *this;
17115 if (!radius) return draw_point(x0,y0,color,opacity);
17116 draw_point(x0-radius,y0,color,opacity).draw_point(x0+radius,y0,color,opacity).
17117 draw_point(x0,y0-radius,color,opacity).draw_point(x0,y0+radius,color,opacity);
17118 if (radius==1) return *this;
17119 for (int f=1-radius, ddFx=0, ddFy=-(radius<<1), x=0, y=radius; x<y; ) {
17120 if (f>=0) { f+=(ddFy+=2); --y; }
17121 ++x; ++(f+=(ddFx+=2));
17122 if (x!=y+1) {
17123 const int x1 = x0-y, x2 = x0+y, y1 = y0-x, y2 = y0+x, x3 = x0-x, x4 = x0+x, y3 = y0-y, y4 = y0+y;
17124 draw_point(x1,y1,color,opacity).draw_point(x1,y2,color,opacity).
17125 draw_point(x2,y1,color,opacity).draw_point(x2,y2,color,opacity);
17126 if (x!=y)
17127 draw_point(x3,y3,color,opacity).draw_point(x4,y4,color,opacity).
17128 draw_point(x4,y3,color,opacity).draw_point(x3,y4,color,opacity);
17129 }
17130 }
17131 }
17132 return *this;
17133 }
17134
17135 template<typename tc>
17136 CImg<T>& draw_circle(const int x0, const int y0, int radius, const CImg<tc>& color, const float opacity, const unsigned int foo) {
17137 return draw_circle(x0,y0,radius,color.data,opacity,foo);
17138 }
17139
17141
17152 template<typename t>
17153 CImg<T>& draw_text(const char *const text,
17154 const int x0, const int y0,
17155 const T *const fgcolor, const T *const bgcolor,
17156 const CImgList<t>& font, const float opacity=1.0f) {
17157 if (!text)
17158 throw CImgArgumentException("CImg<%s>::draw_text() : Specified input string is (null).",pixel_type());
17159 if (!font)
17160 throw CImgArgumentException("CImg<%s>::draw_text() : Specified font (%u,%p) is empty.",
17161 pixel_type(),font.size,font.data);
17162
17163 if (is_empty()) {
17164
17165 int x = 0, y = 0, w = 0;
17166 for (int i=0; i<cimg::strlen(text); ++i) {
17167 const unsigned char c = text[i];
17168 switch (c) {
17169 case '\n': y+=font[' '].height; if (x>w) w = x; x = 0; break;
17170 case '\t': x+=4*font[' '].width; break;
17171 default: if (c<font.size) x+=font[c].width;
17172 }
17173 }
17174 if (x!=0) {
17175 if (x>w) w=x;
17176 y+=font[' '].height;
17177 }
17178 assign(x0+w,y0+y,1,font[' '].dim,0);
17179 if (bgcolor) cimg_forV(*this,k) get_shared_channel(k).fill((T)bgcolor[k]);
17180 }
17181
17182 int x = x0, y = y0;
17183 CImg<T> letter;
17184 for (int i=0; i<cimg::strlen(text); ++i) {
17185 const unsigned char c = text[i];
17186 switch (c) {
17187 case '\n': y+=font[' '].height; x=x0; break;
17188 case '\t': x+=4*font[' '].width; break;
17189 default: if (c<font.size) {
17190 letter = font[c];
17191 const CImg<T>& mask = (c+256)<(int)font.size?font[c+256]:font[c];
17192 if (fgcolor) for (unsigned int p=0; p<letter.width*letter.height; ++p)
17193 if (mask(p)) cimg_forV(*this,k) letter(p,0,0,k) = (T)(letter(p,0,0,k)*fgcolor[k]);
17194 if (bgcolor) for (unsigned int p=0; p<letter.width*letter.height; ++p)
17195 if (!mask(p)) cimg_forV(*this,k) letter(p,0,0,k) = (T)bgcolor[k];
17196 if (!bgcolor && font.size>=512) draw_image(letter,mask,x,y,0,0,(T)1,opacity);
17197 else draw_image(letter,x,y,0,0,opacity);
17198 x+=letter.width;
17199 }
17200 break;
17201 }
17202 }
17203 return *this;
17204 }
17205
17206 template<typename tc, typename t>
17207 CImg<T>& draw_text(const char *const text,
17208 const int x0, const int y0,
17209 const CImg<tc>& fgcolor, const CImg<tc>& bgcolor,
17210 const CImgList<t>& font, const float opacity=1.0f) {
17211 const CImg<T> fgcol(fgcolor), bgcol(bgcolor);
17212 return draw_text(text,x0,y0,fgcol.data,bgcol.data,font,opacity);
17213 }
17214
17216
17227 CImg<T>& draw_text(const char *const text,
17228 const int x0, const int y0,
17229 const T *const fgcolor, const T *const bgcolor=0,
17230 const unsigned int font_size=11, const float opacity=1.0f) {
17231 return draw_text(text,x0,y0,fgcolor,bgcolor,CImgList<T>::get_font(font_size),opacity);
17232 }
17233
17234 template<typename tc>
17235 CImg<T>& draw_text(const char *const text,
17236 const int x0, const int y0,
17237 const CImg<tc>& fgcolor, const CImg<tc>& bgcolor,
17238 const unsigned int font_size=11, const float opacity=1.0f) {
17239 const CImg<T> fgcol(fgcolor), bgcol(bgcolor);
17240 return draw_text(text,x0,y0,fgcol.data,bgcol.data,font_size,opacity);
17241 }
17242
17244
17254 CImg<T>& draw_text(const int x0, const int y0,
17255 const T *const fgcolor, const T *const bgcolor, const unsigned int font_size,
17256 const float opacity, const char *format,...) {
17257 char tmp[2048] = { 0 };
17258 std::va_list ap;
17259 va_start(ap,format);
17260 std::vsprintf(tmp,format,ap);
17261 va_end(ap);
17262 return draw_text(tmp,x0,y0,fgcolor,bgcolor,font_size,opacity);
17263 }
17264
17265 template<typename tc>
17266 CImg<T>& draw_text(const int x0, const int y0,
17267 const CImg<tc>& fgcolor, const CImg<tc>& bgcolor, const unsigned int font_size,
17268 const float opacity, const char *format,...) {
17269 char tmp[2048] = { 0 };
17270 std::va_list ap;
17271 va_start(ap,format);
17272 std::vsprintf(tmp,format,ap);
17273 va_end(ap);
17274 return draw_text(tmp,x0,y0,fgcolor,bgcolor,font_size,opacity);
17275 }
17276
17278
17288 template<typename t>
17289 CImg<T>& draw_text(const int x0, const int y0,
17290 const T *const fgcolor, const T *const bgcolor,
17291 const CImgList<t>& font, const float opacity, const char *format,...) {
17292 char tmp[2048] = { 0 };
17293 std::va_list ap;
17294 va_start(ap,format);
17295 std::vsprintf(tmp,format,ap);
17296 va_end(ap);
17297 return draw_text(tmp,x0,y0,fgcolor,bgcolor,font,opacity);
17298 }
17299
17300 template<typename tc, typename t>
17301 CImg<T>& draw_text(const int x0, const int y0,
17302 const CImg<tc>& fgcolor, const CImg<tc>& bgcolor,
17303 const CImgList<t>& font, const float opacity, const char *format,...) {
17304 char tmp[2048] = { 0 };
17305 std::va_list ap;
17306 va_start(ap,format);
17307 std::vsprintf(tmp,format,ap);
17308 va_end(ap);
17309 return draw_text(tmp,x0,y0,fgcolor,bgcolor,font,opacity);
17310 }
17311
17313
17323 template<typename t1, typename t2>
17324 CImg<T>& draw_quiver(const CImg<t1>& flow, const t2 *const color,
17325 const unsigned int sampling=25, const float factor=-20,
17326 const int quiver_type=0, const float opacity=1.0f, const unsigned int pattern=~0U) {
17327 return draw_quiver(flow,CImg<t2>(color,dim,1,1,1,true),sampling,factor,quiver_type,opacity,pattern);
17328 }
17329
17331
17341 template<typename t1, typename t2>
17342 CImg<T>& draw_quiver(const CImg<t1>& flow, const CImg<t2>& color,
17343 const unsigned int sampling=25, const float factor=-20,
17344 const int quiver_type=0, const float opacity=1.0f, const unsigned int pattern=~0U) {
17345 if (!is_empty()) {
17346 if (!flow || flow.dim!=2)
17347 throw CImgArgumentException("CImg<%s>::draw_quiver() : Specified flow (%u,%u,%u,%u,%p) has wrong dimensions.",
17348 pixel_type(),flow.width,flow.height,flow.depth,flow.dim,flow.data);
17349 if (sampling<=0)
17350 throw CImgArgumentException("CImg<%s>::draw_quiver() : Incorrect sampling value = %g",pixel_type(),sampling);
17351 const bool colorfield = (color.width==flow.width && color.height==flow.height && color.depth==1 && color.dim==dim);
17352 if (is_overlapping(flow)) return draw_quiver(+flow,color,sampling,factor,quiver_type,opacity,pattern);
17353
17354 float vmax,fact;
17355 if (factor<=0) {
17356 float m, M = (float)flow.get_norm_pointwise(2).maxmin(m);
17357 vmax = (float)cimg::max(cimg::abs(m),cimg::abs(M));
17358 fact = -factor;
17359 } else { fact = factor; vmax = 1; }
17360
17361 for (unsigned int y=sampling/2; y<height; y+=sampling)
17362 for (unsigned int x=sampling/2; x<width; x+=sampling) {
17363 const unsigned int X = x*flow.width/width, Y = y*flow.height/height;
17364 float u = (float)flow(X,Y,0,0)*fact/vmax, v = (float)flow(X,Y,0,1)*fact/vmax;
17365 if (!quiver_type) {
17366 const int xx = x+(int)u, yy = y+(int)v;
17367 if (colorfield) draw_arrow(x,y,xx,yy,color.get_vector_at(X,Y).data,45.0f,sampling/5.0f,opacity,pattern);
17368 else draw_arrow(x,y,xx,yy,color,45.0f,sampling/5.0f,opacity,pattern);
17369 } else {
17370 if (colorfield) draw_line((int)(x-0.5*u),(int)(y-0.5*v),(int)(x+0.5*u),(int)(y+0.5*v),color.get_vector_at(X,Y),opacity,pattern);
17371 else draw_line((int)(x-0.5*u),(int)(y-0.5*v),(int)(x+0.5*u),(int)(y+0.5*v),color,opacity,pattern);
17372 }
17373 }
17374 }
17375 return *this;
17376 }
17377
17379
17395 template<typename t, typename tc>
17396 CImg<T>& draw_graph(const CImg<t>& data, const tc *const color, const unsigned int gtype=1,
17397 const double ymin=0, const double ymax=0, const float opacity=1.0f,
17398 const unsigned int pattern=~0U) {
17399 if (!is_empty()) {
17400 if (!color) throw CImgArgumentException("CImg<%s>::draw_graph() : Specified color is (null)",pixel_type());
17401 tc *color1 = new tc[dim], *color2 = new tc[dim];
17402 cimg_forV(*this,k) { color1[k]=(tc)(color[k]*0.6f); color2[k]=(tc)(color[k]*0.3f); }
17403 float m = (float)ymin, M = (float)ymax;
17404 if (ymin==ymax) m = (float)data.maxmin(M);
17405 if (m==M) { --m; ++M; }
17406 const float ca = height>1?(float)(M-m)/(height-1):0;
17407 const int Y0 = (int)(-m/ca);
17408 int pY = 0;
17409 bool init_hatch = true;
17410 if (gtype<3) cimg_foroff(data,off) {
17411 const int Y = (int)((data[off]-m)/ca);
17412 switch (gtype) {
17413 case 0: {
17414 const unsigned int X = off*width/data.size();
17415 draw_point(X,Y,color,opacity);
17416 } break;
17417 case 1:
17418 if (off>0) {
17419 draw_line((int)((off-1)*width/data.size()),pY,(int)(off*width/data.size()),Y,color,opacity,pattern,init_hatch);
17420 init_hatch = false;
17421 }
17422 break;
17423 case 2: {
17424 const unsigned int X = off*width/data.size(), nX = (off+1)*width/data.size()-1;
17425 draw_rectangle(X,(int)Y0,nX,Y,color1,opacity);
17426 draw_line(X,Y,X,(int)Y0,color2,opacity);
17427 draw_line(X,(int)Y0,nX,(int)Y0,Y<=Y0?color2:color,opacity);
17428 draw_line(nX,Y,nX,(int)Y0,color,opacity);
17429 draw_line(X,Y,nX,Y,Y<=Y0?color:color2,opacity);
17430 } break;
17431 }
17432 pY = Y;
17433 } else {
17434 const CImg<t> ndata = data.get_shared_points(0,data.size()-1);
17435 cimg_forX(*this,x) {
17436 const int Y = (int)((ndata.cubic_pix1d((float)x*ndata.width/width)-m)/ca);
17437 if (x>0) draw_line(x,pY,x+1,Y,color,opacity,pattern,init_hatch);
17438 init_hatch = false;
17439 pY = Y;
17440 }
17441 }
17442 delete[] color1; delete[] color2;
17443 }
17444 return *this;
17445 }
17446
17447 template<typename t, typename tc>
17448 CImg<T>& draw_graph(const CImg<t>& data, const CImg<tc>& color, const unsigned int gtype=1,
17449 const double ymin=0, const double ymax=0, const float opacity=1.0f,
17450 const unsigned int pattern=~0U) {
17451 return draw_graph(data,color.data,gtype,ymin,ymax,opacity,pattern);
17452 }
17453
17455
17464 template<typename t, typename tc>
17465 CImg<T>& draw_axis(const CImg<t>& xvalues, const int y,
17466 const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U) {
17467 if (!is_empty()) {
17468 int siz = (int)xvalues.size()-1;
17469 if (siz<=0) draw_line(0,y,width-1,y,color,opacity,pattern);
17470 else {
17471 if (xvalues[0]<xvalues[siz]) draw_arrow(0,y,width-1,y,color,30,5,opacity,pattern);
17472 else draw_arrow(width-1,y,0,y,color,30,5,opacity,pattern);
17473 const int yt = (y+14)<dimy()?(y+3):(y-14);
17474 char txt[32];
17475 cimg_foroff(xvalues,x) {
17476 std::sprintf(txt,"%g",(double)xvalues(x));
17477 const int xi=(int)(x*(width-1)/siz), xt = xi-(int)std::strlen(txt)*3;
17478 draw_point(xi,y-1,color,opacity).draw_point(xi,y+1,color,opacity).
17479 draw_text(txt,xt<0?0:xt,yt,color,(tc*)0,11,opacity);
17480 }
17481 }
17482 }
17483 return *this;
17484 }
17485
17486 template<typename t, typename tc>
17487 CImg<T>& draw_axis(const CImg<t>& xvalues, const int y,
17488 const CImg<tc>& color, const float opacity=1.0f, const unsigned int pattern=~0U) {
17489 return draw_axis(xvalues,y,color.data,opacity,pattern);
17490 }
17491
17493 template<typename t, typename tc>
17494 CImg<T>& draw_axis(const int x, const CImg<t>& yvalues,
17495 const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U) {
17496 if (!is_empty()) {
17497 int siz = (int)yvalues.size()-1;
17498 if (siz<=0) draw_line(x,0,x,height-1,color,opacity,pattern);
17499 else {
17500 if (yvalues[0]<yvalues[siz]) draw_arrow(x,0,x,height-1,color,30,5,opacity,pattern);
17501 else draw_arrow(x,height-1,x,0,color,30,5,opacity,pattern);
17502 char txt[32];
17503 cimg_foroff(yvalues,y) {
17504 std::sprintf(txt,"%g",(double)yvalues(y));
17505 const int
17506 yi = (int)(y*(height-1)/siz),
17507 tmp = yi-5,
17508 nyi = tmp<0?0:(tmp>=dimy()-11?dimy()-11:tmp),
17509 xt = x-(int)std::strlen(txt)*7;
17510 draw_point(x-1,yi,color,opacity).draw_point(x+1,yi,color,opacity);
17511 if (xt>0) draw_text(txt,xt,nyi,color,(tc*)0,11,opacity);
17512 else draw_text(txt,x+3,nyi,color,(tc*)0,11,opacity);
17513 }
17514 }
17515 }
17516 return *this;
17517 }
17518
17519 template<typename t, typename tc>
17520 CImg<T>& draw_axis(const int x, const CImg<t>& yvalues,
17521 const CImg<tc>& color, const float opacity=1.0f, const unsigned int pattern=~0U) {
17522 return draw_axis(x,yvalues,color.data,opacity,pattern);
17523 }
17524
17526 template<typename tx, typename ty, typename tc>
17527 CImg<T>& draw_axis(const CImg<tx>& xvalues, const CImg<ty>& yvalues,
17528 const tc *const color,
17529 const float opacity=1.0f,
17530 const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17531 if (!is_empty()) {
17532 const CImg<tx> nxvalues(xvalues.data,xvalues.size(),1,1,1,true);
17533 const int sizx = (int)xvalues.size()-1, wm1 = (int)(width)-1;
17534 if (sizx>0) {
17535 float ox = (float)nxvalues[0];
17536 for (unsigned int x=1; x<width; ++x) {
17537 const float nx = (float)nxvalues.linear_pix1d((float)x*sizx/wm1);
17538 if (nx*ox<=0) { draw_axis(nx==0?x:x-1,yvalues,color,opacity,patterny); break; }
17539 ox = nx;
17540 }
17541 }
17542 const CImg<ty> nyvalues(yvalues.data,yvalues.size(),1,1,1,true);
17543 const int sizy = (int)yvalues.size()-1, hm1 = (int)(height)-1;
17544 if (sizy>0) {
17545 float oy = (float)nyvalues[0];
17546 for (unsigned int y=1; y<height; ++y) {
17547 const float ny = (float)nyvalues.linear_pix1d((float)y*sizy/hm1);
17548 if (ny*oy<=0) { draw_axis(xvalues,ny==0?y:y-1,color,opacity,patternx); break; }
17549 oy = ny;
17550 }
17551 }
17552 }
17553 return *this;
17554 }
17555
17556 template<typename tx, typename ty, typename tc>
17557 CImg<T>& draw_axis(const CImg<tx>& xvalues, const CImg<ty>& yvalues,
17558 const CImg<tc>& color,
17559 const float opacity=1.0f,
17560 const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17561 return draw_axis(xvalues,yvalues,color.data,opacity,patternx,patterny);
17562 }
17563
17565 template<typename tc>
17566 CImg<T>& draw_axis(const float x0, const float x1, const float y0, const float y1,
17567 const tc *const color,
17568 const int subdivisionx=-60, const int subdivisiony=-60,
17569 const float precisionx=0, const float precisiony=0,
17570 const float opacity=1.0f,
17571 const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17572 const float dx = cimg::abs(x1-x0), dy = cimg::abs(y1-y0);
17573 const float
17574 px = (precisionx==0)?(float)std::pow(10.0,(int)std::log10(dx)-2.0):precisionx,
17575 py = (precisiony==0)?(float)std::pow(10.0,(int)std::log10(dy)-2.0):precisiony;
17576 return draw_axis(CImg<float>::sequence(subdivisionx>0?subdivisionx:1-dimx()/subdivisionx,x0,x1).round(px),
17577 CImg<float>::sequence(subdivisiony>0?subdivisiony:1-dimy()/subdivisiony,y0,y1).round(py),
17578 color,opacity,patternx,patterny);
17579 }
17580
17581 template<typename tc>
17582 CImg<T>& draw_axis(const float x0, const float x1, const float y0, const float y1,
17583 const CImg<tc>& color,
17584 const int subdivisionx=-60, const int subdivisiony=-60,
17585 const float precisionx=0, const float precisiony=0,
17586 const float opacity=1.0f,
17587 const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17588 return draw_axis(x0,x1,y0,y1,color.data,subdivisionx,subdivisiony,precisionx,precisiony,opacity,patternx,patterny);
17589 }
17590
17592 template<typename tx, typename ty, typename tc>
17593 CImg<T>& draw_grid(const CImg<tx>& xvalues, const CImg<ty>& yvalues, const tc *const color,
17594 const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17595 if (!is_empty()) {
17596 if (xvalues) cimg_foroff(xvalues,x) {
17597 const int xi = (int)xvalues[x];
17598 if (xi>=0 && xi<dimx()) draw_line(xi,0,xi,height-1,color,opacity,patternx);
17599 }
17600 if (yvalues) cimg_foroff(yvalues,y) {
17601 const int yi = (int)yvalues[y];
17602 if (yi>=0 && yi<dimy()) draw_line(0,yi,width-1,yi,color,opacity,patterny);
17603 }
17604 }
17605 return *this;
17606 }
17607
17608 template<typename tx, typename ty, typename tc>
17609 CImg<T>& draw_grid(const CImg<tx>& xvalues, const CImg<ty>& yvalues, const CImg<tc>& color,
17610 const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17611 return draw_grid(xvalues,yvalues,color.data,opacity,patternx,patterny);
17612 }
17613
17615 template<typename tc>
17616 CImg<T>& draw_grid(const float deltax, const float deltay,
17617 const float offsetx, const float offsety,
17618 const bool invertx, const bool inverty,
17619 const tc *const color,
17620 const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17621 CImg<unsigned int> seqx, seqy;
17622 if (deltax!=0) {
17623 const float dx = deltax>0?deltax:width*-deltax/100;
17624 const unsigned int nx = (unsigned int)(width/dx);
17625 seqx = CImg<unsigned int>::sequence(1+nx,0,(unsigned int)(dx*nx));
17626 if (offsetx) cimg_foroff(seqx,x) seqx(x) = (unsigned int)cimg::mod(seqx(x)+offsetx,(float)width);
17627 if (invertx) cimg_foroff(seqx,x) seqx(x) = width-1-seqx(x);
17628 }
17629
17630 if (deltay!=0) {
17631 const float dy = deltay>0?deltay:height*-deltay/100;
17632 const unsigned int ny = (unsigned int)(height/dy);
17633 seqy = CImg<unsigned int>::sequence(1+ny,0,(unsigned int)(dy*ny));
17634 if (offsety) cimg_foroff(seqy,y) seqy(y) = (unsigned int)cimg::mod(seqy(y)+offsety,(float)height);
17635 if (inverty) cimg_foroff(seqy,y) seqy(y) = height-1-seqy(y);
17636 }
17637 return draw_grid(seqx,seqy,color,opacity,patternx,patterny);
17638 }
17639
17640 template<typename tc>
17641 CImg<T>& draw_grid(const float deltax, const float deltay,
17642 const float offsetx, const float offsety,
17643 const bool invertx, const bool inverty,
17644 const CImg<tc>& color,
17645 const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17646 return draw_grid(deltax,deltay,offsetx,offsety,invertx,inverty,color.data,opacity,patternx,patterny);
17647 }
17648
17650
17661 template<typename tc, typename t>
17662 CImg<T>& draw_fill(const int x, const int y, const int z,
17663 const tc *const color, CImg<t>& region, const float sigma=0,
17664 const float opacity=1.0f, const bool high_connexity=false) {
17665
17666 #define _cimg_draw_fill_test(x,y,z,res) if (region(x,y,z)) res = false; else { \
17667 res = true; \
17668 const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(x,y,z) + siz; \
17669 for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } \
17670 region(x,y,z) = (t)(res?1:noregion); \
17671 }
17672
17673 #define _cimg_draw_fill_set(x,y,z) { \
17674 const tc *col = color; \
17675 T *ptrd = ptr(x,y,z); \
17676 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=whz; } \
17677 else cimg_forV(*this,k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } \
17678 }
17679
17680 #define _cimg_draw_fill_insert(x,y,z) { \
17681 if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); \
17682 unsigned int *ptrr = remaining.ptr(0,posr1); \
17683 *(ptrr++) = x; *(ptrr++) = y; *(ptrr++) = z; ++posr1; \
17684 }
17685
17686 #define _cimg_draw_fill_test_neighbor(x,y,z,cond) if (cond) { \
17687 const unsigned int tx = x, ty = y, tz = z; \
17688 _cimg_draw_fill_test(tx,ty,tz,res); if (res) _cimg_draw_fill_insert(tx,ty,tz); \
17689 }
17690
17691 if (!color) throw CImgArgumentException("CImg<%s>::draw_fill() : Specified color is (null).",pixel_type());
17692 region.assign(width,height,depth,1,(t)0);
17693 if (x>=0 || x<dimx() || y>=0 || y<dimy() || z>=0 || z<dimz()) {
17694 typedef typename cimg::last<T,unsigned int>::type itype;
17695 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
17696 const unsigned int whz = width*height*depth, siz = dim*whz, W1 = width-1, H1 = height-1, D1 = depth-1;
17697 const bool threed = depth>1;
17698 const CImg<T> reference_color = get_vector_at(x,y,z);
17699 CImg<itype> remaining(3,512,1,1,0);
17700 remaining(0,0) = x; remaining(1,0) = y; remaining(2,0) = z;
17701 unsigned int posr0 = 0, posr1 = 1;
17702 region(x,y,z) = (t)1;
17703 const t noregion = ((t)1==(t)2)?(t)0:(t)(-1);
17704 if (threed) do {
17705 const unsigned int *pcurr = remaining.ptr(0,posr0++), xc = *(pcurr++), yc = *(pcurr++), zc = *(pcurr++);
17706 if (posr0>=512) { remaining.translate(0,posr0); posr1-=posr0; posr0 = 0; }
17707 bool cont, res;
17708 unsigned int nxc = xc;
17709 do {
17710 _cimg_draw_fill_set(nxc,yc,zc);
17711 _cimg_draw_fill_test_neighbor(nxc,yc-1,zc,yc!=0);
17712 _cimg_draw_fill_test_neighbor(nxc,yc+1,zc,yc<H1);
17713 _cimg_draw_fill_test_neighbor(nxc,yc,zc-1,zc!=0);
17714 _cimg_draw_fill_test_neighbor(nxc,yc,zc+1,zc<D1);
17715 if (nxc) { --nxc; _cimg_draw_fill_test(nxc,yc,zc,cont); } else cont = false;
17716 } while (cont);
17717 nxc = xc;
17718 do {
17719 if ((++nxc)<=W1) { _cimg_draw_fill_test(nxc,yc,zc,cont); } else cont = false;
17720 if (cont) {
17721 _cimg_draw_fill_set(nxc,yc,zc);
17722 _cimg_draw_fill_test_neighbor(nxc,yc-1,zc,yc!=0);
17723 _cimg_draw_fill_test_neighbor(nxc,yc+1,zc,yc<H1);
17724 _cimg_draw_fill_test_neighbor(nxc,yc,zc-1,zc!=0);
17725 _cimg_draw_fill_test_neighbor(nxc,yc,zc+1,zc<D1);
17726 }
17727 } while (cont);
17728 unsigned int nyc = yc;
17729 do {
17730 if (nyc) { --nyc; _cimg_draw_fill_test(xc,nyc,zc,cont); } else cont = false;
17731 if (cont) {
17732 _cimg_draw_fill_set(xc,nyc,zc);
17733 _cimg_draw_fill_test_neighbor(xc-1,nyc,zc,xc!=0);
17734 _cimg_draw_fill_test_neighbor(xc+1,nyc,zc,xc<W1);
17735 _cimg_draw_fill_test_neighbor(xc,nyc,zc-1,zc!=0);
17736 _cimg_draw_fill_test_neighbor(xc,nyc,zc+1,zc<D1);
17737 }
17738 } while (cont);
17739 nyc = yc;
17740 do {
17741 if ((++nyc)<=H1) { _cimg_draw_fill_test(xc,nyc,zc,cont); } else cont = false;
17742 if (cont) {
17743 _cimg_draw_fill_set(xc,nyc,zc);
17744 _cimg_draw_fill_test_neighbor(xc-1,nyc,zc,xc!=0);
17745 _cimg_draw_fill_test_neighbor(xc+1,nyc,zc,xc<W1);
17746 _cimg_draw_fill_test_neighbor(xc,nyc,zc-1,zc!=0);
17747 _cimg_draw_fill_test_neighbor(xc,nyc,zc+1,zc<D1);
17748 }
17749 } while (cont);
17750 unsigned int nzc = zc;
17751 do {
17752 if (nzc) { --nzc; _cimg_draw_fill_test(xc,yc,nzc,cont); } else cont = false;
17753 if (cont) {
17754 _cimg_draw_fill_set(xc,yc,nzc);
17755 _cimg_draw_fill_test_neighbor(xc-1,yc,nzc,xc!=0);
17756 _cimg_draw_fill_test_neighbor(xc+1,yc,nzc,xc<W1);
17757 _cimg_draw_fill_test_neighbor(xc,yc-1,nzc,yc!=0);
17758 _cimg_draw_fill_test_neighbor(xc,yc+1,nzc,yc<H1);
17759 }
17760 } while (cont);
17761 nzc = zc;
17762 do {
17763 if ((++nzc)<=D1) { _cimg_draw_fill_test(xc,yc,nzc,cont); } else cont = false;
17764 if (cont) {
17765 _cimg_draw_fill_set(xc,nyc,zc);
17766 _cimg_draw_fill_test_neighbor(xc-1,yc,nzc,xc!=0);
17767 _cimg_draw_fill_test_neighbor(xc+1,yc,nzc,xc<W1);
17768 _cimg_draw_fill_test_neighbor(xc,yc-1,nzc,yc!=0);
17769 _cimg_draw_fill_test_neighbor(xc,yc+1,nzc,yc<H1);
17770 }
17771 } while (cont);
17772 } while (posr1>posr0);
17773 else do {
17774 const unsigned int *pcurr = remaining.ptr(0,posr0++), xc = *(pcurr++), yc = *(pcurr++);
17775 if (posr0>=512) { remaining.translate(0,posr0); posr1-=posr0; posr0 = 0; }
17776 bool cont, res;
17777 unsigned int nxc = xc;
17778 do {
17779 _cimg_draw_fill_set(nxc,yc,0);
17780 _cimg_draw_fill_test_neighbor(nxc,yc-1,0,yc!=0);
17781 _cimg_draw_fill_test_neighbor(nxc,yc+1,0,yc<H1);
17782 if (high_connexity) {
17783 _cimg_draw_fill_test_neighbor(nxc-1,yc-1,0,(nxc!=0 && yc!=0));
17784 _cimg_draw_fill_test_neighbor(nxc+1,yc-1,0,(nxc<W1 && yc!=0));
17785 _cimg_draw_fill_test_neighbor(nxc-1,yc+1,0,(nxc!=0 && yc<H1));
17786 _cimg_draw_fill_test_neighbor(nxc+1,yc+1,0,(nxc<W1 && yc<H1));
17787 }
17788 if (nxc) { --nxc; _cimg_draw_fill_test(nxc,yc,0,cont); } else cont = false;
17789 } while (cont);
17790 nxc = xc;
17791 do {
17792 if ((++nxc)<=W1) { _cimg_draw_fill_test(nxc,yc,0,cont); } else cont = false;
17793 if (cont) {
17794 _cimg_draw_fill_set(nxc,yc,0);
17795 _cimg_draw_fill_test_neighbor(nxc,yc-1,0,yc!=0);
17796 _cimg_draw_fill_test_neighbor(nxc,yc+1,0,yc<H1);
17797 if (high_connexity) {
17798 _cimg_draw_fill_test_neighbor(nxc-1,yc-1,0,(nxc!=0 && yc!=0));
17799 _cimg_draw_fill_test_neighbor(nxc+1,yc-1,0,(nxc<W1 && yc!=0));
17800 _cimg_draw_fill_test_neighbor(nxc-1,yc+1,0,(nxc!=0 && yc<H1));
17801 _cimg_draw_fill_test_neighbor(nxc+1,yc+1,0,(nxc<W1 && yc<H1));
17802 }
17803 }
17804 } while (cont);
17805 unsigned int nyc = yc;
17806 do {
17807 if (nyc) { --nyc; _cimg_draw_fill_test(xc,nyc,0,cont); } else cont = false;
17808 if (cont) {
17809 _cimg_draw_fill_set(xc,nyc,0);
17810 _cimg_draw_fill_test_neighbor(xc-1,nyc,0,xc!=0);
17811 _cimg_draw_fill_test_neighbor(xc+1,nyc,0,xc<W1);
17812 if (high_connexity) {
17813 _cimg_draw_fill_test_neighbor(xc-1,nyc-1,0,(xc!=0 && nyc!=0));
17814 _cimg_draw_fill_test_neighbor(xc+1,nyc-1,0,(xc<W1 && nyc!=0));
17815 _cimg_draw_fill_test_neighbor(xc-1,nyc+1,0,(xc!=0 && nyc<H1));
17816 _cimg_draw_fill_test_neighbor(xc+1,nyc+1,0,(xc<W1 && nyc<H1));
17817 }
17818 }
17819 } while (cont);
17820 nyc = yc;
17821 do {
17822 if ((++nyc)<=H1) { _cimg_draw_fill_test(xc,nyc,0,cont); } else cont = false;
17823 if (cont) {
17824 _cimg_draw_fill_set(xc,nyc,0);
17825 _cimg_draw_fill_test_neighbor(xc-1,nyc,0,xc!=0);
17826 _cimg_draw_fill_test_neighbor(xc+1,nyc,0,xc<W1);
17827 if (high_connexity) {
17828 _cimg_draw_fill_test_neighbor(xc-1,nyc-1,0,(xc!=0 && nyc!=0));
17829 _cimg_draw_fill_test_neighbor(xc+1,nyc-1,0,(xc<W1 && nyc!=0));
17830 _cimg_draw_fill_test_neighbor(xc-1,nyc+1,0,(xc!=0 && nyc<H1));
17831 _cimg_draw_fill_test_neighbor(xc+1,nyc+1,0,(xc<W1 && nyc<H1));
17832 }
17833 }
17834 } while (cont);
17835 } while (posr1>posr0);
17836 if (noregion) cimg_for(region,ptr,t) if (*ptr==noregion) *ptr = (t)0;
17837 }
17838 return *this;
17839 }
17840
17841 template<typename tc, typename t>
17842 CImg<T>& draw_fill(const int x, const int y, const int z,
17843 const CImg<tc>& color, CImg<t>& region, const float sigma=0,
17844 const float opacity=1.0f, const bool high_connexity=false) {
17845 return draw_fill(x,y,z,color.data,region,sigma,opacity,high_connexity);
17846 }
17847
17849
17857 template<typename tc>
17858 CImg<T>& draw_fill(const int x, const int y, const int z, const tc *const color, const float sigma=0,
17859 const float opacity=1.0f, const bool high_connexity=false) {
17860 CImg<bool> tmp;
17861 return draw_fill(x,y,z,color,tmp,sigma,opacity,high_connexity);
17862 }
17863
17864 template<typename tc>
17865 CImg<T>& draw_fill(const int x, const int y, const int z, const CImg<tc>& color, const float sigma=0,
17866 const float opacity=1.0f, const bool high_connexity=false) {
17867 return draw_fill(x,y,z,color.data,sigma,opacity,high_connexity);
17868 }
17869
17871
17878 template<typename tc>
17879 CImg<T>& draw_fill(const int x, const int y, const tc *const color, const float sigma=0,
17880 const float opacity=1.0f, const bool high_connexity=false) {
17881 CImg<bool> tmp;
17882 return draw_fill(x,y,0,color,tmp,sigma,opacity,high_connexity);
17883 }
17884
17885 template<typename tc>
17886 CImg<T>& draw_fill(const int x, const int y, const CImg<tc>& color, const float sigma=0,
17887 const float opacity=1.0f, const bool high_connexity=false) {
17888 return draw_fill(x,y,color.data,sigma,opacity,high_connexity);
17889 }
17890
17892
17901 CImg<T>& draw_plasma(const int x0, const int y0, const int x1, const int y1,
17902 const double alpha=1.0, const double beta=1.0, const float opacity=1.0f) {
17903 if (!is_empty()) {
17904 typedef typename cimg::superset<T,float>::type ftype;
17905 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
17906 int nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1;
17907 if (nx1<nx0) cimg::swap(nx0,nx1);
17908 if (ny1<ny0) cimg::swap(ny0,ny1);
17909 if (nx0<0) nx0 = 0;
17910 if (nx1>=dimx()) nx1 = width-1;
17911 if (ny0<0) ny0 = 0;
17912 if (ny1>=dimy()) ny1 = height-1;
17913 const int xc = (nx0+nx1)/2, yc = (ny0+ny1)/2, dx = (xc-nx0), dy = (yc-ny0);
17914 const ftype dc = (ftype)(std::sqrt((double)(dx*dx+dy*dy))*alpha + beta);
17915 ftype val = 0;
17916 cimg_forV(*this,k) {
17917 if (opacity>=1) {
17918 const ftype
17919 val0 = (*this)(nx0,ny0,0,k), val1 = (*this)(nx1,ny0,0,k),
17920 val2 = (*this)(nx0,ny1,0,k), val3 = (*this)(nx1,ny1,0,k);
17921 (*this)(xc,ny0,0,k) = (T)((val0+val1)/2);
17922 (*this)(xc,ny1,0,k) = (T)((val2+val3)/2);
17923 (*this)(nx0,yc,0,k) = (T)((val0+val2)/2);
17924 (*this)(nx1,yc,0,k) = (T)((val1+val3)/2);
17925 do {
17926 val = (ftype)(0.25f*((ftype)((*this)(nx0,ny0,0,k)) +
17927 (ftype)((*this)(nx1,ny0,0,k)) +
17928 (ftype)((*this)(nx1,ny1,0,k)) +
17929 (ftype)((*this)(nx0,ny1,0,k))) +
17930 dc*cimg::grand());
17931 } while (val<(ftype)cimg::type<T>::min() || val>(ftype)cimg::type<T>::max());
17932 (*this)(xc,yc,0,k) = (T)val;
17933 } else {
17934 const ftype
17935 val0 = (*this)(nx0,ny0,0,k), val1 = (*this)(nx1,ny0,0,k),
17936 val2 = (*this)(nx0,ny1,0,k), val3 = (*this)(nx1,ny1,0,k);
17937 (*this)(xc,ny0,0,k) = (T)(((val0+val1)*nopacity + copacity*(*this)(xc,ny0,0,k))/2);
17938 (*this)(xc,ny1,0,k) = (T)(((val2+val3)*nopacity + copacity*(*this)(xc,ny1,0,k))/2);
17939 (*this)(nx0,yc,0,k) = (T)(((val0+val2)*nopacity + copacity*(*this)(nx0,yc,0,k))/2);
17940 (*this)(nx1,yc,0,k) = (T)(((val1+val3)*nopacity + copacity*(*this)(nx1,yc,0,k))/2);
17941 do {
17942 val = (ftype)(0.25f*(((ftype)((*this)(nx0,ny0,0,k)) +
17943 (ftype)((*this)(nx1,ny0,0,k)) +
17944 (ftype)((*this)(nx1,ny1,0,k)) +
17945 (ftype)((*this)(nx0,ny1,0,k))) +
17946 dc*cimg::grand())*nopacity + copacity*(*this)(xc,yc,0,k));
17947 } while (val<(ftype)cimg::type<T>::min() || val>(ftype)cimg::type<T>::max());
17948 (*this)(xc,yc,0,k) = (T)val;
17949 }
17950 }
17951 if (xc!=nx0 || yc!=ny0) {
17952 draw_plasma(nx0,ny0,xc,yc,alpha,beta,opacity);
17953 draw_plasma(xc,ny0,nx1,yc,alpha,beta,opacity);
17954 draw_plasma(nx0,yc,xc,ny1,alpha,beta,opacity);
17955 draw_plasma(xc,yc,nx1,ny1,alpha,beta,opacity);
17956 }
17957 }
17958 return *this;
17959 }
17960
17962
17967 CImg<T>& draw_plasma(const double alpha=1.0, const double beta=1.0, const float opacity=1.0f) {
17968 return draw_plasma(0,0,width-1,height-1,alpha,beta,opacity);
17969 }
17970
17972
17978 template<typename tc>
17979 CImg<T>& draw_gaussian(const float xc, const double sigma, const tc *const color, const float opacity=1.0f) {
17980 if (!is_empty()) {
17981 if (!color) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Specified color is (null)",pixel_type());
17982 const double sigma2 = 2*sigma*sigma;
17983 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
17984 const unsigned int whz = width*height*depth;
17985 const tc *col = color;
17986 cimg_forX(*this,x) {
17987 const float dx = (x-xc);
17988 const double val = std::exp( -dx*dx/sigma2 );
17989 T *ptrd = ptr(x,0,0,0);
17990 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; }
17991 else cimg_forV(*this,k) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whz; }
17992 col-=dim;
17993 }
17994 }
17995 return *this;
17996 }
17997
17998 template<typename tc>
17999 CImg<T>& draw_gaussian(const float xc, const double sigma, const CImg<tc>& color, const float opacity=1.0f) {
18000 return draw_gaussian(xc,sigma,color.data,opacity);
18001 }
18002
18004
18011 template<typename t, typename tc>
18012 CImg<T>& draw_gaussian(const float xc, const float yc, const CImg<t>& tensor,
18013 const tc *const color, const float opacity=1.0f) {
18014 typedef typename cimg::superset<t,float>::type ftype;
18015 if (!is_empty()) {
18016 if (tensor.width!=2 || tensor.height!=2 || tensor.depth!=1 || tensor.dim!=1)
18017 throw CImgArgumentException("CImg<%s>::draw_gaussian() : Tensor parameter (%u,%u,%u,%u,%p) is not a 2x2 matrix.",
18018 pixel_type(),tensor.width,tensor.height,tensor.depth,tensor.dim,tensor.data);
18019 if (!color) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Specified color is (null)",pixel_type());
18020 const CImg<ftype> invT = tensor.get_inverse(), invT2 = (invT*invT)/(-2.0);
18021 const ftype a = invT2(0,0), b = 2*invT2(1,0), c = invT2(1,1);
18022 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
18023 const unsigned int whz = width*height*depth;
18024 const tc *col = color;
18025 float dy = -yc;
18026 cimg_forY(*this,y) {
18027 float dx = -xc;
18028 cimg_forX(*this,x) {
18029 const float val = (float)std::exp(a*dx*dx + b*dx*dy + c*dy*dy);
18030 T *ptrd = ptr(x,y,0,0);
18031 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; }
18032 else cimg_forV(*this,k) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whz; }
18033 col-=dim;
18034 ++dx;
18035 }
18036 ++dy;
18037 }
18038 }
18039 return *this;
18040 }
18041
18042 template<typename t, typename tc>
18043 CImg<T>& draw_gaussian(const float xc, const float yc, const CImg<t>& tensor,
18044 const CImg<tc>& color, const float opacity=1.0f) {
18045 return draw_gaussian(xc,yc,tensor,color.data,opacity);
18046 }
18047
18049
18056 template<typename tc>
18057 CImg<T>& draw_gaussian(const float xc, const float yc, const float sigma, const tc *const color, const float opacity=1.0f) {
18058 return draw_gaussian(xc,yc,CImg<float>::diagonal(sigma,sigma),color,opacity);
18059 }
18060
18061 template<typename tc>
18062 CImg<T>& draw_gaussian(const float xc, const float yc, const float sigma, const CImg<tc>& color, const float opacity=1.0f) {
18063 return draw_gaussian(xc,yc,sigma,color.data,opacity);
18064 }
18065
18067
18075 template<typename t, typename tc>
18076 CImg<T>& draw_gaussian(const float xc, const float yc, const float zc, const CImg<t>& tensor,
18077 const tc *const color, const float opacity=1.0f) {
18078 if (!is_empty()) {
18079 if (tensor.width!=3 || tensor.height!=3 || tensor.depth!=1 || tensor.dim!=1)
18080 throw CImgArgumentException("CImg<%s>::draw_gaussian() : Tensor parameter (%u,%u,%u,%u,%p) is not a 3x3 matrix.",
18081 pixel_type(),tensor.width,tensor.height,tensor.depth,tensor.dim,tensor.data);
18082 const CImg<t> invT = tensor.get_inverse(), invT2 = (invT*invT)/(-2.0);
18083 const t a=invT(0,0), b=2*invT(1,0), c=2*invT(2,0), d=invT(1,1), e=2*invT(2,1), f=invT(2,2);
18084 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
18085 const unsigned int whz = width*height*depth;
18086 const tc *col = color;
18087 cimg_forXYZ(*this,x,y,z) {
18088 const float dx = (x-xc), dy = (y-yc), dz = (z-zc);
18089 const double val = std::exp(a*dx*dx + b*dx*dy + c*dx*dz + d*dy*dy + e*dy*dz + f*dz*dz);
18090 T *ptrd = ptr(x,y,z,0);
18091 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; }
18092 else cimg_forV(*this,k) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whz; }
18093 col-=dim;
18094 }
18095 }
18096 return *this;
18097 }
18098
18099 template<typename t, typename tc>
18100 CImg<T>& draw_gaussian(const float xc, const float yc, const float zc, const CImg<t>& tensor,
18101 const CImg<tc>& color, const float opacity=1.0f) {
18102 return draw_gaussian(xc,yc,zc,tensor,color.data,opacity);
18103 }
18104
18106
18114 template<typename tc>
18115 CImg<T>& draw_gaussian(const float xc, const float yc, const float zc,
18116 const double sigma, const tc *const color, const float opacity=1.0f) {
18117 return draw_gaussian(xc,yc,zc,CImg<float>::diagonal(sigma,sigma,sigma),color,opacity);
18118 }
18119
18120 template<typename tc>
18121 CImg<T>& draw_gaussian(const float xc, const float yc, const float zc,
18122 const double sigma, const CImg<tc>& color, const float opacity=1.0f) {
18123 return draw_gaussian(xc,yc,zc,sigma,color.data,opacity);
18124 }
18125
18127
18143 template<typename tp, typename tf, typename tc, typename to>
18144 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18145 const CImg<tp>& points, const CImgList<tf>& primitives,
18146 const CImgList<tc>& colors, const CImgList<to>& opacities,
18147 const unsigned int render_type=4,
18148 const bool double_sided=false, const float focale=500,
18149 const float lightx=0, const float lighty=0, const float lightz=-5000,
18150 const float ambient_light=0.05f) {
18151
18152 static CImg<float> light_texture;
18153 if (is_empty() || !points || !primitives) return *this;
18154 if (!colors || !opacities)
18155 throw CImgArgumentException("CImg<%s>::draw_object3d() : Undefined colors or opacities",pixel_type());
18156
18157 if (points.height<3)
18158 return draw_object3d(X,Y,Z,points.get_resize(-100,3,1,1,0),primitives,colors,opacities,
18159 render_type,double_sided,focale,lightx,lighty,lightz,ambient_light);
18160
18161
18162 if (render_type==5) {
18163 if (colors.size>primitives.size) light_texture.assign(colors[primitives.size])/=255;
18164 else {
18165 static float olightx = 0, olighty = 0, olightz = 0, oambient_light = 0;
18166 if (!light_texture || lightx!=olightx || lighty!=olighty || lightz!=olightz || ambient_light!=oambient_light) {
18167 light_texture.assign(512,512);
18168 const float white[] = { 1.0f },
18169 dlx = lightx-X, dly = lighty-Y, dlz = lightz-Z,
18170 nl = (float)std::sqrt(dlx*dlx+dly*dly+dlz*dlz),
18171 nlx = light_texture.width/2*(1+dlx/nl),
18172 nly = light_texture.height/2*(1+dly/nl);
18173 (light_texture.draw_gaussian(nlx,nly,light_texture.width/3.0f,white)+=ambient_light);
18174 olightx = lightx; olighty = lighty; olightz = lightz; oambient_light = ambient_light;
18175 }
18176 }
18177 }
18178
18179
18180 CImg<float> projections(points.width,2);
18181 cimg_forX(points,l) {
18182 const float
18183 x = (float)points(l,0),
18184 y = (float)points(l,1),
18185 z = (float)points(l,2);
18186 const float projectedz = z + Z + focale;
18187 projections(l,1) = Y + focale*y/projectedz;
18188 projections(l,0) = X + focale*x/projectedz;
18189 }
18190
18191
18192 CImg<unsigned int> visibles(primitives.size);
18193 CImg<float> zrange(primitives.size);
18194 unsigned int nb_visibles = 0;
18195 const float zmin = -focale+1.5f;
18196 { cimglist_for(primitives,l) {
18197 const CImg<tf>& primitive = primitives[l];
18198 switch (primitive.size()) {
18199
18200 case 1: {
18201 const unsigned int i0 = (unsigned int)primitive(0);
18202 const float x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2));
18203 if (z0>zmin && x0>=0 && x0<width && y0>=0 && y0<height) {
18204 visibles(nb_visibles) = (unsigned int)l;
18205 zrange(nb_visibles++) = z0;
18206 }
18207 } break;
18208 case 5: {
18209 const unsigned int
18210 i0 = (unsigned int)primitive(0),
18211 i1 = (unsigned int)primitive(1),
18212 i2 = (unsigned int)primitive(2);
18213 const float x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2));
18214 int radius;
18215 if (i2) radius = (int)(i2*focale/(z0+focale));
18216 else {
18217 const float x1 = projections(i1,0), y1 = projections(i1,1);
18218 const int deltax = (int)(x1-x0), deltay = (int)(y1-y0);
18219 radius = (int)std::sqrt((float)(deltax*deltax + deltay*deltay));
18220 }
18221 if (z0>zmin && x0+radius>=0 && x0-radius<width && y0+radius>=0 && y0-radius<height) {
18222 visibles(nb_visibles) = (unsigned int)l;
18223 zrange(nb_visibles++) = z0;
18224 }
18225 } break;
18226 case 2:
18227 case 6: {
18228 const unsigned int
18229 i0 = (unsigned int)primitive(0),
18230 i1 = (unsigned int)primitive(1);
18231 const float
18232 x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)),
18233 x1 = projections(i1,0), y1 = projections(i1,1), z1 = (float)(Z+points(i1,2));
18234 float xm, xM, ym, yM;
18235 if (x0<x1) { xm = x0; xM = x1; } else { xm = x1; xM = x0; }
18236 if (y0<y1) { ym = y0; yM = y1; } else { ym = y1; yM = y0; }
18237 if (z0>zmin && z1>zmin && xM>=0 && xm<width && yM>=0 && ym<height) {
18238 visibles(nb_visibles) = (unsigned int)l;
18239 zrange(nb_visibles++) = 0.5f*(z0+z1);
18240 }
18241 } break;
18242 case 3:
18243 case 9: {
18244 const unsigned int
18245 i0 = (unsigned int)primitive(0),
18246 i1 = (unsigned int)primitive(1),
18247 i2 = (unsigned int)primitive(2);
18248 const float
18249 x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)),
18250 x1 = projections(i1,0), y1 = projections(i1,1), z1 = (float)(Z+points(i1,2)),
18251 x2 = projections(i2,0), y2 = projections(i2,1), z2 = (float)(Z+points(i2,2));
18252 float xm, xM, ym, yM;
18253 if (x0<x1) { xm = x0; xM = x1; } else { xm = x1; xM = x0; }
18254 if (x2<xm) xm = x2;
18255 if (x2>xM) xM = x2;
18256 if (y0<y1) { ym = y0; yM = y1; } else { ym = y1; yM = y0; }
18257 if (y2<ym) ym = y2;
18258 if (y2>yM) yM = y2;
18259 if (z0>zmin && z1>zmin && z2>zmin && xM>=0 && xm<width && yM>=0 && ym<height) {
18260 const float d = (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
18261 if (double_sided || d<0) {
18262 visibles(nb_visibles) = (unsigned int)l;
18263 zrange(nb_visibles++) = (z0+z1+z2)/3;
18264 }
18265 }
18266 } break;
18267 case 4:
18268 case 12: {
18269 const unsigned int
18270 i0 = (unsigned int)primitive(0),
18271 i1 = (unsigned int)primitive(1),
18272 i2 = (unsigned int)primitive(2),
18273 i3 = (unsigned int)primitive(3);
18274 const float
18275 x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)),
18276 x1 = projections(i1,0), y1 = projections(i1,1), z1 = (float)(Z+points(i1,2)),
18277 x2 = projections(i2,0), y2 = projections(i2,1), z2 = (float)(Z+points(i2,2)),
18278 x3 = projections(i3,0), y3 = projections(i3,1), z3 = (float)(Z+points(i3,2));
18279 float xm, xM, ym, yM;
18280 if (x0<x1) { xm = x0; xM = x1; } else { xm = x1; xM = x0; }
18281 if (x2<xm) xm = x2;
18282 if (x2>xM) xM = x2;
18283 if (x3<xm) xm = x3;
18284 if (x3>xM) xM = x3;
18285 if (y0<y1) { ym = y0; yM = y1; } else { ym = y1; yM = y0; }
18286 if (y2<ym) ym = y2;
18287 if (y2>yM) yM = y2;
18288 if (y3<ym) ym = y3;
18289 if (y3>yM) yM = y3;
18290 if (z0>zmin && z1>zmin && z2>zmin && z3>zmin && xM>=0 && xm<width && yM>=0 && ym<height) {
18291 const float d = (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
18292 if (double_sided || d<0) {
18293 visibles(nb_visibles) = (unsigned int)l;
18294 zrange(nb_visibles++) = (z0+z1+z2+z3)/4;
18295 }
18296 }
18297 } break;
18298 default:
18299 throw CImgArgumentException("CImg<%s>::draw_object3d() : Primitive %u is invalid (size = %u, can be 1,2,3,4,5,6,9 or 12)",
18300 pixel_type(),l,primitive.size());
18301 }}
18302 }
18303 if (nb_visibles<=0) return *this;
18304 CImg<unsigned int> permutations;
18305 CImg<float>(zrange.data,nb_visibles,1,1,1,true).sort(permutations,false);
18306
18307
18308 CImg<float> lightprops;
18309 switch (render_type) {
18310 case 3: {
18311 lightprops.assign(nb_visibles);
18312 cimg_forX(lightprops,l) {
18313 const CImg<tf>& primitive = primitives(visibles(permutations(l)));
18314 const unsigned int psize = primitive.size();
18315 if (psize==3 || psize==4 || psize==9 || psize==12) {
18316 const unsigned int
18317 i0 = (unsigned int)primitive(0),
18318 i1 = (unsigned int)primitive(1),
18319 i2 = (unsigned int)primitive(2);
18320 const float
18321 x0 = (float)points(i0,0), y0 = (float)points(i0,1), z0 = (float)points(i0,2),
18322 x1 = (float)points(i1,0), y1 = (float)points(i1,1), z1 = (float)points(i1,2),
18323 x2 = (float)points(i2,0), y2 = (float)points(i2,1), z2 = (float)points(i2,2),
18324 dx1 = x1-x0, dy1 = y1-y0, dz1 = z1-z0,
18325 dx2 = x2-x0, dy2 = y2-y0, dz2 = z2-z0,
18326 nx = dy1*dz2-dz1*dy2,
18327 ny = dz1*dx2-dx1*dz2,
18328 nz = dx1*dy2-dy1*dx2,
18329 norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
18330 lx = X+(x0+x1+x2)/3-lightx,
18331 ly = Y+(y0+y1+y2)/3-lighty,
18332 lz = Z+(z0+z1+z2)/3-lightz,
18333 nl = (float)std::sqrt(1e-5f+lx*lx+ly*ly+lz*lz),
18334 factor = cimg::abs(-lx*nx-ly*ny-lz*nz)/(norm*nl);
18335 lightprops[l] = cimg::max(factor,0.0f) + ambient_light;
18336 } else lightprops[l] = 1.0f;
18337 }
18338 } break;
18339
18340 case 4:
18341 case 5: {
18342 CImg<float> points_normals(points.width,double_sided?7:3,1,1,0);
18343 for (unsigned int l=0; l<nb_visibles; ++l) {
18344 const CImg<tf>& primitive = primitives[visibles(l)];
18345 const unsigned int psize = primitive.size();
18346 const bool
18347 triangle_flag = (psize==3) || (psize==9),
18348 rectangle_flag = (psize==4) || (psize==12);
18349 if (triangle_flag || rectangle_flag) {
18350 const unsigned int
18351 i0 = (unsigned int)primitive(0),
18352 i1 = (unsigned int)primitive(1),
18353 i2 = (unsigned int)primitive(2),
18354 i3 = rectangle_flag?(unsigned int)primitive(3):0;
18355 const float
18356 x0 = (float)points(i0,0), y0 = (float)points(i0,1), z0 = (float)points(i0,2),
18357 x1 = (float)points(i1,0), y1 = (float)points(i1,1), z1 = (float)points(i1,2),
18358 x2 = (float)points(i2,0), y2 = (float)points(i2,1), z2 = (float)points(i2,2),
18359 dx1 = x1-x0, dy1 = y1-y0, dz1 = z1-z0,
18360 dx2 = x2-x0, dy2 = y2-y0, dz2 = z2-z0,
18361 nnx = dy1*dz2-dz1*dy2,
18362 nny = dz1*dx2-dx1*dz2,
18363 nnz = dx1*dy2-dy1*dx2,
18364 norm = 1e-5f + (float)std::sqrt(nnx*nnx+nny*nny+nnz*nnz),
18365 nx = nnx/norm,
18366 ny = nny/norm,
18367 nz = nnz/norm;
18368 if (double_sided) {
18369 unsigned int ind = nz>0?3U:0U;
18370 const float incr = nz>0?-1.0f:1.0f;
18371 points_normals(i0, ind)+=nx; points_normals(i1,ind)+=nx; points_normals(i2,ind)+=nx;
18372 points_normals(i0,++ind)+=ny; points_normals(i1,ind)+=ny; points_normals(i2,ind)+=ny;
18373 points_normals(i0,++ind)+=nz; points_normals(i1,ind)+=nz; points_normals(i2,ind)+=nz;
18374 points_normals(i0,6)+=incr; points_normals(i1,6)+=incr; points_normals(i2,6)+=incr;
18375 if (rectangle_flag) {
18376 points_normals(i3,ind)+=nz; points_normals(i3,--ind)+=ny; points_normals(i3,--ind)+=nz; points_normals(i3,6)+=incr;
18377 }
18378 } else {
18379 points_normals(i0,0)+=nx; points_normals(i0,1)+=ny; points_normals(i0,2)+=nz;
18380 points_normals(i1,0)+=nx; points_normals(i1,1)+=ny; points_normals(i1,2)+=nz;
18381 points_normals(i2,0)+=nx; points_normals(i2,1)+=ny; points_normals(i2,2)+=nz;
18382 if (rectangle_flag) { points_normals(i3,0)+=nx; points_normals(i3,1)+=ny; points_normals(i3,2)+=nz; }
18383 }
18384 }
18385 }
18386
18387 if (double_sided) cimg_forX(points_normals,l) if (points_normals(l,6)<0) {
18388 points_normals(l,0) = -points_normals(l,3);
18389 points_normals(l,1) = -points_normals(l,4);
18390 points_normals(l,2) = -points_normals(l,5);
18391 }
18392
18393 if (render_type==4) {
18394 lightprops.assign(points.width);
18395 cimg_forX(points,ll) {
18396 const float
18397 nx = points_normals(ll,0),
18398 ny = points_normals(ll,1),
18399 nz = points_normals(ll,2),
18400 norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
18401 lx = (float)(X+points(ll,0)-lightx),
18402 ly = (float)(Y+points(ll,1)-lighty),
18403 lz = (float)(Z+points(ll,2)-lightz),
18404 nl = (float)std::sqrt(1e-5f+lx*lx+ly*ly+lz*lz),
18405 factor = (-lx*nx-ly*ny-lz*nz)/(norm*nl);
18406 lightprops[ll] = cimg::max(factor,0.0f) + ambient_light;
18407 }
18408 } else {
18409 const unsigned int
18410 lw2 = light_texture.width/2-1,
18411 lh2 = light_texture.height/2-1;
18412 lightprops.assign(points.width,2);
18413 cimg_forX(points,ll) {
18414 const float
18415 nx = points_normals(ll,0),
18416 ny = points_normals(ll,1),
18417 nz = points_normals(ll,2),
18418 norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
18419 nnx = nx/norm,
18420 nny = ny/norm;
18421 lightprops(ll,0) = lw2*(1+nnx);
18422 lightprops(ll,1) = lh2*(1+nny);
18423 }
18424 }
18425 } break;
18426 }
18427
18428
18429 const unsigned int opacsize = opacities.size;
18430 { for (unsigned int l=0; l<nb_visibles; ++l) {
18431 const unsigned int n_primitive = visibles(permutations(l));
18432 const CImg<tf>& primitive = primitives[n_primitive];
18433 const CImg<tc>& color = colors[n_primitive%colors.size];
18434 const CImg<to>& opacity = opacities[n_primitive%opacsize];
18435 const float opac = opacity.size()?(float)opacity(0):1.0f;
18436
18437 switch (primitive.size()) {
18438 case 1: {
18439 const unsigned int n0 = (unsigned int)primitive[0];
18440 const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1);
18441 if (color.size()==dim) draw_point(x0,y0,color,opac);
18442 else {
18443 const float z = Z + points(n0,2);
18444 const int
18445 factor = (int)(focale*100/(z+focale)),
18446 sw = color.width*factor/200,
18447 sh = color.height*factor/200;
18448 if (x0+sw>=0 && x0-sw<dimx() && y0+sh>=0 && y0-sh<dimy()) {
18449 const CImg<T> sprite = color.get_resize(-factor,-factor,1,-100,render_type<=3?1:3);
18450 if (opacity.width==color.width && opacity.height==color.height)
18451 draw_image(sprite,opacity.get_resize(sprite.width,sprite.height,1,sprite.dim,1),x0-sw,y0-sh,0,0);
18452 else draw_image(sprite,x0-sw,y0-sh,0,0,opac);
18453 }
18454 }
18455 } break;
18456 case 2: {
18457 const unsigned int
18458 n0 = (unsigned int)primitive[0],
18459 n1 = (unsigned int)primitive[1];
18460 const int
18461 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18462 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1);
18463 if (render_type) draw_line(x0,y0,x1,y1,color,opac);
18464 else draw_point(x0,y0,color,opac).draw_point(x1,y1,color,opac);
18465 } break;
18466 case 5: {
18467 const unsigned int
18468 n0 = (unsigned int)primitive[0],
18469 n1 = (unsigned int)primitive[1],
18470 n2 = (unsigned int)primitive[2];
18471 const int
18472 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1);
18473 int radius;
18474 if (n2) radius = (int)(n2*focale/(Z+points(n0,2)+focale));
18475 else {
18476 const int
18477 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18478 deltax = x1-x0, deltay = y1-y0;
18479 radius = (int)std::sqrt((float)(deltax*deltax + deltay*deltay));
18480 }
18481 switch (render_type) {
18482 case 0:
18483 draw_point(x0,y0,color,opac);
18484 break;
18485 case 1:
18486 draw_circle(x0,y0,radius,color,opac,~0U);
18487 break;
18488 default:
18489 draw_circle(x0,y0,radius,color,opac);
18490 break;
18491 }
18492 } break;
18493 case 6: {
18494 const unsigned int
18495 n0 = (unsigned int)primitive[0],
18496 n1 = (unsigned int)primitive[1],
18497 tx0 = (unsigned int)primitive[2],
18498 ty0 = (unsigned int)primitive[3],
18499 tx1 = (unsigned int)primitive[4],
18500 ty1 = (unsigned int)primitive[5];
18501 const int
18502 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18503 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1);
18504 const float
18505 z0 = points(n0,2) + Z + focale,
18506 z1 = points(n1,2) + Z + focale;
18507 if (render_type) draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac);
18508 else draw_point(x0,y0,color.get_vector_at(tx0,ty0),opac).
18509 draw_point(x1,y1,color.get_vector_at(tx1,ty1),opac);
18510 } break;
18511 case 3: {
18512 const unsigned int
18513 n0 = (unsigned int)primitive[0],
18514 n1 = (unsigned int)primitive[1],
18515 n2 = (unsigned int)primitive[2];
18516 const int
18517 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18518 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18519 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1);
18520 switch(render_type) {
18521 case 0:
18522 draw_point(x0,y0,color,opac).draw_point(x1,y1,color,opac).draw_point(x2,y2,color,opac);
18523 break;
18524 case 1:
18525 draw_line(x0,y0,x1,y1,color,opac).draw_line(x0,y0,x2,y2,color,opac).
18526 draw_line(x1,y1,x2,y2,color,opac);
18527 break;
18528 case 2:
18529 draw_triangle(x0,y0,x1,y1,x2,y2,color,opac);
18530 break;
18531 case 3:
18532 _draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opac,lightprops(l));
18533 break;
18534 case 4:
18535 draw_triangle(x0,y0,x1,y1,x2,y2,color,lightprops(n0),lightprops(n1),lightprops(n2),opac);
18536 break;
18537 case 5:
18538 const unsigned int
18539 lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1),
18540 lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1),
18541 lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1);
18542 draw_triangle(x0,y0,x1,y1,x2,y2,color,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac);
18543 break;
18544 }
18545 } break;
18546 case 4: {
18547 const unsigned int
18548 n0 = (unsigned int)primitive[0],
18549 n1 = (unsigned int)primitive[1],
18550 n2 = (unsigned int)primitive[2],
18551 n3 = (unsigned int)primitive[3];
18552 const int
18553 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18554 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18555 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1),
18556 x3 = (int)projections(n3,0), y3 = (int)projections(n3,1);
18557 switch(render_type) {
18558 case 0:
18559 draw_point(x0,y0,color,opac).draw_point(x1,y1,color,opac).
18560 draw_point(x2,y2,color,opac).draw_point(x3,y3,color,opac);
18561 break;
18562 case 1:
18563 draw_line(x0,y0,x1,y1,color,opac).draw_line(x1,y1,x2,y2,color,opac).
18564 draw_line(x2,y2,x3,y3,color,opac).draw_line(x3,y3,x0,y0,color,opac);
18565 break;
18566 case 2:
18567 draw_triangle(x0,y0,x1,y1,x2,y2,color,opac).draw_triangle(x0,y0,x2,y2,x3,y3,color,opac);
18568 break;
18569 case 3:
18570 _draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opac,lightprops(l)).
18571 _draw_triangle(x0,y0,x2,y2,x3,y3,color.data,opac,lightprops(l));
18572 break;
18573 case 4: {
18574 const float
18575 lightprop0 = lightprops(n0), lightprop1 = lightprops(n1),
18576 lightprop2 = lightprops(n2), lightprop3 = lightprops(n3);
18577 draw_triangle(x0,y0,x1,y1,x2,y2,color,lightprop0,lightprop1,lightprop2,opac).
18578 draw_triangle(x0,y0,x2,y2,x3,y3,color,lightprop0,lightprop2,lightprop3,opac);
18579 } break;
18580 case 5: {
18581 const unsigned int
18582 lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1),
18583 lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1),
18584 lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1),
18585 lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1);
18586 draw_triangle(x0,y0,x1,y1,x2,y2,color,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac).
18587 draw_triangle(x0,y0,x2,y2,x3,y3,color,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac);
18588 } break;
18589 }
18590 } break;
18591 case 9: {
18592 const unsigned int
18593 n0 = (unsigned int)primitive[0],
18594 n1 = (unsigned int)primitive[1],
18595 n2 = (unsigned int)primitive[2],
18596 tx0 = (unsigned int)primitive[3],
18597 ty0 = (unsigned int)primitive[4],
18598 tx1 = (unsigned int)primitive[5],
18599 ty1 = (unsigned int)primitive[6],
18600 tx2 = (unsigned int)primitive[7],
18601 ty2 = (unsigned int)primitive[8];
18602 const int
18603 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18604 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18605 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1);
18606 const float
18607 z0 = points(n0,2) + Z + focale,
18608 z1 = points(n1,2) + Z + focale,
18609 z2 = points(n2,2) + Z + focale;
18610 switch(render_type) {
18611 case 0:
18612 draw_point(x0,y0,color.get_vector_at(tx0,ty0),opac).
18613 draw_point(x1,y1,color.get_vector_at(tx1,ty1),opac).
18614 draw_point(x2,y2,color.get_vector_at(tx2,ty2),opac);
18615 break;
18616 case 1:
18617 draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac).
18618 draw_line(x0,y0,z0,x2,y2,z2,color,tx0,ty0,tx2,ty2,opac).
18619 draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac);
18620 break;
18621 case 2:
18622 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac);
18623 break;
18624 case 3:
18625 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l));
18626 break;
18627 case 4:
18628 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprops(n0),lightprops(n1),lightprops(n2),opac);
18629 break;
18630 case 5:
18631 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,
18632 (unsigned int)lightprops(n0,0), (unsigned int)lightprops(n0,1),
18633 (unsigned int)lightprops(n1,0), (unsigned int)lightprops(n1,1),
18634 (unsigned int)lightprops(n2,0), (unsigned int)lightprops(n2,1),
18635 opac);
18636 break;
18637 }
18638 } break;
18639 case 12: {
18640 const unsigned int
18641 n0 = (unsigned int)primitive[0],
18642 n1 = (unsigned int)primitive[1],
18643 n2 = (unsigned int)primitive[2],
18644 n3 = (unsigned int)primitive[3],
18645 tx0 = (unsigned int)primitive[4],
18646 ty0 = (unsigned int)primitive[5],
18647 tx1 = (unsigned int)primitive[6],
18648 ty1 = (unsigned int)primitive[7],
18649 tx2 = (unsigned int)primitive[8],
18650 ty2 = (unsigned int)primitive[9],
18651 tx3 = (unsigned int)primitive[10],
18652 ty3 = (unsigned int)primitive[11];
18653 const int
18654 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18655 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18656 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1),
18657 x3 = (int)projections(n3,0), y3 = (int)projections(n3,1);
18658 const float
18659 z0 = points(n0,2) + Z + focale,
18660 z1 = points(n1,2) + Z + focale,
18661 z2 = points(n2,2) + Z + focale,
18662 z3 = points(n3,2) + Z + focale;
18663 switch(render_type) {
18664 case 0:
18665 draw_point(x0,y0,color.get_vector_at(tx0,ty0),opac).
18666 draw_point(x1,y1,color.get_vector_at(tx1,ty1),opac).
18667 draw_point(x2,y2,color.get_vector_at(tx2,ty2),opac).
18668 draw_point(x3,y3,color.get_vector_at(tx3,ty3),opac);
18669 break;
18670 case 1:
18671 draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac).
18672 draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac).
18673 draw_line(x2,y2,z2,x3,y3,z3,color,tx2,ty2,tx3,ty3,opac).
18674 draw_line(x3,y3,z3,x0,y0,z0,color,tx3,ty3,tx0,ty0,opac);
18675 break;
18676 case 2:
18677 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac).
18678 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac);
18679 break;
18680 case 3:
18681 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l)).
18682 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac,lightprops(l));
18683 break;
18684 case 4: {
18685 const float
18686 lightprop0 = lightprops(n0), lightprop1 = lightprops(n1),
18687 lightprop2 = lightprops(n2), lightprop3 = lightprops(n3);
18688 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprop0,lightprop1,lightprop2,opac).
18689 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,lightprop0,lightprop2,lightprop3,opac);
18690 } break;
18691 case 5: {
18692 const unsigned int
18693 lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1),
18694 lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1),
18695 lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1),
18696 lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1);
18697 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac).
18698 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac);
18699 } break;
18700 }
18701 } break;
18702 }
18703 }
18704 }
18705 return *this;
18706 }
18707
18709 template<typename tp, typename tf, typename tc, typename to>
18710 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18711 const CImgList<tp>& points, const CImgList<tf>& primitives,
18712 const CImgList<tc>& colors, const CImgList<to>& opacities,
18713 const unsigned int render_type=4,
18714 const bool double_sided=false, const float focale=500,
18715 const float lightx=0, const float lighty=0, const float lightz=-5000,
18716 const float ambient_light=0.05f) {
18717 if (!points) return *this;
18718 CImg<tp> npoints(points.size,3,1,1,0);
18719 tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
18720 cimg_forX(npoints,l) {
18721 const CImg<tp>& point = points[l];
18722 const unsigned int siz = point.size();
18723 if (!siz)
18724 throw CImgArgumentException("CImg<%s>::draw_object3d() : Given points (size=%u) contains a null element at "
18725 "position %u.",pixel_type(),points.size,l);
18726 *(ptrZ++) = (siz>2)?point(2):0;
18727 *(ptrY++) = (siz>1)?point(1):0;
18728 *(ptrX++) = point(0);
18729 }
18730 return draw_object3d(X,Y,Z,npoints,primitives,colors,opacities,
18731 render_type,double_sided,focale,lightx,lighty,lightz,ambient_light);
18732 }
18733
18735 template<typename tp, typename tf, typename tc, typename to>
18736 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18737 const CImg<tp>& points, const CImgList<tf>& primitives,
18738 const CImgList<tc>& colors, const CImg<to>& opacities,
18739 const unsigned int render_type=4,
18740 const bool double_sided=false, const float focale=500,
18741 const float lightx=0, const float lighty=0, const float lightz=-5000,
18742 const float ambient_light=0.05f) {
18743 CImgList<to> nopacities(opacities.size(),1);
18744 cimglist_for(nopacities,l) nopacities(l,0) = opacities(l);
18745 return draw_object3d(X,Y,Z,points,primitives,colors,nopacities,
18746 render_type,double_sided,focale,lightx,lighty,lightz,ambient_light);
18747 }
18748
18750 template<typename tp, typename tf, typename tc, typename to>
18751 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18752 const CImgList<tp>& points, const CImgList<tf>& primitives,
18753 const CImgList<tc>& colors, const CImg<to>& opacities,
18754 const unsigned int render_type=4,
18755 const bool double_sided=false, const float focale=500,
18756 const float lightx=0, const float lighty=0, const float lightz=-5000,
18757 const float ambient_light=0.05f) {
18758 CImgList<to> nopacities(opacities.size(),1);
18759 { cimglist_for(nopacities,l) nopacities(l,0) = opacities(l); }
18760 if (!points) return *this;
18761 CImg<tp> npoints(points.size,3,1,1,0);
18762 tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
18763 cimg_forX(npoints,l) {
18764 const CImg<tp>& point = points[l];
18765 const unsigned int siz = point.size();
18766 if (!siz)
18767 throw CImgArgumentException("CImg<%s>::draw_object3d() : Given points (size=%u) contains a null element at "
18768 "position %u.",pixel_type(),points.size,l);
18769 *(ptrZ++) = (siz>2)?point(2):0;
18770 *(ptrY++) = (siz>1)?point(1):0;
18771 *(ptrX++) = point(0);
18772 }
18773 return draw_object3d(X,Y,Z,npoints,primitives,colors,nopacities,
18774 render_type,double_sided,focale,lightx,lighty,lightz,ambient_light);
18775 }
18776
18778 template<typename tp, typename tf, typename tc>
18779 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18780 const tp& points, const CImgList<tf>& primitives,
18781 const CImgList<tc>& colors,
18782 const unsigned int render_type=4,
18783 const bool double_sided=false, const float focale=500,
18784 const float lightx=0, const float lighty=0, const float lightz=-5000,
18785 const float ambient_light=0.05f,
18786 const float opacity=1.0f) {
18787 return draw_object3d(X,Y,Z,points,primitives,colors,
18788 CImg<float>(primitives.size,1,1,1,opacity),
18789 render_type,double_sided,focale,lightx,lighty,lightz,
18790 ambient_light);
18791 }
18792
18794
18795
18797
18798
18799
18801
18810 template<typename t> CImg<typename cimg::superset2<T,t,float>::type>
18811 get_correlate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_correl=false) const {
18812 typedef typename cimg::superset2<T,t,float>::type ftype;
18813 if (is_empty()) return CImg<ftype>();
18814 if (!mask || mask.dim!=1)
18815 throw CImgArgumentException("CImg<%s>::correlate() : Specified mask (%u,%u,%u,%u,%p) is not scalar.",
18816 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
18817 CImg<ftype> dest(width,height,depth,dim);
18818 if (cond && mask.width==mask.height && ((mask.depth==1 && mask.width<=5) || (mask.depth==mask.width && mask.width<=3))) {
18819
18820 switch (mask.depth) {
18821 case 3: {
18822 T I[27] = { 0 };
18823 cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18824 (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] +
18825 I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] +
18826 I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] +
18827 I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] +
18828 I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] +
18829 I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] +
18830 I[18]*mask[18] + I[19]*mask[19] + I[20]*mask[20] +
18831 I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] +
18832 I[24]*mask[24] + I[25]*mask[25] + I[26]*mask[26]);
18833 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) {
18834 const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] +
18835 I[ 3]*I[ 3] + I[ 4]*I[ 4] + I[ 5]*I[ 5] +
18836 I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] +
18837 I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
18838 I[12]*I[12] + I[13]*I[13] + I[14]*I[14] +
18839 I[15]*I[15] + I[16]*I[16] + I[17]*I[17] +
18840 I[18]*I[18] + I[19]*I[19] + I[20]*I[20] +
18841 I[21]*I[21] + I[22]*I[22] + I[23]*I[23] +
18842 I[24]*I[24] + I[25]*I[25] + I[26]*I[26]);
18843 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18844 }
18845 } break;
18846 case 2: {
18847 T I[8] = { 0 };
18848 cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18849 (I[0]*mask[0] + I[1]*mask[1] +
18850 I[2]*mask[2] + I[3]*mask[3] +
18851 I[4]*mask[4] + I[5]*mask[5] +
18852 I[6]*mask[6] + I[7]*mask[7]);
18853 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) {
18854 const double weight = (double)(I[0]*I[0] + I[1]*I[1] +
18855 I[2]*I[2] + I[3]*I[3] +
18856 I[4]*I[4] + I[5]*I[5] +
18857 I[6]*I[6] + I[7]*I[7]);
18858 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18859 }
18860 } break;
18861 default:
18862 case 1:
18863 switch (mask.width) {
18864 case 6: {
18865 T I[36] = { 0 };
18866 cimg_forZV(*this,z,v) cimg_for6x6(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18867 (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] +
18868 I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] +
18869 I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] +
18870 I[18]*mask[18] + I[19]*mask[19] + I[20]*mask[20] + I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] +
18871 I[24]*mask[24] + I[25]*mask[25] + I[26]*mask[26] + I[27]*mask[27] + I[28]*mask[28] + I[29]*mask[29] +
18872 I[30]*mask[30] + I[31]*mask[31] + I[32]*mask[32] + I[33]*mask[33] + I[34]*mask[34] + I[35]*mask[35]);
18873 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) {
18874 const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + I[ 4]*I[ 4] + I[ 5]*I[ 5] +
18875 I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
18876 I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15] + I[16]*I[16] + I[17]*I[17] +
18877 I[18]*I[18] + I[19]*I[19] + I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] +
18878 I[24]*I[24] + I[25]*I[25] + I[26]*I[26] + I[27]*I[27] + I[28]*I[28] + I[29]*I[29] +
18879 I[30]*I[30] + I[31]*I[31] + I[32]*I[32] + I[33]*I[33] + I[34]*I[34] + I[35]*I[35]);
18880 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18881 }
18882 } break;
18883 case 5: {
18884 T I[25] = { 0 };
18885 cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18886 (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] +
18887 I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] +
18888 I[10]*mask[10] + I[11]*mask[11] + I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] +
18889 I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] + I[18]*mask[18] + I[19]*mask[19] +
18890 I[20]*mask[20] + I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] + I[24]*mask[24]);
18891 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) {
18892 const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + I[ 4]*I[ 4] +
18893 I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] +
18894 I[10]*I[10] + I[11]*I[11] + I[12]*I[12] + I[13]*I[13] + I[14]*I[14] +
18895 I[15]*I[15] + I[16]*I[16] + I[17]*I[17] + I[18]*I[18] + I[19]*I[19] +
18896 I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] + I[24]*I[24]);
18897 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18898 }
18899 } break;
18900 case 4: {
18901 T I[16] = { 0 };
18902 cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18903 (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] +
18904 I[ 4]*mask[ 4] + I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] +
18905 I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] +
18906 I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15]);
18907 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) {
18908 const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] +
18909 I[ 4]*I[ 4] + I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] +
18910 I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
18911 I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15]);
18912 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18913 }
18914 } break;
18915 case 3: {
18916 T I[9] = { 0 };
18917 cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18918 (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] +
18919 I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] +
18920 I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]);
18921 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) {
18922 const double weight = (double)(I[0]*I[0] + I[1]*I[1] + I[2]*I[2] +
18923 I[3]*I[3] + I[4]*I[4] + I[5]*I[5] +
18924 I[6]*I[6] + I[7]*I[7] + I[8]*I[8]);
18925 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18926 }
18927 } break;
18928 case 2: {
18929 T I[4] = { 0 };
18930 cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18931 (I[0]*mask[0] + I[1]*mask[1] +
18932 I[2]*mask[2] + I[3]*mask[3]);
18933 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) {
18934 const double weight = (double)(I[0]*I[0] + I[1]*I[1] +
18935 I[2]*I[2] + I[3]*I[3]);
18936 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18937 }
18938 } break;
18939 case 1: (dest.assign(*this))*=mask(0); break;
18940 }
18941 }
18942 } else {
18943
18944 const int cxm=mask.width/2, cym=mask.height/2, czm=mask.depth/2, fxm=cxm-1+(mask.width%2), fym=cym-1+(mask.height%2), fzm=czm-1+(mask.depth%2);
18945 cimg_forV(*this,v)
18946 if (!weighted_correl) {
18947 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
18948 ftype val = 0;
18949 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
18950 val+=(*this)(x+xm,y+ym,z+zm,v)*mask(cxm+xm,cym+ym,czm+zm,0);
18951 dest(x,y,z,v) = (ftype)val;
18952 }
18953 if (cond) cimg_forYZV(*this,y,z,v) for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
18954 ftype val = 0;
18955 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
18956 val+=pix3d(x+xm,y+ym,z+zm,v)*mask(cxm+xm,cym+ym,czm+zm,0);
18957 dest(x,y,z,v) = (ftype)val;
18958 }
18959 else cimg_forYZV(*this,y,z,v) for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
18960 ftype val = 0;
18961 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
18962 val+=pix3d(x+xm,y+ym,z+zm,v,0)*mask(cxm+xm,cym+ym,czm+zm,0);
18963 dest(x,y,z,v) = (ftype)val;
18964 }
18965 } else {
18966 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
18967 ftype val = 0, weight = 0;
18968 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm) {
18969 const T cval = (*this)(x+xm,y+ym,z+zm,v);
18970 val+=cval*mask(cxm+xm,cym+ym,czm+zm,0);
18971 weight+= cval*cval;
18972 }
18973 dest(x,y,z,v) = (weight>0)?(ftype)(val/std::sqrt((double)weight)):0;
18974 }
18975 if (cond) cimg_forYZV(*this,y,z,v) for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
18976 ftype val = 0, weight = 0;
18977 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm) {
18978 const T cval = pix3d(x+xm,y+ym,z+zm,v);
18979 val+=cval*mask(cxm+xm,cym+ym,czm+zm,0);
18980 weight+=cval*cval;
18981 }
18982 dest(x,y,z,v) = (weight>0)?(ftype)(val/std::sqrt((double)weight)):0;
18983 }
18984 else cimg_forYZV(*this,y,z,v) for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
18985 ftype val = 0, weight = 0;
18986 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm) {
18987 const T cval = pix3d(x+xm,y+ym,z+zm,v,0);
18988 val+=cval*mask(cxm+xm,cym+ym,czm+zm,0);
18989 weight+=cval*cval;
18990 }
18991 dest(x,y,z,v) = (weight>0)?(ftype)(val/std::sqrt((double)weight)):0;
18992 }
18993 }
18994 }
18995 return dest;
18996 }
18997
18999 template<typename t> CImg<T>& correlate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_correl=false) {
19000 return get_correlate(mask,cond,weighted_correl).assign_to(*this);
19001 }
19002
19004
19013 template<typename t> CImg<typename cimg::superset2<T,t,float>::type>
19014 get_convolve(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_convol=false) const {
19015 typedef typename cimg::superset2<T,t,float>::type ftype;
19016 if (is_empty()) return CImg<ftype>();
19017 if (!mask || mask.dim!=1)
19018 throw CImgArgumentException("CImg<%s>::convolve() : Specified mask (%u,%u,%u,%u,%p) is not scalar.",
19019 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
19020 return get_correlate(mask.get_mirror('x').mirror('y').mirror('z'),cond,weighted_convol);
19021 }
19022
19024 template<typename t> CImg<T>& convolve(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_convol=false) {
19025 return get_convolve(mask,cond,weighted_convol).assign_to(*this);
19026 }
19027
19029 template<typename t> CImg<typename cimg::superset<T,t>::type>
19030 get_erode(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_erosion=false) const {
19031 typedef typename cimg::superset<T,t>::type restype;
19032 if (is_empty()) return CImg<restype>();
19033 if (!mask || mask.dim!=1)
19034 throw CImgArgumentException("CImg<%s>::erode() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.",
19035 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
19036 CImg<restype> dest(width,height,depth,dim);
19037 const int cxm=mask.width/2, cym=mask.height/2, czm=mask.depth/2,
19038 fxm=cxm-1+(mask.width%2), fym=cym-1+(mask.height%2), fzm=czm-1+(mask.depth%2);
19039 cimg_forV(*this,v)
19040 if (!weighted_erosion) {
19041 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19042 restype min_val = cimg::type<restype>::max();
19043 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19044 if (mask(cxm+xm,cym+ym,czm+zm,0)) min_val = cimg::min((restype)(*this)(x+xm,y+ym,z+zm,v),min_val);
19045 dest(x,y,z,v) = min_val;
19046 }
19047 if (cond) cimg_forYZV(*this,y,z,v)
19048 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
19049 restype min_val = cimg::type<restype>::max();
19050 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19051 if (mask(cxm+xm,cym+ym,czm+zm,0)) min_val = cimg::min((restype)pix3d(x+xm,y+ym,z+zm,v),min_val);
19052 dest(x,y,z,v) = min_val;
19053 }
19054 else cimg_forYZV(*this,y,z,v)
19055 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
19056 restype min_val = cimg::type<restype>::max();
19057 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19058 if (mask(cxm+xm,cym+ym,czm+zm,0)) min_val = cimg::min((restype)pix3d(x+xm,y+ym,z+zm,v,0),min_val);
19059 dest(x,y,z,v) = min_val;
19060 }
19061 } else {
19062 t mval=0;
19063 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19064 restype min_val = cimg::type<restype>::max();
19065 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19066 if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) min_val = cimg::min((restype)((*this)(x+xm,y+ym,z+zm,v)+mval),min_val);
19067 dest(x,y,z,v) = min_val;
19068 }
19069 if (cond) cimg_forYZV(*this,y,z,v)
19070 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
19071 restype min_val = cimg::type<restype>::max();
19072 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19073 if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) min_val = cimg::min((restype)(pix3d(x+xm,y+ym,z+zm,v)+mval),min_val);
19074 dest(x,y,z,v) = min_val;
19075 }
19076 else cimg_forYZV(*this,y,z,v)
19077 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
19078 restype min_val = cimg::type<restype>::max();
19079 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19080 if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) min_val = cimg::min((restype)(pix3d(x+xm,y+ym,z+zm,v,0)+mval),min_val);
19081 dest(x,y,z,v) = min_val;
19082 }
19083 }
19084 return dest;
19085 }
19086
19088 template<typename t> CImg<T>& erode(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_erosion=false) {
19089 return get_erode(mask,cond,weighted_erosion).assign_to(*this);
19090 }
19091
19093 CImg<T> get_erode(const unsigned int n, const unsigned int cond=1) const {
19094 static CImg<T> mask;
19095 if (n<2) return *this;
19096 if (mask.width!=n) mask.assign(n,n,1,1,1);
19097 const CImg<T> res = get_erode(mask,cond,false);
19098 if (n>20) mask.assign();
19099 return res;
19100 }
19101
19103 CImg<T>& erode(const unsigned int n, const unsigned int cond=1) {
19104 if (n<2) return *this;
19105 return get_erode(n,cond).assign_to(*this);
19106 }
19107
19109 template<typename t> CImg<typename cimg::superset<T,t>::type>
19110 get_dilate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_dilatation=false) const {
19111 typedef typename cimg::superset<T,t>::type restype;
19112 if (is_empty()) return CImg<restype>();
19113 if (!mask || mask.dim!=1)
19114 throw CImgArgumentException("CImg<%s>::dilate() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.",
19115 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
19116 CImg<restype> dest(width,height,depth,dim);
19117 const int cxm=mask.width/2, cym=mask.height/2, czm=mask.depth/2,
19118 fxm=cxm-1+(mask.width%2), fym=cym-1+(mask.height%2), fzm=czm-1+(mask.depth%2);
19119 cimg_forV(*this,v)
19120 if (!weighted_dilatation) {
19121 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19122 restype max_val = cimg::type<restype>::min();
19123 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19124 if (mask(cxm+xm,cym+ym,czm+zm,0)) max_val = cimg::max((restype)(*this)(x+xm,y+ym,z+zm,v),max_val);
19125 dest(x,y,z,v) = max_val;
19126 }
19127 if (cond) cimg_forYZV(*this,y,z,v)
19128 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
19129 restype max_val = cimg::type<restype>::min();
19130 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19131 if (mask(cxm+xm,cym+ym,czm+zm,0)) max_val = cimg::max((restype)pix3d(x+xm,y+ym,z+zm,v),max_val);
19132 dest(x,y,z,v) = max_val;
19133 }
19134 else cimg_forYZV(*this,y,z,v)
19135 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
19136 restype max_val = cimg::type<restype>::min();
19137 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19138 if (mask(cxm+xm,cym+ym,czm+zm,0)) max_val = cimg::max((restype)pix3d(x+xm,y+ym,z+zm,v,0),max_val);
19139 dest(x,y,z,v) = max_val;
19140 }
19141 } else {
19142 t mval=0;
19143 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19144 restype max_val = cimg::type<restype>::min();
19145 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19146 if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) max_val = cimg::max((restype)((*this)(x+xm,y+ym,z+zm,v)-mval),max_val);
19147 dest(x,y,z,v) = max_val;
19148 }
19149 if (cond) cimg_forYZV(*this,y,z,v)
19150 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
19151 restype max_val = cimg::type<restype>::min();
19152 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19153 if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) max_val = cimg::max((restype)(pix3d(x+xm,y+ym,z+zm,v)-mval),max_val);
19154 dest(x,y,z,v) = max_val;
19155 }
19156 else cimg_forYZV(*this,y,z,v)
19157 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
19158 restype max_val = cimg::type<restype>::min();
19159 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19160 if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) max_val = cimg::max((restype)(pix3d(x+xm,y+ym,z+zm,v,0)-mval),max_val);
19161 dest(x,y,z,v) = max_val;
19162 }
19163 }
19164 return dest;
19165 }
19166
19167 template<typename t> CImg<T>& dilate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_dilatation=false) {
19168 return get_dilate(mask,cond,weighted_dilatation).assign_to(*this);
19169 }
19170
19172 CImg<T> get_dilate(const unsigned int n, const unsigned int cond=1) const {
19173 static CImg<T> mask;
19174 if (n<2) return *this;
19175 if (mask.width!=n) mask.assign(n,n,1,1,1);
19176 const CImg<T> res = get_dilate(mask,cond,false);
19177 if (n>20) mask.assign();
19178 return res;
19179 }
19180
19182 CImg<T>& dilate(const unsigned int n, const unsigned int cond=1) {
19183 if (n<2) return *this;
19184 return get_dilate(n,cond).assign_to(*this);
19185 }
19186
19188
19193 CImg<T> get_noise(const double sigma=-20, const unsigned int ntype=0) const {
19194 return (+*this).noise(sigma,ntype);
19195 }
19196
19198 CImg<T>& noise(const double sigma=-20, const unsigned int ntype=0) {
19199 if (!is_empty()) {
19200 double nsigma = sigma, max = (double)cimg::type<T>::max(), min = (double)cimg::type<T>::min();
19201 typedef typename cimg::superset<T,float>::type ftype;
19202 cimg::srand();
19203 ftype m = 0, M = 0;
19204 if (nsigma==0) return *this;
19205 if (nsigma<0 || ntype==2) m = (ftype)minmax(M);
19206 if (nsigma<0) nsigma = -nsigma*(M-m)/100.0;
19207 switch (ntype) {
19208 case 0: {
19209 cimg_for(*this,ptr,T) {
19210 double val = *ptr+nsigma*cimg::grand();
19211 if (val>max) val = max;
19212 if (val<min) val = min;
19213 *ptr = (T)val;
19214 }
19215 } break;
19216 case 1: {
19217 cimg_for(*this,ptr,T) {
19218 double val = *ptr+nsigma*cimg::crand();
19219 if (val>max) val = max;
19220 if (val<min) val = min;
19221 *ptr = (T)val;
19222 }
19223 } break;
19224 case 2: {
19225 if (M==m) { m = 0; M = 255; }
19226 cimg_for(*this,ptr,T) if (cimg::rand()*100<nsigma) *ptr = (T)(cimg::rand()<0.5?M:m);
19227 } break;
19228 case 3: {
19229 cimg_for(*this,ptr,T) {
19230 const double z = (double)*ptr;
19231 if (z<=1.0e-10) *ptr = (T)0;
19232 else {
19233 if (z>100.0) *ptr = (T)(unsigned int)((std::sqrt(z) * cimg::grand()) + z);
19234 else {
19235 unsigned int k = 0;
19236 const double y=std::exp(-z);
19237 for (double s=1.0; s>=y; ++k) s *= cimg::rand();
19238 *ptr = (T)(k-1);
19239 }
19240 }
19241 }
19242 } break;
19243 case 4: {
19244 const double sqrt2 = (double)std::sqrt(2.0);
19245 cimg_for(*this,ptr,T) {
19246 const double
19247 val0 = (double)*ptr/sqrt2,
19248 re = val0 + nsigma*cimg::grand(),
19249 im = val0 + nsigma*cimg::grand();
19250 double val = std::sqrt(re*re + im*im);
19251 if (val>max) val = max;
19252 if (val<min) val = min;
19253 *ptr = (T)val;
19254 }
19255 } break;
19256 }
19257 }
19258 return *this;
19259 }
19260
19262
19267 CImg<typename cimg::superset<T,float>::type> get_deriche(const float sigma, const int order=0,
19268 const char axe='x', const bool cond=true) const {
19269 typedef typename cimg::superset<T,float>::type ftype;
19270 return CImg<ftype>(*this,false).deriche(sigma,order,axe,cond);
19271 }
19272
19274 CImg<T>& deriche(const float sigma, const int order=0, const char axe='x', const bool cond=true) {
19275 #define cimg_deriche2_apply \
19276 ftype *ptrY = Y.data, yb = 0, yp = 0; \
19277 T xp = (T)0; \
19278 if (cond) { xp = *ptrX; yb = yp = (ftype)(coefp*xp); } \
19279 for (int m=0; m<N; ++m) { \
19280 const T xc = *ptrX; ptrX+=off; \
19281 const ftype yc = *(ptrY++) = (ftype)(a0*xc + a1*xp - b1*yp - b2*yb); \
19282 xp = xc; yb = yp; yp = yc; \
19283 } \
19284 T xn = (T)0, xa = (T)0; \
19285 ftype yn = 0, ya = 0; \
19286 if (cond) { xn = xa = *(ptrX-off); yn = ya = (ftype)coefn*xn; } \
19287 for (int n=N-1; n>=0; --n) { \
19288 const T xc = *(ptrX-=off); \
19289 const ftype yc = (ftype)(a2*xn + a3*xa - b1*yn - b2*ya); \
19290 xa = xn; xn = xc; ya = yn; yn = yc; \
19291 *ptrX = (T)(*(--ptrY)+yc); \
19292 }
19293 typedef typename cimg::superset<T,float>::type ftype;
19294 if (sigma<0)
19295 throw CImgArgumentException("CImg<%s>::deriche() : Given filter variance (sigma = %g) is negative",pixel_type(),sigma);
19296 if (is_empty() || (sigma<0.1 && !order)) return *this;
19297 const float
19298 nsigma = sigma<0.1f?0.1f:sigma,
19299 alpha = 1.695f/nsigma,
19300 ema = (float)std::exp(-alpha),
19301 ema2 = (float)std::exp(-2*alpha),
19302 b1 = -2*ema,
19303 b2 = ema2;
19304 float a0 = 0, a1 = 0, a2 = 0, a3 = 0, coefp = 0, coefn = 0;
19305 switch (order) {
19306 case 0: {
19307 const float k = (1-ema)*(1-ema)/(1+2*alpha*ema-ema2);
19308 a0 = k;
19309 a1 = k*(alpha-1)*ema;
19310 a2 = k*(alpha+1)*ema;
19311 a3 = -k*ema2;
19312 } break;
19313 case 1: {
19314 const float k = (1-ema)*(1-ema)/ema;
19315 a0 = k*ema;
19316 a1 = a3 = 0;
19317 a2 = -a0;
19318 } break;
19319 case 2: {
19320 const float
19321 ea = (float)std::exp(-alpha),
19322 k = -(ema2-1)/(2*alpha*ema),
19323 kn = (-2*(-1+3*ea-3*ea*ea+ea*ea*ea)/(3*ea+1+3*ea*ea+ea*ea*ea));
19324 a0 = kn;
19325 a1 = -kn*(1+k*alpha)*ema;
19326 a2 = kn*(1-k*alpha)*ema;
19327 a3 = -kn*ema2;
19328 } break;
19329 default:
19330 throw CImgArgumentException("CImg<%s>::deriche() : Given filter order (order = %u) must be 0,1 or 2",pixel_type(),order);
19331 break;
19332 }
19333 coefp = (a0+a1)/(1+b1+b2);
19334 coefn = (a2+a3)/(1+b1+b2);
19335 switch (cimg::uncase(axe)) {
19336 case 'x': {
19337 const int N = width, off = 1;
19338 CImg<ftype> Y(N);
19339 cimg_forYZV(*this,y,z,v) { T *ptrX = ptr(0,y,z,v); cimg_deriche2_apply; }
19340 } break;
19341 case 'y': {
19342 const int N = height, off = width;
19343 CImg<ftype> Y(N);
19344 cimg_forXZV(*this,x,z,v) { T *ptrX = ptr(x,0,z,v); cimg_deriche2_apply; }
19345 } break;
19346 case 'z': {
19347 const int N = depth, off = width*height;
19348 CImg<ftype> Y(N);
19349 cimg_forXYV(*this,x,y,v) { T *ptrX = ptr(x,y,0,v); cimg_deriche2_apply; }
19350 } break;
19351 case 'v': {
19352 const int N = dim, off = width*height*depth;
19353 CImg<ftype> Y(N);
19354 cimg_forXYZ(*this,x,y,z) { T *ptrX = ptr(x,y,z,0); cimg_deriche2_apply; }
19355 } break;
19356 }
19357 return *this;
19358 }
19359
19361
19364 CImg<typename cimg::superset<T,float>::type> get_blur(const float sigmax, const float sigmay, const float sigmaz,
19365 const bool cond=true) const {
19366 typedef typename cimg::superset<T,float>::type ftype;
19367 return CImg<ftype>(*this,false).blur(sigmax,sigmay,sigmaz,cond);
19368 }
19369
19371 CImg<T>& blur(const float sigmax, const float sigmay, const float sigmaz, const bool cond=true) {
19372 if (!is_empty()) {
19373 if (width>1 && sigmax>0) deriche(sigmax,0,'x',cond);
19374 if (height>1 && sigmay>0) deriche(sigmay,0,'y',cond);
19375 if (depth>1 && sigmaz>0) deriche(sigmaz,0,'z',cond);
19376 }
19377 return *this;
19378 }
19379
19381 CImg<typename cimg::superset<T,float>::type> get_blur(const float sigma, const bool cond=true) const {
19382 typedef typename cimg::superset<T,float>::type ftype;
19383 return CImg<ftype>(*this,false).blur(sigma,cond);
19384 }
19385
19387 CImg<T>& blur(const float sigma, const bool cond=true) {
19388 return blur(sigma,sigma,sigma,cond);
19389 }
19390
19392
19401 template<typename t>
19402 CImg<T> get_blur_anisotropic(const CImg<t>& G, const float amplitude=60.0f, const float dl=0.8f, const float da=30.0f,
19403 const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true) const {
19404 return (+*this).blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
19405 }
19406
19408 template<typename t>
19409 CImg<T>& blur_anisotropic(const CImg<t>& G, const float amplitude=60.0f, const float dl=0.8f, const float da=30.0f,
19410 const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true) {
19411 #define cimg_valign2d(i,j) \
19412 { ftype &u = W(i,j,0,0), &v = W(i,j,0,1); \
19413 if (u*curru + v*currv<0) { u=-u; v=-v; }}
19414 #define cimg_valign3d(i,j,k) \
19415 { ftype &u = W(i,j,k,0), &v = W(i,j,k,1), &w = W(i,j,k,2); \
19416 if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}
19417
19418
19419 typedef typename cimg::superset<T,float>::type ftype;
19420 if (!is_empty() && amplitude>0) {
19421 if (!G || (G.dim!=3 && G.dim!=6) || G.width!=width || G.height!=height || G.depth!=depth)
19422 throw CImgArgumentException("CImg<%s>::blur_anisotropic() : Specified tensor field (%u,%u,%u,%u) is not valid.",
19423 pixel_type(),G.width,G.height,G.depth,G.dim);
19424
19425 const float sqrt2amplitude = (float)std::sqrt(2*amplitude);
19426 const bool threed = (G.dim>=6);
19427 const int
19428 dx1 = dimx()-1,
19429 dy1 = dimy()-1,
19430 dz1 = dimz()-1;
19431 CImg<ftype>
19432 dest(width,height,depth,dim,0),
19433 W(width,height,depth,threed?4:3),
19434 tmp(dim);
19435 int N = 0;
19436
19437 if (threed)
19438
19439 for (float phi=(180%(int)da)/2.0f; phi<=180; phi+=da) {
19440 const float
19441 phir = (float)(phi*cimg::PI/180),
19442 datmp = (float)(da/std::cos(phir)),
19443 da2 = datmp<1?360.0f:datmp;
19444
19445 for (float theta=0; theta<360; (theta+=da2),++N) {
19446 const float
19447 thetar = (float)(theta*cimg::PI/180),
19448 vx = (float)(std::cos(thetar)*std::cos(phir)),
19449 vy = (float)(std::sin(thetar)*std::cos(phir)),
19450 vz = (float)std::sin(phir);
19451 const t
19452 *pa = G.ptr(0,0,0,0),
19453 *pb = G.ptr(0,0,0,1),
19454 *pc = G.ptr(0,0,0,2),
19455 *pd = G.ptr(0,0,0,3),
19456 *pe = G.ptr(0,0,0,4),
19457 *pf = G.ptr(0,0,0,5);
19458 ftype
19459 *pd0 = W.ptr(0,0,0,0),
19460 *pd1 = W.ptr(0,0,0,1),
19461 *pd2 = W.ptr(0,0,0,2),
19462 *pd3 = W.ptr(0,0,0,3);
19463 cimg_forXYZ(G,xg,yg,zg) {
19464 const t
19465 a = *(pa++), b = *(pb++), c = *(pc++),
19466 d = *(pd++), e = *(pe++), f = *(pf++);
19467 const float
19468 u = (float)(a*vx + b*vy + c*vz),
19469 v = (float)(b*vx + d*vy + e*vz),
19470 w = (float)(c*vx + e*vy + f*vz),
19471 n = (float)std::sqrt(1e-5+u*u+v*v+w*w),
19472 dln = dl/n;
19473 *(pd0++) = (ftype)(u*dln);
19474 *(pd1++) = (ftype)(v*dln);
19475 *(pd2++) = (ftype)(w*dln);
19476 *(pd3++) = (ftype)n;
19477 }
19478
19479 cimg_forXYZ(*this,x,y,z) {
19480 tmp.fill(0);
19481 const float
19482 cu = (float)W(x,y,z,0),
19483 cv = (float)W(x,y,z,1),
19484 cw = (float)W(x,y,z,2),
19485 n = (float)W(x,y,z,3),
19486 fsigma = (float)(n*sqrt2amplitude),
19487 length = gauss_prec*fsigma,
19488 fsigma2 = 2*fsigma*fsigma;
19489 float
19490 S = 0,
19491 pu = cu,
19492 pv = cv,
19493 pw = cw,
19494 X = (float)x,
19495 Y = (float)y,
19496 Z = (float)z;
19497
19498 switch (interpolation) {
19499 case 0: {
19500
19501 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
19502 const int
19503 cx = (int)(X+0.5f),
19504 cy = (int)(Y+0.5f),
19505 cz = (int)(Z+0.5f);
19506 float
19507 u = (float)W(cx,cy,cz,0),
19508 v = (float)W(cx,cy,cz,1),
19509 w = (float)W(cx,cy,cz,2);
19510 if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; }
19511 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)(*this)(cx,cy,cz,k); ++S; }
19512 else {
19513 const float coef = (float)std::exp(-l*l/fsigma2);
19514 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*(*this)(cx,cy,cz,k));
19515 S+=coef;
19516 }
19517 X+=(pu=u); Y+=(pv=v); Z+=(pw=w);
19518 }
19519 } break;
19520
19521 case 1: {
19522
19523 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
19524 const int
19525 cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
19526 cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1,
19527 cz = (int)Z, pz = (cz-1<0)?0:cz-1, nz = (cz+1>dz1)?dz1:cz+1;
19528 const float
19529 curru = (float)W(cx,cy,cz,0),
19530 currv = (float)W(cx,cy,cz,1),
19531 currw = (float)W(cx,cy,cz,2);
19532 cimg_valign3d(px,py,pz); cimg_valign3d(cx,py,pz); cimg_valign3d(nx,py,pz);
19533 cimg_valign3d(px,cy,pz); cimg_valign3d(cx,cy,pz); cimg_valign3d(nx,cy,pz);
19534 cimg_valign3d(px,ny,pz); cimg_valign3d(cx,ny,pz); cimg_valign3d(nx,ny,pz);
19535 cimg_valign3d(px,py,cz); cimg_valign3d(cx,py,cz); cimg_valign3d(nx,py,cz);
19536 cimg_valign3d(px,cy,cz); cimg_valign3d(nx,cy,cz);
19537 cimg_valign3d(px,ny,cz); cimg_valign3d(cx,ny,cz); cimg_valign3d(nx,ny,cz);
19538 cimg_valign3d(px,py,nz); cimg_valign3d(cx,py,nz); cimg_valign3d(nx,py,nz);
19539 cimg_valign3d(px,cy,nz); cimg_valign3d(cx,cy,nz); cimg_valign3d(nx,cy,nz);
19540 cimg_valign3d(px,ny,nz); cimg_valign3d(cx,ny,nz); cimg_valign3d(nx,ny,nz);
19541 float
19542 u = (float)(W.linear_pix3d(X,Y,Z,0)),
19543 v = (float)(W.linear_pix3d(X,Y,Z,1)),
19544 w = (float)(W.linear_pix3d(X,Y,Z,2));
19545 if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; }
19546 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix3d(X,Y,Z,k); ++S; }
19547 else {
19548 const float coef = (float)std::exp(-l*l/fsigma2);
19549 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix3d(X,Y,Z,k));
19550 S+=coef;
19551 }
19552 X+=(pu=u); Y+=(pv=v); Z+=(pw=w);
19553 }
19554 } break;
19555
19556 default: {
19557
19558 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
19559 const int
19560 cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
19561 cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1,
19562 cz = (int)Z, pz = (cz-1<0)?0:cz-1, nz = (cz+1>dz1)?dz1:cz+1;
19563 const float
19564 curru = (float)W(cx,cy,cz,0),
19565 currv = (float)W(cx,cy,cz,1),
19566 currw = (float)W(cx,cy,cz,2);
19567 cimg_valign3d(px,py,pz); cimg_valign3d(cx,py,pz); cimg_valign3d(nx,py,pz);
19568 cimg_valign3d(px,cy,pz); cimg_valign3d(cx,cy,pz); cimg_valign3d(nx,cy,pz);
19569 cimg_valign3d(px,ny,pz); cimg_valign3d(cx,ny,pz); cimg_valign3d(nx,ny,pz);
19570 cimg_valign3d(px,py,cz); cimg_valign3d(cx,py,cz); cimg_valign3d(nx,py,cz);
19571 cimg_valign3d(px,cy,cz); cimg_valign3d(nx,cy,cz);
19572 cimg_valign3d(px,ny,cz); cimg_valign3d(cx,ny,cz); cimg_valign3d(nx,ny,cz);
19573 cimg_valign3d(px,py,nz); cimg_valign3d(cx,py,nz); cimg_valign3d(nx,py,nz);
19574 cimg_valign3d(px,cy,nz); cimg_valign3d(cx,cy,nz); cimg_valign3d(nx,cy,nz);
19575 cimg_valign3d(px,ny,nz); cimg_valign3d(cx,ny,nz); cimg_valign3d(nx,ny,nz);
19576 const float
19577 u0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,0)),
19578 v0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,1)),
19579 w0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,2));
19580 float
19581 u = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,0)),
19582 v = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,1)),
19583 w = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,2));
19584 if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; }
19585 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix3d(X,Y,Z,k); ++S; }
19586 else {
19587 const float coef = (float)std::exp(-l*l/fsigma2);
19588 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix3d(X,Y,Z,k));
19589 S+=coef;
19590 }
19591 X+=(pu=u); Y+=(pv=v); Z+=(pw=w);
19592 }
19593 } break;
19594 }
19595 if (S>0) cimg_forV(dest,k) dest(x,y,z,k)+=tmp[k]/S;
19596 else cimg_forV(dest,k) dest(x,y,z,k)+=(ftype)((*this)(x,y,z,k));
19597 #ifdef cimg_plugin_greycstoration
19598 if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter);
19599 else return *this;
19600 #endif
19601 }
19602 }
19603 } else
19604
19605 for (float theta=(360%(int)da)/2.0f; theta<360; (theta+=da),++N) {
19606 const float
19607 thetar = (float)(theta*cimg::PI/180),
19608 vx = (float)(std::cos(thetar)),
19609 vy = (float)(std::sin(thetar));
19610 const t
19611 *pa = G.ptr(0,0,0,0),
19612 *pb = G.ptr(0,0,0,1),
19613 *pc = G.ptr(0,0,0,2);
19614 ftype
19615 *pd0 = W.ptr(0,0,0,0),
19616 *pd1 = W.ptr(0,0,0,1),
19617 *pd2 = W.ptr(0,0,0,2);
19618 cimg_forXY(G,xg,yg) {
19619 const t a = *(pa++), b = *(pb++), c = *(pc++);
19620 const float
19621 u = (float)(a*vx + b*vy),
19622 v = (float)(b*vx + c*vy),
19623 n = (float)std::sqrt(1e-5+u*u+v*v),
19624 dln = dl/n;
19625 *(pd0++) = (ftype)(u*dln);
19626 *(pd1++) = (ftype)(v*dln);
19627 *(pd2++) = (ftype)n;
19628 }
19629
19630 cimg_forXY(*this,x,y) {
19631 tmp.fill(0);
19632 const float
19633 cu = (float)W(x,y,0,0),
19634 cv = (float)W(x,y,0,1),
19635 n = (float)W(x,y,0,2),
19636 fsigma = (float)(n*sqrt2amplitude),
19637 length = gauss_prec*fsigma,
19638 fsigma2 = 2*fsigma*fsigma;
19639 float
19640 S = 0,
19641 pu = cu,
19642 pv = cv,
19643 X = (float)x,
19644 Y = (float)y;
19645
19646 switch (interpolation) {
19647
19648 case 0: {
19649
19650 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
19651 const int
19652 cx = (int)(X+0.5f),
19653 cy = (int)(Y+0.5f);
19654 float
19655 u = (float)W(cx,cy,0,0),
19656 v = (float)W(cx,cy,0,1);
19657 if ((pu*u + pv*v)<0) { u=-u; v=-v; }
19658 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)(*this)(cx,cy,0,k); ++S; }
19659 else {
19660 const float coef = (float)std::exp(-l*l/fsigma2);
19661 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*(*this)(cx,cy,0,k));
19662 S+=coef;
19663 }
19664 X+=(pu=u); Y+=(pv=v);
19665 }
19666 } break;
19667
19668 case 1: {
19669
19670 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
19671 const int
19672 cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
19673 cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1;
19674 const float
19675 curru = (float)W(cx,cy,0,0),
19676 currv = (float)W(cx,cy,0,1);
19677 cimg_valign2d(px,py); cimg_valign2d(cx,py); cimg_valign2d(nx,py);
19678 cimg_valign2d(px,cy); cimg_valign2d(nx,cy);
19679 cimg_valign2d(px,ny); cimg_valign2d(cx,ny); cimg_valign2d(nx,ny);
19680 float
19681 u = (float)(W.linear_pix2d(X,Y,0,0)),
19682 v = (float)(W.linear_pix2d(X,Y,0,1));
19683 if ((pu*u + pv*v)<0) { u=-u; v=-v; }
19684 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix2d(X,Y,0,k); ++S; }
19685 else {
19686 const float coef = (float)std::exp(-l*l/fsigma2);
19687 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix2d(X,Y,0,k));
19688 S+=coef;
19689 }
19690 X+=(pu=u); Y+=(pv=v);
19691 }
19692 } break;
19693
19694 default: {
19695
19696 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
19697 const int
19698 cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
19699 cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1;
19700 const float
19701 curru = (float)W(cx,cy,0,0),
19702 currv = (float)W(cx,cy,0,1);
19703 cimg_valign2d(px,py); cimg_valign2d(cx,py); cimg_valign2d(nx,py);
19704 cimg_valign2d(px,cy); cimg_valign2d(nx,cy);
19705 cimg_valign2d(px,ny); cimg_valign2d(cx,ny); cimg_valign2d(nx,ny);
19706 const float
19707 u0 = (float)(0.5f*W.linear_pix2d(X,Y,0,0)),
19708 v0 = (float)(0.5f*W.linear_pix2d(X,Y,0,1));
19709 float
19710 u = (float)(W.linear_pix2d(X+u0,Y+v0,0,0)),
19711 v = (float)(W.linear_pix2d(X+u0,Y+v0,0,1));
19712 if ((pu*u + pv*v)<0) { u=-u; v=-v; }
19713 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix2d(X,Y,0,k); ++S; }
19714 else {
19715 const float coef = (float)std::exp(-l*l/fsigma2);
19716 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix2d(X,Y,0,k));
19717 S+=coef;
19718 }
19719 X+=(pu=u); Y+=(pv=v);
19720 }
19721 } break;
19722 }
19723 if (S>0) cimg_forV(dest,k) dest(x,y,0,k)+=tmp[k]/S;
19724 else cimg_forV(dest,k) dest(x,y,0,k)+=(ftype)((*this)(x,y,0,k));
19725 #ifdef cimg_plugin_greycstoration
19726 if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter);
19727 else return *this;
19728 #endif
19729 }
19730 }
19731 const ftype *ptrs = dest.data+dest.size();
19732 const T m = cimg::type<T>::min(), M = cimg::type<T>::max();
19733 cimg_for(*this,ptrd,T) { const ftype val = *(--ptrs)/N; *ptrd = val<m?m:(val>M?M:(T)val); }
19734 }
19735 return *this;
19736 }
19737
19739
19753 template<typename tm>
19754 CImg<T> get_blur_anisotropic(const CImg<tm>& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
19755 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
19756 const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0,
19757 const bool fast_approx=true, const float geom_factor=1.0f) const {
19758 return (+*this).blur_anisotropic(mask,amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
19759 }
19760
19762 template<typename tm>
19763 CImg<T>& blur_anisotropic(const CImg<tm>& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
19764 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f,
19765 const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true,
19766 const float geom_factor=1.0f) {
19767 if (!is_empty() && amplitude>0) {
19768 if (amplitude==0) return *this;
19769 if (amplitude<0 || sharpness<0 || anisotropy<0 || anisotropy>1 || alpha<0 || sigma<0 || dl<0 || da<0 || gauss_prec<0)
19770 throw CImgArgumentException("CImg<%s>::blur_anisotropic() : Given parameters are amplitude(%g), sharpness(%g), "
19771 "anisotropy(%g), alpha(%g), sigma(%g), dl(%g), da(%g), gauss_prec(%g).\n"
19772 "Admissible parameters are in the range : amplitude>0, sharpness>0, anisotropy in [0,1], "
19773 "alpha>0, sigma>0, dl>0, da>0, gauss_prec>0.",
19774 pixel_type(),amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec);
19775 const bool threed = (depth>1), no_mask = mask.is_empty();
19776 const float nsharpness = cimg::max(sharpness,1e-5f), power1 = 0.5f*nsharpness, power2 = power1/(1e-7f+1.0f-anisotropy);
19777 CImg<float> blurred = CImg<float>(*this,false).blur(alpha);
19778 if (geom_factor>0) blurred*=geom_factor;
19779 else blurred.normalize(0,-geom_factor);
19780
19781 if (threed) {
19782 #ifdef cimg_plugin_greycstoration
19783 greycstoration_mutex_lock(greycstoration_params[0]);
19784 #endif
19785 CImg<float> val(3), vec(3,3), G(blurred.get_structure_tensorXYZ());
19786 if (sigma>0) G.blur(sigma);
19787 cimg_forXYZ(*this,x,y,z) {
19788 if (no_mask || mask(x,y,z)) {
19789 G.get_tensor_at(x,y,z).symmetric_eigen(val,vec);
19790 const float l1 = val[2], l2 = val[1], l3 = val[0],
19791 ux = vec(0,0), uy = vec(0,1), uz = vec(0,2),
19792 vx = vec(1,0), vy = vec(1,1), vz = vec(1,2),
19793 wx = vec(2,0), wy = vec(2,1), wz = vec(2,2),
19794 n1 = (float)std::pow(1.0f+l1+l2+l3,-power1),
19795 n2 = (float)std::pow(1.0f+l1+l2+l3,-power2);
19796 G(x,y,z,0) = n1*(ux*ux + vx*vx) + n2*wx*wx;
19797 G(x,y,z,1) = n1*(ux*uy + vx*vy) + n2*wx*wy;
19798 G(x,y,z,2) = n1*(ux*uz + vx*vz) + n2*wx*wz;
19799 G(x,y,z,3) = n1*(uy*uy + vy*vy) + n2*wy*wy;
19800 G(x,y,z,4) = n1*(uy*uz + vy*vz) + n2*wy*wz;
19801 G(x,y,z,5) = n1*(uz*uz + vz*vz) + n2*wz*wz;
19802 } else G(x,y,z,0) = G(x,y,z,1) = G(x,y,z,2) = G(x,y,z,3) = G(x,y,z,4) = G(x,y,z,5) = 0;
19803 #ifdef cimg_plugin_greycstoration
19804 if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter);
19805 else return *this;
19806 #endif
19807 }
19808 #ifdef cimg_plugin_greycstoration
19809 greycstoration_mutex_unlock(greycstoration_params[0]);
19810 #endif
19811 blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
19812 } else {
19813 #ifdef cimg_plugin_greycstoration
19814 greycstoration_mutex_lock(greycstoration_params[0]);
19815 #endif
19816 CImg<float> val(2), vec(2,2), G(blurred.get_structure_tensorXY());
19817 if (sigma>0) G.blur(sigma);
19818 cimg_forXY(*this,x,y) {
19819 if (no_mask || mask(x,y)) {
19820 G.get_tensor_at(x,y).symmetric_eigen(val,vec);
19821 const float l1 = val[1], l2 = val[0],
19822 ux = vec(1,0), uy = vec(1,1),
19823 vx = vec(0,0), vy = vec(0,1),
19824 n1 = (float)std::pow(1.0f+l1+l2,-power1),
19825 n2 = (float)std::pow(1.0f+l1+l2,-power2);
19826 G(x,y,0,0) = n1*ux*ux + n2*vx*vx;
19827 G(x,y,0,1) = n1*ux*uy + n2*vx*vy;
19828 G(x,y,0,2) = n1*uy*uy + n2*vy*vy;
19829 } else G(x,y,0,0) = G(x,y,0,1) = G(x,y,0,2) = 0;
19830 #ifdef cimg_plugin_greycstoration
19831 if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter);
19832 else return *this;
19833 #endif
19834 }
19835 #ifdef cimg_plugin_greycstoration
19836 greycstoration_mutex_unlock(greycstoration_params[0]);
19837 #endif
19838 blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
19839 }
19840 }
19841 return *this;
19842 }
19843
19845 CImg<T> get_blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
19846 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
19847 const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0,
19848 const bool fast_approx=true, const float geom_factor=1.0f) const {
19849 return (+*this).blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
19850 }
19851
19853 CImg<T>& blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
19854 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f,
19855 const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true,
19856 const float geom_factor=1.0f) {
19857 return blur_anisotropic(CImg<T>(),amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
19858 }
19859
19861
19874 CImg<T> get_blur_bilateral(const float sigmax, const float sigmay, const float sigmaz, const float sigmar,
19875 const int bgridx, const int bgridy, const int bgridz, const int bgridr,
19876 const bool interpolation=true) const {
19877 return (+*this).blur_bilateral(sigmax,sigmay,sigmaz,sigmar,bgridx,bgridy,bgridz,bgridr,interpolation);
19878 }
19879
19881 CImg<T>& blur_bilateral(const float sigmax, const float sigmay, const float sigmaz, const float sigmar,
19882 const int bgridx, const int bgridy, const int bgridz, const int bgridr,
19883 const bool interpolation=true) {
19884 T m, M = maxmin(m);
19885 const float range = (float)(1.0f+M-m);
19886 const unsigned int
19887 bx0 = bgridx>=0?bgridx:width*(-bgridx)/100,
19888 by0 = bgridy>=0?bgridy:height*(-bgridy)/100,
19889 bz0 = bgridz>=0?bgridz:depth*(-bgridz)/100,
19890 br0 = bgridr>=0?bgridr:(int)(-range*bgridr/100),
19891 bx = bx0>0?bx0:1,
19892 by = by0>0?by0:1,
19893 bz = bz0>0?bz0:1,
19894 br = br0>0?br0:1;
19895 const float
19896 nsigmax = sigmax*bx/width,
19897 nsigmay = sigmay*by/height,
19898 nsigmaz = sigmaz*bz/depth,
19899 nsigmar = sigmar*br/range;
19900 if (nsigmax>0 || nsigmay>0 || nsigmaz>0 || nsigmar>0) {
19901 const bool threed = depth>1;
19902 if (threed) {
19903 typedef typename cimg::last<T,float>::type ftype;
19904 CImg<ftype> bgrid(bx,by,bz,br), bgridw(bx,by,bz,br);
19905 cimg_forV(*this,k) {
19906 bgrid.fill(0); bgridw.fill(0);
19907 cimg_forXYZ(*this,x,y,z) {
19908 const T val = (*this)(x,y,z,k);
19909 const int X = x*bx/width, Y = y*by/height, Z = z*bz/depth, R = (int)((val-m)*br/range);
19910 bgrid(X,Y,Z,R) = (float)val;
19911 bgridw(X,Y,Z,R) = 1;
19912 }
19913 bgrid.blur(nsigmax,nsigmay,nsigmaz,true).deriche(nsigmar,0,'v',false);
19914 bgridw.blur(nsigmax,nsigmay,nsigmaz,true).deriche(nsigmar,0,'v',false);
19915 if (interpolation) cimg_forXYZ(*this,x,y,z) {
19916 const T val = (*this)(x,y,z,k);
19917 const float X = (float)x*bx/width, Y = (float)y*by/height, Z = (float)z*bz/depth, R = (val-m)*br/range,
19918 bval0 = bgrid.linear_pix4d(X,Y,Z,R), bval1 = bgridw.linear_pix4d(X,Y,Z,R);
19919 (*this)(x,y,z,k) = (T)(bval0/bval1);
19920 } else cimg_forXYZ(*this,x,y,z) {
19921 const T val = (*this)(x,y,z,k);
19922 const int X = x*bx/width, Y = y*by/height, Z = z*bz/depth, R = (int)((val-m)*br/range);
19923 const float bval0 = bgrid(X,Y,Z,R), bval1 = bgridw(X,Y,Z,R);
19924 (*this)(x,y,z,k) = (T)(bval0/bval1);
19925 }
19926 }
19927 } else {
19928 typedef typename cimg::last<T,float>::type ftype;
19929 CImg<ftype> bgrid(bx,by,br,2);
19930 cimg_forV(*this,k) {
19931 bgrid.fill(0);
19932 cimg_forXY(*this,x,y) {
19933 const T val = (*this)(x,y,k);
19934 const int X = x*bx/width, Y = y*by/height, R = (int)((val-m)*br/range);
19935 bgrid(X,Y,R,0) = (float)val;
19936 bgrid(X,Y,R,1) = 1;
19937 }
19938 bgrid.blur(nsigmax,nsigmay,0,true).blur(0,0,nsigmar,false);
19939 if (interpolation) cimg_forXY(*this,x,y) {
19940 const T val = (*this)(x,y,k);
19941 const float X = (float)x*bx/width, Y = (float)y*by/height, R = (val-m)*br/range,
19942 bval0 = bgrid.linear_pix3d(X,Y,R,0), bval1 = bgrid.linear_pix3d(X,Y,R,1);
19943 (*this)(x,y,k) = (T)(bval0/bval1);
19944 } else cimg_forXY(*this,x,y) {
19945 const T val = (*this)(x,y,k);
19946 const int X = x*bx/width, Y = y*by/height, R = (int)((val-m)*br/range);
19947 const float bval0 = bgrid(X,Y,R,0), bval1 = bgrid(X,Y,R,1);
19948 (*this)(x,y,k) = (T)(bval0/bval1);
19949 }
19950 }
19951 }
19952 }
19953 return *this;
19954 }
19955
19957 CImg<T> get_blur_bilateral(const float sigmas, const float sigmar, const int bgrids=-33, const int bgridr=32,
19958 const bool interpolation=true) const {
19959 return (+*this).blur_bilateral(sigmas,sigmas,sigmas,sigmar,bgrids,bgrids,bgrids,bgridr,interpolation);
19960 }
19961
19963 CImg<T>& blur_bilateral(const float sigmas, const float sigmar, const int bgrids=-33, const int bgridr=32,
19964 const bool interpolation=true) {
19965 return blur_bilateral(sigmas,sigmas,sigmas,sigmar,bgrids,bgrids,bgrids,bgridr,interpolation);
19966 }
19967
19969 CImgList<typename cimg::superset<T,float>::type> get_FFT(const char axe, const bool inverse=false) const {
19970 typedef typename cimg::superset<T,float>::type restype;
19971 return CImgList<restype>(*this).FFT(axe,inverse);
19972 }
19973
19975 CImgList<typename cimg::superset<T,float>::type> get_FFT(const bool inverse=false) const {
19976 typedef typename cimg::superset<T,float>::type restype;
19977 return CImgList<restype>(*this).FFT(inverse);
19978 }
19979
19981 CImg<T> get_blur_median(const unsigned int n=3) {
19982 CImg<T> res(width,height,depth,dim);
19983 if (!n || n==1) return *this;
19984 const int hl=n/2, hr=hl-1+n%2;
19985 if (res.depth!=1) {
19986 CImg<T> vois;
19987 cimg_forXYZV(*this,x,y,z,k) {
19988 const int
19989 x0 = x - hl, y0 = y - hl, z0 = z-hl, x1 = x + hr, y1 = y + hr, z1 = z+hr,
19990 nx0 = x0<0?0:x0, ny0 = y0<0?0:y0, nz0 = z0<0?0:z0,
19991 nx1 = x1>=dimx()?dimx()-1:x1, ny1 = y1>=dimy()?dimy()-1:y1, nz1 = z1>=dimz()?dimz()-1:z1;
19992 vois = get_crop(nx0,ny0,nz0,k,nx1,ny1,nz1,k);
19993 res(x,y,z,k) = vois.median();
19994 }
19995 } else {
19996 #define _median_sort(a,b) if ((a)>(b)) cimg::swap(a,b)
19997 if (res.height!=1) switch (n) {
19998 case 3: {
19999 T I[9] = { 0 };
20000 CImg_3x3(J,T);
20001 cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) {
20002 std::memcpy(J,I,9*sizeof(T));
20003 _median_sort(Jcp, Jnp); _median_sort(Jcc, Jnc); _median_sort(Jcn, Jnn);
20004 _median_sort(Jpp, Jcp); _median_sort(Jpc, Jcc); _median_sort(Jpn, Jcn);
20005 _median_sort(Jcp, Jnp); _median_sort(Jcc, Jnc); _median_sort(Jcn, Jnn);
20006 _median_sort(Jpp, Jpc); _median_sort(Jnc, Jnn); _median_sort(Jcc, Jcn);
20007 _median_sort(Jpc, Jpn); _median_sort(Jcp, Jcc); _median_sort(Jnp, Jnc);
20008 _median_sort(Jcc, Jcn); _median_sort(Jcc, Jnp); _median_sort(Jpn, Jcc);
20009 _median_sort(Jcc, Jnp);
20010 res(x,y,0,k) = Jcc;
20011 }
20012 } break;
20013 case 5: {
20014 T I[25] = { 0 };
20015 CImg_5x5(J,T);
20016 cimg_forV(*this,k) cimg_for5x5(*this,x,y,0,k,I) {
20017 std::memcpy(J,I,25*sizeof(T));
20018 _median_sort(Jbb, Jpb); _median_sort(Jnb, Jab); _median_sort(Jcb, Jab); _median_sort(Jcb, Jnb);
20019 _median_sort(Jpp, Jcp); _median_sort(Jbp, Jcp); _median_sort(Jbp, Jpp); _median_sort(Jap, Jbc);
20020 _median_sort(Jnp, Jbc); _median_sort(Jnp, Jap); _median_sort(Jcc, Jnc); _median_sort(Jpc, Jnc);
20021 _median_sort(Jpc, Jcc); _median_sort(Jbn, Jpn); _median_sort(Jac, Jpn); _median_sort(Jac, Jbn);
20022 _median_sort(Jnn, Jan); _median_sort(Jcn, Jan); _median_sort(Jcn, Jnn); _median_sort(Jpa, Jca);
20023 _median_sort(Jba, Jca); _median_sort(Jba, Jpa); _median_sort(Jna, Jaa); _median_sort(Jcb, Jbp);
20024 _median_sort(Jnb, Jpp); _median_sort(Jbb, Jpp); _median_sort(Jbb, Jnb); _median_sort(Jab, Jcp);
20025 _median_sort(Jpb, Jcp); _median_sort(Jpb, Jab); _median_sort(Jpc, Jac); _median_sort(Jnp, Jac);
20026 _median_sort(Jnp, Jpc); _median_sort(Jcc, Jbn); _median_sort(Jap, Jbn); _median_sort(Jap, Jcc);
20027 _median_sort(Jnc, Jpn); _median_sort(Jbc, Jpn); _median_sort(Jbc, Jnc); _median_sort(Jba, Jna);
20028 _median_sort(Jcn, Jna); _median_sort(Jcn, Jba); _median_sort(Jpa, Jaa); _median_sort(Jnn, Jaa);
20029 _median_sort(Jnn, Jpa); _median_sort(Jan, Jca); _median_sort(Jnp, Jcn); _median_sort(Jap, Jnn);
20030 _median_sort(Jbb, Jnn); _median_sort(Jbb, Jap); _median_sort(Jbc, Jan); _median_sort(Jpb, Jan);
20031 _median_sort(Jpb, Jbc); _median_sort(Jpc, Jba); _median_sort(Jcb, Jba); _median_sort(Jcb, Jpc);
20032 _median_sort(Jcc, Jpa); _median_sort(Jnb, Jpa); _median_sort(Jnb, Jcc); _median_sort(Jnc, Jca);
20033 _median_sort(Jab, Jca); _median_sort(Jab, Jnc); _median_sort(Jac, Jna); _median_sort(Jbp, Jna);
20034 _median_sort(Jbp, Jac); _median_sort(Jbn, Jaa); _median_sort(Jpp, Jaa); _median_sort(Jpp, Jbn);
20035 _median_sort(Jcp, Jpn); _median_sort(Jcp, Jan); _median_sort(Jnc, Jpa); _median_sort(Jbn, Jna);
20036 _median_sort(Jcp, Jnc); _median_sort(Jcp, Jbn); _median_sort(Jpb, Jap); _median_sort(Jnb, Jpc);
20037 _median_sort(Jbp, Jcn); _median_sort(Jpc, Jcn); _median_sort(Jap, Jcn); _median_sort(Jab, Jbc);
20038 _median_sort(Jpp, Jcc); _median_sort(Jcp, Jac); _median_sort(Jab, Jpp); _median_sort(Jab, Jcp);
20039 _median_sort(Jcc, Jac); _median_sort(Jbc, Jac); _median_sort(Jpp, Jcp); _median_sort(Jbc, Jcc);
20040 _median_sort(Jpp, Jbc); _median_sort(Jpp, Jcn); _median_sort(Jcc, Jcn); _median_sort(Jcp, Jcn);
20041 _median_sort(Jcp, Jbc); _median_sort(Jcc, Jnn); _median_sort(Jcp, Jcc); _median_sort(Jbc, Jnn);
20042 _median_sort(Jcc, Jba); _median_sort(Jbc, Jba); _median_sort(Jbc, Jcc);
20043 res(x,y,0,k) = Jcc;
20044 }
20045 } break;
20046 default: {
20047 CImg<T> vois;
20048 cimg_forXYV(*this,x,y,k) {
20049 const int
20050 x0 = x - hl, y0 = y - hl, x1 = x + hr, y1 = y + hr,
20051 nx0 = x0<0?0:x0, ny0 = y0<0?0:y0,
20052 nx1 = x1>=dimx()?dimx()-1:x1, ny1 = y1>=dimy()?dimy()-1:y1;
20053 vois = get_crop(nx0,ny0,0,k,nx1,ny1,0,k);
20054 res(x,y,0,k) = vois.median();
20055 }
20056 } break;
20057 } else switch (n) {
20058 case 2: {
20059 T I[4] = { 0 };
20060 cimg_forV(*this,k) cimg_for2x2(*this,x,y,0,k,I) res(x,0,0,k) = (T)(0.5f*(I[0]+I[1]));
20061 } break;
20062 case 3: {
20063 T I[9] = { 0 };
20064 cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) {
20065 res(x,0,0,k) = I[3]<I[4]?
20066 (I[4]<I[5]?I[4]:
20067 (I[3]<I[5]?I[5]:I[3])):
20068 (I[3]<I[5]?I[3]:
20069 (I[4]<I[5]?I[5]:I[4]));
20070 }
20071 } break;
20072 default: {
20073 CImg<T> vois;
20074 cimg_forXV(*this,x,k) {
20075 const int
20076 x0 = x - hl, x1 = x + hr,
20077 nx0 = x0<0?0:x0, nx1 = x1>=dimx()?dimx()-1:x1;
20078 vois = get_crop(nx0,0,0,k,nx1,0,0,k);
20079 res(x,0,0,k) = vois.median();
20080 }
20081 } break;
20082 }
20083 }
20084 return res;
20085 }
20086
20088 CImg<T>& blur_median(const unsigned int n=3) {
20089 return get_blur_median(n).assign_to(*this);
20090 }
20091
20093 CImg<T> get_sharpen(const float amplitude=50.0f, const float edge=1.0f, const float alpha=0.0f, const float sigma=0.0f) const {
20094 return (+*this).sharpen(amplitude,edge,alpha,sigma);
20095 }
20096
20098 CImg<T>& sharpen(const float amplitude=50.0f, const float edge=1.0f, const float alpha=0.0f, const float sigma=0.0f) {
20099 if (is_empty()) return *this;
20100 const bool threed = (depth>1);
20101 const float nedge = 0.5f*edge;
20102 typedef typename cimg::superset<T,float>::type ftype;
20103 CImg<ftype> val, vec, veloc(width,height,depth,dim);
20104
20105 if (threed) {
20106 CImg<ftype> G = (alpha>0?get_blur(alpha).get_structure_tensorXYZ():get_structure_tensorXYZ());
20107 if (sigma>0) G.blur(sigma);
20108 CImg_3x3x3(I,float);
20109 cimg_forXYZ(G,x,y,z) {
20110 G.get_tensor_at(x,y,z).symmetric_eigen(val,vec);
20111 G(x,y,z,0) = vec(0,0);
20112 G(x,y,z,1) = vec(0,1);
20113 G(x,y,z,2) = vec(0,2);
20114 G(x,y,z,3) = 1.0f-(float)std::pow((float)(1+val[0]+val[1]+val[2]),-nedge);
20115 }
20116 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
20117 const float
20118 u = G(x,y,z,0),
20119 v = G(x,y,z,1),
20120 w = G(x,y,z,2),
20121 amp = G(x,y,z,3),
20122 ixx = Incc+Ipcc-2*Iccc,
20123 ixy = 0.25f*(Innc+Ippc-Inpc-Ipnc),
20124 ixz = 0.25f*(Incn+Ipcp-Incp-Ipcn),
20125 iyy = Icnc+Icpc-2*Iccc,
20126 iyz = 0.25f*(Icnn+Icpp-Icnp-Icpn),
20127 izz = Iccn+Iccp-2*Iccc,
20128 ixf = Incc-Iccc,
20129 ixb = Iccc-Ipcc,
20130 iyf = Icnc-Iccc,
20131 iyb = Iccc-Icpc,
20132 izf = Iccn-Iccc,
20133 izb = Iccc-Iccp,
20134 itt = u*u*ixx + v*v*iyy + w*w*izz + 2*u*v*ixy + 2*u*w*ixz + 2*v*w*iyz,
20135 it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb) + w*cimg::minmod(izf,izb);
20136 veloc(x,y,z,k) = -amp*cimg::sign(itt)*cimg::abs(it);
20137 }
20138 } else {
20139 CImg<ftype> G = (alpha>0?get_blur(alpha).get_structure_tensorXY():get_structure_tensorXY());
20140 if (sigma>0) G.blur(sigma);
20141 CImg_3x3(I,float);
20142 cimg_forXY(G,x,y) {
20143 G.get_tensor_at(x,y).symmetric_eigen(val,vec);
20144 G(x,y,0) = vec(0,0);
20145 G(x,y,1) = vec(0,1);
20146 G(x,y,2) = 1.0f-(float)std::pow((float)(1+val[0]+val[1]),-nedge);
20147 }
20148 cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) {
20149 const float
20150 u = G(x,y,0),
20151 v = G(x,y,1),
20152 amp = G(x,y,2),
20153 ixx = Inc+Ipc-2*Icc,
20154 ixy = 0.25f*(Inn+Ipp-Inp-Ipn),
20155 iyy = Icn+Icp-2*Icc,
20156 ixf = Inc-Icc,
20157 ixb = Icc-Ipc,
20158 iyf = Icn-Icc,
20159 iyb = Icc-Icp,
20160 itt = u*u*ixx + v*v*iyy + 2*u*v*ixy,
20161 it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb);
20162 veloc(x,y,k) = -amp*cimg::sign(itt)*cimg::abs(it);
20163 }
20164 }
20165 float m, M = (float)veloc.maxmin(m);
20166 const float vmax = (float)cimg::max(cimg::abs(m),cimg::abs(M));
20167 if (vmax!=0) { veloc*=amplitude/vmax; (*this)+=veloc; }
20168 return *this;
20169 }
20170
20172
20177 CImg<typename cimg::superset<T,float>::type> get_haar(const char axis, const bool inverse=false, const unsigned int nb_scales=1) const {
20178 if (is_empty() || !nb_scales) return *this;
20179 typedef typename cimg::superset<T,float>::type ftype;
20180 CImg<ftype> res;
20181
20182 if (nb_scales==1) {
20183 switch (cimg::uncase(axis)) {
20184 case 'x': {
20185 const unsigned int w = width/2;
20186 if (w) {
20187 if (w%2) throw CImgInstanceException("CImg<%s>::haar() : Sub-image width = %u is not even at a particular scale (=%u).",pixel_type(),w);
20188 res.assign(width,height,depth,dim);
20189 if (inverse) cimg_forYZV(*this,y,z,v) {
20190 for (unsigned int x=0, xw=w, x2=0; x<w; ++x, ++xw) {
20191 const ftype val0 = (ftype)(*this)(x,y,z,v), val1 = (ftype)(*this)(xw,y,z,v);
20192 res(x2++,y,z,v) = val0 - val1;
20193 res(x2++,y,z,v) = val0 + val1;
20194 }
20195 } else cimg_forYZV(*this,y,z,v) {
20196 for (unsigned int x=0, xw=w, x2=0; x<w; ++x, ++xw) {
20197 const ftype val0 = (ftype)(*this)(x2++,y,z,v), val1 = (ftype)(*this)(x2++,y,z,v);
20198 res(x,y,z,v) = (val0 + val1)/2;
20199 res(xw,y,z,v) = (val1 - val0)/2;
20200 }
20201 }
20202 } else return *this;
20203 } break;
20204 case 'y': {
20205 const unsigned int h = height/2;
20206 if (h) {
20207 if (h%2) throw CImgInstanceException("CImg<%s>::haar() : Sub-image height = %u is not even at a particular scale.",pixel_type(),h);
20208 res.assign(width,height,depth,dim);
20209 if (inverse) cimg_forXZV(*this,x,z,v) {
20210 for (unsigned int y=0, yh=h, y2=0; y<h; ++y, ++yh) {
20211 const ftype val0 = (ftype)(*this)(x,y,z,v), val1 = (ftype)(*this)(x,yh,z,v);
20212 res(x,y2++,z,v) = val0 - val1;
20213 res(x,y2++,z,v) = val0 + val1;
20214 }
20215 } else cimg_forXZV(*this,x,z,v) {
20216 for (unsigned int y=0, yh=h, y2=0; y<h; ++y, ++yh) {
20217 const ftype val0 = (ftype)(*this)(x,y2++,z,v), val1 = (ftype)(*this)(x,y2++,z,v);
20218 res(x,y,z,v) = (val0 + val1)/2;
20219 res(x,yh,z,v) = (val1 - val0)/2;
20220 }
20221 }
20222 } else return *this;
20223 } break;
20224 case 'z': {
20225 const unsigned int d = depth/2;
20226 if (d) {
20227 if (d%2) throw CImgInstanceException("CImg<%s>::haar() : Sub-image depth = %u is not even at a particular scale.",pixel_type(),d);
20228 res.assign(width,height,depth,dim);
20229 if (inverse) cimg_forXYV(*this,x,y,v) {
20230 for (unsigned int z=0, zd=d, z2=0; z<d; ++z, ++zd) {
20231 const ftype val0 = (ftype)(*this)(x,y,z,v), val1 = (ftype)(*this)(x,y,zd,v);
20232 res(x,y,z2++,v) = val0 - val1;
20233 res(x,y,z2++,v) = val0 + val1;
20234 }
20235 } else cimg_forXYV(*this,x,y,v) {
20236 for (unsigned int z=0, zd=d, z2=0; z<d; ++z, ++zd) {
20237 const ftype val0 = (ftype)(*this)(x,y,z2++,v), val1 = (ftype)(*this)(x,y,z2++,v);
20238 res(x,y,z,v) = (val0 + val1)/2;
20239 res(x,y,zd,v) = (val1 - val0)/2;
20240 }
20241 }
20242 } else return *this;
20243 } break;
20244 default: throw CImgArgumentException("CImg<%s>::haar() : Unknown axis '%c'.",pixel_type(),axis); break;
20245 }
20246 } else {
20247 if (inverse) {
20248 res.assign(*this);
20249 switch (cimg::uncase(axis)) {
20250 case 'x': {
20251 unsigned int w = width;
20252 for (unsigned int s=1; w && s<nb_scales; ++s) w/=2;
20253 for (w=w?w:1; w<=width; w*=2) res.draw_image(res.get_crop(0,w-1).get_haar('x',true,1),0);
20254 } break;
20255 case 'y': {
20256 unsigned int h = width;
20257 for (unsigned int s=1; h && s<nb_scales; ++s) h/=2;
20258 for (h=h?h:1; h<=height; h*=2) res.draw_image(res.get_crop(0,0,width-1,h-1).get_haar('y',true,1),0);
20259 } break;
20260 case 'z': {
20261 unsigned int d = depth;
20262 for (unsigned int s=1; d && s<nb_scales; ++s) d/=2;
20263 for (d=d?d:1; d<=depth; d*=2) res.draw_image(res.get_crop(0,0,0,width-1,height-1,d-1).get_haar('z',true,1),0);
20264 } break;
20265 default: throw CImgArgumentException("CImg<%s>::haar() : Unknown axis '%c'.",pixel_type(),axis); break;
20266 }
20267 } else {
20268 res = get_haar(axis,false,1);
20269 switch (cimg::uncase(axis)) {
20270 case 'x': {
20271 for (unsigned int s=1, w=width/2; w && s<nb_scales; ++s, w/=2) res.draw_image(res.get_crop(0,w-1).get_haar('x',false,1),0);
20272 } break;
20273 case 'y': {
20274 for (unsigned int s=1, h=height/2; h && s<nb_scales; ++s, h/=2) res.draw_image(res.get_crop(0,0,width-1,h-1).get_haar('y',false,1),0);
20275 } break;
20276 case 'z': {
20277 for (unsigned int s=1, d=depth/2; d && s<nb_scales; ++s, d/=2) res.draw_image(res.get_crop(0,0,0,width-1,height-1,d-1).get_haar('z',false,1),0);
20278 } break;
20279 default: throw CImgArgumentException("CImg<%s>::haar() : Unknown axis '%c'.",pixel_type(),axis); break;
20280 }
20281 }
20282 }
20283 return res;
20284 }
20285
20287 CImg<T>& haar(const char axis, const bool inverse=false, const unsigned int nb_scales=1) {
20288 return get_haar(axis,inverse,nb_scales).assign_to(*this);
20289 }
20290
20292
20296 CImg<typename cimg::superset<T,float>::type> get_haar(const bool inverse=false, const unsigned int nb_scales=1) const {
20297 typedef typename cimg::superset<T,float>::type ftype;
20298 CImg<ftype> res;
20299
20300 if (nb_scales==1) {
20301 if (width>1) get_haar('x',inverse,1).assign_to(res);
20302 if (height>1) { if (res) res.get_haar('y',inverse,1).assign_to(res); else get_haar('y',inverse,1).assign_to(res); }
20303 if (depth>1) { if (res) res.get_haar('z',inverse,1).assign_to(res); else get_haar('z',inverse,1).assign_to(res); }
20304 if (res) return res;
20305 } else {
20306 if (inverse) {
20307 res.assign(*this);
20308 if (width>1) {
20309 if (height>1) {
20310 if (depth>1) {
20311 unsigned int w = width, h = height, d = depth; for (unsigned int s=1; w && h && d && s<nb_scales; ++s) { w/=2; h/=2; d/=2; }
20312 for (w=w?w:1, h=h?h:1, d=d?d:1; w<=width && h<=height && d<=depth; w*=2, h*=2, d*=2)
20313 res.draw_image(res.get_crop(0,0,0,w-1,h-1,d-1).get_haar(true,1),0,0,0);
20314 } else {
20315 unsigned int w = width, h = height; for (unsigned int s=1; w && h && s<nb_scales; ++s) { w/=2; h/=2; }
20316 for (w=w?w:1, h=h?h:1; w<=width && h<=height; w*=2, h*=2)
20317 res.draw_image(res.get_crop(0,0,0,w-1,h-1,0).get_haar(true,1),0,0,0);
20318 }
20319 } else {
20320 if (depth>1) {
20321 unsigned int w = width, d = depth; for (unsigned int s=1; w && d && s<nb_scales; ++s) { w/=2; d/=2; }
20322 for (w=w?w:1, d=d?d:1; w<=width && d<=depth; w*=2, d*=2)
20323 res.draw_image(res.get_crop(0,0,0,w-1,0,d-1).get_haar(true,1),0,0,0);
20324 } else {
20325 unsigned int w = width; for (unsigned int s=1; w && s<nb_scales; ++s) w/=2;
20326 for (w=w?w:1; w<=width; w*=2)
20327 res.draw_image(res.get_crop(0,0,0,w-1,0,0).get_haar(true,1),0,0,0);
20328 }
20329 }
20330 } else {
20331 if (height>1) {
20332 if (depth>1) {
20333 unsigned int h = height, d = depth; for (unsigned int s=1; h && d && s<nb_scales; ++s) { h/=2; d/=2; }
20334 for (h=h?h:1, d=d?d:1; h<=height && d<=depth; h*=2, d*=2)
20335 res.draw_image(res.get_crop(0,0,0,0,h-1,d-1).get_haar(true,1),0,0,0);
20336 } else {
20337 unsigned int h = height; for (unsigned int s=1; h && s<nb_scales; ++s) h/=2;
20338 for (h=h?h:1; h<=height; h*=2)
20339 res.draw_image(res.get_crop(0,0,0,0,h-1,0).get_haar(true,1),0,0,0);
20340 }
20341 } else {
20342 if (depth>1) {
20343 unsigned int d = depth; for (unsigned int s=1; d && s<nb_scales; ++s) d/=2;
20344 for (d=d?d:1; d<=depth; d*=2)
20345 res.draw_image(res.get_crop(0,0,0,0,0,d-1).get_haar(true,1),0,0,0);
20346 } else return *this;
20347 }
20348 }
20349 } else {
20350 res = get_haar(false,1);
20351 if (width>1) {
20352 if (height>1) {
20353 if (depth>1) for (unsigned int s=1, w=width/2, h=height/2, d=depth/2; w && h && d && s<nb_scales; ++s, w/=2, h/=2, d/=2)
20354 res.draw_image(res.get_crop(0,0,0,w-1,h-1,d-1).haar(false,1),0,0,0);
20355 else for (unsigned int s=1, w=width/2, h=height/2; w && h && s<nb_scales; ++s, w/=2, h/=2)
20356 res.draw_image(res.get_crop(0,0,0,w-1,h-1,0).haar(false,1),0,0,0);
20357 } else {
20358 if (depth>1) for (unsigned int s=1, w=width/2, d=depth/2; w && d && s<nb_scales; ++s, w/=2, d/=2)
20359 res.draw_image(res.get_crop(0,0,0,w-1,0,d-1).haar(false,1),0,0,0);
20360 else for (unsigned int s=1, w=width/2; w && s<nb_scales; ++s, w/=2)
20361 res.draw_image(res.get_crop(0,0,0,w-1,0,0).haar(false,1),0,0,0);
20362 }
20363 } else {
20364 if (height>1) {
20365 if (depth>1) for (unsigned int s=1, h=height/2, d=depth/2; h && d && s<nb_scales; ++s, h/=2, d/=2)
20366 res.draw_image(res.get_crop(0,0,0,0,h-1,d-1).haar(false,1),0,0,0);
20367 else for (unsigned int s=1, h=height/2; h && s<nb_scales; ++s, h/=2)
20368 res.draw_image(res.get_crop(0,0,0,0,h-1,0).haar(false,1),0,0,0);
20369 } else {
20370 if (depth>1) for (unsigned int s=1, d=depth/2; d && s<nb_scales; ++s, d/=2)
20371 res.draw_image(res.get_crop(0,0,0,0,0,d-1).haar(false,1),0,0,0);
20372 else return *this;
20373 }
20374 }
20375 }
20376 return res;
20377 }
20378 return *this;
20379 }
20380
20382 CImg<T>& haar(const bool inverse=false, const unsigned int nb_scales=1) {
20383 return get_haar(inverse,nb_scales).assign_to(*this);
20384 }
20385
20387 CImg<typename cimg::superset<T,float>::type> get_displacement_field(const CImg<T>& reference,
20388 const float smooth=0.1f, const float precision=1e-6f,
20389 const unsigned int nb_scale=0,
20390 const unsigned int itermax=10000) const {
20391
20392 typedef typename cimg::superset<T,float>::type ftype;
20393 if (is_empty() || !reference) return *this;
20394 if (!is_sameXYZ(reference))
20395 throw CImgArgumentException("CImg<%s>::get_displacement_field() : Instance image (%u,%u,%u,%u,%p) and reference image (%u,%u,%u,%u,%p) "
20396 "must have same dimensions",
20397 pixel_type(),width,height,depth,dim,data,
20398 reference.width,reference.height,reference.depth,reference.dim,reference.data);
20399 const bool threed = depth>1;
20400 CImg<ftype> u(width,height,depth,threed?3:2,0);
20401
20402 const unsigned int nbs = nb_scale>0?nb_scale:(unsigned int)(2*std::log((double)(cimg::max(width,height,depth))));
20403 for (int scale=nbs-1; scale>=0; --scale) {
20404 const float fact = (float)std::pow(1.5f,-(float)scale);
20405 const unsigned int
20406 tnw = (unsigned int)(width*fact), nw = tnw?tnw:1,
20407 tnh = (unsigned int)(height*fact), nh = tnh?tnh:1,
20408 tnd = (unsigned int)(depth*fact), nd = tnd?tnd:1;
20409 CImg<ftype>
20410 I1 = get_resize(nw,nh,nd,1,3),
20411 I2 = reference.get_resize(nw,nh,nd,1,3);
20412 I1.norm_pointwise(1);
20413 I2.norm_pointwise(2);
20414 float m1, M1 = (float)I1.maxmin(m1), m2, M2 = (float)I2.maxmin(m2);
20415 const float M = cimg::max(cimg::abs(m1),cimg::abs(M1),cimg::abs(m2),cimg::abs(M2));
20416 I1/=M; I2/=M;
20417 u*=1.5;
20418 u.resize(nw,nh,nd,threed?3:2,3);
20419 float dt = 100, E = cimg::type<float>::max(), nprecision = nw*nh*nd*precision;
20420 const CImgList<ftype> dI = threed?I2.get_gradientXYZ():I2.get_gradientXY();
20421
20422 for (unsigned int iter=0; iter<itermax; ++iter) {
20423 const float Eold = E;
20424 E = 0;
20425 if (threed)
20426 cimg_for3XYZ(u,x,y,z) {
20427 const ftype
20428 X = x + u(x,y,z,0),
20429 Y = y + u(x,y,z,1),
20430 Z = z + u(x,y,z,2),
20431 deltaI = (ftype)(I2.linear_pix3d(X,Y,Z) - I1(x,y,z));
20432 float tmpf = 0;
20433 cimg_forV(u,k) {
20434 const ftype
20435 ux = 0.5f*(u(_n1x,y,z,k) - u(_p1x,y,z,k)),
20436 uy = 0.5f*(u(x,_n1y,z,k) - u(x,_p1y,z,k)),
20437 uz = 0.5f*(u(x,y,_n1z,k) - u(x,y,_p1z,k));
20438 u(x,y,z,k) = (ftype)( u(x,y,z,k) +
20439 dt*(-deltaI*dI[k].linear_pix3d(X,Y,Z) +
20440 smooth* ( u(_n1x,y,z,k) + u(_p1x,y,z,k) + u(x,_n1y,z,k) + u(x,_p1y,z,k) + u(x,y,_n1z,k) + u(x,y,_p1z,k)))
20441 )/(1 + 6*smooth*dt);
20442 tmpf += (float)(ux*ux + uy*uy + uz*uz);
20443 }
20444 E += deltaI*deltaI + smooth * tmpf;
20445 }
20446 else cimg_for3XY(u,x,y) {
20447 const ftype
20448 X = x + u(x,y,0),
20449 Y = y + u(x,y,1),
20450 deltaI = (ftype)(I2.linear_pix2d(X,Y) - I1(x,y));
20451 float tmpf = 0;
20452 cimg_forV(u,k) {
20453 const ftype
20454 ux = 0.5f*(u(_n1x,y,k) - u(_p1x,y,k)),
20455 uy = 0.5f*(u(x,_n1y,k) - u(x,_p1y,k));
20456 u(x,y,k) = (ftype)( u(x,y,k) +
20457 dt*(-deltaI*dI[k].linear_pix2d(X,Y) + smooth* ( u(_n1x,y,k) + u(_p1x,y,k) + u(x,_n1y,k) + u(x,_p1y,k) ))
20458 )/(1 + 4*smooth*dt);
20459 tmpf += (float)(ux*ux + uy*uy);
20460 }
20461 E += deltaI*deltaI + smooth * tmpf;
20462 }
20463 if (cimg::abs(Eold-E)<nprecision) break;
20464 if (Eold<E) { dt/=2; if (dt<0.1) break; }
20465 }
20466 }
20467 return u;
20468 }
20469
20471 CImg<T>& displacement_field(const CImg<T>& reference, const float smooth=0.1f, const float precision=1e-6f,
20472 const unsigned int nb_scale=0, const unsigned int itermax=10000) {
20473 return get_displacement_field(reference,smooth,precision,nb_scale,itermax).assign_to(*this);
20474 }
20475
20477
20478
20480
20481
20482
20484 static CImg<T> vector(const T a0) {
20485 static CImg<T> r(1,1); r[0] = a0;
20486 return r;
20487 }
20488
20490 static CImg<T> vector(const T a0, const T a1) {
20491 static CImg<T> r(1,2); T *ptr = r.data;
20492 *(ptr++) = a0; *(ptr++) = a1;
20493 return r;
20494 }
20495
20497 static CImg<T> vector(const T a0, const T a1, const T a2) {
20498 static CImg<T> r(1,3); T *ptr = r.data;
20499 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2;
20500 return r;
20501 }
20502
20504 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3) {
20505 static CImg<T> r(1,4); T *ptr = r.data;
20506 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
20507 return r;
20508 }
20509
20511 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3, const T a4) {
20512 static CImg<T> r(1,5); T *ptr = r.data;
20513 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4;
20514 return r;
20515 }
20516
20518 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5) {
20519 static CImg<T> r(1,6); T *ptr = r.data;
20520 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5;
20521 return r;
20522 }
20523
20525 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20526 const T a4, const T a5, const T a6) {
20527 static CImg<T> r(1,7); T *ptr = r.data;
20528 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6;
20529 return r;
20530 }
20531
20533 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20534 const T a4, const T a5, const T a6, const T a7) {
20535 static CImg<T> r(1,8); T *ptr = r.data;
20536 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20537 return r;
20538 }
20539
20541 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20542 const T a4, const T a5, const T a6, const T a7, const T a8) {
20543 static CImg<T> r(1,9); T *ptr = r.data;
20544 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20545 *(ptr++) = a8;
20546 return r;
20547 }
20548
20550 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20551 const T a4, const T a5, const T a6, const T a7,
20552 const T a8, const T a9) {
20553 static CImg<T> r(1,10); T *ptr = r.data;
20554 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20555 *(ptr++) = a8; *(ptr++) = a9;
20556 return r;
20557 }
20558
20560 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20561 const T a4, const T a5, const T a6, const T a7,
20562 const T a8, const T a9, const T a10) {
20563 static CImg<T> r(1,11); T *ptr = r.data;
20564 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20565 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10;
20566 return r;
20567 }
20568
20570 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20571 const T a4, const T a5, const T a6, const T a7,
20572 const T a8, const T a9, const T a10, const T a11) {
20573 static CImg<T> r(1,12); T *ptr = r.data;
20574 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20575 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
20576 return r;
20577 }
20578
20580 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20581 const T a4, const T a5, const T a6, const T a7,
20582 const T a8, const T a9, const T a10, const T a11,
20583 const T a12) {
20584 static CImg<T> r(1,13); T *ptr = r.data;
20585 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20586 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12;
20587 return r;
20588 }
20589
20591 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20592 const T a4, const T a5, const T a6, const T a7,
20593 const T a8, const T a9, const T a10, const T a11,
20594 const T a12, const T a13) {
20595 static CImg<T> r(1,14); T *ptr = r.data;
20596 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20597 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13;
20598 return r;
20599 }
20600
20602 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20603 const T a4, const T a5, const T a6, const T a7,
20604 const T a8, const T a9, const T a10, const T a11,
20605 const T a12, const T a13, const T a14) {
20606 static CImg<T> r(1,15); T *ptr = r.data;
20607 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20608 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14;
20609 return r;
20610 }
20611
20613 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20614 const T a4, const T a5, const T a6, const T a7,
20615 const T a8, const T a9, const T a10, const T a11,
20616 const T a12, const T a13, const T a14, const T a15) {
20617 static CImg<T> r(1,16); T *ptr = r.data;
20618 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20619 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15;
20620 return r;
20621 }
20622
20624 template<int N> static CImg<T> vector(const int a0, const int a1, ...) {
20625 CImg<T> res(1,N);
20626 _CImg_stdarg(res,a0,a1,N,int);
20627 return res;
20628 }
20629
20631 template<int N> static CImg<T> vector(const double a0, const double a1, ...) {
20632 CImg<T> res(1,N);
20633 _CImg_stdarg(res,a0,a1,N,double);
20634 return res;
20635 }
20636
20638 static CImg<T> matrix(const T a0) {
20639 return vector(a0);
20640 }
20641
20643 static CImg<T> matrix(const T a0, const T a1,
20644 const T a2, const T a3) {
20645 static CImg<T> r(2,2); T *ptr = r.data;
20646 *(ptr++) = a0; *(ptr++) = a1;
20647 *(ptr++) = a2; *(ptr++) = a3;
20648 return r;
20649 }
20650
20652 static CImg<T> matrix(const T a0, const T a1, const T a2,
20653 const T a3, const T a4, const T a5,
20654 const T a6, const T a7, const T a8) {
20655 static CImg<T> r(3,3); T *ptr = r.data;
20656 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2;
20657 *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5;
20658 *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8;
20659 return r;
20660 }
20661
20663 static CImg<T> matrix(const T a0, const T a1, const T a2, const T a3,
20664 const T a4, const T a5, const T a6, const T a7,
20665 const T a8, const T a9, const T a10, const T a11,
20666 const T a12, const T a13, const T a14, const T a15) {
20667 static CImg<T> r(4,4); T *ptr = r.data;
20668 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
20669 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20670 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
20671 *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15;
20672 return r;
20673 }
20674
20676 static CImg<T> matrix(const T a0, const T a1, const T a2, const T a3, const T a4,
20677 const T a5, const T a6, const T a7, const T a8, const T a9,
20678 const T a10, const T a11, const T a12, const T a13, const T a14,
20679 const T a15, const T a16, const T a17, const T a18, const T a19,
20680 const T a20, const T a21, const T a22, const T a23, const T a24) {
20681 static CImg<T> r(5,5); T *ptr = r.data;
20682 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4;
20683 *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9;
20684 *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14;
20685 *(ptr++) = a15; *(ptr++) = a16; *(ptr++) = a17; *(ptr++) = a18; *(ptr++) = a19;
20686 *(ptr++) = a20; *(ptr++) = a21; *(ptr++) = a22; *(ptr++) = a23; *(ptr++) = a24;
20687 return r;
20688 }
20689
20691 template<int M,int N> static CImg<T> matrix(const int a0, const int a1, ...) {
20692 CImg<T> res(M,N);
20693 _CImg_stdarg(res,a0,a1,M*N,int);
20694 return res;
20695 }
20696
20698 template<int M,int N> static CImg<T> matrix(const double a0, const double a1, ...) {
20699 CImg<T> res(M,N);
20700 _CImg_stdarg(res,a0,a1,M*N,double);
20701 return res;
20702 }
20703
20705 static CImg<T> tensor(const T a1) {
20706 return matrix(a1);
20707 }
20708
20710 static CImg<T> tensor(const T a1, const T a2, const T a3) {
20711 return matrix(a1,a2,a2,a3);
20712 }
20713
20715 static CImg<T> tensor(const T a1, const T a2, const T a3, const T a4, const T a5, const T a6) {
20716 return matrix(a1,a2,a3,a2,a4,a5,a3,a5,a6);
20717 }
20718
20720 static CImg<T> diagonal(const T a0) {
20721 return matrix(a0);
20722 }
20723
20725 static CImg<T> diagonal(const T a0, const T a1) {
20726 return matrix(a0,0,0,a1);
20727 }
20728
20730 static CImg<T> diagonal(const T a0, const T a1, const T a2) {
20731 return matrix(a0,0,0,0,a1,0,0,0,a2);
20732 }
20733
20735 static CImg<T> diagonal(const T a0, const T a1, const T a2, const T a3) {
20736 return matrix(a0,0,0,0,0,a1,0,0,0,0,a2,0,0,0,0,a3);
20737 }
20738
20740 static CImg<T> diagonal(const T a0, const T a1, const T a2, const T a3, const T a4) {
20741 return matrix(a0,0,0,0,0,0,a1,0,0,0,0,0,a2,0,0,0,0,0,a3,0,0,0,0,0,a4);
20742 }
20743
20745 template<int N> static CImg<T> diagonal(const int a0, ...) {
20746 CImg<T> res;
20747 if (N>0) {
20748 res.assign(N,N,1,1,0);
20749 va_list ap;
20750 va_start(ap,a0);
20751 res[0] = (T)a0;
20752 for (int i=1; i<N; ++i) res(i,i) = (T)va_arg(ap,int);
20753 va_end(ap);
20754 }
20755 return res;
20756 }
20757
20759 template<int N> static CImg<T> diagonal(const double a0, ...) {
20760 CImg<T> res;
20761 if (N>0) {
20762 res.assign(N,N,1,1,0);
20763 va_list ap;
20764 va_start(ap,a0);
20765 res[0] = (T)a0;
20766 for (int i=1; i<N; ++i) res(i,i) = (T)va_arg(ap,double);
20767 va_end(ap);
20768 }
20769 return res;
20770 }
20771
20773 static CImg<T> identity_matrix(const unsigned int N) {
20774 CImg<T> res(N,N,1,1,0);
20775 cimg_forX(res,x) res(x,x) = 1;
20776 return res;
20777 }
20778
20780 static CImg<T> sequence(const unsigned int N, const T a0, const T a1) {
20781 if (N) return CImg<T>(1,N).sequence(a0,a1);
20782 return CImg<T>();
20783 }
20784
20786 static CImg<T> rotation_matrix(const float x, const float y, const float z, const float w, const bool quaternion_data=false) {
20787 float X,Y,Z,W;
20788 if (!quaternion_data) {
20789 const float norm = (float)std::sqrt(x*x + y*y + z*z),
20790 nx = norm>0?x/norm:0,
20791 ny = norm>0?y/norm:0,
20792 nz = norm>0?z/norm:1,
20793 nw = norm>0?w:0,
20794 sina = (float)std::sin(nw/2),
20795 cosa = (float)std::cos(nw/2);
20796 X = nx*sina;
20797 Y = ny*sina;
20798 Z = nz*sina;
20799 W = cosa;
20800 } else {
20801 const float norm = (float)std::sqrt(x*x + y*y + z*z + w*w);
20802 if (norm>0) { X = x/norm; Y = y/norm; Z = z/norm; W = w/norm; }
20803 else { X = Y = Z = 0; W = 1; }
20804 }
20805 const float xx = X*X, xy = X*Y, xz = X*Z, xw = X*W, yy = Y*Y, yz = Y*Z, yw = Y*W, zz = Z*Z, zw = Z*W;
20806 return CImg<T>::matrix((T)(1-2*(yy+zz)), (T)(2*(xy+zw)), (T)(2*(xz-yw)),
20807 (T)(2*(xy-zw)), (T)(1-2*(xx+zz)), (T)(2*(yz+xw)),
20808 (T)(2*(xz+yw)), (T)(2*(yz-xw)), (T)(1-2*(xx+yy)));
20809 }
20810
20812 CImg<T> get_vector_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const {
20813 static CImg<T> dest;
20814 if (dest.height!=dim) dest.assign(1,dim);
20815 const unsigned int whz = width*height*depth;
20816 const T *ptrs = ptr(x,y,z);
20817 T *ptrd = dest.data;
20818 cimg_forV(*this,k) { *(ptrd++) = *ptrs; ptrs+=whz; }
20819 return dest;
20820 }
20821
20823 template<typename t> CImg<T>& set_vector_at(const CImg<t>& vec, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) {
20824 if (x<width && y<height && z<depth) {
20825 const unsigned int whz = width*height*depth;
20826 const t *ptrs = vec.data;
20827 T *ptrd = ptr(x,y,z);
20828 for (unsigned int k=cimg::min((unsigned int)vec.size(),dim); k; --k) { *ptrd = (T)*(ptrs++); ptrd+=whz; }
20829 }
20830 return *this;
20831 }
20832
20834 CImg<T> get_matrix_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const {
20835 const int n = (int)std::sqrt((double)dim);
20836 CImg<T> dest(n,n);
20837 cimg_forV(*this,k) dest[k]=(*this)(x,y,z,k);
20838 return dest;
20839 }
20840
20842 template<typename t> CImg<T>& set_matrix_at(const CImg<t>& mat, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) {
20843 return set_vector_at(mat,x,y,z);
20844 }
20845
20847 CImg<T> get_tensor_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const {
20848 if (dim==6) return tensor((*this)(x,y,z,0),(*this)(x,y,z,1),(*this)(x,y,z,2),
20849 (*this)(x,y,z,3),(*this)(x,y,z,4),(*this)(x,y,z,5));
20850 if (dim==3) return tensor((*this)(x,y,z,0),(*this)(x,y,z,1),(*this)(x,y,z,2));
20851 return tensor((*this)(x,y,z,0));
20852 }
20853
20855 template<typename t> CImg<T>& set_tensor_at(const CImg<t>& ten, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) {
20856 if (ten.height==2) {
20857 (*this)(x,y,z,0) = (T)ten[0];
20858 (*this)(x,y,z,1) = (T)ten[1];
20859 (*this)(x,y,z,2) = (T)ten[3];
20860 }
20861 else {
20862 (*this)(x,y,z,0) = (T)ten[0];
20863 (*this)(x,y,z,1) = (T)ten[1];
20864 (*this)(x,y,z,2) = (T)ten[2];
20865 (*this)(x,y,z,3) = (T)ten[4];
20866 (*this)(x,y,z,4) = (T)ten[5];
20867 (*this)(x,y,z,5) = (T)ten[8];
20868 }
20869 return *this;
20870 }
20871
20873 CImg<T> get_vector() const {
20874 return get_unroll('y');
20875 }
20876
20878 CImg<T>& vector() {
20879 return unroll('y');
20880 }
20881
20883 CImg<T> get_matrix() const {
20884 return (+*this).matrix();
20885 }
20886
20888 CImg<T>& matrix() {
20889 const unsigned int siz = size();
20890 switch (siz) {
20891 case 1: break;
20892 case 4: width = height = 2; break;
20893 case 9: width = height = 3; break;
20894 case 16: width = height = 4; break;
20895 case 25: width = height = 5; break;
20896 case 36: width = height = 6; break;
20897 case 49: width = height = 7; break;
20898 case 64: width = height = 8; break;
20899 case 81: width = height = 9; break;
20900 case 100: width = height = 10; break;
20901 default: {
20902 unsigned int i = 11, i2 = i*i;
20903 while (i2<siz) { i2+=2*i+1; ++i; }
20904 if (i2==siz) width = height = i;
20905 else throw CImgInstanceException("CImg<%s>::matrix() : Image size = %u is not a square number",pixel_type(),siz);
20906 } break;
20907 }
20908 return *this;
20909 }
20910
20912 CImg<T> get_tensor() const {
20913 CImg<T> res;
20914 const unsigned int siz = size();
20915 switch (siz) {
20916 case 1: break;
20917 case 3:
20918 res.assign(2,2);
20919 res(0,0) = (*this)(0);
20920 res(1,0) = res(0,1) = (*this)(1);
20921 res(1,1) = (*this)(2);
20922 break;
20923 case 6:
20924 res.assign(3,3);
20925 res(0,0) = (*this)(0);
20926 res(1,0) = res(0,1) = (*this)(1);
20927 res(2,0) = res(0,2) = (*this)(2);
20928 res(1,1) = (*this)(3);
20929 res(2,1) = res(1,2) = (*this)(4);
20930 res(2,2) = (*this)(5);
20931 break;
20932 default:
20933 throw CImgInstanceException("CImg<%s>::tensor() : Wrong vector dimension = %u in instance image.",
20934 pixel_type(), dim);
20935 break;
20936 }
20937 return res;
20938 }
20939
20941 CImg<T>& tensor() {
20942 return get_tensor().assign_to(*this);
20943 }
20944
20946 CImg<T> get_unroll(const char axe='x') const {
20947 return (+*this).unroll(axe);
20948 }
20949
20951 CImg<T>& unroll(const char axe='x') {
20952 const unsigned int siz = size();
20953 if (siz) switch (axe) {
20954 case 'x': width = siz; height=depth=dim=1; break;
20955 case 'y': height = siz; width=depth=dim=1; break;
20956 case 'z': depth = siz; width=height=dim=1; break;
20957 case 'v': dim = siz; width=height=depth=1; break;
20958 default: throw CImgArgumentException("CImg<%s>::unroll() : Given axe is '%c' which is not 'x','y','z' or 'v'",
20959 pixel_type(),axe);
20960 }
20961 return *this;
20962 }
20963
20965 CImg<T> get_diagonal() const {
20966 if (is_empty()) return CImg<T>();
20967 CImg<T> res(size(),size(),1,1,0);
20968 cimg_foroff(*this,off) res(off,off) = (*this)(off);
20969 return res;
20970 }
20971
20973 CImg<T>& diagonal() {
20974 return get_diagonal().assign_to(*this);
20975 }
20976
20978 CImg<T> get_identity_matrix() const {
20979 return identity_matrix(cimg::max(width,height));
20980 }
20981
20983 CImg<T>& identity_matrix() {
20984 return identity_matrix(cimg::max(width,height)).assign_to(*this);
20985 }
20986
20988 CImg<T> get_sequence(const T a0, const T a1) const {
20989 return (+*this).sequence(a0,a1);
20990 }
20991
20993 CImg<T>& sequence(const T a0, const T a1) {
20994 if (!is_empty()) {
20995 const unsigned int siz = size()-1;
20996 const float delta = (float)((float)a1-a0);
20997 T* ptr = data;
20998 cimg_foroff(*this,l) *(ptr++) = (T)(a0 + delta*l/siz);
20999 }
21000 return *this;
21001 }
21002
21004 CImg<T> get_transpose() const {
21005 return get_permute_axes("yxzv");
21006 }
21007
21009 CImg<T>& transpose() {
21010 if (width==1) { width=height; height=1; return *this; }
21011 if (height==1) { height=width; width=1; return *this; }
21012 if (width==height) {
21013 cimg_forYZV(*this,y,z,v) for (int x=y; x<dimx(); ++x) cimg::swap((*this)(x,y,z,v),(*this)(y,x,z,v));
21014 return *this;
21015 }
21016 return get_transpose().assign_to(*this);
21017 }
21018
21020 CImg<typename cimg::superset<T,float>::type> get_inverse(const bool use_LU=true) const {
21021 typedef typename cimg::superset<T,float>::type restype;
21022 return CImg<restype>(*this,false).inverse(use_LU);
21023 }
21024
21026 CImg<T>& inverse(const bool use_LU=true) {
21027 if (!is_empty()) {
21028 if (width!=height || depth!=1 || dim!=1)
21029 throw CImgInstanceException("CImg<%s>::inverse() : Instance matrix (%u,%u,%u,%u,%p) is not square.",
21030 pixel_type(),width,height,depth,dim,data);
21031 #ifdef cimg_use_lapack
21032 typedef typename cimg::superset<T,float>::type ftype;
21033 int INFO = (int)use_LU, N = width, LWORK = 4*N, *IPIV = new int[N];
21034 ftype
21035 *lapA = new ftype[N*N],
21036 *WORK = new ftype[LWORK];
21037 cimg_forXY(*this,k,l) lapA[k*N+l] = (ftype)((*this)(k,l));
21038 cimg::getrf(N,lapA,IPIV,INFO);
21039 if (INFO) cimg::warn("CImg<%s>::inverse() : LAPACK library function dgetrf_() returned error code %d.",pixel_type(),INFO);
21040 else {
21041 cimg::getri(N,lapA,IPIV,WORK,LWORK,INFO);
21042 if (INFO) cimg::warn("CImg<%s>::inverse() : LAPACK library function dgetri_() returned Error code %d",pixel_type(),INFO);
21043 }
21044 if (!INFO) cimg_forXY(*this,k,l) (*this)(k,l) = (T)(lapA[k*N+l]); else fill(0);
21045 delete[] IPIV; delete[] lapA; delete[] WORK;
21046 #else
21047 const double dete = width>3?-1.0:det();
21048 if (dete!=0.0 && width==2) {
21049 const double
21050 a = data[0], c = data[1],
21051 b = data[2], d = data[3];
21052 data[0] = (T)(d/dete); data[1] = (T)(-c/dete);
21053 data[2] = (T)(-b/dete); data[3] = (T)(a/dete);
21054 } else if (dete!=0.0 && width==3) {
21055 const double
21056 a = data[0], d = data[1], g = data[2],
21057 b = data[3], e = data[4], h = data[5],
21058 c = data[6], f = data[7], i = data[8];
21059 data[0] = (T)((i*e-f*h)/dete), data[1] = (T)((g*f-i*d)/dete), data[2] = (T)((d*h-g*e)/dete);
21060 data[3] = (T)((h*c-i*b)/dete), data[4] = (T)((i*a-c*g)/dete), data[5] = (T)((g*b-a*h)/dete);
21061 data[6] = (T)((b*f-e*c)/dete), data[7] = (T)((d*c-a*f)/dete), data[8] = (T)((a*e-d*b)/dete);
21062 } else {
21063 typedef typename cimg::superset<float,T>::type ftype;
21064 if (use_LU) {
21065 CImg<ftype> A(*this), indx, col(1,width);
21066 bool d;
21067 A._LU(indx,d);
21068 cimg_forX(*this,j) {
21069 col.fill(0);
21070 col(j) = 1;
21071 col._solve(A,indx);
21072 cimg_forX(*this,i) (*this)(j,i) = (T)col(i);
21073 }
21074 } else {
21075 CImg<ftype> U(width,width), S(1,width), V(width,width);
21076 SVD(U,S,V,false);
21077 U.transpose();
21078 cimg_forY(S,k) if (S[k]!=0) S[k]=1/S[k];
21079 S.diagonal();
21080 *this = V*S*U;
21081 }
21082 }
21083 #endif
21084 }
21085 return *this;
21086 }
21087
21089 CImg<typename cimg::superset<T,float>::type> get_pseudoinverse() const {
21090 typedef typename cimg::superset<T,float>::type restype;
21091 CImg<restype> U, S, V;
21092 SVD(U,S,V);
21093 cimg_forX(V,x) {
21094 const float s = S(x), invs = s!=0.0f?1.0f/s:0.0f;
21095 cimg_forY(V,y) V(x,y)*=invs;
21096 }
21097 return V*U.transpose();
21098 }
21099
21101 CImg<T>& pseudoinverse() {
21102 return get_pseudoinverse().assign_to(*this);
21103 }
21104
21106 template<typename t> CImg<typename cimg::superset<T,t>::type> get_cross(const CImg<t>& img) const {
21107 typedef typename cimg::superset<T,t>::type restype;
21108 return CImg<restype>(*this).cross(img);
21109 }
21110
21112 template<typename t> CImg<T>& cross(const CImg<t>& img) {
21113 if (width!=1 || height<3 || img.width!=1 || img.height<3)
21114 throw CImgInstanceException("CImg<%s>::cross() : Arguments (%u,%u,%u,%u,%p) and (%u,%u,%u,%u,%p) must be both 3d vectors.",
21115 pixel_type(),width,height,depth,dim,data,img.width,img.height,img.depth,img.dim,img.data);
21116 const T x = (*this)[0], y = (*this)[1], z = (*this)[2];
21117 (*this)[0] = (T)(y*img[2]-z*img[1]);
21118 (*this)[1] = (T)(z*img[0]-x*img[2]);
21119 (*this)[2] = (T)(x*img[1]-y*img[0]);
21120 return *this;
21121 }
21122
21124 template<typename t> CImg<typename cimg::superset2<T,t,float>::type> get_solve(const CImg<t>& A) const {
21125 typedef typename cimg::superset2<T,t,float>::type restype;
21126 return CImg<restype>(*this,false).solve(A);
21127 }
21128
21130 template<typename t> CImg<T>& solve(const CImg<t>& A) {
21131 if (width!=1 || depth!=1 || dim!=1 || height!=A.height || A.depth!=1 || A.dim!=1)
21132 throw CImgArgumentException("CImg<%s>::solve() : Instance matrix size is (%u,%u,%u,%u) while "
21133 "size of given matrix A is (%u,%u,%u,%u).",
21134 pixel_type(),width,height,depth,dim,A.width,A.height,A.depth,A.dim);
21135
21136 typedef typename cimg::superset2<T,t,float>::type ftype;
21137 if (A.width==A.height) {
21138 #ifdef cimg_use_lapack
21139 char TRANS='N';
21140 int INFO, N = height, LWORK = 4*N, one = 1, *IPIV = new int[N];
21141 ftype
21142 *lapA = new ftype[N*N],
21143 *lapB = new ftype[N],
21144 *WORK = new ftype[LWORK];
21145 cimg_forXY(A,k,l) lapA[k*N+l] = (ftype)(A(k,l));
21146 cimg_forY(*this,i) lapB[i] = (ftype)((*this)(i));
21147 cimg::getrf(N,lapA,IPIV,INFO);
21148 if (INFO) cimg::warn("CImg<%s>::solve() : LAPACK library function dgetrf_() returned error code %d.",pixel_type(),INFO);
21149 if (!INFO) {
21150 cimg::getrs(TRANS,N,lapA,IPIV,lapB,INFO);
21151 if (INFO) cimg::warn("CImg<%s>::solve() : LAPACK library function dgetrs_() returned Error code %d",pixel_type(),INFO);
21152 }
21153 if (!INFO) cimg_forY(*this,i) (*this)(i) = (T)(lapB[i]); else fill(0);
21154 delete[] IPIV; delete[] lapA; delete[] lapB; delete[] WORK;
21155 #else
21156 CImg<ftype> lu(A);
21157 CImg<ftype> indx;
21158 bool d;
21159 lu._LU(indx,d);
21160 _solve(lu,indx);
21161 #endif
21162 } else assign(A.get_pseudoinverse()*(*this));
21163 return *this;
21164 }
21165
21166 template<typename t, typename ti> CImg<T>& _solve(const CImg<t>& A, const CImg<ti>& indx) {
21167 typedef typename cimg::superset2<T,t,float>::type ftype;
21168 const int N = size();
21169 int ii = -1;
21170 ftype sum;
21171 for (int i=0; i<N; ++i) {
21172 const int ip = (int)indx[i];
21173 ftype sum = (*this)(ip);
21174 (*this)(ip) = (*this)(i);
21175 if (ii>=0) for (int j=ii; j<=i-1; ++j) sum-=A(j,i)*(*this)(j);
21176 else if (sum!=0) ii=i;
21177 (*this)(i) = (T)sum;
21178 }
21179 { for (int i=N-1; i>=0; --i) {
21180 sum = (*this)(i);
21181 for (int j=i+1; j<N; ++j) sum-=A(j,i)*(*this)(j);
21182 (*this)(i) = (T)(sum/A(i,i));
21183 }}
21184 return *this;
21185 }
21186
21188 template<typename t> CImg<T> get_sort(CImg<t>& permutations, const bool increasing=true) const {
21189 return (+*this).sort(permutations,increasing);
21190 }
21191
21193 template<typename t>
21194 CImg<T>& sort(CImg<t>& permutations, const bool increasing=true) {
21195 if (is_empty()) permutations.assign();
21196 else {
21197 if (permutations.size()!=size()) permutations.assign(size());
21198 cimg_foroff(permutations,off) permutations[off] = (t)off;
21199 _quicksort(0,size()-1,permutations,increasing);
21200 }
21201 return *this;
21202 }
21203
21204
21205 CImg<T> get_sort(const bool increasing=true) const {
21206 return (+*this).sort(increasing);
21207 }
21208
21210 CImg<T>& sort(const bool increasing=true) {
21211 CImg<T> foo;
21212 return sort(foo,increasing);
21213 }
21214
21215 template<typename t> CImg<T>& _quicksort(const int min, const int max, CImg<t>& permutations, const bool increasing) {
21216 if (min<max) {
21217 const int mid = (min+max)/2;
21218 if (increasing) {
21219 if ((*this)[min]>(*this)[mid]) {
21220 cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
21221 if ((*this)[mid]>(*this)[max]) {
21222 cimg::swap((*this)[max],(*this)[mid]); cimg::swap(permutations[max],permutations[mid]); }
21223 if ((*this)[min]>(*this)[mid]) {
21224 cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
21225 } else {
21226 if ((*this)[min]<(*this)[mid]) {
21227 cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
21228 if ((*this)[mid]<(*this)[max]) {
21229 cimg::swap((*this)[max],(*this)[mid]); cimg::swap(permutations[max],permutations[mid]); }
21230 if ((*this)[min]<(*this)[mid]) {
21231 cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
21232 }
21233 if (max-min>=3) {
21234 const T pivot = (*this)[mid];
21235 int i = min, j = max;
21236 if (increasing) {
21237 do {
21238 while ((*this)[i]<pivot) ++i;
21239 while ((*this)[j]>pivot) --j;
21240 if (i<=j) {
21241 cimg::swap((*this)[i],(*this)[j]);
21242 cimg::swap(permutations[i++],permutations[j--]);
21243 }
21244 } while (i<=j);
21245 } else {
21246 do {
21247 while ((*this)[i]>pivot) ++i;
21248 while ((*this)[j]<pivot) --j;
21249 if (i<=j) {
21250 cimg::swap((*this)[i],(*this)[j]);
21251 cimg::swap(permutations[i++],permutations[j--]);
21252 }
21253 } while (i<=j);
21254 }
21255 if (min<j) _quicksort(min,j,permutations,increasing);
21256 if (i<max) _quicksort(i,max,permutations,increasing);
21257 }
21258 }
21259 return *this;
21260 }
21261
21263 template<typename t> CImg<T> get_permute(const CImg<t>& permutation) const {
21264 if (permutation.size()!=size())
21265 throw CImgArgumentException("CImg<%s>::permute() : Instance image (%u,%u,%u,%u,%p) and permutation (%u,%u,%u,%u,%p)"
21266 "have different sizes.",pixel_type(),
21267 width,height,depth,dim,data,
21268 permutation.width,permutation.height,permutation.depth,permutation.dim,permutation.data);
21269 CImg<T> res(width,height,depth,dim);
21270 const t *p = permutation.ptr(permutation.size());
21271 cimg_for(res,ptr,T) *ptr = (*this)[*(--p)];
21272 return res;
21273 }
21274
21276 template<typename t> CImg<T>& permute(const CImg<t>& permutation) {
21277 return get_permute(permutation).assign_to(*this);
21278 }
21279
21281 template<typename t> const CImg<T>& SVD(CImg<t>& U, CImg<t>& S, CImg<t>& V,
21282 const bool sorting=true, const unsigned int max_iter=40, const float lambda=0) const {
21283 if (is_empty()) { U.assign(); S.assign(); V.assign(); }
21284 else {
21285 #ifdef cimg_use_lapack
21286 typedef typename cimg::superset<T,float>::type ftype;
21287 int M = height, N = width, mn = cimg::min(M,N), MN = cimg::max(M,N), LWORK = 4*mn+2*MN, INFO;
21288 char JOB='A';
21289 ftype
21290 *lapA = new ftype[M*N],
21291 *lapS = new ftype[mn],
21292 *lapU = new ftype[M*M],
21293 *lapV = new ftype[N*N],
21294 *WORK = new ftype[LWORK];
21295 cimg_forXY(*this,k,l) lapA[k*N+l] = (ftype)((*this)(k,l));
21296 cimg::gesvd(JOB,M,N,lapA,MN,lapS,lapU,lapV,WORK,LWORK,INFO);
21297 if (INFO) cimg::warn("CImg<%s>::SVD() : LAPACK library function gesvd_() returned error code %d.",pixel_type(),INFO);
21298 U.assign(M,M);
21299 S.assign(1,mn);
21300 V.assign(N,N);
21301 if (!INFO) {
21302 cimg_forY(S,i) S(i) = (T)(lapS[i]);
21303 cimg_forXY(U,p,q) U(p,q) = (T)(lapU[p*N+q]);
21304 cimg_forXY(V,k,l) V(l,k) = (T)(lapV[k*N+l]);
21305 } else { S.fill(0); U.fill(0); V.fill(0); }
21306 delete[] lapA; delete[] lapS; delete[] lapU; delete[] lapV; delete[] WORK;
21307 #else
21308 U = *this;
21309 if (lambda!=0.0f) {
21310 const unsigned int delta = cimg::min(U.width,U.height);
21311 for (unsigned int i=0; i<delta; ++i) U(i,i) = (t)(U(i,i) + lambda);
21312 }
21313 if (S.size()<width) S.assign(1,width);
21314 if (V.width<width || V.height<height) V.assign(width,width);
21315 CImg<t> rv1(width);
21316 t anorm = 0, c, f, g = 0, h, s, scale = 0;
21317 int l = 0, nm = 0;
21318
21319 cimg_forX(U,i) {
21320 l = i+1; rv1[i] = scale*g; g = s = scale = 0;
21321 if (i<dimy()) {
21322 for (int k=i; k<dimy(); ++k) scale+= cimg::abs(U(i,k));
21323 if (scale) {
21324 for (int k=i; k<dimy(); ++k) { U(i,k)/=scale; s+= U(i,k)*U(i,k); }
21325 f = U(i,i); g = (t)((f>=0?-1:1)*std::sqrt(s)); h=f*g-s; U(i,i) = f-g;
21326 for (int j=l; j<dimx(); ++j) {
21327 s = 0; for (int k=i; k<dimy(); ++k) s+= U(i,k)*U(j,k);
21328 f = s/h;
21329 { for (int k=i; k<dimy(); ++k) U(j,k)+= f*U(i,k); }
21330 }
21331 { for (int k=i; k<dimy(); ++k) U(i,k)*= scale; }
21332 }
21333 }
21334 S[i]=scale*g;
21335
21336 g = s = scale = 0;
21337 if (i<dimy() && i!=dimx()-1) {
21338 for (int k=l; k<dimx(); ++k) scale += cimg::abs(U(k,i));
21339 if (scale) {
21340 for (int k=l; k<dimx(); ++k) { U(k,i)/= scale; s+= U(k,i)*U(k,i); }
21341 f = U(l,i); g = (t)((f>=0?-1:1)*std::sqrt(s)); h = f*g-s; U(l,i) = f-g;
21342 { for (int k=l; k<dimx(); ++k) rv1[k]=U(k,i)/h; }
21343 for (int j=l; j<dimy(); ++j) {
21344 s = 0; for (int k=l; k<dimx(); ++k) s+= U(k,j)*U(k,i);
21345 { for (int k=l; k<dimx(); ++k) U(k,j)+= s*rv1[k]; }
21346 }
21347 { for (int k=l; k<dimx(); ++k) U(k,i)*= scale; }
21348 }
21349 }
21350 anorm = (t)cimg::max((float)anorm,(float)(cimg::abs(S[i])+cimg::abs(rv1[i])));
21351 }
21352
21353 { for (int i=dimx()-1; i>=0; --i) {
21354 if (i<dimx()-1) {
21355 if (g) {
21356 { for (int j=l; j<dimx(); ++j) V(i,j) =(U(j,i)/U(l,i))/g; }
21357 for (int j=l; j<dimx(); ++j) {
21358 s = 0; for (int k=l; k<dimx(); ++k) s+= U(k,i)*V(j,k);
21359 { for (int k=l; k<dimx(); ++k) V(j,k)+= s*V(i,k); }
21360 }
21361 }
21362 for (int j=l; j<dimx(); ++j) V(j,i) = V(i,j) = (t)0.0;
21363 }
21364 V(i,i) = (t)1.0; g = rv1[i]; l = i;
21365 }
21366 }
21367
21368 { for (int i=cimg::min(dimx(),dimy())-1; i>=0; --i) {
21369 l = i+1; g = S[i];
21370 for (int j=l; j<dimx(); ++j) U(j,i) = 0;
21371 if (g) {
21372 g = 1/g;
21373 for (int j=l; j<dimx(); ++j) {
21374 s = 0; for (int k=l; k<dimy(); ++k) s+= U(i,k)*U(j,k);
21375 f = (s/U(i,i))*g;
21376 { for (int k=i; k<dimy(); ++k) U(j,k)+= f*U(i,k); }
21377 }
21378 { for (int j=i; j<dimy(); ++j) U(i,j)*= g; }
21379 } else for (int j=i; j<dimy(); ++j) U(i,j) = 0;
21380 ++U(i,i);
21381 }
21382 }
21383
21384 for (int k=dimx()-1; k>=0; --k) {
21385 for (unsigned int its=0; its<max_iter; ++its) {
21386 bool flag = true;
21387 for (l=k; l>=1; --l) {
21388 nm = l-1;
21389 if ((cimg::abs(rv1[l])+anorm)==anorm) { flag = false; break; }
21390 if ((cimg::abs(S[nm])+anorm)==anorm) break;
21391 }
21392 if (flag) {
21393 c = 0; s = 1;
21394 for (int i=l; i<=k; ++i) {
21395 f = s*rv1[i]; rv1[i] = c*rv1[i];
21396 if ((cimg::abs(f)+anorm)==anorm) break;
21397 g = S[i]; h = (t)cimg::pythagore(f,g); S[i] = h; h = 1/h; c = g*h; s = -f*h;
21398 cimg_forY(U,j) { const t y = U(nm,j), z = U(i,j); U(nm,j) = y*c+z*s; U(i,j) = z*c-y*s; }
21399 }
21400 }
21401 const t z = S[k];
21402 if (l==k) { if (z<0) { S[k] = -z; cimg_forX(U,j) V(k,j) = -V(k,j); } break; }
21403 nm = k-1;
21404 t x = S[l], y = S[nm];
21405 g = rv1[nm]; h = rv1[k];
21406 f = ((y-z)*(y+z)+(g-h)*(g+h))/(2*h*y);
21407 g = (t)cimg::pythagore(f,1.0);
21408 f = ((x-z)*(x+z)+h*((y/(f+ (f>=0?g:-g)))-h))/x;
21409 c = s = 1;
21410 for (int j=l; j<=nm; ++j) {
21411 const int i = j+1;
21412 g = rv1[i]; h = s*g; g = c*g;
21413 t y = S[i];
21414 t z = (t)cimg::pythagore(f,h);
21415 rv1[j] = z; c = f/z; s = h/z;
21416 f = x*c+g*s; g = g*c-x*s; h = y*s; y*=c;
21417 cimg_forX(U,jj) { const t x = V(j,jj), z = V(i,jj); V(j,jj) = x*c+z*s; V(i,jj) = z*c-x*s; }
21418 z = (t)cimg::pythagore(f,h); S[j] = z;
21419 if (z) { z = 1/z; c = f*z; s = h*z; }
21420 f = c*g+s*y; x = c*y-s*g;
21421 { cimg_forY(U,jj) { const t y = U(j,jj); z = U(i,jj); U(j,jj) = y*c+z*s; U(i,jj) = z*c-y*s; }}
21422 }
21423 rv1[l] = 0; rv1[k]=f; S[k]=x;
21424 }
21425 }
21426
21427 if (sorting) {
21428 CImg<int> permutations(width);
21429 CImg<t> tmp(width);
21430 S.sort(permutations,false);
21431 cimg_forY(U,k) {
21432 cimg_forX(permutations,x) tmp(x) = U(permutations(x),k);
21433 std::memcpy(U.ptr(0,k),tmp.data,sizeof(t)*width);
21434 }
21435 { cimg_forY(V,k) {
21436 cimg_forX(permutations,x) tmp(x) = V(permutations(x),k);
21437 std::memcpy(V.ptr(0,k),tmp.data,sizeof(t)*width);
21438 }}
21439 }
21440 #endif
21441 }
21442 return *this;
21443 }
21444
21446 template<typename t> const CImg<T>& SVD(CImgList<t>& USV) const {
21447 if (USV.size<3) USV.assign(3);
21448 return SVD(USV[0],USV[1],USV[2]);
21449 }
21450
21452 CImgList<typename cimg::superset<T,float>::type> get_SVD(const bool sorting=true) const {
21453 typedef typename cimg::superset<T,float>::type restype;
21454 CImgList<restype> res(3);
21455 SVD(res[0],res[1],res[2],sorting);
21456 return res;
21457 }
21458
21459
21460 template<typename t> CImg<T>& _LU(CImg<t>& indx, bool& d) {
21461 typedef typename cimg::superset<T,float>::type ftype;
21462 const int N = dimx();
21463 int imax = 0;
21464 CImg<ftype> vv(N);
21465 indx.assign(N);
21466 d = true;
21467 cimg_forX(*this,i) {
21468 ftype vmax = 0;
21469 cimg_forX(*this,j) {
21470 const ftype tmp = cimg::abs((*this)(j,i));
21471 if (tmp>vmax) vmax = tmp;
21472 }
21473 if (vmax==0) { indx.fill(0); return fill(0); }
21474 vv[i] = 1/vmax;
21475 }
21476 cimg_forX(*this,j) {
21477 for (int i=0; i<j; ++i) {
21478 ftype sum=(*this)(j,i);
21479 for (int k=0; k<i; ++k) sum-=(*this)(k,i)*(*this)(j,k);
21480 (*this)(j,i) = (T)sum;
21481 }
21482 ftype vmax = 0;
21483 { for (int i=j; i<dimx(); ++i) {
21484 ftype sum=(*this)(j,i);
21485 for (int k=0; k<j; ++k) sum-=(*this)(k,i)*(*this)(j,k);
21486 (*this)(j,i) = (T)sum;
21487 const ftype tmp = vv[i]*cimg::abs(sum);
21488 if (tmp>=vmax) { vmax=tmp; imax=i; }
21489 }}
21490 if (j!=imax) {
21491 cimg_forX(*this,k) cimg::swap((*this)(k,imax),(*this)(k,j));
21492 d =!d;
21493 vv[imax] = vv[j];
21494 }
21495 indx[j] = (t)imax;
21496 if ((*this)(j,j)==0) (*this)(j,j) = (T)1e-20;
21497 if (j<N) {
21498 const ftype tmp = 1/(ftype)(*this)(j,j);
21499 for (int i=j+1; i<N; ++i) (*this)(j,i) = (T)((*this)(j,i)*tmp);
21500 }
21501 }
21502 return *this;
21503 }
21504
21506 CImgList<typename cimg::superset<T,float>::type> get_eigen() const {
21507 typedef typename cimg::superset<T,float>::type restype;
21508 CImgList<restype> res(2);
21509 eigen(res[0],res[1]);
21510 return res;
21511 }
21512
21514 template<typename t> const CImg<T>& eigen(CImg<t>& val, CImg<t> &vec) const {
21515 if (is_empty()) { val.assign(); vec.assign(); }
21516 else {
21517 if (width!=height || depth>1 || dim>1)
21518 throw CImgInstanceException("CImg<%s>::eigen() : Instance object (%u,%u,%u,%u,%p) is empty.",
21519 pixel_type(),width,height,depth,dim,data);
21520 if (val.size()<width) val.assign(1,width);
21521 if (vec.size()<width*width) vec.assign(width,width);
21522 switch(width) {
21523 case 1: { val[0]=(t)(*this)[0]; vec[0]=(t)1; } break;
21524 case 2: {
21525 const double a = (*this)[0], b = (*this)[1], c = (*this)[2], d = (*this)[3], e = a+d;
21526 double f = e*e-4*(a*d-b*c);
21527 if (f<0) cimg::warn("CImg<%s>::eigen() : Complex eigenvalues",pixel_type());
21528 f = std::sqrt(f);
21529 const double l1 = 0.5*(e-f), l2 = 0.5*(e+f);
21530 const double theta1 = std::atan2(l2-a,b), theta2 = std::atan2(l1-a,b);
21531 val[0]=(t)l2;
21532 val[1]=(t)l1;
21533 vec(0,0) = (t)std::cos(theta1);
21534 vec(0,1) = (t)std::sin(theta1);
21535 vec(1,0) = (t)std::cos(theta2);
21536 vec(1,1) = (t)std::sin(theta2);
21537 } break;
21538 default:
21539 throw CImgInstanceException("CImg<%s>::eigen() : Eigenvalues computation of general matrices is limited"
21540 "to 2x2 matrices (given is %ux%u)", pixel_type(),width,height);
21541 }
21542 }
21543 return *this;
21544 }
21545
21547 CImgList<typename cimg::superset<T,float>::type> get_symmetric_eigen() const {
21548 typedef typename cimg::superset<T,float>::type restype;
21549 CImgList<restype> res(2);
21550 symmetric_eigen(res[0],res[1]);
21551 return res;
21552 }
21553
21555 template<typename t> const CImg<T>& symmetric_eigen(CImg<t>& val, CImg<t>& vec) const {
21556 if (is_empty()) { val.assign(); vec.assign(); }
21557 else {
21558 #ifdef cimg_use_lapack
21559 typedef typename cimg::superset<T,float>::type ftype;
21560 char JOB = 'V', UPLO = 'U';
21561 int N = width, LWORK = 4*N, INFO;
21562 ftype
21563 *lapA = new ftype[N*N],
21564 *lapW = new ftype[N],
21565 *WORK = new ftype[LWORK];
21566 cimg_forXY(*this,k,l) lapA[k*N+l] = (ftype)((*this)(k,l));
21567 cimg::syev(JOB,UPLO,N,lapA,lapW,WORK,LWORK,INFO);
21568 if (INFO) cimg::warn("CImg<%s>::symmetric_eigen() : LAPACK library function dsyev_() returned error code %d.",pixel_type(),INFO);
21569 val.assign(1,N); vec.assign(N,N);
21570 if (!INFO) {
21571 cimg_forY(val,i) val(i) = (T)lapW[N-1-i];
21572 cimg_forXY(vec,k,l) vec(k,l) = (T)(lapA[(N-1-k)*N+l]);
21573 } else { val.fill(0); vec.fill(0); }
21574 delete[] lapA; delete[] lapW; delete[] WORK;
21575 #else
21576 if (width!=height || depth>1 || dim>1)
21577 throw CImgInstanceException("CImg<%s>::eigen() : Instance object (%u,%u,%u,%u,%p) is empty.",
21578 pixel_type(),width,height,depth,dim,data);
21579 if (val.size()<width) val.assign(1,width);
21580 if (vec.data && vec.size()<width*width) vec.assign(width,width);
21581 if (width<3) return eigen(val,vec);
21582 CImg<t> V(width,width);
21583 SVD(vec,val,V,false);
21584 bool ambiguous = false;
21585 float eig = 0;
21586 cimg_forY(val,p) {
21587 if (val[p]>eig) eig = val[p];
21588 t scal = 0;
21589 cimg_forY(vec,y) scal+=vec(p,y)*V(p,y);
21590 if (cimg::abs(scal)<0.9f) ambiguous = true;
21591 if (scal<0) val[p] = -val[p];
21592 }
21593 if (ambiguous) {
21594 (eig*=2)++;
21595 SVD(vec,val,V,false,40,eig);
21596 val-=eig;
21597 }
21598 CImg<int> permutations(width);
21599 CImg<t> tmp(width);
21600 val.sort(permutations,false);
21601 cimg_forY(vec,k) {
21602 cimg_forX(permutations,x) tmp(x) = vec(permutations(x),k);
21603 std::memcpy(vec.ptr(0,k),tmp.data,sizeof(t)*width);
21604 }
21605 #endif
21606 }
21607 return *this;
21608 }
21609
21611
21612
21614
21615
21616
21618 const CImg<T>& display(CImgDisplay& disp) const {
21619 disp.display(*this);
21620 return *this;
21621 }
21622
21626 const CImg<T>& display(const char *const title, const int min_size=128, const int max_size=1024,
21627 const int print_flag=1) const {
21628 if (is_empty())
21629 throw CImgInstanceException("CImg<%s>::display() : Instance image (%u,%u,%u,%u,%p) is empty.",
21630 pixel_type(),width,height,depth,dim,data);
21631 CImgDisplay disp;
21632 unsigned int w = width+(depth>1?depth:0), h = height+(depth>1?depth:0), XYZ[3];
21633 print(title,print_flag);
21634 const unsigned int dmin = cimg::min(w,h), minsiz = min_size>=0?min_size:(-min_size)*dmin/100;
21635 if (dmin<minsiz) { w=w*minsiz/dmin; w+=(w==0); h=h*minsiz/dmin; h+=(h==0); }
21636 const unsigned int dmax = cimg::max(w,h), maxsiz = max_size>=0?max_size:(-max_size)*dmax/100;
21637 if (dmax>maxsiz) { w=w*maxsiz/dmax; w+=(w==0); h=h*maxsiz/dmax; h+=(h==0); }
21638 disp.assign(w,h,title,1,3);
21639 XYZ[0] = width/2; XYZ[1] = height/2; XYZ[2] = depth/2;
21640 while (!disp.is_closed && !disp.key) get_coordinates(1,disp,XYZ);
21641 return *this;
21642 }
21643
21645 const CImg<T>& display(const int min_size=128, const int max_size=1024, const int print_flag=1) const {
21646 char title[256] = { 0 };
21647 std::sprintf(title,"CImg<%s>",pixel_type());
21648 return display(title,min_size,max_size,print_flag);
21649 }
21650
21652
21659 CImg<typename cimg::last<T,int>::type> get_coordinates(const int coords_type, CImgDisplay &disp,
21660 unsigned int *const XYZ=0, const unsigned char *const color=0) const {
21661
21662 if (is_empty()) throw CImgInstanceException("CImg<%s>::get_coordinates() : Instance image (%u,%u,%u,%u,%p) is empty.",
21663 pixel_type(),width,height,depth,dim,data);
21664 const unsigned int
21665 old_events = disp.events,
21666 old_normalization = disp.normalization,
21667 hatch = 0x55555555;
21668
21669 bool old_is_resized = disp.is_resized;
21670 disp.events = 3;
21671 disp.normalization = 0;
21672 disp.show().key = 0;
21673
21674 unsigned char fgcolor[] = { 255,255,105 }, bgcolor[] = { 0,0,0 };
21675 if (color) std::memcpy(fgcolor,color,sizeof(unsigned char)*cimg::min(3,dimv()));
21676
21677 int area = 0, clicked_area = 0, phase = 0,
21678 X0 = (int)((XYZ?XYZ[0]:width/2)%width), Y0 = (int)((XYZ?XYZ[1]:height/2)%height), Z0 = (int)((XYZ?XYZ[2]:depth/2)%depth),
21679 X1 =-1, Y1 = -1, Z1 = -1,
21680 X = -1, Y = -1, Z = -1,
21681 oX = X, oY = Y, oZ = Z;
21682 unsigned int old_button = 0, key = 0;
21683
21684 bool shape_selected = false, text_down = false;
21685 CImg<unsigned char> visu, visu0;
21686 char text[1024] = { 0 };
21687
21688 while (!key && !disp.is_closed && !shape_selected) {
21689
21690
21691 oX = X; oY = Y; oZ = Z;
21692 int mx = disp.mouse_x, my = disp.mouse_y;
21693 const int mX = mx*(width+(depth>1?depth:0))/disp.width, mY = my*(height+(depth>1?depth:0))/disp.height;
21694
21695 area = 0;
21696 if (mX<dimx() && mY<dimy()) { area = 1; X = mX; Y = mY; Z = phase?Z1:Z0; }
21697 if (mX<dimx() && mY>=dimy()) { area = 2; X = mX; Z = mY-height; Y = phase?Y1:Y0; }
21698 if (mX>=dimx() && mY<dimy()) { area = 3; Y = mY; Z = mX-width; X = phase?X1:X0; }
21699
21700 key = disp.key;
21701 if (key && key!=cimg::keyCTRLLEFT) {
21702 if (disp.is_key(cimg::keyCTRLLEFT,true)) {
21703 switch (key) {
21704 case cimg::keyARROWLEFT:
21705 case cimg::keyARROWDOWN: --disp.wheel; break;
21706 case cimg::keyARROWRIGHT:
21707 case cimg::keyARROWUP: ++disp.wheel; break;
21708 case cimg::keyD: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-200,-200); disp.is_resized = true; break;
21709 case cimg::keyC: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-50,-50); disp.is_resized = true; break;
21710 case cimg::keyR: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(*this); disp.is_resized = true; break;
21711 case cimg::keyF:
21712 disp.resize(disp.screen_dimx(),disp.screen_dimy()).toggle_fullscreen();
21713 disp.is_resized = true;
21714 break;
21715 case cimg::keyS: {
21716 static unsigned int snap_number = 0;
21717 char filename[32] = { 0 };
21718 std::FILE *file;
21719 do {
21720 std::sprintf(filename,"CImg_%.4u.bmp",snap_number++);
21721 if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
21722 } while (file);
21723 if (visu0) {
21724 visu.draw_text(2,2,fgcolor,bgcolor,11,0.8f,"Saving snapshot...").display(disp);
21725 visu0.save(filename);
21726 visu.draw_text(2,2,fgcolor,bgcolor,11,0.8f,"Snapshot '%s' saved.",filename).display(disp);
21727 }
21728 } break;
21729 case cimg::keyO: {
21730 static unsigned int snap_number = 0;
21731 char filename[32] = { 0 };
21732 std::FILE *file;
21733 do {
21734 std::sprintf(filename,"CImg_%.4u.cimg",snap_number++);
21735 if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
21736 } while (file);
21737 visu.draw_text(2,2,fgcolor,bgcolor,11,0.8f,"Saving instance...").display(disp);
21738 save(filename);
21739 visu.draw_text(2,2,fgcolor,bgcolor,11,0.8f,"Instance '%s' saved.",filename).display(disp);
21740 } break;
21741 default: break;
21742 }
21743 key = disp.key = 0;
21744 }
21745 } else key = 0;
21746
21747 if (!area) mx = my = X = Y = Z = -1;
21748 else {
21749 if (disp.button&1 && phase<2) { X1 = X; Y1 = Y; Z1 = Z; }
21750 if (!(disp.button&1) && phase>=2) {
21751 switch (clicked_area) {
21752 case 1: Z1 = Z; break;
21753 case 2: Y1 = Y; break;
21754 case 3: X1 = X; break;
21755 }
21756 }
21757 if (disp.button&2) { if (phase) { X1 = X; Y1 = Y; Z1 = Z; } else { X0 = X; Y0 = Y; Z0 = Z; } }
21758 if (disp.button&4) { oX = X = X0; oY = Y = Y0; oZ = Z = Z0; phase = 0; visu.assign(); }
21759 if (disp.wheel) {
21760 switch (area) {
21761 case 1: if (phase) Z = (Z1+=disp.wheel); else Z = (Z0+=disp.wheel); break;
21762 case 2: if (phase) Y = (Y1+=disp.wheel); else Y = (Y0+=disp.wheel); break;
21763 case 3: if (phase) X = (X1+=disp.wheel); else X = (X0+=disp.wheel); break;
21764 default: break;
21765 }
21766 disp.wheel = 0;
21767 }
21768 if ((disp.button&1)!=old_button) {
21769 switch (phase++) {
21770 case 0: X0 = X1 = X; Y0 = Y1 = Y; Z0 = Z1 = Z; clicked_area = area; break;
21771 case 1: X1 = X; Y1 = Y; Z1 = Z; break;
21772 default: break;
21773 }
21774 old_button = disp.button&1;
21775 }
21776 if (depth>1 && (X!=oX || Y!=oY || Z!=oZ)) visu0.assign();
21777 }
21778
21779 if (phase) {
21780 if (!coords_type) shape_selected = phase?true:false;
21781 else {
21782 if (depth>1) shape_selected = (phase==3)?true:false;
21783 else shape_selected = (phase==2)?true:false;
21784 }
21785 }
21786
21787 if (X0<0) X0 = 0; if (X0>=dimx()) X0 = dimx()-1; if (Y0<0) Y0 = 0; if (Y0>=dimy()) Y0 = dimy()-1;
21788 if (Z0<0) Z0 = 0; if (Z0>=dimz()) Z0 = dimz()-1;
21789 if (X1<1) X1 = 0; if (X1>=dimx()) X1 = dimx()-1; if (Y1<0) Y1 = 0; if (Y1>=dimy()) Y1 = dimy()-1;
21790 if (Z1<0) Z1 = 0; if (Z1>=dimz()) Z1 = dimz()-1;
21791
21792
21793 if (oX!=X || oY!=Y || oZ!=Z || !visu0) {
21794 if (!visu0) {
21795 CImg<T> tmp0 = get_shared_channels(0,cimg::min(2U,dim-1)), tmp;
21796 if (depth!=1) tmp = (!phase?tmp0.get_projections2d(X0,Y0,Z0):tmp0.get_projections2d(X1,Y1,Z1)).resize(disp.width,disp.height,1,3);
21797 else tmp = tmp0.get_resize(disp.width,disp.height,1,3);
21798 if (old_normalization) {
21799 if (old_normalization<3 || cimg::type<T>::is_float()) {
21800 if (sizeof(T)>1) visu0.assign(tmp.normalize(0,(T)255));
21801 else visu0.assign(tmp).normalize(0,255);
21802 } else {
21803 if (cimg::type<T>::string()!=cimg::type<unsigned char>::string()) {
21804 const float m = (float)cimg::type<T>::min(), M = (float)cimg::type<T>::max();
21805 visu0.assign((CImg<float>(tmp)-=m)*=255.0f/(M-m));
21806 } else visu0.assign(tmp);
21807 }
21808 } else visu0.assign(tmp);
21809 }
21810 visu = visu0;
21811 if (!color) {
21812 if (visu.mean()<200) { fgcolor[0] = fgcolor[1] = fgcolor[2] = 255; bgcolor[0] = bgcolor[1] = bgcolor[2] = 0; }
21813 else { fgcolor[0] = fgcolor[1] = fgcolor[2] = 0; bgcolor[0] = bgcolor[1] = bgcolor[2] = 255; }
21814 }
21815
21816 const int d=(depth>1)?depth:0;
21817 if (phase) switch (coords_type) {
21818 case 1: {
21819 const int
21820 x0=(int)((X0+0.5f)*disp.width/(width+d)), y0=(int)((Y0+0.5f)*disp.height/(height+d)),
21821 x1=(int)((X1+0.5f)*disp.width/(width+d)), y1=(int)((Y1+0.5f)*disp.height/(height+d));
21822 visu.draw_arrow(x0,y0,x1,y1,fgcolor,30.0f,5.0f,1.0f,hatch);
21823 if (d) {
21824 const int zx0=(int)((width+Z0+0.5f)*disp.width/(width+d)), zx1=(int)((width+Z1+0.5f)*disp.width/(width+d)),
21825 zy0=(int)((height+Z0+0.5f)*disp.height/(height+d)), zy1=(int)((height+Z1+0.5f)*disp.height/(height+d));
21826 visu.draw_arrow(zx0,y0,zx1,y1,fgcolor,30.0f,5.0f,1.0f,hatch).draw_arrow(x0,zy0,x1,zy1,fgcolor,30.0f,5.0f,1.0f,hatch);
21827 }
21828 } break;
21829 case 2: {
21830 const int
21831 x0=(X0<X1?X0:X1)*disp.width/(width+d),
21832 y0=(Y0<Y1?Y0:Y1)*disp.height/(height+d),
21833 x1=((X0<X1?X1:X0)+1)*disp.width/(width+d)-1,
21834 y1=((Y0<Y1?Y1:Y0)+1)*disp.height/(height+d)-1;
21835 visu.draw_rectangle(x0,y0,x1,y1,fgcolor,0.2f).draw_line(x0,y0,x1,y0,fgcolor,1.0f,hatch).
21836 draw_line(x1,y0,x1,y1,fgcolor,1.0f,hatch).draw_line(x1,y1,x0,y1,fgcolor,1.0f,hatch).
21837 draw_line(x0,y1,x0,y0,fgcolor,1.0f,hatch);
21838 if (d) {
21839 const int
21840 zx0=(int)((width+(Z0<Z1?Z0:Z1))*disp.width/(width+d)),
21841 zy0=(int)((height+(Z0<Z1?Z0:Z1))*disp.height/(height+d)),
21842 zx1=(int)((width+(Z0<Z1?Z1:Z0)+1)*disp.width/(width+d))-1,
21843 zy1=(int)((height+(Z0<Z1?Z1:Z0)+1)*disp.height/(height+d))-1;
21844 visu.draw_rectangle(zx0,y0,zx1,y1,fgcolor,0.2f).draw_line(zx0,y0,zx1,y0,fgcolor,1.0f,hatch).
21845 draw_line(zx1,y0,zx1,y1,fgcolor,1.0f,hatch).draw_line(zx1,y1,zx0,y1,fgcolor,1.0f,hatch).
21846 draw_line(zx0,y1,zx0,y0,fgcolor,1.0f,hatch);
21847 visu.draw_rectangle(x0,zy0,x1,zy1,fgcolor,0.2f).draw_line(x0,zy0,x1,zy0,fgcolor,1.0f,hatch).
21848 draw_line(x1,zy0,x1,zy1,fgcolor,1.0f,hatch).draw_line(x1,zy1,x0,zy1,fgcolor,1.0f,hatch).
21849 draw_line(x0,zy1,x0,zy0,fgcolor,1.0f,hatch);
21850 }
21851 } break;
21852 case 3: {
21853 const int
21854 x0=X0*disp.width/(width+d),
21855 y0=Y0*disp.height/(height+d),
21856 x1=X1*disp.width/(width+d)-1,
21857 y1=Y1*disp.height/(height+d)-1;
21858 visu.draw_ellipse(x0,y0,(float)(x1-x0),(float)(y1-y0),1.0f,0.0f,fgcolor,0.2f).
21859 draw_ellipse(x0,y0,(float)(x1-x0),(float)(y1-y0),1.0f,0.0f,fgcolor,1.0f,hatch);
21860 if (d) {
21861 const int
21862 zx0=(int)((width+Z0)*disp.width/(width+d)),
21863 zy0=(int)((height+Z0)*disp.height/(height+d)),
21864 zx1=(int)((width+Z1+1)*disp.width/(width+d))-1,
21865 zy1=(int)((height+Z1+1)*disp.height/(height+d))-1;
21866 visu.draw_ellipse(zx0,y0,(float)(zx1-zx0),(float)(y1-y0),1.0f,0.0f,fgcolor,0.2f).
21867 draw_ellipse(zx0,y0,(float)(zx1-zx0),(float)(y1-y0),1.0f,0.0f,fgcolor,1.0f,hatch).
21868 draw_ellipse(x0,zy0,(float)(x1-x0),(float)(zy1-zy0),1.0f,0.0f,fgcolor,0.2f).
21869 draw_ellipse(x0,zy0,(float)(x1-x0),(float)(zy1-zy0),1.0f,0.0f,fgcolor,1.0f,hatch);
21870 }
21871 } break;
21872 }
21873
21874 if (my<12) text_down = true;
21875 if (my>=visu.dimy()-11) text_down = false;
21876 if (!coords_type || !phase) {
21877 if (X>=0 && Y>=0 && Z>=0 && X<dimx() && Y<dimy() && Z<dimz()) {
21878 if (depth>1) std::sprintf(text,"Point (%d,%d,%d)={ ",X,Y,Z); else std::sprintf(text,"Point (%d,%d)={ ",X,Y);
21879 char *ctext = text + cimg::strlen(text), *const ltext = text + 512;
21880 for (unsigned int k=0; k<dim && ctext<ltext; ++k) {
21881 std::sprintf(ctext,cimg::type<T>::format(),cimg::type<T>::format((*this)(X,Y,Z,k)));
21882 ctext = text + cimg::strlen(text);
21883 *(ctext++) = ' '; *ctext = '\0';
21884 }
21885 std::sprintf(text + cimg::strlen(text),"}");
21886 }
21887 } else switch (coords_type) {
21888 case 1: {
21889 const double dX=(double)(X0-X1), dY=(double)(Y0-Y1), dZ=(double)(Z0-Z1), norm = std::sqrt(dX*dX+dY*dY+dZ*dZ);
21890 if (depth>1) std::sprintf(text,"Vect (%d,%d,%d)-(%d,%d,%d), norm=%g",X0,Y0,Z0,X1,Y1,Z1,norm);
21891 else std::sprintf(text,"Vect (%d,%d)-(%d,%d), norm=%g",X0,Y0,X1,Y1,norm);
21892 } break;
21893 case 2:
21894 if (depth>1) std::sprintf(text,"Box (%d,%d,%d)-(%d,%d,%d), Size=(%d,%d,%d)",
21895 X0<X1?X0:X1,Y0<Y1?Y0:Y1,Z0<Z1?Z0:Z1,
21896 X0<X1?X1:X0,Y0<Y1?Y1:Y0,Z0<Z1?Z1:Z0,
21897 1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1),1+cimg::abs(Z0-Z1));
21898 else std::sprintf(text,"Box (%d,%d)-(%d,%d), Size=(%d,%d)",
21899 X0<X1?X0:X1,Y0<Y1?Y0:Y1,X0<X1?X1:X0,Y0<Y1?Y1:Y0,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1));
21900 break;
21901 default:
21902 if (depth>1) std::sprintf(text,"Ellipse (%d,%d,%d)-(%d,%d,%d), Radii=(%d,%d,%d)",
21903 X0,Y0,Z0,X1,Y1,Z1,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1),1+cimg::abs(Z0-Z1));
21904 else std::sprintf(text,"Ellipse (%d,%d)-(%d,%d), Radii=(%d,%d)",
21905 X0,Y0,X1,Y1,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1));
21906
21907 break;
21908 }
21909 if (phase || (mx>=0 && my>=0)) visu.draw_text(text,0,text_down?visu.dimy()-11:0,fgcolor,bgcolor,11,0.7f);
21910 disp.display(visu).wait(25);
21911 } else disp.wait();
21912
21913 if (disp.is_resized) { disp.resize(false); old_is_resized = true; disp.is_resized = false; visu0.assign(); }
21914 }
21915
21916
21917 typedef typename cimg::last<T,int>::type restype;
21918 CImg<restype> res(1,6,1,1,(restype)-1);
21919 if (XYZ) { XYZ[0] = (unsigned int)X0; XYZ[1] = (unsigned int)Y0; XYZ[2] = (unsigned int)Z0; }
21920 if (shape_selected) {
21921 if (coords_type==2) {
21922 if (X0>X1) cimg::swap(X0,X1);
21923 if (Y0>Y1) cimg::swap(Y0,Y1);
21924 if (Z0>Z1) cimg::swap(Z0,Z1);
21925 }
21926 if (X1<0 || Y1<0 || Z1<0) X0 = Y0 = Z0 = X1 = Y1 = Z1 = -1;
21927 switch(coords_type) {
21928 case 1:
21929 case 2: res[3] = (restype)X1; res[4] = (restype)Y1; res[5] = (restype)Z1;
21930 default: res[0] = (restype)X0; res[1] = (restype)Y0; res[2] = (restype)Z0;
21931 }
21932 }
21933 disp.button = 0;
21934 disp.events = old_events;
21935 disp.normalization = old_normalization;
21936 disp.is_resized = old_is_resized;
21937 disp.key = key;
21938 return res;
21939 }
21940
21942 CImg<typename cimg::last<T,int>::type> get_coordinates(const int coords_type=0,
21943 unsigned int *const XYZ=0, const unsigned char *const color=0) const {
21944 unsigned int w = width + (depth>1?depth:0), h = height + (depth>1?depth:0);
21945 const unsigned int dmin = cimg::min(w,h), minsiz = 256;
21946 if (dmin<minsiz) { w=w*minsiz/dmin; h=h*minsiz/dmin; }
21947 const unsigned int dmax = cimg::max(w,h), maxsiz = 1024;
21948 if (dmax>maxsiz) { w=w*maxsiz/dmax; h=h*maxsiz/dmax; }
21949 CImgDisplay disp(w,h," ",1,3);
21950 return get_coordinates(coords_type,disp,XYZ,color);
21951 }
21952
21953 CImg<T>& coordinates(const int coords_type=0,unsigned int *const XYZ=0, const unsigned char *const color=0) {
21954 return get_coordinates(coords_type,XYZ,color).assign_to(*this);
21955 }
21956
21958 template<typename tp, typename tf, typename tc, typename to>
21959 const CImg<T>& display_object3d(const CImg<tp>& points, const CImgList<tf>& primitives,
21960 const CImgList<tc>& colors, const CImgList<to>& opacities, CImgDisplay& disp,
21961 const bool centering=true,
21962 const int render_static=4, const int render_motion=1,
21963 const bool double_sided=false,
21964 const float focale=500.0f, const float ambient_light=0.05f,
21965 const bool display_axes=true, float *const pose_matrix=0) const {
21966
21967
21968 if (!points || !primitives || !opacities)
21969 throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (%u), primitives (%u) or opacities (%u) are empty.",
21970 pixel_type(),points.size()/3,primitives.size,opacities.size);
21971 if (is_empty())
21972 return CImg<T>(disp.width,disp.height,1,colors[0].size(),0).
21973 display_object3d(points,primitives,colors,opacities,disp,centering,
21974 render_static,render_motion,double_sided,focale,ambient_light,
21975 display_axes,pose_matrix);
21976 if (points.height<3)
21977 return display_object3d(points.get_resize(-100,3,1,1,0),primitives,colors,opacities,disp,
21978 centering,render_static,render_motion,double_sided,focale,ambient_light,
21979 display_axes,pose_matrix);
21980
21981
21982 CImg<float> pose, rot_mat,
21983 centered_points = centering?CImg<float>(points.width,3):CImg<float>(),
21984 rotated_points(points.width,3),
21985 bbox_points, rotated_bbox_points,
21986 axes_points, rotated_axes_points;
21987 CImgList<to> bbox_opacities, axes_opacities;
21988 CImgList<T> bbox_colors, axes_colors;
21989 CImgList<tf> bbox_primitives, axes_primitives;
21990 float nambient = ambient_light, dx = 0, dy = 0, dz = 0, ratio = 1;
21991
21992 T minval = (T)0, maxval = (T)255;
21993 if (disp.normalization) minval = colors.minmax(maxval);
21994 const float meanval = (float)mean();
21995 bool color_model = true;
21996
21997 if (cimg::abs(meanval-minval)>cimg::abs(meanval-maxval)) color_model = false;
21998 const CImg<T>
21999 bgcolor(1,1,1,dim,color_model?minval:maxval),
22000 fgcolor(1,1,1,dim,color_model?maxval:minval);
22001 float
22002 xm, xM = (float)points.get_shared_line(0).maxmin(xm),
22003 ym, yM = (float)points.get_shared_line(1).maxmin(ym),
22004 zm, zM = (float)points.get_shared_line(2).maxmin(zm),
22005 delta = cimg::max(xM-xm,yM-ym,zM-zm);
22006
22007 if (display_axes) {
22008 axes_points.assign(7,3);
22009 rotated_axes_points.assign(7,3);
22010 axes_opacities.assign(3,1,1,1,1,1.0f);
22011 axes_colors.assign(3,dim,1,1,1,fgcolor[0]);
22012 axes_points(0,0) = 0; axes_points(0,1) = 0; axes_points(0,2) = 0;
22013 axes_points(1,0) = 20; axes_points(1,1) = 0; axes_points(1,2) = 0;
22014 axes_points(2,0) = 0; axes_points(2,1) = 20; axes_points(2,2) = 0;
22015 axes_points(3,0) = 0; axes_points(3,1) = 0; axes_points(3,2) = 20;
22016 axes_points(4,0) = 22; axes_points(4,1) = -6; axes_points(4,2) = 0;
22017 axes_points(5,0) = -6; axes_points(5,1) = 22; axes_points(5,2) = 0;
22018 axes_points(6,0) = -6; axes_points(6,1) = -6; axes_points(6,2) = 22;
22019 axes_primitives.insert(CImg<tf>::vector(0,1));
22020 axes_primitives.insert(CImg<tf>::vector(0,2));
22021 axes_primitives.insert(CImg<tf>::vector(0,3));
22022 }
22023
22024
22025 CImg<T> visu0(*this), visu;
22026 bool init = true, clicked = false, redraw = true;
22027 unsigned int key = 0;
22028 int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
22029 const unsigned int old_events = disp.events;
22030 disp.show().button = disp.key = 0;
22031 disp.events = 3;
22032
22033 while (!disp.is_closed && !key) {
22034
22035
22036 if (init) {
22037 ratio = delta>0?(2.0f*cimg::min(disp.width,disp.height)/(3.0f*delta)):0;
22038 dx = 0.5f*(xM+xm); dy = 0.5f*(yM+ym); dz = 0.5f*(zM+zm);
22039 if (centering) {
22040 cimg_forX(centered_points,l) {
22041 centered_points(l,0) = (float)((points(l,0)-dx)*ratio);
22042 centered_points(l,1) = (float)((points(l,1)-dy)*ratio);
22043 centered_points(l,2) = (float)((points(l,2)-dz)*ratio);
22044 }
22045 }
22046
22047 if (render_static<0 || render_motion<0) {
22048 bbox_colors.assign(12,dim,1,1,1,fgcolor[0]);
22049 bbox_primitives.assign(12,1,2);
22050 bbox_points.assign(8,3);
22051 rotated_bbox_points.assign(8,3);
22052 bbox_points(0,0) = xm; bbox_points(0,1) = ym; bbox_points(0,2) = zm;
22053 bbox_points(1,0) = xM; bbox_points(1,1) = ym; bbox_points(1,2) = zm;
22054 bbox_points(2,0) = xM; bbox_points(2,1) = yM; bbox_points(2,2) = zm;
22055 bbox_points(3,0) = xm; bbox_points(3,1) = yM; bbox_points(3,2) = zm;
22056 bbox_points(4,0) = xm; bbox_points(4,1) = ym; bbox_points(4,2) = zM;
22057 bbox_points(5,0) = xM; bbox_points(5,1) = ym; bbox_points(5,2) = zM;
22058 bbox_points(6,0) = xM; bbox_points(6,1) = yM; bbox_points(6,2) = zM;
22059 bbox_points(7,0) = xm; bbox_points(7,1) = yM; bbox_points(7,2) = zM;
22060 bbox_primitives[0].fill(0,1); bbox_primitives[1].fill(1,2); bbox_primitives[2].fill(2,3); bbox_primitives[3].fill(3,0);
22061 bbox_primitives[4].fill(4,5); bbox_primitives[5].fill(5,6); bbox_primitives[6].fill(6,7); bbox_primitives[7].fill(7,4);
22062 bbox_primitives[8].fill(0,4); bbox_primitives[9].fill(1,5); bbox_primitives[10].fill(2,6); bbox_primitives[11].fill(3,7);
22063 bbox_opacities.assign(bbox_primitives.size,1,1,1,1,1.0f);
22064 }
22065
22066 if (!pose) {
22067 if (pose_matrix) pose = CImg<float>(pose_matrix,4,4,1,1,false);
22068 else pose = CImg<float>::identity_matrix(4);
22069 }
22070 init = false;
22071 redraw = true;
22072 }
22073
22074
22075 if (redraw) {
22076 const float
22077 r00 = pose(0,0), r10 = pose(1,0), r20 = pose(2,0), r30 = pose(3,0),
22078 r01 = pose(0,1), r11 = pose(1,1), r21 = pose(2,1), r31 = pose(3,1),
22079 r02 = pose(0,2), r12 = pose(1,2), r22 = pose(2,2), r32 = pose(3,2);
22080 if ((clicked && render_motion>=0) || (!clicked && render_static>=0)) {
22081 if (centering) cimg_forX(centered_points,l) {
22082 const float x = centered_points(l,0), y = centered_points(l,1), z = centered_points(l,2);
22083 rotated_points(l,0) = r00*x + r10*y + r20*z + r30;
22084 rotated_points(l,1) = r01*x + r11*y + r21*z + r31;
22085 rotated_points(l,2) = r02*x + r12*y + r22*z + r32;
22086 } else cimg_forX(points,l) {
22087 const float x = (float)points(l,0), y = (float)points(l,1), z = (float)points(l,2);
22088 rotated_points(l,0) = r00*x + r10*y + r20*z + r30;
22089 rotated_points(l,1) = r01*x + r11*y + r21*z + r31;
22090 rotated_points(l,2) = r02*x + r12*y + r22*z + r32;
22091 }
22092 } else {
22093 if (!centering) cimg_forX(bbox_points,l) {
22094 const float x = bbox_points(l,0), y = bbox_points(l,1), z = bbox_points(l,2);
22095 rotated_bbox_points(l,0) = r00*x + r10*y + r20*z + r30;
22096 rotated_bbox_points(l,1) = r01*x + r11*y + r21*z + r31;
22097 rotated_bbox_points(l,2) = r02*x + r12*y + r22*z + r32;
22098 } else cimg_forX(bbox_points,l) {
22099 const float x = (bbox_points(l,0)-dx)*ratio, y = (bbox_points(l,1)-dy)*ratio, z = (bbox_points(l,2)-dz)*ratio;
22100 rotated_bbox_points(l,0) = r00*x + r10*y + r20*z + r30;
22101 rotated_bbox_points(l,1) = r01*x + r11*y + r21*z + r31;
22102 rotated_bbox_points(l,2) = r02*x + r12*y + r22*z + r32;
22103 }
22104 }
22105
22106
22107 visu = visu0;
22108 if ((clicked && render_motion<0) || (!clicked && render_static<0))
22109 visu.draw_object3d(visu.width/2.0f, visu.height/2.0f, 0,
22110 rotated_bbox_points,bbox_primitives,bbox_colors,bbox_opacities,1,
22111 false,focale,visu.dimx()/2.0f,visu.dimy()/2.0f,-5000.0f,0.2f);
22112 else visu.draw_object3d(visu.width/2.0f, visu.height/2.0f, 0,
22113 rotated_points,primitives,colors,opacities,clicked?render_motion:render_static,
22114 double_sided,focale,visu.dimx()/2.0f,visu.dimy()/2.0f,-5000.0f,nambient);
22115
22116
22117 if (display_axes) {
22118 const float Xaxes = 25.0f, Yaxes = visu.height-35.0f;
22119 cimg_forX(axes_points,l) {
22120 const float x = axes_points(l,0), y = axes_points(l,1), z = axes_points(l,2);
22121 rotated_axes_points(l,0) = r00*x + r10*y + r20*z;
22122 rotated_axes_points(l,1) = r01*x + r11*y + r21*z;
22123 rotated_axes_points(l,2) = r02*x + r12*y + r22*z;
22124 }
22125 axes_opacities(0,0) = (rotated_axes_points(1,2)>0)?0.5f:1.0f;
22126 axes_opacities(1,0) = (rotated_axes_points(2,2)>0)?0.5f:1.0f;
22127 axes_opacities(2,0) = (rotated_axes_points(3,2)>0)?0.5f:1.0f;
22128 visu.draw_object3d(Xaxes,Yaxes,0,rotated_axes_points,axes_primitives,axes_colors,axes_opacities,1,false,focale,0,0,0,0).
22129 draw_text("X",(int)(Xaxes+rotated_axes_points(4,0)), (int)(Yaxes+rotated_axes_points(4,1)), axes_colors[0].data, (T*)0, 11, axes_opacities(0,0)).
22130 draw_text("Y",(int)(Xaxes+rotated_axes_points(5,0)), (int)(Yaxes+rotated_axes_points(5,1)), axes_colors[1].data, (T*)0, 11, axes_opacities(1,0)).
22131 draw_text("Z",(int)(Xaxes+rotated_axes_points(6,0)), (int)(Yaxes+rotated_axes_points(6,1)), axes_colors[2].data, (T*)0, 11, axes_opacities(2,0));
22132 }
22133 visu.display(disp);
22134 if (!clicked || render_motion==render_static) redraw = false;
22135 }
22136
22137
22138 disp.wait();
22139 if ((disp.button || disp.wheel) && disp.mouse_x>=0 && disp.mouse_y>=0) {
22140 redraw = true;
22141 if (!clicked) { x0 = x1 = disp.mouse_x; y0 = y1 = disp.mouse_y; if (!disp.wheel) clicked = true; }
22142 else { x1 = disp.mouse_x; y1 = disp.mouse_y; }
22143 if (disp.button&1) {
22144 const float
22145 R = 0.45f*cimg::min(disp.width,disp.height),
22146 R2 = R*R,
22147 u0 = (float)(x0-disp.dimx()/2),
22148 v0 = (float)(y0-disp.dimy()/2),
22149 u1 = (float)(x1-disp.dimx()/2),
22150 v1 = (float)(y1-disp.dimy()/2),
22151 n0 = (float)std::sqrt(u0*u0+v0*v0),
22152 n1 = (float)std::sqrt(u1*u1+v1*v1),
22153 nu0 = n0>R?(u0*R/n0):u0,
22154 nv0 = n0>R?(v0*R/n0):v0,
22155 nw0 = (float)std::sqrt(cimg::max(0.0f,R2-nu0*nu0-nv0*nv0)),
22156 nu1 = n1>R?(u1*R/n1):u1,
22157 nv1 = n1>R?(v1*R/n1):v1,
22158 nw1 = (float)std::sqrt(cimg::max(0.0f,R2-nu1*nu1-nv1*nv1)),
22159 u = nv0*nw1-nw0*nv1,
22160 v = nw0*nu1-nu0*nw1,
22161 w = nv0*nu1-nu0*nv1,
22162 n = (float)std::sqrt(u*u+v*v+w*w),
22163 alpha = (float)std::asin(n/R2);
22164 rot_mat = CImg<float>::rotation_matrix(u,v,w,alpha);
22165 rot_mat *= pose.get_crop(0,0,2,2);
22166 pose.draw_image(rot_mat,0,0);
22167 x0=x1; y0=y1;
22168 }
22169 if (disp.button&2) { pose(3,2)+=(y1-y0); x0 = x1; y0 = y1; }
22170 if (disp.wheel) { pose(3,2)-=15*disp.wheel; disp.wheel = 0; }
22171 if (disp.button&4) { pose(3,0)+=(x1-x0); pose(3,1)+=(y1-y0); x0 = x1; y0 = y1; }
22172 if ((disp.button&1) && (disp.button&2)) { init = true; disp.button = 0; x0 = x1; y0 = y1; pose = CImg<float>::identity_matrix(4); }
22173 } else if (clicked) { x0 = x1; y0 = y1; clicked = false; redraw = true; }
22174
22175 key = disp.key;
22176 if (key && key!=cimg::keyCTRLLEFT && key!=cimg::keyCTRLRIGHT) {
22177 if (disp.is_key(cimg::keyCTRLLEFT,true) || disp.is_key(cimg::keyCTRLRIGHT,true)) {
22178 switch (key) {
22179 case cimg::keyPAGEDOWN: nambient-=0.1f; if (nambient<-2) nambient = -2; redraw = true; break;
22180 case cimg::keyPAGEUP: nambient+=0.1f; if (nambient>2) nambient = 2; redraw = true; break;
22181 case cimg::keyD: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-200,-200); disp.is_resized = true; break;
22182 case cimg::keyC: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-50,-50); disp.is_resized = true; break;
22183 case cimg::keyR: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(*this); disp.is_resized = true; break;
22184 case cimg::keyF: disp.resize(disp.screen_dimx(),disp.screen_dimy()).toggle_fullscreen().is_resized = true; break;
22185 case cimg::keyS: {
22186 static unsigned int snap_number = 0;
22187 char filename[32] = { 0 };
22188 std::FILE *file;
22189 do {
22190 std::sprintf(filename,"CImg_%.4u.bmp",snap_number++);
22191 if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
22192 } while (file);
22193 (+visu).draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Saving snapshot...",filename).display(disp);
22194 visu.save(filename);
22195 visu.draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Snapshot '%s' saved.",filename).display(disp);
22196 } break;
22197 case cimg::keyO: {
22198 static unsigned int snap_number = 0;
22199 char filename[32] = { 0 };
22200 std::FILE *file;
22201 do {
22202 std::sprintf(filename,"CImg_%.4u.off",snap_number++);
22203 if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
22204 } while (file);
22205 visu.draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Saving object...",filename).display(disp);
22206 points.save_off(filename,primitives,colors);
22207 visu.draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Object '%s' saved.",filename).display(disp);
22208 } break;
22209 }
22210 disp.key = key = 0;
22211 }
22212 } else key = 0;
22213 if (disp.is_resized) { disp.resize(false); visu0 = get_resize(disp,1); redraw = true; }
22214 }
22215 if (pose_matrix) std::memcpy(pose_matrix,pose.data,16*sizeof(float));
22216 disp.events = old_events;
22217 disp.button = 0;
22218 return *this;
22219 }
22220
22222 template<typename tp, typename tf, typename tc, typename to>
22223 const CImg<T>& display_object3d(const CImgList<tp>& points, const CImgList<tf>& primitives,
22224 const CImgList<tc>& colors, const CImgList<to>& opacities, CImgDisplay &disp,
22225 const bool centering=true,
22226 const int render_static=4, const int render_motion=1,
22227 const bool double_sided=false,
22228 const float focale=500.0f, const float ambient_light=0.05f,
22229 const bool display_axes=true, float *const pose_matrix=0) const {
22230 CImg<tp> npoints(points.size,3,1,1,0);
22231 tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
22232 cimg_forX(npoints,l) {
22233 const CImg<tp>& point = points[l];
22234 const unsigned int siz = point.size();
22235 if (!siz)
22236 throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (size=%u) contains a null element at "
22237 "position %u.",pixel_type(),points.size,l);
22238 *(ptrZ++) = (siz>2)?point(2):0;
22239 *(ptrY++) = (siz>1)?point(1):0;
22240 *(ptrX++) = point(0);
22241 }
22242 return display_object3d(npoints,primitives,colors,opacities,disp,centering,
22243 render_static,render_motion,double_sided,focale,ambient_light,
22244 display_axes,pose_matrix);
22245 }
22246
22248 template<typename tp, typename tf, typename tc, typename to>
22249 const CImg<T>& display_object3d(const CImg<tp>& points, const CImgList<tf>& primitives,
22250 const CImgList<tc>& colors, const CImg<to>& opacities, CImgDisplay& disp,
22251 const bool centering=true,
22252 const int render_static=4, const int render_motion=1,
22253 const bool double_sided=false,
22254 const float focale=500.0f, const float ambient_light=0.05f,
22255 const bool display_axes=true, float *const pose_matrix=0) const {
22256 CImgList<to> nopacities(opacities.size(),1);
22257 cimglist_for(nopacities,l) nopacities(l,0) = opacities(l);
22258 return display_object3d(points,primitives,colors,nopacities,disp,centering,
22259 render_static,render_motion,double_sided,focale,ambient_light,
22260 display_axes,pose_matrix);
22261 }
22262
22264 template<typename tp, typename tf, typename tc, typename to>
22265 const CImg<T>& display_object3d(const CImgList<tp>& points, const CImgList<tf>& primitives,
22266 const CImgList<tc>& colors, const CImg<to>& opacities, CImgDisplay& disp,
22267 const bool centering=true,
22268 const int render_static=4, const int render_motion=1,
22269 const bool double_sided=false,
22270 const float focale=500.0f, const float ambient_light=0.05f,
22271 const bool display_axes=true, float *const pose_matrix=0) const {
22272 CImgList<to> nopacities(opacities.size(),1);
22273 cimglist_for(nopacities,l) nopacities(l,0) = opacities(l);
22274 if (!points) throw CImgArgumentException("CImg<%s>::display_object3d() : Given points are empty.",
22275 pixel_type());
22276 CImg<tp> npoints(points.size,3,1,1,0);
22277 tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
22278 { cimg_forX(npoints,l) {
22279 const CImg<tp>& point = points[l];
22280 const unsigned int siz = point.size();
22281 if (!siz)
22282 throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (size=%u) contains a null element at "
22283 "position %u.",pixel_type(),points.size,l);
22284 *(ptrZ++) = (siz>2)?point(2):0;
22285 *(ptrY++) = (siz>1)?point(1):0;
22286 *(ptrX++) = point(0);
22287 }
22288 }
22289 return display_object3d(npoints,primitives,colors,nopacities,disp,centering,
22290 render_static,render_motion,double_sided,focale,ambient_light,
22291 display_axes,pose_matrix);
22292 }
22293
22295 template<typename tp, typename tf, typename tc, typename to>
22296 const CImg<T>& display_object3d(const tp& points, const CImgList<tf>& primitives,
22297 const CImgList<tc>& colors, const to& opacities,
22298 const bool centering=true,
22299 const int render_static=4, const int render_motion=1,
22300 const bool double_sided=false,
22301 const float focale=500.0f, const float ambient_light=0.05f,
22302 const bool display_axes=true, float *const pose_matrix=0) const {
22303 CImgDisplay disp(width,height,0,0);
22304 return display_object3d(points,primitives,colors,opacities,disp,centering,
22305 render_static,render_motion,double_sided,focale,ambient_light,
22306 display_axes,pose_matrix);
22307 }
22308
22310 template<typename tp, typename tf, typename tc>
22311 const CImg<T>& display_object3d(const tp& points, const CImgList<tf>& primitives,
22312 const CImgList<tc>& colors,
22313 const bool centering=true,
22314 const int render_static=4, const int render_motion=1,
22315 const bool double_sided=false,
22316 const float focale=500.0f, const float ambient_light=0.05f,
22317 const bool display_axes=true, float *const pose_matrix=0,
22318 const float opacity=1.0f) const {
22319 CImgDisplay disp(width,height," ",0);
22320 return display_object3d(points,primitives,colors,CImg<float>::vector(opacity),
22321 disp,centering,render_static,render_motion,double_sided,
22322 focale,ambient_light,display_axes,pose_matrix);
22323 }
22324
22326 template<typename tp, typename tf, typename tc>
22327 const CImg<T>& display_object3d(const tp& points, const CImgList<tf>& primitives,
22328 const CImgList<tc>& colors, CImgDisplay &disp,
22329 const bool centering=true,
22330 const int render_static=4, const int render_motion=1,
22331 const bool double_sided=false,
22332 const float focale=500.0f, const float ambient_light=0.05f,
22333 const bool display_axes=true, float *const pose_matrix=0,
22334 const float opacity=1.0f) const {
22335 return display_object3d(points,primitives,colors,CImg<float>::vector(opacity),
22336 disp,centering,render_static,render_motion,double_sided,
22337 focale,ambient_light,display_axes,pose_matrix);
22338 }
22339
22341
22342
22344
22345
22346
22348
22353 static CImg<T> get_load(const char *const filename) {
22354 return CImg<T>().load(filename);
22355 }
22356
22357 CImg<T>& load(const char *const filename) {
22358 const char *ext = cimg::filename_split(filename);
22359 #ifdef cimg_load_plugin
22360 cimg_load_plugin(filename);
22361 #endif
22362 if (!cimg::strncasecmp(ext,"asc",3)) return load_ascii(filename);
22363 if (!cimg::strncasecmp(ext,"dlm",3) ||
22364 !cimg::strncasecmp(ext,"txt",3)) return load_dlm(filename);
22365 if (!cimg::strncasecmp(ext,"inr",3)) return load_inr(filename);
22366 if (!cimg::strncasecmp(ext,"hdr",3) ||
22367 !cimg::strncasecmp(ext,"nii",3)) return load_analyze(filename);
22368 if (!cimg::strncasecmp(ext,"par",3) ||
22369 !cimg::strncasecmp(ext,"rec",3)) return load_parrec(filename);
22370 if (!cimg::strncasecmp(ext,"pan",3)) return load_pandore(filename);
22371 if (!cimg::strncasecmp(ext,"bmp",3)) return load_bmp(filename);
22372 if (!cimg::strncasecmp(ext,"png",3)) return load_png(filename);
22373 if (!cimg::strncasecmp(ext,"tif",3)) return load_tiff(filename);
22374 if (!cimg::strncasecmp(ext,"jpg",3) ||
22375 !cimg::strncasecmp(ext,"jpeg",4)) return load_jpeg(filename);
22376 if (!cimg::strncasecmp(ext,"ppm",3) ||
22377 !cimg::strncasecmp(ext,"pgm",3) ||
22378 !cimg::strncasecmp(ext,"pnm",3)) return load_pnm(filename);
22379 if (!cimg::strncasecmp(ext,"cimg",4) ||
22380 ext[0]=='\0') return load_cimg(filename);
22381 if (!cimg::strncasecmp(ext,"dcm",3) ||
22382 !cimg::strncasecmp(ext,"dicom",5)) return load_dicom(filename);
22383 return load_other(filename);
22384 }
22385
22387 static CImg<T> get_load_ascii(std::FILE *const file, const char *const filename=0) {
22388 return CImg<T>().load_ascii(file,filename);
22389 }
22390
22391 CImg<T>& load_ascii(std::FILE *const file, const char *const filename=0) {
22392 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
22393 char line[256] = { 0 };
22394 std::fscanf(nfile,"%255[^\n]",line);
22395 unsigned int off, dx = 0, dy = 1, dz = 1, dv = 1;
22396 int err = 1;
22397 std::sscanf(line,"%u %u %u %u",&dx,&dy,&dz,&dv);
22398 if (!dx || !dy || !dz || !dv) {
22399 if (!file) cimg::fclose(nfile);
22400 throw CImgIOException("CImg<%s>::load_ascii() : File '%s' is not a valid .ASC file.\n"
22401 "Specified image dimensions are (%u,%u,%u,%u).",
22402 pixel_type(),filename?filename:"(FILE*)",dx,dy,dz,dv);
22403 }
22404 assign(dx,dy,dz,dv);
22405 const unsigned int siz = size();
22406 double val;
22407 T *ptr = data;
22408 for (off=0; off<siz && err==1; ++off) {
22409 err = std::fscanf(nfile,"%lf%*[^0-9.eE+-]",&val);
22410 *(ptr++) = (T)val;
22411 }
22412 if (off<size()) cimg::warn("CImg<%s>::load_ascii() : File '%s', only %u/%u values read.",
22413 pixel_type(),filename?filename:"(FILE*)",off,siz);
22414 if (!file) cimg::fclose(nfile);
22415 return *this;
22416 }
22417
22419 static CImg<T> get_load_ascii(const char *const filename) {
22420 return CImg<T>().load_ascii(0,filename);
22421 }
22422
22423 CImg<T>& load_ascii(const char *const filename) {
22424 return load_ascii(0,filename);
22425 }
22426
22428 static CImg<T> get_load_dlm(std::FILE *const file, const char *const filename=0) {
22429 return CImg<T>().load_dlm(file,filename);
22430 }
22431
22432 CImg<T>& load_dlm(std::FILE *const file, const char *const filename=0) {
22433 std::FILE *const nfile = file?file:cimg::fopen(filename,"r");
22434 assign(256,256);
22435 char c, delimiter[256] = { 0 }, tmp[256];
22436 unsigned int cdx = 0, dx = 0, dy = 0;
22437 int oerr = 0, err;
22438 double val;
22439 while ((err = std::fscanf(nfile,"%lf%255[^0-9.eE+-]",&val,delimiter))!=EOF) {
22440 oerr = err;
22441 if (err>0) (*this)(cdx++,dy) = (T)val;
22442 if (cdx>=width) resize(width+256,1,1,1,0);
22443 c = 0; if (!std::sscanf(delimiter,"%255[^\n]%c",tmp,&c) || c=='\n') {
22444 dx = cimg::max(cdx,dx);
22445 ++dy;
22446 if (dy>=height) resize(width,height+256,1,1,0);
22447 cdx = 0;
22448 }
22449 }
22450 if (cdx && oerr==1) { dx=cdx; ++dy; }
22451 if (!dx || !dy) {
22452 if (!file) cimg::fclose(nfile);
22453 throw CImgIOException("CImg<%s>::load_dlm() : File '%s' is not a valid DLM file.\n"
22454 "Specified image dimensions are (%u,%u).",
22455 pixel_type(),filename?filename:"(FILE*)",dx,dy);
22456 }
22457 resize(dx,dy,1,1,0);
22458 if (!file) cimg::fclose(nfile);
22459 return *this;
22460 }
22461
22463 static CImg<T> get_load_dlm(const char *const filename) {
22464 return CImg<T>().load_dlm(0,filename);
22465 }
22466
22467 CImg<T>& load_dlm(const char *const filename) {
22468 return load_dlm(0,filename);
22469 }
22470
22472 static CImg<T> get_load_pnm(std::FILE *const file, const char *const filename=0) {
22473 return CImg<T>().load_pnm(file, filename);
22474 }
22475
22476 CImg<T>& load_pnm(std::FILE *const file, const char *const filename=0) {
22477 std::FILE *const nfile=file?file:cimg::fopen(filename,"rb");
22478 unsigned int ppm_type, W, H, colormax=255;
22479 char item[1024] = { 0 };
22480 int err, rval, gval, bval;
22481 const int cimg_iobuffer = 12*1024*1024;
22482 while ((err=std::fscanf(nfile,"%1023[^\n]",item))!=EOF && (item[0]=='#' || !err)) std::fgetc(nfile);
22483 if(std::sscanf(item," P%u",&ppm_type)!=1) {
22484 if (!file) cimg::fclose(nfile);
22485 throw CImgIOException("CImg<%s>::load_pnm() : File '%s', PNM header 'P?' not found.",
22486 pixel_type(),filename?filename:"(FILE*)");
22487 }
22488 while ((err=std::fscanf(nfile," %1023[^\n]",item))!=EOF && (item[0]=='#' || !err)) std::fgetc(nfile);
22489 if ((err=std::sscanf(item," %u %u %u",&W,&H,&colormax))<2) {
22490 if (!file) cimg::fclose(nfile);
22491 throw CImgIOException("CImg<%s>::load_pnm() : File '%s', WIDTH and HEIGHT fields are not defined in PNM header.",
22492 pixel_type(),filename?filename:"(FILE*)");
22493 }
22494 if (err==2) {
22495 while ((err=std::fscanf(nfile," %1023[^\n]",item))!=EOF && (item[0]=='#' || !err)) std::fgetc(nfile);
22496 if (std::sscanf(item,"%u",&colormax)!=1)
22497 cimg::warn("CImg<%s>::load_pnm() : File '%s', COLORMAX field is not defined in PNM header.",
22498 pixel_type(),filename?filename:"(FILE*)");
22499 }
22500 std::fgetc(nfile);
22501 assign();
22502
22503 switch (ppm_type) {
22504 case 2: {
22505 assign(W,H,1,1);
22506 T* rdata = data;
22507 cimg_foroff(*this,off) { std::fscanf(nfile,"%d",&rval); *(rdata++) = (T)rval; }
22508 } break;
22509 case 3: {
22510 assign(W,H,1,3);
22511 T *rdata = ptr(0,0,0,0), *gdata = ptr(0,0,0,1), *bdata = ptr(0,0,0,2);
22512 cimg_forXY(*this,x,y) {
22513 std::fscanf(nfile,"%d %d %d",&rval,&gval,&bval);
22514 *(rdata++) = (T)rval;
22515 *(gdata++) = (T)gval;
22516 *(bdata++) = (T)bval; }
22517 } break;
22518 case 5: {
22519 if (colormax<256) {
22520 CImg<unsigned char> raw;
22521 assign(W,H,1,1);
22522 T *ptrd = ptr(0,0,0,0);
22523 for (int toread = (int)size(); toread>0; ) {
22524 raw.assign(cimg::min(toread,cimg_iobuffer));
22525 cimg::fread(raw.data,raw.width,nfile);
22526 toread-=raw.width;
22527 const unsigned char *ptrs = raw.data;
22528 for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++);
22529 }
22530 } else {
22531 CImg<unsigned short> raw;
22532 assign(W,H,1,1);
22533 T *ptrd = ptr(0,0,0,0);
22534 for (int toread = (int)size(); toread>0; ) {
22535 raw.assign(cimg::min(toread,cimg_iobuffer/2));
22536 cimg::fread(raw.data,raw.width,nfile);
22537 toread-=raw.width;
22538 const unsigned short *ptrs = raw.data;
22539 for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++);
22540 }
22541 }
22542 } break;
22543 case 6: {
22544 if (colormax<256) {
22545 CImg<unsigned char> raw;
22546 assign(W,H,1,3);
22547 T
22548 *ptr_r = ptr(0,0,0,0),
22549 *ptr_g = ptr(0,0,0,1),
22550 *ptr_b = ptr(0,0,0,2);
22551 for (int toread = (int)size(); toread>0; ) {
22552 raw.assign(cimg::min(toread,cimg_iobuffer));
22553 cimg::fread(raw.data,raw.width,nfile);
22554 toread-=raw.width;
22555 const unsigned char *ptrs = raw.data;
22556 for (unsigned int off = raw.width/3; off; --off) {
22557 *(ptr_r++) = (T)*(ptrs++);
22558 *(ptr_g++) = (T)*(ptrs++);
22559 *(ptr_b++) = (T)*(ptrs++);
22560 }
22561 }
22562 } else {
22563 CImg<unsigned short> raw;
22564 assign(W,H,1,3);
22565 T
22566 *ptr_r = ptr(0,0,0,0),
22567 *ptr_g = ptr(0,0,0,1),
22568 *ptr_b = ptr(0,0,0,2);
22569 for (int toread = (int)size(); toread>0; ) {
22570 raw.assign(cimg::min(toread,cimg_iobuffer/2));
22571 cimg::fread(raw.data,raw.width,nfile);
22572 if (!cimg::endian()) cimg::endian_swap(raw.data,raw.width);
22573 toread-=raw.width;
22574 const unsigned short *ptrs = raw.data;
22575 for (unsigned int off = raw.width/3; off; --off) {
22576 *(ptr_r++) = (T)*(ptrs++);
22577 *(ptr_g++) = (T)*(ptrs++);
22578 *(ptr_b++) = (T)*(ptrs++);
22579 }
22580 }
22581 }
22582 } break;
22583 default:
22584 if (!file) cimg::fclose(nfile);
22585 throw CImgIOException("CImg<%s>::load_pnm() : File '%s', PPM type 'P%d' not supported.",
22586 pixel_type(),filename?filename:"(FILE*)",ppm_type);
22587 }
22588 if (!file) cimg::fclose(nfile);
22589 return *this;
22590 }
22591
22593 static CImg<T> get_load_pnm(const char *const filename) {
22594 return get_load_pnm(0,filename);
22595 }
22596
22597 CImg<T>& load_pnm(const char *const filename) {
22598 return load_pnm(0,filename);
22599 }
22600
22602 static CImg<T> get_load_bmp(std::FILE *const file, const char *const filename=0) {
22603 return CImg<T>().load_bmp(file,filename);
22604 }
22605
22606 CImg<T>& load_bmp(std::FILE *const file, const char *const filename=0) {
22607 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
22608 unsigned char header[64];
22609 cimg::fread(header,54,nfile);
22610 if (header[0]!='B' || header[1]!='M') {
22611 if (!file) cimg::fclose(nfile);
22612 throw CImgIOException("CImg<%s>::load_bmp() : File '%s' is not a valid BMP file.",
22613 pixel_type(),filename?filename:"(FILE*)");
22614 }
22615 assign();
22616
22617
22618 int
22619 file_size = header[0x02] + (header[0x03]<<8) + (header[0x04]<<16) + (header[0x05]<<24),
22620 offset = header[0x0A] + (header[0x0B]<<8) + (header[0x0C]<<16) + (header[0x0D]<<24),
22621 dx = header[0x12] + (header[0x13]<<8) + (header[0x14]<<16) + (header[0x15]<<24),
22622 dy = header[0x16] + (header[0x17]<<8) + (header[0x18]<<16) + (header[0x19]<<24),
22623 compression = header[0x1E] + (header[0x1F]<<8) + (header[0x20]<<16) + (header[0x21]<<24),
22624 nb_colors = header[0x2E] + (header[0x2F]<<8) + (header[0x30]<<16) + (header[0x31]<<24),
22625 bpp = header[0x1C] + (header[0x1D]<<8),
22626 *palette = 0;
22627 const int
22628 dx_bytes = (bpp==1)?(dx/8+(dx%8?1:0)):((bpp==4)?(dx/2+(dx%2?1:0)):(dx*bpp/8)),
22629 align = (4-dx_bytes%4)%4,
22630 buf_size = cimg::min(cimg::abs(dy)*(dx_bytes+align),file_size-offset);
22631
22632 if (bpp<16) { if (!nb_colors) nb_colors=1<<bpp; } else nb_colors = 0;
22633 if (nb_colors) { palette = new int[nb_colors]; cimg::fread(palette,nb_colors,nfile); }
22634 const int xoffset = offset-54-4*nb_colors;
22635 if (xoffset>0) std::fseek(nfile,xoffset,SEEK_CUR);
22636 unsigned char *buffer = new unsigned char[buf_size], *ptrs = buffer;
22637 cimg::fread(buffer,buf_size,nfile);
22638 if (!file) cimg::fclose(nfile);
22639
22640
22641 if (compression) {
22642 delete[] buffer;
22643 if (file) {
22644 throw CImgIOException("CImg<%s>::load_bmp() : Not able to read a compressed BMP file using a *FILE input",pixel_type());
22645 } else return load_other(filename);
22646 }
22647
22648
22649 assign(dx,cimg::abs(dy),1,3);
22650 switch (bpp) {
22651 case 1: {
22652 for (int y=height-1; y>=0; --y) {
22653 unsigned char mask = 0x80, val = 0;
22654 cimg_forX(*this,x) {
22655 if (mask==0x80) val = *(ptrs++);
22656 const unsigned char *col = (unsigned char*)(palette+(val&mask?1:0));
22657 (*this)(x,y,2) = (T)*(col++);
22658 (*this)(x,y,1) = (T)*(col++);
22659 (*this)(x,y,0) = (T)*(col++);
22660 mask = cimg::ror(mask);
22661 } ptrs+=align; }
22662 } break;
22663 case 4: {
22664 for (int y=height-1; y>=0; --y) {
22665 unsigned char mask = 0xF0, val = 0;
22666 cimg_forX(*this,x) {
22667 if (mask==0xF0) val = *(ptrs++);
22668 const unsigned char color = (unsigned char)((mask<16)?(val&mask):((val&mask)>>4));
22669 unsigned char *col = (unsigned char*)(palette+color);
22670 (*this)(x,y,2) = (T)*(col++);
22671 (*this)(x,y,1) = (T)*(col++);
22672 (*this)(x,y,0) = (T)*(col++);
22673 mask = cimg::ror(mask,4);
22674 } ptrs+=align; }
22675 } break;
22676 case 8: {
22677 for (int y=height-1; y>=0; --y) { cimg_forX(*this,x) {
22678 const unsigned char *col = (unsigned char*)(palette+*(ptrs++));
22679 (*this)(x,y,2) = (T)*(col++);
22680 (*this)(x,y,1) = (T)*(col++);
22681 (*this)(x,y,0) = (T)*(col++);
22682 } ptrs+=align; }
22683 } break;
22684 case 16: {
22685 for (int y=height-1; y>=0; --y) { cimg_forX(*this,x) {
22686 const unsigned char c1 = *(ptrs++), c2 = *(ptrs++);
22687 const unsigned short col = (unsigned short)(c1|(c2<<8));
22688 (*this)(x,y,2) = (T)(col&0x1F);
22689 (*this)(x,y,1) = (T)((col>>5)&0x1F);
22690 (*this)(x,y,0) = (T)((col>>10)&0x1F);
22691 } ptrs+=align; }
22692 } break;
22693 case 24: {
22694 for (int y=height-1; y>=0; --y) { cimg_forX(*this,x) {
22695 (*this)(x,y,2) = (T)*(ptrs++);
22696 (*this)(x,y,1) = (T)*(ptrs++);
22697 (*this)(x,y,0) = (T)*(ptrs++);
22698 } ptrs+=align; }
22699 } break;
22700 case 32: {
22701 for (int y=height-1; y>=0; --y) { cimg_forX(*this,x) {
22702 (*this)(x,y,2) = (T)*(ptrs++);
22703 (*this)(x,y,1) = (T)*(ptrs++);
22704 (*this)(x,y,0) = (T)*(ptrs++);
22705 ++ptrs;
22706 } ptrs+=align; }
22707 } break;
22708 }
22709 if (palette) delete[] palette;
22710 delete[] buffer;
22711 if (dy<0) mirror('y');
22712 return *this;
22713 }
22714
22716 static CImg<T> get_load_bmp(const char *const filename) {
22717 return CImg<T>().load_bmp(0,filename);
22718 }
22719
22720 CImg<T>& load_bmp(const char *const filename) {
22721 return load_bmp(0,filename);
22722 }
22723
22725
22726 static CImg<T> get_load_png(std::FILE *const file, const char *const filename=0) {
22727 return CImg<T>().load_png(file,filename);
22728 }
22729
22730 CImg<T>& load_png(std::FILE *const file, const char *const filename=0) {
22731 #ifndef cimg_use_png
22732 if (file)
22733 throw CImgIOException("CImg<%s>::load_png() : File '(FILE*)' cannot be read without using libpng.",pixel_type());
22734 else return load_other(filename);
22735 #else
22736
22737 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
22738 unsigned char pngCheck[8];
22739 cimg::fread(pngCheck,8,nfile);
22740 if (png_sig_cmp(pngCheck,0,8)) {
22741 if (!file) cimg::fclose(nfile);
22742 throw CImgIOException("CImg<%s>::load_png() : File '%s' is not a valid PNG file.",
22743 pixel_type(),filename?filename:"(FILE*)");
22744 }
22745
22746
22747 png_voidp user_error_ptr = 0;
22748 png_error_ptr user_error_fn = 0, user_warning_fn = 0;
22749 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
22750 user_error_ptr, user_error_fn, user_warning_fn);
22751 if(!png_ptr){
22752 if (!file) cimg::fclose(nfile);
22753 throw CImgIOException("CImg<%s>::load_png() : File '%s', trouble initializing 'png_ptr' data structure.",
22754 pixel_type(),filename?filename:"(FILE*)");
22755 }
22756 png_infop info_ptr = png_create_info_struct(png_ptr);
22757 if(!info_ptr){
22758 if (!file) cimg::fclose(nfile);
22759 png_destroy_read_struct(&png_ptr, (png_infopp)0, (png_infopp)0);
22760 throw CImgIOException("CImg<%s>::load_png() : File '%s', trouble initializing 'info_ptr' data structure.",
22761 pixel_type(),filename?filename:"(FILE*)");
22762 }
22763 png_infop end_info = png_create_info_struct(png_ptr);
22764 if(!end_info){
22765 if (!file) cimg::fclose(nfile);
22766 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)0);
22767 throw CImgIOException("CImg<%s>::load_png() : File '%s', trouble initializing 'end_info' data structure.",
22768 pixel_type(),filename?filename:"(FILE*)");
22769 }
22770
22771
22772 if (setjmp(png_jmpbuf(png_ptr))){
22773 if (!file) cimg::fclose(nfile);
22774 png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
22775 throw CImgIOException("CImg<%s>::load_png() : File '%s', unknown fatal error.",
22776 pixel_type(),filename?filename:"(FILE*)");
22777 }
22778 png_init_io(png_ptr, nfile);
22779 png_set_sig_bytes(png_ptr, 8);
22780
22781
22782 png_read_info(png_ptr, info_ptr);
22783 png_uint_32 W, H;
22784 int bit_depth, color_type, interlace_type;
22785 png_get_IHDR(png_ptr, info_ptr, &W, &H, &bit_depth, &color_type, &interlace_type,
22786 int_p_NULL, int_p_NULL);
22787 int new_bit_depth = bit_depth;
22788 int new_color_type = color_type;
22789
22790
22791 if (new_color_type == PNG_COLOR_TYPE_PALETTE){
22792 png_set_palette_to_rgb(png_ptr);
22793 new_color_type -= PNG_COLOR_MASK_PALETTE;
22794 new_bit_depth = 8;
22795 }
22796 if (new_color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8){
22797 png_set_gray_1_2_4_to_8(png_ptr);
22798 new_bit_depth = 8;
22799 }
22800 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
22801 png_set_tRNS_to_alpha(png_ptr);
22802 if (new_color_type == PNG_COLOR_TYPE_GRAY || new_color_type == PNG_COLOR_TYPE_GRAY_ALPHA){
22803 png_set_gray_to_rgb(png_ptr);
22804 new_color_type |= PNG_COLOR_MASK_COLOR;
22805 }
22806 if (new_color_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, 0xffffU, PNG_FILLER_AFTER);
22807 png_read_update_info(png_ptr, info_ptr);
22808 if (!(new_bit_depth==8 || new_bit_depth==16)) {
22809 if (!file) cimg::fclose(nfile);
22810 png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
22811 throw CImgIOException("CImg<%s>::load_png() : File '%s', wrong bit coding (bit_depth=%u)",
22812 pixel_type(),filename?filename:"(FILE*)",new_bit_depth);
22813 }
22814 const int byte_depth = new_bit_depth>>3;
22815
22816
22817 png_bytep *imgData = new png_bytep[H];
22818 for (unsigned int row=0; row < H; ++row) imgData[row] = new png_byte[byte_depth * 4 * W];
22819 png_read_image(png_ptr, imgData);
22820 png_read_end(png_ptr, end_info);
22821
22822
22823 if (!(new_color_type==PNG_COLOR_TYPE_RGB || new_color_type==PNG_COLOR_TYPE_RGB_ALPHA)) {
22824 if (!file) cimg::fclose(nfile);
22825 png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
22826 throw CImgIOException("CImg<%s>::load_png() : File '%s', wrong color coding (new_color_type=%u)",
22827 pixel_type(),filename?filename:"(FILE*)",new_color_type);
22828 }
22829 const bool no_alpha_channel = (new_color_type==PNG_COLOR_TYPE_RGB);
22830 assign(W,H,1,no_alpha_channel?3:4);
22831 T *ptr1 = ptr(0,0,0,0), *ptr2 = ptr(0,0,0,1), *ptr3 = ptr(0,0,0,2), *ptr4 = ptr(0,0,0,3);
22832 switch(new_bit_depth) {
22833 case 8: {
22834 cimg_forY(*this,y){
22835 const unsigned char *ptrs = (unsigned char*)imgData[y];
22836 cimg_forX(*this,x){
22837 *(ptr1++) = (T)*(ptrs++);
22838 *(ptr2++) = (T)*(ptrs++);
22839 *(ptr3++) = (T)*(ptrs++);
22840 if (no_alpha_channel) ++ptrs; else *(ptr4++) = (T)*(ptrs++);
22841 }
22842 }
22843 } break;
22844 case 16: {
22845 cimg_forY(*this,y){
22846 const unsigned short *ptrs = (unsigned short*)(imgData[y]);
22847 cimg_forX(*this,x){
22848 *(ptr1++) = (T)*(ptrs++);
22849 *(ptr2++) = (T)*(ptrs++);
22850 *(ptr3++) = (T)*(ptrs++);
22851 if (no_alpha_channel) ++ptrs; else *(ptr4++) = (T)*(ptrs++);
22852 }
22853 }
22854 } break;
22855 }
22856 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
22857
22858
22859 for (unsigned int n=0; n<H; ++n) delete[] imgData[n];
22860 delete[] imgData;
22861 if (!file) cimg::fclose(nfile);
22862 return *this;
22863 #endif
22864 }
22865
22867 static CImg<T> get_load_png(const char *const filename) {
22868 return CImg<T>().load_png(0,filename);
22869 }
22870
22871 CImg<T>& load_png(const char *const filename) {
22872 return load_png(0,filename);
22873 }
22874
22876
22877 static CImg<T> get_load_tiff(const char *const filename) {
22878 return CImg<T>().load_tiff(filename);
22879 }
22880
22881 CImg<T>& load_tiff(const char *const filename) {
22882 #ifndef cimg_use_tiff
22883 return load_other(filename);
22884 #else
22885 TIFF *tif = TIFFOpen(filename,"r");
22886 #if cimg_debug>=3
22887 TIFFSetWarningHandler(0);
22888 TIFFSetErrorHandler(0);
22889 #endif
22890 if (tif) {
22891 unsigned int number_of_directories = 0;
22892 do ++number_of_directories; while (TIFFReadDirectory(tif));
22893 uint16 samplesperpixel, bitspersample;
22894 uint32 nx,ny;
22895 TIFFGetField(tif,TIFFTAG_IMAGEWIDTH,&nx);
22896 TIFFGetField(tif,TIFFTAG_IMAGELENGTH,&ny);
22897 TIFFGetField(tif,TIFFTAG_SAMPLESPERPIXEL,&samplesperpixel);
22898 if (samplesperpixel!=1 && samplesperpixel!=3 && samplesperpixel!=4) {
22899 cimg::warn("CImg<%s>::load_tiff() : File '%s', unknow value for tag : TIFFTAG_SAMPLESPERPIXEL, will force it to 1.",
22900 pixel_type(),filename?filename:"(FILE*)");
22901 samplesperpixel=1;
22902 }
22903 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
22904 TIFFClose(tif);
22905 tif = TIFFOpen(filename,"r");
22906 assign(nx,ny,number_of_directories,samplesperpixel);
22907 unsigned int dir = 0;
22908 do {
22909 if (bitspersample!=8 || !(samplesperpixel == 3 || samplesperpixel == 4)) {
22910 uint16 photo, config;
22911 TIFFGetField(tif,TIFFTAG_PLANARCONFIG,&config);
22912 TIFFGetField(tif,TIFFTAG_PHOTOMETRIC,&photo);
22913 if (TIFFIsTiled(tif)) {
22914 uint32 tw, th;
22915 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
22916 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
22917 if (config==PLANARCONFIG_CONTIG) switch(bitspersample) {
22918 case 8: {
22919 unsigned char *buf = (unsigned char*)_TIFFmalloc(TIFFTileSize(tif));
22920 if (buf) {
22921 for (unsigned int row = 0; row<ny; row+=th)
22922 for (unsigned int col = 0; col<nx; col+=tw) {
22923 if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
22924 _TIFFfree(buf); TIFFClose(tif);
22925 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
22926 pixel_type(),filename?filename:"(FILE*)");
22927 } else {
22928 unsigned char *ptr = buf;
22929 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
22930 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
22931 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
22932 (*this)(cc,rr,dir,vv) = (T)(float)(ptr[(rr-row)*th*samplesperpixel + (cc-col)*samplesperpixel + vv]);
22933 }
22934 }
22935 _TIFFfree(buf);
22936 }
22937 } break;
22938 case 16: {
22939 unsigned short *buf = (unsigned short*)_TIFFmalloc(TIFFTileSize(tif));
22940 if (buf) {
22941 for (unsigned int row = 0; row<ny; row+=th)
22942 for (unsigned int col = 0; col<nx; col+=tw) {
22943 if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
22944 _TIFFfree(buf); TIFFClose(tif);
22945 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
22946 pixel_type(),filename?filename:"(FILE*)");
22947 } else {
22948 unsigned short *ptr = buf;
22949 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
22950 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
22951 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
22952 (*this)(cc,rr,dir,vv) = (T)(float)(ptr[(rr-row)*th*samplesperpixel + (cc-col)*samplesperpixel + vv]);
22953 }
22954 }
22955 _TIFFfree(buf);
22956 }
22957 } break;
22958 case 32: {
22959 float *buf = (float*)_TIFFmalloc(TIFFTileSize(tif));
22960 if (buf) {
22961 for (unsigned int row = 0; row<ny; row+=th)
22962 for (unsigned int col = 0; col<nx; col+=tw) {
22963 if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
22964 _TIFFfree(buf); TIFFClose(tif);
22965 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
22966 pixel_type(),filename?filename:"(FILE*)");
22967 } else {
22968 float *ptr = buf;
22969 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
22970 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
22971 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
22972 (*this)(cc,rr,dir,vv) = (T)(float)(ptr[(rr-row)*th*samplesperpixel + (cc-col)*samplesperpixel + vv]);
22973 }
22974 }
22975 _TIFFfree(buf);
22976 }
22977 } break;
22978 } else switch (bitspersample) {
22979 case 8: {
22980 unsigned char *buf = (unsigned char*)_TIFFmalloc(TIFFTileSize(tif));
22981 if (buf) {
22982 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
22983 for (unsigned int row = 0; row<ny; row+=th)
22984 for (unsigned int col = 0; col<nx; col+=tw) {
22985 if (TIFFReadTile(tif,buf,col,row,0,vv)<0) {
22986 _TIFFfree(buf); TIFFClose(tif);
22987 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
22988 pixel_type(),filename?filename:"(FILE*)");
22989 } else {
22990 unsigned char *ptr = buf;
22991 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
22992 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
22993 (*this)(cc,rr,dir,vv) = (T)(float)*(ptr++);
22994 }
22995 }
22996 _TIFFfree(buf);
22997 }
22998 } break;
22999 case 16: {
23000 unsigned short *buf = (unsigned short*)_TIFFmalloc(TIFFTileSize(tif));
23001 if (buf) {
23002 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23003 for (unsigned int row = 0; row<ny; row+=th)
23004 for (unsigned int col = 0; col<nx; col+=tw) {
23005 if (TIFFReadTile(tif,buf,col,row,0,vv)<0) {
23006 _TIFFfree(buf); TIFFClose(tif);
23007 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
23008 pixel_type(),filename?filename:"(FILE*)");
23009 } else {
23010 unsigned short *ptr = buf;
23011 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
23012 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
23013 (*this)(cc,rr,dir,vv) = (T)(float)*(ptr++);
23014 }
23015 }
23016 _TIFFfree(buf);
23017 }
23018 } break;
23019 case 32: {
23020 float *buf = (float*)_TIFFmalloc(TIFFTileSize(tif));
23021 if (buf) {
23022 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23023 for (unsigned int row = 0; row<ny; row+=th)
23024 for (unsigned int col = 0; col<nx; col+=tw) {
23025 if (TIFFReadTile(tif,buf,col,row,0,vv)<0) {
23026 _TIFFfree(buf); TIFFClose(tif);
23027 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
23028 pixel_type(),filename?filename:"(FILE*)");
23029 } else {
23030 float *ptr = buf;
23031 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
23032 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
23033 (*this)(cc,rr,dir,vv) = (T)(float)*(ptr++);
23034 }
23035 }
23036 _TIFFfree(buf);
23037 }
23038 } break;
23039 }
23040 } else {
23041 if (config==PLANARCONFIG_CONTIG) switch (bitspersample) {
23042 case 8: {
23043 unsigned char *buf = (unsigned char*)_TIFFmalloc(TIFFStripSize(tif));
23044 if (buf) {
23045 uint32 row, rowsperstrip = (uint32)-1;
23046 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23047 for (row = 0; row<ny; row+= rowsperstrip) {
23048 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23049 tstrip_t strip = TIFFComputeStrip(tif, row, 0);
23050 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23051 _TIFFfree(buf); TIFFClose(tif);
23052 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a strip.",
23053 pixel_type(),filename?filename:"(FILE*)");
23054 }
23055 unsigned char *ptr = buf;
23056 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23057 for (unsigned int vv=0; vv<samplesperpixel; ++vv) (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23058 }
23059 _TIFFfree(buf);
23060 }
23061 } break;
23062 case 16: {
23063 unsigned short *buf = (unsigned short*)_TIFFmalloc(TIFFStripSize(tif));
23064 if (buf) {
23065 uint32 row, rowsperstrip = (uint32)-1;
23066 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23067 for (row = 0; row<ny; row+= rowsperstrip) {
23068 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23069 tstrip_t strip = TIFFComputeStrip(tif, row, 0);
23070 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23071 _TIFFfree(buf); TIFFClose(tif);
23072 throw CImgException("CImg<%s>::load_tiff() : File '%s', error while reading a strip.",
23073 pixel_type(),filename?filename:"(FILE*)");
23074 }
23075 unsigned short *ptr = buf;
23076 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23077 for (unsigned int vv=0; vv<samplesperpixel; ++vv) (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23078 }
23079 _TIFFfree(buf);
23080 }
23081 } break;
23082 case 32: {
23083 float *buf = (float*)_TIFFmalloc(TIFFStripSize(tif));
23084 if (buf) {
23085 uint32 row, rowsperstrip = (uint32)-1;
23086 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23087 for (row = 0; row<ny; row+= rowsperstrip) {
23088 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23089 tstrip_t strip = TIFFComputeStrip(tif, row, 0);
23090 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23091 _TIFFfree(buf); TIFFClose(tif);
23092 throw CImgException("CImg<%s>::load_tiff() : File '%s', error while reading a strip.",
23093 pixel_type(),filename?filename:"(FILE*)");
23094 }
23095 float *ptr = buf;
23096 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23097 for (unsigned int vv=0; vv<samplesperpixel; ++vv) (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23098 }
23099 _TIFFfree(buf);
23100 }
23101 } break;
23102 } else switch(bitspersample){
23103 case 8: {
23104 unsigned char *buf = (unsigned char*)_TIFFmalloc(TIFFStripSize(tif));
23105 if (buf) {
23106 uint32 row, rowsperstrip = (uint32)-1;
23107 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23108 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23109 for (row = 0; row<ny; row+= rowsperstrip) {
23110 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23111 tstrip_t strip = TIFFComputeStrip(tif, row, vv);
23112 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23113 _TIFFfree(buf); TIFFClose(tif);
23114 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a strip.",
23115 pixel_type(),filename?filename:"(FILE*)");
23116 }
23117 unsigned char *ptr = buf;
23118 for (unsigned int rr=0;rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23119 (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23120 }
23121 _TIFFfree(buf);
23122 }
23123 } break;
23124 case 16: {
23125 unsigned short *buf = (unsigned short*)_TIFFmalloc(TIFFStripSize(tif));
23126 if (buf) {
23127 uint32 row, rowsperstrip = (uint32)-1;
23128 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23129 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23130 for (row = 0; row<ny; row+= rowsperstrip) {
23131 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23132 tstrip_t strip = TIFFComputeStrip(tif, row, vv);
23133 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23134 _TIFFfree(buf); TIFFClose(tif);
23135 throw CImgException("CImg<%s>::load_tiff() : File '%s', error while reading a strip.",
23136 pixel_type(),filename?filename:"(FILE*)");
23137 }
23138 unsigned short *ptr = buf;
23139 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23140 (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23141 }
23142 _TIFFfree(buf);
23143 }
23144 } break;
23145 case 32: {
23146 float *buf = (float*)_TIFFmalloc(TIFFStripSize(tif));
23147 if (buf) {
23148 uint32 row, rowsperstrip = (uint32)-1;
23149 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23150 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23151 for (row = 0; row<ny; row+= rowsperstrip) {
23152 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23153 tstrip_t strip = TIFFComputeStrip(tif, row, vv);
23154 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23155 _TIFFfree(buf); TIFFClose(tif);
23156 throw CImgException("CImg<%s>::load_tiff() : File '%s', error while reading a strip.",
23157 pixel_type(),filename?filename:"(FILE*)");
23158 }
23159 float *ptr = buf;
23160 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23161 (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23162 }
23163 _TIFFfree(buf);
23164 }
23165 } break;
23166 }
23167 }
23168 } else {
23169 uint32* raster = (uint32*)_TIFFmalloc(nx * ny * sizeof (uint32));
23170 if (!raster) {
23171 _TIFFfree(raster); TIFFClose(tif);
23172 throw CImgException("CImg<%s>::load_tiff() : File '%s', not enough memory for buffer allocation.",
23173 pixel_type(),filename?filename:"(FILE*)");
23174 }
23175 TIFFReadRGBAImage(tif,nx,ny,raster,0);
23176 switch (samplesperpixel) {
23177 case 1: {
23178 cimg_forXY(*this,x,y) (*this)(x,y,dir) = (T)(float)((raster[nx*(ny-1-y)+x]+ 128) / 257);
23179 } break;
23180 case 3: {
23181 cimg_forXY(*this,x,y) {
23182 (*this)(x,y,dir,0) = (T)(float)TIFFGetR(raster[nx*(ny-1-y)+x]);
23183 (*this)(x,y,dir,1) = (T)(float)TIFFGetG(raster[nx*(ny-1-y)+x]);
23184 (*this)(x,y,dir,2) = (T)(float)TIFFGetB(raster[nx*(ny-1-y)+x]);
23185 }
23186 } break;
23187 case 4: {
23188 cimg_forXY(*this,x,y) {
23189 (*this)(x,y,dir,0) = (T)(float)TIFFGetR(raster[nx*(ny-1-y)+x]);
23190 (*this)(x,y,dir,1) = (T)(float)TIFFGetG(raster[nx*(ny-1-y)+x]);
23191 (*this)(x,y,dir,2) = (T)(float)TIFFGetB(raster[nx*(ny-1-y)+x]);
23192 (*this)(x,y,dir,3) = (T)(float)TIFFGetA(raster[nx*(ny-1-y)+x]);
23193 }
23194 } break;
23195 }
23196 _TIFFfree(raster);
23197 }
23198 ++dir;
23199 } while (TIFFReadDirectory(tif));
23200 TIFFClose(tif);
23201 } else throw CImgException("CImg<%s>::load_tiff() : File '%s', error while loading the image.",
23202 pixel_type(),filename?filename:"(FILE*)");
23203 return *this;
23204 #endif
23205 }
23206
23208 static CImg<T> get_load_jpeg(std::FILE *const file, const char *const filename=0) {
23209 return CImg<T>().load_jpeg(file,filename);
23210 }
23211
23212 CImg<T>& load_jpeg(std::FILE *const file, const char *const filename=0) {
23213 #ifndef cimg_use_jpeg
23214 if (file)
23215 throw CImgIOException("CImg<%s>::load_jpeg() : File '(FILE*)' cannot be read without using libjpeg.",
23216 pixel_type());
23217 else return load_other(filename);
23218 #else
23219 struct jpeg_decompress_struct cinfo;
23220 struct jpeg_error_mgr jerr;
23221 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23222
23223 cinfo.err = jpeg_std_error(&jerr);
23224 jpeg_create_decompress(&cinfo);
23225 jpeg_stdio_src(&cinfo,nfile);
23226 jpeg_read_header(&cinfo,TRUE);
23227 jpeg_start_decompress(&cinfo);
23228
23229 if (cinfo.output_components!=1 && cinfo.output_components!=3 && cinfo.output_components!=4) {
23230 cimg::warn("CImg<%s>::load_jpeg() : Don't know how to read image '%s' with libpeg, trying ImageMagick's convert",
23231 pixel_type(),filename?filename:"(unknown)");
23232 if (!file) return load_other(filename);
23233 else {
23234 if (!file) cimg::fclose(nfile);
23235 throw CImgIOException("CImg<%s>::load_jpeg() : Cannot read JPEG image '%s' using a *FILE input.",
23236 pixel_type(),filename?filename:"(FILE*)");
23237 }
23238 }
23239
23240 const unsigned int row_stride = cinfo.output_width * cinfo.output_components;
23241 unsigned char *buf = new unsigned char[cinfo.output_width*cinfo.output_height*cinfo.output_components], *buf2 = buf;
23242 JSAMPROW row_pointer[1];
23243 while (cinfo.output_scanline < cinfo.output_height) {
23244 row_pointer[0] = &buf[cinfo.output_scanline*row_stride];
23245 jpeg_read_scanlines(&cinfo,row_pointer,1);
23246 }
23247 jpeg_finish_decompress(&cinfo);
23248 jpeg_destroy_decompress(&cinfo);
23249 if (!file) cimg::fclose(nfile);
23250
23251 assign(cinfo.output_width,cinfo.output_height,1,cinfo.output_components);
23252 switch (dim) {
23253 case 1: {
23254 T *ptr_g = data;
23255 cimg_forXY(*this,x,y) *(ptr_g++) = (T)*(buf2++);
23256 } break;
23257 case 3: {
23258 T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1), *ptr_b = ptr(0,0,0,2);
23259 cimg_forXY(*this,x,y) {
23260 *(ptr_r++) = (T)*(buf2++);
23261 *(ptr_g++) = (T)*(buf2++);
23262 *(ptr_b++) = (T)*(buf2++);
23263 }
23264 } break;
23265 case 4: {
23266 T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1),
23267 *ptr_b = ptr(0,0,0,2), *ptr_a = ptr(0,0,0,3);
23268 cimg_forXY(*this,x,y) {
23269 *(ptr_r++) = (T)*(buf2++);
23270 *(ptr_g++) = (T)*(buf2++);
23271 *(ptr_b++) = (T)*(buf2++);
23272 *(ptr_a++) = (T)*(buf2++);
23273 }
23274 } break;
23275 }
23276 delete[] buf;
23277 return *this;
23278 #endif
23279 }
23280
23282 static CImg<T> get_load_jpeg(const char *const filename) {
23283 return CImg<T>().load_jpeg(0,filename);
23284 }
23285
23286 CImg<T>& load_jpeg(const char *const filename) {
23287 return load_jpeg(0,filename);
23288 }
23289
23291
23295 static CImg<T> get_load_magick(const char *const filename) {
23296 return CImg<T>().load_magick(filename);
23297 }
23298
23299 CImg<T>& load_magick(const char *const filename) {
23300 #ifdef cimg_use_magick
23301 Magick::Image image(filename);
23302 const unsigned int W = image.size().width(), H = image.size().height();
23303 switch (image.type()) {
23304 case Magick::PaletteMatteType:
23305 case Magick::TrueColorMatteType:
23306 case Magick::ColorSeparationType: {
23307 assign(W,H,1,4);
23308 T *rdata = ptr(0,0,0,0), *gdata = ptr(0,0,0,1), *bdata = ptr(0,0,0,2), *adata = ptr(0,0,0,3);
23309 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
23310 for (unsigned int off = W*H; off; --off) {
23311 *(rdata++) = (T)(pixels->red);
23312 *(gdata++) = (T)(pixels->green);
23313 *(bdata++) = (T)(pixels->blue);
23314 *(adata++) = (T)(pixels->opacity);
23315 ++pixels;
23316 }
23317 } break;
23318 case Magick::PaletteType:
23319 case Magick::TrueColorType: {
23320 assign(W,H,1,3);
23321 T *rdata = ptr(0,0,0,0), *gdata = ptr(0,0,0,1), *bdata = ptr(0,0,0,2);
23322 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
23323 for (unsigned int off = W*H; off; --off) {
23324 *(rdata++) = (T)(pixels->red);
23325 *(gdata++) = (T)(pixels->green);
23326 *(bdata++) = (T)(pixels->blue);
23327 ++pixels;
23328 }
23329 } break;
23330 case Magick::GrayscaleMatteType: {
23331 assign(W,H,1,2);
23332 T *data = ptr(0,0,0,0), *adata = ptr(0,0,0,1);
23333 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
23334 for (unsigned int off = W*H; off; --off) {
23335 *(data++) = (T)(pixels->red);
23336 *(adata++) = (T)(pixels->opacity);
23337 ++pixels;
23338 }
23339 } break;
23340 default: {
23341 assign(W,H,1,1);
23342 T *data = ptr(0,0,0,0);
23343 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
23344 for (unsigned int off = W*H; off; --off) {
23345 *(data++) = (T)(pixels->red);
23346 ++pixels;
23347 }
23348 } break;
23349 }
23350 #else
23351 throw CImgIOException("CImg<%s>::load_magick() : File '%s', Magick++ has not been linked during compilation.",
23352 pixel_type(),filename?filename:"(null)");
23353 #endif
23354 return *this;
23355 }
23356
23358 static CImg<T> get_load_raw(std::FILE *const file, const char *const filename,
23359 const unsigned int sizex, const unsigned int sizey=1,
23360 const unsigned int sizez=1, const unsigned int sizev=1,
23361 const bool multiplexed=false, const bool endian_swap=false) {
23362 return CImg<T>().load_raw(file,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap);
23363 }
23364
23365 CImg<T>& load_raw(std::FILE *const file, const char *const filename,
23366 const unsigned int sizex, const unsigned int sizey=1,
23367 const unsigned int sizez=1, const unsigned int sizev=1,
23368 const bool multiplexed = false, const bool endian_swap = false) {
23369 assign(sizex,sizey,sizez,sizev,0);
23370 const unsigned int siz = size();
23371 if (siz) {
23372 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23373 if (!multiplexed) {
23374 cimg::fread(data,siz,nfile);
23375 if (endian_swap) cimg::endian_swap(data,siz);
23376 }
23377 else {
23378 CImg<T> buf(1,1,1,sizev);
23379 cimg_forXYZ(*this,x,y,z) {
23380 cimg::fread(buf.data,sizev,nfile);
23381 if (endian_swap) cimg::endian_swap(buf.data,sizev);
23382 set_vector_at(buf,x,y,z); }
23383 }
23384 if (!file) cimg::fclose(nfile);
23385 }
23386 return *this;
23387 }
23388
23390 static CImg<T> get_load_raw(const char *const filename,
23391 const unsigned int sizex, const unsigned int sizey=1,
23392 const unsigned int sizez=1, const unsigned int sizev=1,
23393 const bool multiplexed = false, const bool endian_swap = false) {
23394 return CImg<T>().load_raw(0,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap);
23395 }
23396
23397 CImg<T>& load_raw(const char *const filename,
23398 const unsigned int sizex, const unsigned int sizey=1,
23399 const unsigned int sizez=1, const unsigned int sizev=1,
23400 const bool multiplexed = false, const bool endian_swap = false) {
23401 return load_raw(0,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap);
23402 }
23403
23405 static CImg<T> get_load_rgba(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23406 return CImg<T>().load_rgba(file,filename,dimw,dimh);
23407 }
23408
23409 CImg<T>& load_rgba(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23410 const int cimg_iobuffer = 12*1024*1024;
23411 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23412 CImg<unsigned char> raw;
23413 assign(dimw,dimh,1,4);
23414 T
23415 *ptr_r = ptr(0,0,0,0),
23416 *ptr_g = ptr(0,0,0,1),
23417 *ptr_b = ptr(0,0,0,2),
23418 *ptr_a = ptr(0,0,0,3);
23419 for (int toread = (int)size(); toread>0; ) {
23420 raw.assign(cimg::min(toread,cimg_iobuffer));
23421 cimg::fread(raw.data,raw.width,nfile);
23422 toread-=raw.width;
23423 const unsigned char *ptrs = raw.data;
23424 for (unsigned int off = raw.width/4; off; --off) {
23425 *(ptr_r++) = (T)*(ptrs++);
23426 *(ptr_g++) = (T)*(ptrs++);
23427 *(ptr_b++) = (T)*(ptrs++);
23428 *(ptr_a++) = (T)*(ptrs++);
23429 }
23430 }
23431 if (!file) cimg::fclose(nfile);
23432 return *this;
23433 }
23434
23436 static CImg<T> get_load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23437 return CImg<T>().load_rgba(0,filename,dimw,dimh);
23438 }
23439
23440 CImg<T>& load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23441 return load_rgba(0,filename,dimw,dimh);
23442 }
23443
23445 static CImg<T> get_load_rgb(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23446 return CImg<T>().load_rgb(file,filename,dimw,dimh);
23447 }
23448
23449 CImg<T>& load_rgb(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23450 const int cimg_iobuffer = 12*1024*1024;
23451 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23452 CImg<unsigned char> raw;
23453 assign(dimw,dimh,1,3);
23454 T
23455 *ptr_r = ptr(0,0,0,0),
23456 *ptr_g = ptr(0,0,0,1),
23457 *ptr_b = ptr(0,0,0,2);
23458 for (int toread = (int)size(); toread>0; ) {
23459 raw.assign(cimg::min(toread,cimg_iobuffer));
23460 cimg::fread(raw.data,raw.width,nfile);
23461 toread-=raw.width;
23462 const unsigned char *ptrs = raw.data;
23463 for (unsigned int off = raw.width/3; off; --off) {
23464 *(ptr_r++) = (T)*(ptrs++);
23465 *(ptr_g++) = (T)*(ptrs++);
23466 *(ptr_b++) = (T)*(ptrs++);
23467 }
23468 }
23469 if (!file) cimg::fclose(nfile);
23470 return *this;
23471 }
23472
23474 static CImg<T> get_load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23475 return CImg<T>().load_rgb(0,filename,dimw,dimh);
23476 }
23477
23478 CImg<T>& load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23479 return load_rgb(0,filename,dimw,dimh);
23480 }
23481
23483 static CImg<T> get_load_inr(std::FILE *const file, const char *const filename=0, float *voxsize=0) {
23484 return CImg<T>().load_inr(file,filename,voxsize);
23485 }
23486
23487 CImg<T>& load_inr(std::FILE *const file, const char *const filename=0, float *const voxsize=0) {
23488
23489 #define cimg_load_inr_case(Tf,sign,pixsize,Ts) \
23490 if (!loaded && fopt[6]==pixsize && fopt[4]==Tf && fopt[5]==sign) { \
23491 Ts *xval, *val = new Ts[fopt[0]*fopt[3]]; \
23492 cimg_forYZ(*this,y,z) { \
23493 cimg::fread(val,fopt[0]*fopt[3],nfile); \
23494 if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); \
23495 xval = val; cimg_forX(*this,x) cimg_forV(*this,k) (*this)(x,y,z,k) = (T)*(xval++); \
23496 } \
23497 delete[] val; \
23498 loaded = true; \
23499 }
23500
23501 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23502 int fopt[8], endian=cimg::endian()?1:0;
23503 bool loaded = false;
23504 if (voxsize) voxsize[0]=voxsize[1]=voxsize[2]=1;
23505 _load_inr(nfile,fopt,voxsize);
23506 assign(fopt[0],fopt[1],fopt[2],fopt[3]);
23507 cimg_load_inr_case(0,0,8, unsigned char);
23508 cimg_load_inr_case(0,1,8, char);
23509 cimg_load_inr_case(0,0,16,unsigned short);
23510 cimg_load_inr_case(0,1,16,short);
23511 cimg_load_inr_case(0,0,32,unsigned int);
23512 cimg_load_inr_case(0,1,32,int);
23513 cimg_load_inr_case(1,0,32,float);
23514 cimg_load_inr_case(1,1,32,float);
23515 cimg_load_inr_case(1,0,64,double);
23516 cimg_load_inr_case(1,1,64,double);
23517 if (!loaded) {
23518 if (!file) cimg::fclose(nfile);
23519 throw CImgIOException("CImg<%s>::load_inr() : File '%s', cannot read images of the type specified in the file",
23520 pixel_type(),filename?filename:"(FILE*)");
23521 }
23522 if (!file) cimg::fclose(nfile);
23523 return *this;
23524 }
23525
23526 static void _load_inr(std::FILE *file, int out[8], float *const voxsize=0) {
23527 char item[1024], tmp1[64], tmp2[64];
23528 out[0] = out[1] = out[2] = out[3] = out[5] = 1; out[4] = out[6] = out[7] = -1;
23529 std::fscanf(file,"%63s",item);
23530 if(cimg::strncasecmp(item,"#INRIMAGE-4#{",13)!=0)
23531 throw CImgIOException("CImg<%s>::load_inr() : File does not appear to be a valid INR file.\n"
23532 "(INRIMAGE-4 identifier not found)",pixel_type());
23533 while (std::fscanf(file," %63[^\n]%*c",item)!=EOF && cimg::strncmp(item,"##}",3)) {
23534 std::sscanf(item," XDIM%*[^0-9]%d",out);
23535 std::sscanf(item," YDIM%*[^0-9]%d",out+1);
23536 std::sscanf(item," ZDIM%*[^0-9]%d",out+2);
23537 std::sscanf(item," VDIM%*[^0-9]%d",out+3);
23538 std::sscanf(item," PIXSIZE%*[^0-9]%d",out+6);
23539 if (voxsize) {
23540 std::sscanf(item," VX%*[^0-9.eE+-]%f",voxsize);
23541 std::sscanf(item," VY%*[^0-9.eE+-]%f",voxsize+1);
23542 std::sscanf(item," VZ%*[^0-9.eE+-]%f",voxsize+2);
23543 }
23544 if (std::sscanf(item," CPU%*[ =]%s",tmp1)) out[7]=cimg::strncasecmp(tmp1,"sun",3)?0:1;
23545 switch(std::sscanf(item," TYPE%*[ =]%s %s",tmp1,tmp2)) {
23546 case 0: break;
23547 case 2: out[5] = cimg::strncasecmp(tmp1,"unsigned",8)?1:0; std::strcpy(tmp1,tmp2);
23548 case 1:
23549 if (!cimg::strncasecmp(tmp1,"int",3) || !cimg::strncasecmp(tmp1,"fixed",5)) out[4] = 0;
23550 if (!cimg::strncasecmp(tmp1,"float",5) || !cimg::strncasecmp(tmp1,"double",6)) out[4] = 1;
23551 if (!cimg::strncasecmp(tmp1,"packed",6)) out[4] = 2;
23552 if (out[4]>=0) break;
23553 default: throw CImgIOException("cimg::inr_header_read() : Invalid TYPE '%s'",tmp2);
23554 }
23555 }
23556 if(out[0]<0 || out[1]<0 || out[2]<0 || out[3]<0)
23557 throw CImgIOException("CImg<%s>::load_inr() : Bad dimensions in .inr file = ( %d , %d , %d , %d )",
23558 pixel_type(),out[0],out[1],out[2],out[3]);
23559 if(out[4]<0 || out[5]<0) throw CImgIOException("CImg<%s>::load_inr() : TYPE is not fully defined",pixel_type());
23560 if(out[6]<0) throw CImgIOException("CImg<%s>::load_inr() : PIXSIZE is not fully defined",pixel_type());
23561 if(out[7]<0) throw CImgIOException("CImg<%s>::load_inr() : Big/Little Endian coding type is not defined",pixel_type());
23562 }
23563
23565 static CImg<T> get_load_inr(const char *const filename, float *const voxsize=0) {
23566 return CImg<T>().load_inr(0,filename,voxsize);
23567 }
23568
23569 CImg<T>& load_inr(const char *const filename, float *const voxsize=0) {
23570 return load_inr(0,filename,voxsize);
23571 }
23572
23574 static CImg<T> get_load_pandore(std::FILE *const file, const char *const filename=0) {
23575 return CImg<T>().load_pandore(file,filename);
23576 }
23577
23578 CImg<T>& load_pandore(std::FILE *const file, const char *const filename) {
23579
23580 #define cimg_load_pandore_case(nid,nbdim,nwidth,nheight,ndepth,ndim,stype) \
23581 case nid: { \
23582 cimg::fread(dims,nbdim,nfile); \
23583 if (endian) cimg::endian_swap(dims,nbdim); \
23584 assign(nwidth,nheight,ndepth,ndim); \
23585 const unsigned int siz = size(); \
23586 stype *buffer = new stype[siz]; \
23587 cimg::fread(buffer,siz,nfile); \
23588 if (endian) cimg::endian_swap(buffer,siz); \
23589 T *ptrd = data; \
23590 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); \
23591 buffer-=siz; \
23592 delete[] buffer; \
23593 } \
23594 break;
23595
23596 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23597 typedef unsigned char uchar;
23598 typedef unsigned short ushort;
23599 typedef unsigned int uint;
23600 typedef unsigned long ulong;
23601 char tmp[32];
23602 cimg::fread(tmp,12,nfile);
23603 if (cimg::strncasecmp("PANDORE",tmp,7)) {
23604 if (!file) cimg::fclose(nfile);
23605 throw CImgIOException("CImg<%s>::load_pandore() : File '%s' is not a valid PANDORE file.\n"
23606 "(PANDORE identifier not found).",pixel_type(),filename?filename:"(FILE*)");
23607 }
23608 unsigned int imageid,dims[8];
23609 int ptbuf[4];
23610 cimg::fread(&imageid,1,nfile);
23611 const bool endian = (imageid>255);
23612 if (endian) cimg::endian_swap(imageid);
23613
23614 cimg::fread(tmp,20,nfile);
23615 switch (imageid) {
23616 cimg_load_pandore_case(2,2,dims[1],1,1,1,uchar);
23617 cimg_load_pandore_case(3,2,dims[1],1,1,1,long);
23618 cimg_load_pandore_case(4,2,dims[1],1,1,1,float);
23619 cimg_load_pandore_case(5,3,dims[2],dims[1],1,1,uchar);
23620 cimg_load_pandore_case(6,3,dims[2],dims[1],1,1,long);
23621 cimg_load_pandore_case(7,3,dims[2],dims[1],1,1,float);
23622 cimg_load_pandore_case(8,4,dims[3],dims[2],dims[1],1,uchar);
23623 cimg_load_pandore_case(9,4,dims[3],dims[2],dims[1],1,long);
23624 cimg_load_pandore_case(10,4,dims[3],dims[2],dims[1],1,float);
23625
23626 case 11: {
23627 cimg::fread(dims,3,nfile);
23628 if (endian) cimg::endian_swap(dims,3);
23629 assign(dims[1],1,1,1);
23630 const unsigned siz = size();
23631 if (dims[2]<256) {
23632 unsigned char *buffer = new unsigned char[siz];
23633 cimg::fread(buffer,siz,nfile);
23634 T *ptrd = data;
23635 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23636 buffer-=siz;
23637 delete[] buffer;
23638 } else {
23639 if (dims[2]<65536) {
23640 unsigned short *buffer = new unsigned short[siz];
23641 cimg::fread(buffer,siz,nfile);
23642 if (endian) cimg::endian_swap(buffer,siz);
23643 T *ptrd = data;
23644 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23645 buffer-=siz;
23646 delete[] buffer;
23647 } else {
23648 unsigned int *buffer = new unsigned int[siz];
23649 cimg::fread(buffer,siz,nfile);
23650 if (endian) cimg::endian_swap(buffer,siz);
23651 T *ptrd = data;
23652 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23653 buffer-=siz;
23654 delete[] buffer;
23655 }
23656 }
23657 }
23658 break;
23659 case 12: {
23660 cimg::fread(dims,4,nfile);
23661 if (endian) cimg::endian_swap(dims,4);
23662 assign(dims[2],dims[1],1,1);
23663 const unsigned int siz = size();
23664 if (dims[3]<256) {
23665 unsigned char *buffer = new unsigned char[siz];
23666 cimg::fread(buffer,siz,nfile);
23667 T *ptrd = data;
23668 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23669 buffer-=siz;
23670 delete[] buffer;
23671 } else {
23672 if (dims[3]<65536) {
23673 unsigned short *buffer = new unsigned short[siz];
23674 cimg::fread(buffer,siz,nfile);
23675 if (endian) cimg::endian_swap(buffer,siz);
23676 T *ptrd = data;
23677 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23678 buffer-=siz;
23679 delete[] buffer;
23680 } else {
23681 unsigned long *buffer = new unsigned long[siz];
23682 cimg::fread(buffer,siz,nfile);
23683 if (endian) cimg::endian_swap(buffer,siz);
23684 T *ptrd = data;
23685 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23686 buffer-=siz;
23687 delete[] buffer;
23688 }
23689 }
23690 }
23691 break;
23692 case 13: {
23693 cimg::fread(dims,5,nfile);
23694 if (endian) cimg::endian_swap(dims,5);
23695 assign(dims[3],dims[2],dims[1],1);
23696 const unsigned int siz = size();
23697 if (dims[4]<256) {
23698 unsigned char *buffer = new unsigned char[siz];
23699 cimg::fread(buffer,siz,nfile);
23700 T *ptrd = data;
23701 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23702 buffer-=siz;
23703 delete[] buffer;
23704 } else {
23705 if (dims[4]<65536) {
23706 unsigned short *buffer = new unsigned short[siz];
23707 cimg::fread(buffer,siz,nfile);
23708 if (endian) cimg::endian_swap(buffer,siz);
23709 T *ptrd = data;
23710 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23711 buffer-=siz;
23712 delete[] buffer;
23713 } else {
23714 unsigned int *buffer = new unsigned int[siz];
23715 cimg::fread(buffer,siz,nfile);
23716 if (endian) cimg::endian_swap(buffer,siz);
23717 T *ptrd = data;
23718 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23719 buffer-=siz;
23720 delete[] buffer;
23721 }
23722 }
23723 }
23724 break;
23725 cimg_load_pandore_case(16,4,dims[2],dims[1],1,3,uchar);
23726 cimg_load_pandore_case(17,4,dims[2],dims[1],1,3,long);
23727 cimg_load_pandore_case(18,4,dims[2],dims[1],1,3,float);
23728 cimg_load_pandore_case(19,5,dims[3],dims[2],dims[1],3,uchar);
23729 cimg_load_pandore_case(20,5,dims[3],dims[2],dims[1],3,long);
23730 cimg_load_pandore_case(21,5,dims[3],dims[2],dims[1],3,float);
23731 cimg_load_pandore_case(22,2,dims[1],1,1,dims[0],uchar);
23732 cimg_load_pandore_case(23,2,dims[1],1,1,dims[0],long);
23733 cimg_load_pandore_case(24,2,dims[1],1,1,dims[0],ulong);
23734 cimg_load_pandore_case(25,2,dims[1],1,1,dims[0],float);
23735 cimg_load_pandore_case(26,3,dims[2],dims[1],1,dims[0],uchar);
23736 cimg_load_pandore_case(27,3,dims[2],dims[1],1,dims[0],long);
23737 cimg_load_pandore_case(28,3,dims[2],dims[1],1,dims[0],ulong);
23738 cimg_load_pandore_case(29,3,dims[2],dims[1],1,dims[0],float);
23739 cimg_load_pandore_case(30,4,dims[3],dims[2],dims[1],dims[0],uchar);
23740 cimg_load_pandore_case(31,4,dims[3],dims[2],dims[1],dims[0],long);
23741 cimg_load_pandore_case(32,4,dims[3],dims[2],dims[1],dims[0],ulong);
23742 cimg_load_pandore_case(33,4,dims[3],dims[2],dims[1],dims[0],float);
23743 case 34:
23744 cimg::fread(ptbuf,1,nfile);
23745 if (endian) cimg::endian_swap(ptbuf,1);
23746 assign(1); (*this)(0) = (T)ptbuf[0];
23747 break;
23748 case 35:
23749 cimg::fread(ptbuf,2,nfile);
23750 if (endian) cimg::endian_swap(ptbuf,2);
23751 assign(2); (*this)(0) = (T)ptbuf[1]; (*this)(1) = (T)ptbuf[0];
23752 break;
23753 case 36:
23754 cimg::fread(ptbuf,3,nfile);
23755 if (endian) cimg::endian_swap(ptbuf,3);
23756 assign(3); (*this)(0) = (T)ptbuf[2]; (*this)(1) = (T)ptbuf[1]; (*this)(2) = (T)ptbuf[0];
23757 break;
23758 default:
23759 if (!file) cimg::fclose(nfile);
23760 throw CImgIOException("CImg<%s>::load_pandore() : File '%s', cannot read images with ID_type=%u",
23761 pixel_type(),filename?filename:"(FILE*)",imageid);
23762 }
23763 if (!file) cimg::fclose(nfile);
23764 return *this;
23765 }
23766
23768 static CImg<T> get_load_pandore(const char *const filename) {
23769 return CImg<T>().load_pandore(0,filename);
23770 }
23771
23772 CImg<T>& load_pandore(const char *const filename) {
23773 return load_pandore(0,filename);
23774 }
23775
23777 static CImg<T> get_load_analyze(const char *const filename, float *const voxsize=0) {
23778 return CImg<T>().load_analyze(filename,voxsize);
23779 }
23780
23781 CImg<T>& load_analyze(const char *const filename, float *const voxsize=0) {
23782 std::FILE *file_header = 0, *file = 0;
23783 bool error_file = false;
23784 char body[1024];
23785 const char *ext = cimg::filename_split(filename,body);
23786 if (!cimg::strncasecmp(ext,"nii",3)) file_header = cimg::fopen(filename,"rb");
23787 else {
23788 if (!cimg::strncasecmp(ext,"hdr",3) ||
23789 !cimg::strncasecmp(ext,"img",3)) {
23790 std::sprintf(body+cimg::strlen(body),".hdr");
23791 file_header = cimg::fopen(body,"rb");
23792 if (!file_header) error_file = true;
23793 else {
23794 std::sprintf(body+cimg::strlen(body)-3,"img");
23795 file = cimg::fopen(body,"rb");
23796 if (!file) { cimg::fclose(file_header); error_file = true; }
23797 }
23798 }
23799 }
23800 if (error_file) throw CImgIOException("CImg<%s>::load_analyze() : Filename '%s', not recognized as an Analyze 7.5 or NIFTI file.",
23801 pixel_type(),filename);
23802
23803
23804 bool endian = false;
23805 unsigned int header_size;
23806 cimg::fread(&header_size,1,file_header);
23807 if (header_size>=4096) { endian = true; cimg::endian_swap(header_size); }
23808 unsigned char *header = new unsigned char[header_size];
23809 cimg::fread(header+4,header_size-4,file_header);
23810 if (file) cimg::fclose(file_header);
23811 if (endian) {
23812 cimg::endian_swap((short*)(header+40),5);
23813 cimg::endian_swap((short*)(header+70),1);
23814 cimg::endian_swap((short*)(header+72),1);
23815 cimg::endian_swap((float*)(header+76),4);
23816 cimg::endian_swap((float*)(header+112),1);
23817 }
23818 unsigned short *dim = (unsigned short*)(header+40), dimx=1, dimy=1, dimz=1, dimv=1;
23819 if (!dim[0]) cimg::warn("CImg<%s>::load_analyze() : Specified image has zero dimensions.",pixel_type());
23820 if (dim[0]>4) cimg::warn("CImg<%s>::load_analyze() : Number of image dimension is %d, reading only the 4 first dimensions",
23821 pixel_type(),dim[0]);
23822 if (dim[0]>=1) dimx = dim[1];
23823 if (dim[0]>=2) dimy = dim[2];
23824 if (dim[0]>=3) dimz = dim[3];
23825 if (dim[0]>=4) dimv = dim[4];
23826
23827 float scalefactor = *(float*)(header+112); if (scalefactor==0) scalefactor=1;
23828 const unsigned short datatype = *(short*)(header+70);
23829 if (voxsize) { const float *vsize = (float*)(header+76); voxsize[0] = vsize[1]; voxsize[1] = vsize[2]; voxsize[2] = vsize[3]; }
23830 delete[] header;
23831
23832
23833 std::FILE *nfile = file?file:file_header;
23834 assign(dimx,dimy,dimz,dimv);
23835 switch (datatype) {
23836 case 2: {
23837 unsigned char *buffer = new unsigned char[dimx*dimy*dimz*dimv];
23838 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23839 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23840 delete[] buffer;
23841 } break;
23842 case 4: {
23843 short *buffer = new short[dimx*dimy*dimz*dimv];
23844 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23845 if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
23846 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23847 delete[] buffer;
23848 } break;
23849 case 8: {
23850 int *buffer = new int[dimx*dimy*dimz*dimv];
23851 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23852 if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
23853 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23854 delete[] buffer;
23855 } break;
23856 case 16: {
23857 float *buffer = new float[dimx*dimy*dimz*dimv];
23858 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23859 if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
23860 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23861 delete[] buffer;
23862 } break;
23863 case 64: {
23864 double *buffer = new double[dimx*dimy*dimz*dimv];
23865 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23866 if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
23867 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23868 delete[] buffer;
23869 } break;
23870 default:
23871 cimg::fclose(nfile);
23872 throw CImgIOException("CImg<%s>::load_analyze() : File '%s, cannot read images with 'datatype = %d'",
23873 pixel_type(),filename,datatype);
23874 }
23875 cimg::fclose(nfile);
23876 return *this;
23877 }
23878
23880 template<typename tf, typename tc>
23881 static CImg<T> get_load_off(const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors,
23882 const bool invert_faces=false) {
23883 return CImg<T>().load_off(filename,primitives,colors,invert_faces);
23884 }
23885
23886 template<typename tf, typename tc>
23887 CImg<T>& load_off(const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors, const bool invert_faces=false) {
23888 std::FILE *file=cimg::fopen(filename,"r");
23889 unsigned int nb_points = 0, nb_primitives = 0, nb_read = 0;
23890 char line[256] = { 0 };
23891 int err;
23892
23893
23894 do { err = std::fscanf(file,"%255[^\n] ",line); } while (!err || (err==1 && line[0]=='#'));
23895 if (cimg::strncasecmp(line,"OFF",3) && cimg::strncasecmp(line,"COFF",4)) {
23896 cimg::fclose(file);
23897 throw CImgIOException("CImg<%s>::load_off() : File '%s', keyword 'OFF' not found.",pixel_type(),filename);
23898 }
23899 do { err = std::fscanf(file,"%255[^\n] ",line); } while (!err || (err==1 && line[0]=='#'));
23900
23901 if ((err = std::sscanf(line,"%u%u%*[^\n] ",&nb_points,&nb_primitives))!=2) {
23902 cimg::fclose(file);
23903 throw CImgIOException("CImg<%s>::load_off() : File '%s', invalid vertices/primitives numbers.",pixel_type(),filename);
23904 }
23905
23906
23907 assign(nb_points,3);
23908 float X = 0, Y = 0, Z = 0;
23909 cimg_forX(*this,l) {
23910 do { err = std::fscanf(file,"%255[^\n] ",line); } while (!err || (err==1 && line[0]=='#'));
23911 if ((err = std::sscanf(line,"%f%f%f%*[^\n] ",&X,&Y,&Z))!=3) {
23912 cimg::fclose(file);
23913 throw CImgIOException("CImg<%s>::load_off() : File '%s', cannot read point %u/%u.\n",pixel_type(),filename,l+1,nb_points);
23914 }
23915 (*this)(l,0) = (T)X; (*this)(l,1) = (T)Y; (*this)(l,2) = (T)Z;
23916 }
23917
23918
23919 primitives.assign();
23920 colors.assign();
23921 bool stopflag = false;
23922 while (!stopflag) {
23923 float c0 = 0.7f, c1 = 0.7f, c2 = 0.7f;
23924 unsigned int prim = 0, i0 = 0, i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
23925 line[0]='\0';
23926 if ((err = std::fscanf(file,"%u",&prim))!=1) stopflag=true;
23927 else {
23928 ++nb_read;
23929 switch (prim) {
23930 case 1: {
23931 if ((err = std::fscanf(file,"%u%255[^\n] ",&i0,line))<2) {
23932 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
23933 pixel_type(),filename,nb_read,nb_primitives);
23934 std::fscanf(file,"%*[^\n] ");
23935 } else {
23936 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
23937 primitives.insert(CImg<tf>::vector(i0));
23938 colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
23939 }
23940 } break;
23941 case 2: {
23942 if ((err = std::fscanf(file,"%u%u%255[^\n] ",&i0,&i1,line))<2) {
23943 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
23944 pixel_type(),filename,nb_read,nb_primitives);
23945 std::fscanf(file,"%*[^\n] ");
23946 } else {
23947 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
23948 primitives.insert(CImg<tf>::vector(i0,i1));
23949 colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
23950 }
23951 } break;
23952 case 3: {
23953 if ((err = std::fscanf(file,"%u%u%u%255[^\n] ",&i0,&i1,&i2,line))<3) {
23954 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
23955 pixel_type(),filename,nb_read,nb_primitives);
23956 std::fscanf(file,"%*[^\n] ");
23957 } else {
23958 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
23959 if (invert_faces) primitives.insert(CImg<tf>::vector(i0,i1,i2));
23960 else primitives.insert(CImg<tf>::vector(i0,i2,i1));
23961 colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
23962 }
23963 } break;
23964 case 4: {
23965 if ((err = std::fscanf(file,"%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,line))<4) {
23966 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
23967 pixel_type(),filename,nb_read,nb_primitives);
23968 std::fscanf(file,"%*[^\n] ");
23969 } else {
23970 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
23971 if (invert_faces) primitives.insert(CImg<tf>::vector(i0,i1,i2,i3));
23972 else primitives.insert(CImg<tf>::vector(i0,i3,i2,i1));
23973 colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
23974 }
23975 } break;
23976 case 5: {
23977 if ((err = std::fscanf(file,"%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,line))<5) {
23978 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
23979 pixel_type(),filename,nb_read,nb_primitives);
23980 std::fscanf(file,"%*[^\n] ");
23981 } else {
23982 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
23983 if (invert_faces) {
23984 primitives.insert(CImg<tf>::vector(i0,i1,i2,i3));
23985 primitives.insert(CImg<tf>::vector(i0,i3,i4));
23986 }
23987 else {
23988 primitives.insert(CImg<tf>::vector(i0,i3,i2,i1));
23989 primitives.insert(CImg<tf>::vector(i0,i4,i3));
23990 }
23991 colors.insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
23992 ++nb_primitives;
23993 }
23994 } break;
23995 case 6: {
23996 if ((err = std::fscanf(file,"%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,line))<6) {
23997 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
23998 pixel_type(),filename,nb_read,nb_primitives);
23999 std::fscanf(file,"%*[^\n] ");
24000 } else {
24001 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24002 if (invert_faces) {
24003 primitives.insert(CImg<tf>::vector(i0,i1,i2,i3));
24004 primitives.insert(CImg<tf>::vector(i0,i3,i4,i5));
24005 }
24006 else {
24007 primitives.insert(CImg<tf>::vector(i0,i3,i2,i1));
24008 primitives.insert(CImg<tf>::vector(i0,i5,i4,i3));
24009 }
24010 colors.insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
24011 ++nb_primitives;
24012 }
24013 } break;
24014 case 7: {
24015 if ((err = std::fscanf(file,"%u%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,&i6,line))<7) {
24016 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
24017 pixel_type(),filename,nb_read,nb_primitives);
24018 std::fscanf(file,"%*[^\n] ");
24019 } else {
24020 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24021 if (invert_faces) {
24022 primitives.insert(CImg<tf>::vector(i0,i1,i3,i4));
24023 primitives.insert(CImg<tf>::vector(i0,i4,i5,i6));
24024 primitives.insert(CImg<tf>::vector(i1,i2,i3));
24025 }
24026 else {
24027 primitives.insert(CImg<tf>::vector(i0,i4,i3,i1));
24028 primitives.insert(CImg<tf>::vector(i0,i6,i5,i4));
24029 primitives.insert(CImg<tf>::vector(i3,i2,i1));
24030 }
24031 colors.insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
24032 ++(++nb_primitives);
24033 }
24034 } break;
24035 case 8: {
24036 if ((err = std::fscanf(file,"%u%u%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7,line))<7) {
24037 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
24038 pixel_type(),filename,nb_read,nb_primitives);
24039 std::fscanf(file,"%*[^\n] ");
24040 } else {
24041 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24042 if (invert_faces) {
24043 primitives.insert(CImg<tf>::vector(i0,i1,i2,i3));
24044 primitives.insert(CImg<tf>::vector(i0,i3,i4,i5));
24045 primitives.insert(CImg<tf>::vector(i0,i5,i6,i7));
24046 }
24047 else {
24048 primitives.insert(CImg<tf>::vector(i0,i3,i2,i1));
24049 primitives.insert(CImg<tf>::vector(i0,i5,i4,i3));
24050 primitives.insert(CImg<tf>::vector(i0,i7,i6,i5));
24051 }
24052 colors.insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
24053 ++(++nb_primitives);
24054 }
24055 } break;
24056 default:
24057 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u (%u vertices).",
24058 pixel_type(),filename,nb_read,nb_primitives,prim);
24059 std::fscanf(file,"%*[^\n] ");
24060 break;
24061 }
24062 }
24063 }
24064 cimg::fclose(file);
24065 if (primitives.size!=nb_primitives)
24066 cimg::warn("CImg<%s>::load_off() : File '%s', read only %u primitives instead of %u as claimed in the header.",
24067 pixel_type(),filename,primitives.size,nb_primitives);
24068 return *this;
24069 }
24070
24072 static CImg<T> get_load_dicom(const char *const filename) {
24073 return CImg<T>().load_dicom(filename);
24074 }
24075
24076 CImg<T>& load_dicom(const char *const filename) {
24077 char command[1024], filetmp[512], body[512];
24078 cimg::fclose(cimg::fopen(filename,"r"));
24079 std::FILE *file;
24080 do {
24081 std::sprintf(filetmp,"%s.hdr",cimg::filenamerand());
24082 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24083 } while (file);
24084 std::sprintf(command,"%s -w -c anlz -o %s -f %s",cimg::medcon_path(),filetmp,filename);
24085 cimg::system(command);
24086 cimg::filename_split(filetmp,body);
24087 std::sprintf(command,"m000-%s.hdr",body);
24088 file = std::fopen(command,"rb");
24089 if (!file) {
24090 throw CImgIOException("CImg<%s>::load_dicom() : Failed to open image '%s'.\n\n"
24091 "Path of 'medcon' : \"%s\"\n"
24092 "Path of temporary filename : \"%s\"",
24093 pixel_type(),filename,cimg::medcon_path(),filetmp);
24094 } else cimg::fclose(file);
24095 load_analyze(command);
24096 std::remove(command);
24097 std::sprintf(command,"m000-%s.img",body);
24098 std::remove(command);
24099 return *this;
24100 }
24101
24103 static CImg<T> get_load_imagemagick(const char *const filename) {
24104 return CImg<T>().load_imagemagick(filename);
24105 }
24106
24107 CImg<T>& load_imagemagick(const char *const filename) {
24108 char command[1024], filetmp[512];
24109 std::FILE *file = 0;
24110 do {
24111 std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24112 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24113 } while (file);
24114 std::sprintf(command,"%s \"%s\" %s",cimg::imagemagick_path(),filename,filetmp);
24115 cimg::system(command,cimg::imagemagick_path());
24116 if (!(file = std::fopen(filetmp,"rb"))) {
24117 cimg::fclose(cimg::fopen(filename,"r"));
24118 throw CImgIOException("CImg<%s>::load_imagemagick() : Failed to open image '%s'.\n\n"
24119 "Path of 'ImageMagick's convert' : \"%s\"\n"
24120 "Path of temporary filename : \"%s\"",
24121 pixel_type(),filename,cimg::imagemagick_path(),filetmp);
24122 } else cimg::fclose(file);
24123 load_pnm(filetmp);
24124 std::remove(filetmp);
24125 return *this;
24126 }
24127
24129 static CImg<T> get_load_graphicsmagick(const char *const filename) {
24130 return CImg<T>().load_graphicsmagick(filename);
24131 }
24132
24133 CImg<T>& load_graphicsmagick(const char *const filename) {
24134 char command[1024], filetmp[512];
24135 std::FILE *file = 0;
24136 do {
24137 std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24138 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24139 } while (file);
24140 std::sprintf(command,"%s convert \"%s\" %s",cimg::graphicsmagick_path(),filename,filetmp);
24141 cimg::system(command,cimg::graphicsmagick_path());
24142 if (!(file = std::fopen(filetmp,"rb"))) {
24143 cimg::fclose(cimg::fopen(filename,"r"));
24144 throw CImgIOException("CImg<%s>::load_graphicsmagick() : Failed to open image '%s'.\n\n"
24145 "Path of 'GraphicsMagick's gm' : \"%s\"\n"
24146 "Path of temporary filename : \"%s\"",
24147 pixel_type(),filename,cimg::graphicsmagick_path(),filetmp);
24148 } else cimg::fclose(file);
24149 load_pnm(filetmp);
24150 std::remove(filetmp);
24151 return *this;
24152 }
24153
24155 static CImg<T> get_load_other(const char *const filename) {
24156 return CImg<T>().load_other(filename);
24157 }
24158
24159 CImg<T>& load_other(const char *const filename) {
24160 const unsigned int odebug = cimg::exception_mode();
24161 cimg::exception_mode() = 0;
24162 try { load_magick(filename); }
24163 catch (CImgException&) {
24164 try { load_imagemagick(filename); }
24165 catch (CImgException&) {
24166 try { load_graphicsmagick(filename); }
24167 catch (CImgException&) {
24168 assign();
24169 }
24170 }
24171 }
24172 cimg::exception_mode() = odebug;
24173 if (is_empty())
24174 throw CImgIOException("CImg<%s>::load_other() : Failed to open image '%s'.\n"
24175 "Check you have either the ImageMagick or GraphicsMagick package installed.",
24176 pixel_type(),filename);
24177 return *this;
24178 }
24179
24181 static CImg<T> get_load_parrec(const char *const filename, const char axis='v', const char align='p') {
24182 return CImg<T>().load_parrec(filename,axis,align);
24183 }
24184
24185 CImg<T>& load_parrec(const char *const filename, const char axis='v', const char align='p') {
24186 CImgList<T> list;
24187 list.load_parrec(filename);
24188 if (list.size==1) return list[0].assign_to(*this);
24189 return assign(list.get_append(axis,align));
24190 }
24191
24193 static CImg<T> get_load_cimg(std::FILE *const file, const char axis='z', const char align='p') {
24194 return CImg<T>().load_cimg(file,axis,align);
24195 }
24196
24197 CImg<T>& load_cimg(std::FILE *const file, const char axis='z', const char align='p') {
24198 CImgList<T> list;
24199 list.load_cimg(file);
24200 if (list.size==1) return list[0].assign_to(*this);
24201 return assign(list.get_append(axis,align));
24202 }
24203
24205 static CImg<T> get_load_cimg(const char *const filename, const char axis='z', const char align='p') {
24206 return CImg<T>().load_cimg(filename,axis,align);
24207 }
24208
24209 CImg<T>& load_cimg(const char *const filename, const char axis='z', const char align='p') {
24210 CImgList<T> list;
24211 list.load_cimg(filename);
24212 if (list.size==1) return list[0].assign_to(*this);
24213 return assign(list.get_append(axis,align));
24214 }
24215
24217 static CImg<T> get_load_cimg(std::FILE *const file,
24218 const unsigned int n0, const unsigned int n1,
24219 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
24220 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1,
24221 const char axis='z', const char align='p') {
24222 return CImg<T>().load_cimg(file,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1,axis,align);
24223 }
24224
24225 CImg<T>& load_cimg(std::FILE *const file,
24226 const unsigned int n0, const unsigned int n1,
24227 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
24228 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1,
24229 const char axis='z', const char align='p') {
24230 CImgList<T> list;
24231 list.load_cimg(file,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
24232 if (list.size==1) return list[0].assign_to(*this);
24233 return assign(list.get_append(axis,align));
24234 }
24235
24237 static CImg<T> get_load_cimg(const char *const filename,
24238 const unsigned int n0, const unsigned int n1,
24239 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
24240 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1,
24241 const char axis='z', const char align='p') {
24242 return CImg<T>().load_cimg(filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1,axis,align);
24243 }
24244
24245 CImg<T>& load_cimg(const char *const filename,
24246 const unsigned int n0, const unsigned int n1,
24247 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
24248 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1,
24249 const char axis='z', const char align='p') {
24250 CImgList<T> list;
24251 list.load_cimg(filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
24252 if (list.size==1) return list[0].assign_to(*this);
24253 return assign(list.get_append(axis,align));
24254 }
24255
24257 static CImg<T> get_load_yuv(std::FILE *const file, const char *const filename,
24258 const unsigned int sizex, const unsigned int sizey=1,
24259 const unsigned int first_frame=0, const int last_frame=-1,
24260 const bool yuv2rgb = false, const char axis='z', const char align='p') {
24261 return CImgList<T>().load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb).get_append(axis,align);
24262 }
24263
24264 CImg<T>& load_yuv(std::FILE *const file, const char *const filename,
24265 const unsigned int sizex, const unsigned int sizey=1,
24266 const unsigned int first_frame=0, const int last_frame=-1,
24267 const bool yuv2rgb = false, const char axis='z', const char align='p') {
24268 return get_load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb,axis,align).assign_to(*this);
24269 }
24270
24272 static CImg<T> get_load_yuv(const char *const filename,
24273 const unsigned int sizex, const unsigned int sizey=1,
24274 const unsigned int first_frame=0, const int last_frame=-1,
24275 const bool yuv2rgb = false, const char axis='z', const char align='p') {
24276 return CImgList<T>().load_yuv(filename,sizex,sizey,first_frame,last_frame,yuv2rgb).get_append(axis,align);
24277 }
24278
24279 CImg<T>& load_yuv(const char *const filename,
24280 const unsigned int sizex, const unsigned int sizey=1,
24281 const unsigned int first_frame=0, const int last_frame=-1,
24282 const bool yuv2rgb = false, const char axis='z', const char align='p') {
24283 return get_load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb,axis,align).assign_to(*this);
24284 }
24285
24287
24292 const CImg<T>& save(const char *const filename, const int number=-1) const {
24293 if (is_empty()) throw CImgInstanceException("CImg<%s>::save() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24294 pixel_type(),width,height,depth,dim,data,filename);
24295 if (!filename) throw CImgArgumentException("CImg<%s>::save() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24296 pixel_type(),width,height,depth,dim,data);
24297 const char *ext = cimg::filename_split(filename);
24298 char nfilename[1024];
24299 const char *const fn = (number>=0)?cimg::filename_number(filename,number,6,nfilename):filename;
24300 #ifdef cimg_save_plugin
24301 cimg_save_plugin(fn);
24302 #endif
24303 if (!cimg::strncasecmp(ext,"asc",3)) return save_ascii(fn);
24304 if (!cimg::strncasecmp(ext,"dlm",3) ||
24305 !cimg::strncasecmp(ext,"txt",3)) return save_dlm(fn);
24306 if (!cimg::strncasecmp(ext,"inr",3)) return save_inr(fn);
24307 if (!cimg::strncasecmp(ext,"hdr",3) ||
24308 !cimg::strncasecmp(ext,"nii",3)) return save_analyze(fn);
24309 if (!cimg::strncasecmp(ext,"dcm",3)) return save_dicom(fn);
24310 if (!cimg::strncasecmp(ext,"pan",3)) return save_pandore(fn);
24311 if (!cimg::strncasecmp(ext,"bmp",3)) return save_bmp(fn);
24312 if (!cimg::strncasecmp(ext,"png",3)) return save_png(fn);
24313 if (!cimg::strncasecmp(ext,"tif",3)) return save_tiff(fn);
24314 if (!cimg::strncasecmp(ext,"jpg",3) ||
24315 !cimg::strncasecmp(ext,"jpeg",4)) return save_jpeg(fn);
24316 if (!cimg::strncasecmp(ext,"rgba",4)) return save_rgba(fn);
24317 if (!cimg::strncasecmp(ext,"rgb",3)) return save_rgb(fn);
24318 if (!cimg::strncasecmp(ext,"raw",3)) return save_raw(fn);
24319 if (!cimg::strncasecmp(ext,"cimg",4) || ext[0]=='\0') return save_cimg(fn);
24320 if (!cimg::strncasecmp(ext,"pgm",3) ||
24321 !cimg::strncasecmp(ext,"ppm",3) ||
24322 !cimg::strncasecmp(ext,"pnm",3)) return save_pnm(fn);
24323 if (!cimg::strncasecmp(ext,"yuv",3)) return save_yuv(fn,true);
24324 return save_other(fn);
24325 }
24326
24328 const CImg<T>& save_ascii(std::FILE *const file, const char *const filename=0) const {
24329 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_ascii() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24330 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24331 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_ascii() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24332 pixel_type(),width,height,depth,dim,data);
24333 std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
24334 std::fprintf(nfile,"%u %u %u %u\n",width,height,depth,dim);
24335 const T* ptrs = data;
24336 cimg_forYZV(*this,y,z,v) {
24337 cimg_forX(*this,x) std::fprintf(nfile,"%g ",(double)*(ptrs++));
24338 std::fputc('\n',nfile);
24339 }
24340 if (!file) cimg::fclose(nfile);
24341 return *this;
24342 }
24343
24345 const CImg<T>& save_ascii(const char *const filename) const {
24346 return save_ascii(0,filename);
24347 }
24348
24350 const CImg<T>& save_dlm(std::FILE *const file, const char *const filename=0) const {
24351 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24352 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24353 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24354 pixel_type(),width,height,depth,dim,data);
24355 if (depth>1)
24356 cimg::warn("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is volumetric. Pixel values along Z will be unrolled (file '%s').",
24357 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24358 if (dim>1)
24359 cimg::warn("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is multispectral. Pixel values along V will be unrolled (file '%s').",
24360 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24361
24362 std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
24363 const T* ptrs = data;
24364 cimg_forYZV(*this,y,z,v) {
24365 cimg_forX(*this,x) std::fprintf(nfile,"%g%s",(double)*(ptrs++),(x==dimx()-1)?"":",");
24366 std::fputc('\n',nfile);
24367 }
24368 if (!file) cimg::fclose(nfile);
24369 return *this;
24370 }
24371
24373 const CImg<T>& save_dlm(const char *const filename) const {
24374 return save_dlm(0,filename);
24375 }
24376
24378 const CImg<T>& save_pnm(std::FILE *const file, const char *const filename=0) const {
24379 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24380 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24381 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24382 pixel_type(),width,height,depth,dim,data);
24383 double stmin, stmax = (double)maxmin(stmin);
24384 if (depth>1)
24385 cimg::warn("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
24386 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24387 if (dim>3)
24388 cimg::warn("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is multispectral. Only the three first channels will be saved (file '%s').",
24389 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24390 if (stmin<0 || stmax>65535) cimg::warn("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) has pixel values in [%g,%g]. Probable type overflow (file '%s').",pixel_type(),width,height,depth,dim,data,stmin,stmax,filename?filename:"(unknown)");
24391 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
24392 const T
24393 *ptrR = ptr(0,0,0,0),
24394 *ptrG = (dim>=2)?ptr(0,0,0,1):ptrR,
24395 *ptrB = (dim>=3)?ptr(0,0,0,2):ptrR;
24396 const unsigned int buf_size = width*height*(dim==1?1:3);
24397
24398 std::fprintf(nfile,"P%c\n# CREATOR: CImg : Original size=%ux%ux%ux%u\n%u %u\n%u\n",
24399 (dim==1?'5':'6'),width,height,depth,dim,width,height,stmax<256?255:65535);
24400
24401 switch(dim) {
24402 case 1: {
24403 if (stmax<256) {
24404 unsigned char *ptrd = new unsigned char[buf_size], *xptrd = ptrd;
24405 cimg_forXY(*this,x,y) *(xptrd++) = (unsigned char)*(ptrR++);
24406 cimg::fwrite(ptrd,buf_size,nfile);
24407 delete[] ptrd;
24408 } else {
24409 unsigned short *ptrd = new unsigned short[buf_size], *xptrd = ptrd;
24410 cimg_forXY(*this,x,y) *(xptrd++) = (unsigned short)*(ptrR++);
24411 if (!cimg::endian()) cimg::endian_swap(ptrd,buf_size);
24412 cimg::fwrite(ptrd,buf_size,nfile);
24413 delete[] ptrd;
24414 }
24415 } break;
24416 default: {
24417 if (stmax<256) {
24418 unsigned char *ptrd = new unsigned char[buf_size], *xptrd = ptrd;
24419 cimg_forXY(*this,x,y) {
24420 *(xptrd++) = (unsigned char)*(ptrR++);
24421 *(xptrd++) = (unsigned char)*(ptrG++);
24422 *(xptrd++) = (unsigned char)*(ptrB++);
24423 }
24424 cimg::fwrite(ptrd,buf_size,nfile);
24425 delete[] ptrd;
24426 } else {
24427 unsigned short *ptrd = new unsigned short[buf_size], *xptrd = ptrd;
24428 cimg_forXY(*this,x,y) {
24429 *(xptrd++) = (unsigned short)*(ptrR++);
24430 *(xptrd++) = (unsigned short)*(ptrG++);
24431 *(xptrd++) = (unsigned short)*(ptrB++);
24432 }
24433 if (!cimg::endian()) cimg::endian_swap(ptrd,buf_size);
24434 cimg::fwrite(ptrd,buf_size,nfile);
24435 delete[] ptrd;
24436 }
24437 } break;
24438 }
24439 if (!file) cimg::fclose(nfile);
24440 return *this;
24441 }
24442
24444 const CImg<T>& save_pnm(const char *const filename) const {
24445 return save_pnm(0,filename);
24446 }
24447
24449 const CImg<T>& save_dicom(const char *const filename) const {
24450 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_dicom() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24451 pixel_type(),width,height,depth,dim,data,filename);
24452 if (!filename) throw CImgArgumentException("CImg<%s>::save_dicom() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24453 pixel_type(),width,height,depth,dim,data);
24454 char command[1024], filetmp[512], body[512];
24455 std::FILE *file;
24456 do {
24457 std::sprintf(filetmp,"%s.hdr",cimg::filenamerand());
24458 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24459 } while (file);
24460 save_analyze(filetmp);
24461 std::sprintf(command,"%s -w -c dicom -o %s -f %s",cimg::medcon_path(),filename,filetmp);
24462 cimg::system(command);
24463 std::remove(filetmp);
24464 cimg::filename_split(filetmp,body);
24465 std::sprintf(filetmp,"%s.img",body);
24466 std::remove(filetmp);
24467 std::sprintf(command,"m000-%s",filename);
24468 file = std::fopen(command,"rb");
24469 if (!file) {
24470 cimg::fclose(cimg::fopen(filename,"r"));
24471 throw CImgIOException("CImg<%s>::save_dicom() : Failed to save image '%s'.\n\n"
24472 "Path of 'medcon' : \"%s\"\n"
24473 "Path of temporary filename : \"%s\"",
24474 pixel_type(),filename,cimg::medcon_path(),filetmp);
24475 } else cimg::fclose(file);
24476 std::rename(command,filename);
24477 return *this;
24478 }
24479
24481 const CImg<T>& save_analyze(const char *const filename, const float *const voxsize=0) const {
24482 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_analyze() : File '%s', instance image (%u,%u,%u,%u,%p) is empty.",
24483 pixel_type(),width,height,depth,dim,data,filename);
24484 if (!filename) throw CImgArgumentException("CImg<%s>::save_analyze() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24485 pixel_type(),width,height,depth,dim,data);
24486 std::FILE *file;
24487 char header[348], hname[1024], iname[1024];
24488 const char *ext = cimg::filename_split(filename);
24489 short datatype=-1;
24490 std::memset(header,0,348);
24491 if (!ext[0]) { std::sprintf(hname,"%s.hdr",filename); std::sprintf(iname,"%s.img",filename); }
24492 if (!cimg::strncasecmp(ext,"hdr",3)) {
24493 std::strcpy(hname,filename); std::strcpy(iname,filename); std::sprintf(iname+cimg::strlen(iname)-3,"img");
24494 }
24495 if (!cimg::strncasecmp(ext,"img",3)) {
24496 std::strcpy(hname,filename); std::strcpy(iname,filename); std::sprintf(hname+cimg::strlen(iname)-3,"hdr");
24497 }
24498 if (!cimg::strncasecmp(ext,"nii",3)) {
24499 std::strcpy(hname,filename); iname[0] = 0;
24500 }
24501 ((int*)(header))[0] = 348;
24502 std::sprintf(header+4,"CImg");
24503 std::sprintf(header+14," ");
24504 ((short*)(header+36))[0] = 4096;
24505 ((char*)(header+38))[0] = 114;
24506 ((short*)(header+40))[0] = 4;
24507 ((short*)(header+40))[1] = width;
24508 ((short*)(header+40))[2] = height;
24509 ((short*)(header+40))[3] = depth;
24510 ((short*)(header+40))[4] = dim;
24511 if (!cimg::strcasecmp(pixel_type(),"bool")) datatype = 2;
24512 if (!cimg::strcasecmp(pixel_type(),"unsigned char")) datatype = 2;
24513 if (!cimg::strcasecmp(pixel_type(),"char")) datatype = 2;
24514 if (!cimg::strcasecmp(pixel_type(),"unsigned short")) datatype = 4;
24515 if (!cimg::strcasecmp(pixel_type(),"short")) datatype = 4;
24516 if (!cimg::strcasecmp(pixel_type(),"unsigned int")) datatype = 8;
24517 if (!cimg::strcasecmp(pixel_type(),"int")) datatype = 8;
24518 if (!cimg::strcasecmp(pixel_type(),"unsigned long")) datatype = 8;
24519 if (!cimg::strcasecmp(pixel_type(),"long")) datatype = 8;
24520 if (!cimg::strcasecmp(pixel_type(),"float")) datatype = 16;
24521 if (!cimg::strcasecmp(pixel_type(),"double")) datatype = 64;
24522 if (datatype<0)
24523 throw CImgIOException("CImg<%s>::save_analyze() : Cannot save image '%s' since pixel type (%s)"
24524 "is not handled in Analyze7.5 specifications.\n",
24525 pixel_type(),filename,pixel_type());
24526 ((short*)(header+70))[0] = datatype;
24527 ((short*)(header+72))[0] = sizeof(T);
24528 ((float*)(header+112))[0] = 1;
24529 ((float*)(header+76))[0] = 0;
24530 if (voxsize) {
24531 ((float*)(header+76))[1] = voxsize[0];
24532 ((float*)(header+76))[2] = voxsize[1];
24533 ((float*)(header+76))[3] = voxsize[2];
24534 } else ((float*)(header+76))[1] = ((float*)(header+76))[2] = ((float*)(header+76))[3] = 1;
24535 file = cimg::fopen(hname,"wb");
24536 cimg::fwrite(header,348,file);
24537 if (iname[0]) { cimg::fclose(file); file = cimg::fopen(iname,"wb"); }
24538 cimg::fwrite(data,size(),file);
24539 cimg::fclose(file);
24540 return *this;
24541 }
24542
24544 const CImg<T>& save_cimg(std::FILE *const file, const char *const filename=0) const {
24545 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_cimg() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24546 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24547 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24548 pixel_type(),width,height,depth,dim,data);
24549 CImgList<T> tmp(1);
24550 tmp[0].width = width;
24551 tmp[0].height = height;
24552 tmp[0].depth = depth;
24553 tmp[0].dim = dim;
24554 tmp[0].data = data;
24555 tmp.save_cimg(file,filename);
24556 tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0;
24557 tmp[0].data = 0;
24558 return *this;
24559 }
24560
24562 const CImg<T>& save_cimg(const char *const filename) const {
24563 return save_cimg(0,filename);
24564 }
24565
24567 const CImg<T>& save_cimg(std::FILE *const file,
24568 const unsigned int n0,
24569 const unsigned int x0, const unsigned int y0,
24570 const unsigned int z0, const unsigned int v0) const {
24571 CImgList<T> tmp(1);
24572 tmp[0].width = width;
24573 tmp[0].height = height;
24574 tmp[0].depth = depth;
24575 tmp[0].dim = dim;
24576 tmp[0].data = data;
24577 tmp.save_cimg(file,n0,x0,y0,z0,v0);
24578 tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0;
24579 tmp[0].data = 0;
24580 return *this;
24581 }
24582
24584 const CImg<T>& save_cimg(const char *const filename,
24585 const unsigned int n0,
24586 const unsigned int x0, const unsigned int y0,
24587 const unsigned int z0, const unsigned int v0) const {
24588 CImgList<T> tmp(1);
24589 tmp[0].width = width;
24590 tmp[0].height = height;
24591 tmp[0].depth = depth;
24592 tmp[0].dim = dim;
24593 tmp[0].data = data;
24594 tmp.save_cimg(filename,n0,x0,y0,z0,v0);
24595 tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0;
24596 tmp[0].data = 0;
24597 return *this;
24598 }
24599
24601 static void save_empty_cimg(std::FILE *const file,
24602 const unsigned int dx, const unsigned int dy=1,
24603 const unsigned int dz=1, const unsigned int dv=1) {
24604 return CImgList<T>::save_empty_cimg(file,1,dx,dy,dz,dv);
24605 }
24606
24608 static void save_empty_cimg(const char *const filename,
24609 const unsigned int dx, const unsigned int dy=1,
24610 const unsigned int dz=1, const unsigned int dv=1) {
24611 return CImgList<T>::save_empty_cimg(filename,1,dx,dy,dz,dv);
24612 }
24613
24615 const CImg<T>& save_raw(std::FILE *const file, const char *const filename=0, const bool multiplexed=false) const {
24616 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_raw() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24617 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24618 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_raw() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24619 pixel_type(),width,height,depth,dim,data);
24620 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
24621 if (!multiplexed) cimg::fwrite(data,size(),nfile);
24622 else {
24623 CImg<T> buf(dim);
24624 cimg_forXYZ(*this,x,y,z) {
24625 cimg_forV(*this,k) buf[k] = (*this)(x,y,z,k);
24626 cimg::fwrite(buf.data,dim,nfile);
24627 }
24628 }
24629 if (!file) cimg::fclose(nfile);
24630 return *this;
24631 }
24632
24634 const CImg<T>& save_raw(const char *const filename=0, const bool multiplexed=false) const {
24635 return save_raw(0,filename,multiplexed);
24636 }
24637
24639
24645 const CImg<T>& save_imagemagick(const char *const filename, const unsigned int quality=100) const {
24646 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_imagemagick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s')",
24647 pixel_type(),width,height,depth,dim,data,filename);
24648 if (!filename) throw CImgArgumentException("CImg<%s>::save_imagemagick() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24649 pixel_type(),width,height,depth,dim,data);
24650 char command[1024],filetmp[512];
24651 std::FILE *file;
24652 do {
24653 if (dim==1) std::sprintf(filetmp,"%s%s%s.pgm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24654 else std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24655 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24656 } while (file);
24657 save_pnm(filetmp);
24658 std::sprintf(command,"%s -quality %u%% %s \"%s\"",cimg::imagemagick_path(),quality,filetmp,filename);
24659 cimg::system(command);
24660 file = std::fopen(filename,"rb");
24661 if (!file) throw CImgIOException("CImg<%s>::save_imagemagick() : Failed to save image '%s'.\n\n"
24662 "Path of 'convert' : \"%s\"\n"
24663 "Path of temporary filename : \"%s\"\n",
24664 pixel_type(),filename,cimg::imagemagick_path(),filetmp);
24665 if (file) cimg::fclose(file);
24666 std::remove(filetmp);
24667 return *this;
24668 }
24669
24671
24677 const CImg<T>& save_graphicsmagick(const char *const filename, const unsigned int quality=100) const {
24678 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_graphicsmagick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s')",
24679 pixel_type(),width,height,depth,dim,data,filename);
24680 if (!filename) throw CImgArgumentException("CImg<%s>::save_graphicsmagick() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24681 pixel_type(),width,height,depth,dim,data);
24682 char command[1024],filetmp[512];
24683 std::FILE *file;
24684 do {
24685 if (dim==1) std::sprintf(filetmp,"%s%s%s.pgm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24686 else std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24687 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24688 } while (file);
24689 save_pnm(filetmp);
24690 std::sprintf(command,"%s -quality %u%% %s \"%s\"",cimg::graphicsmagick_path(),quality,filetmp,filename);
24691 cimg::system(command);
24692 file = std::fopen(filename,"rb");
24693 if (!file) throw CImgIOException("CImg<%s>::save_graphicsmagick() : Failed to save image '%s'.\n\n"
24694 "Path of 'gm' : \"%s\"\n"
24695 "Path of temporary filename : \"%s\"\n",
24696 pixel_type(),filename,cimg::graphicsmagick_path(),filetmp);
24697 if (file) cimg::fclose(file);
24698 std::remove(filetmp);
24699 return *this;
24700 }
24701
24702 const CImg<T>& save_other(const char *const filename, const unsigned int quality=100) const {
24703 const unsigned int odebug = cimg::exception_mode();
24704 bool is_saved = true;
24705 cimg::exception_mode() = 0;
24706 try { save_magick(filename); }
24707 catch (CImgException&) {
24708 try { save_imagemagick(filename,quality); }
24709 catch (CImgException&) {
24710 try { save_graphicsmagick(filename,quality); }
24711 catch (CImgException&) {
24712 is_saved = false;
24713 }
24714 }
24715 }
24716 cimg::exception_mode() = odebug;
24717 if (!is_saved) throw CImgIOException("CImg<%s>::save_other() : File '%s' cannot be saved.\n"
24718 "Check you have either the ImageMagick or GraphicsMagick package installed.",
24719 pixel_type(),filename);
24720 return *this;
24721 }
24722
24724 const CImg<T>& save_inr(std::FILE *const file, const char *const filename=0, const float *const voxsize=0) const {
24725 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_inr() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24726 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24727 if (!filename) throw CImgArgumentException("CImg<%s>::save_inr() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24728 pixel_type(),width,height,depth,dim,data);
24729 int inrpixsize=-1;
24730 const char *inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0";
24731 if (!cimg::strcasecmp(pixel_type(),"unsigned char")) { inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; }
24732 if (!cimg::strcasecmp(pixel_type(),"char")) { inrtype = "fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; }
24733 if (!cimg::strcasecmp(pixel_type(),"unsigned short")) { inrtype = "unsigned fixed\nPIXSIZE=16 bits\nSCALE=2**0";inrpixsize = 2; }
24734 if (!cimg::strcasecmp(pixel_type(),"short")) { inrtype = "fixed\nPIXSIZE=16 bits\nSCALE=2**0"; inrpixsize = 2; }
24735 if (!cimg::strcasecmp(pixel_type(),"unsigned int")) { inrtype = "unsigned fixed\nPIXSIZE=32 bits\nSCALE=2**0";inrpixsize = 4; }
24736 if (!cimg::strcasecmp(pixel_type(),"int")) { inrtype = "fixed\nPIXSIZE=32 bits\nSCALE=2**0"; inrpixsize = 4; }
24737 if (!cimg::strcasecmp(pixel_type(),"float")) { inrtype = "float\nPIXSIZE=32 bits"; inrpixsize = 4; }
24738 if (!cimg::strcasecmp(pixel_type(),"double")) { inrtype = "float\nPIXSIZE=64 bits"; inrpixsize = 8; }
24739 if (inrpixsize<=0) throw CImgIOException("CImg<%s>::save_inr() : Don't know how to save images of '%s'",pixel_type(),pixel_type());
24740 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
24741 char header[257];
24742 int err = std::sprintf(header,"#INRIMAGE-4#{\nXDIM=%u\nYDIM=%u\nZDIM=%u\nVDIM=%u\n",width,height,depth,dim);
24743 if (voxsize) err += std::sprintf(header+err,"VX=%g\nVY=%g\nVZ=%g\n",voxsize[0],voxsize[1],voxsize[2]);
24744 err += std::sprintf(header+err,"TYPE=%s\nCPU=%s\n",inrtype,cimg::endian()?"sun":"decm");
24745 std::memset(header+err,'\n',252-err);
24746 std::memcpy(header+252,"##}\n",4);
24747 cimg::fwrite(header,256,nfile);
24748 cimg_forXYZ(*this,x,y,z) cimg_forV(*this,k) cimg::fwrite(&((*this)(x,y,z,k)),1,nfile);
24749 if (!file) cimg::fclose(nfile);
24750 return *this;
24751 }
24752
24754 const CImg<T>& save_inr(const char *const filename, const float *const voxsize=0) const {
24755 return save_inr(0,filename,voxsize);
24756 }
24757
24758 #define cimg_save_pandore_case(sy,sz,sv,stype,id) \
24759 if (!saved && (sy?(sy==height):true) && (sz?(sz==depth):true) && (sv?(sv==dim):true) && !strcmp(stype,pixel_type())) { \
24760 unsigned int *iheader = (unsigned int*)(header+12); \
24761 nbdims = _save_pandore_header_length((*iheader=id),dims,colorspace); \
24762 cimg::fwrite(header,36,nfile); \
24763 cimg::fwrite(dims,nbdims,nfile); \
24764 if (id==2 || id==5 || id==8 || id==16 || id==19 || id==22 || id==26 || id==30) { \
24765 unsigned char *buffer = new unsigned char[size()]; \
24766 const T *ptrs = data; \
24767 cimg_foroff(*this,off) *(buffer++) = (unsigned char)(*(ptrs++)); \
24768 buffer-=size(); \
24769 cimg::fwrite(buffer,size(),nfile); \
24770 delete[] buffer; \
24771 } \
24772 if (id==3 || id==6 || id==9 || id==17 || id==20 || id==23 || id==27 || id==31) { \
24773 unsigned long *buffer = new unsigned long[size()]; \
24774 const T *ptrs = data; \
24775 cimg_foroff(*this,off) *(buffer++) = (long)(*(ptrs++)); \
24776 buffer-=size(); \
24777 cimg::fwrite(buffer,size(),nfile); \
24778 delete[] buffer; \
24779 } \
24780 if (id==4 || id==7 || id==10 || id==18 || id==21 || id==25 || id==29 || id==33) { \
24781 float *buffer = new float[size()]; \
24782 const T *ptrs = data; \
24783 cimg_foroff(*this,off) *(buffer++) = (float)(*(ptrs++)); \
24784 buffer-=size(); \
24785 cimg::fwrite(buffer,size(),nfile); \
24786 delete[] buffer; \
24787 } \
24788 saved = true; \
24789 }
24790
24791 unsigned int _save_pandore_header_length(unsigned int id, unsigned int *dims, const unsigned int colorspace=0) const {
24792 unsigned int nbdims = 0;
24793 if (id==2 || id==3 || id==4) { dims[0] = 1; dims[1] = width; nbdims = 2; }
24794 if (id==5 || id==6 || id==7) { dims[0] = 1; dims[1] = height; dims[2] = width; nbdims=3; }
24795 if (id==8 || id==9 || id==10) { dims[0] = dim; dims[1] = depth; dims[2] = height; dims[3] = width; nbdims = 4; }
24796 if (id==16 || id==17 || id==18) { dims[0] = 3; dims[1] = height; dims[2] = width; dims[3] = colorspace; nbdims = 4; }
24797 if (id==19 || id==20 || id==21) { dims[0] = 3; dims[1] = depth; dims[2] = height; dims[3] = width; dims[4] = colorspace; nbdims = 5; }
24798 if (id==22 || id==23 || id==25) { dims[0] = dim; dims[1] = width; nbdims = 2; }
24799 if (id==26 || id==27 || id==29) { dims[0] = dim; dims[1] = height; dims[2] = width; nbdims=3; }
24800 if (id==30 || id==31 || id==33) { dims[0] = dim; dims[1] = depth; dims[2] = height; dims[3] = width; nbdims = 4; }
24801 return nbdims;
24802 }
24803
24805 const CImg<T>& save_pandore(std::FILE *const file, const char *const filename=0, const unsigned int colorspace=0) const {
24806 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_pandore() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24807 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24808 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_pandore() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24809 pixel_type(),width,height,depth,dim,data);
24810 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
24811 unsigned char header[36] = { 'P','A','N','D','O','R','E','0','4',0,0,0,
24812 0,0,0,0,
24813 'C','I','m','g',0,0,0,0,0,
24814 'N','o',' ','d','a','t','e',0,0,0,
24815 0 };
24816 unsigned int nbdims,dims[5];
24817 bool saved=false;
24818 cimg_save_pandore_case(1,1,1,"unsigned char",2);
24819 cimg_save_pandore_case(1,1,1,"char",3);
24820 cimg_save_pandore_case(1,1,1,"short",3);
24821 cimg_save_pandore_case(1,1,1,"unsigned short",3);
24822 cimg_save_pandore_case(1,1,1,"unsigned int",3);
24823 cimg_save_pandore_case(1,1,1,"int",3);
24824 cimg_save_pandore_case(1,1,1,"unsigned long",4);
24825 cimg_save_pandore_case(1,1,1,"long",3);
24826 cimg_save_pandore_case(1,1,1,"float",4);
24827 cimg_save_pandore_case(1,1,1,"double",4);
24828
24829 cimg_save_pandore_case(0,1,1,"unsigned char",5);
24830 cimg_save_pandore_case(0,1,1,"char",6);
24831 cimg_save_pandore_case(0,1,1,"short",6);
24832 cimg_save_pandore_case(0,1,1,"unsigned short",6);
24833 cimg_save_pandore_case(0,1,1,"unsigned int",6);
24834 cimg_save_pandore_case(0,1,1,"int",6);
24835 cimg_save_pandore_case(0,1,1,"unsigned long",7);
24836 cimg_save_pandore_case(0,1,1,"long",6);
24837 cimg_save_pandore_case(0,1,1,"float",7);
24838 cimg_save_pandore_case(0,1,1,"double",7);
24839
24840 cimg_save_pandore_case(0,0,1,"unsigned char",8);
24841 cimg_save_pandore_case(0,0,1,"char",9);
24842 cimg_save_pandore_case(0,0,1,"short",9);
24843 cimg_save_pandore_case(0,0,1,"unsigned short",9);
24844 cimg_save_pandore_case(0,0,1,"unsigned int",9);
24845 cimg_save_pandore_case(0,0,1,"int",9);
24846 cimg_save_pandore_case(0,0,1,"unsigned long",10);
24847 cimg_save_pandore_case(0,0,1,"long",9);
24848 cimg_save_pandore_case(0,0,1,"float",10);
24849 cimg_save_pandore_case(0,0,1,"double",10);
24850
24851 cimg_save_pandore_case(0,1,3,"unsigned char",16);
24852 cimg_save_pandore_case(0,1,3,"char",17);
24853 cimg_save_pandore_case(0,1,3,"short",17);
24854 cimg_save_pandore_case(0,1,3,"unsigned short",17);
24855 cimg_save_pandore_case(0,1,3,"unsigned int",17);
24856 cimg_save_pandore_case(0,1,3,"int",17);
24857 cimg_save_pandore_case(0,1,3,"unsigned long",18);
24858 cimg_save_pandore_case(0,1,3,"long",17);
24859 cimg_save_pandore_case(0,1,3,"float",18);
24860 cimg_save_pandore_case(0,1,3,"double",18);
24861
24862 cimg_save_pandore_case(0,0,3,"unsigned char",19);
24863 cimg_save_pandore_case(0,0,3,"char",20);
24864 cimg_save_pandore_case(0,0,3,"short",20);
24865 cimg_save_pandore_case(0,0,3,"unsigned short",20);
24866 cimg_save_pandore_case(0,0,3,"unsigned int",20);
24867 cimg_save_pandore_case(0,0,3,"int",20);
24868 cimg_save_pandore_case(0,0,3,"unsigned long",21);
24869 cimg_save_pandore_case(0,0,3,"long",20);
24870 cimg_save_pandore_case(0,0,3,"float",21);
24871 cimg_save_pandore_case(0,0,3,"double",21);
24872
24873 cimg_save_pandore_case(1,1,0,"unsigned char",22);
24874 cimg_save_pandore_case(1,1,0,"char",23);
24875 cimg_save_pandore_case(1,1,0,"short",23);
24876 cimg_save_pandore_case(1,1,0,"unsigned short",23);
24877 cimg_save_pandore_case(1,1,0,"unsigned int",23);
24878 cimg_save_pandore_case(1,1,0,"int",23);
24879 cimg_save_pandore_case(1,1,0,"unsigned long",25);
24880 cimg_save_pandore_case(1,1,0,"long",23);
24881 cimg_save_pandore_case(1,1,0,"float",25);
24882 cimg_save_pandore_case(1,1,0,"double",25);
24883
24884 cimg_save_pandore_case(0,1,0,"unsigned char",26);
24885 cimg_save_pandore_case(0,1,0,"char",27);
24886 cimg_save_pandore_case(0,1,0,"short",27);
24887 cimg_save_pandore_case(0,1,0,"unsigned short",27);
24888 cimg_save_pandore_case(0,1,0,"unsigned int",27);
24889 cimg_save_pandore_case(0,1,0,"int",27);
24890 cimg_save_pandore_case(0,1,0,"unsigned long",29);
24891 cimg_save_pandore_case(0,1,0,"long",27);
24892 cimg_save_pandore_case(0,1,0,"float",29);
24893 cimg_save_pandore_case(0,1,0,"double",29);
24894
24895 cimg_save_pandore_case(0,0,0,"unsigned char",30);
24896 cimg_save_pandore_case(0,0,0,"char",31);
24897 cimg_save_pandore_case(0,0,0,"short",31);
24898 cimg_save_pandore_case(0,0,0,"unsigned short",31);
24899 cimg_save_pandore_case(0,0,0,"unsigned int",31);
24900 cimg_save_pandore_case(0,0,0,"int",31);
24901 cimg_save_pandore_case(0,0,0,"unsigned long",33);
24902 cimg_save_pandore_case(0,0,0,"long",31);
24903 cimg_save_pandore_case(0,0,0,"float",33);
24904 cimg_save_pandore_case(0,0,0,"double",33);
24905
24906 if (!file) cimg::fclose(nfile);
24907 return *this;
24908 }
24909
24911 const CImg<T>& save_pandore(const char *const filename=0, const unsigned int colorspace=0) const {
24912 return save_pandore(0,filename,colorspace);
24913 }
24914
24916 const CImg<T>& save_yuv(std::FILE *const file, const char *const filename=0, const bool rgb2yuv=true) const {
24917 CImgList<T>(*this).save_yuv(file,filename,rgb2yuv);
24918 return *this;
24919 }
24920
24922 const CImg<T>& save_yuv(const char *const filename, const bool rgb2yuv=true) const {
24923 return save_yuv(0,filename,rgb2yuv);
24924 }
24925
24927 const CImg<T>& save_bmp(std::FILE *const file, const char *const filename=0) const {
24928 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24929 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24930 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24931 pixel_type(),width,height,depth,dim,data);
24932 if (depth>1)
24933 cimg::warn("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
24934 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24935 if (dim>3)
24936 cimg::warn("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is multispectral. Only the three first channels will be saved (file '%s').",
24937 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24938
24939 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
24940 unsigned char header[54] = { 0 }, align_buf[4] = { 0 };
24941 const unsigned int
24942 align = (4-(3*width)%4)%4,
24943 buf_size = (3*width+align)*dimy(),
24944 file_size = 54+buf_size;
24945 header[0] = 'B'; header[1] = 'M';
24946 header[0x02] = file_size&0xFF;
24947 header[0x03] = (file_size>>8)&0xFF;
24948 header[0x04] = (file_size>>16)&0xFF;
24949 header[0x05] = (file_size>>24)&0xFF;
24950 header[0x0A] = 0x36;
24951 header[0x0E] = 0x28;
24952 header[0x12] = width&0xFF;
24953 header[0x13] = (width>>8)&0xFF;
24954 header[0x14] = (width>>16)&0xFF;
24955 header[0x15] = (width>>24)&0xFF;
24956 header[0x16] = height&0xFF;
24957 header[0x17] = (height>>8)&0xFF;
24958 header[0x18] = (height>>16)&0xFF;
24959 header[0x19] = (height>>24)&0xFF;
24960 header[0x1A] = 1;
24961 header[0x1B] = 0;
24962 header[0x1C] = 24;
24963 header[0x1D] = 0;
24964 header[0x22] = buf_size&0xFF;
24965 header[0x23] = (buf_size>>8)&0xFF;
24966 header[0x24] = (buf_size>>16)&0xFF;
24967 header[0x25] = (buf_size>>24)&0xFF;
24968 header[0x27] = 0x1;
24969 header[0x2B] = 0x1;
24970 cimg::fwrite(header,54,nfile);
24971
24972 const T
24973 *pR = ptr(0,height-1,0,0),
24974 *pG = (dim>=2)?ptr(0,height-1,0,1):pR,
24975 *pB = (dim>=3)?ptr(0,height-1,0,2):pR;
24976
24977 cimg_forY(*this,y) {
24978 cimg_forX(*this,x) {
24979 std::fputc((unsigned char)(*(pB++)),nfile);
24980 std::fputc((unsigned char)(*(pG++)),nfile);
24981 std::fputc((unsigned char)(*(pR++)),nfile);
24982 }
24983 cimg::fwrite(align_buf,align,nfile);
24984 pR-=2*width; pG-=2*width; pB-=2*width;
24985 }
24986 if (!file) cimg::fclose(nfile);
24987 return *this;
24988 }
24989
24991 const CImg<T>& save_bmp(const char *const filename) const {
24992 return save_bmp(0,filename);
24993 }
24994
24996
25009 const CImg<T>& save_png(std::FILE *const file, const char *const filename=0) const {
25010 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25011 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25012 if (!filename) throw CImgArgumentException("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
25013 pixel_type(),width,height,depth,dim,data);
25014 if (depth>1)
25015 cimg::warn("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
25016 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25017 #ifndef cimg_use_png
25018 if (!file) return save_other(filename);
25019 else throw CImgIOException("CImg<%s>::save_png() : Cannot save a PNG image in a *FILE output. Use libpng instead.",
25020 pixel_type());
25021 #else
25022 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
25023
25024
25025 png_voidp user_error_ptr = 0;
25026 png_error_ptr user_error_fn = 0, user_warning_fn = 0;
25027 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
25028 user_error_ptr, user_error_fn, user_warning_fn);
25029 if(!png_ptr){
25030 if (!file) cimg::fclose(nfile);
25031 throw CImgIOException("CImg<%s>::save_png() : File '%s', error when initializing 'png_ptr' data structure.",
25032 pixel_type(),filename?filename:"(unknown)");
25033 }
25034 png_infop info_ptr = png_create_info_struct(png_ptr);
25035 if(!info_ptr){
25036 png_destroy_write_struct(&png_ptr,(png_infopp)0);
25037 if (!file) cimg::fclose(nfile);
25038 throw CImgIOException("CImg<%s>::save_png() : File '%s', error when initializing 'info_ptr' data structure.",
25039 pixel_type(),filename?filename:"(unknown)");
25040 }
25041 if (setjmp(png_jmpbuf(png_ptr))){
25042 png_destroy_write_struct(&png_ptr, &info_ptr);
25043 if (!file) cimg::fclose(nfile);
25044 throw CImgIOException("CImg<%s>::save_png() : File '%s', unknown fatal error.",
25045 pixel_type(),filename?filename:"(unknown)");
25046 }
25047
25048 png_init_io(png_ptr, nfile);
25049 png_uint_32 width = dimx();
25050 png_uint_32 height = dimy();
25051 float vmin, vmax = (float)maxmin(vmin);
25052 const int bit_depth = (vmin<0 || vmax>=256)?16:8;
25053 int color_type;
25054 switch (dimv()) {
25055 case 1: color_type = PNG_COLOR_TYPE_GRAY; break;
25056 case 2: color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break;
25057 case 3: color_type = PNG_COLOR_TYPE_RGB; break;
25058 default: color_type = PNG_COLOR_TYPE_RGB_ALPHA;
25059 }
25060 const int interlace_type = PNG_INTERLACE_NONE;
25061 const int compression_type = PNG_COMPRESSION_TYPE_DEFAULT;
25062 const int filter_method = PNG_FILTER_TYPE_DEFAULT;
25063 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type,
25064 compression_type, filter_method);
25065 png_write_info(png_ptr, info_ptr);
25066 const int byte_depth = bit_depth>>3;
25067 const int numChan = dimv()>4?4:dimv();
25068 const int pixel_bit_depth_flag = numChan * (bit_depth-1);
25069
25070
25071 png_bytep *imgData = new png_byte*[height];
25072 for (unsigned int row=0; row<height; ++row) imgData[row] = new png_byte[byte_depth * numChan * width];
25073 const T *pC0 = ptr(0,0,0,0);
25074 switch(pixel_bit_depth_flag) {
25075 case 7 : {
25076 cimg_forY(*this,y) {
25077 unsigned char *ptrs = imgData[y];
25078 cimg_forX(*this,x) *(ptrs++) = (unsigned char)*(pC0++);
25079 }
25080 } break;
25081 case 14: {
25082 const T *pC1 = ptr(0,0,0,1);
25083 cimg_forY(*this,y) {
25084 unsigned char *ptrs = imgData[y];
25085 cimg_forX(*this,x) {
25086 *(ptrs++) = (unsigned char)*(pC0++);
25087 *(ptrs++) = (unsigned char)*(pC1++);
25088 }
25089 }
25090 } break;
25091 case 21: {
25092 const T *pC1 = ptr(0,0,0,1);
25093 const T *pC2 = ptr(0,0,0,2);
25094 cimg_forY(*this,y) {
25095 unsigned char *ptrs = imgData[y];
25096 cimg_forX(*this,x) {
25097 *(ptrs++) = (unsigned char)*(pC0++);
25098 *(ptrs++) = (unsigned char)*(pC1++);
25099 *(ptrs++) = (unsigned char)*(pC2++);
25100 }
25101 }
25102 } break;
25103 case 28: {
25104 const T *pC1 = ptr(0,0,0,1);
25105 const T *pC2 = ptr(0,0,0,2);
25106 const T *pC3 = ptr(0,0,0,3);
25107 cimg_forY(*this,y){
25108 unsigned char *ptrs = imgData[y];
25109 cimg_forX(*this,x){
25110 *(ptrs++) = (unsigned char)*(pC0++);
25111 *(ptrs++) = (unsigned char)*(pC1++);
25112 *(ptrs++) = (unsigned char)*(pC2++);
25113 *(ptrs++) = (unsigned char)*(pC3++);
25114 }
25115 }
25116 } break;
25117 case 15: {
25118 cimg_forY(*this,y){
25119 unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
25120 cimg_forX(*this,x) *(ptrs++) = (unsigned short)*(pC0++);
25121 }
25122 } break;
25123 case 30: {
25124 const T *pC1 = ptr(0,0,0,1);
25125 cimg_forY(*this,y){
25126 unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
25127 cimg_forX(*this,x) {
25128 *(ptrs++) = (unsigned short)*(pC0++);
25129 *(ptrs++) = (unsigned short)*(pC1++);
25130 }
25131 }
25132 } break;
25133 case 45: {
25134 const T *pC1 = ptr(0,0,0,1);
25135 const T *pC2 = ptr(0,0,0,2);
25136 cimg_forY(*this,y) {
25137 unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
25138 cimg_forX(*this,x) {
25139 *(ptrs++) = (unsigned short)*(pC0++);
25140 *(ptrs++) = (unsigned short)*(pC1++);
25141 *(ptrs++) = (unsigned short)*(pC2++);
25142 }
25143 }
25144 } break;
25145 case 60: {
25146 const T *pC1 = ptr(0,0,0,1);
25147 const T *pC2 = ptr(0,0,0,2);
25148 const T *pC3 = ptr(0,0,0,3);
25149 cimg_forY(*this,y) {
25150 unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
25151 cimg_forX(*this,x) {
25152 *(ptrs++) = (unsigned short)*(pC0++);
25153 *(ptrs++) = (unsigned short)*(pC1++);
25154 *(ptrs++) = (unsigned short)*(pC2++);
25155 *(ptrs++) = (unsigned short)*(pC3++);
25156 }
25157 }
25158 } break;
25159 default:
25160 if (!file) cimg::fclose(nfile);
25161 throw CImgIOException("CImg<%s>::save_png() : File '%s', unknown fatal error.",
25162 pixel_type(),filename?filename:"(unknown)");
25163 break;
25164 }
25165 png_write_image(png_ptr, imgData);
25166 png_write_end(png_ptr, info_ptr);
25167 png_destroy_write_struct(&png_ptr, &info_ptr);
25168
25169
25170 for (unsigned int n=0; n<height; ++n) delete[] imgData[n];
25171 delete[] imgData;
25172 if (!file) cimg::fclose(nfile);
25173 return *this;
25174 #endif
25175 }
25176
25178 const CImg<T>& save_png(const char *const filename) const {
25179 return save_png(0,filename);
25180 }
25181
25183 const CImg<T>& save_tiff(const char *const filename) const {
25184 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_tiff() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25185 pixel_type(),width,height,depth,dim,data,filename);
25186 if (!filename) throw CImgArgumentException("CImg<%s>::save_tiff() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
25187 pixel_type(),width,height,depth,dim,data);
25188 #ifdef cimg_use_tiff
25189 uint32 rowsperstrip = (uint32) -1;
25190 uint16 spp = dimv(), bpp = sizeof(T)*8;
25191 uint16 photometric;
25192 if (spp==3 || spp==4)
25193 photometric = PHOTOMETRIC_RGB;
25194 else
25195 photometric = PHOTOMETRIC_MINISBLACK;
25196 uint16 compression = COMPRESSION_NONE;
25197 TIFF *out;
25198 out = TIFFOpen(filename,"w");
25199 if (out) {
25200 for (unsigned int dir=0; dir<depth; ++dir) {
25201 TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32)dimx());
25202 TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32)dimy());
25203 TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
25204 TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
25205 TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bpp);
25206 TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
25207 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
25208 TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
25209 rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
25210 TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
25211 TIFFSetField(out, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
25212 TIFFSetField(out, TIFFTAG_SOFTWARE, "CImg");
25213 T *buf = (T *)_TIFFmalloc(TIFFStripSize(out));
25214 if (buf){
25215 for (unsigned int row = 0; row < height; row+=rowsperstrip) {
25216 uint32 nrow = (row+rowsperstrip>height?height-row:rowsperstrip);
25217 tstrip_t strip = TIFFComputeStrip(out, row, 0);
25218 tsize_t i = 0;
25219 for (unsigned int rr=0; rr<nrow; ++rr)
25220 for (unsigned int cc=0; cc<width; ++cc)
25221 for (unsigned int vv=0; vv<spp; ++vv)
25222 buf[i++] = (*this)(cc,row+rr,dir,vv);
25223 if(TIFFWriteEncodedStrip(out, strip, buf, i*sizeof(T))<0){
25224 throw CImgException("CImg<%s>::save_tiff() : File '%s', an error occure while writing a strip.",
25225 pixel_type(),filename?filename:"(FILE*)");
25226 }
25227 }
25228 _TIFFfree(buf);
25229 }
25230 TIFFWriteDirectory(out);
25231 }
25232 TIFFClose(out);
25233 }
25234 else throw CImgException("CImg<%s>::save_tiff() : File '%s', error while writing tiff file.",
25235 pixel_type(),filename);
25236 #else
25237 return save_other(filename);
25238 #endif
25239 return *this;
25240 }
25241
25243 const CImg<T>& save_jpeg(std::FILE *const file, const char *const filename=0, const unsigned int quality=100) const {
25244 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25245 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25246 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
25247 pixel_type(),width,height,depth,dim,data);
25248 if (depth>1)
25249 cimg::warn("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
25250 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25251 #ifndef cimg_use_jpeg
25252 if (!file) return save_other(filename,quality);
25253 else throw CImgIOException("CImg<%s>::save_jpeg() : Cannot save a JPEG image in a *FILE output. Use libjpeg instead.",
25254 pixel_type());
25255 #else
25256
25257
25258 unsigned char *buf;
25259 unsigned int dimbuf = 0;
25260 J_COLOR_SPACE colortype = JCS_RGB;
25261 switch (dim) {
25262 case 1: {
25263 unsigned char *buf2 = buf = new unsigned char[width*height*(dimbuf=1)];
25264 colortype = JCS_GRAYSCALE;
25265 const T *ptr_g = data;
25266 cimg_forXY(*this,x,y) *(buf2++) = (unsigned char)*(ptr_g++);
25267 } break;
25268 case 2:
25269 case 3: {
25270 unsigned char *buf2 = buf = new unsigned char[width*height*(dimbuf=3)];
25271 const T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1), *ptr_b = ptr(0,0,0,dim>2?2:0);
25272 colortype = JCS_RGB;
25273 cimg_forXY(*this,x,y) {
25274 *(buf2++) = (unsigned char)*(ptr_r++);
25275 *(buf2++) = (unsigned char)*(ptr_g++);
25276 *(buf2++) = (unsigned char)*(ptr_b++);
25277 }
25278 } break;
25279 default: {
25280 unsigned char *buf2 = buf = new unsigned char[width*height*(dimbuf=4)];
25281 const T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1), *ptr_b = ptr(0,0,0,2), *ptr_a = ptr(0,0,0,3);
25282 colortype = JCS_CMYK;
25283 cimg_forXY(*this,x,y) {
25284 *(buf2++) = (unsigned char)*(ptr_r++);
25285 *(buf2++) = (unsigned char)*(ptr_g++);
25286 *(buf2++) = (unsigned char)*(ptr_b++);
25287 *(buf2++) = (unsigned char)*(ptr_a++);
25288 }
25289 } break;
25290 }
25291
25292
25293 struct jpeg_compress_struct cinfo;
25294 struct jpeg_error_mgr jerr;
25295 cinfo.err = jpeg_std_error(&jerr);
25296 jpeg_create_compress(&cinfo);
25297 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
25298 jpeg_stdio_dest(&cinfo,nfile);
25299 cinfo.image_width = width;
25300 cinfo.image_height = height;
25301 cinfo.input_components = dimbuf;
25302 cinfo.in_color_space = colortype;
25303 jpeg_set_defaults(&cinfo);
25304 jpeg_set_quality(&cinfo,quality<100?quality:100,TRUE);
25305 jpeg_start_compress(&cinfo,TRUE);
25306
25307 const unsigned int row_stride = width*dimbuf;
25308 JSAMPROW row_pointer[1];
25309 while (cinfo.next_scanline < cinfo.image_height) {
25310 row_pointer[0] = &buf[cinfo.next_scanline*row_stride];
25311 jpeg_write_scanlines(&cinfo,row_pointer,1);
25312 }
25313 jpeg_finish_compress(&cinfo);
25314
25315 delete[] buf;
25316 if (!file) cimg::fclose(nfile);
25317 jpeg_destroy_compress(&cinfo);
25318 return *this;
25319 #endif
25320 }
25321
25323 const CImg<T>& save_jpeg(const char *const filename, const unsigned int quality=100) const {
25324 return save_jpeg(0,filename,quality);
25325 }
25326
25328 const CImg<T>& save_magick(const char *const filename) const {
25329 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_magick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25330 pixel_type(),width,height,depth,dim,data);
25331 if (!filename) throw CImgArgumentException("CImg<%s>::save_magick() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
25332 pixel_type(),width,height,depth,dim,data);
25333 #ifdef cimg_use_magick
25334 Magick::Image image(Magick::Geometry(width,height),"black");
25335 image.type(Magick::TrueColorType);
25336 const T *rdata = ptr(0,0,0,0), *gdata = dim>1?ptr(0,0,0,1):rdata, *bdata = dim>2?ptr(0,0,0,2):gdata;
25337 Magick::PixelPacket *pixels = image.getPixels(0,0,width,height);
25338 for (unsigned int off = width*height; off; --off) {
25339 pixels->red = Magick::Color::scaleDoubleToQuantum(*(rdata++)/255.0);
25340 pixels->green = Magick::Color::scaleDoubleToQuantum(*(gdata++)/255.0);
25341 pixels->blue = Magick::Color::scaleDoubleToQuantum(*(bdata++)/255.0);
25342 ++pixels;
25343 }
25344 image.syncPixels();
25345 image.write(filename);
25346 #else
25347 throw CImgIOException("CImg<%s>::save_magick() : File '%s', Magick++ library has not been linked.",
25348 pixel_type(),filename);
25349 #endif
25350 return *this;
25351 }
25352
25354 const CImg<T>& save_rgba(std::FILE *const file, const char *const filename=0) const {
25355 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25356 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25357 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
25358 pixel_type(),width,height,depth,dim,data);
25359 if (dim!=4)
25360 cimg::warn("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p) has not exactly 4 channels (file '%s').",
25361 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25362 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
25363 const unsigned int wh = width*height;
25364 unsigned char *buffer = new unsigned char[4*wh], *nbuffer=buffer;
25365 const T
25366 *ptr1 = ptr(0,0,0,0),
25367 *ptr2 = dim>1?ptr(0,0,0,1):ptr1,
25368 *ptr3 = dim>2?ptr(0,0,0,2):ptr1,
25369 *ptr4 = dim>3?ptr(0,0,0,3):0;
25370 for (unsigned int k=0; k<wh; ++k) {
25371 *(nbuffer++) = (unsigned char)(*(ptr1++));
25372 *(nbuffer++) = (unsigned char)(*(ptr2++));
25373 *(nbuffer++) = (unsigned char)(*(ptr3++));
25374 *(nbuffer++) = (unsigned char)(ptr4?(*(ptr4++)):255);
25375 }
25376 cimg::fwrite(buffer,4*wh,nfile);
25377 if (!file) cimg::fclose(nfile);
25378 delete[] buffer;
25379 return *this;
25380 }
25381
25383 const CImg<T>& save_rgba(const char *const filename) const {
25384 return save_rgba(0,filename);
25385 }
25386
25388 const CImg<T>& save_rgb(std::FILE *const file, const char *const filename=0) const {
25389 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25390 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25391 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
25392 pixel_type(),width,height,depth,dim,data);
25393 if (dim!=3)
25394 cimg::warn("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p) has not exactly 3 channels (file '%s').",
25395 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25396 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
25397 const unsigned int wh = width*height;
25398 unsigned char *buffer = new unsigned char[3*wh], *nbuffer=buffer;
25399 const T
25400 *ptr1 = ptr(0,0,0,0),
25401 *ptr2 = dim>1?ptr(0,0,0,1):ptr1,
25402 *ptr3 = dim>2?ptr(0,0,0,2):ptr1;
25403 for (unsigned int k=0; k<wh; ++k) {
25404 *(nbuffer++) = (unsigned char)(*(ptr1++));
25405 *(nbuffer++) = (unsigned char)(*(ptr2++));
25406 *(nbuffer++) = (unsigned char)(*(ptr3++));
25407 }
25408 cimg::fwrite(buffer,3*wh,nfile);
25409 if (!file) cimg::fclose(nfile);
25410 delete[] buffer;
25411 return *this;
25412 }
25413
25415 const CImg<T>& save_rgb(const char *const filename) const {
25416 return save_rgb(0,filename);
25417 }
25418
25420 template<typename tf, typename tc>
25421 const CImg<T>& save_off(std::FILE *const file, const char *const filename,
25422 const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
25423 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_off() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25424 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25425 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_off() : Specified filename is (null).",pixel_type());
25426 if (height<3) return get_resize(-100,3,1,1,0).save_off(file,filename,primitives,colors,invert_faces);
25427 std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
25428 std::fprintf(nfile,"OFF\n%u %u %u\n",width,primitives.size,3*primitives.size);
25429 cimg_forX(*this,i) std::fprintf(nfile,"%f %f %f\n",(float)((*this)(i,0)),(float)((*this)(i,1)),(float)((*this)(i,2)));
25430 cimglist_for(primitives,l) {
25431 const unsigned int prim = primitives[l].size();
25432 const bool textured = (prim>4);
25433 const CImg<tc>& color = colors[l];
25434 const unsigned int s = textured?color.dimv():color.size();
25435 const float
25436 r = textured?(s>0?(float)(color.get_shared_channel(0).mean()/255.0f):1.0f):(s>0?(float)(color(0)/255.0f):1.0f),
25437 g = textured?(s>1?(float)(color.get_shared_channel(1).mean()/255.0f):r) :(s>1?(float)(color(1)/255.0f):r),
25438 b = textured?(s>2?(float)(color.get_shared_channel(2).mean()/255.0f):r) :(s>2?(float)(color(2)/255.0f):r);
25439
25440 switch (prim) {
25441 case 1:
25442 std::fprintf(nfile,"1 %u %f %f %f\n",(unsigned int)primitives(l,0),r,g,b);
25443 break;
25444 case 2: case 6:
25445 std::fprintf(nfile,"2 %u %u %f %f %f\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,1),r,g,b);
25446 break;
25447 case 3: case 9:
25448 if (invert_faces)
25449 std::fprintf(nfile,"3 %u %u %u %f %f %f\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,1),(unsigned int)primitives(l,2),r,g,b);
25450 else
25451 std::fprintf(nfile,"3 %u %u %u %f %f %f\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,2),(unsigned int)primitives(l,1),r,g,b);
25452 break;
25453 case 4: case 12:
25454 if (invert_faces)
25455 std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n",
25456 (unsigned int)primitives(l,0),(unsigned int)primitives(l,1),(unsigned int)primitives(l,2),(unsigned int)primitives(l,3),r,g,b);
25457 else
25458 std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n",
25459 (unsigned int)primitives(l,0),(unsigned int)primitives(l,3),(unsigned int)primitives(l,2),(unsigned int)primitives(l,1),r,g,b);
25460 break;
25461 }
25462 }
25463 if (!file) cimg::fclose(nfile);
25464 return *this;
25465 }
25466
25468 template<typename tf, typename tc>
25469 const CImg<T>& save_off(const char *const filename,
25470 const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
25471 return save_off(0,filename,primitives,colors,invert_faces);
25472 }
25473
25475 static CImg<T> get_logo40x38() {
25476 static bool first_time = true;
25477 static CImg<T> res(40,38,1,3);
25478 if (first_time) {
25479 const unsigned char *ptrs = cimg::logo40x38;
25480 T *ptr1 = res.ptr(0,0,0,0), *ptr2 = res.ptr(0,0,0,1), *ptr3 = res.ptr(0,0,0,2);
25481 for (unsigned int off = 0; off<res.width*res.height;) {
25482 const unsigned char n = *(ptrs++), r = *(ptrs++), g = *(ptrs++), b = *(ptrs++);
25483 for (unsigned int l=0; l<n; ++off, ++l) { *(ptr1++) = (T)r; *(ptr2++) = (T)g; *(ptr3++) = (T)b; }
25484 }
25485 first_time = false;
25486 }
25487 return res;
25488 }
25489
25490 };
25491
25492
25493
25494
25495
25496
25497
25498
25499
25500
25501
25502
25503
25504
25506 template<typename T> struct CImgList {
25507
25509 unsigned int size;
25510
25512 unsigned int allocsize;
25513
25515 CImg<T> *data;
25516
25518 typedef CImg<T>* iterator;
25519
25521 typedef const CImg<T>* const_iterator;
25522
25524 typedef T value_type;
25525
25527
25528
25530
25531
25532 #ifdef cimglist_plugin
25533 #include cimglist_plugin
25534 #endif
25535
25536
25537
25538
25540
25541
25542
25544 CImgList():
25545 size(0),allocsize(0),data(0) {}
25546
25548 ~CImgList() {
25549 if (data) delete[] data;
25550 }
25551
25553 CImgList<T>& assign() {
25554 if (data) delete[] data;
25555 size = allocsize = 0;
25556 data = 0;
25557 return *this;
25558 }
25559
25561 CImgList<T>& clear() {
25562 return assign();
25563 }
25564
25566 template<typename t> CImgList(const CImgList<t>& list):
25567 size(0),allocsize(0),data(0) {
25568 assign(list);
25569 }
25570
25571 CImgList(const CImgList<T>& list):
25572 size(0),allocsize(0),data(0) {
25573 assign(list.size);
25574 cimglist_for(*this,l) (*this)[l].assign(list[l],list[l].is_shared);
25575 }
25576
25578 template<typename t> CImgList(const CImgList<t>& list, const bool shared):
25579 size(0),allocsize(0),data(0) {
25580 assign(list,shared?1:0);
25581 }
25582
25583 CImgList(const CImgList<T>& list, const bool shared):
25584 size(0),allocsize(0),data(0) {
25585 assign(list,shared?1:0);
25586 }
25587
25589 template<typename t> CImgList<T>& assign(const CImgList<t>& list, const int shared=0) {
25590 assign(list.size);
25591 if (shared>=0) cimglist_for(*this,l) (*this)[l].assign(list[l],shared?true:false);
25592 else cimglist_for(*this,l) (*this)[l].assign(list[l],list[l].is_shared);
25593 return *this;
25594 }
25595
25597 explicit CImgList(const unsigned int n):
25598 size(n) {
25599 data = new CImg<T>[allocsize=cimg::nearest_pow2(n)];
25600 }
25601
25603 CImgList<T>& assign(const unsigned int n) {
25604 if (n) {
25605 if (allocsize<n || allocsize>(n<<2)) {
25606 if (data) delete[] data;
25607 data = new CImg<T>[allocsize=cimg::nearest_pow2(n)];
25608 }
25609 size = n;
25610 } else return assign();
25611 return *this;
25612 }
25613
25615 CImgList(const unsigned int n, const unsigned int width, const unsigned int height=1,
25616 const unsigned int depth=1, const unsigned int dim=1):
25617 size(0),allocsize(0),data(0) {
25618 assign(n,width,height,depth,dim);
25619 }
25620
25622 CImgList<T>& assign(const unsigned int n, const unsigned int width, const unsigned int height=1,
25623 const unsigned int depth=1, const unsigned int dim=1) {
25624 const unsigned int siz = width*height*depth*dim;
25625 if (n && siz) { assign(n); cimglist_for(*this,l) data[l].assign(width,height,depth,dim); }
25626 else return assign();
25627 return *this;
25628 }
25629
25631 CImgList(const unsigned int n, const unsigned int width, const unsigned int height,
25632 const unsigned int depth, const unsigned int dim, const T val):
25633 size(0),allocsize(0),data(0) {
25634 assign(n,width,height,depth,dim,val);
25635 }
25636
25638 CImgList<T>& assign(const unsigned int n, const unsigned int width, const unsigned int height,
25639 const unsigned int depth, const unsigned int dim, const T val) {
25640 assign(n,width,height,depth,dim);
25641 cimglist_for(*this,l) data[l].fill(val);
25642 return *this;
25643 }
25644
25646 CImgList(const unsigned int n, const unsigned int width, const unsigned int height,
25647 const unsigned int depth, const unsigned int dim, const int val0, const int val1, ...):
25648 size(0),allocsize(0),data(0) {
25649 #define _CImgList_stdarg(t) \
25650 assign(n,width,height,depth,dim); \
25651 const unsigned int siz = width*height*depth*dim, nsiz = siz*n; \
25652 T *ptrd = data->data; \
25653 va_list ap; \
25654 va_start(ap,val1); \
25655 for (unsigned int l=0, s=0, i=0; i<nsiz; ++i) { \
25656 *(ptrd++) = (T)(i==0?val0:(i==1?val1:va_arg(ap,t))); \
25657 if ((++s)==siz) { ptrd = data[++l].data; s=0; }\
25658 } \
25659 va_end(ap);
25660 _CImgList_stdarg(int);
25661 }
25662
25664 CImgList<T>& assign(const unsigned int n, const unsigned int width, const unsigned int height,
25665 const unsigned int depth, const unsigned int dim, const int val0, const int val1, ...) {
25666 _CImgList_stdarg(int);
25667 return *this;
25668 }
25669
25671 CImgList(const unsigned int n, const unsigned int width, const unsigned int height,
25672 const unsigned int depth, const unsigned int dim, const double val0, const double val1, ...):
25673 size(0),allocsize(0),data(0) {
25674 _CImgList_stdarg(double);
25675 }
25676
25678 CImgList<T>& assign(const unsigned int n, const unsigned int width, const unsigned int height,
25679 const unsigned int depth, const unsigned int dim, const double val0, const double val1, ...) {
25680 _CImgList_stdarg(double);
25681 return *this;
25682 }
25683
25685 template<typename t> CImgList(const unsigned int n, const CImg<t>& img, const bool shared=false):
25686 size(0),allocsize(0),data(0) {
25687 assign(n,img,shared);
25688 }
25689
25691 template<typename t> CImgList<T>& assign(const unsigned int n, const CImg<t>& img, const bool shared=false) {
25692 assign(n);
25693 cimglist_for(*this,l) data[l].assign(img,shared);
25694 return *this;
25695 }
25696
25698 template<typename t> explicit CImgList(const CImg<t>& img, const bool shared=false):
25699 size(0),allocsize(0),data(0) {
25700 assign(img,shared);
25701 }
25702
25704 template<typename t> CImgList<T>& assign(const CImg<t>& img, const bool shared=false) {
25705 return assign(1,img,shared);
25706 }
25707
25709 template<typename t1, typename t2> CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const bool shared=false):
25710 size(0),allocsize(0),data(0) {
25711 assign(img1,img2,shared);
25712 }
25713
25715 template<typename t1, typename t2> CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const bool shared=false) {
25716 assign(2);
25717 data[0].assign(img1,shared); data[1].assign(img2,shared);
25718 return *this;
25719 }
25720
25722 template<typename t1, typename t2, typename t3> CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const bool shared=false):
25723 size(0),allocsize(0),data(0) {
25724 assign(img1,img2,img3,shared);
25725 }
25726
25728 template<typename t1, typename t2, typename t3> CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const bool shared=false) {
25729 assign(3);
25730 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared);
25731 return *this;
25732 }
25733
25735 template<typename t1, typename t2, typename t3, typename t4>
25736 CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const bool shared=false):
25737 size(0),allocsize(0),data(0) {
25738 assign(img1,img2,img3,img4,shared);
25739 }
25740
25742 template<typename t1, typename t2, typename t3, typename t4>
25743 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const bool shared=false) {
25744 assign(4);
25745 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25746 return *this;
25747 }
25748
25750 template<typename t1, typename t2, typename t3, typename t4, typename t5>
25751 CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5, const bool shared=false):
25752 size(0),allocsize(0),data(0) {
25753 assign(img1,img2,img3,img4,img5,shared);
25754 }
25755
25757 template<typename t1, typename t2, typename t3, typename t4, typename t5>
25758 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25759 const bool shared=false) {
25760 assign(5);
25761 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25762 data[4].assign(img5,shared);
25763 return *this;
25764 }
25765
25767 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6>
25768 CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25769 const CImg<t6>& img6, const bool shared=false):
25770 size(0),allocsize(0),data(0) {
25771 assign(img1,img2,img3,img4,img5,img6,shared);
25772 }
25773
25775 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6>
25776 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25777 const CImg<t6>& img6, const bool shared=false) {
25778 assign(6);
25779 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25780 data[4].assign(img5,shared); data[5].assign(img6,shared);
25781 return *this;
25782 }
25783
25785 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7>
25786 CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25787 const CImg<t6>& img6, const CImg<t7>& img7, const bool shared=false):
25788 size(0),allocsize(0),data(0) {
25789 assign(img1,img2,img3,img4,img5,img6,img7,shared);
25790 }
25791
25793 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7>
25794 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25795 const CImg<t6>& img6, const CImg<t7>& img7, const bool shared=false) {
25796 assign(7);
25797 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25798 data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared);
25799 return *this;
25800 }
25801
25803 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8>
25804 CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25805 const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const bool shared=false):
25806 size(0),allocsize(0),data(0) {
25807 assign(img1,img2,img3,img4,img5,img6,img7,img8,shared);
25808 }
25809
25811 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8>
25812 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25813 const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const bool shared=false) {
25814 assign(8);
25815 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25816 data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared); data[7].assign(img8,shared);
25817 return *this;
25818 }
25819
25821 CImgList(const char *const filename):
25822 size(0),allocsize(0),data(0) {
25823 assign(filename);
25824 }
25825
25827 CImgList<T>& assign(const char *const filename) {
25828 return load(filename);
25829 }
25830
25831
25832 CImgList<T>& swap(CImgList<T>& list) {
25833 cimg::swap(size,list.size);
25834 cimg::swap(allocsize,list.allocsize);
25835 cimg::swap(data,list.data);
25836 return list;
25837 }
25838
25839
25840 #ifndef cimg_use_visualcpp6
25841 CImgList<T>& assign_to(CImgList<T>& list) {
25842 return swap(list);
25843 }
25844 #endif
25845
25846 template<typename t> CImgList<T>& assign_to(CImgList<t>& list) {
25847 return list.assign(*this);
25848 }
25849
25851 static const char* pixel_type() {
25852 return cimg::type<T>::string();
25853 }
25854
25856 bool is_empty() const {
25857 return (!data || !size);
25858 }
25859
25860 operator bool() const {
25861 return !is_empty();
25862 }
25863
25865 bool contains(const int k) const {
25866 return data && k<(int)size;
25867 }
25868
25870 bool contains(const int k, const int x, const int y=0, const int z=0, const int v=0) const {
25871 return contains(k) && data[k].contains(x,y,z,v);
25872 }
25873
25875 template<typename t> bool contains(const T& pixel, t& l, t& x, t&y, t& z, t& v) const {
25876 const T *ptr = &pixel;
25877 cimglist_for(*this,i) if (data[i].contains(pixel,x,y,z,v)) { l = (t)i; return true; }
25878 return false;
25879 }
25880
25882 template<typename t> bool contains(const T& pixel, t& l, t& x, t&y, t& z) const {
25883 t v;
25884 return contains(pixel,l,x,y,z,v);
25885 }
25886
25888 template<typename t> bool contains(const T& pixel, t& l, t& x, t&y) const {
25889 t z,v;
25890 return contains(pixel,l,x,y,z,v);
25891 }
25892
25894 template<typename t> bool contains(const T& pixel, t& l, t& x) const {
25895 t y,z,v;
25896 return contains(pixel,l,x,y,z,v);
25897 }
25898
25900 template<typename t> bool contains(const T& pixel, t& l) const {
25901 t x,y,z,v;
25902 return contains(pixel,l,x,y,z,v);
25903 }
25904
25906 template<typename t> bool contains(const T& pixel) const {
25907 t l,x,y,z,v;
25908 return contains(pixel,l,x,y,z,v);
25909 }
25910
25912
25913
25915
25916
25917
25919 template<typename t> CImgList<T>& operator=(const CImgList<t>& list) {
25920 return assign(list);
25921 }
25922
25923 CImgList<T>& operator=(const CImgList<T>& list) {
25924 return assign(list);
25925 }
25926
25928 template<typename t> CImgList<T>& operator=(const CImg<t>& img) {
25929 cimglist_for(*this,l) data[l]=img;
25930 return *this;
25931 }
25932
25934 CImgList<T>& operator=(const T val) {
25935 cimglist_for(*this,l) data[l].fill(val);
25936 return *this;
25937 }
25938
25940 CImgList<T> operator+() const {
25941 return CImgList<T>(*this);
25942 }
25943
25945 #ifdef cimg_use_visualcpp6
25946 CImgList<T>& operator+=(const T val) {
25947 #else
25948 template<typename t> CImgList<T>& operator+=(const t val) {
25949 #endif
25950 cimglist_for(*this,l) (*this)[l]+=val;
25951 return *this;
25952 }
25953
25955 template<typename t> CImgList<T>& operator+=(const CImgList<t>& list) {
25956 const unsigned int sizemax = cimg::min(size,list.size);
25957 for (unsigned int l=0; l<sizemax; ++l) (*this)[l]+=list[l];
25958 return *this;
25959 }
25960
25962 CImgList<T>& operator++() {
25963 cimglist_for(*this,l) ++(*this)[l];
25964 return *this;
25965 }
25966
25968 CImgList<T> operator++(int) {
25969 CImgList<T> copy(*this);
25970 ++*this;
25971 return copy;
25972 }
25973
25975 CImgList<T> operator-() const {
25976 CImgList<T> res(size);
25977 cimglist_for(res,l) res[l].assign(-data[l]);
25978 return res;
25979 }
25980
25982 #ifdef cimg_use_visualcpp6
25983 CImgList<T>& operator-=(const T val) {
25984 #else
25985 template<typename t> CImgList<T>& operator-=(const t val) {
25986 #endif
25987 cimglist_for(*this,l) (*this)[l]-=val;
25988 return *this;
25989 }
25990
25992 template<typename t> CImgList<T>& operator-=(const CImgList<t>& list) {
25993 const unsigned int sizemax = min(size,list.size);
25994 for (unsigned int l=0; l<sizemax; ++l) (*this)[l]-=list[l];
25995 return *this;
25996 }
25997
25999 CImgList<T>& operator--() {
26000 cimglist_for(*this,l) --(*this)[l];
26001 return *this;
26002 }
26003
26005 CImgList<T> operator--(int) {
26006 CImgList<T> copy(*this);
26007 --*this;
26008 return copy;
26009 }
26010
26012 #ifdef cimg_use_visualcpp6
26013 CImgList<T>& operator*=(const double val) {
26014 #else
26015 template<typename t> CImgList<T>& operator*=(const t val) {
26016 #endif
26017 cimglist_for(*this,l) (*this)[l]*=val;
26018 return *this;
26019 }
26020
26022 template<typename t> CImgList<T>& operator*=(const CImgList<t>& list) {
26023 const unsigned int N = cimg::min(size,list.size);
26024 for (unsigned int l=0; l<N; ++l) (*this)[l]*=list[l];
26025 return this;
26026 }
26027
26029 #ifdef cimg_use_visualcpp6
26030 CImgList<T>& operator/=(const double val) {
26031 #else
26032 template<typename t> CImgList<T>& operator/=(const t val) {
26033 #endif
26034 cimglist_for(*this,l) (*this)[l]/=val;
26035 return *this;
26036 }
26037
26039 template<typename t> CImgList<T>& operator/=(const CImgList<t>& list) {
26040 const unsigned int N = cimg::min(size,list.size);
26041 for (unsigned int l=0; l<N; ++l) (*this)[l]/=list[l];
26042 return this;
26043 }
26044
26046 const T& max() const {
26047 if (is_empty()) throw CImgInstanceException("CImgList<%s>::max() : Instance image list is empty.",pixel_type());
26048 const T *ptrmax = data->data;
26049 T max_value = *ptrmax;
26050 cimglist_for(*this,l) {
26051 const CImg<T>& img = data[l];
26052 cimg_for(img,ptr,T) if ((*ptr)>max_value) max_value = *(ptrmax=ptr);
26053 }
26054 return *ptrmax;
26055 }
26056
26058 T& max() {
26059 if (is_empty()) throw CImgInstanceException("CImgList<%s>::max() : Instance image list is empty.",pixel_type());
26060 T *ptrmax = data->data;
26061 T max_value = *ptrmax;
26062 cimglist_for(*this,l) {
26063 const CImg<T>& img = data[l];
26064 cimg_for(img,ptr,T) if ((*ptr)>max_value) max_value = *(ptrmax=ptr);
26065 }
26066 return *ptrmax;
26067 }
26068
26070 const T& min() const {
26071 if (is_empty()) throw CImgInstanceException("CImgList<%s>::min() : Instance image list is empty.",pixel_type());
26072 const T *ptrmin = data->data;
26073 T min_value = *ptrmin;
26074 cimglist_for(*this,l) {
26075 const CImg<T>& img = data[l];
26076 cimg_for(img,ptr,T) if ((*ptr)<min_value) min_value = *(ptrmin=ptr);
26077 }
26078 return *ptrmin;
26079 }
26080
26082 T& min() {
26083 if (is_empty()) throw CImgInstanceException("CImgList<%s>::min() : Instance image list is empty.",pixel_type());
26084 T *ptrmin = data->data;
26085 T min_value = *ptrmin;
26086 cimglist_for(*this,l) {
26087 const CImg<T>& img = data[l];
26088 cimg_for(img,ptr,T) if ((*ptr)<min_value) min_value = *(ptrmin=ptr);
26089 }
26090 return *ptrmin;
26091 }
26092
26094 template<typename t> const T& minmax(t& max_val) const {
26095 if (is_empty()) throw CImgInstanceException("CImgList<%s>::minmax() : Instance image list is empty.",pixel_type());
26096 const T *ptrmin = data->data;
26097 T min_value = *ptrmin, max_value = min_value;
26098 cimglist_for(*this,l) {
26099 const CImg<T>& img = data[l];
26100 cimg_for(img,ptr,T) {
26101 const T val = *ptr;
26102 if (val<min_value) { min_value = val; ptrmin = ptr; }
26103 if (val>max_value) max_value = val;
26104 }
26105 }
26106 max_val = (t)max_value;
26107 return *ptrmin;
26108 }
26109
26111 template<typename t> T& minmax(t& max_val) {
26112 if (is_empty()) throw CImgInstanceException("CImgList<%s>::minmax() : Instance image list is empty.",pixel_type());
26113 T *ptrmin = data->data;
26114 T min_value = *ptrmin, max_value = min_value;
26115 cimglist_for(*this,l) {
26116 const CImg<T>& img = data[l];
26117 cimg_for(img,ptr,T) {
26118 const T val = *ptr;
26119 if (val<min_value) { min_value = val; ptrmin = ptr; }
26120 if (val>max_value) max_value = val;
26121 }
26122 }
26123 max_val = (t)max_value;
26124 return *ptrmin;
26125 }
26126
26128 template<typename t> const T& maxmin(t& min_val) const {
26129 if (is_empty()) throw CImgInstanceException("CImgList<%s>::maxmin() : Instance image list is empty.",pixel_type());
26130 const T *ptrmax = data->data;
26131 T min_value = *ptrmax, max_value = min_value;
26132 cimglist_for(*this,l) {
26133 const CImg<T>& img = data[l];
26134 cimg_for(img,ptr,T) {
26135 const T val = *ptr;
26136 if (val>max_value) { max_value = val; ptrmax = ptr; }
26137 if (val<min_value) min_value = val;
26138 }
26139 }
26140 min_val = (t)min_value;
26141 return *ptrmax;
26142 }
26143
26145 template<typename t> T& maxmin(t& min_val) {
26146 if (is_empty()) throw CImgInstanceException("CImgList<%s>::maxmin() : Instance image list is empty.",pixel_type());
26147 T *ptrmax = data->data;
26148 T min_value = *ptrmax, max_value = min_value;
26149 cimglist_for(*this,l) {
26150 const CImg<T>& img = data[l];
26151 cimg_for(img,ptr,T) {
26152 const T val = *ptr;
26153 if (val>max_value) { max_value = val; ptrmax = ptr; }
26154 if (val<min_value) min_value = val;
26155 }
26156 }
26157 min_val = (t)min_value;
26158 return *ptrmax;
26159 }
26160
26162 double mean() const {
26163 if (is_empty()) throw CImgInstanceException("CImgList<%s>::mean() : Instance image list is empty.",pixel_type());
26164 double val = 0;
26165 unsigned int siz = 0;
26166 cimglist_for(*this,l) {
26167 const CImg<T>& img = data[l];
26168 cimg_for(img,ptr,T) val+=(double)*ptr;
26169 siz+=img.size();
26170 }
26171 return val/siz;
26172 }
26173
26175 double variance() {
26176 if (is_empty())
26177 throw CImgInstanceException("CImgList<%s>::variance() : Instance image list is empty.",pixel_type());
26178 double res = 0;
26179 unsigned int siz = 0;
26180 double S = 0, S2 = 0;
26181 cimglist_for(*this,l) {
26182 const CImg<T>& img = data[l];
26183 cimg_for(img,ptr,T) { const double val = (double)*ptr; S+=val; S2+=val*val; }
26184 siz+=img.size();
26185 }
26186 res = (S2 - S*S/siz)/siz;
26187 return res;
26188 }
26189
26191
26192
26194
26195
26196
26198 CImg<T>& operator[](const unsigned int pos) {
26199 #if cimg_debug>=3
26200 if (pos>=size) {
26201 cimg::warn("CImgList<%s>::operator[] : bad list position %u, in a list of %u images",pixel_type(),pos,size);
26202 return *data;
26203 }
26204 #endif
26205 return data[pos];
26206 }
26207
26208 const CImg<T>& operator[](const unsigned int pos) const {
26209 #if cimg_debug>=3
26210 if (pos>=size) {
26211 cimg::warn("CImgList<%s>::operator[] : bad list position %u, in a list of %u images",pixel_type(),pos,size);
26212 return *data;
26213 }
26214 #endif
26215 return data[pos];
26216 }
26217
26219 CImg<T>& operator()(const unsigned int pos) {
26220 return (*this)[pos];
26221 }
26222
26223 const CImg<T>& operator()(const unsigned int pos) const {
26224 return (*this)[pos];
26225 }
26226
26228 T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0,
26229 const unsigned int z=0, const unsigned int v=0) {
26230 return (*this)[pos](x,y,z,v);
26231 }
26232 const T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0,
26233 const unsigned int z=0, const unsigned int v=0) const {
26234 return (*this)[pos](x,y,z,v);
26235 }
26236
26238 CImg<T>& at(const unsigned int pos) {
26239 if (pos>=size)
26240 throw CImgArgumentException("CImgList<%s>::at() : bad list position %u, in a list of %u images",
26241 pixel_type(),pos,size);
26242 return data[pos];
26243 }
26244
26245 const CImg<T>& at(const unsigned int pos) const {
26246 if (pos>=size)
26247 throw CImgArgumentException("CImgList<%s>::at() : bad list position %u, in a list of %u images",
26248 pixel_type(),pos,size);
26249 return data[pos];
26250 }
26251
26253 CImg<T>& back() {
26254 return (*this)(size-1);
26255 }
26256
26257 const CImg<T>& back() const {
26258 return (*this)(size-1);
26259 }
26260
26262 CImg<T>& front() {
26263 return *data;
26264 }
26265
26266 const CImg<T>& front() const {
26267 return *data;
26268 }
26269
26271 iterator begin() {
26272 return data;
26273 }
26274
26275 const_iterator begin() const {
26276 return data;
26277 }
26278
26280 iterator end() {
26281 return data + size;
26282 }
26283
26284 const_iterator end() const {
26285 return data + size;
26286 }
26287
26289 template<typename t> CImgList<typename cimg::superset<T,t>::type>
26290 get_insert(const CImg<t>& img, const unsigned int pos=~0U, const bool shared=false) const {
26291 typedef typename cimg::superset<T,t>::type restype;
26292 return CImgList<restype>(*this).insert(img,pos,shared);
26293 }
26294
26296 template<typename t> CImgList<T>& insert(const CImg<t>& img, const unsigned int pos, const bool shared) {
26297 const unsigned int npos = pos==~0U?size:pos;
26298 if (npos>size)
26299 throw CImgArgumentException("CImgList<%s>::insert() : Cannot insert at position %u into a list with %u elements",
26300 pixel_type(),npos,size);
26301 if (shared)
26302 throw CImgArgumentException("CImgList<%s>::insert(): Cannot insert a shared image CImg<%s> into a CImgList<%s>",
26303 pixel_type(),img.pixel_type(),pixel_type());
26304 CImg<T> *new_data = (++size>allocsize)?new CImg<T>[allocsize?(allocsize<<=1):(allocsize=1)]:0;
26305 if (!size || !data) {
26306 data = new_data;
26307 *data = img;
26308 } else {
26309 if (new_data) {
26310 if (npos) std::memcpy(new_data,data,sizeof(CImg<T>)*npos);
26311 if (npos!=size-1) std::memcpy(new_data+npos+1,data+npos,sizeof(CImg<T>)*(size-1-npos));
26312 std::memset(data,0,sizeof(CImg<T>)*(size-1));
26313 delete[] data;
26314 data = new_data;
26315 }
26316 else if (npos!=size-1) std::memmove(data+npos+1,data+npos,sizeof(CImg<T>)*(size-1-npos));
26317 data[npos].width = data[npos].height = data[npos].depth = data[npos].dim = 0; data[npos].data = 0;
26318 data[npos] = img;
26319 }
26320 return *this;
26321 }
26322
26323 CImgList<T>& insert(const CImg<T>& img, const unsigned int pos, const bool shared) {
26324 const unsigned int npos = pos==~0U?size:pos;
26325 if (npos>size)
26326 throw CImgArgumentException("CImgList<%s>::insert() : Can't insert at position %u into a list with %u elements",
26327 pixel_type(),npos,size);
26328 CImg<T> *new_data = (++size>allocsize)?new CImg<T>[allocsize?(allocsize<<=1):(allocsize=1)]:0;
26329 if (!size || !data) {
26330 data = new_data;
26331 if (shared && img) {
26332 data->width = img.width; data->height = img.height; data->depth = img.depth; data->dim = img.dim;
26333 data->is_shared = true; data->data = img.data;
26334 } else *data = img;
26335 }
26336 else {
26337 if (new_data) {
26338 if (npos) std::memcpy(new_data,data,sizeof(CImg<T>)*npos);
26339 if (npos!=size-1) std::memcpy(new_data+npos+1,data+npos,sizeof(CImg<T>)*(size-1-npos));
26340 if (shared && img) {
26341 new_data[npos].width = img.width; new_data[npos].height = img.height; new_data[npos].depth = img.depth;
26342 new_data[npos].dim = img.dim; new_data[npos].is_shared = true; new_data[npos].data = img.data;
26343 } else {
26344 new_data[npos].width = new_data[npos].height = new_data[npos].depth = new_data[npos].dim = 0; new_data[npos].data = 0;
26345 new_data[npos] = img;
26346 }
26347 std::memset(data,0,sizeof(CImg<T>)*(size-1));
26348 delete[] data;
26349 data = new_data;
26350 } else {
26351 if (npos!=size-1) std::memmove(data+npos+1,data+npos,sizeof(CImg<T>)*(size-1-npos));
26352 if (shared && img) {
26353 data[npos].width = img.width; data[npos].height = img.height; data[npos].depth = img.depth; data[npos].dim = img.dim;
26354 data[npos].is_shared = true; data[npos].data = img.data;
26355 } else {
26356 data[npos].width = data[npos].height = data[npos].depth = data[npos].dim = 0; data[npos].data = 0;
26357 data[npos] = img;
26358 }
26359 }
26360 }
26361 return *this;
26362 }
26363
26364
26365
26366 template<typename t> CImgList<T>& insert(const CImg<t>& img, const unsigned int pos) {
26367 return insert(img,pos,false);
26368 }
26369
26371 template<typename t> CImgList<T>& insert(const CImg<t>& img) {
26372 return insert(img,~0U,false);
26373 }
26374
26376 template<typename t> CImgList<typename cimg::superset<T,t>::type>
26377 get_insert(const unsigned int n, const CImg<t>& img, const unsigned int pos=~0U, const bool shared=false) const {
26378 typedef typename cimg::superset<T,t>::type restype;
26379 return CImgList<restype>(*this).insert(n,img,pos,shared);
26380 }
26381
26383 template<typename t> CImgList<T>& insert(const unsigned int n, const CImg<t>& img, const unsigned int pos=~0U, const bool shared=false) {
26384 const unsigned int npos = pos==~0U?size:pos;
26385 insert(img,npos,shared);
26386 for (unsigned int i=1; i<n; ++i) insert(data[npos],npos+i,shared);
26387 return *this;
26388 }
26389
26391 template<typename t> CImgList<typename cimg::superset<T,t>::type>
26392 get_insert(const CImgList<t>& list, const unsigned int pos=~0U, int shared=0) const {
26393 typedef typename cimg::superset<T,t>::type restype;
26394 return CImgList<restype>(*this).insert(list,pos,shared);
26395 }
26396
26398 template<typename t> CImgList<T>& insert(const CImgList<t>& list, const unsigned int pos=~0U, const int shared=0) {
26399 const unsigned int npos = pos==~0U?size:pos;
26400 if ((void*)this!=(void*)&list) {
26401 if (shared>=0) cimglist_for(list,l) insert(list[l],npos+l,shared?true:false);
26402 else cimglist_for(list,l) insert(list[l],npos+l,list[l].is_shared);
26403 } else insert(CImgList<T>(list),npos,shared);
26404 return *this;
26405 }
26406
26408 template<typename t> CImgList<typename cimg::superset<T,t>::type>
26409 get_insert(const unsigned int n, const CImgList<t>& list, const unsigned int pos=~0U, const int shared=0) const {
26410 typedef typename cimg::superset<T,t>::type restype;
26411 return CImgList<restype>(*this).insert(n,list,pos,shared);
26412 }
26413
26415 template<typename t> CImgList<T>& insert(const unsigned int n, const CImgList<t>& list, const unsigned int pos=~0U, const int shared=0) {
26416 const unsigned int npos = pos==~0U?size:pos;
26417 for (unsigned int i=0; i<n; ++i) insert(list,npos,shared);
26418 return *this;
26419 }
26420
26422 CImgList<T> get_remove(const unsigned int pos) const {
26423 return (+*this).remove(pos);
26424 }
26425
26427 CImgList<T>& remove(const unsigned int pos) {
26428 if (pos>=size)
26429 cimg::warn("CImgList<%s>::remove() : Cannot remove an image from a list (%p,%u), at position %u.",
26430 pixel_type(),data,size,pos);
26431 else {
26432 data[pos].assign();
26433 if (!(--size)) return assign();
26434 if (size<8 || size>(allocsize>>2)) {
26435 if (pos!=size) {
26436 std::memmove(data+pos,data+pos+1,sizeof(CImg<T>)*(size-pos));
26437 CImg<T> &tmp = data[size];
26438 tmp.width = tmp.height = tmp.depth = tmp.dim = 0; tmp.data = 0;
26439 }
26440 } else {
26441 allocsize>>=2;
26442 CImg<T> *new_data = new CImg<T>[allocsize];
26443 if (pos) std::memcpy(new_data,data,sizeof(CImg<T>)*pos);
26444 if (pos!=size) std::memcpy(new_data+pos,data+pos+1,sizeof(CImg<T>)*(size-pos));
26445 std::memset(data,0,sizeof(CImg<T>)*(size+1));
26446 delete[] data;
26447 data = new_data;
26448 }
26449 }
26450 return *this;
26451 }
26452
26454 CImgList<T> get_remove() const {
26455 return (+*this).remove();
26456 }
26457
26459 CImgList<T>& remove() {
26460 if (size) return remove(size-1);
26461 else cimg::warn("CImgList<%s>::remove() : List is empty",pixel_type());
26462 return *this;
26463 }
26464
26466 CImgList<T> get_reverse() const {
26467 return (+*this).reverse();
26468 }
26469
26471 CImgList<T>& reverse() {
26472 for (unsigned int l=0; l<size/2; ++l) (*this)[l].swap((*this)[size-1-l]);
26473 return *this;
26474 }
26475
26477 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1, const bool shared=false) const {
26478 if (i0>i1 || i1>=size)
26479 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26480 pixel_type(),i0,i1,size,data);
26481 CImgList<T> res(i1-i0+1);
26482 cimglist_for(res,l) res[l].assign((*this)[i0+l],shared);
26483 return res;
26484 }
26485
26487 CImgList<T>& crop(const unsigned int i0, const unsigned int i1, const bool shared=false) {
26488 return get_crop(i0,i1,shared).assign_to(*this);
26489 }
26490
26492 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1,
26493 const int x0, const int y0, const int z0, const int v0,
26494 const int x1, const int y1, const int z1, const int v1) const {
26495 if (i0>i1 || i1>=size)
26496 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26497 pixel_type(),i0,i1,size,data);
26498 CImgList<T> res(i1-i0+1);
26499 cimglist_for(res,l) res[l] = (*this)[i0+l].get_crop(x0,y0,z0,v0,x1,y1,z1,v1);
26500 return res;
26501 }
26502
26504 CImgList<T>& crop(const unsigned int i0, const unsigned int i1,
26505 const int x0, const int y0, const int z0, const int v0,
26506 const int x1, const int y1, const int z1, const int v1) {
26507 return get_crop(i0,i1,x0,y0,z0,v0,x1,y1,z1,v1).assign_to(*this);
26508 }
26509
26511 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1,
26512 const int x0, const int y0, const int z0,
26513 const int x1, const int y1, const int z1) const {
26514 if (i0>i1 || i1>=size)
26515 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26516 pixel_type(),i0,i1,size,data);
26517 CImgList<T> res(i1-i0+1);
26518 cimglist_for(res,l) res[l] = (*this)[i0+l].get_crop(x0,y0,z0,x1,y1,z1);
26519 return res;
26520 }
26521
26523 CImgList<T>& crop(const unsigned int i0, const unsigned int i1,
26524 const int x0, const int y0, const int z0,
26525 const int x1, const int y1, const int z1) {
26526 return get_crop(i0,i1,x0,y0,z0,x1,y1,z1).assign_to(*this);
26527 }
26528
26530 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1,
26531 const int x0, const int y0,
26532 const int x1, const int y1) const {
26533 if (i0>i1 || i1>=size)
26534 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26535 pixel_type(),i0,i1,size,data);
26536 CImgList<T> res(i1-i0+1);
26537 cimglist_for(res,l) res[l] = (*this)[i0+l].get_crop(x0,y0,x1,y1);
26538 return res;
26539 }
26540
26542 CImgList<T>& crop(const unsigned int i0, const unsigned int i1,
26543 const int x0, const int y0,
26544 const int x1, const int y1) {
26545 return get_crop(i0,i1,x0,y0,x1,y1).assign_to(*this);
26546 }
26547
26549 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1,
26550 const int x0, const int x1) const {
26551 if (i0>i1 || i1>=size)
26552 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26553 pixel_type(),i0,i1,size,data);
26554 CImgList<T> res(i1-i0+1);
26555 cimglist_for(res,l) res[l] = (*this)[i0+l].get_crop(x0,x1);
26556 return res;
26557 }
26558
26560 CImgList<T>& crop(const unsigned int i0, const unsigned int i1,
26561 const int x0, const int x1) {
26562 return get_crop(i0,i1,x0,x1).assign_to(*this);
26563 }
26564
26566 template<typename t> CImgList<T>& operator<<(const CImg<t>& img) {
26567 return insert(img);
26568 }
26569
26571 template<typename t> CImgList<T>& operator<<(const CImgList<t>& list) {
26572 return insert(list);
26573 }
26574
26576 template<typename t> CImgList<T>& operator>>(CImg<t>& img) const {
26577 typedef typename cimg::superset<T,t>::type restype;
26578 return CImgList<restype>(*this).insert(img);
26579 }
26580
26582 template<typename t> CImgList<T>& operator>>(CImgList<t>& list) const {
26583 return list.insert(*this,0);
26584 }
26585
26587 const CImgList<T>& operator>>(CImgDisplay& disp) const {
26588 return display(disp);
26589 }
26590
26592 template<typename t> CImgList<T>& push_back(const CImg<t>& img) {
26593 return insert(img);
26594 }
26595
26597 template<typename t> CImgList<T>& push_front(const CImg<t>& img) {
26598 return insert(img,0);
26599 }
26600
26602 template<typename t> CImgList<T>& push_back(const CImgList<t>& list) {
26603 return insert(list);
26604 }
26605
26607 template<typename t> CImgList<T>& push_front(const CImgList<t>& list) {
26608 return insert(list,0);
26609 }
26610
26612 CImgList<T>& pop_back() {
26613 return remove(size-1);
26614 }
26615
26617 CImgList<T>& pop_front() {
26618 return remove(0);
26619 }
26620
26622 CImgList<T>& erase(const iterator iter) {
26623 return remove(iter-data);
26624 }
26625
26627
26628
26630
26631
26632
26634 CImgList<typename cimg::superset<T,float>::type> get_FFT(const char axe, const bool inverse=false) const {
26635 typedef typename cimg::superset<T,float>::type restype;
26636 return CImgList<restype>(*this).FFT(axe,inverse);
26637 }
26638
26640 CImgList<T>& FFT(const char axe, const bool inverse=false) {
26641 if (is_empty()) throw CImgInstanceException("CImgList<%s>::FFT() : Instance list (%u,%p) is empty",pixel_type(),size,data);
26642 if (!data[0]) throw CImgInstanceException("CImgList<%s>::FFT() : Real part (%u,%u,%u,%u,%p) is empty",
26643 pixel_type(),data[0].width,data[0].height,data[0].depth,data[0].dim,data[0].data);
26644 if (size>2) cimg::warn("CImgList<%s>::FFT() : Instance list (%u,%p) have more than 2 images",pixel_type(),size,data);
26645 if (size==1) insert(CImg<T>(data[0].width,data[0].height,data[0].depth,data[0].dim,0));
26646 CImg<T> &Ir = data[0], &Ii = data[1];
26647 if (Ir.width!=Ii.width || Ir.height!=Ii.height || Ir.depth!=Ii.depth || Ir.dim!=Ii.dim)
26648 throw CImgInstanceException("CImgList<%s>::FFT() : Real part (%u,%u,%u,%u,%p) and imaginary part (%u,%u,%u,%u,%p)"
26649 "have different dimensions",pixel_type(),
26650 Ir.width,Ir.height,Ir.depth,Ir.dim,Ir.data,Ii.width,Ii.height,Ii.depth,Ii.dim,Ii.data);
26651
26652 #ifdef cimg_use_fftw3
26653 fftw_complex *data_in;
26654 fftw_plan data_plan;
26655
26656 switch (cimg::uncase(axe)) {
26657 case 'x': {
26658 data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.width);
26659 data_plan = fftw_plan_dft_1d(Ir.width, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
26660 cimg_forYZV(Ir,y,z,k) {
26661 T *ptrr = Ir.ptr(0,y,z,k), *ptri = Ii.ptr(0,y,z,k);
26662 double *ptrd = (double*)data_in;
26663 cimg_forX(Ir,x) { *(ptrd++) = (double)*(ptrr++); *(ptrd++) = (double)*(ptri++); }
26664 fftw_execute(data_plan);
26665 { cimg_forX(Ir,x) { *(--ptri) = (T)*(--ptrd); *(--ptrr) = (T)*(--ptrd); }}
26666 }
26667 } break;
26668
26669 case 'y': {
26670 data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.height);
26671 data_plan = fftw_plan_dft_1d(Ir.height, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
26672 const unsigned int off = Ir.width;
26673 cimg_forXZV(Ir,x,z,k) {
26674 T *ptrr = Ir.ptr(x,0,z,k), *ptri = Ii.ptr(x,0,z,k);
26675 double *ptrd = (double*)data_in;
26676 cimg_forY(Ir,y) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; }
26677 fftw_execute(data_plan);
26678 { cimg_forY(Ir,y) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }}
26679 }
26680 } break;
26681
26682 case 'z': {
26683 data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.depth);
26684 data_plan = fftw_plan_dft_1d(Ir.depth, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
26685 const unsigned int off = Ir.width*Ir.height;
26686 cimg_forXYV(Ir,x,y,k) {
26687 T *ptrr = Ir.ptr(x,y,0,k), *ptri = Ii.ptr(x,y,0,k);
26688 double *ptrd = (double*)data_in;
26689 cimg_forZ(Ir,z) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; }
26690 fftw_execute(data_plan);
26691 { cimg_forZ(Ir,z) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }}
26692 }
26693 } break;
26694
26695 case 'v': {
26696 data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.dim);
26697 data_plan = fftw_plan_dft_1d(Ir.dim, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
26698 const unsigned int off = Ir.width*Ir.height*Ir.depth;
26699 cimg_forXYZ(Ir,x,y,z) {
26700 T *ptrr = Ir.ptr(x,y,z,0), *ptri = Ii.ptr(x,y,z,0);
26701 double *ptrd = (double*)data_in;
26702 cimg_forV(Ir,k) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; }
26703 fftw_execute(data_plan);
26704 { cimg_forV(Ir,k) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }}
26705 }
26706 } break;
26707 }
26708
26709 fftw_destroy_plan(data_plan);
26710 fftw_free(data_in);
26711 #else
26712 switch (cimg::uncase(axe)) {
26713 case 'x': {
26714 const unsigned int N = Ir.width, N2 = (N>>1);
26715 if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image along 'x' is %d != 2^N",
26716 pixel_type(),N);
26717 for (unsigned int i=0, j=0; i<N2; ++i) {
26718 if (j>i) cimg_forYZV(Ir,y,z,v) { cimg::swap(Ir(i,y,z,v),Ir(j,y,z,v)); cimg::swap(Ii(i,y,z,v),Ii(j,y,z,v));
26719 if (j<N2) {
26720 const unsigned int ri = N-1-i, rj = N-1-j;
26721 cimg::swap(Ir(ri,y,z,v),Ir(rj,y,z,v)); cimg::swap(Ii(ri,y,z,v),Ii(rj,y,z,v));
26722 }}
26723 for (unsigned int m=N, n=N2; (j+=n)>=m; j-=m, m=n, n>>=1);
26724 }
26725 for (unsigned int delta=2; delta<=N; delta<<=1) {
26726 const unsigned int delta2 = (delta>>1);
26727 for (unsigned int i=0; i<N; i+=delta) {
26728 float wr = 1, wi = 0;
26729 const float angle = (float)((inverse?+1:-1)*2*cimg::PI/delta),
26730 ca = (float)std::cos(angle),
26731 sa = (float)std::sin(angle);
26732 for (unsigned int k=0; k<delta2; ++k) {
26733 const unsigned int j = i + k, nj = j + delta2;
26734 cimg_forYZV(Ir,y,z,k) {
26735 T &ir = Ir(j,y,z,k), &ii = Ii(j,y,z,k), &nir = Ir(nj,y,z,k), &nii = Ii(nj,y,z,k);
26736 const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
26737 nir = (T)(ir - tmpr);
26738 nii = (T)(ii - tmpi);
26739 ir += (T)tmpr;
26740 ii += (T)tmpi;
26741 }
26742 const float nwr = wr*ca-wi*sa;
26743 wi = wi*ca + wr*sa;
26744 wr = nwr;
26745 }
26746 }
26747 }
26748 if (inverse) (*this)/=N;
26749 } break;
26750
26751 case 'y': {
26752 const unsigned int N = Ir.height, N2 = (N>>1);
26753 if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image(s) along 'y' is %d != 2^N",
26754 pixel_type(),N);
26755 for (unsigned int i=0, j=0; i<N2; ++i) {
26756 if (j>i) cimg_forXZV(Ir,x,z,v) { cimg::swap(Ir(x,i,z,v),Ir(x,j,z,v)); cimg::swap(Ii(x,i,z,v),Ii(x,j,z,v));
26757 if (j<N2) {
26758 const unsigned int ri = N-1-i, rj = N-1-j;
26759 cimg::swap(Ir(x,ri,z,v),Ir(x,rj,z,v)); cimg::swap(Ii(x,ri,z,v),Ii(x,rj,z,v));
26760 }}
26761 for (unsigned int m=N, n=N2; (j+=n)>=m; j-=m, m=n, n>>=1);
26762 }
26763 for (unsigned int delta=2; delta<=N; delta<<=1) {
26764 const unsigned int delta2 = (delta>>1);
26765 for (unsigned int i=0; i<N; i+=delta) {
26766 float wr = 1, wi = 0;
26767 const float angle = (float)((inverse?+1:-1)*2*cimg::PI/delta),
26768 ca = (float)std::cos(angle), sa = (float)std::sin(angle);
26769 for (unsigned int k=0; k<delta2; ++k) {
26770 const unsigned int j = i + k, nj = j + delta2;
26771 cimg_forXZV(Ir,x,z,k) {
26772 T &ir = Ir(x,j,z,k), &ii = Ii(x,j,z,k), &nir = Ir(x,nj,z,k), &nii = Ii(x,nj,z,k);
26773 const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
26774 nir = (T)(ir - tmpr);
26775 nii = (T)(ii - tmpi);
26776 ir += (T)tmpr;
26777 ii += (T)tmpi;
26778 }
26779 const float nwr = wr*ca-wi*sa;
26780 wi = wi*ca + wr*sa;
26781 wr = nwr;
26782 }
26783 }
26784 }
26785 if (inverse) (*this)/=N;
26786 } break;
26787
26788 case 'z': {
26789 const unsigned int N = Ir.depth, N2 = (N>>1);
26790 if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image(s) along 'z' is %d != 2^N",
26791 pixel_type(),N);
26792 for (unsigned int i=0, j=0; i<N2; ++i) {
26793 if (j>i) cimg_forXYV(Ir,x,y,v) { cimg::swap(Ir(x,y,i,v),Ir(x,y,j,v)); cimg::swap(Ii(x,y,i,v),Ii(x,y,j,v));
26794 if (j<N2) {
26795 const unsigned int ri = N-1-i, rj = N-1-j;
26796 cimg::swap(Ir(x,y,ri,v),Ir(x,y,rj,v)); cimg::swap(Ii(x,y,ri,v),Ii(x,y,rj,v));
26797 }}
26798 for (unsigned int m=N, n=N2; (j+=n)>=m; j-=m, m=n, n>>=1);
26799 }
26800 for (unsigned int delta=2; delta<=N; delta<<=1) {
26801 const unsigned int delta2 = (delta>>1);
26802 for (unsigned int i=0; i<N; i+=delta) {
26803 float wr = 1, wi = 0;
26804 const float angle = (float)((inverse?+1:-1)*2*cimg::PI/delta),
26805 ca = (float)std::cos(angle), sa = (float)std::sin(angle);
26806 for (unsigned int k=0; k<delta2; ++k) {
26807 const unsigned int j = i + k, nj = j + delta2;
26808 cimg_forXYV(Ir,x,y,k) {
26809 T &ir = Ir(x,y,j,k), &ii = Ii(x,y,j,k), &nir = Ir(x,y,nj,k), &nii = Ii(x,y,nj,k);
26810 const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
26811 nir = (T)(ir - tmpr);
26812 nii = (T)(ii - tmpi);
26813 ir += (T)tmpr;
26814 ii += (T)tmpi;
26815 }
26816 const float nwr = wr*ca-wi*sa;
26817 wi = wi*ca + wr*sa;
26818 wr = nwr;
26819 }
26820 }
26821 }
26822 if (inverse) (*this)/=N;
26823 } break;
26824
26825 default: throw CImgArgumentException("CImgList<%s>::FFT() : unknown axe '%c', must be 'x','y' or 'z'");
26826 }
26827 #endif
26828 return *this;
26829 }
26830
26832 CImgList<typename cimg::superset<T,float>::type> get_FFT(const bool inverse=false) const {
26833 typedef typename cimg::superset<T,float>::type restype;
26834 return CImgList<restype>(*this).FFT(inverse);
26835 }
26836
26838 CImgList<T>& FFT(const bool inverse=false) {
26839 if (is_empty()) throw CImgInstanceException("CImgList<%s>::FFT() : Instance list (%u,%p) is empty",pixel_type(),size,data);
26840 if (size>2) cimg::warn("CImgList<%s>::FFT() : Instance list (%u,%p) have more than 2 images",pixel_type(),size,data);
26841 if (size==1) insert(CImg<T>(data->width,data->height,data->depth,data->dim,0));
26842 CImg<T> &Ir = data[0], &Ii = data[1];
26843 if (Ii.width!=Ir.width || Ii.height!=Ir.height || Ii.depth!=Ir.depth || Ii.dim!=Ir.dim)
26844 throw CImgInstanceException("CImgList<%s>::FFT() : Real (%u,%u,%u,%u,%p) and Imaginary (%u,%u,%u,%u,%p) parts "
26845 "of the instance image have different dimensions",
26846 pixel_type(),Ir.width,Ir.height,Ir.depth,Ir.dim,Ir.data,
26847 Ii.width,Ii.height,Ii.depth,Ii.dim,Ii.data);
26848 #ifdef cimg_use_fftw3
26849 fftw_complex *data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.width*Ir.height*Ir.depth);
26850 fftw_plan data_plan;
26851 const unsigned int w = Ir.width, wh = w*Ir.height, whd = wh*Ir.depth;
26852 data_plan = fftw_plan_dft_3d(Ir.width, Ir.height, Ir.depth, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
26853 cimg_forV(Ir,k) {
26854 T *ptrr = Ir.ptr(0,0,0,k), *ptri = Ii.ptr(0,0,0,k);
26855 double *ptrd = (double*)data_in;
26856 cimg_forX(Ir,x) {
26857 cimg_forY(Ir,y) {
26858 cimg_forZ(Ir,z) {
26859 *(ptrd++) = (double)*ptrr;
26860 *(ptrd++) = (double)*ptri;
26861 ptrr+=wh;
26862 ptri+=wh;
26863 }
26864 ptrr-=whd-w;
26865 ptri-=whd-w;
26866 }
26867 ptrr-=wh-1;
26868 ptri-=wh-1;
26869 }
26870 fftw_execute(data_plan);
26871 ptrd = (double*)data_in;
26872 ptrr = Ir.ptr(0,0,0,k);
26873 ptri = Ii.ptr(0,0,0,k);
26874 { cimg_forX(Ir,x) {
26875 cimg_forY(Ir,y) {
26876 cimg_forZ(Ir,z) {
26877 *ptrr = (T)*(ptrd++);
26878 *ptri = (T)*(ptrd++);
26879 ptrr+=wh;
26880 ptri+=wh;
26881 }
26882 ptrr-=whd-w;
26883 ptri-=whd-w;
26884 }
26885 ptrr-=wh-1;
26886 ptri-=wh-1;
26887 }}
26888 }
26889 fftw_destroy_plan(data_plan);
26890 fftw_free(data_in);
26891 #else
26892 if (Ir.depth>1) FFT('z',inverse);
26893 if (Ir.height>1) FFT('y',inverse);
26894 if (Ir.width>1) FFT('x',inverse);
26895 #endif
26896 return *this;
26897 }
26898
26900
26901
26903
26904
26905
26907 const CImgList<T>& print(const char* title=0, const int print_flag=1) const {
26908 if (print_flag>=0) {
26909 char tmp[1024];
26910 std::fprintf(stderr,"%-8s(this=%p) : { size=%u, data=%p }\n",title?title:"CImgList",
26911 (void*)this,size,(void*)data);
26912 switch (print_flag) {
26913 case 1: {
26914 cimglist_for(*this,l)
26915 if (l<4 || l>=size-4) {
26916 std::sprintf(tmp,"%s[%d]",title?title:"CImgList",l);
26917 data[l].print(tmp,print_flag);
26918 } else {
26919 if (l==4) std::fprintf(stderr,"...\n");
26920 }
26921 } break;
26922 default: {
26923 cimglist_for(*this,l) {
26924 std::sprintf(tmp,"%s[%d]",title?title:"CImgList",l);
26925 data[l].print(tmp,print_flag);
26926 }
26927 } break;
26928 }
26929 }
26930 return *this;
26931 }
26932
26934 const CImgList<T>& print(const int print_flag) const {
26935 return print(0,print_flag);
26936 }
26937
26939 static CImgList<T> get_load(const char *const filename) {
26940 return CImgList<T>().load(filename);
26941 }
26942
26944 CImgList<T>& load(const char *const filename) {
26945 const char *ext = cimg::filename_split(filename);
26946 #ifdef cimglist_load_plugin
26947 cimglist_load_plugin(filename);
26948 #endif
26949 if (!cimg::strncasecmp(ext,"cimg",4) || !ext[0]) return load_cimg(filename);
26950 if (!cimg::strncasecmp(ext,"rec",3) ||
26951 !cimg::strncasecmp(ext,"par",3)) return load_parrec(filename);
26952 assign(1);
26953 data->load(filename);
26954 return *this;
26955 }
26956
26958 static CImgList<T> get_load_cimg(std::FILE *const file, const char *const filename=0) {
26959 return CImgList<T>().load_cimg(file,filename);
26960 }
26961
26963 CImgList<T>& load_cimg(std::FILE *const file, const char *const filename=0) {
26964 #define cimg_load_cimg_case(Ts,Tss) \
26965 if (!loaded && !cimg::strcasecmp(Ts,str_pixeltype)) { \
26966 for (unsigned int l=0; l<N; ++l) { \
26967 j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++] = (char)i; tmp[j] = '\0'; \
26968 W = H = D = V = 0; \
26969 if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) \
26970 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", \
26971 pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); \
26972 if (W*H*D*V>0) { \
26973 CImg<Tss> raw; \
26974 CImg<T> &img = data[l]; \
26975 img.assign(W,H,D,V); \
26976 T *ptrd = img.data; \
26977 for (int toread = (int)img.size(); toread>0; ) { \
26978 raw.assign(cimg::min(toread,cimg_iobuffer)); \
26979 cimg::fread(raw.data,raw.width,nfile); \
26980 if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); \
26981 toread-=raw.width; \
26982 const Tss *ptrs = raw.data; \
26983 for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); \
26984 } \
26985 } \
26986 } \
26987 loaded = true; \
26988 }
26989 typedef unsigned char uchar;
26990 typedef unsigned short ushort;
26991 typedef unsigned int uint;
26992 typedef unsigned long ulong;
26993 const int cimg_iobuffer = 12*1024*1024;
26994 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
26995 bool loaded = false, endian = cimg::endian();
26996 char tmp[256], str_pixeltype[256], str_endian[256];
26997 unsigned int j, err, N=0, W, H, D, V;
26998 int i;
26999 j = 0; while((i=std::fgetc(nfile))!='\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = '\0';
27000 err = std::sscanf(tmp,"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian);
27001 if (err<2) {
27002 if (!file) cimg::fclose(nfile);
27003 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Unknow CImg RAW header.",
27004 pixel_type(),filename?filename:"(FILE*)");
27005 }
27006 if (!cimg::strncasecmp("little",str_endian,6)) endian = false;
27007 else if (!cimg::strncasecmp("big",str_endian,3)) endian = true;
27008 assign(N);
27009 cimg_load_cimg_case("bool",bool);
27010 cimg_load_cimg_case("unsigned_char",uchar);
27011 cimg_load_cimg_case("uchar",uchar);
27012 cimg_load_cimg_case("char",char);
27013 cimg_load_cimg_case("unsigned_short",ushort);
27014 cimg_load_cimg_case("ushort",ushort);
27015 cimg_load_cimg_case("short",short);
27016 cimg_load_cimg_case("unsigned_int",uint);
27017 cimg_load_cimg_case("uint",uint);
27018 cimg_load_cimg_case("int",int);
27019 cimg_load_cimg_case("unsigned_long",ulong);
27020 cimg_load_cimg_case("ulong",ulong);
27021 cimg_load_cimg_case("long",long);
27022 cimg_load_cimg_case("float",float);
27023 cimg_load_cimg_case("double",double);
27024 if (!loaded) {
27025 if (!file) cimg::fclose(nfile);
27026 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', cannot read images of pixels coded as '%s'.",
27027 pixel_type(),filename?filename:"(FILE*)",str_pixeltype);
27028 }
27029 if (!file) cimg::fclose(nfile);
27030 return *this;
27031 }
27032
27034 static CImgList<T> get_load_cimg(const char *const filename) {
27035 return CImgList<T>().load_cimg(0,filename);
27036 }
27037
27039 CImgList<T>& load_cimg(const char *const filename) {
27040 return load_cimg(0,filename);
27041 }
27042
27044 static CImgList<T> get_load_cimg(std::FILE *const file,
27045 const unsigned int n0, const unsigned int n1,
27046 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27047 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27048 return CImgList<T>().load_cimg(file,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27049 }
27050
27052 CImgList<T>& load_cimg(std::FILE *const file,
27053 const unsigned int n0, const unsigned int n1,
27054 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27055 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27056 return load_cimg(file,0,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27057 }
27058
27060 static CImgList<T> get_load_cimg(const char *const filename,
27061 const unsigned int n0, const unsigned int n1,
27062 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27063 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27064 return CImgList<T>().load_cimg(filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27065 }
27066
27068 CImgList<T>& load_cimg(const char *const filename,
27069 const unsigned int n0, const unsigned int n1,
27070 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27071 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27072 return load_cimg(0,filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27073 }
27074
27076 CImgList<T>& load_cimg(std::FILE *const file, const char *const filename,
27077 const unsigned int n0, const unsigned int n1,
27078 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27079 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27080 #define cimg_load_cimg_case2(Ts,Tss) \
27081 if (!loaded && !cimg::strcasecmp(Ts,str_pixeltype)) { \
27082 for (unsigned int l=0; l<=nn1; ++l) { \
27083 j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; \
27084 W = H = D = V = 0; \
27085 if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) \
27086 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", \
27087 pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); \
27088 if (W*H*D*V>0) { \
27089 if (l<n0 || x0>=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(Tss),SEEK_CUR); \
27090 else { \
27091 const unsigned int \
27092 nx1 = x1>=W?W-1:x1, \
27093 ny1 = y1>=H?H-1:y1, \
27094 nz1 = z1>=D?D-1:z1, \
27095 nv1 = v1>=V?V-1:v1; \
27096 CImg<Tss> raw(1+nx1-x0); \
27097 CImg<T> &img = data[l-n0]; \
27098 img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); \
27099 T *ptrd = img.data; \
27100 const unsigned int skipvb = v0*W*H*D*sizeof(Tss); \
27101 if (skipvb) std::fseek(nfile,skipvb,SEEK_CUR); \
27102 for (unsigned int v=1+nv1-v0; v; --v) { \
27103 const unsigned int skipzb = z0*W*H*sizeof(Tss); \
27104 if (skipzb) std::fseek(nfile,skipzb,SEEK_CUR); \
27105 for (unsigned int z=1+nz1-z0; z; --z) { \
27106 const unsigned int skipyb = y0*W*sizeof(Tss); \
27107 if (skipyb) std::fseek(nfile,skipyb,SEEK_CUR); \
27108 for (unsigned int y=1+ny1-y0; y; --y) { \
27109 const unsigned int skipxb = x0*sizeof(Tss); \
27110 if (skipxb) std::fseek(nfile,skipxb,SEEK_CUR); \
27111 cimg::fread(raw.data,raw.width,nfile); \
27112 if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); \
27113 const Tss *ptrs = raw.data; \
27114 for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); \
27115 const unsigned int skipxe = (W-1-nx1)*sizeof(Tss); \
27116 if (skipxe) std::fseek(nfile,skipxe,SEEK_CUR); \
27117 } \
27118 const unsigned int skipye = (H-1-ny1)*W*sizeof(Tss); \
27119 if (skipye) std::fseek(nfile,skipye,SEEK_CUR); \
27120 } \
27121 const unsigned int skipze = (D-1-nz1)*W*H*sizeof(Tss); \
27122 if (skipze) std::fseek(nfile,skipze,SEEK_CUR); \
27123 } \
27124 const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(Tss); \
27125 if (skipve) std::fseek(nfile,skipve,SEEK_CUR); \
27126 } \
27127 } \
27128 } \
27129 loaded = true; \
27130 }
27131 typedef unsigned char uchar;
27132 typedef unsigned short ushort;
27133 typedef unsigned int uint;
27134 typedef unsigned long ulong;
27135 if (n1<n0 || x1<x0 || y1<y0 || z1<z0 || v1<v0)
27136 throw CImgArgumentException("CImgList<%s>::load_cimg() : File '%s', Bad sub-region coordinates [%u->%u] "
27137 "(%u,%u,%u,%u)->(%u,%u,%u,%u).",pixel_type(),filename?filename:"(FILE*)",
27138 n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27139 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
27140 bool loaded = false, endian = cimg::endian();
27141 char tmp[256], str_pixeltype[256], str_endian[256];
27142 unsigned int j, err, N, W, H, D, V;
27143 int i;
27144 j = 0; while((i=std::fgetc(nfile))!='\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = '\0';
27145 err = std::sscanf(tmp,"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian);
27146 if (err<2) {
27147 if (!file) cimg::fclose(nfile);
27148 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Unknow CImg RAW header.",
27149 pixel_type(),filename?filename:"(FILE*)");
27150 }
27151 if (!cimg::strncasecmp("little",str_endian,6)) endian = false;
27152 else if (!cimg::strncasecmp("big",str_endian,3)) endian = true;
27153 const unsigned int nn1 = n1>=N?N-1:n1;
27154 assign(1+nn1-n0);
27155 cimg_load_cimg_case2("bool",bool);
27156 cimg_load_cimg_case2("unsigned_char",uchar);
27157 cimg_load_cimg_case2("uchar",uchar);
27158 cimg_load_cimg_case2("char",char);
27159 cimg_load_cimg_case2("unsigned_short",ushort);
27160 cimg_load_cimg_case2("ushort",ushort);
27161 cimg_load_cimg_case2("short",short);
27162 cimg_load_cimg_case2("unsigned_int",uint);
27163 cimg_load_cimg_case2("uint",uint);
27164 cimg_load_cimg_case2("int",int);
27165 cimg_load_cimg_case2("unsigned_long",ulong);
27166 cimg_load_cimg_case2("ulong",ulong);
27167 cimg_load_cimg_case2("long",long);
27168 cimg_load_cimg_case2("float",float);
27169 cimg_load_cimg_case2("double",double);
27170 if (!loaded) {
27171 if (!file) cimg::fclose(nfile);
27172 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', cannot read images of pixels coded as '%s'.",
27173 pixel_type(),filename?filename:"(FILE*)",str_pixeltype);
27174 }
27175 if (!file) cimg::fclose(nfile);
27176 return *this;
27177 }
27178
27180 static CImgList<T> get_load_parrec(const char *const filename) {
27181 return CImgList<T>().load_parrec(filename);
27182 }
27183
27185 CImgList<T>& load_parrec(const char *const filename) {
27186 char body[1024], filenamepar[1024], filenamerec[1024];
27187 const char *ext = cimg::filename_split(filename,body);
27188 if (!cimg::strncmp(ext,"par",3)) { std::strcpy(filenamepar,filename); std::sprintf(filenamerec,"%s.rec",body); }
27189 if (!cimg::strncmp(ext,"PAR",3)) { std::strcpy(filenamepar,filename); std::sprintf(filenamerec,"%s.REC",body); }
27190 if (!cimg::strncmp(ext,"rec",3)) { std::strcpy(filenamerec,filename); std::sprintf(filenamepar,"%s.par",body); }
27191 if (!cimg::strncmp(ext,"REC",3)) { std::strcpy(filenamerec,filename); std::sprintf(filenamepar,"%s.PAR",body); }
27192 std::FILE *file = cimg::fopen(filenamepar,"r");
27193
27194
27195 CImgList<float> st_slices;
27196 CImgList<unsigned int> st_global;
27197 int err;
27198 char line[256] = { 0 };
27199 do { err=std::fscanf(file,"%255[^\n]%*c",line); } while (err!=EOF && (line[0]=='#' || line[0]=='.'));
27200 do {
27201 unsigned int sn,sizex,sizey,pixsize;
27202 float rs,ri,ss;
27203 err=std::fscanf(file,"%u%*u%*u%*u%*u%*u%*u%u%*u%u%u%g%g%g%*[^\n]",&sn,&pixsize,&sizex,&sizey,&ri,&rs,&ss);
27204 if (err==7) {
27205 st_slices.insert(CImg<float>::vector((float)sn,(float)pixsize,(float)sizex,(float)sizey,ri,rs,ss,0));
27206 unsigned int i; for (i=0; i<st_global.size && sn<=st_global[i][2]; ++i);
27207 if (i==st_global.size) st_global.insert(CImg<unsigned int>::vector(sizex,sizey,sn));
27208 else {
27209 CImg<unsigned int> &vec = st_global[i];
27210 if (sizex>vec[0]) vec[0] = sizex;
27211 if (sizey>vec[1]) vec[1] = sizey;
27212 vec[2] = sn;
27213 }
27214 st_slices[st_slices.size-1][7] = (float)i;
27215 }
27216 } while (err==7);
27217
27218
27219 std::FILE *file2 = cimg::fopen(filenamerec,"rb");
27220 { cimglist_for(st_global,l) {
27221 const CImg<unsigned int>& vec = st_global[l];
27222 insert(CImg<T>(vec[0],vec[1],vec[2]));
27223 }}
27224
27225 cimglist_for(st_slices,l) {
27226 const CImg<float>& vec = st_slices[l];
27227 const unsigned int
27228 sn = (unsigned int)vec[0]-1,
27229 pixsize = (unsigned int)vec[1],
27230 sizex = (unsigned int)vec[2],
27231 sizey = (unsigned int)vec[3],
27232 imn = (unsigned int)vec[7];
27233 const float ri = vec[4], rs = vec[5], ss = vec[6];
27234 switch (pixsize) {
27235 case 8: {
27236 CImg<unsigned char> buf(sizex,sizey);
27237 cimg::fread(buf.data,sizex*sizey,file2);
27238 if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey);
27239 CImg<T>& img = (*this)[imn];
27240 cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
27241 } break;
27242 case 16: {
27243 CImg<unsigned short> buf(sizex,sizey);
27244 cimg::fread(buf.data,sizex*sizey,file2);
27245 if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey);
27246 CImg<T>& img = (*this)[imn];
27247 cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
27248 } break;
27249 case 32: {
27250 CImg<unsigned int> buf(sizex,sizey);
27251 cimg::fread(buf.data,sizex*sizey,file2);
27252 if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey);
27253 CImg<T>& img = (*this)[imn];
27254 cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
27255 } break;
27256 default:
27257 cimg::fclose(file);
27258 cimg::fclose(file2);
27259 throw CImgIOException("CImg<%s>::load_parrec() : File '%s', cannot handle image with pixsize = %d bits.",
27260 pixel_type(),filename,pixsize);
27261 break;
27262 }
27263 }
27264 cimg::fclose(file);
27265 cimg::fclose(file2);
27266 if (!size)
27267 throw CImgIOException("CImg<%s>::load_parrec() : File '%s' does not appear to be a valid PAR-REC file.",
27268 pixel_type(),filename);
27269 return *this;
27270 }
27271
27273 static CImgList<T> get_load_yuv(std::FILE *const file, const char *const filename,
27274 const unsigned int sizex, const unsigned int sizey=1,
27275 const unsigned int first_frame=0, const int last_frame=-1,
27276 const bool yuv2rgb=false) {
27277 return CImgList<T>().load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb);
27278 }
27279
27281 CImgList<T>& load_yuv(std::FILE *const file, const char *const filename,
27282 const unsigned int sizex, const unsigned int sizey=1,
27283 const unsigned int first_frame=0, const int last_frame=-1,
27284 const bool yuv2rgb=false) {
27285 if (sizex%2 || sizey%2)
27286 throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', image dimensions along X and Y must be "
27287 "even numbers (given are %ux%u)\n",pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27288 if (!sizex || !sizey)
27289 throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', given image sequence size (%u,%u) is invalid",
27290 pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27291 if (last_frame>0 && first_frame>(unsigned int)last_frame)
27292 throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', given first frame %u is posterior to last frame %d.",
27293 pixel_type(),filename?filename:"(unknown)",first_frame,last_frame);
27294 if (!sizex || !sizey)
27295 throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', given frame size (%u,%u) is invalid.",
27296 pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27297 CImg<unsigned char> tmp(sizex,sizey,1,3), UV(sizex/2,sizey/2,1,2);
27298 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
27299 bool stopflag = false;
27300 int err;
27301 if (first_frame) {
27302 err = std::fseek(nfile,first_frame*(sizex*sizey + sizex*sizey/2),SEEK_CUR);
27303 if (err) {
27304 if (!file) cimg::fclose(nfile);
27305 throw CImgIOException("CImgList<%s>::load_yuv() : File '%s' doesn't contain frame number %u "
27306 "(out of range error).",pixel_type(),filename?filename:"(FILE*)",first_frame);
27307 }
27308 }
27309 unsigned int frame;
27310 for (frame = first_frame; !stopflag && (last_frame<0 || frame<=(unsigned int)last_frame); ++frame) {
27311 tmp.fill(0);
27312
27313 err = (int)std::fread((void*)(tmp.data),1,(size_t)(tmp.width*tmp.height),nfile);
27314 if (err!=(int)(tmp.width*tmp.height)) {
27315 stopflag = true;
27316 if (err>0) cimg::warn("CImgList<%s>::load_yuv() : File '%s' contains incomplete data,"
27317 " or given image dimensions (%u,%u) are incorrect.",
27318 pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27319 } else {
27320 UV.fill(0);
27321
27322 err = (int)std::fread((void*)(UV.data),1,(size_t)(UV.size()),nfile);
27323 if (err!=(int)(UV.size())) {
27324 stopflag = true;
27325 if (err>0) cimg::warn("CImgList<%s>::load_yuv() : File '%s' contains incomplete data,"
27326 " or given image dimensions (%u,%u) are incorrect.",
27327 pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27328 } else {
27329 cimg_forXY(UV,x,y) {
27330 const int x2=2*x, y2=2*y;
27331 tmp(x2,y2,1) = tmp(x2+1,y2,1) = tmp(x2,y2+1,1) = tmp(x2+1,y2+1,1) = UV(x,y,0);
27332 tmp(x2,y2,2) = tmp(x2+1,y2,2) = tmp(x2,y2+1,2) = tmp(x2+1,y2+1,2) = UV(x,y,1);
27333 }
27334 if (yuv2rgb) tmp.YCbCrtoRGB();
27335 insert(tmp);
27336 }
27337 }
27338 }
27339 if (stopflag && last_frame>=0 && frame!=(unsigned int)last_frame)
27340 cimg::warn("CImgList<%s>::load_yuv() : File '%s', frame %d not reached since only %u frames were found in the file.",
27341 pixel_type(),filename?filename:"(unknown)",last_frame,frame-1,filename);
27342 if (!file) cimg::fclose(nfile);
27343 return *this;
27344 }
27345
27347 static CImgList<T> get_load_yuv(const char *const filename,
27348 const unsigned int sizex, const unsigned int sizey=1,
27349 const unsigned int first_frame=0, const int last_frame=-1,
27350 const bool yuv2rgb=false) {
27351 return CImgList<T>().load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb);
27352 }
27353
27355 CImgList<T>& load_yuv(const char *const filename,
27356 const unsigned int sizex, const unsigned int sizey,
27357 const unsigned int first_frame=0, const int last_frame=-1,
27358 const bool yuv2rgb=false) {
27359 return load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb);
27360 }
27361
27363 template<typename tf, typename tc>
27364 static CImgList<T> get_load_off(std::FILE *const file, const char *const filename,
27365 CImgList<tf>& primitives, CImgList<tc>& colors,
27366 const bool invert_faces=false) {
27367 return CImgList<T>().load_off(file,filename,primitives,colors,invert_faces);
27368 }
27369
27371 template<typename tf, typename tc>
27372 CImgList<T>& load_off(std::FILE *const file, const char *const filename,
27373 CImgList<tf>& primitives, CImgList<tc>& colors,
27374 const bool invert_faces=false) {
27375 return assign(CImg<T>::get_load_off(file,filename,primitives,colors,invert_faces).get_split('x'));
27376 }
27377
27379 template<typename tf, typename tc>
27380 static CImgList<T> get_load_off(const char *const filename,
27381 CImgList<tf>& primitives, CImgList<tc>& colors,
27382 const bool invert_faces=false) {
27383 return CImgList<T>().load_off(0,filename,primitives,colors,invert_faces);
27384 }
27385
27387 template<typename tf, typename tc>
27388 CImgList<T>& load_off(const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors,
27389 const bool invert_faces=false) {
27390 return load_off(0,filename,primitives,colors,invert_faces);
27391 }
27392
27394
27397 const CImgList<T>& save(const char *const filename, const int number=-1) const {
27398 if (is_empty()) throw CImgInstanceException("CImgList<%s>::save() : Instance list (%u,%p) is empty (file '%s').",
27399 pixel_type(),size,data,filename);
27400 if (!filename) throw CImgArgumentException("CImg<%s>::save() : Instance list (%u,%p), specified filename is (null).",
27401 pixel_type(),size,data);
27402 const char *ext = cimg::filename_split(filename);
27403 char nfilename[1024];
27404 const char *const fn = (number>=0)?cimg::filename_number(filename,number,6,nfilename):filename;
27405 #ifdef cimglist_save_plugin
27406 cimglist_save_plugin(fn);
27407 #endif
27408 if (!cimg::strncasecmp(ext,"cimg",4) || !ext[0]) return save_cimg(fn);
27409 if (!cimg::strncasecmp(ext,"yuv",3)) return save_yuv(fn,true);
27410 if (size==1) data[0].save(fn,-1);
27411 else cimglist_for(*this,l) data[l].save(fn,l);
27412 return *this;
27413 }
27414
27416 const CImgList<T>& save_yuv(std::FILE *const file, const char *const filename=0, const bool rgb2yuv=true) const {
27417 if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_yuv() : Instance list (%u,%p) is empty (file '%s').",
27418 pixel_type(),size,data,filename?filename:"(unknown)");
27419 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_yuv() : Instance list (%u,%p), specified file is (null).",
27420 pixel_type(),size,data);
27421 if ((*this)[0].dimx()%2 || (*this)[0].dimy()%2)
27422 throw CImgInstanceException("CImgList<%s>::save_yuv() : Image dimensions must be even numbers (current are %ux%u, file '%s').",
27423 pixel_type(),(*this)[0].dimx(),(*this)[0].dimy(),filename?filename:"(unknown)");
27424
27425 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
27426 cimglist_for(*this,l) {
27427 CImg<unsigned char> YCbCr((*this)[l]);
27428 if (rgb2yuv) YCbCr.RGBtoYCbCr();
27429 cimg::fwrite(YCbCr.data,YCbCr.width*YCbCr.height,nfile);
27430 cimg::fwrite(YCbCr.get_resize(YCbCr.width/2, YCbCr.height/2,1,3,3).ptr(0,0,0,1),
27431 YCbCr.width*YCbCr.height/2,nfile);
27432 }
27433 if (!file) cimg::fclose(nfile);
27434 return *this;
27435 }
27436
27438 const CImgList<T>& save_yuv(const char *const filename=0, const bool rgb2yuv=true) const {
27439 return save_yuv(0,filename,rgb2yuv);
27440 }
27441
27443
27448 const CImgList<T>& save_cimg(std::FILE *const file, const char *const filename=0) const {
27449 if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_cimg() : Instance list (%u,%p) is empty (file '%s').",
27450 pixel_type(),size,data,filename?filename:"(unknown)");
27451 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance list (%u,%p), specified file is (null).",
27452 pixel_type(),size,data);
27453 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
27454 const char *const ptype = pixel_type(), *const etype = cimg::endian()?"big":"little";
27455 if (!cimg::strncmp(ptype,"unsigned",8)) std::fprintf(nfile,"%u unsigned_%s %s_endian\n",size,ptype+9,etype);
27456 else std::fprintf(nfile,"%u %s %s_endian\n",size,ptype,etype);
27457 cimglist_for(*this,l) {
27458 const CImg<T>& img = data[l];
27459 std::fprintf(nfile,"%u %u %u %u\n",img.width,img.height,img.depth,img.dim);
27460 if (img.data) {
27461 if (cimg::endian()) {
27462 CImg<T> tmp(img);
27463 cimg::endian_swap(tmp.data,tmp.size());
27464 cimg::fwrite(tmp.data,img.width*img.height*img.depth*img.dim,nfile);
27465 } else cimg::fwrite(img.data,img.width*img.height*img.depth*img.dim,nfile);
27466 }
27467 }
27468 if (!file) cimg::fclose(nfile);
27469 return *this;
27470 }
27471
27473 const CImgList<T>& save_cimg(const char *const filename) const {
27474 return save_cimg(0,filename);
27475 }
27476
27477
27478 const CImgList<T>& save_cimg(std::FILE *const file, const char *const filename,
27479 const unsigned int n0,
27480 const unsigned int x0, const unsigned int y0,
27481 const unsigned int z0, const unsigned int v0) const {
27482 #define cimg_save_cimg_case(Ts,Tss) \
27483 if (!saved && !cimg::strcasecmp(Ts,str_pixeltype)) { \
27484 for (unsigned int l=0; l<lmax; ++l) { \
27485 j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; \
27486 W = H = D = V = 0; \
27487 if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) \
27488 throw CImgIOException("CImgList<%s>::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", \
27489 pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); \
27490 if (W*H*D*V>0) { \
27491 if (l<n0 || x0>=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(Tss),SEEK_CUR); \
27492 else { \
27493 const CImg<T>& img = (*this)[l-n0]; \
27494 const T *ptrs = img.data; \
27495 const unsigned int \
27496 x1 = x0 + img.width - 1, \
27497 y1 = y0 + img.height - 1, \
27498 z1 = z0 + img.depth - 1, \
27499 v1 = v0 + img.dim - 1, \
27500 nx1 = x1>=W?W-1:x1, \
27501 ny1 = y1>=H?H-1:y1, \
27502 nz1 = z1>=D?D-1:z1, \
27503 nv1 = v1>=V?V-1:v1; \
27504 CImg<Tss> raw(1+nx1-x0); \
27505 const unsigned int skipvb = v0*W*H*D*sizeof(Tss); \
27506 if (skipvb) std::fseek(nfile,skipvb,SEEK_CUR); \
27507 for (unsigned int v=1+nv1-v0; v; --v) { \
27508 const unsigned int skipzb = z0*W*H*sizeof(Tss); \
27509 if (skipzb) std::fseek(nfile,skipzb,SEEK_CUR); \
27510 for (unsigned int z=1+nz1-z0; z; --z) { \
27511 const unsigned int skipyb = y0*W*sizeof(Tss); \
27512 if (skipyb) std::fseek(nfile,skipyb,SEEK_CUR); \
27513 for (unsigned int y=1+ny1-y0; y; --y) { \
27514 const unsigned int skipxb = x0*sizeof(Tss); \
27515 if (skipxb) std::fseek(nfile,skipxb,SEEK_CUR); \
27516 raw.assign(ptrs, raw.width); \
27517 ptrs+=img.width; \
27518 if (endian) cimg::endian_swap(raw.data,raw.width); \
27519 cimg::fwrite(raw.data,raw.width,nfile); \
27520 const unsigned int skipxe = (W-1-nx1)*sizeof(Tss); \
27521 if (skipxe) std::fseek(nfile,skipxe,SEEK_CUR); \
27522 } \
27523 const unsigned int skipye = (H-1-ny1)*W*sizeof(Tss); \
27524 if (skipye) std::fseek(nfile,skipye,SEEK_CUR); \
27525 } \
27526 const unsigned int skipze = (D-1-nz1)*W*H*sizeof(Tss); \
27527 if (skipze) std::fseek(nfile,skipze,SEEK_CUR); \
27528 } \
27529 const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(Tss); \
27530 if (skipve) std::fseek(nfile,skipve,SEEK_CUR); \
27531 } \
27532 } \
27533 } \
27534 saved = true; \
27535 }
27536 if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_cimg() : Instance list (%u,%p) is empty (file '%s').",
27537 pixel_type(),size,data,filename?filename:"(unknown)");
27538 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance list (%u,%p), specified file is (null).",
27539 pixel_type(),size,data);
27540 typedef unsigned char uchar;
27541 typedef unsigned short ushort;
27542 typedef unsigned int uint;
27543 typedef unsigned long ulong;
27544 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb+");
27545 bool saved = false, endian = cimg::endian();
27546 char tmp[256], str_pixeltype[256], str_endian[256];
27547 unsigned int j, err, N, W, H, D, V;
27548 int i;
27549 j = 0; while((i=std::fgetc(nfile))!='\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = '\0';
27550 err = std::sscanf(tmp,"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian);
27551 if (err<2) {
27552 if (!file) cimg::fclose(nfile);
27553 throw CImgIOException("CImgList<%s>::save_cimg() : File '%s', Unknow CImg RAW header.",
27554 pixel_type(),filename?filename:"(FILE*)");
27555 }
27556 if (!cimg::strncasecmp("little",str_endian,6)) endian = false;
27557 else if (!cimg::strncasecmp("big",str_endian,3)) endian = true;
27558 const unsigned int lmax = cimg::min(N,n0+size);
27559 cimg_save_cimg_case("bool",bool);
27560 cimg_save_cimg_case("unsigned_char",uchar);
27561 cimg_save_cimg_case("uchar",uchar);
27562 cimg_save_cimg_case("char",char);
27563 cimg_save_cimg_case("unsigned_short",ushort);
27564 cimg_save_cimg_case("ushort",ushort);
27565 cimg_save_cimg_case("short",short);
27566 cimg_save_cimg_case("unsigned_int",uint);
27567 cimg_save_cimg_case("uint",uint);
27568 cimg_save_cimg_case("int",int);
27569 cimg_save_cimg_case("unsigned_long",ulong);
27570 cimg_save_cimg_case("ulong",ulong);
27571 cimg_save_cimg_case("long",long);
27572 cimg_save_cimg_case("float",float);
27573 cimg_save_cimg_case("double",double);
27574 if (!saved) {
27575 if (!file) cimg::fclose(nfile);
27576 throw CImgIOException("CImgList<%s>::save_cimg() : File '%s', cannot save images of pixels coded as '%s'.",
27577 pixel_type(),filename?filename:"(FILE*)",str_pixeltype);
27578 }
27579 if (!file) cimg::fclose(nfile);
27580 return *this;
27581 }
27582
27584 const CImgList<T>& save_cimg(std::FILE *const file,
27585 const unsigned int n0,
27586 const unsigned int x0, const unsigned int y0,
27587 const unsigned int z0, const unsigned int v0) const {
27588 return save_cimg(file,0,n0,x0,y0,z0,v0);
27589 }
27590
27592 const CImgList<T>& save_cimg(const char *const filename,
27593 const unsigned int n0,
27594 const unsigned int x0, const unsigned int y0,
27595 const unsigned int z0, const unsigned int v0) const {
27596 return save_cimg(0,filename,n0,x0,y0,z0,v0);
27597 }
27598
27599
27600 static void save_empty_cimg(std::FILE *const file, const char *const filename,
27601 const unsigned int nb,
27602 const unsigned int dx, const unsigned int dy=1,
27603 const unsigned int dz=1, const unsigned int dv=1) {
27604 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
27605 const unsigned int siz = dx*dy*dz*dv*sizeof(T);
27606 std::fprintf(nfile,"%u %s\n",nb,pixel_type());
27607 for (unsigned int i=nb; i; --i) {
27608 std::fprintf(nfile,"%u %u %u %u\n",dx,dy,dz,dv);
27609 for (unsigned int off=siz; off; --off) std::fputc(0,nfile);
27610 }
27611 if (!file) cimg::fclose(nfile);
27612 }
27613
27615 static void save_empty_cimg(std::FILE *const file,
27616 const unsigned int nb,
27617 const unsigned int dx, const unsigned int dy=1,
27618 const unsigned int dz=1, const unsigned int dv=1) {
27619 return save_empty_cimg(file,0,nb,dx,dy,dz,dv);
27620 }
27621
27623 static void save_empty_cimg(const char *const filename,
27624 const unsigned int nb,
27625 const unsigned int dx, const unsigned int dy=1,
27626 const unsigned int dz=1, const unsigned int dv=1) {
27627 return save_empty_cimg(0,filename,nb,dx,dy,dz,dv);
27628 }
27629
27631 template<typename tf, typename tc>
27632 const CImgList<T>& save_off(std::FILE *const file, const char *const filename,
27633 const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
27634 get_append('x','y').save_off(file,filename,primitives,colors,invert_faces);
27635 return *this;
27636 }
27637
27639 template<typename tf, typename tc>
27640 const CImgList<T>& save_off(const char *const filename,
27641 const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
27642 return save_off(0,filename,primitives,colors,invert_faces);
27643 }
27644
27645
27646 CImgList<T> get_split(const char axe='x') const {
27647 CImgList<T> res;
27648 cimglist_for(*this,l) res.insert(data[l].get_split(axe));
27649 return res;
27650 }
27651
27653 CImgList<T>& split(const char axe='x') {
27654 return get_split(axe).assign_to(*this);
27655 }
27656
27658
27663 CImg<T> get_append(const char axe='x', const char align='c') const {
27664 if (is_empty()) return CImg<T>();
27665 if (size==1) return (*this)[0];
27666 unsigned int dx = 0, dy = 0, dz = 0, dv = 0, pos = 0;
27667 CImg<T> res;
27668 switch(cimg::uncase(axe)) {
27669 case 'x': {
27670 switch (cimg::uncase(align)) {
27671 case 'x': { dy = dz = dv = 1; cimglist_for(*this,l) dx+=(*this)[l].size(); } break;
27672 case 'y': { dx = size; dz = dv = 1; cimglist_for(*this,l) dy = cimg::max(dy,(unsigned int)(*this)[l].size()); } break;
27673 case 'z': { dx = size; dy = dv = 1; cimglist_for(*this,l) dz = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27674 case 'v': { dx = size; dy = dz = 1; cimglist_for(*this,l) dv = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27675 default:
27676 cimglist_for(*this,l) {
27677 const CImg<T>& img = (*this)[l];
27678 dx += img.width;
27679 dy = cimg::max(dy,img.height);
27680 dz = cimg::max(dz,img.depth);
27681 dv = cimg::max(dv,img.dim);
27682 }
27683 }
27684 res.assign(dx,dy,dz,dv,0);
27685 switch (cimg::uncase(align)) {
27686 case 'x': {
27687 cimglist_for(*this,l) { res.draw_image(CImg<T>((*this)[l],true).unroll('x'),pos,0,0,0); pos+=(*this)[l].size(); }
27688 } break;
27689 case 'y': {
27690 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('y'),pos++,0,0,0);
27691 } break;
27692 case 'z': {
27693 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('z'),pos++,0,0,0);
27694 } break;
27695 case 'v': {
27696 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('v'),pos++,0,0,0);
27697 } break;
27698 case 'p': {
27699 cimglist_for(*this,l) { res.draw_image((*this)[l],pos,0,0,0); pos+=(*this)[l].width; }
27700 } break;
27701 case 'n': {
27702 cimglist_for(*this,l) { res.draw_image((*this)[l],pos,dy-(*this)[l].height,dz-(*this)[l].depth,dv-(*this)[l].dim); pos+=(*this)[l].width; }
27703 } break;
27704 default : {
27705 cimglist_for(*this,l) { res.draw_image((*this)[l],pos,(dy-(*this)[l].height)/2,(dz-(*this)[l].depth)/2,(dv-(*this)[l].dim)/2); pos+=(*this)[l].width; }
27706 } break;
27707 }
27708 } break;
27709
27710 case 'y': {
27711 switch (cimg::uncase(align)) {
27712 case 'x': { dy = size; dz = dv = 1; cimglist_for(*this,l) dx = cimg::max(dx,(unsigned int)(*this)[l].size()); } break;
27713 case 'y': { dx = dz = dv = 1; cimglist_for(*this,l) dy+=(*this)[l].size(); } break;
27714 case 'z': { dy = size; dx = dv = 1; cimglist_for(*this,l) dz = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27715 case 'v': { dy = size; dx = dz = 1; cimglist_for(*this,l) dv = cimg::max(dv,(unsigned int)(*this)[l].size()); } break;
27716 default:
27717 cimglist_for(*this,l) {
27718 const CImg<T>& img = (*this)[l];
27719 dx = cimg::max(dx,img.width);
27720 dy += img.height;
27721 dz = cimg::max(dz,img.depth);
27722 dv = cimg::max(dv,img.dim);
27723 }
27724 }
27725 res.assign(dx,dy,dz,dv,0);
27726 switch (cimg::uncase(align)) {
27727 case 'x': {
27728 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('x'),0,pos++,0,0);
27729 } break;
27730 case 'y': {
27731 cimglist_for(*this,l) { res.draw_image(CImg<T>((*this)[l],true).unroll('y'),0,pos,0,0); pos+=(*this)[l].size(); }
27732 } break;
27733 case 'z': {
27734 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('z'),0,pos++,0,0);
27735 } break;
27736 case 'v': {
27737 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('v'),0,pos++,0,0);
27738 } break;
27739 case 'p': {
27740 cimglist_for(*this,l) { res.draw_image((*this)[l],0,pos,0,0); pos+=(*this)[l].height; }
27741 } break;
27742 case 'n': {
27743 cimglist_for(*this,l) { res.draw_image((*this)[l],dx-(*this)[l].width,pos,dz-(*this)[l].depth,dv-(*this)[l].dim); pos+=(*this)[l].height; }
27744 } break;
27745 default : {
27746 cimglist_for(*this,l) { res.draw_image((*this)[l],(dx-(*this)[l].width)/2,pos,(dz-(*this)[l].depth)/2,(dv-(*this)[l].dim)/2);
27747 pos+=(*this)[l].height; }
27748 } break;
27749 }
27750 } break;
27751
27752 case 'z': {
27753 switch (cimg::uncase(align)) {
27754 case 'x': { dz = size; dy = dv = 1; cimglist_for(*this,l) dx = cimg::max(dx,(unsigned int)(*this)[l].size()); } break;
27755 case 'y': { dz = size; dx = dv = 1; cimglist_for(*this,l) dy = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27756 case 'z': { dx = dy = dv = 1; cimglist_for(*this,l) dz+=(*this)[l].size(); } break;
27757 case 'v': { dz = size; dx = dz = 1; cimglist_for(*this,l) dv = cimg::max(dv,(unsigned int)(*this)[l].size()); } break;
27758 default :
27759 cimglist_for(*this,l) {
27760 const CImg<T>& img = (*this)[l];
27761 dx = cimg::max(dx,img.width);
27762 dy = cimg::max(dy,img.height);
27763 dz += img.depth;
27764 dv = cimg::max(dv,img.dim);
27765 }
27766 }
27767 res.assign(dx,dy,dz,dv,0);
27768 switch (cimg::uncase(align)) {
27769 case 'x': {
27770 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('x'),0,0,pos++,0);
27771 } break;
27772 case 'y': {
27773 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('y'),0,0,pos++,0);
27774 } break;
27775 case 'z': {
27776 cimglist_for(*this,l) { res.draw_image(CImg<T>((*this)[l],true).unroll('z'),0,0,pos,0); pos+=(*this)[l].size(); }
27777 } break;
27778 case 'v': {
27779 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('v'),0,0,pos++,0);
27780 } break;
27781 case 'p': {
27782 cimglist_for(*this,l) { res.draw_image((*this)[l],0,0,pos,0); pos+=(*this)[l].depth; }
27783 } break;
27784 case 'n': {
27785 cimglist_for(*this,l) { res.draw_image((*this)[l],dx-(*this)[l].width,dy-(*this)[l].height,pos,dv-(*this)[l].dim); pos+=(*this)[l].depth; }
27786 } break;
27787 case 'c': {
27788 cimglist_for(*this,l) { res.draw_image((*this)[l],(dx-(*this)[l].width)/2,(dy-(*this)[l].height)/2,pos,(dv-(*this)[l].dim)/2);
27789 pos+=(*this)[l].depth; }
27790 } break;
27791 }
27792 } break;
27793
27794 case 'v': {
27795 switch (cimg::uncase(align)) {
27796 case 'x': { dv = size; dy = dv = 1; cimglist_for(*this,l) dx = cimg::max(dx,(unsigned int)(*this)[l].size()); } break;
27797 case 'y': { dv = size; dx = dv = 1; cimglist_for(*this,l) dy = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27798 case 'z': { dv = size; dx = dv = 1; cimglist_for(*this,l) dz = cimg::max(dv,(unsigned int)(*this)[l].size()); } break;
27799 case 'v': { dx = dy = dz = 1; cimglist_for(*this,l) dv+=(*this)[l].size(); } break;
27800 default :
27801 cimglist_for(*this,l) {
27802 const CImg<T>& img = (*this)[l];
27803 dx = cimg::max(dx,img.width);
27804 dy = cimg::max(dy,img.height);
27805 dz = cimg::max(dz,img.depth);
27806 dv += img.dim;
27807 }
27808 }
27809 res.assign(dx,dy,dz,dv,0);
27810 switch (cimg::uncase(align)) {
27811 case 'x': {
27812 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('x'),0,0,0,pos++);
27813 } break;
27814 case 'y': {
27815 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('y'),0,0,0,pos++);
27816 } break;
27817 case 'z': {
27818 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('v'),0,0,0,pos++);
27819 } break;
27820 case 'v': {
27821 cimglist_for(*this,l) { res.draw_image(CImg<T>((*this)[l],true).unroll('z'),0,0,0,pos); pos+=(*this)[l].size(); }
27822 } break;
27823 case 'p': {
27824 cimglist_for(*this,l) { res.draw_image((*this)[l],0,0,0,pos); pos+=(*this)[l].dim; }
27825 } break;
27826 case 'n': {
27827 cimglist_for(*this,l) { res.draw_image((*this)[l],dx-(*this)[l].width,dy-(*this)[l].height,dz-(*this)[l].depth,pos); pos+=(*this)[l].dim; }
27828 } break;
27829 case 'c': {
27830 cimglist_for(*this,l) { res.draw_image((*this)[l],(dx-(*this)[l].width)/2,(dy-(*this)[l].height)/2,(dz-(*this)[l].depth)/2,pos);
27831 pos+=(*this)[l].dim; }
27832 } break;
27833 }
27834 } break;
27835 default: throw CImgArgumentException("CImgList<%s>::get_append() : unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe);
27836 }
27837 return res;
27838 }
27839
27840
27841 CImgList<T> get_crop_font() const {
27842 CImgList<T> res;
27843 cimglist_for(*this,l) {
27844 const CImg<T>& letter = (*this)[l];
27845 int xmin = letter.width, xmax = 0;
27846 cimg_forXY(letter,x,y) if (letter(x,y)) { if (x<xmin) xmin=x; if (x>xmax) xmax=x; }
27847 if (xmin>xmax) res.insert(CImg<T>(letter.width,letter.height,1,letter.dim,0));
27848 else res.insert(letter.get_crop(xmin,0,xmax,letter.height-1));
27849 }
27850 res[' '].resize(res['f'].width);
27851 res[' '+256].resize(res['f'].width);
27852 return res;
27853 }
27854
27856 CImgList<T>& crop_font() {
27857 return get_crop_font().assign_to(*this);
27858 }
27859
27860
27861 static CImgList<T> get_font(const unsigned int *const font, const unsigned int w, const unsigned int h,
27862 const unsigned int paddingx, const unsigned int paddingy, const bool variable_size=true) {
27863 CImgList<T> res = CImgList<T>(256,w,h,1,3).insert(CImgList<T>(256,w,h,1,1));
27864 const unsigned int *ptr = font;
27865 unsigned int m = 0, val = 0;
27866 for (unsigned int y=0; y<h; ++y)
27867 for (unsigned int x=0; x<256*w; ++x) {
27868 m>>=1; if (!m) { m = 0x80000000; val = *(ptr++); }
27869 CImg<T>& img = res[x/w], &mask = res[x/w+256];
27870 unsigned int xm = x%w;
27871 img(xm,y,0) = img(xm,y,1) = img(xm,y,2) = mask(xm,y,0) = (T)((val&m)?1:0);
27872 }
27873 if (variable_size) res.crop_font();
27874 if (paddingx || paddingy) cimglist_for(res,l) res[l].resize(res[l].dimx()+paddingx, res[l].dimy()+paddingy,1,-100,0);
27875 return res;
27876 }
27877
27879 CImgList<T>& font(const unsigned int *const font, const unsigned int w, const unsigned int h,
27880 const unsigned int paddingx, const unsigned int paddingy, const bool variable_size=true) {
27881 return get_font(font,w,h,paddingx,paddingy,variable_size).assign_to(*this);
27882 }
27883
27885
27889 static CImgList<T> get_font(const unsigned int font_width, const bool variable_size=true) {
27890 if (font_width<=11) {
27891 static CImgList<T> font7x11, nfont7x11;
27892 if (!variable_size && !font7x11) font7x11 = get_font(cimg::font7x11,7,11,1,0,false);
27893 if (variable_size && !nfont7x11) nfont7x11 = get_font(cimg::font7x11,7,11,1,0,true);
27894 return variable_size?nfont7x11:font7x11;
27895 }
27896 if (font_width<=13) {
27897 static CImgList<T> font10x13, nfont10x13;
27898 if (!variable_size && !font10x13) font10x13 = get_font(cimg::font10x13,10,13,1,0,false);
27899 if (variable_size && !nfont10x13) nfont10x13 = get_font(cimg::font10x13,10,13,1,0,true);
27900 return variable_size?nfont10x13:font10x13;
27901 }
27902 if (font_width<=17) {
27903 static CImgList<T> font8x17, nfont8x17;
27904 if (!variable_size && !font8x17) font8x17 = get_font(cimg::font8x17,8,17,1,0,false);
27905 if (variable_size && !nfont8x17) nfont8x17 = get_font(cimg::font8x17,8,17,1,0,true);
27906 return variable_size?nfont8x17:font8x17;
27907 }
27908 if (font_width<=19) {
27909 static CImgList<T> font10x19, nfont10x19;
27910 if (!variable_size && !font10x19) font10x19 = get_font(cimg::font10x19,10,19,2,0,false);
27911 if (variable_size && !nfont10x19) nfont10x19 = get_font(cimg::font10x19,10,19,2,0,true);
27912 return variable_size?nfont10x19:font10x19;
27913 }
27914 if (font_width<=24) {
27915 static CImgList<T> font12x24, nfont12x24;
27916 if (!variable_size && !font12x24) font12x24 = get_font(cimg::font12x24,12,24,2,0,false);
27917 if (variable_size && !nfont12x24) nfont12x24 = get_font(cimg::font12x24,12,24,2,0,true);
27918 return variable_size?nfont12x24:font12x24;
27919 }
27920 if (font_width<=32) {
27921 static CImgList<T> font16x32, nfont16x32;
27922 if (!variable_size && !font16x32) font16x32 = get_font(cimg::font16x32,16,32,2,0,false);
27923 if (variable_size && !nfont16x32) nfont16x32 = get_font(cimg::font16x32,16,32,2,0,true);
27924 return variable_size?nfont16x32:font16x32;
27925 }
27926 if (font_width<=38) {
27927 static CImgList<T> font19x38, nfont19x38;
27928 if (!variable_size && !font19x38) font19x38 = get_font(cimg::font19x38,19,38,3,0,false);
27929 if (variable_size && !nfont19x38) nfont19x38 = get_font(cimg::font19x38,19,38,3,0,true);
27930 return variable_size?nfont19x38:font19x38;
27931 }
27932 static CImgList<T> font29x57, nfont29x57;
27933 if (!variable_size && !font29x57) font29x57 = get_font(cimg::font29x57,29,57,5,0,false);
27934 if (variable_size && !nfont29x57) nfont29x57 = get_font(cimg::font29x57,29,57,5,0,true);
27935 return variable_size?nfont29x57:font29x57;
27936 }
27937
27939 CImgList<T>& font(const unsigned int font_width, const bool variable_size=true) {
27940 return get_font(font_width,variable_size).assign_to(*this);
27941 }
27942
27944
27953 const CImgList<T>& display(CImgDisplay& disp, const char axe='x', const char align='c') const {
27954 get_append(axe,align).display(disp);
27955 return *this;
27956 }
27957
27959
27972 const CImgList<T>& display(const char* title, const char axe='x', const char align='c',
27973 const int min_size=128, const int max_size=1024, const int print_flag=1) const {
27974
27975 if (is_empty())
27976 throw CImgInstanceException("CImgList<%s>::display() : Instance list (%u,%u) is empty.",
27977 pixel_type(),size,data);
27978 const CImg<T> visu = get_append(axe,align);
27979 CImgDisplay disp;
27980 unsigned int w = visu.width+(visu.depth>1?visu.depth:0), h = visu.height+(visu.depth>1?visu.depth:0), XYZ[3];
27981 print(title,print_flag);
27982 const unsigned int dmin = cimg::min(w,h), minsiz = min_size>=0?min_size:(-min_size)*dmin/100;
27983 if (dmin<minsiz) { w=w*minsiz/dmin; w+=(w==0); h=h*minsiz/dmin; h+=(h==0); }
27984 const unsigned int dmax = cimg::max(w,h), maxsiz = max_size>=0?max_size:(-max_size)*dmax/100;
27985 if (dmax>maxsiz) { w=w*maxsiz/dmax; w+=(w==0); h=h*maxsiz/dmax; h+=(h==0); }
27986 disp.assign(w,h,title,1,3);
27987 XYZ[0] = visu.width/2; XYZ[1] = visu.height/2; XYZ[2] = visu.depth/2;
27988 while (!disp.is_closed && !disp.key) visu.get_coordinates(1,disp,XYZ);
27989 return *this;
27990 }
27991
27993
28005 const CImgList<T>& display(const char axe='x', const char align='c',
28006 const int min_size=128, const int max_size=1024, const int print_flag=1) const {
28007 char title[256] = { 0 };
28008 std::sprintf(title,"CImgList<%s>",pixel_type());
28009 return display(title,axe,align,min_size,max_size,print_flag);
28010 }
28011
28012 };
28013
28014
28015
28016
28017
28018
28019
28020
28021
28022
28023
28024
28025
28026 namespace cimg {
28027
28029
28047 template<typename t>
28048 inline int dialog(const char *title, const char *msg,
28049 const char *button1_txt, const char *button2_txt,
28050 const char *button3_txt, const char *button4_txt,
28051 const char *button5_txt, const char *button6_txt,
28052 const CImg<t>& logo, const bool centering = false) {
28053 #if cimg_display_type!=0
28054 const unsigned char
28055 black[] = { 0,0,0 }, white[] = { 255,255,255 }, gray[] = { 200,200,200 }, gray2[] = { 150,150,150 };
28056
28057
28058 CImgList<unsigned char> buttons, cbuttons, sbuttons;
28059 if (button1_txt) { buttons.insert(CImg<unsigned char>().draw_text(button1_txt,0,0,black,gray,13));
28060 if (button2_txt) { buttons.insert(CImg<unsigned char>().draw_text(button2_txt,0,0,black,gray,13));
28061 if (button3_txt) { buttons.insert(CImg<unsigned char>().draw_text(button3_txt,0,0,black,gray,13));
28062 if (button4_txt) { buttons.insert(CImg<unsigned char>().draw_text(button4_txt,0,0,black,gray,13));
28063 if (button5_txt) { buttons.insert(CImg<unsigned char>().draw_text(button5_txt,0,0,black,gray,13));
28064 if (button6_txt) { buttons.insert(CImg<unsigned char>().draw_text(button6_txt,0,0,black,gray,13));
28065 }}}}}}
28066 if (!buttons.size) throw CImgArgumentException("cimg::dialog() : No buttons have been defined. At least one is necessary");
28067
28068 unsigned int bw = 0, bh = 0;
28069 cimglist_for(buttons,l) { bw = cimg::max(bw,buttons[l].width); bh = cimg::max(bh,buttons[l].height); }
28070 bw+=8; bh+=8;
28071 if (bw<64) bw=64;
28072 if (bw>128) bw=128;
28073 if (bh<24) bh=24;
28074 if (bh>48) bh=48;
28075
28076 CImg<unsigned char> button(bw,bh,1,3);
28077 button.draw_rectangle(0,0,bw-1,bh-1,gray);
28078 button.draw_line(0,0,bw-1,0,white).draw_line(0,bh-1,0,0,white);
28079 button.draw_line(bw-1,0,bw-1,bh-1,black).draw_line(bw-1,bh-1,0,bh-1,black);
28080 button.draw_line(1,bh-2,bw-2,bh-2,gray2).draw_line(bw-2,bh-2,bw-2,1,gray2);
28081 CImg<unsigned char> sbutton(bw,bh,1,3);
28082 sbutton.draw_rectangle(0,0,bw-1,bh-1,gray);
28083 sbutton.draw_line(0,0,bw-1,0,black).draw_line(bw-1,0,bw-1,bh-1,black);
28084 sbutton.draw_line(bw-1,bh-1,0,bh-1,black).draw_line(0,bh-1,0,0,black);
28085 sbutton.draw_line(1,1,bw-2,1,white).draw_line(1,bh-2,1,1,white);
28086 sbutton.draw_line(bw-2,1,bw-2,bh-2,black).draw_line(bw-2,bh-2,1,bh-2,black);
28087 sbutton.draw_line(2,bh-3,bw-3,bh-3,gray2).draw_line(bw-3,bh-3,bw-3,2,gray2);
28088 sbutton.draw_line(4,4,bw-5,4,black,1.0f,0xAAAAAAAA,true).draw_line(bw-5,4,bw-5,bh-5,black,1.0f,0xAAAAAAAA,false);
28089 sbutton.draw_line(bw-5,bh-5,4,bh-5,black,1.0f,0xAAAAAAAA,false).draw_line(4,bh-5,4,4,black,1.0f,0xAAAAAAAA,false);
28090 CImg<unsigned char> cbutton(bw,bh,1,3);
28091 cbutton.draw_rectangle(0,0,bw-1,bh-1,black).draw_rectangle(1,1,bw-2,bh-2,gray2).draw_rectangle(2,2,bw-3,bh-3,gray);
28092 cbutton.draw_line(4,4,bw-5,4,black,1.0f,0xAAAAAAAA,true).draw_line(bw-5,4,bw-5,bh-5,black,1.0f,0xAAAAAAAA,false);
28093 cbutton.draw_line(bw-5,bh-5,4,bh-5,black,1.0f,0xAAAAAAAA,false).draw_line(4,bh-5,4,4,black,1.0f,0xAAAAAAAA,false);
28094
28095 cimglist_for(buttons,ll) {
28096 cbuttons.insert(CImg<unsigned char>(cbutton).draw_image(buttons[ll],1+(bw-buttons[ll].dimx())/2,1+(bh-buttons[ll].dimy())/2));
28097 sbuttons.insert(CImg<unsigned char>(sbutton).draw_image(buttons[ll],(bw-buttons[ll].dimx())/2,(bh-buttons[ll].dimy())/2));
28098 buttons[ll] = CImg<unsigned char>(button).draw_image(buttons[ll],(bw-buttons[ll].dimx())/2,(bh-buttons[ll].dimy())/2);
28099 }
28100
28101 CImg<unsigned char> canvas;
28102 if (msg) canvas = CImg<unsigned char>().draw_text(msg,0,0,black,gray,13);
28103 const unsigned int
28104 bwall = (buttons.size-1)*(12+bw) + bw,
28105 w = cimg::max(196U,36+logo.width+canvas.width, 24+bwall),
28106 h = cimg::max(96U,36+canvas.height+bh,36+logo.height+bh),
28107 lx = 12 + (canvas.data?0:((w-24-logo.width)/2)),
28108 ly = (h-12-bh-logo.height)/2,
28109 tx = lx+logo.width+12,
28110 ty = (h-12-bh-canvas.height)/2,
28111 bx = (w-bwall)/2,
28112 by = h-12-bh;
28113
28114 if (canvas.data)
28115 canvas = CImg<unsigned char>(w,h,1,3).
28116 draw_rectangle(0,0,w-1,h-1,gray).
28117 draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white).
28118 draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black).
28119 draw_image(canvas,tx,ty);
28120 else
28121 canvas = CImg<unsigned char>(w,h,1,3).
28122 draw_rectangle(0,0,w-1,h-1,gray).
28123 draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white).
28124 draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black);
28125 if (logo.data) canvas.draw_image(logo,lx,ly);
28126
28127 unsigned int xbuttons[6];
28128 cimglist_for(buttons,lll) { xbuttons[lll] = bx+(bw+12)*lll; canvas.draw_image(buttons[lll],xbuttons[lll],by); }
28129
28130
28131 CImgDisplay disp(canvas,title?title:" ",0,3,false,centering?true:false);
28132 if (centering) disp.move((CImgDisplay::screen_dimx()-disp.dimx())/2,
28133 (CImgDisplay::screen_dimy()-disp.dimy())/2);
28134 bool stopflag = false, refresh = false;
28135 int oselected = -1, oclicked = -1, selected = -1, clicked = -1;
28136 while (!disp.is_closed && !stopflag) {
28137 if (refresh) {
28138 if (clicked>=0) CImg<unsigned char>(canvas).draw_image(cbuttons[clicked],xbuttons[clicked],by).display(disp);
28139 else {
28140 if (selected>=0) CImg<unsigned char>(canvas).draw_image(sbuttons[selected],xbuttons[selected],by).display(disp);
28141 else canvas.display(disp);
28142 }
28143 refresh = false;
28144 }
28145 disp.wait(15);
28146 if (disp.is_resized) disp.resize(disp);
28147
28148 if (disp.button&1) {
28149 oclicked = clicked;
28150 clicked = -1;
28151 cimglist_for(buttons,l)
28152 if (disp.mouse_y>=(int)by && disp.mouse_y<(int)(by+bh) &&
28153 disp.mouse_x>=(int)xbuttons[l] && disp.mouse_x<(int)(xbuttons[l]+bw)) {
28154 clicked = selected = l;
28155 refresh = true;
28156 }
28157 if (clicked!=oclicked) refresh = true;
28158 } else if (clicked>=0) stopflag = true;
28159
28160 if (disp.key) {
28161 oselected = selected;
28162 switch (disp.key) {
28163 case cimg::keyESC: selected=-1; stopflag=true; break;
28164 case cimg::keyENTER: if (selected<0) selected = 0; stopflag = true; break;
28165 case cimg::keyTAB:
28166 case cimg::keyARROWRIGHT:
28167 case cimg::keyARROWDOWN: selected = (selected+1)%buttons.size; break;
28168 case cimg::keyARROWLEFT:
28169 case cimg::keyARROWUP: selected = (selected+buttons.size-1)%buttons.size; break;
28170 }
28171 disp.key = 0;
28172 if (selected!=oselected) refresh = true;
28173 }
28174 }
28175 if (!disp) selected = -1;
28176 return selected;
28177 #else
28178 std::fprintf(stderr,"<%s>\n\n%s\n\n",title,msg);
28179 return -1+0*(int)(button1_txt-button2_txt+button3_txt-button4_txt+button5_txt-button6_txt+logo.width+(int)centering);
28180 #endif
28181 }
28182
28183 inline int dialog(const char *title, const char *msg,
28184 const char *button1_txt, const char *button2_txt, const char *button3_txt,
28185 const char *button4_txt, const char *button5_txt, const char *button6_txt,
28186 const bool centering) {
28187 return dialog(title,msg,button1_txt,button2_txt,button3_txt,button4_txt,button5_txt,button6_txt,
28188 CImg<unsigned char>::get_logo40x38(),centering);
28189 }
28190
28191
28192
28193 template<typename t> inline int _marching_cubes_indice(const unsigned int edge, const CImg<t>& indices1, const CImg<t>& indices2,
28194 const unsigned int x, const unsigned int y, const unsigned int nx, const unsigned int ny) {
28195 switch (edge) {
28196 case 0: return indices1(x,y,0);
28197 case 1: return indices1(nx,y,1);
28198 case 2: return indices1(x,ny,0);
28199 case 3: return indices1(x,y,1);
28200 case 4: return indices2(x,y,0);
28201 case 5: return indices2(nx,y,1);
28202 case 6: return indices2(x,ny,0);
28203 case 7: return indices2(x,y,1);
28204 case 8: return indices1(x,y,2);
28205 case 9: return indices1(nx,y,2);
28206 case 10: return indices1(nx,ny,2);
28207 case 11: return indices1(x,ny,2);
28208 }
28209 return 0;
28210 }
28211
28213
28214
28215 template<typename tfunc, typename tp, typename tf>
28216 inline void marching_cubes(const tfunc& func, const float isovalue,
28217 const float x0, const float y0, const float z0,
28218 const float x1, const float y1, const float z1,
28219 const float resx, const float resy, const float resz,
28220 CImgList<tp>& points, CImgList<tf>& primitives,
28221 const bool invert_faces) {
28222
28223 static unsigned int edges[256] = {
28224 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
28225 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
28226 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
28227 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
28228 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
28229 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
28230 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
28231 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
28232 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
28233 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
28234 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
28235 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
28236 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
28237 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
28238 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
28239 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000 };
28240
28241 static int triangles[256][16] =
28242 {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28243 {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28244 {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28245 {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
28246 {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28247 {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
28248 {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
28249 {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1}, {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28250 {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28251 {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
28252 {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
28253 {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
28254 {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
28255 {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
28256 {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}, {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
28257 {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1}, {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
28258 {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28259 {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
28260 {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
28261 {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1}, {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
28262 {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
28263 {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
28264 {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}, {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
28265 {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1}, {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
28266 {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
28267 {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1}, {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28268 {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1}, {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
28269 {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1}, {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
28270 {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1}, {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
28271 {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1}, {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
28272 {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1}, {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
28273 {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1}, {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28274 {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28275 {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
28276 {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
28277 {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1}, {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
28278 {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
28279 {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
28280 {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
28281 {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1}, {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
28282 {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
28283 {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
28284 {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}, {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
28285 {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1}, {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
28286 {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
28287 {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}, {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
28288 {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1}, {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
28289 {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1}, {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
28290 {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
28291 {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1}, {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
28292 {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
28293 {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
28294 {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
28295 {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1}, {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
28296 {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1}, {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
28297 {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1}, {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28298 {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1}, {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
28299 {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1}, {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
28300 {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1}, {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
28301 {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1}, {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28302 {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1}, {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
28303 {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1}, {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
28304 {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1}, {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28305 {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1}, {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28306 {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28307 {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
28308 {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
28309 {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
28310 {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
28311 {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}, {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
28312 {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1}, {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
28313 {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1}, {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
28314 {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
28315 {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}, {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
28316 {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}, {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
28317 {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1}, {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
28318 {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1}, {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28319 {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1}, {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
28320 {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1}, {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
28321 {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1}, {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28322 {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
28323 {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
28324 {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
28325 {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1}, {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
28326 {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}, {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
28327 {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1}, {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
28328 {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1}, {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
28329 {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1}, {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
28330 {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1}, {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
28331 {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1}, {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
28332 {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1}, {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
28333 {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1}, {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
28334 {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1}, {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
28335 {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1}, {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28336 {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1}, {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
28337 {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28338 {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
28339 {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}, {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
28340 {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
28341 {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1}, {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
28342 {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1}, {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
28343 {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1}, {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
28344 {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
28345 {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1}, {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28346 {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1}, {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
28347 {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1}, {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
28348 {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1}, {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
28349 {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1}, {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28350 {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1}, {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
28351 {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1}, {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
28352 {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1}, {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28353 {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1}, {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28354 {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
28355 {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1}, {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
28356 {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1}, {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
28357 {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1}, {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
28358 {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1}, {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
28359 {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1}, {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28360 {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1}, {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
28361 {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28362 {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
28363 {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1}, {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28364 {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
28365 {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28366 {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1}, {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28367 {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1}, {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28368 {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
28369 {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}};
28370
28371 const unsigned int
28372 nx = (unsigned int)((x1-x0+1)/resx), nxm1 = nx-1,
28373 ny = (unsigned int)((y1-y0+1)/resy), nym1 = ny-1,
28374 nz = (unsigned int)((z1-z0+1)/resz), nzm1 = nz-1;
28375
28376 if (!nxm1 || !nym1 || !nzm1) return;
28377
28378 CImg<int> indices1(nx,ny,1,3,-1), indices2(indices1);
28379 CImg<float> values1(nx,ny), values2(nx,ny);
28380 float X = 0, Y = 0, Z = 0, nX = 0, nY = 0, nZ = 0;
28381
28382
28383 Y=y0;
28384 cimg_forY(values1,y) {
28385 X = x0;
28386 cimg_forX(values1,x) { values1(x,y) = (float)func(X,Y,z0); X+=resx; }
28387 Y+=resy;
28388 }
28389
28390
28391 Z = z0; nZ = Z + resz;
28392 for (unsigned int zi=0; zi<nzm1; ++zi, Z=nZ, nZ+=resz) {
28393 Y = y0; nY = Y + resy;
28394 indices2.fill(-1);
28395 for (unsigned int yi=0, nyi=1; yi<nym1; ++yi, ++nyi, Y=nY, nY+=resy) {
28396 X = x0; nX = X + resx;
28397 for (unsigned int xi=0, nxi=1; xi<nxm1; ++xi, ++nxi, X=nX, nX+=resx) {
28398
28399
28400 const float
28401 val0 = values1(xi,yi), val1 = values1(nxi,yi), val2 = values1(nxi,nyi), val3 = values1(xi,nyi),
28402 val4 = values2(xi,yi) = (float)func(X,Y,nZ),
28403 val5 = values2(nxi,yi) = (float)func(nX,Y,nZ),
28404 val6 = values2(nxi,nyi) = (float)func(nX,nY,nZ),
28405 val7 = values2(xi,nyi) = (float)func(X,nY,nZ);
28406
28407 const unsigned int configuration =
28408 (val0<isovalue?1:0) | (val1<isovalue?2:0) | (val2<isovalue?4:0) | (val3<isovalue?8:0) |
28409 (val4<isovalue?16:0) | (val5<isovalue?32:0) | (val6<isovalue?64:0) | (val7<isovalue?128:0),
28410 edge = edges[configuration];
28411
28412
28413 if (edge) {
28414 if ((edge&1) && indices1(xi,yi,0)<0) {
28415 const float Xi = X + (isovalue-val0)*resx/(val1-val0);
28416 indices1(xi,yi,0) = points.size;
28417 points.insert(CImg<tp>::vector(Xi,Y,Z));
28418 }
28419 if ((edge&2) && indices1(nxi,yi,1)<0) {
28420 const float Yi = Y + (isovalue-val1)*resy/(val2-val1);
28421 indices1(nxi,yi,1) = points.size;
28422 points.insert(CImg<tp>::vector(nX,Yi,Z));
28423 }
28424 if ((edge&4) && indices1(xi,nyi,0)<0) {
28425 const float Xi = X + (isovalue-val3)*resx/(val2-val3);
28426 indices1(xi,nyi,0) = points.size;
28427 points.insert(CImg<tp>::vector(Xi,nY,Z));
28428 }
28429 if ((edge&8) && indices1(xi,yi,1)<0) {
28430 const float Yi = Y + (isovalue-val0)*resy/(val3-val0);
28431 indices1(xi,yi,1) = points.size;
28432 points.insert(CImg<tp>::vector(X,Yi,Z));
28433 }
28434 if ((edge&16) && indices2(xi,yi,0)<0) {
28435 const float Xi = X + (isovalue-val4)*resx/(val5-val4);
28436 indices2(xi,yi,0) = points.size;
28437 points.insert(CImg<tp>::vector(Xi,Y,nZ));
28438 }
28439 if ((edge&32) && indices2(nxi,yi,1)<0) {
28440 const float Yi = Y + (isovalue-val5)*resy/(val6-val5);
28441 indices2(nxi,yi,1) = points.size;
28442 points.insert(CImg<tp>::vector(nX,Yi,nZ));
28443 }
28444 if ((edge&64) && indices2(xi,nyi,0)<0) {
28445 const float Xi = X + (isovalue-val7)*resx/(val6-val7);
28446 indices2(xi,nyi,0) = points.size;
28447 points.insert(CImg<tp>::vector(Xi,nY,nZ));
28448 }
28449 if ((edge&128) && indices2(xi,yi,1)<0) {
28450 const float Yi = Y + (isovalue-val4)*resy/(val7-val4);
28451 indices2(xi,yi,1) = points.size;
28452 points.insert(CImg<tp>::vector(X,Yi,nZ));
28453 }
28454 if ((edge&256) && indices1(xi,yi,2)<0) {
28455 const float Zi = Z+ (isovalue-val0)*resz/(val4-val0);
28456 indices1(xi,yi,2) = points.size;
28457 points.insert(CImg<tp>::vector(X,Y,Zi));
28458 }
28459 if ((edge&512) && indices1(nxi,yi,2)<0) {
28460 const float Zi = Z + (isovalue-val1)*resz/(val5-val1);
28461 indices1(nxi,yi,2) = points.size;
28462 points.insert(CImg<tp>::vector(nX,Y,Zi));
28463 }
28464 if ((edge&1024) && indices1(nxi,nyi,2)<0) {
28465 const float Zi = Z + (isovalue-val2)*resz/(val6-val2);
28466 indices1(nxi,nyi,2) = points.size;
28467 points.insert(CImg<tp>::vector(nX,nY,Zi));
28468 }
28469 if ((edge&2048) && indices1(xi,nyi,2)<0) {
28470 const float Zi = Z + (isovalue-val3)*resz/(val7-val3);
28471 indices1(xi,nyi,2) = points.size;
28472 points.insert(CImg<tp>::vector(X,nY,Zi));
28473 }
28474
28475
28476 for (int *triangle=triangles[configuration]; *triangle!=-1; ) {
28477 const unsigned int p0 = *(triangle++), p1 = *(triangle++), p2 = *(triangle++);
28478 const tf
28479 i0 = (tf)(_marching_cubes_indice(p0,indices1,indices2,xi,yi,nxi,nyi)),
28480 i1 = (tf)(_marching_cubes_indice(p1,indices1,indices2,xi,yi,nxi,nyi)),
28481 i2 = (tf)(_marching_cubes_indice(p2,indices1,indices2,xi,yi,nxi,nyi));
28482 if (invert_faces) primitives.insert(CImg<tf>::vector(i0,i1,i2));
28483 else primitives.insert(CImg<tf>::vector(i0,i2,i1));
28484 }
28485 }
28486 }
28487 }
28488 cimg::swap(values1,values2);
28489 cimg::swap(indices1,indices2);
28490 }
28491 }
28492
28493
28494 template<typename t> inline int _marching_squares_indice(const unsigned int edge, const CImg<t>& indices1, const CImg<t>& indices2,
28495 const unsigned int x, const unsigned int nx) {
28496 switch (edge) {
28497 case 0: return (int)indices1(x,0);
28498 case 1: return (int)indices1(nx,1);
28499 case 2: return (int)indices2(x,0);
28500 case 3: return (int)indices1(x,1);
28501 }
28502 return 0;
28503 }
28504
28506 template<typename tfunc, typename tp, typename tf>
28507 inline void marching_squares(const tfunc& func, const float isovalue,
28508 const float x0, const float y0,
28509 const float x1, const float y1,
28510 const float resx, const float resy,
28511 CImgList<tp>& points, CImgList<tf>& primitives) {
28512
28513 static unsigned int edges[16] = { 0x0, 0x9, 0x3, 0xa, 0x6, 0xf, 0x5, 0xc, 0xc, 0x5, 0xf, 0x6, 0xa, 0x3, 0x9, 0x0 };
28514 static int segments[16][4] = { { -1,-1,-1,-1 }, { 0,3,-1,-1 }, { 0,1,-1,-1 }, { 1,3,-1,-1 },
28515 { 1,2,-1,-1 }, { 0,1,2,3 }, { 0,2,-1,-1 }, { 2,3,-1,-1 },
28516 { 2,3,-1,-1 }, { 0,2,-1,-1}, { 0,3,1,2 }, { 1,2,-1,-1 },
28517 { 1,3,-1,-1 }, { 0,1,-1,-1}, { 0,3,-1,-1}, { -1,-1,-1,-1 } };
28518 const unsigned int
28519 nx = (unsigned int)((x1-x0+1)/resx), nxm1 = nx-1,
28520 ny = (unsigned int)((y1-y0+1)/resy), nym1 = ny-1;
28521
28522 if (!nxm1 || !nym1) return;
28523
28524 CImg<int> indices1(nx,1,1,2,-1), indices2(nx,1,1,2);
28525 CImg<float> values1(nx), values2(nx);
28526 float X = 0, Y = 0, nX = 0, nY = 0;
28527
28528
28529 cimg_forX(values1,x) { values1(x) = (float)func(X,Y); X+=resx; }
28530
28531
28532 Y = y0; nY = Y + resy;
28533 for (unsigned int yi=0, nyi=1; yi<nym1; ++yi, ++nyi, Y=nY, nY+=resy) {
28534 X = x0; nX = X + resx;
28535 indices2.fill(-1);
28536 for (unsigned int xi=0, nxi=1; xi<nxm1; ++xi, ++nxi, X=nX, nX+=resx) {
28537
28538
28539 const float
28540 val0 = values1(xi), val1 = values1(nxi),
28541 val2 = values2(nxi) = (float)func(nX,nY),
28542 val3 = values2(xi) = (float)func(X,nY);
28543
28544 const unsigned int configuration = (val0<isovalue?1:0) | (val1<isovalue?2:0) | (val2<isovalue?4:0) | (val3<isovalue?8:0),
28545 edge = edges[configuration];
28546
28547
28548 if (edge) {
28549 if ((edge&1) && indices1(xi,0)<0) {
28550 const float Xi = X + (isovalue-val0)*resx/(val1-val0);
28551 indices1(xi,0) = points.size;
28552 points.insert(CImg<tp>::vector(Xi,Y));
28553 }
28554 if ((edge&2) && indices1(nxi,1)<0) {
28555 const float Yi = Y + (isovalue-val1)*resy/(val2-val1);
28556 indices1(nxi,1) = points.size;
28557 points.insert(CImg<tp>::vector(nX,Yi));
28558 }
28559 if ((edge&4) && indices2(xi,0)<0) {
28560 const float Xi = X + (isovalue-val3)*resx/(val2-val3);
28561 indices2(xi,0) = points.size;
28562 points.insert(CImg<tp>::vector(Xi,nY));
28563 }
28564 if ((edge&8) && indices1(xi,1)<0) {
28565 const float Yi = Y + (isovalue-val0)*resy/(val3-val0);
28566 indices1(xi,1) = points.size;
28567 points.insert(CImg<tp>::vector(X,Yi));
28568 }
28569
28570
28571 for (int *segment=segments[configuration]; *segment!=-1; ) {
28572 const unsigned int p0 = *(segment++), p1 = *(segment++);
28573 const tf
28574 i0 = (tf)(_marching_squares_indice(p0,indices1,indices2,xi,nxi)),
28575 i1 = (tf)(_marching_squares_indice(p1,indices1,indices2,xi,nxi));
28576 primitives.insert(CImg<tf>::vector(i0,i1));
28577 }
28578 }
28579 }
28580 values1.swap(values2);
28581 indices1.swap(indices2);
28582 }
28583 }
28584
28585
28586 }
28587
28588
28589 }
28590
28591 #ifdef cimg_use_visualcpp6
28592 #undef std
28593 #endif
28594 #ifdef cimg_redefine_min
28595 #define min(a,b) (((a)<(b))?(a):(b))
28596 #endif
28597 #ifdef cimg_redefine_max
28598 #define max(a,b) (((a)>(b))?(a):(b))
28599 #endif
28600
28601 #endif
28602
28603
28604