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
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef cimg_version
00053 #define cimg_version 128
00054
00055
00056 #if defined(_MSC_VER) && _MSC_VER<1300
00057 #define cimg_use_visualcpp6
00058 #endif
00059
00060
00061 #if defined(_MSC_VER) && _MSC_VER>=1300
00062 #define _CRT_SECURE_NO_DEPRECATE 1
00063 #define _CRT_NONSTDC_NO_DEPRECATE 1
00064 #endif
00065
00066
00067 #include <cstdio>
00068 #include <cstdlib>
00069 #include <cstdarg>
00070 #include <cstring>
00071 #include <cmath>
00072 #include <ctime>
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 #ifndef cimg_OS
00086
00087 #if defined(unix) || defined(__unix) || defined(__unix__) \
00088 || defined(linux) || defined(__linux) || defined(__linux__) \
00089 || defined(sun) || defined(__sun) \
00090 || defined(BSD) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined __DragonFly__ \
00091 || defined(__MACOSX__) || defined(__APPLE__) \
00092 || defined(sgi) || defined(__sgi) \
00093 || defined(__CYGWIN__)
00094 #define cimg_OS 1
00095 #ifndef cimg_display_type
00096 #define cimg_display_type 1
00097 #endif
00098 #ifndef cimg_color_terminal
00099 #define cimg_color_terminal
00100 #endif
00101
00102 #elif defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
00103 || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
00104 #define cimg_OS 2
00105 #ifndef cimg_display_type
00106 #define cimg_display_type 2
00107 #endif
00108
00109 #else
00110 #define cimg_OS 0
00111 #ifndef cimg_display_type
00112 #define cimg_display_type 0
00113 #endif
00114 #endif
00115 #endif
00116
00117
00118
00119
00120
00121
00122
00123 #ifndef cimg_debug
00124 #define cimg_debug 2
00125 #endif
00126
00127
00128 #if cimg_OS==1
00129 #include <sys/time.h>
00130 #include <unistd.h>
00131 #elif cimg_OS==2
00132 #include <windows.h>
00133 #ifndef _WIN32_IE
00134 #define _WIN32_IE 0x0400
00135 #endif
00136 #include <shlobj.h>
00137 #ifdef cimg_use_visualcpp6
00138 #define std
00139 #endif
00140 #endif
00141
00142
00143 #ifdef PI
00144 #error -------------------------------------------------------------------------------
00145 #error The macro value 'PI' has been defined prior to the #include "CImg.h" directive.
00146 #error The CImg Library does not compile with such a macro value defined.
00147 #error Please (re)define this macro *after* including "CImg.h" if really necessary.
00148 #error Following error messages are most probably related to this problem.
00149 #error -------------------------------------------------------------------------------
00150 #endif
00151 #ifdef min
00152 #undef min
00153 #define cimg_redefine_min
00154 #endif
00155 #ifdef max
00156 #undef max
00157 #define cimg_redefine_max
00158 #endif
00159
00160
00161 #if cimg_display_type==1
00162 #include <X11/Xlib.h>
00163 #include <X11/Xutil.h>
00164 #include <X11/keysym.h>
00165 #include <pthread.h>
00166 #ifdef cimg_use_xshm
00167 #include <sys/ipc.h>
00168 #include <sys/shm.h>
00169 #include <X11/extensions/XShm.h>
00170 #endif
00171 #ifdef cimg_use_xrandr
00172 #include <X11/extensions/Xrandr.h>
00173 #endif
00174 #endif
00175
00176
00177
00178
00179
00180
00181
00182
00183 #ifdef cimg_use_png
00184 extern "C" {
00185 #include "png.h"
00186 }
00187 #endif
00188 #ifdef cimg_use_jpeg
00189 extern "C" {
00190 #include "jpeglib.h"
00191 }
00192 #endif
00193 #ifdef cimg_use_tiff
00194 extern "C" {
00195 #include "tiffio.h"
00196 }
00197 #endif
00198 #ifdef cimg_use_magick
00199 #include "Magick++.h"
00200 #endif
00201 #ifdef cimg_use_fftw3
00202 extern "C" {
00203 #include "fftw3.h"
00204 }
00205 #endif
00206 #ifdef cimg_use_lapack
00207 extern "C" {
00208 extern void sgetrf_(int*, int*, float*, int*, int*, int*);
00209 extern void sgetri_(int*, float*, int*, int*, float*, int*, int*);
00210 extern void sgetrs_(char*, int*, int*, float*, int*, int*, float*, int*, int*);
00211 extern void sgesvd_(char*, char*, int*, int*, float*, int*, float*, float*, int*, float*, int*, float*, int*, int*);
00212 extern void ssyev_(char*, char*, int*, float*, int*, float*, float*, int*, int*);
00213 extern void dgetrf_(int*, int*, double*, int*, int*, int*);
00214 extern void dgetri_(int*, double*, int*, int*, double*, int*, int*);
00215 extern void dgetrs_(char*, int*, int*, double*, int*, int*, double*, int*, int*);
00216 extern void dgesvd_(char*, char*, int*, int*, double*, int*, double*, double*, int*, double*, int*, double*, int*, int*);
00217 extern void dsyev_(char*, char*, int*, double*, int*, double*, double*, int*, int*);
00218 }
00219 #endif
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 #define cimg_usage(usage) cimg_library::cimg::option((char*)0,argc,argv,(char*)0,usage)
00234 #define cimg_help(str) cimg_library::cimg::option((char*)0,argc,argv,str,(char*)0)
00235 #define cimg_option(name,defaut,usage) cimg_library::cimg::option(name,argc,argv,defaut,usage)
00236 #define cimg_argument(pos) cimg_library::cimg::argument(pos,argc,argv)
00237 #define cimg_argument1(pos,s0) cimg_library::cimg::argument(pos,argc,argv,1,s0)
00238 #define cimg_argument2(pos,s0,s1) cimg_library::cimg::argument(pos,argc,argv,2,s0,s1)
00239 #define cimg_argument3(pos,s0,s1,s2) cimg_library::cimg::argument(pos,argc,argv,3,s0,s1,s2)
00240 #define cimg_argument4(pos,s0,s1,s2,s3) cimg_library::cimg::argument(pos,argc,argv,4,s0,s1,s2,s3)
00241 #define cimg_argument5(pos,s0,s1,s2,s3,s4) cimg_library::cimg::argument(pos,argc,argv,5,s0,s1,s2,s3,s4)
00242 #define cimg_argument6(pos,s0,s1,s2,s3,s4,s5) cimg_library::cimg::argument(pos,argc,argv,6,s0,s1,s2,s3,s4,s5)
00243 #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)
00244 #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)
00245 #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)
00246
00247
00248
00249 #define CImg_2x2(I,T) T I[4]; \
00250 T& I##cc = I[0]; T& I##nc = I[1]; \
00251 T& I##cn = I[2]; T& I##nn = I[3]; \
00252 I##cc = I##nc = \
00253 I##cn = I##nn = 0
00254
00255 #define CImg_3x3(I,T) T I[9]; \
00256 T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; \
00257 T& I##pc = I[3]; T& I##cc = I[4]; T& I##nc = I[5]; \
00258 T& I##pn = I[6]; T& I##cn = I[7]; T& I##nn = I[8]; \
00259 I##pp = I##cp = I##np = \
00260 I##pc = I##cc = I##nc = \
00261 I##pn = I##cn = I##nn = 0
00262
00263
00264 #define CImg_4x4(I,T) T I[16]; \
00265 T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; T& I##ap = I[3]; \
00266 T& I##pc = I[4]; T& I##cc = I[5]; T& I##nc = I[6]; T& I##ac = I[7]; \
00267 T& I##pn = I[8]; T& I##cn = I[9]; T& I##nn = I[10]; T& I##an = I[11]; \
00268 T& I##pa = I[12]; T& I##ca = I[13]; T& I##na = I[14]; T& I##aa = I[15]; \
00269 I##pp = I##cp = I##np = I##ap = \
00270 I##pc = I##cc = I##nc = I##ac = \
00271 I##pn = I##cn = I##nn = I##an = \
00272 I##pa = I##ca = I##na = I##aa = 0
00273
00274 #define CImg_5x5(I,T) T I[25]; \
00275 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]; \
00276 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]; \
00277 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]; \
00278 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]; \
00279 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]; \
00280 I##bb = I##pb = I##cb = I##nb = I##ab = \
00281 I##bp = I##pp = I##cp = I##np = I##ap = \
00282 I##bc = I##pc = I##cc = I##nc = I##ac = \
00283 I##bn = I##pn = I##cn = I##nn = I##an = \
00284 I##ba = I##pa = I##ca = I##na = I##aa = 0
00285
00286 #define CImg_2x2x2(I,T) T I[8]; \
00287 T& I##ccc = I[0]; T& I##ncc = I[1]; \
00288 T& I##cnc = I[2]; T& I##nnc = I[3]; \
00289 T& I##ccn = I[4]; T& I##ncn = I[5]; \
00290 T& I##cnn = I[6]; T& I##nnn = I[7]; \
00291 I##ccc = I##ncc = \
00292 I##cnc = I##nnc = \
00293 I##ccn = I##ncn = \
00294 I##cnn = I##nnn = 0
00295
00296 #define CImg_3x3x3(I,T) T I[27]; \
00297 T& I##ppp = I[0]; T& I##cpp = I[1]; T& I##npp = I[2]; \
00298 T& I##pcp = I[3]; T& I##ccp = I[4]; T& I##ncp = I[5]; \
00299 T& I##pnp = I[6]; T& I##cnp = I[7]; T& I##nnp = I[8]; \
00300 T& I##ppc = I[9]; T& I##cpc = I[10]; T& I##npc = I[11]; \
00301 T& I##pcc = I[12]; T& I##ccc = I[13]; T& I##ncc = I[14]; \
00302 T& I##pnc = I[15]; T& I##cnc = I[16]; T& I##nnc = I[17]; \
00303 T& I##ppn = I[18]; T& I##cpn = I[19]; T& I##npn = I[20]; \
00304 T& I##pcn = I[21]; T& I##ccn = I[22]; T& I##ncn = I[23]; \
00305 T& I##pnn = I[24]; T& I##cnn = I[25]; T& I##nnn = I[26]; \
00306 I##ppp = I##cpp = I##npp = \
00307 I##pcp = I##ccp = I##ncp = \
00308 I##pnp = I##cnp = I##nnp = \
00309 I##ppc = I##cpc = I##npc = \
00310 I##pcc = I##ccc = I##ncc = \
00311 I##pnc = I##cnc = I##nnc = \
00312 I##ppn = I##cpn = I##npn = \
00313 I##pcn = I##ccn = I##ncn = \
00314 I##pnn = I##cnn = I##nnn = 0
00315
00316 #define cimg_get2x2(img,x,y,z,v,I) \
00317 I[0] = (img)(x, y,z,v), I[1] = (img)(_n1##x, y,z,v), \
00318 I[2] = (img)(x,_n1##y,z,v), I[3] = (img)(_n1##x,_n1##y,z,v)
00319
00320 #define cimg_get3x3(img,x,y,z,v,I) \
00321 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), \
00322 I[3] = (img)(_p1##x, y,z,v), I[4] = (img)(x, y,z,v), I[5] = (img)(_n1##x, y,z,v), \
00323 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)
00324
00325 #define cimg_get4x4(img,x,y,z,v,I) \
00326 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), \
00327 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), \
00328 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), \
00329 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)
00330
00331 #define cimg_get5x5(img,x,y,z,v,I) \
00332 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), \
00333 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), \
00334 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), \
00335 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), \
00336 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)
00337 #define cimg_get6x6(img,x,y,z,v,I) \
00338 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), \
00339 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), \
00340 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), \
00341 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), \
00342 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), \
00343 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);
00344
00345 #define cimg_get7x7(img,x,y,z,v,I) \
00346 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), \
00347 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), \
00348 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), \
00349 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), \
00350 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), \
00351 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), \
00352 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);
00353
00354 #define cimg_get2x2x2(img,x,y,z,v,I) \
00355 I[0] = (img)(x, y, z,v), I[1] = (img)(_n1##x, y, z,v), \
00356 I[2] = (img)(x,_n1##y, z,v), I[3] = (img)(_n1##x,_n1##y, z,v), \
00357 I[4] = (img)(x, y,_n1##z,v), I[5] = (img)(_n1##x, y,_n1##z,v), \
00358 I[6] = (img)(x,_n1##y,_n1##z,v), I[7] = (img)(_n1##x,_n1##y,_n1##z,v)
00359
00360 #define cimg_get3x3x3(img,x,y,z,v,I) \
00361 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), \
00362 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), \
00363 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), \
00364 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), \
00365 I[12] = (img)(_p1##x, y, z,v), I[13] = (img)(x, y, z,v), I[14] = (img)(_n1##x, y, z,v), \
00366 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), \
00367 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), \
00368 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), \
00369 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)
00370
00371
00372
00373
00374 #define cimg_for(img,ptr,T_ptr) for (T_ptr *ptr = (img).data + (img).size(); (ptr--)>(img).data; )
00375 #define cimg_foroff(img,off) for (unsigned int off = 0; off<(img).size(); ++off)
00376 #define cimglist_for(list,l) for (unsigned int l=0; l<(list).size; ++l)
00377 #define cimglist_apply(list,fn) cimglist_for(list,__##fn) (list)[__##fn].fn
00378
00379 #define cimg_for1(bound,i) for (int i = 0; i<(int)(bound); ++i)
00380 #define cimg_forX(img,x) cimg_for1((img).width,x)
00381 #define cimg_forY(img,y) cimg_for1((img).height,y)
00382 #define cimg_forZ(img,z) cimg_for1((img).depth,z)
00383 #define cimg_forV(img,v) cimg_for1((img).dim,v)
00384 #define cimg_forXY(img,x,y) cimg_forY(img,y) cimg_forX(img,x)
00385 #define cimg_forXZ(img,x,z) cimg_forZ(img,z) cimg_forX(img,x)
00386 #define cimg_forYZ(img,y,z) cimg_forZ(img,z) cimg_forY(img,y)
00387 #define cimg_forXV(img,x,v) cimg_forV(img,v) cimg_forX(img,x)
00388 #define cimg_forYV(img,y,v) cimg_forV(img,v) cimg_forY(img,y)
00389 #define cimg_forZV(img,z,v) cimg_forV(img,v) cimg_forZ(img,z)
00390 #define cimg_forXYZ(img,x,y,z) cimg_forZ(img,z) cimg_forXY(img,x,y)
00391 #define cimg_forXYV(img,x,y,v) cimg_forV(img,v) cimg_forXY(img,x,y)
00392 #define cimg_forXZV(img,x,z,v) cimg_forV(img,v) cimg_forXZ(img,x,z)
00393 #define cimg_forYZV(img,y,z,v) cimg_forV(img,v) cimg_forYZ(img,y,z)
00394 #define cimg_forXYZV(img,x,y,z,v) cimg_forV(img,v) cimg_forXYZ(img,x,y,z)
00395
00396 #define cimg_for_in1(bound,i0,i1,i) \
00397 for (int i = (int)(i0)<0?0:(int)(i0), _max##i = (int)(i1)<(int)(bound)?(int)(i1):(int)(bound)-1; i<=_max##i; ++i)
00398 #define cimg_for_inX(img,x0,x1,x) cimg_for_in1((img).width,x0,x1,x)
00399 #define cimg_for_inY(img,y0,y1,y) cimg_for_in1((img).height,y0,y1,y)
00400 #define cimg_for_inZ(img,z0,z1,z) cimg_for_in1((img).depth,z0,z1,z)
00401 #define cimg_for_inV(img,v0,v1,v) cimg_for_in1((img).dim,v0,v1,v)
00402 #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)
00403 #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)
00404 #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)
00405 #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)
00406 #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)
00407 #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)
00408 #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)
00409 #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)
00410 #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)
00411 #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)
00412 #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)
00413 #define cimg_for_insideX(img,x,n) cimg_for_inX(img,n,(img).width-1-(n),x)
00414 #define cimg_for_insideY(img,y,n) cimg_for_inY(img,n,(img).height-1-(n),y)
00415 #define cimg_for_insideZ(img,z,n) cimg_for_inZ(img,n,(img).depth-1-(n),z)
00416 #define cimg_for_insideV(img,v,n) cimg_for_inV(img,n,(img).dim-1-(n),v)
00417 #define cimg_for_insideXY(img,x,y,n) cimg_for_inXY(img,n,n,(img).width-1-(n),(img).height-1-(n),x,y)
00418 #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)
00419 #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)
00420
00421 #define cimg_for_out1(boundi,i0,i1,i) \
00422 for (int i = (int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); ++i, i = i==(int)(i0)?(int)(i1)+1:i)
00423 #define cimg_for_out2(boundi,boundj,i0,j0,i1,j1,i,j) \
00424 for (int j = 0; j<(int)(boundj); ++j) \
00425 for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j?0:(int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); \
00426 ++i, i = _n1j?i:(i==(int)(i0)?(int)(i1)+1:i))
00427 #define cimg_for_out3(boundi,boundj,boundk,i0,j0,k0,i1,j1,k1,i,j,k) \
00428 for (int k = 0; k<(int)(boundk); ++k) \
00429 for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \
00430 for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j || _n1k?0:(int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); \
00431 ++i, i = _n1j || _n1k?i:(i==(int)(i0)?(int)(i1)+1:i))
00432 #define cimg_for_out4(boundi,boundj,boundk,boundl,i0,j0,k0,l0,i1,j1,k1,l1,i,j,k,l) \
00433 for (int l = 0; l<(int)(boundl); ++l) \
00434 for (int _n1l = (int)(l<(int)(l0) || l>(int)(l1)), k = 0; k<(int)(boundk); ++k) \
00435 for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \
00436 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); \
00437 ++i, i = _n1j || _n1k || _n1l?i:(i==(int)(i0)?(int)(i1)+1:i))
00438 #define cimg_for_outX(img,x0,x1,x) cimg_for_out1((img).width,x0,x1,x)
00439 #define cimg_for_outY(img,y0,y1,y) cimg_for_out1((img).height,y0,y1,y)
00440 #define cimg_for_outZ(img,z0,z1,z) cimg_for_out1((img).depth,z0,z1,z)
00441 #define cimg_for_outV(img,v0,v1,v) cimg_for_out1((img).dim,v0,v1,v)
00442 #define cimg_for_outXY(img,x0,y0,x1,y1,x,y) cimg_for_out2((img).width,(img).height,x0,y0,x1,y1,x,y)
00443 #define cimg_for_outXZ(img,x0,z0,x1,z1,x,z) cimg_for_out2((img).width,(img).depth,x0,z0,x1,z1,x,z)
00444 #define cimg_for_outXV(img,x0,v0,x1,v1,x,v) cimg_for_out2((img).width,(img).dim,x0,v0,x1,v1,x,v)
00445 #define cimg_for_outYZ(img,y0,z0,y1,z1,y,z) cimg_for_out2((img).height,(img).depth,y0,z0,y1,z1,y,z)
00446 #define cimg_for_outYV(img,y0,v0,y1,v1,y,v) cimg_for_out2((img).height,(img).dim,y0,v0,y1,v1,y,v)
00447 #define cimg_for_outZV(img,z0,v0,z1,v1,z,v) cimg_for_out2((img).depth,(img).dim,z0,v0,z1,v1,z,v)
00448 #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)
00449 #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)
00450 #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)
00451 #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)
00452 #define cimg_for_outXYZV(img,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v) \
00453 cimg_for_out4((img).width,(img).height,(img).depth,(img).dim,x0,y0,z0,v0,x1,y1,z1,v1,x,y,z,v)
00454 #define cimg_for_borderX(img,x,n) cimg_for_outX(img,n,(img).width-1-(n),x)
00455 #define cimg_for_borderY(img,y,n) cimg_for_outY(img,n,(img).height-1-(n),y)
00456 #define cimg_for_borderZ(img,z,n) cimg_for_outZ(img,n,(img).depth-1-(n),z)
00457 #define cimg_for_borderV(img,v,n) cimg_for_outV(img,n,(img).dim-1-(n),v)
00458 #define cimg_for_borderXY(img,x,y,n) cimg_for_outXY(img,n,n,(img).width-1-(n),(img).height-1-(n),x,y)
00459 #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)
00460 #define cimg_for_borderXYZV(img,x,y,z,v,n) \
00461 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)
00462
00463 #define cimg_for_spiralXY(img,x,y) \
00464 for (int x = 0, y = 0, _n1##x = 1, _n1##y = (int)((img).width*(img).height); _n1##y; \
00465 --_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)
00466
00467 #define cimg_for_lineXY(x,y,x0,y0,x1,y1) \
00468 for (int x = (int)(x0), y = (int)(y0), _sx = 1, _sy = 1, _steep = 0, \
00469 _dx=(x1)>(x0)?(int)(x1)-(int)(x0):(_sx=-1,(int)(x0)-(int)(x1)), \
00470 _dy=(y1)>(y0)?(int)(y1)-(int)(y0):(_sy=-1,(int)(y0)-(int)(y1)), \
00471 _counter = _dx, \
00472 _err = _dx>_dy?(_dy>>1):((_steep=1),(_counter=_dy),(_dx>>1)); \
00473 _counter>=0; \
00474 --_counter, x+=_steep? \
00475 (y+=_sy,(_err-=_dx)<0?_err+=_dy,_sx:0): \
00476 (y+=(_err-=_dy)<0?_err+=_dx,_sy:0,_sx))
00477
00478 #define cimg_for2(bound,i) \
00479 for (int i = 0, _n1##i = 1>=(bound)?(int)(bound)-1:1; \
00480 _n1##i<(int)(bound) || i==--_n1##i; \
00481 ++i, ++_n1##i)
00482 #define cimg_for2X(img,x) cimg_for2((img).width,x)
00483 #define cimg_for2Y(img,y) cimg_for2((img).height,y)
00484 #define cimg_for2Z(img,z) cimg_for2((img).depth,z)
00485 #define cimg_for2V(img,v) cimg_for2((img).dim,v)
00486 #define cimg_for2XY(img,x,y) cimg_for2Y(img,y) cimg_for2X(img,x)
00487 #define cimg_for2XZ(img,x,z) cimg_for2Z(img,z) cimg_for2X(img,x)
00488 #define cimg_for2XV(img,x,v) cimg_for2V(img,v) cimg_for2X(img,x)
00489 #define cimg_for2YZ(img,y,z) cimg_for2Z(img,z) cimg_for2Y(img,y)
00490 #define cimg_for2YV(img,y,v) cimg_for2V(img,v) cimg_for2Y(img,y)
00491 #define cimg_for2ZV(img,z,v) cimg_for2V(img,v) cimg_for2Z(img,z)
00492 #define cimg_for2XYZ(img,x,y,z) cimg_for2Z(img,z) cimg_for2XY(img,x,y)
00493 #define cimg_for2XZV(img,x,z,v) cimg_for2V(img,v) cimg_for2XZ(img,x,z)
00494 #define cimg_for2YZV(img,y,z,v) cimg_for2V(img,v) cimg_for2YZ(img,y,z)
00495 #define cimg_for2XYZV(img,x,y,z,v) cimg_for2V(img,v) cimg_for2XYZ(img,x,y,z)
00496
00497 #define cimg_for_in2(bound,i0,i1,i) \
00498 for (int i = (int)(i0)<0?0:(int)(i0), \
00499 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1; \
00500 i<=(int)(i1) && (_n1##i<(int)(bound) || i==--_n1##i); \
00501 ++i, ++_n1##i)
00502 #define cimg_for_in2X(img,x0,x1,x) cimg_for_in2((img).width,x0,x1,x)
00503 #define cimg_for_in2Y(img,y0,y1,y) cimg_for_in2((img).height,y0,y1,y)
00504 #define cimg_for_in2Z(img,z0,z1,z) cimg_for_in2((img).depth,z0,z1,z)
00505 #define cimg_for_in2V(img,v0,v1,v) cimg_for_in2((img).dim,v0,v1,v)
00506 #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)
00507 #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)
00508 #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)
00509 #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)
00510 #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)
00511 #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)
00512 #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)
00513 #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)
00514 #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)
00515 #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)
00516
00517 #define cimg_for3(bound,i) \
00518 for (int i = 0, _p1##i = 0, \
00519 _n1##i = 1>=(bound)?(int)(bound)-1:1; \
00520 _n1##i<(int)(bound) || i==--_n1##i; \
00521 _p1##i = i++, ++_n1##i)
00522 #define cimg_for3X(img,x) cimg_for3((img).width,x)
00523 #define cimg_for3Y(img,y) cimg_for3((img).height,y)
00524 #define cimg_for3Z(img,z) cimg_for3((img).depth,z)
00525 #define cimg_for3V(img,v) cimg_for3((img).dim,v)
00526 #define cimg_for3XY(img,x,y) cimg_for3Y(img,y) cimg_for3X(img,x)
00527 #define cimg_for3XZ(img,x,z) cimg_for3Z(img,z) cimg_for3X(img,x)
00528 #define cimg_for3XV(img,x,v) cimg_for3V(img,v) cimg_for3X(img,x)
00529 #define cimg_for3YZ(img,y,z) cimg_for3Z(img,z) cimg_for3Y(img,y)
00530 #define cimg_for3YV(img,y,v) cimg_for3V(img,v) cimg_for3Y(img,y)
00531 #define cimg_for3ZV(img,z,v) cimg_for3V(img,v) cimg_for3Z(img,z)
00532 #define cimg_for3XYZ(img,x,y,z) cimg_for3Z(img,z) cimg_for3XY(img,x,y)
00533 #define cimg_for3XZV(img,x,z,v) cimg_for3V(img,v) cimg_for3XZ(img,x,z)
00534 #define cimg_for3YZV(img,y,z,v) cimg_for3V(img,v) cimg_for3YZ(img,y,z)
00535 #define cimg_for3XYZV(img,x,y,z,v) cimg_for3V(img,v) cimg_for3XYZ(img,x,y,z)
00536
00537 #define cimg_for_in3(bound,i0,i1,i) \
00538 for (int i = (int)(i0)<0?0:(int)(i0), \
00539 _p1##i = i-1<0?0:i-1, \
00540 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1; \
00541 i<=(int)(i1) && (_n1##i<(int)(bound) || i==--_n1##i); \
00542 _p1##i = i++, ++_n1##i)
00543 #define cimg_for_in3X(img,x0,x1,x) cimg_for_in3((img).width,x0,x1,x)
00544 #define cimg_for_in3Y(img,y0,y1,y) cimg_for_in3((img).height,y0,y1,y)
00545 #define cimg_for_in3Z(img,z0,z1,z) cimg_for_in3((img).depth,z0,z1,z)
00546 #define cimg_for_in3V(img,v0,v1,v) cimg_for_in3((img).dim,v0,v1,v)
00547 #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)
00548 #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)
00549 #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)
00550 #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)
00551 #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)
00552 #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)
00553 #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)
00554 #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)
00555 #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)
00556 #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)
00557
00558 #define cimg_for4(bound,i) \
00559 for (int i = 0, _p1##i = 0, _n1##i = 1>=(bound)?(int)(bound)-1:1, \
00560 _n2##i = 2>=(bound)?(int)(bound)-1:2; \
00561 _n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i); \
00562 _p1##i = i++, ++_n1##i, ++_n2##i)
00563 #define cimg_for4X(img,x) cimg_for4((img).width,x)
00564 #define cimg_for4Y(img,y) cimg_for4((img).height,y)
00565 #define cimg_for4Z(img,z) cimg_for4((img).depth,z)
00566 #define cimg_for4V(img,v) cimg_for4((img).dim,v)
00567 #define cimg_for4XY(img,x,y) cimg_for4Y(img,y) cimg_for4X(img,x)
00568 #define cimg_for4XZ(img,x,z) cimg_for4Z(img,z) cimg_for4X(img,x)
00569 #define cimg_for4XV(img,x,v) cimg_for4V(img,v) cimg_for4X(img,x)
00570 #define cimg_for4YZ(img,y,z) cimg_for4Z(img,z) cimg_for4Y(img,y)
00571 #define cimg_for4YV(img,y,v) cimg_for4V(img,v) cimg_for4Y(img,y)
00572 #define cimg_for4ZV(img,z,v) cimg_for4V(img,v) cimg_for4Z(img,z)
00573 #define cimg_for4XYZ(img,x,y,z) cimg_for4Z(img,z) cimg_for4XY(img,x,y)
00574 #define cimg_for4XZV(img,x,z,v) cimg_for4V(img,v) cimg_for4XZ(img,x,z)
00575 #define cimg_for4YZV(img,y,z,v) cimg_for4V(img,v) cimg_for4YZ(img,y,z)
00576 #define cimg_for4XYZV(img,x,y,z,v) cimg_for4V(img,v) cimg_for4XYZ(img,x,y,z)
00577
00578 #define cimg_for_in4(bound,i0,i1,i) \
00579 for (int i = (int)(i0)<0?0:(int)(i0), \
00580 _p1##i = i-1<0?0:i-1, \
00581 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
00582 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2; \
00583 i<=(int)(i1) && (_n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i)); \
00584 _p1##i = i++, ++_n1##i, ++_n2##i)
00585 #define cimg_for_in4X(img,x0,x1,x) cimg_for_in4((img).width,x0,x1,x)
00586 #define cimg_for_in4Y(img,y0,y1,y) cimg_for_in4((img).height,y0,y1,y)
00587 #define cimg_for_in4Z(img,z0,z1,z) cimg_for_in4((img).depth,z0,z1,z)
00588 #define cimg_for_in4V(img,v0,v1,v) cimg_for_in4((img).dim,v0,v1,v)
00589 #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)
00590 #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)
00591 #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)
00592 #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)
00593 #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)
00594 #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)
00595 #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)
00596 #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)
00597 #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)
00598 #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)
00599
00600 #define cimg_for5(bound,i) \
00601 for (int i = 0, _p2##i = 0, _p1##i = 0, \
00602 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
00603 _n2##i = 2>=(bound)?(int)(bound)-1:2; \
00604 _n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i); \
00605 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i)
00606 #define cimg_for5X(img,x) cimg_for5((img).width,x)
00607 #define cimg_for5Y(img,y) cimg_for5((img).height,y)
00608 #define cimg_for5Z(img,z) cimg_for5((img).depth,z)
00609 #define cimg_for5V(img,v) cimg_for5((img).dim,v)
00610 #define cimg_for5XY(img,x,y) cimg_for5Y(img,y) cimg_for5X(img,x)
00611 #define cimg_for5XZ(img,x,z) cimg_for5Z(img,z) cimg_for5X(img,x)
00612 #define cimg_for5XV(img,x,v) cimg_for5V(img,v) cimg_for5X(img,x)
00613 #define cimg_for5YZ(img,y,z) cimg_for5Z(img,z) cimg_for5Y(img,y)
00614 #define cimg_for5YV(img,y,v) cimg_for5V(img,v) cimg_for5Y(img,y)
00615 #define cimg_for5ZV(img,z,v) cimg_for5V(img,v) cimg_for5Z(img,z)
00616 #define cimg_for5XYZ(img,x,y,z) cimg_for5Z(img,z) cimg_for5XY(img,x,y)
00617 #define cimg_for5XZV(img,x,z,v) cimg_for5V(img,v) cimg_for5XZ(img,x,z)
00618 #define cimg_for5YZV(img,y,z,v) cimg_for5V(img,v) cimg_for5YZ(img,y,z)
00619 #define cimg_for5XYZV(img,x,y,z,v) cimg_for5V(img,v) cimg_for5XYZ(img,x,y,z)
00620
00621 #define cimg_for_in5(bound,i0,i1,i) \
00622 for (int i = (int)(i0)<0?0:(int)(i0), \
00623 _p2##i = i-2<0?0:i-2, \
00624 _p1##i = i-1<0?0:i-1, \
00625 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
00626 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2; \
00627 i<=(int)(i1) && (_n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i)); \
00628 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i)
00629 #define cimg_for_in5X(img,x0,x1,x) cimg_for_in5((img).width,x0,x1,x)
00630 #define cimg_for_in5Y(img,y0,y1,y) cimg_for_in5((img).height,y0,y1,y)
00631 #define cimg_for_in5Z(img,z0,z1,z) cimg_for_in5((img).depth,z0,z1,z)
00632 #define cimg_for_in5V(img,v0,v1,v) cimg_for_in5((img).dim,v0,v1,v)
00633 #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)
00634 #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)
00635 #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)
00636 #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)
00637 #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)
00638 #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)
00639 #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)
00640 #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)
00641 #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)
00642 #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)
00643
00644 #define cimg_for6(bound,i) \
00645 for (int i = 0, _p2##i = 0, _p1##i = 0, \
00646 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
00647 _n2##i = 2>=(bound)?(int)(bound)-1:2, \
00648 _n3##i = 3>=(bound)?(int)(bound)-1:3; \
00649 _n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i); \
00650 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
00651 #define cimg_for6X(img,x) cimg_for6((img).width,x)
00652 #define cimg_for6Y(img,y) cimg_for6((img).height,y)
00653 #define cimg_for6Z(img,z) cimg_for6((img).depth,z)
00654 #define cimg_for6V(img,v) cimg_for6((img).dim,v)
00655 #define cimg_for6XY(img,x,y) cimg_for6Y(img,y) cimg_for6X(img,x)
00656 #define cimg_for6XZ(img,x,z) cimg_for6Z(img,z) cimg_for6X(img,x)
00657 #define cimg_for6XV(img,x,v) cimg_for6V(img,v) cimg_for6X(img,x)
00658 #define cimg_for6YZ(img,y,z) cimg_for6Z(img,z) cimg_for6Y(img,y)
00659 #define cimg_for6YV(img,y,v) cimg_for6V(img,v) cimg_for6Y(img,y)
00660 #define cimg_for6ZV(img,z,v) cimg_for6V(img,v) cimg_for6Z(img,z)
00661 #define cimg_for6XYZ(img,x,y,z) cimg_for6Z(img,z) cimg_for6XY(img,x,y)
00662 #define cimg_for6XZV(img,x,z,v) cimg_for6V(img,v) cimg_for6XZ(img,x,z)
00663 #define cimg_for6YZV(img,y,z,v) cimg_for6V(img,v) cimg_for6YZ(img,y,z)
00664 #define cimg_for6XYZV(img,x,y,z,v) cimg_for6V(img,v) cimg_for6XYZ(img,x,y,z)
00665
00666 #define cimg_for_in6(bound,i0,i1,i) \
00667 for (int i = (int)(i0)<0?0:(int)(i0), \
00668 _p2##i = i-2<0?0:i-2, \
00669 _p1##i = i-1<0?0:i-1, \
00670 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
00671 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2, \
00672 _n3##i = i+3>=(int)(bound)?(int)(bound)-1:i+3; \
00673 i<=(int)(i1) && (_n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i)); \
00674 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
00675 #define cimg_for_in6X(img,x0,x1,x) cimg_for_in6((img).width,x0,x1,x)
00676 #define cimg_for_in6Y(img,y0,y1,y) cimg_for_in6((img).height,y0,y1,y)
00677 #define cimg_for_in6Z(img,z0,z1,z) cimg_for_in6((img).depth,z0,z1,z)
00678 #define cimg_for_in6V(img,v0,v1,v) cimg_for_in6((img).dim,v0,v1,v)
00679 #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)
00680 #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)
00681 #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)
00682 #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)
00683 #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)
00684 #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)
00685 #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)
00686 #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)
00687 #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)
00688 #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)
00689
00690 #define cimg_for7(bound,i) \
00691 for (int i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \
00692 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
00693 _n2##i = 2>=(bound)?(int)(bound)-1:2, \
00694 _n3##i = 3>=(bound)?(int)(bound)-1:3; \
00695 _n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i); \
00696 _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
00697 #define cimg_for7X(img,x) cimg_for7((img).width,x)
00698 #define cimg_for7Y(img,y) cimg_for7((img).height,y)
00699 #define cimg_for7Z(img,z) cimg_for7((img).depth,z)
00700 #define cimg_for7V(img,v) cimg_for7((img).dim,v)
00701 #define cimg_for7XY(img,x,y) cimg_for7Y(img,y) cimg_for7X(img,x)
00702 #define cimg_for7XZ(img,x,z) cimg_for7Z(img,z) cimg_for7X(img,x)
00703 #define cimg_for7XV(img,x,v) cimg_for7V(img,v) cimg_for7X(img,x)
00704 #define cimg_for7YZ(img,y,z) cimg_for7Z(img,z) cimg_for7Y(img,y)
00705 #define cimg_for7YV(img,y,v) cimg_for7V(img,v) cimg_for7Y(img,y)
00706 #define cimg_for7ZV(img,z,v) cimg_for7V(img,v) cimg_for7Z(img,z)
00707 #define cimg_for7XYZ(img,x,y,z) cimg_for7Z(img,z) cimg_for7XY(img,x,y)
00708 #define cimg_for7XZV(img,x,z,v) cimg_for7V(img,v) cimg_for7XZ(img,x,z)
00709 #define cimg_for7YZV(img,y,z,v) cimg_for7V(img,v) cimg_for7YZ(img,y,z)
00710 #define cimg_for7XYZV(img,x,y,z,v) cimg_for7V(img,v) cimg_for7XYZ(img,x,y,z)
00711
00712 #define cimg_for_in7(bound,i0,i1,i) \
00713 for (int i = (int)(i0)<0?0:(int)(i0), \
00714 _p3##i = i-3<0?0:i-3, \
00715 _p2##i = i-2<0?0:i-2, \
00716 _p1##i = i-1<0?0:i-1, \
00717 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
00718 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2, \
00719 _n3##i = i+3>=(int)(bound)?(int)(bound)-1:i+3; \
00720 i<=(int)(i1) && (_n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i)); \
00721 _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
00722 #define cimg_for_in7X(img,x0,x1,x) cimg_for_in7((img).width,x0,x1,x)
00723 #define cimg_for_in7Y(img,y0,y1,y) cimg_for_in7((img).height,y0,y1,y)
00724 #define cimg_for_in7Z(img,z0,z1,z) cimg_for_in7((img).depth,z0,z1,z)
00725 #define cimg_for_in7V(img,v0,v1,v) cimg_for_in7((img).dim,v0,v1,v)
00726 #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)
00727 #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)
00728 #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)
00729 #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)
00730 #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)
00731 #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)
00732 #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)
00733 #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)
00734 #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)
00735 #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)
00736
00737 #define cimg_for2x2(img,x,y,z,v,I) \
00738 cimg_for2((img).height,y) for (int x = 0, \
00739 _n1##x = (int)( \
00740 (I[0] = (img)(0,y,z,v)), \
00741 (I[2] = (img)(0,_n1##y,z,v)), \
00742 1>=(img).width?(int)((img).width)-1:1); \
00743 (_n1##x<(int)((img).width) && ( \
00744 (I[1] = (img)(_n1##x,y,z,v)), \
00745 (I[3] = (img)(_n1##x,_n1##y,z,v)),1)) || \
00746 x==--_n1##x; \
00747 I[0] = I[1], \
00748 I[2] = I[3], \
00749 ++x, ++_n1##x)
00750
00751 #define cimg_for_in2x2(img,x0,y0,x1,y1,x,y,z,v,I) \
00752 cimg_for_in2((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
00753 _n1##x = (int)( \
00754 (I[0] = (img)(x,y,z,v)), \
00755 (I[2] = (img)(x,_n1##y,z,v)), \
00756 x+1>=(int)(img).width?(int)((img).width)-1:x+1); \
00757 x<=(int)(x1) && ((_n1##x<(int)((img).width) && ( \
00758 (I[1] = (img)(_n1##x,y,z,v)), \
00759 (I[3] = (img)(_n1##x,_n1##y,z,v)),1)) || \
00760 x==--_n1##x); \
00761 I[0] = I[1], \
00762 I[2] = I[3], \
00763 ++x, ++_n1##x)
00764
00765 #define cimg_for3x3(img,x,y,z,v,I) \
00766 cimg_for3((img).height,y) for (int x = 0, \
00767 _p1##x = 0, \
00768 _n1##x = (int)( \
00769 (I[0] = I[1] = (img)(0,_p1##y,z,v)), \
00770 (I[3] = I[4] = (img)(0,y,z,v)), \
00771 (I[6] = I[7] = (img)(0,_n1##y,z,v)), \
00772 1>=(img).width?(int)((img).width)-1:1); \
00773 (_n1##x<(int)((img).width) && ( \
00774 (I[2] = (img)(_n1##x,_p1##y,z,v)), \
00775 (I[5] = (img)(_n1##x,y,z,v)), \
00776 (I[8] = (img)(_n1##x,_n1##y,z,v)),1)) || \
00777 x==--_n1##x; \
00778 I[0] = I[1], I[1] = I[2], \
00779 I[3] = I[4], I[4] = I[5], \
00780 I[6] = I[7], I[7] = I[8], \
00781 _p1##x = x++, ++_n1##x)
00782
00783 #define cimg_for_in3x3(img,x0,y0,x1,y1,x,y,z,v,I) \
00784 cimg_for_in3((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
00785 _p1##x = x-1<0?0:x-1, \
00786 _n1##x = (int)( \
00787 (I[0] = (img)(_p1##x,_p1##y,z,v)), \
00788 (I[3] = (img)(_p1##x,y,z,v)), \
00789 (I[6] = (img)(_p1##x,_n1##y,z,v)), \
00790 (I[1] = (img)(x,_p1##y,z,v)), \
00791 (I[4] = (img)(x,y,z,v)), \
00792 (I[7] = (img)(x,_n1##y,z,v)), \
00793 x+1>=(int)(img).width?(int)((img).width)-1:x+1); \
00794 x<=(int)(x1) && ((_n1##x<(int)((img).width) && ( \
00795 (I[2] = (img)(_n1##x,_p1##y,z,v)), \
00796 (I[5] = (img)(_n1##x,y,z,v)), \
00797 (I[8] = (img)(_n1##x,_n1##y,z,v)),1)) || \
00798 x==--_n1##x); \
00799 I[0] = I[1], I[1] = I[2], \
00800 I[3] = I[4], I[4] = I[5], \
00801 I[6] = I[7], I[7] = I[8], \
00802 _p1##x = x++, ++_n1##x)
00803
00804 #define cimg_for4x4(img,x,y,z,v,I) \
00805 cimg_for4((img).height,y) for (int x = 0, \
00806 _p1##x = 0, \
00807 _n1##x = 1>=(img).width?(int)((img).width)-1:1, \
00808 _n2##x = (int)( \
00809 (I[0] = I[1] = (img)(0,_p1##y,z,v)), \
00810 (I[4] = I[5] = (img)(0,y,z,v)), \
00811 (I[8] = I[9] = (img)(0,_n1##y,z,v)), \
00812 (I[12] = I[13] = (img)(0,_n2##y,z,v)), \
00813 (I[2] = (img)(_n1##x,_p1##y,z,v)), \
00814 (I[6] = (img)(_n1##x,y,z,v)), \
00815 (I[10] = (img)(_n1##x,_n1##y,z,v)), \
00816 (I[14] = (img)(_n1##x,_n2##y,z,v)), \
00817 2>=(img).width?(int)((img).width)-1:2); \
00818 (_n2##x<(int)((img).width) && ( \
00819 (I[3] = (img)(_n2##x,_p1##y,z,v)), \
00820 (I[7] = (img)(_n2##x,y,z,v)), \
00821 (I[11] = (img)(_n2##x,_n1##y,z,v)), \
00822 (I[15] = (img)(_n2##x,_n2##y,z,v)),1)) || \
00823 _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \
00824 I[0] = I[1], I[1] = I[2], I[2] = I[3], \
00825 I[4] = I[5], I[5] = I[6], I[6] = I[7], \
00826 I[8] = I[9], I[9] = I[10], I[10] = I[11], \
00827 I[12] = I[13], I[13] = I[14], I[14] = I[15], \
00828 _p1##x = x++, ++_n1##x, ++_n2##x)
00829
00830 #define cimg_for_in4x4(img,x0,y0,x1,y1,x,y,z,v,I) \
00831 cimg_for_in4((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
00832 _p1##x = x-1<0?0:x-1, \
00833 _n1##x = x+1>=(int)(img).width?(int)((img).width)-1:x+1, \
00834 _n2##x = (int)( \
00835 (I[0] = (img)(_p1##x,_p1##y,z,v)), \
00836 (I[4] = (img)(_p1##x,y,z,v)), \
00837 (I[8] = (img)(_p1##x,_n1##y,z,v)), \
00838 (I[12] = (img)(_p1##x,_n2##y,z,v)), \
00839 (I[1] = (img)(x,_p1##y,z,v)), \
00840 (I[5] = (img)(x,y,z,v)), \
00841 (I[9] = (img)(x,_n1##y,z,v)), \
00842 (I[13] = (img)(x,_n2##y,z,v)), \
00843 (I[2] = (img)(_n1##x,_p1##y,z,v)), \
00844 (I[6] = (img)(_n1##x,y,z,v)), \
00845 (I[10] = (img)(_n1##x,_n1##y,z,v)), \
00846 (I[14] = (img)(_n1##x,_n2##y,z,v)), \
00847 x+2>=(int)(img).width?(int)((img).width)-1:x+2); \
00848 x<=(int)(x1) && ((_n2##x<(int)((img).width) && ( \
00849 (I[3] = (img)(_n2##x,_p1##y,z,v)), \
00850 (I[7] = (img)(_n2##x,y,z,v)), \
00851 (I[11] = (img)(_n2##x,_n1##y,z,v)), \
00852 (I[15] = (img)(_n2##x,_n2##y,z,v)),1)) || \
00853 _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \
00854 I[0] = I[1], I[1] = I[2], I[2] = I[3], \
00855 I[4] = I[5], I[5] = I[6], I[6] = I[7], \
00856 I[8] = I[9], I[9] = I[10], I[10] = I[11], \
00857 I[12] = I[13], I[13] = I[14], I[14] = I[15], \
00858 _p1##x = x++, ++_n1##x, ++_n2##x)
00859
00860 #define cimg_for5x5(img,x,y,z,v,I) \
00861 cimg_for5((img).height,y) for (int x = 0, \
00862 _p2##x = 0, _p1##x = 0, \
00863 _n1##x = 1>=(img).width?(int)((img).width)-1:1, \
00864 _n2##x = (int)( \
00865 (I[0] = I[1] = I[2] = (img)(0,_p2##y,z,v)), \
00866 (I[5] = I[6] = I[7] = (img)(0,_p1##y,z,v)), \
00867 (I[10] = I[11] = I[12] = (img)(0,y,z,v)), \
00868 (I[15] = I[16] = I[17] = (img)(0,_n1##y,z,v)), \
00869 (I[20] = I[21] = I[22] = (img)(0,_n2##y,z,v)), \
00870 (I[3] = (img)(_n1##x,_p2##y,z,v)), \
00871 (I[8] = (img)(_n1##x,_p1##y,z,v)), \
00872 (I[13] = (img)(_n1##x,y,z,v)), \
00873 (I[18] = (img)(_n1##x,_n1##y,z,v)), \
00874 (I[23] = (img)(_n1##x,_n2##y,z,v)), \
00875 2>=(img).width?(int)((img).width)-1:2); \
00876 (_n2##x<(int)((img).width) && ( \
00877 (I[4] = (img)(_n2##x,_p2##y,z,v)), \
00878 (I[9] = (img)(_n2##x,_p1##y,z,v)), \
00879 (I[14] = (img)(_n2##x,y,z,v)), \
00880 (I[19] = (img)(_n2##x,_n1##y,z,v)), \
00881 (I[24] = (img)(_n2##x,_n2##y,z,v)),1)) || \
00882 _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \
00883 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \
00884 I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \
00885 I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \
00886 I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \
00887 I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \
00888 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x)
00889
00890 #define cimg_for_in5x5(img,x0,y0,x1,y1,x,y,z,v,I) \
00891 cimg_for_in5((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
00892 _p2##x = x-2<0?0:x-2, \
00893 _p1##x = x-1<0?0:x-1, \
00894 _n1##x = x+1>=(int)(img).width?(int)((img).width)-1:x+1, \
00895 _n2##x = (int)( \
00896 (I[0] = (img)(_p2##x,_p2##y,z,v)), \
00897 (I[5] = (img)(_p2##x,_p1##y,z,v)), \
00898 (I[10] = (img)(_p2##x,y,z,v)), \
00899 (I[15] = (img)(_p2##x,_n1##y,z,v)), \
00900 (I[20] = (img)(_p2##x,_n2##y,z,v)), \
00901 (I[1] = (img)(_p1##x,_p2##y,z,v)), \
00902 (I[6] = (img)(_p1##x,_p1##y,z,v)), \
00903 (I[11] = (img)(_p1##x,y,z,v)), \
00904 (I[16] = (img)(_p1##x,_n1##y,z,v)), \
00905 (I[21] = (img)(_p1##x,_n2##y,z,v)), \
00906 (I[2] = (img)(x,_p2##y,z,v)), \
00907 (I[7] = (img)(x,_p1##y,z,v)), \
00908 (I[12] = (img)(x,y,z,v)), \
00909 (I[17] = (img)(x,_n1##y,z,v)), \
00910 (I[22] = (img)(x,_n2##y,z,v)), \
00911 (I[3] = (img)(_n1##x,_p2##y,z,v)), \
00912 (I[8] = (img)(_n1##x,_p1##y,z,v)), \
00913 (I[13] = (img)(_n1##x,y,z,v)), \
00914 (I[18] = (img)(_n1##x,_n1##y,z,v)), \
00915 (I[23] = (img)(_n1##x,_n2##y,z,v)), \
00916 x+2>=(int)(img).width?(int)((img).width)-1:x+2); \
00917 x<=(int)(x1) && ((_n2##x<(int)((img).width) && ( \
00918 (I[4] = (img)(_n2##x,_p2##y,z,v)), \
00919 (I[9] = (img)(_n2##x,_p1##y,z,v)), \
00920 (I[14] = (img)(_n2##x,y,z,v)), \
00921 (I[19] = (img)(_n2##x,_n1##y,z,v)), \
00922 (I[24] = (img)(_n2##x,_n2##y,z,v)),1)) || \
00923 _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \
00924 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \
00925 I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \
00926 I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \
00927 I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \
00928 I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \
00929 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x)
00930
00931 #define cimg_for6x6(img,x,y,z,v,I) \
00932 cimg_for6((img).height,y) for (int x = 0, \
00933 _p2##x = 0, _p1##x = 0, \
00934 _n1##x = 1>=(img).width?(int)((img).width)-1:1, \
00935 _n2##x = 2>=(img).width?(int)((img).width)-1:2, \
00936 _n3##x = (int)( \
00937 (I[0] = I[1] = I[2] = (img)(0,_p2##y,z,v)), \
00938 (I[6] = I[7] = I[8] = (img)(0,_p1##y,z,v)), \
00939 (I[12] = I[13] = I[14] = (img)(0,y,z,v)), \
00940 (I[18] = I[19] = I[20] = (img)(0,_n1##y,z,v)), \
00941 (I[24] = I[25] = I[26] = (img)(0,_n2##y,z,v)), \
00942 (I[30] = I[31] = I[32] = (img)(0,_n3##y,z,v)), \
00943 (I[3] = (img)(_n1##x,_p2##y,z,v)), \
00944 (I[9] = (img)(_n1##x,_p1##y,z,v)), \
00945 (I[15] = (img)(_n1##x,y,z,v)), \
00946 (I[21] = (img)(_n1##x,_n1##y,z,v)), \
00947 (I[27] = (img)(_n1##x,_n2##y,z,v)), \
00948 (I[33] = (img)(_n1##x,_n3##y,z,v)), \
00949 (I[4] = (img)(_n2##x,_p2##y,z,v)), \
00950 (I[10] = (img)(_n2##x,_p1##y,z,v)), \
00951 (I[16] = (img)(_n2##x,y,z,v)), \
00952 (I[22] = (img)(_n2##x,_n1##y,z,v)), \
00953 (I[28] = (img)(_n2##x,_n2##y,z,v)), \
00954 (I[34] = (img)(_n2##x,_n3##y,z,v)), \
00955 3>=(img).width?(int)((img).width)-1:3); \
00956 (_n3##x<(int)((img).width) && ( \
00957 (I[5] = (img)(_n3##x,_p2##y,z,v)), \
00958 (I[11] = (img)(_n3##x,_p1##y,z,v)), \
00959 (I[17] = (img)(_n3##x,y,z,v)), \
00960 (I[23] = (img)(_n3##x,_n1##y,z,v)), \
00961 (I[29] = (img)(_n3##x,_n2##y,z,v)), \
00962 (I[35] = (img)(_n3##x,_n3##y,z,v)),1)) || \
00963 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3## x = _n2##x = --_n1##x); \
00964 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \
00965 I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \
00966 I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \
00967 I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \
00968 I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \
00969 I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \
00970 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
00971
00972 #define cimg_for_in6x6(img,x0,y0,x1,y1,x,y,z,v,I) \
00973 cimg_for_in6((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)x0, \
00974 _p2##x = x-2<0?0:x-2, \
00975 _p1##x = x-1<0?0:x-1, \
00976 _n1##x = x+1>=(int)(img).width?(int)((img).width)-1:x+1, \
00977 _n2##x = x+2>=(int)(img).width?(int)((img).width)-1:x+2, \
00978 _n3##x = (int)( \
00979 (I[0] = (img)(_p2##x,_p2##y,z,v)), \
00980 (I[6] = (img)(_p2##x,_p1##y,z,v)), \
00981 (I[12] = (img)(_p2##x,y,z,v)), \
00982 (I[18] = (img)(_p2##x,_n1##y,z,v)), \
00983 (I[24] = (img)(_p2##x,_n2##y,z,v)), \
00984 (I[30] = (img)(_p2##x,_n3##y,z,v)), \
00985 (I[1] = (img)(_p1##x,_p2##y,z,v)), \
00986 (I[7] = (img)(_p1##x,_p1##y,z,v)), \
00987 (I[13] = (img)(_p1##x,y,z,v)), \
00988 (I[19] = (img)(_p1##x,_n1##y,z,v)), \
00989 (I[25] = (img)(_p1##x,_n2##y,z,v)), \
00990 (I[31] = (img)(_p1##x,_n3##y,z,v)), \
00991 (I[2] = (img)(x,_p2##y,z,v)), \
00992 (I[8] = (img)(x,_p1##y,z,v)), \
00993 (I[14] = (img)(x,y,z,v)), \
00994 (I[20] = (img)(x,_n1##y,z,v)), \
00995 (I[26] = (img)(x,_n2##y,z,v)), \
00996 (I[32] = (img)(x,_n3##y,z,v)), \
00997 (I[3] = (img)(_n1##x,_p2##y,z,v)), \
00998 (I[9] = (img)(_n1##x,_p1##y,z,v)), \
00999 (I[15] = (img)(_n1##x,y,z,v)), \
01000 (I[21] = (img)(_n1##x,_n1##y,z,v)), \
01001 (I[27] = (img)(_n1##x,_n2##y,z,v)), \
01002 (I[33] = (img)(_n1##x,_n3##y,z,v)), \
01003 (I[4] = (img)(_n2##x,_p2##y,z,v)), \
01004 (I[10] = (img)(_n2##x,_p1##y,z,v)), \
01005 (I[16] = (img)(_n2##x,y,z,v)), \
01006 (I[22] = (img)(_n2##x,_n1##y,z,v)), \
01007 (I[28] = (img)(_n2##x,_n2##y,z,v)), \
01008 (I[34] = (img)(_n2##x,_n3##y,z,v)), \
01009 x+3>=(int)(img).width?(int)((img).width)-1:x+3); \
01010 x<=(int)(x1) && ((_n3##x<(int)((img).width) && ( \
01011 (I[5] = (img)(_n3##x,_p2##y,z,v)), \
01012 (I[11] = (img)(_n3##x,_p1##y,z,v)), \
01013 (I[17] = (img)(_n3##x,y,z,v)), \
01014 (I[23] = (img)(_n3##x,_n1##y,z,v)), \
01015 (I[29] = (img)(_n3##x,_n2##y,z,v)), \
01016 (I[35] = (img)(_n3##x,_n3##y,z,v)),1)) || \
01017 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3## x = _n2##x = --_n1##x)); \
01018 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \
01019 I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \
01020 I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \
01021 I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \
01022 I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \
01023 I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \
01024 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
01025
01026 #define cimg_for7x7(img,x,y,z,v,I) \
01027 cimg_for7((img).height,y) for (int x = 0, \
01028 _p3##x = 0, _p2##x = 0, _p1##x = 0, \
01029 _n1##x = 1>=(img).width?(int)((img).width)-1:1, \
01030 _n2##x = 2>=(img).width?(int)((img).width)-1:2, \
01031 _n3##x = (int)( \
01032 (I[0] = I[1] = I[2] = I[3] = (img)(0,_p3##y,z,v)), \
01033 (I[7] = I[8] = I[9] = I[10] = (img)(0,_p2##y,z,v)), \
01034 (I[14] = I[15] = I[16] = I[17] = (img)(0,_p1##y,z,v)), \
01035 (I[21] = I[22] = I[23] = I[24] = (img)(0,y,z,v)), \
01036 (I[28] = I[29] = I[30] = I[31] = (img)(0,_n1##y,z,v)), \
01037 (I[35] = I[36] = I[37] = I[38] = (img)(0,_n2##y,z,v)), \
01038 (I[42] = I[43] = I[44] = I[45] = (img)(0,_n3##y,z,v)), \
01039 (I[4] = (img)(_n1##x,_p3##y,z,v)), \
01040 (I[11] = (img)(_n1##x,_p2##y,z,v)), \
01041 (I[18] = (img)(_n1##x,_p1##y,z,v)), \
01042 (I[25] = (img)(_n1##x,y,z,v)), \
01043 (I[32] = (img)(_n1##x,_n1##y,z,v)), \
01044 (I[39] = (img)(_n1##x,_n2##y,z,v)), \
01045 (I[46] = (img)(_n1##x,_n3##y,z,v)), \
01046 (I[5] = (img)(_n2##x,_p3##y,z,v)), \
01047 (I[12] = (img)(_n2##x,_p2##y,z,v)), \
01048 (I[19] = (img)(_n2##x,_p1##y,z,v)), \
01049 (I[26] = (img)(_n2##x,y,z,v)), \
01050 (I[33] = (img)(_n2##x,_n1##y,z,v)), \
01051 (I[40] = (img)(_n2##x,_n2##y,z,v)), \
01052 (I[47] = (img)(_n2##x,_n3##y,z,v)), \
01053 3>=(img).width?(int)((img).width)-1:3); \
01054 (_n3##x<(int)((img).width) && ( \
01055 (I[6] = (img)(_n3##x,_p3##y,z,v)), \
01056 (I[13] = (img)(_n3##x,_p2##y,z,v)), \
01057 (I[20] = (img)(_n3##x,_p1##y,z,v)), \
01058 (I[27] = (img)(_n3##x,y,z,v)), \
01059 (I[34] = (img)(_n3##x,_n1##y,z,v)), \
01060 (I[41] = (img)(_n3##x,_n2##y,z,v)), \
01061 (I[48] = (img)(_n3##x,_n3##y,z,v)),1)) || \
01062 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x); \
01063 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \
01064 I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \
01065 I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \
01066 I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \
01067 I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \
01068 I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \
01069 I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \
01070 _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
01071
01072 #define cimg_for_in7x7(img,x0,y0,x1,y1,x,y,z,v,I) \
01073 cimg_for_in7((img).height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
01074 _p3##x = x-3<0?0:x-3, \
01075 _p2##x = x-2<0?0:x-2, \
01076 _p1##x = x-1<0?0:x-1, \
01077 _n1##x = x+1>=(int)(img).width?(int)((img).width)-1:x+1, \
01078 _n2##x = x+2>=(int)(img).width?(int)((img).width)-1:x+2, \
01079 _n3##x = (int)( \
01080 (I[0] = (img)(_p3##x,_p3##y,z,v)), \
01081 (I[7] = (img)(_p3##x,_p2##y,z,v)), \
01082 (I[14] = (img)(_p3##x,_p1##y,z,v)), \
01083 (I[21] = (img)(_p3##x,y,z,v)), \
01084 (I[28] = (img)(_p3##x,_n1##y,z,v)), \
01085 (I[35] = (img)(_p3##x,_n2##y,z,v)), \
01086 (I[42] = (img)(_p3##x,_n3##y,z,v)), \
01087 (I[1] = (img)(_p2##x,_p3##y,z,v)), \
01088 (I[8] = (img)(_p2##x,_p2##y,z,v)), \
01089 (I[15] = (img)(_p2##x,_p1##y,z,v)), \
01090 (I[22] = (img)(_p2##x,y,z,v)), \
01091 (I[29] = (img)(_p2##x,_n1##y,z,v)), \
01092 (I[36] = (img)(_p2##x,_n2##y,z,v)), \
01093 (I[43] = (img)(_p2##x,_n3##y,z,v)), \
01094 (I[2] = (img)(_p1##x,_p3##y,z,v)), \
01095 (I[9] = (img)(_p1##x,_p2##y,z,v)), \
01096 (I[16] = (img)(_p1##x,_p1##y,z,v)), \
01097 (I[23] = (img)(_p1##x,y,z,v)), \
01098 (I[30] = (img)(_p1##x,_n1##y,z,v)), \
01099 (I[37] = (img)(_p1##x,_n2##y,z,v)), \
01100 (I[44] = (img)(_p1##x,_n3##y,z,v)), \
01101 (I[3] = (img)(x,_p3##y,z,v)), \
01102 (I[10] = (img)(x,_p2##y,z,v)), \
01103 (I[17] = (img)(x,_p1##y,z,v)), \
01104 (I[24] = (img)(x,y,z,v)), \
01105 (I[31] = (img)(x,_n1##y,z,v)), \
01106 (I[38] = (img)(x,_n2##y,z,v)), \
01107 (I[45] = (img)(x,_n3##y,z,v)), \
01108 (I[4] = (img)(_n1##x,_p3##y,z,v)), \
01109 (I[11] = (img)(_n1##x,_p2##y,z,v)), \
01110 (I[18] = (img)(_n1##x,_p1##y,z,v)), \
01111 (I[25] = (img)(_n1##x,y,z,v)), \
01112 (I[32] = (img)(_n1##x,_n1##y,z,v)), \
01113 (I[39] = (img)(_n1##x,_n2##y,z,v)), \
01114 (I[46] = (img)(_n1##x,_n3##y,z,v)), \
01115 (I[5] = (img)(_n2##x,_p3##y,z,v)), \
01116 (I[12] = (img)(_n2##x,_p2##y,z,v)), \
01117 (I[19] = (img)(_n2##x,_p1##y,z,v)), \
01118 (I[26] = (img)(_n2##x,y,z,v)), \
01119 (I[33] = (img)(_n2##x,_n1##y,z,v)), \
01120 (I[40] = (img)(_n2##x,_n2##y,z,v)), \
01121 (I[47] = (img)(_n2##x,_n3##y,z,v)), \
01122 x+3>=(int)(img).width?(int)((img).width)-1:x+3); \
01123 x<=(int)(x1) && ((_n3##x<(int)((img).width) && ( \
01124 (I[6] = (img)(_n3##x,_p3##y,z,v)), \
01125 (I[13] = (img)(_n3##x,_p2##y,z,v)), \
01126 (I[20] = (img)(_n3##x,_p1##y,z,v)), \
01127 (I[27] = (img)(_n3##x,y,z,v)), \
01128 (I[34] = (img)(_n3##x,_n1##y,z,v)), \
01129 (I[41] = (img)(_n3##x,_n2##y,z,v)), \
01130 (I[48] = (img)(_n3##x,_n3##y,z,v)),1)) || \
01131 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x)); \
01132 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \
01133 I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \
01134 I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \
01135 I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \
01136 I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \
01137 I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \
01138 I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \
01139 _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
01140
01141 #define cimg_for2x2x2(img,x,y,z,v,I) \
01142 cimg_for2((img).depth,z) cimg_for2((img).height,y) for (int x = 0, \
01143 _n1##x = (int)( \
01144 (I[0] = (img)(0,y,z,v)), \
01145 (I[2] = (img)(0,_n1##y,z,v)), \
01146 (I[4] = (img)(0,y,_n1##z,v)), \
01147 (I[6] = (img)(0,_n1##y,_n1##z,v)), \
01148 1>=(img).width?(int)((img).width)-1:1); \
01149 (_n1##x<(int)((img).width) && ( \
01150 (I[1] = (img)(_n1##x,y,z,v)), \
01151 (I[3] = (img)(_n1##x,_n1##y,z,v)), \
01152 (I[5] = (img)(_n1##x,y,_n1##z,v)), \
01153 (I[7] = (img)(_n1##x,_n1##y,_n1##z,v)),1)) || \
01154 x==--_n1##x; \
01155 I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], \
01156 ++x, ++_n1##x)
01157
01158 #define cimg_for_in2x2x2(img,x0,y0,z0,x1,y1,z1,x,y,z,v,I) \
01159 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), \
01160 _n1##x = (int)( \
01161 (I[0] = (img)(x,y,z,v)), \
01162 (I[2] = (img)(x,_n1##y,z,v)), \
01163 (I[4] = (img)(x,y,_n1##z,v)), \
01164 (I[6] = (img)(x,_n1##y,_n1##z,v)), \
01165 x+1>=(int)(img).width?(int)((img).width)-1:x+1); \
01166 x<=(int)(x1) && ((_n1##x<(int)((img).width) && ( \
01167 (I[1] = (img)(_n1##x,y,z,v)), \
01168 (I[3] = (img)(_n1##x,_n1##y,z,v)), \
01169 (I[5] = (img)(_n1##x,y,_n1##z,v)), \
01170 (I[7] = (img)(_n1##x,_n1##y,_n1##z,v)),1)) || \
01171 x==--_n1##x); \
01172 I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], \
01173 ++x, ++_n1##x)
01174
01175 #define cimg_for3x3x3(img,x,y,z,v,I) \
01176 cimg_for3((img).depth,z) cimg_for3((img).height,y) for (int x = 0, \
01177 _p1##x = 0, \
01178 _n1##x = (int)( \
01179 (I[0] = I[1] = (img)(0,_p1##y,_p1##z,v)), \
01180 (I[3] = I[4] = (img)(0,y,_p1##z,v)), \
01181 (I[6] = I[7] = (img)(0,_n1##y,_p1##z,v)), \
01182 (I[9] = I[10] = (img)(0,_p1##y,z,v)), \
01183 (I[12] = I[13] = (img)(0,y,z,v)), \
01184 (I[15] = I[16] = (img)(0,_n1##y,z,v)), \
01185 (I[18] = I[19] = (img)(0,_p1##y,_n1##z,v)), \
01186 (I[21] = I[22] = (img)(0,y,_n1##z,v)), \
01187 (I[24] = I[25] = (img)(0,_n1##y,_n1##z,v)), \
01188 1>=(img).width?(int)((img).width)-1:1); \
01189 (_n1##x<(int)((img).width) && ( \
01190 (I[2] = (img)(_n1##x,_p1##y,_p1##z,v)), \
01191 (I[5] = (img)(_n1##x,y,_p1##z,v)), \
01192 (I[8] = (img)(_n1##x,_n1##y,_p1##z,v)), \
01193 (I[11] = (img)(_n1##x,_p1##y,z,v)), \
01194 (I[14] = (img)(_n1##x,y,z,v)), \
01195 (I[17] = (img)(_n1##x,_n1##y,z,v)), \
01196 (I[20] = (img)(_n1##x,_p1##y,_n1##z,v)), \
01197 (I[23] = (img)(_n1##x,y,_n1##z,v)), \
01198 (I[26] = (img)(_n1##x,_n1##y,_n1##z,v)),1)) || \
01199 x==--_n1##x; \
01200 I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], \
01201 I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], \
01202 I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], \
01203 _p1##x = x++, ++_n1##x)
01204
01205 #define cimg_for_in3x3x3(img,x0,y0,z0,x1,y1,z1,x,y,z,v,I) \
01206 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), \
01207 _p1##x = x-1<0?0:x-1, \
01208 _n1##x = (int)( \
01209 (I[0] = (img)(_p1##x,_p1##y,_p1##z,v)), \
01210 (I[3] = (img)(_p1##x,y,_p1##z,v)), \
01211 (I[6] = (img)(_p1##x,_n1##y,_p1##z,v)), \
01212 (I[9] = (img)(_p1##x,_p1##y,z,v)), \
01213 (I[12] = (img)(_p1##x,y,z,v)), \
01214 (I[15] = (img)(_p1##x,_n1##y,z,v)), \
01215 (I[18] = (img)(_p1##x,_p1##y,_n1##z,v)), \
01216 (I[21] = (img)(_p1##x,y,_n1##z,v)), \
01217 (I[24] = (img)(_p1##x,_n1##y,_n1##z,v)), \
01218 (I[1] = (img)(x,_p1##y,_p1##z,v)), \
01219 (I[4] = (img)(x,y,_p1##z,v)), \
01220 (I[7] = (img)(x,_n1##y,_p1##z,v)), \
01221 (I[10] = (img)(x,_p1##y,z,v)), \
01222 (I[13] = (img)(x,y,z,v)), \
01223 (I[16] = (img)(x,_n1##y,z,v)), \
01224 (I[19] = (img)(x,_p1##y,_n1##z,v)), \
01225 (I[22] = (img)(x,y,_n1##z,v)), \
01226 (I[25] = (img)(x,_n1##y,_n1##z,v)), \
01227 x+1>=(int)(img).width?(int)((img).width)-1:x+1); \
01228 x<=(int)(x1) && ((_n1##x<(int)((img).width) && ( \
01229 (I[2] = (img)(_n1##x,_p1##y,_p1##z,v)), \
01230 (I[5] = (img)(_n1##x,y,_p1##z,v)), \
01231 (I[8] = (img)(_n1##x,_n1##y,_p1##z,v)), \
01232 (I[11] = (img)(_n1##x,_p1##y,z,v)), \
01233 (I[14] = (img)(_n1##x,y,z,v)), \
01234 (I[17] = (img)(_n1##x,_n1##y,z,v)), \
01235 (I[20] = (img)(_n1##x,_p1##y,_n1##z,v)), \
01236 (I[23] = (img)(_n1##x,y,_n1##z,v)), \
01237 (I[26] = (img)(_n1##x,_n1##y,_n1##z,v)),1)) || \
01238 x==--_n1##x); \
01239 I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], \
01240 I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], \
01241 I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], \
01242 _p1##x = x++, ++_n1##x)
01243
01244 #define _CImg_stdarg(img,a0,a1,N,t) \
01245 { unsigned int _siz = (unsigned int)N; \
01246 if (_siz--) { \
01247 va_list ap; \
01248 va_start(ap,a1); \
01249 T *ptrd = (img).data; \
01250 *(ptrd++) = (T)a0; \
01251 if (_siz--) { \
01252 *(ptrd++) = (T)a1; \
01253 for (; _siz; --_siz) *(ptrd++) = (T)va_arg(ap,t); \
01254 } \
01255 va_end(ap); \
01256 }}
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01269
01280 namespace cimg_library {
01281
01282
01283 template<typename T=float> struct CImg;
01284 template<typename T=float> struct CImgList;
01285 struct CImgDisplay;
01286 struct CImgException;
01287
01288 namespace cimg {
01289
01290
01291 inline void info();
01292
01293 inline unsigned int& exception_mode();
01294
01295 inline int dialog(const char *title, const char *msg, const char *button1_txt="OK",
01296 const char *button2_txt=0, const char *button3_txt=0,
01297 const char *button4_txt=0, const char *button5_txt=0,
01298 const char *button6_txt=0, const bool centering=false);
01299
01300 template<typename tfunc, typename tp, typename tf>
01301 inline void marching_cubes(const tfunc& func, const float isovalue,
01302 const float x0, const float y0, const float z0,
01303 const float x1, const float y1, const float z1,
01304 const float resx, const float resy, const float resz,
01305 CImgList<tp>& points, CImgList<tf>& primitives,
01306 const bool invert_faces=false);
01307
01308 template<typename tfunc, typename tp, typename tf>
01309 inline void marching_squares(const tfunc& func, const float isovalue,
01310 const float x0, const float y0,
01311 const float x1, const float y1,
01312 const float resx, const float resy,
01313 CImgList<tp>& points, CImgList<tf>& primitives);
01314 }
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327 #define cimg_exception_err(etype,disp_flag) \
01328 std::va_list ap; \
01329 va_start(ap,format); \
01330 std::vsprintf(message,format,ap); \
01331 va_end(ap); \
01332 if (cimg::exception_mode()>=1) { \
01333 if (cimg::exception_mode()>=2 && disp_flag) { \
01334 try { cimg::dialog(etype,message,"Abort"); } \
01335 catch (CImgException&) { std::fprintf(stderr,"\n# %s :\n%s\n\n",etype,message); } \
01336 } else std::fprintf(stderr,"\n# %s :\n%s\n\n",etype,message); \
01337 } \
01338 if (cimg::exception_mode()>=3) cimg_library::cimg::info(); \
01339
01341
01405 struct CImgException {
01406 char message[1024];
01407 CImgException() { message[0]='\0'; }
01408 CImgException(const char *format, ...) { cimg_exception_err("CImgException",true); }
01409 };
01410
01411
01412
01413 struct CImgInstanceException : public CImgException {
01414 CImgInstanceException(const char *format, ...) { cimg_exception_err("CImgInstanceException",true); }
01415 };
01416
01417
01418
01419 struct CImgArgumentException : public CImgException {
01420 CImgArgumentException(const char *format, ...) { cimg_exception_err("CImgArgumentException",true); }
01421 };
01422
01423
01424
01425 struct CImgIOException : public CImgException {
01426 CImgIOException(const char *format, ...) { cimg_exception_err("CImgIOException",true); }
01427 };
01428
01429
01430
01431 struct CImgDisplayException : public CImgException {
01432 CImgDisplayException(const char *format, ...) { cimg_exception_err("CImgDisplayException",false); }
01433 };
01434
01435
01436
01437 struct CImgWarningException : public CImgException {
01438 CImgWarningException(const char *format, ...) { cimg_exception_err("CImgWarningException",false); }
01439 };
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01452
01459 namespace cimg {
01460
01461
01462 template<typename T> struct type {
01463 static const char* string() {
01464 static const char* s[] = { "unknown", "unknown8", "unknown16", "unknown24",
01465 "unknown32", "unknown40", "unknown48", "unknown56",
01466 "unknown64", "unknown72", "unknown80", "unknown88",
01467 "unknown96", "unknown104", "unknown112", "unknown120",
01468 "unknown128" };
01469 return s[(sizeof(T)<17)?sizeof(T):0];
01470 }
01471 static bool is_float() { return false; }
01472 static T min() { return (T)-1>0?(T)0:(T)-1<<(8*sizeof(T)-1); }
01473 static T max() { return (T)-1>0?(T)-1:~((T)-1<<(8*sizeof(T)-1)); }
01474 static const char* format() { return "%s"; }
01475 static const char* format(const T val) { static const char *s = "unknown"; return s; }
01476 };
01477
01478 template<> struct type<bool> {
01479 static const char* string() { static const char *const s = "bool"; return s; }
01480 static bool is_float() { return false; }
01481 static bool min() { return false; }
01482 static bool max() { return true; }
01483 static const char* format() { return "%s"; }
01484 static const char* format(const bool val) { static const char* s[] = { "false", "true" }; return s[val?1:0]; }
01485 };
01486
01487 template<> struct type<unsigned char> {
01488 static const char* string() { static const char *const s = "unsigned char"; return s; }
01489 static bool is_float() { return false; }
01490 static unsigned char min() { return 0; }
01491 static unsigned char max() { return (unsigned char)~0U; }
01492 static const char* format() { return "%u"; }
01493 static const unsigned int format(const unsigned char val) { return (unsigned int)val; }
01494 };
01495
01496 template<> struct type<char> {
01497 static const char* string() { static const char *const s = "char"; return s; }
01498 static bool is_float() { return false; }
01499 static char min() { return (char)(-1L<<(8*sizeof(char)-1)); }
01500 static char max() { return ~((char)(-1L<<(8*sizeof(char)-1))); }
01501 static const char* format() { return "%d"; }
01502 static const int format(const char val) { return (int)val; }
01503 };
01504
01505 template<> struct type<unsigned short> {
01506 static const char* string() { static const char *const s = "unsigned short"; return s; }
01507 static bool is_float() { return false; }
01508 static unsigned short min() { return 0; }
01509 static unsigned short max() { return (unsigned short)~0U; }
01510 static const char* format() { return "%u"; }
01511 static const unsigned int format(const unsigned short val) { return (unsigned int)val; }
01512 };
01513
01514 template<> struct type<short> {
01515 static const char* string() { static const char *const s = "short"; return s; }
01516 static bool is_float() { return false; }
01517 static short min() { return (short)(-1L<<(8*sizeof(short)-1)); }
01518 static short max() { return ~((short)(-1L<<(8*sizeof(short)-1))); }
01519 static const char* format() { return "%d"; }
01520 static const int format(const short val) { return (int)val; }
01521 };
01522
01523 template<> struct type<unsigned int> {
01524 static const char* string() { static const char *const s = "unsigned int"; return s; }
01525 static bool is_float() { return false; }
01526 static unsigned int min() { return 0; }
01527 static unsigned int max() { return (unsigned int)~0U; }
01528 static const char* format() { return "%u"; }
01529 static const unsigned int format(const unsigned int val) { return val; }
01530 };
01531
01532 template<> struct type<int> {
01533 static const char* string() { static const char *const s = "int"; return s; }
01534 static bool is_float() { return false; }
01535 static int min() { return (int)(-1L<<(8*sizeof(int)-1)); }
01536 static int max() { return ~((int)(-1L<<(8*sizeof(int)-1))); }
01537 static const char* format() { return "%d"; }
01538 static const int format(const int val) { return val; }
01539 };
01540
01541 template<> struct type<unsigned long> {
01542 static const char* string() { static const char *const s = "unsigned long"; return s; }
01543 static bool is_float() { return false; }
01544 static unsigned long min() { return 0; }
01545 static unsigned long max() { return (unsigned long)~0UL; }
01546 static const char* format() { return "%lu"; }
01547 static const unsigned long format(const unsigned long val) { return val; }
01548 };
01549
01550 template<> struct type<long> {
01551 static const char* string() { static const char *const s = "long"; return s; }
01552 static bool is_float() { return false; }
01553 static long min() { return (long)(-1L<<(8*sizeof(long)-1)); }
01554 static long max() { return ~((long)(-1L<<(8*sizeof(long)-1))); }
01555 static const char* format() { return "%ld"; }
01556 static const long format(const long val) { return val; }
01557 };
01558
01559 template<> struct type<float> {
01560 static const char* string() { static const char *const s = "float"; return s; }
01561 static bool is_float() { return true; }
01562 static float min() { return -3.4E38f; }
01563 static float max() { return 3.4E38f; }
01564 static const char* format() { return "%g"; }
01565 static const double format(const float val) { return (double)val; }
01566 };
01567
01568 template<> struct type<double> {
01569 static const char* string() { static const char *const s = "double"; return s; }
01570 static bool is_float() { return true; }
01571 static double min() { return -1.7E308; }
01572 static double max() { return 1.7E308; }
01573 static const char* format() { return "%g"; }
01574 static const double format(const double val) { return val; }
01575 };
01576
01577 template<typename T, typename t> struct superset { typedef T type; };
01578 template<> struct superset<bool,unsigned char> { typedef unsigned char type; };
01579 template<> struct superset<bool,char> { typedef char type; };
01580 template<> struct superset<bool,unsigned short> { typedef unsigned short type; };
01581 template<> struct superset<bool,short> { typedef short type; };
01582 template<> struct superset<bool,unsigned int> { typedef unsigned int type; };
01583 template<> struct superset<bool,int> { typedef int type; };
01584 template<> struct superset<bool,unsigned long> { typedef unsigned long type; };
01585 template<> struct superset<bool,long> { typedef long type; };
01586 template<> struct superset<bool,float> { typedef float type; };
01587 template<> struct superset<bool,double> { typedef double type; };
01588 template<> struct superset<unsigned char,char> { typedef short type; };
01589 template<> struct superset<unsigned char,unsigned short> { typedef unsigned short type; };
01590 template<> struct superset<unsigned char,short> { typedef short type; };
01591 template<> struct superset<unsigned char,unsigned int> { typedef unsigned int type; };
01592 template<> struct superset<unsigned char,int> { typedef int type; };
01593 template<> struct superset<unsigned char,unsigned long> { typedef unsigned long type; };
01594 template<> struct superset<unsigned char,long> { typedef long type; };
01595 template<> struct superset<unsigned char,float> { typedef float type; };
01596 template<> struct superset<unsigned char,double> { typedef double type; };
01597 template<> struct superset<char,unsigned char> { typedef short type; };
01598 template<> struct superset<char,unsigned short> { typedef int type; };
01599 template<> struct superset<char,short> { typedef short type; };
01600 template<> struct superset<char,unsigned int> { typedef long type; };
01601 template<> struct superset<char,int> { typedef int type; };
01602 template<> struct superset<char,unsigned long> { typedef long type; };
01603 template<> struct superset<char,long> { typedef long type; };
01604 template<> struct superset<char,float> { typedef float type; };
01605 template<> struct superset<char,double> { typedef double type; };
01606 template<> struct superset<unsigned short,char> { typedef int type; };
01607 template<> struct superset<unsigned short,short> { typedef int type; };
01608 template<> struct superset<unsigned short,unsigned int> { typedef unsigned int type; };
01609 template<> struct superset<unsigned short,int> { typedef int type; };
01610 template<> struct superset<unsigned short,unsigned long> { typedef unsigned long type; };
01611 template<> struct superset<unsigned short,long> { typedef long type; };
01612 template<> struct superset<unsigned short,float> { typedef float type; };
01613 template<> struct superset<unsigned short,double> { typedef double type; };
01614 template<> struct superset<short,unsigned short> { typedef int type; };
01615 template<> struct superset<short,unsigned int> { typedef long type; };
01616 template<> struct superset<short,int> { typedef int type; };
01617 template<> struct superset<short,unsigned long> { typedef long type; };
01618 template<> struct superset<short,long> { typedef long type; };
01619 template<> struct superset<short,float> { typedef float type; };
01620 template<> struct superset<short,double> { typedef double type; };
01621 template<> struct superset<unsigned int,char> { typedef long type; };
01622 template<> struct superset<unsigned int,short> { typedef long type; };
01623 template<> struct superset<unsigned int,int> { typedef long type; };
01624 template<> struct superset<unsigned int,unsigned long> { typedef unsigned long type; };
01625 template<> struct superset<unsigned int,long> { typedef long type; };
01626 template<> struct superset<unsigned int,float> { typedef float type; };
01627 template<> struct superset<unsigned int,double> { typedef double type; };
01628 template<> struct superset<int,unsigned int> { typedef long type; };
01629 template<> struct superset<int,unsigned long> { typedef long type; };
01630 template<> struct superset<int,long> { typedef long type; };
01631 template<> struct superset<int,float> { typedef float type; };
01632 template<> struct superset<int,double> { typedef double type; };
01633 template<> struct superset<unsigned long,char> { typedef long type; };
01634 template<> struct superset<unsigned long,short> { typedef long type; };
01635 template<> struct superset<unsigned long,int> { typedef long type; };
01636 template<> struct superset<unsigned long,long> { typedef long type; };
01637 template<> struct superset<unsigned long,float> { typedef float type; };
01638 template<> struct superset<unsigned long,double> { typedef double type; };
01639 template<> struct superset<long,float> { typedef float type; };
01640 template<> struct superset<long,double> { typedef double type; };
01641 template<> struct superset<float,double> { typedef double type; };
01642
01643 template<typename t1, typename t2, typename t3> struct superset2 {
01644 typedef typename superset<t1, typename superset<t2,t3>::type>::type type;
01645 };
01646
01647 template<typename t1, typename t2> struct last { typedef t2 type; };
01648
01649
01650 #if cimg_display_type==1
01651 struct X11info {
01652 volatile unsigned int nb_wins;
01653 pthread_mutex_t* mutex;
01654 pthread_t* event_thread;
01655 CImgDisplay* wins[1024];
01656 Display* display;
01657 unsigned int nb_bits;
01658 GC* gc;
01659 bool blue_first;
01660 bool byte_order;
01661 bool shm_enabled;
01662 #ifdef cimg_use_xrandr
01663 XRRScreenSize *resolutions;
01664 Rotation curr_rotation;
01665 unsigned int curr_resolution;
01666 unsigned int nb_resolutions;
01667 #endif
01668 X11info():nb_wins(0),mutex(0),event_thread(0),display(0),
01669 nb_bits(0),gc(0),blue_first(false),byte_order(false),shm_enabled(false) {
01670 #ifdef cimg_use_xrandr
01671 resolutions = 0;
01672 curr_rotation = 0;
01673 curr_resolution = nb_resolutions = 0;
01674 #endif
01675 }
01676 };
01677 #if defined(cimg_module)
01678 X11info& X11attr();
01679 #elif defined(cimg_main)
01680 X11info& X11attr() { static X11info val; return val; }
01681 #else
01682 inline X11info& X11attr() { static X11info val; return val; }
01683 #endif
01684
01685 #elif cimg_display_type==2
01686 struct Win32info {
01687 HANDLE wait_event;
01688 Win32info() { wait_event = CreateEvent(0,FALSE,FALSE,0); }
01689 };
01690 #if defined(cimg_module)
01691 Win32info& Win32attr();
01692 #elif defined(cimg_main)
01693 Win32info& Win32attr() { static Win32info val; return val; }
01694 #else
01695 inline Win32info& Win32attr() { static Win32info val; return val; }
01696 #endif
01697 #endif
01698
01699 inline unsigned int& exception_mode() { static unsigned int mode = cimg_debug; return mode; }
01700
01701 #ifdef cimg_color_terminal
01702 const char t_normal[] = { 0x1b,'[','0',';','0',';','0','m','\0' };
01703 const char t_red[] = { 0x1b,'[','4',';','3','1',';','5','9','m','\0' };
01704 const char t_bold[] = { 0x1b,'[','1','m','\0' };
01705 const char t_purple[] = { 0x1b,'[','0',';','3','5',';','5','9','m','\0' };
01706 #else
01707 const char t_normal[] = { '\0' };
01708 const char *const t_red = cimg::t_normal, *const t_bold = cimg::t_normal, *const t_purple = cimg::t_normal;
01709 #endif
01710
01711 #if cimg_display_type==1
01712
01713 const unsigned int keyESC = XK_Escape;
01714 const unsigned int keyF1 = XK_F1;
01715 const unsigned int keyF2 = XK_F2;
01716 const unsigned int keyF3 = XK_F3;
01717 const unsigned int keyF4 = XK_F4;
01718 const unsigned int keyF5 = XK_F5;
01719 const unsigned int keyF6 = XK_F6;
01720 const unsigned int keyF7 = XK_F7;
01721 const unsigned int keyF8 = XK_F8;
01722 const unsigned int keyF9 = XK_F9;
01723 const unsigned int keyF10 = XK_F10;
01724 const unsigned int keyF11 = XK_F11;
01725 const unsigned int keyF12 = XK_F12;
01726 const unsigned int keyPAUSE = XK_Pause;
01727 const unsigned int key1 = XK_1;
01728 const unsigned int key2 = XK_2;
01729 const unsigned int key3 = XK_3;
01730 const unsigned int key4 = XK_4;
01731 const unsigned int key5 = XK_5;
01732 const unsigned int key6 = XK_6;
01733 const unsigned int key7 = XK_7;
01734 const unsigned int key8 = XK_8;
01735 const unsigned int key9 = XK_9;
01736 const unsigned int key0 = XK_0;
01737 const unsigned int keyBACKSPACE = XK_BackSpace;
01738 const unsigned int keyINSERT = XK_Insert;
01739 const unsigned int keyHOME = XK_Home;
01740 const unsigned int keyPAGEUP = XK_Page_Up;
01741 const unsigned int keyTAB = XK_Tab;
01742 const unsigned int keyQ = XK_q;
01743 const unsigned int keyW = XK_w;
01744 const unsigned int keyE = XK_e;
01745 const unsigned int keyR = XK_r;
01746 const unsigned int keyT = XK_t;
01747 const unsigned int keyY = XK_y;
01748 const unsigned int keyU = XK_u;
01749 const unsigned int keyI = XK_i;
01750 const unsigned int keyO = XK_o;
01751 const unsigned int keyP = XK_p;
01752 const unsigned int keyDELETE = XK_Delete;
01753 const unsigned int keyEND = XK_End;
01754 const unsigned int keyPAGEDOWN = XK_Page_Down;
01755 const unsigned int keyCAPSLOCK = XK_Caps_Lock;
01756 const unsigned int keyA = XK_a;
01757 const unsigned int keyS = XK_s;
01758 const unsigned int keyD = XK_d;
01759 const unsigned int keyF = XK_f;
01760 const unsigned int keyG = XK_g;
01761 const unsigned int keyH = XK_h;
01762 const unsigned int keyJ = XK_j;
01763 const unsigned int keyK = XK_k;
01764 const unsigned int keyL = XK_l;
01765 const unsigned int keyENTER = XK_Return;
01766 const unsigned int keySHIFTLEFT = XK_Shift_L;
01767 const unsigned int keyZ = XK_z;
01768 const unsigned int keyX = XK_x;
01769 const unsigned int keyC = XK_c;
01770 const unsigned int keyV = XK_v;
01771 const unsigned int keyB = XK_b;
01772 const unsigned int keyN = XK_n;
01773 const unsigned int keyM = XK_m;
01774 const unsigned int keySHIFTRIGHT = XK_Shift_R;
01775 const unsigned int keyARROWUP = XK_Up;
01776 const unsigned int keyCTRLLEFT = XK_Control_L;
01777 const unsigned int keyAPPLEFT = XK_Super_L;
01778 const unsigned int keySPACE = XK_space;
01779 const unsigned int keyALTGR = XK_Alt_R;
01780 const unsigned int keyAPPRIGHT = XK_Super_R;
01781 const unsigned int keyMENU = XK_Menu;
01782 const unsigned int keyCTRLRIGHT = XK_Control_R;
01783 const unsigned int keyARROWLEFT = XK_Left;
01784 const unsigned int keyARROWDOWN = XK_Down;
01785 const unsigned int keyARROWRIGHT = XK_Right;
01786 const unsigned int keyPAD0 = XK_KP_0;
01787 const unsigned int keyPAD1 = XK_KP_1;
01788 const unsigned int keyPAD2 = XK_KP_2;
01789 const unsigned int keyPAD3 = XK_KP_3;
01790 const unsigned int keyPAD4 = XK_KP_4;
01791 const unsigned int keyPAD5 = XK_KP_5;
01792 const unsigned int keyPAD6 = XK_KP_6;
01793 const unsigned int keyPAD7 = XK_KP_7;
01794 const unsigned int keyPAD8 = XK_KP_8;
01795 const unsigned int keyPAD9 = XK_KP_9;
01796 const unsigned int keyPADADD = XK_KP_Add;
01797 const unsigned int keyPADSUB = XK_KP_Subtract;
01798 const unsigned int keyPADMUL = XK_KP_Multiply;
01799 const unsigned int keyPADDIV = XK_KP_Divide;
01800
01801 #elif (cimg_display_type==2 && cimg_OS==2)
01802
01803 const unsigned int keyESC = VK_ESCAPE;
01804 const unsigned int keyF1 = VK_F1;
01805 const unsigned int keyF2 = VK_F2;
01806 const unsigned int keyF3 = VK_F3;
01807 const unsigned int keyF4 = VK_F4;
01808 const unsigned int keyF5 = VK_F5;
01809 const unsigned int keyF6 = VK_F6;
01810 const unsigned int keyF7 = VK_F7;
01811 const unsigned int keyF8 = VK_F8;
01812 const unsigned int keyF9 = VK_F9;
01813 const unsigned int keyF10 = VK_F10;
01814 const unsigned int keyF11 = VK_F11;
01815 const unsigned int keyF12 = VK_F12;
01816 const unsigned int keyPAUSE = VK_PAUSE;
01817 const unsigned int key1 = '1';
01818 const unsigned int key2 = '2';
01819 const unsigned int key3 = '3';
01820 const unsigned int key4 = '4';
01821 const unsigned int key5 = '5';
01822 const unsigned int key6 = '6';
01823 const unsigned int key7 = '7';
01824 const unsigned int key8 = '8';
01825 const unsigned int key9 = '9';
01826 const unsigned int key0 = '0';
01827 const unsigned int keyBACKSPACE = VK_BACK;
01828 const unsigned int keyINSERT = VK_INSERT;
01829 const unsigned int keyHOME = VK_HOME;
01830 const unsigned int keyPAGEUP = VK_PRIOR;
01831 const unsigned int keyTAB = VK_TAB;
01832 const unsigned int keyQ = 'Q';
01833 const unsigned int keyW = 'W';
01834 const unsigned int keyE = 'E';
01835 const unsigned int keyR = 'R';
01836 const unsigned int keyT = 'T';
01837 const unsigned int keyY = 'Y';
01838 const unsigned int keyU = 'U';
01839 const unsigned int keyI = 'I';
01840 const unsigned int keyO = 'O';
01841 const unsigned int keyP = 'P';
01842 const unsigned int keyDELETE = VK_DELETE;
01843 const unsigned int keyEND = VK_END;
01844 const unsigned int keyPAGEDOWN = VK_NEXT;
01845 const unsigned int keyCAPSLOCK = VK_CAPITAL;
01846 const unsigned int keyA = 'A';
01847 const unsigned int keyS = 'S';
01848 const unsigned int keyD = 'D';
01849 const unsigned int keyF = 'F';
01850 const unsigned int keyG = 'G';
01851 const unsigned int keyH = 'H';
01852 const unsigned int keyJ = 'J';
01853 const unsigned int keyK = 'K';
01854 const unsigned int keyL = 'L';
01855 const unsigned int keyENTER = VK_RETURN;
01856 const unsigned int keySHIFTLEFT = VK_SHIFT;
01857 const unsigned int keyZ = 'Z';
01858 const unsigned int keyX = 'X';
01859 const unsigned int keyC = 'C';
01860 const unsigned int keyV = 'V';
01861 const unsigned int keyB = 'B';
01862 const unsigned int keyN = 'N';
01863 const unsigned int keyM = 'M';
01864 const unsigned int keySHIFTRIGHT = VK_SHIFT;
01865 const unsigned int keyARROWUP = VK_UP;
01866 const unsigned int keyCTRLLEFT = VK_CONTROL;
01867 const unsigned int keyAPPLEFT = VK_LWIN;
01868 const unsigned int keySPACE = VK_SPACE;
01869 const unsigned int keyALTGR = VK_CONTROL;
01870 const unsigned int keyAPPRIGHT = VK_RWIN;
01871 const unsigned int keyMENU = VK_APPS;
01872 const unsigned int keyCTRLRIGHT = VK_CONTROL;
01873 const unsigned int keyARROWLEFT = VK_LEFT;
01874 const unsigned int keyARROWDOWN = VK_DOWN;
01875 const unsigned int keyARROWRIGHT = VK_RIGHT;
01876 const unsigned int keyPAD0 = 0x60;
01877 const unsigned int keyPAD1 = 0x61;
01878 const unsigned int keyPAD2 = 0x62;
01879 const unsigned int keyPAD3 = 0x63;
01880 const unsigned int keyPAD4 = 0x64;
01881 const unsigned int keyPAD5 = 0x65;
01882 const unsigned int keyPAD6 = 0x66;
01883 const unsigned int keyPAD7 = 0x67;
01884 const unsigned int keyPAD8 = 0x68;
01885 const unsigned int keyPAD9 = 0x69;
01886 const unsigned int keyPADADD = VK_ADD;
01887 const unsigned int keyPADSUB = VK_SUBTRACT;
01888 const unsigned int keyPADMUL = VK_MULTIPLY;
01889 const unsigned int keyPADDIV = VK_DIVIDE;
01890 #else
01891
01892 const unsigned int keyESC = 1U;
01893 const unsigned int keyF1 = 2U;
01894 const unsigned int keyF2 = 3U;
01895 const unsigned int keyF3 = 4U;
01896 const unsigned int keyF4 = 5U;
01897 const unsigned int keyF5 = 6U;
01898 const unsigned int keyF6 = 7U;
01899 const unsigned int keyF7 = 8U;
01900 const unsigned int keyF8 = 9U;
01901 const unsigned int keyF9 = 10U;
01902 const unsigned int keyF10 = 11U;
01903 const unsigned int keyF11 = 12U;
01904 const unsigned int keyF12 = 13U;
01905 const unsigned int keyPAUSE = 14U;
01906 const unsigned int key1 = 15U;
01907 const unsigned int key2 = 16U;
01908 const unsigned int key3 = 17U;
01909 const unsigned int key4 = 18U;
01910 const unsigned int key5 = 19U;
01911 const unsigned int key6 = 20U;
01912 const unsigned int key7 = 21U;
01913 const unsigned int key8 = 22U;
01914 const unsigned int key9 = 23U;
01915 const unsigned int key0 = 24U;
01916 const unsigned int keyBACKSPACE = 25U;
01917 const unsigned int keyINSERT = 26U;
01918 const unsigned int keyHOME = 27U;
01919 const unsigned int keyPAGEUP = 28U;
01920 const unsigned int keyTAB = 29U;
01921 const unsigned int keyQ = 30U;
01922 const unsigned int keyW = 31U;
01923 const unsigned int keyE = 32U;
01924 const unsigned int keyR = 33U;
01925 const unsigned int keyT = 34U;
01926 const unsigned int keyY = 35U;
01927 const unsigned int keyU = 36U;
01928 const unsigned int keyI = 37U;
01929 const unsigned int keyO = 38U;
01930 const unsigned int keyP = 39U;
01931 const unsigned int keyDELETE = 40U;
01932 const unsigned int keyEND = 41U;
01933 const unsigned int keyPAGEDOWN = 42U;
01934 const unsigned int keyCAPSLOCK = 43U;
01935 const unsigned int keyA = 44U;
01936 const unsigned int keyS = 45U;
01937 const unsigned int keyD = 46U;
01938 const unsigned int keyF = 47U;
01939 const unsigned int keyG = 48U;
01940 const unsigned int keyH = 49U;
01941 const unsigned int keyJ = 50U;
01942 const unsigned int keyK = 51U;
01943 const unsigned int keyL = 52U;
01944 const unsigned int keyENTER = 53U;
01945 const unsigned int keySHIFTLEFT = 54U;
01946 const unsigned int keyZ = 55U;
01947 const unsigned int keyX = 56U;
01948 const unsigned int keyC = 57U;
01949 const unsigned int keyV = 58U;
01950 const unsigned int keyB = 59U;
01951 const unsigned int keyN = 60U;
01952 const unsigned int keyM = 61U;
01953 const unsigned int keySHIFTRIGHT = 62U;
01954 const unsigned int keyARROWUP = 63U;
01955 const unsigned int keyCTRLLEFT = 64U;
01956 const unsigned int keyAPPLEFT = 65U;
01957 const unsigned int keySPACE = 66U;
01958 const unsigned int keyALTGR = 67U;
01959 const unsigned int keyAPPRIGHT = 68U;
01960 const unsigned int keyMENU = 69U;
01961 const unsigned int keyCTRLRIGHT = 70U;
01962 const unsigned int keyARROWLEFT = 71U;
01963 const unsigned int keyARROWDOWN = 72U;
01964 const unsigned int keyARROWRIGHT = 73U;
01965 const unsigned int keyPAD0 = 74U;
01966 const unsigned int keyPAD1 = 75U;
01967 const unsigned int keyPAD2 = 76U;
01968 const unsigned int keyPAD3 = 77U;
01969 const unsigned int keyPAD4 = 78U;
01970 const unsigned int keyPAD5 = 79U;
01971 const unsigned int keyPAD6 = 80U;
01972 const unsigned int keyPAD7 = 81U;
01973 const unsigned int keyPAD8 = 82U;
01974 const unsigned int keyPAD9 = 83U;
01975 const unsigned int keyPADADD = 84U;
01976 const unsigned int keyPADSUB = 85U;
01977 const unsigned int keyPADMUL = 86U;
01978 const unsigned int keyPADDIV = 87U;
01979 #endif
01980
01981 const double PI = 3.14159265358979323846;
01982
01983
01984 const unsigned int font7x11[7*11*256/32] = {
01985 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,
01986 0x0,0x0,0x0,0x0,0x0,0x0,0x90,0x0,0x7f0000,0x40000,0x0,0x0,0x4010c0a4,0x82000040,0x11848402,0x18480050,0x80430292,0x8023,0x9008000,
01987 0x40218140,0x4000040,0x21800402,0x18000051,0x1060500,0x8083,0x10000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x24002,0x4031,0x80000000,0x10000,
01988 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x81c0400,0x40020000,0x80070080,0x40440e00,0x0,0x0,0x1,0x88180000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01989 0x0,0x200000,0x0,0x0,0x80000,0x0,0x0,0x20212140,0x5000020,0x22400204,0x240000a0,0x40848500,0x4044,0x80010038,0x20424285,0xa000020,
01990 0x42428204,0x2428e0a0,0x82090a14,0x4104,0x85022014,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10240a7,0x88484040,0x40800000,0x270c3,0x87811e0e,
01991 0x7c70e000,0x78,0x3c23c1ef,0x1f3e1e89,0xf1c44819,0xa23cf0f3,0xc3cff120,0xc18307f4,0x4040400,0x20000,0x80080080,0x40200,0x0,
01992 0x40000,0x2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8188,0x50603800,0xf3c00000,0x1c004003,0xc700003e,0x18180,0xc993880,0x10204081,
01993 0x2071ef9,0xf3e7cf9f,0x3e7c7911,0xe3c78f1e,0x7d1224,0x48906048,0x0,0x4000000,0x0,0x9000,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,
01994 0x0,0x10240aa,0x14944080,0x23610000,0x68940,0x40831010,0x8891306,0x802044,0x44522208,0x90202088,0x40448819,0xb242890a,0x24011111,
01995 0x49448814,0x4040a00,0xe2c3c7,0x8e3f3cb9,0xc1c44216,0xee38b0f2,0xe78f9120,0xc18507e2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01996 0x101c207,0x88a04001,0x9c00000,0x2200a041,0x8200113a,0x8240,0x50a3110,0x2850a142,0x850c2081,0x2040204,0x8104592,0x142850a1,
01997 0x42cd1224,0x4888bc48,0x70e1c387,0xe3b3c70,0xe1c38e1c,0x38707171,0xc3870e1c,0x10791224,0x48906c41,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
01998 0x10003ee,0x15140080,0x21810000,0x48840,0x40851020,0x8911306,0x31fd804,0x9c522408,0x90204088,0x4045081a,0xba42890a,0x24011111,
01999 0x49285024,0x2041b00,0x132408,0x910844c8,0x4044821b,0x7244c913,0x24041111,0x49488822,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02000 0x28204,0x85006001,0x6a414000,0x3a004043,0xc700113a,0x8245,0x50a3a00,0x2850a142,0x850c4081,0x2040204,0x81045d2,0x142850a1,
02001 0x24951224,0x48852250,0x8102040,0x81054089,0x12244204,0x8108992,0x24489122,0x991224,0x4888b222,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02002 0x1000143,0xa988080,0x2147c01f,0x88840,0x83091c2c,0x1070f000,0xc000608,0xa48bc408,0x9e3c46f8,0x40460816,0xaa42f10b,0xc3811111,
02003 0x35102044,0x1041100,0xf22408,0x9f084488,0x40470212,0x62448912,0x6041111,0x55308846,0x8061c80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02004 0x1028704,0x8f805801,0x4be28fdf,0x220001f0,0x111a,0x60000182,0x82c5c710,0x44891224,0x489640f1,0xe3c78204,0x810e552,0x142850a1,
02005 0x18a51224,0x48822250,0x78f1e3c7,0x8f1f40f9,0xf3e7c204,0x8108912,0x24489122,0x7ea91224,0x4888a222,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02006 0x10007e2,0x85648080,0x20010000,0x88841,0x8f8232,0x20881000,0xc1fc610,0xbefa2408,0x90204288,0x40450816,0xa642810a,0x4041110a,
02007 0x36282084,0x1042080,0x1122408,0x90084488,0x40450212,0x62448912,0x184110a,0x55305082,0x8042700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02008 0x1028207,0x82004801,0x68050040,0x1c000040,0x110a,0x60000001,0x45484d10,0x7cf9f3e7,0xcf944081,0x2040204,0x8104532,0x142850a1,
02009 0x18a51224,0x48822248,0x89122448,0x91244081,0x2040204,0x8108912,0x24489122,0xc91224,0x48852214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x282,
02010 0x89630080,0x20010c00,0x30108842,0x810222,0x20882306,0x3001800,0x408a2208,0x90202288,0x40448814,0xa642810a,0x2041110a,0x26442104,
02011 0x840000,0x1122408,0x90084488,0x40448212,0x62448912,0x84130a,0x36485102,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x101c208,0x4f802801,
02012 0x8028040,0x40,0x130a,0x2,0x85e897a0,0x44891224,0x489c2081,0x2040204,0x8104532,0x142850a1,0x24cd1224,0x48823c44,0x89122448,
02013 0x91244081,0x2040204,0x8108912,0x24489122,0xc93264,0xc9852214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100028f,0x109f0080,0x20010c00,
02014 0x303071f3,0xc7011c1c,0x4071c306,0x802010,0x3907c1ef,0x1f201e89,0xf3844f90,0xa23c80f2,0x17810e04,0x228223f4,0x840000,0xfbc3c7,
02015 0x8f083c88,0x40444212,0x6238f0f2,0x7039d04,0x228423e2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1008780,0x2201800,0xf0014000,0x1f0,
02016 0x1d0a,0x5,0x851e140,0x83060c18,0x30671ef9,0xf3e7cf9f,0x3e7c7911,0xe3c78f1e,0x42f8e1c3,0x8702205c,0x7cf9f3e7,0xcf9b3c78,0xf1e3c204,
02017 0x8107111,0xc3870e1c,0x10f1d3a7,0x4e823c08,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x40,0x40000400,0x200000,0x0,0x2,0x0,0x0,0x0,0x0,0x18,
02018 0x0,0x4,0x44007f,0x0,0x400,0x400000,0x8010,0x0,0x6002,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x200800,0x0,0x0,0x100a,
02019 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,
02020 0x400000,0x0,0x4,0x0,0x0,0x0,0x0,0xc,0x0,0x7,0x3c0000,0x0,0x3800,0x3800000,0x8010,0x0,0x1c001,0x881c0000,0x0,0x0,0x0,0x0,0x0,0x0,
02021 0x0,0x0,0x207000,0x0,0x0,0x100a,0xc00000,0x3c,0x0,0xc00,0x0,0x0,0x0,0x0,0x0,0x0,0x1800,0x0,0x0,0x0,0x0,0x1c2070
02022 };
02023
02024
02025 const unsigned int font10x13[256*10*13/32] = {
02026 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02027 0x0,0x0,0x0,0x0,0x0,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,
02028 0x68000300,0x801,0xc00010,0x100c000,0x68100,0x100c0680,0x2,0x403000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02029 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02030 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,
02031 0x58120480,0x402,0x1205008,0x2012050,0x58080,0x20120581,0x40000001,0x804812,0x2000000,0x0,0x300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02032 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,
02033 0x0,0x7010,0x7000000,0x8000200,0x20000,0xc0002000,0x8008,0x0,0x0,0x0,0x0,0x808,0x4000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02034 0x0,0x0,0x80000000,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x480,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x80100c0,0x68000480,0x1001,
02035 0xc00010,0x1018000,0x68100,0x100c0680,0x4,0x403000,0x1020000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140,0x28081883,0x200801,
02036 0x2a00000,0x10,0x1c0201c0,0x70040f80,0xc0f81c07,0x0,0x70,0x3e0303c0,0x3c3c0f83,0xe03c2107,0xe08810,0x18c31070,0x3c0703c0,
02037 0x783e0842,0x22222208,0x83e04010,0x1008000,0x4000200,0x20001,0x2002,0x408008,0x0,0x0,0x100000,0x0,0x1008,0x2000000,0x0,0x0,0x0,
02038 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20080,0x38000880,0x8078140f,0x81c00000,0x3e000,0xc020180,0x60080001,0xe0000002,0xc00042,0x108e2010,
02039 0xc0300c0,0x300c0303,0xf83c3e0f,0x83e0f81c,0x701c070,0x3c0c41c0,0x701c0701,0xc0001d08,0x42108421,0x8820088,0x4020120,0x58140480,
02040 0x802,0x1205008,0x3014050,0xc058080,0x20120581,0x40000002,0x804814,0x2020050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140,
02041 0x281e2484,0x80200801,0x1c02000,0x10,0x22060220,0x880c0801,0x82208,0x80000001,0x20008,0x41030220,0x40220802,0x402102,0x209010,
02042 0x18c31088,0x22088220,0x80080842,0x22222208,0x80204010,0x1014000,0x200,0x20001,0x2000,0x8008,0x0,0x0,0x100000,0x0,0x1008,
02043 0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40000500,0x80800010,0x40200000,0x41000,0x12020040,0x10000003,0xa0000006,
02044 0x12000c4,0x31014000,0xc0300c0,0x300c0302,0x80402008,0x2008008,0x2008020,0x220c4220,0x88220882,0x20002208,0x42108421,0x8820088,
02045 0x0,0x300,0x0,0x0,0x0,0x14000000,0x0,0x200200,0x0,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xfc282504,0x80001000,
02046 0x82a02000,0x20,0x22020020,0x8140802,0x102208,0x80801006,0x18008,0x9c848220,0x80210802,0x802102,0x20a010,0x15429104,0x22104220,
02047 0x80080842,0x22221405,0x404008,0x1022000,0x703c0,0x381e0701,0xc0783c02,0xc09008,0x1d83c070,0x3c078140,0x381c0882,0x21242208,
02048 0x81e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0,0x40220500,0x80800027,0x20e02800,0x9c800,0x12020040,
02049 0x20000883,0xa0200002,0x120a044,0x11064010,0x12048120,0x48120484,0x80802008,0x2008008,0x2008020,0x210a4411,0x4411044,0x10884508,
02050 0x42108421,0x503c0b0,0x1c0701c0,0x701c0707,0x70381c07,0x1c07008,0x2008020,0x20f01c0,0x701c0701,0xc0201c08,0x82208822,0x883c088,
02051 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x50281903,0x20001000,0x80802000,0x20,0x22020040,0x30240f03,0xc0101c08,0x80801018,
02052 0x1fc06010,0xa48483c0,0x80210f03,0xe0803f02,0x20c010,0x15429104,0x22104220,0x70080841,0x41540805,0x804008,0x1041000,0x8220,
02053 0x40220881,0x882202,0x40a008,0x12422088,0x22088180,0x40100882,0x21241408,0x80201008,0x2031000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02054 0x0,0x20280,0x401c0200,0x700028,0x21205000,0x92800,0xc1fc080,0x10000883,0xa0200002,0x1205049,0x12c19010,0x12048120,0x48120484,
02055 0xf0803c0f,0x3c0f008,0x2008020,0x790a4411,0x4411044,0x10504908,0x42108421,0x5022088,0x2008020,0x8020080,0x88402208,0x82208808,
02056 0x2008020,0x1e088220,0x88220882,0x20002608,0x82208822,0x8822088,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x501c0264,
02057 0xa0001000,0x8001fc00,0x7000020,0x22020080,0x83e0082,0x20202207,0x80000020,0x1020,0xa4848220,0x80210802,0x9c2102,0x20c010,
02058 0x12425104,0x3c1043c0,0x8080841,0x41540802,0x804008,0x1000000,0x78220,0x40220f81,0x882202,0x40c008,0x12422088,0x22088100,
02059 0x60100881,0x41540805,0x406008,0x1849000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0xf0140200,0x880028,0x20e0a03f,0x709c800,
02060 0x201c0,0x60000881,0xa0000007,0xc0284b,0x122eb020,0x12048120,0x48120487,0x80802008,0x2008008,0x2008020,0x21094411,0x4411044,
02061 0x10204908,0x42108421,0x2022088,0x1e0781e0,0x781e0787,0xf8403e0f,0x83e0f808,0x2008020,0x22088220,0x88220882,0x21fc2a08,0x82208822,
02062 0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0xf80a0294,0x40001000,0x80002000,0x20,0x22020100,0x8040082,0x20202200,
02063 0x80000018,0x1fc06020,0xa48fc220,0x80210802,0x842102,0x20a010,0x12425104,0x20104240,0x8080841,0x41541402,0x1004008,0x1000000,
02064 0x88220,0x40220801,0x882202,0x40a008,0x12422088,0x22088100,0x18100881,0x41540805,0x801008,0x2046000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02065 0x0,0x0,0x0,0x20280,0x401c0f80,0x80880028,0x20005001,0x94800,0x20000,0x880,0xa0000000,0x5015,0x4215040,0x3f0fc3f0,0xfc3f0fc8,
02066 0x80802008,0x2008008,0x2008020,0x21094411,0x4411044,0x10505108,0x42108421,0x203c088,0x22088220,0x88220888,0x80402008,0x2008008,
02067 0x2008020,0x22088220,0x88220882,0x20002a08,0x82208822,0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa00a0494,0x60001000,
02068 0x80002004,0x8020,0x22020200,0x88040882,0x20402201,0x801006,0x18000,0x9f084220,0x40220802,0x442102,0x209010,0x10423088,0x20088220,
02069 0x8080840,0x80882202,0x2004008,0x1000000,0x88220,0x40220881,0x882202,0x409008,0x12422088,0x22088100,0x8100880,0x80881402,
02070 0x1001008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0x40220200,0x80700027,0x20002801,0x92800,0x1fc000,0x980,
02071 0xa0000000,0xa017,0x84417840,0x21084210,0x84210848,0x80402008,0x2008008,0x2008020,0x2208c220,0x88220882,0x20882208,0x42108421,
02072 0x2020088,0x22088220,0x88220888,0xc8402208,0x82208808,0x2008020,0x22088220,0x88220882,0x20203208,0x82208822,0x2022020,0x0,0x0,0x0,
02073 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xa03c0463,0x90000801,0x2004,0x8040,0x1c0703e0,0x70040701,0xc0401c06,0x801001,0x20020,
02074 0x400843c0,0x3c3c0f82,0x3c2107,0x1c0881e,0x10423070,0x20070210,0xf0080780,0x80882202,0x3e04004,0x1000000,0x783c0,0x381e0701,
02075 0x782202,0x408808,0x12422070,0x3c078100,0x700c0780,0x80882202,0x1e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0,
02076 0xf8000200,0x80080010,0x40000001,0x41000,0x0,0xe80,0xa0000000,0x21,0x8e21038,0x21084210,0x84210848,0xf83c3e0f,0x83e0f81c,
02077 0x701c070,0x3c08c1c0,0x701c0701,0xc0005c07,0x81e0781e,0x20200b0,0x1e0781e0,0x781e0787,0x30381c07,0x1c07008,0x2008020,0x1c0881c0,
02078 0x701c0701,0xc0201c07,0x81e0781e,0x203c020,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,0x801,0x4,0x40,0x0,0x0,0x0,0x1000,
02079 0x0,0x3c000000,0x0,0x0,0x0,0x0,0x10000,0x0,0x0,0x4004,0x1000000,0x0,0x0,0x80000,0x400000,0x0,0x20008000,0x0,0x4,0x1008,0x2000000,
02080 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x8008000f,0x80000000,0x3e000,0x0,0x800,0xa0000400,0x0,0x0,0x0,0x0,0x80000,0x0,
02081 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,
02082 0x402,0x8,0x40,0x0,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x0,0x7004,0x70000fc,0x0,0x0,0x700000,0x800000,0x0,0x20008000,
02083 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,
02084 0x300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x4020040
02085 };
02086
02087
02088 const unsigned int font8x17[8*17*256/32] = {
02089 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02090 0x0,0x0,0x0,0x2400,0x2400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20081834,0x1c0000,0x20081800,0x20081800,0x342008,
02091 0x18340000,0x200818,0x80000,0x0,0x180000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4200000,0x0,0x0,
02092 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x380000,0x4000,0x2000c00,0x40100840,0x70000000,0x0,0x0,0x1c,0x10700000,0x7,0x0,
02093 0x1800,0x1800,0x0,0x0,0x0,0x14,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1010242c,0x14140000,0x10102414,0x10102414,0x2c1010,0x242c1400,
02094 0x101024,0x14100038,0x0,0x240000,0x0,0x0,0x30000000,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x12,0x0,0x8100000,0x0,
02095 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x80000,0x10004000,0x2001000,0x40000040,0x10000000,0x0,0x0,0x10,0x10100000,0x4,
02096 0x0,0x18000000,0x0,0x0,0x0,0x34002400,0x2400,0x0,0x0,0x0,0x3c,0x0,0x8000000,0x0,0x60607800,0x0,0x140000,0x0,0x0,0x0,0x0,0x0,
02097 0x44,0x10081834,0x240000,0x10081800,0x10081800,0x1c341008,0x18340000,0x100818,0x84000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102812,
02098 0x8601c10,0x8100800,0x2,0x1c383e3e,0x67e1e7f,0x3e3c0000,0x38,0x1e087e1e,0x7c7f7f1e,0x417c1c42,0x4063611c,0x7e1c7e3e,0xfe414181,
02099 0x63827f10,0x40081000,0x8004000,0x2001000,0x40000040,0x10000000,0x0,0x10000000,0x10,0x10100000,0x3c000008,0x0,0x24003e00,
02100 0x3f007f00,0x0,0x0,0x2ce91800,0x1882,0x10101c,0xc2103c,0x143c3c00,0x3c00,0x18003c3c,0x10001f00,0x181c00,0x20200810,0x8080808,
02101 0x8083e1e,0x7f7f7f7f,0x7c7c7c7c,0x7c611c1c,0x1c1c1c00,0x1e414141,0x41824044,0x810242c,0x14180000,0x8102414,0x8102414,0x382c0810,
02102 0x242c1400,0x81024,0x14104014,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102816,0x3e902010,0x10084910,0x4,0x22084343,0xa402102,0x41620000,
02103 0x44,0x33144121,0x42404021,0x41100444,0x40636122,0x43224361,0x10416381,0x22440310,0x20082800,0x4000,0x2001000,0x40000040,
02104 0x10000000,0x0,0x10000000,0x10,0x10100000,0x24000008,0x0,0x606100,0x68000300,0x8106c,0x34000000,0x4f0000,0x44,0x101020,0x441040,
02105 0x420200,0x4200,0x24000404,0x7d00,0x82200,0x20203010,0x14141414,0x14082821,0x40404040,0x10101010,0x42612222,0x22222200,0x23414141,
02106 0x41447e48,0x0,0x0,0x0,0x0,0x4000000,0x18,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10287f,0x49902010,0x10083e10,0x4,0x41080101,
02107 0x1a404002,0x41411818,0x1004004,0x21144140,0x41404040,0x41100448,0x40555141,0x41414140,0x10412281,0x14280610,0x20084400,0x1c7c1c,
02108 0x3e3c7c3a,0x5c703844,0x107f5c3c,0x7c3e3c3c,0x7e424281,0x66427e10,0x10100000,0x40100008,0x1010,0xa04000,0x48100610,0x100c3024,
02109 0x24000000,0x4f3c00,0x2c107e28,0x3820,0x42281060,0x9d1e12,0xbd00,0x24100818,0x427d00,0x82248,0x20200800,0x14141414,0x14142840,
02110 0x40404040,0x10101010,0x41514141,0x41414142,0x43414141,0x41284350,0x1c1c1c1c,0x1c1c6c1c,0x3c3c3c3c,0x70707070,0x3c5c3c3c,
02111 0x3c3c3c18,0x3e424242,0x42427c42,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102824,0x48623010,0x10081c10,0x8,0x41080103,0x127c5e04,
02112 0x41411818,0xe7f3808,0x4f144140,0x41404040,0x41100450,0x40555141,0x41414160,0x1041225a,0x1c280410,0x1008c600,0x226622,0x66661066,
02113 0x62100848,0x10496266,0x66663242,0x10426681,0x24220260,0x100c0000,0xf8280008,0x1010,0x606000,0x48280428,0x28042014,0x48000000,
02114 0x494200,0x52280228,0x105420,0x3cee1058,0xa12236,0xa500,0x18101004,0x427d00,0x8226c,0x76767e10,0x14141414,0x14142840,0x40404040,
02115 0x10101010,0x41514141,0x41414124,0x45414141,0x41284150,0x22222222,0x22221222,0x66666666,0x10101010,0x66626666,0x66666600,
02116 0x66424242,0x42226622,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100024,0x381c4900,0x10086bfe,0x8,0x4908021c,0x22036304,0x3e630000,
02117 0x70000710,0x51227e40,0x417f7f43,0x7f100470,0x40554941,0x43417e3e,0x1041225a,0x8100810,0x10080000,0x24240,0x42421042,0x42100850,
02118 0x10494242,0x42422040,0x1042245a,0x18240410,0x10103900,0x407c003e,0x1818,0x1c3e10,0x4f7c087c,0x7c002010,0x48000000,0x4008,
02119 0x527c0410,0x105078,0x2410104c,0xa13e6c,0x7f00b900,0xfe3c3c,0x421d18,0x1c1c36,0x38383810,0x22222222,0x22144e40,0x7f7f7f7f,
02120 0x10101010,0xf1494141,0x41414118,0x49414141,0x4110435c,0x2020202,0x2021240,0x42424242,0x10101010,0x42424242,0x424242ff,0x4e424242,
02121 0x42244224,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000fe,0xe664d00,0x10080810,0x380010,0x41080c03,0x42014108,0x633d0000,0x70000710,
02122 0x51224140,0x41404041,0x41100448,0x40494541,0x7e414203,0x1041145a,0x14101010,0x10080000,0x3e4240,0x427e1042,0x42100870,0x10494242,
02123 0x4242203c,0x1042245a,0x18241810,0x10104600,0xf8f60008,0x1010,0x600320,0x48f610f6,0xf6000000,0x187eff,0x3c04,0x5ef61810,0x105020,
02124 0x24fe0064,0x9d006c,0x138ad00,0x100000,0x420518,0x36,0xc0c0c020,0x22222222,0x22224840,0x40404040,0x10101010,0x41454141,0x41414118,
02125 0x51414141,0x41107e46,0x3e3e3e3e,0x3e3e7e40,0x7e7e7e7e,0x10101010,0x42424242,0x42424200,0x5a424242,0x42244224,0x0,0x0,0x0,
02126 0x0,0x0,0x0,0x0,0x0,0x28,0x9094500,0x10080010,0x10,0x41081801,0x7f014118,0x41010000,0xe7f3800,0x513e4140,0x41404041,0x41100444,
02127 0x40414541,0x40414101,0x10411466,0x36103010,0x8080000,0x424240,0x42401042,0x42100848,0x10494242,0x42422002,0x10423c5a,0x18142010,
02128 0x10100000,0x407c0010,0x1010,0x260140,0x487c307c,0x7c000000,0x180000,0x202,0x507c2010,0x105020,0x3c10003c,0x423e36,0x1004200,
02129 0x100000,0x420500,0x3e6c,0x41e0440,0x3e3e3e3e,0x3e3e7840,0x40404040,0x10101010,0x41454141,0x41414124,0x61414141,0x41104042,
02130 0x42424242,0x42425040,0x40404040,0x10101010,0x42424242,0x42424218,0x72424242,0x42144214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100048,
02131 0x49096200,0x8100010,0x18001810,0x22082043,0x2432310,0x61421818,0x1004010,0x4f634121,0x42404021,0x41104444,0x40414322,0x40234143,
02132 0x10411466,0x22106010,0x8080000,0x466622,0x66621066,0x42100844,0x10494266,0x66662042,0x10461824,0x24184010,0x10100000,0x24381010,
02133 0x34001018,0xda4320,0x68386038,0x38000000,0x0,0x4204,0x50384010,0x105420,0x4210100c,0x3c0012,0x3c00,0x0,0x460500,0x48,0xc020c44,
02134 0x63636363,0x63228821,0x40404040,0x10101010,0x42432222,0x22222242,0x62414141,0x41104042,0x46464646,0x46465022,0x62626262,
02135 0x10101010,0x66426666,0x66666618,0x66464646,0x46186618,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100048,0x3e063d00,0x8100000,0x18001820,
02136 0x1c3e7f3e,0x23c1e20,0x3e3c1818,0x10,0x20417e1e,0x7c7f401e,0x417c3842,0x7f41431c,0x401e40be,0x103e0866,0x41107f10,0x4080000,
02137 0x3a5c1c,0x3a3c103a,0x427c0842,0xe49423c,0x7c3e203c,0xe3a1824,0x66087e10,0x10100000,0x3c103010,0x245a1010,0x5a3e10,0x3f107f10,
02138 0x10000000,0x0,0x3c08,0x2e107e10,0x1038fc,0x101004,0x0,0x0,0xfe0000,0x7f0500,0x0,0x14041438,0x41414141,0x41418e1e,0x7f7f7f7f,
02139 0x7c7c7c7c,0x7c431c1c,0x1c1c1c00,0xbc3e3e3e,0x3e10405c,0x3a3a3a3a,0x3a3a6e1c,0x3c3c3c3c,0x7c7c7c7c,0x3c423c3c,0x3c3c3c00,
02140 0x7c3a3a3a,0x3a087c08,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x4200000,0x10000020,0x0,0x0,0x10,0x0,0x30000000,0x0,
02141 0x0,0x0,0x60000,0x0,0x1c,0x4380000,0x0,0x2,0x800,0x0,0x40020000,0x0,0x8000c,0x10600000,0x2010,0x48000000,0x240000,0x0,0x0,
02142 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,
02143 0x84008,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x0,0x20000040,0x0,0x0,0x20,0x0,0x1e000000,0x0,0x0,0x0,0x20000,0x0,
02144 0x0,0x2000000,0x0,0x26,0x800,0x0,0x40020000,0x0,0x100000,0x10000000,0x2030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x1000,0x0,
02145 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,
02146 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,
02147 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,
02148 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,
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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02151 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02152 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
02153
02154
02155 const unsigned int font10x19[10*19*256/32] = {
02156 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02157 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,
02158 0x0,0x180181c0,0xe81b0300,0x1801,0x81c06c18,0x181c06c,0xe8180,0x181c0e81,0xb0000006,0x60701b,0x1800000,0x0,0x0,0x0,0x0,0x0,
02159 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02160 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,
02161 0x0,0x0,0x0,0x0,0x0,0x0,0xc030360,0xb81b0480,0xc03,0x3606c0c,0x303606c,0xb80c0,0x30360b81,0xb0000003,0xc0d81b,0x3000000,0x0,
02162 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,
02163 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,
02164 0x22000,0x0,0x0,0x0,0x0,0x0,0x0,0x30000,0x0,0xe0,0x38078000,0x0,0x480,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3000c080,0x480,0x3000,
02165 0xc0800030,0xc08000,0x300,0xc080000,0xc,0x302000,0xc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x41c01,0xe020060c,
02166 0x800000,0x4,0x1e0703e0,0xf8060fc1,0xe1fe1e07,0x80000000,0x78,0x307e0,0x3c7c1fe7,0xf83c408f,0x80f10440,0x18660878,0x7e0787e0,
02167 0x78ff9024,0xa0140a0,0x27f83840,0x700e000,0x18000400,0x8000,0x70004002,0x410078,0x0,0x0,0x0,0x0,0x1808,0xc000000,0xf000000,
02168 0xe000000,0x1400,0x1e0001f,0x8007f800,0x0,0x0,0x3a3b,0x61400000,0x14202,0x20000,0x38002020,0x3c1b00,0x3e00000,0xf8,0x1c0001c0,
02169 0x78060001,0xf800000e,0x1e00020,0x8004020,0xc0300c0,0x300c0301,0xf83c7f9f,0xe7f9fe3e,0xf83e0f8,0x7c1821e0,0x781e0781,0xe0001f10,
02170 0x24090240,0xa02400f8,0x18018140,0xe81b0480,0x1801,0x81406c18,0x181406c,0x190e8180,0x18140e81,0xb0000006,0x60501b,0x184006c,
02171 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x26042202,0x200c06,0x800000,0x8,0x210d0611,0x40e0803,0x10026188,0x40000000,
02172 0x8c,0xf030418,0xc6431004,0xc64082,0x110840,0x18660884,0x41084410,0x8c081024,0xa012110,0x40082020,0x101b000,0xc000400,0x8000,
02173 0x80004002,0x410008,0x0,0x0,0x100000,0x0,0x2008,0x2000000,0x18800000,0x10000000,0x2200,0x2300024,0x800,0x0,0x0,0x2e13,0x60800000,
02174 0x8104,0x20040,0x64001040,0x80401b07,0x80100000,0x1e000,0x22000020,0x40c0003,0xc8000002,0x3300020,0x8004020,0xc0300c0,0x300c0301,
02175 0x40c64010,0x4010008,0x2008020,0x43182210,0x84210842,0x10002190,0x24090240,0x9044018c,0xc030220,0xb81b0300,0xc03,0x2206c0c,
02176 0x302206c,0x1e0b80c0,0x30220b81,0xb0000003,0xc0881b,0x304006c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x241f2202,
02177 0x200802,0x4900000,0x8,0x21010408,0x20a0802,0x44090,0x20000000,0x4,0x11878408,0x80411004,0x804082,0x111040,0x1ce50986,0x40986409,
02178 0x81022,0x12012108,0x80102020,0x1031800,0x400,0x8000,0x80004000,0x10008,0x0,0x0,0x100000,0x0,0x2008,0x2000000,0x10000000,
02179 0x10000000,0x18,0x4000044,0x1000,0x30180,0xd81b0000,0x13,0xe0000000,0x88,0x40,0x400018c0,0x80400018,0x61f00000,0x61800,0x22020020,
02180 0x4000007,0xc8000002,0x2100020,0x8038000,0x1e0781e0,0x781e0301,0x40804010,0x4010008,0x2008020,0x41142619,0x86619866,0x18002190,
02181 0x24090240,0x8887e104,0x0,0x0,0x0,0x0,0x0,0x2000000,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x2434a202,
02182 0x200802,0x3e00000,0x10,0x40810008,0x21a0804,0x44090,0x20000000,0x80040004,0x20848409,0x409004,0x1004082,0x112040,0x14a50902,
02183 0x40902409,0x81022,0x11321208,0x80202010,0x1060c00,0x7c5e0,0x781e8783,0xf07a5f0e,0x1c10808,0xfc5f078,0x5e07a170,0x7c7e1024,
02184 0xa016190,0x27f82008,0x2000000,0x20000000,0x10000000,0x80200024,0x4000044,0x2000,0x18180,0xc8320000,0x12,0xa1f00037,0x7f888,
02185 0x1e0,0x40410880,0x80600017,0xa2100000,0x5e800,0x22020040,0x38001027,0xc8000002,0x2100020,0x8004020,0x12048120,0x48120482,
02186 0x41004010,0x4010008,0x2008020,0x40942409,0x2409024,0x9044390,0x24090240,0x88841918,0x1f07c1f0,0x7c1f07c3,0x70781e07,0x81e07838,
02187 0xe0380e0,0x1f17c1e0,0x781e0781,0xe0001f90,0x24090240,0x9025e102,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0xff241c41,
02188 0x1001,0x1c02000,0x10,0x40810008,0x6120f85,0xe0086190,0x20c03007,0x8007800c,0x27848419,0x409004,0x1004082,0x114040,0x14a48902,
02189 0x40902409,0x81022,0x11321205,0x602010,0x1000000,0x86610,0x84218840,0x80866182,0x411008,0x9261884,0x61086189,0x82101022,0x12012108,
02190 0x40082008,0x2000000,0x20030000,0x20000000,0x80200024,0x4000044,0x3006030,0xc018100,0x4c260000,0x12,0x26080048,0x83000850,
02191 0x20250,0x403e0500,0x8078002c,0x12302200,0x92400,0x1c0200c0,0x4001027,0xc8000002,0x3308820,0x8004020,0x12048120,0x48120482,
02192 0x41004010,0x4010008,0x2008020,0x40922409,0x2409024,0x8884690,0x24090240,0x85040920,0x21886218,0x86218860,0x88842108,0x42108408,
02193 0x2008020,0x21186210,0x84210842,0x10302190,0x24090240,0x88461084,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x4c240182,
02194 0x80001001,0x6b02000,0x20,0x4c810010,0x78220846,0x10081e10,0x20c0301c,0x1fe0e018,0x4d8487e1,0x409fe7,0xf9007f82,0x11a040,
02195 0x13248902,0x41102418,0xe0081022,0x11320c05,0x402008,0x1000000,0x2409,0x409020,0x81024082,0x412008,0x9240902,0x40902101,0x101022,
02196 0x11321208,0x40102008,0x2000000,0x7e0c8000,0xfc000003,0xf0fc0018,0x43802047,0x8c8040c8,0x32008300,0x44240000,0x0,0x4000048,
02197 0x8c801050,0x20440,0x40221dc0,0x808c0028,0x11d0667f,0x8009c400,0x1fc180,0x4001023,0xc8300002,0x1e0ccfb,0x3ec7b020,0x12048120,
02198 0x48120482,0x79007f9f,0xe7f9fe08,0x2008020,0xf0922409,0x2409024,0x8504490,0x24090240,0x85040920,0x802008,0x2008020,0x89004090,
02199 0x24090208,0x2008020,0x40902409,0x2409024,0x8304390,0x24090240,0x88440884,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,
02200 0x481c0606,0xc8001001,0x802000,0x20,0x4c810020,0x4220024,0x8102108,0x60000070,0x3820,0x48884419,0x409004,0x10e4082,0x112040,
02201 0x13244902,0x7e1027e0,0x3c081021,0x21320c02,0x802008,0x1000000,0x7e409,0x409020,0x81024082,0x414008,0x9240902,0x40902101,
02202 0x80101022,0x11320c08,0x40202008,0x2038800,0x200bc000,0x20000000,0x80200003,0x80f04044,0xbc080bc,0x2f000200,0x0,0x0,0x6001048,
02203 0x8bc02020,0x20441,0xf8220200,0x80820028,0x1000cc00,0x80094400,0x201e0,0x78001021,0xc830000f,0x8000663c,0xf03c0c0,0x21084210,
02204 0x84210846,0x41004010,0x4010008,0x2008020,0x40912409,0x2409024,0x8204890,0x24090240,0x82040930,0x1f87e1f8,0x7e1f87e0,0x89004090,
02205 0x24090208,0x2008020,0x40902409,0x2409024,0x8004690,0x24090240,0x88440884,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,
02206 0x480719c4,0x48001001,0x81fc00,0x7800020,0x40810040,0x2420024,0x8104087,0xa0000070,0x3820,0x48884409,0x409004,0x1024082,0x111040,
02207 0x13244902,0x40102410,0x2081021,0x214a1202,0x1802008,0x1000000,0x182409,0x409fe0,0x81024082,0x41a008,0x9240902,0x40902100,
02208 0xf8101021,0x214a0c04,0x80c0c008,0x1847000,0x7c1ee000,0x20000000,0x8020000c,0x8c044,0x1ee181ee,0x7b800000,0x707,0xf3ff0000,
02209 0x3e0084f,0x9ee0c020,0x20440,0x40221fc0,0xc2002c,0x13f11000,0x87892400,0x20000,0x1020,0x48000000,0x3f011c6,0x31cc6180,0x21084210,
02210 0x84210844,0x41004010,0x4010008,0x2008020,0x40912409,0x2409024,0x8505090,0x24090240,0x8204191c,0x60982609,0x82609823,0xf9007f9f,
02211 0xe7f9fe08,0x2008020,0x40902409,0x2409024,0x9fe4c90,0x24090240,0x84840848,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xfe048224,
02212 0x28001001,0x2000,0x40,0x40810080,0x27f8024,0x8104080,0x2000001c,0x1fe0e020,0x488fc409,0x409004,0x1024082,0x110840,0x10242902,
02213 0x40102408,0x2081021,0x214a1202,0x1002004,0x1000000,0x102409,0x409000,0x81024082,0x411008,0x9240902,0x40902100,0x6101021,
02214 0x214a0c04,0x81002008,0x2000000,0x201dc000,0x20000000,0x80200000,0x98044,0x1dc101dc,0x77000000,0x700,0x0,0x180448,0x1dc10020,
02215 0x20440,0x403e0200,0x620017,0xa000cc00,0x80052800,0x20000,0x1020,0x48000000,0x6606,0x206100,0x3f0fc3f0,0xfc3f0fc7,0xc1004010,
02216 0x4010008,0x2008020,0x4090a409,0x2409024,0x8886090,0x24090240,0x8207e106,0x40902409,0x2409024,0x81004010,0x4010008,0x2008020,
02217 0x40902409,0x2409024,0x8005890,0x24090240,0x84840848,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x98048224,0x30001001,0x2000,
02218 0x40,0x21010100,0x2020024,0x8204080,0x40000007,0x80078000,0x48884408,0x80411004,0x824082,0x110840,0x10242986,0x40086409,0x2081021,
02219 0xe14a2102,0x2002004,0x1000000,0x106409,0x409000,0x81024082,0x410808,0x9240902,0x40902100,0x2101021,0x214a1202,0x82002008,
02220 0x2000000,0x300f8000,0x20000000,0x80fc001d,0xe4088044,0xf8200f8,0x3e000000,0x300,0x0,0x80c48,0xf820020,0x20640,0x40410200,
02221 0x803c0018,0x60006600,0x61800,0x0,0x1020,0x48000000,0xcc0a,0x20a100,0x21084210,0x84210844,0x40804010,0x4010008,0x2008020,
02222 0x4110a619,0x86619866,0x19046110,0x24090240,0x82040102,0x41906419,0x6419064,0x81004010,0x4010008,0x2008020,0x40902409,0x2409024,
02223 0x8307090,0x24090240,0x82840828,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x90248222,0x30000802,0x200c,0xc080,0x21010301,
02224 0x4021042,0x10202108,0xc0c03000,0x80040020,0x4d902418,0xc6431004,0xc24082,0x6210440,0x10241884,0x40084409,0x86080840,0xc0842102,
02225 0x4002002,0x1000000,0x18e610,0x84218820,0x80864082,0x410408,0x9240884,0x61086101,0x6101860,0xc0842103,0x4002008,0x2000000,
02226 0x10850180,0x20330000,0x80200013,0x26184024,0x5040050,0x14000000,0x0,0x0,0x4180848,0x85040020,0x20350,0x40000200,0x800c0007,
02227 0x80002200,0x1e000,0x0,0x1860,0x48000000,0x880a,0x40a188,0x40902409,0x2409028,0x40c64010,0x4010008,0x2008020,0x43106210,0x84210842,
02228 0x10006108,0x42108421,0x2040102,0x6398e639,0x8e6398e4,0x88842088,0x22088208,0x2008020,0x21102210,0x84210842,0x10306118,0x66198661,
02229 0x83061030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0x901f01c1,0xe8000802,0xc,0xc080,0x1e07c7f8,0xf8020f81,0xe0401e07,
02230 0x80c03000,0x20,0x279027e0,0x3c7c1fe4,0x3c408f,0x83c1027f,0x90241878,0x4007c404,0xf8080780,0xc0844082,0x7f82002,0x1000000,
02231 0xfa5e0,0x781e87c0,0x807a409f,0xc0410207,0x9240878,0x5e07a100,0xf80e0fa0,0xc0846183,0x7f82008,0x2000000,0xf020100,0x40321360,
02232 0x80200014,0xa3e0201f,0x8207f820,0x8000000,0x0,0x0,0x3e01037,0x207f820,0x201e1,0xfc000200,0x80040000,0x0,0x0,0x1fc000,0x17b0,
02233 0x48000000,0x12,0xc120f0,0x40902409,0x2409028,0x783c7f9f,0xe7f9fe3e,0xf83e0f8,0x7c1061e0,0x781e0781,0xe000be07,0x81e0781e,
02234 0x204017c,0x3e8fa3e8,0xfa3e8fa3,0x70781f07,0xc1f07c7f,0x1fc7f1fc,0x1e1021e0,0x781e0781,0xe0007e0f,0xa3e8fa3e,0x8305e030,0x0,
02235 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,
02236 0x0,0x0,0x2001,0x1000000,0x0,0x0,0x20000,0x400000,0x0,0x40002000,0x0,0x1,0x2008,0x2000000,0x100,0x40240000,0x80200008,0x40000000,
02237 0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x80040000,0x0,0x0,0x0,0x1000,0x48000000,0x1f,0x181f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02238 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,
02239 0x0,0x0,0x0,0x6000,0x0,0x10000000,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x3800,0x7000000,0x0,0x0,0x840000,0x400000,0x0,0x40002000,
02240 0x0,0x2,0x2008,0x2000000,0x200,0x40440000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x80780000,0x0,0x0,0x0,0x1000,0x48000400,
02241 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,
02242 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,
02243 0x780000,0x3800000,0x0,0x40002000,0x0,0xe,0x1808,0xc000000,0x3,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000,
02244 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,
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,0x3fc,
02246 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,
02247 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
02248
02249
02250 const unsigned int font12x24[12*24*256/32] = {
02251 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02252 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,
02253 0x0,0x198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc001806,0xc81980,0x60000000,0xc001806,0x1980c00,0x18060198,0xc80c,
02254 0x180600,0xc8198000,0xc001,0x80601980,0x18000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02255 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02256 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,
02257 0x0,0x0,0x0,0x0,0x0,0x0,0x600300f,0x1301980,0x90000000,0x600300f,0x1980600,0x300f0198,0x13006,0x300f01,0x30198000,0x6003,
02258 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,
02259 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02260 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,
02261 0x80000000,0x90000000,0x3006019,0x80000300,0x60198000,0x3,0x601980,0x0,0x3006,0x1980000,0x60000000,0x0,0x0,0xe0000000,0x0,
02262 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02263 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,
02264 0x0,0x0,0x0,0x0,0x0,0xc800019,0x80000000,0x198000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x1001,0x420000,0x0,0x0,0x90000000,
02265 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000c06,0xc80001,0x10000000,0x18000c06,0x1800,0xc060000,0xc818,0xc0600,0xc8000000,
02266 0x18000,0xc0600000,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80660207,0x800f8060,0x300c004,0x0,0x6,
02267 0xe00703f,0x3f00383,0xf80f07fc,0x1f01f000,0x0,0xf8,0x607f,0x7c7e07,0xfe7fe0f8,0x6063fc1f,0x86066007,0xe7060f0,0x7f80f07f,
02268 0x81f8fff6,0x6606c03,0x70ee077f,0xe0786000,0xf0070000,0xc000060,0xc0,0x3e000,0x60006003,0x600fc00,0x0,0x0,0x0,0x0,0x0,0x3c0603,
02269 0xc0000000,0x7800000,0xf0000,0x0,0xf00001f,0x80001fe0,0x7fe000,0x0,0x0,0x0,0x168fe609,0x0,0x90e07,0x6000,0x3c000e,0x70000f8,
02270 0x1980001f,0x0,0x1f8,0xf00000f,0xf00180,0xfe000,0xe00e,0x1001,0x20060,0x6006006,0x600600,0x600fe07c,0x7fe7fe7f,0xe7fe3fc3,
02271 0xfc3fc3fc,0x7e07060f,0xf00f00,0xf00f0000,0xf360660,0x6606606e,0x76001e0,0xc00180f,0x1681981,0x10000000,0xc00180f,0x1980c00,
02272 0x180f0198,0x3801680c,0x180f01,0x68198000,0xc001,0x80f01980,0x18600198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,
02273 0x8044020c,0xc01f8060,0x2004004,0x0,0xc,0x3f81f07f,0x87f80383,0xf81f87fc,0x3f83f800,0x0,0x1fc,0x780607f,0x81fe7f87,0xfe7fe1fc,
02274 0x6063fc1f,0x860c6007,0xe7061f8,0x7fc1f87f,0xc3fcfff6,0x6606c03,0x30c6067f,0xe0783000,0xf00d8000,0x6000060,0xc0,0x7e000,0x60006003,
02275 0x600fc00,0x0,0x0,0xc00,0x0,0x0,0x7c0603,0xe0000000,0xfc00000,0x1f0000,0x0,0x900003f,0xc0003fe0,0x7fe000,0x0,0x0,0x0,0x1302660f,
02276 0x0,0xf0606,0x6004,0x7e0006,0x60601f8,0x19800001,0x80000000,0x1f8,0x19800010,0x81080300,0x3f2000,0x2011,0x1001,0x1c0060,0x6006006,
02277 0x600600,0x601fe1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f87061f,0x81f81f81,0xf81f8000,0x3fa60660,0x66066066,0x66003f0,0x6003009,
02278 0x1301981,0x10000000,0x6003009,0x1980600,0x30090198,0x1f013006,0x300901,0x30198000,0x6003,0x901980,0x30600198,0x0,0x0,0x0,
02279 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc0f8c,0xc0180060,0x6006044,0x40000000,0xc,0x3181b041,0xc41c0783,0x388018,
02280 0x71c71800,0x0,0x106,0x18c0f061,0xc38261c6,0x600384,0x60606001,0x86186007,0xe78630c,0x60e30c60,0xe7040606,0x630cc03,0x39c30c00,
02281 0xc0603000,0x3018c000,0x3000060,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600,0x60000000,0x18400000,0x180000,
02282 0x0,0x19800070,0x40003600,0xc000,0x0,0x0,0x0,0x25a06,0x0,0x6030c,0x4,0xe20007,0xe060180,0xf000,0x80000000,0xf0000,0x10800000,
02283 0x80080600,0x7f2000,0x2020,0x80001001,0x20000,0xf00f00f,0xf00f00,0x601b0382,0x60060060,0x6000600,0x60060060,0x61c78630,0xc30c30c3,
02284 0xc30c000,0x30e60660,0x66066063,0xc600738,0x3006019,0x80000000,0xe0000000,0x3006019,0x80000300,0x60198000,0x3e000003,0x601980,
02285 0x0,0x3006,0x1980000,0x60600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc1fcc,0xc0180060,0x6006035,0x80000000,
02286 0x18,0x71c03000,0xc00c0583,0x300018,0x60c60c00,0x0,0x6,0x3060f060,0xc30060c6,0x600300,0x60606001,0x86306007,0x9e78670e,0x60670e60,
02287 0x66000606,0x630c606,0x19830c01,0xc0601800,0x30306000,0x60,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600,
02288 0x60000000,0x18000000,0x300000,0x0,0x78060,0x6600,0x1c000,0x300c,0x39819c0,0x0,0x25a00,0x0,0x30c,0x4,0xc00003,0xc060180,0x30c1f,
02289 0x80000000,0x30c000,0x10800001,0x80700000,0x7f2000,0x2020,0x80001001,0x20060,0xf00f00f,0xf00f00,0xf01b0300,0x60060060,0x6000600,
02290 0x60060060,0x60c78670,0xe70e70e7,0xe70e000,0x70c60660,0x66066063,0xc7f8618,0x0,0x0,0x0,0x0,0x0,0x0,0x7000000,0x0,0x0,0x0,
02291 0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x87ff3a4c,0xc0180060,0x400600e,0x600000,0x18,0x60c03000,
02292 0xc00c0d83,0x700018,0x60c60c00,0x20,0x400006,0x3060f060,0xc6006066,0x600600,0x60606001,0x86606006,0x966c6606,0x60660660,0x66000606,
02293 0x630c666,0xf019801,0x80601800,0x30603000,0x1f06f,0xf01ec0,0xf03fe1ec,0x6703e01f,0x61c0c06,0xdc6701f0,0x6f01ec0c,0xe1f87fc6,
02294 0xc60cc03,0x71c60c7f,0xc0600600,0x60000000,0x30000000,0x300000,0x40040,0x88060,0x6600,0x18000,0x300c,0x1981980,0x0,0x2421f,
02295 0x80003ce0,0x7fc198,0x601f,0xc02021,0x980600c0,0x40230,0x80000000,0x402000,0x19806003,0x80006,0xc7f2000,0x2020,0x80001001,
02296 0x420060,0xf00f00f,0xf00f00,0xf01b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x6606208,0x60e60660,0x66066061,
02297 0x987fc670,0x1f01f01f,0x1f01f01,0xf039c0f0,0xf00f00f,0xf03e03,0xe03e03e0,0x1f06701f,0x1f01f01,0xf01f0060,0x1e660c60,0xc60c60c6,
02298 0xc6f060c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x7ff3207,0x8c0c0000,0xc00300e,0x600000,0x30,0x60c03000,
02299 0xc01c0983,0xf0600030,0x31860c06,0x6001e0,0x78000e,0x23e1f861,0xc6006066,0x600600,0x60606001,0x86c06006,0x966c6606,0x60660660,
02300 0xe7000606,0x630c666,0xf01f803,0x600c00,0x30000000,0x3f87f,0x83f83fc3,0xf83fe3fc,0x7f83e01f,0x6380c07,0xfe7f83f8,0x7f83fc0d,
02301 0xf3fc7fc6,0xc71cc03,0x3183187f,0xc0600600,0x60000000,0xff806000,0x300000,0x40040,0x88070,0x6600,0x60030060,0x6001818,0x1883180,
02302 0x0,0x2423f,0xc0007ff0,0x607fc1f8,0x603f,0x80c01fc1,0xf80601e0,0x5f220,0x80420000,0x5f2000,0xf006006,0x80006,0xc7f2000,0x2020,
02303 0x82107c07,0xc03c0060,0x1f81f81f,0x81f81f80,0xf03b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x660671c,0x61660660,
02304 0x66066061,0xf860e6c0,0x3f83f83f,0x83f83f83,0xf87fe3f8,0x3f83f83f,0x83f83e03,0xe03e03e0,0x3f87f83f,0x83f83f83,0xf83f8060,
02305 0x3fc60c60,0xc60c60c3,0x187f8318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x883200,0x300c0000,0xc003035,0x80600000,
02306 0x30,0x66c03001,0xc0f81983,0xf86f0030,0x1f071c06,0x600787,0xfe1e001c,0x6261987f,0x86006067,0xfe7fc600,0x7fe06001,0x87c06006,
02307 0xf6646606,0x60e6067f,0xc3e00606,0x61986f6,0x600f007,0x600c00,0x30000000,0x21c71,0x830831c3,0x1c06031c,0x71c06003,0x6700c06,
02308 0x6671c318,0x71831c0f,0x16040c06,0xc318606,0x1b031803,0x80600600,0x60000000,0x30009000,0x300000,0x40040,0x7003e,0x67e0,0x90070090,
02309 0x9001818,0x8c3100,0x0,0x60,0x4000e730,0x900380f0,0x6034,0x80c018c7,0xfe060338,0xb0121,0x80c60000,0x909000,0x6008,0x1080006,
02310 0xc3f2000,0x2011,0x3180060,0x60060e0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0x60664660,0x66066066,
02311 0x66063b8,0x62660660,0x66066060,0xf06066c0,0x21c21c21,0xc21c21c2,0x1c466308,0x31c31c31,0xc31c0600,0x60060060,0x31871c31,0x83183183,
02312 0x18318000,0x71860c60,0xc60c60c3,0x18718318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1981a00,0xe03e0000,0xc003044,
02313 0x40600000,0x60,0x66c03001,0x80f03182,0x1c7f8030,0x3f83fc06,0x601e07,0xfe078038,0x6661987f,0x86006067,0xfe7fc61e,0x7fe06001,
02314 0x87e06006,0x66666606,0x7fc6067f,0x81f80606,0x61986f6,0x6006006,0x600600,0x30000000,0xc60,0xc60060c6,0xc06060c,0x60c06003,
02315 0x6e00c06,0x6660c60c,0x60c60c0e,0x6000c06,0xc318666,0x1f031803,0x600600,0x603c2000,0x30016800,0x1fe0000,0x1f81f8,0x1c1f,0x804067e1,
02316 0x68060168,0x16800810,0xc42300,0x0,0x60,0x20c331,0x68030060,0x6064,0x3fc1040,0xf006031c,0xa011e,0x818c7fe0,0x909000,0x7fe1f,
02317 0x80f00006,0xc0f2060,0xf80e,0x18c0780,0x780781c0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0xfc666660,
02318 0x66066066,0x66061f0,0x66660660,0x66066060,0x606066e0,0xc00c00,0xc00c00c0,0xc066600,0x60c60c60,0xc60c0600,0x60060060,0x60c60c60,
02319 0xc60c60c6,0xc60c000,0x61c60c60,0xc60c60c3,0x1860c318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1980f81,0x80373000,
02320 0xc003004,0x7fe0001,0xf0000060,0x60c03003,0x183180,0xc71c060,0x3181ec00,0x7000,0xe070,0x66619860,0xc6006066,0x60061e,0x60606001,
02321 0x87606006,0x66626606,0x7f860661,0xc01c0606,0x6198696,0xf00600e,0x600600,0x30000000,0x1fc60,0xc60060c7,0xfc06060c,0x60c06003,
02322 0x7c00c06,0x6660c60c,0x60c60c0c,0x7f00c06,0xc3b8666,0xe01b007,0x3c00600,0x3c7fe000,0xff03ec00,0x1fe0000,0x40040,0xe001,0xc0806603,
02323 0xec0e03ec,0x3ec00010,0x0,0x60000000,0x7f,0x10c3f3,0xec070060,0x6064,0x3fc1040,0x6000030c,0xa0100,0x3187fe1,0xf09f1000,0x7fe00,
02324 0x6,0xc012060,0x0,0xc63c03,0xc03c0380,0x19819819,0x81981981,0x98330600,0x60060060,0x6000600,0x60060060,0xfc662660,0x66066066,
02325 0x66060e0,0x6c660660,0x66066060,0x6060e630,0x1fc1fc1f,0xc1fc1fc1,0xfc3fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6,
02326 0xc60c7fe,0x62c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe02c6,0x3c633000,0xc003004,
02327 0x7fe0001,0xf00000c0,0x60c03006,0xc6180,0xc60c060,0x60c00c00,0x7000,0xe060,0x66639c60,0x66006066,0x600606,0x60606001,0x86306006,
02328 0x66636606,0x60060660,0xc0060606,0x61f8696,0xf00600c,0x600300,0x30000000,0x3fc60,0xc60060c7,0xfc06060c,0x60c06003,0x7c00c06,
02329 0x6660c60c,0x60c60c0c,0x1f80c06,0xc1b0666,0xe01b00e,0x3c00600,0x3c43c000,0x3007de00,0x600000,0x40040,0x30000,0x61006607,0xde0c07de,
02330 0x7de00000,0x0,0xf07fefff,0x1f,0x8008c3f7,0xde0e0060,0x6064,0xc01047,0xfe00018c,0xb013f,0x86300061,0xf0911000,0x6000,0x6,
02331 0xc012060,0x3f,0x8063c0cc,0x3cc0c700,0x39c39c39,0xc39c39c1,0x98630600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066,
02332 0x66061f0,0x78660660,0x66066060,0x607fc618,0x3fc3fc3f,0xc3fc3fc3,0xfc7fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6,
02333 0xc60c7fe,0x64c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe0260,0x6661b000,0xc003000,
02334 0x600000,0xc0,0x60c0300c,0xc7fe0,0xc60c060,0x60c01c00,0x1e07,0xfe078060,0x6663fc60,0x66006066,0x600606,0x60606001,0x86386006,
02335 0x6636606,0x60060660,0xe0060606,0x60f039c,0x1b806018,0x600300,0x30000000,0x70c60,0xc60060c6,0x6060c,0x60c06003,0x7600c06,
02336 0x6660c60c,0x60c60c0c,0x1c0c06,0xc1b03fc,0xe01f01c,0xe00600,0x70000000,0x3007fc00,0x600000,0x40040,0x0,0x62006607,0xfc1807fc,
02337 0x7fc00000,0x0,0xf0000000,0x1,0xc004c307,0xfc1c0060,0x6064,0xc018c0,0x600000d8,0x5f200,0x3180060,0x50a000,0x6000,0x6,0xc012000,
02338 0x0,0xc601c0,0x4201c600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066,0x66063b8,
02339 0x70660660,0x66066060,0x607f860c,0x70c70c70,0xc70c70c7,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000,
02340 0x68c60c60,0xc60c60c1,0xf060c1f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3300260,0x6661e000,0xc003000,0x600000,
02341 0x180,0x71c03018,0xc7fe0,0xc60c0c0,0x60c01800,0x787,0xfe1e0060,0x6663fc60,0x630060c6,0x600306,0x60606001,0x86186006,0x661e70e,
02342 0x60070c60,0x60060606,0x60f039c,0x19806038,0x600180,0x30000000,0x60c60,0xc60060c6,0x6060c,0x60c06003,0x6700c06,0x6660c60c,
02343 0x60c60c0c,0xc0c06,0xc1b039c,0x1f00e018,0x600600,0x60000000,0x1803f800,0x600000,0x40040,0x39e00,0x63006603,0xf83803f8,0x3f800000,
02344 0x0,0x60000000,0x0,0xc00cc303,0xf8180060,0x6064,0xc01fc0,0x60060070,0x40200,0x18c0060,0x402000,0x6000,0x6,0xc012000,0x0,0x18c0140,
02345 0x2014600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0300,0x60060060,0x6000600,0x60060060,0x60c61e70,0xe70e70e7,0xe70e71c,0x60e60660,0x66066060,
02346 0x6060060c,0x60c60c60,0xc60c60c6,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000,0x70c60c60,0xc60c60c0,
02347 0xe060c0e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x33022e0,0x6670c000,0xc003000,0x600600,0x60180,0x31803030,
02348 0x41c0184,0x1831c0c0,0x71c23806,0x6001e0,0x780000,0x62630c60,0xe38261c6,0x600386,0x60606043,0x860c6006,0x661e30c,0x60030c60,
02349 0x740e0607,0xe0f039c,0x31c06030,0x600180,0x30000000,0x61c71,0x830831c3,0x406031c,0x60c06003,0x6300c06,0x6660c318,0x71831c0c,
02350 0x41c0c07,0x1c0e039c,0x1b00e030,0x600600,0x60000000,0x1c41b00e,0x601cc0,0x401f8,0x45240,0xe1803601,0xb03001b0,0x1b000000,
02351 0x0,0x0,0x41,0xc008e711,0xb0300060,0x6034,0x80c02020,0x60060030,0x30c00,0xc60000,0x30c000,0x0,0x7,0x1c012000,0x0,0x3180240,
02352 0x6024608,0x30c30c30,0xc30c30c3,0xc630382,0x60060060,0x6000600,0x60060060,0x61c61e30,0xc30c30c3,0xc30c208,0x70c70e70,0xe70e70e0,
02353 0x6060068c,0x61c61c61,0xc61c61c6,0x1cc62308,0x30430430,0x43040600,0x60060060,0x31860c31,0x83183183,0x18318060,0x31c71c71,
02354 0xc71c71c0,0xe07180e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2203fc0,0x663f6000,0x6006000,0x600600,0x60300,
02355 0x3f81fe7f,0xc7f80187,0xf83f80c0,0x3f83f006,0x600020,0x400060,0x33e6067f,0xc1fe7f87,0xfe6001fe,0x6063fc7f,0x60e7fe6,0x660e3f8,
02356 0x6001f860,0x37fc0603,0xfc06030c,0x30c0607f,0xe06000c0,0x30000000,0x7fc7f,0x83f83fc3,0xfc0603fc,0x60c7fe03,0x61807c6,0x6660c3f8,
02357 0x7f83fc0c,0x7f80fc3,0xfc0e039c,0x3180607f,0xc0600600,0x60000000,0xfc0e00c,0x601986,0x66040040,0x4527f,0xc0803fe0,0xe07fe0e0,
02358 0xe000000,0x0,0x0,0x7f,0x80107ff0,0xe07fc060,0x603f,0x83fe0000,0x60060018,0xf000,0x420000,0xf0000,0x7fe00,0x7,0xfe012000,
02359 0x0,0x2100640,0xc0643f8,0x60660660,0x66066067,0xec3e1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f860e3f,0x83f83f83,0xf83f8000,
02360 0x5fc3fc3f,0xc3fc3fc0,0x606006fc,0x7fc7fc7f,0xc7fc7fc7,0xfcffe3f8,0x3fc3fc3f,0xc3fc7fe7,0xfe7fe7fe,0x3f860c3f,0x83f83f83,
02361 0xf83f8060,0x7f83fc3f,0xc3fc3fc0,0x607f8060,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2201f80,0x3c1e7000,0x6006000,
02362 0x600,0x60300,0xe01fe7f,0xc3f00183,0xe01f0180,0x1f01e006,0x600000,0x60,0x3006067f,0x807c7e07,0xfe6000f8,0x6063fc3e,0x6067fe6,
02363 0x660e0f0,0x6000f060,0x3bf80601,0xf806030c,0x60e0607f,0xe06000c0,0x30000000,0x1ec6f,0xf01ec0,0xf80601ec,0x60c7fe03,0x61c03c6,
02364 0x6660c1f0,0x6f01ec0c,0x3f007c1,0xcc0e030c,0x71c0c07f,0xc0600600,0x60000000,0x7804018,0xe01186,0x66040040,0x39e3f,0x80401fe0,
02365 0x407fe040,0x4000000,0x0,0x0,0x3f,0x203ce0,0x407fc060,0x601f,0x3fe0000,0x60060018,0x0,0x0,0x0,0x7fe00,0x6,0xe6012000,0x0,
02366 0x7e0,0x1807e1f0,0x60660660,0x66066066,0x6c3e07c,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7e060e0f,0xf00f00,0xf00f0000,0x8f01f81f,
02367 0x81f81f80,0x60600670,0x1ec1ec1e,0xc1ec1ec1,0xec79c0f0,0xf80f80f,0x80f87fe7,0xfe7fe7fe,0x1f060c1f,0x1f01f01,0xf01f0000,0x4f01cc1c,
02368 0xc1cc1cc0,0xc06f00c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x6006000,0x600,0x600,0x0,0x0,0x0,0x0,
02369 0x600000,0x0,0x18000000,0x0,0x0,0x0,0x0,0x0,0x1800,0x0,0x0,0x0,0x600060,0x30000000,0x0,0x0,0xc,0x3,0x0,0x0,0x60000c00,0x0,
02370 0x0,0xc000,0x600600,0x60000000,0x18,0xc03100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f8,0x0,0x0,0x0,0x0,0x6,
02371 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,
02372 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,
02373 0x0,0x1c000000,0x0,0x0,0x0,0x0,0x0,0xc00,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x21c,0x3,0x0,0x0,0x60000c00,0x0,0x0,0xc000,
02374 0x7c0603,0xe0000000,0x10,0xc02300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f0,0x0,0x0,0x0,0x0,0x6,0x12000,0x1000000,
02375 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,
02376 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,
02377 0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x3f8,0x3e,0x0,0x0,0x60000c00,0x0,0x0,0x38000,0x3c0603,0xc0000000,
02378 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,
02379 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,
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,0xffc,0x0,
02381 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,
02382 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,
02383 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,
02384 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,
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 };
02387
02388
02389 const unsigned int font16x32[16*32*256/32] = {
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,0x0,
02392 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,
02393 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70000e0,0x3c00730,0xe7001c0,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0x730,0x70000e0,0x3c00730,
02394 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,
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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02397 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,
02398 0x0,0x0,0x18001c0,0x6600ff0,0xe7003e0,0x0,0x18001c0,0x6600e70,0x18001c0,0x6600e70,0xff0,0x18001c0,0x6600ff0,0xe700000,0x180,
02399 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,
02400 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0x0,0x0,0x0,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,
02402 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,
02403 0xc300ce0,0xe700630,0x0,0x1c00380,0xc300e70,0x1c00380,0xc300e70,0xce0,0x1c00380,0xc300ce0,0xe700000,0x1c0,0x3800c30,0xe700380,
02404 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,
02405 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02406 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,
02407 0x0,0x0,0x0,0x0,0x0,0xc300000,0x0,0xc300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x700000,0x0,0x0,0x0,0x7c007c00,0x3e000000,
02408 0x0,0x0,0x630,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe000070,0x1800000,0xc60,0x0,0xe000070,0x1800000,0xe000070,
02409 0x1800000,0x0,0xe000070,0x1800000,0x0,0xe00,0x700180,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02410 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,
02411 0x0,0x0,0x3f0,0xfc0,0x0,0x7000000,0x38000000,0x1c0000,0xfc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,
02412 0x1801f00,0x0,0x0,0x1c,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7300000,0x6600000,0x0,0x6600000,0x0,0x0,0x0,0x0,0xe700000,
02413 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,
02414 0xf80,0x70000e0,0x3c00730,0xe700c60,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0xe000730,0x70000e0,0x3c00730,0xe700000,0x700,
02415 0xe003c0,0xe7000e0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300000,0x803c00,0x7c00180,
02416 0xc00300,0x1000000,0x0,0x1c,0x3c007c0,0xfc007e0,0xe01ff8,0x3f03ffc,0x7e007c0,0x0,0x0,0x7c0,0x1c0,0x7f8003f0,0x7f007ff8,0x7ff803f0,
02417 0x70381ffc,0xff0700e,0x7000783c,0x783807c0,0x7fc007c0,0x7fc00fc0,0x7fff7038,0x700ee007,0x780f780f,0x7ffc03f0,0x70000fc0,0x3c00000,
02418 0x3000000,0x38000000,0x1c0000,0x1fc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x1801f80,0x0,0x1f80000,
02419 0x7e,0x0,0x0,0x2400000,0xfc00000,0x7ff0000,0x7ffc0000,0x0,0x0,0x0,0x0,0xf30fb0c,0x2400000,0x0,0x240780f,0x1c0,0xfc,0x780f,
02420 0x18003f0,0xe700000,0x7c00000,0x0,0xff0,0x3c00000,0x78007c0,0xc00000,0xff80000,0xf80,0x7c00000,0xc000c00,0x18001c0,0x1c001c0,
02421 0x1c001c0,0x1c003e0,0x7fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007838,0x7c007c0,0x7c007c0,0x7c00000,0x7c67038,
02422 0x70387038,0x7038780f,0x70001fe0,0x30000c0,0x2400f30,0xe700c60,0x0,0x30000c0,0x2400e70,0x30000c0,0x2400e70,0xf700f30,0x30000c0,
02423 0x2400f30,0xe700000,0x300,0xc00240,0xe7000c0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,
02424 0x630018c,0x807e00,0xfe00180,0xc00300,0x1000000,0x0,0x38,0xff01fc0,0x3ff01ff0,0x1e01ff8,0x7f83ffc,0x1ff80ff0,0x0,0x0,0xff0,
02425 0x1f003e0,0x7fe00ff8,0x7fc07ff8,0x7ff80ff8,0x70381ffc,0xff0701c,0x7000783c,0x78381ff0,0x7fe01ff0,0x7fe01ff0,0x7fff7038,0x781ee007,
02426 0x3c1e380e,0x7ffc0380,0x380001c0,0x3c00000,0x1800000,0x38000000,0x1c0000,0x3c00000,0x380001c0,0xe01c00,0x3800000,0x0,0x0,
02427 0x0,0x7000000,0x0,0x0,0x1e0,0x18003c0,0x0,0x3fc0000,0x70,0x0,0x0,0x6600000,0x1ff00000,0x1fff0000,0x7ffc0000,0x0,0x0,0x0,0x0,
02428 0xcf0239c,0x3c00000,0x0,0x3c0380e,0x1c0,0x2001fe,0x380e,0x18007f8,0xe700000,0x8600000,0x0,0xff0,0x7e00000,0x8c00870,0x1800000,
02429 0x1ff80000,0x180,0xc600000,0xc000c00,0x38001c0,0x3e003e0,0x3e003e0,0x3e001c0,0x7fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,
02430 0x7fc07838,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x1fec7038,0x70387038,0x7038380e,0x70003ce0,0x1800180,0x6600cf0,0xe7007c0,0x0,
02431 0x1800180,0x6600e70,0x1800180,0x6600e70,0x7c00cf0,0x1800180,0x6600cf0,0xe700000,0x180,0x1800660,0xe700180,0x38000e70,0x0,
02432 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630030c,0x3f0e700,0x1e200180,0x1800180,0x21100000,0x0,
02433 0x38,0x1e7819c0,0x38781038,0x1e01c00,0xf080038,0x1c381c38,0x0,0x0,0x1878,0x7fc03e0,0x70e01e18,0x70e07000,0x70001e18,0x703801c0,
02434 0x707038,0x70007c7c,0x7c381c70,0x70701c70,0x70703830,0x1c07038,0x381ce007,0x1c1c3c1e,0x3c0380,0x380001c0,0x7e00000,0xc00000,
02435 0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0,0x70c0000,0xe0,
02436 0x0,0x0,0xc300000,0x38300000,0x3c700000,0x3c0000,0x0,0x0,0x0,0x0,0xce022f4,0x1800000,0x0,0x1803c1e,0x1c0,0x2003c2,0x3c1e,
02437 0x1800e08,0x7e0,0x300000,0x0,0x7e00000,0xe700000,0x600030,0x3000000,0x3f980000,0x180,0x18200000,0xc000c00,0x1e0001c0,0x3e003e0,
02438 0x3e003e0,0x3e003e0,0xfe01e18,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70e07c38,0x1c701c70,0x1c701c70,0x1c700000,0x3c787038,
02439 0x70387038,0x70383c1e,0x70003870,0xc00300,0xc300ce0,0x380,0x0,0xc00300,0xc300000,0xc00300,0xc300000,0xfc00ce0,0xc00300,0xc300ce0,
02440 0x0,0xc0,0x3000c30,0x300,0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630031c,0xff8c300,
02441 0x1c000180,0x1800180,0x39380000,0x0,0x70,0x1c3801c0,0x203c001c,0x3e01c00,0x1c000038,0x381c3838,0x0,0x0,0x1038,0xe0e03e0,0x70703c08,
02442 0x70707000,0x70003808,0x703801c0,0x707070,0x70007c7c,0x7c383838,0x70383838,0x70387010,0x1c07038,0x381c700e,0x1e3c1c1c,0x780380,
02443 0x1c0001c0,0xe700000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,
02444 0x0,0xe000000,0xe0,0x0,0x1000100,0x3800,0x70100000,0x38700000,0x780000,0x1c0,0x7801ce0,0xe380000,0x0,0x2264,0x0,0x0,0x1c1c,
02445 0x0,0x200780,0x1c1c,0x1800c00,0x1818,0x7f00000,0x0,0x18180000,0xc300000,0x600070,0x0,0x7f980000,0x180,0x18300000,0xc000c00,
02446 0x3000000,0x3e003e0,0x3e003e0,0x3e003e0,0xee03c08,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838,
02447 0x38380000,0x38387038,0x70387038,0x70381c1c,0x7fc03870,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xbc00000,0x0,0x0,0x0,0x0,0x0,0x0,
02448 0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0xe88c300,0x1c000180,0x38001c0,
02449 0xfe00180,0x0,0x70,0x1c3801c0,0x1c001c,0x6e01c00,0x1c000078,0x381c3818,0x0,0x40000,0x40000038,0x1c0607e0,0x70703800,0x70707000,
02450 0x70003800,0x703801c0,0x7070e0,0x70007c7c,0x7c383838,0x70383838,0x70387000,0x1c07038,0x381c700e,0xf780e38,0x700380,0x1c0001c0,
02451 0x1c380000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0,
02452 0xe000000,0xe0,0x0,0x1000100,0x4400,0x70000000,0x38700000,0x700000,0xe0,0x7001c70,0xe380000,0x0,0x2264,0x0,0x0,0xe38,0x0,
02453 0x200700,0xe38,0x1800c00,0x300c,0xc300000,0x0,0x300c0000,0xc300180,0x6003c0,0x0,0x7f980000,0x180,0x18300000,0xc000c00,0x1800000,
02454 0x7e007e0,0x7e007e0,0x7e003e0,0xee03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838,0x38380000,
02455 0x38387038,0x70387038,0x70380e38,0x7ff039f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e00000,0x0,0x0,0x0,0x40000,0x0,0x0,0x38000000,
02456 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0x1c80e700,0x1c000180,0x38001c0,0x3800180,
02457 0x0,0xe0,0x381c01c0,0x1c001c,0x6e01c00,0x38000070,0x381c381c,0x0,0x3c0000,0x78000078,0x38030770,0x70707800,0x70387000,0x70007000,
02458 0x703801c0,0x7071c0,0x7000745c,0x7638701c,0x7038701c,0x70387000,0x1c07038,0x1c38718e,0x7700f78,0xf00380,0xe0001c0,0x381c0000,
02459 0x7e0,0x39e003e0,0x79c03f0,0x3ffc079c,0x39e01fc0,0xfe01c1e,0x3807778,0x39e007e0,0x39e0079c,0x73c07e0,0x7ff83838,0x701ce007,
02460 0x783c701c,0x1ffc01c0,0x18001c0,0x0,0x1c000100,0xe0,0x0,0x1000100,0x4200,0x70000000,0x70700100,0xf00100,0x10000e0,0x7000c70,
02461 0xc700000,0x0,0x2204,0x7e00000,0x1e380100,0x1ffc0f78,0x0,0xf80700,0xf78,0x1800e00,0x63e6,0x18300000,0x0,0x6fe60000,0xe700180,
02462 0xc00060,0x3838,0x7f980000,0x180,0x18300000,0xc000c00,0x18001c0,0x7700770,0x7700770,0x77007f0,0xee07800,0x70007000,0x70007000,
02463 0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1008,0x707c7038,0x70387038,0x70380f78,0x707039c0,0x7e007e0,0x7e007e0,
02464 0x7e007e0,0x1f3c03e0,0x3f003f0,0x3f003f0,0x1fc01fc0,0x1fc01fc0,0x7f039e0,0x7e007e0,0x7e007e0,0x7e00380,0x7ce3838,0x38383838,
02465 0x3838701c,0x39e0701c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6307fff,0x1c807e0c,0xe000180,
02466 0x30000c0,0x3800180,0x0,0xe0,0x381c01c0,0x1c001c,0xce01fe0,0x38000070,0x381c381c,0x3800380,0xfc0000,0x7e0000f0,0x30030770,
02467 0x70707000,0x70387000,0x70007000,0x703801c0,0x707380,0x700076dc,0x7638701c,0x7038701c,0x70387800,0x1c07038,0x1c3873ce,0x7f00770,
02468 0xe00380,0xe0001c0,0x700e0000,0x1ff8,0x3ff00ff0,0xffc0ff8,0x3ffc0ffc,0x3bf01fc0,0xfe01c3c,0x3807f78,0x3bf00ff0,0x3ff00ffc,
02469 0x77e0ff0,0x7ff83838,0x3838e007,0x3c783838,0x1ffc01c0,0x18001c0,0x0,0x7ff00380,0x1e0,0x0,0x1000100,0x4200,0x78000000,0x70700380,
02470 0xe00380,0x3800060,0xe000e30,0x1c600000,0x0,0x2204,0xff00000,0x7f7c0380,0x1ffc0770,0x1c0,0x3fc0700,0x18040770,0x1800780,0x4e12,
02471 0x18300104,0x0,0x4c320000,0x7e00180,0x1c00030,0x3838,0x7f980000,0x180,0x18302080,0xc000c00,0x18001c0,0x7700770,0x7700770,
02472 0x7700770,0x1ee07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c381c,0x705c7038,0x70387038,
02473 0x70380770,0x70383b80,0x1ff81ff8,0x1ff81ff8,0x1ff81ff8,0x3fbe0ff0,0xff80ff8,0xff80ff8,0x1fc01fc0,0x1fc01fc0,0xff83bf0,0xff00ff0,
02474 0xff00ff0,0xff00380,0xffc3838,0x38383838,0x38383838,0x3ff03838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02475 0x0,0x1c0,0x7fff,0x1c803c38,0xf000000,0x70000e0,0xfe00180,0x0,0x1c0,0x381c01c0,0x3c0078,0xce01ff0,0x39e000f0,0x1c38381c,0x3800380,
02476 0x3e07ffc,0xf8001f0,0x307b0770,0x70e07000,0x70387000,0x70007000,0x703801c0,0x707700,0x700076dc,0x7638701c,0x7038701c,0x70387e00,
02477 0x1c07038,0x1c3873ce,0x3e007f0,0x1e00380,0x70001c0,0x0,0x1038,0x3c381e18,0x1c7c1e3c,0x3801e3c,0x3c7801c0,0xe01c78,0x380739c,
02478 0x3c781c38,0x3c381c3c,0x7c21e10,0x7003838,0x3838700e,0x1ef03838,0x3c01c0,0x18001c0,0x0,0x7fe007c0,0x1c0,0x0,0x1000100,0x6400,
02479 0x7e000000,0x707007c0,0x1e007c0,0x7c00070,0xe000638,0x18600000,0x0,0x0,0x1e100000,0x73ce07c0,0x3c07f0,0x1c0,0x7240700,0x1ddc3ffe,
02480 0x1800de0,0x8c01,0x1870030c,0x0,0x8c310000,0x3c00180,0x3800030,0x3838,0x7f980000,0x180,0x183030c0,0xc000c00,0x430001c0,0x7700770,
02481 0x7700770,0x7700770,0x1ce07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1c38,0x70dc7038,
02482 0x70387038,0x703807f0,0x70383b80,0x10381038,0x10381038,0x10381038,0x21e71e18,0x1e3c1e3c,0x1e3c1e3c,0x1c001c0,0x1c001c0,0x1e383c78,
02483 0x1c381c38,0x1c381c38,0x1c380380,0x1c383838,0x38383838,0x38383838,0x3c383838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02484 0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0x1e8000e0,0x1f000000,0x70000e0,0x39380180,0x0,0x1c0,0x3b9c01c0,0x3c07f0,0x18e01078,0x3bf800e0,
02485 0x7e0383c,0x3800380,0x1f807ffc,0x3f001c0,0x61ff0e38,0x7fc07000,0x70387ff0,0x7ff07000,0x7ff801c0,0x707f00,0x7000729c,0x7338701c,
02486 0x7070701c,0x70703fc0,0x1c07038,0x1e7873ce,0x1c003e0,0x3c00380,0x70001c0,0x0,0x1c,0x3c381c00,0x1c3c1c1c,0x3801c3c,0x383801c0,
02487 0xe01cf0,0x380739c,0x38381c38,0x3c381c3c,0x7801c00,0x7003838,0x3838700e,0xfe03c78,0x7801c0,0x18001c0,0x0,0x1c000c20,0xff8,
02488 0x0,0x1ff01ff0,0x3818,0x3fc00100,0x707e0c20,0x3c00c20,0xc200030,0xc000618,0x18c00000,0x0,0x0,0x1c000080,0xe1ce0c20,0x7803e0,
02489 0x1c0,0xe200700,0xff83ffe,0x1801878,0x9801,0x1cf0071c,0x7ffc0000,0x8c310000,0x7ffe,0x7000030,0x3838,0x3f980380,0x180,0xc6038e0,
02490 0x7f9c7f9c,0x3e1c01c0,0xe380e38,0xe380e38,0xe380f78,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0,0x1c001c0,0xfe387338,0x701c701c,
02491 0x701c701c,0x701c0e70,0x719c7038,0x70387038,0x703803e0,0x70383b80,0x1c001c,0x1c001c,0x1c001c,0xe71c00,0x1c1c1c1c,0x1c1c1c1c,
02492 0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380000,0x3c383838,0x38383838,0x38383c78,0x3c383c78,0x0,0x0,0x0,0x0,
02493 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0xf800380,0x3f830000,0x70000e0,0x31080180,0x0,0x380,0x3b9c01c0,
02494 0x7807e0,0x38e00038,0x3c3800e0,0xff01c3c,0x3800380,0x7c000000,0x7c03c0,0x61870e38,0x7fc07000,0x70387ff0,0x7ff070fc,0x7ff801c0,
02495 0x707f80,0x7000739c,0x7338701c,0x7ff0701c,0x7fe00ff0,0x1c07038,0xe7073ce,0x1c003e0,0x3800380,0x38001c0,0x0,0x1c,0x381c3800,
02496 0x381c380e,0x380381c,0x383801c0,0xe01de0,0x380739c,0x3838381c,0x381c381c,0x7001e00,0x7003838,0x1c70718e,0x7e01c70,0xf00380,
02497 0x18001e0,0x1e000000,0x1c001bb0,0xff8,0x0,0x1000100,0xe0,0xff00300,0x707e1bb0,0x3801bb0,0x1bb00010,0x8000308,0x30c00000,0x0,
02498 0x0,0x1e0000c0,0xe1ce1bb0,0xf003e0,0x1c0,0x1c203ff8,0x63003e0,0x180181c,0x9801,0xfb00e38,0x7ffc0000,0x8fc10000,0x7ffe,0xe000860,
02499 0x3838,0x1f980380,0x180,0x7c01c70,0x1f001f0,0x1f003c0,0xe380e38,0xe380e38,0xe380e38,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0,
02500 0x1c001c0,0xfe387338,0x701c701c,0x701c701c,0x701c07e0,0x731c7038,0x70387038,0x703803e0,0x70383980,0x1c001c,0x1c001c,0x1c001c,
02501 0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x387c3838,0x38383838,0x38381c70,
02502 0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc30,0x7f00e00,0x33c30000,0x70000e0,0x1007ffe,
02503 0x0,0x380,0x3b9c01c0,0xf00078,0x30e0001c,0x3c1c01c0,0x1c381fdc,0x0,0x70000000,0x1c0380,0x63030e38,0x70707000,0x70387000,0x700070fc,
02504 0x703801c0,0x707b80,0x7000739c,0x7338701c,0x7fc0701c,0x7fc001f0,0x1c07038,0xe703e5c,0x3e001c0,0x7800380,0x38001c0,0x0,0x7fc,
02505 0x381c3800,0x381c380e,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7001fc0,0x7003838,0x1c70718e,0x7c01c70,
02506 0xe01f00,0x180007c,0x7f8c0000,0x7fc03fb8,0x1c0,0x0,0x1000100,0x700,0x1f00600,0x70703fb8,0x7803fb8,0x3fb80000,0x8000000,0x180,
02507 0x0,0x0,0x1fc00060,0xe1ce3fb8,0xe001c0,0x1c0,0x1c203ff8,0xc1801c0,0x180c,0x9801,0x1c70,0xc0000,0x8cc10000,0x180,0xfe007c0,
02508 0x3838,0x7980380,0xff0,0xe38,0x3e003e00,0x3e000380,0xe380e38,0xe380e38,0xe380e38,0x38e07000,0x70007000,0x70007000,0x1c001c0,
02509 0x1c001c0,0x70387338,0x701c701c,0x701c701c,0x701c03c0,0x731c7038,0x70387038,0x703801c0,0x703838e0,0x7fc07fc,0x7fc07fc,0x7fc07fc,
02510 0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x38dc3838,0x38383838,0x38381c70,
02511 0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc60,0xf83878,0x71e30000,0x70000e0,0x1007ffe,
02512 0x7f0,0x380,0x381c01c0,0x1e0003c,0x60e0001c,0x381c01c0,0x381c079c,0x0,0x7c000000,0x7c0380,0x63031c1c,0x70307000,0x70387000,
02513 0x7000701c,0x703801c0,0x7071c0,0x7000739c,0x71b8701c,0x7000701c,0x71e00078,0x1c07038,0xe703e7c,0x7e001c0,0xf000380,0x38001c0,
02514 0x0,0x1ffc,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fc0,0x380739c,0x3838381c,0x381c381c,0x7000ff0,0x7003838,0x1ef03bdc,
02515 0x3800ee0,0x1e01f00,0x180007c,0x61fc0000,0x7fc07f3c,0x1c0,0x0,0x1000100,0x1800,0x780c00,0x70707f3c,0xf007f3c,0x7f3c0000,0x0,
02516 0x3c0,0x3ffcffff,0x0,0xff00030,0xe1fe7f3c,0x1e001c0,0x1c0,0x1c200700,0xc183ffe,0xe0c,0x9801,0x1ff038e0,0xc07f0,0x8c610000,
02517 0x180,0x0,0x3838,0x1980380,0x0,0x1ff0071c,0xe000e000,0xe0000f80,0x1c1c1c1c,0x1c1c1c1c,0x1c1c1e38,0x38e07000,0x70007000,0x70007000,
02518 0x1c001c0,0x1c001c0,0x703871b8,0x701c701c,0x701c701c,0x701c03c0,0x761c7038,0x70387038,0x703801c0,0x70703870,0x1ffc1ffc,0x1ffc1ffc,
02519 0x1ffc1ffc,0xfff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x389c3838,0x38383838,
02520 0x38380ee0,0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xfffc,0xbc60fc,0x70e30000,0x70000e0,
02521 0x180,0x7f0,0x700,0x381c01c0,0x3e0001c,0x7ffc001c,0x381c03c0,0x381c001c,0x0,0x1f807ffc,0x3f00380,0x63031ffc,0x70387000,0x70387000,
02522 0x7000701c,0x703801c0,0x7071e0,0x7000701c,0x71b8701c,0x7000701c,0x70f00038,0x1c07038,0x7e03e7c,0x77001c0,0xe000380,0x1c001c0,
02523 0x0,0x3c1c,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x70003f8,0x7003838,0xee03bdc,
02524 0x3c00ee0,0x3c00380,0x18000e0,0xf00000,0x1c007e7c,0x3c0,0x0,0x1000100,0x0,0x381800,0x70707e7c,0xe007e7c,0x7e7c0000,0x0,0x7c0,
02525 0x0,0x0,0x3f80018,0xe1fe7e7c,0x3c001c0,0x1c0,0x1c200700,0xc183ffe,0xf0c,0x8c01,0x38e0,0xc07f0,0x8c710000,0x180,0x0,0x3838,
02526 0x1980000,0x0,0x71c,0x7000f0,0x700f00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x3fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
02527 0x703871b8,0x701c701c,0x701c701c,0x701c07e0,0x7c1c7038,0x70387038,0x703801c0,0x7ff03838,0x3c1c3c1c,0x3c1c3c1c,0x3c1c3c1c,
02528 0x3fff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x391c3838,0x38383838,0x38380ee0,
02529 0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfffc,0x9c01ce,0x70f60000,0x70000e0,0x180,
02530 0x0,0x700,0x381c01c0,0x780001c,0x7ffc001c,0x381c0380,0x381c003c,0x0,0x3e07ffc,0xf800380,0x63031ffc,0x70387000,0x70387000,
02531 0x7000701c,0x703801c0,0x7070f0,0x7000701c,0x71b8701c,0x7000701c,0x70700038,0x1c07038,0x7e03e7c,0xf7801c0,0x1e000380,0x1c001c0,
02532 0x0,0x381c,0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7000078,0x7003838,0xee03a5c,
02533 0x7c00fe0,0x78001c0,0x18001c0,0x0,0x1c003ef8,0x380,0x0,0x1000100,0x810,0x383000,0x70703ef8,0x1e003ef8,0x3ef80000,0x0,0x7c0,
02534 0x0,0x0,0x78000c,0xe1c03ef8,0x78001c0,0x1c0,0x1c200700,0x63001c0,0x18003f8,0x4e12,0x1c70,0xc0000,0x4c320000,0x180,0x0,0x3838,
02535 0x1980000,0x0,0xe38,0x700118,0x701e00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x7fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
02536 0x703871b8,0x701c701c,0x701c701c,0x701c0e70,0x7c1c7038,0x70387038,0x703801c0,0x7fc0381c,0x381c381c,0x381c381c,0x381c381c,
02537 0x78e03800,0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x3b1c3838,0x38383838,0x38380fe0,
02538 0x381c0fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1860,0x9c0186,0x707e0000,0x30000c0,0x180,
02539 0x0,0xe00,0x183801c0,0xf00001c,0xe0001c,0x181c0380,0x381c0038,0x0,0xfc0000,0x7e000000,0x61873c1e,0x70383800,0x70707000,0x7000381c,
02540 0x703801c0,0x707070,0x7000701c,0x70f83838,0x70003838,0x70780038,0x1c07038,0x7e03c3c,0xe3801c0,0x1c000380,0xe001c0,0x0,0x381c,
02541 0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01ef0,0x380739c,0x3838381c,0x381c381c,0x7000038,0x7003838,0xfe03e7c,0xfe007c0,
02542 0x70001c0,0x18001c0,0x0,0xe001ff0,0x380,0x0,0x1000100,0x162c,0x381800,0x30701ff0,0x1c001ff0,0x1ff00000,0x0,0x3c0,0x0,0x0,
02543 0x380018,0xe1c01ff0,0x70001c0,0x1c0,0x1c200700,0xff801c0,0x18000f0,0x63e6,0xe38,0x0,0x6c3e0000,0x0,0x0,0x3838,0x1980000,0x0,
02544 0x1c70,0xf0000c,0xf01c00,0x3c1e3c1e,0x3c1e3c1e,0x3c1e3c1c,0x70e03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x707070f8,
02545 0x38383838,0x38383838,0x38381c38,0x38387038,0x70387038,0x703801c0,0x7000381c,0x381c381c,0x381c381c,0x381c381c,0x70e03800,
02546 0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0380,0x3e1c3838,0x38383838,0x383807c0,0x381c07c0,
02547 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18c0,0x9c0186,0x783c0000,0x38001c0,0x180,0x3800000,
02548 0x3800e00,0x1c3801c0,0x1e00003c,0xe00038,0x1c1c0780,0x381c0038,0x3800380,0x3c0000,0x78000000,0x61ff380e,0x70383808,0x70707000,
02549 0x7000381c,0x703801c0,0x40707078,0x7000701c,0x70f83838,0x70003838,0x70384038,0x1c07038,0x7e03c3c,0x1e3c01c0,0x3c000380,0xe001c0,
02550 0x0,0x383c,0x3c381c00,0x1c3c1c00,0x3801c3c,0x383801c0,0xe01c78,0x380739c,0x38381c38,0x3c381c3c,0x7000038,0x7003878,0x7c01e78,
02551 0x1ef007c0,0xf0001c0,0x18001c0,0x0,0xe000ee0,0x7800380,0xe380000,0x1001ff0,0x2242,0x40380c00,0x38700ee0,0x3c000ee0,0xee00000,
02552 0x0,0x0,0x0,0x0,0x380030,0xe1c00ee0,0xf0001c0,0x1c0,0xe200700,0xdd801c0,0x1800038,0x300c,0x71c,0x0,0x300c0000,0x0,0x0,0x3838,
02553 0x1980000,0x0,0x38e0,0xb0000c,0xb01c08,0x380e380e,0x380e380e,0x380e380e,0x70e03808,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
02554 0x707070f8,0x38383838,0x38383838,0x3838381c,0x38387038,0x70387038,0x703801c0,0x7000381c,0x383c383c,0x383c383c,0x383c383c,
02555 0x70e01c00,0x1c001c00,0x1c001c00,0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383878,0x38783878,0x387807c0,
02556 0x3c3807c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x18c0,0x10b801ce,0x3c3e0000,0x38001c0,0x180,
02557 0x3800000,0x3801c00,0x1e7801c0,0x3c002078,0xe02078,0x1c380700,0x1c3810f0,0x3800380,0x40000,0x40000380,0x307b380e,0x70701e18,
02558 0x70e07000,0x70001c1c,0x703801c0,0x60e0703c,0x7000701c,0x70f83c78,0x70003c70,0x703c70f0,0x1c03870,0x3c01c3c,0x3c1c01c0,0x78000380,
02559 0x7001c0,0x0,0x3c7c,0x3c381e18,0x1c7c1e0c,0x3801c3c,0x383801c0,0xe01c38,0x3c0739c,0x38381c38,0x3c381c3c,0x7001078,0x7803c78,
02560 0x7c01c38,0x1c780380,0x1e0001c0,0x18001c0,0x0,0x70c06c0,0x7000380,0xe300000,0x1000100,0x2142,0x70f00600,0x3c7006c0,0x780006c0,
02561 0x6c00000,0x0,0x0,0x0,0x0,0x10780060,0x73e206c0,0x1e0001c0,0x1c0,0x7240700,0x180c01c0,0x1800018,0x1818,0x30c,0x0,0x18180000,
02562 0x0,0x0,0x3c78,0x1980000,0x0,0x30c0,0x130000c,0x1301c18,0x380e380e,0x380e380e,0x380e380e,0x70e01e18,0x70007000,0x70007000,
02563 0x1c001c0,0x1c001c0,0x70e070f8,0x3c783c78,0x3c783c78,0x3c781008,0x7c783870,0x38703870,0x387001c0,0x70003a3c,0x3c7c3c7c,0x3c7c3c7c,
02564 0x3c7c3c7c,0x79f11e18,0x1e0c1e0c,0x1e0c1e0c,0x1c001c0,0x1c001c0,0x1c783838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383c78,0x3c783c78,
02565 0x3c780380,0x3c380380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x38c0,0x1ff800fc,0x1fee0000,
02566 0x1800180,0x180,0x3800000,0x3801c00,0xff01ffc,0x3ffc3ff0,0xe03ff0,0xff00700,0x1ff81fe0,0x3800380,0x0,0x380,0x3000780f,0x7ff00ff8,
02567 0x7fc07ff8,0x70000ffc,0x70381ffc,0x7fe0701c,0x7ff8701c,0x70781ff0,0x70001ff0,0x701c7ff0,0x1c01fe0,0x3c01c38,0x380e01c0,0x7ffc0380,
02568 0x7001c0,0x0,0x1fdc,0x3ff00ff0,0xffc0ffc,0x3800fdc,0x38383ffe,0xe01c3c,0x1fc739c,0x38380ff0,0x3ff00ffc,0x7001ff0,0x3f81fb8,
02569 0x7c01c38,0x3c3c0380,0x1ffc01c0,0x18001c0,0x0,0x3fc0380,0x7000380,0xc70718c,0x1000100,0x2244,0x7ff00200,0x1fff0380,0x7ffc0380,
02570 0x3800000,0x0,0x0,0x0,0x0,0x1ff000c0,0x7f7e0380,0x1ffc01c0,0x1c0,0x3fc3ffe,0x1c0,0x1800018,0x7e0,0x104,0x0,0x7e00000,0x7ffe,
02571 0x0,0x3fde,0x1980000,0x0,0x2080,0x3300018,0x3300ff0,0x780f780f,0x780f780f,0x780f780e,0xf0fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,
02572 0x1ffc1ffc,0x7fc07078,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x7ff01fe0,0x1fe01fe0,0x1fe001c0,0x70003bf8,0x1fdc1fdc,0x1fdc1fdc,
02573 0x1fdc1fdc,0x3fbf0ff0,0xffc0ffc,0xffc0ffc,0x3ffe3ffe,0x3ffe3ffe,0xff03838,0xff00ff0,0xff00ff0,0xff00000,0x3ff01fb8,0x1fb81fb8,
02574 0x1fb80380,0x3ff00380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x31c0,0x7e00078,0x7cf0000,0x1800180,
02575 0x0,0x3800000,0x3803800,0x3c01ffc,0x3ffc0fe0,0xe01fc0,0x3e00e00,0x7e00f80,0x3800380,0x0,0x380,0x18007007,0x7fc003f0,0x7f007ff8,
02576 0x700003f0,0x70381ffc,0x3f80701e,0x7ff8701c,0x707807c0,0x700007c0,0x701e1fc0,0x1c00fc0,0x3c01818,0x780f01c0,0x7ffc0380,0x3801c0,
02577 0x0,0xf9c,0x39e003e0,0x79c03f0,0x380079c,0x38383ffe,0xe01c1e,0x7c739c,0x383807e0,0x39e0079c,0x7000fc0,0x1f80f38,0x3801c38,
02578 0x781e0380,0x1ffc01c0,0x18001c0,0x0,0x1f80100,0xe000700,0x1c60718c,0x1000100,0x1e3c,0x1fc00100,0x7ff0100,0x7ffc0100,0x1000000,
02579 0x0,0x0,0x0,0x0,0xfc00080,0x3e3c0100,0x1ffc01c0,0x1c0,0xf83ffe,0x1c0,0x1800838,0x0,0x0,0x0,0x0,0x7ffe,0x0,0x3b9e,0x1980000,
02580 0x0,0x0,0x2300038,0x23003e0,0x70077007,0x70077007,0x70077007,0xe0fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007078,
02581 0x7c007c0,0x7c007c0,0x7c00000,0xc7c00fc0,0xfc00fc0,0xfc001c0,0x700039f0,0xf9c0f9c,0xf9c0f9c,0xf9c0f9c,0x1f1e03e0,0x3f003f0,
02582 0x3f003f0,0x3ffe3ffe,0x3ffe3ffe,0x7e03838,0x7e007e0,0x7e007e0,0x7e00000,0x63e00f38,0xf380f38,0xf380380,0x39e00380,0x0,0x0,
02583 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,
02584 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,
02585 0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1c0,0x18001c0,0x0,0x0,0xe000700,0x18600000,0x1000100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02586 0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800ff0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0x1800000,0x0,0x6300070,0x6300000,0x0,
02587 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,
02588 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,
02589 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,
02590 0x0,0x0,0x1c,0x0,0xe00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1e0,0x18003c0,0x0,0x0,0xc000700,0x18c00000,0x1000000,0x0,
02591 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x18007e0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0xc00000,
02592 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,
02593 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,
02594 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,
02595 0x3f0,0xfc0,0x0,0x0,0x0,0x0,0x838,0x0,0x1e00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0xf00,0xfc,0x1801f80,0x0,0x0,0x8008e00,0x30c00000,
02596 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,
02597 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,
02598 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,
02599 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,
02600 0x0,0x0,0xff0,0x0,0x1fc00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x3e00,0x7c,0x1801f00,0x0,0x0,0x800fe00,0x0,0x0,0x0,0x0,0x0,0x0,
02601 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x7c00000,0x0,0x3001fc,0x300000,
02602 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,
02603 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,
02604 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,
02605 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,
02606 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,
02607 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,
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,0xfff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x0,0x0,
02610 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02611 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02612 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02613 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
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,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02618 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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 };
02621
02622
02623 const unsigned int font19x38[19*38*256/32] = {
02624 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x1c380000,0x0,0x1c380,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,0x3800007,0x3c003,0x86000000,
02628 0x1e00000,0x3,0x80000700,0x3c00000,0x380000,0x70003c00,0x0,0xe1800e,0x1c00,0xf000e18,0x0,0x0,0x700000e0,0x780000,0x7000,0x0,
02629 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02630 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0xe700000,0x0,0xe700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02633 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0000e,0x7e003,0xe60071c0,0x7f80000,0x1,0xc0000e00,0x7e0038e,0x1c0000,
02634 0xe0007e00,0x38e00000,0xf98007,0x3800,0x1f800f98,0x1c70000,0x0,0x380001c0,0xfc0071,0xc000e000,0x0,0x0,0x0,0x0,0x3e00000,0x0,
02635 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02636 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,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,
02639 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0001c,0xe7006,0x7c0071c0,0xe180000,0x0,0xe0001c00,0xe70038e,0xe0001,0xc000e700,0x38e00000,
02640 0x19f0003,0x80007000,0x39c019f0,0x1c70000,0x0,0x1c000380,0x1ce0071,0xc001c000,0x0,0x0,0x0,0x0,0x7f00000,0x0,0x0,0x0,0x0,0x0,
02641 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02642 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02643 0x0,0x0,0x0,0x0,0x0,0x0,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,
02644 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,
02645 0x0,0x0,0x700038,0x1c3806,0x3c0071c0,0xc0c0000,0x0,0x70003800,0x1c38038e,0x70003,0x8001c380,0x38e00000,0x18f0001,0xc000e000,
02646 0x70e018f0,0x1c70000,0x0,0xe000700,0x3870071,0xc0038000,0x0,0x0,0x0,0x0,0xe380000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02647 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02648 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02649 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,
02650 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,
02651 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,
02652 0xe,0x380,0x1800000,0xe00000,0x38001800,0x0,0x38,0xe00,0x6000000,0x0,0x1,0xc0000070,0x300000,0x3800,0x0,0x0,0x0,0x0,0x0,0x0,
02653 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,
02654 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,
02655 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,
02656 0x0,0x0,0xc3000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800000,0x0,0x0,0x0,0xe0,0x1c000f,0xc0000000,0x0,0x0,
02657 0x0,0xc0c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7000007,0x3c003,0xc6000000,0xc180000,0x7,0x700,
02658 0x3c00000,0x700000,0x70003c00,0x0,0xf1801c,0x1c00,0xf000f18,0x0,0x0,0xe00000e0,0x780000,0x7000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02659 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,
02660 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,
02661 0x7,0xe000001c,0x1c00,0x1c00700,0x7fc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf800e,0x3e0000,0x0,0x0,0x0,0x1e00000,0x0,0x1,
02662 0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7cc00,0x660,0x0,0x0,0x66000000,0x0,0x0,0x0,0x0,0x7,0x1c000000,0x0,0x0,0x0,0x3fe00000,
02663 0x0,0x0,0x7000000,0x0,0x0,0x0,0x3e0,0x7c001f,0xe0000000,0x0,0x0,0x0,0xe1c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02664 0x0,0x0,0x0,0x1f80,0x380000e,0x7e007,0xe60071c0,0xc180000,0x3,0x80000e00,0x7e0038e,0x380000,0xe0007e00,0x38e00f00,0x1f9800e,
02665 0x3800,0x1f801f98,0x1c70000,0x0,0x700001c0,0xfc0071,0xc000e007,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02666 0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0x61c00600,0x1e00007e,0x70000,0x18003000,0x1800000,0x0,0x0,0x1c01f0,0x7e003f,0xc003f800,
02667 0x1e03ffc,0x7f01ff,0xfc03f000,0x7e000000,0x0,0x0,0xfc0,0x1e,0x7fe000,0x7e03fe00,0x3fff07ff,0xe007e038,0x383ffe0,0xff81c01,
02668 0xe1c000f8,0xf8f00e0,0xfc01ffc,0x3f00ff,0xc000fe07,0xfffc7007,0x1c007700,0x73c01ef,0x78ffff,0xfe0380,0xfe000,0x38000000,0x1800000,
02669 0x700000,0x38,0x1f,0xe000001c,0x1c00,0x1c00700,0x7fc0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x3f800e,0x3f8000,0x0,0xfc0000,
02670 0x0,0x7f00000,0x0,0x1,0x98000000,0x7f00000,0x3ffe00,0xffff0,0x0,0x0,0x0,0x0,0x0,0xcf81f,0xee3807e0,0x0,0x0,0x7e03c01e,0x1c,
02671 0x0,0x1f800000,0xf0078038,0xfc007,0x1c000000,0xfe00000,0x0,0x0,0x3fe000f0,0xf,0xc001f800,0x6000000,0xffc000,0x0,0x1c0007e0,
02672 0x360,0x6c0010,0x70000700,0xf0001e,0x3c000,0x78000f00,0x7f800ff,0xf007e01f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83fc0,
02673 0x7807007,0xe000fc00,0x1f8003f0,0x7e0000,0x1f867,0x70e00e,0x1c01c380,0x38f00787,0x3fe0,0x180000c,0x66006,0x7c0071c0,0xe380000,
02674 0x1,0x80000c00,0x660038e,0x180000,0xc0006600,0x38e0078e,0x19f0006,0x3000,0x198019f0,0x1c70000,0x0,0x30000180,0xcc0071,0xc000c007,
02675 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,
02676 0x38003800,0x1800000,0x0,0x0,0x3807fc,0x1fe00ff,0xf00ffe00,0x3e03ffc,0xff81ff,0xfc07fc01,0xff800000,0x0,0x0,0x3fe0,0xfe001e,
02677 0x7ff801,0xff83ff80,0x3fff07ff,0xe01ff838,0x383ffe0,0xff81c03,0xc1c000f8,0xf8f80e0,0x3ff01fff,0xffc0ff,0xf003ff87,0xfffc7007,
02678 0x1e00f700,0x71c03c7,0x70ffff,0xfe01c0,0xfe000,0x7c000000,0xc00000,0x700000,0x38,0x3f,0xe000001c,0x1c00,0x1c00700,0x7fc0000,
02679 0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x3f800e,0x3f8000,0x0,0x3fe0000,0x0,0xff00000,0x0,0x3,0xc000000,0x1ffc0000,0xfffe00,
02680 0xffff0,0x0,0x0,0x0,0x0,0x0,0xc781f,0xee3803c0,0x0,0x0,0x3c01c01c,0x1c,0xc000,0x7fc00000,0x70070038,0x3fe007,0x1c000000,0x1ff80000,
02681 0x0,0x0,0x3fe003fc,0x1f,0xe003fc00,0xc000000,0x3ffc000,0x0,0x7c000ff0,0x60,0xc0000,0x30000700,0xf0001e,0x3c000,0x78000f00,
02682 0x3f000ff,0xf01ff81f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ff8,0x7c0701f,0xf803ff00,0x7fe00ffc,0x1ff8000,0x7fe67,
02683 0x70e00e,0x1c01c380,0x38700707,0x7ff0,0xc00018,0xc3006,0x3c0071c0,0x7f00000,0x0,0xc0001800,0xc30038e,0xc0001,0x8000c300,0x38e003fc,
02684 0x18f0003,0x6000,0x30c018f0,0x1c70000,0x0,0x18000300,0x1860071,0xc0018007,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02685 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xe1801fc0,0x618001ff,0x70000,0x30001800,0x21840000,0x0,0x0,0x380ffe,0x1fe00ff,
02686 0xfc0fff00,0x3e03ffc,0x1ff81ff,0xfc0ffe03,0xffc00000,0x0,0x0,0x7ff0,0x3ff803f,0x7ffc03,0xffc3ffc0,0x3fff07ff,0xe03ffc38,0x383ffe0,
02687 0xff81c07,0x81c000f8,0xf8f80e0,0x7ff81fff,0x81ffe0ff,0xf80fff87,0xfffc7007,0xe00e700,0x70e0387,0x80f0ffff,0xe001c0,0xe000,
02688 0xfe000000,0xe00000,0x700000,0x38,0x3c,0x1c,0x1c00,0x1c00700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x78000e,0x3c000,
02689 0x0,0x7ff0000,0x0,0xf100000,0x0,0x7,0xe000000,0x7ffc0000,0x1fffe00,0xffff0,0x0,0x0,0x0,0x0,0x0,0x3,0xf780180,0x0,0x0,0x1801e03c,
02690 0x1c,0xc000,0xffc00000,0x780f0038,0x786000,0x7f00,0x18380000,0x0,0xfe00,0x30c,0x10,0x70020e00,0x1c000000,0x7f8c000,0x0,0x6c001c38,
02691 0x60,0xc0000,0x70000700,0x1f8003f,0x7e000,0xfc001f80,0x3f000ff,0xf03ffc1f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ffc,
02692 0x7c0703f,0xfc07ff80,0xfff01ffe,0x3ffc000,0xffec7,0x70e00e,0x1c01c380,0x38780f07,0xf070,0xe00038,0x1c3800,0x0,0x3e00000,0x0,
02693 0xe0003800,0x1c380000,0xe0003,0x8001c380,0x3e0,0x3,0x8000e000,0x70e00000,0x0,0x0,0x1c000700,0x3870000,0x38007,0x0,0x0,0x0,
02694 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xe3807ff0,0xc0c003c1,0x70000,0x70001c00,
02695 0x718e0000,0x0,0x0,0x700f1e,0x1ce00c0,0x3c0c0f80,0x7e03800,0x3e08000,0x381e0f03,0xc1e00000,0x0,0x0,0x7078,0x783c03f,0x701e07,
02696 0xc1c383e0,0x38000700,0x7c1c38,0x3801c00,0x381c0f,0x1c000fc,0x1f8f80e0,0x78781c07,0x81e1e0e0,0x780f0180,0xe007007,0xe00e380,
02697 0xe0f0783,0x80e0000e,0xe000e0,0xe001,0xef000000,0x0,0x700000,0x38,0x38,0x1c,0x0,0x700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,
02698 0x0,0x0,0x0,0x70000e,0x1c000,0x0,0xf830000,0x0,0x1e000000,0x0,0x0,0x10000,0x780c0000,0x3e38000,0xe0,0x0,0x0,0x0,0x0,0x0,0x3,
02699 0xd580000,0x0,0x0,0xe038,0x1c,0xc000,0xf0400000,0x380e0038,0x702000,0x1ffc0,0xc0000,0x0,0x3ff80,0x606,0x0,0x30000600,0x0,
02700 0x7f8c000,0x0,0xc001818,0x60,0xc0003,0xe0000700,0x1f8003f,0x7e000,0xfc001f80,0x73801ee,0x7c1c1c,0x38000,0x70000e00,0xe0001,
02701 0xc0003800,0x700383e,0x7c0703c,0x3c078780,0xf0f01e1e,0x3c3c000,0xf0f87,0x70e00e,0x1c01c380,0x38380e07,0xe038,0x0,0x0,0x0,
02702 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,
02703 0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xc380fff0,0xc0c00380,0x70000,0x70001c00,0x3dbc0070,0x0,0x0,0x701e0f,0xe0000,0x1e000380,
02704 0x6e03800,0x7800000,0x781c0707,0x80e00000,0x0,0x0,0x4038,0xe00c03f,0x700e07,0x4380f0,0x38000700,0x700438,0x3801c00,0x381c0e,
02705 0x1c000ec,0x1b8fc0e0,0xf03c1c03,0xc3c0f0e0,0x3c1e0000,0xe007007,0xe00e380,0xe070703,0xc1e0001e,0xe000e0,0xe001,0xc7000000,
02706 0x0,0x700000,0x38,0x38,0x1c,0x0,0x700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x70000e,0x1c000,0x0,0xe010000,0x0,
02707 0x1c000000,0x10,0x20000,0x6c000,0xf0000000,0x3838000,0x1e0,0x0,0xf000f,0xf1e00,0x78f00000,0x0,0x3,0xdd80000,0x0,0x0,0xf078,
02708 0x0,0xc001,0xe0000000,0x1c1c0038,0x700000,0x3c1e0,0xc0000,0x0,0x783c0,0x606,0x0,0x30000e00,0x0,0xff8c000,0x0,0xc00300c,0x60,
02709 0xc0003,0xe0000000,0x1f8003f,0x7e000,0xfc001f80,0x73801ce,0x70041c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700380f,0x7e07078,
02710 0x1e0f03c1,0xe0783c0f,0x781e000,0x1c0787,0x70e00e,0x1c01c380,0x383c1e07,0xff00e038,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x878,
02711 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,
02712 0x1c7000,0xc301e630,0xc0c00380,0x70000,0xe0000e00,0xff00070,0x0,0x0,0xe01c07,0xe0000,0xe000380,0xce03800,0x7000000,0x701c0707,
02713 0x600000,0x0,0x4000010,0x38,0x1c00e07f,0x80700e0e,0x38070,0x38000700,0xe00038,0x3801c00,0x381c1c,0x1c000ec,0x1b8ec0e0,0xe01c1c01,
02714 0xc38070e0,0x1c1c0000,0xe007007,0x701c380,0xe078e01,0xc1c0003c,0xe00070,0xe003,0x83800000,0x7f,0x71f000,0x3e003e38,0x3f007ff,
02715 0xe01f1c1c,0x7801fc00,0x3fc00701,0xe01c0077,0x8f071e00,0xf801c7c,0x7c700e,0x3e01fc03,0xfff8380e,0xe007700,0x73c0787,0x387ffc,
02716 0x70000e,0x1c000,0x0,0xe000000,0x0,0x1c000000,0x10,0x20000,0xc2000,0xe0000000,0x3838000,0x3c0,0x0,0xf000f,0x78e00,0x70e00000,
02717 0x0,0x3,0xc980fe0,0x1f0,0xf8000007,0xffc07070,0x0,0x3f801,0xc0000000,0x1e3c0038,0x700000,0x70070,0x7fc0000,0x0,0xe00e0,0x606,
02718 0x1c0000,0x70007c00,0x380e,0xff8c000,0x0,0xc00300c,0x60,0xc0000,0x70000000,0x3fc007f,0x800ff001,0xfe003fc0,0x73801ce,0xe0001c,
02719 0x38000,0x70000e00,0xe0001,0xc0003800,0x7003807,0x7607070,0xe0e01c1,0xc0383807,0x700e000,0x1c0387,0x70e00e,0x1c01c380,0x381c1c07,
02720 0xffc0e0f8,0x3f8007f,0xfe001,0xfc003f80,0x7f007e3,0xe003e001,0xf8003f00,0x7e000fc,0xfe001f,0xc003f800,0x7f00003c,0x38f0007,
02721 0xc000f800,0x1f0003e0,0x7c0007,0x8003f0c3,0x80e0701c,0xe0381c0,0x70700387,0x1f01c00e,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02722 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c701f,0xfff1c600,0xc0c00380,0x70000,0xe0000e00,0x3c00070,0x0,0x0,0xe03c07,
02723 0x800e0000,0xe000380,0x1ce03800,0x7000000,0x701c0707,0x7003c0,0x780000,0x3c00001e,0x38,0x18006073,0x80700e0e,0x38070,0x38000700,
02724 0xe00038,0x3801c00,0x381c38,0x1c000ee,0x3b8ee0e1,0xe01e1c01,0xc78078e0,0x1c1c0000,0xe007007,0x701c387,0xe03de00,0xe3800038,
02725 0xe00070,0xe007,0x1c00000,0x1ff,0xc077f801,0xff807fb8,0xff807ff,0xe03fdc1d,0xfc01fc00,0x3fc00703,0xc01c007f,0xdf877f00,0x3fe01dfe,
02726 0xff700e,0xff07ff03,0xfff8380e,0x700f700,0x71e0f03,0x80707ffc,0x70000e,0x1c000,0x0,0x1c000008,0x0,0x1c000000,0x10,0x20000,
02727 0x82000,0xe0000000,0x7038000,0x80000380,0x2000040,0x7000e,0x38700,0xf1e00000,0x0,0x3,0xc183ff8,0x3fd,0xfc008007,0xffc038e0,
02728 0x0,0xffc01,0xc0008008,0xe380038,0x380000,0xe3e38,0x1ffc0040,0x80000000,0x1cfc70,0x606,0x1c0000,0xe0007c00,0x380e,0xff8c000,
02729 0x0,0xc00300c,0x8100060,0xc0000,0x30000700,0x39c0073,0x800e7001,0xce0039c0,0x73801ce,0xe0001c,0x38000,0x70000e00,0xe0001,
02730 0xc0003800,0x7003807,0x77070f0,0xf1e01e3,0xc03c7807,0x8f00f080,0x83c0787,0x70e00e,0x1c01c380,0x380e3807,0xffe0e1c0,0xffe01ff,
02731 0xc03ff807,0xff00ffe0,0x1ffc0ff7,0xf01ff807,0xfc00ff80,0x1ff003fe,0xfe001f,0xc003f800,0x7f0003fc,0x3bf801f,0xf003fe00,0x7fc00ff8,
02732 0x1ff0007,0x8007fd83,0x80e0701c,0xe0381c0,0x70380707,0x7f80e01c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02733 0x0,0x0,0x0,0x0,0x1c,0x1c701f,0xfff1c600,0x618081c0,0x70000,0xe0000e00,0x3c00070,0x0,0x0,0xe03803,0x800e0000,0xe000380,0x18e03800,
02734 0xf000000,0xf01c0707,0x7003c0,0x780000,0xfc00001f,0x80000078,0x301e6073,0x80700e1c,0x38038,0x38000700,0x1c00038,0x3801c00,
02735 0x381c70,0x1c000e6,0x338ee0e1,0xc00e1c01,0xc70038e0,0x1c1c0000,0xe007007,0x701c387,0xe01dc00,0xf7800078,0xe00070,0xe00e,0xe00000,
02736 0x3ff,0xe07ffc03,0xffc0fff8,0x1ffc07ff,0xe07ffc1d,0xfe01fc00,0x3fc00707,0x801c007f,0xdf877f80,0x7ff01fff,0x1fff00e,0xff07ff03,
02737 0xfff8380e,0x700e380,0xe0e0e03,0x80707ffc,0x70000e,0x1c000,0x0,0x7ffc001c,0x0,0x1c000000,0x10,0x20000,0x82000,0xe0000000,
02738 0x7038001,0xc0000780,0x70000e0,0x3800e,0x38700,0xe1c00000,0x0,0x3,0xc183ff8,0x7ff,0xfc01c007,0xffc03de0,0x0,0x1ffc01,0xc001c01c,
02739 0xf780038,0x3c0000,0xcff18,0x380c00c1,0x80000000,0x18fe30,0x30c,0x1c0001,0xc0000e00,0x380e,0xff8c000,0x0,0xc00300c,0xc180060,
02740 0xc0000,0x30000700,0x39c0073,0x800e7001,0xce0039c0,0xe1c038e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x877070e0,
02741 0x71c00e3,0x801c7003,0x8e0071c0,0x1c380fc7,0x70e00e,0x1c01c380,0x380f7807,0x1e0e380,0x1fff03ff,0xe07ffc0f,0xff81fff0,0x3ffe0fff,
02742 0xf03ffc0f,0xfe01ffc0,0x3ff807ff,0xfe001f,0xc003f800,0x7f0007fe,0x3bfc03f,0xf807ff00,0xffe01ffc,0x3ff8007,0x800fff83,0x80e0701c,
02743 0xe0381c0,0x70380707,0xffc0e01c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c701f,
02744 0xfff1c600,0x7f8381e0,0x70000,0xc0000600,0xff00070,0x0,0x0,0x1c03803,0x800e0000,0xe000f00,0x38e03fe0,0xe000000,0xe00e0e07,
02745 0x7003c0,0x780007,0xf0ffff87,0xf00000f0,0x307fe0f3,0xc0703c1c,0x38038,0x38000700,0x1c00038,0x3801c00,0x381ce0,0x1c000e6,0x338e70e1,
02746 0xc00e1c01,0xc70038e0,0x3c1e0000,0xe007007,0x783c38f,0x8e01fc00,0x770000f0,0xe00038,0xe01c,0x700000,0x381,0xe07c1e07,0xc0c1e0f8,
02747 0x3c1e0038,0xf07c1f,0xe001c00,0x1c0070f,0x1c0079,0xf3c7c380,0xf0781f07,0x83c1f00f,0xc10f0300,0x1c00380e,0x700e380,0xe0f1e03,
02748 0xc0f00078,0x70000e,0x1c000,0x0,0xfff8003e,0x0,0x3c000000,0x10,0x20000,0xc6000,0xf0000000,0x7038003,0xe0000f00,0xf8001f0,
02749 0x3801c,0x18300,0xe1800000,0x0,0x3,0xc187818,0x70f,0x9e03e000,0x7801dc0,0x1c,0x3cc401,0xc000efb8,0x7f7f0038,0x3f0000,0x1ce11c,
02750 0x300c01c3,0x80000000,0x38c638,0x3fc,0x1c0003,0x80000600,0x380e,0xff8c000,0x0,0xc00300c,0xe1c0060,0xc0010,0x70000700,0x79e00f3,
02751 0xc01e7803,0xcf0079e0,0xe1c038e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x873870e0,0x71c00e3,0x801c7003,
02752 0x8e0070e0,0x38381dc7,0x70e00e,0x1c01c380,0x38077007,0xf0e700,0x1c0f0381,0xe0703c0e,0x781c0f0,0x381e083e,0x787c0c1e,0xf03c1e0,
02753 0x783c0f07,0x800e0001,0xc0003800,0x7000fff,0x3e1c078,0x3c0f0781,0xe0f03c1e,0x783c000,0x1e0f03,0x80e0701c,0xe0381c0,0x70380f07,
02754 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,
02755 0xc0000700,0x3dbc0070,0x0,0x0,0x1c03803,0x800e0000,0x1e01fe00,0x70e03ff8,0xe3e0001,0xe007fc07,0x80f003c0,0x78001f,0xc0ffff81,
02756 0xfc0001e0,0x30e1e0e1,0xc07ff81c,0x38038,0x3ffe07ff,0xc1c0003f,0xff801c00,0x381de0,0x1c000e7,0x738e70e1,0xc00e1c03,0xc70038e0,
02757 0x780f8000,0xe007007,0x383838d,0x8e00f800,0x7f0000e0,0xe00038,0xe000,0x0,0x200,0xf0780e07,0x8041c078,0x380e0038,0xe03c1e,
02758 0xf001c00,0x1c0071e,0x1c0070,0xe1c783c0,0xe0381e03,0x8380f00f,0xe0000,0x1c00380e,0x381c380,0xe07bc01,0xc0e00078,0x70000e,
02759 0x1c000,0x0,0x1c000061,0x0,0x38000000,0x10,0x20000,0x7c000,0x7c000000,0x703fc06,0x10000e00,0x18400308,0x1801c,0x1c381,0xc3800000,
02760 0x0,0x0,0x7000,0xe0f,0xe061000,0x7801fc0,0x1c,0x38c001,0xc0007ff0,0x7fff0038,0x77c000,0x19c00c,0x301c0387,0x0,0x30c618,0xf0,
02761 0x1c0007,0x600,0x380e,0x7f8c007,0x80000000,0xc001818,0x70e03fc,0x387f871f,0xe0e00700,0x70e00e1,0xc01c3803,0x870070e0,0xe1c038f,
02762 0xe1c0001f,0xff03ffe0,0x7ffc0fff,0x800e0001,0xc0003800,0x7003803,0x873870e0,0x71c00e3,0x801c7003,0x8e007070,0x703839c7,0x70e00e,
02763 0x1c01c380,0x3807f007,0x70e700,0x10078200,0xf0401e08,0x3c10078,0x200f001c,0x3878041c,0x70380e0,0x701c0e03,0x800e0001,0xc0003800,
02764 0x7001e0f,0x3c1e070,0x1c0e0381,0xc070380e,0x701c000,0x1c0f03,0x80e0701c,0xe0381c0,0x701c0e07,0x80e07038,0x0,0x0,0x0,0x0,0x0,
02765 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0x8600e600,0x7803f0,0x1,0xc0000700,0x718e0070,0x0,0x0,0x38038c3,
02766 0x800e0000,0x3c01f800,0x60e03ffc,0xeff8001,0xc001f003,0xc1f003c0,0x7800fe,0xffff80,0x3f8003c0,0x60c0e0e1,0xc07fe01c,0x38038,
02767 0x3ffe07ff,0xc1c07e3f,0xff801c00,0x381fe0,0x1c000e3,0x638e30e1,0xc00e1c07,0x870038ff,0xf00ff800,0xe007007,0x38381cd,0x9c007000,
02768 0x3e0001e0,0xe0001c,0xe000,0x0,0x0,0x70780f0f,0x3c078,0x70070038,0x1e03c1c,0x7001c00,0x1c0073c,0x1c0070,0xe1c701c1,0xe03c1e03,
02769 0xc780f00f,0xe0000,0x1c00380e,0x381c387,0xe03f801,0xc0e000f0,0x70000e,0x1c007,0xe0100000,0x1c0000cd,0x80000003,0xffc00000,
02770 0x3ff,0x807ff000,0xe0,0x7fc00060,0x703fc0c,0xd8001e00,0x3360066c,0x1c018,0xc181,0x83000000,0x0,0x0,0x7000,0x300e07,0xe0cd800,
02771 0xf000f80,0x1c,0x78c00f,0xff0038e0,0x3e00038,0xe1e000,0x19800c,0x383c070e,0x7fffc00,0x30fc18,0x0,0xffff80e,0x20e00,0x380e,
02772 0x7f8c007,0x80000000,0xc001c38,0x38703ff,0xf87fff0f,0xcfe00f00,0x70e00e1,0xc01c3803,0x870070e0,0x1e1e078f,0xe1c0001f,0xff03ffe0,
02773 0x7ffc0fff,0x800e0001,0xc0003800,0x700ff83,0x871870e0,0x71c00e3,0x801c7003,0x8e007038,0xe03871c7,0x70e00e,0x1c01c380,0x3803e007,
02774 0x70e700,0x38000,0x70000e00,0x1c00038,0x7001c,0x38f00038,0x3870070,0xe00e1c01,0xc00e0001,0xc0003800,0x7001c07,0x380e0f0,0x1e1e03c3,
02775 0xc078780f,0xf01e000,0x3c0f03,0x80e0701c,0xe0381c0,0x701c0e07,0x80f07038,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02776 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0x8600ff00,0x1e00778,0x38000001,0xc0000700,0x21843fff,0xe0000000,0x0,0x38039e3,0x800e0000,
02777 0x7c01fe00,0xe0e0203e,0xeffc001,0xc00ffe03,0xff700000,0x7f0,0x0,0x7f00380,0x618060e1,0xc07ffc1c,0x38038,0x3ffe07ff,0xc1c07e3f,
02778 0xff801c00,0x381ff0,0x1c000e3,0x638e38e1,0xc00e1fff,0x870038ff,0xc003fe00,0xe007007,0x38381cd,0x9c00f800,0x3e0003c0,0xe0001c,
02779 0xe000,0x0,0x0,0x7070070e,0x38038,0x70070038,0x1c01c1c,0x7001c00,0x1c00778,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0xfc000,
02780 0x1c00380e,0x381c3c7,0x1e01f001,0xe1e001e0,0xf0000e,0x1e01f,0xf8300000,0x1c00019c,0xc0000003,0xffc00000,0x10,0x20000,0x700,
02781 0x1ff000c0,0x703fc19,0xcc003c00,0x67300ce6,0xc038,0xc181,0x83000000,0x0,0x0,0x7e00,0x180e07,0xe19cc00,0x1e000f80,0x1c,0x70c00f,
02782 0xff007070,0x3e00038,0xe0f000,0x19800c,0x1fec0e1c,0x7fffc00,0x30f818,0x0,0xffff81f,0xf003fc00,0x380e,0x3f8c007,0x80000000,
02783 0x7f800ff0,0x1c3803f,0xe007fc00,0xff800e00,0x70e00e1,0xc01c3803,0x870070e0,0x1c0e070f,0xe1c0001f,0xff03ffe0,0x7ffc0fff,0x800e0001,
02784 0xc0003800,0x700ff83,0x871c70e0,0x71c00e3,0x801c7003,0x8e00701d,0xc038e1c7,0x70e00e,0x1c01c380,0x3803e007,0x70e3c0,0x38000,
02785 0x70000e00,0x1c00038,0x7001c,0x38e00038,0x3870070,0xe00e1c01,0xc00e0001,0xc0003800,0x7003c07,0x8380e0e0,0xe1c01c3,0x80387007,
02786 0xe00e1ff,0xfe381b83,0x80e0701c,0xe0381c0,0x701e1e07,0x707878,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02787 0x0,0x0,0x0,0x0,0x1c,0x3,0xe007fe0,0x7800e3c,0x38000001,0xc0000700,0x1803fff,0xe0000000,0x0,0x70039c3,0x800e0000,0xf8000f80,
02788 0xc0e0000e,0xf83c003,0xc01e0f01,0xff700000,0x7c0,0x0,0x1f00780,0x618061c0,0xe0701e1c,0x38038,0x38000700,0x1c07e38,0x3801c00,
02789 0x381e78,0x1c000e3,0xe38e18e1,0xc00e1fff,0x70038ff,0xe0007f80,0xe007007,0x1c701dd,0x9c00f800,0x1c000780,0xe0000e,0xe000,0x0,
02790 0x7f,0xf070070e,0x38038,0x7fff0038,0x1c01c1c,0x7001c00,0x1c007f8,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x7fc00,0x1c00380e,
02791 0x1c381c7,0x1c01f000,0xe1c001c0,0xfe0000e,0xfe1f,0xfff00000,0x7ff003fc,0xe0000003,0xffc00000,0x10,0x20000,0x3800,0x3fc0180,
02792 0x703803f,0xce007800,0xff381fe7,0x30,0x0,0xc0,0x0,0x0,0x3fe0,0xc0e07,0xfe3fce00,0x1c000700,0x1c,0x70c00f,0xff006030,0x1c00000,
02793 0xe07800,0x19800c,0xfcc1c38,0x7fffc00,0x30d818,0x0,0xffff81f,0xf001f800,0x380e,0xf8c007,0x80000000,0x7f8007e0,0xe1c3fe,0x7fc00f,
02794 0xf8001e00,0xe0701c0,0xe0381c07,0x380e070,0x1c0e070e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700ff83,0x870c70e0,
02795 0x71c00e3,0x801c7003,0x8e00700f,0x8038c1c7,0x70e00e,0x1c01c380,0x3801c007,0xf0e3e0,0x3ff807f,0xf00ffe01,0xffc03ff8,0x7ff03ff,
02796 0xf8e0003f,0xff87fff0,0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e1ff,0xfe383383,0x80e0701c,
02797 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,
02798 0x3c1e1c1c,0x38000001,0xc0000700,0x1803fff,0xe0000007,0xf8000000,0x7003803,0x800e0001,0xf0000381,0xc0e00007,0xf01e003,0x801c0700,
02799 0x7c700000,0x7c0,0x0,0x1f00700,0x618061c0,0xe0700e1c,0x38038,0x38000700,0x1c00e38,0x3801c00,0x381e38,0x1c000e1,0xc38e1ce1,
02800 0xc00e1ffc,0x70038e0,0xf0000780,0xe007007,0x1c701dd,0xdc01fc00,0x1c000780,0xe0000e,0xe000,0x0,0x1ff,0xf070070e,0x38038,0x7fff0038,
02801 0x1c01c1c,0x7001c00,0x1c007f8,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x3ff00,0x1c00380e,0x1c381cd,0x9c00e000,0xe1c003c0,
02802 0xf80000e,0x3e18,0x3ff00000,0xffe007fd,0xf0000000,0x38000000,0x10,0x20000,0x1c000,0x3c0300,0x703807f,0xdf007801,0xff7c3fef,
02803 0x80000000,0x0,0x3e0,0x7ffe7ff,0xff000000,0x1ff8,0x60e07,0xfe7fdf00,0x3c000700,0x1c,0x70c001,0xc0006030,0x7fff0000,0xf03800,
02804 0x19800c,0x1c38,0x1c07,0xf830cc18,0x0,0x1c0000,0x0,0x380e,0x18c007,0x80000000,0x0,0xe1cfe0,0x1fc003f,0x80003c00,0xe0701c0,
02805 0xe0381c07,0x380e070,0x1c0e070e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x870e70e0,0x71c00e3,0x801c7003,
02806 0x8e007007,0x3981c7,0x70e00e,0x1c01c380,0x3801c007,0x1e0e0f8,0xfff81ff,0xf03ffe07,0xffc0fff8,0x1fff07ff,0xf8e0003f,0xff87fff0,
02807 0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e1ff,0xfe386383,0x80e0701c,0xe0381c0,0x700e1c07,
02808 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,
02809 0xc0000700,0x70,0x7,0xf8000000,0xe003803,0x800e0003,0xe00001c3,0x80e00007,0xe00e007,0x80380380,0x700000,0x7f0,0x0,0x7f00700,
02810 0x618061ff,0xe070071c,0x38038,0x38000700,0x1c00e38,0x3801c00,0x381c3c,0x1c000e1,0xc38e1ce1,0xc00e1c00,0x70038e0,0x700003c0,
02811 0xe007007,0x1c701d8,0xdc03dc00,0x1c000f00,0xe00007,0xe000,0x0,0x3ff,0xf070070e,0x38038,0x7fff0038,0x1c01c1c,0x7001c00,0x1c007fc,
02812 0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x3f00,0x1c00380e,0x1c381cd,0x9c01f000,0x73800780,0xfe0000e,0xfe10,0x7c00000,0x1c000ffb,
02813 0xf8000000,0x38000000,0x10,0x20000,0x20000,0x1e0700,0x70380ff,0xbf80f003,0xfefe7fdf,0xc0000000,0x0,0x3f0,0x7ffe7ff,0xff000000,
02814 0x1f8,0x30e07,0xfeffbf80,0x78000700,0x1c,0x70c001,0xc0006030,0x7fff0000,0x783800,0x1ce11c,0xe1c,0x1c07,0xf838ce38,0x0,0x1c0000,
02815 0x0,0x380e,0x18c000,0x0,0x0,0x1c38c00,0x1800030,0x7800,0xfff01ff,0xe03ffc07,0xff80fff0,0x3fff0ffe,0x1c0001c,0x38000,0x70000e00,
02816 0xe0001,0xc0003800,0x7003803,0x870e70e0,0x71c00e3,0x801c7003,0x8e00700f,0x803b81c7,0x70e00e,0x1c01c380,0x3801c007,0xffe0e03c,
02817 0x1fff83ff,0xf07ffe0f,0xffc1fff8,0x3fff0fff,0xf8e0003f,0xff87fff0,0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,
02818 0x80387007,0xe00e000,0x38c383,0x80e0701c,0xe0381c0,0x70073807,0x701ce0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02819 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f,0xffc0063c,0x40619c0f,0x30000001,0xc0000700,0x70,0x7,0xf8000000,0xe003803,0x800e0007,0xc00001c3,
02820 0xfffc0007,0xe00e007,0x380380,0xf00000,0xfe,0xffff80,0x3f800700,0x618063ff,0xf070071c,0x38038,0x38000700,0x1c00e38,0x3801c00,
02821 0x381c1e,0x1c000e0,0x38e0ee1,0xc00e1c00,0x70038e0,0x380001c0,0xe007007,0x1ef01d8,0xdc038e00,0x1c001e00,0xe00007,0xe000,0x0,
02822 0x7c0,0x7070070e,0x38038,0x70000038,0x1c01c1c,0x7001c00,0x1c0079e,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x780,0x1c00380e,
02823 0xe701cd,0x9c01f000,0x73800f00,0xe0000e,0xe000,0x0,0x1c0007f7,0xf0000000,0x70000000,0x10,0x20000,0x0,0xe0e00,0x703807f,0x7f01e001,
02824 0xfdfc3fbf,0x80000000,0x0,0x7f0,0x0,0x0,0x3c,0x18e07,0x7f7f00,0xf0000700,0x1c,0x70c001,0xc0007070,0x1c00000,0x3e7000,0xcff18,
02825 0x3ffc070e,0x1c07,0xf818c630,0x0,0x1c0000,0x0,0x380e,0x18c000,0x0,0x3ffc,0x3870000,0xe000fc00,0x380f000,0x1fff83ff,0xf07ffe0f,
02826 0xffc1fff8,0x3fff0ffe,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x870770e0,0x71c00e3,0x801c7003,0x8e00701d,
02827 0xc03f01c7,0x70e00e,0x1c01c380,0x3801c007,0xffc0e01c,0x3e0387c0,0x70f80e1f,0x1c3e038,0x7c071e1c,0xe00038,0x70000,0xe0001c00,
02828 0xe0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e000,0x398383,0x80e0701c,0xe0381c0,0x70073807,0x701ce0,
02829 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,
02830 0x70,0x0,0x0,0x1c003c07,0x800e000f,0x1c3,0xfffc0007,0xe00e007,0x380380,0xe00000,0x1f,0xc0ffff81,0xfc000700,0x618063ff,0xf070070e,
02831 0x38070,0x38000700,0xe00e38,0x3801c00,0x381c0e,0x1c000e0,0x38e0ee1,0xe01e1c00,0x78078e0,0x380001c0,0xe007007,0xee01f8,0xfc078f00,
02832 0x1c001c00,0xe00003,0x8000e000,0x0,0x700,0x7070070e,0x38038,0x70000038,0x1c01c1c,0x7001c00,0x1c0070e,0x1c0070,0xe1c701c1,
02833 0xc01c1c01,0xc700700e,0x380,0x1c00380e,0xe700ed,0xb803f800,0x77800f00,0x70000e,0x1c000,0x0,0xe0003f7,0xe0000000,0x70000000,
02834 0x10,0x20000,0x1c0e0,0xe1c00,0x703803f,0x7e01c000,0xfdf81fbf,0x0,0x0,0x3f0,0x0,0x0,0x1c,0x1ce07,0x3f7e00,0xf0000700,0x1c,
02835 0x70c001,0xc00038e0,0x1c00038,0xf7000,0xe3e38,0x3ffc0387,0x1c00,0x1cc770,0x0,0x1c0000,0x0,0x380e,0x18c000,0x0,0x3ffc,0x70e0001,
02836 0xe001fe00,0x780e000,0x1fff83ff,0xf07ffe0f,0xffc1fff8,0x3fff0ffe,0xe0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003807,
02837 0x70770f0,0xf1e01e3,0xc03c7807,0x8f00f038,0xe03e03c7,0x70e00e,0x1c01c380,0x3801c007,0xff00e00e,0x38038700,0x70e00e1c,0x1c38038,
02838 0x70071c1c,0xe00038,0x70000,0xe0001c00,0xe0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e000,0x3b0383,0x80e0701c,
02839 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,
02840 0xc0de03,0xe0000001,0xc0000700,0x70,0x0,0x0,0x1c001c07,0xe001e,0x1c3,0xfffc0007,0x600e00e,0x380380,0xe00000,0x7,0xf0ffff87,
02841 0xf0000000,0x60c0e380,0x7070070e,0x38070,0x38000700,0xe00e38,0x3801c00,0x381c0f,0x1c000e0,0x38e06e0,0xe01c1c00,0x38070e0,
02842 0x1c0001c0,0xe007007,0xee00f8,0xf80f0700,0x1c003c00,0xe00003,0x8000e000,0x0,0x700,0x70780f0f,0x3c078,0x70000038,0x1e03c1c,
02843 0x7001c00,0x1c0070f,0x1c0070,0xe1c701c1,0xe03c1e03,0xc780f00e,0x380,0x1c00380e,0xe700f8,0xf807bc00,0x3f001e00,0x70000e,0x1c000,
02844 0x0,0xe0001ff,0xc0000000,0x70000000,0x10,0x20000,0x33110,0xe0e00,0x383801f,0xfc03c000,0x7ff00ffe,0x0,0x0,0x3e0,0x0,0x0,0x1c,
02845 0x38e07,0x1ffc01,0xe0000700,0x1c,0x78c001,0xc0007ff0,0x1c00038,0x7c000,0x70070,0x1c3,0x80001c00,0xe00e0,0x0,0x1c0000,0x0,
02846 0x380e,0x18c000,0x0,0x0,0xe1c0001,0xe0010700,0x780e000,0x1c038380,0x70700e0e,0x1c1c038,0x78070e0e,0xe0001c,0x38000,0x70000e00,
02847 0xe0001,0xc0003800,0x7003807,0x7037070,0xe0e01c1,0xc0383807,0x700e070,0x701c0387,0x70e00e,0x1c01c380,0x3801c007,0xe00e,0x38038700,
02848 0x70e00e1c,0x1c38038,0x70071c1c,0xf00038,0x70000,0xe0001c00,0xe0001,0xc0003800,0x7003c07,0x8380e0f0,0x1e1e03c3,0xc078780f,
02849 0xf01e007,0x803e0783,0x80e0701c,0xe0381c0,0x7003f007,0x80f00fc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02850 0x0,0x0,0x0,0x0,0x0,0x6,0x1800061c,0xc0de01,0xc0000000,0xc0000e00,0x70,0xf0000,0x3c00,0x38001c0f,0xe003c,0x3c0,0xe0000e,0x701e00e,
02851 0x3c0780,0x1e003c0,0x780000,0xfc00001f,0x80000000,0x60e1e780,0x78700f07,0x4380f0,0x38000700,0xf00e38,0x3801c00,0xc0781c07,
02852 0x81c000e0,0x38e07e0,0xe03c1c00,0x380f0e0,0x1e0003c0,0xe00780f,0xee00f0,0x780e0780,0x1c007800,0xe00001,0xc000e000,0x0,0x700,
02853 0xf0780e07,0x8041c078,0x38020038,0xe03c1c,0x7001c00,0x1c00707,0x801c0070,0xe1c701c0,0xe0381e03,0x8380f00e,0x80380,0x1c003c1e,
02854 0x7e00f8,0xf80f1e00,0x3f003c00,0x70000e,0x1c000,0x0,0xf0100f7,0x80078000,0x700078f0,0x10,0x7ff000,0x61208,0x1e0700,0x383800f,
02855 0x78078000,0x3de007bc,0x0,0x0,0x0,0x0,0x0,0x401c,0x70e0f,0xf7803,0xc0000700,0x1c,0x38c001,0xc000efb8,0x1c00038,0x1e000,0x3c1e0,
02856 0xc1,0x80000000,0x783c0,0x0,0x0,0x0,0x3c1e,0x18c000,0x0,0x0,0xc180003,0x60000300,0xd80e010,0x3c03c780,0x78f00f1e,0x1e3c03c,
02857 0x70039c0e,0x70041c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700380f,0x703f070,0x1e0e03c1,0xc078380f,0x701e0e0,0x381c0787,
02858 0x80f0f01e,0x1e03c3c0,0x7801c007,0xe00e,0x38078700,0xf0e01e1c,0x3c38078,0x700f1c1c,0x78041c,0x1038020,0x70040e00,0x800e0001,
02859 0xc0003800,0x7001c07,0x380e070,0x1c0e0381,0xc070380e,0x701c007,0x801e0703,0xc1e0783c,0xf0781e0,0xf003f007,0x80e00fc0,0x0,
02860 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xe,0x1801867c,0xc0cf83,0xe0000000,0xe0000e00,
02861 0x70,0xf0000,0x3c00,0x38000f1e,0xe0070,0x180780,0xe0603e,0x783c01e,0x1e0f01,0x7c003c0,0x780000,0x3c00001e,0x700,0x307fe700,
02862 0x38701e07,0xc1c383e0,0x38000700,0x7c1e38,0x3801c00,0xe0f01c03,0x81c000e0,0x38e03e0,0x78781c00,0x1e1e0e0,0xe180780,0xe003c1e,
02863 0x7c00f0,0x781e03c0,0x1c007000,0xe00001,0xc000e000,0x0,0x783,0xf07c1e07,0xc0c1e0f8,0x3e0e0038,0xf07c1c,0x7001c00,0x1c00703,
02864 0xc01e0070,0xe1c701c0,0xf0781f07,0x83c1f00e,0xe0f80,0x1e003c3e,0x7e00f8,0xf80e0e00,0x3f003800,0x70000e,0x1c000,0x0,0x7830077,
02865 0xf0000,0x700078f0,0x10,0x20000,0x41208,0xc03c0380,0x3c38007,0x70070000,0x1dc003b8,0x0,0x0,0x0,0x0,0x0,0x707c,0x6070f,0x86077003,
02866 0x80000700,0x1c,0x3ec401,0xc001c01c,0x1c00038,0xf000,0x1ffc0,0x40,0x80000000,0x3ff80,0x0,0x0,0x0,0x3e3e,0x18c000,0x0,0x0,
02867 0x8100006,0x60000300,0x1980f070,0x3801c700,0x38e0071c,0xe3801c,0x70039c0e,0x7c1c1c,0x38000,0x70000e00,0xe0001,0xc0003800,
02868 0x700383e,0x701f03c,0x3c078780,0xf0f01e1e,0x3c3c1c0,0x1c3f0f03,0xc1e0783c,0xf0781e0,0xf001c007,0xe81e,0x3c1f8783,0xf0f07e1e,
02869 0xfc3c1f8,0x783f1e3e,0x187c0c1f,0x703e0e0,0x7c1c0f83,0x800e0001,0xc0003800,0x7001e0f,0x380e078,0x3c0f0781,0xe0f03c1e,0x783c007,
02870 0x801e0f03,0xc3e0787c,0xf0f81e1,0xf003f007,0xc1e00fc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02871 0x0,0x0,0x1c,0xe,0x3801fff8,0x6187ff,0xe0000000,0xe0000e00,0x70,0xf0000,0x3c00,0x38000ffe,0x1fff0ff,0xfe1fff80,0xe07ffc,0x3ffc01c,
02872 0x1fff01,0xff8003c0,0x780000,0x4000010,0x700,0x301e6700,0x387ffe03,0xffc3ffc0,0x3fff0700,0x3ffe38,0x383ffe0,0xfff01c03,0xc1fff8e0,
02873 0x38e03e0,0x7ff81c00,0x1ffe0e0,0xf1fff80,0xe003ffe,0x7c00f0,0x781c01c0,0x1c00ffff,0xe00001,0xc000e000,0x0,0x3ff,0x707ffc03,
02874 0xffc0fff8,0x1ffe0038,0x7ffc1c,0x707fff0,0x1c00701,0xc00ff070,0xe1c701c0,0x7ff01fff,0x1fff00e,0xfff00,0xff81fee,0x7e00f0,
02875 0x781e0f00,0x1e007ffc,0x70000e,0x1c000,0x0,0x3ff003e,0xf0000,0xe00070e0,0x60830010,0x20000,0x41208,0xfffc01c0,0x1fffe03,0xe00ffff0,
02876 0xf8001f0,0x0,0x0,0x0,0x0,0x0,0x7ff8,0xc07fd,0xfe03e007,0xffc00700,0x1c,0x1ffc1f,0xffc08008,0x1c00038,0x7000,0x7f00,0x0,0x0,
02877 0xfe00,0x0,0xffff800,0x0,0x3ff7,0x8018c000,0x0,0x0,0x6,0x60000700,0x19807ff0,0x3801c700,0x38e0071c,0xe3801c,0x70039c0f,0xf03ffc1f,
02878 0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ffc,0x701f03f,0xfc07ff80,0xfff01ffe,0x3ffc080,0x83fff03,0xffe07ffc,0xfff81ff,
02879 0xf001c007,0xeffc,0x1ffb83ff,0x707fee0f,0xfdc1ffb8,0x3ff70ff7,0xf83ffc0f,0xff01ffe0,0x3ffc07ff,0x83fff87f,0xff0fffe1,0xfffc0ffe,
02880 0x380e03f,0xf807ff00,0xffe01ffc,0x3ff8007,0x803ffe01,0xfee03fdc,0x7fb80ff,0x7001e007,0xffc00780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02881 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xc,0x3801fff0,0x7f83fe,0x70000000,0xe0000e00,0x0,0xf0000,0x3c00,0x700007fc,
02882 0x1fff0ff,0xfe1ffe00,0xe07ff8,0x1ff801c,0xffe01,0xff0003c0,0x780000,0x0,0x700,0x38000f00,0x3c7ffc01,0xff83ff80,0x3fff0700,
02883 0x1ffc38,0x383ffe0,0x7fe01c01,0xe1fff8e0,0x38e03e0,0x3ff01c00,0xffc0e0,0x71fff00,0xe001ffc,0x7c00f0,0x783c01e0,0x1c00ffff,
02884 0xe00000,0xe000e000,0x0,0x1ff,0x7077f801,0xff807fb8,0xffc0038,0x3fdc1c,0x707fff0,0x1c00701,0xe007f070,0xe1c701c0,0x3fe01dfe,
02885 0xff700e,0x7fe00,0xff80fee,0x3c0070,0x703c0780,0x1e007ffc,0x70000e,0x1c000,0x0,0x1fe001c,0xe0000,0xe000e1c0,0x71c78010,0x20000,
02886 0x21318,0xfff800c0,0xfffe01,0xc00ffff0,0x70000e0,0x0,0x0,0x0,0x0,0x0,0x3ff0,0x1803fd,0xfe01c007,0xffc00700,0x1c,0xffc1f,0xffc00000,
02887 0x1c00038,0x7000,0x0,0x0,0x0,0x0,0x0,0xffff800,0x0,0x3ff7,0x8018c000,0x0,0x0,0xc,0x60000e00,0x31803fe0,0x7801ef00,0x3de007bc,
02888 0xf7801e,0xf003fc0f,0xf01ff81f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ff8,0x701f01f,0xf803ff00,0x7fe00ffc,0x1ff8000,
02889 0x67fe01,0xffc03ff8,0x7ff00ff,0xe001c007,0xeff8,0xffb81ff,0x703fee07,0xfdc0ffb8,0x1ff70ff7,0xf81ff807,0xfe00ffc0,0x1ff803ff,
02890 0x3fff87f,0xff0fffe1,0xfffc07fc,0x380e01f,0xf003fe00,0x7fc00ff8,0x1ff0000,0x37fc00,0xfee01fdc,0x3fb807f,0x7001e007,0x7f800780,
02891 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,
02892 0x0,0xe0000,0x3c00,0x700001f0,0x1fff0ff,0xfe07f800,0xe01fe0,0x7e0038,0x3f800,0xfc0003c0,0x700000,0x0,0x700,0x18000e00,0x1c7ff000,
02893 0x7e03fe00,0x3fff0700,0x7f038,0x383ffe0,0x1f801c00,0xf1fff8e0,0x38e01e0,0xfc01c00,0x3f80e0,0x787fc00,0xe0007f0,0x7c00f0,0x387800f0,
02894 0x1c00ffff,0xe00000,0xe000e000,0x0,0xfc,0x7071f000,0x3f003e38,0x3f00038,0x1f1c1c,0x707fff0,0x1c00700,0xf003f070,0xe1c701c0,
02895 0x1f801c7c,0x7c700e,0x1f800,0x3f8078e,0x3c0070,0x707803c0,0x1c007ffc,0x70000e,0x1c000,0x0,0x7c0008,0x1e0000,0xe000e1c0,0x71c30010,
02896 0x20000,0x1e1f0,0x3fe00020,0x3ffe00,0x800ffff0,0x2000040,0x0,0x0,0x0,0x0,0x0,0xfc0,0x3001f0,0x78008007,0xffc00700,0x1c,0x3f81f,
02897 0xffc00000,0x1c00038,0x407000,0x0,0x0,0x0,0x0,0x0,0xffff800,0x0,0x39c7,0x18c000,0x0,0x0,0x18,0x60001c00,0x61801f80,0x7000ee00,
02898 0x1dc003b8,0x77000e,0xe001f80f,0xf007e01f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83fc0,0x700f007,0xe000fc00,0x1f8003f0,
02899 0x7e0000,0xe1f800,0x7f000fe0,0x1fc003f,0x8001c007,0xe7f0,0x7e380fc,0x701f8e03,0xf1c07e38,0xfc703c1,0xe003f001,0xf8003f00,
02900 0x7e000fc,0x3fff87f,0xff0fffe1,0xfffc03f8,0x380e00f,0xc001f800,0x3f0007e0,0xfc0000,0x61f800,0x78e00f1c,0x1e3803c,0x7001c007,
02901 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,
02902 0x1c0000,0x0,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,
02903 0x0,0x0,0x0,0x0,0xe00000,0x7000e000,0x0,0x0,0x0,0x0,0x0,0x1c00,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x1c000000,
02904 0x70000e,0x1c000,0x0,0x0,0x1c0000,0xe000c180,0x10,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,
02905 0x0,0x38,0x70e000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x2000,0x0,0x1f,0xf8003800,0x7fe00000,0x0,0x0,0x0,0x0,0x4000,
02906 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,
02907 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,
02908 0x0,0x1c0000,0x0,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0xe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e000,
02909 0x0,0x0,0x0,0x0,0x0,0xe00000,0x7000e000,0x0,0x0,0x0,0x0,0x0,0x1c00,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x1c000000,
02910 0x70000e,0x1c000,0x0,0x0,0x1c0001,0xe001c380,0x10,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,
02911 0x0,0x38,0x7fe000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x3000,0x0,0x1f,0xf8007000,0x7fe00000,0x0,0x0,0x0,0x0,0x6000,
02912 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,
02913 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,
02914 0x0,0x380000,0x1,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00000,0x0,0x0,0x3c18000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf000,
02915 0x0,0x0,0x0,0x0,0x0,0xfe0000,0x380fe000,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x38000000,
02916 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,
02917 0x38,0x1f8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x1800,0x0,0x0,0x6000e000,0x1800000,0x0,0x0,0x0,0x0,0x3000,0x0,
02918 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,
02919 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,
02920 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,
02921 0x0,0x0,0x0,0xfe0000,0xfe000,0x0,0x0,0x0,0x0,0x0,0x607800,0x0,0x3c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x78000000,
02922 0x3f800e,0x3f8000,0x0,0x0,0x300043,0xc0018200,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,
02923 0x0,0x38,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x11800,0x0,0x0,0x6001ff00,0x1800000,0x0,0x0,0x0,0x0,0x23000,0x0,0x0,
02924 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,
02925 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,
02926 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,
02927 0xfe000,0x0,0x0,0x0,0x0,0x0,0x7ff000,0x0,0x7f800000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xf8000000,0x3f800e,0x3f8000,0x0,
02928 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,
02929 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,
02930 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,
02931 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x7fff8,0x0,0x0,0x0,0x0,0x7fe000,0x0,
02933 0x7f000000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xf0000000,0xf800e,0x3e0000,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02934 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,
02935 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,
02936 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,
02937 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02938 0x0,0x0,0x0,0x0,0x7fff8,0x0,0x0,0x0,0x0,0x1fc000,0x0,0x7e000000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xc0000000,0xe,0x0,
02939 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,
02940 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,
02941 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,
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,0x7fff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02944 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,
02945 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02946 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
02947
02948
02949 const unsigned int font29x57[29*57*256/32] = {
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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
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,0x0,0x0,
02954 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,
02955 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,
02956 0xc0000000,0x0,0x7c00,0xf80,0x7e000,0x0,0x7c00000,0xf80000,0x7e000000,0x0,0x0,0x1f00,0x3e0,0x1f800,0x0,0x0,0x0,0x3,0xe0000000,
02957 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,
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,0x0,0x0,0x0,0x0,0x0,
02961 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02962 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,
02963 0x0,0x0,0x0,0x0,0x0,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,
02964 0x1f0000,0x7e00000,0xf838001f,0xf80001f,0xf0000000,0x0,0x3e00,0x1f00,0x7e000,0x3e1f000,0x3e00000,0x1f00000,0x7e00003e,0x1f000000,
02965 0x3e0,0xe0000f80,0x7c0,0x1f800,0x3e0e00,0x7c3e000,0x0,0x1,0xf0000000,0xf800003f,0x1f0f,0x800001f0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02970 0x0,0x0,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,
02971 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,
02972 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0000,0x1e0000,0xff00001,0xfe38001f,0xf80003f,
02973 0xf8000000,0x0,0x1e00,0x1e00,0xff000,0x3e1f000,0x1e00000,0x1e00000,0xff00003e,0x1f000000,0x7f8,0xe0000780,0x780,0x3fc00,0x7f8e00,
02974 0x7c3e000,0x0,0x0,0xf0000000,0xf000007f,0x80001f0f,0x800001e0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02979 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,
02980 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,
02981 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000,0x3c0000,0x1e780003,0xfff8001f,0xf80003c,0x78000000,0x0,0xf00,0x3c00,0x1e7800,
02982 0x3e1f000,0xf00000,0x3c00001,0xe780003e,0x1f000000,0xfff,0xe00003c0,0xf00,0x79e00,0xfffe00,0x7c3e000,0x0,0x0,0x78000001,0xe00000f3,
02983 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,
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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
02988 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,
02989 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,
02990 0x0,0x78000,0x780000,0x3c3c0003,0x8ff0001f,0xf800078,0x3c000000,0x0,0x780,0x7800,0x3c3c00,0x3e1f000,0x780000,0x7800003,0xc3c0003e,
02991 0x1f000000,0xe3f,0xc00001e0,0x1e00,0xf0f00,0xe3fc00,0x7c3e000,0x0,0x0,0x3c000003,0xc00001e1,0xe0001f0f,0x80000780,0x0,0x0,
02992 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,
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,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,
02998 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,
02999 0x83e0001f,0xf800070,0x1c000000,0x0,0x3c0,0xf000,0x781e00,0x3e1f000,0x3c0000,0xf000007,0x81e0003e,0x1f000000,0xe0f,0x800000f0,
03000 0x3c00,0x1e0780,0xe0f800,0x7c3e000,0x0,0x0,0x1e000007,0x800003c0,0xf0001f0f,0x80000f00,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf8000000,
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,0x0,0x0,0x0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03004 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03005 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03006 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03007 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,
03008 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,
03009 0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0x0,0x0,
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,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,
03013 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,
03014 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,
03015 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,
03016 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00000,0x3e000,0x3e00000,0x0,0x78,0x3c000000,0x0,0x1f000,0x3e0,
03017 0x3e000,0x0,0x1f000000,0x3e0000,0x3e000000,0x0,0x0,0x7c00,0xf8,0xf800,0x0,0x0,0x0,0xf,0x80000000,0x1f00001f,0x0,0x3e,0x0,
03018 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03019 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,
03020 0x0,0x0,0x0,0x0,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,
03021 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03022 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,
03023 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,
03024 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,
03025 0x0,0x0,0xf80000,0x7c000,0x3e00000,0xf0380000,0x70,0x1c000000,0x0,0xf800,0x7c0,0x3e000,0x0,0xf800000,0x7c0000,0x3e000000,
03026 0x0,0x3c0,0xe0003e00,0x1f0,0xf800,0x3c0e00,0x0,0x0,0x7,0xc0000000,0x3e00001f,0x0,0x7c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03027 0x0,0x0,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,
03028 0xf8,0xf8000,0x1c000,0x0,0x0,0x0,0x0,0x1f,0xc0000000,0x1ff8,0xff00,0x0,0x0,0x3fe000,0x0,0x1fc00001,0xfe000000,0x0,0x0,0x0,
03029 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,
03030 0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x780000,0x1,0xe0000000,0x0,0x780000,0x3,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,
03031 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,
03032 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,
03033 0x0,0x0,0x1ff,0x1f0f8,0x0,0xff000,0x0,0x0,0x0,0x3f,0xff00000f,0x80000000,0xfe0,0x3f80,0xf00,0x0,0x0,0x0,0x1,0xf8000003,0xe0000000,
03034 0x1c00,0xe000,0xe00,0x0,0x0,0x0,0x0,0x0,0x3c,0x78000000,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000,
03035 0x7f0000,0x0,0x1fc07000,0x0,0x0,0x0,0x0,0x0,0x3f800,0x780000,0x78000,0x7f00001,0xfc38001f,0xf800070,0x1c000000,0x0,0x7800,
03036 0x780,0x7f000,0x3e1f000,0x7800000,0x780000,0x7f00003e,0x1f0003f0,0x7f0,0xe0001e00,0x1e0,0x1fc00,0x7f0e00,0x7c3e000,0x0,0x3,
03037 0xc0000000,0x3c00003f,0x80001f0f,0x80000078,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03038 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x1e078000,0x30000000,0x3ff,0xc00001e0,0xf0,
03039 0x78000,0x1c000,0x0,0x0,0x0,0x0,0x1e0007f,0xf000007e,0x1ffff,0x7ffe0,0x1f80,0x3ffff80,0xfff803,0xfffff800,0xfff80007,0xff800000,
03040 0x0,0x0,0x0,0x0,0x1ffe00,0x0,0xfe0003,0xfff80000,0x3ffe01ff,0xe00003ff,0xffe01fff,0xff0003ff,0xe01e0007,0x803ffff0,0xfff80,
03041 0x3c000fc0,0x7800001f,0x8003f07e,0x1e000f,0xfe0007ff,0xf00003ff,0x8007ffe0,0x1fff8,0x7fffffe,0xf0003c1,0xe000079e,0xf1f,0x1f3e0,
03042 0x1f01ff,0xfff8003f,0xf003c000,0x7fe0,0x3f00,0x0,0x3c0000,0x1,0xe0000000,0x0,0x780000,0xf,0xfe000000,0x78000,0x3c00,0xf000,
03043 0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xfc0000f0,0x3fe00,0x0,0x0,0xfff00,0x0,0x0,0x3fe000,
03044 0x0,0x0,0x0,0x1dc0,0x0,0x3fff00,0x0,0x3ffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff1c07ff,0x3c0f001e,0x3c000000,
03045 0x0,0x0,0x1e3c0,0xf80007c,0x0,0x780000,0x0,0xfff8000,0x3e00,0x1f00000,0x7ff,0xc001f0f8,0x0,0x3ffc00,0x0,0x0,0x0,0x3f,0xff00003f,
03046 0xe0000000,0x3ff8,0xffe0,0x1e00,0x0,0xfffc00,0x0,0x7,0xf800000f,0xf8000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000,
03047 0x3f800001,0xfc00003f,0xf80000ff,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc,
03048 0xfc00,0x3c001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x0,0x7ff8f0f0,0x3c0780,0x1e03c00,0xf01e000,0x783e0001,0xf01e0000,0xffe00,
03049 0x3c0000,0xf0000,0x7700001,0xfe38001f,0xf800070,0x1c000000,0x0,0x3c00,0xf00,0x77000,0x3e1f000,0x3c00000,0xf00000,0x7700003e,
03050 0x1f0000f8,0xc0007f8,0xe0000f00,0x3c0,0x1dc00,0x7f8e00,0x7c3e000,0x0,0x1,0xe0000000,0x7800003b,0x80001f0f,0x800000f0,0x1e0000,
03051 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,
03052 0x0,0x0,0x780000,0x3c1e0000,0x1e070000,0x300001f0,0x7ff,0xc00001e0,0x1e0,0x7c000,0x1c000,0x0,0x0,0x0,0x0,0x3c000ff,0xf80007fe,
03053 0x3ffff,0x801ffff8,0x1f80,0x3ffff80,0x3fff803,0xfffff801,0xfffc000f,0xffc00000,0x0,0x0,0x0,0x0,0x7fff80,0x0,0xfe0003,0xffff0000,
03054 0xffff01ff,0xfc0003ff,0xffe01fff,0xff000fff,0xf01e0007,0x803ffff0,0xfff80,0x3c001f80,0x7800001f,0xc007f07e,0x1e001f,0xff0007ff,
03055 0xfc0007ff,0xc007fffc,0x3fffc,0x7fffffe,0xf0003c1,0xf0000f9e,0xf0f,0x8003e1e0,0x1e01ff,0xfff8003f,0xf001e000,0x7fe0,0x3f00,
03056 0x0,0x1e0000,0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,
03057 0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x1fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x3de0,0x0,0x7fff80,0x0,0xfffff80,
03058 0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe7bc07ff,0x3e1f000f,0x78000000,0x0,0x0,0xf780,0x7800078,0x0,0x780000,0x180000,
03059 0x1fff8000,0x1e00,0x1e0003c,0xfff,0xc001f0f8,0x0,0x7ffe00,0x0,0x0,0x0,0x3f,0xff00007f,0xf0000000,0x3ffc,0xfff0,0x3c00,0x0,
03060 0x7fffc00,0x0,0x7,0xf800003f,0xfe000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xe00001ff,
03061 0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000fc00,0x3c003ffe,0x1fff0,
03062 0xfff80,0x7ffc00,0x3ffe000,0x0,0xfffce0f0,0x3c0780,0x1e03c00,0xf01e000,0x781e0001,0xe01e0000,0x3fff00,0x1e0000,0x1e0000,0xf780003,
03063 0xcf78001f,0xf800078,0x3c000000,0x0,0x1e00,0x1e00,0xf7800,0x3e1f000,0x1e00000,0x1e00000,0xf780003e,0x1f0000fc,0x7c000f3d,
03064 0xe0000780,0x780,0x3de00,0xf3de00,0x7c3e000,0x0,0x0,0xf0000000,0xf000007b,0xc0001f0f,0x800001e0,0x1e0000,0x3e1f00,0x0,0x0,
03065 0x0,0x0,0x0,0x0,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,
03066 0x3c1e0000,0x1e0f0000,0x300007fc,0xfff,0xc00001e0,0x1e0,0x3c000,0x1c000,0x0,0x0,0x0,0x0,0x3c001ff,0xfc001ffe,0x3ffff,0xc01ffffc,
03067 0x3f80,0x3ffff80,0x7fff803,0xfffff803,0xfffe001f,0xffe00000,0x0,0x0,0x0,0x0,0xffff80,0x7f800,0xfe0003,0xffff8001,0xffff01ff,
03068 0xff0003ff,0xffe01fff,0xff001fff,0xf01e0007,0x803ffff0,0xfff80,0x3c003f00,0x7800001f,0xc007f07f,0x1e003f,0xff8007ff,0xff000fff,
03069 0xe007ffff,0x7fffc,0x7fffffe,0xf0003c0,0xf0000f1e,0xf07,0x8003c1f0,0x3e01ff,0xfff8003f,0xf001e000,0x7fe0,0x7f80,0x0,0xe0000,
03070 0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,
03071 0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x3fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x78f0,0x0,0xffff80,0x0,0x3fffff80,0x1f,
03072 0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc7f80070,0x3e1f0007,0x70000000,0x0,0x0,0x7700,0x7c000f8,0x0,0x780000,0x180000,
03073 0x3fff8000,0x1f00,0x3e0003c,0x1f03,0xc001f0f8,0x0,0x703f00,0x0,0x0,0x0,0x3f,0xff0000f0,0xf8000000,0x303e,0xc0f8,0x7800,0x0,
03074 0xffffc00,0x0,0x7,0x3800003e,0x3e000000,0x1c00,0xe000,0x3c00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00000f,0xe00001ff,
03075 0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000fe00,0x3c007fff,0x3fff8,
03076 0x1fffc0,0xfffe00,0x7fff000,0x1,0xffffc0f0,0x3c0780,0x1e03c00,0xf01e000,0x781f0003,0xe01e0000,0x3fff80,0xe0000,0x3c0000,0x1e3c0003,
03077 0x8ff0001f,0xf80003c,0x78000000,0x0,0xe00,0x3c00,0x1e3c00,0x3e1f000,0xe00000,0x3c00001,0xe3c0003e,0x1f00007f,0xf8000e3f,0xc0000380,
03078 0xf00,0x78f00,0xe3fc00,0x7c3e000,0x0,0x0,0x70000001,0xe00000f1,0xe0001f0f,0x800003c0,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,
03079 0x0,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,
03080 0x30000ffe,0xf80,0xc00001e0,0x3c0,0x1e000,0x101c040,0x0,0x0,0x0,0x0,0x78003f0,0x7e001ffe,0x3f807,0xe01f00fe,0x3f80,0x3ffff80,
03081 0x7e01803,0xfffff007,0xe03f003f,0x3f00000,0x0,0x0,0x0,0x0,0xfc0fc0,0x3ffe00,0xfe0003,0xffffc003,0xf81f01ff,0xff8003ff,0xffe01fff,
03082 0xff003f01,0xf01e0007,0x803ffff0,0xfff80,0x3c007e00,0x7800001f,0xc007f07f,0x1e007e,0xfc007ff,0xff801f83,0xf007ffff,0x800fc07c,
03083 0x7fffffe,0xf0003c0,0xf0000f0f,0x1e07,0xc007c0f8,0x7c01ff,0xfff8003c,0xf000,0x1e0,0xffc0,0x0,0xf0000,0x1,0xe0000000,0x0,0x780000,
03084 0x3e,0x0,0x78000,0x3c00,0xf000,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0x800000f0,0x1f80,
03085 0x0,0x0,0x7e0780,0x0,0x0,0x1f82000,0x0,0x0,0x0,0x7070,0x0,0x1f80f80,0x0,0x7fffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,
03086 0x0,0x1,0xc3f80070,0x3f3f0007,0xf0000000,0x0,0x0,0x7f00,0x3e001f0,0x0,0x780000,0x180000,0x7f018000,0xf80,0x7c0003c,0x3e00,
03087 0x4001f0f8,0xfe00,0x400f00,0x0,0x0,0x0,0x7f000000,0xe0,0x38000000,0x1e,0x38,0x7800,0x0,0x1ffe1c00,0x0,0x0,0x38000078,0xf000000,
03088 0x1c00,0xe000,0x7f800,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xf00001ff,0xffc03f81,0xf007ffff,0xc03ffffe,
03089 0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf800fe00,0x3c00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800,
03090 0x3,0xf07fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x780f8007,0xc01e0000,0x7e0fc0,0xf0000,0x3c0000,0x1c1c0003,0x87f0001f,0xf80003f,
03091 0xf8000000,0x0,0xf00,0x3c00,0x1c1c00,0x3e1f000,0xf00000,0x3c00001,0xc1c0003e,0x1f00003f,0xc0000e1f,0xc00003c0,0xf00,0x70700,
03092 0xe1fc00,0x7c3e000,0x0,0x0,0x78000001,0xe00000e0,0xe0001f0f,0x800003c0,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03093 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,
03094 0x1f00,0x1e0,0x3c0,0x1e000,0x3c1c1e0,0x0,0x0,0x0,0x0,0x78007c0,0x1f001f9e,0x3c001,0xf010003e,0x7780,0x3c00000,0xf800000,0xf007,
03095 0xc01f007c,0x1f80000,0x0,0x0,0x0,0x0,0xe003e0,0x7fff00,0x1ef0003,0xc007e007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x301e0007,
03096 0x80007800,0x780,0x3c00fc00,0x7800001f,0xe00ff07f,0x1e00f8,0x3e00780,0x1fc03e00,0xf807801f,0xc01f001c,0xf000,0xf0003c0,0xf0000f0f,
03097 0x1e03,0xc00f8078,0x780000,0xf0003c,0xf000,0x1e0,0x1f3e0,0x0,0x78000,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,
03098 0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0xf0,0xf80,0x0,0x0,0xf80180,0x0,0x0,0x1e00000,
03099 0x0,0x0,0x0,0xe038,0x0,0x3e00380,0x0,0xfe0f0000,0x0,0xf0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc0f00070,0x3b370003,0xe0000000,
03100 0x0,0x0,0x3e00,0x1e001e0,0x0,0x780000,0x180000,0x7c000000,0x780,0x780003c,0x3c00,0x0,0x7ffc0,0x780,0x0,0x0,0x3,0xffe00000,
03101 0x1c0,0x3c000000,0xe,0x38,0xf000,0x0,0x3ffe1c00,0x0,0x0,0x38000078,0xf000000,0x1c00,0xe000,0x7f000,0xf000,0x3de000,0x1ef0000,
03102 0xf780000,0x7bc00003,0xde00001e,0xf00003e7,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
03103 0xe0001e03,0xfc00fe00,0x3c01f007,0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x7,0xc01f80f0,0x3c0780,0x1e03c00,0xf01e000,0x78078007,
03104 0x801e0000,0x7803c0,0x78000,0x780000,0x380e0003,0x81e00000,0x1f,0xf0000000,0x0,0x780,0x7800,0x380e00,0x0,0x780000,0x7800003,
03105 0x80e00000,0x1ff,0x80000e07,0x800001e0,0x1e00,0xe0380,0xe07800,0x0,0x0,0x0,0x3c000003,0xc00001c0,0x70000000,0x780,0x1e0000,
03106 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03107 0x780000,0x3c1e0000,0x3c0e0007,0xfff01c07,0x1e00,0x1e0,0x780,0xf000,0x3e1c3e0,0x0,0x0,0x0,0x0,0xf0007c0,0x1f00181e,0x20000,
03108 0xf000001f,0xf780,0x3c00000,0x1f000000,0x1f00f,0x800f8078,0xf80000,0x0,0x0,0x0,0x0,0x8003e0,0x1fc0f80,0x1ef0003,0xc001e007,
03109 0x800101e0,0x7e003c0,0x1e00,0x7800,0x101e0007,0x80007800,0x780,0x3c00f800,0x7800001e,0xe00ef07f,0x801e00f0,0x1e00780,0x7c03c00,
03110 0x78078007,0xc01e0004,0xf000,0xf0003c0,0x78001e0f,0x1e03,0xe00f807c,0xf80000,0x1f0003c,0x7800,0x1e0,0x3e1f0,0x0,0x3c000,0x1,
03111 0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,
03112 0x1e,0xf0,0x780,0x0,0x0,0x1f00080,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x1e03c,0x0,0x3c00080,0x0,0xf80f0000,0x0,0x1f0000,0x0,0x0,
03113 0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x3bf70003,0xe0000000,0x0,0x0,0x3e00,0x1f003e0,0x0,0x780000,0x180000,0x78000000,0x7c0,0xf80003c,
03114 0x3c00,0x0,0x1f01f0,0x780,0x0,0x0,0xf,0x80f80000,0x1c0,0x1c000000,0xe,0x38,0x1e000,0x0,0x7ffe1c00,0x0,0x0,0x380000f0,0x7800000,
03115 0x1c00,0xe000,0x7fc00,0xf000,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x80007800,0x10078000,0x3c0000,
03116 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00ff00,0x3c01e003,0xc00f001e,0x7800f0,0x3c00780,0x1e003c00,
03117 0x7,0x800f00f0,0x3c0780,0x1e03c00,0xf01e000,0x7807c00f,0x801e0000,0xf803c0,0x3c000,0xf00000,0x780f0000,0x0,0x7,0xc0000000,
03118 0x0,0x3c0,0xf000,0x780f00,0x0,0x3c0000,0xf000007,0x80f00000,0x7ff,0xc0000000,0xf0,0x3c00,0x1e03c0,0x0,0x0,0x0,0x0,0x1e000007,
03119 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,
03120 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c1e001f,0xfff03803,0x80001e00,0x1e0,0x780,0xf000,0xf9cf80,
03121 0x0,0x0,0x0,0x0,0xf000780,0xf00001e,0x0,0xf800000f,0xe780,0x3c00000,0x1e000000,0x1e00f,0x78078,0x7c0000,0x0,0x0,0x0,0x0,0x1e0,
03122 0x3f003c0,0x1ef0003,0xc000f00f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780,0x3c01f000,0x7800001e,0xe00ef07f,
03123 0x801e01f0,0x1e00780,0x3c07c00,0x78078003,0xc03e0000,0xf000,0xf0003c0,0x78001e0f,0x1e01,0xf01f003c,0xf00000,0x3e0003c,0x7800,
03124 0x1e0,0x7c0f8,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,
03125 0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,0x0,0x0,0x3c00000,0x0,0x8,0x40,0x0,0x7e0000,0x7c00000,0x1,0xf00f0000,
03126 0x0,0x3e0000,0x0,0x3f,0xfc0,0xfc3f0,0xfc3f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0,0xf003c0,0x0,0x0,0x180000,0xf8000000,
03127 0x3c0,0xf00003c,0x3c00,0x0,0x3c0078,0x7ff80,0x0,0x0,0x1e,0x3c0000,0x1c0,0x1c000000,0xe,0xf0,0x0,0x0,0x7ffe1c00,0x0,0x0,0x380000f0,
03128 0x7800000,0x1c00,0xe000,0x3c00,0x0,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x8000f800,0x78000,0x3c0000,
03129 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00ff00,0x3c03e003,0xc01f001e,0xf800f0,0x7c00780,0x3e003c00,
03130 0xf,0x800f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803c00f,0x1fffc0,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03131 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,
03132 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x781e003f,0xfff03803,
03133 0x80001e00,0x1e0,0xf80,0xf000,0x3dde00,0x0,0x0,0x0,0x0,0xf000f00,0x780001e,0x0,0x7800000f,0x1e780,0x3c00000,0x3e000000,0x3e00f,
03134 0x780f0,0x7c0000,0x0,0x0,0x0,0x0,0x1e0,0x7c001e0,0x3ef8003,0xc000f00f,0x1e0,0xf003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780,
03135 0x3c03e000,0x7800001e,0xf01ef07b,0xc01e01e0,0xf00780,0x3e07800,0x3c078003,0xe03c0000,0xf000,0xf0003c0,0x78001e0f,0x1e00,0xf01e003e,
03136 0x1f00000,0x3c0003c,0x7800,0x1e0,0x78078,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,
03137 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,
03138 0xe70000,0x7800000,0x1,0xe00f0000,0x0,0x3c0000,0x0,0x3f,0xfc0,0xfc1f0,0x1f83f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0,
03139 0xf807c0,0x0,0x0,0x180000,0xf0000000,0x3e0,0x1f00003c,0x3e00,0x0,0x70001c,0x3fff80,0x0,0x0,0x38,0xe0000,0x1c0,0x1c000078,
03140 0x1c,0x1fe0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x7df000,0x3ef8000,0x1f7c0000,0xfbe00007,
03141 0xdf00003c,0x780003c7,0x8000f000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f780,
03142 0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0xf80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803e01f,0x1ffff8,0xf001e0,
03143 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,
03144 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03145 0x780000,0x3c1e0000,0x781e003e,0x30703803,0x80001e00,0x1e0,0xf00,0x7800,0xff800,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e,
03146 0x0,0x7800000f,0x3c780,0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x2000000,0x800000,0x1e0,0x78000e0,0x3c78003,
03147 0xc000f01e,0x1e0,0xf803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x701cf07b,0xc01e01e0,0xf00780,0x1e07800,
03148 0x3c078001,0xe03c0000,0xf000,0xf0003c0,0x7c003e0f,0x1e00,0xf83e001e,0x1e00000,0x7c0003c,0x3c00,0x1e0,0xf807c,0x0,0x0,0x1fe0001,
03149 0xe1fc0000,0x7f00003,0xf8780007,0xf000003c,0x7f0,0x783f0,0x0,0x0,0x7800000,0x1e00000,0x3e0f8000,0xfc00007,0xf8000007,0xf00001fc,
03150 0xf,0xc0003fc0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x3c00000,0x0,0x0,0x3c00000,0x0,0x18,0xc0,0x0,0x1818000,
03151 0x7800000,0x1,0xe00f0000,0x0,0x7c0000,0x0,0x1f,0x80001f80,0x7c1f8,0x1f83e0,0x0,0x0,0x0,0x70,0x38c70007,0xf8000000,0x7f03,
03152 0xf0000000,0x0,0x780780,0x0,0x0,0xfe0000,0xf0000000,0x1e0,0x1e00003c,0x3f00,0x0,0xe07f0e,0x7fff80,0x0,0x0,0x70,0x70000,0x1c0,
03153 0x1c000078,0x3c,0x1fc0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x78f000,0x3c78000,0x1e3c0000,
03154 0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,
03155 0xf80f780,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0x1f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801e01e,0x1ffffc,
03156 0xf007e0,0x3fc000,0x1fe0000,0xff00000,0x7f800003,0xfc00001f,0xe0000fc0,0xfc00007f,0xfe0,0x7f00,0x3f800,0x1fc000,0x0,0x0,0x0,
03157 0x1,0xf000001f,0x80000ff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x1f80000,0x1fc1e000,0x0,0x0,0x0,0x0,0x1e1fc0,0x0,0x0,0x0,0x0,
03158 0x0,0x0,0x0,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,
03159 0x781c007c,0x30003803,0x80001f00,0x1e0,0xf00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e,0x0,0x7800000f,0x3c780,
03160 0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x1e000000,0xf00000,0x3e0,0xf0000e0,0x3c78003,0xc000f01e,0x1e0,0x7803c0,
03161 0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c0f8000,0x7800001e,0x701cf079,0xe01e01e0,0xf00780,0x1e07800,0x3c078001,0xe03c0000,
03162 0xf000,0xf0003c0,0x3c003c0f,0x3e00,0x787c001f,0x3e00000,0xf80003c,0x3c00,0x1e0,0x1f003e,0x0,0x0,0x1fffc001,0xe7ff0000,0x3ffe000f,
03163 0xfe78003f,0xfc001fff,0xfe001ffc,0xf0078ffc,0x1ffc00,0x7ff000,0x7800f80,0x1e0000f,0x7f1fc01e,0x3ff0001f,0xfe00079f,0xfc0007ff,
03164 0x3c003c7f,0xf001fff8,0x1fffff0,0x3c003c0,0xf0000f1e,0xf1f,0x7c1f0,0x1f00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3c00000,0x100000,
03165 0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7800000,0x1,0xe00f0000,0x1000000,0xf80000,0x40000002,0xf,0x80001f00,0x7e0f8,0x1f07c0,
03166 0x0,0x0,0x0,0x70,0x38c7003f,0xff000000,0xff8f,0xf8000100,0xffffe,0x7c0f80,0x0,0x0,0x3ffc000,0xf0000020,0x1001f0,0x3c00003c,
03167 0x1f80,0x0,0x1c3ffc7,0x7c0780,0x0,0x0,0xe3,0xff038000,0xe0,0x38000078,0x78,0x1ff0,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0,
03168 0x7800000,0x1c00,0xe000,0xe00,0xf000,0x78f000,0x3c78000,0x1e3c0000,0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000,
03169 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,
03170 0x4000200f,0x3f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801f03e,0x1ffffe,0xf01fe0,0x3fff800,0x1fffc000,0xfffe0007,0xfff0003f,
03171 0xff8001ff,0xfc003ff3,0xfe0003ff,0xe0007ff8,0x3ffc0,0x1ffe00,0xfff000,0x3ff80001,0xffc0000f,0xfe00007f,0xf000003f,0xf8003c7f,
03172 0xe0003ffc,0x1ffe0,0xfff00,0x7ff800,0x3ffc000,0x1f80000,0xfff1c03c,0x3c01e0,0x1e00f00,0xf007800,0x781f0001,0xf01e7ff0,0x7c0007c,
03173 0x0,0x0,0x0,0x0,0x0,0x0,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,
03174 0x3c1e003f,0xfffff078,0x30003803,0x80000f00,0x1e0,0x1f00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x3c000f00,0x780001e,0x0,0x7800000f,
03175 0x78780,0x3c00000,0x3c000000,0x7c00f,0x780f0,0x3c0007,0xe000003f,0x0,0xfe000000,0xfe0000,0x3c0,0x1f000070,0x7c7c003,0xc000f01e,
03176 0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c1f0000,0x7800001e,0x783cf079,0xe01e03c0,0xf00780,0x1e0f000,0x3c078001,
03177 0xe03c0000,0xf000,0xf0003c0,0x3c003c07,0x81f03c00,0x7c7c000f,0x87c00000,0xf00003c,0x1e00,0x1e0,0x3e001f,0x0,0x0,0x3fffe001,
03178 0xefff8000,0x7fff001f,0xff78007f,0xfe001fff,0xfe003ffe,0xf0079ffe,0x1ffc00,0x7ff000,0x7801f00,0x1e0000f,0xffbfe01e,0x7ff8003f,
03179 0xff0007bf,0xfe000fff,0xbc003cff,0xf803fffc,0x1fffff0,0x3c003c0,0x78001e1e,0xf0f,0x800f80f0,0x1e00ff,0xffe0001e,0xf0,0x780,
03180 0x0,0x0,0x3c00000,0x380000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1008000,0x7800000,0x3,0xe00f0000,0x3800000,0xf00000,0xe0000007,
03181 0xf,0x80001f00,0x3e0f8,0x1e07c0,0x0,0x0,0x0,0x70,0x3807007f,0xff800000,0x1ffdf,0xfc000380,0xffffe,0x3e1f00,0x0,0x0,0xfffe000,
03182 0xf0000030,0x3800f8,0x7c00003c,0xfc0,0x0,0x18780c3,0xf00780,0x80100,0x0,0xc3,0xffc18000,0xf0,0x78000078,0xf0,0xf0,0x0,0x3c003c0,
03183 0xfffe1c00,0x0,0x0,0x380000f0,0x7800801,0x1c00,0xe000,0x1e00,0xf000,0xf8f800,0x7c7c000,0x3e3e0001,0xf1f0000f,0x8f80007c,0x7c000787,
03184 0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078001,0xe03c000f,
03185 0x1e00078,0xf0003c0,0x78001e00,0xe000701f,0x3fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x7800f87c,0x1e007f,0xf07e00,0x7fffc00,0x3fffe001,
03186 0xffff000f,0xfff8007f,0xffc003ff,0xfe007ff7,0xff0007ff,0xf000fffc,0x7ffe0,0x3fff00,0x1fff800,0x3ff80001,0xffc0000f,0xfe00007f,
03187 0xf00000ff,0xf8003cff,0xf0007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x1f80001,0xfffb803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001,
03188 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,
03189 0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e003f,0xfffff078,0x30001c07,0xf80,0x1e0,0x1e00,0x3c00,0xff800,0x1e0000,0x0,0x0,0x0,0x3c001e00,
03190 0x3c0001e,0x0,0x7800001e,0x70780,0x3c00000,0x78000000,0x78007,0x800f00f0,0x3e0007,0xe000003f,0x3,0xfe000000,0xff8000,0x7c0,
03191 0x1e000070,0x783c003,0xc001f01e,0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c3e0000,0x7800001e,0x3838f079,
03192 0xe01e03c0,0x780780,0x1e0f000,0x1e078001,0xe03c0000,0xf000,0xf0003c0,0x3c007c07,0x81f03c00,0x3ef80007,0x87800000,0x1f00003c,
03193 0x1e00,0x1e0,0x7c000f,0x80000000,0x0,0x3ffff001,0xffffc000,0xffff003f,0xff7800ff,0xff001fff,0xfe007ffe,0xf007bffe,0x1ffc00,
03194 0x7ff000,0x7803e00,0x1e0000f,0xffffe01e,0xfff8007f,0xff8007ff,0xff001fff,0xbc003dff,0xf807fffc,0x1fffff0,0x3c003c0,0x78001e0f,
03195 0x1e07,0xc01f00f0,0x1e00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7c00000,0x7c0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1018000,0x7800000,
03196 0x3,0xc00f0000,0x7c00000,0x1f00001,0xf000000f,0x80000007,0xc0003e00,0x1e07c,0x3e0780,0x0,0x0,0x0,0x70,0x380700ff,0xff800000,
03197 0x3ffff,0xfe0007c0,0xffffe,0x1e1e00,0x0,0x780000,0x1fffe000,0xf0000078,0x7c0078,0x7800003c,0xff0,0x0,0x38e0003,0x80f00780,
03198 0x180300,0x0,0x1c3,0x81e1c000,0x7f,0xf0000078,0x1e0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800c01,0x80001c00,
03199 0xe000,0x603e00,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x7800078,0x3c000f87,0x8001e000,0x78000,0x3c0000,0x1e00000,
03200 0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f01,0xf000f81e,
03201 0x7bc0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007878,0x1e001f,0xf0f800,0x7fffe00,0x3ffff001,0xffff800f,0xfffc007f,0xffe003ff,
03202 0xff007fff,0xff800fff,0xf001fffe,0xffff0,0x7fff80,0x3fffc00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00001ff,0xfc003dff,0xf000ffff,
03203 0x7fff8,0x3fffc0,0x1fffe00,0xffff000,0x1f80003,0xffff803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001,0xe01ffffc,0x3c00078,0x0,
03204 0x0,0x0,0x0,0x0,0x0,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,
03205 0x3c1e003f,0xfffff078,0x30001e0f,0x300780,0x1e0,0x1e00,0x3c00,0x3dde00,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf800003e,
03206 0xf0780,0x3dfc000,0x783f8000,0xf8007,0xc01f00f0,0x3e0007,0xe000003f,0x1f,0xfc000000,0x7ff000,0xf80,0x3e007c70,0x783c003,0xc001e03c,
03207 0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007,0x80007800,0x780,0x3c7c0000,0x7800001e,0x3878f078,0xf01e03c0,0x780780,0x1e0f000,0x1e078001,
03208 0xe03e0000,0xf000,0xf0003c0,0x1e007807,0x83f03c00,0x3ef00007,0xcf800000,0x3e00003c,0xf00,0x1e0,0xf80007,0xc0000000,0x0,0x3e01f801,
03209 0xfe07e001,0xf80f007e,0x7f801f8,0x1f801fff,0xfe00fc0f,0xf007f83f,0x1ffc00,0x7ff000,0x7807c00,0x1e0000f,0x87e1e01f,0xe0fc00fc,
03210 0xfc007f8,0x1f803f03,0xfc003df0,0x3807e03c,0x1fffff0,0x3c003c0,0x78003e0f,0x1e03,0xe03e00f8,0x3e00ff,0xffe0001e,0xf0,0x780,
03211 0x0,0x0,0x7800000,0xfe0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7c00000,0x3,0xc00f0000,0xfe00000,0x3e00003,0xf800001f,
03212 0xc0000007,0xc0003e00,0x1e03c,0x3c0f80,0x0,0x0,0x0,0x70,0x380700fc,0x7800000,0x7c1fe,0x3e000fe0,0xffffe,0x1f3e00,0x0,0x780000,
03213 0x3f98e000,0xf000003c,0xfcf8007c,0xf800003c,0x3ffc,0x0,0x31c0001,0x80f00f80,0x380700,0x0,0x183,0x80e0c000,0x3f,0xe0000078,
03214 0x3c0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x38000078,0xf000e01,0xc003ffe0,0x1fff00,0x7ffc00,0xf000,0xf07800,0x783c000,0x3c1e0001,
03215 0xe0f0000f,0x7800078,0x3c000f07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,
03216 0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf801f01e,0xf3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007cf8,
03217 0x1e000f,0x80f0f000,0x7c03f00,0x3e01f801,0xf00fc00f,0x807e007c,0x3f003e0,0x1f80707f,0x8f801f80,0xf003f03f,0x1f81f8,0xfc0fc0,
03218 0x7e07e00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00003ff,0xfc003fc1,0xf801f81f,0x800fc0fc,0x7e07e0,0x3f03f00,0x1f81f800,0x1f80007,
03219 0xe07f003c,0x3c01e0,0x1e00f00,0xf007800,0x780f8003,0xe01fe07e,0x3e000f8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03220 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3f,0xfffff078,0x30000ffe,0x1f007c0,0x0,0x1e00,
03221 0x3c00,0xf9cf80,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf00000fc,0x1e0780,0x3fff800,0x78ffe000,0xf0003,0xe03e00f0,
03222 0x3e0007,0xe000003f,0x7f,0xe01fffff,0xf00ffc00,0x1f80,0x3c01ff70,0x783c003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007,
03223 0x80007800,0x780,0x3cfc0000,0x7800001e,0x3c78f078,0xf01e03c0,0x780780,0x3e0f000,0x1e078003,0xc01f0000,0xf000,0xf0003c0,0x1e007807,
03224 0x83f83c00,0x1ff00003,0xcf000000,0x3e00003c,0xf00,0x1e0,0x0,0x0,0x0,0x20007801,0xfc03e003,0xe003007c,0x3f803e0,0x7c0003c,
03225 0xf807,0xf007e00f,0x3c00,0xf000,0x780f800,0x1e0000f,0x87e1f01f,0x803c00f8,0x7c007f0,0xf803e01,0xfc003f80,0x80f8004,0x3c000,
03226 0x3c003c0,0x3c003c0f,0x1e03,0xe03e0078,0x3c0000,0x7c0001e,0xf0,0x780,0x0,0x0,0x3ffff800,0x1ff0000,0x0,0x7800000,0x0,0x18,
03227 0xc0,0x0,0x1818000,0x3e00000,0x3,0xc00f0000,0x1ff00000,0x3e00007,0xfc00003f,0xe0000003,0xc0003c00,0xf03c,0x3c0f00,0x0,0x0,
03228 0x0,0x70,0x380701f0,0x800000,0x780fc,0x1e001ff0,0x7c,0xf3c00,0x0,0x780000,0x7e182000,0xf000001f,0xfff00ffc,0xffc0003c,0x3cfe,
03229 0x0,0x31c0001,0x80f01f80,0x780f00,0x0,0x183,0x80e0c000,0xf,0x80000078,0x780,0x38,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x38000078,
03230 0xf000f01,0xe003ffe0,0x1fff00,0x7ff800,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x78000f8,0x3e000f07,0x8003c000,0x78000,
03231 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,
03232 0x78000f00,0x7c03e01e,0x1e3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78003cf0,0x1e0007,0x80f1e000,0x4000f00,0x20007801,0x3c008,
03233 0x1e0040,0xf00200,0x780403f,0x7803e00,0x3007c00f,0x803e007c,0x1f003e0,0xf801f00,0x780000,0x3c00000,0x1e000000,0xf00007f0,
03234 0x3e003f00,0x7801f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e003c,0x3c01e0,0x1e00f00,0xf007800,0x78078003,
03235 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,
03236 0x0,0x0,0x0,0x0,0x0,0x780000,0x0,0xf078007c,0x300007fc,0x7e00fe0,0x0,0x1e00,0x3c00,0x3e1c3e0,0x1e0000,0x0,0x0,0x0,0xf0001e00,
03237 0x3c0001e,0x1,0xf000fff8,0x1e0780,0x3fffe00,0x79fff000,0x1f0001,0xfffc00f0,0x7e0007,0xe000003f,0x3ff,0x801fffff,0xf003ff80,
03238 0x3f00,0x3c03fff0,0xf01e003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3df80000,0x7800001e,
03239 0x1c70f078,0x781e03c0,0x780780,0x3c0f000,0x1e078007,0xc01f8000,0xf000,0xf0003c0,0x1e007807,0x83f83c00,0xfe00003,0xff000000,
03240 0x7c00003c,0x780,0x1e0,0x0,0x0,0x0,0x7c01,0xf801f007,0xc00100f8,0x1f803c0,0x3c0003c,0x1f003,0xf007c00f,0x80003c00,0xf000,
03241 0x783f000,0x1e0000f,0x3c0f01f,0x3e01f0,0x3e007e0,0x7c07c00,0xfc003f00,0xf0000,0x3c000,0x3c003c0,0x3c003c0f,0x1e01,0xf07c007c,
03242 0x7c0000,0xfc0001e,0xf0,0x780,0x0,0x0,0x3ffff000,0x3838000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0xff0000,0x3f00000,0x3,0xc00fff00,
03243 0x38380000,0x7c0000e,0xe000070,0x70000001,0xe0003c00,0xf01e,0x780e00,0x0,0x0,0x0,0x0,0x1e0,0x0,0x780f8,0xf003838,0xfc,0xffc00,
03244 0x0,0x780000,0x7c180000,0xf000000f,0xffe00fff,0xffc0003c,0x783f,0x80000000,0x6380000,0xc0f83f80,0xf81f00,0x0,0x303,0x80e06000,
03245 0x0,0x78,0xf00,0x78,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x3800003c,0x3e000f81,0xf003ffe0,0x1fff00,0x1fc000,0xf000,0x1e03c00,
03246 0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e000f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,
03247 0x3c000001,0xe0001e00,0x3c0f0f0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3e07c01e,0x1e3c0f0,0x3c0780,0x1e03c00,
03248 0xf01e000,0x78003ff0,0x1e0007,0x80f1e000,0xf80,0x7c00,0x3e000,0x1f0000,0xf80000,0x7c0001e,0x3c07c00,0x10078007,0x803c003c,
03249 0x1e001e0,0xf000f00,0x780000,0x3c00000,0x1e000000,0xf00007c0,0x1e003e00,0x7c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00,
03250 0xf,0x801f003c,0x3c01e0,0x1e00f00,0xf007800,0x7807c007,0xc01f801f,0x1f001f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03251 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x0,0xe078003c,0x300001f0,0x3f801ff0,0x0,
03252 0x3c00,0x1e00,0x3c1c1e0,0x1e0000,0x0,0x0,0x0,0xf0001e0f,0x3c0001e,0x3,0xe000fff0,0x3c0780,0x3ffff00,0x7bfff800,0x1e0000,0x7ff00078,
03253 0x7e0007,0xe000003f,0x1ffc,0x1fffff,0xf0007ff0,0x7e00,0x3c07c3f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,
03254 0x1fffff,0x80007800,0x780,0x3ffc0000,0x7800001e,0x1ef0f078,0x781e03c0,0x780780,0x7c0f000,0x1e07801f,0x800ff000,0xf000,0xf0003c0,
03255 0xf00f807,0x83b83c00,0xfc00001,0xfe000000,0xf800003c,0x780,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0xc00000f0,0xf80780,0x3c0003c,
03256 0x1e001,0xf007c007,0x80003c00,0xf000,0x787e000,0x1e0000f,0x3c0f01f,0x1e01e0,0x1e007c0,0x3c07800,0x7c003f00,0xf0000,0x3c000,
03257 0x3c003c0,0x3e007c07,0x80003c00,0xf8f8003c,0x780000,0xf80001e,0xf0,0x780,0x0,0x0,0x7ffff000,0x601c000,0x3,0xffff0000,0x0,
03258 0xfff,0xf8007fff,0xc0000000,0x7e003c,0x1fe0000,0xc0003,0xc00fff00,0x601c0000,0xf800018,0x70000c0,0x38000001,0xe0007800,0x701e,
03259 0x701e00,0x0,0x0,0x0,0x0,0x1e0,0x6,0x700f8,0xf00601c,0xf8,0x7f800,0x0,0x780000,0xf8180000,0xf000000f,0x87c00fff,0xffc0003c,
03260 0xf01f,0xc0000000,0x6380000,0xc07ff780,0x1f03e03,0xfffffe00,0x303,0x81c06000,0x0,0x1ffff,0xfe001e00,0x180f8,0x0,0x3c003c0,
03261 0x3ffe1c00,0x3f00000,0x0,0x3800003f,0xfe0007c0,0xf8000000,0x18000000,0xc0000006,0x1f000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e,
03262 0x3c000f0,0x1e001f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f0f0,
03263 0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f0f801e,0x3c3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007,
03264 0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07c00,0xf0007,0x8078003c,0x3c001e0,0x1e000f00,0x780000,0x3c00000,
03265 0x1e000000,0xf0000f80,0x1f003e00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0xf,0x3f003c,0x3c01e0,0x1e00f00,0xf007800,
03266 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,
03267 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe078003f,0xb0000000,0xfc003cf0,0x0,0x3c00,0x1e00,0x101c040,0x1e0000,0x0,0x0,0x1,
03268 0xe0001e1f,0x83c0001e,0x7,0xe000fff0,0x3c0780,0x3c03f80,0x7fc0fc00,0x1e0000,0xfff80078,0xfe0007,0xe000003f,0x7fe0,0x1fffff,
03269 0xf0000ffc,0xfc00,0x780f81f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3ffc0000,
03270 0x7800001e,0x1ef0f078,0x3c1e03c0,0x780780,0x1fc0f000,0x1e07ffff,0x7ff00,0xf000,0xf0003c0,0xf00f007,0xc3b87c00,0x7c00001,0xfe000000,
03271 0xf800003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0x800000f0,0xf80780,0x1e0003c,0x1e001,0xf0078007,0x80003c00,0xf000,0x78fc000,
03272 0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,0x3c07800,0x7c003e00,0xf0000,0x3c000,0x3c003c0,0x1e007807,0x80003c00,0x7df0003c,0x780000,
03273 0x1f00001e,0xf0,0x780,0x0,0x0,0x7800000,0xe7ce000,0x3,0xffff0000,0x0,0xfff,0xf8007fff,0xc0000000,0x1f0,0xffe000,0x1c0003,
03274 0xc00fff00,0xe7ce0000,0xf800039,0xf38001cf,0x9c000000,0xe0007800,0x780e,0x701c00,0x0,0x0,0x0,0x0,0x1e0,0x7,0xf0078,0xf00e7ce,
03275 0x1f0,0x7f800,0x0,0x780000,0xf0180000,0xf000000e,0x1c0001f,0xe000003c,0xf007,0xe0000000,0x6380000,0xc03fe780,0x3e07c03,0xfffffe00,
03276 0x303,0xffc06000,0x0,0x1ffff,0xfe003ffe,0x1fff0,0x0,0x3c003c0,0x1ffe1c00,0x3f00000,0x7,0xffc0001f,0xfc0003e0,0x7c000001,0xfc00000f,
03277 0xe000007f,0x1e000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,
03278 0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e,
03279 0x783c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007,0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07800,
03280 0xf0003,0xc078001e,0x3c000f0,0x1e000780,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c03c003,0xc01e001e,0xf000f0,
03281 0x7800780,0x3c003c00,0xf,0x7f003c,0x3c01e0,0x1e00f00,0xf007800,0x7803c007,0x801f000f,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03282 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,
03283 0xf0007cf8,0x7800000,0x3c00,0x1e00,0x1c000,0x1e0000,0x0,0x0,0x1,0xe0001e1f,0x83c0001e,0xf,0xc000fff8,0x780780,0x2000f80,0x7f803e00,
03284 0x3e0003,0xfffe007c,0x1fe0000,0x0,0x3ff00,0x0,0x1ff,0x8001f000,0x780f00f0,0x1f00f003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff,
03285 0xfe03c00f,0xf81fffff,0x80007800,0x780,0x3ffe0000,0x7800001e,0xee0f078,0x3c1e03c0,0x7807ff,0xff80f000,0x1e07fffe,0x3ffe0,
03286 0xf000,0xf0003c0,0xf00f003,0xc7bc7800,0xfc00000,0xfc000001,0xf000003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xe000f80f,0x800001e0,
03287 0xf80f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x79f8000,0x1e0000f,0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003e00,
03288 0xf0000,0x3c000,0x3c003c0,0x1e007807,0x81e03c00,0x7df0003e,0xf80000,0x3e00003e,0xf0,0x7c0,0xfc000,0x80000000,0x7800000,0x1e7cf000,
03289 0x3,0xffff0000,0x0,0x18,0xc0,0x0,0xf80,0x7ffc00,0x380003,0xc00fff01,0xe7cf0000,0x1f000079,0xf3c003cf,0x9e000000,0xe0007000,
03290 0x380e,0xe01c00,0x0,0x0,0x0,0x0,0x1e0,0x3,0x800f0078,0xf01e7cf,0x3e0,0x3f000,0x0,0x780000,0xf018001f,0xfff8001e,0x1e0000f,
03291 0xc000003c,0xf003,0xe0000000,0x6380000,0xc00fc780,0x7c0f803,0xfffffe00,0x303,0xfe006000,0x0,0x1ffff,0xfe003ffe,0x1ffe0,0x0,
03292 0x3c003c0,0xffe1c00,0x3f00000,0x7,0xffc00007,0xf00001f0,0x3e00001f,0xfc0000ff,0xe00007ff,0x3e000,0x3e01e00,0x1f00f000,0xf8078007,
03293 0xc03c003e,0x1e001e0,0xf001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,
03294 0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000fc0,
03295 0x1e0007,0x80f1f000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c0f800,0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000,
03296 0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1e,0xf7803c,0x3c01e0,0x1e00f00,
03297 0xf007800,0x7803e00f,0x801e000f,0x80f803e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03298 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe0f0000f,0xff00001f,0x8000f87c,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,
03299 0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x1f,0x800000fe,0xf00780,0x7c0,0x7f001e00,0x3c0007,0xe03f003f,0x3fe0000,0x0,0x3fc00,0x0,
03300 0x7f,0x8001e000,0x781f00f0,0x1e00f003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3f9f0000,0x7800001e,
03301 0xfe0f078,0x3c1e03c0,0x7807ff,0xff00f000,0x1e07fff8,0xfff8,0xf000,0xf0003c0,0xf81f003,0xc7bc7800,0xfe00000,0x78000003,0xe000003c,
03302 0x1e0,0x1e0,0x0,0x0,0x0,0x1fffc01,0xe000780f,0x1e0,0x780f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7bf0000,0x1e0000f,
03303 0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xf8000,0x3c000,0x3c003c0,0x1f00f807,0x81f03c00,0x3fe0001e,0xf00000,0x7c00007c,
03304 0xf0,0x3e0,0x3ff801,0x80000000,0x7800000,0x3cfcf800,0x3,0xffff0000,0x0,0x18,0xc0,0x0,0x7c00,0x1fff00,0x700003,0xc00f0003,
03305 0xcfcf8000,0x3e0000f3,0xf3e0079f,0x9f000000,0xf000,0x1000,0x0,0x0,0x0,0x0,0x0,0x1f0,0x1,0xc00f0078,0xf03cfcf,0x800007c0,0x1e000,
03306 0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x8000003c,0xf001,0xf0000000,0x6380000,0xc0000000,0xf81f003,0xfffffe00,0x303,
03307 0x87006000,0x0,0x1ffff,0xfe003ffe,0x7f00,0x0,0x3c003c0,0x3fe1c00,0x3f00000,0x7,0xffc00000,0xf8,0x1f0001ff,0xf0000fff,0x80007ffc,
03308 0xfc000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf001e07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,
03309 0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3fc001e,0x1e03c0f0,0x3c0780,
03310 0x1e03c00,0xf01e000,0x78000780,0x1e0007,0x80f0fc00,0x3fff80,0x1fffc00,0xfffe000,0x7fff0003,0xfff8001f,0xffc0001e,0x3c0f000,
03311 0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000,0x3c00000,0x1e000000,0xf0001e00,0xf803c00,0x3c078001,0xe03c000f,0x1e00078,
03312 0xf0003c0,0x78001e07,0xfffffe1e,0x1e7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801e00f,0x1e0007,0x807803c0,0x0,0x0,0x0,0x0,0x0,
03313 0x0,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,
03314 0xffc0007e,0xf03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x3f,0x3e,0xf00780,0x3c0,0x7e001e00,
03315 0x7c000f,0x800f001f,0xffde0000,0x0,0x3e000,0x0,0xf,0x8003e000,0x781e0070,0x1e00f003,0xc001f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,
03316 0xf81e0007,0x80007800,0x780,0x3f1f0000,0x7800001e,0x7c0f078,0x1e1e03c0,0x7807ff,0xfc00f000,0x1e07fffe,0xffc,0xf000,0xf0003c0,
03317 0x781e003,0xc71c7800,0x1ff00000,0x78000003,0xe000003c,0x1e0,0x1e0,0x0,0x0,0x0,0xffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,
03318 0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7f000,0x3c000,
03319 0x3c003c0,0xf00f007,0xc1f07c00,0x1fc0001f,0x1f00000,0xfc000ff8,0xf0,0x1ff,0xfffe07,0x80000000,0x7800000,0x7ffcfc00,0x0,0xf000000,
03320 0x0,0x18,0xc0,0x0,0x3e000,0x1ff80,0xe00003,0xc00f0007,0xffcfc000,0x3e0001ff,0xf3f00fff,0x9f800000,0x6000,0x0,0x0,0x7c000,
03321 0x0,0x0,0x0,0xfe,0x0,0xe00f007f,0xff07ffcf,0xc0000fc0,0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x80000000,0xf800,
03322 0xf0000000,0x6380000,0xc0000000,0x1f03c000,0x1e00,0x303,0x83806000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xfe1c00,0x3f00000,0x0,
03323 0x0,0x3c,0xf801fff,0xfff8,0x7ffc0,0x1f8000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf003c07,0x8003c000,0x78000,
03324 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,
03325 0x78000f00,0x1f8001e,0x1e03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e000f,0x80f0ff00,0x1ffff80,0xffffc00,0x7fffe003,
03326 0xffff001f,0xfff800ff,0xffc007ff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,
03327 0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x3c7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801f01f,
03328 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,
03329 0x0,0x0,0x0,0x0,0x780000,0x3,0xc0f00000,0xfff003f0,0x1f00f03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x7ff80000,0x3,
03330 0xc0001e0f,0x3c0001e,0x7e,0x1f,0x1e00780,0x3e0,0x7e000f00,0x78000f,0x7800f,0xff9e0000,0x0,0x3fc00,0x0,0x7f,0x8003c000,0x781e0070,
03331 0x3e00f803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3e0f8000,0x7800001e,0x7c0f078,0x1e1e03c0,
03332 0x7807ff,0xf000f000,0x1e07807f,0xfe,0xf000,0xf0003c0,0x781e003,0xc71c7800,0x3ef00000,0x78000007,0xc000003c,0x1e0,0x1e0,0x0,
03333 0x0,0x0,0x1ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e,
03334 0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7ff80,0x3c000,0x3c003c0,0xf00f003,0xc1f07800,0x1fc0000f,0x1e00000,0xf8000ff0,0xf0,
03335 0xff,0xffffff,0x80000000,0x3fffc000,0xfff9fe00,0x0,0xf000000,0x0,0x18,0xc0,0x0,0x1f0000,0x1fc0,0x1c00003,0xc00f000f,0xff9fe000,
03336 0x7c0003ff,0xe7f81fff,0x3fc00000,0x0,0x0,0x0,0xfe000,0x1ffffc0f,0xfffffc00,0x0,0xff,0xf0000000,0x700f007f,0xff0fff9f,0xe0000f80,
03337 0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00fff,0xffc00000,0xf800,0xf0000000,0x6380000,0xc0ffff80,0x3e078000,0x1e00,0x7ff80303,
03338 0x83c06000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000,0x0,0x7f,0xff00001e,0x7c1fff0,0xfff80,0x7ffc00,0x3f0000,0x7c01f00,
03339 0x3e00f801,0xf007c00f,0x803e007c,0x1f003e0,0xf803c07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
03340 0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f8001e,0x3c03c0f0,0x3c0780,0x1e03c00,0xf01e000,
03341 0x78000780,0x1e001f,0xf07f80,0x3ffff80,0x1ffffc00,0xffffe007,0xffff003f,0xfff801ff,0xffc03fff,0xffc0f000,0x1fffff,0xc0fffffe,
03342 0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,
03343 0xfffffe1e,0x787803c,0x3c01e0,0x1e00f00,0xf007800,0x7800f01e,0x1e0007,0x803c0780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03344 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,
03345 0x7800000,0x3c00,0x1e00,0x0,0x7fffff80,0x0,0x7ff80000,0x7,0x80001e00,0x3c0001e,0xfc,0xf,0x1e00780,0x1e0,0x7c000f00,0x78000f,
03346 0x78007,0xff1e0000,0x0,0x3ff00,0x0,0x1ff,0x8003c000,0x781e0070,0x3c007803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007,
03347 0x80007800,0x780,0x3c07c000,0x7800001e,0x7c0f078,0xf1e03c0,0x780780,0xf000,0x1e07801f,0x3e,0xf000,0xf0003c0,0x781e003,0xcf1c7800,
03348 0x3cf80000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0,0x0,0x0,0x3ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,
03349 0x80003c00,0xf000,0x7ff8000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3fff0,0x3c000,0x3c003c0,0xf81f003,
03350 0xc3b87800,0xf80000f,0x1e00001,0xf0000ff0,0xf0,0xff,0xf03fff,0x80000000,0x3fff8001,0xfff1ff00,0x0,0xf000000,0x0,0x18,0xc0,
03351 0x0,0x380000,0x7c0,0x3c00003,0xc00f001f,0xff1ff000,0xf80007ff,0xc7fc3ffe,0x3fe00000,0x0,0x0,0x0,0x1ff000,0x7ffffe1f,0xffffff00,
03352 0x0,0x7f,0xfe000000,0x780f007f,0xff1fff1f,0xf0001f00,0x1e000,0x0,0x780001,0xe0180000,0xf000001c,0xe00fff,0xffc00000,0x7c00,
03353 0xf0000000,0x31c0001,0x80ffff80,0x3e078000,0x1e00,0x7ff80183,0x81c0c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000,
03354 0x0,0x7f,0xff00001e,0x7c7ff03,0xc03ff8fe,0x1ffc0f0,0x7e0000,0x7800f00,0x3c007801,0xe003c00f,0x1e0078,0xf003c0,0x7803c07,0x8003c000,
03355 0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c,
03356 0xf0001e0,0x78000f00,0x3fc001e,0x7803c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e007f,0xf03fe0,0x7ffff80,0x3ffffc01,
03357 0xffffe00f,0xffff007f,0xfff803ff,0xffc07fff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,
03358 0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x707803c,0x3c01e0,0x1e00f00,0xf007800,
03359 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,
03360 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x30f81f00,0xffe1e00f,0x87800000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000,
03361 0x7,0x80001e00,0x3c0001e,0x1f8,0x7,0x83c00780,0x1e0,0x7c000f00,0xf8001e,0x3c001,0xfc1e0000,0x0,0x7fe0,0x0,0xffc,0x3c000,0x781e0070,
03362 0x3ffff803,0xc000783c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x380f078,0xf1e03c0,
03363 0x780780,0xf000,0x1e07800f,0x8000001e,0xf000,0xf0003c0,0x3c3c003,0xcf1e7800,0x7c780000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0,
03364 0x0,0x0,0x7f003c01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7f7c000,0x1e0000f,0x3c0f01e,
03365 0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfff8,0x3c000,0x3c003c0,0x781e003,0xc3b87800,0x1fc00007,0x83e00003,0xe0000ff8,0xf0,
03366 0x1ff,0xc007fe,0x0,0x7fff8001,0xffe3ff00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x3c0,0x7800003,0xc00f001f,0xfe3ff000,0xf80007ff,
03367 0x8ffc3ffc,0x7fe00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x1f,0xff000000,0x3c0f007f,0xff1ffe3f,0xf0003e00,0x1e000,0x0,0x780001,
03368 0xe0180000,0xf000001e,0x1e00fff,0xffc00000,0x3f00,0xf0000000,0x31c0001,0x80ffff80,0x1f03c000,0x1e00,0x7ff80183,0x81c0c000,
03369 0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x7f,0xff00003c,0xf87f007,0xc03f83ff,0x81fc01f0,0x7c0000,0x7ffff00,0x3ffff801,
03370 0xffffc00f,0xfffe007f,0xfff003ff,0xff807fff,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
03371 0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf003c0f0,0x3c0780,0x1e03c00,0xf01e000,
03372 0x78000780,0x1ffffe,0xf00ff0,0xfe00780,0x7f003c03,0xf801e01f,0xc00f00fe,0x7807f0,0x3c0ffff,0xffc0f000,0x1fffff,0xc0fffffe,
03373 0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,
03374 0x1e,0xf07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783e,0x1e0007,0x801e0f80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03375 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x307c0801,0xe1f1e00f,0x87000000,
03376 0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000,0xf,0x1e00,0x3c0001e,0x3f0,0x7,0x83fffffc,0x1e0,0x7c000f00,0xf0001e,0x3c000,0x3e0000,
03377 0x0,0x1ffc,0x1fffff,0xf0007ff0,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x3c000,0x781e0007,0x80007800,
03378 0x780,0x3c03e000,0x7800001e,0xf078,0x79e03c0,0x780780,0xf000,0x1e078007,0x8000000f,0xf000,0xf0003c0,0x3c3c001,0xee0ef000,
03379 0xf87c0000,0x7800001f,0x3c,0x78,0x1e0,0x0,0x0,0x0,0x7c003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00,
03380 0xf000,0x7e3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x1ffc,0x3c000,0x3c003c0,0x781e003,0xe3b8f800,
03381 0x1fc00007,0x83c00007,0xc00000fc,0xf0,0x3e0,0x8001f8,0x0,0x7800000,0xffc7fe00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0,
03382 0xf000003,0xc00f000f,0xfc7fe001,0xf00003ff,0x1ff81ff8,0xffc00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x3,0xff800000,0x1e0f0078,
03383 0xffc7f,0xe0007c00,0x1e000,0x0,0x780001,0xe0180000,0xf000000e,0x1c00007,0x80000000,0x1f81,0xe0000000,0x38e0003,0x80000000,
03384 0xf81f000,0x1e00,0x7ff801c3,0x80e1c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf8,0x1f070007,0xc03803ff,0xc1c001f0,
03385 0xf80000,0xfffff00,0x7ffff803,0xffffc01f,0xfffe00ff,0xfff007ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,
03386 0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f00f,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e,0xf003c0f0,
03387 0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1ffffc,0xf003f8,0xf800780,0x7c003c03,0xe001e01f,0xf00f8,0x7807c0,0x3c0fc1e,0xf000,
03388 0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,
03389 0xf0003c0,0x78001e00,0x1e,0x1e07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783c,0x1e0007,0x801e0f00,0x0,0x0,0x0,0x0,0x0,0x0,
03390 0x0,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,
03391 0xc071e007,0xcf000000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0xf,0xf00,0x780001e,0x7e0,0x7,0x83fffffc,0x1e0,0x7c000f00,0x1f0001e,
03392 0x3c000,0x3c0000,0x0,0x3ff,0x801fffff,0xf003ff80,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007,
03393 0x80007800,0x780,0x3c01f000,0x7800001e,0xf078,0x79e03c0,0xf00780,0xf000,0x3e078007,0xc000000f,0xf000,0xf0003c0,0x3c3c001,
03394 0xee0ef000,0xf03e0000,0x7800003e,0x3c,0x78,0x1e0,0x0,0x0,0x0,0xf8003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,
03395 0x80003c00,0xf000,0x7c3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfc,0x3c000,0x3c003c0,0x3c3e001,0xe7b8f000,
03396 0x3fe00007,0xc7c0000f,0xc000003e,0xf0,0x7c0,0x0,0x0,0x7c00000,0x7fcffc00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0,0x1e000003,
03397 0xc00f0007,0xfcffc003,0xe00001ff,0x3ff00ff9,0xff800000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x1f800000,0xf0f0078,0x7fcff,
03398 0xc000fc00,0x1e000,0x0,0x780001,0xe0180000,0xf000000f,0x87c00007,0x80000000,0xfe3,0xe0000000,0x18780c3,0x0,0x7c0f800,0x1e00,
03399 0xc3,0x80e18000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x1f0,0x3e00000f,0xc0000303,0xe00003f0,0xf00000,0xfffff80,
03400 0x7ffffc03,0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,
03401 0x3c000001,0xe0001e00,0x780f00f,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1f0f801f,0xe00780f0,0x3c0780,0x1e03c00,
03402 0xf01e000,0x78000780,0x1ffff8,0xf000f8,0x1f000780,0xf8003c07,0xc001e03e,0xf01f0,0x780f80,0x3c1f01e,0xf000,0x1e0000,0xf00000,
03403 0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,
03404 0x1e,0x3c07803c,0x3c01e0,0x1e00f00,0xf007800,0x78007c7c,0x1e0007,0x801f1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03405 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x81c00000,0x303c0003,0x8039e003,0xef000000,
03406 0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0xfc0,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000,
03407 0x0,0x7f,0xe01fffff,0xf00ffc00,0x3c000,0x781f00f0,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007,0x80007800,
03408 0x780,0x3c01f000,0x7800001e,0xf078,0x7de01e0,0xf00780,0x7800,0x3c078003,0xc000000f,0xf000,0xf0003c0,0x3e7c001,0xee0ef001,
03409 0xf01e0000,0x7800003e,0x3c,0x3c,0x1e0,0x0,0x0,0x0,0xf0003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00,
03410 0xf000,0x781f000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0x7df00003,
03411 0xc780000f,0x8000003e,0xf0,0x780,0x0,0x0,0x3c00000,0x3fcff800,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x1f00fc,0x1e0,0x1e000001,
03412 0xe00f0003,0xfcff8003,0xe00000ff,0x3fe007f9,0xff000000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x7c00000,0xf0f0078,0x3fcff,0x8000f800,
03413 0x1e000,0x0,0x780001,0xe0180000,0xf000001f,0xffe00007,0x8000003c,0x7ff,0xc0000000,0x1c3ffc7,0x0,0x3e07c00,0x1e00,0xe3,0x80738000,
03414 0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x3e0,0x7c00001d,0xc0000001,0xe0000770,0x1f00000,0xfffff80,0x7ffffc03,
03415 0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
03416 0xe0001e00,0x780f00f,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0x3e07c01f,0xc00780f0,0x3c0780,0x1e03c00,0xf01e000,
03417 0x78000780,0x1fffc0,0xf0007c,0x1e000780,0xf0003c07,0x8001e03c,0xf01e0,0x780f00,0x3c1e01e,0xf000,0x1e0000,0xf00000,0x7800000,
03418 0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1e,0x7807803c,
03419 0x3c01e0,0x1e00f00,0xf007800,0x78003c78,0x1e0007,0x800f1e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03420 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x83c00000,0x303c0003,0x8039e001,0xee000000,0x1e00,0x3c00,
03421 0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0x1f80,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000,0x0,0x1f,0xfc1fffff,
03422 0xf07ff000,0x0,0x780f00f0,0x78003c03,0xc000781e,0x1e0,0xf803c0,0x1e00,0x1e000,0x781e0007,0x80007800,0x780,0x3c00f800,0x7800001e,
03423 0xf078,0x3de01e0,0xf00780,0x7800,0x3c078003,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfe0ff003,0xe01f0000,0x7800007c,0x3c,0x3c,
03424 0x1e0,0x0,0x0,0x0,0xf0007c01,0xe000f80f,0x800001e0,0xf80f00,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x780f800,0x1e0000f,
03425 0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003c00,0x1e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0xf8f80003,0xe780001f,0x1e,
03426 0xf0,0x780,0x0,0x0,0x3c00000,0x1ffff000,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x3bc1de,0x1e0,0xf000001,0xe00f0001,0xffff0007,0xc000007f,
03427 0xffc003ff,0xfe000000,0x0,0x0,0x0,0xfe000,0x0,0x0,0x0,0x0,0x3c00000,0x1e0f0078,0x1ffff,0x1f000,0x1e000,0x0,0x780000,0xf0180000,
03428 0xf000001f,0xfff00007,0x8000003c,0x1ff,0x80000000,0xe0ff0e,0x0,0x1f03e00,0x1e00,0x70,0x70000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,
03429 0xe1c00,0x0,0x0,0x0,0x7c0,0xf8000019,0xc0000000,0xe0000670,0x1e00000,0xf000780,0x78003c03,0xc001e01e,0xf00f0,0x780780,0x3c0f807,
03430 0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf80f007,0xbc03c001,0xe01e000f,
03431 0xf00078,0x78003c0,0x3c001e00,0x7c03e00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,
03432 0xf0007c07,0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0xf800,0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,
03433 0xf0001e00,0x7803c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1f8001f,0xf00f803c,0x3c01e0,0x1e00f00,0xf007800,
03434 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,
03435 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x3c00000,0x303c0003,0x8039f001,0xfe000000,0x1e00,0x3c00,0x0,0x1e0000,0x0,0x0,0x3c,0xf00,
03436 0x780001e,0x3f00,0x7,0x80000780,0x3e0,0x3e000f00,0x3c0001e,0x3c000,0x7c0000,0x0,0x3,0xfe000000,0xff8000,0x0,0x3c0f81f0,0xf0001e03,
03437 0xc000780f,0x1e0,0xf003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x780,0x3c007c00,0x7800001e,0xf078,0x3de01e0,0xf00780,0x7800,
03438 0x3c078001,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfc07f003,0xe00f0000,0x78000078,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01,
03439 0xf000f007,0x800000f0,0xf80780,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,
03440 0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78001,0xe71df000,0xf8f80001,0xef80003e,0x1e,0xf0,0x780,0x0,0x0,0x3c00000,
03441 0xfffe000,0x0,0x3e000000,0x0,0x18,0x7fff,0xc0000000,0x60c306,0x1e0,0x7800001,0xe00f0000,0xfffe0007,0x8000003f,0xff8001ff,
03442 0xfc000000,0x0,0x0,0x0,0x7c000,0x0,0x0,0x0,0x0,0x3c00000,0x3c0f0078,0xfffe,0x3e000,0x1e000,0x0,0x780000,0xf0180000,0xf000003c,
03443 0xfcf80007,0x8000003c,0x7f,0x0,0x70001c,0x0,0xf81f00,0x0,0x38,0xe0000,0x0,0x0,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf81,
03444 0xf0000039,0xc0000000,0xe0000e70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,0x8000f000,0x78000,
03445 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f007,0xbc03c001,0xe01e000f,0xf00078,0x78003c0,
03446 0x3c001e00,0xf801f00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07,0x8003e03c,
03447 0x1f01e0,0xf80f00,0x7c1e01e,0x7800,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00,
03448 0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xe00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef8,0x1f000f,
03449 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,
03450 0x0,0x0,0xf,0x3c00000,0x307c0003,0x8038f000,0xfc000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e00003c,0x780,0xf00001e,
03451 0x7e00,0xf,0x80000780,0x3c0,0x3e001e00,0x3c0001f,0x7c000,0x780007,0xe000003f,0x0,0xfe000000,0xfe0000,0x0,0x3c07c3f0,0xf0001e03,
03452 0xc000f80f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x4000f80,0x3c003c00,0x7800001e,0xf078,0x1fe01f0,0x1f00780,
03453 0x7c00,0x7c078001,0xf000001f,0xf000,0xf0003c0,0x1e78001,0xfc07f007,0xc00f8000,0x780000f8,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01,
03454 0xf000f007,0xc00000f0,0xf80780,0x3c,0x1f003,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,
03455 0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78000,0xfe0fe001,0xf07c0001,0xef00007c,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,
03456 0x7cfc000,0xfc00000,0x3c00000f,0xc3f00000,0x18,0x7fff,0xc0000000,0x406303,0x3e0,0x3c00001,0xf00f0000,0x7cfc000f,0x8000001f,
03457 0x3f0000f9,0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x780700f8,0x7cfc,0x7c000,0x1e000,0x0,0x780000,0xf8180000,
03458 0xf0000070,0x3c0007,0x8000003c,0x3f,0x80000000,0x3c0078,0x0,0x780f00,0x0,0x1e,0x3c0000,0x0,0x0,0x0,0x0,0x0,0x3e007c0,0xe1c00,
03459 0x0,0x0,0x0,0xf01,0xe0000071,0xc0000000,0xe0001c70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,
03460 0x8000f800,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00f003,0xfc03e003,0xe01f001f,
03461 0xf800f8,0x7c007c0,0x3e003e01,0xf000f80f,0xf00f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07,
03462 0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0x7c00,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00,
03463 0xf003c00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xc00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef0,
03464 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,
03465 0x0,0x0,0x0,0x0,0x780000,0xf,0x3800040,0x30780003,0x8038f800,0x78000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078,
03466 0x780,0x1f00001e,0xfc00,0x20001f,0x780,0x80007c0,0x1f001e00,0x7c0000f,0x78000,0xf80007,0xe000003f,0x0,0x1e000000,0xf00000,
03467 0x3c000,0x3c03fff0,0xf0001e03,0xc001f007,0x800101e0,0x7e003c0,0x1e00,0x7800,0x781e0007,0x80007800,0x6000f00,0x3c003e00,0x7800001e,
03468 0xf078,0x1fe00f0,0x1e00780,0x3c00,0x78078000,0xf020001e,0xf000,0x7800780,0xff0001,0xfc07f00f,0x8007c000,0x780001f0,0x3c,0xf,
03469 0x1e0,0x0,0x0,0x0,0xf800fc01,0xf801f007,0xc00100f8,0x1f807c0,0x40003c,0xf807,0xf0078007,0x80003c00,0xf000,0x7803e00,0x1f0000f,
03470 0x3c0f01e,0x1e01f0,0x3e007e0,0x7c07c00,0xfc003c00,0x1e,0x3e000,0x3e007c0,0x1ff8000,0xfe0fe003,0xe03e0001,0xff0000fc,0x1e,
03471 0xf0,0x780,0x0,0x0,0x1f00080,0x3cf8000,0xfc00000,0x3c00001f,0x83f00000,0x18,0xc0,0x0,0xc06203,0x40003c0,0x1c00000,0xf80f0000,
03472 0x3cf8001f,0xf,0x3e000079,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x700780fc,0x3cf8,0xfc000,0x1e000,0x0,0x780000,
03473 0x7c180000,0xf0000020,0x100007,0x8000003c,0xf,0x80000000,0x1f01f0,0x0,0x380700,0x0,0xf,0x80f80000,0x0,0x0,0x0,0x0,0x0,0x3e007c0,
03474 0xe1c00,0x0,0x0,0x0,0xe01,0xc0000071,0xc0000001,0xc0001c70,0x1e00040,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,
03475 0x80007800,0x10078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00f003,0xfc01e003,0xc00f001e,
03476 0x7800f0,0x3c00780,0x1e003c00,0xe000700f,0x800f0078,0x7803c0,0x3c01e00,0x1e00f000,0xf0000780,0x1e0000,0xf0003c,0x1f001f80,
03477 0xf800fc07,0xc007e03e,0x3f01f0,0x1f80f80,0xfc1e01f,0x7c00,0x100f8000,0x807c0004,0x3e00020,0x1f000100,0x780000,0x3c00000,0x1e000000,
03478 0xf0000f80,0x1f003c00,0x3c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00,0x1f8000f,0x801f003e,0x7c01f0,0x3e00f80,0x1f007c00,
03479 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,
03480 0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0xf,0x7800078,0x31f80001,0xc070fc00,0xfc000000,0x1e00,0x7c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078,
03481 0x7c0,0x1f00001e,0x1f000,0x38003f,0x780,0xe000f80,0x1f803e00,0x780000f,0x800f8000,0x1f00007,0xe000003f,0x0,0x2000000,0x800000,
03482 0x3c000,0x3e01ff71,0xf0001f03,0xc007f007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x781e0007,0x80007800,0x7801f00,0x3c001f00,0x7800001e,
03483 0xf078,0xfe00f8,0x3e00780,0x3e00,0xf8078000,0xf838003e,0xf000,0x7c00f80,0xff0000,0xfc07e00f,0x8003c000,0x780001e0,0x3c,0xf,
03484 0x1e0,0x0,0x0,0x0,0xf801fc01,0xfc03e003,0xe003007c,0x3f803e0,0x1c0003c,0xfc0f,0xf0078007,0x80003c00,0xf000,0x7801f00,0xf8000f,
03485 0x3c0f01e,0x1e00f8,0x7c007f0,0xf803e01,0xfc003c00,0x8003e,0x1f000,0x1e00fc0,0xff0000,0xfe0fe007,0xc01f0000,0xfe0000f8,0x1e,
03486 0xf0,0x780,0x0,0x0,0xf80180,0x1cf0000,0x1f800000,0x3c00001f,0x83e00000,0x18,0xc0,0x0,0xc06203,0x70007c0,0xe00000,0x7e0f0000,
03487 0x1cf0001e,0x7,0x3c000039,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x7c00000,0xe00780fc,0x2001cf0,0xf8000,0x1e000,0x0,
03488 0x780000,0x7e182000,0xf0000000,0x7,0x8000003c,0x7,0xc0000000,0x7ffc0,0x0,0x180300,0x0,0x3,0xffe00000,0x0,0x0,0x0,0x0,0x0,
03489 0x3f00fc0,0xe1c00,0x0,0x0,0x0,0xc01,0x800000e1,0xc0000003,0xc0003870,0x1f001c0,0x3e0003e1,0xf0001f0f,0x8000f87c,0x7c3e0,0x3e1f00,
03490 0x1f1e007,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e03,0xfc00f001,0xfc01f007,
03491 0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x4000201f,0xc01f007c,0xf803e0,0x7c01f00,0x3e00f801,0xf0000780,0x1e0000,0xf0007c,
03492 0x1f003f80,0xf801fc07,0xc00fe03e,0x7f01f0,0x3f80f80,0x1fc1f03f,0x803e00,0x3007c003,0x803e001c,0x1f000e0,0xf800700,0x780000,
03493 0x3c00000,0x1e000000,0xf00007c0,0x3e003c00,0x3c01f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e001e,0xfc00f0,
03494 0x7e00780,0x3f003c01,0xf8000fe0,0x1fc03e,0x3f800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03495 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x780007f,0xfff00001,0xe0f07f03,0xfe000000,0xf00,0x7800,0x0,
03496 0x1e0000,0xfc0000,0x0,0x7e0000f0,0x3f0,0x7e000fff,0xfc03ffff,0xf83f00fe,0x780,0xfc03f80,0xfc0fc00,0xf800007,0xe03f0018,0x7e00007,
03497 0xe000003f,0x0,0x0,0x0,0x3c000,0x1e007c71,0xe0000f03,0xffffe003,0xf01f01ff,0xff8003ff,0xffe01e00,0x3f01,0xf81e0007,0x803ffff0,
03498 0x7e03f00,0x3c000f00,0x7ffffe1e,0xf078,0xfe007e,0xfc00780,0x1f83,0xf0078000,0x783f00fe,0xf000,0x3f03f00,0xff0000,0xfc07e01f,
03499 0x3e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7e07fc01,0xfe07e001,0xf80f007e,0x7f801f8,0xfc0003c,0x7ffe,0xf0078007,
03500 0x807ffffe,0xf000,0x7801f00,0xfff00f,0x3c0f01e,0x1e00fc,0xfc007f8,0x1f803f03,0xfc003c00,0xf80fc,0x1fff0,0x1f83fc0,0xff0000,
03501 0xfc07e007,0xc01f0000,0xfe0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfe0780,0xfe0000,0x1f000000,0x3c00001f,0x7c00e03,0x81c00018,
03502 0xc0,0x0,0x406203,0x7e01fc0,0x700000,0x7fffff80,0xfe0003f,0xffffc003,0xf800001f,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0,
03503 0x1f800001,0xc007c1fe,0x6000fe0,0x1ffffe,0x1e000,0x0,0x780000,0x3f98e03f,0xffff8000,0x7,0x8000003c,0x7,0xc0000000,0xfe00,
03504 0x0,0x80100,0x0,0x0,0x7f000000,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3f83fe8,0xe1c00,0x0,0x0,0x0,0x801,0xc1,0xc0000007,0x80003070,
03505 0xfc0fc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc03f01,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,
03506 0xffff001f,0xfff800ff,0xffc01fff,0xf800f001,0xfc00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800,0x1f,0xf07e003f,0x3f001f8,
03507 0x1f800fc0,0xfc007e07,0xe0000780,0x1e0000,0xf301f8,0xfc0ff80,0x7e07fc03,0xf03fe01f,0x81ff00fc,0xff807e0,0x7fc0f87f,0x81801f80,
03508 0xf003f01f,0x801f80fc,0xfc07e0,0x7e03f00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff807e0,0x7e003c00,0x3c01f81f,0x800fc0fc,0x7e07e0,
03509 0x3f03f00,0x1f81f800,0x1f8000f,0xe07e001f,0x83fc00fc,0x1fe007e0,0xff003f07,0xf8000fe0,0x1fe07e,0x3f800,0x0,0x0,0x0,0x0,0x0,
03510 0x0,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,
03511 0xffe00000,0xffe03fff,0xdf000000,0xf00,0x7800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0x1ff,0xfc000fff,0xfc03ffff,0xf83ffffc,0x780,
03512 0xfffff00,0x7fff800,0xf000007,0xffff001f,0xffe00007,0xe000003f,0x0,0x0,0x0,0x3c000,0x1e000001,0xe0000f03,0xffffc001,0xffff01ff,
03513 0xff0003ff,0xffe01e00,0x1fff,0xf81e0007,0x803ffff0,0x7fffe00,0x3c000f80,0x7ffffe1e,0xf078,0xfe003f,0xff800780,0xfff,0xf0078000,
03514 0x7c3ffffc,0xf000,0x3ffff00,0xff0000,0xf803e01e,0x1e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7fffbc01,0xffffc000,
03515 0xffff003f,0xfff800ff,0xffc0003c,0x3ffe,0xf0078007,0x807ffffe,0xf000,0x7800f80,0x7ff00f,0x3c0f01e,0x1e007f,0xff8007ff,0xff001fff,
03516 0xbc003c00,0xffffc,0x1fff0,0x1fffbc0,0xff0000,0x7c07c00f,0x800f8000,0x7e0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7fff80,0x7c0000,
03517 0x1f000000,0x3c00001e,0x7c00f07,0xc1e00018,0xc0,0x0,0x60e303,0x7ffff80,0x380000,0x3fffff80,0x7c0003f,0xffffc001,0xf000000f,
03518 0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff800003,0x8003ffff,0xfe0007c0,0x1ffffe,0x1e000,0x0,0x780000,0x1fffe03f,0xffff8000,
03519 0x7,0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3fffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x1c1,
03520 0xc000000f,0x7070,0x7fffc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0,
03521 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000f001,0xfc007fff,0x3fff8,0x1fffc0,0xfffe00,0x7fff000,0x3b,0xfffc003f,
03522 0xfff001ff,0xff800fff,0xfc007fff,0xe0000780,0x1e0000,0xf3fff8,0xffff780,0x7fffbc03,0xfffde01f,0xffef00ff,0xff7807ff,0xfbc0ffff,
03523 0xff800fff,0xf001ffff,0x800ffffc,0x7fffe0,0x3ffff00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff803ff,0xfc003c00,0x3c00ffff,0x7fff8,
03524 0x3fffc0,0x1fffe00,0xffff000,0x1f,0xfffc001f,0xffbc00ff,0xfde007ff,0xef003fff,0x780007e0,0x1ffffc,0x1f800,0x0,0x0,0x0,0x0,
03525 0x0,0x0,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,
03526 0xffc00000,0x7fc01fff,0x9f800000,0xf80,0xf800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0xff,0xf8000fff,0xfc03ffff,0xf83ffff8,0x780,
03527 0xffffe00,0x7fff000,0xf000003,0xfffe001f,0xffc00007,0xe000003f,0x0,0x0,0x0,0x3c000,0xf000003,0xe0000f83,0xffff0000,0xffff01ff,
03528 0xfc0003ff,0xffe01e00,0xfff,0xf01e0007,0x803ffff0,0x7fffc00,0x3c0007c0,0x7ffffe1e,0xf078,0x7e003f,0xff000780,0x7ff,0xe0078000,
03529 0x3c3ffff8,0xf000,0x1fffe00,0x7e0000,0xf803e03e,0x1f000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x3fff3c01,0xefff8000,
03530 0x7ffe001f,0xff78007f,0xff80003c,0x1ffc,0xf0078007,0x807ffffe,0xf000,0x78007c0,0x3ff00f,0x3c0f01e,0x1e003f,0xff0007bf,0xfe000fff,
03531 0xbc003c00,0xffff8,0xfff0,0xfff3c0,0x7e0000,0x7c07c01f,0x7c000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3fff80,0x380000,
03532 0x3e000000,0x7c00003e,0x7801f07,0xc1e00018,0xc0,0x0,0x39c1ce,0x7ffff00,0x1c0000,0xfffff80,0x380003f,0xffffc000,0xe0000007,
03533 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff000007,0x1ffcf,0xfe000380,0x1ffffe,0x1e000,0x0,0x780000,0xfffe03f,0xffff8000,0x7,
03534 0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x381,
03535 0xc000001e,0xe070,0x7fff80,0x7c0001f3,0xe0000f9f,0x7cf8,0x3e7c0,0x1f3e00,0xfbe007,0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0,
03536 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000f000,0xfc007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x79,0xfff8001f,
03537 0xffe000ff,0xff0007ff,0xf8003fff,0xc0000780,0x1e0000,0xf3fff0,0x7ffe780,0x3fff3c01,0xfff9e00f,0xffcf007f,0xfe7803ff,0xf3c07ff3,
03538 0xff8007ff,0xe000ffff,0x7fff8,0x3fffc0,0x1fffe00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff801ff,0xf8003c00,0x3c007ffe,0x3fff0,
03539 0x1fff80,0xfffc00,0x7ffe000,0x1d,0xfff8000f,0xff3c007f,0xf9e003ff,0xcf001ffe,0x780007c0,0x1efff8,0x1f000,0x0,0x0,0x0,0x0,
03540 0x0,0x0,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,
03541 0xfe000000,0x1f000fff,0xfc00000,0x780,0xf000,0x0,0x0,0xf80000,0x0,0x7e0001e0,0x7f,0xf0000fff,0xfc03ffff,0xf81ffff0,0x780,
03542 0x7fff800,0x1ffe000,0x1f000000,0xfff8001f,0xff000007,0xe000003e,0x0,0x0,0x0,0x3c000,0xf800003,0xc0000783,0xfff80000,0x3ffe01ff,
03543 0xe00003ff,0xffe01e00,0x7ff,0xc01e0007,0x803ffff0,0x3fff800,0x3c0003c0,0x7ffffe1e,0xf078,0x7e000f,0xfe000780,0x3ff,0xc0078000,
03544 0x3e1fffe0,0xf000,0x7ff800,0x7e0000,0xf803e07c,0xf800,0x780003ff,0xfffc003c,0x3,0xc00001e0,0x0,0x0,0x0,0xffe3c01,0xe7ff0000,
03545 0x3ffc000f,0xfe78003f,0xfe00003c,0x7f0,0xf0078007,0x807ffffe,0xf000,0x78003e0,0xff00f,0x3c0f01e,0x1e001f,0xfe00079f,0xfc0007ff,
03546 0x3c003c00,0x7ffe0,0x1ff0,0x7fe3c0,0x7e0000,0x7c07c03e,0x3e000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfff00,0x100000,
03547 0x3e000000,0x7800003c,0xf800f07,0xc1e00018,0xc0,0x0,0x1f80fc,0x3fffc00,0xc0000,0x3ffff80,0x100003f,0xffffc000,0x40000002,
03548 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xfc000006,0xff87,0xfc000100,0x1ffffe,0x1e000,0x0,0x780000,0x3ffc03f,0xffff8000,0x7,
03549 0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dff9f8,0xe1c00,0x0,0x0,0x0,0x0,0x3ff,
03550 0xf800003c,0xfffe,0x1ffe00,0x780000f3,0xc000079e,0x3cf0,0x1e780,0xf3c00,0x7bc007,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0,
03551 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc,0xf000,0xfc001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x70,0xfff00007,
03552 0xff80003f,0xfc0001ff,0xe0000fff,0x780,0x1e0000,0xf3ffe0,0x1ffc780,0xffe3c00,0x7ff1e003,0xff8f001f,0xfc7800ff,0xe3c03fe1,
03553 0xff0003ff,0xc0007ffc,0x3ffe0,0x1fff00,0xfff800,0xfffffc07,0xffffe03f,0xffff01ff,0xfff800ff,0xf0003c00,0x3c003ffc,0x1ffe0,
03554 0xfff00,0x7ff800,0x3ffc000,0x38,0xfff00007,0xfe3c003f,0xf1e001ff,0x8f000ffc,0x780007c0,0x1e7ff0,0x1f000,0x0,0x0,0x0,0x0,0x0,
03555 0x0,0x0,0x0,0x0,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,
03556 0x1fc,0x0,0x780,0xf000,0x0,0x0,0x1f80000,0x0,0x1e0,0x1f,0xc0000000,0x0,0x1ff80,0x0,0xffc000,0x7f8000,0x0,0x3fe00007,0xfc000000,
03557 0x7e,0x0,0x0,0x0,0x0,0x7c00000,0x0,0x0,0xff00000,0x0,0x0,0xfe,0x0,0x0,0x3fc000,0x0,0x0,0x0,0x3,0xf8000000,0xff,0xc0000000,
03558 0x1ff00,0x0,0x1fe000,0x0,0x0,0x0,0x0,0x3c,0x3,0xc00001e0,0x0,0x0,0x0,0x3f80000,0x1fc0000,0x7f00003,0xf8000007,0xf0000000,
03559 0x0,0xf0000000,0x0,0xf000,0x0,0x0,0x0,0x7,0xf8000787,0xf00001fc,0x3c000000,0x7f80,0x0,0x1f8000,0x0,0x0,0x0,0x7c000000,0x1e,
03560 0xf0,0x780,0x0,0x0,0x3fc00,0x0,0x3c000000,0x7800003c,0xf000601,0xc00018,0xc0,0x0,0x0,0x3fe000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03561 0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xf0000000,0x7e03,0xf0000000,0x0,0x0,0x0,0x0,0xfe0000,0x0,0x0,0x3c,0x2007,0x80000000,0x0,0x0,
03562 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c7e0f0,0xe1c00,0x0,0x3800000,0x0,0x0,0x3ff,0xf8000078,0xfffe,0x7f800,0x0,0x0,0x0,0x0,
03563 0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000,0x7f0000,0x70,0x3fc00001,0xfe00000f,0xf000007f,
03564 0x800003fc,0x0,0x0,0xff00,0x7f0000,0x3f80000,0x1fc00000,0xfe000007,0xf000003f,0x80001f80,0xfc00007f,0xfe0,0x7f00,0x3f800,
03565 0x1fc000,0x0,0x0,0x0,0x3f,0xc0000000,0xff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x78,0x3fc00001,0xf800000f,0xc000007e,0x3f0,0x7c0,
03566 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,
03567 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,
03568 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,
03569 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,
03570 0x0,0x0,0x0,0x0,0x0,0x0,0x78000000,0x1e,0xf0,0x780,0x0,0x0,0x0,0x0,0x3c000000,0x78000078,0xf000000,0x18,0xc0,0x0,0x0,0x0,
03571 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,
03572 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0x1800000,0x0,0x0,0x3ff,0xf80000f0,0xfffe,0x0,0x0,0x0,0x0,
03573 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,
03574 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,
03575 0x0,0x0,0x0,0x0,0x0,0x0,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,
03576 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,
03577 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,
03578 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,
03579 0x1f,0xf0,0xf80,0x0,0x0,0x0,0x0,0x78000000,0xf8000078,0x1e000000,0x8,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03580 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,
03581 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,
03582 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,
03583 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,
03584 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,
03585 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,
03586 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,
03587 0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x1f,0x800000f0,0x1f80,0x0,0x0,0x0,0x0,
03588 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,
03589 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,
03590 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,
03591 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,
03592 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,
03593 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,
03594 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,
03595 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4003,0xe0000000,0x0,0x1f000,0x0,0x0,
03596 0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x1,0xf0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0x70000001,0xf00000e0,
03597 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,
03598 0x0,0x0,0x3c,0xff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0xe00000,0x0,0x0,0x1,0xc00003ff,
03599 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,
03600 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,
03601 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,
03602 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,
03603 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,
03604 0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780f,0xc0000000,0x0,0x3e000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,
03605 0x0,0x0,0x0,0x0,0x3,0xe0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0xf0000103,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03606 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,
03607 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x21e00000,0x0,0x0,0x1,0xc00003ff,0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10f,
03608 0x0,0x0,0x0,0x0,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,
03609 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,
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,0x30000000,0x0,0x0,
03611 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,
03612 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,
03613 0x0,0x0,0x7fff,0xc0000000,0x0,0x3ffe000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0xe0000000,0x7,0xfc0000f0,
03614 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,
03615 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,
03616 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,
03617 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,
03618 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,
03619 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03620 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03621 0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fff,0x80000000,0x0,0x3ffc000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,
03622 0x0,0x0,0x0,0x0,0x7f,0xc0000000,0x0,0xfc0000f0,0x3f000,0x0,0x0,0x0,0x0,0x1ff,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03623 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,
03624 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,
03625 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,
03626 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,
03627 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03628 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03629 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,
03630 0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0x80000000,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x80000000,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,0x3c00000,0x0,0x0,0x3f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fc,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,0x1fc,0x0,0x0,
03634 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,
03635 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0x0,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,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f8,0x0,0x0,0x3fe0000,
03638 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,
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,0x3c00000,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,0x7e000,0x1e0000,0x1f80000,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,0x0,0x0,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,0x1fffffe0,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,0xf0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03648 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03649 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03650 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03651 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03652 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03653 0x0,0x0,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,
03654 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03655 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03656 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
03657 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
03658
03659
03660 const unsigned char logo40x38[4576] = {
03661 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,
03662 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,
03663 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,
03664 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,
03665 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,
03666 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,
03667 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,
03668 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,
03669 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,
03670 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,
03671 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,
03672 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,
03673 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,
03674 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,
03675 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,
03676 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,
03677 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,
03678 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,
03679 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,
03680 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,
03681 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,
03682 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,
03683 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,
03684 200,200,200,91,49,124,118,124,71,32,124,95,49,56,114,52,82,121,0};
03685
03686
03687 inline void warn(const char *format, ...) {
03688 if (cimg::exception_mode()>=1) {
03689 char message[8192];
03690 std::va_list ap;
03691 va_start(ap,format);
03692 std::vsprintf(message,format,ap);
03693 va_end(ap);
03694 #ifdef cimg_strict_warnings
03695 throw CImgWarningException(message);
03696 #else
03697 std::fprintf(stderr,"\n<CImg Warning> %s\n",message);
03698 #endif
03699 }
03700 }
03701
03702 inline int xln(const int x) {
03703 return x>0?(int)(1+std::log10((double)x)):1;
03704 }
03705
03706 inline char uncase(const char x) {
03707 return (char)((x<'A'||x>'Z')?x:x-'A'+'a');
03708 }
03709
03710 inline float atof(const char *str) {
03711 float x = 0,y = 1;
03712 if (!str) return 0; else { std::sscanf(str,"%g/%g",&x,&y); return x/y; }
03713 }
03714
03715 inline int strlen(const char *s) {
03716 if (s) { int k; for (k=0; s[k]; ++k) ; return k; }
03717 return -1;
03718 }
03719
03720 inline int strncmp(const char *s1, const char *s2, const int l) {
03721 if (s1 && s2) { int n = 0; for (int k=0; k<l; ++k) n+=std::abs(s1[k] - s2[k]); return n; }
03722 return 0;
03723 }
03724
03725 inline int strncasecmp(const char *s1, const char *s2, const int l) {
03726 if (s1 && s2) { int n = 0; for (int k=0; k<l; ++k) n+=std::abs(uncase(s1[k])-uncase(s2[k])); return n; }
03727 return 0;
03728 }
03729
03730 inline int strcmp(const char *s1, const char *s2) {
03731 const int l1 = cimg::strlen(s1), l2 = cimg::strlen(s2);
03732 return cimg::strncmp(s1,s2,1+(l1<l2?l1:l2));
03733 }
03734
03735 inline int strcasecmp(const char *s1, const char *s2) {
03736 const int l1 = cimg::strlen(s1), l2 = cimg::strlen(s2);
03737 return cimg::strncasecmp(s1,s2,1+(l1<l2?l1:l2));
03738 }
03739
03740 inline int strfind(const char *s, const char c) {
03741 if (s) {
03742 int l; for (l=cimg::strlen(s); l>=0 && s[l]!=c; --l) ;
03743 return l;
03744 }
03745 return -1;
03746 }
03747
03748 inline const char* basename(const char *s) {
03749 return (cimg_OS!=2)?(s?s+1+cimg::strfind(s,'/'):0):(s?s+1+cimg::strfind(s,'\\'):0);
03750 }
03751
03753 inline bool endian() {
03754 const int x=1;
03755 return ((unsigned char*)&x)[0]?false:true;
03756 }
03757
03759 inline unsigned long time() {
03760 #if cimg_OS==1
03761 struct timeval st_time;
03762 gettimeofday(&st_time,0);
03763 return (unsigned long)(st_time.tv_usec/1000 + st_time.tv_sec*1000);
03764 #elif cimg_OS==2
03765 static SYSTEMTIME st_time;
03766 GetSystemTime(&st_time);
03767 return (unsigned long)(st_time.wMilliseconds + 1000*(st_time.wSecond + 60*(st_time.wMinute + 60*st_time.wHour)));
03768 #else
03769 return 0;
03770 #endif
03771 }
03772
03774
03779 inline void sleep(const unsigned int milliseconds) {
03780 #if cimg_OS==1
03781 struct timespec tv;
03782 tv.tv_sec = milliseconds/1000;
03783 tv.tv_nsec = (milliseconds%1000)*1000000;
03784 nanosleep(&tv,0);
03785 #elif cimg_OS==2
03786 Sleep(milliseconds);
03787 #endif
03788 }
03789
03790 inline unsigned int wait(const unsigned int milliseconds, unsigned long& timer) {
03791 if (!timer) timer = cimg::time();
03792 const unsigned long current_time = cimg::time();
03793 if (current_time>=timer+milliseconds) { timer = current_time; return 0; }
03794 const unsigned long time_diff = timer + milliseconds - current_time;
03795 timer = current_time + time_diff;
03796 cimg::sleep(time_diff);
03797 return (unsigned int)time_diff;
03798 }
03799
03801
03806 inline unsigned int wait(const unsigned int milliseconds) {
03807 static unsigned long timer = 0;
03808 if (!timer) timer = cimg::time();
03809 return wait(milliseconds,timer);
03810 }
03811
03812
03813
03814 inline void srand() {
03815 static bool first_time = true;
03816 if (first_time) {
03817 std::srand(cimg::time());
03818 unsigned char *const rand_mem = new unsigned char[1+std::rand()%2048];
03819 std::srand((unsigned int)(std::rand() + (unsigned long)rand_mem));
03820 delete[] rand_mem;
03821 first_time = false;
03822 }
03823 }
03824
03825 inline const char *const filenamerand() {
03826 static char id[9] = { 0,0,0,0,0,0,0,0,0 };
03827 cimg::srand();
03828 for (unsigned int k=0; k<8; k++) {
03829 const int v = (int)std::rand()%3;
03830 id[k] = v==0?('0'+(std::rand()%10)):(v==1?('a'+(std::rand()%26)):('A'+(std::rand()%26)));
03831 }
03832 return id;
03833 }
03834
03835 inline void system(const char *command, const char *module_name=0) {
03836 #if cimg_OS==2
03837 PROCESS_INFORMATION pi;
03838 STARTUPINFO si;
03839 std::memset(&pi, 0, sizeof(PROCESS_INFORMATION));
03840 std::memset(&si, 0, sizeof(STARTUPINFO));
03841 GetStartupInfo(&si);
03842 si.cb = sizeof(si);
03843 si.wShowWindow = SW_HIDE;
03844 si.dwFlags |= SW_HIDE;
03845 const BOOL res = CreateProcess((LPCTSTR)module_name,(LPTSTR)command,0,0,FALSE,0,0,0,&si,&pi);
03846 if (res) {
03847 WaitForSingleObject(pi.hProcess, INFINITE);
03848 CloseHandle(pi.hThread);
03849 CloseHandle(pi.hProcess);
03850 } else
03851 #endif
03852 std::system(command);
03853 command = module_name = 0;
03854 }
03855
03856
03857 #if cimg_OS==2
03858 inline void winformat_string(char *const s) {
03859 if (s && s[0]) {
03860 char *const ns = new char[MAX_PATH];
03861 if (GetShortPathNameA(s,ns,MAX_PATH)) std::strcpy(s,ns);
03862 }
03863 }
03864 #else
03865 inline void winformat_string(char *const) {}
03866 #endif
03867
03868
03873 #if cimg_OS==2
03874 inline const char* programfiles_path() {
03875 static char *st_programfiles_path = 0;
03876 if (!st_programfiles_path) {
03877 st_programfiles_path = new char[MAX_PATH];
03878 std::memset(st_programfiles_path,0,MAX_PATH);
03879
03880 #if !defined(__INTEL_COMPILER)
03881 if (!SHGetSpecialFolderPathA(0,st_programfiles_path,0x0026,false)) {
03882 const char *pfPath = getenv("PROGRAMFILES");
03883 if (pfPath) std::strcpy(st_programfiles_path,pfPath);
03884 else std::strcpy(st_programfiles_path,"C:\\PROGRA~1");
03885 }
03886 #else
03887 std::strcpy(st_programfiles_path,"C:\\PROGRA~1");
03888 #endif
03889 }
03890 return st_programfiles_path;
03891 }
03892 #endif
03893
03895
03916 inline const char* imagemagick_path() {
03917 static char *st_imagemagick_path = 0;
03918 if (!st_imagemagick_path) {
03919 st_imagemagick_path = new char[1024];
03920 std::memset(st_imagemagick_path,0,1024);
03921 bool path_found = false;
03922 std::FILE *file = 0;
03923 #ifdef cimg_imagemagick_path
03924 std::strncpy(st_imagemagick_path,cimg_imagemagick_path,1023);
03925 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03926 #endif
03927 #if cimg_OS==2
03928 const char *pf_path = programfiles_path();
03929 if (!path_found) {
03930 std::sprintf(st_imagemagick_path,".\\convert.exe");
03931 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03932 }
03933 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03934 std::sprintf(st_imagemagick_path,"%s\\IMAGEM~1.%u-Q\\convert.exe",pf_path,k);
03935 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03936 }}
03937 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03938 std::sprintf(st_imagemagick_path,"%s\\IMAGEM~1.%u\\convert.exe",pf_path,k);
03939 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03940 }}
03941 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03942 std::sprintf(st_imagemagick_path,"%s\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",pf_path,k);
03943 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03944 }}
03945 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03946 std::sprintf(st_imagemagick_path,"%s\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",pf_path,k);
03947 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03948 }}
03949 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03950 std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u-Q\\convert.exe",k);
03951 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03952 }}
03953 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03954 std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u\\convert.exe",k);
03955 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03956 }}
03957 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03958 std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",k);
03959 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03960 }}
03961 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03962 std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",k);
03963 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03964 }}
03965 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03966 std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u-Q\\convert.exe",k);
03967 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03968 }}
03969 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03970 std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u\\convert.exe",k);
03971 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03972 }}
03973 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03974 std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",k);
03975 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03976 }}
03977 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
03978 std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",k);
03979 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03980 }}
03981 if (!path_found) std::strcpy(st_imagemagick_path,"convert.exe");
03982 #else
03983 if (!path_found) {
03984 std::sprintf(st_imagemagick_path,"./convert");
03985 if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
03986 }
03987 if (!path_found) std::strcpy(st_imagemagick_path,"convert");
03988 #endif
03989 winformat_string(st_imagemagick_path);
03990 }
03991 return st_imagemagick_path;
03992 }
03993
03995
04016 inline const char* graphicsmagick_path() {
04017 static char *st_graphicsmagick_path = 0;
04018 if (!st_graphicsmagick_path) {
04019 st_graphicsmagick_path = new char[1024];
04020 std::memset(st_graphicsmagick_path,0,1024);
04021 bool path_found = false;
04022 std::FILE *file = 0;
04023 #ifdef cimg_graphicsmagick_path
04024 std::strcpy(st_graphicsmagick_path,cimg_graphicsmagick_path);
04025 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04026 #endif
04027 #if cimg_OS==2
04028 const char* pf_path = programfiles_path();
04029 if (!path_found) {
04030 std::sprintf(st_graphicsmagick_path,".\\gm.exe");
04031 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04032 }
04033 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04034 std::sprintf(st_graphicsmagick_path,"%s\\GRAPHI~1.%u-Q\\gm.exe",pf_path,k);
04035 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04036 }}
04037 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04038 std::sprintf(st_graphicsmagick_path,"%s\\GRAPHI~1.%u\\gm.exe",pf_path,k);
04039 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04040 }}
04041 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04042 std::sprintf(st_graphicsmagick_path,"%s\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",pf_path,k);
04043 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04044 }}
04045 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04046 std::sprintf(st_graphicsmagick_path,"%s\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",pf_path,k);
04047 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04048 }}
04049 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04050 std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u-Q\\gm.exe",k);
04051 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04052 }}
04053 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04054 std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u\\gm.exe",k);
04055 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04056 }}
04057 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04058 std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",k);
04059 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04060 }}
04061 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04062 std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",k);
04063 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04064 }}
04065 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04066 std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u-Q\\gm.exe",k);
04067 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04068 }}
04069 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04070 std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u\\gm.exe",k);
04071 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04072 }}
04073 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04074 std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",k);
04075 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04076 }}
04077 { for (unsigned int k=0; k<=9 && !path_found; ++k) {
04078 std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",k);
04079 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04080 }}
04081 if (!path_found) std::strcpy(st_graphicsmagick_path,"gm.exe");
04082 #else
04083 if (!path_found) {
04084 std::sprintf(st_graphicsmagick_path,"./gm");
04085 if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
04086 }
04087 if (!path_found) std::strcpy(st_graphicsmagick_path,"gm");
04088 #endif
04089 winformat_string(st_graphicsmagick_path);
04090 }
04091 return st_graphicsmagick_path;
04092 }
04093
04095
04116 inline const char* medcon_path() {
04117 static char *st_medcon_path = 0;
04118 if (!st_medcon_path) {
04119 st_medcon_path = new char[1024];
04120 std::memset(st_medcon_path,0,1024);
04121 bool path_found = false;
04122 std::FILE *file = 0;
04123 #ifdef cimg_medcon_path
04124 std::strcpy(st_medcon_path,cimg_medcon_path);
04125 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04126 #endif
04127 #if cimg_OS==2
04128 const char* pf_path = programfiles_path();
04129 if (!path_found) {
04130 std::sprintf(st_medcon_path,".\\medcon.bat");
04131 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04132 }
04133 if (!path_found) {
04134 std::sprintf(st_medcon_path,".\\medcon.exe");
04135 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04136 }
04137 if (!path_found) {
04138 std::sprintf(st_medcon_path,"%s\\XMedCon\\bin\\medcon.bat",pf_path);
04139 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04140 }
04141 if (!path_found) {
04142 std::sprintf(st_medcon_path,"%s\\XMedCon\\bin\\medcon.exe",pf_path);
04143 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04144 }
04145 if (!path_found) std::strcpy(st_medcon_path,"medcon.bat");
04146 #else
04147 if (!path_found) {
04148 std::sprintf(st_medcon_path,"./medcon");
04149 if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
04150 }
04151 if (!path_found) std::strcpy(st_medcon_path,"medcon");
04152 #endif
04153 winformat_string(st_medcon_path);
04154 }
04155 return st_medcon_path;
04156 }
04157
04159
04179 inline const char* temporary_path() {
04180
04181 #define cimg_test_temporary_path(p) \
04182 if (!path_found) { \
04183 std::sprintf(st_temporary_path,"%s",p); \
04184 std::sprintf(tmp,"%s%s%s",st_temporary_path,cimg_OS==2?"\\":"/",filetmp); \
04185 if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; } \
04186 }
04187
04188 static char *st_temporary_path = 0;
04189 if (!st_temporary_path) {
04190 st_temporary_path = new char[1024];
04191 std::memset(st_temporary_path,0,1024);
04192 bool path_found = false;
04193 char tmp[1024], filetmp[512];
04194 std::FILE *file = 0;
04195 std::sprintf(filetmp,"%s.tmp",cimg::filenamerand());
04196 #ifdef cimg_temporary_path
04197 cimg_test_temporary_path(cimg_temporary_path);
04198 #endif
04199 char *tmpPath = getenv("TMP");
04200 if (tmpPath==NULL) { tmpPath = getenv("TEMP"); winformat_string(tmpPath); }
04201 if (tmpPath!=NULL) cimg_test_temporary_path(tmpPath);
04202 #if cimg_OS==2
04203 cimg_test_temporary_path("C:\\WINNT\\Temp");
04204 cimg_test_temporary_path("C:\\WINDOWS\\Temp");
04205 cimg_test_temporary_path("C:\\Temp");
04206 cimg_test_temporary_path("C:");
04207 cimg_test_temporary_path("D:\\WINNT\\Temp");
04208 cimg_test_temporary_path("D:\\WINDOWS\\Temp");
04209 cimg_test_temporary_path("D:\\Temp");
04210 cimg_test_temporary_path("D:");
04211 #else
04212 cimg_test_temporary_path("/tmp");
04213 cimg_test_temporary_path("/var/tmp");
04214 #endif
04215 if (!path_found) {
04216 st_temporary_path[0]='\0';
04217 std::strcpy(tmp,filetmp);
04218 if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; }
04219 }
04220 if (!path_found)
04221 throw CImgIOException("cimg::temporary_path() : Unable to find a temporary path accessible for writing\n"
04222 "you have to set the macro 'cimg_temporary_path' to a valid path where you have writing access :\n"
04223 "#define cimg_temporary_path \"path\" (before including 'CImg.h')");
04224 }
04225 return st_temporary_path;
04226 }
04227
04228 inline const char *filename_split(const char *const filename, char *const body=0) {
04229 if (!filename) { if (body) body[0]='\0'; return 0; }
04230 int l = cimg::strfind(filename,'.');
04231 if (l>=0) { if (body) { std::strncpy(body,filename,l); body[l]='\0'; }}
04232 else { if (body) std::strcpy(body,filename); l=(int)std::strlen(filename)-1; }
04233 return filename+l+1;
04234 }
04235
04236 inline char* filename_number(const char *const filename, const int number, const unsigned int n, char *const string) {
04237 if (!filename) { if (string) string[0]='\0'; return 0; }
04238 char format[1024],body[1024];
04239 const char *ext = cimg::filename_split(filename,body);
04240 if (n>0) std::sprintf(format,"%s_%%.%ud.%s",body,n,ext);
04241 else std::sprintf(format,"%s_%%d.%s",body,ext);
04242 std::sprintf(string,format,number);
04243 return string;
04244 }
04245
04246 inline std::FILE *fopen(const char *const path, const char *const mode) {
04247 if(!path || !mode)
04248 throw CImgArgumentException("cimg::fopen() : File '%s' cannot be opened with mode '%s'.",
04249 path?path:"(null)",mode?mode:"(null)");
04250 if (path[0]=='-') return (mode[0]=='r')?stdin:stdout;
04251 std::FILE *dest = std::fopen(path,mode);
04252 if (!dest)
04253 throw CImgIOException("cimg::fopen() : File '%s' cannot be opened%s",
04254 path,mode[0]=='r'?" for reading.":(mode[0]=='w'?" for writing.":"."),path);
04255 return dest;
04256 }
04257
04258 inline int fclose(std::FILE *file) {
04259 if (!file) warn("cimg::fclose() : Can't close (null) file");
04260 if (!file || file==stdin || file==stdout) return 0;
04261 const int errn = std::fclose(file);
04262 if (errn!=0) warn("cimg::fclose() : Error %d during file closing",errn);
04263 return errn;
04264 }
04265
04266 template<typename T> inline int fread(T *const ptr, const unsigned int nmemb, std::FILE *stream) {
04267 if (!ptr || nmemb<=0 || !stream)
04268 throw CImgArgumentException("cimg::fread() : Can't read %u x %u bytes of file pointer '%p' in buffer '%p'",
04269 nmemb,sizeof(T),stream,ptr);
04270 const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
04271 unsigned int toread = nmemb, alread = 0, ltoread = 0, lalread = 0;
04272 do {
04273 ltoread = (toread*sizeof(T))<wlimitT?toread:wlimit;
04274 lalread = (unsigned int)std::fread((void*)(ptr+alread),sizeof(T),ltoread,stream);
04275 alread+=lalread;
04276 toread-=lalread;
04277 } while (ltoread==lalread && toread>0);
04278 if (toread>0) warn("cimg::fread() : File reading problems, only %u/%u elements read",alread,nmemb);
04279 return alread;
04280 }
04281
04282 template<typename T> inline int fwrite(const T *ptr, const unsigned int nmemb, std::FILE *stream) {
04283 if (!ptr || !stream)
04284 throw CImgArgumentException("cimg::fwrite() : Can't write %u x %u bytes of file pointer '%p' from buffer '%p'",
04285 nmemb,sizeof(T),stream,ptr);
04286 if (nmemb<=0) return 0;
04287 const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
04288 unsigned int towrite = nmemb, alwrite = 0, ltowrite = 0, lalwrite = 0;
04289 do {
04290 ltowrite = (towrite*sizeof(T))<wlimitT?towrite:wlimit;
04291 lalwrite = (unsigned int)std::fwrite((void*)(ptr+alwrite),sizeof(T),ltowrite,stream);
04292 alwrite+=lalwrite;
04293 towrite-=lalwrite;
04294 } while (ltowrite==lalwrite && towrite>0);
04295 if (towrite>0) warn("cimg::fwrite() : File writing problems, only %u/%u elements written",alwrite,nmemb);
04296 return alwrite;
04297 }
04298
04299
04300 template<typename T> inline void swap(T& a, T& b) { T t = a; a = b; b = t; }
04301
04302 template<typename T1, typename T2> inline void swap(T1& a1, T1& b1, T2& a2, T2& b2) {
04303 cimg::swap(a1,b1); cimg::swap(a2,b2);
04304 }
04305
04306 template<typename T1, typename T2, typename T3> inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3) {
04307 cimg::swap(a1,b1,a2,b2); cimg::swap(a3,b3);
04308 }
04309
04310 template<typename T1, typename T2, typename T3, typename T4>
04311 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4) {
04312 cimg::swap(a1,b1,a2,b2,a3,b3); cimg::swap(a4,b4);
04313 }
04314
04315 template<typename T1, typename T2, typename T3, typename T4, typename T5>
04316 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5) {
04317 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4); cimg::swap(a5,b5);
04318 }
04319
04320 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
04321 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) {
04322 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5); cimg::swap(a6,b6);
04323 }
04324
04325 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
04326 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,
04327 T7& a7, T7& b7) {
04328 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6); cimg::swap(a7,b7);
04329 }
04330
04331 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
04332 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,
04333 T7& a7, T7& b7, T8& a8, T8& b8) {
04334 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6,a7,b7); cimg::swap(a8,b8);
04335 }
04336
04337 template<typename T> inline void endian_swap(T* const buffer, const unsigned int size) {
04338 switch (sizeof(T)) {
04339 case 1: break;
04340 case 2: {
04341 for (unsigned short *ptr = (unsigned short*)buffer+size; ptr>(unsigned short*)buffer; ) {
04342 const unsigned short val = *(--ptr);
04343 *ptr = (unsigned short)((val>>8)|((val<<8)));
04344 }
04345 } break;
04346 case 4: {
04347 for (unsigned int *ptr = (unsigned int*)buffer+size; ptr>(unsigned int*)buffer; ) {
04348 const unsigned int val = *(--ptr);
04349 *ptr = (val>>24)|((val>>8)&0xff00)|((val<<8)&0xff0000)|(val<<24);
04350 }
04351 } break;
04352 default: {
04353 for (T* ptr = buffer+size; ptr>buffer; ) {
04354 unsigned char *pb = (unsigned char*)(--ptr), *pe = pb + sizeof(T);
04355 for (int i=0; i<(int)sizeof(T)/2; ++i) cimg::swap(*(pb++),*(--pe));
04356 } break;
04357 }
04358 }
04359 }
04360
04361 template<typename T> inline T& endian_swap(T& a) {
04362 endian_swap(&a,1);
04363 return a;
04364 }
04365
04366 inline const char* option(const char *const name, const int argc, char **argv,
04367 const char *defaut, const char *const usage=0) {
04368 static bool first = true, visu = false;
04369 const char *res = 0;
04370 if (first) {
04371 first=false;
04372 visu = (cimg::option("-h",argc,argv,(char*)0)!=0);
04373 visu |= (cimg::option("-help",argc,argv,(char*)0)!=0);
04374 visu |= (cimg::option("--help",argc,argv,(char*)0)!=0);
04375 }
04376 if (!name && visu) {
04377 if (usage) {
04378 std::fprintf(stderr,"\n %s%s%s",cimg::t_red,cimg::basename(argv[0]),cimg::t_normal);
04379 std::fprintf(stderr," : %s",usage);
04380 std::fprintf(stderr," (%s, %s)\n\n",__DATE__,__TIME__);
04381 }
04382 if (defaut) std::fprintf(stderr,"%s\n",defaut);
04383 }
04384 if (name) {
04385 if (argc>0) {
04386 int k = 0,i;
04387 while (k<argc && cimg::strcmp(argv[k],name)) ++k;
04388 i=k;
04389 res=(k++==argc?defaut:(k==argc?argv[--k]:argv[k]));
04390 } else res = defaut;
04391 if (visu && usage) std::fprintf(stderr," %s%-8s%s = %-12s : %s%s%s\n",
04392 cimg::t_bold,name,cimg::t_normal,res?res:"0",cimg::t_purple,usage,cimg::t_normal);
04393 }
04394 return res;
04395 }
04396
04397 inline bool option(const char *const name, const int argc, char **argv,
04398 const bool defaut, const char *const usage=0) {
04399 const char *s = cimg::option(name,argc,argv,(char*)0);
04400 const bool res = s?(cimg::strcasecmp(s,"false") && cimg::strcasecmp(s,"off") && cimg::strcasecmp(s,"0")):defaut;
04401 cimg::option(name,0,0,res?"true":"false",usage);
04402 return res;
04403 }
04404
04405 inline int option(const char *const name, const int argc, char **argv,
04406 const int defaut, const char *const usage=0) {
04407 const char *s = cimg::option(name,argc,argv,(char*)0);
04408 const int res = s?std::atoi(s):defaut;
04409 char tmp[256];
04410 std::sprintf(tmp,"%d",res);
04411 cimg::option(name,0,0,tmp,usage);
04412 return res;
04413 }
04414
04415 inline char option(const char *const name, const int argc, char **argv,
04416 const char defaut, const char *const usage=0) {
04417 const char *s = cimg::option(name,argc,argv,(char*)0);
04418 const char res = s?s[0]:defaut;
04419 char tmp[8];
04420 tmp[0] = res;
04421 tmp[1] ='\0';
04422 cimg::option(name,0,0,tmp,usage);
04423 return res;
04424 }
04425
04426 inline float option(const char *const name, const int argc, char **argv,
04427 const float defaut, const char *const usage=0) {
04428 const char *s = cimg::option(name,argc,argv,(char*)0);
04429 const float 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 double option(const char *const name, const int argc, char **argv,
04437 const double defaut, const char *const usage=0) {
04438 const char *s = cimg::option(name,argc,argv,(char*)0);
04439 const double res = s?cimg::atof(s):defaut;
04440 char tmp[256];
04441 std::sprintf(tmp,"%g",res);
04442 cimg::option(name,0,0,tmp,usage);
04443 return res;
04444 }
04445
04446 inline const char* argument(const unsigned int nb, const int argc, char **argv, const unsigned int nb_singles=0, ...) {
04447 for (int k=1, pos=0; k<argc;) {
04448 const char *const item = argv[k];
04449 bool option = (*item=='-'), single_option = false;
04450 if (option) {
04451 va_list ap;
04452 va_start(ap,nb_singles);
04453 for (unsigned int i=0; i<nb_singles; ++i) if (!cimg::strcasecmp(item,va_arg(ap,char*))) { single_option = true; break; }
04454 va_end(ap);
04455 }
04456 if (option) { ++k; if (!single_option) ++k; }
04457 else { if (pos++==(int)nb) return item; else ++k; }
04458 }
04459 return 0;
04460 }
04461
04462 template<typename T> inline const T rol(const T a, const unsigned int n=1) {
04463 return n?(T)((a<<n)|(a>>((sizeof(T)<<3)-n))):a;
04464 }
04465
04466 template<typename T> inline const T ror(const T a, const unsigned int n=1) {
04467 return n?(T)((a>>n)|(a<<((sizeof(T)<<3)-n))):a;
04468 }
04469
04471 template<typename T> inline T abs(const T a) {
04472 return a>=0?a:-a;
04473 }
04474
04475 inline bool abs(const bool a) {
04476 return a;
04477 }
04478
04479 inline unsigned char abs(const unsigned char a) {
04480 return a;
04481 }
04482
04483 inline unsigned short abs(const unsigned short a) {
04484 return a;
04485 }
04486
04487 inline unsigned int abs(const unsigned int a) {
04488 return a;
04489 }
04490
04491 inline unsigned long abs(const unsigned long a) {
04492 return a;
04493 }
04494
04495 inline double abs(const double a) {
04496 return std::fabs(a);
04497 }
04498
04499 inline float abs(const float a) {
04500 return (float)std::fabs((double)a);
04501 }
04502
04503 inline int abs(const int a) {
04504 return std::abs(a);
04505 }
04506
04507 template<typename T> inline T sqr(const T val) {
04508 return val*val;
04509 }
04510
04512 template<typename T> inline T min(const T a, const T b) {
04513 return a<=b?a:b;
04514 }
04515
04517 template<typename T> inline T min(const T a, const T b, const T c) {
04518 return cimg::min(cimg::min(a,b),c);
04519 }
04520
04522 template<typename T> inline T min(const T a, const T b, const T c, const T d) {
04523 return cimg::min(cimg::min(a,b,c),d);
04524 }
04525
04527 template<typename T> inline T max(const T a, const T b) {
04528 return a>=b?a:b;
04529 }
04530
04532 template<typename T> inline T max(const T a, const T b, const T c) {
04533 return cimg::max(cimg::max(a,b),c);
04534 }
04535
04537 template<typename T> inline T max(const T a, const T b, const T c, const T d) {
04538 return cimg::max(cimg::max(a,b,c),d);
04539 }
04540
04542 template<typename T> inline T sign(const T x) {
04543 return (x<0)?(T)(-1):(x==0?(T)0:(T)1);
04544 }
04545
04547 template<typename T> inline unsigned long nearest_pow2(const T x) {
04548 unsigned long i=1;
04549 while (x>i) i<<=1;
04550 return i;
04551 }
04552
04554
04557 template<typename T> inline T mod(const T& x, const T& m) {
04558 const double dx = (double)x, dm = (double)m;
04559 if (x<0) { return (T)(dm+dx+dm*std::floor(-dx/dm)); }
04560 return (T)(dx-dm*std::floor(dx/dm));
04561 }
04562
04563 inline int mod(const char x, const char m) {
04564 return x>=0?x%m:(x%m?m+x%m:0);
04565 }
04566
04567 inline int mod(const short x, const short m) {
04568 return x>=0?x%m:(x%m?m+x%m:0);
04569 }
04570
04571 inline int mod(const int x, const int m) {
04572 return x>=0?x%m:(x%m?m+x%m:0);
04573 }
04574
04575 inline int mod(const long x, const long m) {
04576 return x>=0?x%m:(x%m?m+x%m:0);
04577 }
04578
04579 inline int mod(const unsigned char x, const unsigned char m) {
04580 return x%m;
04581 }
04582
04583 inline int mod(const unsigned short x, const unsigned short m) {
04584 return x%m;
04585 }
04586
04587 inline int mod(const unsigned int x, const unsigned int m) {
04588 return x%m;
04589 }
04590
04591 inline int mod(const unsigned long x, const unsigned long m) {
04592 return x%m;
04593 }
04594
04596
04601 template<typename T> inline T minmod(const T a, const T b) {
04602 return a*b<=0?0:(a>0?(a<b?a:b):(a<b?b:a));
04603 }
04604
04606 inline double rand() {
04607 return (double)std::rand()/RAND_MAX;
04608 }
04609
04611 inline double crand() {
04612 return 1-2*cimg::rand();
04613 }
04614
04616 inline double grand() {
04617 double x1, w;
04618 do {
04619 const double x2 = 2*cimg::rand()-1.0;
04620 x1 = 2*cimg::rand()-1.0;
04621 w = x1*x1 + x2*x2;
04622 } while (w<=0 || w>=1.0);
04623 return x1*std::sqrt((-2*std::log(w))/w);
04624 }
04625
04627 inline double round(const double x, const double y, const unsigned int round_type=0) {
04628 if (y<=0) return x;
04629 const double delta = cimg::mod(x,y);
04630 if (delta==0.0) return x;
04631 const double
04632 backward = x-delta,
04633 forward = backward+y;
04634 return round_type==1?backward:(round_type==2?forward:(2*delta<y?backward:forward));
04635 }
04636
04637 inline double pythagore(double a, double b) {
04638 const double absa = cimg::abs(a), absb = cimg::abs(b);
04639 if (absa>absb) { const double tmp = absb/absa; return absa*std::sqrt(1.0+tmp*tmp); }
04640 else { const double tmp = absa/absb; return (absb==0?0:absb*std::sqrt(1.0+tmp*tmp)); }
04641 }
04642
04644
04647 inline void info() {
04648 char tmp[1024] = { 0 };
04649 std::fprintf(stderr,"\n %sCImg Library %u.%u.%u%s, compiled %s ( %s ) with the following flags :\n\n",
04650 cimg::t_red,cimg_version/100,(cimg_version%100)/10,cimg_version%10,cimg::t_normal,__DATE__,__TIME__);
04651
04652 std::fprintf(stderr," > CPU endianness : %s%s Endian%s\n",
04653 cimg::t_bold,
04654 cimg::endian()?"Big":"Little",
04655 cimg::t_normal);
04656
04657 std::fprintf(stderr," > Operating System : %s%-13s%s %s('cimg_OS'=%d)%s\n",
04658 cimg::t_bold,
04659 cimg_OS==1?"Unix":(cimg_OS==2?"Windows":"Unknow"),
04660 cimg::t_normal,cimg::t_purple,
04661 cimg_OS,
04662 cimg::t_normal);
04663
04664 #ifdef cimg_use_visualcpp6
04665 std::fprintf(stderr," > Using Visual C++ 6.0 : %s%-13s%s %s('cimg_use_visualcpp6' defined)%s\n",
04666 cimg::t_bold,"Yes",cimg::t_normal,cimg::t_purple,cimg::t_normal);
04667 #endif
04668
04669 std::fprintf(stderr," > Display type : %s%-13s%s %s('cimg_display_type'=%d)%s\n",
04670 cimg::t_bold,
04671 cimg_display_type==0?"No display":(cimg_display_type==1?"X11":(cimg_display_type==2?"Windows GDI":"Unknow")),
04672 cimg::t_normal,cimg::t_purple,
04673 cimg_display_type,
04674 cimg::t_normal);
04675
04676 std::fprintf(stderr," > Color terminal : %s%-13s%s %s('cimg_color_terminal' %s)%s\n",
04677 cimg::t_bold,
04678 #ifdef cimg_color_terminal
04679 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04680 #else
04681 "No",cimg::t_normal,cimg::t_purple,"undefined",
04682 #endif
04683 cimg::t_normal);
04684
04685 std::fprintf(stderr," > Debug messages : %s%-13s%s %s('cimg_debug'=%d)%s\n",
04686 cimg::t_bold,
04687 cimg_debug==0?"No":(cimg_debug==1 || cimg_debug==2?"Yes":(cimg_debug==3?"Yes+":"Unknown")),
04688 cimg::t_normal,cimg::t_purple,
04689 cimg_debug,
04690 cimg::t_normal);
04691
04692 #if cimg_display_type==1
04693 std::fprintf(stderr," > Using XShm for X11 : %s%-13s%s %s('cimg_use_xshm' %s)%s\n",
04694 cimg::t_bold,
04695 #ifdef cimg_use_xshm
04696 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04697 #else
04698 "No",cimg::t_normal,cimg::t_purple,"undefined",
04699 #endif
04700 cimg::t_normal);
04701
04702 std::fprintf(stderr," > Using XRand for X11 : %s%-13s%s %s('cimg_use_xrandr' %s)%s\n",
04703 cimg::t_bold,
04704 #ifdef cimg_use_xrandr
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 #endif
04711
04712 std::fprintf(stderr," > Using PNG library : %s%-13s%s %s('cimg_use_png' %s)%s\n",
04713 cimg::t_bold,
04714 #ifdef cimg_use_png
04715 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04716 #else
04717 "No",cimg::t_normal,cimg::t_purple,"undefined",
04718 #endif
04719 cimg::t_normal);
04720 std::fprintf(stderr," > Using JPEG library : %s%-13s%s %s('cimg_use_jpeg' %s)%s\n",
04721 cimg::t_bold,
04722 #ifdef cimg_use_jpeg
04723 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04724 #else
04725 "No",cimg::t_normal,cimg::t_purple,"undefined",
04726 #endif
04727 cimg::t_normal);
04728
04729 std::fprintf(stderr," > Using TIFF library : %s%-13s%s %s('cimg_use_tiff' %s)%s\n",
04730 cimg::t_bold,
04731 #ifdef cimg_use_tiff
04732 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04733 #else
04734 "No",cimg::t_normal,cimg::t_purple,"undefined",
04735 #endif
04736 cimg::t_normal);
04737
04738 std::fprintf(stderr," > Using Magick++ library : %s%-13s%s %s('cimg_use_magick' %s)%s\n",
04739 cimg::t_bold,
04740 #ifdef cimg_use_magick
04741 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04742 #else
04743 "No",cimg::t_normal,cimg::t_purple,"undefined",
04744 #endif
04745 cimg::t_normal);
04746
04747 std::fprintf(stderr," > Using FFTW3 library : %s%-13s%s %s('cimg_use_fftw3' %s)%s\n",
04748 cimg::t_bold,
04749 #ifdef cimg_use_fftw3
04750 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04751 #else
04752 "No",cimg::t_normal,cimg::t_purple,"undefined",
04753 #endif
04754 cimg::t_normal);
04755
04756 std::fprintf(stderr," > Using LAPACK library : %s%-13s%s %s('cimg_use_lapack' %s)%s\n",
04757 cimg::t_bold,
04758 #ifdef cimg_use_lapack
04759 "Yes",cimg::t_normal,cimg::t_purple,"defined",
04760 #else
04761 "No",cimg::t_normal,cimg::t_purple,"undefined",
04762 #endif
04763 cimg::t_normal);
04764
04765 std::sprintf(tmp,"\"%.1020s\"",cimg::imagemagick_path());
04766 std::fprintf(stderr," > Path of ImageMagick : %s%-13s%s %s('cimg_imagemagick_path'%s)%s\n",
04767 cimg::t_bold,
04768 tmp,
04769 cimg::t_normal,
04770 #ifdef cimg_imagemagick_path
04771 cimg::t_purple,"=\""cimg_imagemagick_path"\"",
04772 #else
04773 cimg::t_purple," undefined",
04774 #endif
04775 cimg::t_normal);
04776
04777 std::sprintf(tmp,"\"%.1020s\"",cimg::graphicsmagick_path());
04778 std::fprintf(stderr," > Path of GraphicsMagick : %s%-13s%s %s('cimg_graphicsmagick_path'%s)%s\n",
04779 cimg::t_bold,
04780 tmp,
04781 cimg::t_normal,
04782 #ifdef cimg_graphicsmagick_path
04783 cimg::t_purple,"=\""cimg_graphicsmagick_path"\"",
04784 #else
04785 cimg::t_purple," undefined",
04786 #endif
04787 cimg::t_normal);
04788
04789 std::sprintf(tmp,"\"%.1020s\"",cimg::medcon_path());
04790 std::fprintf(stderr," > Path of 'medcon' : %s%-13s%s %s('cimg_medcon_path'%s)%s\n",
04791 cimg::t_bold,
04792 tmp,
04793 cimg::t_normal,
04794 #ifdef cimg_medcon_path
04795 cimg::t_purple,"=\""cimg_medcon_path"\"",
04796 #else
04797 cimg::t_purple," undefined",
04798 #endif
04799 cimg::t_normal);
04800
04801 std::sprintf(tmp,"\"%.1020s\"",cimg::temporary_path());
04802 std::fprintf(stderr," > Temporary path : %s%-13s%s %s('cimg_temporary_path'%s)%s\n",
04803 cimg::t_bold,
04804 tmp,
04805 cimg::t_normal,
04806 #ifdef cimg_temporary_path
04807 cimg::t_purple,"=\""cimg_temporary_path"\"",
04808 #else
04809 cimg::t_purple," undefined",
04810 #endif
04811 cimg::t_normal);
04812
04813 std::fprintf(stderr,"\n");
04814 }
04815
04816 #ifdef cimg_use_lapack
04817 template<typename T> inline void getrf(int &N, T *lapA, int *IPIV, int &INFO) {
04818 dgetrf_(&N,&N,lapA,&N,IPIV,&INFO);
04819 }
04820
04821 inline void getrf(int &N, float *lapA, int *IPIV, int &INFO) {
04822 sgetrf_(&N,&N,lapA,&N,IPIV,&INFO);
04823 }
04824
04825 template<typename T> inline void getri(int &N, T *lapA, int *IPIV, T* WORK, int &LWORK, int &INFO) {
04826 dgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO);
04827 }
04828
04829 inline void getri(int &N, float *lapA, int *IPIV, float* WORK, int &LWORK, int &INFO) {
04830 sgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO);
04831 }
04832
04833 template<typename T> inline void gesvd(char &JOB, int &M, int &N, T *lapA, int &MN,
04834 T *lapS, T *lapU, T *lapV, T *WORK, int &LWORK, int &INFO) {
04835 dgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO);
04836 }
04837
04838 inline void gesvd(char &JOB, int &M, int &N, float *lapA, int &MN,
04839 float *lapS, float *lapU, float *lapV, float *WORK, int &LWORK, int &INFO) {
04840 sgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO);
04841 }
04842
04843 template<typename T> inline void getrs(char &TRANS, int &N, T *lapA, int *IPIV, T *lapB, int &INFO) {
04844 int one = 1;
04845 dgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO);
04846 }
04847
04848 inline void getrs(char &TRANS, int &N, float *lapA, int *IPIV, float *lapB, int &INFO) {
04849 int one = 1;
04850 sgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO);
04851 }
04852
04853 template<typename T> inline void syev(char &JOB, char &UPLO, int &N, T *lapA, T *lapW, T *WORK, int &LWORK, int &INFO) {
04854 dsyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO);
04855 }
04856
04857 inline void syev(char &JOB, char &UPLO, int &N, float *lapA, float *lapW, float *WORK, int &LWORK, int &INFO) {
04858 ssyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO);
04859 }
04860 #endif
04861
04862
04863 }
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877 #ifdef cimg_use_visualcpp6
04878 template<typename t> inline CImg<t> operator+(const CImg<t>& img, const t val) {
04879 return CImg<t>(img,false)+=val;
04880 }
04881 #else
04882 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator+(const CImg<t1>& img, const t2 val) {
04883 typedef typename cimg::superset<t1,t2>::type restype;
04884 return CImg<restype>(img,false)+=val;
04885 }
04886 #endif
04887
04888 #ifdef cimg_use_visualcpp6
04889 template<typename t> inline CImg<t> operator+(const t val, const CImg<t>& img) {
04890 return img+val;
04891 }
04892 #else
04893 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator+(const t1 val, const CImg<t2>& img) {
04894 return img+val;
04895 }
04896 #endif
04897
04898 #ifdef cimg_use_visualcpp6
04899 template<typename t> inline CImgList<t> operator+(const CImgList<t>& list, const t val) {
04900 return CImgList<t>(list)+=val;
04901 }
04902 #else
04903 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const CImgList<t1>& list, const t2 val) {
04904 typedef typename cimg::superset<t1,t2>::type restype;
04905 return CImgList<restype>(list)+=val;
04906 }
04907 #endif
04908
04909 #ifdef cimg_use_visualcpp6
04910 template<typename t> inline CImgList<t> operator+(const t val, const CImgList<t>& list) {
04911 return list+val;
04912 }
04913 #else
04914 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const t1 val, const CImgList<t2>& list) {
04915 return list+val;
04916 }
04917 #endif
04918
04919 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator+(const CImg<t1>& img1, const CImg<t2>& img2) {
04920 typedef typename cimg::superset<t1,t2>::type restype;
04921 return CImg<restype>(img1,false)+=img2;
04922 }
04923
04924 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const CImg<t1>& img, const CImgList<t2>& list) {
04925 typedef typename cimg::superset<t1,t2>::type restype;
04926 return CImgList<restype>(list)+=img;
04927 }
04928
04929 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const CImgList<t1>& list, const CImg<t2>& img) {
04930 return img+list;
04931 }
04932
04933 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator+(const CImgList<t1>& list1, const CImgList<t2>& list2) {
04934 typedef typename cimg::superset<t1,t2>::type restype;
04935 return CImgList<restype>(list1)+=list2;
04936 }
04937
04938 #ifdef cimg_use_visualcpp6
04939 template<typename t> inline CImg<t> operator-(const CImg<t>& img, const t val) {
04940 return CImg<t>(img,false)-=val;
04941 }
04942 #else
04943 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator-(const CImg<t1>& img, const t2 val) {
04944 typedef typename cimg::superset<t1,t2>::type restype;
04945 return CImg<restype>(img,false)-=val;
04946 }
04947 #endif
04948
04949 #ifdef cimg_use_visualcpp6
04950 template<typename t> inline CImg<t> operator-(const t val, const CImg<t>& img) {
04951 return CImg<t>(img.width,img.height,img.depth,img.dim,val)-=img;
04952 }
04953 #else
04954 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator-(const t1 val, const CImg<t2>& img) {
04955 typedef typename cimg::superset<t1,t2>::type restype;
04956 return CImg<restype>(img.width,img.height,img.depth,img.dim,(restype)val)-=img;
04957 }
04958 #endif
04959
04960 #ifdef cimg_use_visualcpp6
04961 template<typename t> inline CImgList<t> operator-(const CImgList<t>& list, const t val) {
04962 return CImgList<t>(list)-=val;
04963 }
04964 #else
04965 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const CImgList<t1>& list, const t2 val) {
04966 typedef typename cimg::superset<t1,t2>::type restype;
04967 return CImgList<restype>(list)-=val;
04968 }
04969 #endif
04970
04971 #ifdef cimg_use_visualcpp6
04972 template<typename t> inline CImgList<double> operator-(const t val, const CImgList<t>& list) {
04973 CImgList<t> res(list.size);
04974 cimglist_for(res,l) res[l] = val-list[l];
04975 return res;
04976 }
04977 #else
04978 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const t1 val, const CImgList<t2>& list) {
04979 typedef typename cimg::superset<t1,t2>::type restype;
04980 CImgList<restype> res(list.size);
04981 cimglist_for(res,l) res[l] = val-list[l];
04982 return res;
04983 }
04984 #endif
04985
04986 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator-(const CImg<t1>& img1, const CImg<t2>& img2) {
04987 typedef typename cimg::superset<t1,t2>::type restype;
04988 return CImg<restype>(img1,false)-=img2;
04989 }
04990
04991 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const CImg<t1>& img, const CImgList<t2>& list) {
04992 typedef typename cimg::superset<t1,t2>::type restype;
04993 CImgList<restype> res(list.size);
04994 cimglist_for(res,l) res[l] = img-list[l];
04995 return res;
04996 }
04997
04998 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const CImgList<t1>& list, const CImg<t2>& img) {
04999 typedef typename cimg::superset<t1,t2>::type restype;
05000 return CImgList<restype>(list)-=img;
05001 }
05002
05003 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator-(const CImgList<t1>& list1, const CImgList<t2>& list2) {
05004 typedef typename cimg::superset<t1,t2>::type restype;
05005 return CImgList<restype>(list1)-=list2;
05006 }
05007
05008 #ifdef cimg_use_visualcpp6
05009 template<typename t> inline CImg<t> operator*(const CImg<t>& img, const double val) {
05010 return CImg<t>(img,false)*=val;
05011 }
05012 #else
05013 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator*(const CImg<t1>& img, const t2 val) {
05014 typedef typename cimg::superset<t1,t2>::type restype;
05015 return CImg<restype>(img,false)*=val;
05016 }
05017 #endif
05018
05019 #ifdef cimg_use_visualcpp6
05020 template<typename t> inline CImg<t> operator*(const double val, const CImg<t>& img) {
05021 return img*val;
05022 }
05023 #else
05024 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator*(const t1 val, const CImg<t2>& img) {
05025 return img*val;
05026 }
05027 #endif
05028
05029 #ifdef cimg_use_visualcpp6
05030 template<typename t> inline CImgList<t> operator*(const CImgList<t>& list, const double val) {
05031 return CImgList<t>(list)*=val;
05032 }
05033 #else
05034 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const CImgList<t1>& list, const t2 val) {
05035 typedef typename cimg::superset<t1,t2>::type restype;
05036 return CImgList<restype>(list)*=val;
05037 }
05038 #endif
05039
05040 #ifdef cimg_use_visualcpp6
05041 template<typename t> inline CImgList<t> operator*(const double val, const CImgList<t>& list) {
05042 return list*val;
05043 }
05044 #else
05045 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const t1 val, const CImgList<t2>& list) {
05046 return list*val;
05047 }
05048 #endif
05049
05050 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator*(const CImg<t1>& img1, const CImg<t2>& img2) {
05051 typedef typename cimg::superset<t1,t2>::type restype;
05052 if (img1.width!=img2.height)
05053 throw CImgArgumentException("operator*() : can't multiply a matrix (%ux%u) by a matrix (%ux%u)",
05054 img1.width,img1.height,img2.width,img2.height);
05055 CImg<restype> res(img2.width,img1.height);
05056 restype val;
05057 cimg_forXY(res,i,j) { val = 0; cimg_forX(img1,k) val+=img1(k,j)*img2(i,k); res(i,j) = val; }
05058 return res;
05059 }
05060
05061 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const CImg<t1>& img, const CImgList<t2>& list) {
05062 typedef typename cimg::superset<t1,t2>::type restype;
05063 CImgList<restype> res(list.size);
05064 cimglist_for(res,l) res[l] = img*list[l];
05065 return res;
05066 }
05067
05068 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const CImgList<t1>& list, const CImg<t2>& img) {
05069 typedef typename cimg::superset<t1,t2>::type restype;
05070 CImgList<restype> res(list.size);
05071 cimglist_for(res,l) res[l] = list[l]*img;
05072 return res;
05073 }
05074
05075 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator*(const CImgList<t1>& list1, const CImgList<t2>& list2) {
05076 typedef typename cimg::superset<t1,t2>::type restype;
05077 CImgList<restype> res(cimg::min(list1.size,list2.size));
05078 cimglist_for(res,l) res[l] = list1[l]*list2[l];
05079 return res;
05080 }
05081
05082 #ifdef cimg_use_visualcpp6
05083 template<typename t> inline CImg<t> operator/(const CImg<t>& img, const double val) {
05084 return CImg<t>(img,false)/=val;
05085 }
05086 #else
05087 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator/(const CImg<t1>& img, const t2 val) {
05088 typedef typename cimg::superset<t1,t2>::type restype;
05089 return CImg<restype>(img,false)/=val;
05090 }
05091 #endif
05092
05093 #ifdef cimg_use_visualcpp6
05094 template<typename t> inline CImg<t> operator/(const double val, CImg<t>& img) {
05095 return val*img.get_inverse();
05096 }
05097 #else
05098 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator/(const t1 val, CImg<t2>& img) {
05099 return val*img.get_inverse();
05100 }
05101 #endif
05102
05103 #ifdef cimg_use_visualcpp6
05104 template<typename t> inline CImgList<t> operator/(const CImgList<t>& list, const double val) {
05105 return CImgList<t>(list)/=val;
05106 }
05107 #else
05108 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator/(const CImgList<t1>& list, const t2 val) {
05109 typedef typename cimg::superset<t1,t2>::type restype;
05110 return CImgList<restype>(list)/=val;
05111 }
05112 #endif
05113
05114 #ifdef cimg_use_visualcpp6
05115 template<typename t> inline CImgList<t> operator/(const double val, const CImgList<t>& list) {
05116 CImgList<t> res(list.size);
05117 cimglist_for(res,l) res[l] = val/list[l];
05118 return res;
05119 }
05120 #else
05121 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator/(const t1 val, const CImgList<t2>& list) {
05122 typedef typename cimg::superset<t1,t2>::type restype;
05123 CImgList<restype> res(list.size);
05124 cimglist_for(res,l) res[l] = val/list[l];
05125 return res;
05126 }
05127 #endif
05128
05129 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator/(const CImg<t1>& img1, const CImg<t2>& img2) {
05130 typedef typename cimg::superset<t1,t2>::type restype;
05131 return CImg<restype>(img1,false)*=img2.get_inverse();
05132 }
05133
05134 template<typename t1, typename t2> inline CImg<typename cimg::superset<t1,t2>::type> operator/(const CImg<t1>& img, const CImgList<t2>& list) {
05135 typedef typename cimg::superset<t1,t2>::type restype;
05136 CImgList<restype> res(list.size);
05137 cimglist_for(res,l) res[l] = img/list[l];
05138 return res;
05139 }
05140
05141 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator/(const CImgList<t1>& list, const CImg<t2>& img) {
05142 typedef typename cimg::superset<t1,t2>::type restype;
05143 return CImgList<restype>(list)/=img;
05144 }
05145
05146 template<typename t1, typename t2> inline CImgList<typename cimg::superset<t1,t2>::type> operator/(const CImgList<t1>& list1, const CImgList<t2>& list2) {
05147 typedef typename cimg::superset<t1,t2>::type restype;
05148 return CImgList<restype>(list1)/=list2;
05149 }
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163 template<typename T, typename t> inline CImg<T> apply(const CImg<T>& instance, t& func) {
05164 return instance.get_apply(func);
05165 }
05166
05167 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> mul(const CImg<T>& instance, const CImg<t>& img) {
05168 return instance.get_mul(img);
05169 }
05170
05171 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> div(const CImg<T>& instance, const CImg<t>& img) {
05172 return instance.get_div(img);
05173 }
05174
05175 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> max(const CImg<T>& instance, const CImg<t>& img) {
05176 return instance.get_max(img);
05177 }
05178
05179 template<typename T> inline CImg<T> max(const CImg<T>& instance, const T val) {
05180 return instance.get_max(val);
05181 }
05182
05183 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> min(const CImg<T>& instance, const CImg<t>& img) {
05184 return instance.get_min(img);
05185 }
05186
05187 template<typename T> inline CImg<typename cimg::last<T,double>::type> stats(const CImg<T>& instance) {
05188 return instance.get_stats();
05189 }
05190
05191 template<typename T> inline CImg<T> min(const CImg<T>& instance, const T val) {
05192 return instance.get_min(val);
05193 }
05194
05195 template<typename T> inline CImg<typename cimg::superset<T,float>::type> sqr(const CImg<T>& instance) {
05196 return instance.get_sqr();
05197 }
05198
05199 template<typename T> inline CImg<typename cimg::superset<T,float>::type> sqrt(const CImg<T>& instance) {
05200 return instance.get_sqrt();
05201 }
05202
05203 template<typename T> inline CImg<typename cimg::superset<T,float>::type> exp(const CImg<T>& instance) {
05204 return instance.get_exp();
05205 }
05206
05207 template<typename T> inline CImg<typename cimg::superset<T,float>::type> log(const CImg<T>& instance) {
05208 return instance.get_log();
05209 }
05210
05211 template<typename T> inline CImg<typename cimg::superset<T,float>::type> log10(const CImg<T>& instance) {
05212 return instance.get_log10();
05213 }
05214
05215 template<typename T> inline CImg<typename cimg::superset<T,float>::type> pow(const CImg<T>& instance, const double p) {
05216 return instance.get_pow(p);
05217 }
05218
05219 template<typename T, typename t> inline CImg<typename cimg::superset<T,float>::type> pow(const CImg<T>& instance, const CImg<t>& img) {
05220 return instance.get_pow(img);
05221 }
05222
05223 template<typename T> inline CImg<typename cimg::superset<T,float>::type> abs(const CImg<T>& instance) {
05224 return instance.get_abs();
05225 }
05226
05227 template<typename T> inline CImg<typename cimg::superset<T,float>::type> cos(const CImg<T>& instance) {
05228 return instance.get_cos();
05229 }
05230
05231 template<typename T> inline CImg<typename cimg::superset<T,float>::type> sin(const CImg<T>& instance) {
05232 return instance.get_sin();
05233 }
05234
05235 template<typename T> inline CImg<typename cimg::superset<T,float>::type> tan(const CImg<T>& instance) {
05236 return instance.get_tan();
05237 }
05238
05239 template<typename T> inline CImg<typename cimg::superset<T,float>::type> acos(const CImg<T>& instance) {
05240 return instance.get_acos();
05241 }
05242
05243 template<typename T> inline CImg<typename cimg::superset<T,float>::type> asin(const CImg<T>& instance) {
05244 return instance.get_asin();
05245 }
05246
05247 template<typename T> inline CImg<typename cimg::superset<T,float>::type> atan(const CImg<T>& instance) {
05248 return instance.get_atan();
05249 }
05250
05251 template<typename T> inline CImg<T> round(const CImg<T>& instance, const float x, const unsigned int round_type=0) {
05252 return instance.get_round(x,round_type);
05253 }
05254
05255 template<typename T> inline CImg<T> rand(const CImg<T>& instance, const T val_min, const T val_max) {
05256 return instance.get_rand(val_min,val_max);
05257 }
05258
05259 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val) {
05260 return instance.get_fill(val);
05261 }
05262
05263 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1) {
05264 return instance.get_fill(val0,val1);
05265 }
05266
05267 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2) {
05268 return instance.get_fill(val0,val1,val2);
05269 }
05270
05271 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3) {
05272 return instance.get_fill(val0,val1,val2,val3);
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) {
05277 return instance.get_fill(val0,val1,val2,val3,val4);
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) {
05282 return instance.get_fill(val0,val1,val2,val3,val4,val5);
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) {
05287 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6);
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) {
05292 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7);
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) {
05297 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8);
05298 }
05299
05300 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05301 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9) {
05302 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9);
05303 }
05304
05305 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05306 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05307 const T val10) {
05308 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10);
05309 }
05310
05311 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05312 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05313 const T val10, const T val11) {
05314 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11);
05315 }
05316
05317 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05318 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05319 const T val10, const T val11, const T val12) {
05320 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12);
05321 }
05322
05323 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05324 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05325 const T val10, const T val11, const T val12, const T val13) {
05326 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13);
05327 }
05328
05329 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05330 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05331 const T val10, const T val11, const T val12, const T val13, const T val14) {
05332 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14);
05333 }
05334
05335 template<typename T> inline CImg<T> fill(const CImg<T>& instance, const T val0, const T val1, const T val2, const T val3,
05336 const T val4, const T val5, const T val6, const T val7, const T val8, const T val9,
05337 const T val10, const T val11, const T val12, const T val13, const T val14, const T val15) {
05338 return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14,val15);
05339 }
05340
05341 template<typename T, int N> inline CImg<T> fill(const CImg<T>& instance, const int val0, ...) {
05342 CImg<T> res(instance,false);
05343 va_list ap;
05344 va_start(ap,val0);
05345 res.template _fill<N,int>(val0,ap);
05346 va_end(ap);
05347 return res;
05348 }
05349
05350 template<typename T, int N> inline CImg<T> fill(const CImg<T>& instance, const double val0, ...) {
05351 CImg<T> res(instance,false);
05352 va_list ap;
05353 va_start(ap,val0);
05354 res.template _fill<N,double>(val0,ap);
05355 va_end(ap);
05356 return res;
05357 }
05358
05359 template<typename T> inline CImg<T> normalize(const CImg<T>& instance, const T a, const T b) {
05360 return instance.get_normalize(a,b);
05361 }
05362
05363 template<typename T> inline CImg<T> cut(const CImg<T>& instance, const T a, const T b) {
05364 return instance.get_cut(a,b);
05365 }
05366
05367 template<typename T> inline CImg<T> quantize(const CImg<T>& instance, const unsigned int n=256, const bool keep_range=true) {
05368 return instance.get_quantize(n,keep_range);
05369 }
05370
05371 template<typename T> inline CImg<T> threshold(const CImg<T>& instance, const T thres) {
05372 return instance.get_threshold(thres);
05373 }
05374
05375 template<typename T> inline CImg<T> rotate(const CImg<T>& instance, const float angle, const unsigned int cond=3) {
05376 return instance.get_rotate(angle,cond);
05377 }
05378
05379 template<typename T> inline CImg<T> rotate(const CImg<T>& instance, const float angle, const float cx, const float cy,
05380 const float zoom=1, const unsigned int cond=3) {
05381 return instance.get_rotate(angle,cx,cy,zoom,cond);
05382 }
05383
05384 template<typename T> inline CImg<T> resize(const CImg<T>& instance,
05385 const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100,
05386 const int interp=1, const int border_condition=-1, const bool center=false) {
05387 return instance.get_resize(pdx,pdy,pdz,pdv,interp,border_condition,center);
05388 }
05389
05390 template<typename T, typename t> inline CImg<T> resize(const CImg<T>& instance, const CImg<t>& src,
05391 const int interp=1, const int border_condition=-1,
05392 const bool center=false) {
05393 return instance.get_resize(src,interp,border_condition,center);
05394 }
05395
05396 template<typename T> inline CImg<T> resize(const CImg<T>& instance, const CImgDisplay& disp,
05397 const int interp=1, const int border_condition=-1, const bool center=false) {
05398 return instance.get_resize(disp,interp,border_condition,center);
05399 }
05400
05401 template<typename T> inline CImg<T> permute_axes(const CImg<T>& instance, const char *permut="vxyz") {
05402 return instance.get_permute_axes(instance,permut);
05403 }
05404
05405 template<typename T> inline CImg<T> resize_halfXY(const CImg<T>& instance) {
05406 return instance.get_resize_halfXY();
05407 }
05408
05409 template<typename T> inline CImg<T> crop(const CImg<T>& instance, const int x0, const int y0, const int z0, const int v0,
05410 const int x1, const int y1, const int z1, const int v1,
05411 const bool border_condition=false) {
05412 return instance.get_crop(x0,y0,z0,v0,x1,y1,z1,v1,border_condition);
05413 }
05414
05415 template<typename T> inline CImg<T> crop(const CImg<T>& instance, const int x0, const int y0, const int z0,
05416 const int x1, const int y1, const int z1,
05417 const bool border_condition=false) {
05418 return instance.get_crop(x0,y0,z0,x1,y1,z1,border_condition);
05419 }
05420
05421 template<typename T> inline CImg<T> crop(const CImg<T>& instance, const int x0, const int y0,
05422 const int x1, const int y1,
05423 const bool border_condition=false) {
05424 return instance.get_crop(x0,y0,x1,y1,border_condition);
05425 }
05426
05427 template<typename T> inline CImg<T> crop(const CImg<T>& instance, const int x0, const int x1,
05428 const bool border_condition=false) {
05429 return instance.get_crop(x0,x1,border_condition);
05430 }
05431
05432 template<typename T> inline CImg<T> columns(const CImg<T>& instance, const unsigned int x0, const unsigned int x1) {
05433 return instance.get_columns(x0,x1);
05434 }
05435
05436 template<typename T> inline CImg<T> column(const CImg<T>& instance, const unsigned int x0) {
05437 return instance.get_column(x0);
05438 }
05439
05440 template<typename T> inline CImg<T> lines(const CImg<T>& instance, const unsigned int y0, const unsigned int y1) {
05441 return instance.get_lines(y0,y1);
05442 }
05443
05444 template<typename T> inline CImg<T> line(const CImg<T>& instance, const unsigned int y0) {
05445 return instance.get_line(y0);
05446 }
05447
05448 template<typename T> inline CImg<T> slices(const CImg<T>& instance, const unsigned int z0, const unsigned int z1) {
05449 return instance.get_slices(z0,z1);
05450 }
05451
05452 template<typename T> inline CImg<T> slice(const CImg<T>& instance, const unsigned int z0) {
05453 return instance.get_slice(z0);
05454 }
05455
05456 template<typename T> inline CImg<T> channels(const CImg<T>& instance, const unsigned int v0, const unsigned int v1) {
05457 return instance.get_channels(v0,v1);
05458 }
05459
05460 template<typename T> inline CImg<T> channel(const CImg<T>& instance, const unsigned int v0) {
05461 return instance.get_channel(v0);
05462 }
05463
05464 template<typename T> inline CImg<T> shared_points(CImg<T>& instance, const unsigned int x0, const unsigned int x1,
05465 const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) {
05466 return instance.get_shared_points(x0,x1,y0,z0,v0);
05467 }
05468
05469 template<typename T> inline CImg<T> shared_points(const CImg<T>& instance, const unsigned int x0, const unsigned int x1,
05470 const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) {
05471 return instance.get_shared_points(x0,x1,y0,z0,v0);
05472 }
05473
05474 template<typename T> inline CImg<T> shared_lines(CImg<T>& instance, const unsigned int y0, const unsigned int y1,
05475 const unsigned int z0=0, const unsigned int v0=0) {
05476 return instance.get_shared_lines(y0,y1,z0,v0);
05477 }
05478
05479 template<typename T> inline CImg<T> shared_lines(const CImg<T>& instance, const unsigned int y0, const unsigned int y1,
05480 const unsigned int z0=0, const unsigned int v0=0) {
05481 return instance.get_shared_lines(y0,y1,z0,v0);
05482 }
05483
05484 template<typename T> inline CImg<T> shared_line(CImg<T>& instance,
05485 const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) {
05486 return instance.get_shared_line(y0,z0,v0);
05487 }
05488
05489 template<typename T> inline CImg<T> shared_line(const CImg<T>& instance,
05490 const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) {
05491 return instance.get_shared_line(y0,z0,v0);
05492 }
05493
05494 template<typename T> inline CImg<T> shared_planes(CImg<T>& instance,
05495 const unsigned int z0, const unsigned int z1, const unsigned int v0=0) {
05496 return instance.get_shared_planes(z0,z1,v0);
05497 }
05498
05499 template<typename T> inline CImg<T> shared_planes(const CImg<T>& instance,
05500 const unsigned int z0, const unsigned int z1, const unsigned int v0=0) {
05501 return instance.get_shared_planes(z0,z1,v0);
05502 }
05503
05504 template<typename T> inline CImg<T> shared_plane(CImg<T>& instance, const unsigned int z0, const unsigned int v0=0) {
05505 return instance.get_shared_plane(z0,v0);
05506 }
05507
05508 template<typename T> inline CImg<T> shared_plane(const CImg<T>& instance, const unsigned int z0, const unsigned int v0=0) {
05509 return instance.get_shared_plane(z0,v0);
05510 }
05511
05512 template<typename T> inline CImg<T> shared_channels(CImg<T>& instance, const unsigned int v0, const unsigned int v1) {
05513 return instance.get_shared_channels(v0,v1);
05514 }
05515
05516 template<typename T> inline CImg<T> shared_channels(const CImg<T>& instance, const unsigned int v0, const unsigned int v1) {
05517 return instance.get_shared_channels(v0,v1);
05518 }
05519
05520 template<typename T> inline CImg<T> shared_channel(CImg<T>& instance, const unsigned int v0) {
05521 return instance.get_shared_channel(v0);
05522 }
05523
05524 template<typename T> inline CImg<T> shared_channel(const CImg<T>& instance, const unsigned int v0) {
05525 return instance.get_shared_channel(v0);
05526 }
05527
05528 template<typename T> inline CImg<T> shared(CImg<T>& instance) {
05529 return instance.get_shared();
05530 }
05531
05532 template<typename T> inline CImg<T> shared(const CImg<T>& instance) {
05533 return instance.get_shared();
05534 }
05535
05536 template<typename T> inline CImg<T> mirror(const CImg<T>& instance, const char axe='x') {
05537 return instance.get_mirror(axe);
05538 }
05539
05540 template<typename T> inline CImg<T> translate(const CImg<T>& instance, const int deltax, const int deltay=0, const int deltaz=0,
05541 const int deltav=0, const int border_condition=0) {
05542 return instance.get_translate(deltax,deltay,deltaz,deltav,border_condition);
05543 }
05544
05545 template<typename T> inline CImg<T> projections2d(const CImg<T>& instance,
05546 const unsigned int x0, const unsigned int y0, const unsigned int z0,
05547 const int dx=-100, const int dy=-100, const int dz=-100) {
05548 return instance.get_projections2d(x0,y0,z0,dx,dy,dz);
05549 }
05550
05551 template<typename T> inline CImg<typename cimg::last<T,float>::type>
05552 histogram(const CImg<T>& instance, const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) {
05553 return instance.get_histogram(nblevels,val_min,val_max);
05554 }
05555
05556 template<typename T> inline CImg<T> equalize_histogram(const CImg<T>& instance,
05557 const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) {
05558 return instance.get_equalize_histogram(nblevels,val_min,val_max);
05559 }
05560
05561 template<typename T> inline CImg<typename cimg::last<T,unsigned int>::type> label_regions(const CImg<T>& instance) {
05562 return instance.get_label_regions();
05563 }
05564
05565 template<typename T> inline CImg<typename cimg::superset<T,float>::type> norm_pointwise(const CImg<T>& instance, int norm_type=2) {
05566 return instance.get_norm_pointwise(norm_type);
05567 }
05568
05569 template<typename T> inline CImg<typename cimg::superset<T,float>::type> orientation_pointwise(const CImg<T>& instance) {
05570 return instance.get_orientation_pointwise();
05571 }
05572
05573 template<typename T> inline CImgList<T> split(const CImg<T>& instance, const char axe='x', const unsigned int nb=0) {
05574 return instance.get_split(axe,nb);
05575 }
05576
05577 template<typename T> inline CImg<T> append(const CImg<T>& instance, const CImg<T>& img, const char axis='x', const char align='c') {
05578 return instance.get_append(img,axis,align);
05579 }
05580
05581 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> gradientXY(const CImg<T>& instance, const int scheme=0) {
05582 return instance.get_gradientXY(scheme);
05583 }
05584
05585 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> gradientXYZ(const CImg<T>& instance, const int scheme=0) {
05586 return instance.get_gradientXYZ(scheme);
05587 }
05588
05589 template<typename T> inline CImg<typename cimg::superset<T,float>::type> structure_tensorXY(const CImg<T>& instance, const int scheme=1) {
05590 return instance.get_structure_tensorXY(scheme);
05591 }
05592
05593 template<typename T> inline CImg<typename cimg::superset<T,float>::type> structure_tensorXYZ(const CImg<T>& instance, const int scheme=1) {
05594 return instance.get_structure_tensorXYZ(scheme);
05595 }
05596
05597 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05598 distance_function(const CImg<T>& instance, const unsigned int nb_iter=100, const float band_size=0.0f, const float precision=0.5f) {
05599 return instance.get_distance_function(nb_iter,band_size,precision);
05600 }
05601
05602 template<typename T, typename t> inline CImg<typename cimg::superset<T,float>::type>
05603 dijkstra(const CImg<T>& instance, const unsigned int starting_node, const unsigned int ending_node, CImg<t>& previous) {
05604 return instance.get_dijkstra(starting_node,ending_node,previous);
05605 }
05606
05607 template<typename T, typename t> inline CImg<typename cimg::superset<T,float>::type>
05608 dijkstra(const CImg<T>& instance, const unsigned int starting_node, const unsigned int ending_node=~0U) {
05609 return instance.get_dijkstra(starting_node,ending_node);
05610 }
05611
05612 template<typename T, typename t> inline CImg<t> RGBtoLUT(const CImg<T>& instance, const CImg<t>& palette,
05613 const bool dithering=true, const bool indexing=false) {
05614 return instance.get_RGBtoLUT(palette,dithering,indexing);
05615 }
05616
05617 template<typename T> inline CImg<T> RGBtoLUT(const CImg<T>& instance, const bool dithering=true, const bool indexing=false) {
05618 return instance.get_RGBtoLUT(dithering,indexing);
05619 }
05620
05621 template<typename T, typename t> inline CImg<t> LUTtoRGB(const CImg<T>& instance, const CImg<t>& palette) {
05622 return instance.get_LUTtoRGB(palette);
05623 }
05624
05625 template<typename T> inline CImg<T> LUTtoRGB(const CImg<T>& instance) {
05626 return instance.get_LUTtoRGB();
05627 }
05628
05629 template<typename T> inline CImg<typename cimg::superset<T,float>::type> RGBtoHSV(const CImg<T>& instance) {
05630 return instance.get_RGBtoHSV();
05631 }
05632
05633 template<typename T> inline CImg<T> HSVtoRGB(const CImg<T>& instance) {
05634 return instance.get_HSVtoRGB();
05635 }
05636
05637 template<typename T> inline CImg<typename cimg::superset<T,float>::type> RGBtoHSL(const CImg<T>& instance) {
05638 return instance.get_RGBtoHSL();
05639 }
05640
05641 template<typename T> inline CImg<T> HSLtoRGB(const CImg<T>& instance) {
05642 return instance.get_HSLtoRGB();
05643 }
05644
05645 template<typename T> inline CImg<T> RGBtoYCbCr(const CImg<T>& instance) {
05646 return instance.get_RGBtoYCbCr();
05647 }
05648
05649 template<typename T> inline CImg<T> YCbCrtoRGB(const CImg<T>& instance) {
05650 return instance.get_YCbCrtoRGB();
05651 }
05652
05653 template<typename T> inline CImg<typename cimg::superset<T,float>::type> RGBtoYUV(const CImg<T>& instance) {
05654 return instance.get_RGBtoYUV();
05655 }
05656
05657 template<typename T> inline CImg<T> YUVtoRGB(const CImg<T>& instance) {
05658 return instance.get_YUVtoRGB();
05659 }
05660
05661 template<typename T> inline CImg<typename cimg::superset<T,float>::type> RGBtoXYZ(const CImg<T>& instance) {
05662 return instance.get_RGBtoXYZ();
05663 }
05664
05665 template<typename T> inline CImg<T> XYZtoRGB(const CImg<T>& instance) {
05666 return instance.get_XYZtoRGB();
05667 }
05668
05669 template<typename T> inline CImg<T> XYZtoLab(const CImg<T>& instance) {
05670 return instance.get_XYZtoLab();
05671 }
05672
05673 template<typename T> inline CImg<T> LabtoXYZ(const CImg<T>& instance) {
05674 return instance.get_LabtoXYZ();
05675 }
05676
05677 template<typename T> inline CImg<T> XYZtoxyY(const CImg<T>& instance) {
05678 return instance.get_XYZtoxyY();
05679 }
05680
05681 template<typename T> inline CImg<T> xyYtoXYZ(const CImg<T>& instance) {
05682 return instance.get_xyYtoXYZ();
05683 }
05684
05685 template<typename T> inline CImg<T> RGBtoLab(const CImg<T>& instance) {
05686 return instance.get_RGBtoLab();
05687 }
05688
05689 template<typename T> inline CImg<T> LabtoRGB(const CImg<T>& instance) {
05690 return instance.get_LabtoRGB();
05691 }
05692
05693 template<typename T> inline CImg<T> RGBtoxyY(const CImg<T>& instance) {
05694 return instance.get_RGBtoxyY();
05695 }
05696
05697 template<typename T> inline CImg<T> xyYtoRGB(const CImg<T>& instance) {
05698 return instance.get_xyYtoRGB();
05699 }
05700
05701 template<typename T> inline CImg<T> RGBtoBayer(const CImg<T>& instance, const bool even_mode=true) {
05702 return instance.get_RGBtoBayer(even_mode);
05703 }
05704
05705 template<typename T> inline CImg<T> BayertoRGB(const CImg<T>& instance, const unsigned int interpolation_type=3, const bool even_mode=true) {
05706 return instance.get_BayertoRGB(interpolation_type,even_mode);
05707 }
05708
05709 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type>
05710 correlate(const CImg<T>& instance, const CImg<t>& mask, const unsigned int cond=1, const bool weighted_correl=false) {
05711 return instance.get_correlate(mask,cond,weighted_correl);
05712 }
05713
05714 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type>
05715 convolve(const CImg<T>& instance, const CImg<t>& mask, const unsigned int cond=1, const bool weighted_convol=false) {
05716 return instance.get_convolve(mask,cond,weighted_convol);
05717 }
05718
05719 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type>
05720 erode(const CImg<T>& instance, const CImg<t>& mask, const unsigned int cond=1, const bool weighted_erosion=false) {
05721 return instance.get_erode(mask,cond,weighted_erosion);
05722 }
05723
05724 template<typename T> inline CImg<T> erode(const CImg<T>& instance, const unsigned int n, const unsigned int cond=1) {
05725 return instance.get_erode(n,cond);
05726 }
05727
05728 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type>
05729 dilate(const CImg<T>& instance, const CImg<t>& mask, const unsigned int cond=1, const bool weighted_dilatation=false) {
05730 return instance.get_dilate(mask,cond,weighted_dilatation);
05731 }
05732
05733 template<typename T> inline CImg<T> dilate(const CImg<T>& instance, const unsigned int n, const unsigned int cond=1) {
05734 return instance.get_dilate(n,cond);
05735 }
05736
05737 template<typename T> inline CImg<T> noise(const CImg<T>& instance, const double sigma=-20, const unsigned int ntype=0) {
05738 return instance.get_noise(sigma,ntype);
05739 }
05740
05741 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05742 deriche(const CImg<T>& instance, const float sigma, const int order=0, const char axe='x', const bool cond=true) {
05743 return instance.get_deriche(sigma,order,axe,cond);
05744 }
05745
05746 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05747 blur(const CImg<T>& instance, const float sigmax, const float sigmay, const float sigmaz, const bool cond=true) {
05748 return instance.get_blur(sigmax,sigmay,sigmaz,cond);
05749 }
05750
05751 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05752 blur(const CImg<T>& instance, const float sigma, const bool cond=true) {
05753 return instance.get_blur(sigma,cond);
05754 }
05755
05756 template<typename T, typename t> inline CImg<T> blur_anisotropic(const CImg<T>& instance, const CImg<t>& G, const float amplitude=60.0f,
05757 const float dl=0.8f, const float da=30.0f,
05758 const float gauss_prec=2.0f, const unsigned int interpolation=0,
05759 const bool fast_approx=true) {
05760 return instance.get_blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
05761 }
05762
05763 template<typename T, typename tm> inline CImg<T> blur_anisotropic(const CImg<T>& instance, const CImg<tm>& mask,
05764 const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
05765 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
05766 const float da=30.0f, const float gauss_prec=2.0f,
05767 const unsigned int interpolation=0, const bool fast_approx=true,
05768 const float geom_factor=1.0f) {
05769 return instance.get_blur_anisotropic(mask,amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
05770 }
05771
05772 template<typename T> inline CImg<T> blur_anisotropic(const CImg<T>& instance, const float amplitude, const float sharpness=0.7f,
05773 const float anisotropy=0.3f,
05774 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
05775 const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0,
05776 const bool fast_approx=true, const float geom_factor=1.0f) {
05777 return instance.get_blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
05778 }
05779
05780 template<typename T> inline CImg<T> blur_bilateral(const CImg<T>& instance,
05781 const float sigmax, const float sigmay, const float sigmaz, const float sigmar,
05782 const int bgridx, const int bgridy, const int bgridz, const int bgridr,
05783 const bool interpolation=true) {
05784 return instance.get_blur_bilateral(sigmax,sigmay,sigmaz,sigmar,bgridx,bgridy,bgridz,bgridr,interpolation);
05785 }
05786
05787 template<typename T> inline CImg<T> blur_bilateral(const CImg<T>& instance,
05788 const float sigmas, const float sigmar, const int bgrids=-33, const int bgridr=32,
05789 const bool interpolation=true) {
05790 return instance.get_blur_bilateral(sigmas,sigmar,bgrids,bgridr,interpolation);
05791 }
05792
05793 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> FFT(const CImg<T>& instance, const char axe, const bool inverse=false) {
05794 return instance.get_FFT(axe,inverse);
05795 }
05796
05797 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> FFT(const CImg<T>& instance, const bool inverse=false) {
05798 return instance.get_FFT(inverse);
05799 }
05800
05801 template<typename T> inline CImg<T> blur_median(const CImg<T>& instance, const unsigned int n=3) {
05802 return instance.get_blur_median(n);
05803 }
05804
05805 template<typename T> inline CImg<T> sharpen(const CImg<T>& instance, const float amplitude=50.0f, const float edge=1.0f,
05806 const float alpha=0.0f, const float sigma=0.0f) {
05807 return instance.get_sharpen(amplitude,edge,alpha,sigma);
05808 }
05809
05810 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05811 haar(const CImg<T>& instance, const char axis, const bool inverse=false, const unsigned int nb_scales=1) {
05812 return instance.get_haar(axis,inverse,nb_scales);
05813 }
05814
05815 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05816 haar(const CImg<T>& instance, const bool inverse=false, const unsigned int nb_scales=1) {
05817 return instance.get_haar(inverse,nb_scales);
05818 }
05819
05820 template<typename T> inline CImg<typename cimg::superset<T,float>::type>
05821 displacement_field(const CImg<T>& instance, const CImg<T>& reference,
05822 const float smooth=0.1f, const float precision=1e-6f,
05823 const unsigned int nb_scale=0,
05824 const unsigned int itermax=10000) {
05825 return instance.get_displacement_field(reference,smooth,precision,nb_scale,itermax);
05826 }
05827
05828 template<typename T> inline CImg<T> matrix(const CImg<T>& instance) {
05829 return instance.get_matrix();
05830 }
05831
05832 template<typename T> inline CImg<T> tensor(const CImg<T>& instance) {
05833 return instance.get_tensor();
05834 }
05835
05836 template<typename T> inline CImg<T> unroll(const CImg<T>& instance, const char axe='x') {
05837 return instance.get_unroll(axe);
05838 }
05839
05840 template<typename T> inline CImg<T> diagonal(const CImg<T>& instance) {
05841 return instance.get_diagonal();
05842 }
05843
05844 template<typename T> inline CImg<T> identity_matrix(const CImg<T>& instance) {
05845 return instance.get_identity_matrix();
05846 }
05847
05848 template<typename T> inline CImg<T> sequence(const CImg<T>& instance, const T a0, const T a1) {
05849 return instance.get_sequence(a0,a1);
05850 }
05851
05852 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) {
05853 return instance.get_vector_at(x,y,z);
05854 }
05855
05856 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) {
05857 return instance.get_matrix_at(x,y,z);
05858 }
05859
05860 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) {
05861 return instance.get_tensor_at(x,y,z);
05862 }
05863
05864 template<typename T> inline CImg<T> transpose(const CImg<T>& instance) {
05865 return instance.get_transpose();
05866 }
05867
05868 template<typename T> inline CImg<typename cimg::superset<T,float>::type> inverse(const CImg<T>& instance, const bool use_LU=true) {
05869 return instance.get_inverse(use_LU);
05870 }
05871
05872 template<typename T> inline CImg<typename cimg::superset<T,float>::type> pseudoinverse(const CImg<T>& instance) {
05873 return instance.get_pseudoinverse();
05874 }
05875
05876 template<typename T, typename t> inline CImg<typename cimg::superset<T,t>::type> cross(const CImg<T>& instance, const CImg<t>& img) {
05877 return instance.get_cross(img);
05878 }
05879
05880 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> SVD(const CImg<T>& instance, const bool sorting=true) {
05881 return instance.get_SVD(sorting);
05882 }
05883
05884 template<typename T, typename t> inline CImg<typename cimg::superset2<T,t,float>::type> solve(const CImg<T>& instance, const CImg<t>& A) {
05885 return instance.get_solve(A);
05886 }
05887
05888 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> eigen(const CImg<T>& instance) {
05889 return instance.get_eigen();
05890 }
05891
05892 template<typename T> inline CImgList<typename cimg::superset<T,float>::type> symmetric_eigen(const CImg<T>& instance) {
05893 return instance.get_symmetric_eigen();
05894 }
05895
05896 template<typename T, typename t> inline CImg<T> sort(const CImg<T>& instance, CImg<t>& permutations, const bool increasing=true) {
05897 return instance.get_sort(permutations,increasing);
05898 }
05899
05900 template<typename T> inline CImg<T> sort(const CImg<T>& instance, const bool increasing=true) {
05901 return instance.get_sort(increasing);
05902 }
05903
05904 template<typename T, typename t> inline CImg<T> permute(const CImg<T>& instance, const CImg<t>& permutation) {
05905 return instance.get_permute(permutation);
05906 }
05907
05908 template<typename T> inline CImg<typename cimg::last<T,int>::type>
05909 coordinates(const CImg<T>& instance, const int coords_type, CImgDisplay &disp,
05910 unsigned int *const XYZ=0, const unsigned char *const color=0) {
05911 return instance.get_coordinates(coords_type,disp,XYZ,color);
05912 }
05913
05914 template<typename T, typename t> inline CImgList<typename cimg::superset<T,t>::type>
05915 insert(const CImgList<T>& instance, const CImg<t>& img, const unsigned int pos=~0U, const bool shared=false) {
05916 return instance.get_insert(img,pos,shared);
05917 }
05918
05919 template<typename T, typename t> inline CImgList<typename cimg::superset<T,t>::type>
05920 insert(const CImgList<T>& instance, const unsigned int n, const CImg<t>& img,
05921 const unsigned int pos=~0U, const bool shared=false) {
05922 return instance.get_insert(n,img,pos,shared);
05923 }
05924
05925 template<typename T, typename t> inline CImgList<typename cimg::superset<T,t>::type>
05926 insert(const CImgList<T>& instance, const CImgList<t>& list, const unsigned int pos=~0U, int shared=0) {
05927 return instance.get_insert(list,pos,shared);
05928 }
05929
05930 template<typename T, typename t> inline CImgList<typename cimg::superset<T,t>::type>
05931 insert(const CImgList<T>& instance, const unsigned int n, const CImgList<t>& list, const unsigned int pos=~0U, const int shared=0) {
05932 return instance.insert(n,list,pos,shared);
05933 }
05934
05935 template<typename T> inline CImgList<T> remove(const CImgList<T>& instance, const unsigned int pos) {
05936 return instance.get_remove(pos);
05937 }
05938
05939 template<typename T> inline CImgList<T> remove(const CImgList<T>& instance) {
05940 return instance.get_remove();
05941 }
05942
05943 template<typename T> inline CImgList<T> reverse(const CImgList<T>& instance) {
05944 return instance.get_reverse();
05945 }
05946
05947 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05948 const bool shared=false) {
05949 return instance.get_crop(i0,i1,shared);
05950 }
05951
05952 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05953 const int x0, const int y0, const int z0, const int v0,
05954 const int x1, const int y1, const int z1, const int v1) {
05955 return instance.get_crop(i0,i1,x0,y0,z0,v0,x1,y1,z1,v1);
05956 }
05957
05958 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05959 const int x0, const int y0, const int z0,
05960 const int x1, const int y1, const int z1) {
05961 return instance.get_crop(i0,i1,x0,y0,z0,x1,y1,z1);
05962 }
05963
05964 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05965 const int x0, const int y0,
05966 const int x1, const int y1) {
05967 return instance.get_crop(i0,i1,x0,y0,x1,y1);
05968 }
05969
05970 template<typename T> inline CImgList<T> crop(const CImgList<T>& instance, const unsigned int i0, const unsigned int i1,
05971 const int x0, const int x1) {
05972 return instance.get_crop(i0,i1,x0,x1);
05973 }
05974
05975 template<typename T> inline CImgList<typename cimg::superset<T,float>::type>
05976 FFT(const CImgList<T>& instance, const char axe, const bool inverse=false) {
05977 return instance.get_FFT(axe,inverse);
05978 }
05979
05980 template<typename T> inline CImgList<typename cimg::superset<T,float>::type>
05981 FFT(const CImgList<T>& instance, const bool inverse=false) {
05982 return instance.get_FFT(inverse);
05983 }
05984
05985 template<typename T> inline CImgList<T> split(const CImgList<T>& instance, const char axe='x') {
05986 return instance.get_split(axe);
05987 }
05988
05989 template<typename T> inline CImg<T> append(const CImgList<T>& instance, const char axe='x', const char align='c') {
05990 return instance.get_append(axe,align);
05991 }
05992
05993 template<typename T> inline CImgList<T> crop_font(const CImgList<T>& instance) {
05994 return instance.get_crop_font();
05995 }
05996
05997
05998
05999
06000
06001
06002
06003
06004
06005
06006
06007
06008
06010
06018 struct CImgDisplay {
06019
06021 unsigned int width;
06022
06024 unsigned int height;
06025
06027 unsigned int normalization;
06028
06030 unsigned int events;
06031
06033 char* title;
06034
06036 volatile int window_x;
06037
06039 volatile int window_y;
06040
06042 volatile unsigned int window_width;
06043
06045 volatile unsigned int window_height;
06046
06048 volatile int mouse_x;
06049
06051 volatile int mouse_y;
06052
06054 volatile unsigned int buttons[512];
06055 volatile unsigned int& button;
06056
06058 volatile int wheel;
06059
06061 volatile unsigned int& key;
06062 volatile unsigned int keys[512];
06063
06065 volatile unsigned int& released_key;
06066 volatile unsigned int released_keys[512];
06067
06069 volatile bool is_closed;
06070
06072 volatile bool is_resized;
06073
06075 volatile bool is_moved;
06076
06078 volatile bool is_event;
06079
06081 bool is_fullscreen;
06082
06083 float fps_fps, min, max;
06084 unsigned long timer, fps_frames, fps_timer;
06085
06086 #ifdef cimgdisplay_plugin
06087 #include cimgdisplay_plugin
06088 #endif
06089 #ifdef cimgdisplay_plugin1
06090 #include cimgdisplay_plugin1
06091 #endif
06092 #ifdef cimgdisplay_plugin2
06093 #include cimgdisplay_plugin2
06094 #endif
06095 #ifdef cimgdisplay_plugin3
06096 #include cimgdisplay_plugin3
06097 #endif
06098 #ifdef cimgdisplay_plugin4
06099 #include cimgdisplay_plugin4
06100 #endif
06101 #ifdef cimgdisplay_plugin5
06102 #include cimgdisplay_plugin5
06103 #endif
06104 #ifdef cimgdisplay_plugin6
06105 #include cimgdisplay_plugin6
06106 #endif
06107 #ifdef cimgdisplay_plugin7
06108 #include cimgdisplay_plugin7
06109 #endif
06110 #ifdef cimgdisplay_plugin8
06111 #include cimgdisplay_plugin8
06112 #endif
06113
06115 CImgDisplay():
06116 width(0),height(0),normalization(0),events(0),title(0),
06117 window_x(0),window_y(0),window_width(0),window_height(0),
06118 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06119 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),
06120 min(0),max(0) {}
06121
06123
06132 CImgDisplay(const unsigned int dimw, const unsigned int dimh, const char *title=0,
06133 const unsigned int normalization_type=3, const unsigned int events_type=3,
06134 const bool fullscreen_flag=false, const bool closed_flag=false):
06135 width(0),height(0),normalization(0),events(0),title(0),
06136 window_x(0),window_y(0),window_width(0),window_height(0),
06137 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06138 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),
06139 min(0),max(0) {
06140 assign(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06141 }
06142
06144
06151 template<typename T>
06152 CImgDisplay(const CImg<T>& img, const char *title=0,
06153 const unsigned int normalization_type=3, const unsigned int events_type=3,
06154 const bool fullscreen_flag=false, const bool closed_flag=false):
06155 width(0),height(0),normalization(0),events(0),title(0),
06156 window_x(0),window_y(0),window_width(0),window_height(0),
06157 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06158 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),min(0),max(0) {
06159 assign(img,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06160 }
06161
06163
06170 template<typename T>
06171 CImgDisplay(const CImgList<T>& list, const char *title=0,
06172 const unsigned int normalization_type=3, const unsigned int events_type=3,
06173 const bool fullscreen_flag=false, const bool closed_flag=false):
06174 width(0),height(0),normalization(0),events(0),title(0),
06175 window_x(0),window_y(0),window_width(0),window_height(0),
06176 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06177 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),min(0),max(0) {
06178 assign(list,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06179 }
06180
06182
06185 CImgDisplay(const CImgDisplay& disp):
06186 width(0),height(0),normalization(0),events(0),title(0),
06187 window_x(0),window_y(0),window_width(0),window_height(0),
06188 mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
06189 is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),min(0),max(0) {
06190 assign(disp);
06191 }
06192
06194 ~CImgDisplay() {
06195 assign();
06196 }
06197
06199 CImgDisplay& operator=(const CImgDisplay& disp) {
06200 return assign(disp);
06201 }
06202
06204 bool is_empty() const {
06205 return (!width || !height);
06206 }
06207
06209 operator bool() const {
06210 return !is_empty();
06211 }
06212
06214 int dimx() const {
06215 return (int)width;
06216 }
06217
06219 int dimy() const {
06220 return (int)height;
06221 }
06222
06224 int window_dimx() const {
06225 return (int)window_width;
06226 }
06227
06229 int window_dimy() const {
06230 return (int)window_height;
06231 }
06232
06234 int window_posx() const {
06235 return window_x;
06236 }
06237
06239 int window_posy() const {
06240 return window_y;
06241 }
06242
06244
06246 CImgDisplay& wait(const unsigned int milliseconds) {
06247 cimg::wait(milliseconds, timer);
06248 return *this;
06249 }
06250
06252 CImgDisplay& wait() {
06253 if (!is_empty()) wait(*this);
06254 return *this;
06255 }
06256
06258 static void wait(CImgDisplay& disp1) {
06259 disp1.is_event = 0;
06260 while (!disp1.is_event) wait_all();
06261 }
06262
06264 static void wait(CImgDisplay& disp1, CImgDisplay& disp2) {
06265 disp1.is_event = disp2.is_event = 0;
06266 while (!disp1.is_event && !disp2.is_event) wait_all();
06267 }
06268
06270 static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3) {
06271 disp1.is_event = disp2.is_event = disp3.is_event = 0;
06272 while (!disp1.is_event && !disp2.is_event && !disp3.is_event) wait_all();
06273 }
06274
06276 static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4) {
06277 disp1.is_event = disp2.is_event = disp3.is_event = disp4.is_event = 0;
06278 while (!disp1.is_event && !disp2.is_event && !disp3.is_event && !disp4.is_event) wait_all();
06279 }
06280
06282 float frames_per_second() {
06283 if (!fps_timer) fps_timer = cimg::time();
06284 const float delta = (cimg::time()-fps_timer)/1000.0f;
06285 ++fps_frames;
06286 if (delta>=1.0f) {
06287 fps_fps = fps_frames/delta;
06288 fps_frames = 0;
06289 fps_timer = cimg::time();
06290 }
06291 return fps_fps;
06292 }
06293
06295
06304 template<typename T> CImgDisplay& display(const CImgList<T>& list, const char axe='x', const char align='c') {
06305 return display(list.get_append(axe,align));
06306 }
06307
06309 template<typename T> CImgDisplay& operator<<(const CImg<T>& img) {
06310 return display(img);
06311 }
06312
06314 template<typename T> CImgDisplay& operator<<(const CImgList<T>& list) {
06315 return display(list);
06316 }
06317
06319
06323 template<typename T> CImgDisplay& resize(const CImg<T>& img, const bool redraw=true) {
06324 return resize(img.width,img.height,redraw);
06325 }
06326
06328 CImgDisplay& resize(const CImgDisplay& disp, const bool redraw=true) {
06329 return resize(disp.width,disp.height,redraw);
06330 }
06331
06333 CImgDisplay& resize(const bool redraw=true) {
06334 resize(window_width,window_height,redraw);
06335 return *this;
06336 }
06337
06339 template<typename tp, typename tf, typename tc, typename to>
06340 CImgDisplay& display_object3d(const tp& points, const CImgList<tf>& primitives,
06341 const CImgList<tc>& colors, const to& opacities,
06342 const bool centering=true,
06343 const int render_static=4, const int render_motion=1,
06344 const bool double_sided=false,
06345 const float focale=500.0f, const float ambient_light=0.05f,
06346 const bool display_axes=true, float *const pose_matrix=0) {
06347 CImg<tc>(width,height,1,3,0).display_object3d(points,primitives,colors,opacities,*this,
06348 centering,render_static,render_motion,
06349 double_sided,focale,ambient_light,
06350 display_axes,pose_matrix);
06351 return *this;
06352 }
06353
06355 template<typename tp, typename tf, typename tc>
06356 CImgDisplay& display_object3d(const tp& points, const CImgList<tf>& primitives,
06357 const CImgList<tc>& colors,
06358 const bool centering=true,
06359 const int render_static=4, const int render_motion=1,
06360 const bool double_sided=false,
06361 const float focale=500.0f, const float ambient_light=0.05f,
06362 const bool display_axes=true,
06363 float *const pose_matrix=0,
06364 const float opacity=1.0f) {
06365 typedef typename cimg::superset<tc,float>::type to;
06366 CImg<tc>(width,height,1,3,0).display_object3d(points,primitives,colors,
06367 CImg<to>::vector((to)opacity),
06368 *this,centering,render_static,render_motion,
06369 double_sided,focale,ambient_light,display_axes,pose_matrix);
06370 return *this;
06371 }
06372
06374 CImgDisplay& toggle_fullscreen() {
06375 return assign(width,height,title,normalization,events,!is_fullscreen,is_closed);
06376 }
06377
06378
06379 template<typename t, typename T> static void _render_resize(const T *ptrs, const unsigned int ws, const unsigned int hs,
06380 t *ptrd, const unsigned int wd, const unsigned int hd) {
06381 unsigned int *const offx = new unsigned int[wd], *const offy = new unsigned int[hd+1], *poffx, *poffy;
06382 float s, curr, old;
06383 s = (float)ws/wd;
06384 poffx = offx; curr = 0; for (unsigned int x=0; x<wd; ++x) { old=curr; curr+=s; *(poffx++) = (unsigned int)curr-(unsigned int)old; }
06385 s = (float)hs/hd;
06386 poffy = offy; curr = 0; for (unsigned int y=0; y<hd; ++y) { old=curr; curr+=s; *(poffy++) = ws*((unsigned int)curr-(unsigned int)old); }
06387 *poffy = 0;
06388 poffy = offy;
06389 {for (unsigned int y=0; y<hd; ) {
06390 const T *ptr = ptrs;
06391 poffx = offx;
06392 for (unsigned int x=0; x<wd; ++x) { *(ptrd++) = *ptr; ptr+=*(poffx++); }
06393 ++y;
06394 unsigned int dy=*(poffy++);
06395 for (;!dy && y<hd; std::memcpy(ptrd, ptrd-wd, sizeof(t)*wd), ++y, ptrd+=wd, dy=*(poffy++));
06396 ptrs+=dy;
06397 }}
06398 delete[] offx; delete[] offy;
06399 }
06400
06402 CImgDisplay& flush() {
06403 std::memset((void*)buttons,0,512*sizeof(unsigned int));
06404 std::memset((void*)keys,0,512*sizeof(unsigned int));
06405 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
06406 mouse_x = mouse_y = -1;
06407 return *this;
06408 }
06409
06411 bool is_key(const bool remove=false) {
06412 for (unsigned int *ptrs=(unsigned int*)keys+512-1; ptrs>=keys; --ptrs) if (*ptrs) { if (remove) *ptrs = 0; return true; }
06413 return false;
06414 }
06415
06417 bool is_key(const unsigned int key1, const bool remove) {
06418 for (unsigned int *ptrs=(unsigned int*)keys+512-1; ptrs>=keys; --ptrs) if (*ptrs==key1) { if (remove) *ptrs = 0; return true; }
06419 return false;
06420 }
06421
06423 bool is_key(const unsigned int key1, const unsigned int key2, const bool remove) {
06424 const unsigned int seq[] = { key1, key2 };
06425 return is_key(seq,2,remove);
06426 }
06427
06429 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3, const bool remove) {
06430 const unsigned int seq[] = { key1, key2, key3 };
06431 return is_key(seq,3,remove);
06432 }
06433
06435 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06436 const unsigned int key4, const bool remove) {
06437 const unsigned int seq[] = { key1, key2, key3, key4 };
06438 return is_key(seq,4,remove);
06439 }
06440
06442 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06443 const unsigned int key4, const unsigned int key5, const bool remove) {
06444 const unsigned int seq[] = { key1, key2, key3, key4, key5 };
06445 return is_key(seq,5,remove);
06446 }
06447
06449 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06450 const unsigned int key4, const unsigned int key5, const unsigned int key6, const bool remove) {
06451 const unsigned int seq[] = { key1, key2, key3, key4, key5, key6 };
06452 return is_key(seq,6,remove);
06453 }
06454
06456 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06457 const unsigned int key4, const unsigned int key5, const unsigned int key6,
06458 const unsigned int key7, const bool remove) {
06459 const unsigned int seq[] = { key1, key2, key3, key4, key5, key6, key7 };
06460 return is_key(seq,7,remove);
06461 }
06462
06464 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06465 const unsigned int key4, const unsigned int key5, const unsigned int key6,
06466 const unsigned int key7, const unsigned int key8, const bool remove) {
06467 const unsigned int seq[] = { key1, key2, key3, key4, key5, key6, key7, key8 };
06468 return is_key(seq,8,remove);
06469 }
06470
06472 bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3,
06473 const unsigned int key4, const unsigned int key5, const unsigned int key6,
06474 const unsigned int key7, const unsigned int key8, const unsigned int key9, const bool remove) {
06475 const unsigned int seq[] = { key1, key2, key3, key4, key5, key6, key7, key8, key9 };
06476 return is_key(seq,9,remove);
06477 }
06478
06480 bool is_key(const unsigned int *const keyseq, const unsigned int N, const bool remove=true) {
06481 if (keyseq && N) {
06482 const unsigned int *const ps_end = keyseq+N-1, k = *ps_end, *const pk_end = (unsigned int*)keys+1+512-N;
06483 for (unsigned int *pk = (unsigned int*)keys; pk<pk_end; ) {
06484 if (*(pk++)==k) {
06485 bool res = true;
06486 const unsigned int *ps = ps_end, *pk2 = pk;
06487 for (unsigned int i=1; i<N; ++i) res = (*(--ps)==*(pk2++));
06488 if (res) {
06489 if (remove) std::memset((void*)(pk-1),0,sizeof(unsigned int)*N);
06490 return true;
06491 }
06492 }
06493 }
06494 }
06495 return false;
06496 }
06497
06498
06499
06500 #if cimg_display_type==0
06501
06503 static int screen_dimx() {
06504 return 0;
06505 }
06506
06508 static int screen_dimy() {
06509 return 0;
06510 }
06511
06513 CImgDisplay& assign() {
06514 return *this;
06515 }
06516
06518 CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0,
06519 const unsigned int normalization_type=3, const unsigned int events_type=3,
06520 const bool fullscreen_flag=false, const bool closed_flag=false) {
06521 throw CImgDisplayException("CImgDisplay() : Display has been required but is not available (cimg_display_type=0)");
06522 fps_timer = 0*(unsigned long)(dimw + dimh + title + normalization_type + events_type + (int)fullscreen_flag + (int)closed_flag);
06523 return *this;
06524 }
06525
06527 template<typename T> CImgDisplay& assign(const CImg<T>& img, const char *title=0,
06528 const unsigned int normalization_type=3, const unsigned int events_type=3,
06529 const bool fullscreen_flag=false, const bool closed_flag=false) {
06530 fps_timer = 0*(unsigned long)(img.width + title + normalization_type + events_type + (int)fullscreen_flag + (int)closed_flag);
06531 return assign(0,0);
06532 }
06533
06535 template<typename T> CImgDisplay& assign(const CImgList<T>& list, const char *title=0,
06536 const unsigned int normalization_type=3, const unsigned int events_type=3,
06537 const bool fullscreen_flag=false, const bool closed_flag=false) {
06538 fps_timer = 0*(unsigned long)(list.size + title + normalization_type + events_type + (int)fullscreen_flag + (int)closed_flag);
06539 return assign(0,0);
06540 }
06541
06543 CImgDisplay& assign(const CImgDisplay &disp) {
06544 return assign(disp.width,disp.height);
06545 }
06546
06548 template<typename T> CImgDisplay& display(const CImg<T>& img) {
06549 fps_timer = 0*img.width;
06550 return *this;
06551 }
06552
06554 CImgDisplay& resize(const int width, const int height, const bool redraw=true) {
06555 fps_timer = 0*width*height*(int)redraw;
06556 return *this;
06557 }
06558
06560 CImgDisplay& move(const int posx, const int posy) {
06561 fps_timer = 0*posx*posy;
06562 return *this;
06563 }
06564
06566 CImgDisplay& set_mouse(const int posx, const int posy) {
06567 fps_timer = 0*posx*posy;
06568 return *this;
06569 }
06570
06572 CImgDisplay& hide_mouse() {
06573 return *this;
06574 }
06575
06577 CImgDisplay& show_mouse() {
06578 return *this;
06579 }
06580
06582 static void wait_all() {}
06583
06585 CImgDisplay& show() {
06586 return *this;
06587 }
06588
06590 CImgDisplay& close() {
06591 return *this;
06592 }
06593
06595 CImgDisplay& set_title(const char *format, ...) {
06596 fps_timer = 0*(unsigned long)format;
06597 return *this;
06598 }
06599
06601 CImgDisplay& paint() {
06602 return *this;
06603 }
06604
06606 template<typename T> CImgDisplay& render(const CImg<T>& img) {
06607 fps_timer = 0*img.width;
06608 return *this;
06609 }
06610
06612 template<typename T> const CImgDisplay& snapshot(CImg<T>& img) const {
06613 img.assign(width,height,1,3,0);
06614 return *this;
06615 }
06616
06617
06618
06619 #elif cimg_display_type==1
06620 void *data;
06621 Window window;
06622 Window background_window;
06623 XImage *image;
06624 Colormap colormap;
06625 Atom wm_delete_window, wm_delete_protocol;
06626 #ifdef cimg_use_xshm
06627 XShmSegmentInfo *shminfo;
06628 #endif
06629
06630 static int screen_dimx() {
06631 int res = 0;
06632 if (!cimg::X11attr().display) {
06633 Display *disp = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0"));
06634 if (!disp) throw CImgDisplayException("CImgDisplay::screen_dimx() : Can't open X11 display");
06635 res = DisplayWidth(disp,DefaultScreen(disp));
06636 XCloseDisplay(disp);
06637 } else {
06638 #ifdef cimg_use_xrandr
06639 if (cimg::X11attr().resolutions && cimg::X11attr().curr_resolution)
06640 res = cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].width;
06641 else
06642 #endif
06643 res = DisplayWidth(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
06644 }
06645 return res;
06646 }
06647
06648 static int screen_dimy() {
06649 int res = 0;
06650 if (!cimg::X11attr().display) {
06651 Display *disp = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0"));
06652 if (!disp) throw CImgDisplayException("CImgDisplay::screen_dimy() : Can't open X11 display");
06653 res = DisplayHeight(disp,DefaultScreen(disp));
06654 XCloseDisplay(disp);
06655 } else {
06656 #ifdef cimg_use_xrandr
06657 if (cimg::X11attr().resolutions && cimg::X11attr().curr_resolution)
06658 res = cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].height; else
06659 #endif
06660 res = DisplayHeight(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
06661 }
06662 return res;
06663 }
06664
06665 CImgDisplay& assign() {
06666 if (!is_empty()) {
06667 pthread_mutex_lock(cimg::X11attr().mutex);
06668
06669
06670 unsigned int i;
06671 for (i=0; i<cimg::X11attr().nb_wins && cimg::X11attr().wins[i]!=this; ++i);
06672 for (; i<cimg::X11attr().nb_wins-1; ++i) cimg::X11attr().wins[i]=cimg::X11attr().wins[i+1];
06673 --cimg::X11attr().nb_wins;
06674
06675
06676 if (is_fullscreen) _desinit_fullscreen();
06677 XDestroyWindow(cimg::X11attr().display,window);
06678 window = 0;
06679 #ifdef cimg_use_xshm
06680 if (shminfo) {
06681 XShmDetach(cimg::X11attr().display, shminfo);
06682 XDestroyImage(image);
06683 shmdt(shminfo->shmaddr);
06684 shmctl(shminfo->shmid,IPC_RMID,0);
06685 delete shminfo;
06686 shminfo = 0;
06687 } else
06688 #endif
06689 XDestroyImage(image);
06690 data = 0;
06691 image = 0;
06692 if (cimg::X11attr().nb_bits==8) XFreeColormap(cimg::X11attr().display,colormap);
06693 colormap = 0;
06694 XSync(cimg::X11attr().display, False);
06695
06696
06697 if (title) delete[] title;
06698 width = height = normalization = events = 0;
06699 is_fullscreen = is_resized = is_moved = is_event = false;
06700 is_closed = true;
06701 title = 0;
06702 window_x = window_y = window_width = window_height = mouse_x = mouse_y = wheel = 0;
06703 std::memset((void*)buttons,0,512*sizeof(unsigned int));
06704 std::memset((void*)keys,0,512*sizeof(unsigned int));
06705 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
06706 min = max = 0;
06707
06708
06709 if (!cimg::X11attr().nb_wins) {
06710
06711
06712 pthread_cancel(*cimg::X11attr().event_thread);
06713 pthread_mutex_unlock(cimg::X11attr().mutex);
06714 pthread_join(*cimg::X11attr().event_thread,0);
06715 delete cimg::X11attr().event_thread;
06716 cimg::X11attr().event_thread = 0;
06717 pthread_mutex_destroy(cimg::X11attr().mutex);
06718 delete cimg::X11attr().mutex;
06719 cimg::X11attr().mutex = 0;
06720 XSync(cimg::X11attr().display, False);
06721 XCloseDisplay(cimg::X11attr().display);
06722 cimg::X11attr().display = 0;
06723 delete cimg::X11attr().gc;
06724 cimg::X11attr().gc = 0;
06725 } else pthread_mutex_unlock(cimg::X11attr().mutex);
06726 }
06727 return *this;
06728 }
06729
06730 CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0,
06731 const unsigned int normalization_type=3, const unsigned int events_type=3,
06732 const bool fullscreen_flag=false, const bool closed_flag=false) {
06733 if (!dimw || !dimh) return assign();
06734 _assign(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06735 min = max = 0;
06736 std::memset(data,0,(cimg::X11attr().nb_bits==8?sizeof(unsigned char):
06737 (cimg::X11attr().nb_bits==16?sizeof(unsigned short):sizeof(unsigned int)))*width*height);
06738 return paint();
06739 }
06740
06741 template<typename T> CImgDisplay& assign(const CImg<T>& img, const char *title=0,
06742 const unsigned int normalization_type=3, const unsigned int events_type=3,
06743 const bool fullscreen_flag=false, const bool closed_flag=false) {
06744 if (!img) return assign();
06745 CImg<T> tmp;
06746 const CImg<T>& nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
06747 _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06748 if (normalization==2) min = (float)nimg.minmax(max);
06749 return render(nimg).paint();
06750 }
06751
06752 template<typename T> CImgDisplay& assign(const CImgList<T>& list, const char *title=0,
06753 const unsigned int normalization_type=3, const unsigned int events_type=3,
06754 const bool fullscreen_flag=false, const bool closed_flag=false) {
06755 if (!list) return assign();
06756 CImg<T> tmp;
06757 const CImg<T> img = list.get_append('x','p'),
06758 &nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
06759 _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
06760 if (normalization==2) min = (float)nimg.minmax(max);
06761 return render(nimg).paint();
06762 }
06763
06764 CImgDisplay& assign(const CImgDisplay& win) {
06765 if (!win) return assign();
06766 _assign(win.width,win.height,win.title,win.normalization,win.events,win.is_fullscreen,win.is_closed);
06767 std::memcpy(data,win.data,(cimg::X11attr().nb_bits==8?sizeof(unsigned char):
06768 cimg::X11attr().nb_bits==16?sizeof(unsigned short):
06769 sizeof(unsigned int))*width*height);
06770 return paint();
06771 }
06772
06773 template<typename T> CImgDisplay& display(const CImg<T>& img) {
06774 if (is_empty()) assign(img.width,img.height);
06775 return render(img).paint(false);
06776 }
06777
06778 CImgDisplay& resize(const int nwidth, const int nheight, const bool redraw=true) {
06779 if (!nwidth || !nheight) return assign();
06780 if (is_empty()) return assign(cimg::max(nwidth,0),cimg::max(nheight,0));
06781 const unsigned int
06782 tmpdimx = (nwidth>0)?nwidth:(-nwidth*width/100),
06783 tmpdimy = (nheight>0)?nheight:(-nheight*height/100),
06784 dimx = cimg::min(tmpdimx?tmpdimx:1,(unsigned int)screen_dimx()),
06785 dimy = cimg::min(tmpdimy?tmpdimy:1,(unsigned int)screen_dimy());
06786 const bool
06787 is_disp_different = (width!=dimx || height!=dimy),
06788 is_win_different = (window_width!=dimx || window_height!=dimy);
06789 if (is_disp_different || is_win_different) {
06790 pthread_mutex_lock(cimg::X11attr().mutex);
06791 XResizeWindow(cimg::X11attr().display,window,dimx,dimy);
06792 window_width = dimx;
06793 window_height = dimy;
06794 is_resized = false;
06795 if (is_disp_different) {
06796 switch (cimg::X11attr().nb_bits) {
06797 case 8: { unsigned char foo = 0; _resize(foo,dimx,dimy,redraw); } break;
06798 case 16: { unsigned short foo = 0; _resize(foo,dimx,dimy,redraw); } break;
06799 default: { unsigned int foo = 0; _resize(foo,dimx,dimy,redraw); } break;
06800 }
06801 width = dimx;
06802 height = dimy;
06803 }
06804 pthread_mutex_unlock(cimg::X11attr().mutex);
06805 if (is_fullscreen) move((screen_dimx()-width)/2,(screen_dimy()-height)/2);
06806 if (redraw) return paint();
06807 }
06808 return *this;
06809 }
06810
06811 CImgDisplay& move(const int posx, const int posy) {
06812 if (is_empty()) return *this;
06813 show();
06814 pthread_mutex_lock(cimg::X11attr().mutex);
06815 XMoveWindow(cimg::X11attr().display,window,posx,posy);
06816 is_moved = false;
06817 window_x = posx;
06818 window_y = posy;
06819 pthread_mutex_unlock(cimg::X11attr().mutex);
06820 return paint();
06821 }
06822
06823 CImgDisplay& set_mouse(const int posx, const int posy) {
06824 if (!is_closed && posx>=0 && posy>=0) {
06825 pthread_mutex_lock(cimg::X11attr().mutex);
06826 XWarpPointer(cimg::X11attr().display,None,window,0,0,0,0,posx,posy);
06827 is_moved = false;
06828 mouse_x = posx;
06829 mouse_y = posy;
06830 XSync(cimg::X11attr().display, False);
06831 pthread_mutex_unlock(cimg::X11attr().mutex);
06832 }
06833 return *this;
06834 }
06835
06836 CImgDisplay& hide_mouse() {
06837 if (cimg::X11attr().display) {
06838 pthread_mutex_lock(cimg::X11attr().mutex);
06839 const char pix_data[8] = { 0 };
06840 XColor col;
06841 col.red = col.green = col.blue = 0;
06842 Pixmap pix = XCreateBitmapFromData(cimg::X11attr().display,window,pix_data,8,8);
06843 Cursor cur = XCreatePixmapCursor(cimg::X11attr().display,pix,pix,&col,&col,0,0);
06844 XFreePixmap(cimg::X11attr().display,pix);
06845 XDefineCursor(cimg::X11attr().display,window,cur);
06846 pthread_mutex_unlock(cimg::X11attr().mutex);
06847 }
06848 return *this;
06849 }
06850
06851 CImgDisplay& show_mouse() {
06852 if (cimg::X11attr().display) {
06853 pthread_mutex_lock(cimg::X11attr().mutex);
06854 XDefineCursor(cimg::X11attr().display,window,None);
06855 pthread_mutex_unlock(cimg::X11attr().mutex);
06856 }
06857 return *this;
06858 }
06859
06860 static void wait_all() {
06861 if (cimg::X11attr().display) {
06862 pthread_mutex_lock(cimg::X11attr().mutex);
06863 bool flag = true;
06864 XEvent event;
06865 while (flag) {
06866 for (unsigned int i=0; i<cimg::X11attr().nb_wins; ++i) {
06867 cimg::X11attr().wins[i]->is_event = false;
06868 const unsigned int xevent_type = (cimg::X11attr().wins[i]->events)&3;
06869 const unsigned int emask =
06870 ((xevent_type>=1)?ExposureMask|StructureNotifyMask:0)|
06871 ((xevent_type>=2)?ButtonPressMask|KeyPressMask|PointerMotionMask|LeaveWindowMask:0)|
06872 ((xevent_type>=3)?ButtonReleaseMask|KeyReleaseMask:0);
06873 XSelectInput(cimg::X11attr().display,cimg::X11attr().wins[i]->window,emask);
06874 }
06875 XNextEvent(cimg::X11attr().display, &event);
06876 for (unsigned int i=0; i<cimg::X11attr().nb_wins; ++i)
06877 if (!cimg::X11attr().wins[i]->is_closed && event.xany.window==cimg::X11attr().wins[i]->window) {
06878 cimg::X11attr().wins[i]->_handle_events(&event);
06879 if (cimg::X11attr().wins[i]->is_event) flag = false;
06880 }
06881 }
06882 pthread_mutex_unlock(cimg::X11attr().mutex);
06883 }
06884 }
06885
06886 CImgDisplay& show() {
06887 if (is_empty()) return *this;
06888 if (is_closed) {
06889 pthread_mutex_lock(cimg::X11attr().mutex);
06890 if (is_fullscreen) _init_fullscreen();
06891 _map_window();
06892 is_closed = false;
06893 pthread_mutex_unlock(cimg::X11attr().mutex);
06894 }
06895 return paint();
06896 }
06897
06898 CImgDisplay& close() {
06899 if (is_empty()) return *this;
06900 if (!is_closed) {
06901 pthread_mutex_lock(cimg::X11attr().mutex);
06902 if (is_fullscreen) _desinit_fullscreen();
06903 XUnmapWindow(cimg::X11attr().display,window);
06904 window_x = window_y = -1;
06905 is_closed = true;
06906 pthread_mutex_unlock(cimg::X11attr().mutex);
06907 }
06908 return *this;
06909 }
06910
06911 CImgDisplay& set_title(const char *format, ...) {
06912 if (is_empty()) return *this;
06913 char tmp[1024] = {0};
06914 va_list ap;
06915 va_start(ap, format);
06916 std::vsprintf(tmp,format,ap);
06917 va_end(ap);
06918 if (title) delete[] title;
06919 const int s = cimg::strlen(tmp)+1;
06920 title = new char[s];
06921 std::memcpy(title,tmp,s*sizeof(char));
06922 pthread_mutex_lock(cimg::X11attr().mutex);
06923 XStoreName(cimg::X11attr().display,window,tmp);
06924 pthread_mutex_unlock(cimg::X11attr().mutex);
06925 return *this;
06926 }
06927
06928 CImgDisplay& paint(const bool wait_expose=true) {
06929 if (is_empty()) return *this;
06930 pthread_mutex_lock(cimg::X11attr().mutex);
06931 _paint(wait_expose);
06932 pthread_mutex_unlock(cimg::X11attr().mutex);
06933 return *this;
06934 }
06935
06936 template<typename T> CImgDisplay& render(const CImg<T>& img, const bool flag8=false) {
06937 if (is_empty()) return *this;
06938 if (!img)
06939 throw CImgArgumentException("CImgDisplay::_render_image() : Specified input image (%u,%u,%u,%u,%p) is empty.",
06940 img.width,img.height,img.depth,img.dim,img.data);
06941 if (img.depth!=1) return render(img.get_projections2d(img.width/2,img.height/2,img.depth/2));
06942 if (cimg::X11attr().nb_bits==8 && (img.width!=width || img.height!=height)) return render(img.get_resize(width,height,1,-100,1));
06943 if (cimg::X11attr().nb_bits==8 && !flag8 && img.dim==3) return render(img.get_RGBtoLUT(true),true);
06944
06945 const unsigned int xymax = img.width*img.height;
06946 const T
06947 *data1 = img.data,
06948 *data2 = (img.dim>=2)?img.ptr(0,0,0,1):data1,
06949 *data3 = (img.dim>=3)?img.ptr(0,0,0,2):data1;
06950 if (cimg::X11attr().blue_first) cimg::swap(data1,data3);
06951 pthread_mutex_lock(cimg::X11attr().mutex);
06952
06953 if (!normalization || (normalization==3 && cimg::type<T>::string()==cimg::type<unsigned char>::string())) {
06954 min = max = 0;
06955 switch (cimg::X11attr().nb_bits) {
06956 case 8: {
06957 _set_colormap(colormap,img.dim);
06958 unsigned char *const ndata = (img.width==width && img.height==height)?(unsigned char*)data:new unsigned char[img.width*img.height];
06959 unsigned char *ptrd = (unsigned char*)ndata;
06960 switch (img.dim) {
06961 case 1: for (unsigned int xy=0; xy<xymax; ++xy) (*ptrd++) = (unsigned char)*(data1++);
06962 break;
06963 case 2: for (unsigned int xy=0; xy<xymax; ++xy) {
06964 const unsigned char R = (unsigned char)*(data1++), G = (unsigned char)*(data2++);
06965 (*ptrd++) = (R&0xf0)|(G>>4);
06966 } break;
06967 default: for (unsigned int xy=0; xy<xymax; ++xy) {
06968 const unsigned char R = (unsigned char)*(data1++), G = (unsigned char)*(data2++), B = (unsigned char)*(data3++);
06969 (*ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6);
06970 } break;
06971 }
06972 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned char*)data,width,height); delete[] ndata; }
06973 } break;
06974 case 16: {
06975 unsigned short *const ndata = (img.width==width && img.height==height)?(unsigned short*)data:new unsigned short[img.width*img.height];
06976 unsigned char *ptrd = (unsigned char*)ndata;
06977 const unsigned int M = 248;
06978 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
06979 const unsigned char G = (unsigned char)*(data2++)>>2;
06980 *(ptrd++) = (unsigned char)*(data1++)&M | (G>>3);
06981 *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3);
06982 } else for (unsigned int xy=0; xy<xymax; ++xy) {
06983 const unsigned char G = (unsigned char)*(data2++)>>2;
06984 *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3);
06985 *(ptrd++) = (unsigned char)*(data1++)&M | (G>>3);
06986 }
06987 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned short*)data,width,height); delete[] ndata; }
06988 } break;
06989 default: {
06990 unsigned int *const ndata = (img.width==width && img.height==height)?(unsigned int*)data:new unsigned int[img.width*img.height];
06991 unsigned char *ptrd = (unsigned char*)ndata;
06992 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
06993 *(ptrd++) = 0;
06994 *(ptrd++) = (unsigned char)*(data1++);
06995 *(ptrd++) = (unsigned char)*(data2++);
06996 *(ptrd++) = (unsigned char)*(data3++);
06997 } else for (unsigned int xy=0; xy<xymax; ++xy) {
06998 *(ptrd++) = (unsigned char)*(data3++);
06999 *(ptrd++) = (unsigned char)*(data2++);
07000 *(ptrd++) = (unsigned char)*(data1++);
07001 *(ptrd++) = 0;
07002 }
07003 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned int*)data,width,height); delete[] ndata; }
07004 } break;
07005 };
07006 } else {
07007 if (normalization==3) {
07008 if (cimg::type<T>::is_float()) min = (float)img.minmax(max);
07009 else { min = (float)cimg::type<T>::min(); max = (float)cimg::type<T>::max(); }
07010 } else if ((min>max) || normalization==1) min = (float)img.minmax(max);
07011 const float delta = max-min, mm = delta?delta:1.0f;
07012 switch (cimg::X11attr().nb_bits) {
07013 case 8: {
07014 _set_colormap(colormap,img.dim);
07015 unsigned char *const ndata = (img.width==width && img.height==height)?(unsigned char*)data:new unsigned char[img.width*img.height];
07016 unsigned char *ptrd = (unsigned char*)ndata;
07017 switch (img.dim) {
07018 case 1: for (unsigned int xy=0; xy<xymax; ++xy) {
07019 const unsigned char R = (unsigned char)(255*(*(data1++)-min)/mm);
07020 *(ptrd++) = R;
07021 } break;
07022 case 2: for (unsigned int xy=0; xy<xymax; ++xy) {
07023 const unsigned char
07024 R = (unsigned char)(255*(*(data1++)-min)/mm),
07025 G = (unsigned char)(255*(*(data2++)-min)/mm);
07026 (*ptrd++) = (R&0xf0) | (G>>4);
07027 } break;
07028 default:
07029 for (unsigned int xy=0; xy<xymax; ++xy) {
07030 const unsigned char
07031 R = (unsigned char)(255*(*(data1++)-min)/mm),
07032 G = (unsigned char)(255*(*(data2++)-min)/mm),
07033 B = (unsigned char)(255*(*(data3++)-min)/mm);
07034 *(ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6);
07035 } break;
07036 }
07037 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned char*)data,width,height); delete[] ndata; }
07038 } break;
07039 case 16: {
07040 unsigned short *const ndata = (img.width==width && img.height==height)?(unsigned short*)data:new unsigned short[img.width*img.height];
07041 unsigned char *ptrd = (unsigned char*)ndata;
07042 const unsigned int M = 248;
07043 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
07044 const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2;
07045 *(ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm)&M | (G>>3);
07046 *(ptrd++) = (G<<5) | ((unsigned char)(255*(*(data3++)-min)/mm)>>3);
07047 } else for (unsigned int xy=0; xy<xymax; ++xy) {
07048 const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2;
07049 *(ptrd++) = (G<<5) | ((unsigned char)(255*(*(data3++)-min)/mm)>>3);
07050 *(ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm)&M | (G>>3);
07051 }
07052 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned short*)data,width,height); delete[] ndata; }
07053 } break;
07054 default: {
07055 unsigned int *const ndata = (img.width==width && img.height==height)?(unsigned int*)data:new unsigned int[img.width*img.height];
07056 unsigned char *ptrd = (unsigned char*)ndata;
07057 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
07058 (*ptrd++) = 0;
07059 (*ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm);
07060 (*ptrd++) = (unsigned char)(255*(*(data2++)-min)/mm);
07061 (*ptrd++) = (unsigned char)(255*(*(data3++)-min)/mm);
07062 } else for (unsigned int xy=0; xy<xymax; ++xy) {
07063 (*ptrd++) = (unsigned char)(255*(*(data3++)-min)/mm);
07064 (*ptrd++) = (unsigned char)(255*(*(data2++)-min)/mm);
07065 (*ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm);
07066 (*ptrd++) = 0;
07067 }
07068 if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned int*)data,width,height); delete[] ndata; }
07069 } break;
07070 }
07071 }
07072 pthread_mutex_unlock(cimg::X11attr().mutex);
07073 return *this;
07074 }
07075
07076 template<typename T> const CImgDisplay& snapshot(CImg<T>& img) const {
07077 if (is_empty()) img.assign();
07078 else {
07079 img.assign(width,height,1,3);
07080 const unsigned int xymax = width*height;
07081 T
07082 *data1 = img.ptr(0,0,0,0),
07083 *data2 = img.ptr(0,0,0,1),
07084 *data3 = img.ptr(0,0,0,2);
07085 if (cimg::X11attr().blue_first) cimg::swap(data1,data3);
07086 switch (cimg::X11attr().nb_bits) {
07087 case 8: {
07088 unsigned char *ptrs = (unsigned char*)data;
07089 for (unsigned int xy=0; xy<xymax; ++xy) {
07090 const unsigned char val = *(ptrs++);
07091 *(data1++) = val&0xe0;
07092 *(data2++) = (val&0x1c)<<3;
07093 *(data3++) = val<<6;
07094 }
07095 } break;
07096 case 16: {
07097 unsigned char *ptrs = (unsigned char*)data;
07098 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
07099 const unsigned char val0 = *(ptrs++), val1 = *(ptrs++);
07100 *(data1++) = val0&0xf8;
07101 *(data2++) = (val0<<5) | ((val1&0xe0)>>5);
07102 *(data3++) = val1<<3;
07103 } else for (unsigned int xy=0; xy<xymax; ++xy) {
07104 const unsigned short val0 = *(ptrs++), val1 = *(ptrs++);
07105 *(data1++) = val1&0xf8;
07106 *(data2++) = (val1<<5) | ((val0&0xe0)>>5);
07107 *(data3++) = val0<<3;
07108 }
07109 } break;
07110 default: {
07111 unsigned char *ptrs = (unsigned char*)data;
07112 if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; ++xy) {
07113 ++ptrs;
07114 *(data1++) = *(ptrs++);
07115 *(data2++) = *(ptrs++);
07116 *(data3++) = *(ptrs++);
07117 } else for (unsigned int xy=0; xy<xymax; ++xy) {
07118 *(data3++) = *(ptrs++);
07119 *(data2++) = *(ptrs++);
07120 *(data1++) = *(ptrs++);
07121 ++ptrs;
07122 }
07123 } break;
07124 }
07125 }
07126 return *this;
07127 }
07128
07129 static int _assign_xshm(Display *dpy, XErrorEvent *error) {
07130 dpy = 0; error = 0;
07131 cimg::X11attr().shm_enabled = false;
07132 return 0;
07133 }
07134
07135 void _assign(const unsigned int dimw, const unsigned int dimh, const char *ptitle=0,
07136 const unsigned int normalization_type=3, const unsigned int events_type=3,
07137 const bool fullscreen_flag=false, const bool closed_flag=false) {
07138
07139
07140 const int s = cimg::strlen(ptitle)+1;
07141 char *tmp_title = s?new char[s]:0;
07142 if (s) std::memcpy(tmp_title,ptitle,s*sizeof(char));
07143
07144
07145 if (!is_empty()) assign();
07146
07147
07148 if (!cimg::X11attr().display) {
07149 cimg::X11attr().nb_wins = 0;
07150 cimg::X11attr().mutex = new pthread_mutex_t;
07151 pthread_mutex_init(cimg::X11attr().mutex,0);
07152
07153 cimg::X11attr().display = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0"));
07154 if (!cimg::X11attr().display)
07155 throw CImgDisplayException("CImgDisplay::_create_window() : Can't open X11 display");
07156 cimg::X11attr().nb_bits = DefaultDepth(cimg::X11attr().display, DefaultScreen(cimg::X11attr().display));
07157 if (cimg::X11attr().nb_bits!=8 && cimg::X11attr().nb_bits!=16 && cimg::X11attr().nb_bits!=24 && cimg::X11attr().nb_bits!=32)
07158 throw CImgDisplayException("CImgDisplay::_create_window() : %u bits mode is not supported "
07159 "(only 8, 16, 24 and 32 bits modes are supported)",cimg::X11attr().nb_bits);
07160 cimg::X11attr().gc = new GC;
07161 *cimg::X11attr().gc = DefaultGC(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
07162 Visual *visual = DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
07163 XVisualInfo vtemplate;
07164 vtemplate.visualid = XVisualIDFromVisual(visual);
07165 int nb_visuals;
07166 XVisualInfo *vinfo = XGetVisualInfo(cimg::X11attr().display,VisualIDMask,&vtemplate,&nb_visuals);
07167 if (vinfo && vinfo->red_mask<vinfo->blue_mask) cimg::X11attr().blue_first = true;
07168 cimg::X11attr().byte_order = ImageByteOrder(cimg::X11attr().display);
07169 XFree(vinfo);
07170 pthread_mutex_lock(cimg::X11attr().mutex);
07171 cimg::X11attr().event_thread = new pthread_t;
07172 pthread_create(cimg::X11attr().event_thread,0,_events_thread,0);
07173 } else pthread_mutex_lock(cimg::X11attr().mutex);
07174
07175
07176 width = cimg::min(dimw,(unsigned int)screen_dimx());
07177 height = cimg::min(dimh,(unsigned int)screen_dimy());
07178 normalization = normalization_type%4;
07179 events = events_type%4;
07180 is_fullscreen = fullscreen_flag;
07181 title = tmp_title;
07182 window_x = window_y = wheel = 0;
07183 mouse_x = mouse_y = -1;
07184 std::memset((void*)buttons,0,512*sizeof(unsigned int));
07185 std::memset((void*)keys,0,512*sizeof(unsigned int));
07186 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
07187 is_resized = is_moved = is_event = false;
07188 is_closed = closed_flag;
07189 fps_timer = fps_frames = timer = 0;
07190 fps_fps = 0;
07191
07192
07193 if (is_fullscreen) {
07194 _init_fullscreen();
07195 const unsigned int sx = screen_dimx(), sy = screen_dimy();
07196 XSetWindowAttributes winattr;
07197 winattr.override_redirect = True;
07198 window = XCreateWindow(cimg::X11attr().display,
07199 RootWindow(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07200 (sx-width)/2,(sy-height)/2,
07201 width,height,0,0,InputOutput,CopyFromParent,CWOverrideRedirect,&winattr);
07202 } else
07203 window = XCreateSimpleWindow(cimg::X11attr().display,
07204 RootWindow(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07205 0,0,width,height,2,0,0x0L);
07206 XStoreName(cimg::X11attr().display,window,title?title:" ");
07207 if (cimg::X11attr().nb_bits==8) {
07208 colormap = XCreateColormap(cimg::X11attr().display,window,DefaultVisual(cimg::X11attr().display,
07209 DefaultScreen(cimg::X11attr().display)),AllocAll);
07210 _set_colormap(colormap,3);
07211 XSetWindowColormap(cimg::X11attr().display,window,colormap);
07212 }
07213 window_width = width;
07214 window_height = height;
07215
07216
07217 const unsigned int bufsize = width*height*(cimg::X11attr().nb_bits==8?1:(cimg::X11attr().nb_bits==16?2:4));
07218 #ifdef cimg_use_xshm
07219 shminfo = 0;
07220 if (XShmQueryExtension(cimg::X11attr().display)) {
07221 shminfo = new XShmSegmentInfo;
07222 image = XShmCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07223 cimg::X11attr().nb_bits,ZPixmap,0,shminfo,width,height);
07224 if (!image) {
07225 delete shminfo;
07226 shminfo = 0;
07227 } else {
07228 shminfo->shmid = shmget(IPC_PRIVATE, bufsize, IPC_CREAT | 0777);
07229 if (shminfo->shmid==-1) {
07230 XDestroyImage(image);
07231 delete shminfo;
07232 shminfo = 0;
07233 } else {
07234 shminfo->shmaddr = image->data = (char*)(data = shmat(shminfo->shmid,0,0));
07235 if (shminfo->shmaddr==(char*)-1) {
07236 shmctl(shminfo->shmid,IPC_RMID,0);
07237 XDestroyImage(image);
07238 delete shminfo;
07239 shminfo = 0;
07240 } else {
07241 shminfo->readOnly = False;
07242 cimg::X11attr().shm_enabled = true;
07243 XErrorHandler oldXErrorHandler = XSetErrorHandler(_assign_xshm);
07244 XShmAttach(cimg::X11attr().display, shminfo);
07245 XSync(cimg::X11attr().display, False);
07246 XSetErrorHandler(oldXErrorHandler);
07247 if (!cimg::X11attr().shm_enabled) {
07248 shmdt(shminfo->shmaddr);
07249 shmctl(shminfo->shmid,IPC_RMID,0);
07250 XDestroyImage(image);
07251 delete shminfo;
07252 shminfo = 0;
07253 }
07254 }
07255 }
07256 }
07257 }
07258 if (!shminfo)
07259 #endif
07260 {
07261 data = std::malloc(bufsize);
07262 image = XCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07263 cimg::X11attr().nb_bits,ZPixmap,0,(char*)data,width,height,8,0);
07264 }
07265
07266 if (!is_closed) _map_window(); else { window_x = window_y = cimg::type<int>::min(); }
07267
07268 if (events) {
07269 wm_delete_window = XInternAtom(cimg::X11attr().display, "WM_DELETE_WINDOW", False);
07270 wm_delete_protocol = XInternAtom(cimg::X11attr().display, "WM_PROTOCOLS", False);
07271 XSetWMProtocols(cimg::X11attr().display, window, &wm_delete_window, 1);
07272 if (is_fullscreen) XGrabKeyboard(cimg::X11attr().display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
07273 }
07274 cimg::X11attr().wins[cimg::X11attr().nb_wins++]=this;
07275 pthread_mutex_unlock(cimg::X11attr().mutex);
07276 }
07277
07278 void _map_window() {
07279 XWindowAttributes attr;
07280 XEvent event;
07281 XSelectInput(cimg::X11attr().display,window,ExposureMask | StructureNotifyMask);
07282 bool exposed = false, mapped = false;
07283 XMapRaised(cimg::X11attr().display,window);
07284 XSync(cimg::X11attr().display,False);
07285 do {
07286 XWindowEvent(cimg::X11attr().display,window,StructureNotifyMask | ExposureMask,&event);
07287 switch (event.type) {
07288 case MapNotify: mapped = true; break;
07289 case Expose: exposed = true; break;
07290 default: XSync(cimg::X11attr().display, False); cimg::sleep(10);
07291 }
07292 } while (!(exposed && mapped));
07293 do {
07294 XGetWindowAttributes(cimg::X11attr().display, window, &attr);
07295 if (attr.map_state!=IsViewable) { XSync(cimg::X11attr().display,False); cimg::sleep(10); }
07296 } while (attr.map_state != IsViewable);
07297 window_x = attr.x;
07298 window_y = attr.y;
07299 }
07300
07301 void _set_colormap(Colormap& colormap, const unsigned int dim) {
07302 XColor palette[256];
07303 switch (dim) {
07304 case 1:
07305 for (unsigned int index=0; index<256; ++index) {
07306 palette[index].pixel = index;
07307 palette[index].red = palette[index].green = palette[index].blue = (unsigned short)(index<<8);
07308 palette[index].flags = DoRed | DoGreen | DoBlue;
07309 }
07310 break;
07311 case 2:
07312 for (unsigned int index=0, r=8; r<256; r+=16)
07313 for (unsigned int g=8; g<256; g+=16) {
07314 palette[index].pixel = index;
07315 palette[index].red = palette[index].blue = (unsigned short)(r<<8);
07316 palette[index].green = (unsigned short)(g<<8);
07317 palette[index++].flags = DoRed | DoGreen | DoBlue;
07318 }
07319 break;
07320 default:
07321 for (unsigned int index=0, r=16; r<256; r+=32)
07322 for (unsigned int g=16; g<256; g+=32)
07323 for (unsigned int b=32; b<256; b+=64) {
07324 palette[index].pixel = index;
07325 palette[index].red = (unsigned short)(r<<8);
07326 palette[index].green = (unsigned short)(g<<8);
07327 palette[index].blue = (unsigned short)(b<<8);
07328 palette[index++].flags = DoRed | DoGreen | DoBlue;
07329 }
07330 break;
07331 }
07332 XStoreColors(cimg::X11attr().display,colormap,palette,256);
07333 }
07334
07335 void _paint(const bool wait_expose=true) {
07336 if (!is_closed) {
07337 if (wait_expose) {
07338 static XEvent event;
07339 event.xexpose.type = Expose;
07340 event.xexpose.serial = 0;
07341 event.xexpose.send_event = True;
07342 event.xexpose.display = cimg::X11attr().display;
07343 event.xexpose.window = window;
07344 event.xexpose.x = 0;
07345 event.xexpose.y = 0;
07346 event.xexpose.width = dimx();
07347 event.xexpose.height = dimy();
07348 event.xexpose.count = 0;
07349 XSendEvent(cimg::X11attr().display, window, False, 0, &event);
07350 } else {
07351 #ifdef cimg_use_xshm
07352 if (shminfo) XShmPutImage(cimg::X11attr().display,window,*cimg::X11attr().gc,image,0,0,0,0,width,height,False);
07353 else
07354 #endif
07355 XPutImage(cimg::X11attr().display,window,*cimg::X11attr().gc,image,0,0,0,0,width,height);
07356 XSync(cimg::X11attr().display, False);
07357 }
07358 }
07359 }
07360
07361 template<typename T> void _resize(T foo, const unsigned int ndimx, const unsigned int ndimy, const bool redraw) {
07362 foo = 0;
07363 #ifdef cimg_use_xshm
07364 if (shminfo) {
07365 XShmSegmentInfo *nshminfo = new XShmSegmentInfo;
07366 XImage *nimage = XShmCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07367 cimg::X11attr().nb_bits,ZPixmap,0,nshminfo,ndimx,ndimy);
07368 if (!nimage) {
07369 delete nshminfo;
07370 return;
07371 } else {
07372 nshminfo->shmid = shmget(IPC_PRIVATE, ndimx*ndimy*sizeof(T), IPC_CREAT | 0777);
07373 if (nshminfo->shmid==-1) {
07374 XDestroyImage(nimage);
07375 delete nshminfo;
07376 return;
07377 } else {
07378 nshminfo->shmaddr = nimage->data = (char*)shmat(nshminfo->shmid,0,0);
07379 if (nshminfo->shmaddr==(char*)-1) {
07380 shmctl(nshminfo->shmid,IPC_RMID,0);
07381 XDestroyImage(nimage);
07382 delete nshminfo;
07383 return;
07384 } else {
07385 nshminfo->readOnly = False;
07386 cimg::X11attr().shm_enabled = true;
07387 XErrorHandler oldXErrorHandler = XSetErrorHandler(_assign_xshm);
07388 XShmAttach(cimg::X11attr().display, nshminfo);
07389 XSync(cimg::X11attr().display, False);
07390 XSetErrorHandler(oldXErrorHandler);
07391 if (!cimg::X11attr().shm_enabled) {
07392 shmdt(nshminfo->shmaddr);
07393 shmctl(nshminfo->shmid,IPC_RMID,0);
07394 XDestroyImage(nimage);
07395 delete nshminfo;
07396 return;
07397 } else {
07398 T *const ndata = (T*)nimage->data;
07399 if (redraw) _render_resize((T*)data,width,height,ndata,ndimx,ndimy);
07400 else std::memset(ndata,0,sizeof(T)*ndimx*ndimy);
07401 XShmDetach(cimg::X11attr().display, shminfo);
07402 XDestroyImage(image);
07403 shmdt(shminfo->shmaddr);
07404 shmctl(shminfo->shmid,IPC_RMID,0);
07405 delete shminfo;
07406 shminfo = nshminfo;
07407 image = nimage;
07408 data = (void*)ndata;
07409 }
07410 }
07411 }
07412 }
07413 } else
07414 #endif
07415 {
07416 T *ndata = (T*)std::malloc(ndimx*ndimy*sizeof(T));
07417 if (redraw) _render_resize((T*)data,width,height,ndata,ndimx,ndimy);
07418 else std::memset(ndata,0,sizeof(T)*ndimx*ndimy);
07419 data = (void*)ndata;
07420 XDestroyImage(image);
07421 image = XCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07422 cimg::X11attr().nb_bits,ZPixmap,0,(char*)data,ndimx,ndimy,8,0);
07423 }
07424 }
07425
07426 void _init_fullscreen() {
07427 background_window = 0;
07428 if (is_fullscreen && !is_closed) {
07429 #ifdef cimg_use_xrandr
07430 int foo;
07431 if (XRRQueryExtension(cimg::X11attr().display,&foo,&foo)) {
07432 XRRRotations(cimg::X11attr().display, DefaultScreen(cimg::X11attr().display), &cimg::X11attr().curr_rotation);
07433 if (!cimg::X11attr().resolutions) {
07434 cimg::X11attr().resolutions = XRRSizes(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display),&foo);
07435 cimg::X11attr().nb_resolutions = (unsigned int)foo;
07436 }
07437 if (cimg::X11attr().resolutions) {
07438 cimg::X11attr().curr_resolution = 0;
07439 for (unsigned int i=0; i<cimg::X11attr().nb_resolutions; ++i) {
07440 const unsigned int
07441 nw = (unsigned int)(cimg::X11attr().resolutions[i].width),
07442 nh = (unsigned int)(cimg::X11attr().resolutions[i].height);
07443 if (nw>=width && nh>=height &&
07444 nw<=(unsigned int)(cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].width) &&
07445 nh<=(unsigned int)(cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].height))
07446 cimg::X11attr().curr_resolution = i;
07447 }
07448 if (cimg::X11attr().curr_resolution>0) {
07449 XRRScreenConfiguration *config = XRRGetScreenInfo(cimg::X11attr().display, DefaultRootWindow(cimg::X11attr().display));
07450 XRRSetScreenConfig(cimg::X11attr().display, config, DefaultRootWindow(cimg::X11attr().display),
07451 cimg::X11attr().curr_resolution, cimg::X11attr().curr_rotation, CurrentTime);
07452 XRRFreeScreenConfigInfo(config);
07453 XSync(cimg::X11attr().display, False);
07454 }
07455 }
07456 }
07457 if (!cimg::X11attr().resolutions) cimg::warn("CImgDisplay::_create_window() : Xrandr extension is not supported by the X server.");
07458 #endif
07459 const unsigned int sx = screen_dimx(), sy = screen_dimy();
07460 XSetWindowAttributes winattr;
07461 winattr.override_redirect = True;
07462 if (sx!=width || sy!=height) {
07463 background_window = XCreateWindow(cimg::X11attr().display,
07464 RootWindow(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),0,0,
07465 sx,sy,0,0,InputOutput,CopyFromParent,CWOverrideRedirect,&winattr);
07466 const unsigned int bufsize = sx*sy*(cimg::X11attr().nb_bits==8?1:(cimg::X11attr().nb_bits==16?2:4));
07467 void *background_data = std::malloc(bufsize);
07468 std::memset(background_data,0,bufsize);
07469 XImage *background_image = XCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
07470 cimg::X11attr().nb_bits,ZPixmap,0,(char*)background_data,sx,sy,8,0);
07471 XEvent event;
07472 XSelectInput(cimg::X11attr().display,background_window,StructureNotifyMask);
07473 XMapRaised(cimg::X11attr().display,background_window);
07474 do XWindowEvent(cimg::X11attr().display,background_window,StructureNotifyMask,&event);
07475 while (event.type!=MapNotify);
07476 #ifdef cimg_use_xshm
07477 if (shminfo) XShmPutImage(cimg::X11attr().display,background_window,*cimg::X11attr().gc,background_image,0,0,0,0,sx,sy,False);
07478 else
07479 #endif
07480 XPutImage(cimg::X11attr().display,background_window,*cimg::X11attr().gc,background_image,0,0,0,0,sx,sy);
07481 XWindowAttributes attr;
07482 XGetWindowAttributes(cimg::X11attr().display, background_window, &attr);
07483 while (attr.map_state != IsViewable) XSync(cimg::X11attr().display, False);
07484 XDestroyImage(background_image);
07485 }
07486 }
07487 }
07488
07489 void _desinit_fullscreen() {
07490 if (is_fullscreen) {
07491 XUngrabKeyboard(cimg::X11attr().display,CurrentTime);
07492 #ifdef cimg_use_xrandr
07493 if (cimg::X11attr().resolutions && cimg::X11attr().curr_resolution) {
07494 XRRScreenConfiguration *config = XRRGetScreenInfo(cimg::X11attr().display, DefaultRootWindow(cimg::X11attr().display));
07495 XRRSetScreenConfig(cimg::X11attr().display, config, DefaultRootWindow(cimg::X11attr().display),
07496 0, cimg::X11attr().curr_rotation, CurrentTime);
07497 XRRFreeScreenConfigInfo(config);
07498 XSync(cimg::X11attr().display, False);
07499 cimg::X11attr().curr_resolution = 0;
07500 }
07501 #endif
07502 if (background_window) XDestroyWindow(cimg::X11attr().display,background_window);
07503 background_window = 0;
07504 is_fullscreen = false;
07505 }
07506 }
07507
07508 void _handle_events(const XEvent *const pevent) {
07509 XEvent event=*pevent;
07510 switch (event.type) {
07511 case ClientMessage:
07512 if ((int)event.xclient.message_type==(int)wm_delete_protocol &&
07513 (int)event.xclient.data.l[0]==(int)wm_delete_window) {
07514 XUnmapWindow(cimg::X11attr().display,window);
07515 mouse_x = mouse_y = -1;
07516 if (button) {
07517 std::memmove((void*)(buttons+1),(void*)buttons,512-1);
07518 button = 0;
07519 }
07520 if (key) {
07521 std::memmove((void*)(keys+1),(void*)keys,512-1);
07522 key = 0;
07523 }
07524 if (released_key) {
07525 std::memmove((void*)(released_keys+1),(void*)released_keys,512-1);
07526 released_key = 0;
07527 }
07528 is_closed = is_event = true;
07529 }
07530 break;
07531 case ConfigureNotify: {
07532 while (XCheckWindowEvent(cimg::X11attr().display,window,StructureNotifyMask,&event));
07533 const unsigned int
07534 nw = event.xconfigure.width,
07535 nh = event.xconfigure.height;
07536 const int
07537 nx = event.xconfigure.x,
07538 ny = event.xconfigure.y;
07539 if (nw && nh && (nw!=window_width || nh!=window_height)) {
07540 window_width = nw;
07541 window_height = nh;
07542 mouse_x = mouse_y = -1;
07543 XResizeWindow(cimg::X11attr().display,window,window_width,window_height);
07544 is_resized = is_event = true;
07545 }
07546 if (nx!=window_x || ny!=window_y) {
07547 window_x = nx;
07548 window_y = ny;
07549 is_moved = is_event = true;
07550 }
07551 } break;
07552 case Expose: {
07553 while (XCheckWindowEvent(cimg::X11attr().display,window,ExposureMask,&event));
07554 _paint(false);
07555 if (is_fullscreen) {
07556 XWindowAttributes attr;
07557 XGetWindowAttributes(cimg::X11attr().display, window, &attr);
07558 while (attr.map_state != IsViewable) XSync(cimg::X11attr().display, False);
07559 XSetInputFocus(cimg::X11attr().display, window, RevertToParent, CurrentTime);
07560 }
07561 } break;
07562 case ButtonPress: {
07563 do {
07564 switch (event.xbutton.button) {
07565 case 1: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button|=1; is_event = true; break;
07566 case 2: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button|=4; is_event = true; break;
07567 case 3: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button|=2; is_event = true; break;
07568 default: break;
07569 }
07570 } while (XCheckWindowEvent(cimg::X11attr().display,window,ButtonPressMask,&event));
07571 } break;
07572 case ButtonRelease: {
07573 do {
07574 switch (event.xbutton.button) {
07575 case 1: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button&=~1U; is_event = true; break;
07576 case 2: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button&=~4U; is_event = true; break;
07577 case 3: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button&=~2U; is_event = true; break;
07578 case 4: ++wheel; is_event = true; break;
07579 case 5: --wheel; is_event = true; break;
07580 default: break;
07581 }
07582 } while (XCheckWindowEvent(cimg::X11attr().display,window,ButtonReleaseMask,&event));
07583 } break;
07584 case KeyPress: {
07585 char tmp;
07586 KeySym ksym;
07587 XLookupString(&event.xkey,&tmp,1,&ksym,0);
07588 if (key) std::memmove((void*)(keys+1),(void*)keys,512-1);
07589 key = (unsigned int)ksym;
07590 if (released_key) {
07591 std::memmove((void*)(released_keys+1),(void*)released_keys,512-1);
07592 released_key = 0;
07593 }
07594 is_event = true;
07595 } break;
07596 case KeyRelease: {
07597 char tmp;
07598 KeySym ksym;
07599 XLookupString(&event.xkey,&tmp,1,&ksym,0);
07600 if (key) {
07601 std::memmove((void*)(keys+1),(void*)keys,512-1);
07602 key = 0;
07603 }
07604 if (released_key) std::memmove((void*)(released_keys+1),(void*)released_keys,512-1);
07605 released_key = (unsigned int)ksym;
07606 is_event = true;
07607 } break;
07608 case LeaveNotify:
07609 while (XCheckWindowEvent(cimg::X11attr().display,window,LeaveWindowMask,&event));
07610 mouse_x = mouse_y =-1;
07611 is_event = true;
07612 break;
07613 case MotionNotify:
07614 while (XCheckWindowEvent(cimg::X11attr().display,window,PointerMotionMask,&event));
07615 mouse_x = event.xmotion.x;
07616 mouse_y = event.xmotion.y;
07617 if (mouse_x<0 || mouse_y<0 || mouse_x>=dimx() || mouse_y>=dimy()) mouse_x = mouse_y = -1;
07618 is_event = true;
07619 break;
07620 }
07621 }
07622
07623 static void* _events_thread(void *arg) {
07624 arg = 0;
07625 XEvent event;
07626 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,0);
07627 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
07628 for (;;) {
07629 pthread_mutex_lock(cimg::X11attr().mutex);
07630 for (unsigned int i=0; i<cimg::X11attr().nb_wins; ++i) {
07631 const unsigned int xevent_type = (cimg::X11attr().wins[i]->events)&3;
07632 const unsigned int emask =
07633 ((xevent_type>=1)?ExposureMask|StructureNotifyMask:0)|
07634 ((xevent_type>=2)?ButtonPressMask|KeyPressMask|PointerMotionMask|LeaveWindowMask:0)|
07635 ((xevent_type>=3)?ButtonReleaseMask|KeyReleaseMask:0);
07636 XSelectInput(cimg::X11attr().display,cimg::X11attr().wins[i]->window,emask);
07637 }
07638 bool event_flag = XCheckTypedEvent(cimg::X11attr().display, ClientMessage, &event);
07639 if (!event_flag) event_flag = XCheckMaskEvent(cimg::X11attr().display,
07640 ExposureMask|StructureNotifyMask|ButtonPressMask|
07641 KeyPressMask|PointerMotionMask|LeaveWindowMask|ButtonReleaseMask|
07642 KeyReleaseMask,&event);
07643 if (event_flag) {
07644 for (unsigned int i=0; i<cimg::X11attr().nb_wins; ++i)
07645 if (!cimg::X11attr().wins[i]->is_closed && event.xany.window==cimg::X11attr().wins[i]->window)
07646 cimg::X11attr().wins[i]->_handle_events(&event);
07647 }
07648 pthread_mutex_unlock(cimg::X11attr().mutex);
07649 pthread_testcancel();
07650 cimg::sleep(7);
07651 }
07652 return 0;
07653 }
07654
07655
07656
07657 #elif cimg_display_type==2
07658 CLIENTCREATESTRUCT ccs;
07659 BITMAPINFO bmi;
07660 unsigned int *data;
07661 DEVMODE curr_mode;
07662 HWND window;
07663 HWND background_window;
07664 HDC hdc;
07665 HANDLE thread;
07666 HANDLE created;
07667 HANDLE mutex;
07668 bool visible_cursor;
07669
07670 static int screen_dimx() {
07671 DEVMODE mode;
07672 mode.dmSize = sizeof(DEVMODE);
07673 mode.dmDriverExtra = 0;
07674 EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode);
07675 return mode.dmPelsWidth;
07676 }
07677
07678 static int screen_dimy() {
07679 DEVMODE mode;
07680 mode.dmSize = sizeof(DEVMODE);
07681 mode.dmDriverExtra = 0;
07682 EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode);
07683 return mode.dmPelsHeight;
07684 }
07685
07686 CImgDisplay& assign() {
07687 if (!is_empty()) {
07688 DestroyWindow(window);
07689 if (events) TerminateThread(thread,0);
07690 if (data) delete[] data;
07691 if (title) delete[] title;
07692 if (is_fullscreen) _desinit_fullscreen();
07693 width = height = normalization = events = 0;
07694 is_fullscreen = is_resized = is_moved = is_event = false;
07695 is_closed = true;
07696 title = 0;
07697 window_x = window_y = window_width = window_height = mouse_x = mouse_y = wheel = 0;
07698 std::memset((void*)buttons,0,512*sizeof(unsigned int));
07699 std::memset((void*)keys,0,512*sizeof(unsigned int));
07700 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
07701 min = max = 0;
07702 }
07703 return *this;
07704 }
07705
07706 CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0,
07707 const unsigned int normalization_type=3, const unsigned int events_type=3,
07708 const bool fullscreen_flag=false, const bool closed_flag=false) {
07709 if (!dimw || !dimh) return assign();
07710 _assign(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag);
07711 min = max = 0;
07712 std::memset(data,0,sizeof(unsigned int)*width*height);
07713 return paint();
07714 }
07715
07716 template<typename T> CImgDisplay& assign(const CImg<T>& img, const char *title=0,
07717 const unsigned int normalization_type=3, const unsigned int events_type=3,
07718 const bool fullscreen_flag=false, const bool closed_flag=false) {
07719 if (!img) return assign();
07720 CImg<T> tmp;
07721 const CImg<T>& nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
07722 _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
07723 if (normalization==2) min = (float)nimg.minmax(max);
07724 return display(nimg);
07725 }
07726
07727 template<typename T> CImgDisplay& assign(const CImgList<T>& list, const char *title=0,
07728 const unsigned int normalization_type=3, const unsigned int events_type=3,
07729 const bool fullscreen_flag=false, const bool closed_flag=false) {
07730 if (!list) return assign();
07731 CImg<T> tmp;
07732 const CImg<T> img = list.get_append('x','p'),
07733 &nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
07734 _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
07735 if (normalization==2) min = (float)nimg.minmax(max);
07736 return display(nimg);
07737 }
07738
07739 CImgDisplay& assign(const CImgDisplay& win) {
07740 if (!win) return assign();
07741 _assign(win.width,win.height,win.title,win.normalization,win.events,win.is_fullscreen,win.is_closed);
07742 std::memcpy(data,win.data,sizeof(unsigned int)*width*height);
07743 return paint();
07744 }
07745
07746 template<typename T> CImgDisplay& display(const CImg<T>& img) {
07747 if (is_empty()) assign(img.width,img.height);
07748 return render(img).paint();
07749 }
07750
07751 CImgDisplay& resize(const int nwidth, const int nheight, const bool redraw=true) {
07752 if (!nwidth || !nheight) return assign();
07753 if (is_empty()) return assign(cimg::max(nwidth,0),cimg::max(nheight,0));
07754 const unsigned int
07755 tmpdimx=(nwidth>0)?nwidth:(-nwidth*width/100),
07756 tmpdimy=(nheight>0)?nheight:(-nheight*height/100),
07757 dimx = cimg::min(tmpdimx?tmpdimx:1,(unsigned int)screen_dimx()),
07758 dimy = cimg::min(tmpdimy?tmpdimy:1,(unsigned int)screen_dimy());
07759 const bool
07760 is_disp_different = (width!=dimx || height!=dimy),
07761 is_win_different = (window_width!=dimx || window_height!=dimy);
07762
07763 if (is_disp_different || is_win_different) {
07764 RECT rect; rect.left = rect.top = 0; rect.right = dimx-1; rect.bottom = dimy-1;
07765 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
07766 const int cwidth = rect.right-rect.left+1, cheight = rect.bottom-rect.top+1;
07767 SetWindowPos(window,0,0,0,cwidth,cheight,SWP_NOMOVE | SWP_NOZORDER | SWP_NOCOPYBITS);
07768 window_width = dimx;
07769 window_height = dimy;
07770 is_resized = false;
07771 if (is_disp_different) {
07772 unsigned int *ndata = new unsigned int[dimx*dimy];
07773 if (redraw) _render_resize(data,width,height,ndata,dimx,dimy);
07774 else std::memset(ndata,0x80,sizeof(unsigned int)*dimx*dimy);
07775 delete[] data;
07776 data = ndata;
07777 bmi.bmiHeader.biWidth = dimx;
07778 bmi.bmiHeader.biHeight = -(int)dimy;
07779 width = dimx;
07780 height = dimy;
07781 }
07782 if (is_fullscreen) move((screen_dimx()-width)/2,(screen_dimy()-height)/2);
07783 if (redraw) return paint();
07784 }
07785 return *this;
07786 }
07787
07788 CImgDisplay& move(const int posx, const int posy) {
07789 if (is_empty()) return *this;
07790 if (!is_fullscreen) {
07791 RECT rect; rect.left = rect.top = 0; rect.right=window_width-1; rect.bottom=window_height-1;
07792 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
07793 const int border1 = (rect.right-rect.left+1-width)/2, border2 = rect.bottom-rect.top+1-height-border1;
07794 SetWindowPos(window,0,posx-border1,posy-border2,0,0,SWP_NOSIZE | SWP_NOZORDER);
07795 } else SetWindowPos(window,0,posx,posy,0,0,SWP_NOSIZE | SWP_NOZORDER);
07796 window_x = posx;
07797 window_y = posy;
07798 is_moved = false;
07799 return show();
07800 }
07801
07802 CImgDisplay& set_mouse(const int posx, const int posy) {
07803 if (!is_closed && posx>=0 && posy>=0) {
07804 _update_window_pos();
07805 const int res = (int)SetCursorPos(window_x+posx,window_y+posy);
07806 if (res) { mouse_x = posx; mouse_y = posy; }
07807 }
07808 return *this;
07809 }
07810
07811 CImgDisplay& hide_mouse() {
07812 if (is_empty()) return *this;
07813 visible_cursor = false;
07814 ShowCursor(FALSE);
07815 SendMessage(window,WM_SETCURSOR,0,0);
07816 return *this;
07817 }
07818
07819 CImgDisplay& show_mouse() {
07820 if (is_empty()) return *this;
07821 visible_cursor = true;
07822 ShowCursor(TRUE);
07823 SendMessage(window,WM_SETCURSOR,0,0);
07824 return *this;
07825 }
07826
07827 static void wait_all() {
07828 WaitForSingleObject(cimg::Win32attr().wait_event,INFINITE);
07829 }
07830
07831 CImgDisplay& show() {
07832 if (is_empty()) return *this;
07833 if (is_closed) {
07834 is_closed = false;
07835 if (is_fullscreen) _init_fullscreen();
07836 ShowWindow(window,SW_SHOW);
07837 _update_window_pos();
07838 }
07839 return paint();
07840 }
07841
07842 CImgDisplay& close() {
07843 if (is_empty()) return *this;
07844 if (!is_closed && !is_fullscreen) {
07845 if (is_fullscreen) _desinit_fullscreen();
07846 ShowWindow(window,SW_HIDE);
07847 is_closed = true;
07848 window_x = window_y = 0;
07849 }
07850 return *this;
07851 }
07852
07853 CImgDisplay& set_title(const char *format, ...) {
07854 if (is_empty()) return *this;
07855 char tmp[1024] = {0};
07856 va_list ap;
07857 va_start(ap, format);
07858 std::vsprintf(tmp,format,ap);
07859 va_end(ap);
07860 if (title) delete[] title;
07861 const int s = cimg::strlen(tmp)+1;
07862 title = new char[s];
07863 std::memcpy(title,tmp,s*sizeof(char));
07864 SetWindowTextA(window, tmp);
07865 return *this;
07866 }
07867
07868 CImgDisplay& paint() {
07869 if (!is_closed) {
07870 WaitForSingleObject(mutex,INFINITE);
07871 SetDIBitsToDevice(hdc,0,0,width,height,0,0,0,height,data,&bmi,DIB_RGB_COLORS);
07872 ReleaseMutex(mutex);
07873 }
07874 return *this;
07875 }
07876
07877 template<typename T> CImgDisplay& render(const CImg<T>& img) {
07878 if (is_empty()) return *this;
07879 if (!img)
07880 throw CImgArgumentException("CImgDisplay::_render_image() : Specified input image (%u,%u,%u,%u,%p) is empty.",
07881 img.width,img.height,img.depth,img.dim,img.data);
07882 if (img.depth!=1) return render(img.get_projections2d(img.width/2,img.height/2,img.depth/2));
07883
07884 const T
07885 *data1 = img.data,
07886 *data2 = (img.dim>=2)?img.ptr(0,0,0,1):data1,
07887 *data3 = (img.dim>=3)?img.ptr(0,0,0,2):data1;
07888
07889 WaitForSingleObject(mutex,INFINITE);
07890 unsigned int
07891 *const ndata = (img.width==width && img.height==height)?data:new unsigned int[img.width*img.height],
07892 *ptrd = ndata;
07893
07894 if (!normalization || (normalization==3 && cimg::type<T>::string()==cimg::type<unsigned char>::string())) {
07895 min = max = 0;
07896 for (unsigned int xy = img.width*img.height; xy>0; --xy)
07897 *(ptrd++) = ((unsigned char)*(data1++)<<16) | ((unsigned char)*(data2++)<<8) | (unsigned char)*(data3++);
07898 } else {
07899 if (normalization==3) {
07900 if (cimg::type<T>::is_float()) min = (float)img.minmax(max);
07901 else { min = (float)cimg::type<T>::min(); max = (float)cimg::type<T>::max(); }
07902 } else if ((min>max) || normalization==1) min = (float)img.minmax(max);
07903 const float delta = max-min, mm = delta?delta:1.0f;
07904 for (unsigned int xy = img.width*img.height; xy>0; --xy) {
07905 const unsigned char
07906 R = (unsigned char)(255*(*(data1++)-min)/mm),
07907 G = (unsigned char)(255*(*(data2++)-min)/mm),
07908 B = (unsigned char)(255*(*(data3++)-min)/mm);
07909 *(ptrd++) = (R<<16) | (G<<8) | (B);
07910 }
07911 }
07912 if (ndata!=data) { _render_resize(ndata,img.width,img.height,data,width,height); delete[] ndata; }
07913 ReleaseMutex(mutex);
07914 return *this;
07915 }
07916
07917 template<typename T> const CImgDisplay& snapshot(CImg<T>& img) const {
07918 if (is_empty()) img.assign();
07919 else {
07920 img.assign(width,height,1,3);
07921 T
07922 *data1 = img.ptr(0,0,0,0),
07923 *data2 = img.ptr(0,0,0,1),
07924 *data3 = img.ptr(0,0,0,2);
07925 unsigned int *ptrs = data;
07926 for (unsigned int xy = img.width*img.height; xy>0; --xy) {
07927 const unsigned int val = *(ptrs++);
07928 *(data1++) = (unsigned char)(val>>16);
07929 *(data2++) = (unsigned char)((val>>8)&0xFF);
07930 *(data3++) = (unsigned char)(val&0xFF);
07931 }
07932 }
07933 return *this;
07934 }
07935
07936 CImgDisplay& _assign(const unsigned int dimw, const unsigned int dimh, const char *ptitle=0,
07937 const unsigned int normalization_type=3, const unsigned int events_type=3,
07938 const bool fullscreen_flag=false, const bool closed_flag=false) {
07939
07940
07941 const int s = cimg::strlen(ptitle)+1;
07942 char *tmp_title = s?new char[s]:0;
07943 if (s) std::memcpy(tmp_title,ptitle,s*sizeof(char));
07944
07945
07946 if (!is_empty()) assign();
07947
07948
07949 width = cimg::min(dimw,(unsigned int)screen_dimx());
07950 height = cimg::min(dimh,(unsigned int)screen_dimy());
07951 normalization = normalization_type%4;
07952 events = events_type%4;
07953 is_fullscreen = fullscreen_flag;
07954 title = tmp_title;
07955 window_x = window_y = wheel = 0;
07956 mouse_x = mouse_y = -1;
07957 std::memset((void*)buttons,0,512*sizeof(unsigned int));
07958 std::memset((void*)keys,0,512*sizeof(unsigned int));
07959 std::memset((void*)released_keys,0,512*sizeof(unsigned int));
07960 is_resized = is_moved = is_event = false;
07961 is_closed = closed_flag;
07962 fps_timer = fps_frames = timer = 0;
07963 fps_fps = 0;
07964 visible_cursor = true;
07965
07966 if (is_fullscreen) _init_fullscreen();
07967
07968
07969 void *arg = (void*)(new void*[2]);
07970 ((void**)arg)[0]=(void*)this;
07971 ((void**)arg)[1]=(void*)title;
07972 if (events) {
07973 unsigned long ThreadID = 0;
07974 mutex = CreateMutex(0,FALSE,0);
07975 created = CreateEvent(0,FALSE,FALSE,0);
07976 thread = CreateThread(0,0,_events_thread,arg,0,&ThreadID);
07977 WaitForSingleObject(created,INFINITE);
07978 } else _events_thread(arg);
07979
07980 return *this;
07981 }
07982
07983 static LRESULT APIENTRY _handle_events(HWND window,UINT msg,WPARAM wParam,LPARAM lParam) {
07984 #ifdef _WIN64
07985 CImgDisplay* disp = (CImgDisplay*)GetWindowLongPtr(window,GWLP_USERDATA);
07986 #else
07987 CImgDisplay* disp = (CImgDisplay*)GetWindowLong(window,GWL_USERDATA);
07988 #endif
07989 MSG st_msg;
07990
07991 switch(msg) {
07992 case WM_CLOSE:
07993 disp->mouse_x = disp->mouse_y = -1;
07994 disp->window_x = disp->window_y = 0;
07995 if (disp->button) {
07996 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
07997 disp->button = 0;
07998 }
07999 if (disp->key) {
08000 std::memmove((void*)(disp->keys+1),(void*)disp->keys,512-1);
08001 disp->key = 0;
08002 }
08003 if (disp->released_key) {
08004 std::memmove((void*)(disp->released_keys+1),(void*)disp->released_keys,512-1);
08005 disp->released_key = 0;
08006 }
08007 disp->is_closed = true;
08008 ReleaseMutex(disp->mutex);
08009 ShowWindow(disp->window,SW_HIDE);
08010 disp->is_event = true;
08011 SetEvent(cimg::Win32attr().wait_event);
08012 return 0;
08013 case WM_SIZE: {
08014 while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE));
08015 WaitForSingleObject(disp->mutex,INFINITE);
08016 const unsigned int nw = LOWORD(lParam),nh = HIWORD(lParam);
08017 if (nw && nh && (nw!=disp->width || nh!=disp->height)) {
08018 disp->window_width = nw;
08019 disp->window_height = nh;
08020 disp->mouse_x = disp->mouse_y = -1;
08021 disp->is_resized = disp->is_event = true;
08022 SetEvent(cimg::Win32attr().wait_event);
08023 }
08024 ReleaseMutex(disp->mutex);
08025 } break;
08026 case WM_MOVE: {
08027 while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE));
08028 WaitForSingleObject(disp->mutex,INFINITE);
08029 const int nx = (int)(short)(LOWORD(lParam)), ny = (int)(short)(HIWORD(lParam));
08030 if (nx!=disp->window_x || ny!=disp->window_y) {
08031 disp->window_x = nx;
08032 disp->window_y = ny;
08033 disp->is_moved = disp->is_event = true;
08034 SetEvent(cimg::Win32attr().wait_event);
08035 }
08036 ReleaseMutex(disp->mutex);
08037 } break;
08038 case WM_PAINT:
08039 disp->paint();
08040 break;
08041 }
08042 if (disp->events>=2) switch(msg) {
08043 case WM_KEYDOWN:
08044 if (disp->key) std::memmove((void*)(disp->keys+1),(void*)disp->keys,512-1);
08045 disp->key = (int)wParam;
08046 if (disp->released_key) {
08047 std::memmove((void*)(disp->released_keys+1),(void*)disp->released_keys,512-1);
08048 disp->released_key = 0;
08049 }
08050 disp->is_event = true;
08051 SetEvent(cimg::Win32attr().wait_event);
08052 break;
08053 case WM_MOUSEMOVE: {
08054 while (PeekMessage(&st_msg,window,WM_MOUSEMOVE,WM_MOUSEMOVE,PM_REMOVE));
08055 disp->mouse_x = LOWORD(lParam);
08056 disp->mouse_y = HIWORD(lParam);
08057 if (disp->mouse_x<0 || disp->mouse_y<0 || disp->mouse_x>=disp->dimx() || disp->mouse_y>=disp->dimy())
08058 disp->mouse_x=disp->mouse_y=-1;
08059 disp->is_event = true;
08060 SetEvent(cimg::Win32attr().wait_event);
08061 } break;
08062 case WM_LBUTTONDOWN:
08063 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08064 disp->button|=1U;
08065 disp->is_event = true;
08066 SetEvent(cimg::Win32attr().wait_event);
08067 break;
08068 case WM_RBUTTONDOWN:
08069 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08070 disp->button|=2U;
08071 disp->is_event = true;
08072 SetEvent(cimg::Win32attr().wait_event);
08073 break;
08074 case WM_MBUTTONDOWN:
08075 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08076 disp->button|=4U;
08077 disp->is_event = true;
08078 SetEvent(cimg::Win32attr().wait_event);
08079 break;
08080 case 0x020A:
08081 disp->wheel+=(int)((short)HIWORD(wParam))/120;
08082 disp->is_event = true;
08083 SetEvent(cimg::Win32attr().wait_event);
08084 }
08085
08086 if (disp->events>=3) switch(msg) {
08087 case WM_KEYUP:
08088 if (disp->key) {
08089 std::memmove((void*)(disp->keys+1),(void*)disp->keys,512-1);
08090 disp->key = 0;
08091 }
08092 if (disp->released_key) std::memmove((void*)(disp->released_keys+1),(void*)disp->released_keys,512-1);
08093 disp->released_key = (int)wParam;
08094 disp->is_event = true;
08095 SetEvent(cimg::Win32attr().wait_event);
08096 break;
08097 case WM_LBUTTONUP:
08098 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08099 disp->button&=~1U;
08100 disp->is_event = true;
08101 SetEvent(cimg::Win32attr().wait_event);
08102 break;
08103 case WM_RBUTTONUP:
08104 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08105 disp->button&=~2U;
08106 disp->is_event = true;
08107 SetEvent(cimg::Win32attr().wait_event);
08108 break;
08109 case WM_MBUTTONUP:
08110 std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,512-1);
08111 disp->button&=~4U;
08112 disp->is_event = true;
08113 SetEvent(cimg::Win32attr().wait_event);
08114 break;
08115 case WM_SETCURSOR:
08116 if (disp->visible_cursor) ShowCursor(TRUE);
08117 else ShowCursor(FALSE);
08118 break;
08119 }
08120 return DefWindowProc(window,msg,wParam,lParam);
08121 }
08122
08123 static DWORD WINAPI _events_thread(void* arg) {
08124 CImgDisplay *disp = (CImgDisplay*)(((void**)arg)[0]);
08125 const char *title = (const char*)(((void**)arg)[1]);
08126 MSG msg;
08127 delete[] (void**)arg;
08128 disp->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
08129 disp->bmi.bmiHeader.biWidth = disp->width;
08130 disp->bmi.bmiHeader.biHeight = -(int)disp->height;
08131 disp->bmi.bmiHeader.biPlanes = 1;
08132 disp->bmi.bmiHeader.biBitCount = 32;
08133 disp->bmi.bmiHeader.biCompression = BI_RGB;
08134 disp->bmi.bmiHeader.biSizeImage = 0;
08135 disp->bmi.bmiHeader.biXPelsPerMeter = 1;
08136 disp->bmi.bmiHeader.biYPelsPerMeter = 1;
08137 disp->bmi.bmiHeader.biClrUsed = 0;
08138 disp->bmi.bmiHeader.biClrImportant = 0;
08139 disp->data = new unsigned int[disp->width*disp->height];
08140 if (!disp->is_fullscreen) {
08141 RECT rect;
08142 rect.left = rect.top = 0; rect.right = disp->width-1; rect.bottom = disp->height-1;
08143 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
08144 const int border1 = (rect.right-rect.left+1-disp->width)/2, border2 = rect.bottom-rect.top+1-disp->height-border1;
08145 disp->window = CreateWindowA("MDICLIENT",title?title:" ",
08146 WS_OVERLAPPEDWINDOW | (disp->is_closed?0:WS_VISIBLE), CW_USEDEFAULT,CW_USEDEFAULT,
08147 disp->width + 2*border1, disp->height + border1 + border2,
08148 0,0,0,&(disp->ccs));
08149 if (!disp->is_closed) {
08150 GetWindowRect(disp->window,&rect);
08151 disp->window_x = rect.left + border1;
08152 disp->window_y = rect.top + border2;
08153 } else disp->window_x = disp->window_y = 0;
08154 } else {
08155 const unsigned int sx = screen_dimx(), sy = screen_dimy();
08156 disp->window = CreateWindowA("MDICLIENT",title?title:" ",
08157 WS_POPUP | (disp->is_closed?0:WS_VISIBLE), (sx-disp->width)/2, (sy-disp->height)/2,
08158 disp->width,disp->height,0,0,0,&(disp->ccs));
08159 disp->window_x = disp->window_y = 0;
08160 }
08161 SetForegroundWindow(disp->window);
08162 disp->hdc = GetDC(disp->window);
08163 disp->window_width = disp->width;
08164 disp->window_height = disp->height;
08165 disp->mouse_x = disp->mouse_y = -1;
08166 disp->wheel = 0;
08167 std::memset((void*)disp->buttons,0,512*sizeof(unsigned int));
08168 std::memset((void*)disp->keys,0,512*sizeof(unsigned int));
08169 std::memset((void*)disp->released_keys,0,512*sizeof(unsigned int));
08170 disp->is_resized = disp->is_moved = disp->is_event = false;
08171 if (disp->events) {
08172 #ifdef _WIN64
08173 SetWindowLongPtr(disp->window,GWLP_USERDATA,(LONG_PTR)disp);
08174 SetWindowLongPtr(disp->window,GWLP_WNDPROC,(LONG_PTR)_handle_events);
08175 #else
08176 SetWindowLong(disp->window,GWL_USERDATA,(LONG)disp);
08177 SetWindowLong(disp->window,GWL_WNDPROC,(LONG)_handle_events);
08178 #endif
08179 SetEvent(disp->created);
08180 while (GetMessage(&msg,0,0,0)) DispatchMessage(&msg);
08181 }
08182 return 0;
08183 }
08184
08185 void _init_fullscreen() {
08186 background_window = 0;
08187 if (is_fullscreen && !is_closed) {
08188 DEVMODE mode;
08189 unsigned int imode = 0, ibest = 0, bestbpp = 0, bw = ~0U, bh = ~0U;
08190 for (mode.dmSize = sizeof(DEVMODE), mode.dmDriverExtra = 0; EnumDisplaySettings(0,imode,&mode); ++imode) {
08191 const unsigned int nw = mode.dmPelsWidth, nh = mode.dmPelsHeight;
08192 if (nw>=width && nh>=height && mode.dmBitsPerPel>=bestbpp && nw<=bw && nh<=bh) {
08193 bestbpp = mode.dmBitsPerPel;
08194 ibest = imode;
08195 bw = nw; bh = nh;
08196 }
08197 }
08198 if (bestbpp) {
08199 curr_mode.dmSize = sizeof(DEVMODE); curr_mode.dmDriverExtra = 0;
08200 EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&curr_mode);
08201 EnumDisplaySettings(0,ibest,&mode);
08202 ChangeDisplaySettings(&mode,0);
08203 } else curr_mode.dmSize = 0;
08204
08205 const unsigned int sx = screen_dimx(), sy = screen_dimy();
08206 if (sx!=width || sy!=height) {
08207 CLIENTCREATESTRUCT background_ccs;
08208 background_window = CreateWindowA("MDICLIENT"," ",WS_POPUP | WS_VISIBLE, 0,0,sx,sy,0,0,0,&background_ccs);
08209 SetForegroundWindow(background_window);
08210 }
08211 } else curr_mode.dmSize = 0;
08212 }
08213
08214 void _desinit_fullscreen() {
08215 if (is_fullscreen) {
08216 if (background_window) DestroyWindow(background_window);
08217 background_window = 0;
08218 if (curr_mode.dmSize) ChangeDisplaySettings(&curr_mode,0);
08219 is_fullscreen = false;
08220 }
08221 }
08222
08223 CImgDisplay& _update_window_pos() {
08224 if (!is_closed) {
08225 RECT rect;
08226 rect.left = rect.top = 0; rect.right = width-1; rect.bottom = height-1;
08227 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
08228 const int border1 = (rect.right-rect.left+1-width)/2, border2 = rect.bottom-rect.top+1-height-border1;
08229 GetWindowRect(window,&rect);
08230 window_x = rect.left + border1;
08231 window_y = rect.top + border2;
08232 } else window_x = window_y = -1;
08233 return *this;
08234 }
08235
08236 #endif
08237
08238 };
08239
08240
08241
08242
08243
08244
08245
08246
08247
08248
08249
08250
08251
08253
08344 template<typename T> struct CImg {
08345
08347
08354 unsigned int width;
08355
08357
08365 unsigned int height;
08366
08368
08376 unsigned int depth;
08377
08379
08387 unsigned int dim;
08388
08390 bool is_shared;
08391
08393 T *data;
08394
08396
08401 typedef T* iterator;
08402
08404
08409 typedef const T* const_iterator;
08410
08412 typedef T value_type;
08413
08415
08416
08418
08419
08420 #ifdef cimg_plugin
08421 #include cimg_plugin
08422 #endif
08423 #ifdef cimg_plugin1
08424 #include cimg_plugin1
08425 #endif
08426 #ifdef cimg_plugin2
08427 #include cimg_plugin2
08428 #endif
08429 #ifdef cimg_plugin3
08430 #include cimg_plugin3
08431 #endif
08432 #ifdef cimg_plugin4
08433 #include cimg_plugin4
08434 #endif
08435 #ifdef cimg_plugin5
08436 #include cimg_plugin5
08437 #endif
08438 #ifdef cimg_plugin6
08439 #include cimg_plugin6
08440 #endif
08441 #ifdef cimg_plugin7
08442 #include cimg_plugin7
08443 #endif
08444 #ifdef cimg_plugin8
08445 #include cimg_plugin8
08446 #endif
08447
08449
08450
08451
08453
08454
08455
08457
08465 CImg():
08466 width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {}
08467
08469
08478 ~CImg() {
08479 if (data && !is_shared) delete[] data;
08480 }
08481
08483
08492 CImg<T>& assign() {
08493 if (data && !is_shared) delete[] data;
08494 width = height = depth = dim = 0; is_shared = false; data = 0;
08495 return *this;
08496 }
08497
08499
08504 CImg<T>& clear() {
08505 return assign();
08506 }
08507
08509
08525 explicit CImg(const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1):
08526 is_shared(false) {
08527 const unsigned long siz = dx*dy*dz*dv;
08528 if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new T[siz]; }
08529 else { width = height = depth = dim = 0; data = 0; }
08530 }
08531
08533
08549 CImg<T>& assign(const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) {
08550 const unsigned long siz = dx*dy*dz*dv;
08551 if (!siz) return assign();
08552 const unsigned long curr_siz = size();
08553 if (is_shared) {
08554 if (siz>curr_siz)
08555 throw CImgArgumentException("CImg<%s>::assign() : Cannot assign image (%u,%u,%u,%u) to shared instance image (%u,%u,%u,%u,%p).",
08556 pixel_type(),dx,dy,dz,dv,width,height,depth,dim,data);
08557 } else {
08558 if (siz!=curr_siz) { if (data) delete[] data; data = new T[siz]; }
08559 width = dx; height = dy; depth = dz; dim = dv;
08560 }
08561 return *this;
08562 }
08563
08565
08577 CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const T val):
08578 is_shared(false) {
08579 const unsigned long siz = dx*dy*dz*dv;
08580 if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new T[siz]; fill(val); }
08581 else { width = height = depth = dim = 0; data = 0; }
08582 }
08583
08585
08597 CImg<T>& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const T val) {
08598 return assign(dx,dy,dz,dv).fill(val);
08599 }
08600
08602
08606 template<typename t> CImg(const t *const data_buffer, const unsigned int dx, const unsigned int dy=1,
08607 const unsigned int dz=1, const unsigned int dv=1, const bool shared=false):is_shared(false) {
08608 if (shared) throw CImgArgumentException("CImg<%s>::CImg() : Cannot construct a shared copy from a (%s*) buffer "
08609 "(different pixel types).",pixel_type(),CImg<t>::pixel_type());
08610 const unsigned long siz = dx*dy*dz*dv;
08611 if (data_buffer && siz) {
08612 width = dx; height = dy; depth = dz; dim = dv; data = new T[siz];
08613 const t *ptrs = data_buffer + siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
08614 } else { width = height = depth = dim = 0; data = 0; }
08615 }
08616
08617 #ifdef cimg_use_visualcpp6
08618 CImg(const T *const data_buffer, const unsigned int dx, const unsigned int dy,
08619 const unsigned int dz, const unsigned int dv, const bool shared) {
08620 #else
08621 CImg(const T *const data_buffer, const unsigned int dx, const unsigned int dy=1,
08622 const unsigned int dz=1, const unsigned int dv=1, const bool shared=false) {
08623 #endif
08624 const unsigned long siz = dx*dy*dz*dv;
08625 if (data_buffer && siz) {
08626 width = dx; height = dy; depth = dz; dim = dv; is_shared = shared;
08627 if (is_shared) data = const_cast<T*>(data_buffer);
08628 else { data = new T[siz]; std::memcpy(data,data_buffer,siz*sizeof(T)); }
08629 } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
08630 }
08631
08633 #ifdef cimg_use_visualcpp6
08634 template<typename t> CImg<T>& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy,
08635 const unsigned int dz, const unsigned int dv) {
08636 #else
08637 template<typename t> CImg<T>& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy=1,
08638 const unsigned int dz=1, const unsigned int dv=1) {
08639 #endif
08640 const unsigned long siz = dx*dy*dz*dv;
08641 if (!data_buffer || !siz) return assign();
08642 assign(dx,dy,dz,dv);
08643 const t *ptrs = data_buffer + siz;
08644 cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
08645 return *this;
08646 }
08647
08648 CImg<T>& assign(const T *const data_buffer, const unsigned int dx, const unsigned int dy=1,
08649 const unsigned int dz=1, const unsigned int dv=1) {
08650 const unsigned long siz = dx*dy*dz*dv;
08651 if (!data_buffer || !siz) return assign();
08652 const unsigned long curr_siz = size();
08653 if (data_buffer==data && siz==curr_siz) return assign(dx,dy,dz,dv);
08654 if (is_shared || data_buffer+siz<data || data_buffer>=data+size()) {
08655 assign(dx,dy,dz,dv);
08656 if (is_shared) std::memmove(data,data_buffer,siz*sizeof(T));
08657 else std::memcpy(data,data_buffer,siz*sizeof(T));
08658 } else {
08659 T *new_data = new T[siz];
08660 std::memcpy(new_data,data_buffer,siz*sizeof(T));
08661 delete[] data; data = new_data; width = dx; height = dy; depth = dz; dim = dv;
08662 }
08663 return *this;
08664 }
08665
08667 template<typename t> CImg<T>& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy,
08668 const unsigned int dz, const unsigned int dv, const bool shared) {
08669 if (shared) throw CImgArgumentException("CImg<%s>::assign() : Cannot construct a shared copy from a (%s*) buffer "
08670 "(different pixel types).",pixel_type(),CImg<t>::pixel_type());
08671 return assign().assign(data_buffer,dx,dy,dz,dv);
08672 }
08673
08674 CImg<T>& assign(const T *const data_buffer, const unsigned int dx, const unsigned int dy,
08675 const unsigned int dz, const unsigned int dv, const bool shared) {
08676 if (!shared) return assign(data_buffer,dx,dy,dz,dv);
08677 const unsigned long siz = dx*dy*dz*dv;
08678 if (!data_buffer || !siz)
08679 throw CImgArgumentException("CImg<%s>::assign() : Cannot construct a shared copy of an empty image.",pixel_type());
08680 if (!is_shared) {
08681 if (data_buffer+siz<data || data_buffer>=data+size()) assign();
08682 else cimg::warn("CImg<%s>::assign() : Create shared version of previous parts of the instance image, possible memory leaks !",
08683 pixel_type());
08684 }
08685 width = dx; height = dy; depth = dz; dim = dv; is_shared = true;
08686 data = const_cast<T*>(data_buffer);
08687 return *this;
08688 }
08689
08691
08709 template<typename t> CImg(const CImg<t>& img):is_shared(false) {
08710 const unsigned int siz = img.size();
08711 if (img.data && siz) {
08712 width = img.width; height = img.height; depth = img.depth; dim = img.dim; data = new T[siz];
08713 const t *ptrs = img.data + siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
08714 } else { width = height = depth = dim = 0; data = 0; }
08715 }
08716
08717 CImg(const CImg<T>& img) {
08718 const unsigned int siz = img.size();
08719 if (img.data && siz) {
08720 width = img.width; height = img.height; depth = img.depth; dim = img.dim; is_shared = img.is_shared;
08721 if (is_shared) data = const_cast<T*>(img.data);
08722 else { data = new T[siz]; std::memcpy(data,img.data,siz*sizeof(T)); }
08723 } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
08724 }
08725
08727
08737 template<typename t> CImg<T>& assign(const CImg<t>& img) {
08738 return assign(img.data,img.width,img.height,img.depth,img.dim);
08739 }
08740
08742
08756 template<typename t> CImg(const CImg<t>& img, const bool shared):is_shared(false) {
08757 if (shared) throw CImgArgumentException("CImg<%s>::CImg() : Cannot construct a shared copy from a CImg<%s> image "
08758 "(different pixel types).",pixel_type(),CImg<t>::pixel_type());
08759 const unsigned int siz = img.size();
08760 if (img.data && siz) {
08761 width = img.width; height = img.height; depth = img.depth; dim = img.dim; data = new T[siz];
08762 const t *ptrs = img.data+siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
08763 } else { width = height = depth = dim = 0; data = 0; }
08764 }
08765
08766 CImg(const CImg<T>& img, const bool shared) {
08767 const unsigned int siz = img.size();
08768 if (img.data && siz) {
08769 width = img.width; height = img.height; depth = img.depth; dim = img.dim; is_shared = shared;
08770 if (is_shared) data = const_cast<T*>(img.data);
08771 else { data = new T[siz]; std::memcpy(data,img.data,siz*sizeof(T)); }
08772 } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
08773 }
08774
08776
08789 template<typename t> CImg<T>& assign(const CImg<t>& img, const bool shared) {
08790 return assign(img.data,img.width,img.height,img.depth,img.dim,shared);
08791 }
08792
08794 CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv,
08795 const int val0, const int val1, ...):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08796 assign(dx,dy,dz,dv);
08797 _CImg_stdarg(*this,val0,val1,dx*dy*dz*dv,int);
08798 }
08799
08801 CImg<T>& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv,
08802 const int val0, const int val1, ...) {
08803 assign(dx,dy,dz,dv);
08804 _CImg_stdarg(*this,val0,val1,dx*dy*dz*dv,int);
08805 return *this;
08806 }
08807
08809 CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv,
08810 const double val0, const double val1, ...):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08811 assign(dx,dy,dz,dv);
08812 _CImg_stdarg(*this,val0,val1,dx*dy*dz*dv,double);
08813 }
08814
08816 CImg<T>& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv,
08817 const double val0, const double val1, ...) {
08818 assign(dx,dy,dz,dv);
08819 _CImg_stdarg(*this,val0,val1,dx*dy*dz*dv,double);
08820 return *this;
08821 }
08822
08824 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) {
08825 assign(img,dimensions);
08826 }
08827
08829 template<typename t> CImg<T>& assign(const CImg<t>& img, const char *const dimensions) {
08830 if (dimensions) {
08831 unsigned int siz[4] = { 0,1,1,1 };
08832 const char *s = dimensions;
08833 char tmp[256] = { 0 }, c = 0;
08834 int val = 0;
08835 for (unsigned int k=0; k<4; ++k) {
08836 const int err = std::sscanf(s,"%[-0-9]%c",tmp,&c);
08837 if (err>=1) {
08838 const int err = std::sscanf(s,"%d",&val);
08839 if (err==1) {
08840 int val2 = val<0?-val:(c=='%'?val:-1);
08841 if (val2>=0) {
08842 val = (int)((k==0?img.width:(k==1?img.height:(k==2?img.depth:img.dim)))*val2/100);
08843 if (c!='%' && !val) val = 1;
08844 }
08845 siz[k] = val;
08846 }
08847 s+=cimg::strlen(tmp);
08848 if (c=='%') ++s;
08849 }
08850 if (!err) {
08851 if (!cimg::strncasecmp(s,"x",1)) { ++s; siz[k] = img.width; }
08852 else if (!cimg::strncasecmp(s,"y",1)) { ++s; siz[k] = img.height; }
08853 else if (!cimg::strncasecmp(s,"z",1)) { ++s; siz[k] = img.depth; }
08854 else if (!cimg::strncasecmp(s,"v",1)) { ++s; siz[k] = img.dim; }
08855 else if (!cimg::strncasecmp(s,"dx",2)) { s+=2; siz[k] = img.width; }
08856 else if (!cimg::strncasecmp(s,"dy",2)) { s+=2; siz[k] = img.height; }
08857 else if (!cimg::strncasecmp(s,"dz",2)) { s+=2; siz[k] = img.depth; }
08858 else if (!cimg::strncasecmp(s,"dv",2)) { s+=2; siz[k] = img.dim; }
08859 else if (!cimg::strncasecmp(s,"dimx",4)) { s+=4; siz[k] = img.width; }
08860 else if (!cimg::strncasecmp(s,"dimy",4)) { s+=4; siz[k] = img.height; }
08861 else if (!cimg::strncasecmp(s,"dimz",4)) { s+=4; siz[k] = img.depth; }
08862 else if (!cimg::strncasecmp(s,"dimv",4)) { s+=4; siz[k] = img.dim; }
08863 else if (!cimg::strncasecmp(s,"width",5)) { s+=5; siz[k] = img.width; }
08864 else if (!cimg::strncasecmp(s,"height",6)) { s+=6; siz[k] = img.height; }
08865 else if (!cimg::strncasecmp(s,"depth",5)) { s+=5; siz[k] = img.depth; }
08866 else if (!cimg::strncasecmp(s,"dim",3)) { s+=3; siz[k] = img.dim; }
08867 else { ++s; --k; }
08868 }
08869 }
08870 return assign(siz[0],siz[1],siz[2],siz[3]);
08871 }
08872 return assign();
08873 }
08874
08876 template<typename t> CImg(const CImg<t>& img, const char *const dimensions, const T val):
08877 width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08878 assign(img,dimensions).fill(val);
08879 }
08880
08882 template<typename t> CImg<T>& assign(const CImg<t>& img, const char *const dimensions, const T val) {
08883 return assign(img,dimensions).fill(val);
08884 }
08885
08887
08898 CImg(const char *const filename):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08899 assign(filename);
08900 }
08901
08903
08912 CImg<T>& assign(const char *const filename) {
08913 return load(filename);
08914 }
08915
08917 CImg(const CImgDisplay &disp):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
08918 disp.snapshot(*this);
08919 }
08920
08922 CImg<T>& assign(const CImgDisplay &disp) {
08923 disp.snapshot(*this);
08924 return *this;
08925 }
08926
08927
08928 CImg<T>& swap(CImg<T>& img) {
08929 cimg::swap(width,img.width);
08930 cimg::swap(height,img.height);
08931 cimg::swap(depth,img.depth);
08932 cimg::swap(dim,img.dim);
08933 cimg::swap(data,img.data);
08934 cimg::swap(is_shared,img.is_shared);
08935 return img;
08936 }
08937
08938
08939 #ifndef cimg_use_visualcpp6
08940 CImg<T>& assign_to(CImg<T>& img) {
08941 if (is_shared || img.is_shared) return img.assign(*this);
08942 cimg::swap(width,img.width);
08943 cimg::swap(height,img.height);
08944 cimg::swap(depth,img.depth);
08945 cimg::swap(dim,img.dim);
08946 cimg::swap(data,img.data);
08947 return img;
08948 }
08949 #endif
08950
08951 template<typename t> CImg<t>& assign_to(CImg<t>& img) {
08952 return img.assign(*this);
08953 }
08954
08956
08957
08959
08960
08961
08963
08968 static const char* pixel_type() {
08969 return cimg::type<T>::string();
08970 }
08971
08973
08983 unsigned long size() const {
08984 return width*height*depth*dim;
08985 }
08986
08988
08991 int dimx() const {
08992 return (int)width;
08993 }
08994
08996
08999 int dimy() const {
09000 return (int)height;
09001 }
09002
09004
09007 int dimz() const {
09008 return (int)depth;
09009 }
09010
09012
09015 int dimv() const {
09016 return (int)dim;
09017 }
09018
09020 template<typename t> bool is_sameX(const CImg<t>& img) const {
09021 return (width==img.width);
09022 }
09023
09025 bool is_sameX(const CImgDisplay& disp) const {
09026 return (width==disp.width);
09027 }
09028
09030 template<typename t> bool is_sameY(const CImg<t>& img) const {
09031 return (height==img.height);
09032 }
09033
09035 bool is_sameY(const CImgDisplay& disp) const {
09036 return (height==disp.height);
09037 }
09038
09040 template<typename t> bool is_sameZ(const CImg<t>& img) const {
09041 return (depth==img.depth);
09042 }
09043
09045 template<typename t> bool is_sameV(const CImg<t>& img) const {
09046 return (dim==img.dim);
09047 }
09048
09050 template<typename t> bool is_sameXY(const CImg<t>& img) const {
09051 return (is_sameX(img) && is_sameY(img));
09052 }
09053
09055 bool is_sameXY(const CImgDisplay& disp) const {
09056 return (is_sameX(disp) && is_sameY(disp));
09057 }
09058
09060 template<typename t> bool is_sameXZ(const CImg<t>& img) const {
09061 return (is_sameX(img) && is_sameZ(img));
09062 }
09063
09065 template<typename t> bool is_sameXV(const CImg<t>& img) const {
09066 return (is_sameX(img) && is_sameV(img));
09067 }
09068
09070 template<typename t> bool is_sameYZ(const CImg<t>& img) const {
09071 return (is_sameY(img) && is_sameZ(img));
09072 }
09073
09075 template<typename t> bool is_sameYV(const CImg<t>& img) const {
09076 return (is_sameY(img) && is_sameV(img));
09077 }
09078
09080 template<typename t> bool is_sameZV(const CImg<t>& img) const {
09081 return (is_sameZ(img) && is_sameV(img));
09082 }
09083
09085 template<typename t> bool is_sameXYZ(const CImg<t>& img) const {
09086 return (is_sameXY(img) && is_sameZ(img));
09087 }
09088
09090 template<typename t> bool is_sameXYV(const CImg<t>& img) const {
09091 return (is_sameXY(img) && is_sameZ(img));
09092 }
09093
09095 template<typename t> bool is_sameXZV(const CImg<t>& img) const {
09096 return (is_sameXY(img) && is_sameZ(img));
09097 }
09098
09100 template<typename t> bool is_sameYZV(const CImg<t>& img) const {
09101 return (is_sameXY(img) && is_sameZ(img));
09102 }
09103
09105 template<typename t> bool is_sameXYZV(const CImg<t>& img) const {
09106 return (is_sameXYZ(img) && is_sameV(img));
09107 }
09108
09110 bool contains(const int x, const int y=0, const int z=0, const int v=0) const {
09111 return data && x>=0 && x<dimx() && y>=0 && y<dimy() && z>=0 && z<dimz() && v>=0 && v<dimv();
09112 }
09113
09115 template<typename t> bool contains(const T& pixel, t& x, t& y, t& z, t& v) const {
09116 const T *ptr = &pixel;
09117 unsigned long off = (unsigned long)(ptr-data);
09118 const unsigned long whz = width*height*depth, wh = width*height;
09119 v = (t)(off/whz); off%=whz; z =(t)(off/wh); off%=wh; y = (t)(off/width); x = (t)(off%width);
09120 return contains(x,y,z,v);
09121 }
09122
09124 template<typename t> bool contains(const T& pixel, t& x, t& y, t& z) const {
09125 t v;
09126 return contains(pixel,x,y,z,v);
09127 }
09128
09130 template<typename t> bool contains(const T& pixel, t& x, t& y) const {
09131 t z,v;
09132 return contains(pixel,x,y,z,v);
09133 }
09134
09136 template<typename t> bool contains(const T& pixel, t& x) const {
09137 t y,z,v;
09138 return contains(pixel,x,y,z,v);
09139 }
09140
09142 template<typename t> bool contains(const T& pixel) const {
09143 t x,y,z,v;
09144 return contains(pixel,x,y,z,v);
09145 }
09146
09148
09151 template<typename t> bool is_overlapping(const CImg<t>& img) const {
09152 const unsigned long csiz = size(), isiz = img.size();
09153 return !((void*)(data+csiz)<=(void*)img.data || (void*)data>=(void*)(img.data+isiz));
09154 }
09155
09157 bool is_empty() const {
09158 return !(data && width && height && depth && dim);
09159 }
09160
09162 operator bool() const {
09163 return !is_empty();
09164 }
09165
09167
09183 long offset(const int x=0, const int y=0, const int z=0, const int v=0) const {
09184 return x + y*width + z*width*height + v*width*height*depth;
09185 }
09186
09188
09206 T* ptr(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) {
09207 const long off = offset(x,y,z,v);
09208 #if cimg_debug>=3
09209 if (off<0 || off>=(long)size()) {
09210 cimg::warn("CImg<%s>::ptr() : Asked for a pointer at coordinates (%u,%u,%u,%u) (offset=%u), "
09211 "outside image range (%u,%u,%u,%u) (size=%u)",
09212 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09213 return data;
09214 }
09215 #endif
09216 return data+off;
09217 }
09218
09219 const T* ptr(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const {
09220 const long off = offset(x,y,z,v);
09221 #if cimg_debug>=3
09222 if (off<0 || off>=(long)size()) {
09223 cimg::warn("CImg<%s>::ptr() : Trying to get a pointer at (%u,%u,%u,%u) (offset=%u) which is"
09224 "outside the data of the image (%u,%u,%u,%u) (size=%u)",
09225 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09226 return data;
09227 }
09228 #endif
09229 return data+off;
09230 }
09231
09233 iterator begin() {
09234 return data;
09235 }
09236
09237 const_iterator begin() const {
09238 return data;
09239 }
09240
09242 iterator end() {
09243 return data + size();
09244 }
09245
09246 const_iterator end() const {
09247 return data + size();
09248 }
09249
09251
09273 T& operator()(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) {
09274 const long off = offset(x,y,z,v);
09275 #if cimg_debug>=3
09276 if (!data || off>=(long)size()) {
09277 cimg::warn("CImg<%s>::operator() : Pixel access requested at (%u,%u,%u,%u) (offset=%u) "
09278 "outside the image range (%u,%u,%u,%u) (size=%u)",
09279 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09280 return *data;
09281 }
09282 #endif
09283 return data[off];
09284 }
09285
09286 const T& operator()(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const {
09287 const long off = offset(x,y,z,v);
09288 #if cimg_debug>=3
09289 if (!data || off>=(long)size()) {
09290 cimg::warn("CImg<%s>::operator() : Pixel access requested at (%u,%u,%u,%u) (offset=%u) "
09291 "outside the image range (%u,%u,%u,%u) (size=%u)",
09292 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09293 return *data;
09294 }
09295 #endif
09296 return data[off];
09297 }
09298
09300 T& at(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) {
09301 const long off = offset(x,y,z,v);
09302 if (!data || off>=(long)size())
09303 throw CImgArgumentException("CImg<%s>::at() : Pixel access requested at (%u,%u,%u,%u) (offset=%u) "
09304 "outside the image range (%u,%u,%u,%u) (size=%u)",
09305 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09306 return data[off];
09307 }
09308
09309 const T& at(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const {
09310 const long off = offset(x,y,z,v);
09311 if (!data || off>=(long)size())
09312 throw CImgArgumentException("CImg<%s>::at() : Pixel access requested at (%u,%u,%u,%u) (offset=%u) "
09313 "outside the image range (%u,%u,%u,%u) (size=%u)",
09314 pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
09315 return data[off];
09316 }
09317
09319
09336 T& operator[](const unsigned long off) {
09337 return operator()(off);
09338 }
09339
09340 const T& operator[](const unsigned long off) const {
09341 return operator()(off);
09342 }
09343
09345 T& back() {
09346 return operator()(size()-1);
09347 }
09348
09349 const T& back() const {
09350 return operator()(size()-1);
09351 }
09352
09354 T& front() {
09355 return *data;
09356 }
09357
09358 const T& front() const {
09359 return *data;
09360 }
09361
09363
09385 T pix1d(const int x, const int y, const int z, const int v, const T out_val) const {
09386 return (x<0 || x>=dimx())?out_val:(*this)(x,y,z,v);
09387 }
09388
09389 const T& pix1d(const int x, const int y=0, const int z=0, const int v=0) const {
09390 return (*this)(x<0?0:(x>=dimx()?dimx()-1:x),y,z,v);
09391 }
09392
09394 T pix2d(const int x, const int y, const int z, const int v, const T out_val) const {
09395 return (x<0 || y<0 || x>=dimx() || y>=dimy())?out_val:(*this)(x,y,z,v);
09396 }
09397
09398 const T& pix2d(const int x, const int y, const int z=0, const int v=0) const {
09399 return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),z,v);
09400 }
09401
09403 T pix3d(const int x, const int y, const int z, const int v, const T out_val) const {
09404 return (x<0 || y<0 || z<0 || x>=dimx() || y>=dimy() || z>=dimz())?out_val:(*this)(x,y,z,v);
09405 }
09406
09407 const T& pix3d(const int x, const int y, const int z, const int v=0) const {
09408 return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),
09409 z<0?0:(z>=dimz()?dimz()-1:z),v);
09410 }
09411
09413 T pix4d(const int x, const int y, const int z, const int v, const T out_val) const {
09414 return (x<0 || y<0 || z<0 || v<0 || x>=dimx() || y>=dimy() || z>=dimz() || v>=dimv())?out_val:(*this)(x,y,z,v);
09415 }
09416
09417 T pix4d(const int x, const int y, const int z, const int v) const {
09418 return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),
09419 z<0?0:(z>=dimz()?dimz()-1:z), v<0?0:(v>=dimv()?dimv()-1:v));
09420 }
09421
09423
09428 typename cimg::superset<T,float>::type linear_pix1d(const float fx, const int y, const int z, const int v,
09429 const T out_val) const {
09430 typedef typename cimg::superset<T,float>::type ftype;
09431 const int
09432 x = (int)fx-(fx>=0?0:1), nx = x+1;
09433 const float
09434 dx = fx-x;
09435 const ftype
09436 Ic = (ftype)pix1d(x,y,z,v,out_val), In = (ftype)pix2d(nx,y,z,v,out_val);
09437 return Ic + dx*(In-Ic);
09438 }
09439
09440 typename cimg::superset<T,float>::type linear_pix1d(const float fx, const int y=0, const int z=0, const int v=0) const {
09441 typedef typename cimg::superset<T,float>::type ftype;
09442 const float
09443 nfx = fx<0?0:(fx>width-1?width-1:fx);
09444 const unsigned int
09445 x = (unsigned int)nfx;
09446 const float
09447 dx = nfx-x;
09448 const unsigned int
09449 nx = dx>0?x+1:x;
09450 const ftype
09451 Ic = (ftype)(*this)(x,y,z,v), In = (ftype)(*this)(nx,y,z,v);
09452 return Ic + dx*(In-Ic);
09453 }
09454
09456
09461 typename cimg::superset<T,float>::type linear_pix2d(const float fx, const float fy, const int z, const int v,
09462 const T out_val) const {
09463 typedef typename cimg::superset<T,float>::type ftype;
09464 const int
09465 x = (int)fx-(fx>=0?0:1), nx = x+1,
09466 y = (int)fy-(fy>=0?0:1), ny = y+1;
09467 const float
09468 dx = fx-x,
09469 dy = fy-y;
09470 const ftype
09471 Icc = (ftype)pix2d(x,y,z,v,out_val), Inc = (ftype)pix2d(nx,y,z,v,out_val),
09472 Icn = (ftype)pix2d(x,ny,z,v,out_val), Inn = (ftype)pix2d(nx,ny,z,v,out_val);
09473 return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc);
09474 }
09475
09476 typename cimg::superset<T,float>::type linear_pix2d(const float fx, const float fy, const int z=0, const int v=0) const {
09477 typedef typename cimg::superset<T,float>::type ftype;
09478 const float
09479 nfx = fx<0?0:(fx>width-1?width-1:fx),
09480 nfy = fy<0?0:(fy>height-1?height-1:fy);
09481 const unsigned int
09482 x = (unsigned int)nfx,
09483 y = (unsigned int)nfy;
09484 const float
09485 dx = nfx-x,
09486 dy = nfy-y;
09487 const unsigned int
09488 nx = dx>0?x+1:x,
09489 ny = dy>0?y+1:y;
09490 const ftype
09491 Icc = (ftype)(*this)(x,y,z,v), Inc = (ftype)(*this)(nx,y,z,v),
09492 Icn = (ftype)(*this)(x,ny,z,v), Inn = (ftype)(*this)(nx,ny,z,v);
09493 return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc);
09494 }
09495
09497
09502 typename cimg::superset<T,float>::type linear_pix3d(const float fx, const float fy, const float fz, const int v,
09503 const T out_val) const {
09504 typedef typename cimg::superset<T,float>::type ftype;
09505 const int
09506 x = (int)fx-(fx>=0?0:1), nx = x+1,
09507 y = (int)fy-(fy>=0?0:1), ny = y+1,
09508 z = (int)fz-(fz>=0?0:1), nz = z+1;
09509 const float
09510 dx = fx-x,
09511 dy = fy-y,
09512 dz = fz-z;
09513 const ftype
09514 Iccc = (ftype)pix3d(x,y,z,v,out_val), Incc = (ftype)pix3d(nx,y,z,v,out_val),
09515 Icnc = (ftype)pix3d(x,ny,z,v,out_val), Innc = (ftype)pix3d(nx,ny,z,v,out_val),
09516 Iccn = (ftype)pix3d(x,y,nz,v,out_val), Incn = (ftype)pix3d(nx,y,nz,v,out_val),
09517 Icnn = (ftype)pix3d(x,ny,nz,v,out_val), Innn = (ftype)pix3d(nx,ny,nz,v,out_val);
09518 return Iccc +
09519 dx*(Incc-Iccc +
09520 dy*(Iccc+Innc-Icnc-Incc +
09521 dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) +
09522 dz*(Iccc+Incn-Iccn-Incc)) +
09523 dy*(Icnc-Iccc +
09524 dz*(Iccc+Icnn-Iccn-Icnc)) +
09525 dz*(Iccn-Iccc);
09526 }
09527
09528 typename cimg::superset<T,float>::type linear_pix3d(const float fx, const float fy=0, const float fz=0, const int v=0) const {
09529 typedef typename cimg::superset<T,float>::type ftype;
09530 const float
09531 nfx = fx<0?0:(fx>width-1?width-1:fx),
09532 nfy = fy<0?0:(fy>height-1?height-1:fy),
09533 nfz = fz<0?0:(fz>depth-1?depth-1:fz);
09534 const unsigned int
09535 x = (unsigned int)nfx,
09536 y = (unsigned int)nfy,
09537 z = (unsigned int)nfz;
09538 const float
09539 dx = nfx-x,
09540 dy = nfy-y,
09541 dz = nfz-z;
09542 const unsigned int
09543 nx = dx>0?x+1:x,
09544 ny = dy>0?y+1:y,
09545 nz = dz>0?z+1:z;
09546 const ftype
09547 Iccc = (ftype)(*this)(x,y,z,v), Incc = (ftype)(*this)(nx,y,z,v),
09548 Icnc = (ftype)(*this)(x,ny,z,v), Innc = (ftype)(*this)(nx,ny,z,v),
09549 Iccn = (ftype)(*this)(x,y,nz,v), Incn = (ftype)(*this)(nx,y,nz,v),
09550 Icnn = (ftype)(*this)(x,ny,nz,v), Innn = (ftype)(*this)(nx,ny,nz,v);
09551 return Iccc +
09552 dx*(Incc-Iccc +
09553 dy*(Iccc+Innc-Icnc-Incc +
09554 dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) +
09555 dz*(Iccc+Incn-Iccn-Incc)) +
09556 dy*(Icnc-Iccc +
09557 dz*(Iccc+Icnn-Iccn-Icnc)) +
09558 dz*(Iccn-Iccc);
09559 }
09560
09562
09586 typename cimg::superset<T,float>::type linear_pix4d(const float fx, const float fy, const float fz, const float fv,
09587 const T out_val) const {
09588 typedef typename cimg::superset<T,float>::type ftype;
09589 const int
09590 x = (int)fx-(fx>=0?0:1), nx = x+1,
09591 y = (int)fy-(fy>=0?0:1), ny = y+1,
09592 z = (int)fz-(fz>=0?0:1), nz = z+1,
09593 v = (int)fv-(fv>=0?0:1), nv = v+1;
09594 const float
09595 dx = fx-x,
09596 dy = fy-y,
09597 dz = fz-z,
09598 dv = fv-v;
09599 const ftype
09600 Icccc = (ftype)pix4d(x,y,z,v,out_val), Inccc = (ftype)pix4d(nx,y,z,v,out_val),
09601 Icncc = (ftype)pix4d(x,ny,z,v,out_val), Inncc = (ftype)pix4d(nx,ny,z,v,out_val),
09602 Iccnc = (ftype)pix4d(x,y,nz,v,out_val), Incnc = (ftype)pix4d(nx,y,nz,v,out_val),
09603 Icnnc = (ftype)pix4d(x,ny,nz,v,out_val), Innnc = (ftype)pix4d(nx,ny,nz,v,out_val),
09604 Icccn = (ftype)pix4d(x,y,z,nv,out_val), Inccn = (ftype)pix4d(nx,y,z,nv,out_val),
09605 Icncn = (ftype)pix4d(x,ny,z,nv,out_val), Inncn = (ftype)pix4d(nx,ny,z,nv,out_val),
09606 Iccnn = (ftype)pix4d(x,y,nz,nv,out_val), Incnn = (ftype)pix4d(nx,y,nz,nv,out_val),
09607 Icnnn = (ftype)pix4d(x,ny,nz,nv,out_val), Innnn = (ftype)pix4d(nx,ny,nz,nv,out_val);
09608 return Icccc +
09609 dx*(Inccc-Icccc +
09610 dy*(Icccc+Inncc-Icncc-Inccc +
09611 dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc +
09612 dv*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) +
09613 dv*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) +
09614 dz*(Icccc+Incnc-Iccnc-Inccc +
09615 dv*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) +
09616 dv*(Icccc+Inccn-Inccc-Icccn)) +
09617 dy*(Icncc-Icccc +
09618 dz*(Icccc+Icnnc-Iccnc-Icncc +
09619 dv*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) +
09620 dv*(Icccc+Icncn-Icncc-Icccn)) +
09621 dz*(Iccnc-Icccc +
09622 dv*(Icccc+Iccnn-Iccnc-Icccn)) +
09623 dv*(Icccn-Icccc);
09624 }
09625
09626 typename cimg::superset<T,float>::type linear_pix4d(const float fx, const float fy=0, const float fz=0, const float fv=0) const {
09627 typedef typename cimg::superset<T,float>::type ftype;
09628 const float
09629 nfx = fx<0?0:(fx>width-1?width-1:fx),
09630 nfy = fy<0?0:(fy>height-1?height-1:fy),
09631 nfz = fz<0?0:(fz>depth-1?depth-1:fz),
09632 nfv = fv<0?0:(fv>dim-1?dim-1:fv);
09633 const unsigned int
09634 x = (unsigned int)nfx,
09635 y = (unsigned int)nfy,
09636 z = (unsigned int)nfz,
09637 v = (unsigned int)nfv;
09638 const float
09639 dx = nfx-x,
09640 dy = nfy-y,
09641 dz = nfz-z,
09642 dv = nfv-v;
09643 const unsigned int
09644 nx = dx>0?x+1:x,
09645 ny = dy>0?y+1:y,
09646 nz = dz>0?z+1:z,
09647 nv = dv>0?v+1:v;
09648 const ftype
09649 Icccc = (ftype)(*this)(x,y,z,v), Inccc = (ftype)(*this)(nx,y,z,v),
09650 Icncc = (ftype)(*this)(x,ny,z,v), Inncc = (ftype)(*this)(nx,ny,z,v),
09651 Iccnc = (ftype)(*this)(x,y,nz,v), Incnc = (ftype)(*this)(nx,y,nz,v),
09652 Icnnc = (ftype)(*this)(x,ny,nz,v), Innnc = (ftype)(*this)(nx,ny,nz,v),
09653 Icccn = (ftype)(*this)(x,y,z,nv), Inccn = (ftype)(*this)(nx,y,z,nv),
09654 Icncn = (ftype)(*this)(x,ny,z,nv), Inncn = (ftype)(*this)(nx,ny,z,nv),
09655 Iccnn = (ftype)(*this)(x,y,nz,nv), Incnn = (ftype)(*this)(nx,y,nz,nv),
09656 Icnnn = (ftype)(*this)(x,ny,nz,nv), Innnn = (ftype)(*this)(nx,ny,nz,nv);
09657 return Icccc +
09658 dx*(Inccc-Icccc +
09659 dy*(Icccc+Inncc-Icncc-Inccc +
09660 dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc +
09661 dv*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) +
09662 dv*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) +
09663 dz*(Icccc+Incnc-Iccnc-Inccc +
09664 dv*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) +
09665 dv*(Icccc+Inccn-Inccc-Icccn)) +
09666 dy*(Icncc-Icccc +
09667 dz*(Icccc+Icnnc-Iccnc-Icncc +
09668 dv*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) +
09669 dv*(Icccc+Icncn-Icncc-Icccn)) +
09670 dz*(Iccnc-Icccc +
09671 dv*(Icccc+Iccnn-Iccnc-Icccn)) +
09672 dv*(Icccn-Icccc);
09673 }
09674
09676
09681 typename cimg::superset<T,float>::type cubic_pix1d(const float fx, const int y, const int z, const int v,
09682 const T out_val) const {
09683 typedef typename cimg::superset<T,float>::type ftype;
09684 const int
09685 x = (int)fx-(fx>=0?0:1), px = x-1, nx = x+1, ax = x+2;
09686 const float
09687 dx = fx-x;
09688 const ftype
09689 Ip = (ftype)pix1d(px,y,z,v,out_val), Ic = (ftype)pix1d(x,y,z,v,out_val),
09690 In = (ftype)pix1d(nx,y,z,v,out_val), Ia = (ftype)pix1d(ax,y,z,v,out_val),
09691 valm = cimg::min(Ip,In,Ic,Ia), valM = cimg::max(Ip,In,Ic,Ia),
09692 u0 = Ic - Ip,
09693 u1 = Ia - In,
09694 a = 2*(Ic-In) + u0 + u1,
09695 b = 3*(In-Ic) - 2*u0 - u1,
09696 val = a*dx*dx*dx + b*dx*dx + u0*dx + Ic;
09697 return val<valm?valm:(val>valM?valM:val);
09698 }
09699
09700 typename cimg::superset<T,float>::type cubic_pix1d(const float fx, const int y=0, const int z=0, const int v=0) const {
09701 typedef typename cimg::superset<T,float>::type ftype;
09702 const float
09703 nfx = fx<0?0:(fx>width-1?width-1:fx);
09704 const int
09705 x = (int)nfx;
09706 const float
09707 dx = nfx-x;
09708 const int
09709 px = x-1<0?0:x-1, nx = dx>0?x+1:x, ax = x+2>=dimx()?dimx()-1:x+2;
09710 const ftype
09711 Ip = (ftype)(*this)(px,y,z,v), Ic = (ftype)(*this)(x,y,z,v),
09712 In = (ftype)(*this)(nx,y,z,v), Ia = (ftype)(*this)(ax,y,z,v),
09713 valm = cimg::min(Ip,In,Ic,Ia), valM = cimg::max(Ip,In,Ic,Ia),
09714 u0 = Ic - Ip,
09715 u1 = Ia - In,
09716 a = 2*(Ic-In) + u0 + u1,
09717 b = 3*(In-Ic) - 2*u0 - u1,
09718 val = a*dx*dx*dx + b*dx*dx + u0*dx + Ic;
09719 return val<valm?valm:(val>valM?valM:val);
09720 }
09721
09723
09737 typename cimg::superset<T,float>::type cubic_pix2d(const float fx, const float fy, const int z, const int v,
09738 const T out_val) const {
09739 typedef typename cimg::superset<T,float>::type ftype;
09740 const int
09741 x = (int)fx-(fx>=0?0:1), px = x-1, nx = x+1, ax = x+2,
09742 y = (int)fy-(fy>=0?0:1), py = y-1, ny = y+1, ay = y+2;
09743 const float
09744 dx = fx-x, dx2 = dx*dx, dx3 = dx2*dx,
09745 dy = fy-y;
09746 const ftype
09747 Ipp = (ftype)pix2d(px,py,z,v,out_val), Icp = (ftype)pix2d(x,py,z,v,out_val),
09748 Inp = (ftype)pix2d(nx,py,z,v,out_val), Iap = (ftype)pix2d(ax,py,z,v,out_val),
09749 Ipc = (ftype)pix2d(px,y,z,v,out_val), Icc = (ftype)pix2d(x,y,z,v,out_val),
09750 Inc = (ftype)pix2d(nx,y,z,v,out_val), Iac = (ftype)pix2d(ax,y,z,v,out_val),
09751 Ipn = (ftype)pix2d(px,ny,z,v,out_val), Icn = (ftype)pix2d(x,ny,z,v,out_val),
09752 Inn = (ftype)pix2d(nx,ny,z,v,out_val), Ian = (ftype)pix2d(ax,ny,z,v,out_val),
09753 Ipa = (ftype)pix2d(px,ay,z,v,out_val), Ica = (ftype)pix2d(x,ay,z,v,out_val),
09754 Ina = (ftype)pix2d(nx,ay,z,v,out_val), Iaa = (ftype)pix2d(ax,ay,z,v,out_val),
09755 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)),
09756 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)),
09757 u0p = Icp - Ipp,
09758 u1p = Iap - Inp,
09759 ap = 2*(Icp-Inp) + u0p + u1p,
09760 bp = 3*(Inp-Icp) - 2*u0p - u1p,
09761 u0c = Icc - Ipc,
09762 u1c = Iac - Inc,
09763 ac = 2*(Icc-Inc) + u0c + u1c,
09764 bc = 3*(Inc-Icc) - 2*u0c - u1c,
09765 u0n = Icn - Ipn,
09766 u1n = Ian - Inn,
09767 an = 2*(Icn-Inn) + u0n + u1n,
09768 bn = 3*(Inn-Icn) - 2*u0n - u1n,
09769 u0a = Ica - Ipa,
09770 u1a = Iaa - Ina,
09771 aa = 2*(Ica-Ina) + u0a + u1a,
09772 ba = 3*(Ina-Ica) - 2*u0a - u1a,
09773 valp = ap*dx3 + bp*dx2 + u0p*dx + Icp,
09774 valc = ac*dx3 + bc*dx2 + u0c*dx + Icc,
09775 valn = an*dx3 + bn*dx2 + u0n*dx + Icn,
09776 vala = aa*dx3 + ba*dx2 + u0a*dx + Ica,
09777 u0 = valc - valp,
09778 u1 = vala - valn,
09779 a = 2*(valc-valn) + u0 + u1,
09780 b = 3*(valn-valc) - 2*u0 - u1,
09781 val = a*dy*dy*dy + b*dy*dy + u0*dy + valc;
09782 return val<valm?valm:(val>valM?valM:val);
09783 }
09784
09785 typename cimg::superset<T,float>::type cubic_pix2d(const float fx, const float fy, const int z=0, const int v=0) const {
09786 typedef typename cimg::superset<T,float>::type ftype;
09787 const float
09788 nfx = fx<0?0:(fx>width-1?width-1:fx),
09789 nfy = fy<0?0:(fy>height-1?height-1:fy);
09790 const int
09791 x = (int)nfx,
09792 y = (int)nfy;
09793 const float
09794 dx = nfx-x, dx2 = dx*dx, dx3 = dx2*dx,
09795 dy = nfy-y;
09796 const int
09797 px = x-1<0?0:x-1, nx = dx>0?x+1:x, ax = x+2>=dimx()?dimx()-1:x+2,
09798 py = y-1<0?0:y-1, ny = dy>0?y+1:y, ay = y+2>=dimy()?dimy()-1:y+2;
09799 const ftype
09800 Ipp = (ftype)(*this)(px,py,z,v), Icp = (ftype)(*this)(x,py,z,v),
09801 Inp = (ftype)(*this)(nx,py,z,v), Iap = (ftype)(*this)(ax,py,z,v),
09802 Ipc = (ftype)(*this)(px,y,z,v), Icc = (ftype)(*this)(x,y,z,v),
09803 Inc = (ftype)(*this)(nx,y,z,v), Iac = (ftype)(*this)(ax,y,z,v),
09804 Ipn = (ftype)(*this)(px,ny,z,v), Icn = (ftype)(*this)(x,ny,z,v),
09805 Inn = (ftype)(*this)(nx,ny,z,v), Ian = (ftype)(*this)(ax,ny,z,v),
09806 Ipa = (ftype)(*this)(px,ay,z,v), Ica = (ftype)(*this)(x,ay,z,v),
09807 Ina = (ftype)(*this)(nx,ay,z,v), Iaa = (ftype)(*this)(ax,ay,z,v),
09808 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)),
09809 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)),
09810 u0p = Icp - Ipp,
09811 u1p = Iap - Inp,
09812 ap = 2*(Icp-Inp) + u0p + u1p,
09813 bp = 3*(Inp-Icp) - 2*u0p - u1p,
09814 u0c = Icc - Ipc,
09815 u1c = Iac - Inc,
09816 ac = 2*(Icc-Inc) + u0c + u1c,
09817 bc = 3*(Inc-Icc) - 2*u0c - u1c,
09818 u0n = Icn - Ipn,
09819 u1n = Ian - Inn,
09820 an = 2*(Icn-Inn) + u0n + u1n,
09821 bn = 3*(Inn-Icn) - 2*u0n - u1n,
09822 u0a = Ica - Ipa,
09823 u1a = Iaa - Ina,
09824 aa = 2*(Ica-Ina) + u0a + u1a,
09825 ba = 3*(Ina-Ica) - 2*u0a - u1a,
09826 valp = ap*dx3 + bp*dx2 + u0p*dx + Icp,
09827 valc = ac*dx3 + bc*dx2 + u0c*dx + Icc,
09828 valn = an*dx3 + bn*dx2 + u0n*dx + Icn,
09829 vala = aa*dx3 + ba*dx2 + u0a*dx + Ica,
09830 u0 = valc - valp,
09831 u1 = vala - valn,
09832 a = 2*(valc-valn) + u0 + u1,
09833 b = 3*(valn-valc) - 2*u0 - u1,
09834 val = a*dy*dy*dy + b*dy*dy + u0*dy + valc;
09835 return val<valm?valm:(val>valM?valM:val);
09836 }
09837
09839 const T& max() const {
09840 if (is_empty()) throw CImgInstanceException("CImg<%s>::max() : Instance image is empty.",pixel_type());
09841 const T *ptrmax = data;
09842 T max_value = *ptrmax;
09843 cimg_for(*this,ptr,T) if ((*ptr)>max_value) max_value = *(ptrmax=ptr);
09844 return *ptrmax;
09845 }
09846
09848 T& max() {
09849 if (is_empty()) throw CImgInstanceException("CImg<%s>::max() : Instance image is empty.",pixel_type());
09850 T *ptrmax = data;
09851 T max_value = *ptrmax;
09852 cimg_for(*this,ptr,T) if ((*ptr)>max_value) max_value = *(ptrmax=ptr);
09853 return *ptrmax;
09854 }
09855
09857 const T& min() const {
09858 if (is_empty()) throw CImgInstanceException("CImg<%s>::min() : Instance image is empty.",pixel_type());
09859 const T *ptrmin = data;
09860 T min_value = *ptrmin;
09861 cimg_for(*this,ptr,T) if ((*ptr)<min_value) min_value = *(ptrmin=ptr);
09862 return *ptrmin;
09863 }
09864
09866 T& min() {
09867 if (is_empty()) throw CImgInstanceException("CImg<%s>::min() : Instance image is empty.",pixel_type());
09868 T *ptrmin = data;
09869 T min_value = *ptrmin;
09870 cimg_for(*this,ptr,T) if ((*ptr)<min_value) min_value = *(ptrmin=ptr);
09871 return *ptrmin;
09872 }
09873
09875 template<typename t> const T& minmax(t& max_val) const {
09876 if (is_empty()) throw CImgInstanceException("CImg<%s>::minmax() : Instance image is empty.",pixel_type());
09877 const T *ptrmin = data;
09878 T min_value = *ptrmin, max_value = min_value;
09879 cimg_for(*this,ptr,T) {
09880 const T val = *ptr;
09881 if (val<min_value) { min_value = val; ptrmin = ptr; }
09882 if (val>max_value) max_value = val;
09883 }
09884 max_val = (t)max_value;
09885 return *ptrmin;
09886 }
09887
09889 template<typename t> T& minmax(t& max_val) {
09890 if (is_empty()) throw CImgInstanceException("CImg<%s>::minmax() : Instance image is empty.",pixel_type());
09891 T *ptrmin = data;
09892 T min_value = *ptrmin, max_value = min_value;
09893 cimg_for(*this,ptr,T) {
09894 const T val = *ptr;
09895 if (val<min_value) { min_value = val; ptrmin = ptr; }
09896 if (val>max_value) max_value = val;
09897 }
09898 max_val = (t)max_value;
09899 return *ptrmin;
09900 }
09901
09903 template<typename t> const T& maxmin(t& min_val) const {
09904 if (is_empty()) throw CImgInstanceException("CImg<%s>::maxmin() : Instance image is empty.",pixel_type());
09905 const T *ptrmax = data;
09906 T max_value = *ptrmax, min_value = max_value;
09907 cimg_for(*this,ptr,T) {
09908 const T val = *ptr;
09909 if (val>max_value) { max_value = val; ptrmax = ptr; }
09910 if (val<min_value) min_value = val;
09911 }
09912 min_val = (t)min_value;
09913 return *ptrmax;
09914 }
09915
09917 template<typename t> T& maxmin(t& min_val) {
09918 if (is_empty()) throw CImgInstanceException("CImg<%s>::maxmin() : Instance image is empty.",pixel_type());
09919 T *ptrmax = data;
09920 T max_value = *ptrmax, min_value = max_value;
09921 cimg_for(*this,ptr,T) {
09922 const T val = *ptr;
09923 if (val>max_value) { max_value = val; ptrmax = ptr; }
09924 if (val<min_value) min_value = val;
09925 }
09926 min_val = (t)min_value;
09927 return *ptrmax;
09928 }
09929
09931 double mean() const {
09932 if (is_empty()) throw CImgInstanceException("CImg<%s>::mean() : Instance image is empty.",pixel_type());
09933 double val = 0;
09934 cimg_for(*this,ptr,T) val+=(double)*ptr;
09935 return val/size();
09936 }
09937
09939 template<typename t> double variancemean(const unsigned int variance_method, t& mean) const {
09940 if (is_empty())
09941 throw CImgInstanceException("CImg<%s>::variance() : Instance image is empty.",pixel_type());
09942 double variance = 0, average = 0;
09943 const unsigned int siz = size();
09944 switch (variance_method) {
09945 case 3: {
09946 CImg<double> buf(*this);
09947 const unsigned int siz2 = siz>>1;
09948 { cimg_for(buf,ptrs,double) { const double val = *ptrs; (*ptrs)*=val; average+=val; }}
09949 buf.sort();
09950 double a = 0;
09951 const double *ptrs = buf.ptr();
09952 for (unsigned int j=0; j<siz2; ++j) a+=(*ptrs++);
09953 const double sig = 2.6477*std::sqrt(a/siz2);
09954 variance = sig*sig;
09955 } break;
09956 case 2: {
09957 CImg<double> buf(*this);
09958 buf.sort();
09959 const unsigned int siz2 = siz>>1;
09960 const double med_i = buf[siz2];
09961 cimg_for(buf,ptrs,double) { const double val = *ptrs; *ptrs = cimg::abs(val-med_i); average+=val; }
09962 buf.sort();
09963 const double sig = 1.4828*buf[siz2];
09964 variance = sig*sig;
09965 } break;
09966 case 1: {
09967 double S = 0, S2 = 0;
09968 cimg_for(*this,ptr,T) { const double val = (double)*ptr; S+=val; S2+=val*val; }
09969 variance = siz>1?(S2 - S*S/siz)/(siz-1):0;
09970 average = S;
09971 } break;
09972 default:{
09973 double S = 0, S2 = 0;
09974 cimg_for(*this,ptr,T) { const double val = (double)*ptr; S+=val; S2+=val*val; }
09975 variance = (S2 - S*S/siz)/siz;
09976 average = S;
09977 } break;
09978 }
09979 mean = (t)(average/siz);
09980 return variance;
09981 }
09982
09984 double variance(const unsigned int variance_method=0) const {
09985 double foo;
09986 return variancemean(variance_method,foo);
09987 }
09988
09990 template<typename t> double MSE(const CImg<t>& img) const {
09991 if (img.size()!=size())
09992 throw CImgArgumentException("CImg<%s>::MSE() : Instance image (%u,%u,%u,%u) and given image (%u,%u,%u,%u) have different dimensions.",
09993 pixel_type(),width,height,depth,dim,img.width,img.height,img.depth,img.dim);
09994
09995 double vMSE = 0;
09996 const t* ptr2 = img.end();
09997 cimg_for(*this,ptr1,T) {
09998 const double diff = (double)*ptr1 - (double)*(--ptr2);
09999 vMSE += diff*diff;
10000 }
10001 vMSE/=img.size();
10002 return vMSE;
10003 }
10004
10006 template<typename t> double PSNR(const CImg<t>& img, const double valmax=255.0) const {
10007 const double vMSE = std::sqrt(MSE(img));
10008 return (vMSE!=0)?(20*std::log10(valmax/vMSE)):(cimg::type<double>::max());
10009 }
10010
10012 double trace() const {
10013 if (is_empty())
10014 throw CImgInstanceException("CImg<%s>::trace() : Instance matrix (%u,%u,%u,%u,%p) is empty.",
10015 pixel_type(),width,height,depth,dim,data);
10016 double res = 0;
10017 cimg_forX(*this,k) res+=(*this)(k,k);
10018 return res;
10019 }
10020
10022 T median() const {
10023 const unsigned int s = size();
10024 const T res = kth_smallest(s>>1);
10025 return (s%2)?res:((res+kth_smallest((s>>1)-1))/2);
10026 }
10027
10029 template<typename t> double dot(const CImg<t>& img) const {
10030 if (is_empty())
10031 throw CImgInstanceException("CImg<%s>::dot() : Instance object (%u,%u,%u,%u,%p) is empty.",
10032 pixel_type(),width,height,depth,dim,data);
10033 if (!img)
10034 throw CImgArgumentException("CImg<%s>::trace() : Specified argument (%u,%u,%u,%u,%p) is empty.",
10035 pixel_type(),img.width,img.height,img.depth,img.dim,img.data);
10036 const unsigned long nb = cimg::min(size(),img.size());
10037 double res = 0;
10038 for (unsigned long off=0; off<nb; ++off) res+=(double)data[off]*(double)img[off];
10039 return res;
10040 }
10041
10043 double det() const {
10044 if (is_empty() || width!=height || depth!=1 || dim!=1)
10045 throw CImgInstanceException("CImg<%s>::det() : Instance matrix (%u,%u,%u,%u,%p) is not square or is empty.",
10046 pixel_type(),width,height,depth,dim,data);
10047 switch (width) {
10048 case 1: return (*this)(0,0);
10049 case 2: return (*this)(0,0)*(*this)(1,1)-(*this)(0,1)*(*this)(1,0);
10050 case 3: {
10051 const double
10052 a = data[0], d = data[1], g = data[2],
10053 b = data[3], e = data[4], h = data[5],
10054 c = data[6], f = data[7], i = data[8];
10055 return i*a*e-a*h*f-i*b*d+b*g*f+c*d*h-c*g*e;
10056 }
10057 default: {
10058 typedef typename cimg::superset<T,float>::type ftype;
10059 CImg<ftype> lu(*this);
10060 CImg<unsigned int> indx;
10061 bool d;
10062 lu._LU(indx,d);
10063 double res = d?1.0:-1.0;
10064 cimg_forX(lu,i) res*=lu(i,i);
10065 return res;
10066 }
10067 }
10068 return 0;
10069 }
10070
10072 double norm(const int norm_type=2) const {
10073 if (is_empty())
10074 throw CImgInstanceException("CImg<%s>::norm() : Instance object (%u,%u,%u,%u,%p) is empty.",
10075 pixel_type(),width,height,depth,dim,data);
10076 double res = 0;
10077 switch (norm_type) {
10078 case -1: {
10079 cimg_foroff(*this,off) {
10080 const double tmp = cimg::abs((double)data[off]);
10081 if (tmp>res) res = tmp;
10082 }
10083 return res;
10084 } break;
10085 case 1 : {
10086 cimg_foroff(*this,off) res+=cimg::abs((double)data[off]);
10087 return res;
10088 } break;
10089 default: { return std::sqrt(dot(*this)); }
10090 }
10091 return 0;
10092 }
10093
10095 double sum() const {
10096 if (is_empty())
10097 throw CImgInstanceException("CImg<%s>::sum() : Instance object (%u,%u,%u,%u,%p) is empty.",
10098 pixel_type(),width,height,depth,dim,data);
10099 double res = 0;
10100 cimg_for(*this,ptr,T) res+=*ptr;
10101 return res;
10102 }
10103
10105
10106 const T kth_smallest(const unsigned int k) const {
10107 if (is_empty())
10108 throw CImgInstanceException("CImg<%s>::kth_smallest() : Instance image (%u,%u,%u,%u,%p) is empty.",
10109 pixel_type(),width,height,depth,dim,data);
10110 CImg<T> arr(*this);
10111 unsigned long l = 0, ir = size()-1;
10112 for (;;) {
10113 if (ir<=l+1) {
10114 if (ir==l+1 && arr[ir]<arr[l]) cimg::swap(arr[l],arr[ir]);
10115 return arr[k];
10116 } else {
10117 const unsigned long mid = (l+ir)>>1;
10118 cimg::swap(arr[mid],arr[l+1]);
10119 if (arr[l]>arr[ir]) cimg::swap(arr[l],arr[ir]);
10120 if (arr[l+1]>arr[ir]) cimg::swap(arr[l+1],arr[ir]);
10121 if (arr[l]>arr[l+1]) cimg::swap(arr[l],arr[l+1]);
10122 unsigned long i = l+1, j = ir;
10123 const T pivot = arr[l+1];
10124 for (;;) {
10125 do ++i; while (arr[i]<pivot);
10126 do --j; while (arr[j]>pivot);
10127 if (j<i) break;
10128 cimg::swap(arr[i],arr[j]);
10129 }
10130 arr[l+1] = arr[j];
10131 arr[j] = pivot;
10132 if (j>=k) ir=j-1;
10133 if (j<=k) l=i;
10134 }
10135 }
10136 return 0;
10137 }
10138
10140
10157 const CImg<T>& print(const char *title=0, const int print_flag=1) const {
10158 typedef typename cimg::last<T,double>::type cdouble;
10159 static CImg<cdouble> st;
10160 if (print_flag>=0) {
10161 std::fprintf(stderr,"%-8s(this=%p): { size=(%u,%u,%u,%u), data=(%s*)%p (%s)",
10162 title?title:"CImg",(void*)this,
10163 width,height,depth,dim,pixel_type(),(void*)data,
10164 is_shared?"shared":"not shared");
10165 if (is_empty()) { std::fprintf(stderr,", [Undefined pixel data] }\n"); return *this; }
10166 if (print_flag>=1) {
10167 st = get_stats();
10168 int xm, ym, zm, vm, xM, yM, zM, vM;
10169 contains(data[(int)st(4)],xm,ym,zm,vm);
10170 contains(data[(int)st(5)],xM,yM,zM,vM);
10171 std::fprintf(stderr,", min=%g, mean=%g [std=%g], max=%g, pmin=(%d,%d,%d,%d), pmax=(%d,%d,%d,%d)",
10172 st[0],st[2],std::sqrt(st[3]),st[1],xm,ym,zm,vm,xM,yM,zM,vM);
10173 }
10174 if (print_flag>=2 || size()<=16) {
10175 std::fprintf(stderr," }\n%s = [ ",title?title:"data");
10176 cimg_forXYZV(*this,x,y,z,k) {
10177 std::fprintf(stderr,cimg::type<T>::format(),cimg::type<T>::format((*this)(x,y,z,k)));
10178 std::fprintf(stderr,"%s",((x+1)*(y+1)*(z+1)*(k+1)==(int)size()?" ]\n":(((x+1)%width==0)?" ; ":" ")));
10179 }
10180 } else std::fprintf(stderr," }\n");
10181 }
10182 return *this;
10183 }
10184
10186 const CImg<T>& print(const int print_flag) const {
10187 return print(0,print_flag);
10188 }
10189
10191
10192
10194
10195
10196
10198
10205 template<typename t> CImg<T>& operator=(const CImg<t>& img) {
10206 return assign(img);
10207 }
10208
10209 CImg<T>& operator=(const CImg<T>& img) {
10210 return assign(img);
10211 }
10212
10214
10227 CImg<T>& operator=(const T *buf) {
10228 return assign(buf,width,height,depth,dim);
10229 }
10230
10232 CImg<T>& operator=(const T val) {
10233 return fill(val);
10234 }
10235
10237
10241 CImg<T> operator+() const {
10242 return CImg<T>(*this,false);
10243 }
10244
10246 #ifdef cimg_use_visualcpp6
10247 CImg<T>& operator+=(const T val) {
10248 #else
10249 template<typename t> CImg<T>& operator+=(const t val) {
10250 #endif
10251 cimg_for(*this,ptr,T) (*ptr) = (T)((*ptr)+val);
10252 return *this;
10253 }
10254
10256 template<typename t> CImg<T>& operator+=(const CImg<t>& img) {
10257 if (is_overlapping(img)) return *this+=+img;
10258 const unsigned int smin = cimg::min(size(),img.size());
10259 t *ptrs = img.data + smin;
10260 for (T *ptrd = data + smin; ptrd>data; --ptrd, (*ptrd)=(T)((*ptrd)+(*(--ptrs))));
10261 return *this;
10262 }
10263
10265 CImg<T>& operator++() {
10266 cimg_for(*this,ptr,T) ++(*ptr);
10267 return *this;
10268 }
10269
10271 CImg<T> operator++(int) {
10272 CImg<T> copy(*this,false);
10273 ++*this;
10274 return copy;
10275 }
10276
10278 CImg<T> operator-() const {
10279 return CImg<T>(width,height,depth,dim,0)-=*this;
10280 }
10281
10283 #ifdef cimg_use_visualcpp6
10284 CImg<T>& operator-=(const T val) {
10285 #else
10286 template<typename t> CImg<T>& operator-=(const t val) {
10287 #endif
10288 cimg_for(*this,ptr,T) (*ptr) = (T)((*ptr)-val);
10289 return *this;
10290 }
10291
10293 template<typename t> CImg<T>& operator-=(const CImg<t>& img) {
10294 if (is_overlapping(img)) return *this-=+img;
10295 const unsigned int smin = cimg::min(size(),img.size());
10296 t *ptrs = img.data+smin;
10297 for (T *ptrd = data+smin; ptrd>data; --ptrd, (*ptrd) = (T)((*ptrd)-(*(--ptrs))));
10298 return *this;
10299 }
10300
10302 CImg<T>& operator--() {
10303 cimg_for(*this,ptr,T) *ptr = *ptr-(T)1;
10304 return *this;
10305 }
10306
10308 CImg<T> operator--(int) {
10309 CImg<T> copy(*this,false);
10310 --*this;
10311 return copy;
10312 }
10313
10315 #ifdef cimg_use_visualcpp6
10316 CImg<T>& operator*=(const double val) {
10317 #else
10318 template<typename t> CImg<T>& operator*=(const t val) {
10319 #endif
10320 cimg_for(*this,ptr,T) (*ptr) = (T)((*ptr)*val);
10321 return *this;
10322 }
10323
10325 template<typename t> CImg<T>& operator*=(const CImg<t>& img) {
10326 return ((*this)*img).assign_to(*this);
10327 }
10328
10330 #ifdef cimg_use_visualcpp6
10331 CImg<T>& operator/=(const double val) {
10332 #else
10333 template<typename t> CImg<T>& operator/=(const t val) {
10334 #endif
10335 cimg_for(*this,ptr,T) (*ptr) = (T)((*ptr)/val);
10336 return *this;
10337 }
10338
10340 template<typename t> CImg<T>& operator/=(const CImg<t>& img) {
10341 return assign(*this*img.get_inverse());
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 CImg<T>& operator%=(const T val) {
10357 cimg_for(*this,ptr,T) (*ptr) = (T)cimg::mod(*ptr,val);
10358 return *this;
10359 }
10360
10362 template<typename t> CImg<T>& operator%=(const CImg<t>& img) {
10363 if (is_overlapping(img)) return *this%=+img;
10364 typedef typename cimg::superset<T,t>::type btype;
10365 const unsigned int smin = cimg::min(size(),img.size());
10366 const t *ptrs = img.data + smin;
10367 for (T *ptrd = data + smin; ptrd>data; ) {
10368 T& val = *(--ptrd);
10369 val = (T)cimg::mod((btype)val,(btype)*(--ptrs));
10370 }
10371 return *this;
10372 }
10373
10375 template<typename t> CImg<typename cimg::superset<T,t>::type> operator&(const CImg<t>& img) const {
10376 typedef typename cimg::superset<T,t>::type restype;
10377 return CImg<restype>(*this,false)&=img;
10378 }
10379
10381 CImg<T> operator&(const T val) const {
10382 return (+*this)&=val;
10383 }
10384
10386 template<typename t> CImg<T>& operator&=(const CImg<t>& img) {
10387 if (is_overlapping(img)) return *this&=+img;
10388 const unsigned int smin = cimg::min(size(),img.size());
10389 const t *ptrs = img.data + smin;
10390 for (T *ptrd = data + smin; ptrd>data; ) {
10391 T& val = *(--ptrd);
10392 val = (T)((unsigned long)val & (unsigned long)*(--ptrs));
10393 }
10394 return *this;
10395 }
10396
10398 CImg<T>& operator&=(const T val) {
10399 cimg_for(*this,ptr,T) *ptr = (T)((unsigned long)*ptr & (unsigned long)val);
10400 return *this;
10401 }
10402
10404 template<typename t> CImg<typename cimg::superset<T,t>::type> operator|(const CImg<t>& img) const {
10405 typedef typename cimg::superset<T,t>::type restype;
10406 return CImg<restype>(*this,false)|=img;
10407 }
10408
10410 CImg<T> operator|(const T val) const {
10411 return (+*this)|=val;
10412 }
10413
10415 template<typename t> CImg<T>& operator|=(const CImg<t>& img) {
10416 if (is_overlapping(img)) return *this|=+img;
10417 const unsigned int smin = cimg::min(size(),img.size());
10418 const t *ptrs = img.data + smin;
10419 for (T *ptrd = data + smin; ptrd>data; ) {
10420 T& val = *(--ptrd);
10421 val = (T)((unsigned long)val | (unsigned long)*(--ptrs));
10422 }
10423 return *this;
10424 }
10425
10427 CImg<T>& operator|=(const T val) {
10428 cimg_for(*this,ptr,T) *ptr = (T)((unsigned long)*ptr | (unsigned long)val);
10429 return *this;
10430 }
10431
10433 template<typename t> CImg<typename cimg::superset<T,t>::type> operator^(const CImg<t>& img) const {
10434 typedef typename cimg::superset<T,t>::type restype;
10435 return CImg<restype>(*this,false)^=img;
10436 }
10437
10439 CImg<T> operator^(const T val) const {
10440 return (+*this)^=val;
10441 }
10442
10444 template<typename t> CImg<T>& operator^=(const CImg<t>& img) {
10445 if (is_overlapping(img)) return *this^=+img;
10446 const unsigned int smin = cimg::min(size(),img.size());
10447 const t *ptrs = img.data + smin;
10448 for (T *ptrd = data+smin; ptrd>data; ) {
10449 T& val = *(--ptrd);
10450 val =(T)((unsigned long)val ^ (unsigned long)*(--ptrs));
10451 }
10452 return *this;
10453 }
10454
10456 CImg<T>& operator^=(const T val) {
10457 cimg_for(*this,ptr,T) *ptr = (T)((unsigned long)*ptr ^ (unsigned long)val);
10458 return *this;
10459 }
10460
10462 CImg<T> operator~() const {
10463 CImg<T> res(width,height,depth,dim);
10464 const T *ptrs = end();
10465 cimg_for(res,ptrd,T) *ptrd = (T)~(unsigned long)*(--ptrs);
10466 return res;
10467 }
10468
10470 CImg<T>& operator<<=(const int n) {
10471 cimg_for(*this,ptr,T) *ptr = (T)(((long)*ptr)<<n);
10472 return *this;
10473 }
10474
10476 CImg<T> operator<<(const int n) const {
10477 return (+*this)<<=n;
10478 }
10479
10481 CImg<T>& operator>>=(const int n) {
10482 cimg_for(*this,ptr,T) *ptr = (T)(((long)*ptr)>>n);
10483 return *this;
10484 }
10485
10487 CImg<T> operator>>(const int n) const {
10488 return (+*this)>>=n;
10489 }
10490
10492 template<typename t> bool operator==(const CImg<t>& img) const {
10493 const unsigned int siz = size();
10494 bool vequal = true;
10495 if (siz!=img.size()) return false;
10496 t *ptrs=img.data+siz;
10497 for (T *ptrd=data+siz; vequal && ptrd>data; vequal=vequal&&((*(--ptrd))==(*(--ptrs))));
10498 return vequal;
10499 }
10500
10502 template<typename t> bool operator!=(const CImg<t>& img) const {
10503 return !((*this)==img);
10504 }
10505
10507 template<typename t> CImgList<typename cimg::superset<T,t>::type> operator<<(const CImg<t>& img) const {
10508 typedef typename cimg::superset<T,t>::type restype;
10509 return CImgList<restype>(*this,img);
10510 }
10511
10513 template<typename t> CImgList<typename cimg::superset<T,t>::type> operator<<(const CImgList<t>& list) const {
10514 typedef typename cimg::superset<T,t>::type restype;
10515 return CImgList<restype>(list).insert(*this,0);
10516 }
10517
10519 template<typename t> CImgList<typename cimg::superset<T,t>::type> operator>>(const CImg<t>& img) const {
10520 return (*this)<<img;
10521 }
10522
10524 template<typename t> CImgList<t>& operator>>(const CImgList<t>& list) const {
10525 return list.insert(*this,0);
10526 }
10527
10529 const CImg<T>& operator>>(CImgDisplay& disp) const {
10530 return display(disp);
10531 }
10532
10534
10535
10537
10538
10539
10541 template<typename t> CImg<T> get_apply(t& func) const {
10542 return (+*this).apply(func);
10543 }
10544
10546 template<typename t> CImg<T>& apply(t& func) {
10547 cimg_for(*this,ptr,T) *ptr = func(*ptr);
10548 return *this;
10549 }
10550
10552 template<typename t> CImg<typename cimg::superset<T,t>::type> get_mul(const CImg<t>& img) const {
10553 typedef typename cimg::superset<T,t>::type restype;
10554 return CImg<restype>(*this,false).mul(img);
10555 }
10556
10558 template<typename t> CImg<T>& mul(const CImg<t>& img) {
10559 if (is_overlapping(img)) return mul(+img);
10560 t *ptrs = img.data;
10561 T *ptrf = data + cimg::min(size(),img.size());
10562 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = (T)(*ptrd*(*(ptrs++)));
10563 return *this;
10564 }
10565
10567 template<typename t> CImg<typename cimg::superset<T,t>::type> get_div(const CImg<t>& img) const {
10568 typedef typename cimg::superset<T,t>::type restype;
10569 return CImg<restype>(*this,false).div(img);
10570 }
10571
10573 template<typename t> CImg<T>& div(const CImg<t>& img) {
10574 if (is_overlapping(img)) return div(+img);
10575 t *ptrs = img.data;
10576 T *ptrf = data + cimg::min(size(),img.size());
10577 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = (T)(*ptrd/(*(ptrs++)));
10578 return *this;
10579 }
10580
10582 template<typename t> CImg<typename cimg::superset<T,t>::type> get_max(const CImg<t>& img) const {
10583 typedef typename cimg::superset<T,t>::type restype;
10584 return CImg<restype>(*this,false).max(img);
10585 }
10586
10588 template<typename t> CImg<T>& max(const CImg<t>& img) {
10589 if (is_overlapping(img)) return max(+img);
10590 t *ptrs = img.data;
10591 T *ptrf = data + cimg::min(size(),img.size());
10592 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = cimg::max((T)*(ptrs++),*ptrd);
10593 return *this;
10594 }
10595
10597 CImg<T> get_max(const T val) const {
10598 return (+*this).max(val);
10599 }
10600
10602 CImg<T>& max(const T val) {
10603 cimg_for(*this,ptr,T) (*ptr) = cimg::max(*ptr,val);
10604 return *this;
10605 }
10606
10608 template<typename t> CImg<typename cimg::superset<T,t>::type> get_min(const CImg<t>& img) const {
10609 typedef typename cimg::superset<T,t>::type restype;
10610 return CImg<restype>(*this,false).min(img);
10611 }
10612
10614 template<typename t> CImg<T>& min(const CImg<t>& img) {
10615 if (is_overlapping(img)) return min(+img);
10616 t *ptrs = img.data;
10617 T *ptrf = data + cimg::min(size(),img.size());
10618 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = cimg::min((T)*(ptrs++),*ptrd);
10619 return *this;
10620 }
10621
10623 CImg<T> get_min(const T val) const {
10624 return (+*this).min(val);
10625 }
10626
10628 CImg<T>& min(const T val) {
10629 cimg_for(*this,ptr,T) (*ptr) = cimg::min(*ptr,val);
10630 return *this;
10631 }
10632
10634 CImg<typename cimg::last<T,double>::type> get_stats() const {
10635 typedef typename cimg::last<T,double>::type restype;
10636 return CImg<restype>(*this).stats();
10637 }
10638
10640 CImg<T>& stats() {
10641 if (is_empty())
10642 throw CImgInstanceException("CImg<%s>::stats() : Instance image is empty.",pixel_type());
10643 const unsigned long siz = size();
10644 const T *pm = data, *pM = pm;
10645 double S = 0, S2 = 0;
10646 T m = *pm, M = m;
10647 cimg_for(*this,ptr,T) {
10648 const T val = *ptr;
10649 const double fval = (double)val;
10650 if (val<m) { m = val; pm = ptr; }
10651 if (val>M) { M = val; pM = ptr; }
10652 S+=fval;
10653 S2+=fval*fval;
10654 }
10655 return assign(1,6).fill((T)m,(T)M,(T)(S/siz),(T)((S2-S*S/siz)/siz),(T)(pm-data),(T)(pM-data));
10656 }
10657
10659 CImg<typename cimg::superset<T,float>::type> get_sqr() const {
10660 typedef typename cimg::superset<T,float>::type restype;
10661 return CImg<restype>(*this,false).sqr();
10662 }
10663
10665 CImg<T>& sqr() {
10666 cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = (T)(val*val); };
10667 return *this;
10668 }
10669
10671 CImg<typename cimg::superset<T,float>::type> get_sqrt() const {
10672 typedef typename cimg::superset<T,float>::type restype;
10673 return CImg<restype>(*this,false).sqrt();
10674 }
10675
10677 CImg<T>& sqrt() {
10678 cimg_for(*this,ptr,T) (*ptr) = (T)std::sqrt((double)(*ptr));
10679 return *this;
10680 }
10681
10683 CImg<typename cimg::superset<T,float>::type> get_exp() const {
10684 typedef typename cimg::superset<T,float>::type restype;
10685 return CImg<restype>(*this,false).exp();
10686 }
10687
10689 CImg<T>& exp() {
10690 cimg_for(*this,ptr,T) (*ptr) = (T)std::exp((double)(*ptr));
10691 return *this;
10692 }
10693
10695 CImg<typename cimg::superset<T,float>::type> get_log() const {
10696 typedef typename cimg::superset<T,float>::type restype;
10697 return CImg<restype>(*this,false).log();
10698 }
10699
10701 CImg<T>& log() {
10702 cimg_for(*this,ptr,T) (*ptr) = (T)std::log((double)(*ptr));
10703 return *this;
10704 }
10705
10707 CImg<typename cimg::superset<T,float>::type> get_log10() const {
10708 typedef typename cimg::superset<T,float>::type restype;
10709 return CImg<restype>(*this,false).log10();
10710 }
10711
10713 CImg<T>& log10() {
10714 cimg_for(*this,ptr,T) (*ptr) = (T)std::log10((double)(*ptr));
10715 return *this;
10716 }
10717
10719 CImg<typename cimg::superset<T,float>::type> get_pow(const double p) const {
10720 typedef typename cimg::superset<T,float>::type restype;
10721 return CImg<restype>(*this,false).pow(p);
10722 }
10723
10725 CImg<T>& pow(const double p) {
10726 if (p==0) return fill(1);
10727 if (p==0.5) { cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = (T)std::sqrt((double)val); } return *this; }
10728 if (p==1) return *this;
10729 if (p==2) { cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = val*val; } return *this; }
10730 if (p==3) { cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = val*val*val; } return *this; }
10731 if (p==4) { cimg_for(*this,ptr,T) { const T val = *ptr; *ptr = val*val*val*val; } return *this; }
10732 cimg_for(*this,ptr,T) (*ptr) = (T)std::pow((double)(*ptr),p);
10733 return *this;
10734 }
10735
10737 template<typename t> CImg<typename cimg::superset<T,float>::type> get_pow(const CImg<t>& img) const {
10738 typedef typename cimg::superset<T,float>::type restype;
10739 return CImg<restype>(*this,false).pow(img);
10740 }
10741
10743 template<typename t> CImg<T>& pow(const CImg<t>& img) {
10744 if (is_overlapping(img)) return pow(+img);
10745 t *ptrs = img.data;
10746 T *ptrf = data + cimg::min(size(),img.size());
10747 for (T* ptrd = data; ptrd<ptrf; ++ptrd) (*ptrd) = (T)std::pow((double)*ptrd,(double)(*(ptrs++)));
10748 return *this;
10749 }
10750
10752 CImg<typename cimg::superset<T,float>::type> get_abs() const {
10753 typedef typename cimg::superset<T,float>::type restype;
10754 return CImg<restype>(*this,false).abs();
10755 }
10756
10758 CImg<T>& abs() {
10759 cimg_for(*this,ptr,T) (*ptr) = cimg::abs(*ptr);
10760 return *this;
10761 }
10762
10764 CImg<typename cimg::superset<T,float>::type> get_cos() const {
10765 typedef typename cimg::superset<T,float>::type restype;
10766 return CImg<restype>(*this,false).cos();
10767 }
10768
10770 CImg<T>& cos() {
10771 cimg_for(*this,ptr,T) (*ptr) = (T)std::cos((double)(*ptr));
10772 return *this;
10773 }
10774
10776 CImg<typename cimg::superset<T,float>::type> get_sin() const {
10777 typedef typename cimg::superset<T,float>::type restype;
10778 return CImg<restype>(*this,false).sin();
10779 }
10780
10782 CImg<T>& sin() {
10783 cimg_for(*this,ptr,T) (*ptr) = (T)std::sin((double)(*ptr));
10784 return *this;
10785 }
10786
10788 CImg<typename cimg::superset<T,float>::type> get_tan() const {
10789 typedef typename cimg::superset<T,float>::type restype;
10790 return CImg<restype>(*this,false).tan();
10791 }
10792
10794 CImg<T>& tan() {
10795 cimg_for(*this,ptr,T) (*ptr) = (T)std::tan((double)(*ptr));
10796 return *this;
10797 }
10798
10800 CImg<typename cimg::superset<T,float>::type> get_acos() const {
10801 typedef typename cimg::superset<T,float>::type restype;
10802 return CImg<restype>(*this,false).acos();
10803 }
10804
10806 CImg<T>& acos() {
10807 cimg_for(*this,ptr,T) (*ptr) = (T)std::acos((double)(*ptr));
10808 return *this;
10809 }
10810
10812 CImg<typename cimg::superset<T,float>::type> get_asin() const {
10813 typedef typename cimg::superset<T,float>::type restype;
10814 return CImg<restype>(*this,false).asin();
10815 }
10816
10818 CImg<T>& asin() {
10819 cimg_for(*this,ptr,T) (*ptr) = (T)std::asin((double)(*ptr));
10820 return *this;
10821 }
10822
10824 CImg<typename cimg::superset<T,float>::type> get_atan() const {
10825 typedef typename cimg::superset<T,float>::type restype;
10826 return CImg<restype>(*this,false).atan();
10827 }
10828
10830 CImg<T>& atan() {
10831 cimg_for(*this,ptr,T) (*ptr) = (T)std::atan((double)(*ptr));
10832 return *this;
10833 }
10834
10836
10840 CImg<T> get_round(const float x, const unsigned int round_type=0) const {
10841 return (+*this).round(x,round_type);
10842 }
10843
10845 CImg<T>& round(const float x, const unsigned int round_type=0) {
10846 cimg_for(*this,ptr,T) (*ptr) = (T)cimg::round(*ptr,x,round_type);
10847 return *this;
10848 }
10849
10851 CImg<T> get_rand(const T val_min, const T val_max) const {
10852 return (+*this).rand(val_min,val_max);
10853 }
10854
10856 CImg<T>& rand(const T val_min, const T val_max) {
10857 const float delta = (float)val_max - (float)val_min;
10858 cimg_for(*this,ptr,T) *ptr = (T)(val_min + cimg::rand()*delta);
10859 return *this;
10860 }
10861
10863
10864
10866
10867
10868
10870
10875 CImg<T> get_fill(const T val) const {
10876 return CImg<T>(width,height,depth,dim).fill(val);
10877 }
10878
10880 CImg<T>& fill(const T val) {
10881 if (!is_empty()) {
10882 if (val && sizeof(T)!=1) cimg_for(*this,ptr,T) *ptr = val;
10883 else std::memset(data,(int)val,size()*sizeof(T));
10884 }
10885 return *this;
10886 }
10887
10889 CImg<T> get_fill(const T val0, const T val1) const {
10890 return CImg<T>(width,height,depth,dim).fill(val0,val1);
10891 }
10892
10894 CImg<T>& fill(const T val0, const T val1) {
10895 if (!is_empty()) {
10896 T *ptr, *ptr_end = end()-1;
10897 for (ptr=data; ptr<ptr_end; ) { *(ptr++) = val0; *(ptr++) = val1; }
10898 if (ptr!=ptr_end+1) *(ptr++) = val0;
10899 }
10900 return *this;
10901 }
10902
10904 CImg<T> get_fill(const T val0, const T val1, const T val2) const {
10905 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2);
10906 }
10907
10909 CImg<T>& fill(const T val0, const T val1, const T val2) {
10910 if (!is_empty()) {
10911 T *ptr, *ptr_end = end()-2;
10912 for (ptr=data; ptr<ptr_end; ) { *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; }
10913 ptr_end+=2;
10914 switch (ptr_end-ptr) {
10915 case 2: *(--ptr_end) = val1;
10916 case 1: *(--ptr_end) = val0;
10917 }
10918 }
10919 return *this;
10920 }
10921
10923 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3) const {
10924 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3);
10925 }
10926
10928 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3) {
10929 if (!is_empty()) {
10930 T *ptr, *ptr_end = end()-3;
10931 for (ptr=data; ptr<ptr_end; ) { *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; }
10932 ptr_end+=3;
10933 switch (ptr_end-ptr) {
10934 case 3: *(--ptr_end) = val2;
10935 case 2: *(--ptr_end) = val1;
10936 case 1: *(--ptr_end) = val0;
10937 }
10938 }
10939 return *this;
10940 }
10941
10943 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4) const {
10944 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4);
10945 }
10946
10948 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4) {
10949 if (!is_empty()) {
10950 T *ptr, *ptr_end = end()-4;
10951 for (ptr=data; ptr<ptr_end; ) { *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; }
10952 ptr_end+=4;
10953 switch (ptr_end-ptr) {
10954 case 4: *(--ptr_end) = val3;
10955 case 3: *(--ptr_end) = val2;
10956 case 2: *(--ptr_end) = val1;
10957 case 1: *(--ptr_end) = val0;
10958 }
10959 }
10960 return *this;
10961 }
10962
10964 CImg<T> get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5) const {
10965 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5);
10966 }
10967
10969 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5) {
10970 if (!is_empty()) {
10971 T *ptr, *ptr_end = end()-5;
10972 for (ptr=data; ptr<ptr_end; ) {
10973 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
10974 }
10975 ptr_end+=5;
10976 switch (ptr_end-ptr) {
10977 case 5: *(--ptr_end) = val4;
10978 case 4: *(--ptr_end) = val3;
10979 case 3: *(--ptr_end) = val2;
10980 case 2: *(--ptr_end) = val1;
10981 case 1: *(--ptr_end) = val0;
10982 }
10983 }
10984 return *this;
10985 }
10986
10988 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 {
10989 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6);
10990 }
10991
10993 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6) {
10994 if (!is_empty()) {
10995 T *ptr, *ptr_end = end()-6;
10996 for (ptr=data; ptr<ptr_end; ) {
10997 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5; *(ptr++) = val6;
10998 }
10999 ptr_end+=6;
11000 switch (ptr_end-ptr) {
11001 case 6: *(--ptr_end) = val5;
11002 case 5: *(--ptr_end) = val4;
11003 case 4: *(--ptr_end) = val3;
11004 case 3: *(--ptr_end) = val2;
11005 case 2: *(--ptr_end) = val1;
11006 case 1: *(--ptr_end) = val0;
11007 }
11008 }
11009 return *this;
11010 }
11011
11013 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,
11014 const T val7) const {
11015 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7);
11016 }
11017
11019 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11020 const T val7) {
11021 if (!is_empty()) {
11022 T *ptr, *ptr_end = end()-7;
11023 for (ptr=data; ptr<ptr_end; ) {
11024 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3;
11025 *(ptr++) = val4; *(ptr++) = val5; *(ptr++) = val6; *(ptr++) = val7;
11026 }
11027 ptr_end+=7;
11028 switch (ptr_end-ptr) {
11029 case 7: *(--ptr_end) = val6;
11030 case 6: *(--ptr_end) = val5;
11031 case 5: *(--ptr_end) = val4;
11032 case 4: *(--ptr_end) = val3;
11033 case 3: *(--ptr_end) = val2;
11034 case 2: *(--ptr_end) = val1;
11035 case 1: *(--ptr_end) = val0;
11036 }
11037 }
11038 return *this;
11039 }
11040
11042 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,
11043 const T val7, const T val8) const {
11044 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8);
11045 }
11046
11048 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11049 const T val7, const T val8) {
11050 if (!is_empty()) {
11051 T *ptr, *ptr_end = end()-8;
11052 for (ptr=data; ptr<ptr_end; ) {
11053 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2;
11054 *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11055 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8;
11056 }
11057 ptr_end+=8;
11058 switch (ptr_end-ptr) {
11059 case 8: *(--ptr_end) = val7;
11060 case 7: *(--ptr_end) = val6;
11061 case 6: *(--ptr_end) = val5;
11062 case 5: *(--ptr_end) = val4;
11063 case 4: *(--ptr_end) = val3;
11064 case 3: *(--ptr_end) = val2;
11065 case 2: *(--ptr_end) = val1;
11066 case 1: *(--ptr_end) = val0;
11067 }
11068 }
11069 return *this;
11070 }
11071
11073 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,
11074 const T val7, const T val8, const T val9) const {
11075 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9);
11076 }
11077
11079 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11080 const T val7, const T val8, const T val9) {
11081 if (!is_empty()) {
11082 T *ptr, *ptr_end = end()-9;
11083 for (ptr=data; ptr<ptr_end; ) {
11084 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4;
11085 *(ptr++) = val5; *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9;
11086 }
11087 ptr_end+=9;
11088 switch (ptr_end-ptr) {
11089 case 9: *(--ptr_end) = val8;
11090 case 8: *(--ptr_end) = val7;
11091 case 7: *(--ptr_end) = val6;
11092 case 6: *(--ptr_end) = val5;
11093 case 5: *(--ptr_end) = val4;
11094 case 4: *(--ptr_end) = val3;
11095 case 3: *(--ptr_end) = val2;
11096 case 2: *(--ptr_end) = val1;
11097 case 1: *(--ptr_end) = val0;
11098 }
11099 }
11100 return *this;
11101 }
11102
11104 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,
11105 const T val7, const T val8, const T val9, const T val10) const {
11106 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10);
11107 }
11108
11110 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11111 const T val7, const T val8, const T val9, const T val10) {
11112 if (!is_empty()) {
11113 T *ptr, *ptr_end = end()-10;
11114 for (ptr=data; ptr<ptr_end; ) {
11115 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4;
11116 *(ptr++) = val5; *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9;
11117 *(ptr++) = val10;
11118 }
11119 ptr_end+=10;
11120 switch (ptr_end-ptr) {
11121 case 10: *(--ptr_end) = val9;
11122 case 9: *(--ptr_end) = val8;
11123 case 8: *(--ptr_end) = val7;
11124 case 7: *(--ptr_end) = val6;
11125 case 6: *(--ptr_end) = val5;
11126 case 5: *(--ptr_end) = val4;
11127 case 4: *(--ptr_end) = val3;
11128 case 3: *(--ptr_end) = val2;
11129 case 2: *(--ptr_end) = val1;
11130 case 1: *(--ptr_end) = val0;
11131 }
11132 }
11133 return *this;
11134 }
11135
11137 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,
11138 const T val7, const T val8, const T val9, const T val10, const T val11) const {
11139 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11);
11140 }
11141
11143 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11144 const T val7, const T val8, const T val9, const T val10, const T val11) {
11145 if (!is_empty()) {
11146 T *ptr, *ptr_end = end()-11;
11147 for (ptr=data; ptr<ptr_end; ) {
11148 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11149 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11150 }
11151 ptr_end+=11;
11152 switch (ptr_end-ptr) {
11153 case 11: *(--ptr_end) = val10;
11154 case 10: *(--ptr_end) = val9;
11155 case 9: *(--ptr_end) = val8;
11156 case 8: *(--ptr_end) = val7;
11157 case 7: *(--ptr_end) = val6;
11158 case 6: *(--ptr_end) = val5;
11159 case 5: *(--ptr_end) = val4;
11160 case 4: *(--ptr_end) = val3;
11161 case 3: *(--ptr_end) = val2;
11162 case 2: *(--ptr_end) = val1;
11163 case 1: *(--ptr_end) = val0;
11164 }
11165 }
11166 return *this;
11167 }
11168
11170 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,
11171 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12) const {
11172 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12);
11173 }
11174
11176 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11177 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12) {
11178 if (!is_empty()) {
11179 T *ptr, *ptr_end = end()-12;
11180 for (ptr=data; ptr<ptr_end; ) {
11181 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11182 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11183 *(ptr++) = val12;
11184 }
11185 ptr_end+=12;
11186 switch (ptr_end-ptr) {
11187 case 12: *(--ptr_end) = val11;
11188 case 11: *(--ptr_end) = val10;
11189 case 10: *(--ptr_end) = val9;
11190 case 9: *(--ptr_end) = val8;
11191 case 8: *(--ptr_end) = val7;
11192 case 7: *(--ptr_end) = val6;
11193 case 6: *(--ptr_end) = val5;
11194 case 5: *(--ptr_end) = val4;
11195 case 4: *(--ptr_end) = val3;
11196 case 3: *(--ptr_end) = val2;
11197 case 2: *(--ptr_end) = val1;
11198 case 1: *(--ptr_end) = val0;
11199 }
11200 }
11201 return *this;
11202 }
11203
11205 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,
11206 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11207 const T val13) const {
11208 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13);
11209 }
11210
11212 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11213 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11214 const T val13) {
11215 if (!is_empty()) {
11216 T *ptr, *ptr_end = end()-13;
11217 for (ptr=data; ptr<ptr_end; ) {
11218 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11219 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11220 *(ptr++) = val12; *(ptr++) = val13;
11221 }
11222 ptr_end+=13;
11223 switch (ptr_end-ptr) {
11224 case 13: *(--ptr_end) = val12;
11225 case 12: *(--ptr_end) = val11;
11226 case 11: *(--ptr_end) = val10;
11227 case 10: *(--ptr_end) = val9;
11228 case 9: *(--ptr_end) = val8;
11229 case 8: *(--ptr_end) = val7;
11230 case 7: *(--ptr_end) = val6;
11231 case 6: *(--ptr_end) = val5;
11232 case 5: *(--ptr_end) = val4;
11233 case 4: *(--ptr_end) = val3;
11234 case 3: *(--ptr_end) = val2;
11235 case 2: *(--ptr_end) = val1;
11236 case 1: *(--ptr_end) = val0;
11237 }
11238 }
11239 return *this;
11240 }
11241
11243 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,
11244 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11245 const T val13, const T val14) const {
11246 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14);
11247 }
11248
11250 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11251 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11252 const T val13, const T val14) {
11253 if (!is_empty()) {
11254 T *ptr, *ptr_end = end()-14;
11255 for (ptr=data; ptr<ptr_end; ) {
11256 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11257 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11258 *(ptr++) = val12; *(ptr++) = val13; *(ptr++) = val14;
11259 }
11260 ptr_end+=14;
11261 switch (ptr_end-ptr) {
11262 case 14: *(--ptr_end) = val13;
11263 case 13: *(--ptr_end) = val12;
11264 case 12: *(--ptr_end) = val11;
11265 case 11: *(--ptr_end) = val10;
11266 case 10: *(--ptr_end) = val9;
11267 case 9: *(--ptr_end) = val8;
11268 case 8: *(--ptr_end) = val7;
11269 case 7: *(--ptr_end) = val6;
11270 case 6: *(--ptr_end) = val5;
11271 case 5: *(--ptr_end) = val4;
11272 case 4: *(--ptr_end) = val3;
11273 case 3: *(--ptr_end) = val2;
11274 case 2: *(--ptr_end) = val1;
11275 case 1: *(--ptr_end) = val0;
11276 }
11277 }
11278 return *this;
11279 }
11280
11282 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,
11283 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11284 const T val13, const T val14, const T val15) const {
11285 return CImg<T>(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14,val15);
11286 }
11287
11289 CImg<T>& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6,
11290 const T val7, const T val8, const T val9, const T val10, const T val11, const T val12,
11291 const T val13, const T val14, const T val15) {
11292 if (!is_empty()) {
11293 T *ptr, *ptr_end = end()-15;
11294 for (ptr=data; ptr<ptr_end; ) {
11295 *(ptr++) = val0; *(ptr++) = val1; *(ptr++) = val2; *(ptr++) = val3; *(ptr++) = val4; *(ptr++) = val5;
11296 *(ptr++) = val6; *(ptr++) = val7; *(ptr++) = val8; *(ptr++) = val9; *(ptr++) = val10; *(ptr++) = val11;
11297 *(ptr++) = val12; *(ptr++) = val13; *(ptr++) = val14; *(ptr++) = val15;
11298 }
11299 ptr_end+=15;
11300 switch (ptr_end-ptr) {
11301 case 15: *(--ptr_end) = val14;
11302 case 14: *(--ptr_end) = val13;
11303 case 13: *(--ptr_end) = val12;
11304 case 12: *(--ptr_end) = val11;
11305 case 11: *(--ptr_end) = val10;
11306 case 10: *(--ptr_end) = val9;
11307 case 9: *(--ptr_end) = val8;
11308 case 8: *(--ptr_end) = val7;
11309 case 7: *(--ptr_end) = val6;
11310 case 6: *(--ptr_end) = val5;
11311 case 5: *(--ptr_end) = val4;
11312 case 4: *(--ptr_end) = val3;
11313 case 3: *(--ptr_end) = val2;
11314 case 2: *(--ptr_end) = val1;
11315 case 1: *(--ptr_end) = val0;
11316 }
11317 }
11318 return *this;
11319 }
11320
11322 template<int N> CImg<T> get_fill(const int val0, ...) const {
11323 CImg<T> res(*this,false);
11324 va_list ap;
11325 va_start(ap,val0);
11326 res._fill<N,int>(val0,ap);
11327 va_end(ap);
11328 return res;
11329 }
11330
11332 template<int N> CImg<T>& fill(const int val0, ...) {
11333 va_list ap;
11334 va_start(ap,val0);
11335 _fill<N,int>(val0,ap);
11336 va_end(ap);
11337 return *this;
11338 }
11339
11341 template<int N> CImg<T> get_fill(const double val0, ...) const {
11342 CImg<T> res(*this,false);
11343 va_list ap;
11344 va_start(ap,val0);
11345 res._fill<N,double>(val0,ap);
11346 va_end(ap);
11347 return res;
11348 }
11349
11351 template<int N> CImg<T>& fill(const double val0, ...) {
11352 va_list ap;
11353 va_start(ap,val0);
11354 _fill<N,double>(val0,ap);
11355 va_end(ap);
11356 return *this;
11357 }
11358
11359 template<int N, typename t> CImg<T>& _fill(const t val0, va_list &ap) {
11360 if (N>0 && !is_empty()) {
11361 CImg<T> vals(N);
11362 T *ptrs = vals.data;
11363 *(ptrs++) = (T)val0;
11364 for (int i=1; i<N; ++i) *(ptrs++) = (T)va_arg(ap,t);
11365 ptrs-=N;
11366 T *ptr, *ptr_end = end()+1-N;
11367 for (ptr=data; ptr<ptr_end; ) { ptrs = vals.data; for (int i=0; i<N; ++i) *(ptr++) = *(ptrs++); }
11368 ptr_end+=N-1;
11369 ptrs = vals.data;
11370 for (int i = ptr_end-ptr; i>0; --i) *(ptr++) = *(ptrs++);
11371 }
11372 return *this;
11373 }
11374
11376 CImg<T>& fillV(const unsigned int x, const unsigned int y, const unsigned int z, const int a0, ...) {
11377
11378 #define _cimg_fillv(x,y,z,a0,t) if (x<width && y<height && z<depth) { \
11379 va_list ap; va_start(ap,a0); \
11380 const unsigned int whz = width*height*depth; \
11381 T *ptrd = ptr(x,y,z,0); *ptrd = (T)a0; \
11382 for (unsigned int k=1; k<dim; ++k) { ptrd+=whz; *ptrd = (T)va_arg(ap,t); } \
11383 va_end(ap); }
11384 _cimg_fillv(x,y,z,a0,int);
11385 return *this;
11386 }
11387
11389 CImg<T>& fillV(const unsigned int x, const unsigned int y, const unsigned int z, const double a0, ...) {
11390 _cimg_fillv(x,y,z,a0,double);
11391 return *this;
11392 }
11393
11395 CImg<T>& fillZV(const unsigned int x, const unsigned int y, const int a0, ...) {
11396
11397 #define _cimg_fillzv(x,y,a0,t) if (x<width && y<height) { \
11398 va_list ap; va_start(ap,a0); \
11399 const unsigned int wh = width*height, zd = depth*dim; \
11400 T *ptrd = ptr(x,y,0,0); *ptrd = (T)a0; \
11401 for (unsigned int k=1; k<zd; ++k) { ptrd+=wh; *ptrd = (T)va_arg(ap,t); } \
11402 va_end(ap); }
11403 _cimg_fillzv(x,y,a0,int);
11404 return *this;
11405 }
11406
11408 CImg<T>& fillZV(const unsigned int x, const unsigned int y, const double a0, ...) {
11409 _cimg_fillzv(x,y,a0,double);
11410 return *this;
11411 }
11412
11414 CImg<T>& fillYZV(const unsigned int x, const int a0, ...) {
11415 #define _cimg_fillyzv(x,a0,t) if (x<width) { \
11416 va_list ap; va_start(ap,a0); \
11417 const unsigned int hzd = height*depth*dim; \
11418 T *ptrd = ptr(x,0,0,0); *ptrd = (T)a0; \
11419 for (unsigned int k=1; k<hzd; ++k) { ptrd+=width; *ptrd = (T)va_arg(ap,t); } \
11420 va_end(ap); \
11421 }
11422 _cimg_fillyzv(x,a0,int);
11423 return *this;
11424 }
11425
11427 CImg<T>& fillYZV(const unsigned int x, const double a0, ...) {
11428 _cimg_fillyzv(x,a0,double);
11429 return *this;
11430 }
11431
11433
11437 CImg<T> get_normalize(const T a, const T b) const {
11438 return (+*this).normalize(a,b);
11439 }
11440
11442 CImg<T>& normalize(const T a, const T b) {
11443 if (!is_empty()) {
11444 typedef typename cimg::superset<T,float>::type ftype;
11445 T m, M = maxmin(m);
11446 const ftype fm = (ftype)m, fM = (ftype)M;
11447 if (m==M) return fill(0);
11448 if (m!=a || M!=b) cimg_for(*this,ptr,T) *ptr = (T)((*ptr-fm)/(fM-fm)*(b-a)+a);
11449 }
11450 return *this;
11451 }
11452
11454
11458 CImg<T> get_cut(const T a, const T b) const {
11459 return (+*this).cut(a,b);
11460 }
11461
11463 CImg<T>& cut(const T a, const T b) {
11464 if (!is_empty())
11465 cimg_for(*this,ptr,T) *ptr = (*ptr<a)?a:((*ptr>b)?b:*ptr);
11466 return *this;
11467 }
11468
11470
11474 CImg<T> get_quantize(const unsigned int n=256, const bool keep_range=true) const {
11475 return (+*this).quantize(n,keep_range);
11476 }
11477
11479 CImg<T>& quantize(const unsigned int n=256, const bool keep_range=true) {
11480 if (!is_empty()) {
11481 if (!n) throw CImgArgumentException("CImg<%s>::quantize() : Cannot quantize image to 0 values.",
11482 pixel_type());
11483 typedef typename cimg::superset<T,float>::type ftype;
11484 ftype m, M = (ftype)maxmin(m), range = M - m;
11485 if (range>0) {
11486 if (keep_range) cimg_for(*this,ptr,T) {
11487 const unsigned int val = (unsigned int)((*ptr-m)*n/range);
11488 *ptr = (T)(m + cimg::min(val,n-1)*range/n);
11489 } else cimg_for(*this,ptr,T) {
11490 const unsigned int val = (unsigned int)((*ptr-m)*n/range);
11491 *ptr = (T)cimg::min(val,n-1);
11492 }
11493 }
11494 }
11495 return *this;
11496 }
11497
11499
11502 CImg<T> get_threshold(const T thres) const {
11503 return (+*this).threshold(thres);
11504 }
11505
11507 CImg<T>& threshold(const T thres) {
11508 if (!is_empty()) cimg_for(*this,ptr,T) *ptr = *ptr<=thres?(T)0:(T)1;
11509 return *this;
11510 }
11511
11513
11521 CImg<T> get_rotate(const float angle, const unsigned int cond=3) const {
11522 if (is_empty()) return CImg<T>();
11523 CImg<T> dest;
11524 const float nangle = cimg::mod(angle,360.0f), rad = (float)((nangle*cimg::PI)/180.0),
11525 ca=(float)std::cos(rad), sa=(float)std::sin(rad);
11526 if (cond!=1 && cimg::mod(nangle,90.0f)==0) {
11527 const int wm1 = dimx()-1, hm1 = dimy()-1;
11528 const int iangle = (int)nangle/90;
11529 switch (iangle) {
11530 case 1: {
11531 dest.assign(height,width,depth,dim);
11532 cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(y,hm1-x,z,v);
11533 } break;
11534 case 2: {
11535 dest.assign(width,height,depth,dim);
11536 cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(wm1-x,hm1-y,z,v);
11537 } break;
11538 case 3: {
11539 dest.assign(height,width,depth,dim);
11540 cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(wm1-y,x,z,v);
11541 } break;
11542 default:
11543 return *this;
11544 }
11545 } else {
11546 const float
11547 ux = (float)(cimg::abs(width*ca)), uy = (float)(cimg::abs(width*sa)),
11548 vx = (float)(cimg::abs(height*sa)), vy = (float)(cimg::abs(height*ca)),
11549 w2 = 0.5f*width, h2 = 0.5f*height,
11550 dw2 = 0.5f*(ux+vx), dh2 = 0.5f*(uy+vy);
11551 dest.assign((int)(ux+vx), (int)(uy+vy),depth,dim);
11552 switch (cond) {
11553 case 0: {
11554 cimg_forXY(dest,x,y)
11555 cimg_forZV(*this,z,v)
11556 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);
11557 } break;
11558 case 1: {
11559 cimg_forXY(dest,x,y)
11560 cimg_forZV(*this,z,v)
11561 dest(x,y,z,v) = (*this)(cimg::mod((int)(w2 + (x-dw2)*ca + (y-dh2)*sa),dimx()),
11562 cimg::mod((int)(h2 - (x-dw2)*sa + (y-dh2)*ca),dimy()),z,v);
11563 } break;
11564 case 2: {
11565 cimg_forXY(dest,x,y) {
11566 const float X = w2 + (x-dw2)*ca + (y-dh2)*sa, Y = h2 - (x-dw2)*sa + (y-dh2)*ca;
11567 cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)linear_pix2d(X,Y,z,v,0);
11568 }
11569 } break;
11570 default: {
11571 cimg_forXY(dest,x,y) {
11572 const float X = w2 + (x-dw2)*ca + (y-dh2)*sa, Y = h2 - (x-dw2)*sa + (y-dh2)*ca;
11573 cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)cubic_pix2d(X,Y,z,v,0);
11574 }
11575 } break;
11576 }
11577 }
11578 return dest;
11579 }
11580
11582 CImg<T>& rotate(const float angle, const unsigned int cond=3) {
11583 return get_rotate(angle,cond).assign_to(*this);
11584 }
11585
11587
11598 CImg<T> get_rotate(const float angle, const float cx, const float cy, const float zoom=1, const unsigned int cond=3) const {
11599 if (is_empty()) return CImg<T>();
11600 CImg<T> dest(width,height,depth,dim);
11601 const float nangle = cimg::mod(angle,360.0f), rad = (float)((nangle*cimg::PI)/180.0),
11602 ca=(float)std::cos(rad)/zoom, sa=(float)std::sin(rad)/zoom;
11603 if (cond!=1 && zoom==1 && cimg::mod(nangle,90.0f)==0) {
11604 const int iangle = (int)nangle/90;
11605 switch (iangle) {
11606 case 1: {
11607 dest.fill(0);
11608 const unsigned int
11609 xmin = cimg::max(0,(dimx()-dimy())/2), xmax = cimg::min(width,xmin+height),
11610 ymin = cimg::max(0,(dimy()-dimx())/2), ymax = cimg::min(height,ymin+width),
11611 xoff = xmin + cimg::min(0,(dimx()-dimy())/2),
11612 yoff = ymin + cimg::min(0,(dimy()-dimx())/2);
11613 cimg_forZV(dest,z,v) for (unsigned int y=ymin; y<ymax; ++y) for (unsigned int x=xmin; x<xmax; ++x)
11614 dest(x,y,z,v) = (*this)(y-yoff,height-1-x+xoff,z,v);
11615 } break;
11616 case 2: {
11617 cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(width-1-x,height-1-y,z,v);
11618 } break;
11619 case 3: {
11620 dest.fill(0);
11621 const unsigned int
11622 xmin = cimg::max(0,(dimx()-dimy())/2), xmax = cimg::min(width,xmin+height),
11623 ymin = cimg::max(0,(dimy()-dimx())/2), ymax = cimg::min(height,ymin+width),
11624 xoff = xmin + cimg::min(0,(dimx()-dimy())/2),
11625 yoff = ymin + cimg::min(0,(dimy()-dimx())/2);
11626 cimg_forZV(dest,z,v) for (unsigned int y=ymin; y<ymax; ++y) for (unsigned int x=xmin; x<xmax; ++x)
11627 dest(x,y,z,v) = (*this)(width-1-y+yoff,x-xoff,z,v);
11628 } break;
11629 default:
11630 return *this;
11631 }
11632 } else
11633 switch (cond) {
11634 case 0: {
11635 cimg_forXY(dest,x,y)
11636 cimg_forZV(*this,z,v)
11637 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);
11638 } break;
11639 case 1: {
11640 cimg_forXY(dest,x,y)
11641 cimg_forZV(*this,z,v)
11642 dest(x,y,z,v) = (*this)(cimg::mod((int)(cx + (x-cx)*ca + (y-cy)*sa),dimx()),
11643 cimg::mod((int)(cy - (x-cx)*sa + (y-cy)*ca),dimy()),z,v);
11644 } break;
11645 case 2: {
11646 cimg_forXY(dest,x,y) {
11647 const float X = cx + (x-cx)*ca + (y-cy)*sa, Y = cy - (x-cx)*sa + (y-cy)*ca;
11648 cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)linear_pix2d(X,Y,z,v,0);
11649 }
11650 } break;
11651 default: {
11652 cimg_forXY(dest,x,y) {
11653 const float X = cx + (x-cx)*ca + (y-cy)*sa, Y = cy - (x-cx)*sa + (y-cy)*ca;
11654 cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)cubic_pix2d(X,Y,z,v,0);
11655 }
11656 } break;
11657 }
11658 return dest;
11659 }
11660
11662 CImg<T>& rotate(const float angle, const float cx, const float cy, const float zoom=1, const unsigned int cond=3) {
11663 return get_rotate(angle,cx,cy,zoom,cond).assign_to(*this);
11664 }
11665
11667
11684 CImg<T> get_resize(const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100,
11685 const int interp=1, const int border_condition=-1, const bool center=false) const {
11686 if (!pdx || !pdy || !pdz || !pdv) return CImg<T>();
11687 const unsigned int
11688 tdx = pdx<0?-pdx*width/100:pdx,
11689 tdy = pdy<0?-pdy*height/100:pdy,
11690 tdz = pdz<0?-pdz*depth/100:pdz,
11691 tdv = pdv<0?-pdv*dim/100:pdv,
11692 dx = tdx?tdx:1,
11693 dy = tdy?tdy:1,
11694 dz = tdz?tdz:1,
11695 dv = tdv?tdv:1;
11696 if (width==dx && height==dy && depth==dz && dim==dv) return *this;
11697 if (is_empty()) return CImg<T>(dx,dy,dz,dv,0);
11698
11699 CImg<T> res;
11700
11701 switch (interp) {
11702 case -1:
11703 std::memcpy(res.assign(dx,dy,dz,dv,0).data,data,sizeof(T)*cimg::min(size(),(long unsigned int)dx*dy*dz*dv));
11704 break;
11705
11706 case 0: {
11707 const unsigned int bx = width-1, by = height-1, bz = depth-1, bv = dim-1;
11708 res.assign(dx,dy,dz,dv);
11709 switch (border_condition) {
11710 case 1: {
11711 if (center) {
11712 const int
11713 x0 = (res.dimx()-dimx())/2,
11714 y0 = (res.dimy()-dimy())/2,
11715 z0 = (res.dimz()-dimz())/2,
11716 v0 = (res.dimv()-dimv())/2,
11717 x1 = x0 + (int)bx,
11718 y1 = y0 + (int)by,
11719 z1 = z0 + (int)bz,
11720 v1 = v0 + (int)bv;
11721 res.draw_image(*this,x0,y0,z0,v0);
11722 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);
11723 } else {
11724 res.draw_image(*this,0,0,0,0);
11725 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);
11726 }
11727 } break;
11728 case 2 : {
11729 const int
11730 x0 = (res.dimx()-dimx())/2,
11731 y0 = (res.dimy()-dimy())/2,
11732 z0 = (res.dimz()-dimz())/2,
11733 v0 = (res.dimv()-dimv())/2,
11734 nx0 = x0>0?x0-(1+x0/width)*width:x0,
11735 ny0 = y0>0?y0-(1+y0/height)*height:y0,
11736 nz0 = z0>0?z0-(1+z0/depth)*depth:z0,
11737 nv0 = v0>0?v0-(1+v0/dim)*dim:v0;
11738 for (int k=nv0; k<(int)dv; k+=dimv())
11739 for (int z=nz0; z<(int)dz; z+=dimz())
11740 for (int y=ny0; y<(int)dy; y+=dimy())
11741 for (int x=nx0; x<(int)dx; x+=dimx()) res.draw_image(*this,x,y,z,k);
11742 } break;
11743 default: {
11744 res.fill(0);
11745 if (center) res.draw_image(*this,(res.dimx()-dimx())/2,(res.dimy()-dimy())/2,(res.dimz()-dimz())/2,(res.dimv()-dimv())/2);
11746 else res.draw_image(*this,0,0,0,0);
11747 } break;
11748 }
11749 } break;
11750
11751 case 1: {
11752 res.assign(dx,dy,dz,dv);
11753 unsigned int
11754 *const offx = new unsigned int[dx],
11755 *const offy = new unsigned int[dy+1],
11756 *const offz = new unsigned int[dz+1],
11757 *const offv = new unsigned int[dv+1],
11758 *poffx, *poffy, *poffz, *poffv,
11759 curr, old;
11760 const unsigned int wh = width*height, whd = width*height*depth, rwh = dx*dy, rwhd = dx*dy*dz;
11761 poffx = offx; curr = 0; { cimg_forX(res,x) { old=curr; curr=(x+1)*width/dx; *(poffx++) = (unsigned int)curr-(unsigned int)old; }}
11762 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;
11763 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;
11764 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;
11765 T *ptrd = res.data;
11766 const T* ptrv = data;
11767 poffv = offv;
11768 for (unsigned int k=0; k<dv; ) {
11769 const T *ptrz = ptrv;
11770 poffz = offz;
11771 for (unsigned int z=0; z<dz; ) {
11772 const T *ptry = ptrz;
11773 poffy = offy;
11774 for (unsigned int y=0; y<dy; ) {
11775 const T *ptrx = ptry;
11776 poffx = offx;
11777 cimg_forX(res,x) { *(ptrd++) = *ptrx; ptrx+=*(poffx++); }
11778 ++y;
11779 unsigned int dy = *(poffy++);
11780 for (;!dy && y<dy; std::memcpy(ptrd, ptrd-dx, sizeof(T)*dx), ++y, ptrd+=dx, dy=*(poffy++));
11781 ptry+=dy;
11782 }
11783 ++z;
11784 unsigned int dz = *(poffz++);
11785 for (;!dz && z<dz; std::memcpy(ptrd, ptrd-rwh, sizeof(T)*rwh), ++z, ptrd+=rwh, dz=*(poffz++));
11786 ptrz+=dz;
11787 }
11788 ++k;
11789 unsigned int dv = *(poffv++);
11790 for (;!dv && k<dv; std::memcpy(ptrd, ptrd-rwhd, sizeof(T)*rwhd), ++k, ptrd+=rwhd, dv=*(poffv++));
11791 ptrv+=dv;
11792 }
11793 delete[] offx; delete[] offy; delete[] offz; delete[] offv;
11794 } break;
11795
11796 case 2: {
11797 typedef typename cimg::superset<T,float>::type ftype;
11798 bool instance_first = true;
11799 if (dx!=width) {
11800 CImg<ftype> tmp(dx,height,depth,dim,0);
11801 for (unsigned int a=width*dx, b=width, c=dx, s=0, t=0; a; ) {
11802 const unsigned int d = cimg::min(b,c);
11803 a-=d; b-=d; c-=d;
11804 cimg_forYZV(tmp,y,z,v) tmp(t,y,z,v)+=(ftype)(*this)(s,y,z,v)*d;
11805 if (!b) { cimg_forYZV(tmp,y,z,v) tmp(t,y,z,v)/=width; ++t; b = width; }
11806 if (!c) { ++s; c = dx; }
11807 }
11808 tmp.assign_to(res);
11809 instance_first = false;
11810 }
11811 if (dy!=height) {
11812 CImg<ftype> tmp(dx,dy,depth,dim,0);
11813 for (unsigned int a=height*dy, b=height, c=dy, s=0, t=0; a; ) {
11814 const unsigned int d = cimg::min(b,c);
11815 a-=d; b-=d; c-=d;
11816 if (instance_first) cimg_forXZV(tmp,x,z,v) tmp(x,t,z,v)+=(ftype)(*this)(x,s,z,v)*d;
11817 else cimg_forXZV(tmp,x,z,v) tmp(x,t,z,v)+=(ftype)res(x,s,z,v)*d;
11818 if (!b) { cimg_forXZV(tmp,x,z,v) tmp(x,t,z,v)/=height; ++t; b = height; }
11819 if (!c) { ++s; c = dy; }
11820 }
11821 tmp.assign_to(res);
11822 instance_first = false;
11823 }
11824 if (dz!=depth) {
11825 CImg<ftype> tmp(dx,dy,dz,dim,0);
11826 for (unsigned int a=depth*dz, b=depth, c=dz, s=0, t=0; a; ) {
11827 const unsigned int d = cimg::min(b,c);
11828 a-=d; b-=d; c-=d;
11829 if (instance_first) cimg_forXYV(tmp,x,y,v) tmp(x,y,t,v)+=(ftype)(*this)(x,y,s,v)*d;
11830 else cimg_forXYV(tmp,x,y,v) tmp(x,y,t,v)+=(ftype)res(x,y,s,v)*d;
11831 if (!b) { cimg_forXYV(tmp,x,y,v) tmp(x,y,t,v)/=depth; ++t; b = depth; }
11832 if (!c) { ++s; c = dz; }
11833 }
11834 tmp.assign_to(res);
11835 instance_first = false;
11836 }
11837 if (dv!=dim) {
11838 CImg<ftype> tmp(dx,dy,dz,dv,0);
11839 for (unsigned int a=dim*dv, b=dim, c=dv, s=0, t=0; a; ) {
11840 const unsigned int d = cimg::min(b,c);
11841 a-=d; b-=d; c-=d;
11842 if (instance_first) cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)+=(ftype)(*this)(x,y,z,s)*d;
11843 else cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)+=(ftype)res(x,y,z,s)*d;
11844 if (!b) { cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)/=dim; ++t; b = dim; }
11845 if (!c) { ++s; c = dv; }
11846 }
11847 tmp.assign_to(res);
11848 instance_first = false;
11849 }
11850 } break;
11851
11852 case 3: {
11853 const unsigned int dimmax = cimg::max(dx,dy,dz,dv);
11854 const float
11855 sx = (border_condition<0 && dx>width )?(dx>1?(width-1.0f)/(dx-1) :0):(float)width/dx,
11856 sy = (border_condition<0 && dy>height)?(dy>1?(height-1.0f)/(dy-1):0):(float)height/dy,
11857 sz = (border_condition<0 && dz>depth )?(dz>1?(depth-1.0f)/(dz-1) :0):(float)depth/dz,
11858 sv = (border_condition<0 && dv>dim )?(dv>1?(dim-1.0f)/(dv-1) :0):(float)dim/dv;
11859
11860 unsigned int *const off = new unsigned int[dimmax], *poff;
11861 float *const foff = new float[dimmax], *pfoff, old, curr;
11862 CImg<T> resx, resy, resz, resv;
11863 T *ptrd;
11864
11865 if (dx!=width) {
11866 if (width==1) resx = get_resize(dx,height,depth,dim,1,0);
11867 else {
11868 resx.assign(dx,height,depth,dim);
11869 curr = old = 0; poff = off; pfoff = foff;
11870 cimg_forX(resx,x) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sx; *(poff++) = (unsigned int)curr-(unsigned int)old; }
11871 ptrd = resx.data;
11872 const T *ptrs0 = data;
11873 cimg_forYZV(resx,y,z,k) {
11874 poff = off; pfoff = foff;
11875 const T *ptrs = ptrs0, *const ptrsmax = ptrs0 + (width-1);
11876 cimg_forX(resx,x) {
11877 const float alpha = *(pfoff++);
11878 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+1):(border_condition?val1:0);
11879 *(ptrd++) = (T)((1-alpha)*val1 + alpha*val2);
11880 ptrs+=*(poff++);
11881 }
11882 ptrs0+=width;
11883 }
11884 }
11885 } else resx.assign(*this,true);
11886
11887 if (dy!=height) {
11888 if (height==1) resy = resx.get_resize(dx,dy,depth,dim,1,0);
11889 else {
11890 resy.assign(dx,dy,depth,dim);
11891 curr = old = 0; poff = off; pfoff = foff;
11892 cimg_forY(resy,y) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sy; *(poff++) = dx*((unsigned int)curr-(unsigned int)old); }
11893 cimg_forXZV(resy,x,z,k) {
11894 ptrd = resy.ptr(x,0,z,k);
11895 const T *ptrs = resx.ptr(x,0,z,k), *const ptrsmax = ptrs + (height-1)*dx;
11896 poff = off; pfoff = foff;
11897 cimg_forY(resy,y) {
11898 const float alpha = *(pfoff++);
11899 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+dx):(border_condition?val1:0);
11900 *ptrd = (T)((1-alpha)*val1 + alpha*val2);
11901 ptrd+=dx;
11902 ptrs+=*(poff++);
11903 }
11904 }
11905 }
11906 resx.assign();
11907 } else resy.assign(resx,true);
11908
11909 if (dz!=depth) {
11910 if (depth==1) resz = resy.get_resize(dx,dy,dz,dim,1,0);
11911 else {
11912 const unsigned int wh = dx*dy;
11913 resz.assign(dx,dy,dz,dim);
11914 curr = old = 0; poff = off; pfoff = foff;
11915 cimg_forZ(resz,z) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sz; *(poff++) = wh*((unsigned int)curr-(unsigned int)old); }
11916 cimg_forXYV(resz,x,y,k) {
11917 ptrd = resz.ptr(x,y,0,k);
11918 const T *ptrs = resy.ptr(x,y,0,k), *const ptrsmax = ptrs + (depth-1)*wh;
11919 poff = off; pfoff = foff;
11920 cimg_forZ(resz,z) {
11921 const float alpha = *(pfoff++);
11922 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+wh):(border_condition?val1:0);
11923 *ptrd = (T)((1-alpha)*val1 + alpha*val2);
11924 ptrd+=wh;
11925 ptrs+=*(poff++);
11926 }
11927 }
11928 }
11929 resy.assign();
11930 } else resz.assign(resy,true);
11931
11932 if (dv!=dim) {
11933 if (dim==1) resv = resz.get_resize(dx,dy,dz,dv,1,0);
11934 else {
11935 const unsigned int whd = dx*dy*dz;
11936 resv.assign(dx,dy,dz,dv);
11937 curr = old = 0; poff = off; pfoff = foff;
11938 cimg_forV(resv,k) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sv; *(poff++) = whd*((unsigned int)curr-(unsigned int)old); }
11939 cimg_forXYZ(resv,x,y,z) {
11940 ptrd = resv.ptr(x,y,z,0);
11941 const T *ptrs = resz.ptr(x,y,z,0), *const ptrsmax = ptrs + (dim-1)*whd;
11942 poff = off; pfoff = foff;
11943 cimg_forV(resv,k) {
11944 const float alpha = *(pfoff++);
11945 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+whd):(border_condition?val1:0);
11946 *ptrd = (T)((1-alpha)*val1 + alpha*val2);
11947 ptrd+=whd;
11948 ptrs+=*(poff++);
11949 }
11950 }
11951 }
11952 resz.assign();
11953 } else resv.assign(resz,true);
11954
11955 delete[] off; delete[] foff;
11956 return resv.is_shared?(resz.is_shared?(resy.is_shared?(resx.is_shared?(+(*this)):resx):resy):resz):resv;
11957 } break;
11958
11959 case 4: {
11960 res.assign(dx,dy,dz,dv,0);
11961 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);
11962 } break;
11963
11964 case 5: {
11965 typedef typename cimg::superset<T,float>::type ftype;
11966 const float
11967 sx = (border_condition<0 && dx>width )?(dx>1?(width-1.0f)/(dx-1) :0):(float)width/dx,
11968 sy = (border_condition<0 && dy>height)?(dy>1?(height-1.0f)/(dy-1):0):(float)height/dy,
11969 sz = (border_condition<0 && dz>depth )?(dz>1?(depth-1.0f)/(dz-1) :0):(float)depth/dz,
11970 sv = (border_condition<0 && dv>dim )?(dv>1?(dim-1.0f)/(dv-1) :0):(float)dim/dv;
11971 res.assign(dx,dy,dz,dv);
11972 T *ptrd = res.ptr();
11973 float cx, cy, cz, ck = 0;
11974 cimg_forV(res,k) { cz = 0;
11975 cimg_forZ(res,z) { cy = 0;
11976 cimg_forY(res,y) { cx = 0;
11977 cimg_forX(res,x) {
11978 *(ptrd++) = (T)(border_condition?cubic_pix2d(cx,cy,(int)cz,(int)ck):cubic_pix2d(cx,cy,(int)cz,(int)ck,0));
11979 cx+=sx;
11980 } cy+=sy;
11981 } cz+=sz;
11982 } ck+=sv;
11983 }
11984 } break;
11985
11986 default:
11987 throw CImgArgumentException("CImg<%s>::resize() : Invalid interpolation method : %d specified.",
11988 pixel_type(),interp);
11989 }
11990 return res;
11991 }
11992
11994 CImg<T>& resize(const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100,
11995 const int interp=1, const int border_condition=-1, const bool center=false) {
11996 if (!pdx || !pdy || !pdz || !pdv) return assign();
11997 const unsigned int
11998 dx = pdx<0?-pdx*width/100:pdx,
11999 dy = pdy<0?-pdy*height/100:pdy,
12000 dz = pdz<0?-pdz*depth/100:pdz,
12001 dv = pdv<0?-pdv*dim/100:pdv;
12002 if (width==dx && height==dy && depth==dz && dim==dv) return *this;
12003 if (interp==-1 && dx*dy*dz*dv==size()) {
12004 width = dx; height = dy; depth = dz; dim = dv;
12005 return *this;
12006 }
12007 return get_resize(dx,dy,dz,dv,interp,border_condition,center).assign_to(*this);
12008 }
12009
12011
12024 template<typename t> CImg<T> get_resize(const CImg<t>& src, const int interp=1,
12025 const int border_condition=-1, const bool center=false) const {
12026 return get_resize(src.width,src.height,src.depth,src.dim,interp,border_condition,center);
12027 }
12028
12030 template<typename t> CImg<T>& resize(const CImg<t>& src, const int interp=1,
12031 const int border_condition=-1, const bool center=false) {
12032 return resize(src.width,src.height,src.depth,src.dim,interp,border_condition,center);
12033 }
12034
12036
12049 CImg<T> get_resize(const CImgDisplay& disp, const int interp=1,
12050 const int border_condition=-1, const bool center=false) const {
12051 return get_resize(disp.width,disp.height,depth,dim,interp,border_condition,center);
12052 }
12053
12055 CImg<T>& resize(const CImgDisplay& disp, const int interp=1,
12056 const int border_condition=-1, const bool center=false) {
12057 return resize(disp.width,disp.height,depth,dim,interp,border_condition,center);
12058 }
12059
12061
12065 CImg<T> get_permute_axes(const char *permut="vxyz") const {
12066 if (is_empty() || !permut) return (+*this);
12067 CImg<T> res;
12068 const T* ptr = data;
12069 if (!cimg::strncasecmp(permut,"xyzv",4)) return (+*this);
12070 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; }
12071 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; }
12072 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; }
12073 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; }
12074 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; }
12075 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; }
12076 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; }
12077 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; }
12078 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; }
12079 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; }
12080 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; }
12081 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; }
12082 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; }
12083 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; }
12084 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; }
12085 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; }
12086 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; }
12087 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; }
12088 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; }
12089 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; }
12090 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; }
12091 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; }
12092 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; }
12093 throw CImgArgumentException("CImg<%s>::permute_axes() : Invalid input permutation '%s'.",pixel_type(),permut);
12094 return res;
12095 }
12096
12098 CImg<T>& permute_axes(const char *order="vxyz") {
12099 return get_permute_axes(order).assign_to(*this);
12100 }
12101
12103 CImg<T> get_resize_halfXY() const {
12104 typedef typename cimg::superset<T,float>::type ftype;
12105 if (is_empty()) return CImg<T>();
12106 const ftype mask[9] = { 0.07842776544f, 0.1231940459f, 0.07842776544f,
12107 0.1231940459f, 0.1935127547f, 0.1231940459f,
12108 0.07842776544f, 0.1231940459f, 0.07842776544f };
12109 ftype I[9] = { 0 };
12110 CImg<T> dest(width/2,height/2,depth,dim);
12111 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I)
12112 if (x%2 && y%2) dest(x/2,y/2,z,k) = (T)
12113 (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] +
12114 I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] +
12115 I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]);
12116 return dest;
12117 }
12118
12120 CImg<T>& resize_halfXY() {
12121 return get_resize_halfXY().assign_to(*this);
12122 }
12123
12125 CImg<T> get_mirror(const char axe='x') const {
12126 return (+*this).mirror(axe);
12127 }
12128
12130 CImg<T>& mirror(const char axe='x') {
12131 if (!is_empty()) {
12132 T *pf, *pb, *buf = 0;
12133 switch (cimg::uncase(axe)) {
12134 case 'x': {
12135 pf = data; pb = ptr(width-1);
12136 for (unsigned int yzv=0; yzv<height*depth*dim; ++yzv) {
12137 for (unsigned int x=0; x<width/2; ++x) { const T val = *pf; *(pf++) = *pb; *(pb--) = val; }
12138 pf+=width-width/2;
12139 pb+=width+width/2;
12140 }
12141 } break;
12142 case 'y': {
12143 buf = new T[width];
12144 pf = data; pb = ptr(0,height-1);
12145 for (unsigned int zv=0; zv<depth*dim; ++zv) {
12146 for (unsigned int y=0; y<height/2; ++y) {
12147 std::memcpy(buf,pf,width*sizeof(T));
12148 std::memcpy(pf,pb,width*sizeof(T));
12149 std::memcpy(pb,buf,width*sizeof(T));
12150 pf+=width;
12151 pb-=width;
12152 }
12153 pf+=width*(height-height/2);
12154 pb+=width*(height+height/2);
12155 }
12156 } break;
12157 case 'z': {
12158 buf = new T[width*height];
12159 pf = data; pb = ptr(0,0,depth-1);
12160 cimg_forV(*this,v) {
12161 for (unsigned int z=0; z<depth/2; ++z) {
12162 std::memcpy(buf,pf,width*height*sizeof(T));
12163 std::memcpy(pf,pb,width*height*sizeof(T));
12164 std::memcpy(pb,buf,width*height*sizeof(T));
12165 pf+=width*height;
12166 pb-=width*height;
12167 }
12168 pf+=width*height*(depth-depth/2);
12169 pb+=width*height*(depth+depth/2);
12170 }
12171 } break;
12172 case 'v': {
12173 buf = new T[width*height*depth];
12174 pf = data; pb = ptr(0,0,0,dim-1);
12175 for (unsigned int v=0; v<dim/2; ++v) {
12176 std::memcpy(buf,pf,width*height*depth*sizeof(T));
12177 std::memcpy(pf,pb,width*height*depth*sizeof(T));
12178 std::memcpy(pb,buf,width*height*depth*sizeof(T));
12179 pf+=width*height*depth;
12180 pb-=width*height*depth;
12181 }
12182 } break;
12183 default:
12184 throw CImgArgumentException("CImg<%s>::mirror() : unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe);
12185 }
12186 if (buf) delete[] buf;
12187 }
12188 return *this;
12189 }
12190
12192
12204 CImg<T> get_translate(const int deltax, const int deltay=0, const int deltaz=0, const int deltav=0,
12205 const int border_condition=0) const {
12206 return (+*this).translate(deltax,deltay,deltaz,deltav,border_condition);
12207 }
12208
12210 CImg<T>& translate(const int deltax, const int deltay=0, const int deltaz=0, const int deltav=0,
12211 const int border_condition=0) {
12212 if (!is_empty()) {
12213
12214 if (deltax)
12215 switch (border_condition) {
12216 case 0:
12217 if (cimg::abs(deltax)>=dimx()) return fill(0);
12218 if (deltax>0) cimg_forYZV(*this,y,z,k) {
12219 std::memmove(ptr(0,y,z,k),ptr(deltax,y,z,k),(width-deltax)*sizeof(T));
12220 std::memset(ptr(width-deltax,y,z,k),0,deltax*sizeof(T));
12221 } else cimg_forYZV(*this,y,z,k) {
12222 std::memmove(ptr(-deltax,y,z,k),ptr(0,y,z,k),(width+deltax)*sizeof(T));
12223 std::memset(ptr(0,y,z,k),0,-deltax*sizeof(T));
12224 }
12225 break;
12226 case 1:
12227 if (deltax>0) {
12228 const int ndeltax = (deltax>=dimx())?width-1:deltax;
12229 if (!ndeltax) return *this;
12230 cimg_forYZV(*this,y,z,k) {
12231 std::memmove(ptr(0,y,z,k),ptr(ndeltax,y,z,k),(width-ndeltax)*sizeof(T));
12232 T *ptrd = ptr(width-1,y,z,k);
12233 const T val = *ptrd;
12234 for (int l=0; l<ndeltax-1; ++l) *(--ptrd) = val;
12235 }
12236 } else {
12237 const int ndeltax = (-deltax>=dimx())?width-1:-deltax;
12238 if (!ndeltax) return *this;
12239 cimg_forYZV(*this,y,z,k) {
12240 std::memmove(ptr(ndeltax,y,z,k),ptr(0,y,z,k),(width-ndeltax)*sizeof(T));
12241 T *ptrd = ptr(0,y,z,k);
12242 const T val = *ptrd;
12243 for (int l=0; l<ndeltax-1; ++l) *(++ptrd) = val;
12244 }
12245 }
12246 break;
12247 case 2: {
12248 const int ml = cimg::mod(deltax,dimx()), ndeltax = (ml<=dimx()/2)?ml:(ml-dimx());
12249 if (!ndeltax) return *this;
12250 T* buf = new T[cimg::abs(ndeltax)];
12251 if (ndeltax>0) cimg_forYZV(*this,y,z,k) {
12252 std::memcpy(buf,ptr(0,y,z,k),ndeltax*sizeof(T));
12253 std::memmove(ptr(0,y,z,k),ptr(ndeltax,y,z,k),(width-ndeltax)*sizeof(T));
12254 std::memcpy(ptr(width-ndeltax,y,z,k),buf,ndeltax*sizeof(T));
12255 } else cimg_forYZV(*this,y,z,k) {
12256 std::memcpy(buf,ptr(width+ndeltax,y,z,k),-ndeltax*sizeof(T));
12257 std::memmove(ptr(-ndeltax,y,z,k),ptr(0,y,z,k),(width+ndeltax)*sizeof(T));
12258 std::memcpy(ptr(0,y,z,k),buf,-ndeltax*sizeof(T));
12259 }
12260 delete[] buf;
12261 } break;
12262 }
12263
12264 if (deltay)
12265 switch (border_condition) {
12266 case 0:
12267 if (cimg::abs(deltay)>=dimy()) return fill(0);
12268 if (deltay>0) cimg_forZV(*this,z,k) {
12269 std::memmove(ptr(0,0,z,k),ptr(0,deltay,z,k),width*(height-deltay)*sizeof(T));
12270 std::memset(ptr(0,height-deltay,z,k),0,width*deltay*sizeof(T));
12271 } else cimg_forZV(*this,z,k) {
12272 std::memmove(ptr(0,-deltay,z,k),ptr(0,0,z,k),width*(height+deltay)*sizeof(T));
12273 std::memset(ptr(0,0,z,k),0,-deltay*width*sizeof(T));
12274 }
12275 break;
12276 case 1:
12277 if (deltay>0) {
12278 const int ndeltay = (deltay>=dimy())?height-1:deltay;
12279 if (!ndeltay) return *this;
12280 cimg_forZV(*this,z,k) {
12281 std::memmove(ptr(0,0,z,k),ptr(0,ndeltay,z,k),width*(height-ndeltay)*sizeof(T));
12282 T *ptrd = ptr(0,height-ndeltay,z,k), *ptrs = ptr(0,height-1,z,k);
12283 for (int l=0; l<ndeltay-1; ++l) { std::memcpy(ptrd,ptrs,width*sizeof(T)); ptrd+=width; }
12284 }
12285 } else {
12286 const int ndeltay = (-deltay>=dimy())?height-1:-deltay;
12287 if (!ndeltay) return *this;
12288 cimg_forZV(*this,z,k) {
12289 std::memmove(ptr(0,ndeltay,z,k),ptr(0,0,z,k),width*(height-ndeltay)*sizeof(T));
12290 T *ptrd = ptr(0,1,z,k), *ptrs = ptr(0,0,z,k);
12291 for (int l=0; l<ndeltay-1; ++l) { std::memcpy(ptrd,ptrs,width*sizeof(T)); ptrd+=width; }
12292 }
12293 }
12294 break;
12295 case 2: {
12296 const int ml = cimg::mod(deltay,dimy()), ndeltay = (ml<=dimy()/2)?ml:(ml-dimy());
12297 if (!ndeltay) return *this;
12298 T* buf = new T[width*cimg::abs(ndeltay)];
12299 if (ndeltay>0) cimg_forZV(*this,z,k) {
12300 std::memcpy(buf,ptr(0,0,z,k),width*ndeltay*sizeof(T));
12301 std::memmove(ptr(0,0,z,k),ptr(0,ndeltay,z,k),width*(height-ndeltay)*sizeof(T));
12302 std::memcpy(ptr(0,height-ndeltay,z,k),buf,width*ndeltay*sizeof(T));
12303 } else cimg_forZV(*this,z,k) {
12304 std::memcpy(buf,ptr(0,height+ndeltay,z,k),-ndeltay*width*sizeof(T));
12305 std::memmove(ptr(0,-ndeltay,z,k),ptr(0,0,z,k),width*(height+ndeltay)*sizeof(T));
12306 std::memcpy(ptr(0,0,z,k),buf,-ndeltay*width*sizeof(T));
12307 }
12308 delete[] buf;
12309 } break;
12310 }
12311
12312 if (deltaz)
12313 switch (border_condition) {
12314 case 0:
12315 if (cimg::abs(deltaz)>=dimz()) return fill(0);
12316 if (deltaz>0) cimg_forV(*this,k) {
12317 std::memmove(ptr(0,0,0,k),ptr(0,0,deltaz,k),width*height*(depth-deltaz)*sizeof(T));
12318 std::memset(ptr(0,0,depth-deltaz,k),0,width*height*deltaz*sizeof(T));
12319 } else cimg_forV(*this,k) {
12320 std::memmove(ptr(0,0,-deltaz,k),ptr(0,0,0,k),width*height*(depth+deltaz)*sizeof(T));
12321 std::memset(ptr(0,0,0,k),0,-deltaz*width*height*sizeof(T));
12322 }
12323 break;
12324 case 1:
12325 if (deltaz>0) {
12326 const int ndeltaz = (deltaz>=dimz())?depth-1:deltaz;
12327 if (!ndeltaz) return *this;
12328 cimg_forV(*this,k) {
12329 std::memmove(ptr(0,0,0,k),ptr(0,0,ndeltaz,k),width*height*(depth-ndeltaz)*sizeof(T));
12330 T *ptrd = ptr(0,0,depth-ndeltaz,k), *ptrs = ptr(0,0,depth-1,k);
12331 for (int l=0; l<ndeltaz-1; ++l) { std::memcpy(ptrd,ptrs,width*height*sizeof(T)); ptrd+=width*height; }
12332 }
12333 } else {
12334 const int ndeltaz = (-deltaz>=dimz())?depth-1:-deltaz;
12335 if (!ndeltaz) return *this;
12336 cimg_forV(*this,k) {
12337 std::memmove(ptr(0,0,ndeltaz,k),ptr(0,0,0,k),width*height*(depth-ndeltaz)*sizeof(T));
12338 T *ptrd = ptr(0,0,1,k), *ptrs = ptr(0,0,0,k);
12339 for (int l=0; l<ndeltaz-1; ++l) { std::memcpy(ptrd,ptrs,width*height*sizeof(T)); ptrd+=width*height; }
12340 }
12341 }
12342 break;
12343 case 2: {
12344 const int ml = cimg::mod(deltaz,dimz()), ndeltaz = (ml<=dimz()/2)?ml:(ml-dimz());
12345 if (!ndeltaz) return *this;
12346 T* buf = new T[width*height*cimg::abs(ndeltaz)];
12347 if (ndeltaz>0) cimg_forV(*this,k) {
12348 std::memcpy(buf,ptr(0,0,0,k),width*height*ndeltaz*sizeof(T));
12349 std::memmove(ptr(0,0,0,k),ptr(0,0,ndeltaz,k),width*height*(depth-ndeltaz)*sizeof(T));
12350 std::memcpy(ptr(0,0,depth-ndeltaz,k),buf,width*height*ndeltaz*sizeof(T));
12351 } else cimg_forV(*this,k) {
12352 std::memcpy(buf,ptr(0,0,depth+ndeltaz,k),-ndeltaz*width*height*sizeof(T));
12353 std::memmove(ptr(0,0,-ndeltaz,k),ptr(0,0,0,k),width*height*(depth+ndeltaz)*sizeof(T));
12354 std::memcpy(ptr(0,0,0,k),buf,-ndeltaz*width*height*sizeof(T));
12355 }
12356 delete[] buf;
12357 } break;
12358 }
12359
12360 if (deltav)
12361 switch (border_condition) {
12362 case 0:
12363 if (cimg::abs(deltav)>=dimv()) return fill(0);
12364 if (deltav>0) {
12365 std::memmove(data,ptr(0,0,0,deltav),width*height*depth*(dim-deltav)*sizeof(T));
12366 std::memset(ptr(0,0,0,dim-deltav),0,width*height*depth*deltav*sizeof(T));
12367 } else cimg_forV(*this,k) {
12368 std::memmove(ptr(0,0,0,-deltav),data,width*height*depth*(dim+deltav)*sizeof(T));
12369 std::memset(data,0,-deltav*width*height*depth*sizeof(T));
12370 }
12371 break;
12372 case 1:
12373 if (deltav>0) {
12374 const int ndeltav = (deltav>=dimv())?dim-1:deltav;
12375 if (!ndeltav) return *this;
12376 std::memmove(data,ptr(0,0,0,ndeltav),width*height*depth*(dim-ndeltav)*sizeof(T));
12377 T *ptrd = ptr(0,0,0,dim-ndeltav), *ptrs = ptr(0,0,0,dim-1);
12378 for (int l=0; l<ndeltav-1; ++l) { std::memcpy(ptrd,ptrs,width*height*depth*sizeof(T)); ptrd+=width*height*depth; }
12379 } else {
12380 const int ndeltav = (-deltav>=dimv())?dim-1:-deltav;
12381 if (!ndeltav) return *this;
12382 std::memmove(ptr(0,0,0,ndeltav),data,width*height*depth*(dim-ndeltav)*sizeof(T));
12383 T *ptrd = ptr(0,0,0,1);
12384 for (int l=0; l<ndeltav-1; ++l) { std::memcpy(ptrd,data,width*height*depth*sizeof(T)); ptrd+=width*height*depth; }
12385 }
12386 break;
12387 case 2: {
12388 const int ml = cimg::mod(deltav,dimv()), ndeltav = (ml<=dimv()/2)?ml:(ml-dimv());
12389 if (!ndeltav) return *this;
12390 T* buf = new T[width*height*depth*cimg::abs(ndeltav)];
12391 if (ndeltav>0) {
12392 std::memcpy(buf,data,width*height*depth*ndeltav*sizeof(T));
12393 std::memmove(data,ptr(0,0,0,ndeltav),width*height*depth*(dim-ndeltav)*sizeof(T));
12394 std::memcpy(ptr(0,0,0,dim-ndeltav),buf,width*height*depth*ndeltav*sizeof(T));
12395 } else {
12396 std::memcpy(buf,ptr(0,0,0,dim+ndeltav),-ndeltav*width*height*depth*sizeof(T));
12397 std::memmove(ptr(0,0,0,-ndeltav),data,width*height*depth*(dim+ndeltav)*sizeof(T));
12398 std::memcpy(data,buf,-ndeltav*width*height*depth*sizeof(T));
12399 }
12400 delete[] buf;
12401 } break;
12402 }
12403 }
12404 return *this;
12405 }
12406
12408
12419 CImg<T> get_crop(const int x0, const int y0, const int z0, const int v0,
12420 const int x1, const int y1, const int z1, const int v1,
12421 const bool border_condition=false) const {
12422 if (is_empty()) return *this;
12423 const int
12424 nx0 = x0<x1?x0:x1, nx1 = x0^x1^nx0,
12425 ny0 = y0<y1?y0:y1, ny1 = y0^y1^ny0,
12426 nz0 = z0<z1?z0:z1, nz1 = z0^z1^nz0,
12427 nv0 = v0<v1?v0:v1, nv1 = v0^v1^nv0;
12428 CImg<T> dest(1U+nx1-nx0,1U+ny1-ny0,1U+nz1-nz0,1U+nv1-nv0);
12429 if (nx0<0 || nx1>=dimx() || ny0<0 || ny1>=dimy() || nz0<0 || nz1>=dimz() || nv0<0 || nv1>=dimv()) {
12430 if (border_condition) cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = pix4d(nx0+x,ny0+y,nz0+z,nv0+v);
12431 else dest.fill(0).draw_image(*this,-nx0,-ny0,-nz0,-nv0);
12432 } else dest.draw_image(*this,-nx0,-ny0,-nz0,-nv0);
12433 return dest;
12434 }
12435
12437 CImg<T>& crop(const int x0, const int y0, const int z0, const int v0,
12438 const int x1, const int y1, const int z1, const int v1,
12439 const bool border_condition=false) {
12440 return get_crop(x0,y0,z0,v0,x1,y1,z1,v1,border_condition).assign_to(*this);
12441 }
12442
12444
12454 CImg<T> get_crop(const int x0, const int y0, const int z0,
12455 const int x1, const int y1, const int z1,
12456 const bool border_condition=false) const {
12457 return get_crop(x0,y0,z0,0,x1,y1,z1,dim-1,border_condition);
12458 }
12459
12461 CImg<T>& crop(const int x0, const int y0, const int z0,
12462 const int x1, const int y1, const int z1,
12463 const bool border_condition=false) {
12464 return crop(x0,y0,z0,0,x1,y1,z1,dim-1,border_condition);
12465 }
12466
12468
12476 CImg<T> get_crop(const int x0, const int y0,
12477 const int x1, const int y1,
12478 const bool border_condition=false) const {
12479 return get_crop(x0,y0,0,0,x1,y1,depth-1,dim-1,border_condition);
12480 }
12481
12483 CImg<T>& crop(const int x0, const int y0,
12484 const int x1, const int y1,
12485 const bool border_condition=false) {
12486 return crop(x0,y0,0,0,x1,y1,depth-1,dim-1,border_condition);
12487 }
12488
12490
12496 CImg<T> get_crop(const int x0, const int x1, const bool border_condition=false) const {
12497 return get_crop(x0,0,0,0,x1,height-1,depth-1,dim-1,border_condition);
12498 }
12499
12501 CImg<T>& crop(const int x0, const int x1, const bool border_condition=false) {
12502 return crop(x0,0,0,0,x1,height-1,depth-1,dim-1,border_condition);
12503 }
12504
12506 CImg<T> get_columns(const unsigned int x0, const unsigned int x1) const {
12507 return get_crop((int)x0,0,0,0,(int)x1,dimy()-1,dimz()-1,dimv()-1);
12508 }
12509
12511 CImg<T>& columns(const unsigned int x0, const unsigned int x1) {
12512 return get_columns(x0,x1).assign_to(*this);
12513 }
12514
12516 CImg<T> get_column(const unsigned int x0) const {
12517 return get_columns(x0,x0);
12518 }
12519
12521 CImg<T>& column(const unsigned int x0) {
12522 return columns(x0,x0);
12523 }
12524
12526 CImg<T> get_lines(const unsigned int y0, const unsigned int y1) const {
12527 return get_crop(0,(int)y0,0,0,dimx()-1,(int)y1,dimz()-1,dimv()-1);
12528 }
12529
12531 CImg<T>& lines(const unsigned int y0, const unsigned int y1) {
12532 return get_lines(y0,y1).assign_to(*this);
12533 }
12534
12536 CImg<T> get_line(const unsigned int y0) const {
12537 return get_lines(y0,y0);
12538 }
12539
12541 CImg<T>& line(const unsigned int y0) {
12542 return lines(y0,y0);
12543 }
12544
12546 CImg<T> get_slices(const unsigned int z0, const unsigned int z1) const {
12547 return get_crop(0,0,(int)z0,0,dimx()-1,dimy()-1,(int)z1,dimv()-1);
12548 }
12549
12551 CImg<T>& slices(const unsigned int z0, const unsigned int z1) {
12552 return get_slices(z0,z1).assign_to(*this);
12553 }
12554
12556 CImg<T> get_slice(const unsigned int z0) const {
12557 return get_slices(z0,z0);
12558 }
12559
12561 CImg<T>& slice(const unsigned int z0) {
12562 return slices(z0,z0);
12563 }
12564
12566 CImg<T> get_channels(const unsigned int v0, const unsigned int v1) const {
12567 return get_crop(0,0,0,(int)v0,dimx()-1,dimy()-1,dimz()-1,(int)v1);
12568 }
12569
12571 CImg<T>& channels(const unsigned int v0, const unsigned int v1) {
12572 return get_channels(v0,v1).assign_to(*this);
12573 }
12574
12576 CImg<T> get_channel(const unsigned int v0) const {
12577 return get_channels(v0,v0);
12578 }
12579
12581 CImg<T>& channel(const unsigned int v0) {
12582 return channels(v0,v0);
12583 }
12584
12586 CImg<T> get_shared_points(const unsigned int x0, const unsigned int x1,
12587 const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) {
12588 const unsigned long beg = offset(x0,y0,z0,v0), end = offset(x1,y0,z0,v0);
12589 if (beg>end || beg>=size() || end>=size())
12590 throw CImgArgumentException("CImg<%s>::get_shared_points() : Cannot return a shared-memory subset (%u->%u,%u,%u,%u) from "
12591 "a (%u,%u,%u,%u) image.",pixel_type(),x0,x1,y0,z0,v0,width,height,depth,dim);
12592 return CImg<T>(data+beg,x1-x0+1,1,1,1,true);
12593 }
12594
12596 const CImg<T> get_shared_points(const unsigned int x0, const unsigned int x1,
12597 const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) const {
12598 const unsigned long beg = offset(x0,y0,z0,v0), end = offset(x1,y0,z0,v0);
12599 if (beg>end || beg>=size() || end>=size())
12600 throw CImgArgumentException("CImg<%s>::get_shared_points() : Cannot return a shared-memory subset (%u->%u,%u,%u,%u) from "
12601 "a (%u,%u,%u,%u) image.",pixel_type(),x0,x1,y0,z0,v0,width,height,depth,dim);
12602 return CImg<T>(data+beg,x1-x0+1,1,1,1,true);
12603 }
12604
12606 CImg<T> get_shared_lines(const unsigned int y0, const unsigned int y1,
12607 const unsigned int z0=0, const unsigned int v0=0) {
12608 const unsigned long beg = offset(0,y0,z0,v0), end = offset(0,y1,z0,v0);
12609 if (beg>end || beg>=size() || end>=size())
12610 throw CImgArgumentException("CImg<%s>::get_shared_lines() : Cannot return a shared-memory subset (0->%u,%u->%u,%u,%u) from "
12611 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,y0,y1,z0,v0,width,height,depth,dim);
12612 return CImg<T>(data+beg,width,y1-y0+1,1,1,true);
12613 }
12614
12616 const CImg<T> get_shared_lines(const unsigned int y0, const unsigned int y1,
12617 const unsigned int z0=0, const unsigned int v0=0) const {
12618 const unsigned long beg = offset(0,y0,z0,v0), end = offset(0,y1,z0,v0);
12619 if (beg>end || beg>=size() || end>=size())
12620 throw CImgArgumentException("CImg<%s>::get_shared_lines() : Cannot return a shared-memory subset (0->%u,%u->%u,%u,%u) from "
12621 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,y0,y1,z0,v0,width,height,depth,dim);
12622 return CImg<T>(data+beg,width,y1-y0+1,1,1,true);
12623 }
12624
12626 CImg<T> get_shared_line(const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) {
12627 return get_shared_lines(y0,y0,z0,v0);
12628 }
12629
12631 const CImg<T> get_shared_line(const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) const {
12632 return get_shared_lines(y0,y0,z0,v0);
12633 }
12634
12636 CImg<T> get_shared_planes(const unsigned int z0, const unsigned int z1, const unsigned int v0=0) {
12637 const unsigned long beg = offset(0,0,z0,v0), end = offset(0,0,z1,v0);
12638 if (beg>end || beg>=size() || end>=size())
12639 throw CImgArgumentException("CImg<%s>::get_shared_planes() : Cannot return a shared-memory subset (0->%u,0->%u,%u->%u,%u) from "
12640 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,z0,z1,v0,width,height,depth,dim);
12641 return CImg<T>(data+beg,width,height,z1-z0+1,1,true);
12642 }
12643
12645 const CImg<T> get_shared_planes(const unsigned int z0, const unsigned int z1, const unsigned int v0=0) const {
12646 const unsigned long beg = offset(0,0,z0,v0), end = offset(0,0,z1,v0);
12647 if (beg>end || beg>=size() || end>=size())
12648 throw CImgArgumentException("CImg<%s>::get_shared_planes() : Cannot return a shared-memory subset (0->%u,0->%u,%u->%u,%u) from "
12649 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,z0,z1,v0,width,height,depth,dim);
12650 return CImg<T>(data+beg,width,height,z1-z0+1,1,true);
12651 }
12652
12654 CImg<T> get_shared_plane(const unsigned int z0, const unsigned int v0=0) {
12655 return get_shared_planes(z0,z0,v0);
12656 }
12657
12659 const CImg<T> get_shared_plane(const unsigned int z0, const unsigned int v0=0) const {
12660 return get_shared_planes(z0,z0,v0);
12661 }
12662
12664 CImg<T> get_shared_channels(const unsigned int v0, const unsigned int v1) {
12665 const unsigned long beg = offset(0,0,0,v0), end = offset(0,0,0,v1);
12666 if (beg>end || beg>=size() || end>=size())
12667 throw CImgArgumentException("CImg<%s>::get_shared_channels() : Cannot return a shared-memory subset (0->%u,0->%u,0->%u,%u->%u) from "
12668 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,depth-1,v0,v1,width,height,depth,dim);
12669 return CImg<T>(data+beg,width,height,depth,v1-v0+1,true);
12670 }
12671
12673 const CImg<T> get_shared_channels(const unsigned int v0, const unsigned int v1) const {
12674 const unsigned long beg = offset(0,0,0,v0), end = offset(0,0,0,v1);
12675 if (beg>end || beg>=size() || end>=size())
12676 throw CImgArgumentException("CImg<%s>::get_shared_channels() : Cannot return a shared-memory subset (0->%u,0->%u,0->%u,%u->%u) from "
12677 "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,depth-1,v0,v1,width,height,depth,dim);
12678 return CImg<T>(data+beg,width,height,depth,v1-v0+1,true);
12679 }
12680
12682 CImg<T> get_shared_channel(const unsigned int v0) {
12683 return get_shared_channels(v0,v0);
12684 }
12685
12687 const CImg<T> get_shared_channel(const unsigned int v0) const {
12688 return get_shared_channels(v0,v0);
12689 }
12690
12692 CImg<T> get_shared() {
12693 return CImg<T>(data,width,height,depth,dim,true);
12694 }
12695
12697 const CImg<T> get_shared() const {
12698 return CImg<T>(data,width,height,depth,dim,true);
12699 }
12700
12702 CImg<T> get_projections2d(const unsigned int x0, const unsigned int y0, const unsigned int z0,
12703 const int dx=-100, const int dy=-100, const int dz=-100) const {
12704 if (is_empty()) return CImg<T>();
12705 const unsigned int
12706 nx0 = (x0>=width)?width-1:x0,
12707 ny0 = (y0>=height)?height-1:y0,
12708 nz0 = (z0>=depth)?depth-1:z0;
12709 CImg<T>
12710 imgxy(width,height,1,dim),
12711 imgzy(depth,height,1,dim),
12712 imgxz(width,depth,1,dim);
12713 { cimg_forXYV(*this,x,y,k) imgxy(x,y,k) = (*this)(x,y,nz0,k); }
12714 { cimg_forYZV(*this,y,z,k) imgzy(z,y,k) = (*this)(nx0,y,z,k); }
12715 { cimg_forXZV(*this,x,z,k) imgxz(x,z,k) = (*this)(x,ny0,z,k); }
12716 imgxy.resize(dx,dy,1,dim,1);
12717 imgzy.resize(dz,dy,1,dim,1);
12718 imgxz.resize(dx,dz,1,dim,1);
12719 return CImg<T>(imgxy.width+imgzy.width,imgxy.height+imgxz.height,1,dim,0).
12720 draw_image(imgxy,0,0).
12721 draw_image(imgzy,imgxy.width,0).
12722 draw_image(imgxz,0,imgxy.height);
12723 }
12724
12726 CImg<T>& projections2d(const unsigned int x0, const unsigned int y0, const unsigned int z0,
12727 const int dx=-100, const int dy=-100, const int dz=-100) {
12728 return get_projections2d(x0,y0,z0,dx,dy,dz).assign_to(*this);
12729 }
12730
12732
12750 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 {
12751 typedef typename cimg::last<T,float>::type ftype;
12752 if (is_empty()) return CImg<ftype>();
12753 if (!nblevels)
12754 throw CImgArgumentException("CImg<%s>::get_histogram() : Can't compute an histogram with 0 levels",
12755 pixel_type());
12756 T vmin = val_min, vmax = val_max;
12757 CImg<ftype> res(nblevels,1,1,1,0);
12758 if (vmin>=vmax && vmin==0) vmin = minmax(vmax);
12759 if (vmin<vmax) cimg_for(*this,ptr,T) {
12760 const int pos = (int)((*ptr-vmin)*(nblevels-1)/(vmax-vmin));
12761 if (pos>=0 && pos<(int)nblevels) ++res[pos];
12762 } else res[0]+=size();
12763 return res;
12764 }
12765
12767 CImg<T>& histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) {
12768 return get_histogram(nblevels,val_min,val_max).assign_to(*this);
12769 }
12770
12772
12786 CImg<T> get_equalize_histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) const {
12787 return (+*this).equalize_histogram(nblevels,val_min,val_max);
12788 }
12789
12791 CImg<T>& equalize_histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) {
12792 if (!is_empty()) {
12793 T vmin = val_min, vmax = val_max;
12794 if (vmin==vmax && vmin==0) vmin = minmax(vmax);
12795 if (vmin<vmax) {
12796 CImg<float> hist = get_histogram(nblevels,vmin,vmax);
12797 float cumul = 0;
12798 cimg_forX(hist,pos) { cumul+=hist[pos]; hist[pos]=cumul; }
12799 cimg_for(*this,ptr,T) {
12800 const int pos = (unsigned int)((*ptr-vmin)*(nblevels-1)/(vmax-vmin));
12801 if (pos>=0 && pos<(int)nblevels) *ptr = (T)(vmin + (vmax-vmin)*hist[pos]/size());
12802 }
12803 }
12804 }
12805 return *this;
12806 }
12807
12809 CImg<typename cimg::last<T,unsigned int>::type> get_label_regions() const {
12810
12811 #define _cimg_get_label_test(p,q) { \
12812 flag = true; \
12813 const T *ptr1 = ptr(x,y) + siz, *ptr2 = ptr(p,q) + siz; \
12814 for (unsigned int i = dim; flag && i; --i) { ptr1-=wh; ptr2-=wh; flag = (*ptr1==*ptr2); } \
12815 }
12816
12817 if (depth>1)
12818 throw CImgInstanceException("CImg<%s>::label_regions() : Instance image must be a 2D image");
12819 typedef typename cimg::last<T,unsigned int>::type uitype;
12820 CImg<uitype> res(width,height,depth,1,0);
12821 unsigned int label = 1;
12822 const unsigned int wh = width*height, siz = width*height*dim;
12823 const int W1 = dimx()-1, H1 = dimy()-1;
12824 bool flag;
12825 cimg_forXY(*this,x,y) {
12826 bool done = false;
12827 if (y) {
12828 _cimg_get_label_test(x,y-1);
12829 if (flag) {
12830 const unsigned int lab = (res(x,y) = res(x,y-1));
12831 done = true;
12832 if (x && res(x-1,y)!=lab) {
12833 _cimg_get_label_test(x-1,y);
12834 if (flag) {
12835 const unsigned int lold = res(x-1,y), *const cptr = res.ptr(x,y);
12836 for (unsigned int *ptr = res.ptr(); ptr<cptr; ++ptr) if (*ptr==lold) *ptr = lab;
12837 }
12838 }
12839 }
12840 }
12841 if (x && !done) { _cimg_get_label_test(x-1,y); if (flag) { res(x,y) = res(x-1,y); done = true; }}
12842 if (!done) res(x,y) = label++;
12843 }
12844 for (int y=H1; y>=0; --y) for (int x=W1; x>=0; --x) {
12845 bool done = false;
12846 if (y<H1) {
12847 _cimg_get_label_test(x,y+1);
12848 if (flag) {
12849 const unsigned int lab = (res(x,y) = res(x,y+1));
12850 done = true;
12851 if (x<W1 && res(x+1,y)!=lab) {
12852 _cimg_get_label_test(x+1,y);
12853 if (flag) {
12854 const unsigned int lold = res(x+1,y), *const cptr = res.ptr(x,y);
12855 for (unsigned int *ptr = res.ptr()+res.size()-1; ptr>cptr; --ptr) if (*ptr==lold) *ptr = lab;
12856 }
12857 }
12858 }
12859 }
12860 if (x<W1 && !done) { _cimg_get_label_test(x+1,y); if (flag) res(x,y) = res(x+1,y); done = true; }
12861 }
12862 const unsigned int lab0 = res.max()+1;
12863 label = lab0;
12864 cimg_foroff(res,off) {
12865 const unsigned int lab = res[off];
12866 if (lab<lab0) { cimg_for(res,ptr,unsigned int) if (*ptr==lab) *ptr = label; ++label; }
12867 }
12868 return (res-=lab0);
12869 }
12870
12872 CImg<T>& label_regions() {
12873 return get_label_regions().assign_to(*this);
12874 }
12875
12877
12885 CImg<typename cimg::superset<T,float>::type> get_norm_pointwise(int norm_type=2) const {
12886 typedef typename cimg::superset<T,float>::type restype;
12887 if (is_empty()) return CImg<restype>();
12888 CImg<restype> res(width,height,depth);
12889 switch(norm_type) {
12890 case -1: {
12891 cimg_forXYZ(*this,x,y,z) {
12892 restype n = 0; cimg_forV(*this,v) {
12893 const restype tmp = (restype)cimg::abs((*this)(x,y,z,v));
12894 if (tmp>n) n=tmp; res(x,y,z) = n;
12895 }
12896 }
12897 } break;
12898 case 1: {
12899 cimg_forXYZ(*this,x,y,z) {
12900 restype n = 0; cimg_forV(*this,v) n+=cimg::abs((*this)(x,y,z,v)); res(x,y,z) = n;
12901 }
12902 } break;
12903 default: {
12904 cimg_forXYZ(*this,x,y,z) {
12905 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);
12906 }
12907 } break;
12908 }
12909 return res;
12910 }
12911
12913 CImg<T>& norm_pointwise(int norm_type=2) {
12914 return get_norm_pointwise(norm_type).assign_to(*this);
12915 }
12916
12918
12924 CImg<typename cimg::superset<T,float>::type> get_orientation_pointwise() const {
12925 typedef typename cimg::superset<T,float>::type restype;
12926 if (is_empty()) return CImg<restype>();
12927 return CImg<restype>(*this,false).orientation_pointwise();
12928 }
12929
12931 CImg<T>& orientation_pointwise() {
12932 cimg_forXYZ(*this,x,y,z) {
12933 float n = 0.0f;
12934 cimg_forV(*this,v) n+=(float)((*this)(x,y,z,v)*(*this)(x,y,z,v));
12935 n = (float)std::sqrt(n);
12936 if (n>0) cimg_forV(*this,v) (*this)(x,y,z,v) = (T)((*this)(x,y,z,v)/n);
12937 else cimg_forV(*this,v) (*this)(x,y,z,v) = 0;
12938 }
12939 return *this;
12940 }
12941
12943 CImgList<T> get_split(const char axe='x', const unsigned int nb=0) const {
12944 if (is_empty()) return CImgList<T>();
12945 CImgList<T> res;
12946 switch (cimg::uncase(axe)) {
12947 case 'x': {
12948 if (nb>width)
12949 throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'x' into %u images.",
12950 pixel_type(),width,height,depth,dim,data,nb);
12951 res.assign(nb?nb:width);
12952 const unsigned int delta = width/res.size + ((width%res.size)?1:0);
12953 unsigned int l,x;
12954 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);
12955 res[res.size-1] = get_crop(x,0,0,0,width-1,height-1,depth-1,dim-1);
12956 } break;
12957 case 'y': {
12958 if (nb>height)
12959 throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'y' into %u images.",
12960 pixel_type(),width,height,depth,dim,data,nb);
12961 res.assign(nb?nb:height);
12962 const unsigned int delta = height/res.size + ((height%res.size)?1:0);
12963 unsigned int l,x;
12964 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);
12965 res[res.size-1] = get_crop(0,x,0,0,width-1,height-1,depth-1,dim-1);
12966 } break;
12967 case 'z': {
12968 if (nb>depth)
12969 throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'z' into %u images.",
12970 pixel_type(),width,height,depth,dim,data,nb);
12971 res.assign(nb?nb:depth);
12972 const unsigned int delta = depth/res.size + ((depth%res.size)?1:0);
12973 unsigned int l,x;
12974 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);
12975 res[res.size-1] = get_crop(0,0,x,0,width-1,height-1,depth-1,dim-1);
12976 } break;
12977 case 'v': {
12978 if (nb>dim)
12979 throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'v' into %u images.",
12980 pixel_type(),width,height,depth,dim,data,nb);
12981 res.assign(nb?nb:dim);
12982 const unsigned int delta = dim/res.size + ((dim%res.size)?1:0);
12983 unsigned int l,x;
12984 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);
12985 res[res.size-1] = get_crop(0,0,0,x,width-1,height-1,depth-1,dim-1);
12986 } break;
12987 default:
12988 throw CImgArgumentException("CImg<%s>::get_split() : Unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe);
12989 break;
12990 }
12991 return res;
12992 }
12993
12995 CImg<T> get_append(const CImg<T>& img, const char axis='x', const char align='c') const {
12996 if (!img) return *this;
12997 if (is_empty()) return img;
12998 CImgList<T> temp(2);
12999 temp[0].width = width; temp[0].height = height; temp[0].depth = depth;
13000 temp[0].dim = dim; temp[0].data = data;
13001 temp[1].width = img.width; temp[1].height = img.height; temp[1].depth = img.depth;
13002 temp[1].dim = img.dim; temp[1].data = img.data;
13003 const CImg<T> res = temp.get_append(axis,align);
13004 temp[0].width = temp[0].height = temp[0].depth = temp[0].dim = 0; temp[0].data = 0;
13005 temp[1].width = temp[1].height = temp[1].depth = temp[1].dim = 0; temp[1].data = 0;
13006 return res;
13007 }
13008
13010 CImg<T>& append(const CImg<T>& img, const char axis='x', const char align='c') {
13011 if (!img) return *this;
13012 if (is_empty()) return (*this=img);
13013 return get_append(img,axis,align).assign_to(*this);
13014 }
13015
13017
13026 CImgList<typename cimg::superset<T,float>::type> get_gradientXY(const int scheme=0) const {
13027 typedef typename cimg::superset<T,float>::type restype;
13028 if (is_empty()) return CImgList<restype>(2);
13029 CImgList<restype> res(2,width,height,depth,dim);
13030 switch(scheme) {
13031 case -1: {
13032 CImg_3x3(I,restype);
13033 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; }
13034 } break;
13035 case 1: {
13036 CImg_2x2(I,restype);
13037 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; }
13038 } break;
13039 case 2: {
13040 CImg_3x3(I,restype);
13041 const float a = 1, b = 2;
13042 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
13043 res[0](x,y,z,k) = -a*Ipp-b*Ipc-a*Ipn+a*Inp+b*Inc+a*Inn;
13044 res[1](x,y,z,k) = -a*Ipp-b*Icp-a*Inp+a*Ipn+b*Icn+a*Inn;
13045 }
13046 } break;
13047 case 3: {
13048 CImg_3x3(I,restype);
13049 const float a = (float)(0.25*(2-std::sqrt(2.0))), b = (float)(0.5f*(std::sqrt(2.0)-1));
13050 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
13051 res[0](x,y,z,k) = -a*Ipp-b*Ipc-a*Ipn+a*Inp+b*Inc+a*Inn;
13052 res[1](x,y,z,k) = -a*Ipp-b*Icp-a*Inp+a*Ipn+b*Icn+a*Inn;
13053 }
13054 } break;
13055 case 4: {
13056 res[0] = get_deriche(0,1,'x');
13057 res[1] = get_deriche(0,1,'y');
13058 } break;
13059 default: {
13060 CImg_3x3(I,restype);
13061 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
13062 res[0](x,y,z,k) = 0.5f*(Inc-Ipc);
13063 res[1](x,y,z,k) = 0.5f*(Icn-Icp);
13064 }
13065 } break;
13066 }
13067 return res;
13068 }
13069
13071
13074 CImgList<typename cimg::superset<T,float>::type> get_gradientXYZ(const int scheme=0) const {
13075 typedef typename cimg::superset<T,float>::type restype;
13076 if (is_empty()) return CImgList<restype>(3);
13077 CImgList<restype> res(3,width,height,depth,dim);
13078 CImg_3x3x3(I,restype);
13079 switch(scheme) {
13080 case -1: {
13081 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13082 res[0](x,y,z,k) = Iccc-Ipcc;
13083 res[1](x,y,z,k) = Iccc-Icpc;
13084 res[2](x,y,z,k) = Iccc-Iccp;
13085 }
13086 } break;
13087 case 1: {
13088 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13089 res[0](x,y,z,k) = Incc-Iccc;
13090 res[1](x,y,z,k) = Icnc-Iccc;
13091 res[2](x,y,z,k) = Iccn-Iccc;
13092 }
13093 } break;
13094 case 4: {
13095 res[0] = get_deriche(0,1,'x');
13096 res[1] = get_deriche(0,1,'y');
13097 res[2] = get_deriche(0,1,'z');
13098 } break;
13099 default: {
13100 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13101 res[0](x,y,z,k) = 0.5f*(Incc-Ipcc);
13102 res[1](x,y,z,k) = 0.5f*(Icnc-Icpc);
13103 res[2](x,y,z,k) = 0.5f*(Iccn-Iccp);
13104 }
13105 } break;
13106 }
13107 return res;
13108 }
13109
13111 CImg<typename cimg::superset<T,float>::type> get_structure_tensorXY(const int scheme=1) const {
13112 typedef typename cimg::superset<T,float>::type restype;
13113 if (is_empty()) return CImg<restype>();
13114 CImg<restype> res(width,height,depth,3,0);
13115 CImg_3x3(I,restype);
13116 switch (scheme) {
13117 case 0: {
13118 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,0,k,I) {
13119 const restype
13120 ix = 0.5f*(Inc-Ipc),
13121 iy = 0.5f*(Icn-Icp);
13122 res(x,y,z,0)+=ix*ix;
13123 res(x,y,z,1)+=ix*iy;
13124 res(x,y,z,2)+=iy*iy;
13125 }
13126 } break;
13127 default: {
13128 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,0,k,I) {
13129 const restype
13130 ixf = Inc-Icc, ixb = Icc-Ipc,
13131 iyf = Icn-Icc, iyb = Icc-Icp;
13132 res(x,y,z,0) += 0.5f*(ixf*ixf+ixb*ixb);
13133 res(x,y,z,1) += 0.25f*(ixf*iyf+ixf*iyb+ixb*iyf+ixb*iyb);
13134 res(x,y,z,2) += 0.5f*(iyf*iyf+iyb*iyb);
13135 }
13136 } break;
13137 }
13138 return res;
13139 }
13140
13142 CImg<T>& structure_tensorXY(const int scheme=1) {
13143 return get_structure_tensorXY(scheme).assign_to(*this);
13144 }
13145
13147 CImg<typename cimg::superset<T,float>::type> get_structure_tensorXYZ(const int scheme=1) const {
13148 typedef typename cimg::superset<T,float>::type restype;
13149 if (is_empty()) return CImg<restype>();
13150 CImg<restype> res(width,height,depth,6,0);
13151 CImg_3x3x3(I,restype);
13152 switch (scheme) {
13153 case 0: {
13154 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13155 const restype
13156 ix = 0.5f*(Incc-Ipcc),
13157 iy = 0.5f*(Icnc-Icpc),
13158 iz = 0.5f*(Iccn-Iccp);
13159 res(x,y,z,0)+=ix*ix;
13160 res(x,y,z,1)+=ix*iy;
13161 res(x,y,z,2)+=ix*iz;
13162 res(x,y,z,3)+=iy*iy;
13163 res(x,y,z,4)+=iy*iz;
13164 res(x,y,z,5)+=iz*iz;
13165 }
13166 } break;
13167 default: {
13168 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13169 const restype
13170 ixf = Incc-Iccc, ixb = Iccc-Ipcc,
13171 iyf = Icnc-Iccc, iyb = Iccc-Icpc,
13172 izf = Iccn-Iccc, izb = Iccc-Iccp;
13173 res(x,y,z,0) += 0.5f*(ixf*ixf + ixb*ixb);
13174 res(x,y,z,1) += 0.25f*(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb);
13175 res(x,y,z,2) += 0.25f*(ixf*izf + ixf*izb + ixb*izf + ixb*izb);
13176 res(x,y,z,3) += 0.5f*(iyf*iyf + iyb*iyb);
13177 res(x,y,z,4) += 0.25f*(iyf*izf + iyf*izb + iyb*izf + iyb*izb);
13178 res(x,y,z,5) += 0.5f*(izf*izf + izb*izb);
13179 }
13180 } break;
13181 }
13182 return res;
13183 }
13184
13186 CImg<T>& structure_tensorXYZ(const int scheme=1) {
13187 return get_structure_tensorXYZ(scheme).assign_to(*this);
13188 }
13189
13191
13194 CImgList<typename cimg::superset<T,float>::type> get_hessianXY() {
13195 typedef typename cimg::superset<T,float>::type ftype;
13196 if (is_empty()) return CImgList<ftype>(3);
13197 CImgList<ftype> res(3,width,height,depth,dim);
13198 CImg_3x3(I,ftype);
13199 cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
13200 res[0](x,y,z,k) = Ipc + Inc - 2*Icc;
13201 res[1](x,y,z,k) = 0.25f*(Ipp + Inn - Ipn - Inp);
13202 res[2](x,y,z,k) = Icp + Icn - 2*Icc;
13203 }
13204 return res;
13205 }
13206
13208
13211 CImgList<typename cimg::superset<T,float>::type> get_hessianXYZ() {
13212 typedef typename cimg::superset<T,float>::type ftype;
13213 if (is_empty()) return CImgList<ftype>(6);
13214 CImgList<ftype> res(6,width,height,depth,dim);
13215 CImg_3x3x3(I,ftype);
13216 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
13217 res[0](x,y,z,k) = Ipcc + Incc - 2*Iccc;
13218 res[1](x,y,z,k) = 0.25f*(Ippc + Innc - Ipnc - Inpc);
13219 res[2](x,y,z,k) = 0.25f*(Ipcp + Incn - Ipcn - Incp);
13220 res[3](x,y,z,k) = Icpc + Icnc - 2*Iccc;
13221 res[4](x,y,z,k) = 0.25f*(Icpp + Icnn - Icpn - Icnp);
13222 res[5](x,y,z,k) = Iccn + Iccp - 2*Iccc;
13223 }
13224 return res;
13225 }
13226
13228 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 {
13229 typedef typename cimg::superset<T,float>::type ftype;
13230 return CImg<ftype>(*this,false).distance_function(nb_iter,band_size,precision);
13231 }
13232
13234 CImg<T>& distance_function(const unsigned int nb_iter=100, const float band_size=0.0f, const float precision=0.5f) {
13235 typedef typename cimg::superset<T,float>::type ftype;
13236 if (is_empty()) return *this;
13237 CImg<ftype> veloc(*this);
13238 for (unsigned int iter=0; iter<nb_iter; ++iter) {
13239
13240 if (depth>1) {
13241 CImg_3x3x3(I,ftype);
13242 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) if (band_size<=0 || cimg::abs(Iccc)<band_size) {
13243 const ftype
13244 gx = 0.5f*(Incc-Ipcc),
13245 gy = 0.5f*(Icnc-Icpc),
13246 gz = 0.5f*(Iccn-Iccp),
13247 sgn = -cimg::sign(Iccc),
13248 ix = gx*sgn>0?Incc-Iccc:Iccc-Ipcc,
13249 iy = gy*sgn>0?Icnc-Iccc:Iccc-Icpc,
13250 iz = gz*sgn>0?Iccn-Iccc:Iccc-Iccp,
13251 ng = 1e-5f+(ftype)std::sqrt(gx*gx+gy*gy+gz*gz),
13252 ngx = gx/ng,
13253 ngy = gy/ng,
13254 ngz = gz/ng;
13255 veloc(x,y,z,k) = sgn*(ngx*ix+ngy*iy+ngz*iz-1);
13256 }
13257 } else {
13258 CImg_3x3(I,ftype);
13259 cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) if (band_size<=0 || cimg::abs(Icc)<band_size) {
13260 const ftype
13261 gx = 0.5f*(Inc-Ipc),
13262 gy = 0.5f*(Icn-Icp),
13263 sgn = -cimg::sign(Icc),
13264 ix = gx*sgn>0?Inc-Icc:Icc-Ipc,
13265 iy = gy*sgn>0?Icn-Icc:Icc-Icp,
13266 ng = 1e-5f+(ftype)std::sqrt(gx*gx+gy*gy),
13267 ngx = gx/ng,
13268 ngy = gy/ng;
13269 veloc(x,y,k) = sgn*(ngx*ix+ngy*iy-1);
13270 }
13271 }
13272 float m, M = (float)veloc.maxmin(m), xdt = precision/(float)cimg::max(cimg::abs(m),cimg::abs(M));
13273 *this+=(veloc*=xdt);
13274 }
13275 return *this;
13276 }
13277
13279
13287 template<typename tf, typename t>
13288 static CImg<T> get_dijkstra(const tf& distance, const unsigned int nb_nodes,
13289 const unsigned int starting_node, const unsigned int ending_node,
13290 CImg<t>& previous) {
13291
13292 CImg<T> dist(1,nb_nodes,1,1,cimg::type<T>::max());
13293 dist(starting_node) = 0;
13294 previous.assign(1,nb_nodes,1,1,(t)-1);
13295 previous(starting_node) = (t)starting_node;
13296 typedef typename cimg::last<T,unsigned int>::type uitype;
13297 CImg<uitype> Q(nb_nodes);
13298 cimg_forX(Q,u) Q(u) = u;
13299 cimg::swap(Q(starting_node),Q(0));
13300 unsigned int sizeQ = nb_nodes;
13301 while (sizeQ) {
13302
13303 const unsigned int umin = Q(0);
13304 if (umin==ending_node) sizeQ = 0;
13305 else {
13306 const T dmin = dist(umin);
13307 const T infty = cimg::type<T>::max();
13308 for (unsigned int q=1; q<sizeQ; ++q) {
13309 const unsigned int v = Q(q);
13310 const T d = (T)distance(v,umin);
13311 if (d<infty) {
13312 const T alt = dmin + d;
13313 if (alt<dist(v)) {
13314 dist(v) = alt;
13315 previous(v) = (t)umin;
13316 const T distpos = dist(Q(q));
13317 for (unsigned int pos = q, par = 0; pos && distpos<dist(Q(par=(pos+1)/2-1)); pos=par) cimg::swap(Q(pos),Q(par));
13318 }
13319 }
13320 }
13321
13322 Q(0) = Q(--sizeQ);
13323 const T distpos = dist(Q(0));
13324 for (unsigned int pos = 0, left = 0, right = 0;
13325 ((right=2*(pos+1),(left=right-1))<sizeQ && distpos>dist(Q(left))) || (right<sizeQ && distpos>dist(Q(right)));) {
13326 if (right<sizeQ) {
13327 if (dist(Q(left))<dist(Q(right))) { cimg::swap(Q(pos),Q(left)); pos = left; }
13328 else { cimg::swap(Q(pos),Q(right)); pos = right; }
13329 } else { cimg::swap(Q(pos),Q(left)); pos = left; }
13330 }
13331 }
13332 }
13333 return dist;
13334 }
13335
13336 template<typename tf, typename t>
13337 static CImg<T> get_dijkstra(const tf& distance, const unsigned int nb_nodes,
13338 const unsigned int starting_node, const unsigned int ending_node=~0U) {
13339 typedef typename cimg::last<T,unsigned int>::type uitype;
13340 CImg<uitype> foo;
13341 return get_dijkstra(distance,nb_nodes,starting_node,ending_node,foo);
13342 }
13343
13345
13351 template<typename t> CImg<T> get_dijkstra(const unsigned int starting_node, const unsigned int ending_node, CImg<t>& previous) const {
13352 if (width!=height || depth!=1 || dim!=1)
13353 throw CImgInstanceException("CImg<%s>::dijkstra() : Instance image (%u,%u,%u,%u,%p) is not a graph adjacency matrix",
13354 pixel_type(),width,height,depth,dim,data);
13355 return CImg<T>::get_dijkstra(*this,width,starting_node,ending_node,previous);
13356 }
13357
13358
13359 template<typename t> CImg<T>& dijkstra(const unsigned int starting_node, const unsigned int ending_node, CImg<t>& previous) {
13360 return get_dijkstra(starting_node,ending_node,previous).assign_to(*this);
13361 }
13362
13364 CImg<typename cimg::superset<T,float>::type> get_dijkstra(const unsigned int starting_node, const unsigned int ending_node=~0U) const {
13365 typedef typename cimg::last<T,unsigned int>::type uitype;
13366 CImg<uitype> foo;
13367 return get_dijkstra(starting_node,ending_node,foo);
13368 }
13369
13370
13371 CImg<T>& dijkstra(const unsigned int starting_node, const unsigned int ending_node=~0U) {
13372 return get_dijkstra(starting_node,ending_node).assign_to(*this);
13373 }
13374
13376
13377
13379
13380
13381
13382 struct _marching_squares_func {
13383 const CImg<T>& ref;
13384 _marching_squares_func(const CImg<T>& pref):ref(pref) {}
13385 float operator()(const float x, const float y) const {
13386 return (float)ref((int)x,(int)y);
13387 }
13388 };
13389
13390 struct _marching_cubes_func {
13391 const CImg<T>& ref;
13392 _marching_cubes_func(const CImg<T>& pref):ref(pref) {}
13393 float operator()(const float x, const float y, const float z) const {
13394 return (float)ref((int)x,(int)y,(int)z);
13395 }
13396 };
13397
13398 struct _marching_squares_func_float {
13399 const CImg<T>& ref;
13400 _marching_squares_func_float(const CImg<T>& pref):ref(pref) {}
13401 float operator()(const float x, const float y) const {
13402 return (float)ref.linear_pix2d(x,y);
13403 }
13404 };
13405
13406 struct _marching_cubes_func_float {
13407 const CImg<T>& ref;
13408 _marching_cubes_func_float(const CImg<T>& pref):ref(pref) {}
13409 float operator()(const float x, const float y, const float z) const {
13410 return (float)ref.linear_pix3d(x,y,z);
13411 }
13412 };
13413
13415 template<typename tp, typename tf>
13416 const CImg<T>& marching_squares(const float isovalue, CImgList<tp>& points, CImgList<tf>& primitives) const {
13417 if (height<=1 || depth>1 || dim>1)
13418 throw CImgInstanceException("CImg<%s>::marching_squares() : Instance image (%u,%u,%u,%u,%p) is not a 2D scalar image.",
13419 pixel_type(),width,height,depth,dim,data);
13420 const _marching_squares_func func(*this);
13421 cimg::marching_squares(func,isovalue,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,1.0f,1.0f,points,primitives);
13422 return *this;
13423 }
13424
13426
13429 template<typename tp, typename tf>
13430 const CImg<T>& marching_squares(const float isovalue,
13431 const float resx, const float resy,
13432 CImgList<tp>& points, CImgList<tf>& primitives) const {
13433 if (height<=1 || depth>1 || dim>1)
13434 throw CImgInstanceException("CImg<%s>::marching_squares() : Instance image (%u,%u,%u,%u,%p) is not a 2D scalar image.",
13435 pixel_type(),width,height,depth,dim,data);
13436 const _marching_squares_func_float func(*this);
13437 cimg::marching_squares(func,isovalue,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,resx,resy,points,primitives);
13438 return *this;
13439 }
13440
13442 template<typename tp, typename tf>
13443 const CImg<T>& marching_cubes(const float isovalue, CImgList<tp>& points, CImgList<tf>& primitives,
13444 const bool invert_faces = false) const {
13445 if (depth<=1 || dim>1)
13446 throw CImgInstanceException("CImg<%s>::marching_cubes() : Instance image (%u,%u,%u,%u,%p) is not a 3D scalar image.",
13447 pixel_type(),width,height,depth,dim,data);
13448 const _marching_cubes_func func(*this);
13449 cimg::marching_cubes(func,isovalue,0.0f,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,dimz()-1.0f,
13450 1.0f,1.0f,1.0f,points,primitives,invert_faces);
13451 return *this;
13452 }
13453
13455
13458 template<typename tp, typename tf>
13459 const CImg<T>& marching_cubes(const float isovalue,
13460 const float resx, const float resy, const float resz,
13461 CImgList<tp>& points, CImgList<tf>& primitives,
13462 const bool invert_faces = false) const {
13463 if (depth<=1 || dim>1)
13464 throw CImgInstanceException("CImg<%s>::marching_cubes() : Instance image (%u,%u,%u,%u,%p) is not a 3D scalar image.",
13465 pixel_type(),width,height,depth,dim,data);
13466 const _marching_cubes_func_float func(*this);
13467 cimg::marching_cubes(func,isovalue,0.0f,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,dimz()-1.0f,
13468 resx,resy,resz,points,primitives,invert_faces);
13469 return *this;
13470 }
13471
13473
13474
13476
13477
13478
13480
13486 static CImg<T> get_default_LUT8() {
13487 static CImg<T> palette;
13488 if (!palette) {
13489 palette.assign(1,256,1,3);
13490 for (unsigned int index=0, r=16; r<256; r+=32)
13491 for (unsigned int g=16; g<256; g+=32)
13492 for (unsigned int b=32; b<256; b+=64) {
13493 palette(0,index,0) = (T)r;
13494 palette(0,index,1) = (T)g;
13495 palette(0,index++,2) = (T)b;
13496 }
13497 }
13498 return palette;
13499 }
13500
13502 static CImg<T> get_rainbow_LUT8() {
13503 static CImg<T> palette;
13504 if (!palette) {
13505 typedef typename cimg::superset<T,int>::type itype;
13506 CImg<itype> tmp(1,256,1,3,255);
13507 tmp.get_shared_channel(0).sequence(0,359);
13508 tmp.HSVtoRGB();
13509 palette = tmp;
13510 }
13511 return palette;
13512 }
13513
13515 static CImg<T> get_cluster_LUT8() {
13516 static const unsigned char pal[] =
13517 { 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,
13518 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,
13519 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,
13520 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,
13521 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,
13522 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,
13523 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,
13524 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,
13525 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,
13526 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,
13527 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,
13528 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,
13529 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,
13530 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,
13531 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,
13532 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,
13533 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,
13534 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,
13535 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,
13536 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,
13537 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,
13538 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,
13539 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,
13540 23,168,19,50,240,244,185,0,1,144,10,168,31,82,1,13 };
13541 static const CImg<T> palette(pal,256,1,1,3,false);
13542 return palette;
13543 }
13544
13546
13554 template<typename t> CImg<t> get_RGBtoLUT(const CImg<t>& palette, const bool dithering=true, const bool indexing=false) const {
13555 if (is_empty()) return CImg<t>();
13556 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoLUT() : Input image dimension is dim=%u, "
13557 "should be a (R,G,B) image.",pixel_type(),dim);
13558 if (palette.data && palette.dim!=3)
13559 throw CImgArgumentException("CImg<%s>::RGBtoLUT() : Given palette dimension is dim=%u, "
13560 "should be a (R,G,B) palette",pixel_type(),palette.dim);
13561 CImg<t> res(width,height,depth,indexing?1:3), pal = palette.data?palette:CImg<t>::get_default_LUT8();
13562 float *line1 = new float[3*width], *line2 = new float[3*width], *pline1 = line1, *pline2 = line2;
13563 cimg_forZ(*this,z) {
13564 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); }
13565 cimg_forY(*this,y) {
13566 cimg::swap(pline1,pline2);
13567 if (y<dimy()-1) {
13568 const int ny = y+1;
13569 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); }
13570 }
13571 float *ptr1=pline1, *ptr2=pline2;
13572 cimg_forX(*this,x) {
13573 float R = *(ptr1++), G = *(ptr1++), B = *(ptr1++);
13574 R = R<0?0:(R>255?255:R); G = G<0?0:(G>255?255:G); B = B<0?0:(B>255?255:B);
13575 int best_index = 0;
13576 t Rbest = 0, Gbest = 0, Bbest = 0;
13577 if (palette.data) {
13578 float min = cimg::type<float>::max();
13579 cimg_forX(palette,off) {
13580 const t Rp = palette(off,0), Gp = palette(off,1), Bp = palette(off,2);
13581 const float error = (float)((Rp-R)*(Rp-R) + (Gp-G)*(Gp-G) + (Bp-B)*(Bp-B));
13582 if (error<min) { min=error; best_index=off; Rbest=Rp; Gbest=Gp; Bbest=Bp; }
13583 }
13584 } else {
13585 Rbest = (t)((unsigned char)R&0xe0); Gbest = (t)((unsigned char)G&0xe0); Bbest = (t)((unsigned char)B&0xc0);
13586 best_index = (unsigned char)Rbest | ((unsigned char)Gbest>>3) | ((unsigned char)Bbest>>6);
13587 }
13588 if (indexing) res(x,y,z) = best_index;
13589 else { res(x,y,z,0) = Rbest; res(x,y,z,1) = Gbest; res(x,y,z,2) = Bbest; }
13590 if (dithering) {
13591 const float dR = (float)(R-Rbest), dG = (float)(G-Gbest), dB = (float)(B-Bbest);
13592 if (x<dimx()-1) { *(ptr1++)+= dR*7/16; *(ptr1++)+= dG*7/16; *(ptr1++)+= dB*7/16; ptr1-=3; }
13593 if (y<dimy()-1) {
13594 *(ptr2++)+= dR*5/16; *(ptr2++)+= dG*5/16; *ptr2+= dB*5/16; ptr2-=2;
13595 if (x>0) { *(--ptr2)+= dB*3/16; *(--ptr2)+= dG*3/16; *(--ptr2)+= dR*3/16; ptr2+=3; }
13596 if (x<dimx()-1) { ptr2+=3; *(ptr2++)+= dR/16; *(ptr2++)+= dG/16; *ptr2+= dB/16; ptr2-=5; }
13597 }
13598 }
13599 ptr2+=3;
13600 }
13601 }
13602 }
13603 delete[] line1; delete[] line2;
13604 return res;
13605 }
13606
13608 CImg<T>& RGBtoLUT(const CImg<T>& palette, const bool dithering=true, const bool indexing=false) {
13609 return get_RGBtoLUT(palette,dithering,indexing).assign_to(*this);
13610 }
13611
13613
13616 CImg<T> get_RGBtoLUT(const bool dithering=true, const bool indexing=false) const {
13617 CImg<T> foo;
13618 return get_RGBtoLUT(foo,dithering,indexing);
13619 }
13620
13622 CImg<T>& RGBtoLUT(const bool dithering=true, const bool indexing=false) {
13623 CImg<T> foo;
13624 return get_RGBtoLUT(foo,dithering,indexing).assign_to(*this);
13625 }
13626
13628 template<typename t> CImg<t> get_LUTtoRGB(const CImg<t>& palette) const {
13629 if (is_empty()) return CImg<t>();
13630 if (dim!=1) throw CImgInstanceException("CImg<%s>::LUTtoRGB() : Input image dimension is dim=%u, "
13631 "should be a LUT image",pixel_type(),dim);
13632 if (palette.data && palette.dim!=3)
13633 throw CImgArgumentException("CImg<%s>::LUTtoRGB() : Given palette dimension is dim=%u, "
13634 "should be a (R,G,B) palette",pixel_type(),palette.dim);
13635 CImg<t> res(width,height,depth,3);
13636 CImg<t> pal = palette.data?palette:CImg<t>::get_default_LUT8();
13637 cimg_forXYZ(*this,x,y,z) {
13638 const unsigned int index = (unsigned int)(*this)(x,y,z);
13639 res(x,y,z,0) = pal(index,0);
13640 res(x,y,z,1) = pal(index,1);
13641 res(x,y,z,2) = pal(index,2);
13642 }
13643 return res;
13644 }
13645
13647 CImg<T>& LUTtoRGB(const CImg<T>& palette) {
13648 return get_LUTtoRGB(palette).assign_to(*this);
13649 }
13650
13652 CImg<T> get_LUTtoRGB() const {
13653 CImg<T> foo;
13654 return get_LUTtoRGB(foo);
13655 }
13656
13658 CImg<T>& LUTtoRGB() {
13659 CImg<T> foo;
13660 return get_LUTtoRGB(foo).assign_to(*this);
13661 }
13662
13664 CImg<typename cimg::superset<T,float>::type> get_RGBtoHSV() const {
13665 typedef typename cimg::superset<T,float>::type ftype;
13666 return CImg<ftype>(*this).RGBtoHSV();
13667 }
13668
13670 CImg<T>& RGBtoHSV() {
13671 if (!is_empty()) {
13672 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoHSV() : Input image dimension is dim=%u, "
13673 "should be a (R,G,B) image.",pixel_type(),dim);
13674 cimg_forXYZ(*this,x,y,z) {
13675 const float
13676 R = (float)((*this)(x,y,z,0)/255.0f),
13677 G = (float)((*this)(x,y,z,1)/255.0f),
13678 B = (float)((*this)(x,y,z,2)/255.0f);
13679 const float m = cimg::min(R,G,B), M = cimg::max(R,G,B);
13680 float H = 0, S = 0;
13681 if (M!=m) {
13682 const float
13683 f = (R==m)?(G-B):((G==m)?(B-R):(R-G)),
13684 i = (R==m)?3.0f:((G==m)?5.0f:1.0f);
13685 H = (i-f/(M-m));
13686 if (H>=6.0f) H-=6.0f;
13687 H*=60;
13688 S = (M-m)/M;
13689 }
13690 (*this)(x,y,z,0) = (T)H;
13691 (*this)(x,y,z,1) = (T)S;
13692 (*this)(x,y,z,2) = (T)M;
13693 }
13694 }
13695 return *this;
13696 }
13697
13699 CImg<T> get_HSVtoRGB() const {
13700 return (+*this).HSVtoRGB();
13701 }
13702
13704 CImg<T>& HSVtoRGB() {
13705 if (!is_empty()) {
13706 if (dim!=3) throw CImgInstanceException("CImg<%s>::HSVtoRGB() : Input image dimension is dim=%u, "
13707 "should be a (H,S,V) image",pixel_type(),dim);
13708 cimg_forXYZ(*this,x,y,z) {
13709 float
13710 H = (float)((*this)(x,y,z,0)),
13711 S = (float)((*this)(x,y,z,1)),
13712 V = (float)((*this)(x,y,z,2));
13713 float R = 0, G = 0, B = 0;
13714 if (H<0) R = G = B = V;
13715 else {
13716 H/=60.0f;
13717 const int i = (int)std::floor(H);
13718 const float
13719 f = (i&1)?(H-i):(1.0f-H+i),
13720 m = V*(1.0f-S),
13721 n = V*(1.0f-S*f);
13722 switch(i) {
13723 case 6:
13724 case 0: R = V; G = n; B = m; break;
13725 case 1: R = n; G = V; B = m; break;
13726 case 2: R = m; G = V; B = n; break;
13727 case 3: R = m; G = n; B = V; break;
13728 case 4: R = n; G = m; B = V; break;
13729 case 5: R = V; G = m; B = n; break;
13730 }
13731 }
13732 (*this)(x,y,z,0) = (T)(R*255.0f);
13733 (*this)(x,y,z,1) = (T)(G*255.0f);
13734 (*this)(x,y,z,2) = (T)(B*255.0f);
13735 }
13736 }
13737 return *this;
13738 }
13739
13741 CImg<typename cimg::superset<T,float>::type> get_RGBtoHSL() const {
13742 typedef typename cimg::superset<T,float>::type ftype;
13743 return CImg<ftype>(*this).RGBtoHSL();
13744 }
13745
13747 CImg<T>& RGBtoHSL() {
13748 if (!is_empty()) {
13749 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoHSL() : Input image dimension is dim=%u, "
13750 "should be a (R,G,B) image.",pixel_type(),dim);
13751 cimg_forXYZ(*this,x,y,z) {
13752 const float
13753 R = (float)((*this)(x,y,z,0)/255.0f),
13754 G = (float)((*this)(x,y,z,1)/255.0f),
13755 B = (float)((*this)(x,y,z,2)/255.0f);
13756 const float m = cimg::min(R,G,B), M = cimg::max(R,G,B), L = 0.5f*(m+M);
13757 float H = 0, S = 0;
13758 if (M==m || L==0) H = S = 0;
13759 else {
13760 const float
13761 f = (R==m)?(G-B):((G==m)?(B-R):(R-G)),
13762 i = (R==m)?3.0f:((G==m)?5.0f:1.0f);
13763 H = (i-f/(M-m));
13764 if (H>=6.0f) H-=6.0f;
13765 H*=60;
13766 S = (L<=0.5f)?((M-m)/(M+m)):((M-m)/(2-M-m));
13767 }
13768 (*this)(x,y,z,0) = (T)H;
13769 (*this)(x,y,z,1) = (T)S;
13770 (*this)(x,y,z,2) = (T)L;
13771 }
13772 }
13773 return *this;
13774 }
13775
13777 CImg<T> get_RGBtoYCbCr() const {
13778 return (+*this).RGBtoYCbCr();
13779 }
13780
13782 CImg<T>& RGBtoYCbCr() {
13783 if (!is_empty()) {
13784 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoYCbCr() : Input image dimension is dim=%u, "
13785 "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
13786 cimg_forXYZ(*this,x,y,z) {
13787 const int
13788 R = (int)((*this)(x,y,z,0)),
13789 G = (int)((*this)(x,y,z,1)),
13790 B = (int)((*this)(x,y,z,2));
13791 const int
13792 Y = ((66*R+129*G+25*B+128)>>8) + 16,
13793 Cb = ((-38*R-74*G+112*B+128)>>8) + 128,
13794 Cr = ((112*R-94*G-18*B+128)>>8) + 128;
13795 (*this)(x,y,z,0) = (T)(Y<0?0:(Y>255?255:Y));
13796 (*this)(x,y,z,1) = (T)(Cb<0?0:(Cb>255?255:Cb));
13797 (*this)(x,y,z,2) = (T)(Cr<0?0:(Cr>255?255:Cr));
13798 }
13799 }
13800 return *this;
13801 }
13802
13804 CImg<T> get_YCbCrtoRGB() const {
13805 return (+*this).YCbCrtoRGB();
13806 }
13807
13809 CImg<T>& YCbCrtoRGB() {
13810 if (!is_empty()) {
13811 if (dim!=3) throw CImgInstanceException("CImg<%s>::YCbCrtoRGB() : Input image dimension is dim=%u, "
13812 "should be a (Y,Cb,Cr)_8 image (dim=3)",pixel_type(),dim);
13813 cimg_forXYZ(*this,x,y,z) {
13814 const int
13815 Y = (int)((*this)(x, y, z, 0)-16),
13816 Cb = (int)((*this)(x, y, z, 1)-128),
13817 Cr = (int)((*this)(x, y, z, 2)-128);
13818 const int
13819 R = ((298*Y + 409*Cr + 128) >> 8 ),
13820 G = ((298*Y - 100*Cb - 208*Cr + 128) >> 8 ),
13821 B = ((298*Y + 516*Cb + 128) >> 8 );
13822 (*this)(x,y,z,0) = (T)(R<0?0:(R>255?255:R));
13823 (*this)(x,y,z,1) = (T)(G<0?0:(G>255?255:G));
13824 (*this)(x,y,z,2) = (T)(B<0?0:(B>255?255:B));
13825 }
13826 }
13827 return *this;
13828 }
13829
13831 CImg<typename cimg::superset<T,float>::type> get_RGBtoYUV() const {
13832 typedef typename cimg::superset<T,float>::type restype;
13833 return CImg<restype>(*this,false).RGBtoYUV();
13834 }
13835
13837 CImg<T>& RGBtoYUV() {
13838 if (!is_empty()) {
13839 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoYUV() : Input image dimension is dim=%u, "
13840 "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
13841 cimg_forXYZ(*this,x,y,z) {
13842 const float
13843 R = (*this)(x,y,z,0)/255.0f,
13844 G = (*this)(x,y,z,1)/255.0f,
13845 B = (*this)(x,y,z,2)/255.0f,
13846 Y = (T)(0.299*R + 0.587*G + 0.114*B);
13847 (*this)(x,y,z,0) = (T)Y;
13848 (*this)(x,y,z,1) = (T)(0.492*(B-Y));
13849 (*this)(x,y,z,2) = (T)(0.877*(R-Y));
13850 }
13851 }
13852 return *this;
13853 }
13854
13856 CImg<T> get_YUVtoRGB() const {
13857 return (+*this).YUVtoRGB();
13858 }
13859
13861 CImg<T>& YUVtoRGB() {
13862 if (!is_empty()) {
13863 if (dim!=3) throw CImgInstanceException("CImg<%s>::YUVtoRGB() : Input image dimension is dim=%u, "
13864 "should be a (Y,U,V) image (dim=3)",pixel_type(),dim);
13865 cimg_forXYZ(*this,x,y,z) {
13866 const T Y = (*this)(x,y,z,0), U = (*this)(x,y,z,1), V = (*this)(x,y,z,2);
13867 (*this)(x,y,z,0) = (T)((Y + 1.140*V)*255.0f);
13868 (*this)(x,y,z,1) = (T)((Y - 0.395*U - 0.581*V)*255.0f);
13869 (*this)(x,y,z,2) = (T)((Y + 2.032*U)*255.0f);
13870 }
13871 }
13872 return *this;
13873 }
13874
13876 CImg<typename cimg::superset<T,float>::type> get_RGBtoXYZ() const {
13877 typedef typename cimg::superset<T,float>::type restype;
13878 return CImg<restype>(*this,false).RGBtoXYZ();
13879 }
13880
13882 CImg<T>& RGBtoXYZ() {
13883 if (!is_empty()) {
13884 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoXYZ() : Input image dimension is dim=%u, "
13885 "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
13886 cimg_forXYZ(*this,x,y,z) {
13887 const float
13888 R = (float)((*this)(x,y,z,0)/255.0f),
13889 G = (float)((*this)(x,y,z,1)/255.0f),
13890 B = (float)((*this)(x,y,z,2)/255.0f);
13891 (*this)(x,y,z,0) = (T)(0.412453*R + 0.357580*G + 0.180423*B);
13892 (*this)(x,y,z,1) = (T)(0.212671*R + 0.715160*G + 0.072169*B);
13893 (*this)(x,y,z,2) = (T)(0.019334*R + 0.119193*G + 0.950227*B);
13894 }
13895 }
13896 return *this;
13897 }
13898
13900 CImg<T> get_XYZtoRGB() const {
13901 return (+*this).XYZtoRGB();
13902 }
13903
13905 CImg<T>& XYZtoRGB() {
13906 if (!is_empty()) {
13907 if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoRGB() : Input image dimension is dim=%u, "
13908 "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
13909 cimg_forXYZ(*this,x,y,z) {
13910 const float
13911 X = (float)(255.0f*(*this)(x,y,z,0)),
13912 Y = (float)(255.0f*(*this)(x,y,z,1)),
13913 Z = (float)(255.0f*(*this)(x,y,z,2));
13914 (*this)(x,y,z,0) = (T)(3.240479*X - 1.537150*Y - 0.498535*Z);
13915 (*this)(x,y,z,1) = (T)(-0.969256*X + 1.875992*Y + 0.041556*Z);
13916 (*this)(x,y,z,2) = (T)(0.055648*X - 0.204043*Y + 1.057311*Z);
13917 }
13918 }
13919 return *this;
13920 }
13921
13923 CImg<T> get_XYZtoLab() const {
13924 return (+*this).XYZtoLab();
13925 }
13926
13928 CImg<T>& XYZtoLab() {
13929 #define cimg_Labf(x) ((x)>=0.008856?(std::pow(x,1/3.0)):(7.787*(x)+16.0/116.0))
13930 if (!is_empty()) {
13931 if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoLab() : Input image dimension is dim=%u, "
13932 "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
13933 const double
13934 Xn = 0.412453 + 0.357580 + 0.180423,
13935 Yn = 0.212671 + 0.715160 + 0.072169,
13936 Zn = 0.019334 + 0.119193 + 0.950227;
13937 cimg_forXYZ(*this,x,y,z) {
13938 const T X = (*this)(x,y,z,0), Y = (*this)(x,y,z,1), Z = (*this)(x,y,z,2);
13939 const double
13940 XXn = X/Xn, YYn = Y/Yn, ZZn = Z/Zn,
13941 fX = cimg_Labf(XXn), fY = cimg_Labf(YYn), fZ = cimg_Labf(ZZn);
13942 (*this)(x,y,z,0) = (T)(116*fY-16);
13943 (*this)(x,y,z,1) = (T)(500*(fX-fY));
13944 (*this)(x,y,z,2) = (T)(200*(fY-fZ));
13945 }
13946 }
13947 return *this;
13948 }
13949
13951 CImg<T> get_LabtoXYZ() const {
13952 return (+*this).LabtoXYZ();
13953 }
13954
13956 CImg<T>& LabtoXYZ() {
13957 #define cimg_Labfi(x) ((x)>=0.206893?((x)*(x)*(x)):(((x)-16.0/116.0)/7.787))
13958 if (!is_empty()) {
13959 if (dim!=3) throw CImgInstanceException("CImg<%s>::LabtoXYZ() : Input image dimension is dim=%u, "
13960 "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
13961 const double
13962 Xn = 0.412453 + 0.357580 + 0.180423,
13963 Yn = 0.212671 + 0.715160 + 0.072169,
13964 Zn = 0.019334 + 0.119193 + 0.950227;
13965 cimg_forXYZ(*this,x,y,z) {
13966 const T L = (*this)(x,y,z,0), a = (*this)(x,y,z,1), b = (*this)(x,y,z,2);
13967 const double
13968 cY = (L+16)/116.0,
13969 Y = Yn*cimg_Labfi(cY),
13970 pY = std::pow(Y/Yn,1.0/3),
13971 cX = a/500+pY,
13972 X = Xn*cX*cX*cX,
13973 cZ = pY-b/200,
13974 Z = Zn*cZ*cZ*cZ;
13975 (*this)(x,y,z,0) = (T)(X);
13976 (*this)(x,y,z,1) = (T)(Y);
13977 (*this)(x,y,z,2) = (T)(Z);
13978 }
13979 }
13980 return *this;
13981 }
13982
13984 CImg<T> get_XYZtoxyY() const {
13985 return (+*this).XYZtoxyY();
13986 }
13987
13989 CImg<T>& XYZtoxyY() {
13990 if (!is_empty()) {
13991 if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoxyY() : Input image dimension is dim=%u, "
13992 "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
13993 cimg_forXYZ(*this,x,y,z) {
13994 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;
13995 (*this)(x,y,z,0) = X/nsum;
13996 (*this)(x,y,z,1) = Y/nsum;
13997 (*this)(x,y,z,2) = Y;
13998 }
13999 }
14000 return *this;
14001 }
14002
14004 CImg<T> get_xyYtoXYZ() const {
14005 return (+*this).xyYtoXYZ();
14006 }
14007
14009 CImg<T>& xyYtoXYZ() {
14010 if (!is_empty()) {
14011 if (dim!=3) throw CImgInstanceException("CImg<%s>::xyYtoXYZ() : Input image dimension is dim=%u, "
14012 "should be a (x,y,Y) image (dim=3)",pixel_type(),dim);
14013 cimg_forXYZ(*this,x,y,z) {
14014 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;
14015 (*this)(x,y,z,0) = (T)(px*Y/ny);
14016 (*this)(x,y,z,1) = Y;
14017 (*this)(x,y,z,2) = (T)((1-px-py)*Y/ny);
14018 }
14019 }
14020 return *this;
14021 }
14022
14024 CImg<T> get_RGBtoLab() const {
14025 return (+*this).RGBtoLab();
14026 }
14027
14029 CImg<T>& RGBtoLab() {
14030 return RGBtoXYZ().XYZtoLab();
14031 }
14032
14034 CImg<T> get_LabtoRGB() const {
14035 return (+*this).LabtoRGB();
14036 }
14037
14039 CImg<T>& LabtoRGB() {
14040 return LabtoXYZ().XYZtoRGB();
14041 }
14042
14044 CImg<T> get_RGBtoxyY() const {
14045 return (+*this).RGBtoxyY();
14046 }
14047
14049 CImg<T>& RGBtoxyY() {
14050 return RGBtoXYZ().XYZtoxyY();
14051 }
14052
14054 CImg<T> get_xyYtoRGB() const {
14055 return (+*this).xyYtoRGB();
14056 }
14057
14059 CImg<T>& xyYtoRGB() {
14060 return xyYtoXYZ().XYZtoRGB();
14061 }
14062
14064
14067 CImg<T> get_RGBtoBayer() const {
14068 if (is_empty()) return *this;
14069 if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoBayer() : Input image dimension is dim=%u, "
14070 "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
14071 CImg<T> res(width,height,depth,1);
14072 const T
14073 *pR = ptr(0,0,0,0),
14074 *pG = ptr(0,0,0,1),
14075 *pB = ptr(0,0,0,2);
14076 T *ptrd = res.data;
14077 cimg_forXYZ(*this,x,y,z) {
14078 if (y%2) {
14079 if (x%2) *(ptrd++) = *pB;
14080 else *(ptrd++) = *pG;
14081 } else {
14082 if (x%2) *(ptrd++) = *pG;
14083 else *(ptrd++) = *pR;
14084 }
14085 ++pR; ++pG; ++pB;
14086 }
14087 return res;
14088 }
14089
14090
14091 CImg<T>& RGBtoBayer() {
14092 return get_RGBtoBayer().assign_to(*this);
14093 }
14094
14096 CImg<T> get_BayertoRGB(const unsigned int interpolation_type=3) const {
14097 if (is_empty()) return *this;
14098 if (dim!=1) throw CImgInstanceException("CImg<%s>::BayertoRGB() : Input image dimension is dim=%u, "
14099 "should be a Bayer image (dim=1)",pixel_type(),dim);
14100 CImg<T> res(width,height,depth,3);
14101 CImg_3x3(I,T);
14102 T
14103 *pR = res.ptr(0,0,0,0),
14104 *pG = res.ptr(0,0,0,1),
14105 *pB = res.ptr(0,0,0,2);
14106 switch(interpolation_type) {
14107 case 3: {
14108 CImg_3x3(R,T);
14109 CImg_3x3(G,T);
14110 CImg_3x3(B,T);
14111 cimg_forXYZ(*this,x,y,z) {
14112 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;
14113 cimg_get3x3(*this,x,y,z,0,I);
14114 if (y%2) {
14115 if (x%2) {
14116 const float alpha = cimg::sqr(Inc-Ipc), beta = cimg::sqr(Icn-Icp), cx = 1/(1+alpha), cy = 1/(1+beta);
14117 *pG = (T)((cx*(Inc+Ipc) + cy*(Icn+Icp))/(2*(cx+cy)));
14118 } else *pG = Icc;
14119 } else {
14120 if (x%2) *pG = Icc;
14121 else {
14122 const float alpha = cimg::sqr(Inc-Ipc), beta = cimg::sqr(Icn-Icp), cx = 1/(1+alpha), cy = 1/(1+beta);
14123 *pG = (T)((cx*(Inc+Ipc) + cy*(Icn+Icp))/(2*(cx+cy)));
14124 }
14125 }
14126 ++pG;
14127 }
14128 cimg_forXYZ(*this,x,y,z) {
14129 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;
14130 cimg_get3x3(*this,x,y,z,0,I);
14131 cimg_get3x3(res,x,y,z,1,G);
14132 if (y%2) {
14133 if (x%2) *pB = Icc;
14134 else { *pR = (T)((Icn+Icp)/2); *pB = (T)((Inc+Ipc)/2); }
14135 } else {
14136 if (x%2) { *pR = (T)((Inc+Ipc)/2); *pB = (T)((Icn+Icp)/2); }
14137 else *pR = Icc;
14138 }
14139 ++pR; ++pB;
14140 }
14141 pR = res.ptr(0,0,0,0);
14142 pG = res.ptr(0,0,0,1);
14143 pB = res.ptr(0,0,0,2);
14144 cimg_forXYZ(*this,x,y,z) {
14145 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;
14146 cimg_get3x3(res,x,y,z,0,R);
14147 cimg_get3x3(res,x,y,z,1,G);
14148 cimg_get3x3(res,x,y,z,2,B);
14149 if (y%2) {
14150 if (x%2) {
14151 const float alpha = cimg::sqr(Rnc-Rpc), beta = cimg::sqr(Rcn-Rcp), cx = 1/(1+alpha), cy = 1/(1+beta);
14152 *pR = (T)((cx*(Rnc+Rpc) + cy*(Rcn+Rcp))/(2*(cx+cy)));
14153 }
14154 } else {
14155 if (!(x%2)) {
14156 const float alpha = cimg::sqr(Bnc-Bpc), beta = cimg::sqr(Bcn-Bcp), cx = 1/(1+alpha), cy = 1/(1+beta);
14157 *pB = (T)((cx*(Bnc+Bpc) + cy*(Bcn+Bcp))/(2*(cx+cy)));
14158 }
14159 }
14160 ++pR; ++pG; ++pB;
14161 }
14162 } break;
14163 case 2: {
14164 cimg_forXYZ(*this,x,y,z) {
14165 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;
14166 cimg_get3x3(*this,x,y,z,0,I);
14167 if (y%2) {
14168 if (x%2) { *pR = (Ipp+Inn+Ipn+Inp)/4; *pG = (Inc+Ipc+Icn+Icp)/4; *pB = Icc; }
14169 else { *pR = (Icp+Icn)/2; *pG = Icc; *pB = (Inc+Ipc)/2; }
14170 } else {
14171 if (x%2) { *pR = (Ipc+Inc)/2; *pG = Icc; *pB = (Icn+Icp)/2; }
14172 else { *pR = Icc; *pG = (Inc+Ipc+Icn+Icp)/4; *pB = (Ipp+Inn+Ipn+Inp)/4; }
14173 }
14174 ++pR; ++pG; ++pB;
14175 }
14176 } break;
14177 case 1: {
14178 cimg_forXYZ(*this,x,y,z) {
14179 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;
14180 cimg_get3x3(*this,x,y,z,0,I);
14181 if (y%2) {
14182 if (x%2) { *pR = cimg::min(Ipp,Inn,Ipn,Inp); *pG = cimg::min(Inc,Ipc,Icn,Icp); *pB = Icc; }
14183 else { *pR = cimg::min(Icn,Icp); *pG = Icc; *pB = cimg::min(Inc,Ipc); }
14184 } else {
14185 if (x%2) { *pR = cimg::min(Inc,Ipc); *pG = Icc; *pB = cimg::min(Icn,Icp); }
14186 else { *pR = Icc; *pG = cimg::min(Inc,Ipc,Icn,Icp); *pB = cimg::min(Ipp,Inn,Ipn,Inp); }
14187 }
14188 ++pR; ++pG; ++pB;
14189 }
14190 } break;
14191 default: {
14192 const T *ptrs = data;
14193 res.fill(0);
14194 cimg_forXYZ(*this,x,y,z) {
14195 const T val = *(ptrs++);
14196 if (y%2) { if (x%2) *pB = val; else *pG = val; } else { if (x%2) *pG = val; else *pR = val; }
14197 ++pR; ++pG; ++pB;
14198 }
14199 } break;
14200 }
14201 return res;
14202 }
14203
14204
14205 CImg<T>& BayertoRGB(const unsigned int interpolation_type=3) {
14206 return get_BayertoRGB(interpolation_type).assign_to(*this);
14207 }
14208
14210
14211
14213
14214
14215
14216
14217
14218 template<typename tc>
14219 CImg<T>& _draw_scanline(const int x0, const int x1, const int y, const tc *const color,
14220 const float opacity=1.0f, const float brightness=1.0f, const bool init=false) {
14221 static const T maxval = cimg::type<T>::max(), minval = cimg::type<T>::min();
14222 static float nopacity = 0, copacity = 0;
14223 static unsigned int whz = 0;
14224 static const tc *col = 0;
14225 if (init) {
14226 nopacity = cimg::abs(opacity);
14227 copacity = 1.0f - cimg::max(opacity,0.0f);
14228 whz = width*height*depth;
14229 } else {
14230 const int nx0 = x0>0?x0:0, nx1 = x1<dimx()?x1:dimx()-1, dx = nx1 - nx0;
14231 if (dx>=0) {
14232 col = color;
14233 const unsigned int off = whz-dx-1;
14234 T *ptrd = ptr(nx0,y);
14235 if (opacity>=1) {
14236 if (brightness==1.0f) {
14237 if (sizeof(T)!=1) cimg_forV(*this,k) {
14238 const T val = (T)*(col++);
14239 for (int x=dx; x>=0; --x) *(ptrd++) = val;
14240 ptrd+=off;
14241 } else cimg_forV(*this,k) {
14242 const T val = (T)*(col++);
14243 std::memset(ptrd,(int)val,dx+1);
14244 ptrd+=whz;
14245 }
14246 } else {
14247 if (brightness>1.0f) {
14248 if (sizeof(T)!=1) cimg_forV(*this,k) {
14249 const float tval = (float)(*(col++)*brightness);
14250 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
14251 for (int x=dx; x>=0; --x) *(ptrd++) = val;
14252 ptrd+=off;
14253 } else cimg_forV(*this,k) {
14254 const float tval = (float)(*(col++)*brightness);
14255 const T val = tval<(float)maxval?(T)tval:maxval;
14256 std::memset(ptrd,(int)val,dx+1);
14257 ptrd+=whz;
14258 }
14259 } else {
14260 if (sizeof(T)!=1) cimg_forV(*this,k) {
14261 const T val = (T)(*(col++)*brightness);
14262 for (int x=dx; x>=0; --x) *(ptrd++) = val;
14263 ptrd+=off;
14264 } else cimg_forV(*this,k) {
14265 const T val = (T)(*(col++)*brightness);
14266 std::memset(ptrd,(int)val,dx+1);
14267 ptrd+=whz;
14268 }
14269 }
14270 }
14271 } else {
14272 if (brightness==1.0f) {
14273 cimg_forV(*this,k) {
14274 const T val = (T)*(col++);
14275 for (int x=dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; }
14276 ptrd+=off;
14277 }
14278 } else {
14279 if (brightness>1.0f) {
14280 cimg_forV(*this,k) {
14281 const float tval = (float)(*(col++)*brightness);
14282 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
14283 for (int x=dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; }
14284 ptrd+=off;
14285 }
14286 } else {
14287 cimg_forV(*this,k) {
14288 const T val = (T)(*(col++)*brightness);
14289 for (int x=dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; }
14290 ptrd+=off;
14291 }
14292 }
14293 }
14294 }
14295 }
14296 }
14297 return *this;
14298 }
14299
14300 template<typename tc>
14301 CImg<T>& _draw_scanline(const tc *const color, const float opacity=1.0f) {
14302 return _draw_scanline(0,0,0,color,opacity,1.0f,true);
14303 }
14304
14306
14322 template<typename tc>
14323 CImg<T>& draw_point(const int x0, const int y0, const tc *const color, const float opacity=1.0f) {
14324 return draw_point(x0,y0,0,color,opacity);
14325 }
14326
14327 template<typename tc>
14328 CImg<T>& draw_point(const int x0, const int y0, const CImg<tc>& color, const float opacity=1.0f) {
14329 return draw_point(x0,y0,color.data,opacity);
14330 }
14331
14333
14337 template<typename tc>
14338 CImg<T>& draw_point(const int x0, const int y0, const int z0, const tc *const color, const float opacity=1.0f) {
14339 if (!is_empty()) {
14340 if (!color) throw CImgArgumentException("CImg<%s>::draw_point() : Specified color is (null)",pixel_type());
14341 if (x0>=0 && y0>=0 && z0>=0 && x0<dimx() && y0<dimy() && z0<dimz()) {
14342 const tc *col = color;
14343 const unsigned int whz = width*height*depth;
14344 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
14345 T *ptrd = ptr(x0,y0,z0,0);
14346 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=whz; }
14347 else cimg_forV(*this,k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; }
14348 }
14349 }
14350 return *this;
14351 }
14352
14353 template<typename tc>
14354 CImg<T>& draw_point(const int x0, const int y0, const int z0, const CImg<tc>& color, const float opacity=1.0f) {
14355 return draw_point(x0,y0,z0,color.data,opacity);
14356 }
14357
14358
14359 template<typename t, typename tc>
14360 CImg<T>& _draw_point(const t& points, const tc *const color,
14361 const float opacity, const unsigned int W, const unsigned int H) {
14362 if (points && W && H>1) {
14363 if (H==2) for (unsigned int i=0; i<W; ++i) {
14364 const int x = (int)points(i,0), y = (int)points(i,1);
14365 draw_point(x,y,color,opacity);
14366 } else for (unsigned int i=0; i<W; ++i) {
14367 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
14368 draw_point(x,y,z,color,opacity);
14369 }
14370 }
14371 return *this;
14372 }
14373
14375
14395 template<typename t, typename tc>
14396 CImg<T>& draw_point(const CImgList<t>& points, const tc *const color, const float opacity=1.0f) {
14397 unsigned int H = ~0U; cimglist_for(points,p) H = cimg::min(H,(unsigned int)(points[p].size()));
14398 return _draw_point(points,color,opacity,points.size,H);
14399 }
14400
14401 template<typename t, typename tc>
14402 CImg<T>& draw_point(const CImgList<t>& points, const CImg<tc>& color, const float opacity=1.0f) {
14403 return draw_point(points,color.data,opacity);
14404 }
14405
14407
14412 template<typename t, typename tc>
14413 CImg<T>& draw_point(const CImg<t>& points, const tc *const color, const float opacity=1.0f) {
14414 return _draw_point(points,color,opacity,points.width,points.height);
14415 }
14416
14417 template<typename t, typename tc>
14418 CImg<T>& draw_point(const CImg<t>& points, const CImg<tc>& color, const float opacity=1.0f) {
14419 return draw_point(points,color.data,opacity);
14420 }
14421
14423
14443 template<typename tc>
14444 CImg<T>& draw_line(const int x0, const int y0, const int x1, const int y1,
14445 const tc *const color, const float opacity=1.0f,
14446 const unsigned int pattern=~0U, const bool init_hatch=true) {
14447 if (!is_empty()) {
14448 if (!color) throw CImgArgumentException("CImg<%s>::draw_line() : Specified color is (null)",pixel_type());
14449 static unsigned int hatch = ~0U-(~0U>>1);
14450 if (init_hatch) hatch = ~0U-(~0U>>1);
14451 const tc* col = color;
14452 const bool xdir = x0<x1, ydir = y0<y1;
14453 int
14454 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
14455 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1,
14456 &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
14457 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1,
14458 &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0;
14459 if (xright<0 || xleft>=dimx()) return *this;
14460 if (xleft<0) { yleft-=xleft*(yright-yleft)/(xright-xleft); xleft = 0; }
14461 if (xright>=dimx()) { yright-=(xright-dimx())*(yright-yleft)/(xright-xleft); xright = dimx()-1; }
14462 if (ydown<0 || yup>=dimy()) return *this;
14463 if (yup<0) { xup-=yup*(xdown-xup)/(ydown-yup); yup = 0; }
14464 if (ydown>=dimy()) { xdown-=(ydown-dimy())*(xdown-xup)/(ydown-yup); ydown = dimy()-1; }
14465 T *ptrd0 = ptr(nx0,ny0,0,0);
14466 int dx = xright-xleft, dy = ydown-yup;
14467 const bool steep = dy>dx;
14468 if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
14469 const int
14470 offx = (nx0<nx1?1:-1)*(steep?width:1),
14471 offy = (ny0<ny1?1:-1)*(steep?1:width),
14472 wh = width*height;
14473 if (opacity>=1) {
14474 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14475 T *ptrd = ptrd0;
14476 if (pattern&hatch) { cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=wh; } col-=dim; }
14477 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14478 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14479 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14480 T *ptrd = ptrd0;
14481 cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=wh; } col-=dim;
14482 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14483 }
14484 } else {
14485 const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f);
14486 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14487 T *ptrd = ptrd0;
14488 if (pattern&hatch) { cimg_forV(*this,k) { const tc& c = *(col++); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } col-=dim; }
14489 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14490 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14491 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14492 T *ptrd = ptrd0;
14493 cimg_forV(*this,k) { const tc& c = *(col++); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } col-=dim;
14494 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
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 x1, const int y1,
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,x1,y1,color.data,opacity,pattern,init_hatch);
14506 }
14507
14509
14513 template<typename tc>
14514 CImg<T>& draw_line(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1,
14515 const tc *const color, const float opacity=1.0f,
14516 const unsigned int pattern=~0U, const bool init_hatch=true) {
14517 if (!is_empty()) {
14518 if (!color) throw CImgArgumentException("CImg<%s>::draw_line() : Specified color is (null)",pixel_type());
14519 static unsigned int hatch = ~0U-(~0U>>1);
14520 if (init_hatch) hatch = ~0U-(~0U>>1);
14521 const tc *col = color;
14522 int nx0 = x0, ny0 = y0, nz0 = z0, nx1 = x1, ny1 = y1, nz1 = z1;
14523 if (nx0>nx1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
14524 if (nx1<0 || nx0>=dimx()) return *this;
14525 if (nx0<0) { const int D=1+nx1-nx0; ny0-=nx0*(1+ny1-ny0)/D; nz0-=nx0*(1+nz1-nz0)/D; nx0 = 0; }
14526 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; }
14527 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
14528 if (ny1<0 || ny0>=dimy()) return *this;
14529 if (ny0<0) { const int D=1+ny1-ny0; nx0-=ny0*(1+nx1-nx0)/D; nz0-=ny0*(1+nz1-nz0)/D; ny0 = 0; }
14530 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; }
14531 if (nz0>nz1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
14532 if (nz1<0 || nz0>=dimz()) return *this;
14533 if (nz0<0) { const int D=1+nz1-nz0; nx0-=nz0*(1+nx1-nx0)/D; ny0-=nz0*(1+ny1-ny0)/D; nz0 = 0; }
14534 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; }
14535 const unsigned int dmax = cimg::max(cimg::abs(nx1-nx0),cimg::abs(ny1-ny0),nz1-nz0), whz = width*height*depth;
14536 const float px = (nx1-nx0)/(float)dmax, py = (ny1-ny0)/(float)dmax, pz = (nz1-nz0)/(float)dmax;
14537 float x = (float)nx0, y = (float)ny0, z = (float)nz0;
14538 if (opacity>=1) for (unsigned int t=0; t<=dmax; ++t) {
14539 if (!(~pattern) || (~pattern && pattern&hatch)) {
14540 T* ptrd = ptr((unsigned int)x,(unsigned int)y,(unsigned int)z,0);
14541 cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=whz; }
14542 col-=dim;
14543 }
14544 x+=px; y+=py; z+=pz; if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1));
14545 } else {
14546 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
14547 for (unsigned int t=0; t<=dmax; ++t) {
14548 if (!(~pattern) || (~pattern && pattern&hatch)) {
14549 T* ptrd = ptr((unsigned int)x,(unsigned int)y,(unsigned int)z,0);
14550 cimg_forV(*this,k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; }
14551 col-=dim;
14552 }
14553 x+=px; y+=py; z+=pz; if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1));
14554 }
14555 }
14556 }
14557 return *this;
14558 }
14559
14560 template<typename tc>
14561 CImg<T>& draw_line(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1,
14562 const CImg<tc>& color, const float opacity=1.0f,
14563 const unsigned int pattern=~0U, const bool init_hatch=true) {
14564 return draw_line(x0,y0,z0,x1,y1,z1,color.data,opacity,pattern,init_hatch);
14565 }
14566
14568
14591 template<typename t>
14592 CImg<T>& draw_line(const int x0, const int y0, const int x1, const int y1,
14593 const CImg<t>& texture,
14594 const int tx0, const int ty0, const int tx1, const int ty1,
14595 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14596 if (!is_empty()) {
14597 if (!texture || texture.dim<dim)
14598 throw CImgArgumentException("CImg<%s>::draw_line() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
14599 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
14600 if (is_overlapping(texture)) return draw_line(x0,y0,x1,y1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);
14601 static unsigned int hatch = ~0U-(~0U>>1);
14602 if (init_hatch) hatch = ~0U-(~0U>>1);
14603 const bool xdir = x0<x1, ydir = y0<y1;
14604 int
14605 dtx = tx1-tx0, dty = ty1-ty0,
14606 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
14607 tnx0 = tx0, tnx1 = tx1, tny0 = ty0, tny1 = ty1,
14608 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1, &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
14609 &txleft = xdir?tnx0:tnx1, &tyleft = xdir?tny0:tny1, &txright = xdir?tnx1:tnx0, &tyright = xdir?tny1:tny0,
14610 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1, &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0,
14611 &txup = ydir?tnx0:tnx1, &tyup = ydir?tny0:tny1, &txdown = ydir?tnx1:tnx0, &tydown = ydir?tny1:tny0;
14612 if (xright<0 || xleft>=dimx()) return *this;
14613 if (xleft<0) {
14614 const int D = xright-xleft;
14615 yleft-=xleft*(yright-yleft)/D;
14616 txleft-=xleft*(txright-txleft)/D;
14617 tyleft-=xleft*(tyright-tyleft)/D;
14618 xleft = 0;
14619 }
14620 if (xright>=dimx()) {
14621 const int d = xright-dimx(), D = xright-xleft;
14622 yright-=d*(yright-yleft)/D;
14623 txright-=d*(txright-txleft)/D;
14624 tyright-=d*(tyright-tyleft)/D;
14625 xright = dimx()-1;
14626 }
14627 if (ydown<0 || yup>=dimy()) return *this;
14628 if (yup<0) {
14629 const int D = ydown-yup;
14630 xup-=yup*(xdown-xup)/D;
14631 txup-=yup*(txdown-txup)/D;
14632 tyup-=yup*(tydown-tyup)/D;
14633 yup = 0;
14634 }
14635 if (ydown>=dimy()) {
14636 const int d = ydown-dimy(), D = ydown-yup;
14637 xdown-=d*(xdown-xup)/D;
14638 txdown-=d*(txdown-txup)/D;
14639 tydown-=d*(tydown-tyup)/D;
14640 ydown = dimy()-1;
14641 }
14642 T *ptrd0 = ptr(nx0,ny0,0,0);
14643 int dx = xright-xleft, dy = ydown-yup;
14644 const bool steep = dy>dx;
14645 if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
14646 const int
14647 offx = (nx0<nx1?1:-1)*(steep?width:1),
14648 offy = (ny0<ny1?1:-1)*(steep?1:width),
14649 wh = width*height,
14650 ndx = dx>0?dx:1;
14651 if (opacity>=1) {
14652 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14653 T *ptrd = ptrd0;
14654 if (pattern&hatch) {
14655 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
14656 cimg_forV(*this,k) { *ptrd = texture(tx,ty,0,k); ptrd+=wh; }
14657 }
14658 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14659 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14660 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14661 T *ptrd = ptrd0;
14662 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
14663 cimg_forV(*this,k) { *ptrd = texture(tx,ty,0,k); ptrd+=wh; }
14664 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14665 }
14666 } else {
14667 const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f);
14668 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14669 T *ptrd = ptrd0;
14670 if (pattern&hatch) {
14671 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
14672 cimg_forV(*this,k) { const T c = (T)texture(tx,ty,0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; }
14673 }
14674 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14675 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14676 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14677 T *ptrd = ptrd0;
14678 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
14679 cimg_forV(*this,k) { const T c = (T)texture(tx,ty,0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; }
14680 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14681 }
14682 }
14683 }
14684 return *this;
14685 }
14686
14688 template<typename t>
14689 CImg<T>& draw_line(const int x0, const int y0, const float z0, const int x1, const int y1, const float z1,
14690 const CImg<t>& texture,
14691 const int tx0, const int ty0, const int tx1, const int ty1,
14692 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14693 if (!is_empty() && z0>0 && z1>0) {
14694 if (!texture || texture.dim<dim)
14695 throw CImgArgumentException("CImg<%s>::draw_line() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
14696 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
14697 if (is_overlapping(texture)) return draw_line(x0,y0,z0,x1,y1,z1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);
14698 static unsigned int hatch = ~0U-(~0U>>1);
14699 if (init_hatch) hatch = ~0U-(~0U>>1);
14700 const bool xdir = x0<x1, ydir = y0<y1;
14701 int
14702 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
14703 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1,
14704 &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
14705 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1,
14706 &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0;
14707 float
14708 Tx0 = tx0/z0, Tx1 = tx1/z1,
14709 Ty0 = ty0/z0, Ty1 = ty1/z1,
14710 Z0 = 1.0f/z0, Z1 = 1.0f/z1,
14711 dz = Z1-Z0, dtx = Tx1-Tx0, dty = Ty1-Ty0,
14712 tnx0 = Tx0, tnx1 = Tx1, tny0 = Ty0, tny1 = Ty1, nz0 = Z0, nz1 = Z1,
14713 &zleft = xdir?nz0:nz1, &txleft = xdir?tnx0:tnx1, &tyleft = xdir?tny0:tny1,
14714 &zright = xdir?nz1:nz0, &txright = xdir?tnx1:tnx0, &tyright = xdir?tny1:tny0,
14715 &zup = ydir?nz0:nz1, &txup = ydir?tnx0:tnx1, &tyup = ydir?tny0:tny1,
14716 &zdown = ydir?nz1:nz0, &txdown = ydir?tnx1:tnx0, &tydown = ydir?tny1:tny0;
14717
14718 if (xright<0 || xleft>=dimx()) return *this;
14719 if (xleft<0) {
14720 const int D = xright-xleft;
14721 yleft-=xleft*(yright-yleft)/D;
14722 zleft-=xleft*(zright-zleft)/D;
14723 txleft-=xleft*(txright-txleft)/D;
14724 tyleft-=xleft*(tyright-tyleft)/D;
14725 xleft = 0;
14726 }
14727 if (xright>=dimx()) {
14728 const int d = xright-dimx(), D = xright-xleft;
14729 yright-=d*(yright-yleft)/D;
14730 zright-=d*(zright-zleft)/D;
14731 txright-=d*(txright-txleft)/D;
14732 tyright-=d*(tyright-tyleft)/D;
14733 xright = dimx()-1;
14734 }
14735 if (ydown<0 || yup>=dimy()) return *this;
14736 if (yup<0) {
14737 const int D = ydown-yup;
14738 xup-=yup*(xdown-xup)/D;
14739 zup-=yup*(zdown-zup)/D;
14740 txup-=yup*(txdown-txup)/D;
14741 tyup-=yup*(tydown-tyup)/D;
14742 yup = 0;
14743 }
14744 if (ydown>=dimy()) {
14745 const int d = ydown-dimy(), D = ydown-yup;
14746 xdown-=d*(xdown-xup)/D;
14747 zdown-=d*(zdown-zup)/D;
14748 txdown-=d*(txdown-txup)/D;
14749 tydown-=d*(tydown-tyup)/D;
14750 ydown = dimy()-1;
14751 }
14752 T *ptrd0 = ptr(nx0,ny0,0,0);
14753 int dx = xright-xleft, dy = ydown-yup;
14754 const bool steep = dy>dx;
14755 if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
14756 const int
14757 offx = (nx0<nx1?1:-1)*(steep?width:1),
14758 offy = (ny0<ny1?1:-1)*(steep?1:width),
14759 wh = width*height,
14760 ndx = dx>0?dx:1;
14761 if (opacity>=1) {
14762 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14763 T *ptrd = ptrd0;
14764 if (pattern&hatch) {
14765 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
14766 cimg_forV(*this,k) { *ptrd = texture((int)(tx/z),(int)(ty/z),0,k); ptrd+=wh; }
14767 }
14768 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14769 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14770 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14771 T *ptrd = ptrd0;
14772 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
14773 cimg_forV(*this,k) { *ptrd = texture((int)(tx/z),(int)(ty/z),0,k); ptrd+=wh; }
14774 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14775 }
14776 } else {
14777 const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f);
14778 if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) {
14779 T *ptrd = ptrd0;
14780 if (pattern&hatch) {
14781 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
14782 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; }
14783 }
14784 hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1);
14785 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14786 } else for (int error=dx>>1, x=0; x<=dx; ++x) {
14787 T *ptrd = ptrd0;
14788 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
14789 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; }
14790 ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
14791 }
14792 }
14793 }
14794 return *this;
14795 }
14796
14797
14798 template<typename t, typename tc>
14799 CImg<T>& _draw_line(const t& points, const tc *const color,
14800 const float opacity, const unsigned int pattern, const bool init_hatch,
14801 const unsigned int W, const unsigned int H) {
14802 bool ninit_hatch = init_hatch;
14803 if (points && W>1 && H>1) {
14804 if (H==2) {
14805 const int x0 = (int)points(0,0), y0 = (int)points(0,1);
14806 int ox = x0, oy = y0;
14807 for (unsigned int i=1; i<W; ++i) {
14808 const int x = (int)points(i,0), y = (int)points(i,1);
14809 draw_line(ox,oy,x,y,color,opacity,pattern,ninit_hatch);
14810 ninit_hatch = false;
14811 ox = x; oy = y;
14812 }
14813 } else {
14814 const int x0 = (int)points(0,0), y0 = (int)points(0,1), z0 = (int)points(0,2);
14815 int ox = x0, oy = y0, oz = z0;
14816 for (unsigned int i=1; i<W; ++i) {
14817 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
14818 draw_line(ox,oy,oz,x,y,z,color,opacity,pattern,ninit_hatch);
14819 ninit_hatch = false;
14820 ox = x; oy = y; oz = z;
14821 }
14822 }
14823 }
14824 return *this;
14825 }
14826
14828
14850 template<typename t, typename tc>
14851 CImg<T>& draw_line(const CImgList<t>& points, const tc *const color,
14852 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14853 unsigned int H = ~0U; cimglist_for(points,p) H = cimg::min(H,(unsigned int)(points[p].size()));
14854 return _draw_line(points,color,opacity,pattern,init_hatch,points.size,H);
14855 }
14856
14857 template<typename t, typename tc>
14858 CImg<T>& draw_line(const CImgList<t>& points, const CImg<tc>& color,
14859 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14860 return draw_line(points,color.data,opacity,pattern,init_hatch);
14861 }
14862
14864
14869 template<typename t, typename tc>
14870 CImg<T>& draw_line(const CImg<t>& points, const tc *const color,
14871 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14872 return _draw_line(points,color,opacity,pattern,init_hatch,points.width,points.height);
14873 }
14874
14875 template<typename t, typename tc>
14876 CImg<T>& draw_line(const CImg<t>& points, const CImg<tc>& color,
14877 const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) {
14878 return draw_line(points,color.data,opacity,pattern,init_hatch);
14879 }
14880
14881
14882 template<typename t, typename tc>
14883 CImg<T>& _draw_polygon(const t& points, const tc *const color, const float opacity, const unsigned int N) {
14884 if (!is_empty() && N>2) {
14885 if (!color) throw CImgArgumentException("CImg<%s>::draw_polygon() : Specified color is (null).",pixel_type());
14886 _draw_scanline(color,opacity);
14887 int xmin = (int)(~0U>>1), xmax = 0, ymin = (int)(~0U>>1), ymax = 0;
14888 { for (unsigned int p=0; p<N; ++p) {
14889 const int x = (int)points(p,0), y = (int)points(p,1);
14890 if (x<xmin) xmin = x;
14891 if (x>xmax) xmax = x;
14892 if (y<ymin) ymin = y;
14893 if (y>ymax) ymax = y;
14894 }}
14895 if (xmax<0 || xmin>=dimx() || ymax<0 || ymin>=dimx()) return *this;
14896 const unsigned int
14897 nymin = ymin<0?0:(unsigned int)ymin,
14898 nymax = ymax>=dimy()?height-1:(unsigned int)ymax,
14899 dy = 1 + nymax - nymin;
14900 typedef typename cimg::last<T,int>::type cint;
14901 CImg<cint> X(1+N,dy,1,2,0), done(N,2,1,1,0), tmp;
14902 int ox = (int)points(0,0), oy = (int)points(0,1), op = 0;
14903 for (unsigned int p=1; p<=N; ++p) {
14904 const int cp = p!=N?p:0, cx = (int)points(cp,0), cy = (int)points(cp,1),
14905 y0 = oy-nymin, y1 = cy-nymin, dir = (y1>y0?0:1);
14906 for (int x=ox, y=y0, _sx=1, _sy=1,
14907 _dx = cx>ox?cx-ox:((_sx=-1),ox-cx),
14908 _dy = y1>y0?y1-y0:((_sy=-1),y0-y1),
14909 _counter = ((_dx-=_dy?_dy*(_dx/_dy):0),_dy),
14910 _err = _dx>>1,
14911 _rx = _dy?(cx-ox)/_dy:0;
14912 _counter>0;
14913 --_counter, y+=_sy, x+=_rx + ((_err-=_dx)<0?_err+=_dy,_sx:0))
14914 if (y>=0 && y<=(int)dy && y!=y0) X(++X(0,y,dir),y,dir) = x;
14915 if (!done(op,dir)) { X(++X(0,y0,dir),y0,dir) = ox; ++done(op,dir); }
14916 if (!done(cp,dir)) { X(++X(0,y1,dir),y1,dir) = cx; ++done(cp,dir); }
14917 ox = cx; oy = cy; op = cp;
14918 }
14919 for (int y=0; y<(int)dy; ++y) {
14920 tmp.assign(X.ptr(1,y,0),X(0,y,0),1,1,1,true).sort();
14921 tmp.assign(X.ptr(1,y,1),X(0,y,1),1,1,1,true).sort();
14922 for (int i=X(0,y,0); i>=1; --i) {
14923 const int xb = X(i,y,0), xe = X(i,y,1);
14924 if (xe>xb) _draw_scanline(xb,xe,nymin+y,color,opacity);
14925 else _draw_scanline(xe,xb,nymin+y,color,opacity);
14926 }
14927 }
14928 }
14929 return *this;
14930 }
14931
14933 template<typename t, typename tc>
14934 CImg<T>& draw_polygon(const CImgList<t>& points, const tc *const color, const float opacity=1.0f) {
14935 return _draw_polygon(points,color,opacity,points.size);
14936 }
14937
14938 template<typename t, typename tc>
14939 CImg<T>& draw_polygon(const CImgList<t>& points, const CImg<tc>& color, const float opacity=1.0f) {
14940 return draw_polygon(points,color.data,opacity);
14941 }
14942
14944 template<typename t, typename tc>
14945 CImg<T>& draw_polygon(const CImg<t>& points, const tc *const color, const float opacity=1.0f) {
14946 return _draw_polygon(points,color,opacity,points.width);
14947 }
14948
14949 template<typename t, typename tc>
14950 CImg<T>& draw_polygon(const CImg<t>& points, const CImg<tc>& color, const float opacity=1.0f) {
14951 return draw_polygon(points,color.data,opacity);
14952 }
14953
14954
14955 template<typename t, typename tc>
14956 CImg<T>& _draw_polygon(const t& points, const tc *const color,
14957 const float opacity, const unsigned int pattern,
14958 const unsigned int W, const unsigned int H) {
14959 bool ninit_hatch = true;
14960 if (points && W>2 && H>1) {
14961 if (H==2) {
14962 const int x0 = (int)points(0,0), y0 = (int)points(0,1);
14963 int ox = x0, oy = y0;
14964 for (unsigned int i=1; i<W; ++i) {
14965 const int x = (int)points(i,0), y = (int)points(i,1);
14966 draw_line(ox,oy,x,y,color,opacity,pattern,ninit_hatch);
14967 ninit_hatch = false;
14968 ox = x; oy = y;
14969 }
14970 draw_line(ox,oy,x0,y0,color,opacity,pattern,false);
14971 } else {
14972 const int x0 = (int)points(0,0), y0 = (int)points(0,1), z0 = (int)points(0,2);
14973 int ox = x0, oy = y0, oz = z0;
14974 for (unsigned int i=1; i<W; ++i) {
14975 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
14976 draw_line(ox,oy,oz,x,y,z,color,opacity,pattern,ninit_hatch);
14977 ninit_hatch = false;
14978 ox = x; oy = y; oz = z;
14979 }
14980 draw_line(ox,oy,oz,x0,y0,z0,color,opacity,pattern,false);
14981 }
14982 }
14983 return *this;
14984 }
14985
14986
14987 template<typename t, typename tc>
14988 CImg<T>& draw_polygon(const CImgList<t>& points, const tc *const color,
14989 const float opacity, const unsigned int pattern) {
14990 unsigned int H = ~0U; cimglist_for(points,p) H = cimg::min(H,(unsigned int)(points[p].size()));
14991 return _draw_polygon(points,color,opacity,pattern,points.size,H);
14992 }
14993
14994 template<typename t, typename tc>
14995 CImg<T>& draw_polygon(const CImgList<t>& points, const CImg<tc>& color,
14996 const float opacity, const unsigned int pattern) {
14997 return draw_polygon(points,color.data,opacity,pattern);
14998 }
14999
15000
15001 template<typename t, typename tc>
15002 CImg<T>& draw_polygon(const CImg<t>& points, const tc *const color,
15003 const float opacity, const unsigned int pattern) {
15004 return _draw_polygon(points,color,opacity,pattern,points.width,points.height);
15005 }
15006
15007 template<typename t, typename tc>
15008 CImg<T>& draw_polygon(const CImg<t>& points, const CImg<tc>& color,
15009 const float opacity, const unsigned int pattern) {
15010 return draw_polygon(points,color.data,opacity,pattern);
15011 }
15012
15014
15045 template<typename tc>
15046 CImg<T>& draw_spline(const int x0, const int y0, const float u0, const float v0,
15047 const int x1, const int y1, const float u1, const float v1,
15048 const tc *const color,
15049 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
15050 const bool init_hatch=true) {
15051 if (!is_empty()) {
15052 if (!color) throw CImgArgumentException("CImg<%s>::draw_spline() : Specified color is (null)",pixel_type());
15053 bool ninit_hatch = init_hatch;
15054 const float
15055 dx = (float)(x1-x0),
15056 dy = (float)(y1-y0),
15057 dmax = cimg::max(cimg::abs(dx),cimg::abs(dy)),
15058 ax = -2*dx + u0 + u1,
15059 bx = 3*dx - 2*u0 - u1,
15060 ay = -2*dy + v0 + v1,
15061 by = 3*dy - 2*v0 - v1,
15062 xprecision = dmax>0?precision/dmax:1.0f,
15063 tmax = 1.0f + (dmax>0?xprecision:0.0f);
15064 int ox = x0, oy = y0;
15065 for (float t=0.0f; t<tmax; t+=xprecision) {
15066 const float
15067 t2 = t*t,
15068 t3 = t2*t;
15069 const int
15070 nx = (int)(ax*t3 + bx*t2 + u0*t + x0),
15071 ny = (int)(ay*t3 + by*t2 + v0*t + y0);
15072 draw_line(ox,oy,nx,ny,color,opacity,pattern,ninit_hatch);
15073 ninit_hatch = false;
15074 ox = nx; oy = ny;
15075 }
15076 }
15077 return *this;
15078 }
15079
15080 template<typename tc>
15081 CImg<T>& draw_spline(const int x0, const int y0, const float u0, const float v0,
15082 const int x1, const int y1, const float u1, const float v1,
15083 const CImg<tc>& color,
15084 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
15085 const bool init_hatch=true) {
15086 return draw_spline(x0,y0,u0,v0,x1,y1,u1,v1,color.data,precision,opacity,pattern,init_hatch);
15087 }
15088
15090
15094 template<typename tc>
15095 CImg<T>& draw_spline(const int x0, const int y0, const int z0, const float u0, const float v0, const float w0,
15096 const int x1, const int y1, const int z1, const float u1, const float v1, const float w1,
15097 const tc *const color,
15098 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
15099 const bool init_hatch=true) {
15100 if (!is_empty()) {
15101 if (!color) throw CImgArgumentException("CImg<%s>::draw_spline() : Specified color is (null)",pixel_type());
15102 bool ninit_hatch = init_hatch;
15103 const float
15104 dx = (float)(x1-x0),
15105 dy = (float)(y1-y0),
15106 dz = (float)(z1-z0),
15107 dmax = cimg::max(cimg::abs(dx),cimg::abs(dy),cimg::abs(dz)),
15108 ax = -2*dx + u0 + u1,
15109 bx = 3*dx - 2*u0 - u1,
15110 ay = -2*dy + v0 + v1,
15111 by = 3*dy - 2*v0 - v1,
15112 az = -2*dz + w0 + w1,
15113 bz = 3*dz - 2*w0 - w1,
15114 xprecision = dmax>0?precision/dmax:1.0f,
15115 tmax = 1.0f + (dmax>0?xprecision:0.0f);
15116 int ox = x0, oy = y0, oz = z0;
15117 for (float t=0.0f; t<tmax; t+=xprecision) {
15118 const float
15119 t2 = t*t,
15120 t3 = t2*t;
15121 const int
15122 nx = (int)(ax*t3 + bx*t2 + u0*t + x0),
15123 ny = (int)(ay*t3 + by*t2 + v0*t + y0),
15124 nz = (int)(az*t3 + bz*t2 + w0*t + z0);
15125 draw_line(ox,oy,oz,nx,ny,nz,color,opacity,pattern,ninit_hatch);
15126 ninit_hatch = false;
15127 ox = nx; oy = ny; oz = nz;
15128 }
15129 }
15130 return *this;
15131 }
15132
15133 template<typename tc>
15134 CImg<T>& draw_spline(const int x0, const int y0, const int z0, const float u0, const float v0, const float w0,
15135 const int x1, const int y1, const int z1, const float u1, const float v1, const float w1,
15136 const CImg<tc>& color,
15137 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
15138 const bool init_hatch=true) {
15139 return draw_spline(x0,y0,z0,u0,v0,w0,x1,y1,z1,u1,v1,w1,color.data,precision,opacity,pattern,init_hatch);
15140 }
15141
15143
15162 template<typename t>
15163 CImg<T>& draw_spline(const int x0, const int y0, const float u0, const float v0,
15164 const int x1, const int y1, const float u1, const float v1,
15165 const CImg<t>& texture,
15166 const int tx0, const int ty0, const int tx1, const int ty1,
15167 const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U,
15168 const bool init_hatch=true) {
15169 if (!is_empty()) {
15170 if (!texture || texture.dim<dim)
15171 throw CImgArgumentException("CImg<%s>::draw_line() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
15172 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
15173 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);
15174 bool ninit_hatch = true;
15175 const float
15176 dx = (float)(x1-x0),
15177 dy = (float)(y1-y0),
15178 dmax = cimg::max(cimg::abs(dx),cimg::abs(dy)),
15179 ax = -2*dx + u0 + u1,
15180 bx = 3*dx - 2*u0 - u1,
15181 ay = -2*dy + v0 + v1,
15182 by = 3*dy - 2*v0 - v1,
15183 xprecision = dmax>0?precision/dmax:1.0f,
15184 tmax = 1.0f + (dmax>0?xprecision:0.0f);
15185 int ox = x0, oy = y0, otx = tx0, oty = ty0;
15186 for (float t1=0.0f; t1<tmax; t1+=xprecision) {
15187 const float
15188 t2 = t1*t1,
15189 t3 = t2*t1;
15190 const int
15191 nx = (int)(ax*t3 + bx*t2 + u0*t1 + x0),
15192 ny = (int)(ay*t3 + by*t2 + v0*t1 + y0),
15193 ntx = tx0 + (int)((tx1-tx0)*t1/tmax),
15194 nty = ty0 + (int)((ty1-ty0)*t1/tmax);
15195 draw_line(ox,oy,nx,ny,texture,otx,oty,ntx,nty,opacity,pattern,ninit_hatch);
15196 ninit_hatch = false;
15197 ox = nx; oy = ny; otx = ntx; oty = nty;
15198 }
15199 }
15200 return *this;
15201 }
15202
15203
15204 template<typename tp, typename tt, typename tc>
15205 CImg<T>& _draw_spline(const tp& points, const tt& tangents,
15206 const tc *const color, const bool close_set,
15207 const float precision, const float opacity, const unsigned int pattern, const bool init_hatch,
15208 const unsigned int W, const unsigned int H) {
15209 bool ninit_hatch = init_hatch;
15210 if (points && tangents && W>1 && H>1) {
15211 if (H==2) {
15212 const int x0 = (int)points(0,0), y0 = (int)points(0,1);
15213 const float u0 = (float)tangents(0,0), v0 = (float)tangents(0,1);
15214 int ox = x0, oy = y0;
15215 float ou = u0, ov = v0;
15216 for (unsigned int i=1; i<W; ++i) {
15217 const int x = (int)points(i,0), y = (int)points(i,1);
15218 const float u = (float)tangents(i,0), v = (float)tangents(i,1);
15219 draw_spline(ox,oy,ou,ov,x,y,u,v,color,precision,opacity,pattern,ninit_hatch);
15220 ninit_hatch = false;
15221 ox = x; oy = y; ou = u; ov = v;
15222 }
15223 if (close_set) draw_spline(ox,oy,ou,ov,x0,y0,u0,v0,color,precision,opacity,pattern,false);
15224 } else {
15225 const int x0 = (int)points(0,0), y0 = (int)points(0,1), z0 = (int)points(0,2);
15226 const float u0 = (float)tangents(0,0), v0 = (float)tangents(0,1), w0 = (float)tangents(0,2);
15227 int ox = x0, oy = y0, oz = z0;
15228 float ou = u0, ov = v0, ow = w0;
15229 for (unsigned int i=1; i<W; ++i) {
15230 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
15231 const float u = (float)tangents(i,0), v = (float)tangents(i,1), w = (float)tangents(i,2);
15232 draw_spline(ox,oy,oz,ou,ov,ow,x,y,z,u,v,w,color,opacity,pattern,ninit_hatch);
15233 ninit_hatch = false;
15234 ox = x; oy = y; oz = z; ou = u; ov = v; ow = w;
15235 }
15236 if (close_set) draw_spline(ox,oy,oz,ou,ov,ow,x0,y0,z0,u0,v0,w0,color,precision,opacity,pattern,false);
15237 }
15238 }
15239 return *this;
15240 }
15241
15242 template<typename tp, typename tc>
15243 CImg<T>& _draw_spline(const tp& points,
15244 const tc *const color, const bool close_set,
15245 const float precision, const float opacity, const unsigned int pattern, const bool init_hatch,
15246 const unsigned int W, const unsigned int H) {
15247 typedef typename cimg::superset<T,float>::type ftype;
15248 CImg<ftype> tangents;
15249 if (points && W>1 && H>1) {
15250 if (H==2) {
15251 tangents.assign(W,H);
15252 for (unsigned int p=0; p<W; ++p) {
15253 const unsigned int
15254 p0 = close_set?(p+W-1)%W:(p?p-1:0),
15255 p1 = close_set?(p+1)%W:(p+1<W?p+1:p);
15256 const float
15257 x = (float)points(p,0),
15258 y = (float)points(p,1),
15259 x0 = (float)points(p0,0),
15260 y0 = (float)points(p0,1),
15261 x1 = (float)points(p1,0),
15262 y1 = (float)points(p1,1),
15263 u0 = x-x0,
15264 v0 = y-y0,
15265 n0 = 1e-8f + (float)std::sqrt(u0*u0+v0*v0),
15266 u1 = x1-x,
15267 v1 = y1-y,
15268 n1 = 1e-8f + (float)std::sqrt(u1*u1+v1*v1),
15269 u = u0/n0 + u1/n1,
15270 v = v0/n0 + v1/n1,
15271 n = 1e-8f + (float)std::sqrt(u*u+v*v),
15272 fact = 0.5f*(n0 + n1);
15273 tangents(p,0) = (ftype)(fact*u/n);
15274 tangents(p,1) = (ftype)(fact*v/n);
15275 }
15276 } else {
15277 tangents.assign(W,H);
15278 for (unsigned int p=0; p<W; ++p) {
15279 const unsigned int
15280 p0 = close_set?(p+W-1)%W:(p?p-1:0),
15281 p1 = close_set?(p+1)%W:(p+1<W?p+1:p);
15282 const float
15283 x = (float)points(p,0),
15284 y = (float)points(p,1),
15285 z = (float)points(p,2),
15286 x0 = (float)points(p0,0),
15287 y0 = (float)points(p0,1),
15288 z0 = (float)points(p0,2),
15289 x1 = (float)points(p1,0),
15290 y1 = (float)points(p1,1),
15291 z1 = (float)points(p1,2),
15292 u0 = x-x0,
15293 v0 = y-y0,
15294 w0 = z-z0,
15295 n0 = 1e-8f + (float)std::sqrt(u0*u0+v0*v0+w0*w0),
15296 u1 = x1-x,
15297 v1 = y1-y,
15298 w1 = z1-z,
15299 n1 = 1e-8f + (float)std::sqrt(u1*u1+v1*v1+w1*w1),
15300 u = u0/n0 + u1/n1,
15301 v = v0/n0 + v1/n1,
15302 w = w0/n0 + w1/n1,
15303 n = 1e-8f + (float)std::sqrt(u*u+v*v+w*w),
15304 fact = 0.5f*(n0 + n1);
15305 tangents(p,0) = (ftype)(fact*u/n);
15306 tangents(p,1) = (ftype)(fact*v/n);
15307 tangents(p,2) = (ftype)(fact*w/n);
15308 }
15309 }
15310 _draw_spline(points,tangents,color,close_set,precision,opacity,pattern,init_hatch,W,H);
15311 }
15312 return *this;
15313 }
15314
15316 template<typename tp, typename tt, typename tc>
15317 CImg<T>& draw_spline(const CImgList<tp>& points, const CImgList<tt>& tangents,
15318 const tc *const color, const bool close_set=false,
15319 const float precision=4.0f, const float opacity=1.0f,
15320 const unsigned int pattern=~0U, const bool init_hatch=true) {
15321 unsigned int H = ~0U; cimglist_for(points,p) H = cimg::min(H,(unsigned int)(points[p].size()),(unsigned int)(tangents[p].size()));
15322 return _draw_spline(points,tangents,color,close_set,precision,opacity,pattern,init_hatch,points.size,H);
15323 }
15324
15325 template<typename tp, typename tt, typename tc>
15326 CImg<T>& draw_spline(const CImgList<tp>& points, const CImgList<tt>& tangents,
15327 const CImg<tc>& color, const bool close_set=false,
15328 const float precision=4.0f, const float opacity=1.0f,
15329 const unsigned int pattern=~0U, const bool init_hatch=true) {
15330 return draw_spline(points,tangents,color.data,close_set,precision,opacity,pattern,init_hatch);
15331 }
15332
15334 template<typename tp, typename tt, typename tc>
15335 CImg<T>& draw_spline(const CImg<tp>& points, const CImg<tt>& tangents,
15336 const tc *const color, const bool close_set=false,
15337 const float precision=4.0f, const float opacity=1.0f,
15338 const unsigned int pattern=~0U, const bool init_hatch=true) {
15339 return _draw_spline(points,tangents,color,close_set,precision,opacity,pattern,init_hatch,points.width,points.height);
15340 }
15341
15342 template<typename tp, typename tt, typename tc>
15343 CImg<T>& draw_spline(const CImg<tp>& points, const CImg<tt>& tangents,
15344 const CImg<tc>& color, const bool close_set=false,
15345 const float precision=4.0f, const float opacity=1.0f,
15346 const unsigned int pattern=~0U, const bool init_hatch=true) {
15347 return draw_spline(points,tangents,color.data,close_set,precision,opacity,pattern,init_hatch);
15348 }
15349
15351 template<typename t, typename tc>
15352 CImg<T>& draw_spline(const CImgList<t>& points, const tc *const color,
15353 const bool close_set=false, const float precision=4.0f, const float opacity=1.0f,
15354 const unsigned int pattern=~0U, const bool init_hatch=true) {
15355 unsigned int H = ~0U;
15356 cimglist_for(points,p) {
15357 const unsigned int s = points[p].size();
15358 if (s<H) H = s;
15359 }
15360 return _draw_spline(points,color,close_set,precision,opacity,pattern,init_hatch,points.size,H);
15361 }
15362
15363 template<typename t, typename tc>
15364 CImg<T>& draw_spline(const CImgList<t>& points, CImg<tc>& color,
15365 const bool close_set=false, const float precision=4.0f, const float opacity=1.0f,
15366 const unsigned int pattern=~0U, const bool init_hatch=true) {
15367 return draw_spline(points,color.data,close_set,precision,opacity,pattern,init_hatch);
15368 }
15369
15371 template<typename t, typename tc>
15372 CImg<T>& draw_spline(const CImg<t>& points, const tc *const color,
15373 const bool close_set=false, const float precision=4.0f, const float opacity=1.0f,
15374 const unsigned int pattern=~0U, const bool init_hatch=true) {
15375 return _draw_spline(points,color,close_set,precision,opacity,pattern,init_hatch,points.width,points.height);
15376 }
15377
15378 template<typename t, typename tc>
15379 CImg<T>& draw_spline(const CImg<t>& points, const CImg<tc>& color,
15380 const bool close_set=false, const float precision=4.0f, const float opacity=1.0f,
15381 const unsigned int pattern=~0U, const bool init_hatch=true) {
15382 return draw_spline(points,color.data,close_set,precision,opacity,pattern,init_hatch);
15383 }
15384
15386
15399 template<typename tc>
15400 CImg<T>& draw_arrow(const int x0, const int y0, const int x1, const int y1,
15401 const tc *const color,
15402 const float angle=30, const float length=-10,
15403 const float opacity=1.0f, const unsigned int pattern=~0U) {
15404 if (!is_empty()) {
15405 const float u = (float)(x0-x1), v = (float)(y0-y1), sq = u*u+v*v,
15406 deg = (float)(angle*cimg::PI/180), ang = (sq>0)?(float)std::atan2(v,u):0.0f,
15407 l = (length>=0)?length:-length*(float)std::sqrt(sq)/100;
15408 if (sq>0) {
15409 const double cl = std::cos(ang-deg), sl = std::sin(ang-deg), cr = std::cos(ang+deg), sr = std::sin(ang+deg);
15410 const int
15411 xl = x1+(int)(l*cl), yl = y1+(int)(l*sl),
15412 xr = x1+(int)(l*cr), yr = y1+(int)(l*sr),
15413 xc = x1+(int)((l+1)*(cl+cr))/2, yc = y1+(int)((l+1)*(sl+sr))/2;
15414 draw_line(x0,y0,xc,yc,color,opacity,pattern).draw_triangle(x1,y1,xl,yl,xr,yr,color,opacity);
15415 } else draw_point(x0,y0,color,opacity);
15416 }
15417 return *this;
15418 }
15419
15420 template<typename tc>
15421 CImg<T>& draw_arrow(const int x0, const int y0, const int x1, const int y1,
15422 const CImg<tc>& color,
15423 const float angle=30, const float length=-10,
15424 const float opacity=1.0f, const unsigned int pattern=~0U) {
15425 return draw_arrow(x0,y0,x1,y1,color.data,angle,length,opacity,pattern);
15426 }
15427
15429
15439 template<typename t>
15440 CImg<T>& draw_image(const CImg<t>& sprite,
15441 const int x0, const int y0=0, const int z0=0, const int v0=0,
15442 const float opacity=1.0f) {
15443 if (!is_empty()) {
15444 if (!sprite)
15445 throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
15446 pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
15447 if (is_overlapping(sprite)) return draw_image(+sprite,x0,y0,z0,v0,opacity);
15448 const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0);
15449 const int
15450 lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0),
15451 lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0),
15452 lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0),
15453 lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0);
15454 const t
15455 *ptrs = sprite.data -
15456 (bx?x0:0) -
15457 (by?y0*sprite.dimx():0) -
15458 (bz?z0*sprite.dimx()*sprite.dimy():0) -
15459 (bv?v0*sprite.dimx()*sprite.dimy()*sprite.dimz():0);
15460 const unsigned int
15461 offX = width-lX, soffX = sprite.width-lX,
15462 offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY),
15463 offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ);
15464 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
15465 T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
15466 if (lX>0 && lY>0 && lZ>0 && lV>0)
15467 for (int v=0; v<lV; ++v) {
15468 for (int z=0; z<lZ; ++z) {
15469 for (int y=0; y<lY; ++y) {
15470 if (opacity>=1) for (int x=0; x<lX; ++x) *(ptrd++) = (T)*(ptrs++);
15471 else for (int x=0; x<lX; ++x) { *ptrd = (T)(nopacity*(*(ptrs++)) + *ptrd*copacity); ++ptrd; }
15472 ptrd+=offX; ptrs+=soffX;
15473 }
15474 ptrd+=offY; ptrs+=soffY;
15475 }
15476 ptrd+=offZ; ptrs+=soffZ;
15477 }
15478 }
15479 return *this;
15480 }
15481
15482 #ifndef cimg_use_visualcpp6
15483 CImg<T>& draw_image(const CImg<T>& sprite,
15484 const int x0, const int y0=0, const int z0=0, const int v0=0,
15485 const float opacity=1.0f) {
15486 if (!is_empty()) {
15487 if (!sprite)
15488 throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
15489 pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
15490 if (is_overlapping(sprite)) return draw_image(+sprite,x0,y0,z0,v0,opacity);
15491 const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0);
15492 const int
15493 lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0),
15494 lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0),
15495 lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0),
15496 lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0);
15497 const T
15498 *ptrs = sprite.data -
15499 (bx?x0:0) -
15500 (by?y0*sprite.dimx():0) -
15501 (bz?z0*sprite.dimx()*sprite.dimy():0) -
15502 (bv?v0*sprite.dimx()*sprite.dimy()*sprite.dimz():0);
15503 const unsigned int
15504 offX = width-lX, soffX = sprite.width-lX,
15505 offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY),
15506 offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ),
15507 slX = lX*sizeof(T);
15508 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
15509 T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
15510 if (lX>0 && lY>0 && lZ>0 && lV>0)
15511 for (int v=0; v<lV; ++v) {
15512 for (int z=0; z<lZ; ++z) {
15513 if (opacity>=1) for (int y=0; y<lY; ++y) { std::memcpy(ptrd,ptrs,slX); ptrd+=width; ptrs+=sprite.width; }
15514 else for (int y=0; y<lY; ++y) {
15515 for (int x=0; x<lX; ++x) { *ptrd = (T)(nopacity*(*(ptrs++)) + *ptrd*copacity); ++ptrd; }
15516 ptrd+=offX; ptrs+=soffX;
15517 }
15518 ptrd+=offY; ptrs+=soffY;
15519 }
15520 ptrd+=offZ; ptrs+=soffZ;
15521 }
15522 }
15523 return *this;
15524 }
15525 #endif
15526
15528
15542 template<typename ti, typename tm>
15543 CImg<T>& draw_image(const CImg<ti>& sprite, const CImg<tm>& mask,
15544 const int x0, const int y0=0, const int z0=0, const int v0=0,
15545 const float mask_valmax=1.0f, const float opacity=1.0f) {
15546 if (!is_empty()) {
15547 if (!sprite)
15548 throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
15549 pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
15550 if (!mask)
15551 throw CImgArgumentException("CImg<%s>::draw_image() : Specified mask image (%u,%u,%u,%u,%p) is empty.",
15552 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
15553 if (is_overlapping(sprite)) return draw_image(+sprite,mask,x0,y0,z0,v0,mask_valmax,opacity);
15554 if (is_overlapping(mask)) return draw_image(sprite,+mask,x0,y0,z0,v0,mask_valmax,opacity);
15555 if (mask.width!=sprite.width || mask.height!=sprite.height || mask.depth!=sprite.depth)
15556 throw CImgArgumentException("CImg<%s>::draw_image() : Mask dimension is (%u,%u,%u,%u), while sprite is (%u,%u,%u,%u)",
15557 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,sprite.width,sprite.height,sprite.depth,sprite.dim);
15558 const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0);
15559 const int
15560 lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0),
15561 lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0),
15562 lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0),
15563 lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0);
15564 const int
15565 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),
15566 ssize = mask.dimx()*mask.dimy()*mask.dimz();
15567 const ti *ptrs = sprite.data + coff;
15568 const tm *ptrm = mask.data + coff;
15569 const unsigned int
15570 offX = width-lX, soffX = sprite.width-lX,
15571 offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY),
15572 offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ);
15573 T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
15574 if (lX>0 && lY>0 && lZ>0 && lV>0)
15575 for (int v=0; v<lV; ++v) {
15576 ptrm = mask.data + (ptrm - mask.data)%ssize;
15577 for (int z=0; z<lZ; ++z) {
15578 for (int y=0; y<lY; ++y) {
15579 for (int x=0; x<lX; ++x) {
15580 const float mopacity = *(ptrm++)*opacity,
15581 nopacity = cimg::abs(mopacity), copacity = mask_valmax-cimg::max(mopacity,0.0f);
15582 *ptrd = (T)((nopacity*(*(ptrs++)) + *ptrd*copacity)/mask_valmax);
15583 ++ptrd;
15584 }
15585 ptrd+=offX; ptrs+=soffX; ptrm+=soffX;
15586 }
15587 ptrd+=offY; ptrs+=soffY; ptrm+=soffY;
15588 }
15589 ptrd+=offZ; ptrs+=soffZ; ptrm+=soffZ;
15590 }
15591 }
15592 return *this;
15593 }
15594
15596
15610 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0, const int v0,
15611 const int x1, const int y1, const int z1, const int v1,
15612 const T val, const float opacity=1.0f) {
15613 if (!is_empty()) {
15614 const bool bx=(x0<x1), by=(y0<y1), bz=(z0<z1), bv=(v0<v1);
15615 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;
15616 const int
15617 lX = (1+nx1-nx0) + (nx1>=dimx()?dimx()-1-nx1:0) + (nx0<0?nx0:0),
15618 lY = (1+ny1-ny0) + (ny1>=dimy()?dimy()-1-ny1:0) + (ny0<0?ny0:0),
15619 lZ = (1+nz1-nz0) + (nz1>=dimz()?dimz()-1-nz1:0) + (nz0<0?nz0:0),
15620 lV = (1+nv1-nv0) + (nv1>=dimv()?dimv()-1-nv1:0) + (nv0<0?nv0:0);
15621 const unsigned int offX = width-lX, offY = width*(height-lY), offZ = width*height*(depth-lZ);
15622 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
15623 T *ptrd = ptr(nx0<0?0:nx0,ny0<0?0:ny0,nz0<0?0:nz0,nv0<0?0:nv0);
15624 if (lX>0 && lY>0 && lZ>0 && lV>0)
15625 for (int v=0; v<lV; ++v) {
15626 for (int z=0; z<lZ; ++z) {
15627 for (int y=0; y<lY; ++y) {
15628 if (opacity>=1) {
15629 if (sizeof(T)!=1) { for (int x=0; x<lX; ++x) *(ptrd++) = val; ptrd+=offX; }
15630 else { std::memset(ptrd,(int)val,lX); ptrd+=width; }
15631 } else { for (int x=0; x<lX; ++x) { *ptrd = (T)(nopacity*val + *ptrd*copacity); ++ptrd; } ptrd+=offX; }
15632 }
15633 ptrd+=offY;
15634 }
15635 ptrd+=offZ;
15636 }
15637 }
15638 return *this;
15639 }
15640
15642
15654 template<typename tc>
15655 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0,
15656 const int x1, const int y1, const int z1,
15657 const tc *const color, const float opacity=1.0f) {
15658 if (!color) throw CImgArgumentException("CImg<%s>::draw_rectangle : specified color is (null)",pixel_type());
15659 cimg_forV(*this,k) draw_rectangle(x0,y0,z0,k,x1,y1,z1,k,color[k],opacity);
15660 return *this;
15661 }
15662
15663 template<typename tc>
15664 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0,
15665 const int x1, const int y1, const int z1,
15666 const CImg<tc>& color, const float opacity=1.0f) {
15667 return draw_rectangle(x0,y0,z0,x1,y1,z1,color.data,opacity);
15668 }
15669
15671 template<typename tc>
15672 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0,
15673 const int x1, const int y1, const int z1,
15674 const tc *const color, const float opacity, const unsigned int pattern) {
15675 return draw_line(x0,y0,z0,x1,y0,z0,color,opacity,pattern,true).
15676 draw_line(x1,y0,z0,x1,y1,z0,color,opacity,pattern,false).
15677 draw_line(x1,y1,z0,x0,y1,z0,color,opacity,pattern,false).
15678 draw_line(x0,y1,z0,x0,y0,z0,color,opacity,pattern,false).
15679 draw_line(x0,y0,z1,x1,y0,z1,color,opacity,pattern,true).
15680 draw_line(x1,y0,z1,x1,y1,z1,color,opacity,pattern,false).
15681 draw_line(x1,y1,z1,x0,y1,z1,color,opacity,pattern,false).
15682 draw_line(x0,y1,z1,x0,y0,z1,color,opacity,pattern,false).
15683 draw_line(x0,y0,z0,x0,y0,z1,color,opacity,pattern,true).
15684 draw_line(x1,y0,z0,x1,y0,z1,color,opacity,pattern,true).
15685 draw_line(x1,y1,z0,x1,y1,z1,color,opacity,pattern,true).
15686 draw_line(x0,y1,z0,x0,y1,z1,color,opacity,pattern,true);
15687 }
15688
15689 template<typename tc>
15690 CImg<T>& draw_rectangle(const int x0, const int y0, const int z0,
15691 const int x1, const int y1, const int z1,
15692 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
15693 return draw_rectangle(x0,y0,z0,x1,y1,z1,color.data,opacity,pattern);
15694 }
15695
15697
15707 template<typename tc>
15708 CImg<T>& draw_rectangle(const int x0, const int y0, const int x1, const int y1,
15709 const tc *const color, const float opacity=1.0f) {
15710 return draw_rectangle(x0,y0,0,x1,y1,depth-1,color,opacity);
15711 }
15712
15713 template<typename tc>
15714 CImg<T>& draw_rectangle(const int x0, const int y0, const int x1, const int y1,
15715 const CImg<tc>& color, const float opacity=1.0f) {
15716 return draw_rectangle(x0,y0,x1,y1,color.data,opacity);
15717 }
15718
15720 template<typename tc>
15721 CImg<T>& draw_rectangle(const int x0, const int y0, const int x1, const int y1,
15722 const tc *const color, const float opacity, const unsigned int pattern) {
15723 return draw_line(x0,y0,x1,y0,color,opacity,pattern,true).
15724 draw_line(x1,y0,x1,y1,color,opacity,pattern,false).
15725 draw_line(x1,y1,x0,y1,color,opacity,pattern,false).
15726 draw_line(x0,y1,x0,y0,color,opacity,pattern,false);
15727 }
15728
15729 template<typename tc>
15730 CImg<T>& draw_rectangle(const int x0, const int y0, const int x1, const int y1,
15731 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
15732 return draw_rectangle(x0,y0,x1,y1,color.data,opacity,pattern);
15733 }
15734
15735
15736 #define _cimg_for_triangle1(img,xl,xr,y,x0,y0,x1,y1,x2,y2) \
15737 for (int y = y0<0?0:y0, \
15738 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15739 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15740 _sxn=1, \
15741 _sxr=1, \
15742 _sxl=1, \
15743 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
15744 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
15745 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
15746 _dyn = y2-y1, \
15747 _dyr = y2-y0, \
15748 _dyl = y1-y0, \
15749 _counter = (_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15750 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15751 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15752 cimg::min((int)(img).height-y-1,y2-y)), \
15753 _errn = _dyn/2, \
15754 _errr = _dyr/2, \
15755 _errl = _dyl/2, \
15756 _rxn = _dyn?(x2-x1)/_dyn:0, \
15757 _rxr = _dyr?(x2-x0)/_dyr:0, \
15758 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
15759 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn); \
15760 _counter>=0; --_counter, ++y, \
15761 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
15762 xl+=(y!=y1)?_rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0): \
15763 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
15764
15765 #define _cimg_for_triangle2(img,xl,cl,xr,cr,y,x0,y0,c0,x1,y1,c1,x2,y2,c2) \
15766 for (int y = y0<0?0:y0, \
15767 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15768 cr = y0>=0?c0:(c0-y0*(c2-c0)/(y2-y0)), \
15769 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15770 cl = y1>=0?(y0>=0?(y0==y1?c1:c0):(c0-y0*(c1-c0)/(y1-y0))):(c1-y1*(c2-c1)/(y2-y1)), \
15771 _sxn=1, _scn=1, \
15772 _sxr=1, _scr=1, \
15773 _sxl=1, _scl=1, \
15774 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
15775 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
15776 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
15777 _dcn = c2>c1?c2-c1:(_scn=-1,c1-c2), \
15778 _dcr = c2>c0?c2-c0:(_scr=-1,c0-c2), \
15779 _dcl = c1>c0?c1-c0:(_scl=-1,c0-c1), \
15780 _dyn = y2-y1, \
15781 _dyr = y2-y0, \
15782 _dyl = y1-y0, \
15783 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15784 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15785 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15786 _dcn-=_dyn?_dyn*(_dcn/_dyn):0, \
15787 _dcr-=_dyr?_dyr*(_dcr/_dyr):0, \
15788 _dcl-=_dyl?_dyl*(_dcl/_dyl):0, \
15789 cimg::min((int)(img).height-y-1,y2-y)), \
15790 _errn = _dyn/2, _errcn = _errn, \
15791 _errr = _dyr/2, _errcr = _errr, \
15792 _errl = _dyl/2, _errcl = _errl, \
15793 _rxn = _dyn?(x2-x1)/_dyn:0, \
15794 _rcn = _dyn?(c2-c1)/_dyn:0, \
15795 _rxr = _dyr?(x2-x0)/_dyr:0, \
15796 _rcr = _dyr?(c2-c0)/_dyr:0, \
15797 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
15798 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
15799 _rcl = (y0!=y1 && y1>0)?(_dyl?(c1-c0)/_dyl:0): \
15800 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ); \
15801 _counter>=0; --_counter, ++y, \
15802 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
15803 cr+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), \
15804 xl+=(y!=y1)?(cl+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), \
15805 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
15806 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cl=c1, \
15807 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
15808
15809 #define _cimg_for_triangle3(img,xl,txl,tyl,xr,txr,tyr,y,x0,y0,tx0,ty0,x1,y1,tx1,ty1,x2,y2,tx2,ty2) \
15810 for (int y = y0<0?0:y0, \
15811 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15812 txr = y0>=0?tx0:(tx0-y0*(tx2-tx0)/(y2-y0)), \
15813 tyr = y0>=0?ty0:(ty0-y0*(ty2-ty0)/(y2-y0)), \
15814 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15815 txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0-y0*(tx1-tx0)/(y1-y0))):(tx1-y1*(tx2-tx1)/(y2-y1)), \
15816 tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0-y0*(ty1-ty0)/(y1-y0))):(ty1-y1*(ty2-ty1)/(y2-y1)), \
15817 _sxn=1, _stxn=1, _styn=1, \
15818 _sxr=1, _stxr=1, _styr=1, \
15819 _sxl=1, _stxl=1, _styl=1, \
15820 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
15821 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
15822 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
15823 _dtxn = tx2>tx1?tx2-tx1:(_stxn=-1,tx1-tx2), \
15824 _dtxr = tx2>tx0?tx2-tx0:(_stxr=-1,tx0-tx2), \
15825 _dtxl = tx1>tx0?tx1-tx0:(_stxl=-1,tx0-tx1), \
15826 _dtyn = ty2>ty1?ty2-ty1:(_styn=-1,ty1-ty2), \
15827 _dtyr = ty2>ty0?ty2-ty0:(_styr=-1,ty0-ty2), \
15828 _dtyl = ty1>ty0?ty1-ty0:(_styl=-1,ty0-ty1), \
15829 _dyn = y2-y1, \
15830 _dyr = y2-y0, \
15831 _dyl = y1-y0, \
15832 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15833 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15834 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15835 _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \
15836 _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \
15837 _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \
15838 _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \
15839 _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \
15840 _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \
15841 cimg::min((int)(img).height-y-1,y2-y)), \
15842 _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, \
15843 _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, \
15844 _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, \
15845 _rxn = _dyn?(x2-x1)/_dyn:0, \
15846 _rtxn = _dyn?(tx2-tx1)/_dyn:0, \
15847 _rtyn = _dyn?(ty2-ty1)/_dyn:0, \
15848 _rxr = _dyr?(x2-x0)/_dyr:0, \
15849 _rtxr = _dyr?(tx2-tx0)/_dyr:0, \
15850 _rtyr = _dyr?(ty2-ty0)/_dyr:0, \
15851 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
15852 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
15853 _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1-tx0)/_dyl:0): \
15854 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \
15855 _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1-ty0)/_dyl:0): \
15856 (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); \
15857 _counter>=0; --_counter, ++y, \
15858 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
15859 txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \
15860 tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \
15861 xl+=(y!=y1)?(txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \
15862 tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \
15863 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
15864 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \
15865 _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1,\
15866 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
15867
15868 #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) \
15869 for (int y = y0<0?0:y0, \
15870 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15871 cr = y0>=0?c0:(c0-y0*(c2-c0)/(y2-y0)), \
15872 txr = y0>=0?tx0:(tx0-y0*(tx2-tx0)/(y2-y0)), \
15873 tyr = y0>=0?ty0:(ty0-y0*(ty2-ty0)/(y2-y0)), \
15874 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15875 cl = y1>=0?(y0>=0?(y0==y1?c1:c0):(c0-y0*(c1-c0)/(y1-y0))):(c1-y1*(c2-c1)/(y2-y1)), \
15876 txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0-y0*(tx1-tx0)/(y1-y0))):(tx1-y1*(tx2-tx1)/(y2-y1)), \
15877 tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0-y0*(ty1-ty0)/(y1-y0))):(ty1-y1*(ty2-ty1)/(y2-y1)), \
15878 _sxn=1, _scn=1, _stxn=1, _styn=1, \
15879 _sxr=1, _scr=1, _stxr=1, _styr=1, \
15880 _sxl=1, _scl=1, _stxl=1, _styl=1, \
15881 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
15882 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
15883 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
15884 _dcn = c2>c1?c2-c1:(_scn=-1,c1-c2), \
15885 _dcr = c2>c0?c2-c0:(_scr=-1,c0-c2), \
15886 _dcl = c1>c0?c1-c0:(_scl=-1,c0-c1), \
15887 _dtxn = tx2>tx1?tx2-tx1:(_stxn=-1,tx1-tx2), \
15888 _dtxr = tx2>tx0?tx2-tx0:(_stxr=-1,tx0-tx2), \
15889 _dtxl = tx1>tx0?tx1-tx0:(_stxl=-1,tx0-tx1), \
15890 _dtyn = ty2>ty1?ty2-ty1:(_styn=-1,ty1-ty2), \
15891 _dtyr = ty2>ty0?ty2-ty0:(_styr=-1,ty0-ty2), \
15892 _dtyl = ty1>ty0?ty1-ty0:(_styl=-1,ty0-ty1), \
15893 _dyn = y2-y1, \
15894 _dyr = y2-y0, \
15895 _dyl = y1-y0, \
15896 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15897 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15898 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15899 _dcn-=_dyn?_dyn*(_dcn/_dyn):0, \
15900 _dcr-=_dyr?_dyr*(_dcr/_dyr):0, \
15901 _dcl-=_dyl?_dyl*(_dcl/_dyl):0, \
15902 _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \
15903 _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \
15904 _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \
15905 _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \
15906 _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \
15907 _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \
15908 cimg::min((int)(img).height-y-1,y2-y)), \
15909 _errn = _dyn/2, _errcn = _errn, _errtxn = _errn, _errtyn = _errn, \
15910 _errr = _dyr/2, _errcr = _errr, _errtxr = _errr, _errtyr = _errr, \
15911 _errl = _dyl/2, _errcl = _errl, _errtxl = _errl, _errtyl = _errl, \
15912 _rxn = _dyn?(x2-x1)/_dyn:0, \
15913 _rcn = _dyn?(c2-c1)/_dyn:0, \
15914 _rtxn = _dyn?(tx2-tx1)/_dyn:0, \
15915 _rtyn = _dyn?(ty2-ty1)/_dyn:0, \
15916 _rxr = _dyr?(x2-x0)/_dyr:0, \
15917 _rcr = _dyr?(c2-c0)/_dyr:0, \
15918 _rtxr = _dyr?(tx2-tx0)/_dyr:0, \
15919 _rtyr = _dyr?(ty2-ty0)/_dyr:0, \
15920 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
15921 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
15922 _rcl = (y0!=y1 && y1>0)?(_dyl?(c1-c0)/_dyl:0): \
15923 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ), \
15924 _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1-tx0)/_dyl:0): \
15925 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \
15926 _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1-ty0)/_dyl:0): \
15927 (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); \
15928 _counter>=0; --_counter, ++y, \
15929 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
15930 cr+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), \
15931 txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \
15932 tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \
15933 xl+=(y!=y1)?(cl+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), \
15934 txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \
15935 tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \
15936 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
15937 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cl=c1, \
15938 _errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \
15939 _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1, \
15940 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
15941
15942 #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) \
15943 for (int y = y0<0?0:y0, \
15944 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
15945 txr = y0>=0?tx0:(tx0-y0*(tx2-tx0)/(y2-y0)), \
15946 tyr = y0>=0?ty0:(ty0-y0*(ty2-ty0)/(y2-y0)), \
15947 lxr = y0>=0?lx0:(lx0-y0*(lx2-lx0)/(y2-y0)), \
15948 lyr = y0>=0?ly0:(ly0-y0*(ly2-ly0)/(y2-y0)), \
15949 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
15950 txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0-y0*(tx1-tx0)/(y1-y0))):(tx1-y1*(tx2-tx1)/(y2-y1)), \
15951 tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0-y0*(ty1-ty0)/(y1-y0))):(ty1-y1*(ty2-ty1)/(y2-y1)), \
15952 lxl = y1>=0?(y0>=0?(y0==y1?lx1:lx0):(lx0-y0*(lx1-lx0)/(y1-y0))):(lx1-y1*(lx2-lx1)/(y2-y1)), \
15953 lyl = y1>=0?(y0>=0?(y0==y1?ly1:ly0):(ly0-y0*(ly1-ly0)/(y1-y0))):(ly1-y1*(ly2-ly1)/(y2-y1)), \
15954 _sxn=1, _stxn=1, _styn=1, _slxn=1, _slyn=1, \
15955 _sxr=1, _stxr=1, _styr=1, _slxr=1, _slyr=1, \
15956 _sxl=1, _stxl=1, _styl=1, _slxl=1, _slyl=1, \
15957 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), _dyn = y2-y1, \
15958 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), _dyr = y2-y0, \
15959 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), _dyl = y1-y0, \
15960 _dtxn = tx2>tx1?tx2-tx1:(_stxn=-1,tx1-tx2), \
15961 _dtxr = tx2>tx0?tx2-tx0:(_stxr=-1,tx0-tx2), \
15962 _dtxl = tx1>tx0?tx1-tx0:(_stxl=-1,tx0-tx1), \
15963 _dtyn = ty2>ty1?ty2-ty1:(_styn=-1,ty1-ty2), \
15964 _dtyr = ty2>ty0?ty2-ty0:(_styr=-1,ty0-ty2), \
15965 _dtyl = ty1>ty0?ty1-ty0:(_styl=-1,ty0-ty1), \
15966 _dlxn = lx2>lx1?lx2-lx1:(_slxn=-1,lx1-lx2), \
15967 _dlxr = lx2>lx0?lx2-lx0:(_slxr=-1,lx0-lx2), \
15968 _dlxl = lx1>lx0?lx1-lx0:(_slxl=-1,lx0-lx1), \
15969 _dlyn = ly2>ly1?ly2-ly1:(_slyn=-1,ly1-ly2), \
15970 _dlyr = ly2>ly0?ly2-ly0:(_slyr=-1,ly0-ly2), \
15971 _dlyl = ly1>ly0?ly1-ly0:(_slyl=-1,ly0-ly1), \
15972 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
15973 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
15974 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
15975 _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \
15976 _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \
15977 _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \
15978 _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \
15979 _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \
15980 _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \
15981 _dlxn-=_dyn?_dyn*(_dlxn/_dyn):0, \
15982 _dlxr-=_dyr?_dyr*(_dlxr/_dyr):0, \
15983 _dlxl-=_dyl?_dyl*(_dlxl/_dyl):0, \
15984 _dlyn-=_dyn?_dyn*(_dlyn/_dyn):0, \
15985 _dlyr-=_dyr?_dyr*(_dlyr/_dyr):0, \
15986 _dlyl-=_dyl?_dyl*(_dlyl/_dyl):0, \
15987 cimg::min((int)(img).height-y-1,y2-y)), \
15988 _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, _errlxn = _errn, _errlyn = _errn, \
15989 _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, _errlxr = _errr, _errlyr = _errr, \
15990 _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, _errlxl = _errl, _errlyl = _errl, \
15991 _rxn = _dyn?(x2-x1)/_dyn:0, \
15992 _rtxn = _dyn?(tx2-tx1)/_dyn:0, \
15993 _rtyn = _dyn?(ty2-ty1)/_dyn:0, \
15994 _rlxn = _dyn?(lx2-lx1)/_dyn:0, \
15995 _rlyn = _dyn?(ly2-ly1)/_dyn:0, \
15996 _rxr = _dyr?(x2-x0)/_dyr:0, \
15997 _rtxr = _dyr?(tx2-tx0)/_dyr:0, \
15998 _rtyr = _dyr?(ty2-ty0)/_dyr:0, \
15999 _rlxr = _dyr?(lx2-lx0)/_dyr:0, \
16000 _rlyr = _dyr?(ly2-ly0)/_dyr:0, \
16001 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
16002 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
16003 _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1-tx0)/_dyl:0): \
16004 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \
16005 _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1-ty0)/_dyl:0): \
16006 (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ), \
16007 _rlxl = (y0!=y1 && y1>0)?(_dyl?(lx1-lx0)/_dyl:0): \
16008 (_errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxn ), \
16009 _rlyl = (y0!=y1 && y1>0)?(_dyl?(ly1-ly0)/_dyl:0): \
16010 (_errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyn ); \
16011 _counter>=0; --_counter, ++y, \
16012 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
16013 txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \
16014 tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \
16015 lxr+=_rlxr+((_errlxr-=_dlxr)<0?_errlxr+=_dyr,_slxr:0), \
16016 lyr+=_rlyr+((_errlyr-=_dlyr)<0?_errlyr+=_dyr,_slyr:0), \
16017 xl+=(y!=y1)?(txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \
16018 tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \
16019 lxl+=_rlxl+((_errlxl-=_dlxl)<0?(_errlxl+=_dyl,_slxl):0), \
16020 lyl+=_rlyl+((_errlyl-=_dlyl)<0?(_errlyl+=_dyl,_slyl):0), \
16021 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
16022 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \
16023 _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1, \
16024 _errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxl=_rlxn, lxl=lx1, \
16025 _errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyl=_rlyn, lyl=ly1, \
16026 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
16027
16028
16029 template<typename tc>
16030 CImg<T>& _draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
16031 const tc *const color, const float opacity, const float brightness) {
16032 _draw_scanline(color,opacity);
16033 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2;
16034 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1);
16035 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2);
16036 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2);
16037 if (ny0<dimy() && ny2>=0) {
16038 if ((nx1-nx0)*(ny2-ny0)-(nx2-nx0)*(ny1-ny0)<0)
16039 _cimg_for_triangle1(*this,xl,xr,y,nx0,ny0,nx1,ny1,nx2,ny2) _draw_scanline(xl,xr,y,color,opacity,brightness);
16040 else
16041 _cimg_for_triangle1(*this,xl,xr,y,nx0,ny0,nx1,ny1,nx2,ny2) _draw_scanline(xr,xl,y,color,opacity,brightness);
16042 }
16043 return *this;
16044 }
16045
16047 template<typename tc>
16048 CImg<T>& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
16049 const tc *const color, const float opacity=1.0f) {
16050 if (!is_empty()) {
16051 if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type());
16052 _draw_triangle(x0,y0,x1,y1,x2,y2,color,opacity,1.0f);
16053 }
16054 return *this;
16055 }
16056
16057 template<typename tc>
16058 CImg<T>& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
16059 const CImg<tc>& color, const float opacity=1.0f) {
16060 return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opacity);
16061 }
16062
16064 template<typename tc>
16065 CImg<T>& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
16066 const tc *const color, const float opacity, const unsigned int pattern) {
16067 if (!is_empty()) {
16068 if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type());
16069 draw_line(x0,y0,x1,y1,color,opacity,pattern,true).
16070 draw_line(x1,y1,x2,y2,color,opacity,pattern,false).
16071 draw_line(x2,y2,x0,y0,color,opacity,pattern,false);
16072 }
16073 return *this;
16074 }
16075
16076 template<typename tc>
16077 CImg<T>& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2,
16078 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
16079 return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opacity,pattern);
16080 }
16081
16083
16097 template<typename tc>
16098 CImg<T>& draw_triangle(const int x0, const int y0,
16099 const int x1, const int y1,
16100 const int x2, const int y2,
16101 const tc *const color,
16102 const float c0,
16103 const float c1,
16104 const float c2,
16105 const float opacity=1.0f) {
16106 if (!is_empty()) {
16107 if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type());
16108 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16109 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16110 const int whz = width*height*depth, offx = dim*whz-1;
16111 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16112 nc0 = (int)(c0*256), nc1 = (int)(c1*256), nc2 = (int)(c2*256);
16113 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nc0,nc1);
16114 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nc0,nc2);
16115 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nc1,nc2);
16116 if (ny0<dimy() && ny2>=0) {
16117 _cimg_for_triangle2(*this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) {
16118 int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0;
16119 if (xright<xleft) cimg::swap(xleft,xright,cleft,cright);
16120 const int
16121 dx = xright-xleft,
16122 dc = cright>cleft?cright-cleft:cleft-cright,
16123 rc = dx?(cright-cleft)/dx:0,
16124 sc = cright>cleft?1:-1,
16125 ndc = dc-(dx?dx*(dc/dx):0);
16126 int errc = dx>>1;
16127 if (xleft<0 && dx) cleft-=xleft*(cright-cleft)/dx;
16128 if (xleft<0) xleft=0;
16129 if (xright>=dimx()-1) xright=dimx()-1;
16130 T* ptrd = ptr(xleft,y,0,0);
16131 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16132 const tc *col = color;
16133 cimg_forV(*this,k) {
16134 const float tval = (float)((cleft**(col++))/256);
16135 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16136 *ptrd = val;
16137 ptrd+=whz;
16138 }
16139 ptrd-=offx;
16140 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16141 } else for (int x=xleft; x<=xright; ++x) {
16142 const tc *col = color;
16143 cimg_forV(*this,k) {
16144 const float tval = (float)((cleft**(col++))/256);
16145 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16146 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16147 ptrd+=whz;
16148 }
16149 ptrd-=offx;
16150 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16151 }
16152 }
16153 }
16154 }
16155 return *this;
16156 }
16157
16158 template<typename tc>
16159 CImg<T>& draw_triangle(const int x0, const int y0,
16160 const int x1, const int y1,
16161 const int x2, const int y2,
16162 const CImg<tc>& color,
16163 const float c0,
16164 const float c1,
16165 const float c2,
16166 const float opacity=1.0f) {
16167 return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,c0,c1,c2,opacity);
16168 }
16169
16171
16189 template<typename t> CImg<T>& draw_triangle(const int x0, const int y0,
16190 const int x1, const int y1,
16191 const int x2, const int y2,
16192 const CImg<t>& texture,
16193 const int tx0, const int ty0,
16194 const int tx1, const int ty1,
16195 const int tx2, const int ty2,
16196 const float opacity=1.0f,
16197 const float brightness=1.0f) {
16198 if (!is_empty()) {
16199 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16200 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16201 if (is_overlapping(texture)) return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness);
16202 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16203 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16204 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16205 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16206 ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2;
16207 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1);
16208 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2);
16209 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2);
16210 if (ny0<dimy() && ny2>=0) {
16211 _cimg_for_triangle3(*this,xleft0,txleft0,tyleft0,xright0,txright0,tyright0,y,
16212 nx0,ny0,ntx0,nty0,nx1,ny1,ntx1,nty1,nx2,ny2,ntx2,nty2) {
16213 int
16214 xleft = xleft0, xright = xright0,
16215 txleft = txleft0, txright = txright0,
16216 tyleft = tyleft0, tyright = tyright0;
16217 if (xright<xleft) cimg::swap(xleft,xright,txleft,txright,tyleft,tyright);
16218 const int
16219 dx = xright-xleft,
16220 dtx = txright>txleft?txright-txleft:txleft-txright,
16221 dty = tyright>tyleft?tyright-tyleft:tyleft-tyright,
16222 rtx = dx?(txright-txleft)/dx:0,
16223 rty = dx?(tyright-tyleft)/dx:0,
16224 stx = txright>txleft?1:-1,
16225 sty = tyright>tyleft?1:-1,
16226 ndtx = dtx-(dx?dx*(dtx/dx):0),
16227 ndty = dty-(dx?dx*(dty/dx):0);
16228 int errtx = dx>>1, errty = errtx;
16229 if (xleft<0 && dx) {
16230 txleft-=xleft*(txright-txleft)/dx;
16231 tyleft-=xleft*(tyright-tyleft)/dx;
16232 }
16233 if (xleft<0) xleft=0;
16234 if (xright>=dimx()-1) xright=dimx()-1;
16235 T* ptrd = ptr(xleft,y,0,0);
16236 if (opacity>=1) {
16237 if (brightness<=1) for (int x=xleft; x<=xright; ++x) {
16238 const t *col = texture.ptr(txleft,tyleft);
16239 cimg_forV(*this,k) {
16240 *ptrd = (T)(brightness**col);
16241 ptrd+=whz; col+=twhz;
16242 }
16243 ptrd-=offx;
16244 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16245 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16246 } else for (int x=xleft; x<=xright; ++x) {
16247 const t *col = texture.ptr(txleft,tyleft);
16248 cimg_forV(*this,k) {
16249 const float tval = (float)(brightness**col);
16250 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16251 *ptrd = val;
16252 ptrd+=whz; col+=twhz;
16253 }
16254 ptrd-=offx;
16255 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16256 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16257 }
16258 } else {
16259 if (brightness<=1) for (int x=xleft; x<=xright; ++x) {
16260 const t *col = texture.ptr(txleft,tyleft);
16261 cimg_forV(*this,k) {
16262 *ptrd = (T)(nopacity*brightness**col + *ptrd*copacity);
16263 ptrd+=whz; col+=twhz;
16264 }
16265 ptrd-=offx;
16266 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16267 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16268 } else for (int x=xleft; x<=xright; ++x) {
16269 const t *col = texture.ptr(txleft,tyleft);
16270 cimg_forV(*this,k) {
16271 const float tval = (float)(brightness**col);
16272 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16273 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16274 ptrd+=whz; col+=twhz;
16275 }
16276 ptrd-=offx;
16277 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16278 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16279 }
16280 }
16281 }
16282 }
16283 }
16284 return *this;
16285 }
16286
16288 template<typename t> CImg<T>& draw_triangle(const int x0, const int y0, const float z0,
16289 const int x1, const int y1, const float z1,
16290 const int x2, const int y2, const float z2,
16291 const CImg<t>& texture,
16292 const int tx0, const int ty0,
16293 const int tx1, const int ty1,
16294 const int tx2, const int ty2,
16295 const float opacity=1.0f,
16296 const float brightness=1.0f) {
16297 if (!is_empty() && z0>0 && z1>0 && z2>0) {
16298 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16299 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16300 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);
16301 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16302 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16303 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16304 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2;
16305 float
16306 ntx0 = tx0/z0, nty0 = ty0/z0,
16307 ntx1 = tx1/z1, nty1 = ty1/z1,
16308 ntx2 = tx2/z2, nty2 = ty2/z2,
16309 nz0 = 1.0f/z0, nz1 = 1.0f/z1, nz2 = 1.0f/z2;
16310 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1);
16311 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2);
16312 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2);
16313 if (ny0<dimy() && ny2>=0) {
16314 float
16315 ptxl = (ntx1-ntx0)/(ny1-ny0),
16316 ptxr = (ntx2-ntx0)/(ny2-ny0),
16317 ptxn = (ntx2-ntx1)/(ny2-ny1),
16318 ptyl = (nty1-nty0)/(ny1-ny0),
16319 ptyr = (nty2-nty0)/(ny2-ny0),
16320 ptyn = (nty2-nty1)/(ny2-ny1),
16321 pzl = (nz1-nz0)/(ny1-ny0),
16322 pzr = (nz2-nz0)/(ny2-ny0),
16323 pzn = (nz2-nz1)/(ny2-ny1),
16324 zr = ny0>=0?nz0:(nz0-ny0*(nz2-nz0)/(ny2-ny0)),
16325 txr = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)),
16326 tyr = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)),
16327 zl = ny1>=0?(ny0>=0?nz0:(nz0-ny0*(nz1-nz0)/(ny1-ny0))):(pzl=pzn,(nz1-ny1*(nz2-nz1)/(ny2-ny1))),
16328 txl = ny1>=0?(ny0>=0?ntx0:(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ptxl=ptxn,(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1))),
16329 tyl = ny1>=0?(ny0>=0?nty0:(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(ptyl=ptyn,(nty1-ny1*(nty2-nty1)/(ny2-ny1)));
16330 _cimg_for_triangle1(*this,xleft0,xright0,y,nx0,ny0,nx1,ny1,nx2,ny2) {
16331 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
16332 int xleft = xleft0, xright = xright0;
16333 float
16334 zleft = zl, zright = zr,
16335 txleft = txl, txright = txr,
16336 tyleft = tyl, tyright = tyr;
16337 if (xright<xleft) cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright);
16338 const int dx = xright-xleft;
16339 const float
16340 pentez = (zright-zleft)/dx,
16341 pentetx = (txright-txleft)/dx,
16342 pentety = (tyright-tyleft)/dx;
16343 if (xleft<0 && dx) {
16344 zleft-=xleft*(zright-zleft)/dx;
16345 txleft-=xleft*(txright-txleft)/dx;
16346 tyleft-=xleft*(tyright-tyleft)/dx;
16347 }
16348 if (xleft<0) xleft=0;
16349 if (xright>=dimx()-1) xright=dimx()-1;
16350 T* ptrd = ptr(xleft,y,0,0);
16351 if (opacity>=1) {
16352 if (brightness<=1) for (int x=xleft; x<=xright; ++x) {
16353 const float invz = 1.0f/zleft;
16354 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16355 cimg_forV(*this,k) {
16356 *ptrd = (T)(brightness**col);
16357 ptrd+=whz; col+=twhz;
16358 }
16359 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16360 } else for (int x=xleft; x<=xright; ++x) {
16361 const float invz = 1.0f/zleft;
16362 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16363 cimg_forV(*this,k) {
16364 const float tval = (float)(brightness**col);
16365 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16366 *ptrd = val;
16367 ptrd+=whz; col+=twhz;
16368 }
16369 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16370 }
16371 } else {
16372 if (brightness<=1) for (int x=xleft; x<=xright; ++x) {
16373 const float invz = 1.0f/zleft;
16374 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16375 cimg_forV(*this,k) {
16376 *ptrd = (T)(nopacity*brightness**col + *ptrd*copacity);
16377 ptrd+=whz; col+=twhz;
16378 }
16379 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16380 } else for (int x=xleft; x<=xright; ++x) {
16381 const float invz = 1.0f/zleft;
16382 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16383 cimg_forV(*this,k) {
16384 const float tval = (float)(brightness**col);
16385 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16386 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16387 ptrd+=whz; col+=twhz;
16388 }
16389 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16390 }
16391 }
16392 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
16393 }
16394 }
16395 }
16396 return *this;
16397 }
16398
16400
16418 template<typename tc, typename t>
16419 CImg<T>& draw_triangle(const int x0, const int y0,
16420 const int x1, const int y1,
16421 const int x2, const int y2,
16422 const tc *const color,
16423 const CImg<t>& light,
16424 const int lx0, const int ly0,
16425 const int lx1, const int ly1,
16426 const int lx2, const int ly2,
16427 const float opacity=1.0f) {
16428 if (!is_empty()) {
16429 if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type());
16430 if (!light) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.",
16431 pixel_type(),light.width,light.height,light.depth,light.dim,light.data);
16432 if (is_overlapping(light)) return draw_triangle(x0,y0,x1,y1,x2,y2,color,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
16433 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16434 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16435 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16436 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
16437 const int whz = width*height*depth, offx = dim*whz-1;
16438 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nlx0,nlx1,nly0,nly1);
16439 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nlx0,nlx2,nly0,nly2);
16440 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nlx1,nlx2,nly1,nly2);
16441 if (ny0<dimy() && ny2>=0) {
16442 _cimg_for_triangle3(*this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y,
16443 nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) {
16444 int
16445 xleft = xleft0, xright = xright0,
16446 lxleft = lxleft0, lxright = lxright0,
16447 lyleft = lyleft0, lyright = lyright0;
16448 if (xright<xleft) cimg::swap(xleft,xright,lxleft,lxright,lyleft,lyright);
16449 const int
16450 dx = xright-xleft,
16451 dlx = lxright>lxleft?lxright-lxleft:lxleft-lxright,
16452 dly = lyright>lyleft?lyright-lyleft:lyleft-lyright,
16453 rlx = dx?(lxright-lxleft)/dx:0,
16454 rly = dx?(lyright-lyleft)/dx:0,
16455 slx = lxright>lxleft?1:-1,
16456 sly = lyright>lyleft?1:-1,
16457 ndlx = dlx-(dx?dx*(dlx/dx):0),
16458 ndly = dly-(dx?dx*(dly/dx):0);
16459 int errlx = dx>>1, errly = errlx;
16460 if (xleft<0 && dx) {
16461 lxleft-=xleft*(lxright-lxleft)/dx;
16462 lyleft-=xleft*(lyright-lyleft)/dx;
16463 }
16464 if (xleft<0) xleft=0;
16465 if (xright>=dimx()-1) xright=dimx()-1;
16466 T* ptrd = ptr(xleft,y,0,0);
16467 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16468 const t lightness = light(lxleft,lyleft);
16469 const tc *col = color;
16470 cimg_forV(*this,k) {
16471 const float tval = (float)(*(col++)*lightness);
16472 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16473 *ptrd = val;
16474 ptrd+=whz;
16475 }
16476 ptrd-=offx;
16477 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16478 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16479 } else for (int x=xleft; x<=xright; ++x) {
16480 const t lightness = light(lxleft,lyleft);
16481 const tc *col = color;
16482 cimg_forV(*this,k) {
16483 const float tval = (float)(*(col++)*lightness);
16484 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16485 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16486 ptrd+=whz;
16487 }
16488 ptrd-=offx;
16489 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16490 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16491 }
16492 }
16493 }
16494 }
16495 return *this;
16496 }
16497
16498 template<typename tc, typename t>
16499 CImg<T>& draw_triangle(const int x0, const int y0,
16500 const int x1, const int y1,
16501 const int x2, const int y2,
16502 const CImg<tc>& color,
16503 const CImg<t>& light,
16504 const int lx0, const int ly0,
16505 const int lx1, const int ly1,
16506 const int lx2, const int ly2,
16507 const float opacity=1.0f) {
16508 return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
16509 }
16510
16512
16532 template<typename t> CImg<T>& draw_triangle(const int x0, const int y0,
16533 const int x1, const int y1,
16534 const int x2, const int y2,
16535 const CImg<t>& texture,
16536 const int tx0, const int ty0,
16537 const int tx1, const int ty1,
16538 const int tx2, const int ty2,
16539 const float c0,
16540 const float c1,
16541 const float c2,
16542 const float opacity=1) {
16543 if (!is_empty()) {
16544 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16545 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16546 if (is_overlapping(texture)) return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,c0,c1,c2,opacity);
16547 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16548 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16549 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16550 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16551 ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2,
16552 nc0 = (int)(c0*256), nc1 = (int)(c1*256), nc2 = (int)(c2*256);
16553 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nc0,nc1);
16554 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nc0,nc2);
16555 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nc1,nc2);
16556 if (ny0<dimy() && ny2>=0) {
16557 _cimg_for_triangle4(*this,xleft0,cleft0,txleft0,tyleft0,xright0,cright0,txright0,tyright0,y,
16558 nx0,ny0,nc0,ntx0,nty0,nx1,ny1,nc1,ntx1,nty1,nx2,ny2,nc2,ntx2,nty2) {
16559 int
16560 xleft = xleft0, xright = xright0,
16561 cleft = cleft0, cright = cright0,
16562 txleft = txleft0, txright = txright0,
16563 tyleft = tyleft0, tyright = tyright0;
16564 if (xright<xleft) cimg::swap(xleft,xright,cleft,cright,txleft,txright,tyleft,tyright);
16565 const int
16566 dx = xright-xleft,
16567 dc = cright>cleft?cright-cleft:cleft-cright,
16568 dtx = txright>txleft?txright-txleft:txleft-txright,
16569 dty = tyright>tyleft?tyright-tyleft:tyleft-tyright,
16570 rc = dx?(cright-cleft)/dx:0,
16571 rtx = dx?(txright-txleft)/dx:0,
16572 rty = dx?(tyright-tyleft)/dx:0,
16573 sc = cright>cleft?1:-1,
16574 stx = txright>txleft?1:-1,
16575 sty = tyright>tyleft?1:-1,
16576 ndc = dc-(dx?dx*(dc/dx):0),
16577 ndtx = dtx-(dx?dx*(dtx/dx):0),
16578 ndty = dty-(dx?dx*(dty/dx):0);
16579 int errc = dx>>1, errtx = errc, errty = errc;
16580 if (xleft<0 && dx) {
16581 cleft-=xleft*(cright-cleft)/dx;
16582 txleft-=xleft*(txright-txleft)/dx;
16583 tyleft-=xleft*(tyright-tyleft)/dx;
16584 }
16585 if (xleft<0) xleft=0;
16586 if (xright>=dimx()-1) xright=dimx()-1;
16587 T* ptrd = ptr(xleft,y,0,0);
16588 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16589 const t *col = texture.ptr(txleft,tyleft);
16590 cimg_forV(*this,k) {
16591 const float tval = (float)(cleft**col/256);
16592 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16593 *ptrd = (T)val;
16594 ptrd+=whz; col+=twhz;
16595 }
16596 ptrd-=offx;
16597 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16598 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16599 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16600 } else for (int x=xleft; x<=xright; ++x) {
16601 const t *col = texture.ptr(txleft,tyleft);
16602 cimg_forV(*this,k) {
16603 const float tval = (float)(cleft**col/256);
16604 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16605 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16606 ptrd+=whz; col+=twhz;
16607 }
16608 ptrd-=offx;
16609 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16610 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16611 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16612 }
16613 }
16614 }
16615 }
16616 return *this;
16617 }
16618
16620 template<typename t> CImg<T>& draw_triangle(const int x0, const int y0, const float z0,
16621 const int x1, const int y1, const float z1,
16622 const int x2, const int y2, const float z2,
16623 const CImg<t>& texture,
16624 const int tx0, const int ty0,
16625 const int tx1, const int ty1,
16626 const int tx2, const int ty2,
16627 const float c0,
16628 const float c1,
16629 const float c2,
16630 const float opacity=1.0f) {
16631 if (!is_empty() && z0>0 && z1>0 && z2>0) {
16632 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16633 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16634 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);
16635 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16636 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16637 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16638 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16639 nc0 = (int)(c0*256), nc1 = (int)(c1*256), nc2 = (int)(c2*256);
16640 float
16641 ntx0 = tx0/z0, nty0 = ty0/z0,
16642 ntx1 = tx1/z1, nty1 = ty1/z1,
16643 ntx2 = tx2/z2, nty2 = ty2/z2,
16644 nz0 = 1.0f/z0, nz1 = 1.0f/z1, nz2 = 1.0f/z2;
16645 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1,nc0,nc1);
16646 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2,nc0,nc2);
16647 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2,nc1,nc2);
16648 if (ny0<dimy() && ny2>=0) {
16649 float
16650 ptxl = (ntx1-ntx0)/(ny1-ny0),
16651 ptxr = (ntx2-ntx0)/(ny2-ny0),
16652 ptxn = (ntx2-ntx1)/(ny2-ny1),
16653 ptyl = (nty1-nty0)/(ny1-ny0),
16654 ptyr = (nty2-nty0)/(ny2-ny0),
16655 ptyn = (nty2-nty1)/(ny2-ny1),
16656 pzl = (nz1-nz0)/(ny1-ny0),
16657 pzr = (nz2-nz0)/(ny2-ny0),
16658 pzn = (nz2-nz1)/(ny2-ny1),
16659 zr = ny0>=0?nz0:(nz0-ny0*(nz2-nz0)/(ny2-ny0)),
16660 txr = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)),
16661 tyr = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)),
16662 zl = ny1>=0?(ny0>=0?nz0:(nz0-ny0*(nz1-nz0)/(ny1-ny0))):(pzl=pzn,(nz1-ny1*(nz2-nz1)/(ny2-ny1))),
16663 txl = ny1>=0?(ny0>=0?ntx0:(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ptxl=ptxn,(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1))),
16664 tyl = ny1>=0?(ny0>=0?nty0:(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(ptyl=ptyn,(nty1-ny1*(nty2-nty1)/(ny2-ny1)));
16665 _cimg_for_triangle2(*this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) {
16666 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
16667 int
16668 xleft = xleft0, xright = xright0,
16669 cleft = cleft0, cright = cright0;
16670 float
16671 zleft = zl, zright = zr,
16672 txleft = txl, txright = txr,
16673 tyleft = tyl, tyright = tyr;
16674 if (xright<xleft) cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright,cleft,cright);
16675 const int
16676 dx = xright-xleft,
16677 dc = cright>cleft?cright-cleft:cleft-cright,
16678 rc = dx?(cright-cleft)/dx:0,
16679 sc = cright>cleft?1:-1,
16680 ndc = dc-(dx?dx*(dc/dx):0);
16681 const float
16682 pentez = (zright-zleft)/dx,
16683 pentetx = (txright-txleft)/dx,
16684 pentety = (tyright-tyleft)/dx;
16685 int errc = dx>>1;
16686 if (xleft<0 && dx) {
16687 cleft-=xleft*(cright-cleft)/dx;
16688 zleft-=xleft*(zright-zleft)/dx;
16689 txleft-=xleft*(txright-txleft)/dx;
16690 tyleft-=xleft*(tyright-tyleft)/dx;
16691 }
16692 if (xleft<0) xleft=0;
16693 if (xright>=dimx()-1) xright=dimx()-1;
16694 T* ptrd = ptr(xleft,y,0,0);
16695 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16696 const float invz = 1.0f/zleft;
16697 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16698 cimg_forV(*this,k) {
16699 const float tval = (float)(cleft**col/256);
16700 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16701 *ptrd = val;
16702 ptrd+=whz; col+=twhz;
16703 }
16704 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16705 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16706 } else for (int x=xleft; x<=xright; ++x) {
16707 const float invz = 1.0f/zleft;
16708 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16709 cimg_forV(*this,k) {
16710 const float tval = (float)(cleft**col/256);
16711 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16712 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16713 ptrd+=whz; col+=twhz;
16714 }
16715 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16716 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
16717 }
16718 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
16719 }
16720 }
16721 }
16722 return *this;
16723 }
16724
16726
16750 template<typename t, typename tl> CImg<T>& draw_triangle(const int x0, const int y0,
16751 const int x1, const int y1,
16752 const int x2, const int y2,
16753 const CImg<t>& texture,
16754 const int tx0, const int ty0,
16755 const int tx1, const int ty1,
16756 const int tx2, const int ty2,
16757 const CImg<tl>& light,
16758 const int lx0, const int ly0,
16759 const int lx1, const int ly1,
16760 const int lx2, const int ly2,
16761 const float opacity=1.0f) {
16762 if (!is_empty()) {
16763 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16764 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16765 if (!light) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.",
16766 pixel_type(),light.width,light.height,light.depth,light.dim,light.data);
16767 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);
16768 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);
16769 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16770 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16771 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16772 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16773 ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2,
16774 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
16775 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1);
16776 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2);
16777 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2);
16778 if (ny0<dimy() && ny2>=0) {
16779 _cimg_for_triangle5(*this,xleft0,lxleft0,lyleft0,txleft0,tyleft0,xright0,lxright0,lyright0,txright0,tyright0,y,
16780 nx0,ny0,nlx0,nly0,ntx0,nty0,nx1,ny1,nlx1,nly1,ntx1,nty1,nx2,ny2,nlx2,nly2,ntx2,nty2) {
16781 int
16782 xleft = xleft0, xright = xright0,
16783 lxleft = lxleft0, lxright = lxright0,
16784 lyleft = lyleft0, lyright = lyright0,
16785 txleft = txleft0, txright = txright0,
16786 tyleft = tyleft0, tyright = tyright0;
16787 if (xright<xleft) cimg::swap(xleft,xright,lxleft,lxright,lyleft,lyright,txleft,txright,tyleft,tyright);
16788 const int
16789 dx = xright-xleft,
16790 dlx = lxright>lxleft?lxright-lxleft:lxleft-lxright,
16791 dly = lyright>lyleft?lyright-lyleft:lyleft-lyright,
16792 dtx = txright>txleft?txright-txleft:txleft-txright,
16793 dty = tyright>tyleft?tyright-tyleft:tyleft-tyright,
16794 rlx = dx?(lxright-lxleft)/dx:0,
16795 rly = dx?(lyright-lyleft)/dx:0,
16796 rtx = dx?(txright-txleft)/dx:0,
16797 rty = dx?(tyright-tyleft)/dx:0,
16798 slx = lxright>lxleft?1:-1,
16799 sly = lyright>lyleft?1:-1,
16800 stx = txright>txleft?1:-1,
16801 sty = tyright>tyleft?1:-1,
16802 ndlx = dlx-(dx?dx*(dlx/dx):0),
16803 ndly = dly-(dx?dx*(dly/dx):0),
16804 ndtx = dtx-(dx?dx*(dtx/dx):0),
16805 ndty = dty-(dx?dx*(dty/dx):0);
16806 int errlx = dx>>1, errly = errlx, errtx = errlx, errty = errlx;
16807 if (xleft<0 && dx) {
16808 lxleft-=xleft*(lxright-lxleft)/dx;
16809 lyleft-=xleft*(lyright-lyleft)/dx;
16810 txleft-=xleft*(txright-txleft)/dx;
16811 tyleft-=xleft*(tyright-tyleft)/dx;
16812 }
16813 if (xleft<0) xleft=0;
16814 if (xright>=dimx()-1) xright=dimx()-1;
16815 T* ptrd = ptr(xleft,y,0,0);
16816 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16817 const tl lightness = light(lxleft,lyleft);
16818 const t *col = texture.ptr(txleft,tyleft);
16819 cimg_forV(*this,k) {
16820 const float tval = (float)(lightness**col);
16821 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16822 *ptrd = (T)val;
16823 ptrd+=whz; col+=twhz;
16824 }
16825 ptrd-=offx;
16826 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16827 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16828 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16829 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16830 } else for (int x=xleft; x<=xright; ++x) {
16831 const tl lightness = light(lxleft,lyleft);
16832 const t *col = texture.ptr(txleft,tyleft);
16833 cimg_forV(*this,k) {
16834 const float tval = (float)(lightness**col);
16835 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16836 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16837 ptrd+=whz; col+=twhz;
16838 }
16839 ptrd-=offx;
16840 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16841 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16842 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
16843 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
16844 }
16845 }
16846 }
16847 }
16848 return *this;
16849 }
16850
16852 template<typename t, typename tl> CImg<T>& draw_triangle(const int x0, const int y0, const float z0,
16853 const int x1, const int y1, const float z1,
16854 const int x2, const int y2, const float z2,
16855 const CImg<t>& texture,
16856 const int tx0, const int ty0,
16857 const int tx1, const int ty1,
16858 const int tx2, const int ty2,
16859 const CImg<tl>& light,
16860 const int lx0, const int ly0,
16861 const int lx1, const int ly1,
16862 const int lx2, const int ly2,
16863 const float opacity=1.0f) {
16864 if (!is_empty() && z0>0 && z1>0 && z2>0) {
16865 if (!texture || texture.dim<dim) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.",
16866 pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
16867 if (!light) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.",
16868 pixel_type(),light.width,light.height,light.depth,light.dim,light.data);
16869 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);
16870 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);
16871 static const T minval = cimg::type<T>::min(), maxval = cimg::type<T>::max();
16872 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
16873 const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1;
16874 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
16875 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
16876 float
16877 ntx0 = tx0/z0, nty0 = ty0/z0,
16878 ntx1 = tx1/z1, nty1 = ty1/z1,
16879 ntx2 = tx2/z2, nty2 = ty2/z2,
16880 nz0 = 1.0f/z0, nz1 = 1.0f/z1, nz2 = 1.0f/z2;
16881 if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1,nz0,nz1);
16882 if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2,nz0,nz2);
16883 if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2,nz1,nz2);
16884 if (ny0<dimy() && ny2>=0) {
16885 float
16886 ptxl = (ntx1-ntx0)/(ny1-ny0),
16887 ptxr = (ntx2-ntx0)/(ny2-ny0),
16888 ptxn = (ntx2-ntx1)/(ny2-ny1),
16889 ptyl = (nty1-nty0)/(ny1-ny0),
16890 ptyr = (nty2-nty0)/(ny2-ny0),
16891 ptyn = (nty2-nty1)/(ny2-ny1),
16892 pzl = (nz1-nz0)/(ny1-ny0),
16893 pzr = (nz2-nz0)/(ny2-ny0),
16894 pzn = (nz2-nz1)/(ny2-ny1),
16895 zr = ny0>=0?nz0:(nz0-ny0*(nz2-nz0)/(ny2-ny0)),
16896 txr = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)),
16897 tyr = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)),
16898 zl = ny1>=0?(ny0>=0?nz0:(nz0-ny0*(nz1-nz0)/(ny1-ny0))):(pzl=pzn,(nz1-ny1*(nz2-nz1)/(ny2-ny1))),
16899 txl = ny1>=0?(ny0>=0?ntx0:(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ptxl=ptxn,(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1))),
16900 tyl = ny1>=0?(ny0>=0?nty0:(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(ptyl=ptyn,(nty1-ny1*(nty2-nty1)/(ny2-ny1)));
16901 _cimg_for_triangle3(*this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y,
16902 nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) {
16903 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
16904 int
16905 xleft = xleft0, xright = xright0,
16906 lxleft = lxleft0, lxright = lxright0,
16907 lyleft = lyleft0, lyright = lyright0;
16908 float
16909 zleft = zl, zright = zr,
16910 txleft = txl, txright = txr,
16911 tyleft = tyl, tyright = tyr;
16912 if (xright<xleft) cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright,lxleft,lxright,lyleft,lyright);
16913 const int
16914 dx = xright-xleft,
16915 dlx = lxright>lxleft?lxright-lxleft:lxleft-lxright,
16916 dly = lyright>lyleft?lyright-lyleft:lyleft-lyright,
16917 rlx = dx?(lxright-lxleft)/dx:0,
16918 rly = dx?(lyright-lyleft)/dx:0,
16919 slx = lxright>lxleft?1:-1,
16920 sly = lyright>lyleft?1:-1,
16921 ndlx = dlx-(dx?dx*(dlx/dx):0),
16922 ndly = dly-(dx?dx*(dly/dx):0);
16923 const float
16924 pentez = (zright-zleft)/dx,
16925 pentetx = (txright-txleft)/dx,
16926 pentety = (tyright-tyleft)/dx;
16927 int errlx = dx>>1, errly = errlx;
16928 if (xleft<0 && dx) {
16929 zleft-=xleft*(zright-zleft)/dx;
16930 lxleft-=xleft*(lxright-lxleft)/dx;
16931 lyleft-=xleft*(lyright-lyleft)/dx;
16932 txleft-=xleft*(txright-txleft)/dx;
16933 tyleft-=xleft*(tyright-tyleft)/dx;
16934 }
16935 if (xleft<0) xleft=0;
16936 if (xright>=dimx()-1) xright=dimx()-1;
16937 T* ptrd = ptr(xleft,y,0,0);
16938 if (opacity>=1) for (int x=xleft; x<=xright; ++x) {
16939 const float invz = 1.0f/zleft;
16940 const tl lightness = light(lxleft,lyleft);
16941 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16942 cimg_forV(*this,k) {
16943 const float tval = (float)(lightness**col);
16944 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16945 *ptrd = val;
16946 ptrd+=whz; col+=twhz;
16947 }
16948 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16949 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16950 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16951 } else for (int x=xleft; x<=xright; ++x) {
16952 const float invz = 1.0f/zleft;
16953 const tl lightness = light(lxleft,lyleft);
16954 const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz));
16955 cimg_forV(*this,k) {
16956 const float tval = (float)(lightness**col);
16957 const T val = tval<(float)maxval?(tval>(float)minval?(T)tval:minval):maxval;
16958 *ptrd = (T)(nopacity*val + *ptrd*copacity);
16959 ptrd+=whz; col+=twhz;
16960 }
16961 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
16962 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
16963 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
16964 }
16965 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
16966 }
16967 }
16968 }
16969 return *this;
16970 }
16971
16972
16973 template<typename tc>
16974 CImg<T>& _draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
16975 const tc *const color, const float opacity, const unsigned int pattern) {
16976 if (!is_empty()) {
16977 if (!color) throw CImgArgumentException("CImg<%s>::draw_ellipse : Specified color is (null).",pixel_type());
16978 _draw_scanline(color,opacity);
16979 const float
16980 nr1 = cimg::abs(r1), nr2 = cimg::abs(r2),
16981 norm = (float)std::sqrt(ru*ru+rv*rv),
16982 u = norm>0?ru/norm:1,
16983 v = norm>0?rv/norm:0,
16984 rmax = cimg::max(nr1,nr2),
16985 l1 = (float)std::pow(rmax/(nr1>0?nr1:1e-6),2),
16986 l2 = (float)std::pow(rmax/(nr2>0?nr2:1e-6),2),
16987 a = l1*u*u + l2*v*v,
16988 b = u*v*(l1-l2),
16989 c = l1*v*v + l2*u*u;
16990 const int
16991 yb = (int)std::sqrt(a*rmax*rmax/(a*c-b*b)),
16992 tymin = y0-yb,
16993 tymax = y0+yb,
16994 ymin = tymin<0?0:tymin,
16995 ymax = tymax>=dimy()?height-1:tymax;
16996 int oxmin = 0, oxmax = 0;
16997 bool first_line = true;
16998 for (int y=ymin; y<=ymax; ++y) {
16999 const float
17000 Y = y-y0 + (y<y0?0.5f:-0.5f),
17001 delta = b*b*Y*Y-a*(c*Y*Y-rmax*rmax),
17002 sdelta = delta>0?(float)std::sqrt(delta)/a:0.0f,
17003 bY = b*Y/a,
17004 fxmin = x0-0.5f-bY-sdelta,
17005 fxmax = x0+0.5f-bY+sdelta;
17006 const int xmin = (int)fxmin, xmax = (int)fxmax;
17007 if (!pattern) _draw_scanline(xmin,xmax,y,color,opacity);
17008 else {
17009 if (first_line) {
17010 if (y0-yb>=0) _draw_scanline(xmin,xmax,y,color,opacity);
17011 else draw_point(xmin,y,color,opacity).draw_point(xmax,y,color,opacity);
17012 first_line = false;
17013 } else {
17014 if (xmin<oxmin) _draw_scanline(xmin,oxmin-1,y,color,opacity);
17015 else _draw_scanline(oxmin+(oxmin==xmin?0:1),xmin,y,color,opacity);
17016 if (xmax<oxmax) _draw_scanline(xmax,oxmax-1,y,color,opacity);
17017 else _draw_scanline(oxmax+(oxmax==xmax?0:1),xmax,y,color,opacity);
17018 if (y==tymax) _draw_scanline(xmin+1,xmax-1,y,color,opacity);
17019 }
17020 }
17021 oxmin = xmin; oxmax = xmax;
17022 }
17023 }
17024 return *this;
17025 }
17026
17028
17039 template<typename tc>
17040 CImg<T>& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
17041 const tc *const color, const float opacity, const unsigned int pattern) {
17042 if (pattern) _draw_ellipse(x0,y0,r1,r2,ru,rv,color,opacity,pattern);
17043 return *this;
17044 }
17045
17046 template<typename tc>
17047 CImg<T>& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
17048 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
17049 return draw_ellipse(x0,y0,r1,r2,ru,rv,color.data,opacity,pattern);
17050 }
17051
17053
17063 template<typename tc>
17064 CImg<T>& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
17065 const tc *const color, const float opacity=1.0f) {
17066 return _draw_ellipse(x0,y0,r1,r2,ru,rv,color,opacity,0U);
17067 }
17068
17069 template<typename tc>
17070 CImg<T>& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv,
17071 const CImg<tc>& color, const float opacity=1.0f) {
17072 return draw_ellipse(x0,y0,r1,r2,ru,rv,color.data,opacity);
17073 }
17074
17076
17083 template<typename t, typename tc>
17084 CImg<T>& draw_ellipse(const int x0, const int y0, const CImg<t> &tensor,
17085 const tc *const color, const float opacity=1.0f) {
17086 CImgList<t> eig = tensor.get_symmetric_eigen();
17087 const CImg<t> &val = eig[0], &vec = eig[1];
17088 return draw_ellipse(x0,y0,val(0),val(1),vec(0,0),vec(0,1),color,opacity);
17089 }
17090
17091 template<typename t, typename tc>
17092 CImg<T>& draw_ellipse(const int x0, const int y0, const CImg<t> &tensor,
17093 const CImg<tc>& color, const float opacity=1.0f) {
17094 return draw_ellipse(x0,y0,tensor,color.data,opacity);
17095 }
17096
17098
17106 template<typename t, typename tc>
17107 CImg<T>& draw_ellipse(const int x0, const int y0, const CImg<t> &tensor,
17108 const tc *const color, const float opacity, const unsigned int pattern) {
17109 CImgList<t> eig = tensor.get_symmetric_eigen();
17110 const CImg<t> &val = eig[0], &vec = eig[1];
17111 return draw_ellipse(x0,y0,val(0),val(1),vec(0,0),vec(0,1),color,opacity,pattern);
17112 }
17113
17114 template<typename t, typename tc>
17115 CImg<T>& draw_ellipse(const int x0, const int y0, const CImg<t> &tensor,
17116 const CImg<tc>& color, const float opacity, const unsigned int pattern) {
17117 return draw_ellipse(x0,y0,tensor,color.data,opacity,pattern);
17118 }
17119
17121
17130 template<typename tc>
17131 CImg<T>& draw_circle(const int x0, const int y0, int radius, const tc *const color, const float opacity=1.0f) {
17132 if (!is_empty()) {
17133 if (!color) throw CImgArgumentException("CImg<%s>::draw_circle : Specified color is (null).",pixel_type());
17134 _draw_scanline(color,opacity);
17135 if (radius<0 || x0-radius>=dimx() || y0+radius<0 || y0-radius>=dimy()) return *this;
17136 if (y0>=0 && y0<dimy()) _draw_scanline(x0-radius,x0+radius,y0,color,opacity);
17137 for (int f=1-radius, ddFx=0, ddFy=-(radius<<1), x=0, y=radius; x<y; ) {
17138 if (f>=0) {
17139 const int x1 = x0-x, x2 = x0+x, y1 = y0-y, y2 = y0+y;
17140 if (y1>=0 && y1<dimy()) _draw_scanline(x1,x2,y1,color,opacity);
17141 if (y2>=0 && y2<dimy()) _draw_scanline(x1,x2,y2,color,opacity);
17142 f+=(ddFy+=2); --y;
17143 }
17144 const bool no_diag = y!=(x++);
17145 ++(f+=(ddFx+=2));
17146 const int x1 = x0-y, x2 = x0+y, y1 = y0-x, y2 = y0+x;
17147 if (no_diag) {
17148 if (y1>=0 && y1<dimy()) _draw_scanline(x1,x2,y1,color,opacity);
17149 if (y2>=0 && y2<dimy()) _draw_scanline(x1,x2,y2,color,opacity);
17150 }
17151 }
17152 }
17153 return *this;
17154 }
17155
17156 template<typename tc>
17157 CImg<T>& draw_circle(const int x0, const int y0, int radius, const CImg<tc>& color, const float opacity=1.0f) {
17158 return draw_circle(x0,y0,radius,color.data,opacity);
17159 }
17160
17162
17169 template<typename tc>
17170 CImg<T>& draw_circle(const int x0, const int y0, int radius, const tc *const color, const float opacity, const unsigned int) {
17171 if (!is_empty()) {
17172 if (!color) throw CImgArgumentException("CImg<%s>::draw_circle : Specified color is (null).",pixel_type());
17173 if (radius<0 || x0-radius>=dimx() || y0+radius<0 || y0-radius>=dimy()) return *this;
17174 if (!radius) return draw_point(x0,y0,color,opacity);
17175 draw_point(x0-radius,y0,color,opacity).draw_point(x0+radius,y0,color,opacity).
17176 draw_point(x0,y0-radius,color,opacity).draw_point(x0,y0+radius,color,opacity);
17177 if (radius==1) return *this;
17178 for (int f=1-radius, ddFx=0, ddFy=-(radius<<1), x=0, y=radius; x<y; ) {
17179 if (f>=0) { f+=(ddFy+=2); --y; }
17180 ++x; ++(f+=(ddFx+=2));
17181 if (x!=y+1) {
17182 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;
17183 draw_point(x1,y1,color,opacity).draw_point(x1,y2,color,opacity).
17184 draw_point(x2,y1,color,opacity).draw_point(x2,y2,color,opacity);
17185 if (x!=y)
17186 draw_point(x3,y3,color,opacity).draw_point(x4,y4,color,opacity).
17187 draw_point(x4,y3,color,opacity).draw_point(x3,y4,color,opacity);
17188 }
17189 }
17190 }
17191 return *this;
17192 }
17193
17194 template<typename tc>
17195 CImg<T>& draw_circle(const int x0, const int y0, int radius, const CImg<tc>& color, const float opacity, const unsigned int foo) {
17196 return draw_circle(x0,y0,radius,color.data,opacity,foo);
17197 }
17198
17200
17211 template<typename t>
17212 CImg<T>& draw_text(const char *const text,
17213 const int x0, const int y0,
17214 const T *const fgcolor, const T *const bgcolor,
17215 const CImgList<t>& font, const float opacity=1.0f) {
17216 if (!text)
17217 throw CImgArgumentException("CImg<%s>::draw_text() : Specified input string is (null).",pixel_type());
17218 if (!font)
17219 throw CImgArgumentException("CImg<%s>::draw_text() : Specified font (%u,%p) is empty.",
17220 pixel_type(),font.size,font.data);
17221
17222 if (is_empty()) {
17223
17224 int x = 0, y = 0, w = 0;
17225 for (int i=0; i<cimg::strlen(text); ++i) {
17226 const unsigned char c = text[i];
17227 switch (c) {
17228 case '\n': y+=font[' '].height; if (x>w) w = x; x = 0; break;
17229 case '\t': x+=4*font[' '].width; break;
17230 default: if (c<font.size) x+=font[c].width;
17231 }
17232 }
17233 if (x!=0) {
17234 if (x>w) w=x;
17235 y+=font[' '].height;
17236 }
17237 assign(x0+w,y0+y,1,font[' '].dim,0);
17238 if (bgcolor) cimg_forV(*this,k) get_shared_channel(k).fill((T)bgcolor[k]);
17239 }
17240
17241 int x = x0, y = y0;
17242 CImg<T> letter;
17243 for (int i=0; i<cimg::strlen(text); ++i) {
17244 const unsigned char c = text[i];
17245 switch (c) {
17246 case '\n': y+=font[' '].height; x=x0; break;
17247 case '\t': x+=4*font[' '].width; break;
17248 default: if (c<font.size) {
17249 letter = font[c];
17250 const CImg<T>& mask = (c+256)<(int)font.size?font[c+256]:font[c];
17251 if (fgcolor) for (unsigned int p=0; p<letter.width*letter.height; ++p)
17252 if (mask(p)) cimg_forV(*this,k) letter(p,0,0,k) = (T)(letter(p,0,0,k)*fgcolor[k]);
17253 if (bgcolor) for (unsigned int p=0; p<letter.width*letter.height; ++p)
17254 if (!mask(p)) cimg_forV(*this,k) letter(p,0,0,k) = (T)bgcolor[k];
17255 if (!bgcolor && font.size>=512) draw_image(letter,mask,x,y,0,0,(T)1,opacity);
17256 else draw_image(letter,x,y,0,0,opacity);
17257 x+=letter.width;
17258 }
17259 break;
17260 }
17261 }
17262 return *this;
17263 }
17264
17265 template<typename tc, typename t>
17266 CImg<T>& draw_text(const char *const text,
17267 const int x0, const int y0,
17268 const CImg<tc>& fgcolor, const CImg<tc>& bgcolor,
17269 const CImgList<t>& font, const float opacity=1.0f) {
17270 const CImg<T> fgcol(fgcolor), bgcol(bgcolor);
17271 return draw_text(text,x0,y0,fgcol.data,bgcol.data,font,opacity);
17272 }
17273
17275
17286 CImg<T>& draw_text(const char *const text,
17287 const int x0, const int y0,
17288 const T *const fgcolor, const T *const bgcolor=0,
17289 const unsigned int font_size=11, const float opacity=1.0f) {
17290 return draw_text(text,x0,y0,fgcolor,bgcolor,CImgList<T>::get_font(font_size),opacity);
17291 }
17292
17293 template<typename tc>
17294 CImg<T>& draw_text(const char *const text,
17295 const int x0, const int y0,
17296 const CImg<tc>& fgcolor, const CImg<tc>& bgcolor,
17297 const unsigned int font_size=11, const float opacity=1.0f) {
17298 const CImg<T> fgcol(fgcolor), bgcol(bgcolor);
17299 return draw_text(text,x0,y0,fgcol.data,bgcol.data,font_size,opacity);
17300 }
17301
17303
17313 CImg<T>& draw_text(const int x0, const int y0,
17314 const T *const fgcolor, const T *const bgcolor, const unsigned int font_size,
17315 const float opacity, const char *format, ...) {
17316 char tmp[2048] = { 0 };
17317 std::va_list ap;
17318 va_start(ap,format);
17319 std::vsprintf(tmp,format,ap);
17320 va_end(ap);
17321 return draw_text(tmp,x0,y0,fgcolor,bgcolor,font_size,opacity);
17322 }
17323
17324 template<typename tc>
17325 CImg<T>& draw_text(const int x0, const int y0,
17326 const CImg<tc>& fgcolor, const CImg<tc>& bgcolor, const unsigned int font_size,
17327 const float opacity, const char *format, ...) {
17328 char tmp[2048] = { 0 };
17329 std::va_list ap;
17330 va_start(ap,format);
17331 std::vsprintf(tmp,format,ap);
17332 va_end(ap);
17333 return draw_text(tmp,x0,y0,fgcolor,bgcolor,font_size,opacity);
17334 }
17335
17337
17347 template<typename t>
17348 CImg<T>& draw_text(const int x0, const int y0,
17349 const T *const fgcolor, const T *const bgcolor,
17350 const CImgList<t>& font, const float opacity, const char *format, ...) {
17351 char tmp[2048] = { 0 };
17352 std::va_list ap;
17353 va_start(ap,format);
17354 std::vsprintf(tmp,format,ap);
17355 va_end(ap);
17356 return draw_text(tmp,x0,y0,fgcolor,bgcolor,font,opacity);
17357 }
17358
17359 template<typename tc, typename t>
17360 CImg<T>& draw_text(const int x0, const int y0,
17361 const CImg<tc>& fgcolor, const CImg<tc>& bgcolor,
17362 const CImgList<t>& font, const float opacity, const char *format, ...) {
17363 char tmp[2048] = { 0 };
17364 std::va_list ap;
17365 va_start(ap,format);
17366 std::vsprintf(tmp,format,ap);
17367 va_end(ap);
17368 return draw_text(tmp,x0,y0,fgcolor,bgcolor,font,opacity);
17369 }
17370
17372
17382 template<typename t1, typename t2>
17383 CImg<T>& draw_quiver(const CImg<t1>& flow, const t2 *const color,
17384 const unsigned int sampling=25, const float factor=-20,
17385 const int quiver_type=0, const float opacity=1.0f, const unsigned int pattern=~0U) {
17386 return draw_quiver(flow,CImg<t2>(color,dim,1,1,1,true),sampling,factor,quiver_type,opacity,pattern);
17387 }
17388
17390
17400 template<typename t1, typename t2>
17401 CImg<T>& draw_quiver(const CImg<t1>& flow, const CImg<t2>& color,
17402 const unsigned int sampling=25, const float factor=-20,
17403 const int quiver_type=0, const float opacity=1.0f, const unsigned int pattern=~0U) {
17404 if (!is_empty()) {
17405 if (!flow || flow.dim!=2)
17406 throw CImgArgumentException("CImg<%s>::draw_quiver() : Specified flow (%u,%u,%u,%u,%p) has wrong dimensions.",
17407 pixel_type(),flow.width,flow.height,flow.depth,flow.dim,flow.data);
17408 if (sampling<=0)
17409 throw CImgArgumentException("CImg<%s>::draw_quiver() : Incorrect sampling value = %g",pixel_type(),sampling);
17410 const bool colorfield = (color.width==flow.width && color.height==flow.height && color.depth==1 && color.dim==dim);
17411 if (is_overlapping(flow)) return draw_quiver(+flow,color,sampling,factor,quiver_type,opacity,pattern);
17412
17413 float vmax,fact;
17414 if (factor<=0) {
17415 float m, M = (float)flow.get_norm_pointwise(2).maxmin(m);
17416 vmax = (float)cimg::max(cimg::abs(m),cimg::abs(M));
17417 fact = -factor;
17418 } else { fact = factor; vmax = 1; }
17419
17420 for (unsigned int y=sampling/2; y<height; y+=sampling)
17421 for (unsigned int x=sampling/2; x<width; x+=sampling) {
17422 const unsigned int X = x*flow.width/width, Y = y*flow.height/height;
17423 float u = (float)flow(X,Y,0,0)*fact/vmax, v = (float)flow(X,Y,0,1)*fact/vmax;
17424 if (!quiver_type) {
17425 const int xx = x+(int)u, yy = y+(int)v;
17426 if (colorfield) draw_arrow(x,y,xx,yy,color.get_vector_at(X,Y).data,45.0f,sampling/5.0f,opacity,pattern);
17427 else draw_arrow(x,y,xx,yy,color,45.0f,sampling/5.0f,opacity,pattern);
17428 } else {
17429 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);
17430 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);
17431 }
17432 }
17433 }
17434 return *this;
17435 }
17436
17438
17454 template<typename t, typename tc>
17455 CImg<T>& draw_graph(const CImg<t>& data, const tc *const color, const unsigned int gtype=1,
17456 const double ymin=0, const double ymax=0, const float opacity=1.0f,
17457 const unsigned int pattern=~0U) {
17458 if (!is_empty()) {
17459 if (!color) throw CImgArgumentException("CImg<%s>::draw_graph() : Specified color is (null)",pixel_type());
17460 tc *color1 = new tc[dim], *color2 = new tc[dim];
17461 cimg_forV(*this,k) { color1[k]=(tc)(color[k]*0.6f); color2[k]=(tc)(color[k]*0.3f); }
17462 float m = (float)ymin, M = (float)ymax;
17463 if (ymin==ymax) m = (float)data.maxmin(M);
17464 if (m==M) { --m; ++M; }
17465 const float ca = height>1?(float)(M-m)/(height-1):0;
17466 const int Y0 = (int)(-m/ca);
17467 int pY = 0;
17468 bool init_hatch = true;
17469 if (gtype<3) cimg_foroff(data,off) {
17470 const int Y = (int)((data[off]-m)/ca);
17471 switch (gtype) {
17472 case 0: {
17473 const unsigned int X = off*width/data.size();
17474 draw_point(X,Y,color,opacity);
17475 } break;
17476 case 1:
17477 if (off>0) {
17478 draw_line((int)((off-1)*width/data.size()),pY,(int)(off*width/data.size()),Y,color,opacity,pattern,init_hatch);
17479 init_hatch = false;
17480 }
17481 break;
17482 case 2: {
17483 const unsigned int X = off*width/data.size(), nX = (off+1)*width/data.size()-1;
17484 draw_rectangle(X,(int)Y0,nX,Y,color1,opacity);
17485 draw_line(X,Y,X,(int)Y0,color2,opacity);
17486 draw_line(X,(int)Y0,nX,(int)Y0,Y<=Y0?color2:color,opacity);
17487 draw_line(nX,Y,nX,(int)Y0,color,opacity);
17488 draw_line(X,Y,nX,Y,Y<=Y0?color:color2,opacity);
17489 } break;
17490 }
17491 pY = Y;
17492 } else {
17493 const CImg<t> ndata = data.get_shared_points(0,data.size()-1);
17494 cimg_forX(*this,x) {
17495 const int Y = (int)((ndata.cubic_pix1d((float)x*ndata.width/width)-m)/ca);
17496 if (x>0) draw_line(x,pY,x+1,Y,color,opacity,pattern,init_hatch);
17497 init_hatch = false;
17498 pY = Y;
17499 }
17500 }
17501 delete[] color1; delete[] color2;
17502 }
17503 return *this;
17504 }
17505
17506 template<typename t, typename tc>
17507 CImg<T>& draw_graph(const CImg<t>& data, const CImg<tc>& color, const unsigned int gtype=1,
17508 const double ymin=0, const double ymax=0, const float opacity=1.0f,
17509 const unsigned int pattern=~0U) {
17510 return draw_graph(data,color.data,gtype,ymin,ymax,opacity,pattern);
17511 }
17512
17514
17523 template<typename t, typename tc>
17524 CImg<T>& draw_axis(const CImg<t>& xvalues, const int y,
17525 const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U) {
17526 if (!is_empty()) {
17527 int siz = (int)xvalues.size()-1;
17528 if (siz<=0) draw_line(0,y,width-1,y,color,opacity,pattern);
17529 else {
17530 if (xvalues[0]<xvalues[siz]) draw_arrow(0,y,width-1,y,color,30,5,opacity,pattern);
17531 else draw_arrow(width-1,y,0,y,color,30,5,opacity,pattern);
17532 const int yt = (y+14)<dimy()?(y+3):(y-14);
17533 char txt[32];
17534 cimg_foroff(xvalues,x) {
17535 std::sprintf(txt,"%g",(double)xvalues(x));
17536 const int xi=(int)(x*(width-1)/siz), xt = xi-(int)std::strlen(txt)*3;
17537 draw_point(xi,y-1,color,opacity).draw_point(xi,y+1,color,opacity).
17538 draw_text(txt,xt<0?0:xt,yt,color,(tc*)0,11,opacity);
17539 }
17540 }
17541 }
17542 return *this;
17543 }
17544
17545 template<typename t, typename tc>
17546 CImg<T>& draw_axis(const CImg<t>& xvalues, const int y,
17547 const CImg<tc>& color, const float opacity=1.0f, const unsigned int pattern=~0U) {
17548 return draw_axis(xvalues,y,color.data,opacity,pattern);
17549 }
17550
17552 template<typename t, typename tc>
17553 CImg<T>& draw_axis(const int x, const CImg<t>& yvalues,
17554 const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U) {
17555 if (!is_empty()) {
17556 int siz = (int)yvalues.size()-1;
17557 if (siz<=0) draw_line(x,0,x,height-1,color,opacity,pattern);
17558 else {
17559 if (yvalues[0]<yvalues[siz]) draw_arrow(x,0,x,height-1,color,30,5,opacity,pattern);
17560 else draw_arrow(x,height-1,x,0,color,30,5,opacity,pattern);
17561 char txt[32];
17562 cimg_foroff(yvalues,y) {
17563 std::sprintf(txt,"%g",(double)yvalues(y));
17564 const int
17565 yi = (int)(y*(height-1)/siz),
17566 tmp = yi-5,
17567 nyi = tmp<0?0:(tmp>=dimy()-11?dimy()-11:tmp),
17568 xt = x-(int)std::strlen(txt)*7;
17569 draw_point(x-1,yi,color,opacity).draw_point(x+1,yi,color,opacity);
17570 if (xt>0) draw_text(txt,xt,nyi,color,(tc*)0,11,opacity);
17571 else draw_text(txt,x+3,nyi,color,(tc*)0,11,opacity);
17572 }
17573 }
17574 }
17575 return *this;
17576 }
17577
17578 template<typename t, typename tc>
17579 CImg<T>& draw_axis(const int x, const CImg<t>& yvalues,
17580 const CImg<tc>& color, const float opacity=1.0f, const unsigned int pattern=~0U) {
17581 return draw_axis(x,yvalues,color.data,opacity,pattern);
17582 }
17583
17585 template<typename tx, typename ty, typename tc>
17586 CImg<T>& draw_axis(const CImg<tx>& xvalues, const CImg<ty>& yvalues,
17587 const tc *const color,
17588 const float opacity=1.0f,
17589 const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17590 if (!is_empty()) {
17591 const CImg<tx> nxvalues(xvalues.data,xvalues.size(),1,1,1,true);
17592 const int sizx = (int)xvalues.size()-1, wm1 = (int)(width)-1;
17593 if (sizx>0) {
17594 float ox = (float)nxvalues[0];
17595 for (unsigned int x=1; x<width; ++x) {
17596 const float nx = (float)nxvalues.linear_pix1d((float)x*sizx/wm1);
17597 if (nx*ox<=0) { draw_axis(nx==0?x:x-1,yvalues,color,opacity,patterny); break; }
17598 ox = nx;
17599 }
17600 }
17601 const CImg<ty> nyvalues(yvalues.data,yvalues.size(),1,1,1,true);
17602 const int sizy = (int)yvalues.size()-1, hm1 = (int)(height)-1;
17603 if (sizy>0) {
17604 float oy = (float)nyvalues[0];
17605 for (unsigned int y=1; y<height; ++y) {
17606 const float ny = (float)nyvalues.linear_pix1d((float)y*sizy/hm1);
17607 if (ny*oy<=0) { draw_axis(xvalues,ny==0?y:y-1,color,opacity,patternx); break; }
17608 oy = ny;
17609 }
17610 }
17611 }
17612 return *this;
17613 }
17614
17615 template<typename tx, typename ty, typename tc>
17616 CImg<T>& draw_axis(const CImg<tx>& xvalues, const CImg<ty>& yvalues,
17617 const CImg<tc>& color,
17618 const float opacity=1.0f,
17619 const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17620 return draw_axis(xvalues,yvalues,color.data,opacity,patternx,patterny);
17621 }
17622
17624 template<typename tc>
17625 CImg<T>& draw_axis(const float x0, const float x1, const float y0, const float y1,
17626 const tc *const color,
17627 const int subdivisionx=-60, const int subdivisiony=-60,
17628 const float precisionx=0, const float precisiony=0,
17629 const float opacity=1.0f,
17630 const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17631 const float dx = cimg::abs(x1-x0), dy = cimg::abs(y1-y0);
17632 const float
17633 px = (precisionx==0)?(float)std::pow(10.0,(int)std::log10(dx)-2.0):precisionx,
17634 py = (precisiony==0)?(float)std::pow(10.0,(int)std::log10(dy)-2.0):precisiony;
17635 return draw_axis(CImg<float>::sequence(subdivisionx>0?subdivisionx:1-dimx()/subdivisionx,x0,x1).round(px),
17636 CImg<float>::sequence(subdivisiony>0?subdivisiony:1-dimy()/subdivisiony,y0,y1).round(py),
17637 color,opacity,patternx,patterny);
17638 }
17639
17640 template<typename tc>
17641 CImg<T>& draw_axis(const float x0, const float x1, const float y0, const float y1,
17642 const CImg<tc>& color,
17643 const int subdivisionx=-60, const int subdivisiony=-60,
17644 const float precisionx=0, const float precisiony=0,
17645 const float opacity=1.0f,
17646 const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17647 return draw_axis(x0,x1,y0,y1,color.data,subdivisionx,subdivisiony,precisionx,precisiony,opacity,patternx,patterny);
17648 }
17649
17651 template<typename tx, typename ty, typename tc>
17652 CImg<T>& draw_grid(const CImg<tx>& xvalues, const CImg<ty>& yvalues, const tc *const color,
17653 const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17654 if (!is_empty()) {
17655 if (xvalues) cimg_foroff(xvalues,x) {
17656 const int xi = (int)xvalues[x];
17657 if (xi>=0 && xi<dimx()) draw_line(xi,0,xi,height-1,color,opacity,patternx);
17658 }
17659 if (yvalues) cimg_foroff(yvalues,y) {
17660 const int yi = (int)yvalues[y];
17661 if (yi>=0 && yi<dimy()) draw_line(0,yi,width-1,yi,color,opacity,patterny);
17662 }
17663 }
17664 return *this;
17665 }
17666
17667 template<typename tx, typename ty, typename tc>
17668 CImg<T>& draw_grid(const CImg<tx>& xvalues, const CImg<ty>& yvalues, const CImg<tc>& color,
17669 const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17670 return draw_grid(xvalues,yvalues,color.data,opacity,patternx,patterny);
17671 }
17672
17674 template<typename tc>
17675 CImg<T>& draw_grid(const float deltax, const float deltay,
17676 const float offsetx, const float offsety,
17677 const bool invertx, const bool inverty,
17678 const tc *const color,
17679 const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17680 CImg<unsigned int> seqx, seqy;
17681 if (deltax!=0) {
17682 const float dx = deltax>0?deltax:width*-deltax/100;
17683 const unsigned int nx = (unsigned int)(width/dx);
17684 seqx = CImg<unsigned int>::sequence(1+nx,0,(unsigned int)(dx*nx));
17685 if (offsetx) cimg_foroff(seqx,x) seqx(x) = (unsigned int)cimg::mod(seqx(x)+offsetx,(float)width);
17686 if (invertx) cimg_foroff(seqx,x) seqx(x) = width-1-seqx(x);
17687 }
17688
17689 if (deltay!=0) {
17690 const float dy = deltay>0?deltay:height*-deltay/100;
17691 const unsigned int ny = (unsigned int)(height/dy);
17692 seqy = CImg<unsigned int>::sequence(1+ny,0,(unsigned int)(dy*ny));
17693 if (offsety) cimg_foroff(seqy,y) seqy(y) = (unsigned int)cimg::mod(seqy(y)+offsety,(float)height);
17694 if (inverty) cimg_foroff(seqy,y) seqy(y) = height-1-seqy(y);
17695 }
17696 return draw_grid(seqx,seqy,color,opacity,patternx,patterny);
17697 }
17698
17699 template<typename tc>
17700 CImg<T>& draw_grid(const float deltax, const float deltay,
17701 const float offsetx, const float offsety,
17702 const bool invertx, const bool inverty,
17703 const CImg<tc>& color,
17704 const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) {
17705 return draw_grid(deltax,deltay,offsetx,offsety,invertx,inverty,color.data,opacity,patternx,patterny);
17706 }
17707
17709
17720 template<typename tc, typename t>
17721 CImg<T>& draw_fill(const int x, const int y, const int z,
17722 const tc *const color, CImg<t>& region, const float sigma=0,
17723 const float opacity=1.0f, const bool high_connexity=false) {
17724
17725 #define _cimg_draw_fill_test(x,y,z,res) if (region(x,y,z)) res = false; else { \
17726 res = true; \
17727 const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(x,y,z) + siz; \
17728 for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } \
17729 region(x,y,z) = (t)(res?1:noregion); \
17730 }
17731
17732 #define _cimg_draw_fill_set(x,y,z) { \
17733 const tc *col = color; \
17734 T *ptrd = ptr(x,y,z); \
17735 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)*(col++); ptrd+=whz; } \
17736 else cimg_forV(*this,k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } \
17737 }
17738
17739 #define _cimg_draw_fill_insert(x,y,z) { \
17740 if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); \
17741 unsigned int *ptrr = remaining.ptr(0,posr1); \
17742 *(ptrr++) = x; *(ptrr++) = y; *(ptrr++) = z; ++posr1; \
17743 }
17744
17745 #define _cimg_draw_fill_test_neighbor(x,y,z,cond) if (cond) { \
17746 const unsigned int tx = x, ty = y, tz = z; \
17747 _cimg_draw_fill_test(tx,ty,tz,res); if (res) _cimg_draw_fill_insert(tx,ty,tz); \
17748 }
17749
17750 if (!color) throw CImgArgumentException("CImg<%s>::draw_fill() : Specified color is (null).",pixel_type());
17751 region.assign(width,height,depth,1,(t)0);
17752 if (x>=0 || x<dimx() || y>=0 || y<dimy() || z>=0 || z<dimz()) {
17753 typedef typename cimg::last<T,unsigned int>::type itype;
17754 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
17755 const unsigned int whz = width*height*depth, siz = dim*whz, W1 = width-1, H1 = height-1, D1 = depth-1;
17756 const bool threed = depth>1;
17757 const CImg<T> reference_color = get_vector_at(x,y,z);
17758 CImg<itype> remaining(3,512,1,1,0);
17759 remaining(0,0) = x; remaining(1,0) = y; remaining(2,0) = z;
17760 unsigned int posr0 = 0, posr1 = 1;
17761 region(x,y,z) = (t)1;
17762 const t noregion = ((t)1==(t)2)?(t)0:(t)(-1);
17763 if (threed) do {
17764 const unsigned int *pcurr = remaining.ptr(0,posr0++), xc = *(pcurr++), yc = *(pcurr++), zc = *(pcurr++);
17765 if (posr0>=512) { remaining.translate(0,posr0); posr1-=posr0; posr0 = 0; }
17766 bool cont, res;
17767 unsigned int nxc = xc;
17768 do {
17769 _cimg_draw_fill_set(nxc,yc,zc);
17770 _cimg_draw_fill_test_neighbor(nxc,yc-1,zc,yc!=0);
17771 _cimg_draw_fill_test_neighbor(nxc,yc+1,zc,yc<H1);
17772 _cimg_draw_fill_test_neighbor(nxc,yc,zc-1,zc!=0);
17773 _cimg_draw_fill_test_neighbor(nxc,yc,zc+1,zc<D1);
17774 if (nxc) { --nxc; _cimg_draw_fill_test(nxc,yc,zc,cont); } else cont = false;
17775 } while (cont);
17776 nxc = xc;
17777 do {
17778 if ((++nxc)<=W1) { _cimg_draw_fill_test(nxc,yc,zc,cont); } else cont = false;
17779 if (cont) {
17780 _cimg_draw_fill_set(nxc,yc,zc);
17781 _cimg_draw_fill_test_neighbor(nxc,yc-1,zc,yc!=0);
17782 _cimg_draw_fill_test_neighbor(nxc,yc+1,zc,yc<H1);
17783 _cimg_draw_fill_test_neighbor(nxc,yc,zc-1,zc!=0);
17784 _cimg_draw_fill_test_neighbor(nxc,yc,zc+1,zc<D1);
17785 }
17786 } while (cont);
17787 unsigned int nyc = yc;
17788 do {
17789 if (nyc) { --nyc; _cimg_draw_fill_test(xc,nyc,zc,cont); } else cont = false;
17790 if (cont) {
17791 _cimg_draw_fill_set(xc,nyc,zc);
17792 _cimg_draw_fill_test_neighbor(xc-1,nyc,zc,xc!=0);
17793 _cimg_draw_fill_test_neighbor(xc+1,nyc,zc,xc<W1);
17794 _cimg_draw_fill_test_neighbor(xc,nyc,zc-1,zc!=0);
17795 _cimg_draw_fill_test_neighbor(xc,nyc,zc+1,zc<D1);
17796 }
17797 } while (cont);
17798 nyc = yc;
17799 do {
17800 if ((++nyc)<=H1) { _cimg_draw_fill_test(xc,nyc,zc,cont); } else cont = false;
17801 if (cont) {
17802 _cimg_draw_fill_set(xc,nyc,zc);
17803 _cimg_draw_fill_test_neighbor(xc-1,nyc,zc,xc!=0);
17804 _cimg_draw_fill_test_neighbor(xc+1,nyc,zc,xc<W1);
17805 _cimg_draw_fill_test_neighbor(xc,nyc,zc-1,zc!=0);
17806 _cimg_draw_fill_test_neighbor(xc,nyc,zc+1,zc<D1);
17807 }
17808 } while (cont);
17809 unsigned int nzc = zc;
17810 do {
17811 if (nzc) { --nzc; _cimg_draw_fill_test(xc,yc,nzc,cont); } else cont = false;
17812 if (cont) {
17813 _cimg_draw_fill_set(xc,yc,nzc);
17814 _cimg_draw_fill_test_neighbor(xc-1,yc,nzc,xc!=0);
17815 _cimg_draw_fill_test_neighbor(xc+1,yc,nzc,xc<W1);
17816 _cimg_draw_fill_test_neighbor(xc,yc-1,nzc,yc!=0);
17817 _cimg_draw_fill_test_neighbor(xc,yc+1,nzc,yc<H1);
17818 }
17819 } while (cont);
17820 nzc = zc;
17821 do {
17822 if ((++nzc)<=D1) { _cimg_draw_fill_test(xc,yc,nzc,cont); } else cont = false;
17823 if (cont) {
17824 _cimg_draw_fill_set(xc,nyc,zc);
17825 _cimg_draw_fill_test_neighbor(xc-1,yc,nzc,xc!=0);
17826 _cimg_draw_fill_test_neighbor(xc+1,yc,nzc,xc<W1);
17827 _cimg_draw_fill_test_neighbor(xc,yc-1,nzc,yc!=0);
17828 _cimg_draw_fill_test_neighbor(xc,yc+1,nzc,yc<H1);
17829 }
17830 } while (cont);
17831 } while (posr1>posr0);
17832 else do {
17833 const unsigned int *pcurr = remaining.ptr(0,posr0++), xc = *(pcurr++), yc = *(pcurr++);
17834 if (posr0>=512) { remaining.translate(0,posr0); posr1-=posr0; posr0 = 0; }
17835 bool cont, res;
17836 unsigned int nxc = xc;
17837 do {
17838 _cimg_draw_fill_set(nxc,yc,0);
17839 _cimg_draw_fill_test_neighbor(nxc,yc-1,0,yc!=0);
17840 _cimg_draw_fill_test_neighbor(nxc,yc+1,0,yc<H1);
17841 if (high_connexity) {
17842 _cimg_draw_fill_test_neighbor(nxc-1,yc-1,0,(nxc!=0 && yc!=0));
17843 _cimg_draw_fill_test_neighbor(nxc+1,yc-1,0,(nxc<W1 && yc!=0));
17844 _cimg_draw_fill_test_neighbor(nxc-1,yc+1,0,(nxc!=0 && yc<H1));
17845 _cimg_draw_fill_test_neighbor(nxc+1,yc+1,0,(nxc<W1 && yc<H1));
17846 }
17847 if (nxc) { --nxc; _cimg_draw_fill_test(nxc,yc,0,cont); } else cont = false;
17848 } while (cont);
17849 nxc = xc;
17850 do {
17851 if ((++nxc)<=W1) { _cimg_draw_fill_test(nxc,yc,0,cont); } else cont = false;
17852 if (cont) {
17853 _cimg_draw_fill_set(nxc,yc,0);
17854 _cimg_draw_fill_test_neighbor(nxc,yc-1,0,yc!=0);
17855 _cimg_draw_fill_test_neighbor(nxc,yc+1,0,yc<H1);
17856 if (high_connexity) {
17857 _cimg_draw_fill_test_neighbor(nxc-1,yc-1,0,(nxc!=0 && yc!=0));
17858 _cimg_draw_fill_test_neighbor(nxc+1,yc-1,0,(nxc<W1 && yc!=0));
17859 _cimg_draw_fill_test_neighbor(nxc-1,yc+1,0,(nxc!=0 && yc<H1));
17860 _cimg_draw_fill_test_neighbor(nxc+1,yc+1,0,(nxc<W1 && yc<H1));
17861 }
17862 }
17863 } while (cont);
17864 unsigned int nyc = yc;
17865 do {
17866 if (nyc) { --nyc; _cimg_draw_fill_test(xc,nyc,0,cont); } else cont = false;
17867 if (cont) {
17868 _cimg_draw_fill_set(xc,nyc,0);
17869 _cimg_draw_fill_test_neighbor(xc-1,nyc,0,xc!=0);
17870 _cimg_draw_fill_test_neighbor(xc+1,nyc,0,xc<W1);
17871 if (high_connexity) {
17872 _cimg_draw_fill_test_neighbor(xc-1,nyc-1,0,(xc!=0 && nyc!=0));
17873 _cimg_draw_fill_test_neighbor(xc+1,nyc-1,0,(xc<W1 && nyc!=0));
17874 _cimg_draw_fill_test_neighbor(xc-1,nyc+1,0,(xc!=0 && nyc<H1));
17875 _cimg_draw_fill_test_neighbor(xc+1,nyc+1,0,(xc<W1 && nyc<H1));
17876 }
17877 }
17878 } while (cont);
17879 nyc = yc;
17880 do {
17881 if ((++nyc)<=H1) { _cimg_draw_fill_test(xc,nyc,0,cont); } else cont = false;
17882 if (cont) {
17883 _cimg_draw_fill_set(xc,nyc,0);
17884 _cimg_draw_fill_test_neighbor(xc-1,nyc,0,xc!=0);
17885 _cimg_draw_fill_test_neighbor(xc+1,nyc,0,xc<W1);
17886 if (high_connexity) {
17887 _cimg_draw_fill_test_neighbor(xc-1,nyc-1,0,(xc!=0 && nyc!=0));
17888 _cimg_draw_fill_test_neighbor(xc+1,nyc-1,0,(xc<W1 && nyc!=0));
17889 _cimg_draw_fill_test_neighbor(xc-1,nyc+1,0,(xc!=0 && nyc<H1));
17890 _cimg_draw_fill_test_neighbor(xc+1,nyc+1,0,(xc<W1 && nyc<H1));
17891 }
17892 }
17893 } while (cont);
17894 } while (posr1>posr0);
17895 if (noregion) cimg_for(region,ptr,t) if (*ptr==noregion) *ptr = (t)0;
17896 }
17897 return *this;
17898 }
17899
17900 template<typename tc, typename t>
17901 CImg<T>& draw_fill(const int x, const int y, const int z,
17902 const CImg<tc>& color, CImg<t>& region, const float sigma=0,
17903 const float opacity=1.0f, const bool high_connexity=false) {
17904 return draw_fill(x,y,z,color.data,region,sigma,opacity,high_connexity);
17905 }
17906
17908
17916 template<typename tc>
17917 CImg<T>& draw_fill(const int x, const int y, const int z, const tc *const color, const float sigma=0,
17918 const float opacity=1.0f, const bool high_connexity=false) {
17919 CImg<bool> tmp;
17920 return draw_fill(x,y,z,color,tmp,sigma,opacity,high_connexity);
17921 }
17922
17923 template<typename tc>
17924 CImg<T>& draw_fill(const int x, const int y, const int z, const CImg<tc>& color, const float sigma=0,
17925 const float opacity=1.0f, const bool high_connexity=false) {
17926 return draw_fill(x,y,z,color.data,sigma,opacity,high_connexity);
17927 }
17928
17930
17937 template<typename tc>
17938 CImg<T>& draw_fill(const int x, const int y, const tc *const color, const float sigma=0,
17939 const float opacity=1.0f, const bool high_connexity=false) {
17940 CImg<bool> tmp;
17941 return draw_fill(x,y,0,color,tmp,sigma,opacity,high_connexity);
17942 }
17943
17944 template<typename tc>
17945 CImg<T>& draw_fill(const int x, const int y, const CImg<tc>& color, const float sigma=0,
17946 const float opacity=1.0f, const bool high_connexity=false) {
17947 return draw_fill(x,y,color.data,sigma,opacity,high_connexity);
17948 }
17949
17951
17960 CImg<T>& draw_plasma(const int x0, const int y0, const int x1, const int y1,
17961 const double alpha=1.0, const double beta=1.0, const float opacity=1.0f) {
17962 if (!is_empty()) {
17963 typedef typename cimg::superset<T,float>::type ftype;
17964 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
17965 int nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1;
17966 if (nx1<nx0) cimg::swap(nx0,nx1);
17967 if (ny1<ny0) cimg::swap(ny0,ny1);
17968 if (nx0<0) nx0 = 0;
17969 if (nx1>=dimx()) nx1 = width-1;
17970 if (ny0<0) ny0 = 0;
17971 if (ny1>=dimy()) ny1 = height-1;
17972 const int xc = (nx0+nx1)/2, yc = (ny0+ny1)/2, dx = (xc-nx0), dy = (yc-ny0);
17973 const ftype dc = (ftype)(std::sqrt((double)(dx*dx+dy*dy))*alpha + beta);
17974 ftype val = 0;
17975 cimg_forV(*this,k) {
17976 if (opacity>=1) {
17977 const ftype
17978 val0 = (*this)(nx0,ny0,0,k), val1 = (*this)(nx1,ny0,0,k),
17979 val2 = (*this)(nx0,ny1,0,k), val3 = (*this)(nx1,ny1,0,k);
17980 (*this)(xc,ny0,0,k) = (T)((val0+val1)/2);
17981 (*this)(xc,ny1,0,k) = (T)((val2+val3)/2);
17982 (*this)(nx0,yc,0,k) = (T)((val0+val2)/2);
17983 (*this)(nx1,yc,0,k) = (T)((val1+val3)/2);
17984 do {
17985 val = (ftype)(0.25f*((ftype)((*this)(nx0,ny0,0,k)) +
17986 (ftype)((*this)(nx1,ny0,0,k)) +
17987 (ftype)((*this)(nx1,ny1,0,k)) +
17988 (ftype)((*this)(nx0,ny1,0,k))) +
17989 dc*cimg::grand());
17990 } while (val<(ftype)cimg::type<T>::min() || val>(ftype)cimg::type<T>::max());
17991 (*this)(xc,yc,0,k) = (T)val;
17992 } else {
17993 const ftype
17994 val0 = (*this)(nx0,ny0,0,k), val1 = (*this)(nx1,ny0,0,k),
17995 val2 = (*this)(nx0,ny1,0,k), val3 = (*this)(nx1,ny1,0,k);
17996 (*this)(xc,ny0,0,k) = (T)(((val0+val1)*nopacity + copacity*(*this)(xc,ny0,0,k))/2);
17997 (*this)(xc,ny1,0,k) = (T)(((val2+val3)*nopacity + copacity*(*this)(xc,ny1,0,k))/2);
17998 (*this)(nx0,yc,0,k) = (T)(((val0+val2)*nopacity + copacity*(*this)(nx0,yc,0,k))/2);
17999 (*this)(nx1,yc,0,k) = (T)(((val1+val3)*nopacity + copacity*(*this)(nx1,yc,0,k))/2);
18000 do {
18001 val = (ftype)(0.25f*(((ftype)((*this)(nx0,ny0,0,k)) +
18002 (ftype)((*this)(nx1,ny0,0,k)) +
18003 (ftype)((*this)(nx1,ny1,0,k)) +
18004 (ftype)((*this)(nx0,ny1,0,k))) +
18005 dc*cimg::grand())*nopacity + copacity*(*this)(xc,yc,0,k));
18006 } while (val<(ftype)cimg::type<T>::min() || val>(ftype)cimg::type<T>::max());
18007 (*this)(xc,yc,0,k) = (T)val;
18008 }
18009 }
18010 if (xc!=nx0 || yc!=ny0) {
18011 draw_plasma(nx0,ny0,xc,yc,alpha,beta,opacity);
18012 draw_plasma(xc,ny0,nx1,yc,alpha,beta,opacity);
18013 draw_plasma(nx0,yc,xc,ny1,alpha,beta,opacity);
18014 draw_plasma(xc,yc,nx1,ny1,alpha,beta,opacity);
18015 }
18016 }
18017 return *this;
18018 }
18019
18021
18026 CImg<T>& draw_plasma(const double alpha=1.0, const double beta=1.0, const float opacity=1.0f) {
18027 return draw_plasma(0,0,width-1,height-1,alpha,beta,opacity);
18028 }
18029
18031
18037 template<typename tc>
18038 CImg<T>& draw_gaussian(const float xc, const double sigma, const tc *const color, const float opacity=1.0f) {
18039 if (!is_empty()) {
18040 if (!color) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Specified color is (null)",pixel_type());
18041 const double sigma2 = 2*sigma*sigma;
18042 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
18043 const unsigned int whz = width*height*depth;
18044 const tc *col = color;
18045 cimg_forX(*this,x) {
18046 const float dx = (x-xc);
18047 const double val = std::exp( -dx*dx/sigma2 );
18048 T *ptrd = ptr(x,0,0,0);
18049 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; }
18050 else cimg_forV(*this,k) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whz; }
18051 col-=dim;
18052 }
18053 }
18054 return *this;
18055 }
18056
18057 template<typename tc>
18058 CImg<T>& draw_gaussian(const float xc, const double sigma, const CImg<tc>& color, const float opacity=1.0f) {
18059 return draw_gaussian(xc,sigma,color.data,opacity);
18060 }
18061
18063
18070 template<typename t, typename tc>
18071 CImg<T>& draw_gaussian(const float xc, const float yc, const CImg<t>& tensor,
18072 const tc *const color, const float opacity=1.0f) {
18073 typedef typename cimg::superset<t,float>::type ftype;
18074 if (!is_empty()) {
18075 if (tensor.width!=2 || tensor.height!=2 || tensor.depth!=1 || tensor.dim!=1)
18076 throw CImgArgumentException("CImg<%s>::draw_gaussian() : Tensor parameter (%u,%u,%u,%u,%p) is not a 2x2 matrix.",
18077 pixel_type(),tensor.width,tensor.height,tensor.depth,tensor.dim,tensor.data);
18078 if (!color) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Specified color is (null)",pixel_type());
18079 const CImg<ftype> invT = tensor.get_inverse(), invT2 = (invT*invT)/(-2.0);
18080 const ftype a = invT2(0,0), b = 2*invT2(1,0), c = invT2(1,1);
18081 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
18082 const unsigned int whz = width*height*depth;
18083 const tc *col = color;
18084 float dy = -yc;
18085 cimg_forY(*this,y) {
18086 float dx = -xc;
18087 cimg_forX(*this,x) {
18088 const float val = (float)std::exp(a*dx*dx + b*dx*dy + c*dy*dy);
18089 T *ptrd = ptr(x,y,0,0);
18090 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; }
18091 else cimg_forV(*this,k) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whz; }
18092 col-=dim;
18093 ++dx;
18094 }
18095 ++dy;
18096 }
18097 }
18098 return *this;
18099 }
18100
18101 template<typename t, typename tc>
18102 CImg<T>& draw_gaussian(const float xc, const float yc, const CImg<t>& tensor,
18103 const CImg<tc>& color, const float opacity=1.0f) {
18104 return draw_gaussian(xc,yc,tensor,color.data,opacity);
18105 }
18106
18108
18115 template<typename tc>
18116 CImg<T>& draw_gaussian(const float xc, const float yc, const float sigma, const tc *const color, const float opacity=1.0f) {
18117 return draw_gaussian(xc,yc,CImg<float>::diagonal(sigma,sigma),color,opacity);
18118 }
18119
18120 template<typename tc>
18121 CImg<T>& draw_gaussian(const float xc, const float yc, const float sigma, const CImg<tc>& color, const float opacity=1.0f) {
18122 return draw_gaussian(xc,yc,sigma,color.data,opacity);
18123 }
18124
18126
18134 template<typename t, typename tc>
18135 CImg<T>& draw_gaussian(const float xc, const float yc, const float zc, const CImg<t>& tensor,
18136 const tc *const color, const float opacity=1.0f) {
18137 if (!is_empty()) {
18138 if (tensor.width!=3 || tensor.height!=3 || tensor.depth!=1 || tensor.dim!=1)
18139 throw CImgArgumentException("CImg<%s>::draw_gaussian() : Tensor parameter (%u,%u,%u,%u,%p) is not a 3x3 matrix.",
18140 pixel_type(),tensor.width,tensor.height,tensor.depth,tensor.dim,tensor.data);
18141 const CImg<t> invT = tensor.get_inverse(), invT2 = (invT*invT)/(-2.0);
18142 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);
18143 const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
18144 const unsigned int whz = width*height*depth;
18145 const tc *col = color;
18146 cimg_forXYZ(*this,x,y,z) {
18147 const float dx = (x-xc), dy = (y-yc), dz = (z-zc);
18148 const double val = std::exp(a*dx*dx + b*dx*dy + c*dx*dz + d*dy*dy + e*dy*dz + f*dz*dz);
18149 T *ptrd = ptr(x,y,z,0);
18150 if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; }
18151 else cimg_forV(*this,k) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whz; }
18152 col-=dim;
18153 }
18154 }
18155 return *this;
18156 }
18157
18158 template<typename t, typename tc>
18159 CImg<T>& draw_gaussian(const float xc, const float yc, const float zc, const CImg<t>& tensor,
18160 const CImg<tc>& color, const float opacity=1.0f) {
18161 return draw_gaussian(xc,yc,zc,tensor,color.data,opacity);
18162 }
18163
18165
18173 template<typename tc>
18174 CImg<T>& draw_gaussian(const float xc, const float yc, const float zc,
18175 const double sigma, const tc *const color, const float opacity=1.0f) {
18176 return draw_gaussian(xc,yc,zc,CImg<float>::diagonal(sigma,sigma,sigma),color,opacity);
18177 }
18178
18179 template<typename tc>
18180 CImg<T>& draw_gaussian(const float xc, const float yc, const float zc,
18181 const double sigma, const CImg<tc>& color, const float opacity=1.0f) {
18182 return draw_gaussian(xc,yc,zc,sigma,color.data,opacity);
18183 }
18184
18186
18202 template<typename tp, typename tf, typename tc, typename to>
18203 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18204 const CImg<tp>& points, const CImgList<tf>& primitives,
18205 const CImgList<tc>& colors, const CImgList<to>& opacities,
18206 const unsigned int render_type=4,
18207 const bool double_sided=false, const float focale=500,
18208 const float lightx=0, const float lighty=0, const float lightz=-5000,
18209 const float ambient_light=0.05f) {
18210
18211 static CImg<float> light_texture;
18212 if (is_empty() || !points || !primitives) return *this;
18213 if (!colors || !opacities)
18214 throw CImgArgumentException("CImg<%s>::draw_object3d() : Undefined colors or opacities",pixel_type());
18215
18216 if (points.height<3)
18217 return draw_object3d(X,Y,Z,points.get_resize(-100,3,1,1,0),primitives,colors,opacities,
18218 render_type,double_sided,focale,lightx,lighty,lightz,ambient_light);
18219
18220
18221 if (render_type==5) {
18222 if (colors.size>primitives.size) light_texture.assign(colors[primitives.size])/=255;
18223 else {
18224 static float olightx = 0, olighty = 0, olightz = 0, oambient_light = 0;
18225 if (!light_texture || lightx!=olightx || lighty!=olighty || lightz!=olightz || ambient_light!=oambient_light) {
18226 light_texture.assign(512,512);
18227 const float white[] = { 1.0f },
18228 dlx = lightx-X, dly = lighty-Y, dlz = lightz-Z,
18229 nl = (float)std::sqrt(dlx*dlx+dly*dly+dlz*dlz),
18230 nlx = light_texture.width/2*(1+dlx/nl),
18231 nly = light_texture.height/2*(1+dly/nl);
18232 (light_texture.draw_gaussian(nlx,nly,light_texture.width/3.0f,white)+=ambient_light);
18233 olightx = lightx; olighty = lighty; olightz = lightz; oambient_light = ambient_light;
18234 }
18235 }
18236 }
18237
18238
18239 CImg<float> projections(points.width,2);
18240 cimg_forX(points,l) {
18241 const float
18242 x = (float)points(l,0),
18243 y = (float)points(l,1),
18244 z = (float)points(l,2);
18245 const float projectedz = z + Z + focale;
18246 projections(l,1) = Y + focale*y/projectedz;
18247 projections(l,0) = X + focale*x/projectedz;
18248 }
18249
18250
18251 CImg<unsigned int> visibles(primitives.size);
18252 CImg<float> zrange(primitives.size);
18253 unsigned int nb_visibles = 0;
18254 const float zmin = -focale+1.5f;
18255 { cimglist_for(primitives,l) {
18256 const CImg<tf>& primitive = primitives[l];
18257 switch (primitive.size()) {
18258
18259 case 1: {
18260 const unsigned int i0 = (unsigned int)primitive(0);
18261 const float x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2));
18262 if (z0>zmin && x0>=0 && x0<width && y0>=0 && y0<height) {
18263 visibles(nb_visibles) = (unsigned int)l;
18264 zrange(nb_visibles++) = z0;
18265 }
18266 } break;
18267 case 5: {
18268 const unsigned int
18269 i0 = (unsigned int)primitive(0),
18270 i1 = (unsigned int)primitive(1),
18271 i2 = (unsigned int)primitive(2);
18272 const float x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2));
18273 int radius;
18274 if (i2) radius = (int)(i2*focale/(z0+focale));
18275 else {
18276 const float x1 = projections(i1,0), y1 = projections(i1,1);
18277 const int deltax = (int)(x1-x0), deltay = (int)(y1-y0);
18278 radius = (int)std::sqrt((float)(deltax*deltax + deltay*deltay));
18279 }
18280 if (z0>zmin && x0+radius>=0 && x0-radius<width && y0+radius>=0 && y0-radius<height) {
18281 visibles(nb_visibles) = (unsigned int)l;
18282 zrange(nb_visibles++) = z0;
18283 }
18284 } break;
18285 case 2:
18286 case 6: {
18287 const unsigned int
18288 i0 = (unsigned int)primitive(0),
18289 i1 = (unsigned int)primitive(1);
18290 const float
18291 x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)),
18292 x1 = projections(i1,0), y1 = projections(i1,1), z1 = (float)(Z+points(i1,2));
18293 float xm, xM, ym, yM;
18294 if (x0<x1) { xm = x0; xM = x1; } else { xm = x1; xM = x0; }
18295 if (y0<y1) { ym = y0; yM = y1; } else { ym = y1; yM = y0; }
18296 if (z0>zmin && z1>zmin && xM>=0 && xm<width && yM>=0 && ym<height) {
18297 visibles(nb_visibles) = (unsigned int)l;
18298 zrange(nb_visibles++) = 0.5f*(z0+z1);
18299 }
18300 } break;
18301 case 3:
18302 case 9: {
18303 const unsigned int
18304 i0 = (unsigned int)primitive(0),
18305 i1 = (unsigned int)primitive(1),
18306 i2 = (unsigned int)primitive(2);
18307 const float
18308 x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)),
18309 x1 = projections(i1,0), y1 = projections(i1,1), z1 = (float)(Z+points(i1,2)),
18310 x2 = projections(i2,0), y2 = projections(i2,1), z2 = (float)(Z+points(i2,2));
18311 float xm, xM, ym, yM;
18312 if (x0<x1) { xm = x0; xM = x1; } else { xm = x1; xM = x0; }
18313 if (x2<xm) xm = x2;
18314 if (x2>xM) xM = x2;
18315 if (y0<y1) { ym = y0; yM = y1; } else { ym = y1; yM = y0; }
18316 if (y2<ym) ym = y2;
18317 if (y2>yM) yM = y2;
18318 if (z0>zmin && z1>zmin && z2>zmin && xM>=0 && xm<width && yM>=0 && ym<height) {
18319 const float d = (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
18320 if (double_sided || d<0) {
18321 visibles(nb_visibles) = (unsigned int)l;
18322 zrange(nb_visibles++) = (z0+z1+z2)/3;
18323 }
18324 }
18325 } break;
18326 case 4:
18327 case 12: {
18328 const unsigned int
18329 i0 = (unsigned int)primitive(0),
18330 i1 = (unsigned int)primitive(1),
18331 i2 = (unsigned int)primitive(2),
18332 i3 = (unsigned int)primitive(3);
18333 const float
18334 x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)),
18335 x1 = projections(i1,0), y1 = projections(i1,1), z1 = (float)(Z+points(i1,2)),
18336 x2 = projections(i2,0), y2 = projections(i2,1), z2 = (float)(Z+points(i2,2)),
18337 x3 = projections(i3,0), y3 = projections(i3,1), z3 = (float)(Z+points(i3,2));
18338 float xm, xM, ym, yM;
18339 if (x0<x1) { xm = x0; xM = x1; } else { xm = x1; xM = x0; }
18340 if (x2<xm) xm = x2;
18341 if (x2>xM) xM = x2;
18342 if (x3<xm) xm = x3;
18343 if (x3>xM) xM = x3;
18344 if (y0<y1) { ym = y0; yM = y1; } else { ym = y1; yM = y0; }
18345 if (y2<ym) ym = y2;
18346 if (y2>yM) yM = y2;
18347 if (y3<ym) ym = y3;
18348 if (y3>yM) yM = y3;
18349 if (z0>zmin && z1>zmin && z2>zmin && z3>zmin && xM>=0 && xm<width && yM>=0 && ym<height) {
18350 const float d = (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
18351 if (double_sided || d<0) {
18352 visibles(nb_visibles) = (unsigned int)l;
18353 zrange(nb_visibles++) = (z0+z1+z2+z3)/4;
18354 }
18355 }
18356 } break;
18357 default:
18358 throw CImgArgumentException("CImg<%s>::draw_object3d() : Primitive %u is invalid (size = %u, can be 1,2,3,4,5,6,9 or 12)",
18359 pixel_type(),l,primitive.size());
18360 }}
18361 }
18362 if (nb_visibles<=0) return *this;
18363 CImg<unsigned int> permutations;
18364 CImg<float>(zrange.data,nb_visibles,1,1,1,true).sort(permutations,false);
18365
18366
18367 CImg<float> lightprops;
18368 switch (render_type) {
18369 case 3: {
18370 lightprops.assign(nb_visibles);
18371 cimg_forX(lightprops,l) {
18372 const CImg<tf>& primitive = primitives(visibles(permutations(l)));
18373 const unsigned int psize = primitive.size();
18374 if (psize==3 || psize==4 || psize==9 || psize==12) {
18375 const unsigned int
18376 i0 = (unsigned int)primitive(0),
18377 i1 = (unsigned int)primitive(1),
18378 i2 = (unsigned int)primitive(2);
18379 const float
18380 x0 = (float)points(i0,0), y0 = (float)points(i0,1), z0 = (float)points(i0,2),
18381 x1 = (float)points(i1,0), y1 = (float)points(i1,1), z1 = (float)points(i1,2),
18382 x2 = (float)points(i2,0), y2 = (float)points(i2,1), z2 = (float)points(i2,2),
18383 dx1 = x1-x0, dy1 = y1-y0, dz1 = z1-z0,
18384 dx2 = x2-x0, dy2 = y2-y0, dz2 = z2-z0,
18385 nx = dy1*dz2-dz1*dy2,
18386 ny = dz1*dx2-dx1*dz2,
18387 nz = dx1*dy2-dy1*dx2,
18388 norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
18389 lx = X+(x0+x1+x2)/3-lightx,
18390 ly = Y+(y0+y1+y2)/3-lighty,
18391 lz = Z+(z0+z1+z2)/3-lightz,
18392 nl = (float)std::sqrt(1e-5f+lx*lx+ly*ly+lz*lz),
18393 factor = cimg::abs(-lx*nx-ly*ny-lz*nz)/(norm*nl);
18394 lightprops[l] = cimg::max(factor,0.0f) + ambient_light;
18395 } else lightprops[l] = 1.0f;
18396 }
18397 } break;
18398
18399 case 4:
18400 case 5: {
18401 CImg<float> points_normals(points.width,double_sided?7:3,1,1,0);
18402 for (unsigned int l=0; l<nb_visibles; ++l) {
18403 const CImg<tf>& primitive = primitives[visibles(l)];
18404 const unsigned int psize = primitive.size();
18405 const bool
18406 triangle_flag = (psize==3) || (psize==9),
18407 rectangle_flag = (psize==4) || (psize==12);
18408 if (triangle_flag || rectangle_flag) {
18409 const unsigned int
18410 i0 = (unsigned int)primitive(0),
18411 i1 = (unsigned int)primitive(1),
18412 i2 = (unsigned int)primitive(2),
18413 i3 = rectangle_flag?(unsigned int)primitive(3):0;
18414 const float
18415 x0 = (float)points(i0,0), y0 = (float)points(i0,1), z0 = (float)points(i0,2),
18416 x1 = (float)points(i1,0), y1 = (float)points(i1,1), z1 = (float)points(i1,2),
18417 x2 = (float)points(i2,0), y2 = (float)points(i2,1), z2 = (float)points(i2,2),
18418 dx1 = x1-x0, dy1 = y1-y0, dz1 = z1-z0,
18419 dx2 = x2-x0, dy2 = y2-y0, dz2 = z2-z0,
18420 nnx = dy1*dz2-dz1*dy2,
18421 nny = dz1*dx2-dx1*dz2,
18422 nnz = dx1*dy2-dy1*dx2,
18423 norm = 1e-5f + (float)std::sqrt(nnx*nnx+nny*nny+nnz*nnz),
18424 nx = nnx/norm,
18425 ny = nny/norm,
18426 nz = nnz/norm;
18427 if (double_sided) {
18428 unsigned int ind = nz>0?3U:0U;
18429 const float incr = nz>0?-1.0f:1.0f;
18430 points_normals(i0, ind)+=nx; points_normals(i1,ind)+=nx; points_normals(i2,ind)+=nx;
18431 points_normals(i0,++ind)+=ny; points_normals(i1,ind)+=ny; points_normals(i2,ind)+=ny;
18432 points_normals(i0,++ind)+=nz; points_normals(i1,ind)+=nz; points_normals(i2,ind)+=nz;
18433 points_normals(i0,6)+=incr; points_normals(i1,6)+=incr; points_normals(i2,6)+=incr;
18434 if (rectangle_flag) {
18435 points_normals(i3,ind)+=nz; points_normals(i3,--ind)+=ny; points_normals(i3,--ind)+=nz; points_normals(i3,6)+=incr;
18436 }
18437 } else {
18438 points_normals(i0,0)+=nx; points_normals(i0,1)+=ny; points_normals(i0,2)+=nz;
18439 points_normals(i1,0)+=nx; points_normals(i1,1)+=ny; points_normals(i1,2)+=nz;
18440 points_normals(i2,0)+=nx; points_normals(i2,1)+=ny; points_normals(i2,2)+=nz;
18441 if (rectangle_flag) { points_normals(i3,0)+=nx; points_normals(i3,1)+=ny; points_normals(i3,2)+=nz; }
18442 }
18443 }
18444 }
18445
18446 if (double_sided) cimg_forX(points_normals,l) if (points_normals(l,6)<0) {
18447 points_normals(l,0) = -points_normals(l,3);
18448 points_normals(l,1) = -points_normals(l,4);
18449 points_normals(l,2) = -points_normals(l,5);
18450 }
18451
18452 if (render_type==4) {
18453 lightprops.assign(points.width);
18454 cimg_forX(points,ll) {
18455 const float
18456 nx = points_normals(ll,0),
18457 ny = points_normals(ll,1),
18458 nz = points_normals(ll,2),
18459 norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
18460 lx = (float)(X+points(ll,0)-lightx),
18461 ly = (float)(Y+points(ll,1)-lighty),
18462 lz = (float)(Z+points(ll,2)-lightz),
18463 nl = (float)std::sqrt(1e-5f+lx*lx+ly*ly+lz*lz),
18464 factor = (-lx*nx-ly*ny-lz*nz)/(norm*nl);
18465 lightprops[ll] = cimg::max(factor,0.0f) + ambient_light;
18466 }
18467 } else {
18468 const unsigned int
18469 lw2 = light_texture.width/2-1,
18470 lh2 = light_texture.height/2-1;
18471 lightprops.assign(points.width,2);
18472 cimg_forX(points,ll) {
18473 const float
18474 nx = points_normals(ll,0),
18475 ny = points_normals(ll,1),
18476 nz = points_normals(ll,2),
18477 norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
18478 nnx = nx/norm,
18479 nny = ny/norm;
18480 lightprops(ll,0) = lw2*(1+nnx);
18481 lightprops(ll,1) = lh2*(1+nny);
18482 }
18483 }
18484 } break;
18485 }
18486
18487
18488 const unsigned int opacsize = opacities.size;
18489 { for (unsigned int l=0; l<nb_visibles; ++l) {
18490 const unsigned int n_primitive = visibles(permutations(l));
18491 const CImg<tf>& primitive = primitives[n_primitive];
18492 const CImg<tc>& color = colors[n_primitive%colors.size];
18493 const CImg<to>& opacity = opacities[n_primitive%opacsize];
18494 const float opac = opacity.size()?(float)opacity(0):1.0f;
18495
18496 switch (primitive.size()) {
18497 case 1: {
18498 const unsigned int n0 = (unsigned int)primitive[0];
18499 const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1);
18500 if (color.size()==dim) draw_point(x0,y0,color,opac);
18501 else {
18502 const float z = Z + points(n0,2);
18503 const int
18504 factor = (int)(focale*100/(z+focale)),
18505 sw = color.width*factor/200,
18506 sh = color.height*factor/200;
18507 if (x0+sw>=0 && x0-sw<dimx() && y0+sh>=0 && y0-sh<dimy()) {
18508 const CImg<T> sprite = color.get_resize(-factor,-factor,1,-100,render_type<=3?1:3);
18509 if (opacity.width==color.width && opacity.height==color.height)
18510 draw_image(sprite,opacity.get_resize(sprite.width,sprite.height,1,sprite.dim,1),x0-sw,y0-sh,0,0);
18511 else draw_image(sprite,x0-sw,y0-sh,0,0,opac);
18512 }
18513 }
18514 } break;
18515 case 2: {
18516 const unsigned int
18517 n0 = (unsigned int)primitive[0],
18518 n1 = (unsigned int)primitive[1];
18519 const int
18520 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18521 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1);
18522 if (render_type) draw_line(x0,y0,x1,y1,color,opac);
18523 else draw_point(x0,y0,color,opac).draw_point(x1,y1,color,opac);
18524 } break;
18525 case 5: {
18526 const unsigned int
18527 n0 = (unsigned int)primitive[0],
18528 n1 = (unsigned int)primitive[1],
18529 n2 = (unsigned int)primitive[2];
18530 const int
18531 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1);
18532 int radius;
18533 if (n2) radius = (int)(n2*focale/(Z+points(n0,2)+focale));
18534 else {
18535 const int
18536 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18537 deltax = x1-x0, deltay = y1-y0;
18538 radius = (int)std::sqrt((float)(deltax*deltax + deltay*deltay));
18539 }
18540 switch (render_type) {
18541 case 0:
18542 draw_point(x0,y0,color,opac);
18543 break;
18544 case 1:
18545 draw_circle(x0,y0,radius,color,opac,~0U);
18546 break;
18547 default:
18548 draw_circle(x0,y0,radius,color,opac);
18549 break;
18550 }
18551 } break;
18552 case 6: {
18553 const unsigned int
18554 n0 = (unsigned int)primitive[0],
18555 n1 = (unsigned int)primitive[1],
18556 tx0 = (unsigned int)primitive[2],
18557 ty0 = (unsigned int)primitive[3],
18558 tx1 = (unsigned int)primitive[4],
18559 ty1 = (unsigned int)primitive[5];
18560 const int
18561 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18562 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1);
18563 const float
18564 z0 = points(n0,2) + Z + focale,
18565 z1 = points(n1,2) + Z + focale;
18566 if (render_type) draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac);
18567 else draw_point(x0,y0,color.get_vector_at(tx0,ty0),opac).
18568 draw_point(x1,y1,color.get_vector_at(tx1,ty1),opac);
18569 } break;
18570 case 3: {
18571 const unsigned int
18572 n0 = (unsigned int)primitive[0],
18573 n1 = (unsigned int)primitive[1],
18574 n2 = (unsigned int)primitive[2];
18575 const int
18576 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18577 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18578 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1);
18579 switch(render_type) {
18580 case 0:
18581 draw_point(x0,y0,color,opac).draw_point(x1,y1,color,opac).draw_point(x2,y2,color,opac);
18582 break;
18583 case 1:
18584 draw_line(x0,y0,x1,y1,color,opac).draw_line(x0,y0,x2,y2,color,opac).
18585 draw_line(x1,y1,x2,y2,color,opac);
18586 break;
18587 case 2:
18588 draw_triangle(x0,y0,x1,y1,x2,y2,color,opac);
18589 break;
18590 case 3:
18591 _draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opac,lightprops(l));
18592 break;
18593 case 4:
18594 draw_triangle(x0,y0,x1,y1,x2,y2,color,lightprops(n0),lightprops(n1),lightprops(n2),opac);
18595 break;
18596 case 5:
18597 const unsigned int
18598 lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1),
18599 lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1),
18600 lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1);
18601 draw_triangle(x0,y0,x1,y1,x2,y2,color,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac);
18602 break;
18603 }
18604 } break;
18605 case 4: {
18606 const unsigned int
18607 n0 = (unsigned int)primitive[0],
18608 n1 = (unsigned int)primitive[1],
18609 n2 = (unsigned int)primitive[2],
18610 n3 = (unsigned int)primitive[3];
18611 const int
18612 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18613 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18614 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1),
18615 x3 = (int)projections(n3,0), y3 = (int)projections(n3,1);
18616 switch(render_type) {
18617 case 0:
18618 draw_point(x0,y0,color,opac).draw_point(x1,y1,color,opac).
18619 draw_point(x2,y2,color,opac).draw_point(x3,y3,color,opac);
18620 break;
18621 case 1:
18622 draw_line(x0,y0,x1,y1,color,opac).draw_line(x1,y1,x2,y2,color,opac).
18623 draw_line(x2,y2,x3,y3,color,opac).draw_line(x3,y3,x0,y0,color,opac);
18624 break;
18625 case 2:
18626 draw_triangle(x0,y0,x1,y1,x2,y2,color,opac).draw_triangle(x0,y0,x2,y2,x3,y3,color,opac);
18627 break;
18628 case 3:
18629 _draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opac,lightprops(l)).
18630 _draw_triangle(x0,y0,x2,y2,x3,y3,color.data,opac,lightprops(l));
18631 break;
18632 case 4: {
18633 const float
18634 lightprop0 = lightprops(n0), lightprop1 = lightprops(n1),
18635 lightprop2 = lightprops(n2), lightprop3 = lightprops(n3);
18636 draw_triangle(x0,y0,x1,y1,x2,y2,color,lightprop0,lightprop1,lightprop2,opac).
18637 draw_triangle(x0,y0,x2,y2,x3,y3,color,lightprop0,lightprop2,lightprop3,opac);
18638 } break;
18639 case 5: {
18640 const unsigned int
18641 lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1),
18642 lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1),
18643 lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1),
18644 lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1);
18645 draw_triangle(x0,y0,x1,y1,x2,y2,color,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac).
18646 draw_triangle(x0,y0,x2,y2,x3,y3,color,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac);
18647 } break;
18648 }
18649 } break;
18650 case 9: {
18651 const unsigned int
18652 n0 = (unsigned int)primitive[0],
18653 n1 = (unsigned int)primitive[1],
18654 n2 = (unsigned int)primitive[2],
18655 tx0 = (unsigned int)primitive[3],
18656 ty0 = (unsigned int)primitive[4],
18657 tx1 = (unsigned int)primitive[5],
18658 ty1 = (unsigned int)primitive[6],
18659 tx2 = (unsigned int)primitive[7],
18660 ty2 = (unsigned int)primitive[8];
18661 const int
18662 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18663 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18664 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1);
18665 const float
18666 z0 = points(n0,2) + Z + focale,
18667 z1 = points(n1,2) + Z + focale,
18668 z2 = points(n2,2) + Z + focale;
18669 switch(render_type) {
18670 case 0:
18671 draw_point(x0,y0,color.get_vector_at(tx0,ty0),opac).
18672 draw_point(x1,y1,color.get_vector_at(tx1,ty1),opac).
18673 draw_point(x2,y2,color.get_vector_at(tx2,ty2),opac);
18674 break;
18675 case 1:
18676 draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac).
18677 draw_line(x0,y0,z0,x2,y2,z2,color,tx0,ty0,tx2,ty2,opac).
18678 draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac);
18679 break;
18680 case 2:
18681 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac);
18682 break;
18683 case 3:
18684 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l));
18685 break;
18686 case 4:
18687 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);
18688 break;
18689 case 5:
18690 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,
18691 (unsigned int)lightprops(n0,0), (unsigned int)lightprops(n0,1),
18692 (unsigned int)lightprops(n1,0), (unsigned int)lightprops(n1,1),
18693 (unsigned int)lightprops(n2,0), (unsigned int)lightprops(n2,1),
18694 opac);
18695 break;
18696 }
18697 } break;
18698 case 12: {
18699 const unsigned int
18700 n0 = (unsigned int)primitive[0],
18701 n1 = (unsigned int)primitive[1],
18702 n2 = (unsigned int)primitive[2],
18703 n3 = (unsigned int)primitive[3],
18704 tx0 = (unsigned int)primitive[4],
18705 ty0 = (unsigned int)primitive[5],
18706 tx1 = (unsigned int)primitive[6],
18707 ty1 = (unsigned int)primitive[7],
18708 tx2 = (unsigned int)primitive[8],
18709 ty2 = (unsigned int)primitive[9],
18710 tx3 = (unsigned int)primitive[10],
18711 ty3 = (unsigned int)primitive[11];
18712 const int
18713 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
18714 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
18715 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1),
18716 x3 = (int)projections(n3,0), y3 = (int)projections(n3,1);
18717 const float
18718 z0 = points(n0,2) + Z + focale,
18719 z1 = points(n1,2) + Z + focale,
18720 z2 = points(n2,2) + Z + focale,
18721 z3 = points(n3,2) + Z + focale;
18722 switch(render_type) {
18723 case 0:
18724 draw_point(x0,y0,color.get_vector_at(tx0,ty0),opac).
18725 draw_point(x1,y1,color.get_vector_at(tx1,ty1),opac).
18726 draw_point(x2,y2,color.get_vector_at(tx2,ty2),opac).
18727 draw_point(x3,y3,color.get_vector_at(tx3,ty3),opac);
18728 break;
18729 case 1:
18730 draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac).
18731 draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac).
18732 draw_line(x2,y2,z2,x3,y3,z3,color,tx2,ty2,tx3,ty3,opac).
18733 draw_line(x3,y3,z3,x0,y0,z0,color,tx3,ty3,tx0,ty0,opac);
18734 break;
18735 case 2:
18736 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac).
18737 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac);
18738 break;
18739 case 3:
18740 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l)).
18741 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac,lightprops(l));
18742 break;
18743 case 4: {
18744 const float
18745 lightprop0 = lightprops(n0), lightprop1 = lightprops(n1),
18746 lightprop2 = lightprops(n2), lightprop3 = lightprops(n3);
18747 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprop0,lightprop1,lightprop2,opac).
18748 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,lightprop0,lightprop2,lightprop3,opac);
18749 } break;
18750 case 5: {
18751 const unsigned int
18752 lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1),
18753 lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1),
18754 lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1),
18755 lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1);
18756 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).
18757 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);
18758 } break;
18759 }
18760 } break;
18761 }
18762 }
18763 }
18764 return *this;
18765 }
18766
18768 template<typename tp, typename tf, typename tc, typename to>
18769 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18770 const CImgList<tp>& points, const CImgList<tf>& primitives,
18771 const CImgList<tc>& colors, const CImgList<to>& opacities,
18772 const unsigned int render_type=4,
18773 const bool double_sided=false, const float focale=500,
18774 const float lightx=0, const float lighty=0, const float lightz=-5000,
18775 const float ambient_light=0.05f) {
18776 if (!points) return *this;
18777 CImg<tp> npoints(points.size,3,1,1,0);
18778 tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
18779 cimg_forX(npoints,l) {
18780 const CImg<tp>& point = points[l];
18781 const unsigned int siz = point.size();
18782 if (!siz)
18783 throw CImgArgumentException("CImg<%s>::draw_object3d() : Given points (size=%u) contains a null element at "
18784 "position %u.",pixel_type(),points.size,l);
18785 *(ptrZ++) = (siz>2)?point(2):0;
18786 *(ptrY++) = (siz>1)?point(1):0;
18787 *(ptrX++) = point(0);
18788 }
18789 return draw_object3d(X,Y,Z,npoints,primitives,colors,opacities,
18790 render_type,double_sided,focale,lightx,lighty,lightz,ambient_light);
18791 }
18792
18794 template<typename tp, typename tf, typename tc, typename to>
18795 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18796 const CImg<tp>& points, const CImgList<tf>& primitives,
18797 const CImgList<tc>& colors, const CImg<to>& opacities,
18798 const unsigned int render_type=4,
18799 const bool double_sided=false, const float focale=500,
18800 const float lightx=0, const float lighty=0, const float lightz=-5000,
18801 const float ambient_light=0.05f) {
18802 CImgList<to> nopacities(opacities.size(),1);
18803 cimglist_for(nopacities,l) nopacities(l,0) = opacities(l);
18804 return draw_object3d(X,Y,Z,points,primitives,colors,nopacities,
18805 render_type,double_sided,focale,lightx,lighty,lightz,ambient_light);
18806 }
18807
18809 template<typename tp, typename tf, typename tc, typename to>
18810 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18811 const CImgList<tp>& points, const CImgList<tf>& primitives,
18812 const CImgList<tc>& colors, const CImg<to>& opacities,
18813 const unsigned int render_type=4,
18814 const bool double_sided=false, const float focale=500,
18815 const float lightx=0, const float lighty=0, const float lightz=-5000,
18816 const float ambient_light=0.05f) {
18817 CImgList<to> nopacities(opacities.size(),1);
18818 { cimglist_for(nopacities,l) nopacities(l,0) = opacities(l); }
18819 if (!points) return *this;
18820 CImg<tp> npoints(points.size,3,1,1,0);
18821 tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
18822 cimg_forX(npoints,l) {
18823 const CImg<tp>& point = points[l];
18824 const unsigned int siz = point.size();
18825 if (!siz)
18826 throw CImgArgumentException("CImg<%s>::draw_object3d() : Given points (size=%u) contains a null element at "
18827 "position %u.",pixel_type(),points.size,l);
18828 *(ptrZ++) = (siz>2)?point(2):0;
18829 *(ptrY++) = (siz>1)?point(1):0;
18830 *(ptrX++) = point(0);
18831 }
18832 return draw_object3d(X,Y,Z,npoints,primitives,colors,nopacities,
18833 render_type,double_sided,focale,lightx,lighty,lightz,ambient_light);
18834 }
18835
18837 template<typename tp, typename tf, typename tc>
18838 CImg<T>& draw_object3d(const float X, const float Y, const float Z,
18839 const tp& points, const CImgList<tf>& primitives,
18840 const CImgList<tc>& colors,
18841 const unsigned int render_type=4,
18842 const bool double_sided=false, const float focale=500,
18843 const float lightx=0, const float lighty=0, const float lightz=-5000,
18844 const float ambient_light=0.05f,
18845 const float opacity=1.0f) {
18846 return draw_object3d(X,Y,Z,points,primitives,colors,
18847 CImg<float>(primitives.size,1,1,1,opacity),
18848 render_type,double_sided,focale,lightx,lighty,lightz,
18849 ambient_light);
18850 }
18851
18853
18854
18856
18857
18858
18860
18869 template<typename t> CImg<typename cimg::superset2<T,t,float>::type>
18870 get_correlate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_correl=false) const {
18871 typedef typename cimg::superset2<T,t,float>::type ftype;
18872 if (is_empty()) return CImg<ftype>();
18873 if (!mask || mask.dim!=1)
18874 throw CImgArgumentException("CImg<%s>::correlate() : Specified mask (%u,%u,%u,%u,%p) is not scalar.",
18875 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
18876 CImg<ftype> dest(width,height,depth,dim);
18877 if (cond && mask.width==mask.height && ((mask.depth==1 && mask.width<=5) || (mask.depth==mask.width && mask.width<=3))) {
18878
18879 switch (mask.depth) {
18880 case 3: {
18881 T I[27] = { 0 };
18882 cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18883 (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] +
18884 I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] +
18885 I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] +
18886 I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] +
18887 I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] +
18888 I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] +
18889 I[18]*mask[18] + I[19]*mask[19] + I[20]*mask[20] +
18890 I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] +
18891 I[24]*mask[24] + I[25]*mask[25] + I[26]*mask[26]);
18892 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) {
18893 const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] +
18894 I[ 3]*I[ 3] + I[ 4]*I[ 4] + I[ 5]*I[ 5] +
18895 I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] +
18896 I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
18897 I[12]*I[12] + I[13]*I[13] + I[14]*I[14] +
18898 I[15]*I[15] + I[16]*I[16] + I[17]*I[17] +
18899 I[18]*I[18] + I[19]*I[19] + I[20]*I[20] +
18900 I[21]*I[21] + I[22]*I[22] + I[23]*I[23] +
18901 I[24]*I[24] + I[25]*I[25] + I[26]*I[26]);
18902 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18903 }
18904 } break;
18905 case 2: {
18906 T I[8] = { 0 };
18907 cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18908 (I[0]*mask[0] + I[1]*mask[1] +
18909 I[2]*mask[2] + I[3]*mask[3] +
18910 I[4]*mask[4] + I[5]*mask[5] +
18911 I[6]*mask[6] + I[7]*mask[7]);
18912 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) {
18913 const double weight = (double)(I[0]*I[0] + I[1]*I[1] +
18914 I[2]*I[2] + I[3]*I[3] +
18915 I[4]*I[4] + I[5]*I[5] +
18916 I[6]*I[6] + I[7]*I[7]);
18917 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18918 }
18919 } break;
18920 default:
18921 case 1:
18922 switch (mask.width) {
18923 case 6: {
18924 T I[36] = { 0 };
18925 cimg_forZV(*this,z,v) cimg_for6x6(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18926 (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] +
18927 I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] +
18928 I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] +
18929 I[18]*mask[18] + I[19]*mask[19] + I[20]*mask[20] + I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] +
18930 I[24]*mask[24] + I[25]*mask[25] + I[26]*mask[26] + I[27]*mask[27] + I[28]*mask[28] + I[29]*mask[29] +
18931 I[30]*mask[30] + I[31]*mask[31] + I[32]*mask[32] + I[33]*mask[33] + I[34]*mask[34] + I[35]*mask[35]);
18932 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) {
18933 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] +
18934 I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
18935 I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15] + I[16]*I[16] + I[17]*I[17] +
18936 I[18]*I[18] + I[19]*I[19] + I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] +
18937 I[24]*I[24] + I[25]*I[25] + I[26]*I[26] + I[27]*I[27] + I[28]*I[28] + I[29]*I[29] +
18938 I[30]*I[30] + I[31]*I[31] + I[32]*I[32] + I[33]*I[33] + I[34]*I[34] + I[35]*I[35]);
18939 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18940 }
18941 } break;
18942 case 5: {
18943 T I[25] = { 0 };
18944 cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18945 (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] +
18946 I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] +
18947 I[10]*mask[10] + I[11]*mask[11] + I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] +
18948 I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] + I[18]*mask[18] + I[19]*mask[19] +
18949 I[20]*mask[20] + I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] + I[24]*mask[24]);
18950 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) {
18951 const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + I[ 4]*I[ 4] +
18952 I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] +
18953 I[10]*I[10] + I[11]*I[11] + I[12]*I[12] + I[13]*I[13] + I[14]*I[14] +
18954 I[15]*I[15] + I[16]*I[16] + I[17]*I[17] + I[18]*I[18] + I[19]*I[19] +
18955 I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] + I[24]*I[24]);
18956 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18957 }
18958 } break;
18959 case 4: {
18960 T I[16] = { 0 };
18961 cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18962 (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] +
18963 I[ 4]*mask[ 4] + I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] +
18964 I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] +
18965 I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15]);
18966 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) {
18967 const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] +
18968 I[ 4]*I[ 4] + I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] +
18969 I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
18970 I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15]);
18971 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18972 }
18973 } break;
18974 case 3: {
18975 T I[9] = { 0 };
18976 cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18977 (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] +
18978 I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] +
18979 I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]);
18980 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) {
18981 const double weight = (double)(I[0]*I[0] + I[1]*I[1] + I[2]*I[2] +
18982 I[3]*I[3] + I[4]*I[4] + I[5]*I[5] +
18983 I[6]*I[6] + I[7]*I[7] + I[8]*I[8]);
18984 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18985 }
18986 } break;
18987 case 2: {
18988 T I[4] = { 0 };
18989 cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) dest(x,y,z,v) = (ftype)
18990 (I[0]*mask[0] + I[1]*mask[1] +
18991 I[2]*mask[2] + I[3]*mask[3]);
18992 if (weighted_correl) cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) {
18993 const double weight = (double)(I[0]*I[0] + I[1]*I[1] +
18994 I[2]*I[2] + I[3]*I[3]);
18995 if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight);
18996 }
18997 } break;
18998 case 1: (dest.assign(*this))*=mask(0); break;
18999 }
19000 }
19001 } else {
19002
19003 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);
19004 cimg_forV(*this,v)
19005 if (!weighted_correl) {
19006 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19007 ftype val = 0;
19008 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19009 val+=(*this)(x+xm,y+ym,z+zm,v)*mask(cxm+xm,cym+ym,czm+zm,0);
19010 dest(x,y,z,v) = (ftype)val;
19011 }
19012 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))) {
19013 ftype val = 0;
19014 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19015 val+=pix3d(x+xm,y+ym,z+zm,v)*mask(cxm+xm,cym+ym,czm+zm,0);
19016 dest(x,y,z,v) = (ftype)val;
19017 }
19018 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))) {
19019 ftype val = 0;
19020 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19021 val+=pix3d(x+xm,y+ym,z+zm,v,0)*mask(cxm+xm,cym+ym,czm+zm,0);
19022 dest(x,y,z,v) = (ftype)val;
19023 }
19024 } else {
19025 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19026 ftype val = 0, weight = 0;
19027 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm) {
19028 const T cval = (*this)(x+xm,y+ym,z+zm,v);
19029 val+=cval*mask(cxm+xm,cym+ym,czm+zm,0);
19030 weight+= cval*cval;
19031 }
19032 dest(x,y,z,v) = (weight>0)?(ftype)(val/std::sqrt((double)weight)):0;
19033 }
19034 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))) {
19035 ftype val = 0, weight = 0;
19036 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm) {
19037 const T cval = pix3d(x+xm,y+ym,z+zm,v);
19038 val+=cval*mask(cxm+xm,cym+ym,czm+zm,0);
19039 weight+=cval*cval;
19040 }
19041 dest(x,y,z,v) = (weight>0)?(ftype)(val/std::sqrt((double)weight)):0;
19042 }
19043 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))) {
19044 ftype val = 0, weight = 0;
19045 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm) {
19046 const T cval = pix3d(x+xm,y+ym,z+zm,v,0);
19047 val+=cval*mask(cxm+xm,cym+ym,czm+zm,0);
19048 weight+=cval*cval;
19049 }
19050 dest(x,y,z,v) = (weight>0)?(ftype)(val/std::sqrt((double)weight)):0;
19051 }
19052 }
19053 }
19054 return dest;
19055 }
19056
19058 template<typename t> CImg<T>& correlate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_correl=false) {
19059 return get_correlate(mask,cond,weighted_correl).assign_to(*this);
19060 }
19061
19063
19072 template<typename t> CImg<typename cimg::superset2<T,t,float>::type>
19073 get_convolve(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_convol=false) const {
19074 typedef typename cimg::superset2<T,t,float>::type ftype;
19075 if (is_empty()) return CImg<ftype>();
19076 if (!mask || mask.dim!=1)
19077 throw CImgArgumentException("CImg<%s>::convolve() : Specified mask (%u,%u,%u,%u,%p) is not scalar.",
19078 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
19079 return get_correlate(mask.get_mirror('x').mirror('y').mirror('z'),cond,weighted_convol);
19080 }
19081
19083 template<typename t> CImg<T>& convolve(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_convol=false) {
19084 return get_convolve(mask,cond,weighted_convol).assign_to(*this);
19085 }
19086
19088 template<typename t> CImg<typename cimg::superset<T,t>::type>
19089 get_erode(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_erosion=false) const {
19090 typedef typename cimg::superset<T,t>::type restype;
19091 if (is_empty()) return CImg<restype>();
19092 if (!mask || mask.dim!=1)
19093 throw CImgArgumentException("CImg<%s>::erode() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.",
19094 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
19095 CImg<restype> dest(width,height,depth,dim);
19096 const int cxm=mask.width/2, cym=mask.height/2, czm=mask.depth/2,
19097 fxm=cxm-1+(mask.width%2), fym=cym-1+(mask.height%2), fzm=czm-1+(mask.depth%2);
19098 cimg_forV(*this,v)
19099 if (!weighted_erosion) {
19100 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19101 restype min_val = cimg::type<restype>::max();
19102 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19103 if (mask(cxm+xm,cym+ym,czm+zm,0)) min_val = cimg::min((restype)(*this)(x+xm,y+ym,z+zm,v),min_val);
19104 dest(x,y,z,v) = min_val;
19105 }
19106 if (cond) cimg_forYZV(*this,y,z,v)
19107 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))) {
19108 restype min_val = cimg::type<restype>::max();
19109 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19110 if (mask(cxm+xm,cym+ym,czm+zm,0)) min_val = cimg::min((restype)pix3d(x+xm,y+ym,z+zm,v),min_val);
19111 dest(x,y,z,v) = min_val;
19112 }
19113 else cimg_forYZV(*this,y,z,v)
19114 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))) {
19115 restype min_val = cimg::type<restype>::max();
19116 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19117 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);
19118 dest(x,y,z,v) = min_val;
19119 }
19120 } else {
19121 t mval=0;
19122 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19123 restype min_val = cimg::type<restype>::max();
19124 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19125 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);
19126 dest(x,y,z,v) = min_val;
19127 }
19128 if (cond) cimg_forYZV(*this,y,z,v)
19129 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))) {
19130 restype min_val = cimg::type<restype>::max();
19131 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19132 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);
19133 dest(x,y,z,v) = min_val;
19134 }
19135 else cimg_forYZV(*this,y,z,v)
19136 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))) {
19137 restype min_val = cimg::type<restype>::max();
19138 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19139 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);
19140 dest(x,y,z,v) = min_val;
19141 }
19142 }
19143 return dest;
19144 }
19145
19147 template<typename t> CImg<T>& erode(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_erosion=false) {
19148 return get_erode(mask,cond,weighted_erosion).assign_to(*this);
19149 }
19150
19152 CImg<T> get_erode(const unsigned int n, const unsigned int cond=1) const {
19153 static CImg<T> mask;
19154 if (n<2) return *this;
19155 if (mask.width!=n) mask.assign(n,n,1,1,1);
19156 const CImg<T> res = get_erode(mask,cond,false);
19157 if (n>20) mask.assign();
19158 return res;
19159 }
19160
19162 CImg<T>& erode(const unsigned int n, const unsigned int cond=1) {
19163 if (n<2) return *this;
19164 return get_erode(n,cond).assign_to(*this);
19165 }
19166
19168 template<typename t> CImg<typename cimg::superset<T,t>::type>
19169 get_dilate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_dilatation=false) const {
19170 typedef typename cimg::superset<T,t>::type restype;
19171 if (is_empty()) return CImg<restype>();
19172 if (!mask || mask.dim!=1)
19173 throw CImgArgumentException("CImg<%s>::dilate() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.",
19174 pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
19175 CImg<restype> dest(width,height,depth,dim);
19176 const int cxm=mask.width/2, cym=mask.height/2, czm=mask.depth/2,
19177 fxm=cxm-1+(mask.width%2), fym=cym-1+(mask.height%2), fzm=czm-1+(mask.depth%2);
19178 cimg_forV(*this,v)
19179 if (!weighted_dilatation) {
19180 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19181 restype max_val = cimg::type<restype>::min();
19182 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19183 if (mask(cxm+xm,cym+ym,czm+zm,0)) max_val = cimg::max((restype)(*this)(x+xm,y+ym,z+zm,v),max_val);
19184 dest(x,y,z,v) = max_val;
19185 }
19186 if (cond) cimg_forYZV(*this,y,z,v)
19187 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))) {
19188 restype max_val = cimg::type<restype>::min();
19189 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19190 if (mask(cxm+xm,cym+ym,czm+zm,0)) max_val = cimg::max((restype)pix3d(x+xm,y+ym,z+zm,v),max_val);
19191 dest(x,y,z,v) = max_val;
19192 }
19193 else cimg_forYZV(*this,y,z,v)
19194 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))) {
19195 restype max_val = cimg::type<restype>::min();
19196 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19197 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);
19198 dest(x,y,z,v) = max_val;
19199 }
19200 } else {
19201 t mval=0;
19202 for (int z=czm; z<dimz()-czm; ++z) for (int y=cym; y<dimy()-cym; ++y) for (int x=cxm; x<dimx()-cxm; ++x) {
19203 restype max_val = cimg::type<restype>::min();
19204 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19205 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);
19206 dest(x,y,z,v) = max_val;
19207 }
19208 if (cond) cimg_forYZV(*this,y,z,v)
19209 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))) {
19210 restype max_val = cimg::type<restype>::min();
19211 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19212 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);
19213 dest(x,y,z,v) = max_val;
19214 }
19215 else cimg_forYZV(*this,y,z,v)
19216 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))) {
19217 restype max_val = cimg::type<restype>::min();
19218 for (int zm=-czm; zm<=fzm; ++zm) for (int ym=-cym; ym<=fym; ++ym) for (int xm=-cxm; xm<=fxm; ++xm)
19219 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);
19220 dest(x,y,z,v) = max_val;
19221 }
19222 }
19223 return dest;
19224 }
19225
19226 template<typename t> CImg<T>& dilate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_dilatation=false) {
19227 return get_dilate(mask,cond,weighted_dilatation).assign_to(*this);
19228 }
19229
19231 CImg<T> get_dilate(const unsigned int n, const unsigned int cond=1) const {
19232 static CImg<T> mask;
19233 if (n<2) return *this;
19234 if (mask.width!=n) mask.assign(n,n,1,1,1);
19235 const CImg<T> res = get_dilate(mask,cond,false);
19236 if (n>20) mask.assign();
19237 return res;
19238 }
19239
19241 CImg<T>& dilate(const unsigned int n, const unsigned int cond=1) {
19242 if (n<2) return *this;
19243 return get_dilate(n,cond).assign_to(*this);
19244 }
19245
19247
19252 CImg<T> get_noise(const double sigma=-20, const unsigned int ntype=0) const {
19253 return (+*this).noise(sigma,ntype);
19254 }
19255
19257 CImg<T>& noise(const double sigma=-20, const unsigned int ntype=0) {
19258 if (!is_empty()) {
19259 double nsigma = sigma, max = (double)cimg::type<T>::max(), min = (double)cimg::type<T>::min();
19260 typedef typename cimg::superset<T,float>::type ftype;
19261 cimg::srand();
19262 ftype m = 0, M = 0;
19263 if (nsigma==0) return *this;
19264 if (nsigma<0 || ntype==2) m = (ftype)minmax(M);
19265 if (nsigma<0) nsigma = -nsigma*(M-m)/100.0;
19266 switch (ntype) {
19267 case 0: {
19268 cimg_for(*this,ptr,T) {
19269 double val = *ptr+nsigma*cimg::grand();
19270 if (val>max) val = max;
19271 if (val<min) val = min;
19272 *ptr = (T)val;
19273 }
19274 } break;
19275 case 1: {
19276 cimg_for(*this,ptr,T) {
19277 double val = *ptr+nsigma*cimg::crand();
19278 if (val>max) val = max;
19279 if (val<min) val = min;
19280 *ptr = (T)val;
19281 }
19282 } break;
19283 case 2: {
19284 if (M==m) { m = 0; M = 255; }
19285 cimg_for(*this,ptr,T) if (cimg::rand()*100<nsigma) *ptr = (T)(cimg::rand()<0.5?M:m);
19286 } break;
19287 case 3: {
19288 cimg_for(*this,ptr,T) {
19289 const double z = (double)*ptr;
19290 if (z<=1.0e-10) *ptr = (T)0;
19291 else {
19292 if (z>100.0) *ptr = (T)(unsigned int)((std::sqrt(z) * cimg::grand()) + z);
19293 else {
19294 unsigned int k = 0;
19295 const double y=std::exp(-z);
19296 for (double s=1.0; s>=y; ++k) s *= cimg::rand();
19297 *ptr = (T)(k-1);
19298 }
19299 }
19300 }
19301 } break;
19302 case 4: {
19303 const double sqrt2 = (double)std::sqrt(2.0);
19304 cimg_for(*this,ptr,T) {
19305 const double
19306 val0 = (double)*ptr/sqrt2,
19307 re = val0 + nsigma*cimg::grand(),
19308 im = val0 + nsigma*cimg::grand();
19309 double val = std::sqrt(re*re + im*im);
19310 if (val>max) val = max;
19311 if (val<min) val = min;
19312 *ptr = (T)val;
19313 }
19314 } break;
19315 }
19316 }
19317 return *this;
19318 }
19319
19321
19326 CImg<typename cimg::superset<T,float>::type> get_deriche(const float sigma, const int order=0,
19327 const char axe='x', const bool cond=true) const {
19328 typedef typename cimg::superset<T,float>::type ftype;
19329 return CImg<ftype>(*this,false).deriche(sigma,order,axe,cond);
19330 }
19331
19333 CImg<T>& deriche(const float sigma, const int order=0, const char axe='x', const bool cond=true) {
19334 #define cimg_deriche2_apply \
19335 ftype *ptrY = Y.data, yb = 0, yp = 0; \
19336 T xp = (T)0; \
19337 if (cond) { xp = *ptrX; yb = yp = (ftype)(coefp*xp); } \
19338 for (int m=0; m<N; ++m) { \
19339 const T xc = *ptrX; ptrX+=off; \
19340 const ftype yc = *(ptrY++) = (ftype)(a0*xc + a1*xp - b1*yp - b2*yb); \
19341 xp = xc; yb = yp; yp = yc; \
19342 } \
19343 T xn = (T)0, xa = (T)0; \
19344 ftype yn = 0, ya = 0; \
19345 if (cond) { xn = xa = *(ptrX-off); yn = ya = (ftype)coefn*xn; } \
19346 for (int n=N-1; n>=0; --n) { \
19347 const T xc = *(ptrX-=off); \
19348 const ftype yc = (ftype)(a2*xn + a3*xa - b1*yn - b2*ya); \
19349 xa = xn; xn = xc; ya = yn; yn = yc; \
19350 *ptrX = (T)(*(--ptrY)+yc); \
19351 }
19352 typedef typename cimg::superset<T,float>::type ftype;
19353 if (sigma<0)
19354 throw CImgArgumentException("CImg<%s>::deriche() : Given filter variance (sigma = %g) is negative",pixel_type(),sigma);
19355 if (is_empty() || (sigma<0.1 && !order)) return *this;
19356 const float
19357 nsigma = sigma<0.1f?0.1f:sigma,
19358 alpha = 1.695f/nsigma,
19359 ema = (float)std::exp(-alpha),
19360 ema2 = (float)std::exp(-2*alpha),
19361 b1 = -2*ema,
19362 b2 = ema2;
19363 float a0 = 0, a1 = 0, a2 = 0, a3 = 0, coefp = 0, coefn = 0;
19364 switch (order) {
19365 case 0: {
19366 const float k = (1-ema)*(1-ema)/(1+2*alpha*ema-ema2);
19367 a0 = k;
19368 a1 = k*(alpha-1)*ema;
19369 a2 = k*(alpha+1)*ema;
19370 a3 = -k*ema2;
19371 } break;
19372 case 1: {
19373 const float k = (1-ema)*(1-ema)/ema;
19374 a0 = k*ema;
19375 a1 = a3 = 0;
19376 a2 = -a0;
19377 } break;
19378 case 2: {
19379 const float
19380 ea = (float)std::exp(-alpha),
19381 k = -(ema2-1)/(2*alpha*ema),
19382 kn = (-2*(-1+3*ea-3*ea*ea+ea*ea*ea)/(3*ea+1+3*ea*ea+ea*ea*ea));
19383 a0 = kn;
19384 a1 = -kn*(1+k*alpha)*ema;
19385 a2 = kn*(1-k*alpha)*ema;
19386 a3 = -kn*ema2;
19387 } break;
19388 default:
19389 throw CImgArgumentException("CImg<%s>::deriche() : Given filter order (order = %u) must be 0,1 or 2",pixel_type(),order);
19390 break;
19391 }
19392 coefp = (a0+a1)/(1+b1+b2);
19393 coefn = (a2+a3)/(1+b1+b2);
19394 switch (cimg::uncase(axe)) {
19395 case 'x': {
19396 const int N = width, off = 1;
19397 CImg<ftype> Y(N);
19398 cimg_forYZV(*this,y,z,v) { T *ptrX = ptr(0,y,z,v); cimg_deriche2_apply; }
19399 } break;
19400 case 'y': {
19401 const int N = height, off = width;
19402 CImg<ftype> Y(N);
19403 cimg_forXZV(*this,x,z,v) { T *ptrX = ptr(x,0,z,v); cimg_deriche2_apply; }
19404 } break;
19405 case 'z': {
19406 const int N = depth, off = width*height;
19407 CImg<ftype> Y(N);
19408 cimg_forXYV(*this,x,y,v) { T *ptrX = ptr(x,y,0,v); cimg_deriche2_apply; }
19409 } break;
19410 case 'v': {
19411 const int N = dim, off = width*height*depth;
19412 CImg<ftype> Y(N);
19413 cimg_forXYZ(*this,x,y,z) { T *ptrX = ptr(x,y,z,0); cimg_deriche2_apply; }
19414 } break;
19415 }
19416 return *this;
19417 }
19418
19420
19423 CImg<typename cimg::superset<T,float>::type> get_blur(const float sigmax, const float sigmay, const float sigmaz,
19424 const bool cond=true) const {
19425 typedef typename cimg::superset<T,float>::type ftype;
19426 return CImg<ftype>(*this,false).blur(sigmax,sigmay,sigmaz,cond);
19427 }
19428
19430 CImg<T>& blur(const float sigmax, const float sigmay, const float sigmaz, const bool cond=true) {
19431 if (!is_empty()) {
19432 if (width>1 && sigmax>0) deriche(sigmax,0,'x',cond);
19433 if (height>1 && sigmay>0) deriche(sigmay,0,'y',cond);
19434 if (depth>1 && sigmaz>0) deriche(sigmaz,0,'z',cond);
19435 }
19436 return *this;
19437 }
19438
19440 CImg<typename cimg::superset<T,float>::type> get_blur(const float sigma, const bool cond=true) const {
19441 typedef typename cimg::superset<T,float>::type ftype;
19442 return CImg<ftype>(*this,false).blur(sigma,cond);
19443 }
19444
19446 CImg<T>& blur(const float sigma, const bool cond=true) {
19447 return blur(sigma,sigma,sigma,cond);
19448 }
19449
19451
19460 template<typename t>
19461 CImg<T> get_blur_anisotropic(const CImg<t>& G, const float amplitude=60.0f, const float dl=0.8f, const float da=30.0f,
19462 const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true) const {
19463 return (+*this).blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
19464 }
19465
19467 template<typename t>
19468 CImg<T>& blur_anisotropic(const CImg<t>& G, const float amplitude=60.0f, const float dl=0.8f, const float da=30.0f,
19469 const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true) {
19470 #define cimg_valign2d(i,j) \
19471 { ftype &u = W(i,j,0,0), &v = W(i,j,0,1); \
19472 if (u*curru + v*currv<0) { u=-u; v=-v; }}
19473 #define cimg_valign3d(i,j,k) \
19474 { ftype &u = W(i,j,k,0), &v = W(i,j,k,1), &w = W(i,j,k,2); \
19475 if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}
19476
19477
19478 typedef typename cimg::superset<T,float>::type ftype;
19479 if (!is_empty() && amplitude>0) {
19480 if (!G || (G.dim!=3 && G.dim!=6) || G.width!=width || G.height!=height || G.depth!=depth)
19481 throw CImgArgumentException("CImg<%s>::blur_anisotropic() : Specified tensor field (%u,%u,%u,%u) is not valid.",
19482 pixel_type(),G.width,G.height,G.depth,G.dim);
19483
19484 const float sqrt2amplitude = (float)std::sqrt(2*amplitude);
19485 const bool threed = (G.dim>=6);
19486 const int
19487 dx1 = dimx()-1,
19488 dy1 = dimy()-1,
19489 dz1 = dimz()-1;
19490 CImg<ftype>
19491 dest(width,height,depth,dim,0),
19492 W(width,height,depth,threed?4:3),
19493 tmp(dim);
19494 int N = 0;
19495
19496 if (threed)
19497
19498 for (float phi=(180%(int)da)/2.0f; phi<=180; phi+=da) {
19499 const float
19500 phir = (float)(phi*cimg::PI/180),
19501 datmp = (float)(da/std::cos(phir)),
19502 da2 = datmp<1?360.0f:datmp;
19503
19504 for (float theta=0; theta<360; (theta+=da2),++N) {
19505 const float
19506 thetar = (float)(theta*cimg::PI/180),
19507 vx = (float)(std::cos(thetar)*std::cos(phir)),
19508 vy = (float)(std::sin(thetar)*std::cos(phir)),
19509 vz = (float)std::sin(phir);
19510 const t
19511 *pa = G.ptr(0,0,0,0),
19512 *pb = G.ptr(0,0,0,1),
19513 *pc = G.ptr(0,0,0,2),
19514 *pd = G.ptr(0,0,0,3),
19515 *pe = G.ptr(0,0,0,4),
19516 *pf = G.ptr(0,0,0,5);
19517 ftype
19518 *pd0 = W.ptr(0,0,0,0),
19519 *pd1 = W.ptr(0,0,0,1),
19520 *pd2 = W.ptr(0,0,0,2),
19521 *pd3 = W.ptr(0,0,0,3);
19522 cimg_forXYZ(G,xg,yg,zg) {
19523 const t
19524 a = *(pa++), b = *(pb++), c = *(pc++),
19525 d = *(pd++), e = *(pe++), f = *(pf++);
19526 const float
19527 u = (float)(a*vx + b*vy + c*vz),
19528 v = (float)(b*vx + d*vy + e*vz),
19529 w = (float)(c*vx + e*vy + f*vz),
19530 n = (float)std::sqrt(1e-5+u*u+v*v+w*w),
19531 dln = dl/n;
19532 *(pd0++) = (ftype)(u*dln);
19533 *(pd1++) = (ftype)(v*dln);
19534 *(pd2++) = (ftype)(w*dln);
19535 *(pd3++) = (ftype)n;
19536 }
19537
19538 cimg_forXYZ(*this,x,y,z) {
19539 tmp.fill(0);
19540 const float
19541 cu = (float)W(x,y,z,0),
19542 cv = (float)W(x,y,z,1),
19543 cw = (float)W(x,y,z,2),
19544 n = (float)W(x,y,z,3),
19545 fsigma = (float)(n*sqrt2amplitude),
19546 length = gauss_prec*fsigma,
19547 fsigma2 = 2*fsigma*fsigma;
19548 float
19549 S = 0,
19550 pu = cu,
19551 pv = cv,
19552 pw = cw,
19553 X = (float)x,
19554 Y = (float)y,
19555 Z = (float)z;
19556
19557 switch (interpolation) {
19558 case 0: {
19559
19560 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
19561 const int
19562 cx = (int)(X+0.5f),
19563 cy = (int)(Y+0.5f),
19564 cz = (int)(Z+0.5f);
19565 float
19566 u = (float)W(cx,cy,cz,0),
19567 v = (float)W(cx,cy,cz,1),
19568 w = (float)W(cx,cy,cz,2);
19569 if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; }
19570 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)(*this)(cx,cy,cz,k); ++S; }
19571 else {
19572 const float coef = (float)std::exp(-l*l/fsigma2);
19573 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*(*this)(cx,cy,cz,k));
19574 S+=coef;
19575 }
19576 X+=(pu=u); Y+=(pv=v); Z+=(pw=w);
19577 }
19578 } break;
19579
19580 case 1: {
19581
19582 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
19583 const int
19584 cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
19585 cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1,
19586 cz = (int)Z, pz = (cz-1<0)?0:cz-1, nz = (cz+1>dz1)?dz1:cz+1;
19587 const float
19588 curru = (float)W(cx,cy,cz,0),
19589 currv = (float)W(cx,cy,cz,1),
19590 currw = (float)W(cx,cy,cz,2);
19591 cimg_valign3d(px,py,pz); cimg_valign3d(cx,py,pz); cimg_valign3d(nx,py,pz);
19592 cimg_valign3d(px,cy,pz); cimg_valign3d(cx,cy,pz); cimg_valign3d(nx,cy,pz);
19593 cimg_valign3d(px,ny,pz); cimg_valign3d(cx,ny,pz); cimg_valign3d(nx,ny,pz);
19594 cimg_valign3d(px,py,cz); cimg_valign3d(cx,py,cz); cimg_valign3d(nx,py,cz);
19595 cimg_valign3d(px,cy,cz); cimg_valign3d(nx,cy,cz);
19596 cimg_valign3d(px,ny,cz); cimg_valign3d(cx,ny,cz); cimg_valign3d(nx,ny,cz);
19597 cimg_valign3d(px,py,nz); cimg_valign3d(cx,py,nz); cimg_valign3d(nx,py,nz);
19598 cimg_valign3d(px,cy,nz); cimg_valign3d(cx,cy,nz); cimg_valign3d(nx,cy,nz);
19599 cimg_valign3d(px,ny,nz); cimg_valign3d(cx,ny,nz); cimg_valign3d(nx,ny,nz);
19600 float
19601 u = (float)(W.linear_pix3d(X,Y,Z,0)),
19602 v = (float)(W.linear_pix3d(X,Y,Z,1)),
19603 w = (float)(W.linear_pix3d(X,Y,Z,2));
19604 if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; }
19605 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix3d(X,Y,Z,k); ++S; }
19606 else {
19607 const float coef = (float)std::exp(-l*l/fsigma2);
19608 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix3d(X,Y,Z,k));
19609 S+=coef;
19610 }
19611 X+=(pu=u); Y+=(pv=v); Z+=(pw=w);
19612 }
19613 } break;
19614
19615 default: {
19616
19617 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
19618 const int
19619 cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
19620 cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1,
19621 cz = (int)Z, pz = (cz-1<0)?0:cz-1, nz = (cz+1>dz1)?dz1:cz+1;
19622 const float
19623 curru = (float)W(cx,cy,cz,0),
19624 currv = (float)W(cx,cy,cz,1),
19625 currw = (float)W(cx,cy,cz,2);
19626 cimg_valign3d(px,py,pz); cimg_valign3d(cx,py,pz); cimg_valign3d(nx,py,pz);
19627 cimg_valign3d(px,cy,pz); cimg_valign3d(cx,cy,pz); cimg_valign3d(nx,cy,pz);
19628 cimg_valign3d(px,ny,pz); cimg_valign3d(cx,ny,pz); cimg_valign3d(nx,ny,pz);
19629 cimg_valign3d(px,py,cz); cimg_valign3d(cx,py,cz); cimg_valign3d(nx,py,cz);
19630 cimg_valign3d(px,cy,cz); cimg_valign3d(nx,cy,cz);
19631 cimg_valign3d(px,ny,cz); cimg_valign3d(cx,ny,cz); cimg_valign3d(nx,ny,cz);
19632 cimg_valign3d(px,py,nz); cimg_valign3d(cx,py,nz); cimg_valign3d(nx,py,nz);
19633 cimg_valign3d(px,cy,nz); cimg_valign3d(cx,cy,nz); cimg_valign3d(nx,cy,nz);
19634 cimg_valign3d(px,ny,nz); cimg_valign3d(cx,ny,nz); cimg_valign3d(nx,ny,nz);
19635 const float
19636 u0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,0)),
19637 v0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,1)),
19638 w0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,2));
19639 float
19640 u = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,0)),
19641 v = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,1)),
19642 w = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,2));
19643 if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; }
19644 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix3d(X,Y,Z,k); ++S; }
19645 else {
19646 const float coef = (float)std::exp(-l*l/fsigma2);
19647 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix3d(X,Y,Z,k));
19648 S+=coef;
19649 }
19650 X+=(pu=u); Y+=(pv=v); Z+=(pw=w);
19651 }
19652 } break;
19653 }
19654 if (S>0) cimg_forV(dest,k) dest(x,y,z,k)+=tmp[k]/S;
19655 else cimg_forV(dest,k) dest(x,y,z,k)+=(ftype)((*this)(x,y,z,k));
19656 #ifdef cimg_plugin_greycstoration
19657 if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter);
19658 else return *this;
19659 #endif
19660 }
19661 }
19662 } else
19663
19664 for (float theta=(360%(int)da)/2.0f; theta<360; (theta+=da),++N) {
19665 const float
19666 thetar = (float)(theta*cimg::PI/180),
19667 vx = (float)(std::cos(thetar)),
19668 vy = (float)(std::sin(thetar));
19669 const t
19670 *pa = G.ptr(0,0,0,0),
19671 *pb = G.ptr(0,0,0,1),
19672 *pc = G.ptr(0,0,0,2);
19673 ftype
19674 *pd0 = W.ptr(0,0,0,0),
19675 *pd1 = W.ptr(0,0,0,1),
19676 *pd2 = W.ptr(0,0,0,2);
19677 cimg_forXY(G,xg,yg) {
19678 const t a = *(pa++), b = *(pb++), c = *(pc++);
19679 const float
19680 u = (float)(a*vx + b*vy),
19681 v = (float)(b*vx + c*vy),
19682 n = (float)std::sqrt(1e-5+u*u+v*v),
19683 dln = dl/n;
19684 *(pd0++) = (ftype)(u*dln);
19685 *(pd1++) = (ftype)(v*dln);
19686 *(pd2++) = (ftype)n;
19687 }
19688
19689 cimg_forXY(*this,x,y) {
19690 tmp.fill(0);
19691 const float
19692 cu = (float)W(x,y,0,0),
19693 cv = (float)W(x,y,0,1),
19694 n = (float)W(x,y,0,2),
19695 fsigma = (float)(n*sqrt2amplitude),
19696 length = gauss_prec*fsigma,
19697 fsigma2 = 2*fsigma*fsigma;
19698 float
19699 S = 0,
19700 pu = cu,
19701 pv = cv,
19702 X = (float)x,
19703 Y = (float)y;
19704
19705 switch (interpolation) {
19706
19707 case 0: {
19708
19709 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
19710 const int
19711 cx = (int)(X+0.5f),
19712 cy = (int)(Y+0.5f);
19713 float
19714 u = (float)W(cx,cy,0,0),
19715 v = (float)W(cx,cy,0,1);
19716 if ((pu*u + pv*v)<0) { u=-u; v=-v; }
19717 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)(*this)(cx,cy,0,k); ++S; }
19718 else {
19719 const float coef = (float)std::exp(-l*l/fsigma2);
19720 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*(*this)(cx,cy,0,k));
19721 S+=coef;
19722 }
19723 X+=(pu=u); Y+=(pv=v);
19724 }
19725 } break;
19726
19727 case 1: {
19728
19729 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
19730 const int
19731 cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
19732 cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1;
19733 const float
19734 curru = (float)W(cx,cy,0,0),
19735 currv = (float)W(cx,cy,0,1);
19736 cimg_valign2d(px,py); cimg_valign2d(cx,py); cimg_valign2d(nx,py);
19737 cimg_valign2d(px,cy); cimg_valign2d(nx,cy);
19738 cimg_valign2d(px,ny); cimg_valign2d(cx,ny); cimg_valign2d(nx,ny);
19739 float
19740 u = (float)(W.linear_pix2d(X,Y,0,0)),
19741 v = (float)(W.linear_pix2d(X,Y,0,1));
19742 if ((pu*u + pv*v)<0) { u=-u; v=-v; }
19743 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix2d(X,Y,0,k); ++S; }
19744 else {
19745 const float coef = (float)std::exp(-l*l/fsigma2);
19746 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix2d(X,Y,0,k));
19747 S+=coef;
19748 }
19749 X+=(pu=u); Y+=(pv=v);
19750 }
19751 } break;
19752
19753 default: {
19754
19755 for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
19756 const int
19757 cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
19758 cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1;
19759 const float
19760 curru = (float)W(cx,cy,0,0),
19761 currv = (float)W(cx,cy,0,1);
19762 cimg_valign2d(px,py); cimg_valign2d(cx,py); cimg_valign2d(nx,py);
19763 cimg_valign2d(px,cy); cimg_valign2d(nx,cy);
19764 cimg_valign2d(px,ny); cimg_valign2d(cx,ny); cimg_valign2d(nx,ny);
19765 const float
19766 u0 = (float)(0.5f*W.linear_pix2d(X,Y,0,0)),
19767 v0 = (float)(0.5f*W.linear_pix2d(X,Y,0,1));
19768 float
19769 u = (float)(W.linear_pix2d(X+u0,Y+v0,0,0)),
19770 v = (float)(W.linear_pix2d(X+u0,Y+v0,0,1));
19771 if ((pu*u + pv*v)<0) { u=-u; v=-v; }
19772 if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix2d(X,Y,0,k); ++S; }
19773 else {
19774 const float coef = (float)std::exp(-l*l/fsigma2);
19775 cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix2d(X,Y,0,k));
19776 S+=coef;
19777 }
19778 X+=(pu=u); Y+=(pv=v);
19779 }
19780 } break;
19781 }
19782 if (S>0) cimg_forV(dest,k) dest(x,y,0,k)+=tmp[k]/S;
19783 else cimg_forV(dest,k) dest(x,y,0,k)+=(ftype)((*this)(x,y,0,k));
19784 #ifdef cimg_plugin_greycstoration
19785 if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter);
19786 else return *this;
19787 #endif
19788 }
19789 }
19790 const ftype *ptrs = dest.data+dest.size();
19791 const T m = cimg::type<T>::min(), M = cimg::type<T>::max();
19792 cimg_for(*this,ptrd,T) { const ftype val = *(--ptrs)/N; *ptrd = val<m?m:(val>M?M:(T)val); }
19793 }
19794 return *this;
19795 }
19796
19798
19812 template<typename tm>
19813 CImg<T> get_blur_anisotropic(const CImg<tm>& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
19814 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
19815 const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0,
19816 const bool fast_approx=true, const float geom_factor=1.0f) const {
19817 return (+*this).blur_anisotropic(mask,amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
19818 }
19819
19821 template<typename tm>
19822 CImg<T>& blur_anisotropic(const CImg<tm>& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
19823 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f,
19824 const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true,
19825 const float geom_factor=1.0f) {
19826 if (!is_empty() && amplitude>0) {
19827 if (amplitude==0) return *this;
19828 if (amplitude<0 || sharpness<0 || anisotropy<0 || anisotropy>1 || alpha<0 || sigma<0 || dl<0 || da<0 || gauss_prec<0)
19829 throw CImgArgumentException("CImg<%s>::blur_anisotropic() : Given parameters are amplitude(%g), sharpness(%g), "
19830 "anisotropy(%g), alpha(%g), sigma(%g), dl(%g), da(%g), gauss_prec(%g).\n"
19831 "Admissible parameters are in the range : amplitude>0, sharpness>0, anisotropy in [0,1], "
19832 "alpha>0, sigma>0, dl>0, da>0, gauss_prec>0.",
19833 pixel_type(),amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec);
19834 const bool threed = (depth>1), no_mask = mask.is_empty();
19835 const float nsharpness = cimg::max(sharpness,1e-5f), power1 = 0.5f*nsharpness, power2 = power1/(1e-7f+1.0f-anisotropy);
19836 CImg<float> blurred = CImg<float>(*this,false).blur(alpha);
19837 if (geom_factor>0) blurred*=geom_factor;
19838 else blurred.normalize(0,-geom_factor);
19839
19840 if (threed) {
19841 #ifdef cimg_plugin_greycstoration
19842 greycstoration_mutex_lock(greycstoration_params[0]);
19843 #endif
19844 CImg<float> val(3), vec(3,3), G(blurred.get_structure_tensorXYZ());
19845 if (sigma>0) G.blur(sigma);
19846 cimg_forXYZ(*this,x,y,z) {
19847 if (no_mask || mask(x,y,z)) {
19848 G.get_tensor_at(x,y,z).symmetric_eigen(val,vec);
19849 const float l1 = val[2], l2 = val[1], l3 = val[0],
19850 ux = vec(0,0), uy = vec(0,1), uz = vec(0,2),
19851 vx = vec(1,0), vy = vec(1,1), vz = vec(1,2),
19852 wx = vec(2,0), wy = vec(2,1), wz = vec(2,2),
19853 n1 = (float)std::pow(1.0f+l1+l2+l3,-power1),
19854 n2 = (float)std::pow(1.0f+l1+l2+l3,-power2);
19855 G(x,y,z,0) = n1*(ux*ux + vx*vx) + n2*wx*wx;
19856 G(x,y,z,1) = n1*(ux*uy + vx*vy) + n2*wx*wy;
19857 G(x,y,z,2) = n1*(ux*uz + vx*vz) + n2*wx*wz;
19858 G(x,y,z,3) = n1*(uy*uy + vy*vy) + n2*wy*wy;
19859 G(x,y,z,4) = n1*(uy*uz + vy*vz) + n2*wy*wz;
19860 G(x,y,z,5) = n1*(uz*uz + vz*vz) + n2*wz*wz;
19861 } 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;
19862 #ifdef cimg_plugin_greycstoration
19863 if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter);
19864 else return *this;
19865 #endif
19866 }
19867 #ifdef cimg_plugin_greycstoration
19868 greycstoration_mutex_unlock(greycstoration_params[0]);
19869 #endif
19870 blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
19871 } else {
19872 #ifdef cimg_plugin_greycstoration
19873 greycstoration_mutex_lock(greycstoration_params[0]);
19874 #endif
19875 CImg<float> val(2), vec(2,2), G(blurred.get_structure_tensorXY());
19876 if (sigma>0) G.blur(sigma);
19877 cimg_forXY(*this,x,y) {
19878 if (no_mask || mask(x,y)) {
19879 G.get_tensor_at(x,y).symmetric_eigen(val,vec);
19880 const float l1 = val[1], l2 = val[0],
19881 ux = vec(1,0), uy = vec(1,1),
19882 vx = vec(0,0), vy = vec(0,1),
19883 n1 = (float)std::pow(1.0f+l1+l2,-power1),
19884 n2 = (float)std::pow(1.0f+l1+l2,-power2);
19885 G(x,y,0,0) = n1*ux*ux + n2*vx*vx;
19886 G(x,y,0,1) = n1*ux*uy + n2*vx*vy;
19887 G(x,y,0,2) = n1*uy*uy + n2*vy*vy;
19888 } else G(x,y,0,0) = G(x,y,0,1) = G(x,y,0,2) = 0;
19889 #ifdef cimg_plugin_greycstoration
19890 if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter);
19891 else return *this;
19892 #endif
19893 }
19894 #ifdef cimg_plugin_greycstoration
19895 greycstoration_mutex_unlock(greycstoration_params[0]);
19896 #endif
19897 blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
19898 }
19899 }
19900 return *this;
19901 }
19902
19904 CImg<T> get_blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
19905 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
19906 const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0,
19907 const bool fast_approx=true, const float geom_factor=1.0f) const {
19908 return (+*this).blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
19909 }
19910
19912 CImg<T>& blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
19913 const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f,
19914 const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true,
19915 const float geom_factor=1.0f) {
19916 return blur_anisotropic(CImg<T>(),amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
19917 }
19918
19920
19933 CImg<T> get_blur_bilateral(const float sigmax, const float sigmay, const float sigmaz, const float sigmar,
19934 const int bgridx, const int bgridy, const int bgridz, const int bgridr,
19935 const bool interpolation=true) const {
19936 return (+*this).blur_bilateral(sigmax,sigmay,sigmaz,sigmar,bgridx,bgridy,bgridz,bgridr,interpolation);
19937 }
19938
19940 CImg<T>& blur_bilateral(const float sigmax, const float sigmay, const float sigmaz, const float sigmar,
19941 const int bgridx, const int bgridy, const int bgridz, const int bgridr,
19942 const bool interpolation=true) {
19943 T m, M = maxmin(m);
19944 const float range = (float)(1.0f+M-m);
19945 const unsigned int
19946 bx0 = bgridx>=0?bgridx:width*(-bgridx)/100,
19947 by0 = bgridy>=0?bgridy:height*(-bgridy)/100,
19948 bz0 = bgridz>=0?bgridz:depth*(-bgridz)/100,
19949 br0 = bgridr>=0?bgridr:(int)(-range*bgridr/100),
19950 bx = bx0>0?bx0:1,
19951 by = by0>0?by0:1,
19952 bz = bz0>0?bz0:1,
19953 br = br0>0?br0:1;
19954 const float
19955 nsigmax = sigmax*bx/width,
19956 nsigmay = sigmay*by/height,
19957 nsigmaz = sigmaz*bz/depth,
19958 nsigmar = sigmar*br/range;
19959 if (nsigmax>0 || nsigmay>0 || nsigmaz>0 || nsigmar>0) {
19960 const bool threed = depth>1;
19961 if (threed) {
19962 typedef typename cimg::last<T,float>::type ftype;
19963 CImg<ftype> bgrid(bx,by,bz,br), bgridw(bx,by,bz,br);
19964 cimg_forV(*this,k) {
19965 bgrid.fill(0); bgridw.fill(0);
19966 cimg_forXYZ(*this,x,y,z) {
19967 const T val = (*this)(x,y,z,k);
19968 const int X = x*bx/width, Y = y*by/height, Z = z*bz/depth, R = (int)((val-m)*br/range);
19969 bgrid(X,Y,Z,R) = (float)val;
19970 bgridw(X,Y,Z,R) = 1;
19971 }
19972 bgrid.blur(nsigmax,nsigmay,nsigmaz,true).deriche(nsigmar,0,'v',false);
19973 bgridw.blur(nsigmax,nsigmay,nsigmaz,true).deriche(nsigmar,0,'v',false);
19974 if (interpolation) cimg_forXYZ(*this,x,y,z) {
19975 const T val = (*this)(x,y,z,k);
19976 const float X = (float)x*bx/width, Y = (float)y*by/height, Z = (float)z*bz/depth, R = (val-m)*br/range,
19977 bval0 = bgrid.linear_pix4d(X,Y,Z,R), bval1 = bgridw.linear_pix4d(X,Y,Z,R);
19978 (*this)(x,y,z,k) = (T)(bval0/bval1);
19979 } else cimg_forXYZ(*this,x,y,z) {
19980 const T val = (*this)(x,y,z,k);
19981 const int X = x*bx/width, Y = y*by/height, Z = z*bz/depth, R = (int)((val-m)*br/range);
19982 const float bval0 = bgrid(X,Y,Z,R), bval1 = bgridw(X,Y,Z,R);
19983 (*this)(x,y,z,k) = (T)(bval0/bval1);
19984 }
19985 }
19986 } else {
19987 typedef typename cimg::last<T,float>::type ftype;
19988 CImg<ftype> bgrid(bx,by,br,2);
19989 cimg_forV(*this,k) {
19990 bgrid.fill(0);
19991 cimg_forXY(*this,x,y) {
19992 const T val = (*this)(x,y,k);
19993 const int X = x*bx/width, Y = y*by/height, R = (int)((val-m)*br/range);
19994 bgrid(X,Y,R,0) = (float)val;
19995 bgrid(X,Y,R,1) = 1;
19996 }
19997 bgrid.blur(nsigmax,nsigmay,0,true).blur(0,0,nsigmar,false);
19998 if (interpolation) cimg_forXY(*this,x,y) {
19999 const T val = (*this)(x,y,k);
20000 const float X = (float)x*bx/width, Y = (float)y*by/height, R = (val-m)*br/range,
20001 bval0 = bgrid.linear_pix3d(X,Y,R,0), bval1 = bgrid.linear_pix3d(X,Y,R,1);
20002 (*this)(x,y,k) = (T)(bval0/bval1);
20003 } else cimg_forXY(*this,x,y) {
20004 const T val = (*this)(x,y,k);
20005 const int X = x*bx/width, Y = y*by/height, R = (int)((val-m)*br/range);
20006 const float bval0 = bgrid(X,Y,R,0), bval1 = bgrid(X,Y,R,1);
20007 (*this)(x,y,k) = (T)(bval0/bval1);
20008 }
20009 }
20010 }
20011 }
20012 return *this;
20013 }
20014
20016 CImg<T> get_blur_bilateral(const float sigmas, const float sigmar, const int bgrids=-33, const int bgridr=32,
20017 const bool interpolation=true) const {
20018 return (+*this).blur_bilateral(sigmas,sigmas,sigmas,sigmar,bgrids,bgrids,bgrids,bgridr,interpolation);
20019 }
20020
20022 CImg<T>& blur_bilateral(const float sigmas, const float sigmar, const int bgrids=-33, const int bgridr=32,
20023 const bool interpolation=true) {
20024 return blur_bilateral(sigmas,sigmas,sigmas,sigmar,bgrids,bgrids,bgrids,bgridr,interpolation);
20025 }
20026
20028 CImgList<typename cimg::superset<T,float>::type> get_FFT(const char axe, const bool inverse=false) const {
20029 typedef typename cimg::superset<T,float>::type restype;
20030 return CImgList<restype>(*this).FFT(axe,inverse);
20031 }
20032
20034 CImgList<typename cimg::superset<T,float>::type> get_FFT(const bool inverse=false) const {
20035 typedef typename cimg::superset<T,float>::type restype;
20036 return CImgList<restype>(*this).FFT(inverse);
20037 }
20038
20040 CImg<T> get_blur_median(const unsigned int n=3) {
20041 CImg<T> res(width,height,depth,dim);
20042 if (!n || n==1) return *this;
20043 const int hl=n/2, hr=hl-1+n%2;
20044 if (res.depth!=1) {
20045 CImg<T> vois;
20046 cimg_forXYZV(*this,x,y,z,k) {
20047 const int
20048 x0 = x - hl, y0 = y - hl, z0 = z-hl, x1 = x + hr, y1 = y + hr, z1 = z+hr,
20049 nx0 = x0<0?0:x0, ny0 = y0<0?0:y0, nz0 = z0<0?0:z0,
20050 nx1 = x1>=dimx()?dimx()-1:x1, ny1 = y1>=dimy()?dimy()-1:y1, nz1 = z1>=dimz()?dimz()-1:z1;
20051 vois = get_crop(nx0,ny0,nz0,k,nx1,ny1,nz1,k);
20052 res(x,y,z,k) = vois.median();
20053 }
20054 } else {
20055 #define _median_sort(a,b) if ((a)>(b)) cimg::swap(a,b)
20056 if (res.height!=1) switch (n) {
20057 case 3: {
20058 T I[9] = { 0 };
20059 CImg_3x3(J,T);
20060 cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) {
20061 std::memcpy(J,I,9*sizeof(T));
20062 _median_sort(Jcp, Jnp); _median_sort(Jcc, Jnc); _median_sort(Jcn, Jnn);
20063 _median_sort(Jpp, Jcp); _median_sort(Jpc, Jcc); _median_sort(Jpn, Jcn);
20064 _median_sort(Jcp, Jnp); _median_sort(Jcc, Jnc); _median_sort(Jcn, Jnn);
20065 _median_sort(Jpp, Jpc); _median_sort(Jnc, Jnn); _median_sort(Jcc, Jcn);
20066 _median_sort(Jpc, Jpn); _median_sort(Jcp, Jcc); _median_sort(Jnp, Jnc);
20067 _median_sort(Jcc, Jcn); _median_sort(Jcc, Jnp); _median_sort(Jpn, Jcc);
20068 _median_sort(Jcc, Jnp);
20069 res(x,y,0,k) = Jcc;
20070 }
20071 } break;
20072 case 5: {
20073 T I[25] = { 0 };
20074 CImg_5x5(J,T);
20075 cimg_forV(*this,k) cimg_for5x5(*this,x,y,0,k,I) {
20076 std::memcpy(J,I,25*sizeof(T));
20077 _median_sort(Jbb, Jpb); _median_sort(Jnb, Jab); _median_sort(Jcb, Jab); _median_sort(Jcb, Jnb);
20078 _median_sort(Jpp, Jcp); _median_sort(Jbp, Jcp); _median_sort(Jbp, Jpp); _median_sort(Jap, Jbc);
20079 _median_sort(Jnp, Jbc); _median_sort(Jnp, Jap); _median_sort(Jcc, Jnc); _median_sort(Jpc, Jnc);
20080 _median_sort(Jpc, Jcc); _median_sort(Jbn, Jpn); _median_sort(Jac, Jpn); _median_sort(Jac, Jbn);
20081 _median_sort(Jnn, Jan); _median_sort(Jcn, Jan); _median_sort(Jcn, Jnn); _median_sort(Jpa, Jca);
20082 _median_sort(Jba, Jca); _median_sort(Jba, Jpa); _median_sort(Jna, Jaa); _median_sort(Jcb, Jbp);
20083 _median_sort(Jnb, Jpp); _median_sort(Jbb, Jpp); _median_sort(Jbb, Jnb); _median_sort(Jab, Jcp);
20084 _median_sort(Jpb, Jcp); _median_sort(Jpb, Jab); _median_sort(Jpc, Jac); _median_sort(Jnp, Jac);
20085 _median_sort(Jnp, Jpc); _median_sort(Jcc, Jbn); _median_sort(Jap, Jbn); _median_sort(Jap, Jcc);
20086 _median_sort(Jnc, Jpn); _median_sort(Jbc, Jpn); _median_sort(Jbc, Jnc); _median_sort(Jba, Jna);
20087 _median_sort(Jcn, Jna); _median_sort(Jcn, Jba); _median_sort(Jpa, Jaa); _median_sort(Jnn, Jaa);
20088 _median_sort(Jnn, Jpa); _median_sort(Jan, Jca); _median_sort(Jnp, Jcn); _median_sort(Jap, Jnn);
20089 _median_sort(Jbb, Jnn); _median_sort(Jbb, Jap); _median_sort(Jbc, Jan); _median_sort(Jpb, Jan);
20090 _median_sort(Jpb, Jbc); _median_sort(Jpc, Jba); _median_sort(Jcb, Jba); _median_sort(Jcb, Jpc);
20091 _median_sort(Jcc, Jpa); _median_sort(Jnb, Jpa); _median_sort(Jnb, Jcc); _median_sort(Jnc, Jca);
20092 _median_sort(Jab, Jca); _median_sort(Jab, Jnc); _median_sort(Jac, Jna); _median_sort(Jbp, Jna);
20093 _median_sort(Jbp, Jac); _median_sort(Jbn, Jaa); _median_sort(Jpp, Jaa); _median_sort(Jpp, Jbn);
20094 _median_sort(Jcp, Jpn); _median_sort(Jcp, Jan); _median_sort(Jnc, Jpa); _median_sort(Jbn, Jna);
20095 _median_sort(Jcp, Jnc); _median_sort(Jcp, Jbn); _median_sort(Jpb, Jap); _median_sort(Jnb, Jpc);
20096 _median_sort(Jbp, Jcn); _median_sort(Jpc, Jcn); _median_sort(Jap, Jcn); _median_sort(Jab, Jbc);
20097 _median_sort(Jpp, Jcc); _median_sort(Jcp, Jac); _median_sort(Jab, Jpp); _median_sort(Jab, Jcp);
20098 _median_sort(Jcc, Jac); _median_sort(Jbc, Jac); _median_sort(Jpp, Jcp); _median_sort(Jbc, Jcc);
20099 _median_sort(Jpp, Jbc); _median_sort(Jpp, Jcn); _median_sort(Jcc, Jcn); _median_sort(Jcp, Jcn);
20100 _median_sort(Jcp, Jbc); _median_sort(Jcc, Jnn); _median_sort(Jcp, Jcc); _median_sort(Jbc, Jnn);
20101 _median_sort(Jcc, Jba); _median_sort(Jbc, Jba); _median_sort(Jbc, Jcc);
20102 res(x,y,0,k) = Jcc;
20103 }
20104 } break;
20105 default: {
20106 CImg<T> vois;
20107 cimg_forXYV(*this,x,y,k) {
20108 const int
20109 x0 = x - hl, y0 = y - hl, x1 = x + hr, y1 = y + hr,
20110 nx0 = x0<0?0:x0, ny0 = y0<0?0:y0,
20111 nx1 = x1>=dimx()?dimx()-1:x1, ny1 = y1>=dimy()?dimy()-1:y1;
20112 vois = get_crop(nx0,ny0,0,k,nx1,ny1,0,k);
20113 res(x,y,0,k) = vois.median();
20114 }
20115 } break;
20116 } else switch (n) {
20117 case 2: {
20118 T I[4] = { 0 };
20119 cimg_forV(*this,k) cimg_for2x2(*this,x,y,0,k,I) res(x,0,0,k) = (T)(0.5f*(I[0]+I[1]));
20120 } break;
20121 case 3: {
20122 T I[9] = { 0 };
20123 cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) {
20124 res(x,0,0,k) = I[3]<I[4]?
20125 (I[4]<I[5]?I[4]:
20126 (I[3]<I[5]?I[5]:I[3])):
20127 (I[3]<I[5]?I[3]:
20128 (I[4]<I[5]?I[5]:I[4]));
20129 }
20130 } break;
20131 default: {
20132 CImg<T> vois;
20133 cimg_forXV(*this,x,k) {
20134 const int
20135 x0 = x - hl, x1 = x + hr,
20136 nx0 = x0<0?0:x0, nx1 = x1>=dimx()?dimx()-1:x1;
20137 vois = get_crop(nx0,0,0,k,nx1,0,0,k);
20138 res(x,0,0,k) = vois.median();
20139 }
20140 } break;
20141 }
20142 }
20143 return res;
20144 }
20145
20147 CImg<T>& blur_median(const unsigned int n=3) {
20148 return get_blur_median(n).assign_to(*this);
20149 }
20150
20152 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 {
20153 return (+*this).sharpen(amplitude,edge,alpha,sigma);
20154 }
20155
20157 CImg<T>& sharpen(const float amplitude=50.0f, const float edge=1.0f, const float alpha=0.0f, const float sigma=0.0f) {
20158 if (is_empty()) return *this;
20159 const bool threed = (depth>1);
20160 const float nedge = 0.5f*edge;
20161 typedef typename cimg::superset<T,float>::type ftype;
20162 CImg<ftype> val, vec, veloc(width,height,depth,dim);
20163
20164 if (threed) {
20165 CImg<ftype> G = (alpha>0?get_blur(alpha).get_structure_tensorXYZ():get_structure_tensorXYZ());
20166 if (sigma>0) G.blur(sigma);
20167 CImg_3x3x3(I,float);
20168 cimg_forXYZ(G,x,y,z) {
20169 G.get_tensor_at(x,y,z).symmetric_eigen(val,vec);
20170 G(x,y,z,0) = vec(0,0);
20171 G(x,y,z,1) = vec(0,1);
20172 G(x,y,z,2) = vec(0,2);
20173 G(x,y,z,3) = 1.0f-(float)std::pow((float)(1+val[0]+val[1]+val[2]),-nedge);
20174 }
20175 cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
20176 const float
20177 u = G(x,y,z,0),
20178 v = G(x,y,z,1),
20179 w = G(x,y,z,2),
20180 amp = G(x,y,z,3),
20181 ixx = Incc+Ipcc-2*Iccc,
20182 ixy = 0.25f*(Innc+Ippc-Inpc-Ipnc),
20183 ixz = 0.25f*(Incn+Ipcp-Incp-Ipcn),
20184 iyy = Icnc+Icpc-2*Iccc,
20185 iyz = 0.25f*(Icnn+Icpp-Icnp-Icpn),
20186 izz = Iccn+Iccp-2*Iccc,
20187 ixf = Incc-Iccc,
20188 ixb = Iccc-Ipcc,
20189 iyf = Icnc-Iccc,
20190 iyb = Iccc-Icpc,
20191 izf = Iccn-Iccc,
20192 izb = Iccc-Iccp,
20193 itt = u*u*ixx + v*v*iyy + w*w*izz + 2*u*v*ixy + 2*u*w*ixz + 2*v*w*iyz,
20194 it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb) + w*cimg::minmod(izf,izb);
20195 veloc(x,y,z,k) = -amp*cimg::sign(itt)*cimg::abs(it);
20196 }
20197 } else {
20198 CImg<ftype> G = (alpha>0?get_blur(alpha).get_structure_tensorXY():get_structure_tensorXY());
20199 if (sigma>0) G.blur(sigma);
20200 CImg_3x3(I,float);
20201 cimg_forXY(G,x,y) {
20202 G.get_tensor_at(x,y).symmetric_eigen(val,vec);
20203 G(x,y,0) = vec(0,0);
20204 G(x,y,1) = vec(0,1);
20205 G(x,y,2) = 1.0f-(float)std::pow((float)(1+val[0]+val[1]),-nedge);
20206 }
20207 cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) {
20208 const float
20209 u = G(x,y,0),
20210 v = G(x,y,1),
20211 amp = G(x,y,2),
20212 ixx = Inc+Ipc-2*Icc,
20213 ixy = 0.25f*(Inn+Ipp-Inp-Ipn),
20214 iyy = Icn+Icp-2*Icc,
20215 ixf = Inc-Icc,
20216 ixb = Icc-Ipc,
20217 iyf = Icn-Icc,
20218 iyb = Icc-Icp,
20219 itt = u*u*ixx + v*v*iyy + 2*u*v*ixy,
20220 it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb);
20221 veloc(x,y,k) = -amp*cimg::sign(itt)*cimg::abs(it);
20222 }
20223 }
20224 float m, M = (float)veloc.maxmin(m);
20225 const float vmax = (float)cimg::max(cimg::abs(m),cimg::abs(M));
20226 if (vmax!=0) { veloc*=amplitude/vmax; (*this)+=veloc; }
20227 return *this;
20228 }
20229
20231
20236 CImg<typename cimg::superset<T,float>::type> get_haar(const char axis, const bool inverse=false, const unsigned int nb_scales=1) const {
20237 if (is_empty() || !nb_scales) return *this;
20238 typedef typename cimg::superset<T,float>::type ftype;
20239 CImg<ftype> res;
20240
20241 if (nb_scales==1) {
20242 switch (cimg::uncase(axis)) {
20243 case 'x': {
20244 const unsigned int w = width/2;
20245 if (w) {
20246 if (w%2) throw CImgInstanceException("CImg<%s>::haar() : Sub-image width = %u is not even at a particular scale (=%u).",pixel_type(),w);
20247 res.assign(width,height,depth,dim);
20248 if (inverse) cimg_forYZV(*this,y,z,v) {
20249 for (unsigned int x=0, xw=w, x2=0; x<w; ++x, ++xw) {
20250 const ftype val0 = (ftype)(*this)(x,y,z,v), val1 = (ftype)(*this)(xw,y,z,v);
20251 res(x2++,y,z,v) = val0 - val1;
20252 res(x2++,y,z,v) = val0 + val1;
20253 }
20254 } else cimg_forYZV(*this,y,z,v) {
20255 for (unsigned int x=0, xw=w, x2=0; x<w; ++x, ++xw) {
20256 const ftype val0 = (ftype)(*this)(x2++,y,z,v), val1 = (ftype)(*this)(x2++,y,z,v);
20257 res(x,y,z,v) = (val0 + val1)/2;
20258 res(xw,y,z,v) = (val1 - val0)/2;
20259 }
20260 }
20261 } else return *this;
20262 } break;
20263 case 'y': {
20264 const unsigned int h = height/2;
20265 if (h) {
20266 if (h%2) throw CImgInstanceException("CImg<%s>::haar() : Sub-image height = %u is not even at a particular scale.",pixel_type(),h);
20267 res.assign(width,height,depth,dim);
20268 if (inverse) cimg_forXZV(*this,x,z,v) {
20269 for (unsigned int y=0, yh=h, y2=0; y<h; ++y, ++yh) {
20270 const ftype val0 = (ftype)(*this)(x,y,z,v), val1 = (ftype)(*this)(x,yh,z,v);
20271 res(x,y2++,z,v) = val0 - val1;
20272 res(x,y2++,z,v) = val0 + val1;
20273 }
20274 } else cimg_forXZV(*this,x,z,v) {
20275 for (unsigned int y=0, yh=h, y2=0; y<h; ++y, ++yh) {
20276 const ftype val0 = (ftype)(*this)(x,y2++,z,v), val1 = (ftype)(*this)(x,y2++,z,v);
20277 res(x,y,z,v) = (val0 + val1)/2;
20278 res(x,yh,z,v) = (val1 - val0)/2;
20279 }
20280 }
20281 } else return *this;
20282 } break;
20283 case 'z': {
20284 const unsigned int d = depth/2;
20285 if (d) {
20286 if (d%2) throw CImgInstanceException("CImg<%s>::haar() : Sub-image depth = %u is not even at a particular scale.",pixel_type(),d);
20287 res.assign(width,height,depth,dim);
20288 if (inverse) cimg_forXYV(*this,x,y,v) {
20289 for (unsigned int z=0, zd=d, z2=0; z<d; ++z, ++zd) {
20290 const ftype val0 = (ftype)(*this)(x,y,z,v), val1 = (ftype)(*this)(x,y,zd,v);
20291 res(x,y,z2++,v) = val0 - val1;
20292 res(x,y,z2++,v) = val0 + val1;
20293 }
20294 } else cimg_forXYV(*this,x,y,v) {
20295 for (unsigned int z=0, zd=d, z2=0; z<d; ++z, ++zd) {
20296 const ftype val0 = (ftype)(*this)(x,y,z2++,v), val1 = (ftype)(*this)(x,y,z2++,v);
20297 res(x,y,z,v) = (val0 + val1)/2;
20298 res(x,y,zd,v) = (val1 - val0)/2;
20299 }
20300 }
20301 } else return *this;
20302 } break;
20303 default: throw CImgArgumentException("CImg<%s>::haar() : Unknown axis '%c'.",pixel_type(),axis); break;
20304 }
20305 } else {
20306 if (inverse) {
20307 res.assign(*this);
20308 switch (cimg::uncase(axis)) {
20309 case 'x': {
20310 unsigned int w = width;
20311 for (unsigned int s=1; w && s<nb_scales; ++s) w/=2;
20312 for (w=w?w:1; w<=width; w*=2) res.draw_image(res.get_crop(0,w-1).get_haar('x',true,1),0);
20313 } break;
20314 case 'y': {
20315 unsigned int h = width;
20316 for (unsigned int s=1; h && s<nb_scales; ++s) h/=2;
20317 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);
20318 } break;
20319 case 'z': {
20320 unsigned int d = depth;
20321 for (unsigned int s=1; d && s<nb_scales; ++s) d/=2;
20322 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);
20323 } break;
20324 default: throw CImgArgumentException("CImg<%s>::haar() : Unknown axis '%c'.",pixel_type(),axis); break;
20325 }
20326 } else {
20327 res = get_haar(axis,false,1);
20328 switch (cimg::uncase(axis)) {
20329 case 'x': {
20330 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);
20331 } break;
20332 case 'y': {
20333 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);
20334 } break;
20335 case 'z': {
20336 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);
20337 } break;
20338 default: throw CImgArgumentException("CImg<%s>::haar() : Unknown axis '%c'.",pixel_type(),axis); break;
20339 }
20340 }
20341 }
20342 return res;
20343 }
20344
20346 CImg<T>& haar(const char axis, const bool inverse=false, const unsigned int nb_scales=1) {
20347 return get_haar(axis,inverse,nb_scales).assign_to(*this);
20348 }
20349
20351
20355 CImg<typename cimg::superset<T,float>::type> get_haar(const bool inverse=false, const unsigned int nb_scales=1) const {
20356 typedef typename cimg::superset<T,float>::type ftype;
20357 CImg<ftype> res;
20358
20359 if (nb_scales==1) {
20360 if (width>1) get_haar('x',inverse,1).assign_to(res);
20361 if (height>1) { if (res) res.get_haar('y',inverse,1).assign_to(res); else get_haar('y',inverse,1).assign_to(res); }
20362 if (depth>1) { if (res) res.get_haar('z',inverse,1).assign_to(res); else get_haar('z',inverse,1).assign_to(res); }
20363 if (res) return res;
20364 } else {
20365 if (inverse) {
20366 res.assign(*this);
20367 if (width>1) {
20368 if (height>1) {
20369 if (depth>1) {
20370 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; }
20371 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)
20372 res.draw_image(res.get_crop(0,0,0,w-1,h-1,d-1).get_haar(true,1),0,0,0);
20373 } else {
20374 unsigned int w = width, h = height; for (unsigned int s=1; w && h && s<nb_scales; ++s) { w/=2; h/=2; }
20375 for (w=w?w:1, h=h?h:1; w<=width && h<=height; w*=2, h*=2)
20376 res.draw_image(res.get_crop(0,0,0,w-1,h-1,0).get_haar(true,1),0,0,0);
20377 }
20378 } else {
20379 if (depth>1) {
20380 unsigned int w = width, d = depth; for (unsigned int s=1; w && d && s<nb_scales; ++s) { w/=2; d/=2; }
20381 for (w=w?w:1, d=d?d:1; w<=width && d<=depth; w*=2, d*=2)
20382 res.draw_image(res.get_crop(0,0,0,w-1,0,d-1).get_haar(true,1),0,0,0);
20383 } else {
20384 unsigned int w = width; for (unsigned int s=1; w && s<nb_scales; ++s) w/=2;
20385 for (w=w?w:1; w<=width; w*=2)
20386 res.draw_image(res.get_crop(0,0,0,w-1,0,0).get_haar(true,1),0,0,0);
20387 }
20388 }
20389 } else {
20390 if (height>1) {
20391 if (depth>1) {
20392 unsigned int h = height, d = depth; for (unsigned int s=1; h && d && s<nb_scales; ++s) { h/=2; d/=2; }
20393 for (h=h?h:1, d=d?d:1; h<=height && d<=depth; h*=2, d*=2)
20394 res.draw_image(res.get_crop(0,0,0,0,h-1,d-1).get_haar(true,1),0,0,0);
20395 } else {
20396 unsigned int h = height; for (unsigned int s=1; h && s<nb_scales; ++s) h/=2;
20397 for (h=h?h:1; h<=height; h*=2)
20398 res.draw_image(res.get_crop(0,0,0,0,h-1,0).get_haar(true,1),0,0,0);
20399 }
20400 } else {
20401 if (depth>1) {
20402 unsigned int d = depth; for (unsigned int s=1; d && s<nb_scales; ++s) d/=2;
20403 for (d=d?d:1; d<=depth; d*=2)
20404 res.draw_image(res.get_crop(0,0,0,0,0,d-1).get_haar(true,1),0,0,0);
20405 } else return *this;
20406 }
20407 }
20408 } else {
20409 res = get_haar(false,1);
20410 if (width>1) {
20411 if (height>1) {
20412 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)
20413 res.draw_image(res.get_crop(0,0,0,w-1,h-1,d-1).haar(false,1),0,0,0);
20414 else for (unsigned int s=1, w=width/2, h=height/2; w && h && s<nb_scales; ++s, w/=2, h/=2)
20415 res.draw_image(res.get_crop(0,0,0,w-1,h-1,0).haar(false,1),0,0,0);
20416 } else {
20417 if (depth>1) for (unsigned int s=1, w=width/2, d=depth/2; w && d && s<nb_scales; ++s, w/=2, d/=2)
20418 res.draw_image(res.get_crop(0,0,0,w-1,0,d-1).haar(false,1),0,0,0);
20419 else for (unsigned int s=1, w=width/2; w && s<nb_scales; ++s, w/=2)
20420 res.draw_image(res.get_crop(0,0,0,w-1,0,0).haar(false,1),0,0,0);
20421 }
20422 } else {
20423 if (height>1) {
20424 if (depth>1) for (unsigned int s=1, h=height/2, d=depth/2; h && d && s<nb_scales; ++s, h/=2, d/=2)
20425 res.draw_image(res.get_crop(0,0,0,0,h-1,d-1).haar(false,1),0,0,0);
20426 else for (unsigned int s=1, h=height/2; h && s<nb_scales; ++s, h/=2)
20427 res.draw_image(res.get_crop(0,0,0,0,h-1,0).haar(false,1),0,0,0);
20428 } else {
20429 if (depth>1) for (unsigned int s=1, d=depth/2; d && s<nb_scales; ++s, d/=2)
20430 res.draw_image(res.get_crop(0,0,0,0,0,d-1).haar(false,1),0,0,0);
20431 else return *this;
20432 }
20433 }
20434 }
20435 return res;
20436 }
20437 return *this;
20438 }
20439
20441 CImg<T>& haar(const bool inverse=false, const unsigned int nb_scales=1) {
20442 return get_haar(inverse,nb_scales).assign_to(*this);
20443 }
20444
20446 CImg<typename cimg::superset<T,float>::type> get_displacement_field(const CImg<T>& reference,
20447 const float smooth=0.1f, const float precision=1e-6f,
20448 const unsigned int nb_scale=0,
20449 const unsigned int itermax=10000) const {
20450
20451 typedef typename cimg::superset<T,float>::type ftype;
20452 if (is_empty() || !reference) return *this;
20453 if (!is_sameXYZ(reference))
20454 throw CImgArgumentException("CImg<%s>::get_displacement_field() : Instance image (%u,%u,%u,%u,%p) and reference image (%u,%u,%u,%u,%p) "
20455 "must have same dimensions",
20456 pixel_type(),width,height,depth,dim,data,
20457 reference.width,reference.height,reference.depth,reference.dim,reference.data);
20458 const bool threed = depth>1;
20459 CImg<ftype> u(width,height,depth,threed?3:2,0);
20460
20461 const unsigned int nbs = nb_scale>0?nb_scale:(unsigned int)(2*std::log((double)(cimg::max(width,height,depth))));
20462 for (int scale=nbs-1; scale>=0; --scale) {
20463 const float fact = (float)std::pow(1.5f,-(float)scale);
20464 const unsigned int
20465 tnw = (unsigned int)(width*fact), nw = tnw?tnw:1,
20466 tnh = (unsigned int)(height*fact), nh = tnh?tnh:1,
20467 tnd = (unsigned int)(depth*fact), nd = tnd?tnd:1;
20468 CImg<ftype>
20469 I1 = get_resize(nw,nh,nd,1,3),
20470 I2 = reference.get_resize(nw,nh,nd,1,3);
20471 I1.norm_pointwise(1);
20472 I2.norm_pointwise(2);
20473 float m1, M1 = (float)I1.maxmin(m1), m2, M2 = (float)I2.maxmin(m2);
20474 const float M = cimg::max(cimg::abs(m1),cimg::abs(M1),cimg::abs(m2),cimg::abs(M2));
20475 I1/=M; I2/=M;
20476 u*=1.5;
20477 u.resize(nw,nh,nd,threed?3:2,3);
20478 float dt = 100, E = cimg::type<float>::max(), nprecision = nw*nh*nd*precision;
20479 const CImgList<ftype> dI = threed?I2.get_gradientXYZ():I2.get_gradientXY();
20480
20481 for (unsigned int iter=0; iter<itermax; ++iter) {
20482 const float Eold = E;
20483 E = 0;
20484 if (threed)
20485 cimg_for3XYZ(u,x,y,z) {
20486 const ftype
20487 X = x + u(x,y,z,0),
20488 Y = y + u(x,y,z,1),
20489 Z = z + u(x,y,z,2),
20490 deltaI = (ftype)(I2.linear_pix3d(X,Y,Z) - I1(x,y,z));
20491 float tmpf = 0;
20492 cimg_forV(u,k) {
20493 const ftype
20494 ux = 0.5f*(u(_n1x,y,z,k) - u(_p1x,y,z,k)),
20495 uy = 0.5f*(u(x,_n1y,z,k) - u(x,_p1y,z,k)),
20496 uz = 0.5f*(u(x,y,_n1z,k) - u(x,y,_p1z,k));
20497 u(x,y,z,k) = (ftype)( u(x,y,z,k) +
20498 dt*(-deltaI*dI[k].linear_pix3d(X,Y,Z) +
20499 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)))
20500 )/(1 + 6*smooth*dt);
20501 tmpf += (float)(ux*ux + uy*uy + uz*uz);
20502 }
20503 E += deltaI*deltaI + smooth * tmpf;
20504 }
20505 else cimg_for3XY(u,x,y) {
20506 const ftype
20507 X = x + u(x,y,0),
20508 Y = y + u(x,y,1),
20509 deltaI = (ftype)(I2.linear_pix2d(X,Y) - I1(x,y));
20510 float tmpf = 0;
20511 cimg_forV(u,k) {
20512 const ftype
20513 ux = 0.5f*(u(_n1x,y,k) - u(_p1x,y,k)),
20514 uy = 0.5f*(u(x,_n1y,k) - u(x,_p1y,k));
20515 u(x,y,k) = (ftype)( u(x,y,k) +
20516 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) ))
20517 )/(1 + 4*smooth*dt);
20518 tmpf += (float)(ux*ux + uy*uy);
20519 }
20520 E += deltaI*deltaI + smooth * tmpf;
20521 }
20522 if (cimg::abs(Eold-E)<nprecision) break;
20523 if (Eold<E) { dt/=2; if (dt<0.1) break; }
20524 }
20525 }
20526 return u;
20527 }
20528
20530 CImg<T>& displacement_field(const CImg<T>& reference, const float smooth=0.1f, const float precision=1e-6f,
20531 const unsigned int nb_scale=0, const unsigned int itermax=10000) {
20532 return get_displacement_field(reference,smooth,precision,nb_scale,itermax).assign_to(*this);
20533 }
20534
20536
20537
20539
20540
20541
20543 static CImg<T> vector(const T a0) {
20544 static CImg<T> r(1,1); r[0] = a0;
20545 return r;
20546 }
20547
20549 static CImg<T> vector(const T a0, const T a1) {
20550 static CImg<T> r(1,2); T *ptr = r.data;
20551 *(ptr++) = a0; *(ptr++) = a1;
20552 return r;
20553 }
20554
20556 static CImg<T> vector(const T a0, const T a1, const T a2) {
20557 static CImg<T> r(1,3); T *ptr = r.data;
20558 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2;
20559 return r;
20560 }
20561
20563 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3) {
20564 static CImg<T> r(1,4); T *ptr = r.data;
20565 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
20566 return r;
20567 }
20568
20570 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3, const T a4) {
20571 static CImg<T> r(1,5); T *ptr = r.data;
20572 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4;
20573 return r;
20574 }
20575
20577 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5) {
20578 static CImg<T> r(1,6); T *ptr = r.data;
20579 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5;
20580 return r;
20581 }
20582
20584 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20585 const T a4, const T a5, const T a6) {
20586 static CImg<T> r(1,7); T *ptr = r.data;
20587 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6;
20588 return r;
20589 }
20590
20592 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20593 const T a4, const T a5, const T a6, const T a7) {
20594 static CImg<T> r(1,8); T *ptr = r.data;
20595 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20596 return r;
20597 }
20598
20600 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20601 const T a4, const T a5, const T a6, const T a7, const T a8) {
20602 static CImg<T> r(1,9); T *ptr = r.data;
20603 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20604 *(ptr++) = a8;
20605 return r;
20606 }
20607
20609 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20610 const T a4, const T a5, const T a6, const T a7,
20611 const T a8, const T a9) {
20612 static CImg<T> r(1,10); T *ptr = r.data;
20613 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20614 *(ptr++) = a8; *(ptr++) = a9;
20615 return r;
20616 }
20617
20619 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20620 const T a4, const T a5, const T a6, const T a7,
20621 const T a8, const T a9, const T a10) {
20622 static CImg<T> r(1,11); T *ptr = r.data;
20623 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20624 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10;
20625 return r;
20626 }
20627
20629 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20630 const T a4, const T a5, const T a6, const T a7,
20631 const T a8, const T a9, const T a10, const T a11) {
20632 static CImg<T> r(1,12); T *ptr = r.data;
20633 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20634 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
20635 return r;
20636 }
20637
20639 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20640 const T a4, const T a5, const T a6, const T a7,
20641 const T a8, const T a9, const T a10, const T a11,
20642 const T a12) {
20643 static CImg<T> r(1,13); T *ptr = r.data;
20644 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20645 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12;
20646 return r;
20647 }
20648
20650 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20651 const T a4, const T a5, const T a6, const T a7,
20652 const T a8, const T a9, const T a10, const T a11,
20653 const T a12, const T a13) {
20654 static CImg<T> r(1,14); T *ptr = r.data;
20655 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20656 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13;
20657 return r;
20658 }
20659
20661 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20662 const T a4, const T a5, const T a6, const T a7,
20663 const T a8, const T a9, const T a10, const T a11,
20664 const T a12, const T a13, const T a14) {
20665 static CImg<T> r(1,15); T *ptr = r.data;
20666 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20667 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14;
20668 return r;
20669 }
20670
20672 static CImg<T> vector(const T a0, const T a1, const T a2, const T a3,
20673 const T a4, const T a5, const T a6, const T a7,
20674 const T a8, const T a9, const T a10, const T a11,
20675 const T a12, const T a13, const T a14, const T a15) {
20676 static CImg<T> r(1,16); T *ptr = r.data;
20677 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20678 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15;
20679 return r;
20680 }
20681
20683 template<int N> static CImg<T> vector(const int a0, const int a1, ...) {
20684 CImg<T> res(1,N);
20685 _CImg_stdarg(res,a0,a1,N,int);
20686 return res;
20687 }
20688
20690 template<int N> static CImg<T> vector(const double a0, const double a1, ...) {
20691 CImg<T> res(1,N);
20692 _CImg_stdarg(res,a0,a1,N,double);
20693 return res;
20694 }
20695
20697 static CImg<T> matrix(const T a0) {
20698 return vector(a0);
20699 }
20700
20702 static CImg<T> matrix(const T a0, const T a1,
20703 const T a2, const T a3) {
20704 static CImg<T> r(2,2); T *ptr = r.data;
20705 *(ptr++) = a0; *(ptr++) = a1;
20706 *(ptr++) = a2; *(ptr++) = a3;
20707 return r;
20708 }
20709
20711 static CImg<T> matrix(const T a0, const T a1, const T a2,
20712 const T a3, const T a4, const T a5,
20713 const T a6, const T a7, const T a8) {
20714 static CImg<T> r(3,3); T *ptr = r.data;
20715 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2;
20716 *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5;
20717 *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8;
20718 return r;
20719 }
20720
20722 static CImg<T> matrix(const T a0, const T a1, const T a2, const T a3,
20723 const T a4, const T a5, const T a6, const T a7,
20724 const T a8, const T a9, const T a10, const T a11,
20725 const T a12, const T a13, const T a14, const T a15) {
20726 static CImg<T> r(4,4); T *ptr = r.data;
20727 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
20728 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
20729 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
20730 *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15;
20731 return r;
20732 }
20733
20735 static CImg<T> matrix(const T a0, const T a1, const T a2, const T a3, const T a4,
20736 const T a5, const T a6, const T a7, const T a8, const T a9,
20737 const T a10, const T a11, const T a12, const T a13, const T a14,
20738 const T a15, const T a16, const T a17, const T a18, const T a19,
20739 const T a20, const T a21, const T a22, const T a23, const T a24) {
20740 static CImg<T> r(5,5); T *ptr = r.data;
20741 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4;
20742 *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9;
20743 *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14;
20744 *(ptr++) = a15; *(ptr++) = a16; *(ptr++) = a17; *(ptr++) = a18; *(ptr++) = a19;
20745 *(ptr++) = a20; *(ptr++) = a21; *(ptr++) = a22; *(ptr++) = a23; *(ptr++) = a24;
20746 return r;
20747 }
20748
20750 template<int M,int N> static CImg<T> matrix(const int a0, const int a1, ...) {
20751 CImg<T> res(M,N);
20752 _CImg_stdarg(res,a0,a1,M*N,int);
20753 return res;
20754 }
20755
20757 template<int M,int N> static CImg<T> matrix(const double a0, const double a1, ...) {
20758 CImg<T> res(M,N);
20759 _CImg_stdarg(res,a0,a1,M*N,double);
20760 return res;
20761 }
20762
20764 static CImg<T> tensor(const T a1) {
20765 return matrix(a1);
20766 }
20767
20769 static CImg<T> tensor(const T a1, const T a2, const T a3) {
20770 return matrix(a1,a2,a2,a3);
20771 }
20772
20774 static CImg<T> tensor(const T a1, const T a2, const T a3, const T a4, const T a5, const T a6) {
20775 return matrix(a1,a2,a3,a2,a4,a5,a3,a5,a6);
20776 }
20777
20779 static CImg<T> diagonal(const T a0) {
20780 return matrix(a0);
20781 }
20782
20784 static CImg<T> diagonal(const T a0, const T a1) {
20785 return matrix(a0,0,0,a1);
20786 }
20787
20789 static CImg<T> diagonal(const T a0, const T a1, const T a2) {
20790 return matrix(a0,0,0,0,a1,0,0,0,a2);
20791 }
20792
20794 static CImg<T> diagonal(const T a0, const T a1, const T a2, const T a3) {
20795 return matrix(a0,0,0,0,0,a1,0,0,0,0,a2,0,0,0,0,a3);
20796 }
20797
20799 static CImg<T> diagonal(const T a0, const T a1, const T a2, const T a3, const T a4) {
20800 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);
20801 }
20802
20804 template<int N> static CImg<T> diagonal(const int a0, ...) {
20805 CImg<T> res;
20806 if (N>0) {
20807 res.assign(N,N,1,1,0);
20808 va_list ap;
20809 va_start(ap,a0);
20810 res[0] = (T)a0;
20811 for (int i=1; i<N; ++i) res(i,i) = (T)va_arg(ap,int);
20812 va_end(ap);
20813 }
20814 return res;
20815 }
20816
20818 template<int N> static CImg<T> diagonal(const double a0, ...) {
20819 CImg<T> res;
20820 if (N>0) {
20821 res.assign(N,N,1,1,0);
20822 va_list ap;
20823 va_start(ap,a0);
20824 res[0] = (T)a0;
20825 for (int i=1; i<N; ++i) res(i,i) = (T)va_arg(ap,double);
20826 va_end(ap);
20827 }
20828 return res;
20829 }
20830
20832 static CImg<T> identity_matrix(const unsigned int N) {
20833 CImg<T> res(N,N,1,1,0);
20834 cimg_forX(res,x) res(x,x) = 1;
20835 return res;
20836 }
20837
20839 static CImg<T> sequence(const unsigned int N, const T a0, const T a1) {
20840 if (N) return CImg<T>(1,N).sequence(a0,a1);
20841 return CImg<T>();
20842 }
20843
20845 static CImg<T> rotation_matrix(const float x, const float y, const float z, const float w, const bool quaternion_data=false) {
20846 float X,Y,Z,W;
20847 if (!quaternion_data) {
20848 const float norm = (float)std::sqrt(x*x + y*y + z*z),
20849 nx = norm>0?x/norm:0,
20850 ny = norm>0?y/norm:0,
20851 nz = norm>0?z/norm:1,
20852 nw = norm>0?w:0,
20853 sina = (float)std::sin(nw/2),
20854 cosa = (float)std::cos(nw/2);
20855 X = nx*sina;
20856 Y = ny*sina;
20857 Z = nz*sina;
20858 W = cosa;
20859 } else {
20860 const float norm = (float)std::sqrt(x*x + y*y + z*z + w*w);
20861 if (norm>0) { X = x/norm; Y = y/norm; Z = z/norm; W = w/norm; }
20862 else { X = Y = Z = 0; W = 1; }
20863 }
20864 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;
20865 return CImg<T>::matrix((T)(1-2*(yy+zz)), (T)(2*(xy+zw)), (T)(2*(xz-yw)),
20866 (T)(2*(xy-zw)), (T)(1-2*(xx+zz)), (T)(2*(yz+xw)),
20867 (T)(2*(xz+yw)), (T)(2*(yz-xw)), (T)(1-2*(xx+yy)));
20868 }
20869
20871 CImg<T> get_vector_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const {
20872 static CImg<T> dest;
20873 if (dest.height!=dim) dest.assign(1,dim);
20874 const unsigned int whz = width*height*depth;
20875 const T *ptrs = ptr(x,y,z);
20876 T *ptrd = dest.data;
20877 cimg_forV(*this,k) { *(ptrd++) = *ptrs; ptrs+=whz; }
20878 return dest;
20879 }
20880
20882 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) {
20883 if (x<width && y<height && z<depth) {
20884 const unsigned int whz = width*height*depth;
20885 const t *ptrs = vec.data;
20886 T *ptrd = ptr(x,y,z);
20887 for (unsigned int k=cimg::min((unsigned int)vec.size(),dim); k; --k) { *ptrd = (T)*(ptrs++); ptrd+=whz; }
20888 }
20889 return *this;
20890 }
20891
20893 CImg<T> get_matrix_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const {
20894 const int n = (int)std::sqrt((double)dim);
20895 CImg<T> dest(n,n);
20896 cimg_forV(*this,k) dest[k]=(*this)(x,y,z,k);
20897 return dest;
20898 }
20899
20901 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) {
20902 return set_vector_at(mat,x,y,z);
20903 }
20904
20906 CImg<T> get_tensor_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const {
20907 if (dim==6) return tensor((*this)(x,y,z,0),(*this)(x,y,z,1),(*this)(x,y,z,2),
20908 (*this)(x,y,z,3),(*this)(x,y,z,4),(*this)(x,y,z,5));
20909 if (dim==3) return tensor((*this)(x,y,z,0),(*this)(x,y,z,1),(*this)(x,y,z,2));
20910 return tensor((*this)(x,y,z,0));
20911 }
20912
20914 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) {
20915 if (ten.height==2) {
20916 (*this)(x,y,z,0) = (T)ten[0];
20917 (*this)(x,y,z,1) = (T)ten[1];
20918 (*this)(x,y,z,2) = (T)ten[3];
20919 }
20920 else {
20921 (*this)(x,y,z,0) = (T)ten[0];
20922 (*this)(x,y,z,1) = (T)ten[1];
20923 (*this)(x,y,z,2) = (T)ten[2];
20924 (*this)(x,y,z,3) = (T)ten[4];
20925 (*this)(x,y,z,4) = (T)ten[5];
20926 (*this)(x,y,z,5) = (T)ten[8];
20927 }
20928 return *this;
20929 }
20930
20932 CImg<T> get_vector() const {
20933 return get_unroll('y');
20934 }
20935
20937 CImg<T>& vector() {
20938 return unroll('y');
20939 }
20940
20942 CImg<T> get_matrix() const {
20943 return (+*this).matrix();
20944 }
20945
20947 CImg<T>& matrix() {
20948 const unsigned int siz = size();
20949 switch (siz) {
20950 case 1: break;
20951 case 4: width = height = 2; break;
20952 case 9: width = height = 3; break;
20953 case 16: width = height = 4; break;
20954 case 25: width = height = 5; break;
20955 case 36: width = height = 6; break;
20956 case 49: width = height = 7; break;
20957 case 64: width = height = 8; break;
20958 case 81: width = height = 9; break;
20959 case 100: width = height = 10; break;
20960 default: {
20961 unsigned int i = 11, i2 = i*i;
20962 while (i2<siz) { i2+=2*i+1; ++i; }
20963 if (i2==siz) width = height = i;
20964 else throw CImgInstanceException("CImg<%s>::matrix() : Image size = %u is not a square number",pixel_type(),siz);
20965 } break;
20966 }
20967 return *this;
20968 }
20969
20971 CImg<T> get_tensor() const {
20972 CImg<T> res;
20973 const unsigned int siz = size();
20974 switch (siz) {
20975 case 1: break;
20976 case 3:
20977 res.assign(2,2);
20978 res(0,0) = (*this)(0);
20979 res(1,0) = res(0,1) = (*this)(1);
20980 res(1,1) = (*this)(2);
20981 break;
20982 case 6:
20983 res.assign(3,3);
20984 res(0,0) = (*this)(0);
20985 res(1,0) = res(0,1) = (*this)(1);
20986 res(2,0) = res(0,2) = (*this)(2);
20987 res(1,1) = (*this)(3);
20988 res(2,1) = res(1,2) = (*this)(4);
20989 res(2,2) = (*this)(5);
20990 break;
20991 default:
20992 throw CImgInstanceException("CImg<%s>::tensor() : Wrong vector dimension = %u in instance image.",
20993 pixel_type(), dim);
20994 break;
20995 }
20996 return res;
20997 }
20998
21000 CImg<T>& tensor() {
21001 return get_tensor().assign_to(*this);
21002 }
21003
21005 CImg<T> get_unroll(const char axe='x') const {
21006 return (+*this).unroll(axe);
21007 }
21008
21010 CImg<T>& unroll(const char axe='x') {
21011 const unsigned int siz = size();
21012 if (siz) switch (axe) {
21013 case 'x': width = siz; height=depth=dim=1; break;
21014 case 'y': height = siz; width=depth=dim=1; break;
21015 case 'z': depth = siz; width=height=dim=1; break;
21016 case 'v': dim = siz; width=height=depth=1; break;
21017 default: throw CImgArgumentException("CImg<%s>::unroll() : Given axe is '%c' which is not 'x','y','z' or 'v'",
21018 pixel_type(),axe);
21019 }
21020 return *this;
21021 }
21022
21024 CImg<T> get_diagonal() const {
21025 if (is_empty()) return CImg<T>();
21026 CImg<T> res(size(),size(),1,1,0);
21027 cimg_foroff(*this,off) res(off,off) = (*this)(off);
21028 return res;
21029 }
21030
21032 CImg<T>& diagonal() {
21033 return get_diagonal().assign_to(*this);
21034 }
21035
21037 CImg<T> get_identity_matrix() const {
21038 return identity_matrix(cimg::max(width,height));
21039 }
21040
21042 CImg<T>& identity_matrix() {
21043 return identity_matrix(cimg::max(width,height)).assign_to(*this);
21044 }
21045
21047 CImg<T> get_sequence(const T a0, const T a1) const {
21048 return (+*this).sequence(a0,a1);
21049 }
21050
21052 CImg<T>& sequence(const T a0, const T a1) {
21053 if (!is_empty()) {
21054 const unsigned int siz = size()-1;
21055 const float delta = (float)((float)a1-a0);
21056 T* ptr = data;
21057 cimg_foroff(*this,l) *(ptr++) = (T)(a0 + delta*l/siz);
21058 }
21059 return *this;
21060 }
21061
21063 CImg<T> get_transpose() const {
21064 return get_permute_axes("yxzv");
21065 }
21066
21068 CImg<T>& transpose() {
21069 if (width==1) { width=height; height=1; return *this; }
21070 if (height==1) { height=width; width=1; return *this; }
21071 if (width==height) {
21072 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));
21073 return *this;
21074 }
21075 return get_transpose().assign_to(*this);
21076 }
21077
21079 CImg<typename cimg::superset<T,float>::type> get_inverse(const bool use_LU=true) const {
21080 typedef typename cimg::superset<T,float>::type restype;
21081 return CImg<restype>(*this,false).inverse(use_LU);
21082 }
21083
21085 CImg<T>& inverse(const bool use_LU=true) {
21086 if (!is_empty()) {
21087 if (width!=height || depth!=1 || dim!=1)
21088 throw CImgInstanceException("CImg<%s>::inverse() : Instance matrix (%u,%u,%u,%u,%p) is not square.",
21089 pixel_type(),width,height,depth,dim,data);
21090 #ifdef cimg_use_lapack
21091 typedef typename cimg::superset<T,float>::type ftype;
21092 int INFO = (int)use_LU, N = width, LWORK = 4*N, *IPIV = new int[N];
21093 ftype
21094 *lapA = new ftype[N*N],
21095 *WORK = new ftype[LWORK];
21096 cimg_forXY(*this,k,l) lapA[k*N+l] = (ftype)((*this)(k,l));
21097 cimg::getrf(N,lapA,IPIV,INFO);
21098 if (INFO) cimg::warn("CImg<%s>::inverse() : LAPACK library function dgetrf_() returned error code %d.",pixel_type(),INFO);
21099 else {
21100 cimg::getri(N,lapA,IPIV,WORK,LWORK,INFO);
21101 if (INFO) cimg::warn("CImg<%s>::inverse() : LAPACK library function dgetri_() returned Error code %d",pixel_type(),INFO);
21102 }
21103 if (!INFO) cimg_forXY(*this,k,l) (*this)(k,l) = (T)(lapA[k*N+l]); else fill(0);
21104 delete[] IPIV; delete[] lapA; delete[] WORK;
21105 #else
21106 const double dete = width>3?-1.0:det();
21107 if (dete!=0.0 && width==2) {
21108 const double
21109 a = data[0], c = data[1],
21110 b = data[2], d = data[3];
21111 data[0] = (T)(d/dete); data[1] = (T)(-c/dete);
21112 data[2] = (T)(-b/dete); data[3] = (T)(a/dete);
21113 } else if (dete!=0.0 && width==3) {
21114 const double
21115 a = data[0], d = data[1], g = data[2],
21116 b = data[3], e = data[4], h = data[5],
21117 c = data[6], f = data[7], i = data[8];
21118 data[0] = (T)((i*e-f*h)/dete), data[1] = (T)((g*f-i*d)/dete), data[2] = (T)((d*h-g*e)/dete);
21119 data[3] = (T)((h*c-i*b)/dete), data[4] = (T)((i*a-c*g)/dete), data[5] = (T)((g*b-a*h)/dete);
21120 data[6] = (T)((b*f-e*c)/dete), data[7] = (T)((d*c-a*f)/dete), data[8] = (T)((a*e-d*b)/dete);
21121 } else {
21122 typedef typename cimg::superset<float,T>::type ftype;
21123 if (use_LU) {
21124 CImg<ftype> A(*this), indx, col(1,width);
21125 bool d;
21126 A._LU(indx,d);
21127 cimg_forX(*this,j) {
21128 col.fill(0);
21129 col(j) = 1;
21130 col._solve(A,indx);
21131 cimg_forX(*this,i) (*this)(j,i) = (T)col(i);
21132 }
21133 } else {
21134 CImg<ftype> U(width,width), S(1,width), V(width,width);
21135 SVD(U,S,V,false);
21136 U.transpose();
21137 cimg_forY(S,k) if (S[k]!=0) S[k]=1/S[k];
21138 S.diagonal();
21139 *this = V*S*U;
21140 }
21141 }
21142 #endif
21143 }
21144 return *this;
21145 }
21146
21148 CImg<typename cimg::superset<T,float>::type> get_pseudoinverse() const {
21149 typedef typename cimg::superset<T,float>::type restype;
21150 CImg<restype> U, S, V;
21151 SVD(U,S,V);
21152 cimg_forX(V,x) {
21153 const float s = S(x), invs = s!=0.0f?1.0f/s:0.0f;
21154 cimg_forY(V,y) V(x,y)*=invs;
21155 }
21156 return V*U.transpose();
21157 }
21158
21160 CImg<T>& pseudoinverse() {
21161 return get_pseudoinverse().assign_to(*this);
21162 }
21163
21165 template<typename t> CImg<typename cimg::superset<T,t>::type> get_cross(const CImg<t>& img) const {
21166 typedef typename cimg::superset<T,t>::type restype;
21167 return CImg<restype>(*this).cross(img);
21168 }
21169
21171 template<typename t> CImg<T>& cross(const CImg<t>& img) {
21172 if (width!=1 || height<3 || img.width!=1 || img.height<3)
21173 throw CImgInstanceException("CImg<%s>::cross() : Arguments (%u,%u,%u,%u,%p) and (%u,%u,%u,%u,%p) must be both 3d vectors.",
21174 pixel_type(),width,height,depth,dim,data,img.width,img.height,img.depth,img.dim,img.data);
21175 const T x = (*this)[0], y = (*this)[1], z = (*this)[2];
21176 (*this)[0] = (T)(y*img[2]-z*img[1]);
21177 (*this)[1] = (T)(z*img[0]-x*img[2]);
21178 (*this)[2] = (T)(x*img[1]-y*img[0]);
21179 return *this;
21180 }
21181
21183 template<typename t> CImg<typename cimg::superset2<T,t,float>::type> get_solve(const CImg<t>& A) const {
21184 typedef typename cimg::superset2<T,t,float>::type restype;
21185 return CImg<restype>(*this,false).solve(A);
21186 }
21187
21189 template<typename t> CImg<T>& solve(const CImg<t>& A) {
21190 if (width!=1 || depth!=1 || dim!=1 || height!=A.height || A.depth!=1 || A.dim!=1)
21191 throw CImgArgumentException("CImg<%s>::solve() : Instance matrix size is (%u,%u,%u,%u) while "
21192 "size of given matrix A is (%u,%u,%u,%u).",
21193 pixel_type(),width,height,depth,dim,A.width,A.height,A.depth,A.dim);
21194
21195 typedef typename cimg::superset2<T,t,float>::type ftype;
21196 if (A.width==A.height) {
21197 #ifdef cimg_use_lapack
21198 char TRANS='N';
21199 int INFO, N = height, LWORK = 4*N, one = 1, *IPIV = new int[N];
21200 ftype
21201 *lapA = new ftype[N*N],
21202 *lapB = new ftype[N],
21203 *WORK = new ftype[LWORK];
21204 cimg_forXY(A,k,l) lapA[k*N+l] = (ftype)(A(k,l));
21205 cimg_forY(*this,i) lapB[i] = (ftype)((*this)(i));
21206 cimg::getrf(N,lapA,IPIV,INFO);
21207 if (INFO) cimg::warn("CImg<%s>::solve() : LAPACK library function dgetrf_() returned error code %d.",pixel_type(),INFO);
21208 if (!INFO) {
21209 cimg::getrs(TRANS,N,lapA,IPIV,lapB,INFO);
21210 if (INFO) cimg::warn("CImg<%s>::solve() : LAPACK library function dgetrs_() returned Error code %d",pixel_type(),INFO);
21211 }
21212 if (!INFO) cimg_forY(*this,i) (*this)(i) = (T)(lapB[i]); else fill(0);
21213 delete[] IPIV; delete[] lapA; delete[] lapB; delete[] WORK;
21214 #else
21215 CImg<ftype> lu(A);
21216 CImg<ftype> indx;
21217 bool d;
21218 lu._LU(indx,d);
21219 _solve(lu,indx);
21220 #endif
21221 } else assign(A.get_pseudoinverse()*(*this));
21222 return *this;
21223 }
21224
21225 template<typename t, typename ti> CImg<T>& _solve(const CImg<t>& A, const CImg<ti>& indx) {
21226 typedef typename cimg::superset2<T,t,float>::type ftype;
21227 const int N = size();
21228 int ii = -1;
21229 ftype sum;
21230 for (int i=0; i<N; ++i) {
21231 const int ip = (int)indx[i];
21232 ftype sum = (*this)(ip);
21233 (*this)(ip) = (*this)(i);
21234 if (ii>=0) for (int j=ii; j<=i-1; ++j) sum-=A(j,i)*(*this)(j);
21235 else if (sum!=0) ii=i;
21236 (*this)(i) = (T)sum;
21237 }
21238 { for (int i=N-1; i>=0; --i) {
21239 sum = (*this)(i);
21240 for (int j=i+1; j<N; ++j) sum-=A(j,i)*(*this)(j);
21241 (*this)(i) = (T)(sum/A(i,i));
21242 }}
21243 return *this;
21244 }
21245
21247 template<typename t> CImg<T> get_sort(CImg<t>& permutations, const bool increasing=true) const {
21248 return (+*this).sort(permutations,increasing);
21249 }
21250
21252 template<typename t>
21253 CImg<T>& sort(CImg<t>& permutations, const bool increasing=true) {
21254 if (is_empty()) permutations.assign();
21255 else {
21256 if (permutations.size()!=size()) permutations.assign(size());
21257 cimg_foroff(permutations,off) permutations[off] = (t)off;
21258 _quicksort(0,size()-1,permutations,increasing);
21259 }
21260 return *this;
21261 }
21262
21263
21264 CImg<T> get_sort(const bool increasing=true) const {
21265 return (+*this).sort(increasing);
21266 }
21267
21269 CImg<T>& sort(const bool increasing=true) {
21270 CImg<T> foo;
21271 return sort(foo,increasing);
21272 }
21273
21274 template<typename t> CImg<T>& _quicksort(const int min, const int max, CImg<t>& permutations, const bool increasing) {
21275 if (min<max) {
21276 const int mid = (min+max)/2;
21277 if (increasing) {
21278 if ((*this)[min]>(*this)[mid]) {
21279 cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
21280 if ((*this)[mid]>(*this)[max]) {
21281 cimg::swap((*this)[max],(*this)[mid]); cimg::swap(permutations[max],permutations[mid]); }
21282 if ((*this)[min]>(*this)[mid]) {
21283 cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
21284 } else {
21285 if ((*this)[min]<(*this)[mid]) {
21286 cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
21287 if ((*this)[mid]<(*this)[max]) {
21288 cimg::swap((*this)[max],(*this)[mid]); cimg::swap(permutations[max],permutations[mid]); }
21289 if ((*this)[min]<(*this)[mid]) {
21290 cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
21291 }
21292 if (max-min>=3) {
21293 const T pivot = (*this)[mid];
21294 int i = min, j = max;
21295 if (increasing) {
21296 do {
21297 while ((*this)[i]<pivot) ++i;
21298 while ((*this)[j]>pivot) --j;
21299 if (i<=j) {
21300 cimg::swap((*this)[i],(*this)[j]);
21301 cimg::swap(permutations[i++],permutations[j--]);
21302 }
21303 } while (i<=j);
21304 } else {
21305 do {
21306 while ((*this)[i]>pivot) ++i;
21307 while ((*this)[j]<pivot) --j;
21308 if (i<=j) {
21309 cimg::swap((*this)[i],(*this)[j]);
21310 cimg::swap(permutations[i++],permutations[j--]);
21311 }
21312 } while (i<=j);
21313 }
21314 if (min<j) _quicksort(min,j,permutations,increasing);
21315 if (i<max) _quicksort(i,max,permutations,increasing);
21316 }
21317 }
21318 return *this;
21319 }
21320
21322 template<typename t> CImg<T> get_permute(const CImg<t>& permutation) const {
21323 if (permutation.size()!=size())
21324 throw CImgArgumentException("CImg<%s>::permute() : Instance image (%u,%u,%u,%u,%p) and permutation (%u,%u,%u,%u,%p)"
21325 "have different sizes.",pixel_type(),
21326 width,height,depth,dim,data,
21327 permutation.width,permutation.height,permutation.depth,permutation.dim,permutation.data);
21328 CImg<T> res(width,height,depth,dim);
21329 const t *p = permutation.ptr(permutation.size());
21330 cimg_for(res,ptr,T) *ptr = (*this)[*(--p)];
21331 return res;
21332 }
21333
21335 template<typename t> CImg<T>& permute(const CImg<t>& permutation) {
21336 return get_permute(permutation).assign_to(*this);
21337 }
21338
21340 template<typename t> const CImg<T>& SVD(CImg<t>& U, CImg<t>& S, CImg<t>& V,
21341 const bool sorting=true, const unsigned int max_iter=40, const float lambda=0) const {
21342 if (is_empty()) { U.assign(); S.assign(); V.assign(); }
21343 else {
21344 #ifdef cimg_use_lapack
21345 typedef typename cimg::superset<T,float>::type ftype;
21346 int M = height, N = width, mn = cimg::min(M,N), MN = cimg::max(M,N), LWORK = 4*mn+2*MN, INFO;
21347 char JOB='A';
21348 ftype
21349 *lapA = new ftype[M*N],
21350 *lapS = new ftype[mn],
21351 *lapU = new ftype[M*M],
21352 *lapV = new ftype[N*N],
21353 *WORK = new ftype[LWORK];
21354 cimg_forXY(*this,k,l) lapA[k*N+l] = (ftype)((*this)(k,l));
21355 cimg::gesvd(JOB,M,N,lapA,MN,lapS,lapU,lapV,WORK,LWORK,INFO);
21356 if (INFO) cimg::warn("CImg<%s>::SVD() : LAPACK library function gesvd_() returned error code %d.",pixel_type(),INFO);
21357 U.assign(M,M);
21358 S.assign(1,mn);
21359 V.assign(N,N);
21360 if (!INFO) {
21361 cimg_forY(S,i) S(i) = (T)(lapS[i]);
21362 cimg_forXY(U,p,q) U(p,q) = (T)(lapU[p*N+q]);
21363 cimg_forXY(V,k,l) V(l,k) = (T)(lapV[k*N+l]);
21364 } else { S.fill(0); U.fill(0); V.fill(0); }
21365 delete[] lapA; delete[] lapS; delete[] lapU; delete[] lapV; delete[] WORK;
21366 #else
21367 U = *this;
21368 if (lambda!=0.0f) {
21369 const unsigned int delta = cimg::min(U.width,U.height);
21370 for (unsigned int i=0; i<delta; ++i) U(i,i) = (t)(U(i,i) + lambda);
21371 }
21372 if (S.size()<width) S.assign(1,width);
21373 if (V.width<width || V.height<height) V.assign(width,width);
21374 CImg<t> rv1(width);
21375 t anorm = 0, c, f, g = 0, h, s, scale = 0;
21376 int l = 0, nm = 0;
21377
21378 cimg_forX(U,i) {
21379 l = i+1; rv1[i] = scale*g; g = s = scale = 0;
21380 if (i<dimy()) {
21381 for (int k=i; k<dimy(); ++k) scale+= cimg::abs(U(i,k));
21382 if (scale) {
21383 for (int k=i; k<dimy(); ++k) { U(i,k)/=scale; s+= U(i,k)*U(i,k); }
21384 f = U(i,i); g = (t)((f>=0?-1:1)*std::sqrt(s)); h=f*g-s; U(i,i) = f-g;
21385 for (int j=l; j<dimx(); ++j) {
21386 s = 0; for (int k=i; k<dimy(); ++k) s+= U(i,k)*U(j,k);
21387 f = s/h;
21388 { for (int k=i; k<dimy(); ++k) U(j,k)+= f*U(i,k); }
21389 }
21390 { for (int k=i; k<dimy(); ++k) U(i,k)*= scale; }
21391 }
21392 }
21393 S[i]=scale*g;
21394
21395 g = s = scale = 0;
21396 if (i<dimy() && i!=dimx()-1) {
21397 for (int k=l; k<dimx(); ++k) scale += cimg::abs(U(k,i));
21398 if (scale) {
21399 for (int k=l; k<dimx(); ++k) { U(k,i)/= scale; s+= U(k,i)*U(k,i); }
21400 f = U(l,i); g = (t)((f>=0?-1:1)*std::sqrt(s)); h = f*g-s; U(l,i) = f-g;
21401 { for (int k=l; k<dimx(); ++k) rv1[k]=U(k,i)/h; }
21402 for (int j=l; j<dimy(); ++j) {
21403 s = 0; for (int k=l; k<dimx(); ++k) s+= U(k,j)*U(k,i);
21404 { for (int k=l; k<dimx(); ++k) U(k,j)+= s*rv1[k]; }
21405 }
21406 { for (int k=l; k<dimx(); ++k) U(k,i)*= scale; }
21407 }
21408 }
21409 anorm = (t)cimg::max((float)anorm,(float)(cimg::abs(S[i])+cimg::abs(rv1[i])));
21410 }
21411
21412 { for (int i=dimx()-1; i>=0; --i) {
21413 if (i<dimx()-1) {
21414 if (g) {
21415 { for (int j=l; j<dimx(); ++j) V(i,j) =(U(j,i)/U(l,i))/g; }
21416 for (int j=l; j<dimx(); ++j) {
21417 s = 0; for (int k=l; k<dimx(); ++k) s+= U(k,i)*V(j,k);
21418 { for (int k=l; k<dimx(); ++k) V(j,k)+= s*V(i,k); }
21419 }
21420 }
21421 for (int j=l; j<dimx(); ++j) V(j,i) = V(i,j) = (t)0.0;
21422 }
21423 V(i,i) = (t)1.0; g = rv1[i]; l = i;
21424 }
21425 }
21426
21427 { for (int i=cimg::min(dimx(),dimy())-1; i>=0; --i) {
21428 l = i+1; g = S[i];
21429 for (int j=l; j<dimx(); ++j) U(j,i) = 0;
21430 if (g) {
21431 g = 1/g;
21432 for (int j=l; j<dimx(); ++j) {
21433 s = 0; for (int k=l; k<dimy(); ++k) s+= U(i,k)*U(j,k);
21434 f = (s/U(i,i))*g;
21435 { for (int k=i; k<dimy(); ++k) U(j,k)+= f*U(i,k); }
21436 }
21437 { for (int j=i; j<dimy(); ++j) U(i,j)*= g; }
21438 } else for (int j=i; j<dimy(); ++j) U(i,j) = 0;
21439 ++U(i,i);
21440 }
21441 }
21442
21443 for (int k=dimx()-1; k>=0; --k) {
21444 for (unsigned int its=0; its<max_iter; ++its) {
21445 bool flag = true;
21446 for (l=k; l>=1; --l) {
21447 nm = l-1;
21448 if ((cimg::abs(rv1[l])+anorm)==anorm) { flag = false; break; }
21449 if ((cimg::abs(S[nm])+anorm)==anorm) break;
21450 }
21451 if (flag) {
21452 c = 0; s = 1;
21453 for (int i=l; i<=k; ++i) {
21454 f = s*rv1[i]; rv1[i] = c*rv1[i];
21455 if ((cimg::abs(f)+anorm)==anorm) break;
21456 g = S[i]; h = (t)cimg::pythagore(f,g); S[i] = h; h = 1/h; c = g*h; s = -f*h;
21457 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; }
21458 }
21459 }
21460 const t z = S[k];
21461 if (l==k) { if (z<0) { S[k] = -z; cimg_forX(U,j) V(k,j) = -V(k,j); } break; }
21462 nm = k-1;
21463 t x = S[l], y = S[nm];
21464 g = rv1[nm]; h = rv1[k];
21465 f = ((y-z)*(y+z)+(g-h)*(g+h))/(2*h*y);
21466 g = (t)cimg::pythagore(f,1.0);
21467 f = ((x-z)*(x+z)+h*((y/(f+ (f>=0?g:-g)))-h))/x;
21468 c = s = 1;
21469 for (int j=l; j<=nm; ++j) {
21470 const int i = j+1;
21471 g = rv1[i]; h = s*g; g = c*g;
21472 t y = S[i];
21473 t z = (t)cimg::pythagore(f,h);
21474 rv1[j] = z; c = f/z; s = h/z;
21475 f = x*c+g*s; g = g*c-x*s; h = y*s; y*=c;
21476 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; }
21477 z = (t)cimg::pythagore(f,h); S[j] = z;
21478 if (z) { z = 1/z; c = f*z; s = h*z; }
21479 f = c*g+s*y; x = c*y-s*g;
21480 { 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; }}
21481 }
21482 rv1[l] = 0; rv1[k]=f; S[k]=x;
21483 }
21484 }
21485
21486 if (sorting) {
21487 CImg<int> permutations(width);
21488 CImg<t> tmp(width);
21489 S.sort(permutations,false);
21490 cimg_forY(U,k) {
21491 cimg_forX(permutations,x) tmp(x) = U(permutations(x),k);
21492 std::memcpy(U.ptr(0,k),tmp.data,sizeof(t)*width);
21493 }
21494 { cimg_forY(V,k) {
21495 cimg_forX(permutations,x) tmp(x) = V(permutations(x),k);
21496 std::memcpy(V.ptr(0,k),tmp.data,sizeof(t)*width);
21497 }}
21498 }
21499 #endif
21500 }
21501 return *this;
21502 }
21503
21505 template<typename t> const CImg<T>& SVD(CImgList<t>& USV) const {
21506 if (USV.size<3) USV.assign(3);
21507 return SVD(USV[0],USV[1],USV[2]);
21508 }
21509
21511 CImgList<typename cimg::superset<T,float>::type> get_SVD(const bool sorting=true) const {
21512 typedef typename cimg::superset<T,float>::type restype;
21513 CImgList<restype> res(3);
21514 SVD(res[0],res[1],res[2],sorting);
21515 return res;
21516 }
21517
21518
21519 template<typename t> CImg<T>& _LU(CImg<t>& indx, bool& d) {
21520 typedef typename cimg::superset<T,float>::type ftype;
21521 const int N = dimx();
21522 int imax = 0;
21523 CImg<ftype> vv(N);
21524 indx.assign(N);
21525 d = true;
21526 cimg_forX(*this,i) {
21527 ftype vmax = 0;
21528 cimg_forX(*this,j) {
21529 const ftype tmp = cimg::abs((*this)(j,i));
21530 if (tmp>vmax) vmax = tmp;
21531 }
21532 if (vmax==0) { indx.fill(0); return fill(0); }
21533 vv[i] = 1/vmax;
21534 }
21535 cimg_forX(*this,j) {
21536 for (int i=0; i<j; ++i) {
21537 ftype sum=(*this)(j,i);
21538 for (int k=0; k<i; ++k) sum-=(*this)(k,i)*(*this)(j,k);
21539 (*this)(j,i) = (T)sum;
21540 }
21541 ftype vmax = 0;
21542 { for (int i=j; i<dimx(); ++i) {
21543 ftype sum=(*this)(j,i);
21544 for (int k=0; k<j; ++k) sum-=(*this)(k,i)*(*this)(j,k);
21545 (*this)(j,i) = (T)sum;
21546 const ftype tmp = vv[i]*cimg::abs(sum);
21547 if (tmp>=vmax) { vmax=tmp; imax=i; }
21548 }}
21549 if (j!=imax) {
21550 cimg_forX(*this,k) cimg::swap((*this)(k,imax),(*this)(k,j));
21551 d =!d;
21552 vv[imax] = vv[j];
21553 }
21554 indx[j] = (t)imax;
21555 if ((*this)(j,j)==0) (*this)(j,j) = (T)1e-20;
21556 if (j<N) {
21557 const ftype tmp = 1/(ftype)(*this)(j,j);
21558 for (int i=j+1; i<N; ++i) (*this)(j,i) = (T)((*this)(j,i)*tmp);
21559 }
21560 }
21561 return *this;
21562 }
21563
21565 CImgList<typename cimg::superset<T,float>::type> get_eigen() const {
21566 typedef typename cimg::superset<T,float>::type restype;
21567 CImgList<restype> res(2);
21568 eigen(res[0],res[1]);
21569 return res;
21570 }
21571
21573 template<typename t> const CImg<T>& eigen(CImg<t>& val, CImg<t> &vec) const {
21574 if (is_empty()) { val.assign(); vec.assign(); }
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.size()<width*width) vec.assign(width,width);
21581 switch(width) {
21582 case 1: { val[0]=(t)(*this)[0]; vec[0]=(t)1; } break;
21583 case 2: {
21584 const double a = (*this)[0], b = (*this)[1], c = (*this)[2], d = (*this)[3], e = a+d;
21585 double f = e*e-4*(a*d-b*c);
21586 if (f<0) cimg::warn("CImg<%s>::eigen() : Complex eigenvalues",pixel_type());
21587 f = std::sqrt(f);
21588 const double l1 = 0.5*(e-f), l2 = 0.5*(e+f);
21589 const double theta1 = std::atan2(l2-a,b), theta2 = std::atan2(l1-a,b);
21590 val[0]=(t)l2;
21591 val[1]=(t)l1;
21592 vec(0,0) = (t)std::cos(theta1);
21593 vec(0,1) = (t)std::sin(theta1);
21594 vec(1,0) = (t)std::cos(theta2);
21595 vec(1,1) = (t)std::sin(theta2);
21596 } break;
21597 default:
21598 throw CImgInstanceException("CImg<%s>::eigen() : Eigenvalues computation of general matrices is limited"
21599 "to 2x2 matrices (given is %ux%u)", pixel_type(),width,height);
21600 }
21601 }
21602 return *this;
21603 }
21604
21606 CImgList<typename cimg::superset<T,float>::type> get_symmetric_eigen() const {
21607 typedef typename cimg::superset<T,float>::type restype;
21608 CImgList<restype> res(2);
21609 symmetric_eigen(res[0],res[1]);
21610 return res;
21611 }
21612
21614 template<typename t> const CImg<T>& symmetric_eigen(CImg<t>& val, CImg<t>& vec) const {
21615 if (is_empty()) { val.assign(); vec.assign(); }
21616 else {
21617 #ifdef cimg_use_lapack
21618 typedef typename cimg::superset<T,float>::type ftype;
21619 char JOB = 'V', UPLO = 'U';
21620 int N = width, LWORK = 4*N, INFO;
21621 ftype
21622 *lapA = new ftype[N*N],
21623 *lapW = new ftype[N],
21624 *WORK = new ftype[LWORK];
21625 cimg_forXY(*this,k,l) lapA[k*N+l] = (ftype)((*this)(k,l));
21626 cimg::syev(JOB,UPLO,N,lapA,lapW,WORK,LWORK,INFO);
21627 if (INFO) cimg::warn("CImg<%s>::symmetric_eigen() : LAPACK library function dsyev_() returned error code %d.",pixel_type(),INFO);
21628 val.assign(1,N); vec.assign(N,N);
21629 if (!INFO) {
21630 cimg_forY(val,i) val(i) = (T)lapW[N-1-i];
21631 cimg_forXY(vec,k,l) vec(k,l) = (T)(lapA[(N-1-k)*N+l]);
21632 } else { val.fill(0); vec.fill(0); }
21633 delete[] lapA; delete[] lapW; delete[] WORK;
21634 #else
21635 if (width!=height || depth>1 || dim>1)
21636 throw CImgInstanceException("CImg<%s>::eigen() : Instance object (%u,%u,%u,%u,%p) is empty.",
21637 pixel_type(),width,height,depth,dim,data);
21638 if (val.size()<width) val.assign(1,width);
21639 if (vec.data && vec.size()<width*width) vec.assign(width,width);
21640 if (width<3) return eigen(val,vec);
21641 CImg<t> V(width,width);
21642 SVD(vec,val,V,false);
21643 bool ambiguous = false;
21644 float eig = 0;
21645 cimg_forY(val,p) {
21646 if (val[p]>eig) eig = val[p];
21647 t scal = 0;
21648 cimg_forY(vec,y) scal+=vec(p,y)*V(p,y);
21649 if (cimg::abs(scal)<0.9f) ambiguous = true;
21650 if (scal<0) val[p] = -val[p];
21651 }
21652 if (ambiguous) {
21653 (eig*=2)++;
21654 SVD(vec,val,V,false,40,eig);
21655 val-=eig;
21656 }
21657 CImg<int> permutations(width);
21658 CImg<t> tmp(width);
21659 val.sort(permutations,false);
21660 cimg_forY(vec,k) {
21661 cimg_forX(permutations,x) tmp(x) = vec(permutations(x),k);
21662 std::memcpy(vec.ptr(0,k),tmp.data,sizeof(t)*width);
21663 }
21664 #endif
21665 }
21666 return *this;
21667 }
21668
21670
21671
21673
21674
21675
21677 const CImg<T>& display(CImgDisplay& disp) const {
21678 disp.display(*this);
21679 return *this;
21680 }
21681
21685 const CImg<T>& display(const char *const title, const int min_size=128, const int max_size=1024,
21686 const int print_flag=1) const {
21687 if (is_empty())
21688 throw CImgInstanceException("CImg<%s>::display() : Instance image (%u,%u,%u,%u,%p) is empty.",
21689 pixel_type(),width,height,depth,dim,data);
21690 CImgDisplay disp;
21691 unsigned int w = width+(depth>1?depth:0), h = height+(depth>1?depth:0), XYZ[3];
21692 print(title,print_flag);
21693 const unsigned int dmin = cimg::min(w,h), minsiz = min_size>=0?min_size:(-min_size)*dmin/100;
21694 if (dmin<minsiz) { w=w*minsiz/dmin; w+=(w==0); h=h*minsiz/dmin; h+=(h==0); }
21695 const unsigned int dmax = cimg::max(w,h), maxsiz = max_size>=0?max_size:(-max_size)*dmax/100;
21696 if (dmax>maxsiz) { w=w*maxsiz/dmax; w+=(w==0); h=h*maxsiz/dmax; h+=(h==0); }
21697 disp.assign(w,h,title,1,3);
21698 XYZ[0] = width/2; XYZ[1] = height/2; XYZ[2] = depth/2;
21699 while (!disp.is_closed && !disp.key) get_coordinates(1,disp,XYZ);
21700 return *this;
21701 }
21702
21704 const CImg<T>& display(const int min_size=128, const int max_size=1024, const int print_flag=1) const {
21705 char title[256] = { 0 };
21706 std::sprintf(title,"CImg<%s>",pixel_type());
21707 return display(title,min_size,max_size,print_flag);
21708 }
21709
21711
21718 CImg<typename cimg::last<T,int>::type> get_coordinates(const int coords_type, CImgDisplay &disp,
21719 unsigned int *const XYZ=0, const unsigned char *const color=0) const {
21720
21721 if (is_empty()) throw CImgInstanceException("CImg<%s>::get_coordinates() : Instance image (%u,%u,%u,%u,%p) is empty.",
21722 pixel_type(),width,height,depth,dim,data);
21723 const unsigned int
21724 old_events = disp.events,
21725 old_normalization = disp.normalization,
21726 hatch = 0x55555555;
21727
21728 bool old_is_resized = disp.is_resized;
21729 disp.events = 3;
21730 disp.normalization = 0;
21731 disp.show().key = 0;
21732
21733 unsigned char fgcolor[] = { 255,255,105 }, bgcolor[] = { 0,0,0 };
21734 if (color) std::memcpy(fgcolor,color,sizeof(unsigned char)*cimg::min(3,dimv()));
21735
21736 int area = 0, clicked_area = 0, phase = 0,
21737 X0 = (int)((XYZ?XYZ[0]:width/2)%width), Y0 = (int)((XYZ?XYZ[1]:height/2)%height), Z0 = (int)((XYZ?XYZ[2]:depth/2)%depth),
21738 X1 =-1, Y1 = -1, Z1 = -1,
21739 X = -1, Y = -1, Z = -1,
21740 oX = X, oY = Y, oZ = Z;
21741 unsigned int old_button = 0, key = 0;
21742
21743 bool shape_selected = false, text_down = false;
21744 CImg<unsigned char> visu, visu0;
21745 char text[1024] = { 0 };
21746
21747 while (!key && !disp.is_closed && !shape_selected) {
21748
21749
21750 oX = X; oY = Y; oZ = Z;
21751 int mx = disp.mouse_x, my = disp.mouse_y;
21752 const int mX = mx*(width+(depth>1?depth:0))/disp.width, mY = my*(height+(depth>1?depth:0))/disp.height;
21753
21754 area = 0;
21755 if (mX<dimx() && mY<dimy()) { area = 1; X = mX; Y = mY; Z = phase?Z1:Z0; }
21756 if (mX<dimx() && mY>=dimy()) { area = 2; X = mX; Z = mY-height; Y = phase?Y1:Y0; }
21757 if (mX>=dimx() && mY<dimy()) { area = 3; Y = mY; Z = mX-width; X = phase?X1:X0; }
21758
21759 key = disp.key;
21760 if (key && key!=cimg::keyCTRLLEFT) {
21761 if (disp.is_key(cimg::keyCTRLLEFT,true)) {
21762 switch (key) {
21763 case cimg::keyARROWLEFT:
21764 case cimg::keyARROWDOWN: --disp.wheel; break;
21765 case cimg::keyARROWRIGHT:
21766 case cimg::keyARROWUP: ++disp.wheel; break;
21767 case cimg::keyD: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-200,-200); disp.is_resized = true; break;
21768 case cimg::keyC: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-50,-50); disp.is_resized = true; break;
21769 case cimg::keyR: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(*this); disp.is_resized = true; break;
21770 case cimg::keyF:
21771 disp.resize(disp.screen_dimx(),disp.screen_dimy()).toggle_fullscreen();
21772 disp.is_resized = true;
21773 break;
21774 case cimg::keyS: {
21775 static unsigned int snap_number = 0;
21776 char filename[32] = { 0 };
21777 std::FILE *file;
21778 do {
21779 std::sprintf(filename,"CImg_%.4u.bmp",snap_number++);
21780 if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
21781 } while (file);
21782 if (visu0) {
21783 visu.draw_text(2,2,fgcolor,bgcolor,11,0.8f,"Saving snapshot...").display(disp);
21784 visu0.save(filename);
21785 visu.draw_text(2,2,fgcolor,bgcolor,11,0.8f,"Snapshot '%s' saved.",filename).display(disp);
21786 }
21787 } break;
21788 case cimg::keyO: {
21789 static unsigned int snap_number = 0;
21790 char filename[32] = { 0 };
21791 std::FILE *file;
21792 do {
21793 std::sprintf(filename,"CImg_%.4u.cimg",snap_number++);
21794 if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
21795 } while (file);
21796 visu.draw_text(2,2,fgcolor,bgcolor,11,0.8f,"Saving instance...").display(disp);
21797 save(filename);
21798 visu.draw_text(2,2,fgcolor,bgcolor,11,0.8f,"Instance '%s' saved.",filename).display(disp);
21799 } break;
21800 default: break;
21801 }
21802 key = disp.key = 0;
21803 }
21804 } else key = 0;
21805
21806 if (!area) mx = my = X = Y = Z = -1;
21807 else {
21808 if (disp.button&1 && phase<2) { X1 = X; Y1 = Y; Z1 = Z; }
21809 if (!(disp.button&1) && phase>=2) {
21810 switch (clicked_area) {
21811 case 1: Z1 = Z; break;
21812 case 2: Y1 = Y; break;
21813 case 3: X1 = X; break;
21814 }
21815 }
21816 if (disp.button&2) { if (phase) { X1 = X; Y1 = Y; Z1 = Z; } else { X0 = X; Y0 = Y; Z0 = Z; } }
21817 if (disp.button&4) { oX = X = X0; oY = Y = Y0; oZ = Z = Z0; phase = 0; visu.assign(); }
21818 if (disp.wheel) {
21819 switch (area) {
21820 case 1: if (phase) Z = (Z1+=disp.wheel); else Z = (Z0+=disp.wheel); break;
21821 case 2: if (phase) Y = (Y1+=disp.wheel); else Y = (Y0+=disp.wheel); break;
21822 case 3: if (phase) X = (X1+=disp.wheel); else X = (X0+=disp.wheel); break;
21823 default: break;
21824 }
21825 disp.wheel = 0;
21826 }
21827 if ((disp.button&1)!=old_button) {
21828 switch (phase++) {
21829 case 0: X0 = X1 = X; Y0 = Y1 = Y; Z0 = Z1 = Z; clicked_area = area; break;
21830 case 1: X1 = X; Y1 = Y; Z1 = Z; break;
21831 default: break;
21832 }
21833 old_button = disp.button&1;
21834 }
21835 if (depth>1 && (X!=oX || Y!=oY || Z!=oZ)) visu0.assign();
21836 }
21837
21838 if (phase) {
21839 if (!coords_type) shape_selected = phase?true:false;
21840 else {
21841 if (depth>1) shape_selected = (phase==3)?true:false;
21842 else shape_selected = (phase==2)?true:false;
21843 }
21844 }
21845
21846 if (X0<0) X0 = 0; if (X0>=dimx()) X0 = dimx()-1; if (Y0<0) Y0 = 0; if (Y0>=dimy()) Y0 = dimy()-1;
21847 if (Z0<0) Z0 = 0; if (Z0>=dimz()) Z0 = dimz()-1;
21848 if (X1<1) X1 = 0; if (X1>=dimx()) X1 = dimx()-1; if (Y1<0) Y1 = 0; if (Y1>=dimy()) Y1 = dimy()-1;
21849 if (Z1<0) Z1 = 0; if (Z1>=dimz()) Z1 = dimz()-1;
21850
21851
21852 if (oX!=X || oY!=Y || oZ!=Z || !visu0) {
21853 if (!visu0) {
21854 CImg<T> tmp0 = get_shared_channels(0,cimg::min(2U,dim-1)), tmp;
21855 if (depth!=1) tmp = (!phase?tmp0.get_projections2d(X0,Y0,Z0):tmp0.get_projections2d(X1,Y1,Z1)).resize(disp.width,disp.height,1,3);
21856 else tmp = tmp0.get_resize(disp.width,disp.height,1,3);
21857 if (old_normalization) {
21858 if (old_normalization<3 || cimg::type<T>::is_float()) {
21859 if (sizeof(T)>1) visu0.assign(tmp.normalize(0,(T)255));
21860 else visu0.assign(tmp).normalize(0,255);
21861 } else {
21862 if (cimg::type<T>::string()!=cimg::type<unsigned char>::string()) {
21863 const float m = (float)cimg::type<T>::min(), M = (float)cimg::type<T>::max();
21864 visu0.assign((CImg<float>(tmp)-=m)*=255.0f/(M-m));
21865 } else visu0.assign(tmp);
21866 }
21867 } else visu0.assign(tmp);
21868 }
21869 visu = visu0;
21870 if (!color) {
21871 if (visu.mean()<200) { fgcolor[0] = fgcolor[1] = fgcolor[2] = 255; bgcolor[0] = bgcolor[1] = bgcolor[2] = 0; }
21872 else { fgcolor[0] = fgcolor[1] = fgcolor[2] = 0; bgcolor[0] = bgcolor[1] = bgcolor[2] = 255; }
21873 }
21874
21875 const int d=(depth>1)?depth:0;
21876 if (phase) switch (coords_type) {
21877 case 1: {
21878 const int
21879 x0=(int)((X0+0.5f)*disp.width/(width+d)), y0=(int)((Y0+0.5f)*disp.height/(height+d)),
21880 x1=(int)((X1+0.5f)*disp.width/(width+d)), y1=(int)((Y1+0.5f)*disp.height/(height+d));
21881 visu.draw_arrow(x0,y0,x1,y1,fgcolor,30.0f,5.0f,1.0f,hatch);
21882 if (d) {
21883 const int zx0=(int)((width+Z0+0.5f)*disp.width/(width+d)), zx1=(int)((width+Z1+0.5f)*disp.width/(width+d)),
21884 zy0=(int)((height+Z0+0.5f)*disp.height/(height+d)), zy1=(int)((height+Z1+0.5f)*disp.height/(height+d));
21885 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);
21886 }
21887 } break;
21888 case 2: {
21889 const int
21890 x0=(X0<X1?X0:X1)*disp.width/(width+d),
21891 y0=(Y0<Y1?Y0:Y1)*disp.height/(height+d),
21892 x1=((X0<X1?X1:X0)+1)*disp.width/(width+d)-1,
21893 y1=((Y0<Y1?Y1:Y0)+1)*disp.height/(height+d)-1;
21894 visu.draw_rectangle(x0,y0,x1,y1,fgcolor,0.2f).draw_line(x0,y0,x1,y0,fgcolor,1.0f,hatch).
21895 draw_line(x1,y0,x1,y1,fgcolor,1.0f,hatch).draw_line(x1,y1,x0,y1,fgcolor,1.0f,hatch).
21896 draw_line(x0,y1,x0,y0,fgcolor,1.0f,hatch);
21897 if (d) {
21898 const int
21899 zx0=(int)((width+(Z0<Z1?Z0:Z1))*disp.width/(width+d)),
21900 zy0=(int)((height+(Z0<Z1?Z0:Z1))*disp.height/(height+d)),
21901 zx1=(int)((width+(Z0<Z1?Z1:Z0)+1)*disp.width/(width+d))-1,
21902 zy1=(int)((height+(Z0<Z1?Z1:Z0)+1)*disp.height/(height+d))-1;
21903 visu.draw_rectangle(zx0,y0,zx1,y1,fgcolor,0.2f).draw_line(zx0,y0,zx1,y0,fgcolor,1.0f,hatch).
21904 draw_line(zx1,y0,zx1,y1,fgcolor,1.0f,hatch).draw_line(zx1,y1,zx0,y1,fgcolor,1.0f,hatch).
21905 draw_line(zx0,y1,zx0,y0,fgcolor,1.0f,hatch);
21906 visu.draw_rectangle(x0,zy0,x1,zy1,fgcolor,0.2f).draw_line(x0,zy0,x1,zy0,fgcolor,1.0f,hatch).
21907 draw_line(x1,zy0,x1,zy1,fgcolor,1.0f,hatch).draw_line(x1,zy1,x0,zy1,fgcolor,1.0f,hatch).
21908 draw_line(x0,zy1,x0,zy0,fgcolor,1.0f,hatch);
21909 }
21910 } break;
21911 case 3: {
21912 const int
21913 x0=X0*disp.width/(width+d),
21914 y0=Y0*disp.height/(height+d),
21915 x1=X1*disp.width/(width+d)-1,
21916 y1=Y1*disp.height/(height+d)-1;
21917 visu.draw_ellipse(x0,y0,(float)(x1-x0),(float)(y1-y0),1.0f,0.0f,fgcolor,0.2f).
21918 draw_ellipse(x0,y0,(float)(x1-x0),(float)(y1-y0),1.0f,0.0f,fgcolor,1.0f,hatch);
21919 if (d) {
21920 const int
21921 zx0=(int)((width+Z0)*disp.width/(width+d)),
21922 zy0=(int)((height+Z0)*disp.height/(height+d)),
21923 zx1=(int)((width+Z1+1)*disp.width/(width+d))-1,
21924 zy1=(int)((height+Z1+1)*disp.height/(height+d))-1;
21925 visu.draw_ellipse(zx0,y0,(float)(zx1-zx0),(float)(y1-y0),1.0f,0.0f,fgcolor,0.2f).
21926 draw_ellipse(zx0,y0,(float)(zx1-zx0),(float)(y1-y0),1.0f,0.0f,fgcolor,1.0f,hatch).
21927 draw_ellipse(x0,zy0,(float)(x1-x0),(float)(zy1-zy0),1.0f,0.0f,fgcolor,0.2f).
21928 draw_ellipse(x0,zy0,(float)(x1-x0),(float)(zy1-zy0),1.0f,0.0f,fgcolor,1.0f,hatch);
21929 }
21930 } break;
21931 }
21932
21933 if (my<12) text_down = true;
21934 if (my>=visu.dimy()-11) text_down = false;
21935 if (!coords_type || !phase) {
21936 if (X>=0 && Y>=0 && Z>=0 && X<dimx() && Y<dimy() && Z<dimz()) {
21937 if (depth>1) std::sprintf(text,"Point (%d,%d,%d)={ ",X,Y,Z); else std::sprintf(text,"Point (%d,%d)={ ",X,Y);
21938 char *ctext = text + cimg::strlen(text), *const ltext = text + 512;
21939 for (unsigned int k=0; k<dim && ctext<ltext; ++k) {
21940 std::sprintf(ctext,cimg::type<T>::format(),cimg::type<T>::format((*this)(X,Y,Z,k)));
21941 ctext = text + cimg::strlen(text);
21942 *(ctext++) = ' '; *ctext = '\0';
21943 }
21944 std::sprintf(text + cimg::strlen(text),"}");
21945 }
21946 } else switch (coords_type) {
21947 case 1: {
21948 const double dX=(double)(X0-X1), dY=(double)(Y0-Y1), dZ=(double)(Z0-Z1), norm = std::sqrt(dX*dX+dY*dY+dZ*dZ);
21949 if (depth>1) std::sprintf(text,"Vect (%d,%d,%d)-(%d,%d,%d), norm=%g",X0,Y0,Z0,X1,Y1,Z1,norm);
21950 else std::sprintf(text,"Vect (%d,%d)-(%d,%d), norm=%g",X0,Y0,X1,Y1,norm);
21951 } break;
21952 case 2:
21953 if (depth>1) std::sprintf(text,"Box (%d,%d,%d)-(%d,%d,%d), Size=(%d,%d,%d)",
21954 X0<X1?X0:X1,Y0<Y1?Y0:Y1,Z0<Z1?Z0:Z1,
21955 X0<X1?X1:X0,Y0<Y1?Y1:Y0,Z0<Z1?Z1:Z0,
21956 1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1),1+cimg::abs(Z0-Z1));
21957 else std::sprintf(text,"Box (%d,%d)-(%d,%d), Size=(%d,%d)",
21958 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));
21959 break;
21960 default:
21961 if (depth>1) std::sprintf(text,"Ellipse (%d,%d,%d)-(%d,%d,%d), Radii=(%d,%d,%d)",
21962 X0,Y0,Z0,X1,Y1,Z1,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1),1+cimg::abs(Z0-Z1));
21963 else std::sprintf(text,"Ellipse (%d,%d)-(%d,%d), Radii=(%d,%d)",
21964 X0,Y0,X1,Y1,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1));
21965
21966 break;
21967 }
21968 if (phase || (mx>=0 && my>=0)) visu.draw_text(text,0,text_down?visu.dimy()-11:0,fgcolor,bgcolor,11,0.7f);
21969 disp.display(visu).wait(25);
21970 } else disp.wait();
21971
21972 if (disp.is_resized) { disp.resize(false); old_is_resized = true; disp.is_resized = false; visu0.assign(); }
21973 }
21974
21975
21976 typedef typename cimg::last<T,int>::type restype;
21977 CImg<restype> res(1,6,1,1,(restype)-1);
21978 if (XYZ) { XYZ[0] = (unsigned int)X0; XYZ[1] = (unsigned int)Y0; XYZ[2] = (unsigned int)Z0; }
21979 if (shape_selected) {
21980 if (coords_type==2) {
21981 if (X0>X1) cimg::swap(X0,X1);
21982 if (Y0>Y1) cimg::swap(Y0,Y1);
21983 if (Z0>Z1) cimg::swap(Z0,Z1);
21984 }
21985 if (X1<0 || Y1<0 || Z1<0) X0 = Y0 = Z0 = X1 = Y1 = Z1 = -1;
21986 switch(coords_type) {
21987 case 1:
21988 case 2: res[3] = (restype)X1; res[4] = (restype)Y1; res[5] = (restype)Z1;
21989 default: res[0] = (restype)X0; res[1] = (restype)Y0; res[2] = (restype)Z0;
21990 }
21991 }
21992 disp.button = 0;
21993 disp.events = old_events;
21994 disp.normalization = old_normalization;
21995 disp.is_resized = old_is_resized;
21996 disp.key = key;
21997 return res;
21998 }
21999
22001 CImg<typename cimg::last<T,int>::type> get_coordinates(const int coords_type=0,
22002 unsigned int *const XYZ=0, const unsigned char *const color=0) const {
22003 unsigned int w = width + (depth>1?depth:0), h = height + (depth>1?depth:0);
22004 const unsigned int dmin = cimg::min(w,h), minsiz = 256;
22005 if (dmin<minsiz) { w=w*minsiz/dmin; h=h*minsiz/dmin; }
22006 const unsigned int dmax = cimg::max(w,h), maxsiz = 1024;
22007 if (dmax>maxsiz) { w=w*maxsiz/dmax; h=h*maxsiz/dmax; }
22008 CImgDisplay disp(w,h," ",1,3);
22009 return get_coordinates(coords_type,disp,XYZ,color);
22010 }
22011
22012 CImg<T>& coordinates(const int coords_type=0,unsigned int *const XYZ=0, const unsigned char *const color=0) {
22013 return get_coordinates(coords_type,XYZ,color).assign_to(*this);
22014 }
22015
22017 template<typename tp, typename tf, typename tc, typename to>
22018 const CImg<T>& display_object3d(const CImg<tp>& points, const CImgList<tf>& primitives,
22019 const CImgList<tc>& colors, const CImgList<to>& opacities, CImgDisplay& disp,
22020 const bool centering=true,
22021 const int render_static=4, const int render_motion=1,
22022 const bool double_sided=false,
22023 const float focale=500.0f, const float ambient_light=0.05f,
22024 const bool display_axes=true, float *const pose_matrix=0) const {
22025
22026
22027 if (!points || !primitives || !opacities)
22028 throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (%u), primitives (%u) or opacities (%u) are empty.",
22029 pixel_type(),points.size()/3,primitives.size,opacities.size);
22030 if (is_empty())
22031 return CImg<T>(disp.width,disp.height,1,colors[0].size(),0).
22032 display_object3d(points,primitives,colors,opacities,disp,centering,
22033 render_static,render_motion,double_sided,focale,ambient_light,
22034 display_axes,pose_matrix);
22035 if (points.height<3)
22036 return display_object3d(points.get_resize(-100,3,1,1,0),primitives,colors,opacities,disp,
22037 centering,render_static,render_motion,double_sided,focale,ambient_light,
22038 display_axes,pose_matrix);
22039
22040
22041 CImg<float> pose, rot_mat,
22042 centered_points = centering?CImg<float>(points.width,3):CImg<float>(),
22043 rotated_points(points.width,3),
22044 bbox_points, rotated_bbox_points,
22045 axes_points, rotated_axes_points;
22046 CImgList<to> bbox_opacities, axes_opacities;
22047 CImgList<T> bbox_colors, axes_colors;
22048 CImgList<tf> bbox_primitives, axes_primitives;
22049 float nambient = ambient_light, dx = 0, dy = 0, dz = 0, ratio = 1;
22050
22051 T minval = (T)0, maxval = (T)255;
22052 if (disp.normalization) minval = colors.minmax(maxval);
22053 const float meanval = (float)mean();
22054 bool color_model = true;
22055
22056 if (cimg::abs(meanval-minval)>cimg::abs(meanval-maxval)) color_model = false;
22057 const CImg<T>
22058 bgcolor(1,1,1,dim,color_model?minval:maxval),
22059 fgcolor(1,1,1,dim,color_model?maxval:minval);
22060 float
22061 xm, xM = (float)points.get_shared_line(0).maxmin(xm),
22062 ym, yM = (float)points.get_shared_line(1).maxmin(ym),
22063 zm, zM = (float)points.get_shared_line(2).maxmin(zm),
22064 delta = cimg::max(xM-xm,yM-ym,zM-zm);
22065
22066 if (display_axes) {
22067 axes_points.assign(7,3);
22068 rotated_axes_points.assign(7,3);
22069 axes_opacities.assign(3,1,1,1,1,1.0f);
22070 axes_colors.assign(3,dim,1,1,1,fgcolor[0]);
22071 axes_points(0,0) = 0; axes_points(0,1) = 0; axes_points(0,2) = 0;
22072 axes_points(1,0) = 20; axes_points(1,1) = 0; axes_points(1,2) = 0;
22073 axes_points(2,0) = 0; axes_points(2,1) = 20; axes_points(2,2) = 0;
22074 axes_points(3,0) = 0; axes_points(3,1) = 0; axes_points(3,2) = 20;
22075 axes_points(4,0) = 22; axes_points(4,1) = -6; axes_points(4,2) = 0;
22076 axes_points(5,0) = -6; axes_points(5,1) = 22; axes_points(5,2) = 0;
22077 axes_points(6,0) = -6; axes_points(6,1) = -6; axes_points(6,2) = 22;
22078 axes_primitives.insert(CImg<tf>::vector(0,1));
22079 axes_primitives.insert(CImg<tf>::vector(0,2));
22080 axes_primitives.insert(CImg<tf>::vector(0,3));
22081 }
22082
22083
22084 CImg<T> visu0(*this), visu;
22085 bool init = true, clicked = false, redraw = true;
22086 unsigned int key = 0;
22087 int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
22088 const unsigned int old_events = disp.events;
22089 disp.show().button = disp.key = 0;
22090 disp.events = 3;
22091
22092 while (!disp.is_closed && !key) {
22093
22094
22095 if (init) {
22096 ratio = delta>0?(2.0f*cimg::min(disp.width,disp.height)/(3.0f*delta)):0;
22097 dx = 0.5f*(xM+xm); dy = 0.5f*(yM+ym); dz = 0.5f*(zM+zm);
22098 if (centering) {
22099 cimg_forX(centered_points,l) {
22100 centered_points(l,0) = (float)((points(l,0)-dx)*ratio);
22101 centered_points(l,1) = (float)((points(l,1)-dy)*ratio);
22102 centered_points(l,2) = (float)((points(l,2)-dz)*ratio);
22103 }
22104 }
22105
22106 if (render_static<0 || render_motion<0) {
22107 bbox_colors.assign(12,dim,1,1,1,fgcolor[0]);
22108 bbox_primitives.assign(12,1,2);
22109 bbox_points.assign(8,3);
22110 rotated_bbox_points.assign(8,3);
22111 bbox_points(0,0) = xm; bbox_points(0,1) = ym; bbox_points(0,2) = zm;
22112 bbox_points(1,0) = xM; bbox_points(1,1) = ym; bbox_points(1,2) = zm;
22113 bbox_points(2,0) = xM; bbox_points(2,1) = yM; bbox_points(2,2) = zm;
22114 bbox_points(3,0) = xm; bbox_points(3,1) = yM; bbox_points(3,2) = zm;
22115 bbox_points(4,0) = xm; bbox_points(4,1) = ym; bbox_points(4,2) = zM;
22116 bbox_points(5,0) = xM; bbox_points(5,1) = ym; bbox_points(5,2) = zM;
22117 bbox_points(6,0) = xM; bbox_points(6,1) = yM; bbox_points(6,2) = zM;
22118 bbox_points(7,0) = xm; bbox_points(7,1) = yM; bbox_points(7,2) = zM;
22119 bbox_primitives[0].fill(0,1); bbox_primitives[1].fill(1,2); bbox_primitives[2].fill(2,3); bbox_primitives[3].fill(3,0);
22120 bbox_primitives[4].fill(4,5); bbox_primitives[5].fill(5,6); bbox_primitives[6].fill(6,7); bbox_primitives[7].fill(7,4);
22121 bbox_primitives[8].fill(0,4); bbox_primitives[9].fill(1,5); bbox_primitives[10].fill(2,6); bbox_primitives[11].fill(3,7);
22122 bbox_opacities.assign(bbox_primitives.size,1,1,1,1,1.0f);
22123 }
22124
22125 if (!pose) {
22126 if (pose_matrix) pose = CImg<float>(pose_matrix,4,4,1,1,false);
22127 else pose = CImg<float>::identity_matrix(4);
22128 }
22129 init = false;
22130 redraw = true;
22131 }
22132
22133
22134 if (redraw) {
22135 const float
22136 r00 = pose(0,0), r10 = pose(1,0), r20 = pose(2,0), r30 = pose(3,0),
22137 r01 = pose(0,1), r11 = pose(1,1), r21 = pose(2,1), r31 = pose(3,1),
22138 r02 = pose(0,2), r12 = pose(1,2), r22 = pose(2,2), r32 = pose(3,2);
22139 if ((clicked && render_motion>=0) || (!clicked && render_static>=0)) {
22140 if (centering) cimg_forX(centered_points,l) {
22141 const float x = centered_points(l,0), y = centered_points(l,1), z = centered_points(l,2);
22142 rotated_points(l,0) = r00*x + r10*y + r20*z + r30;
22143 rotated_points(l,1) = r01*x + r11*y + r21*z + r31;
22144 rotated_points(l,2) = r02*x + r12*y + r22*z + r32;
22145 } else cimg_forX(points,l) {
22146 const float x = (float)points(l,0), y = (float)points(l,1), z = (float)points(l,2);
22147 rotated_points(l,0) = r00*x + r10*y + r20*z + r30;
22148 rotated_points(l,1) = r01*x + r11*y + r21*z + r31;
22149 rotated_points(l,2) = r02*x + r12*y + r22*z + r32;
22150 }
22151 } else {
22152 if (!centering) cimg_forX(bbox_points,l) {
22153 const float x = bbox_points(l,0), y = bbox_points(l,1), z = bbox_points(l,2);
22154 rotated_bbox_points(l,0) = r00*x + r10*y + r20*z + r30;
22155 rotated_bbox_points(l,1) = r01*x + r11*y + r21*z + r31;
22156 rotated_bbox_points(l,2) = r02*x + r12*y + r22*z + r32;
22157 } else cimg_forX(bbox_points,l) {
22158 const float x = (bbox_points(l,0)-dx)*ratio, y = (bbox_points(l,1)-dy)*ratio, z = (bbox_points(l,2)-dz)*ratio;
22159 rotated_bbox_points(l,0) = r00*x + r10*y + r20*z + r30;
22160 rotated_bbox_points(l,1) = r01*x + r11*y + r21*z + r31;
22161 rotated_bbox_points(l,2) = r02*x + r12*y + r22*z + r32;
22162 }
22163 }
22164
22165
22166 visu = visu0;
22167 if ((clicked && render_motion<0) || (!clicked && render_static<0))
22168 visu.draw_object3d(visu.width/2.0f, visu.height/2.0f, 0,
22169 rotated_bbox_points,bbox_primitives,bbox_colors,bbox_opacities,1,
22170 false,focale,visu.dimx()/2.0f,visu.dimy()/2.0f,-5000.0f,0.2f);
22171 else visu.draw_object3d(visu.width/2.0f, visu.height/2.0f, 0,
22172 rotated_points,primitives,colors,opacities,clicked?render_motion:render_static,
22173 double_sided,focale,visu.dimx()/2.0f,visu.dimy()/2.0f,-5000.0f,nambient);
22174
22175
22176 if (display_axes) {
22177 const float Xaxes = 25.0f, Yaxes = visu.height-35.0f;
22178 cimg_forX(axes_points,l) {
22179 const float x = axes_points(l,0), y = axes_points(l,1), z = axes_points(l,2);
22180 rotated_axes_points(l,0) = r00*x + r10*y + r20*z;
22181 rotated_axes_points(l,1) = r01*x + r11*y + r21*z;
22182 rotated_axes_points(l,2) = r02*x + r12*y + r22*z;
22183 }
22184 axes_opacities(0,0) = (rotated_axes_points(1,2)>0)?0.5f:1.0f;
22185 axes_opacities(1,0) = (rotated_axes_points(2,2)>0)?0.5f:1.0f;
22186 axes_opacities(2,0) = (rotated_axes_points(3,2)>0)?0.5f:1.0f;
22187 visu.draw_object3d(Xaxes,Yaxes,0,rotated_axes_points,axes_primitives,axes_colors,axes_opacities,1,false,focale,0,0,0,0).
22188 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)).
22189 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)).
22190 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));
22191 }
22192 visu.display(disp);
22193 if (!clicked || render_motion==render_static) redraw = false;
22194 }
22195
22196
22197 disp.wait();
22198 if ((disp.button || disp.wheel) && disp.mouse_x>=0 && disp.mouse_y>=0) {
22199 redraw = true;
22200 if (!clicked) { x0 = x1 = disp.mouse_x; y0 = y1 = disp.mouse_y; if (!disp.wheel) clicked = true; }
22201 else { x1 = disp.mouse_x; y1 = disp.mouse_y; }
22202 if (disp.button&1) {
22203 const float
22204 R = 0.45f*cimg::min(disp.width,disp.height),
22205 R2 = R*R,
22206 u0 = (float)(x0-disp.dimx()/2),
22207 v0 = (float)(y0-disp.dimy()/2),
22208 u1 = (float)(x1-disp.dimx()/2),
22209 v1 = (float)(y1-disp.dimy()/2),
22210 n0 = (float)std::sqrt(u0*u0+v0*v0),
22211 n1 = (float)std::sqrt(u1*u1+v1*v1),
22212 nu0 = n0>R?(u0*R/n0):u0,
22213 nv0 = n0>R?(v0*R/n0):v0,
22214 nw0 = (float)std::sqrt(cimg::max(0.0f,R2-nu0*nu0-nv0*nv0)),
22215 nu1 = n1>R?(u1*R/n1):u1,
22216 nv1 = n1>R?(v1*R/n1):v1,
22217 nw1 = (float)std::sqrt(cimg::max(0.0f,R2-nu1*nu1-nv1*nv1)),
22218 u = nv0*nw1-nw0*nv1,
22219 v = nw0*nu1-nu0*nw1,
22220 w = nv0*nu1-nu0*nv1,
22221 n = (float)std::sqrt(u*u+v*v+w*w),
22222 alpha = (float)std::asin(n/R2);
22223 rot_mat = CImg<float>::rotation_matrix(u,v,w,alpha);
22224 rot_mat *= pose.get_crop(0,0,2,2);
22225 pose.draw_image(rot_mat,0,0);
22226 x0=x1; y0=y1;
22227 }
22228 if (disp.button&2) { pose(3,2)+=(y1-y0); x0 = x1; y0 = y1; }
22229 if (disp.wheel) { pose(3,2)-=15*disp.wheel; disp.wheel = 0; }
22230 if (disp.button&4) { pose(3,0)+=(x1-x0); pose(3,1)+=(y1-y0); x0 = x1; y0 = y1; }
22231 if ((disp.button&1) && (disp.button&2)) { init = true; disp.button = 0; x0 = x1; y0 = y1; pose = CImg<float>::identity_matrix(4); }
22232 } else if (clicked) { x0 = x1; y0 = y1; clicked = false; redraw = true; }
22233
22234 key = disp.key;
22235 if (key && key!=cimg::keyCTRLLEFT && key!=cimg::keyCTRLRIGHT) {
22236 if (disp.is_key(cimg::keyCTRLLEFT,true) || disp.is_key(cimg::keyCTRLRIGHT,true)) {
22237 switch (key) {
22238 case cimg::keyPAGEDOWN: nambient-=0.1f; if (nambient<-2) nambient = -2; redraw = true; break;
22239 case cimg::keyPAGEUP: nambient+=0.1f; if (nambient>2) nambient = 2; redraw = true; break;
22240 case cimg::keyD: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-200,-200); disp.is_resized = true; break;
22241 case cimg::keyC: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-50,-50); disp.is_resized = true; break;
22242 case cimg::keyR: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(*this); disp.is_resized = true; break;
22243 case cimg::keyF: disp.resize(disp.screen_dimx(),disp.screen_dimy()).toggle_fullscreen().is_resized = true; break;
22244 case cimg::keyS: {
22245 static unsigned int snap_number = 0;
22246 char filename[32] = { 0 };
22247 std::FILE *file;
22248 do {
22249 std::sprintf(filename,"CImg_%.4u.bmp",snap_number++);
22250 if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
22251 } while (file);
22252 (+visu).draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Saving snapshot...",filename).display(disp);
22253 visu.save(filename);
22254 visu.draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Snapshot '%s' saved.",filename).display(disp);
22255 } break;
22256 case cimg::keyO: {
22257 static unsigned int snap_number = 0;
22258 char filename[32] = { 0 };
22259 std::FILE *file;
22260 do {
22261 std::sprintf(filename,"CImg_%.4u.off",snap_number++);
22262 if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
22263 } while (file);
22264 visu.draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Saving object...",filename).display(disp);
22265 points.save_off(filename,primitives,colors);
22266 visu.draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Object '%s' saved.",filename).display(disp);
22267 } break;
22268 }
22269 disp.key = key = 0;
22270 }
22271 } else key = 0;
22272 if (disp.is_resized) { disp.resize(false); visu0 = get_resize(disp,1); redraw = true; }
22273 }
22274 if (pose_matrix) std::memcpy(pose_matrix,pose.data,16*sizeof(float));
22275 disp.events = old_events;
22276 disp.button = 0;
22277 return *this;
22278 }
22279
22281 template<typename tp, typename tf, typename tc, typename to>
22282 const CImg<T>& display_object3d(const CImgList<tp>& points, const CImgList<tf>& primitives,
22283 const CImgList<tc>& colors, const CImgList<to>& opacities, CImgDisplay &disp,
22284 const bool centering=true,
22285 const int render_static=4, const int render_motion=1,
22286 const bool double_sided=false,
22287 const float focale=500.0f, const float ambient_light=0.05f,
22288 const bool display_axes=true, float *const pose_matrix=0) const {
22289 CImg<tp> npoints(points.size,3,1,1,0);
22290 tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
22291 cimg_forX(npoints,l) {
22292 const CImg<tp>& point = points[l];
22293 const unsigned int siz = point.size();
22294 if (!siz)
22295 throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (size=%u) contains a null element at "
22296 "position %u.",pixel_type(),points.size,l);
22297 *(ptrZ++) = (siz>2)?point(2):0;
22298 *(ptrY++) = (siz>1)?point(1):0;
22299 *(ptrX++) = point(0);
22300 }
22301 return display_object3d(npoints,primitives,colors,opacities,disp,centering,
22302 render_static,render_motion,double_sided,focale,ambient_light,
22303 display_axes,pose_matrix);
22304 }
22305
22307 template<typename tp, typename tf, typename tc, typename to>
22308 const CImg<T>& display_object3d(const CImg<tp>& points, const CImgList<tf>& primitives,
22309 const CImgList<tc>& colors, const CImg<to>& opacities, CImgDisplay& disp,
22310 const bool centering=true,
22311 const int render_static=4, const int render_motion=1,
22312 const bool double_sided=false,
22313 const float focale=500.0f, const float ambient_light=0.05f,
22314 const bool display_axes=true, float *const pose_matrix=0) const {
22315 CImgList<to> nopacities(opacities.size(),1);
22316 cimglist_for(nopacities,l) nopacities(l,0) = opacities(l);
22317 return display_object3d(points,primitives,colors,nopacities,disp,centering,
22318 render_static,render_motion,double_sided,focale,ambient_light,
22319 display_axes,pose_matrix);
22320 }
22321
22323 template<typename tp, typename tf, typename tc, typename to>
22324 const CImg<T>& display_object3d(const CImgList<tp>& points, const CImgList<tf>& primitives,
22325 const CImgList<tc>& colors, const CImg<to>& opacities, CImgDisplay& disp,
22326 const bool centering=true,
22327 const int render_static=4, const int render_motion=1,
22328 const bool double_sided=false,
22329 const float focale=500.0f, const float ambient_light=0.05f,
22330 const bool display_axes=true, float *const pose_matrix=0) const {
22331 CImgList<to> nopacities(opacities.size(),1);
22332 cimglist_for(nopacities,l) nopacities(l,0) = opacities(l);
22333 if (!points) throw CImgArgumentException("CImg<%s>::display_object3d() : Given points are empty.",
22334 pixel_type());
22335 CImg<tp> npoints(points.size,3,1,1,0);
22336 tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
22337 { cimg_forX(npoints,l) {
22338 const CImg<tp>& point = points[l];
22339 const unsigned int siz = point.size();
22340 if (!siz)
22341 throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (size=%u) contains a null element at "
22342 "position %u.",pixel_type(),points.size,l);
22343 *(ptrZ++) = (siz>2)?point(2):0;
22344 *(ptrY++) = (siz>1)?point(1):0;
22345 *(ptrX++) = point(0);
22346 }
22347 }
22348 return display_object3d(npoints,primitives,colors,nopacities,disp,centering,
22349 render_static,render_motion,double_sided,focale,ambient_light,
22350 display_axes,pose_matrix);
22351 }
22352
22354 template<typename tp, typename tf, typename tc, typename to>
22355 const CImg<T>& display_object3d(const tp& points, const CImgList<tf>& primitives,
22356 const CImgList<tc>& colors, const to& opacities,
22357 const bool centering=true,
22358 const int render_static=4, const int render_motion=1,
22359 const bool double_sided=false,
22360 const float focale=500.0f, const float ambient_light=0.05f,
22361 const bool display_axes=true, float *const pose_matrix=0) const {
22362 CImgDisplay disp(width,height,0,0);
22363 return display_object3d(points,primitives,colors,opacities,disp,centering,
22364 render_static,render_motion,double_sided,focale,ambient_light,
22365 display_axes,pose_matrix);
22366 }
22367
22369 template<typename tp, typename tf, typename tc>
22370 const CImg<T>& display_object3d(const tp& points, const CImgList<tf>& primitives,
22371 const CImgList<tc>& colors,
22372 const bool centering=true,
22373 const int render_static=4, const int render_motion=1,
22374 const bool double_sided=false,
22375 const float focale=500.0f, const float ambient_light=0.05f,
22376 const bool display_axes=true, float *const pose_matrix=0,
22377 const float opacity=1.0f) const {
22378 CImgDisplay disp(width,height," ",0);
22379 return display_object3d(points,primitives,colors,CImg<float>::vector(opacity),
22380 disp,centering,render_static,render_motion,double_sided,
22381 focale,ambient_light,display_axes,pose_matrix);
22382 }
22383
22385 template<typename tp, typename tf, typename tc>
22386 const CImg<T>& display_object3d(const tp& points, const CImgList<tf>& primitives,
22387 const CImgList<tc>& colors, CImgDisplay &disp,
22388 const bool centering=true,
22389 const int render_static=4, const int render_motion=1,
22390 const bool double_sided=false,
22391 const float focale=500.0f, const float ambient_light=0.05f,
22392 const bool display_axes=true, float *const pose_matrix=0,
22393 const float opacity=1.0f) const {
22394 return display_object3d(points,primitives,colors,CImg<float>::vector(opacity),
22395 disp,centering,render_static,render_motion,double_sided,
22396 focale,ambient_light,display_axes,pose_matrix);
22397 }
22398
22400
22401
22403
22404
22405
22407
22412 static CImg<T> get_load(const char *const filename) {
22413 return CImg<T>().load(filename);
22414 }
22415
22416 CImg<T>& load(const char *const filename) {
22417 const char *ext = cimg::filename_split(filename);
22418 #ifdef cimg_load_plugin
22419 cimg_load_plugin(filename);
22420 #endif
22421 #ifdef cimg_load_plugin1
22422 cimg_load_plugin1(filename);
22423 #endif
22424 #ifdef cimg_load_plugin2
22425 cimg_load_plugin2(filename);
22426 #endif
22427 #ifdef cimg_load_plugin3
22428 cimg_load_plugin3(filename);
22429 #endif
22430 #ifdef cimg_load_plugin4
22431 cimg_load_plugin4(filename);
22432 #endif
22433 #ifdef cimg_load_plugin5
22434 cimg_load_plugin5(filename);
22435 #endif
22436 #ifdef cimg_load_plugin6
22437 cimg_load_plugin6(filename);
22438 #endif
22439 #ifdef cimg_load_plugin7
22440 cimg_load_plugin7(filename);
22441 #endif
22442 #ifdef cimg_load_plugin8
22443 cimg_load_plugin8(filename);
22444 #endif
22445 if (!cimg::strncasecmp(ext,"asc",3)) return load_ascii(filename);
22446 if (!cimg::strncasecmp(ext,"dlm",3) ||
22447 !cimg::strncasecmp(ext,"txt",3)) return load_dlm(filename);
22448 if (!cimg::strncasecmp(ext,"inr",3)) return load_inr(filename);
22449 if (!cimg::strncasecmp(ext,"hdr",3) ||
22450 !cimg::strncasecmp(ext,"nii",3)) return load_analyze(filename);
22451 if (!cimg::strncasecmp(ext,"par",3) ||
22452 !cimg::strncasecmp(ext,"rec",3)) return load_parrec(filename);
22453 if (!cimg::strncasecmp(ext,"pan",3)) return load_pandore(filename);
22454 if (!cimg::strncasecmp(ext,"bmp",3)) return load_bmp(filename);
22455 if (!cimg::strncasecmp(ext,"png",3)) return load_png(filename);
22456 if (!cimg::strncasecmp(ext,"tif",3)) return load_tiff(filename);
22457 if (!cimg::strncasecmp(ext,"jpg",3) ||
22458 !cimg::strncasecmp(ext,"jpeg",4)) return load_jpeg(filename);
22459 if (!cimg::strncasecmp(ext,"ppm",3) ||
22460 !cimg::strncasecmp(ext,"pgm",3) ||
22461 !cimg::strncasecmp(ext,"pnm",3)) return load_pnm(filename);
22462 if (!cimg::strncasecmp(ext,"cimg",4) ||
22463 ext[0]=='\0') return load_cimg(filename);
22464 if (!cimg::strncasecmp(ext,"dcm",3) ||
22465 !cimg::strncasecmp(ext,"dicom",5)) return load_dicom(filename);
22466 return load_other(filename);
22467 }
22468
22470 static CImg<T> get_load_ascii(std::FILE *const file, const char *const filename=0) {
22471 return CImg<T>().load_ascii(file,filename);
22472 }
22473
22474 CImg<T>& load_ascii(std::FILE *const file, const char *const filename=0) {
22475 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
22476 char line[256] = { 0 };
22477 std::fscanf(nfile,"%255[^\n]",line);
22478 unsigned int off, dx = 0, dy = 1, dz = 1, dv = 1;
22479 int err = 1;
22480 std::sscanf(line,"%u %u %u %u",&dx,&dy,&dz,&dv);
22481 if (!dx || !dy || !dz || !dv) {
22482 if (!file) cimg::fclose(nfile);
22483 throw CImgIOException("CImg<%s>::load_ascii() : File '%s' is not a valid .ASC file.\n"
22484 "Specified image dimensions are (%u,%u,%u,%u).",
22485 pixel_type(),filename?filename:"(FILE*)",dx,dy,dz,dv);
22486 }
22487 assign(dx,dy,dz,dv);
22488 const unsigned int siz = size();
22489 double val;
22490 T *ptr = data;
22491 for (off=0; off<siz && err==1; ++off) {
22492 err = std::fscanf(nfile,"%lf%*[^0-9.eE+-]",&val);
22493 *(ptr++) = (T)val;
22494 }
22495 if (off<size()) cimg::warn("CImg<%s>::load_ascii() : File '%s', only %u/%u values read.",
22496 pixel_type(),filename?filename:"(FILE*)",off,siz);
22497 if (!file) cimg::fclose(nfile);
22498 return *this;
22499 }
22500
22502 static CImg<T> get_load_ascii(const char *const filename) {
22503 return CImg<T>().load_ascii(0,filename);
22504 }
22505
22506 CImg<T>& load_ascii(const char *const filename) {
22507 return load_ascii(0,filename);
22508 }
22509
22511 static CImg<T> get_load_dlm(std::FILE *const file, const char *const filename=0) {
22512 return CImg<T>().load_dlm(file,filename);
22513 }
22514
22515 CImg<T>& load_dlm(std::FILE *const file, const char *const filename=0) {
22516 std::FILE *const nfile = file?file:cimg::fopen(filename,"r");
22517 assign(256,256);
22518 char c, delimiter[256] = { 0 }, tmp[256];
22519 unsigned int cdx = 0, dx = 0, dy = 0;
22520 int oerr = 0, err;
22521 double val;
22522 while ((err = std::fscanf(nfile,"%lf%255[^0-9.eE+-]",&val,delimiter))!=EOF) {
22523 oerr = err;
22524 if (err>0) (*this)(cdx++,dy) = (T)val;
22525 if (cdx>=width) resize(width+256,1,1,1,0);
22526 c = 0; if (!std::sscanf(delimiter,"%255[^\n]%c",tmp,&c) || c=='\n') {
22527 dx = cimg::max(cdx,dx);
22528 ++dy;
22529 if (dy>=height) resize(width,height+256,1,1,0);
22530 cdx = 0;
22531 }
22532 }
22533 if (cdx && oerr==1) { dx=cdx; ++dy; }
22534 if (!dx || !dy) {
22535 if (!file) cimg::fclose(nfile);
22536 throw CImgIOException("CImg<%s>::load_dlm() : File '%s' is not a valid DLM file.\n"
22537 "Specified image dimensions are (%u,%u).",
22538 pixel_type(),filename?filename:"(FILE*)",dx,dy);
22539 }
22540 resize(dx,dy,1,1,0);
22541 if (!file) cimg::fclose(nfile);
22542 return *this;
22543 }
22544
22546 static CImg<T> get_load_dlm(const char *const filename) {
22547 return CImg<T>().load_dlm(0,filename);
22548 }
22549
22550 CImg<T>& load_dlm(const char *const filename) {
22551 return load_dlm(0,filename);
22552 }
22553
22555 static CImg<T> get_load_pnm(std::FILE *const file, const char *const filename=0) {
22556 return CImg<T>().load_pnm(file, filename);
22557 }
22558
22559 CImg<T>& load_pnm(std::FILE *const file, const char *const filename=0) {
22560 std::FILE *const nfile=file?file:cimg::fopen(filename,"rb");
22561 unsigned int ppm_type, W, H, colormax=255;
22562 char item[1024] = { 0 };
22563 int err, rval, gval, bval;
22564 const int cimg_iobuffer = 12*1024*1024;
22565 while ((err=std::fscanf(nfile,"%1023[^\n]",item))!=EOF && (item[0]=='#' || !err)) std::fgetc(nfile);
22566 if(std::sscanf(item," P%u",&ppm_type)!=1) {
22567 if (!file) cimg::fclose(nfile);
22568 throw CImgIOException("CImg<%s>::load_pnm() : File '%s', PNM header 'P?' not found.",
22569 pixel_type(),filename?filename:"(FILE*)");
22570 }
22571 while ((err=std::fscanf(nfile," %1023[^\n]",item))!=EOF && (item[0]=='#' || !err)) std::fgetc(nfile);
22572 if ((err=std::sscanf(item," %u %u %u",&W,&H,&colormax))<2) {
22573 if (!file) cimg::fclose(nfile);
22574 throw CImgIOException("CImg<%s>::load_pnm() : File '%s', WIDTH and HEIGHT fields are not defined in PNM header.",
22575 pixel_type(),filename?filename:"(FILE*)");
22576 }
22577 if (err==2) {
22578 while ((err=std::fscanf(nfile," %1023[^\n]",item))!=EOF && (item[0]=='#' || !err)) std::fgetc(nfile);
22579 if (std::sscanf(item,"%u",&colormax)!=1)
22580 cimg::warn("CImg<%s>::load_pnm() : File '%s', COLORMAX field is not defined in PNM header.",
22581 pixel_type(),filename?filename:"(FILE*)");
22582 }
22583 std::fgetc(nfile);
22584 assign();
22585
22586 switch (ppm_type) {
22587 case 2: {
22588 assign(W,H,1,1);
22589 T* rdata = data;
22590 cimg_foroff(*this,off) { std::fscanf(nfile,"%d",&rval); *(rdata++) = (T)rval; }
22591 } break;
22592 case 3: {
22593 assign(W,H,1,3);
22594 T *rdata = ptr(0,0,0,0), *gdata = ptr(0,0,0,1), *bdata = ptr(0,0,0,2);
22595 cimg_forXY(*this,x,y) {
22596 std::fscanf(nfile,"%d %d %d",&rval,&gval,&bval);
22597 *(rdata++) = (T)rval;
22598 *(gdata++) = (T)gval;
22599 *(bdata++) = (T)bval; }
22600 } break;
22601 case 5: {
22602 if (colormax<256) {
22603 CImg<unsigned char> raw;
22604 assign(W,H,1,1);
22605 T *ptrd = ptr(0,0,0,0);
22606 for (int toread = (int)size(); toread>0; ) {
22607 raw.assign(cimg::min(toread,cimg_iobuffer));
22608 cimg::fread(raw.data,raw.width,nfile);
22609 toread-=raw.width;
22610 const unsigned char *ptrs = raw.data;
22611 for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++);
22612 }
22613 } else {
22614 CImg<unsigned short> raw;
22615 assign(W,H,1,1);
22616 T *ptrd = ptr(0,0,0,0);
22617 for (int toread = (int)size(); toread>0; ) {
22618 raw.assign(cimg::min(toread,cimg_iobuffer/2));
22619 cimg::fread(raw.data,raw.width,nfile);
22620 toread-=raw.width;
22621 const unsigned short *ptrs = raw.data;
22622 for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++);
22623 }
22624 }
22625 } break;
22626 case 6: {
22627 if (colormax<256) {
22628 CImg<unsigned char> raw;
22629 assign(W,H,1,3);
22630 T
22631 *ptr_r = ptr(0,0,0,0),
22632 *ptr_g = ptr(0,0,0,1),
22633 *ptr_b = ptr(0,0,0,2);
22634 for (int toread = (int)size(); toread>0; ) {
22635 raw.assign(cimg::min(toread,cimg_iobuffer));
22636 cimg::fread(raw.data,raw.width,nfile);
22637 toread-=raw.width;
22638 const unsigned char *ptrs = raw.data;
22639 for (unsigned int off = raw.width/3; off; --off) {
22640 *(ptr_r++) = (T)*(ptrs++);
22641 *(ptr_g++) = (T)*(ptrs++);
22642 *(ptr_b++) = (T)*(ptrs++);
22643 }
22644 }
22645 } else {
22646 CImg<unsigned short> raw;
22647 assign(W,H,1,3);
22648 T
22649 *ptr_r = ptr(0,0,0,0),
22650 *ptr_g = ptr(0,0,0,1),
22651 *ptr_b = ptr(0,0,0,2);
22652 for (int toread = (int)size(); toread>0; ) {
22653 raw.assign(cimg::min(toread,cimg_iobuffer/2));
22654 cimg::fread(raw.data,raw.width,nfile);
22655 if (!cimg::endian()) cimg::endian_swap(raw.data,raw.width);
22656 toread-=raw.width;
22657 const unsigned short *ptrs = raw.data;
22658 for (unsigned int off = raw.width/3; off; --off) {
22659 *(ptr_r++) = (T)*(ptrs++);
22660 *(ptr_g++) = (T)*(ptrs++);
22661 *(ptr_b++) = (T)*(ptrs++);
22662 }
22663 }
22664 }
22665 } break;
22666 default:
22667 if (!file) cimg::fclose(nfile);
22668 throw CImgIOException("CImg<%s>::load_pnm() : File '%s', PPM type 'P%d' not supported.",
22669 pixel_type(),filename?filename:"(FILE*)",ppm_type);
22670 }
22671 if (!file) cimg::fclose(nfile);
22672 return *this;
22673 }
22674
22676 static CImg<T> get_load_pnm(const char *const filename) {
22677 return get_load_pnm(0,filename);
22678 }
22679
22680 CImg<T>& load_pnm(const char *const filename) {
22681 return load_pnm(0,filename);
22682 }
22683
22685 static CImg<T> get_load_bmp(std::FILE *const file, const char *const filename=0) {
22686 return CImg<T>().load_bmp(file,filename);
22687 }
22688
22689 CImg<T>& load_bmp(std::FILE *const file, const char *const filename=0) {
22690 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
22691 unsigned char header[64];
22692 cimg::fread(header,54,nfile);
22693 if (header[0]!='B' || header[1]!='M') {
22694 if (!file) cimg::fclose(nfile);
22695 throw CImgIOException("CImg<%s>::load_bmp() : File '%s' is not a valid BMP file.",
22696 pixel_type(),filename?filename:"(FILE*)");
22697 }
22698 assign();
22699
22700
22701 int
22702 file_size = header[0x02] + (header[0x03]<<8) + (header[0x04]<<16) + (header[0x05]<<24),
22703 offset = header[0x0A] + (header[0x0B]<<8) + (header[0x0C]<<16) + (header[0x0D]<<24),
22704 dx = header[0x12] + (header[0x13]<<8) + (header[0x14]<<16) + (header[0x15]<<24),
22705 dy = header[0x16] + (header[0x17]<<8) + (header[0x18]<<16) + (header[0x19]<<24),
22706 compression = header[0x1E] + (header[0x1F]<<8) + (header[0x20]<<16) + (header[0x21]<<24),
22707 nb_colors = header[0x2E] + (header[0x2F]<<8) + (header[0x30]<<16) + (header[0x31]<<24),
22708 bpp = header[0x1C] + (header[0x1D]<<8),
22709 *palette = 0;
22710 const int
22711 dx_bytes = (bpp==1)?(dx/8+(dx%8?1:0)):((bpp==4)?(dx/2+(dx%2?1:0)):(dx*bpp/8)),
22712 align = (4-dx_bytes%4)%4,
22713 buf_size = cimg::min(cimg::abs(dy)*(dx_bytes+align),file_size-offset);
22714
22715 if (bpp<16) { if (!nb_colors) nb_colors=1<<bpp; } else nb_colors = 0;
22716 if (nb_colors) { palette = new int[nb_colors]; cimg::fread(palette,nb_colors,nfile); }
22717 const int xoffset = offset-54-4*nb_colors;
22718 if (xoffset>0) std::fseek(nfile,xoffset,SEEK_CUR);
22719 unsigned char *buffer = new unsigned char[buf_size], *ptrs = buffer;
22720 cimg::fread(buffer,buf_size,nfile);
22721 if (!file) cimg::fclose(nfile);
22722
22723
22724 if (compression) {
22725 delete[] buffer;
22726 if (file) {
22727 throw CImgIOException("CImg<%s>::load_bmp() : Not able to read a compressed BMP file using a *FILE input",pixel_type());
22728 } else return load_other(filename);
22729 }
22730
22731
22732 assign(dx,cimg::abs(dy),1,3);
22733 switch (bpp) {
22734 case 1: {
22735 for (int y=height-1; y>=0; --y) {
22736 unsigned char mask = 0x80, val = 0;
22737 cimg_forX(*this,x) {
22738 if (mask==0x80) val = *(ptrs++);
22739 const unsigned char *col = (unsigned char*)(palette+(val&mask?1:0));
22740 (*this)(x,y,2) = (T)*(col++);
22741 (*this)(x,y,1) = (T)*(col++);
22742 (*this)(x,y,0) = (T)*(col++);
22743 mask = cimg::ror(mask);
22744 } ptrs+=align; }
22745 } break;
22746 case 4: {
22747 for (int y=height-1; y>=0; --y) {
22748 unsigned char mask = 0xF0, val = 0;
22749 cimg_forX(*this,x) {
22750 if (mask==0xF0) val = *(ptrs++);
22751 const unsigned char color = (unsigned char)((mask<16)?(val&mask):((val&mask)>>4));
22752 unsigned char *col = (unsigned char*)(palette+color);
22753 (*this)(x,y,2) = (T)*(col++);
22754 (*this)(x,y,1) = (T)*(col++);
22755 (*this)(x,y,0) = (T)*(col++);
22756 mask = cimg::ror(mask,4);
22757 } ptrs+=align; }
22758 } break;
22759 case 8: {
22760 for (int y=height-1; y>=0; --y) { cimg_forX(*this,x) {
22761 const unsigned char *col = (unsigned char*)(palette+*(ptrs++));
22762 (*this)(x,y,2) = (T)*(col++);
22763 (*this)(x,y,1) = (T)*(col++);
22764 (*this)(x,y,0) = (T)*(col++);
22765 } ptrs+=align; }
22766 } break;
22767 case 16: {
22768 for (int y=height-1; y>=0; --y) { cimg_forX(*this,x) {
22769 const unsigned char c1 = *(ptrs++), c2 = *(ptrs++);
22770 const unsigned short col = (unsigned short)(c1|(c2<<8));
22771 (*this)(x,y,2) = (T)(col&0x1F);
22772 (*this)(x,y,1) = (T)((col>>5)&0x1F);
22773 (*this)(x,y,0) = (T)((col>>10)&0x1F);
22774 } ptrs+=align; }
22775 } break;
22776 case 24: {
22777 for (int y=height-1; y>=0; --y) { cimg_forX(*this,x) {
22778 (*this)(x,y,2) = (T)*(ptrs++);
22779 (*this)(x,y,1) = (T)*(ptrs++);
22780 (*this)(x,y,0) = (T)*(ptrs++);
22781 } ptrs+=align; }
22782 } break;
22783 case 32: {
22784 for (int y=height-1; y>=0; --y) { cimg_forX(*this,x) {
22785 (*this)(x,y,2) = (T)*(ptrs++);
22786 (*this)(x,y,1) = (T)*(ptrs++);
22787 (*this)(x,y,0) = (T)*(ptrs++);
22788 ++ptrs;
22789 } ptrs+=align; }
22790 } break;
22791 }
22792 if (palette) delete[] palette;
22793 delete[] buffer;
22794 if (dy<0) mirror('y');
22795 return *this;
22796 }
22797
22799 static CImg<T> get_load_bmp(const char *const filename) {
22800 return CImg<T>().load_bmp(0,filename);
22801 }
22802
22803 CImg<T>& load_bmp(const char *const filename) {
22804 return load_bmp(0,filename);
22805 }
22806
22808
22809 static CImg<T> get_load_png(std::FILE *const file, const char *const filename=0) {
22810 return CImg<T>().load_png(file,filename);
22811 }
22812
22813 CImg<T>& load_png(std::FILE *const file, const char *const filename=0) {
22814 #ifndef cimg_use_png
22815 if (file)
22816 throw CImgIOException("CImg<%s>::load_png() : File '(FILE*)' cannot be read without using libpng.",pixel_type());
22817 else return load_other(filename);
22818 #else
22819
22820 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
22821 unsigned char pngCheck[8];
22822 cimg::fread(pngCheck,8,nfile);
22823 if (png_sig_cmp(pngCheck,0,8)) {
22824 if (!file) cimg::fclose(nfile);
22825 throw CImgIOException("CImg<%s>::load_png() : File '%s' is not a valid PNG file.",
22826 pixel_type(),filename?filename:"(FILE*)");
22827 }
22828
22829
22830 png_voidp user_error_ptr = 0;
22831 png_error_ptr user_error_fn = 0, user_warning_fn = 0;
22832 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
22833 user_error_ptr, user_error_fn, user_warning_fn);
22834 if(!png_ptr){
22835 if (!file) cimg::fclose(nfile);
22836 throw CImgIOException("CImg<%s>::load_png() : File '%s', trouble initializing 'png_ptr' data structure.",
22837 pixel_type(),filename?filename:"(FILE*)");
22838 }
22839 png_infop info_ptr = png_create_info_struct(png_ptr);
22840 if(!info_ptr){
22841 if (!file) cimg::fclose(nfile);
22842 png_destroy_read_struct(&png_ptr, (png_infopp)0, (png_infopp)0);
22843 throw CImgIOException("CImg<%s>::load_png() : File '%s', trouble initializing 'info_ptr' data structure.",
22844 pixel_type(),filename?filename:"(FILE*)");
22845 }
22846 png_infop end_info = png_create_info_struct(png_ptr);
22847 if(!end_info){
22848 if (!file) cimg::fclose(nfile);
22849 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)0);
22850 throw CImgIOException("CImg<%s>::load_png() : File '%s', trouble initializing 'end_info' data structure.",
22851 pixel_type(),filename?filename:"(FILE*)");
22852 }
22853
22854
22855 if (setjmp(png_jmpbuf(png_ptr))){
22856 if (!file) cimg::fclose(nfile);
22857 png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
22858 throw CImgIOException("CImg<%s>::load_png() : File '%s', unknown fatal error.",
22859 pixel_type(),filename?filename:"(FILE*)");
22860 }
22861 png_init_io(png_ptr, nfile);
22862 png_set_sig_bytes(png_ptr, 8);
22863
22864
22865 png_read_info(png_ptr, info_ptr);
22866 png_uint_32 W, H;
22867 int bit_depth, color_type, interlace_type;
22868 png_get_IHDR(png_ptr, info_ptr, &W, &H, &bit_depth, &color_type, &interlace_type,
22869 int_p_NULL, int_p_NULL);
22870 int new_bit_depth = bit_depth;
22871 int new_color_type = color_type;
22872
22873
22874 if (new_color_type == PNG_COLOR_TYPE_PALETTE){
22875 png_set_palette_to_rgb(png_ptr);
22876 new_color_type -= PNG_COLOR_MASK_PALETTE;
22877 new_bit_depth = 8;
22878 }
22879 if (new_color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8){
22880 png_set_gray_1_2_4_to_8(png_ptr);
22881 new_bit_depth = 8;
22882 }
22883 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
22884 png_set_tRNS_to_alpha(png_ptr);
22885 if (new_color_type == PNG_COLOR_TYPE_GRAY || new_color_type == PNG_COLOR_TYPE_GRAY_ALPHA){
22886 png_set_gray_to_rgb(png_ptr);
22887 new_color_type |= PNG_COLOR_MASK_COLOR;
22888 }
22889 if (new_color_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, 0xffffU, PNG_FILLER_AFTER);
22890 png_read_update_info(png_ptr, info_ptr);
22891 if (!(new_bit_depth==8 || new_bit_depth==16)) {
22892 if (!file) cimg::fclose(nfile);
22893 png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
22894 throw CImgIOException("CImg<%s>::load_png() : File '%s', wrong bit coding (bit_depth=%u)",
22895 pixel_type(),filename?filename:"(FILE*)",new_bit_depth);
22896 }
22897 const int byte_depth = new_bit_depth>>3;
22898
22899
22900 png_bytep *imgData = new png_bytep[H];
22901 for (unsigned int row=0; row < H; ++row) imgData[row] = new png_byte[byte_depth * 4 * W];
22902 png_read_image(png_ptr, imgData);
22903 png_read_end(png_ptr, end_info);
22904
22905
22906 if (!(new_color_type==PNG_COLOR_TYPE_RGB || new_color_type==PNG_COLOR_TYPE_RGB_ALPHA)) {
22907 if (!file) cimg::fclose(nfile);
22908 png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
22909 throw CImgIOException("CImg<%s>::load_png() : File '%s', wrong color coding (new_color_type=%u)",
22910 pixel_type(),filename?filename:"(FILE*)",new_color_type);
22911 }
22912 const bool no_alpha_channel = (new_color_type==PNG_COLOR_TYPE_RGB);
22913 assign(W,H,1,no_alpha_channel?3:4);
22914 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);
22915 switch(new_bit_depth) {
22916 case 8: {
22917 cimg_forY(*this,y){
22918 const unsigned char *ptrs = (unsigned char*)imgData[y];
22919 cimg_forX(*this,x){
22920 *(ptr1++) = (T)*(ptrs++);
22921 *(ptr2++) = (T)*(ptrs++);
22922 *(ptr3++) = (T)*(ptrs++);
22923 if (no_alpha_channel) ++ptrs; else *(ptr4++) = (T)*(ptrs++);
22924 }
22925 }
22926 } break;
22927 case 16: {
22928 cimg_forY(*this,y){
22929 const unsigned short *ptrs = (unsigned short*)(imgData[y]);
22930 cimg_forX(*this,x){
22931 *(ptr1++) = (T)*(ptrs++);
22932 *(ptr2++) = (T)*(ptrs++);
22933 *(ptr3++) = (T)*(ptrs++);
22934 if (no_alpha_channel) ++ptrs; else *(ptr4++) = (T)*(ptrs++);
22935 }
22936 }
22937 } break;
22938 }
22939 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
22940
22941
22942 for (unsigned int n=0; n<H; ++n) delete[] imgData[n];
22943 delete[] imgData;
22944 if (!file) cimg::fclose(nfile);
22945 return *this;
22946 #endif
22947 }
22948
22950 static CImg<T> get_load_png(const char *const filename) {
22951 return CImg<T>().load_png(0,filename);
22952 }
22953
22954 CImg<T>& load_png(const char *const filename) {
22955 return load_png(0,filename);
22956 }
22957
22959
22960 static CImg<T> get_load_tiff(const char *const filename) {
22961 return CImg<T>().load_tiff(filename);
22962 }
22963
22964 CImg<T>& load_tiff(const char *const filename) {
22965 #ifndef cimg_use_tiff
22966 return load_other(filename);
22967 #else
22968 TIFF *tif = TIFFOpen(filename,"r");
22969 #if cimg_debug>=3
22970 TIFFSetWarningHandler(0);
22971 TIFFSetErrorHandler(0);
22972 #endif
22973 if (tif) {
22974 unsigned int number_of_directories = 0;
22975 do ++number_of_directories; while (TIFFReadDirectory(tif));
22976 uint16 samplesperpixel, bitspersample;
22977 uint32 nx,ny;
22978 TIFFGetField(tif,TIFFTAG_IMAGEWIDTH,&nx);
22979 TIFFGetField(tif,TIFFTAG_IMAGELENGTH,&ny);
22980 TIFFGetField(tif,TIFFTAG_SAMPLESPERPIXEL,&samplesperpixel);
22981 if (samplesperpixel!=1 && samplesperpixel!=3 && samplesperpixel!=4) {
22982 cimg::warn("CImg<%s>::load_tiff() : File '%s', unknow value for tag : TIFFTAG_SAMPLESPERPIXEL, will force it to 1.",
22983 pixel_type(),filename?filename:"(FILE*)");
22984 samplesperpixel=1;
22985 }
22986 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
22987 TIFFClose(tif);
22988 tif = TIFFOpen(filename,"r");
22989 assign(nx,ny,number_of_directories,samplesperpixel);
22990 unsigned int dir = 0;
22991 do {
22992 if (bitspersample!=8 || !(samplesperpixel == 3 || samplesperpixel == 4)) {
22993 uint16 photo, config;
22994 TIFFGetField(tif,TIFFTAG_PLANARCONFIG,&config);
22995 TIFFGetField(tif,TIFFTAG_PHOTOMETRIC,&photo);
22996 if (TIFFIsTiled(tif)) {
22997 uint32 tw, th;
22998 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
22999 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
23000 if (config==PLANARCONFIG_CONTIG) switch(bitspersample) {
23001 case 8: {
23002 unsigned char *buf = (unsigned char*)_TIFFmalloc(TIFFTileSize(tif));
23003 if (buf) {
23004 for (unsigned int row = 0; row<ny; row+=th)
23005 for (unsigned int col = 0; col<nx; col+=tw) {
23006 if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
23007 _TIFFfree(buf); TIFFClose(tif);
23008 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
23009 pixel_type(),filename?filename:"(FILE*)");
23010 } else {
23011 unsigned char *ptr = buf;
23012 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
23013 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
23014 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23015 (*this)(cc,rr,dir,vv) = (T)(float)(ptr[(rr-row)*th*samplesperpixel + (cc-col)*samplesperpixel + vv]);
23016 }
23017 }
23018 _TIFFfree(buf);
23019 }
23020 } break;
23021 case 16: {
23022 unsigned short *buf = (unsigned short*)_TIFFmalloc(TIFFTileSize(tif));
23023 if (buf) {
23024 for (unsigned int row = 0; row<ny; row+=th)
23025 for (unsigned int col = 0; col<nx; col+=tw) {
23026 if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
23027 _TIFFfree(buf); TIFFClose(tif);
23028 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
23029 pixel_type(),filename?filename:"(FILE*)");
23030 } else {
23031 unsigned short *ptr = buf;
23032 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
23033 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
23034 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23035 (*this)(cc,rr,dir,vv) = (T)(float)(ptr[(rr-row)*th*samplesperpixel + (cc-col)*samplesperpixel + vv]);
23036 }
23037 }
23038 _TIFFfree(buf);
23039 }
23040 } break;
23041 case 32: {
23042 float *buf = (float*)_TIFFmalloc(TIFFTileSize(tif));
23043 if (buf) {
23044 for (unsigned int row = 0; row<ny; row+=th)
23045 for (unsigned int col = 0; col<nx; col+=tw) {
23046 if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
23047 _TIFFfree(buf); TIFFClose(tif);
23048 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
23049 pixel_type(),filename?filename:"(FILE*)");
23050 } else {
23051 float *ptr = buf;
23052 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
23053 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
23054 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23055 (*this)(cc,rr,dir,vv) = (T)(float)(ptr[(rr-row)*th*samplesperpixel + (cc-col)*samplesperpixel + vv]);
23056 }
23057 }
23058 _TIFFfree(buf);
23059 }
23060 } break;
23061 } else switch (bitspersample) {
23062 case 8: {
23063 unsigned char *buf = (unsigned char*)_TIFFmalloc(TIFFTileSize(tif));
23064 if (buf) {
23065 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23066 for (unsigned int row = 0; row<ny; row+=th)
23067 for (unsigned int col = 0; col<nx; col+=tw) {
23068 if (TIFFReadTile(tif,buf,col,row,0,vv)<0) {
23069 _TIFFfree(buf); TIFFClose(tif);
23070 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
23071 pixel_type(),filename?filename:"(FILE*)");
23072 } else {
23073 unsigned char *ptr = buf;
23074 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
23075 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
23076 (*this)(cc,rr,dir,vv) = (T)(float)*(ptr++);
23077 }
23078 }
23079 _TIFFfree(buf);
23080 }
23081 } break;
23082 case 16: {
23083 unsigned short *buf = (unsigned short*)_TIFFmalloc(TIFFTileSize(tif));
23084 if (buf) {
23085 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23086 for (unsigned int row = 0; row<ny; row+=th)
23087 for (unsigned int col = 0; col<nx; col+=tw) {
23088 if (TIFFReadTile(tif,buf,col,row,0,vv)<0) {
23089 _TIFFfree(buf); TIFFClose(tif);
23090 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
23091 pixel_type(),filename?filename:"(FILE*)");
23092 } else {
23093 unsigned short *ptr = buf;
23094 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
23095 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
23096 (*this)(cc,rr,dir,vv) = (T)(float)*(ptr++);
23097 }
23098 }
23099 _TIFFfree(buf);
23100 }
23101 } break;
23102 case 32: {
23103 float *buf = (float*)_TIFFmalloc(TIFFTileSize(tif));
23104 if (buf) {
23105 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23106 for (unsigned int row = 0; row<ny; row+=th)
23107 for (unsigned int col = 0; col<nx; col+=tw) {
23108 if (TIFFReadTile(tif,buf,col,row,0,vv)<0) {
23109 _TIFFfree(buf); TIFFClose(tif);
23110 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a tile.",
23111 pixel_type(),filename?filename:"(FILE*)");
23112 } else {
23113 float *ptr = buf;
23114 for (unsigned int rr=row; rr<cimg::min((unsigned int)(row+th),(unsigned int)ny); ++rr)
23115 for (unsigned int cc=col; cc<cimg::min((unsigned int)(col+tw),(unsigned int)nx); ++cc)
23116 (*this)(cc,rr,dir,vv) = (T)(float)*(ptr++);
23117 }
23118 }
23119 _TIFFfree(buf);
23120 }
23121 } break;
23122 }
23123 } else {
23124 if (config==PLANARCONFIG_CONTIG) switch (bitspersample) {
23125 case 8: {
23126 unsigned char *buf = (unsigned char*)_TIFFmalloc(TIFFStripSize(tif));
23127 if (buf) {
23128 uint32 row, rowsperstrip = (uint32)-1;
23129 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23130 for (row = 0; row<ny; row+= rowsperstrip) {
23131 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23132 tstrip_t strip = TIFFComputeStrip(tif, row, 0);
23133 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23134 _TIFFfree(buf); TIFFClose(tif);
23135 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a strip.",
23136 pixel_type(),filename?filename:"(FILE*)");
23137 }
23138 unsigned char *ptr = buf;
23139 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23140 for (unsigned int vv=0; vv<samplesperpixel; ++vv) (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23141 }
23142 _TIFFfree(buf);
23143 }
23144 } break;
23145 case 16: {
23146 unsigned short *buf = (unsigned short*)_TIFFmalloc(TIFFStripSize(tif));
23147 if (buf) {
23148 uint32 row, rowsperstrip = (uint32)-1;
23149 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23150 for (row = 0; row<ny; row+= rowsperstrip) {
23151 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23152 tstrip_t strip = TIFFComputeStrip(tif, row, 0);
23153 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23154 _TIFFfree(buf); TIFFClose(tif);
23155 throw CImgException("CImg<%s>::load_tiff() : File '%s', error while reading a strip.",
23156 pixel_type(),filename?filename:"(FILE*)");
23157 }
23158 unsigned short *ptr = buf;
23159 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23160 for (unsigned int vv=0; vv<samplesperpixel; ++vv) (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23161 }
23162 _TIFFfree(buf);
23163 }
23164 } break;
23165 case 32: {
23166 float *buf = (float*)_TIFFmalloc(TIFFStripSize(tif));
23167 if (buf) {
23168 uint32 row, rowsperstrip = (uint32)-1;
23169 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23170 for (row = 0; row<ny; row+= rowsperstrip) {
23171 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23172 tstrip_t strip = TIFFComputeStrip(tif, row, 0);
23173 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23174 _TIFFfree(buf); TIFFClose(tif);
23175 throw CImgException("CImg<%s>::load_tiff() : File '%s', error while reading a strip.",
23176 pixel_type(),filename?filename:"(FILE*)");
23177 }
23178 float *ptr = buf;
23179 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23180 for (unsigned int vv=0; vv<samplesperpixel; ++vv) (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23181 }
23182 _TIFFfree(buf);
23183 }
23184 } break;
23185 } else switch(bitspersample){
23186 case 8: {
23187 unsigned char *buf = (unsigned char*)_TIFFmalloc(TIFFStripSize(tif));
23188 if (buf) {
23189 uint32 row, rowsperstrip = (uint32)-1;
23190 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23191 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23192 for (row = 0; row<ny; row+= rowsperstrip) {
23193 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23194 tstrip_t strip = TIFFComputeStrip(tif, row, vv);
23195 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23196 _TIFFfree(buf); TIFFClose(tif);
23197 throw CImgException("CImg<%s>::load_tiff() : File '%s', an error occure while reading a strip.",
23198 pixel_type(),filename?filename:"(FILE*)");
23199 }
23200 unsigned char *ptr = buf;
23201 for (unsigned int rr=0;rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23202 (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23203 }
23204 _TIFFfree(buf);
23205 }
23206 } break;
23207 case 16: {
23208 unsigned short *buf = (unsigned short*)_TIFFmalloc(TIFFStripSize(tif));
23209 if (buf) {
23210 uint32 row, rowsperstrip = (uint32)-1;
23211 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23212 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23213 for (row = 0; row<ny; row+= rowsperstrip) {
23214 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23215 tstrip_t strip = TIFFComputeStrip(tif, row, vv);
23216 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23217 _TIFFfree(buf); TIFFClose(tif);
23218 throw CImgException("CImg<%s>::load_tiff() : File '%s', error while reading a strip.",
23219 pixel_type(),filename?filename:"(FILE*)");
23220 }
23221 unsigned short *ptr = buf;
23222 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23223 (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23224 }
23225 _TIFFfree(buf);
23226 }
23227 } break;
23228 case 32: {
23229 float *buf = (float*)_TIFFmalloc(TIFFStripSize(tif));
23230 if (buf) {
23231 uint32 row, rowsperstrip = (uint32)-1;
23232 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
23233 for (unsigned int vv=0; vv<samplesperpixel; ++vv)
23234 for (row = 0; row<ny; row+= rowsperstrip) {
23235 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
23236 tstrip_t strip = TIFFComputeStrip(tif, row, vv);
23237 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
23238 _TIFFfree(buf); TIFFClose(tif);
23239 throw CImgException("CImg<%s>::load_tiff() : File '%s', error while reading a strip.",
23240 pixel_type(),filename?filename:"(FILE*)");
23241 }
23242 float *ptr = buf;
23243 for (unsigned int rr=0; rr<nrow; ++rr) for (unsigned int cc=0; cc<nx; ++cc)
23244 (*this)(cc,row+rr,dir,vv) = (T)(float)*(ptr++);
23245 }
23246 _TIFFfree(buf);
23247 }
23248 } break;
23249 }
23250 }
23251 } else {
23252 uint32* raster = (uint32*)_TIFFmalloc(nx * ny * sizeof (uint32));
23253 if (!raster) {
23254 _TIFFfree(raster); TIFFClose(tif);
23255 throw CImgException("CImg<%s>::load_tiff() : File '%s', not enough memory for buffer allocation.",
23256 pixel_type(),filename?filename:"(FILE*)");
23257 }
23258 TIFFReadRGBAImage(tif,nx,ny,raster,0);
23259 switch (samplesperpixel) {
23260 case 1: {
23261 cimg_forXY(*this,x,y) (*this)(x,y,dir) = (T)(float)((raster[nx*(ny-1-y)+x]+ 128) / 257);
23262 } break;
23263 case 3: {
23264 cimg_forXY(*this,x,y) {
23265 (*this)(x,y,dir,0) = (T)(float)TIFFGetR(raster[nx*(ny-1-y)+x]);
23266 (*this)(x,y,dir,1) = (T)(float)TIFFGetG(raster[nx*(ny-1-y)+x]);
23267 (*this)(x,y,dir,2) = (T)(float)TIFFGetB(raster[nx*(ny-1-y)+x]);
23268 }
23269 } break;
23270 case 4: {
23271 cimg_forXY(*this,x,y) {
23272 (*this)(x,y,dir,0) = (T)(float)TIFFGetR(raster[nx*(ny-1-y)+x]);
23273 (*this)(x,y,dir,1) = (T)(float)TIFFGetG(raster[nx*(ny-1-y)+x]);
23274 (*this)(x,y,dir,2) = (T)(float)TIFFGetB(raster[nx*(ny-1-y)+x]);
23275 (*this)(x,y,dir,3) = (T)(float)TIFFGetA(raster[nx*(ny-1-y)+x]);
23276 }
23277 } break;
23278 }
23279 _TIFFfree(raster);
23280 }
23281 ++dir;
23282 } while (TIFFReadDirectory(tif));
23283 TIFFClose(tif);
23284 } else throw CImgException("CImg<%s>::load_tiff() : File '%s', error while loading the image.",
23285 pixel_type(),filename?filename:"(FILE*)");
23286 return *this;
23287 #endif
23288 }
23289
23291 static CImg<T> get_load_jpeg(std::FILE *const file, const char *const filename=0) {
23292 return CImg<T>().load_jpeg(file,filename);
23293 }
23294
23295 CImg<T>& load_jpeg(std::FILE *const file, const char *const filename=0) {
23296 #ifndef cimg_use_jpeg
23297 if (file)
23298 throw CImgIOException("CImg<%s>::load_jpeg() : File '(FILE*)' cannot be read without using libjpeg.",
23299 pixel_type());
23300 else return load_other(filename);
23301 #else
23302 struct jpeg_decompress_struct cinfo;
23303 struct jpeg_error_mgr jerr;
23304 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23305
23306 cinfo.err = jpeg_std_error(&jerr);
23307 jpeg_create_decompress(&cinfo);
23308 jpeg_stdio_src(&cinfo,nfile);
23309 jpeg_read_header(&cinfo,TRUE);
23310 jpeg_start_decompress(&cinfo);
23311
23312 if (cinfo.output_components!=1 && cinfo.output_components!=3 && cinfo.output_components!=4) {
23313 cimg::warn("CImg<%s>::load_jpeg() : Don't know how to read image '%s' with libpeg, trying ImageMagick's convert",
23314 pixel_type(),filename?filename:"(unknown)");
23315 if (!file) return load_other(filename);
23316 else {
23317 if (!file) cimg::fclose(nfile);
23318 throw CImgIOException("CImg<%s>::load_jpeg() : Cannot read JPEG image '%s' using a *FILE input.",
23319 pixel_type(),filename?filename:"(FILE*)");
23320 }
23321 }
23322
23323 const unsigned int row_stride = cinfo.output_width * cinfo.output_components;
23324 unsigned char *buf = new unsigned char[cinfo.output_width*cinfo.output_height*cinfo.output_components], *buf2 = buf;
23325 JSAMPROW row_pointer[1];
23326 while (cinfo.output_scanline < cinfo.output_height) {
23327 row_pointer[0] = &buf[cinfo.output_scanline*row_stride];
23328 jpeg_read_scanlines(&cinfo,row_pointer,1);
23329 }
23330 jpeg_finish_decompress(&cinfo);
23331 jpeg_destroy_decompress(&cinfo);
23332 if (!file) cimg::fclose(nfile);
23333
23334 assign(cinfo.output_width,cinfo.output_height,1,cinfo.output_components);
23335 switch (dim) {
23336 case 1: {
23337 T *ptr_g = data;
23338 cimg_forXY(*this,x,y) *(ptr_g++) = (T)*(buf2++);
23339 } break;
23340 case 3: {
23341 T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1), *ptr_b = ptr(0,0,0,2);
23342 cimg_forXY(*this,x,y) {
23343 *(ptr_r++) = (T)*(buf2++);
23344 *(ptr_g++) = (T)*(buf2++);
23345 *(ptr_b++) = (T)*(buf2++);
23346 }
23347 } break;
23348 case 4: {
23349 T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1),
23350 *ptr_b = ptr(0,0,0,2), *ptr_a = ptr(0,0,0,3);
23351 cimg_forXY(*this,x,y) {
23352 *(ptr_r++) = (T)*(buf2++);
23353 *(ptr_g++) = (T)*(buf2++);
23354 *(ptr_b++) = (T)*(buf2++);
23355 *(ptr_a++) = (T)*(buf2++);
23356 }
23357 } break;
23358 }
23359 delete[] buf;
23360 return *this;
23361 #endif
23362 }
23363
23365 static CImg<T> get_load_jpeg(const char *const filename) {
23366 return CImg<T>().load_jpeg(0,filename);
23367 }
23368
23369 CImg<T>& load_jpeg(const char *const filename) {
23370 return load_jpeg(0,filename);
23371 }
23372
23374
23378 static CImg<T> get_load_magick(const char *const filename) {
23379 return CImg<T>().load_magick(filename);
23380 }
23381
23382 CImg<T>& load_magick(const char *const filename) {
23383 #ifdef cimg_use_magick
23384 Magick::Image image(filename);
23385 const unsigned int W = image.size().width(), H = image.size().height();
23386 switch (image.type()) {
23387 case Magick::PaletteMatteType:
23388 case Magick::TrueColorMatteType:
23389 case Magick::ColorSeparationType: {
23390 assign(W,H,1,4);
23391 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);
23392 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
23393 for (unsigned int off = W*H; off; --off) {
23394 *(rdata++) = (T)(pixels->red);
23395 *(gdata++) = (T)(pixels->green);
23396 *(bdata++) = (T)(pixels->blue);
23397 *(adata++) = (T)(pixels->opacity);
23398 ++pixels;
23399 }
23400 } break;
23401 case Magick::PaletteType:
23402 case Magick::TrueColorType: {
23403 assign(W,H,1,3);
23404 T *rdata = ptr(0,0,0,0), *gdata = ptr(0,0,0,1), *bdata = ptr(0,0,0,2);
23405 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
23406 for (unsigned int off = W*H; off; --off) {
23407 *(rdata++) = (T)(pixels->red);
23408 *(gdata++) = (T)(pixels->green);
23409 *(bdata++) = (T)(pixels->blue);
23410 ++pixels;
23411 }
23412 } break;
23413 case Magick::GrayscaleMatteType: {
23414 assign(W,H,1,2);
23415 T *data = ptr(0,0,0,0), *adata = ptr(0,0,0,1);
23416 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
23417 for (unsigned int off = W*H; off; --off) {
23418 *(data++) = (T)(pixels->red);
23419 *(adata++) = (T)(pixels->opacity);
23420 ++pixels;
23421 }
23422 } break;
23423 default: {
23424 assign(W,H,1,1);
23425 T *data = ptr(0,0,0,0);
23426 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
23427 for (unsigned int off = W*H; off; --off) {
23428 *(data++) = (T)(pixels->red);
23429 ++pixels;
23430 }
23431 } break;
23432 }
23433 #else
23434 throw CImgIOException("CImg<%s>::load_magick() : File '%s', Magick++ has not been linked during compilation.",
23435 pixel_type(),filename?filename:"(null)");
23436 #endif
23437 return *this;
23438 }
23439
23441 static CImg<T> get_load_raw(std::FILE *const file, const char *const filename,
23442 const unsigned int sizex, const unsigned int sizey=1,
23443 const unsigned int sizez=1, const unsigned int sizev=1,
23444 const bool multiplexed=false, const bool endian_swap=false) {
23445 return CImg<T>().load_raw(file,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap);
23446 }
23447
23448 CImg<T>& load_raw(std::FILE *const file, const char *const filename,
23449 const unsigned int sizex, const unsigned int sizey=1,
23450 const unsigned int sizez=1, const unsigned int sizev=1,
23451 const bool multiplexed = false, const bool endian_swap = false) {
23452 assign(sizex,sizey,sizez,sizev,0);
23453 const unsigned int siz = size();
23454 if (siz) {
23455 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23456 if (!multiplexed) {
23457 cimg::fread(data,siz,nfile);
23458 if (endian_swap) cimg::endian_swap(data,siz);
23459 }
23460 else {
23461 CImg<T> buf(1,1,1,sizev);
23462 cimg_forXYZ(*this,x,y,z) {
23463 cimg::fread(buf.data,sizev,nfile);
23464 if (endian_swap) cimg::endian_swap(buf.data,sizev);
23465 set_vector_at(buf,x,y,z); }
23466 }
23467 if (!file) cimg::fclose(nfile);
23468 }
23469 return *this;
23470 }
23471
23473 static CImg<T> get_load_raw(const char *const filename,
23474 const unsigned int sizex, const unsigned int sizey=1,
23475 const unsigned int sizez=1, const unsigned int sizev=1,
23476 const bool multiplexed = false, const bool endian_swap = false) {
23477 return CImg<T>().load_raw(0,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap);
23478 }
23479
23480 CImg<T>& load_raw(const char *const filename,
23481 const unsigned int sizex, const unsigned int sizey=1,
23482 const unsigned int sizez=1, const unsigned int sizev=1,
23483 const bool multiplexed = false, const bool endian_swap = false) {
23484 return load_raw(0,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap);
23485 }
23486
23488 static CImg<T> get_load_rgba(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23489 return CImg<T>().load_rgba(file,filename,dimw,dimh);
23490 }
23491
23492 CImg<T>& load_rgba(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23493 const int cimg_iobuffer = 12*1024*1024;
23494 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23495 CImg<unsigned char> raw;
23496 assign(dimw,dimh,1,4);
23497 T
23498 *ptr_r = ptr(0,0,0,0),
23499 *ptr_g = ptr(0,0,0,1),
23500 *ptr_b = ptr(0,0,0,2),
23501 *ptr_a = ptr(0,0,0,3);
23502 for (int toread = (int)size(); toread>0; ) {
23503 raw.assign(cimg::min(toread,cimg_iobuffer));
23504 cimg::fread(raw.data,raw.width,nfile);
23505 toread-=raw.width;
23506 const unsigned char *ptrs = raw.data;
23507 for (unsigned int off = raw.width/4; off; --off) {
23508 *(ptr_r++) = (T)*(ptrs++);
23509 *(ptr_g++) = (T)*(ptrs++);
23510 *(ptr_b++) = (T)*(ptrs++);
23511 *(ptr_a++) = (T)*(ptrs++);
23512 }
23513 }
23514 if (!file) cimg::fclose(nfile);
23515 return *this;
23516 }
23517
23519 static CImg<T> get_load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23520 return CImg<T>().load_rgba(0,filename,dimw,dimh);
23521 }
23522
23523 CImg<T>& load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23524 return load_rgba(0,filename,dimw,dimh);
23525 }
23526
23528 static CImg<T> get_load_rgb(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23529 return CImg<T>().load_rgb(file,filename,dimw,dimh);
23530 }
23531
23532 CImg<T>& load_rgb(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23533 const int cimg_iobuffer = 12*1024*1024;
23534 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23535 CImg<unsigned char> raw;
23536 assign(dimw,dimh,1,3);
23537 T
23538 *ptr_r = ptr(0,0,0,0),
23539 *ptr_g = ptr(0,0,0,1),
23540 *ptr_b = ptr(0,0,0,2);
23541 for (int toread = (int)size(); toread>0; ) {
23542 raw.assign(cimg::min(toread,cimg_iobuffer));
23543 cimg::fread(raw.data,raw.width,nfile);
23544 toread-=raw.width;
23545 const unsigned char *ptrs = raw.data;
23546 for (unsigned int off = raw.width/3; off; --off) {
23547 *(ptr_r++) = (T)*(ptrs++);
23548 *(ptr_g++) = (T)*(ptrs++);
23549 *(ptr_b++) = (T)*(ptrs++);
23550 }
23551 }
23552 if (!file) cimg::fclose(nfile);
23553 return *this;
23554 }
23555
23557 static CImg<T> get_load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23558 return CImg<T>().load_rgb(0,filename,dimw,dimh);
23559 }
23560
23561 CImg<T>& load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
23562 return load_rgb(0,filename,dimw,dimh);
23563 }
23564
23566 static CImg<T> get_load_inr(std::FILE *const file, const char *const filename=0, float *voxsize=0) {
23567 return CImg<T>().load_inr(file,filename,voxsize);
23568 }
23569
23570 CImg<T>& load_inr(std::FILE *const file, const char *const filename=0, float *const voxsize=0) {
23571
23572 #define cimg_load_inr_case(Tf,sign,pixsize,Ts) \
23573 if (!loaded && fopt[6]==pixsize && fopt[4]==Tf && fopt[5]==sign) { \
23574 Ts *xval, *val = new Ts[fopt[0]*fopt[3]]; \
23575 cimg_forYZ(*this,y,z) { \
23576 cimg::fread(val,fopt[0]*fopt[3],nfile); \
23577 if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); \
23578 xval = val; cimg_forX(*this,x) cimg_forV(*this,k) (*this)(x,y,z,k) = (T)*(xval++); \
23579 } \
23580 delete[] val; \
23581 loaded = true; \
23582 }
23583
23584 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23585 int fopt[8], endian=cimg::endian()?1:0;
23586 bool loaded = false;
23587 if (voxsize) voxsize[0]=voxsize[1]=voxsize[2]=1;
23588 _load_inr(nfile,fopt,voxsize);
23589 assign(fopt[0],fopt[1],fopt[2],fopt[3]);
23590 cimg_load_inr_case(0,0,8, unsigned char);
23591 cimg_load_inr_case(0,1,8, char);
23592 cimg_load_inr_case(0,0,16,unsigned short);
23593 cimg_load_inr_case(0,1,16,short);
23594 cimg_load_inr_case(0,0,32,unsigned int);
23595 cimg_load_inr_case(0,1,32,int);
23596 cimg_load_inr_case(1,0,32,float);
23597 cimg_load_inr_case(1,1,32,float);
23598 cimg_load_inr_case(1,0,64,double);
23599 cimg_load_inr_case(1,1,64,double);
23600 if (!loaded) {
23601 if (!file) cimg::fclose(nfile);
23602 throw CImgIOException("CImg<%s>::load_inr() : File '%s', cannot read images of the type specified in the file",
23603 pixel_type(),filename?filename:"(FILE*)");
23604 }
23605 if (!file) cimg::fclose(nfile);
23606 return *this;
23607 }
23608
23609 static void _load_inr(std::FILE *file, int out[8], float *const voxsize=0) {
23610 char item[1024], tmp1[64], tmp2[64];
23611 out[0] = out[1] = out[2] = out[3] = out[5] = 1; out[4] = out[6] = out[7] = -1;
23612 std::fscanf(file,"%63s",item);
23613 if(cimg::strncasecmp(item,"#INRIMAGE-4#{",13)!=0)
23614 throw CImgIOException("CImg<%s>::load_inr() : File does not appear to be a valid INR file.\n"
23615 "(INRIMAGE-4 identifier not found)",pixel_type());
23616 while (std::fscanf(file," %63[^\n]%*c",item)!=EOF && cimg::strncmp(item,"##}",3)) {
23617 std::sscanf(item," XDIM%*[^0-9]%d",out);
23618 std::sscanf(item," YDIM%*[^0-9]%d",out+1);
23619 std::sscanf(item," ZDIM%*[^0-9]%d",out+2);
23620 std::sscanf(item," VDIM%*[^0-9]%d",out+3);
23621 std::sscanf(item," PIXSIZE%*[^0-9]%d",out+6);
23622 if (voxsize) {
23623 std::sscanf(item," VX%*[^0-9.eE+-]%f",voxsize);
23624 std::sscanf(item," VY%*[^0-9.eE+-]%f",voxsize+1);
23625 std::sscanf(item," VZ%*[^0-9.eE+-]%f",voxsize+2);
23626 }
23627 if (std::sscanf(item," CPU%*[ =]%s",tmp1)) out[7]=cimg::strncasecmp(tmp1,"sun",3)?0:1;
23628 switch(std::sscanf(item," TYPE%*[ =]%s %s",tmp1,tmp2)) {
23629 case 0: break;
23630 case 2: out[5] = cimg::strncasecmp(tmp1,"unsigned",8)?1:0; std::strcpy(tmp1,tmp2);
23631 case 1:
23632 if (!cimg::strncasecmp(tmp1,"int",3) || !cimg::strncasecmp(tmp1,"fixed",5)) out[4] = 0;
23633 if (!cimg::strncasecmp(tmp1,"float",5) || !cimg::strncasecmp(tmp1,"double",6)) out[4] = 1;
23634 if (!cimg::strncasecmp(tmp1,"packed",6)) out[4] = 2;
23635 if (out[4]>=0) break;
23636 default: throw CImgIOException("cimg::inr_header_read() : Invalid TYPE '%s'",tmp2);
23637 }
23638 }
23639 if(out[0]<0 || out[1]<0 || out[2]<0 || out[3]<0)
23640 throw CImgIOException("CImg<%s>::load_inr() : Bad dimensions in .inr file = ( %d , %d , %d , %d )",
23641 pixel_type(),out[0],out[1],out[2],out[3]);
23642 if(out[4]<0 || out[5]<0) throw CImgIOException("CImg<%s>::load_inr() : TYPE is not fully defined",pixel_type());
23643 if(out[6]<0) throw CImgIOException("CImg<%s>::load_inr() : PIXSIZE is not fully defined",pixel_type());
23644 if(out[7]<0) throw CImgIOException("CImg<%s>::load_inr() : Big/Little Endian coding type is not defined",pixel_type());
23645 }
23646
23648 static CImg<T> get_load_inr(const char *const filename, float *const voxsize=0) {
23649 return CImg<T>().load_inr(0,filename,voxsize);
23650 }
23651
23652 CImg<T>& load_inr(const char *const filename, float *const voxsize=0) {
23653 return load_inr(0,filename,voxsize);
23654 }
23655
23657 static CImg<T> get_load_pandore(std::FILE *const file, const char *const filename=0) {
23658 return CImg<T>().load_pandore(file,filename);
23659 }
23660
23661 CImg<T>& load_pandore(std::FILE *const file, const char *const filename) {
23662
23663 #define cimg_load_pandore_case(nid,nbdim,nwidth,nheight,ndepth,ndim,stype) \
23664 case nid: { \
23665 cimg::fread(dims,nbdim,nfile); \
23666 if (endian) cimg::endian_swap(dims,nbdim); \
23667 assign(nwidth,nheight,ndepth,ndim); \
23668 const unsigned int siz = size(); \
23669 stype *buffer = new stype[siz]; \
23670 cimg::fread(buffer,siz,nfile); \
23671 if (endian) cimg::endian_swap(buffer,siz); \
23672 T *ptrd = data; \
23673 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); \
23674 buffer-=siz; \
23675 delete[] buffer; \
23676 } \
23677 break;
23678
23679 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
23680 typedef unsigned char uchar;
23681 typedef unsigned short ushort;
23682 typedef unsigned int uint;
23683 typedef unsigned long ulong;
23684 char tmp[32];
23685 cimg::fread(tmp,12,nfile);
23686 if (cimg::strncasecmp("PANDORE",tmp,7)) {
23687 if (!file) cimg::fclose(nfile);
23688 throw CImgIOException("CImg<%s>::load_pandore() : File '%s' is not a valid PANDORE file.\n"
23689 "(PANDORE identifier not found).",pixel_type(),filename?filename:"(FILE*)");
23690 }
23691 unsigned int imageid,dims[8];
23692 int ptbuf[4];
23693 cimg::fread(&imageid,1,nfile);
23694 const bool endian = (imageid>255);
23695 if (endian) cimg::endian_swap(imageid);
23696
23697 cimg::fread(tmp,20,nfile);
23698 switch (imageid) {
23699 cimg_load_pandore_case(2,2,dims[1],1,1,1,uchar);
23700 cimg_load_pandore_case(3,2,dims[1],1,1,1,long);
23701 cimg_load_pandore_case(4,2,dims[1],1,1,1,float);
23702 cimg_load_pandore_case(5,3,dims[2],dims[1],1,1,uchar);
23703 cimg_load_pandore_case(6,3,dims[2],dims[1],1,1,long);
23704 cimg_load_pandore_case(7,3,dims[2],dims[1],1,1,float);
23705 cimg_load_pandore_case(8,4,dims[3],dims[2],dims[1],1,uchar);
23706 cimg_load_pandore_case(9,4,dims[3],dims[2],dims[1],1,long);
23707 cimg_load_pandore_case(10,4,dims[3],dims[2],dims[1],1,float);
23708
23709 case 11: {
23710 cimg::fread(dims,3,nfile);
23711 if (endian) cimg::endian_swap(dims,3);
23712 assign(dims[1],1,1,1);
23713 const unsigned siz = size();
23714 if (dims[2]<256) {
23715 unsigned char *buffer = new unsigned char[siz];
23716 cimg::fread(buffer,siz,nfile);
23717 T *ptrd = data;
23718 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23719 buffer-=siz;
23720 delete[] buffer;
23721 } else {
23722 if (dims[2]<65536) {
23723 unsigned short *buffer = new unsigned short[siz];
23724 cimg::fread(buffer,siz,nfile);
23725 if (endian) cimg::endian_swap(buffer,siz);
23726 T *ptrd = data;
23727 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23728 buffer-=siz;
23729 delete[] buffer;
23730 } else {
23731 unsigned int *buffer = new unsigned int[siz];
23732 cimg::fread(buffer,siz,nfile);
23733 if (endian) cimg::endian_swap(buffer,siz);
23734 T *ptrd = data;
23735 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23736 buffer-=siz;
23737 delete[] buffer;
23738 }
23739 }
23740 }
23741 break;
23742 case 12: {
23743 cimg::fread(dims,4,nfile);
23744 if (endian) cimg::endian_swap(dims,4);
23745 assign(dims[2],dims[1],1,1);
23746 const unsigned int siz = size();
23747 if (dims[3]<256) {
23748 unsigned char *buffer = new unsigned char[siz];
23749 cimg::fread(buffer,siz,nfile);
23750 T *ptrd = data;
23751 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23752 buffer-=siz;
23753 delete[] buffer;
23754 } else {
23755 if (dims[3]<65536) {
23756 unsigned short *buffer = new unsigned short[siz];
23757 cimg::fread(buffer,siz,nfile);
23758 if (endian) cimg::endian_swap(buffer,siz);
23759 T *ptrd = data;
23760 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23761 buffer-=siz;
23762 delete[] buffer;
23763 } else {
23764 unsigned long *buffer = new unsigned long[siz];
23765 cimg::fread(buffer,siz,nfile);
23766 if (endian) cimg::endian_swap(buffer,siz);
23767 T *ptrd = data;
23768 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23769 buffer-=siz;
23770 delete[] buffer;
23771 }
23772 }
23773 }
23774 break;
23775 case 13: {
23776 cimg::fread(dims,5,nfile);
23777 if (endian) cimg::endian_swap(dims,5);
23778 assign(dims[3],dims[2],dims[1],1);
23779 const unsigned int siz = size();
23780 if (dims[4]<256) {
23781 unsigned char *buffer = new unsigned char[siz];
23782 cimg::fread(buffer,siz,nfile);
23783 T *ptrd = data;
23784 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23785 buffer-=siz;
23786 delete[] buffer;
23787 } else {
23788 if (dims[4]<65536) {
23789 unsigned short *buffer = new unsigned short[siz];
23790 cimg::fread(buffer,siz,nfile);
23791 if (endian) cimg::endian_swap(buffer,siz);
23792 T *ptrd = data;
23793 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23794 buffer-=siz;
23795 delete[] buffer;
23796 } else {
23797 unsigned int *buffer = new unsigned int[siz];
23798 cimg::fread(buffer,siz,nfile);
23799 if (endian) cimg::endian_swap(buffer,siz);
23800 T *ptrd = data;
23801 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++);
23802 buffer-=siz;
23803 delete[] buffer;
23804 }
23805 }
23806 }
23807 break;
23808 cimg_load_pandore_case(16,4,dims[2],dims[1],1,3,uchar);
23809 cimg_load_pandore_case(17,4,dims[2],dims[1],1,3,long);
23810 cimg_load_pandore_case(18,4,dims[2],dims[1],1,3,float);
23811 cimg_load_pandore_case(19,5,dims[3],dims[2],dims[1],3,uchar);
23812 cimg_load_pandore_case(20,5,dims[3],dims[2],dims[1],3,long);
23813 cimg_load_pandore_case(21,5,dims[3],dims[2],dims[1],3,float);
23814 cimg_load_pandore_case(22,2,dims[1],1,1,dims[0],uchar);
23815 cimg_load_pandore_case(23,2,dims[1],1,1,dims[0],long);
23816 cimg_load_pandore_case(24,2,dims[1],1,1,dims[0],ulong);
23817 cimg_load_pandore_case(25,2,dims[1],1,1,dims[0],float);
23818 cimg_load_pandore_case(26,3,dims[2],dims[1],1,dims[0],uchar);
23819 cimg_load_pandore_case(27,3,dims[2],dims[1],1,dims[0],long);
23820 cimg_load_pandore_case(28,3,dims[2],dims[1],1,dims[0],ulong);
23821 cimg_load_pandore_case(29,3,dims[2],dims[1],1,dims[0],float);
23822 cimg_load_pandore_case(30,4,dims[3],dims[2],dims[1],dims[0],uchar);
23823 cimg_load_pandore_case(31,4,dims[3],dims[2],dims[1],dims[0],long);
23824 cimg_load_pandore_case(32,4,dims[3],dims[2],dims[1],dims[0],ulong);
23825 cimg_load_pandore_case(33,4,dims[3],dims[2],dims[1],dims[0],float);
23826 case 34:
23827 cimg::fread(ptbuf,1,nfile);
23828 if (endian) cimg::endian_swap(ptbuf,1);
23829 assign(1); (*this)(0) = (T)ptbuf[0];
23830 break;
23831 case 35:
23832 cimg::fread(ptbuf,2,nfile);
23833 if (endian) cimg::endian_swap(ptbuf,2);
23834 assign(2); (*this)(0) = (T)ptbuf[1]; (*this)(1) = (T)ptbuf[0];
23835 break;
23836 case 36:
23837 cimg::fread(ptbuf,3,nfile);
23838 if (endian) cimg::endian_swap(ptbuf,3);
23839 assign(3); (*this)(0) = (T)ptbuf[2]; (*this)(1) = (T)ptbuf[1]; (*this)(2) = (T)ptbuf[0];
23840 break;
23841 default:
23842 if (!file) cimg::fclose(nfile);
23843 throw CImgIOException("CImg<%s>::load_pandore() : File '%s', cannot read images with ID_type=%u",
23844 pixel_type(),filename?filename:"(FILE*)",imageid);
23845 }
23846 if (!file) cimg::fclose(nfile);
23847 return *this;
23848 }
23849
23851 static CImg<T> get_load_pandore(const char *const filename) {
23852 return CImg<T>().load_pandore(0,filename);
23853 }
23854
23855 CImg<T>& load_pandore(const char *const filename) {
23856 return load_pandore(0,filename);
23857 }
23858
23860 static CImg<T> get_load_analyze(const char *const filename, float *const voxsize=0) {
23861 return CImg<T>().load_analyze(filename,voxsize);
23862 }
23863
23864 CImg<T>& load_analyze(const char *const filename, float *const voxsize=0) {
23865 std::FILE *file_header = 0, *file = 0;
23866 bool error_file = false;
23867 char body[1024];
23868 const char *ext = cimg::filename_split(filename,body);
23869 if (!cimg::strncasecmp(ext,"nii",3)) file_header = cimg::fopen(filename,"rb");
23870 else {
23871 if (!cimg::strncasecmp(ext,"hdr",3) ||
23872 !cimg::strncasecmp(ext,"img",3)) {
23873 std::sprintf(body+cimg::strlen(body),".hdr");
23874 file_header = cimg::fopen(body,"rb");
23875 if (!file_header) error_file = true;
23876 else {
23877 std::sprintf(body+cimg::strlen(body)-3,"img");
23878 file = cimg::fopen(body,"rb");
23879 if (!file) { cimg::fclose(file_header); error_file = true; }
23880 }
23881 }
23882 }
23883 if (error_file) throw CImgIOException("CImg<%s>::load_analyze() : Filename '%s', not recognized as an Analyze 7.5 or NIFTI file.",
23884 pixel_type(),filename);
23885
23886
23887 bool endian = false;
23888 unsigned int header_size;
23889 cimg::fread(&header_size,1,file_header);
23890 if (header_size>=4096) { endian = true; cimg::endian_swap(header_size); }
23891 unsigned char *header = new unsigned char[header_size];
23892 cimg::fread(header+4,header_size-4,file_header);
23893 if (file) cimg::fclose(file_header);
23894 if (endian) {
23895 cimg::endian_swap((short*)(header+40),5);
23896 cimg::endian_swap((short*)(header+70),1);
23897 cimg::endian_swap((short*)(header+72),1);
23898 cimg::endian_swap((float*)(header+76),4);
23899 cimg::endian_swap((float*)(header+112),1);
23900 }
23901 unsigned short *dim = (unsigned short*)(header+40), dimx=1, dimy=1, dimz=1, dimv=1;
23902 if (!dim[0]) cimg::warn("CImg<%s>::load_analyze() : Specified image has zero dimensions.",pixel_type());
23903 if (dim[0]>4) cimg::warn("CImg<%s>::load_analyze() : Number of image dimension is %d, reading only the 4 first dimensions",
23904 pixel_type(),dim[0]);
23905 if (dim[0]>=1) dimx = dim[1];
23906 if (dim[0]>=2) dimy = dim[2];
23907 if (dim[0]>=3) dimz = dim[3];
23908 if (dim[0]>=4) dimv = dim[4];
23909
23910 float scalefactor = *(float*)(header+112); if (scalefactor==0) scalefactor=1;
23911 const unsigned short datatype = *(short*)(header+70);
23912 if (voxsize) { const float *vsize = (float*)(header+76); voxsize[0] = vsize[1]; voxsize[1] = vsize[2]; voxsize[2] = vsize[3]; }
23913 delete[] header;
23914
23915
23916 std::FILE *nfile = file?file:file_header;
23917 assign(dimx,dimy,dimz,dimv);
23918 switch (datatype) {
23919 case 2: {
23920 unsigned char *buffer = new unsigned char[dimx*dimy*dimz*dimv];
23921 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23922 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23923 delete[] buffer;
23924 } break;
23925 case 4: {
23926 short *buffer = new short[dimx*dimy*dimz*dimv];
23927 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23928 if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
23929 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23930 delete[] buffer;
23931 } break;
23932 case 8: {
23933 int *buffer = new int[dimx*dimy*dimz*dimv];
23934 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23935 if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
23936 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23937 delete[] buffer;
23938 } break;
23939 case 16: {
23940 float *buffer = new float[dimx*dimy*dimz*dimv];
23941 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23942 if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
23943 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23944 delete[] buffer;
23945 } break;
23946 case 64: {
23947 double *buffer = new double[dimx*dimy*dimz*dimv];
23948 cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile);
23949 if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
23950 cimg_foroff(*this,off) data[off] = (T)(buffer[off]*scalefactor);
23951 delete[] buffer;
23952 } break;
23953 default:
23954 cimg::fclose(nfile);
23955 throw CImgIOException("CImg<%s>::load_analyze() : File '%s, cannot read images with 'datatype = %d'",
23956 pixel_type(),filename,datatype);
23957 }
23958 cimg::fclose(nfile);
23959 return *this;
23960 }
23961
23963 template<typename tf, typename tc>
23964 static CImg<T> get_load_off(const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors,
23965 const bool invert_faces=false) {
23966 return CImg<T>().load_off(filename,primitives,colors,invert_faces);
23967 }
23968
23969 template<typename tf, typename tc>
23970 CImg<T>& load_off(const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors, const bool invert_faces=false) {
23971 std::FILE *file=cimg::fopen(filename,"r");
23972 unsigned int nb_points = 0, nb_primitives = 0, nb_read = 0;
23973 char line[256] = { 0 };
23974 int err;
23975
23976
23977 do { err = std::fscanf(file,"%255[^\n] ",line); } while (!err || (err==1 && line[0]=='#'));
23978 if (cimg::strncasecmp(line,"OFF",3) && cimg::strncasecmp(line,"COFF",4)) {
23979 cimg::fclose(file);
23980 throw CImgIOException("CImg<%s>::load_off() : File '%s', keyword 'OFF' not found.",pixel_type(),filename);
23981 }
23982 do { err = std::fscanf(file,"%255[^\n] ",line); } while (!err || (err==1 && line[0]=='#'));
23983
23984 if ((err = std::sscanf(line,"%u%u%*[^\n] ",&nb_points,&nb_primitives))!=2) {
23985 cimg::fclose(file);
23986 throw CImgIOException("CImg<%s>::load_off() : File '%s', invalid vertices/primitives numbers.",pixel_type(),filename);
23987 }
23988
23989
23990 assign(nb_points,3);
23991 float X = 0, Y = 0, Z = 0;
23992 cimg_forX(*this,l) {
23993 do { err = std::fscanf(file,"%255[^\n] ",line); } while (!err || (err==1 && line[0]=='#'));
23994 if ((err = std::sscanf(line,"%f%f%f%*[^\n] ",&X,&Y,&Z))!=3) {
23995 cimg::fclose(file);
23996 throw CImgIOException("CImg<%s>::load_off() : File '%s', cannot read point %u/%u.\n",pixel_type(),filename,l+1,nb_points);
23997 }
23998 (*this)(l,0) = (T)X; (*this)(l,1) = (T)Y; (*this)(l,2) = (T)Z;
23999 }
24000
24001
24002 primitives.assign();
24003 colors.assign();
24004 bool stopflag = false;
24005 while (!stopflag) {
24006 float c0 = 0.7f, c1 = 0.7f, c2 = 0.7f;
24007 unsigned int prim = 0, i0 = 0, i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
24008 line[0]='\0';
24009 if ((err = std::fscanf(file,"%u",&prim))!=1) stopflag=true;
24010 else {
24011 ++nb_read;
24012 switch (prim) {
24013 case 1: {
24014 if ((err = std::fscanf(file,"%u%255[^\n] ",&i0,line))<2) {
24015 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
24016 pixel_type(),filename,nb_read,nb_primitives);
24017 std::fscanf(file,"%*[^\n] ");
24018 } else {
24019 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24020 primitives.insert(CImg<tf>::vector(i0));
24021 colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
24022 }
24023 } break;
24024 case 2: {
24025 if ((err = std::fscanf(file,"%u%u%255[^\n] ",&i0,&i1,line))<2) {
24026 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
24027 pixel_type(),filename,nb_read,nb_primitives);
24028 std::fscanf(file,"%*[^\n] ");
24029 } else {
24030 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24031 primitives.insert(CImg<tf>::vector(i0,i1));
24032 colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
24033 }
24034 } break;
24035 case 3: {
24036 if ((err = std::fscanf(file,"%u%u%u%255[^\n] ",&i0,&i1,&i2,line))<3) {
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) primitives.insert(CImg<tf>::vector(i0,i1,i2));
24043 else primitives.insert(CImg<tf>::vector(i0,i2,i1));
24044 colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
24045 }
24046 } break;
24047 case 4: {
24048 if ((err = std::fscanf(file,"%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,line))<4) {
24049 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
24050 pixel_type(),filename,nb_read,nb_primitives);
24051 std::fscanf(file,"%*[^\n] ");
24052 } else {
24053 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24054 if (invert_faces) primitives.insert(CImg<tf>::vector(i0,i1,i2,i3));
24055 else primitives.insert(CImg<tf>::vector(i0,i3,i2,i1));
24056 colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
24057 }
24058 } break;
24059 case 5: {
24060 if ((err = std::fscanf(file,"%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,line))<5) {
24061 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
24062 pixel_type(),filename,nb_read,nb_primitives);
24063 std::fscanf(file,"%*[^\n] ");
24064 } else {
24065 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24066 if (invert_faces) {
24067 primitives.insert(CImg<tf>::vector(i0,i1,i2,i3));
24068 primitives.insert(CImg<tf>::vector(i0,i3,i4));
24069 }
24070 else {
24071 primitives.insert(CImg<tf>::vector(i0,i3,i2,i1));
24072 primitives.insert(CImg<tf>::vector(i0,i4,i3));
24073 }
24074 colors.insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
24075 ++nb_primitives;
24076 }
24077 } break;
24078 case 6: {
24079 if ((err = std::fscanf(file,"%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,line))<6) {
24080 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
24081 pixel_type(),filename,nb_read,nb_primitives);
24082 std::fscanf(file,"%*[^\n] ");
24083 } else {
24084 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24085 if (invert_faces) {
24086 primitives.insert(CImg<tf>::vector(i0,i1,i2,i3));
24087 primitives.insert(CImg<tf>::vector(i0,i3,i4,i5));
24088 }
24089 else {
24090 primitives.insert(CImg<tf>::vector(i0,i3,i2,i1));
24091 primitives.insert(CImg<tf>::vector(i0,i5,i4,i3));
24092 }
24093 colors.insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
24094 ++nb_primitives;
24095 }
24096 } break;
24097 case 7: {
24098 if ((err = std::fscanf(file,"%u%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,&i6,line))<7) {
24099 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
24100 pixel_type(),filename,nb_read,nb_primitives);
24101 std::fscanf(file,"%*[^\n] ");
24102 } else {
24103 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24104 if (invert_faces) {
24105 primitives.insert(CImg<tf>::vector(i0,i1,i3,i4));
24106 primitives.insert(CImg<tf>::vector(i0,i4,i5,i6));
24107 primitives.insert(CImg<tf>::vector(i1,i2,i3));
24108 }
24109 else {
24110 primitives.insert(CImg<tf>::vector(i0,i4,i3,i1));
24111 primitives.insert(CImg<tf>::vector(i0,i6,i5,i4));
24112 primitives.insert(CImg<tf>::vector(i3,i2,i1));
24113 }
24114 colors.insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
24115 ++(++nb_primitives);
24116 }
24117 } break;
24118 case 8: {
24119 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) {
24120 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.",
24121 pixel_type(),filename,nb_read,nb_primitives);
24122 std::fscanf(file,"%*[^\n] ");
24123 } else {
24124 std::sscanf(line,"%f%f%f",&c0,&c1,&c2);
24125 if (invert_faces) {
24126 primitives.insert(CImg<tf>::vector(i0,i1,i2,i3));
24127 primitives.insert(CImg<tf>::vector(i0,i3,i4,i5));
24128 primitives.insert(CImg<tf>::vector(i0,i5,i6,i7));
24129 }
24130 else {
24131 primitives.insert(CImg<tf>::vector(i0,i3,i2,i1));
24132 primitives.insert(CImg<tf>::vector(i0,i5,i4,i3));
24133 primitives.insert(CImg<tf>::vector(i0,i7,i6,i5));
24134 }
24135 colors.insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
24136 ++(++nb_primitives);
24137 }
24138 } break;
24139 default:
24140 cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u (%u vertices).",
24141 pixel_type(),filename,nb_read,nb_primitives,prim);
24142 std::fscanf(file,"%*[^\n] ");
24143 break;
24144 }
24145 }
24146 }
24147 cimg::fclose(file);
24148 if (primitives.size!=nb_primitives)
24149 cimg::warn("CImg<%s>::load_off() : File '%s', read only %u primitives instead of %u as claimed in the header.",
24150 pixel_type(),filename,primitives.size,nb_primitives);
24151 return *this;
24152 }
24153
24155 static CImg<T> get_load_dicom(const char *const filename) {
24156 return CImg<T>().load_dicom(filename);
24157 }
24158
24159 CImg<T>& load_dicom(const char *const filename) {
24160 char command[1024], filetmp[512], body[512];
24161 cimg::fclose(cimg::fopen(filename,"r"));
24162 std::FILE *file;
24163 do {
24164 std::sprintf(filetmp,"%s.hdr",cimg::filenamerand());
24165 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24166 } while (file);
24167 std::sprintf(command,"%s -w -c anlz -o %s -f %s",cimg::medcon_path(),filetmp,filename);
24168 cimg::system(command);
24169 cimg::filename_split(filetmp,body);
24170 std::sprintf(command,"m000-%s.hdr",body);
24171 file = std::fopen(command,"rb");
24172 if (!file) {
24173 throw CImgIOException("CImg<%s>::load_dicom() : Failed to open image '%s'.\n\n"
24174 "Path of 'medcon' : \"%s\"\n"
24175 "Path of temporary filename : \"%s\"",
24176 pixel_type(),filename,cimg::medcon_path(),filetmp);
24177 } else cimg::fclose(file);
24178 load_analyze(command);
24179 std::remove(command);
24180 std::sprintf(command,"m000-%s.img",body);
24181 std::remove(command);
24182 return *this;
24183 }
24184
24186 static CImg<T> get_load_imagemagick(const char *const filename) {
24187 return CImg<T>().load_imagemagick(filename);
24188 }
24189
24190 CImg<T>& load_imagemagick(const char *const filename) {
24191 char command[1024], filetmp[512];
24192 std::FILE *file = 0;
24193 do {
24194 std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24195 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24196 } while (file);
24197 std::sprintf(command,"%s \"%s\" %s",cimg::imagemagick_path(),filename,filetmp);
24198 cimg::system(command,cimg::imagemagick_path());
24199 if (!(file = std::fopen(filetmp,"rb"))) {
24200 cimg::fclose(cimg::fopen(filename,"r"));
24201 throw CImgIOException("CImg<%s>::load_imagemagick() : Failed to open image '%s'.\n\n"
24202 "Path of 'ImageMagick's convert' : \"%s\"\n"
24203 "Path of temporary filename : \"%s\"",
24204 pixel_type(),filename,cimg::imagemagick_path(),filetmp);
24205 } else cimg::fclose(file);
24206 load_pnm(filetmp);
24207 std::remove(filetmp);
24208 return *this;
24209 }
24210
24212 static CImg<T> get_load_graphicsmagick(const char *const filename) {
24213 return CImg<T>().load_graphicsmagick(filename);
24214 }
24215
24216 CImg<T>& load_graphicsmagick(const char *const filename) {
24217 char command[1024], filetmp[512];
24218 std::FILE *file = 0;
24219 do {
24220 std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24221 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24222 } while (file);
24223 std::sprintf(command,"%s convert \"%s\" %s",cimg::graphicsmagick_path(),filename,filetmp);
24224 cimg::system(command,cimg::graphicsmagick_path());
24225 if (!(file = std::fopen(filetmp,"rb"))) {
24226 cimg::fclose(cimg::fopen(filename,"r"));
24227 throw CImgIOException("CImg<%s>::load_graphicsmagick() : Failed to open image '%s'.\n\n"
24228 "Path of 'GraphicsMagick's gm' : \"%s\"\n"
24229 "Path of temporary filename : \"%s\"",
24230 pixel_type(),filename,cimg::graphicsmagick_path(),filetmp);
24231 } else cimg::fclose(file);
24232 load_pnm(filetmp);
24233 std::remove(filetmp);
24234 return *this;
24235 }
24236
24238 static CImg<T> get_load_other(const char *const filename) {
24239 return CImg<T>().load_other(filename);
24240 }
24241
24242 CImg<T>& load_other(const char *const filename) {
24243 const unsigned int odebug = cimg::exception_mode();
24244 cimg::exception_mode() = 0;
24245 try { load_magick(filename); }
24246 catch (CImgException&) {
24247 try { load_imagemagick(filename); }
24248 catch (CImgException&) {
24249 try { load_graphicsmagick(filename); }
24250 catch (CImgException&) {
24251 assign();
24252 }
24253 }
24254 }
24255 cimg::exception_mode() = odebug;
24256 if (is_empty())
24257 throw CImgIOException("CImg<%s>::load_other() : Failed to open image '%s'.\n"
24258 "Check you have either the ImageMagick or GraphicsMagick package installed.",
24259 pixel_type(),filename);
24260 return *this;
24261 }
24262
24264 static CImg<T> get_load_parrec(const char *const filename, const char axis='v', const char align='p') {
24265 return CImg<T>().load_parrec(filename,axis,align);
24266 }
24267
24268 CImg<T>& load_parrec(const char *const filename, const char axis='v', const char align='p') {
24269 CImgList<T> list;
24270 list.load_parrec(filename);
24271 if (list.size==1) return list[0].assign_to(*this);
24272 return assign(list.get_append(axis,align));
24273 }
24274
24276 static CImg<T> get_load_cimg(std::FILE *const file, const char axis='z', const char align='p') {
24277 return CImg<T>().load_cimg(file,axis,align);
24278 }
24279
24280 CImg<T>& load_cimg(std::FILE *const file, const char axis='z', const char align='p') {
24281 CImgList<T> list;
24282 list.load_cimg(file);
24283 if (list.size==1) return list[0].assign_to(*this);
24284 return assign(list.get_append(axis,align));
24285 }
24286
24288 static CImg<T> get_load_cimg(const char *const filename, const char axis='z', const char align='p') {
24289 return CImg<T>().load_cimg(filename,axis,align);
24290 }
24291
24292 CImg<T>& load_cimg(const char *const filename, const char axis='z', const char align='p') {
24293 CImgList<T> list;
24294 list.load_cimg(filename);
24295 if (list.size==1) return list[0].assign_to(*this);
24296 return assign(list.get_append(axis,align));
24297 }
24298
24300 static CImg<T> get_load_cimg(std::FILE *const file,
24301 const unsigned int n0, const unsigned int n1,
24302 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
24303 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1,
24304 const char axis='z', const char align='p') {
24305 return CImg<T>().load_cimg(file,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1,axis,align);
24306 }
24307
24308 CImg<T>& load_cimg(std::FILE *const file,
24309 const unsigned int n0, const unsigned int n1,
24310 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
24311 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1,
24312 const char axis='z', const char align='p') {
24313 CImgList<T> list;
24314 list.load_cimg(file,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
24315 if (list.size==1) return list[0].assign_to(*this);
24316 return assign(list.get_append(axis,align));
24317 }
24318
24320 static CImg<T> get_load_cimg(const char *const filename,
24321 const unsigned int n0, const unsigned int n1,
24322 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
24323 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1,
24324 const char axis='z', const char align='p') {
24325 return CImg<T>().load_cimg(filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1,axis,align);
24326 }
24327
24328 CImg<T>& load_cimg(const char *const filename,
24329 const unsigned int n0, const unsigned int n1,
24330 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
24331 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1,
24332 const char axis='z', const char align='p') {
24333 CImgList<T> list;
24334 list.load_cimg(filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
24335 if (list.size==1) return list[0].assign_to(*this);
24336 return assign(list.get_append(axis,align));
24337 }
24338
24340 static CImg<T> get_load_yuv(std::FILE *const file, const char *const filename,
24341 const unsigned int sizex, const unsigned int sizey=1,
24342 const unsigned int first_frame=0, const int last_frame=-1,
24343 const bool yuv2rgb = false, const char axis='z', const char align='p') {
24344 return CImgList<T>().load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb).get_append(axis,align);
24345 }
24346
24347 CImg<T>& load_yuv(std::FILE *const file, const char *const filename,
24348 const unsigned int sizex, const unsigned int sizey=1,
24349 const unsigned int first_frame=0, const int last_frame=-1,
24350 const bool yuv2rgb = false, const char axis='z', const char align='p') {
24351 return get_load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb,axis,align).assign_to(*this);
24352 }
24353
24355 static CImg<T> get_load_yuv(const char *const filename,
24356 const unsigned int sizex, const unsigned int sizey=1,
24357 const unsigned int first_frame=0, const int last_frame=-1,
24358 const bool yuv2rgb = false, const char axis='z', const char align='p') {
24359 return CImgList<T>().load_yuv(filename,sizex,sizey,first_frame,last_frame,yuv2rgb).get_append(axis,align);
24360 }
24361
24362 CImg<T>& load_yuv(const char *const filename,
24363 const unsigned int sizex, const unsigned int sizey=1,
24364 const unsigned int first_frame=0, const int last_frame=-1,
24365 const bool yuv2rgb = false, const char axis='z', const char align='p') {
24366 return get_load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb,axis,align).assign_to(*this);
24367 }
24368
24370
24375 const CImg<T>& save(const char *const filename, const int number=-1) const {
24376 if (is_empty()) throw CImgInstanceException("CImg<%s>::save() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24377 pixel_type(),width,height,depth,dim,data,filename);
24378 if (!filename) throw CImgArgumentException("CImg<%s>::save() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24379 pixel_type(),width,height,depth,dim,data);
24380 const char *ext = cimg::filename_split(filename);
24381 char nfilename[1024];
24382 const char *const fn = (number>=0)?cimg::filename_number(filename,number,6,nfilename):filename;
24383 #ifdef cimg_save_plugin
24384 cimg_save_plugin(fn);
24385 #endif
24386 #ifdef cimg_save_plugin1
24387 cimg_save_plugin1(fn);
24388 #endif
24389 #ifdef cimg_save_plugin2
24390 cimg_save_plugin2(fn);
24391 #endif
24392 #ifdef cimg_save_plugin3
24393 cimg_save_plugin3(fn);
24394 #endif
24395 #ifdef cimg_save_plugin4
24396 cimg_save_plugin4(fn);
24397 #endif
24398 #ifdef cimg_save_plugin5
24399 cimg_save_plugin5(fn);
24400 #endif
24401 #ifdef cimg_save_plugin6
24402 cimg_save_plugin6(fn);
24403 #endif
24404 #ifdef cimg_save_plugin7
24405 cimg_save_plugin7(fn);
24406 #endif
24407 #ifdef cimg_save_plugin8
24408 cimg_save_plugin8(fn);
24409 #endif
24410 if (!cimg::strncasecmp(ext,"asc",3)) return save_ascii(fn);
24411 if (!cimg::strncasecmp(ext,"dlm",3) ||
24412 !cimg::strncasecmp(ext,"txt",3)) return save_dlm(fn);
24413 if (!cimg::strncasecmp(ext,"inr",3)) return save_inr(fn);
24414 if (!cimg::strncasecmp(ext,"hdr",3) ||
24415 !cimg::strncasecmp(ext,"nii",3)) return save_analyze(fn);
24416 if (!cimg::strncasecmp(ext,"dcm",3)) return save_dicom(fn);
24417 if (!cimg::strncasecmp(ext,"pan",3)) return save_pandore(fn);
24418 if (!cimg::strncasecmp(ext,"bmp",3)) return save_bmp(fn);
24419 if (!cimg::strncasecmp(ext,"png",3)) return save_png(fn);
24420 if (!cimg::strncasecmp(ext,"tif",3)) return save_tiff(fn);
24421 if (!cimg::strncasecmp(ext,"jpg",3) ||
24422 !cimg::strncasecmp(ext,"jpeg",4)) return save_jpeg(fn);
24423 if (!cimg::strncasecmp(ext,"rgba",4)) return save_rgba(fn);
24424 if (!cimg::strncasecmp(ext,"rgb",3)) return save_rgb(fn);
24425 if (!cimg::strncasecmp(ext,"raw",3)) return save_raw(fn);
24426 if (!cimg::strncasecmp(ext,"cimg",4) || ext[0]=='\0') return save_cimg(fn);
24427 if (!cimg::strncasecmp(ext,"pgm",3) ||
24428 !cimg::strncasecmp(ext,"ppm",3) ||
24429 !cimg::strncasecmp(ext,"pnm",3)) return save_pnm(fn);
24430 if (!cimg::strncasecmp(ext,"yuv",3)) return save_yuv(fn,true);
24431 return save_other(fn);
24432 }
24433
24435 const CImg<T>& save_ascii(std::FILE *const file, const char *const filename=0) const {
24436 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_ascii() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24437 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24438 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_ascii() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24439 pixel_type(),width,height,depth,dim,data);
24440 std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
24441 std::fprintf(nfile,"%u %u %u %u\n",width,height,depth,dim);
24442 const T* ptrs = data;
24443 cimg_forYZV(*this,y,z,v) {
24444 cimg_forX(*this,x) std::fprintf(nfile,"%g ",(double)*(ptrs++));
24445 std::fputc('\n',nfile);
24446 }
24447 if (!file) cimg::fclose(nfile);
24448 return *this;
24449 }
24450
24452 const CImg<T>& save_ascii(const char *const filename) const {
24453 return save_ascii(0,filename);
24454 }
24455
24457 const CImg<T>& save_dlm(std::FILE *const file, const char *const filename=0) const {
24458 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24459 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24460 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24461 pixel_type(),width,height,depth,dim,data);
24462 if (depth>1)
24463 cimg::warn("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is volumetric. Pixel values along Z will be unrolled (file '%s').",
24464 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24465 if (dim>1)
24466 cimg::warn("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is multispectral. Pixel values along V will be unrolled (file '%s').",
24467 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24468
24469 std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
24470 const T* ptrs = data;
24471 cimg_forYZV(*this,y,z,v) {
24472 cimg_forX(*this,x) std::fprintf(nfile,"%g%s",(double)*(ptrs++),(x==dimx()-1)?"":",");
24473 std::fputc('\n',nfile);
24474 }
24475 if (!file) cimg::fclose(nfile);
24476 return *this;
24477 }
24478
24480 const CImg<T>& save_dlm(const char *const filename) const {
24481 return save_dlm(0,filename);
24482 }
24483
24485 const CImg<T>& save_pnm(std::FILE *const file, const char *const filename=0) const {
24486 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24487 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24488 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24489 pixel_type(),width,height,depth,dim,data);
24490 double stmin, stmax = (double)maxmin(stmin);
24491 if (depth>1)
24492 cimg::warn("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
24493 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24494 if (dim>3)
24495 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').",
24496 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24497 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)");
24498 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
24499 const T
24500 *ptrR = ptr(0,0,0,0),
24501 *ptrG = (dim>=2)?ptr(0,0,0,1):ptrR,
24502 *ptrB = (dim>=3)?ptr(0,0,0,2):ptrR;
24503 const unsigned int buf_size = width*height*(dim==1?1:3);
24504
24505 std::fprintf(nfile,"P%c\n# CREATOR: CImg : Original size=%ux%ux%ux%u\n%u %u\n%u\n",
24506 (dim==1?'5':'6'),width,height,depth,dim,width,height,stmax<256?255:65535);
24507
24508 switch(dim) {
24509 case 1: {
24510 if (stmax<256) {
24511 unsigned char *ptrd = new unsigned char[buf_size], *xptrd = ptrd;
24512 cimg_forXY(*this,x,y) *(xptrd++) = (unsigned char)*(ptrR++);
24513 cimg::fwrite(ptrd,buf_size,nfile);
24514 delete[] ptrd;
24515 } else {
24516 unsigned short *ptrd = new unsigned short[buf_size], *xptrd = ptrd;
24517 cimg_forXY(*this,x,y) *(xptrd++) = (unsigned short)*(ptrR++);
24518 if (!cimg::endian()) cimg::endian_swap(ptrd,buf_size);
24519 cimg::fwrite(ptrd,buf_size,nfile);
24520 delete[] ptrd;
24521 }
24522 } break;
24523 default: {
24524 if (stmax<256) {
24525 unsigned char *ptrd = new unsigned char[buf_size], *xptrd = ptrd;
24526 cimg_forXY(*this,x,y) {
24527 *(xptrd++) = (unsigned char)*(ptrR++);
24528 *(xptrd++) = (unsigned char)*(ptrG++);
24529 *(xptrd++) = (unsigned char)*(ptrB++);
24530 }
24531 cimg::fwrite(ptrd,buf_size,nfile);
24532 delete[] ptrd;
24533 } else {
24534 unsigned short *ptrd = new unsigned short[buf_size], *xptrd = ptrd;
24535 cimg_forXY(*this,x,y) {
24536 *(xptrd++) = (unsigned short)*(ptrR++);
24537 *(xptrd++) = (unsigned short)*(ptrG++);
24538 *(xptrd++) = (unsigned short)*(ptrB++);
24539 }
24540 if (!cimg::endian()) cimg::endian_swap(ptrd,buf_size);
24541 cimg::fwrite(ptrd,buf_size,nfile);
24542 delete[] ptrd;
24543 }
24544 } break;
24545 }
24546 if (!file) cimg::fclose(nfile);
24547 return *this;
24548 }
24549
24551 const CImg<T>& save_pnm(const char *const filename) const {
24552 return save_pnm(0,filename);
24553 }
24554
24556 const CImg<T>& save_dicom(const char *const filename) const {
24557 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_dicom() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24558 pixel_type(),width,height,depth,dim,data,filename);
24559 if (!filename) throw CImgArgumentException("CImg<%s>::save_dicom() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24560 pixel_type(),width,height,depth,dim,data);
24561 char command[1024], filetmp[512], body[512];
24562 std::FILE *file;
24563 do {
24564 std::sprintf(filetmp,"%s.hdr",cimg::filenamerand());
24565 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24566 } while (file);
24567 save_analyze(filetmp);
24568 std::sprintf(command,"%s -w -c dicom -o %s -f %s",cimg::medcon_path(),filename,filetmp);
24569 cimg::system(command);
24570 std::remove(filetmp);
24571 cimg::filename_split(filetmp,body);
24572 std::sprintf(filetmp,"%s.img",body);
24573 std::remove(filetmp);
24574 std::sprintf(command,"m000-%s",filename);
24575 file = std::fopen(command,"rb");
24576 if (!file) {
24577 cimg::fclose(cimg::fopen(filename,"r"));
24578 throw CImgIOException("CImg<%s>::save_dicom() : Failed to save image '%s'.\n\n"
24579 "Path of 'medcon' : \"%s\"\n"
24580 "Path of temporary filename : \"%s\"",
24581 pixel_type(),filename,cimg::medcon_path(),filetmp);
24582 } else cimg::fclose(file);
24583 std::rename(command,filename);
24584 return *this;
24585 }
24586
24588 const CImg<T>& save_analyze(const char *const filename, const float *const voxsize=0) const {
24589 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_analyze() : File '%s', instance image (%u,%u,%u,%u,%p) is empty.",
24590 pixel_type(),width,height,depth,dim,data,filename);
24591 if (!filename) throw CImgArgumentException("CImg<%s>::save_analyze() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24592 pixel_type(),width,height,depth,dim,data);
24593 std::FILE *file;
24594 char header[348], hname[1024], iname[1024];
24595 const char *ext = cimg::filename_split(filename);
24596 short datatype=-1;
24597 std::memset(header,0,348);
24598 if (!ext[0]) { std::sprintf(hname,"%s.hdr",filename); std::sprintf(iname,"%s.img",filename); }
24599 if (!cimg::strncasecmp(ext,"hdr",3)) {
24600 std::strcpy(hname,filename); std::strcpy(iname,filename); std::sprintf(iname+cimg::strlen(iname)-3,"img");
24601 }
24602 if (!cimg::strncasecmp(ext,"img",3)) {
24603 std::strcpy(hname,filename); std::strcpy(iname,filename); std::sprintf(hname+cimg::strlen(iname)-3,"hdr");
24604 }
24605 if (!cimg::strncasecmp(ext,"nii",3)) {
24606 std::strcpy(hname,filename); iname[0] = 0;
24607 }
24608 ((int*)(header))[0] = 348;
24609 std::sprintf(header+4,"CImg");
24610 std::sprintf(header+14," ");
24611 ((short*)(header+36))[0] = 4096;
24612 ((char*)(header+38))[0] = 114;
24613 ((short*)(header+40))[0] = 4;
24614 ((short*)(header+40))[1] = width;
24615 ((short*)(header+40))[2] = height;
24616 ((short*)(header+40))[3] = depth;
24617 ((short*)(header+40))[4] = dim;
24618 if (!cimg::strcasecmp(pixel_type(),"bool")) datatype = 2;
24619 if (!cimg::strcasecmp(pixel_type(),"unsigned char")) datatype = 2;
24620 if (!cimg::strcasecmp(pixel_type(),"char")) datatype = 2;
24621 if (!cimg::strcasecmp(pixel_type(),"unsigned short")) datatype = 4;
24622 if (!cimg::strcasecmp(pixel_type(),"short")) datatype = 4;
24623 if (!cimg::strcasecmp(pixel_type(),"unsigned int")) datatype = 8;
24624 if (!cimg::strcasecmp(pixel_type(),"int")) datatype = 8;
24625 if (!cimg::strcasecmp(pixel_type(),"unsigned long")) datatype = 8;
24626 if (!cimg::strcasecmp(pixel_type(),"long")) datatype = 8;
24627 if (!cimg::strcasecmp(pixel_type(),"float")) datatype = 16;
24628 if (!cimg::strcasecmp(pixel_type(),"double")) datatype = 64;
24629 if (datatype<0)
24630 throw CImgIOException("CImg<%s>::save_analyze() : Cannot save image '%s' since pixel type (%s)"
24631 "is not handled in Analyze7.5 specifications.\n",
24632 pixel_type(),filename,pixel_type());
24633 ((short*)(header+70))[0] = datatype;
24634 ((short*)(header+72))[0] = sizeof(T);
24635 ((float*)(header+112))[0] = 1;
24636 ((float*)(header+76))[0] = 0;
24637 if (voxsize) {
24638 ((float*)(header+76))[1] = voxsize[0];
24639 ((float*)(header+76))[2] = voxsize[1];
24640 ((float*)(header+76))[3] = voxsize[2];
24641 } else ((float*)(header+76))[1] = ((float*)(header+76))[2] = ((float*)(header+76))[3] = 1;
24642 file = cimg::fopen(hname,"wb");
24643 cimg::fwrite(header,348,file);
24644 if (iname[0]) { cimg::fclose(file); file = cimg::fopen(iname,"wb"); }
24645 cimg::fwrite(data,size(),file);
24646 cimg::fclose(file);
24647 return *this;
24648 }
24649
24651 const CImg<T>& save_cimg(std::FILE *const file, const char *const filename=0) const {
24652 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_cimg() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24653 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24654 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24655 pixel_type(),width,height,depth,dim,data);
24656 CImgList<T> tmp(1);
24657 tmp[0].width = width;
24658 tmp[0].height = height;
24659 tmp[0].depth = depth;
24660 tmp[0].dim = dim;
24661 tmp[0].data = data;
24662 tmp.save_cimg(file,filename);
24663 tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0;
24664 tmp[0].data = 0;
24665 return *this;
24666 }
24667
24669 const CImg<T>& save_cimg(const char *const filename) const {
24670 return save_cimg(0,filename);
24671 }
24672
24674 const CImg<T>& save_cimg(std::FILE *const file,
24675 const unsigned int n0,
24676 const unsigned int x0, const unsigned int y0,
24677 const unsigned int z0, const unsigned int v0) const {
24678 CImgList<T> tmp(1);
24679 tmp[0].width = width;
24680 tmp[0].height = height;
24681 tmp[0].depth = depth;
24682 tmp[0].dim = dim;
24683 tmp[0].data = data;
24684 tmp.save_cimg(file,n0,x0,y0,z0,v0);
24685 tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0;
24686 tmp[0].data = 0;
24687 return *this;
24688 }
24689
24691 const CImg<T>& save_cimg(const char *const filename,
24692 const unsigned int n0,
24693 const unsigned int x0, const unsigned int y0,
24694 const unsigned int z0, const unsigned int v0) const {
24695 CImgList<T> tmp(1);
24696 tmp[0].width = width;
24697 tmp[0].height = height;
24698 tmp[0].depth = depth;
24699 tmp[0].dim = dim;
24700 tmp[0].data = data;
24701 tmp.save_cimg(filename,n0,x0,y0,z0,v0);
24702 tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0;
24703 tmp[0].data = 0;
24704 return *this;
24705 }
24706
24708 static void save_empty_cimg(std::FILE *const file,
24709 const unsigned int dx, const unsigned int dy=1,
24710 const unsigned int dz=1, const unsigned int dv=1) {
24711 return CImgList<T>::save_empty_cimg(file,1,dx,dy,dz,dv);
24712 }
24713
24715 static void save_empty_cimg(const char *const filename,
24716 const unsigned int dx, const unsigned int dy=1,
24717 const unsigned int dz=1, const unsigned int dv=1) {
24718 return CImgList<T>::save_empty_cimg(filename,1,dx,dy,dz,dv);
24719 }
24720
24722 const CImg<T>& save_raw(std::FILE *const file, const char *const filename=0, const bool multiplexed=false) const {
24723 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_raw() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24724 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24725 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_raw() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24726 pixel_type(),width,height,depth,dim,data);
24727 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
24728 if (!multiplexed) cimg::fwrite(data,size(),nfile);
24729 else {
24730 CImg<T> buf(dim);
24731 cimg_forXYZ(*this,x,y,z) {
24732 cimg_forV(*this,k) buf[k] = (*this)(x,y,z,k);
24733 cimg::fwrite(buf.data,dim,nfile);
24734 }
24735 }
24736 if (!file) cimg::fclose(nfile);
24737 return *this;
24738 }
24739
24741 const CImg<T>& save_raw(const char *const filename=0, const bool multiplexed=false) const {
24742 return save_raw(0,filename,multiplexed);
24743 }
24744
24746
24752 const CImg<T>& save_imagemagick(const char *const filename, const unsigned int quality=100) const {
24753 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_imagemagick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s')",
24754 pixel_type(),width,height,depth,dim,data,filename);
24755 if (!filename) throw CImgArgumentException("CImg<%s>::save_imagemagick() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24756 pixel_type(),width,height,depth,dim,data);
24757 char command[1024],filetmp[512];
24758 std::FILE *file;
24759 do {
24760 if (dim==1) std::sprintf(filetmp,"%s%s%s.pgm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24761 else std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24762 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24763 } while (file);
24764 save_pnm(filetmp);
24765 std::sprintf(command,"%s -quality %u%% %s \"%s\"",cimg::imagemagick_path(),quality,filetmp,filename);
24766 cimg::system(command);
24767 file = std::fopen(filename,"rb");
24768 if (!file) throw CImgIOException("CImg<%s>::save_imagemagick() : Failed to save image '%s'.\n\n"
24769 "Path of 'convert' : \"%s\"\n"
24770 "Path of temporary filename : \"%s\"\n",
24771 pixel_type(),filename,cimg::imagemagick_path(),filetmp);
24772 if (file) cimg::fclose(file);
24773 std::remove(filetmp);
24774 return *this;
24775 }
24776
24778
24784 const CImg<T>& save_graphicsmagick(const char *const filename, const unsigned int quality=100) const {
24785 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_graphicsmagick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s')",
24786 pixel_type(),width,height,depth,dim,data,filename);
24787 if (!filename) throw CImgArgumentException("CImg<%s>::save_graphicsmagick() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
24788 pixel_type(),width,height,depth,dim,data);
24789 char command[1024],filetmp[512];
24790 std::FILE *file;
24791 do {
24792 if (dim==1) std::sprintf(filetmp,"%s%s%s.pgm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24793 else std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",cimg::filenamerand());
24794 if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
24795 } while (file);
24796 save_pnm(filetmp);
24797 std::sprintf(command,"%s -quality %u%% %s \"%s\"",cimg::graphicsmagick_path(),quality,filetmp,filename);
24798 cimg::system(command);
24799 file = std::fopen(filename,"rb");
24800 if (!file) throw CImgIOException("CImg<%s>::save_graphicsmagick() : Failed to save image '%s'.\n\n"
24801 "Path of 'gm' : \"%s\"\n"
24802 "Path of temporary filename : \"%s\"\n",
24803 pixel_type(),filename,cimg::graphicsmagick_path(),filetmp);
24804 if (file) cimg::fclose(file);
24805 std::remove(filetmp);
24806 return *this;
24807 }
24808
24809 const CImg<T>& save_other(const char *const filename, const unsigned int quality=100) const {
24810 const unsigned int odebug = cimg::exception_mode();
24811 bool is_saved = true;
24812 cimg::exception_mode() = 0;
24813 try { save_magick(filename); }
24814 catch (CImgException&) {
24815 try { save_imagemagick(filename,quality); }
24816 catch (CImgException&) {
24817 try { save_graphicsmagick(filename,quality); }
24818 catch (CImgException&) {
24819 is_saved = false;
24820 }
24821 }
24822 }
24823 cimg::exception_mode() = odebug;
24824 if (!is_saved) throw CImgIOException("CImg<%s>::save_other() : File '%s' cannot be saved.\n"
24825 "Check you have either the ImageMagick or GraphicsMagick package installed.",
24826 pixel_type(),filename);
24827 return *this;
24828 }
24829
24831 const CImg<T>& save_inr(std::FILE *const file, const char *const filename=0, const float *const voxsize=0) const {
24832 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_inr() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24833 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24834 if (!filename) throw CImgArgumentException("CImg<%s>::save_inr() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24835 pixel_type(),width,height,depth,dim,data);
24836 int inrpixsize=-1;
24837 const char *inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0";
24838 if (!cimg::strcasecmp(pixel_type(),"unsigned char")) { inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; }
24839 if (!cimg::strcasecmp(pixel_type(),"char")) { inrtype = "fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; }
24840 if (!cimg::strcasecmp(pixel_type(),"unsigned short")) { inrtype = "unsigned fixed\nPIXSIZE=16 bits\nSCALE=2**0";inrpixsize = 2; }
24841 if (!cimg::strcasecmp(pixel_type(),"short")) { inrtype = "fixed\nPIXSIZE=16 bits\nSCALE=2**0"; inrpixsize = 2; }
24842 if (!cimg::strcasecmp(pixel_type(),"unsigned int")) { inrtype = "unsigned fixed\nPIXSIZE=32 bits\nSCALE=2**0";inrpixsize = 4; }
24843 if (!cimg::strcasecmp(pixel_type(),"int")) { inrtype = "fixed\nPIXSIZE=32 bits\nSCALE=2**0"; inrpixsize = 4; }
24844 if (!cimg::strcasecmp(pixel_type(),"float")) { inrtype = "float\nPIXSIZE=32 bits"; inrpixsize = 4; }
24845 if (!cimg::strcasecmp(pixel_type(),"double")) { inrtype = "float\nPIXSIZE=64 bits"; inrpixsize = 8; }
24846 if (inrpixsize<=0) throw CImgIOException("CImg<%s>::save_inr() : Don't know how to save images of '%s'",pixel_type(),pixel_type());
24847 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
24848 char header[257];
24849 int err = std::sprintf(header,"#INRIMAGE-4#{\nXDIM=%u\nYDIM=%u\nZDIM=%u\nVDIM=%u\n",width,height,depth,dim);
24850 if (voxsize) err += std::sprintf(header+err,"VX=%g\nVY=%g\nVZ=%g\n",voxsize[0],voxsize[1],voxsize[2]);
24851 err += std::sprintf(header+err,"TYPE=%s\nCPU=%s\n",inrtype,cimg::endian()?"sun":"decm");
24852 std::memset(header+err,'\n',252-err);
24853 std::memcpy(header+252,"##}\n",4);
24854 cimg::fwrite(header,256,nfile);
24855 cimg_forXYZ(*this,x,y,z) cimg_forV(*this,k) cimg::fwrite(&((*this)(x,y,z,k)),1,nfile);
24856 if (!file) cimg::fclose(nfile);
24857 return *this;
24858 }
24859
24861 const CImg<T>& save_inr(const char *const filename, const float *const voxsize=0) const {
24862 return save_inr(0,filename,voxsize);
24863 }
24864
24865 #define cimg_save_pandore_case(sy,sz,sv,stype,id) \
24866 if (!saved && (sy?(sy==height):true) && (sz?(sz==depth):true) && (sv?(sv==dim):true) && !strcmp(stype,pixel_type())) { \
24867 unsigned int *iheader = (unsigned int*)(header+12); \
24868 nbdims = _save_pandore_header_length((*iheader=id),dims,colorspace); \
24869 cimg::fwrite(header,36,nfile); \
24870 cimg::fwrite(dims,nbdims,nfile); \
24871 if (id==2 || id==5 || id==8 || id==16 || id==19 || id==22 || id==26 || id==30) { \
24872 unsigned char *buffer = new unsigned char[size()]; \
24873 const T *ptrs = data; \
24874 cimg_foroff(*this,off) *(buffer++) = (unsigned char)(*(ptrs++)); \
24875 buffer-=size(); \
24876 cimg::fwrite(buffer,size(),nfile); \
24877 delete[] buffer; \
24878 } \
24879 if (id==3 || id==6 || id==9 || id==17 || id==20 || id==23 || id==27 || id==31) { \
24880 unsigned long *buffer = new unsigned long[size()]; \
24881 const T *ptrs = data; \
24882 cimg_foroff(*this,off) *(buffer++) = (long)(*(ptrs++)); \
24883 buffer-=size(); \
24884 cimg::fwrite(buffer,size(),nfile); \
24885 delete[] buffer; \
24886 } \
24887 if (id==4 || id==7 || id==10 || id==18 || id==21 || id==25 || id==29 || id==33) { \
24888 float *buffer = new float[size()]; \
24889 const T *ptrs = data; \
24890 cimg_foroff(*this,off) *(buffer++) = (float)(*(ptrs++)); \
24891 buffer-=size(); \
24892 cimg::fwrite(buffer,size(),nfile); \
24893 delete[] buffer; \
24894 } \
24895 saved = true; \
24896 }
24897
24898 unsigned int _save_pandore_header_length(unsigned int id, unsigned int *dims, const unsigned int colorspace=0) const {
24899 unsigned int nbdims = 0;
24900 if (id==2 || id==3 || id==4) { dims[0] = 1; dims[1] = width; nbdims = 2; }
24901 if (id==5 || id==6 || id==7) { dims[0] = 1; dims[1] = height; dims[2] = width; nbdims=3; }
24902 if (id==8 || id==9 || id==10) { dims[0] = dim; dims[1] = depth; dims[2] = height; dims[3] = width; nbdims = 4; }
24903 if (id==16 || id==17 || id==18) { dims[0] = 3; dims[1] = height; dims[2] = width; dims[3] = colorspace; nbdims = 4; }
24904 if (id==19 || id==20 || id==21) { dims[0] = 3; dims[1] = depth; dims[2] = height; dims[3] = width; dims[4] = colorspace; nbdims = 5; }
24905 if (id==22 || id==23 || id==25) { dims[0] = dim; dims[1] = width; nbdims = 2; }
24906 if (id==26 || id==27 || id==29) { dims[0] = dim; dims[1] = height; dims[2] = width; nbdims=3; }
24907 if (id==30 || id==31 || id==33) { dims[0] = dim; dims[1] = depth; dims[2] = height; dims[3] = width; nbdims = 4; }
24908 return nbdims;
24909 }
24910
24912 const CImg<T>& save_pandore(std::FILE *const file, const char *const filename=0, const unsigned int colorspace=0) const {
24913 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_pandore() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
24914 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
24915 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_pandore() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
24916 pixel_type(),width,height,depth,dim,data);
24917 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
24918 unsigned char header[36] = { 'P','A','N','D','O','R','E','0','4',0,0,0,
24919 0,0,0,0,
24920 'C','I','m','g',0,0,0,0,0,
24921 'N','o',' ','d','a','t','e',0,0,0,
24922 0 };
24923 unsigned int nbdims,dims[5];
24924 bool saved=false;
24925 cimg_save_pandore_case(1,1,1,"unsigned char",2);
24926 cimg_save_pandore_case(1,1,1,"char",3);
24927 cimg_save_pandore_case(1,1,1,"short",3);
24928 cimg_save_pandore_case(1,1,1,"unsigned short",3);
24929 cimg_save_pandore_case(1,1,1,"unsigned int",3);
24930 cimg_save_pandore_case(1,1,1,"int",3);
24931 cimg_save_pandore_case(1,1,1,"unsigned long",4);
24932 cimg_save_pandore_case(1,1,1,"long",3);
24933 cimg_save_pandore_case(1,1,1,"float",4);
24934 cimg_save_pandore_case(1,1,1,"double",4);
24935
24936 cimg_save_pandore_case(0,1,1,"unsigned char",5);
24937 cimg_save_pandore_case(0,1,1,"char",6);
24938 cimg_save_pandore_case(0,1,1,"short",6);
24939 cimg_save_pandore_case(0,1,1,"unsigned short",6);
24940 cimg_save_pandore_case(0,1,1,"unsigned int",6);
24941 cimg_save_pandore_case(0,1,1,"int",6);
24942 cimg_save_pandore_case(0,1,1,"unsigned long",7);
24943 cimg_save_pandore_case(0,1,1,"long",6);
24944 cimg_save_pandore_case(0,1,1,"float",7);
24945 cimg_save_pandore_case(0,1,1,"double",7);
24946
24947 cimg_save_pandore_case(0,0,1,"unsigned char",8);
24948 cimg_save_pandore_case(0,0,1,"char",9);
24949 cimg_save_pandore_case(0,0,1,"short",9);
24950 cimg_save_pandore_case(0,0,1,"unsigned short",9);
24951 cimg_save_pandore_case(0,0,1,"unsigned int",9);
24952 cimg_save_pandore_case(0,0,1,"int",9);
24953 cimg_save_pandore_case(0,0,1,"unsigned long",10);
24954 cimg_save_pandore_case(0,0,1,"long",9);
24955 cimg_save_pandore_case(0,0,1,"float",10);
24956 cimg_save_pandore_case(0,0,1,"double",10);
24957
24958 cimg_save_pandore_case(0,1,3,"unsigned char",16);
24959 cimg_save_pandore_case(0,1,3,"char",17);
24960 cimg_save_pandore_case(0,1,3,"short",17);
24961 cimg_save_pandore_case(0,1,3,"unsigned short",17);
24962 cimg_save_pandore_case(0,1,3,"unsigned int",17);
24963 cimg_save_pandore_case(0,1,3,"int",17);
24964 cimg_save_pandore_case(0,1,3,"unsigned long",18);
24965 cimg_save_pandore_case(0,1,3,"long",17);
24966 cimg_save_pandore_case(0,1,3,"float",18);
24967 cimg_save_pandore_case(0,1,3,"double",18);
24968
24969 cimg_save_pandore_case(0,0,3,"unsigned char",19);
24970 cimg_save_pandore_case(0,0,3,"char",20);
24971 cimg_save_pandore_case(0,0,3,"short",20);
24972 cimg_save_pandore_case(0,0,3,"unsigned short",20);
24973 cimg_save_pandore_case(0,0,3,"unsigned int",20);
24974 cimg_save_pandore_case(0,0,3,"int",20);
24975 cimg_save_pandore_case(0,0,3,"unsigned long",21);
24976 cimg_save_pandore_case(0,0,3,"long",20);
24977 cimg_save_pandore_case(0,0,3,"float",21);
24978 cimg_save_pandore_case(0,0,3,"double",21);
24979
24980 cimg_save_pandore_case(1,1,0,"unsigned char",22);
24981 cimg_save_pandore_case(1,1,0,"char",23);
24982 cimg_save_pandore_case(1,1,0,"short",23);
24983 cimg_save_pandore_case(1,1,0,"unsigned short",23);
24984 cimg_save_pandore_case(1,1,0,"unsigned int",23);
24985 cimg_save_pandore_case(1,1,0,"int",23);
24986 cimg_save_pandore_case(1,1,0,"unsigned long",25);
24987 cimg_save_pandore_case(1,1,0,"long",23);
24988 cimg_save_pandore_case(1,1,0,"float",25);
24989 cimg_save_pandore_case(1,1,0,"double",25);
24990
24991 cimg_save_pandore_case(0,1,0,"unsigned char",26);
24992 cimg_save_pandore_case(0,1,0,"char",27);
24993 cimg_save_pandore_case(0,1,0,"short",27);
24994 cimg_save_pandore_case(0,1,0,"unsigned short",27);
24995 cimg_save_pandore_case(0,1,0,"unsigned int",27);
24996 cimg_save_pandore_case(0,1,0,"int",27);
24997 cimg_save_pandore_case(0,1,0,"unsigned long",29);
24998 cimg_save_pandore_case(0,1,0,"long",27);
24999 cimg_save_pandore_case(0,1,0,"float",29);
25000 cimg_save_pandore_case(0,1,0,"double",29);
25001
25002 cimg_save_pandore_case(0,0,0,"unsigned char",30);
25003 cimg_save_pandore_case(0,0,0,"char",31);
25004 cimg_save_pandore_case(0,0,0,"short",31);
25005 cimg_save_pandore_case(0,0,0,"unsigned short",31);
25006 cimg_save_pandore_case(0,0,0,"unsigned int",31);
25007 cimg_save_pandore_case(0,0,0,"int",31);
25008 cimg_save_pandore_case(0,0,0,"unsigned long",33);
25009 cimg_save_pandore_case(0,0,0,"long",31);
25010 cimg_save_pandore_case(0,0,0,"float",33);
25011 cimg_save_pandore_case(0,0,0,"double",33);
25012
25013 if (!file) cimg::fclose(nfile);
25014 return *this;
25015 }
25016
25018 const CImg<T>& save_pandore(const char *const filename=0, const unsigned int colorspace=0) const {
25019 return save_pandore(0,filename,colorspace);
25020 }
25021
25023 const CImg<T>& save_yuv(std::FILE *const file, const char *const filename=0, const bool rgb2yuv=true) const {
25024 CImgList<T>(*this).save_yuv(file,filename,rgb2yuv);
25025 return *this;
25026 }
25027
25029 const CImg<T>& save_yuv(const char *const filename, const bool rgb2yuv=true) const {
25030 return save_yuv(0,filename,rgb2yuv);
25031 }
25032
25034 const CImg<T>& save_bmp(std::FILE *const file, const char *const filename=0) const {
25035 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25036 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25037 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
25038 pixel_type(),width,height,depth,dim,data);
25039 if (depth>1)
25040 cimg::warn("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
25041 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25042 if (dim>3)
25043 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').",
25044 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25045
25046 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
25047 unsigned char header[54] = { 0 }, align_buf[4] = { 0 };
25048 const unsigned int
25049 align = (4-(3*width)%4)%4,
25050 buf_size = (3*width+align)*dimy(),
25051 file_size = 54+buf_size;
25052 header[0] = 'B'; header[1] = 'M';
25053 header[0x02] = file_size&0xFF;
25054 header[0x03] = (file_size>>8)&0xFF;
25055 header[0x04] = (file_size>>16)&0xFF;
25056 header[0x05] = (file_size>>24)&0xFF;
25057 header[0x0A] = 0x36;
25058 header[0x0E] = 0x28;
25059 header[0x12] = width&0xFF;
25060 header[0x13] = (width>>8)&0xFF;
25061 header[0x14] = (width>>16)&0xFF;
25062 header[0x15] = (width>>24)&0xFF;
25063 header[0x16] = height&0xFF;
25064 header[0x17] = (height>>8)&0xFF;
25065 header[0x18] = (height>>16)&0xFF;
25066 header[0x19] = (height>>24)&0xFF;
25067 header[0x1A] = 1;
25068 header[0x1B] = 0;
25069 header[0x1C] = 24;
25070 header[0x1D] = 0;
25071 header[0x22] = buf_size&0xFF;
25072 header[0x23] = (buf_size>>8)&0xFF;
25073 header[0x24] = (buf_size>>16)&0xFF;
25074 header[0x25] = (buf_size>>24)&0xFF;
25075 header[0x27] = 0x1;
25076 header[0x2B] = 0x1;
25077 cimg::fwrite(header,54,nfile);
25078
25079 const T
25080 *pR = ptr(0,height-1,0,0),
25081 *pG = (dim>=2)?ptr(0,height-1,0,1):pR,
25082 *pB = (dim>=3)?ptr(0,height-1,0,2):pR;
25083
25084 cimg_forY(*this,y) {
25085 cimg_forX(*this,x) {
25086 std::fputc((unsigned char)(*(pB++)),nfile);
25087 std::fputc((unsigned char)(*(pG++)),nfile);
25088 std::fputc((unsigned char)(*(pR++)),nfile);
25089 }
25090 cimg::fwrite(align_buf,align,nfile);
25091 pR-=2*width; pG-=2*width; pB-=2*width;
25092 }
25093 if (!file) cimg::fclose(nfile);
25094 return *this;
25095 }
25096
25098 const CImg<T>& save_bmp(const char *const filename) const {
25099 return save_bmp(0,filename);
25100 }
25101
25103
25116 const CImg<T>& save_png(std::FILE *const file, const char *const filename=0) const {
25117 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25118 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25119 if (!filename) throw CImgArgumentException("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
25120 pixel_type(),width,height,depth,dim,data);
25121 if (depth>1)
25122 cimg::warn("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
25123 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25124 #ifndef cimg_use_png
25125 if (!file) return save_other(filename);
25126 else throw CImgIOException("CImg<%s>::save_png() : Cannot save a PNG image in a *FILE output. Use libpng instead.",
25127 pixel_type());
25128 #else
25129 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
25130
25131
25132 png_voidp user_error_ptr = 0;
25133 png_error_ptr user_error_fn = 0, user_warning_fn = 0;
25134 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
25135 user_error_ptr, user_error_fn, user_warning_fn);
25136 if(!png_ptr){
25137 if (!file) cimg::fclose(nfile);
25138 throw CImgIOException("CImg<%s>::save_png() : File '%s', error when initializing 'png_ptr' data structure.",
25139 pixel_type(),filename?filename:"(unknown)");
25140 }
25141 png_infop info_ptr = png_create_info_struct(png_ptr);
25142 if(!info_ptr){
25143 png_destroy_write_struct(&png_ptr,(png_infopp)0);
25144 if (!file) cimg::fclose(nfile);
25145 throw CImgIOException("CImg<%s>::save_png() : File '%s', error when initializing 'info_ptr' data structure.",
25146 pixel_type(),filename?filename:"(unknown)");
25147 }
25148 if (setjmp(png_jmpbuf(png_ptr))){
25149 png_destroy_write_struct(&png_ptr, &info_ptr);
25150 if (!file) cimg::fclose(nfile);
25151 throw CImgIOException("CImg<%s>::save_png() : File '%s', unknown fatal error.",
25152 pixel_type(),filename?filename:"(unknown)");
25153 }
25154
25155 png_init_io(png_ptr, nfile);
25156 png_uint_32 width = dimx();
25157 png_uint_32 height = dimy();
25158 float vmin, vmax = (float)maxmin(vmin);
25159 const int bit_depth = (vmin<0 || vmax>=256)?16:8;
25160 int color_type;
25161 switch (dimv()) {
25162 case 1: color_type = PNG_COLOR_TYPE_GRAY; break;
25163 case 2: color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break;
25164 case 3: color_type = PNG_COLOR_TYPE_RGB; break;
25165 default: color_type = PNG_COLOR_TYPE_RGB_ALPHA;
25166 }
25167 const int interlace_type = PNG_INTERLACE_NONE;
25168 const int compression_type = PNG_COMPRESSION_TYPE_DEFAULT;
25169 const int filter_method = PNG_FILTER_TYPE_DEFAULT;
25170 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type,
25171 compression_type, filter_method);
25172 png_write_info(png_ptr, info_ptr);
25173 const int byte_depth = bit_depth>>3;
25174 const int numChan = dimv()>4?4:dimv();
25175 const int pixel_bit_depth_flag = numChan * (bit_depth-1);
25176
25177
25178 png_bytep *imgData = new png_byte*[height];
25179 for (unsigned int row=0; row<height; ++row) imgData[row] = new png_byte[byte_depth * numChan * width];
25180 const T *pC0 = ptr(0,0,0,0);
25181 switch(pixel_bit_depth_flag) {
25182 case 7 : {
25183 cimg_forY(*this,y) {
25184 unsigned char *ptrs = imgData[y];
25185 cimg_forX(*this,x) *(ptrs++) = (unsigned char)*(pC0++);
25186 }
25187 } break;
25188 case 14: {
25189 const T *pC1 = ptr(0,0,0,1);
25190 cimg_forY(*this,y) {
25191 unsigned char *ptrs = imgData[y];
25192 cimg_forX(*this,x) {
25193 *(ptrs++) = (unsigned char)*(pC0++);
25194 *(ptrs++) = (unsigned char)*(pC1++);
25195 }
25196 }
25197 } break;
25198 case 21: {
25199 const T *pC1 = ptr(0,0,0,1);
25200 const T *pC2 = ptr(0,0,0,2);
25201 cimg_forY(*this,y) {
25202 unsigned char *ptrs = imgData[y];
25203 cimg_forX(*this,x) {
25204 *(ptrs++) = (unsigned char)*(pC0++);
25205 *(ptrs++) = (unsigned char)*(pC1++);
25206 *(ptrs++) = (unsigned char)*(pC2++);
25207 }
25208 }
25209 } break;
25210 case 28: {
25211 const T *pC1 = ptr(0,0,0,1);
25212 const T *pC2 = ptr(0,0,0,2);
25213 const T *pC3 = ptr(0,0,0,3);
25214 cimg_forY(*this,y){
25215 unsigned char *ptrs = imgData[y];
25216 cimg_forX(*this,x){
25217 *(ptrs++) = (unsigned char)*(pC0++);
25218 *(ptrs++) = (unsigned char)*(pC1++);
25219 *(ptrs++) = (unsigned char)*(pC2++);
25220 *(ptrs++) = (unsigned char)*(pC3++);
25221 }
25222 }
25223 } break;
25224 case 15: {
25225 cimg_forY(*this,y){
25226 unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
25227 cimg_forX(*this,x) *(ptrs++) = (unsigned short)*(pC0++);
25228 }
25229 } break;
25230 case 30: {
25231 const T *pC1 = ptr(0,0,0,1);
25232 cimg_forY(*this,y){
25233 unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
25234 cimg_forX(*this,x) {
25235 *(ptrs++) = (unsigned short)*(pC0++);
25236 *(ptrs++) = (unsigned short)*(pC1++);
25237 }
25238 }
25239 } break;
25240 case 45: {
25241 const T *pC1 = ptr(0,0,0,1);
25242 const T *pC2 = ptr(0,0,0,2);
25243 cimg_forY(*this,y) {
25244 unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
25245 cimg_forX(*this,x) {
25246 *(ptrs++) = (unsigned short)*(pC0++);
25247 *(ptrs++) = (unsigned short)*(pC1++);
25248 *(ptrs++) = (unsigned short)*(pC2++);
25249 }
25250 }
25251 } break;
25252 case 60: {
25253 const T *pC1 = ptr(0,0,0,1);
25254 const T *pC2 = ptr(0,0,0,2);
25255 const T *pC3 = ptr(0,0,0,3);
25256 cimg_forY(*this,y) {
25257 unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
25258 cimg_forX(*this,x) {
25259 *(ptrs++) = (unsigned short)*(pC0++);
25260 *(ptrs++) = (unsigned short)*(pC1++);
25261 *(ptrs++) = (unsigned short)*(pC2++);
25262 *(ptrs++) = (unsigned short)*(pC3++);
25263 }
25264 }
25265 } break;
25266 default:
25267 if (!file) cimg::fclose(nfile);
25268 throw CImgIOException("CImg<%s>::save_png() : File '%s', unknown fatal error.",
25269 pixel_type(),filename?filename:"(unknown)");
25270 break;
25271 }
25272 png_write_image(png_ptr, imgData);
25273 png_write_end(png_ptr, info_ptr);
25274 png_destroy_write_struct(&png_ptr, &info_ptr);
25275
25276
25277 for (unsigned int n=0; n<height; ++n) delete[] imgData[n];
25278 delete[] imgData;
25279 if (!file) cimg::fclose(nfile);
25280 return *this;
25281 #endif
25282 }
25283
25285 const CImg<T>& save_png(const char *const filename) const {
25286 return save_png(0,filename);
25287 }
25288
25290 const CImg<T>& save_tiff(const char *const filename) const {
25291 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_tiff() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25292 pixel_type(),width,height,depth,dim,data,filename);
25293 if (!filename) throw CImgArgumentException("CImg<%s>::save_tiff() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
25294 pixel_type(),width,height,depth,dim,data);
25295 #ifdef cimg_use_tiff
25296 uint32 rowsperstrip = (uint32) -1;
25297 uint16 spp = dimv(), bpp = sizeof(T)*8;
25298 uint16 photometric;
25299 if (spp==3 || spp==4)
25300 photometric = PHOTOMETRIC_RGB;
25301 else
25302 photometric = PHOTOMETRIC_MINISBLACK;
25303 uint16 compression = COMPRESSION_NONE;
25304 TIFF *out;
25305 out = TIFFOpen(filename,"w");
25306 if (out) {
25307 for (unsigned int dir=0; dir<depth; ++dir) {
25308 TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32)dimx());
25309 TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32)dimy());
25310 TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
25311 TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
25312 if (cimg::type<T>::is_float()) TIFFSetField(out, TIFFTAG_SAMPLEFORMAT,3);
25313 else if (cimg::type<T>::min()==0) TIFFSetField(out, TIFFTAG_SAMPLEFORMAT,2);
25314 else TIFFSetField(out, TIFFTAG_SAMPLEFORMAT,1);
25315 TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bpp);
25316 TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
25317 TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
25318 TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
25319 rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
25320 TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
25321 TIFFSetField(out, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
25322 TIFFSetField(out, TIFFTAG_SOFTWARE, "CImg");
25323 T *buf = (T *)_TIFFmalloc(TIFFStripSize(out));
25324 if (buf){
25325 for (unsigned int row = 0; row < height; row+=rowsperstrip) {
25326 uint32 nrow = (row+rowsperstrip>height?height-row:rowsperstrip);
25327 tstrip_t strip = TIFFComputeStrip(out, row, 0);
25328 tsize_t i = 0;
25329 for (unsigned int rr=0; rr<nrow; ++rr)
25330 for (unsigned int cc=0; cc<width; ++cc)
25331 for (unsigned int vv=0; vv<spp; ++vv)
25332 buf[i++] = (*this)(cc,row+rr,dir,vv);
25333 if(TIFFWriteEncodedStrip(out, strip, buf, i*sizeof(T))<0){
25334 throw CImgException("CImg<%s>::save_tiff() : File '%s', an error occure while writing a strip.",
25335 pixel_type(),filename?filename:"(FILE*)");
25336 }
25337 }
25338 _TIFFfree(buf);
25339 }
25340 TIFFWriteDirectory(out);
25341 }
25342 TIFFClose(out);
25343 }
25344 else throw CImgException("CImg<%s>::save_tiff() : File '%s', error while writing tiff file.",
25345 pixel_type(),filename);
25346 #else
25347 return save_other(filename);
25348 #endif
25349 return *this;
25350 }
25351
25353 const CImg<T>& save_jpeg(std::FILE *const file, const char *const filename=0, const unsigned int quality=100) const {
25354 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25355 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25356 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
25357 pixel_type(),width,height,depth,dim,data);
25358 if (depth>1)
25359 cimg::warn("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
25360 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25361 #ifndef cimg_use_jpeg
25362 if (!file) return save_other(filename,quality);
25363 else throw CImgIOException("CImg<%s>::save_jpeg() : Cannot save a JPEG image in a *FILE output. Use libjpeg instead.",
25364 pixel_type());
25365 #else
25366
25367
25368 unsigned char *buf;
25369 unsigned int dimbuf = 0;
25370 J_COLOR_SPACE colortype = JCS_RGB;
25371 switch (dim) {
25372 case 1: {
25373 unsigned char *buf2 = buf = new unsigned char[width*height*(dimbuf=1)];
25374 colortype = JCS_GRAYSCALE;
25375 const T *ptr_g = data;
25376 cimg_forXY(*this,x,y) *(buf2++) = (unsigned char)*(ptr_g++);
25377 } break;
25378 case 2:
25379 case 3: {
25380 unsigned char *buf2 = buf = new unsigned char[width*height*(dimbuf=3)];
25381 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);
25382 colortype = JCS_RGB;
25383 cimg_forXY(*this,x,y) {
25384 *(buf2++) = (unsigned char)*(ptr_r++);
25385 *(buf2++) = (unsigned char)*(ptr_g++);
25386 *(buf2++) = (unsigned char)*(ptr_b++);
25387 }
25388 } break;
25389 default: {
25390 unsigned char *buf2 = buf = new unsigned char[width*height*(dimbuf=4)];
25391 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);
25392 colortype = JCS_CMYK;
25393 cimg_forXY(*this,x,y) {
25394 *(buf2++) = (unsigned char)*(ptr_r++);
25395 *(buf2++) = (unsigned char)*(ptr_g++);
25396 *(buf2++) = (unsigned char)*(ptr_b++);
25397 *(buf2++) = (unsigned char)*(ptr_a++);
25398 }
25399 } break;
25400 }
25401
25402
25403 struct jpeg_compress_struct cinfo;
25404 struct jpeg_error_mgr jerr;
25405 cinfo.err = jpeg_std_error(&jerr);
25406 jpeg_create_compress(&cinfo);
25407 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
25408 jpeg_stdio_dest(&cinfo,nfile);
25409 cinfo.image_width = width;
25410 cinfo.image_height = height;
25411 cinfo.input_components = dimbuf;
25412 cinfo.in_color_space = colortype;
25413 jpeg_set_defaults(&cinfo);
25414 jpeg_set_quality(&cinfo,quality<100?quality:100,TRUE);
25415 jpeg_start_compress(&cinfo,TRUE);
25416
25417 const unsigned int row_stride = width*dimbuf;
25418 JSAMPROW row_pointer[1];
25419 while (cinfo.next_scanline < cinfo.image_height) {
25420 row_pointer[0] = &buf[cinfo.next_scanline*row_stride];
25421 jpeg_write_scanlines(&cinfo,row_pointer,1);
25422 }
25423 jpeg_finish_compress(&cinfo);
25424
25425 delete[] buf;
25426 if (!file) cimg::fclose(nfile);
25427 jpeg_destroy_compress(&cinfo);
25428 return *this;
25429 #endif
25430 }
25431
25433 const CImg<T>& save_jpeg(const char *const filename, const unsigned int quality=100) const {
25434 return save_jpeg(0,filename,quality);
25435 }
25436
25438 const CImg<T>& save_magick(const char *const filename) const {
25439 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_magick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25440 pixel_type(),width,height,depth,dim,data);
25441 if (!filename) throw CImgArgumentException("CImg<%s>::save_magick() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
25442 pixel_type(),width,height,depth,dim,data);
25443 #ifdef cimg_use_magick
25444 Magick::Image image(Magick::Geometry(width,height),"black");
25445 image.type(Magick::TrueColorType);
25446 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;
25447 Magick::PixelPacket *pixels = image.getPixels(0,0,width,height);
25448 for (unsigned int off = width*height; off; --off) {
25449 pixels->red = Magick::Color::scaleDoubleToQuantum(*(rdata++)/255.0);
25450 pixels->green = Magick::Color::scaleDoubleToQuantum(*(gdata++)/255.0);
25451 pixels->blue = Magick::Color::scaleDoubleToQuantum(*(bdata++)/255.0);
25452 ++pixels;
25453 }
25454 image.syncPixels();
25455 image.write(filename);
25456 #else
25457 throw CImgIOException("CImg<%s>::save_magick() : File '%s', Magick++ library has not been linked.",
25458 pixel_type(),filename);
25459 #endif
25460 return *this;
25461 }
25462
25464 const CImg<T>& save_rgba(std::FILE *const file, const char *const filename=0) const {
25465 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25466 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25467 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
25468 pixel_type(),width,height,depth,dim,data);
25469 if (dim!=4)
25470 cimg::warn("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p) has not exactly 4 channels (file '%s').",
25471 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25472 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
25473 const unsigned int wh = width*height;
25474 unsigned char *buffer = new unsigned char[4*wh], *nbuffer=buffer;
25475 const T
25476 *ptr1 = ptr(0,0,0,0),
25477 *ptr2 = dim>1?ptr(0,0,0,1):ptr1,
25478 *ptr3 = dim>2?ptr(0,0,0,2):ptr1,
25479 *ptr4 = dim>3?ptr(0,0,0,3):0;
25480 for (unsigned int k=0; k<wh; ++k) {
25481 *(nbuffer++) = (unsigned char)(*(ptr1++));
25482 *(nbuffer++) = (unsigned char)(*(ptr2++));
25483 *(nbuffer++) = (unsigned char)(*(ptr3++));
25484 *(nbuffer++) = (unsigned char)(ptr4?(*(ptr4++)):255);
25485 }
25486 cimg::fwrite(buffer,4*wh,nfile);
25487 if (!file) cimg::fclose(nfile);
25488 delete[] buffer;
25489 return *this;
25490 }
25491
25493 const CImg<T>& save_rgba(const char *const filename) const {
25494 return save_rgba(0,filename);
25495 }
25496
25498 const CImg<T>& save_rgb(std::FILE *const file, const char *const filename=0) const {
25499 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25500 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25501 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
25502 pixel_type(),width,height,depth,dim,data);
25503 if (dim!=3)
25504 cimg::warn("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p) has not exactly 3 channels (file '%s').",
25505 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25506 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
25507 const unsigned int wh = width*height;
25508 unsigned char *buffer = new unsigned char[3*wh], *nbuffer=buffer;
25509 const T
25510 *ptr1 = ptr(0,0,0,0),
25511 *ptr2 = dim>1?ptr(0,0,0,1):ptr1,
25512 *ptr3 = dim>2?ptr(0,0,0,2):ptr1;
25513 for (unsigned int k=0; k<wh; ++k) {
25514 *(nbuffer++) = (unsigned char)(*(ptr1++));
25515 *(nbuffer++) = (unsigned char)(*(ptr2++));
25516 *(nbuffer++) = (unsigned char)(*(ptr3++));
25517 }
25518 cimg::fwrite(buffer,3*wh,nfile);
25519 if (!file) cimg::fclose(nfile);
25520 delete[] buffer;
25521 return *this;
25522 }
25523
25525 const CImg<T>& save_rgb(const char *const filename) const {
25526 return save_rgb(0,filename);
25527 }
25528
25530 template<typename tf, typename tc>
25531 const CImg<T>& save_off(std::FILE *const file, const char *const filename,
25532 const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
25533 if (is_empty()) throw CImgInstanceException("CImg<%s>::save_off() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
25534 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
25535 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_off() : Specified filename is (null).",pixel_type());
25536 if (height<3) return get_resize(-100,3,1,1,0).save_off(file,filename,primitives,colors,invert_faces);
25537 std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
25538 std::fprintf(nfile,"OFF\n%u %u %u\n",width,primitives.size,3*primitives.size);
25539 cimg_forX(*this,i) std::fprintf(nfile,"%f %f %f\n",(float)((*this)(i,0)),(float)((*this)(i,1)),(float)((*this)(i,2)));
25540 cimglist_for(primitives,l) {
25541 const unsigned int prim = primitives[l].size();
25542 const bool textured = (prim>4);
25543 const CImg<tc>& color = colors[l];
25544 const unsigned int s = textured?color.dimv():color.size();
25545 const float
25546 r = textured?(s>0?(float)(color.get_shared_channel(0).mean()/255.0f):1.0f):(s>0?(float)(color(0)/255.0f):1.0f),
25547 g = textured?(s>1?(float)(color.get_shared_channel(1).mean()/255.0f):r) :(s>1?(float)(color(1)/255.0f):r),
25548 b = textured?(s>2?(float)(color.get_shared_channel(2).mean()/255.0f):r) :(s>2?(float)(color(2)/255.0f):r);
25549
25550 switch (prim) {
25551 case 1:
25552 std::fprintf(nfile,"1 %u %f %f %f\n",(unsigned int)primitives(l,0),r,g,b);
25553 break;
25554 case 2: case 6:
25555 std::fprintf(nfile,"2 %u %u %f %f %f\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,1),r,g,b);
25556 break;
25557 case 3: case 9:
25558 if (invert_faces)
25559 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);
25560 else
25561 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);
25562 break;
25563 case 4: case 12:
25564 if (invert_faces)
25565 std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n",
25566 (unsigned int)primitives(l,0),(unsigned int)primitives(l,1),(unsigned int)primitives(l,2),(unsigned int)primitives(l,3),r,g,b);
25567 else
25568 std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n",
25569 (unsigned int)primitives(l,0),(unsigned int)primitives(l,3),(unsigned int)primitives(l,2),(unsigned int)primitives(l,1),r,g,b);
25570 break;
25571 }
25572 }
25573 if (!file) cimg::fclose(nfile);
25574 return *this;
25575 }
25576
25578 template<typename tf, typename tc>
25579 const CImg<T>& save_off(const char *const filename,
25580 const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
25581 return save_off(0,filename,primitives,colors,invert_faces);
25582 }
25583
25585 static CImg<T> get_logo40x38() {
25586 static bool first_time = true;
25587 static CImg<T> res(40,38,1,3);
25588 if (first_time) {
25589 const unsigned char *ptrs = cimg::logo40x38;
25590 T *ptr1 = res.ptr(0,0,0,0), *ptr2 = res.ptr(0,0,0,1), *ptr3 = res.ptr(0,0,0,2);
25591 for (unsigned int off = 0; off<res.width*res.height;) {
25592 const unsigned char n = *(ptrs++), r = *(ptrs++), g = *(ptrs++), b = *(ptrs++);
25593 for (unsigned int l=0; l<n; ++off, ++l) { *(ptr1++) = (T)r; *(ptr2++) = (T)g; *(ptr3++) = (T)b; }
25594 }
25595 first_time = false;
25596 }
25597 return res;
25598 }
25599
25600 };
25601
25602
25603
25604
25605
25606
25607
25608
25609
25610
25611
25612
25613
25614
25616 template<typename T> struct CImgList {
25617
25619 unsigned int size;
25620
25622 unsigned int allocsize;
25623
25625 CImg<T> *data;
25626
25628 typedef CImg<T>* iterator;
25629
25631 typedef const CImg<T>* const_iterator;
25632
25634 typedef T value_type;
25635
25637
25638
25640
25641
25642 #ifdef cimglist_plugin
25643 #include cimglist_plugin
25644 #endif
25645 #ifdef cimglist_plugin1
25646 #include cimglist_plugin1
25647 #endif
25648 #ifdef cimglist_plugin2
25649 #include cimglist_plugin2
25650 #endif
25651 #ifdef cimglist_plugin3
25652 #include cimglist_plugin3
25653 #endif
25654 #ifdef cimglist_plugin4
25655 #include cimglist_plugin4
25656 #endif
25657 #ifdef cimglist_plugin5
25658 #include cimglist_plugin5
25659 #endif
25660 #ifdef cimglist_plugin6
25661 #include cimglist_plugin6
25662 #endif
25663 #ifdef cimglist_plugin7
25664 #include cimglist_plugin7
25665 #endif
25666 #ifdef cimglist_plugin8
25667 #include cimglist_plugin8
25668 #endif
25669
25670
25671
25672
25674
25675
25676
25678 CImgList():
25679 size(0),allocsize(0),data(0) {}
25680
25682 ~CImgList() {
25683 if (data) delete[] data;
25684 }
25685
25687 CImgList<T>& assign() {
25688 if (data) delete[] data;
25689 size = allocsize = 0;
25690 data = 0;
25691 return *this;
25692 }
25693
25695 CImgList<T>& clear() {
25696 return assign();
25697 }
25698
25700 template<typename t> CImgList(const CImgList<t>& list):
25701 size(0),allocsize(0),data(0) {
25702 assign(list);
25703 }
25704
25705 CImgList(const CImgList<T>& list):
25706 size(0),allocsize(0),data(0) {
25707 assign(list.size);
25708 cimglist_for(*this,l) (*this)[l].assign(list[l],list[l].is_shared);
25709 }
25710
25712 template<typename t> CImgList(const CImgList<t>& list, const bool shared):
25713 size(0),allocsize(0),data(0) {
25714 assign(list,shared?1:0);
25715 }
25716
25717 CImgList(const CImgList<T>& list, const bool shared):
25718 size(0),allocsize(0),data(0) {
25719 assign(list,shared?1:0);
25720 }
25721
25723 template<typename t> CImgList<T>& assign(const CImgList<t>& list, const int shared=0) {
25724 assign(list.size);
25725 if (shared>=0) cimglist_for(*this,l) (*this)[l].assign(list[l],shared?true:false);
25726 else cimglist_for(*this,l) (*this)[l].assign(list[l],list[l].is_shared);
25727 return *this;
25728 }
25729
25731 explicit CImgList(const unsigned int n):
25732 size(n) {
25733 data = new CImg<T>[allocsize=cimg::nearest_pow2(n)];
25734 }
25735
25737 CImgList<T>& assign(const unsigned int n) {
25738 if (n) {
25739 if (allocsize<n || allocsize>(n<<2)) {
25740 if (data) delete[] data;
25741 data = new CImg<T>[allocsize=cimg::nearest_pow2(n)];
25742 }
25743 size = n;
25744 } else return assign();
25745 return *this;
25746 }
25747
25749 CImgList(const unsigned int n, const unsigned int width, const unsigned int height=1,
25750 const unsigned int depth=1, const unsigned int dim=1):
25751 size(0),allocsize(0),data(0) {
25752 assign(n,width,height,depth,dim);
25753 }
25754
25756 CImgList<T>& assign(const unsigned int n, const unsigned int width, const unsigned int height=1,
25757 const unsigned int depth=1, const unsigned int dim=1) {
25758 const unsigned int siz = width*height*depth*dim;
25759 if (n && siz) { assign(n); cimglist_for(*this,l) data[l].assign(width,height,depth,dim); }
25760 else return assign();
25761 return *this;
25762 }
25763
25765 CImgList(const unsigned int n, const unsigned int width, const unsigned int height,
25766 const unsigned int depth, const unsigned int dim, const T val):
25767 size(0),allocsize(0),data(0) {
25768 assign(n,width,height,depth,dim,val);
25769 }
25770
25772 CImgList<T>& assign(const unsigned int n, const unsigned int width, const unsigned int height,
25773 const unsigned int depth, const unsigned int dim, const T val) {
25774 assign(n,width,height,depth,dim);
25775 cimglist_for(*this,l) data[l].fill(val);
25776 return *this;
25777 }
25778
25780 CImgList(const unsigned int n, const unsigned int width, const unsigned int height,
25781 const unsigned int depth, const unsigned int dim, const int val0, const int val1, ...):
25782 size(0),allocsize(0),data(0) {
25783 #define _CImgList_stdarg(t) \
25784 assign(n,width,height,depth,dim); \
25785 const unsigned int siz = width*height*depth*dim, nsiz = siz*n; \
25786 T *ptrd = data->data; \
25787 va_list ap; \
25788 va_start(ap,val1); \
25789 for (unsigned int l=0, s=0, i=0; i<nsiz; ++i) { \
25790 *(ptrd++) = (T)(i==0?val0:(i==1?val1:va_arg(ap,t))); \
25791 if ((++s)==siz) { ptrd = data[++l].data; s=0; }\
25792 } \
25793 va_end(ap);
25794 _CImgList_stdarg(int);
25795 }
25796
25798 CImgList<T>& assign(const unsigned int n, const unsigned int width, const unsigned int height,
25799 const unsigned int depth, const unsigned int dim, const int val0, const int val1, ...) {
25800 _CImgList_stdarg(int);
25801 return *this;
25802 }
25803
25805 CImgList(const unsigned int n, const unsigned int width, const unsigned int height,
25806 const unsigned int depth, const unsigned int dim, const double val0, const double val1, ...):
25807 size(0),allocsize(0),data(0) {
25808 _CImgList_stdarg(double);
25809 }
25810
25812 CImgList<T>& assign(const unsigned int n, const unsigned int width, const unsigned int height,
25813 const unsigned int depth, const unsigned int dim, const double val0, const double val1, ...) {
25814 _CImgList_stdarg(double);
25815 return *this;
25816 }
25817
25819 template<typename t> CImgList(const unsigned int n, const CImg<t>& img, const bool shared=false):
25820 size(0),allocsize(0),data(0) {
25821 assign(n,img,shared);
25822 }
25823
25825 template<typename t> CImgList<T>& assign(const unsigned int n, const CImg<t>& img, const bool shared=false) {
25826 assign(n);
25827 cimglist_for(*this,l) data[l].assign(img,shared);
25828 return *this;
25829 }
25830
25832 template<typename t> explicit CImgList(const CImg<t>& img, const bool shared=false):
25833 size(0),allocsize(0),data(0) {
25834 assign(img,shared);
25835 }
25836
25838 template<typename t> CImgList<T>& assign(const CImg<t>& img, const bool shared=false) {
25839 return assign(1,img,shared);
25840 }
25841
25843 template<typename t1, typename t2> CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const bool shared=false):
25844 size(0),allocsize(0),data(0) {
25845 assign(img1,img2,shared);
25846 }
25847
25849 template<typename t1, typename t2> CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const bool shared=false) {
25850 assign(2);
25851 data[0].assign(img1,shared); data[1].assign(img2,shared);
25852 return *this;
25853 }
25854
25856 template<typename t1, typename t2, typename t3> CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const bool shared=false):
25857 size(0),allocsize(0),data(0) {
25858 assign(img1,img2,img3,shared);
25859 }
25860
25862 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) {
25863 assign(3);
25864 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared);
25865 return *this;
25866 }
25867
25869 template<typename t1, typename t2, typename t3, typename t4>
25870 CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const bool shared=false):
25871 size(0),allocsize(0),data(0) {
25872 assign(img1,img2,img3,img4,shared);
25873 }
25874
25876 template<typename t1, typename t2, typename t3, typename t4>
25877 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const bool shared=false) {
25878 assign(4);
25879 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25880 return *this;
25881 }
25882
25884 template<typename t1, typename t2, typename t3, typename t4, typename t5>
25885 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):
25886 size(0),allocsize(0),data(0) {
25887 assign(img1,img2,img3,img4,img5,shared);
25888 }
25889
25891 template<typename t1, typename t2, typename t3, typename t4, typename t5>
25892 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25893 const bool shared=false) {
25894 assign(5);
25895 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25896 data[4].assign(img5,shared);
25897 return *this;
25898 }
25899
25901 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6>
25902 CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25903 const CImg<t6>& img6, const bool shared=false):
25904 size(0),allocsize(0),data(0) {
25905 assign(img1,img2,img3,img4,img5,img6,shared);
25906 }
25907
25909 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6>
25910 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25911 const CImg<t6>& img6, const bool shared=false) {
25912 assign(6);
25913 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25914 data[4].assign(img5,shared); data[5].assign(img6,shared);
25915 return *this;
25916 }
25917
25919 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7>
25920 CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25921 const CImg<t6>& img6, const CImg<t7>& img7, const bool shared=false):
25922 size(0),allocsize(0),data(0) {
25923 assign(img1,img2,img3,img4,img5,img6,img7,shared);
25924 }
25925
25927 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7>
25928 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25929 const CImg<t6>& img6, const CImg<t7>& img7, const bool shared=false) {
25930 assign(7);
25931 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25932 data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared);
25933 return *this;
25934 }
25935
25937 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8>
25938 CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25939 const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const bool shared=false):
25940 size(0),allocsize(0),data(0) {
25941 assign(img1,img2,img3,img4,img5,img6,img7,img8,shared);
25942 }
25943
25945 template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8>
25946 CImgList<T>& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
25947 const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const bool shared=false) {
25948 assign(8);
25949 data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
25950 data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared); data[7].assign(img8,shared);
25951 return *this;
25952 }
25953
25955 CImgList(const char *const filename):
25956 size(0),allocsize(0),data(0) {
25957 assign(filename);
25958 }
25959
25961 CImgList<T>& assign(const char *const filename) {
25962 return load(filename);
25963 }
25964
25965
25966 CImgList<T>& swap(CImgList<T>& list) {
25967 cimg::swap(size,list.size);
25968 cimg::swap(allocsize,list.allocsize);
25969 cimg::swap(data,list.data);
25970 return list;
25971 }
25972
25973
25974 #ifndef cimg_use_visualcpp6
25975 CImgList<T>& assign_to(CImgList<T>& list) {
25976 return swap(list);
25977 }
25978 #endif
25979
25980 template<typename t> CImgList<T>& assign_to(CImgList<t>& list) {
25981 return list.assign(*this);
25982 }
25983
25985 static const char* pixel_type() {
25986 return cimg::type<T>::string();
25987 }
25988
25990 bool is_empty() const {
25991 return (!data || !size);
25992 }
25993
25994 operator bool() const {
25995 return !is_empty();
25996 }
25997
25999 bool contains(const int k) const {
26000 return data && k<(int)size;
26001 }
26002
26004 bool contains(const int k, const int x, const int y=0, const int z=0, const int v=0) const {
26005 return contains(k) && data[k].contains(x,y,z,v);
26006 }
26007
26009 template<typename t> bool contains(const T& pixel, t& l, t& x, t&y, t& z, t& v) const {
26010 const T *ptr = &pixel;
26011 cimglist_for(*this,i) if (data[i].contains(pixel,x,y,z,v)) { l = (t)i; return true; }
26012 return false;
26013 }
26014
26016 template<typename t> bool contains(const T& pixel, t& l, t& x, t&y, t& z) const {
26017 t v;
26018 return contains(pixel,l,x,y,z,v);
26019 }
26020
26022 template<typename t> bool contains(const T& pixel, t& l, t& x, t&y) const {
26023 t z,v;
26024 return contains(pixel,l,x,y,z,v);
26025 }
26026
26028 template<typename t> bool contains(const T& pixel, t& l, t& x) const {
26029 t y,z,v;
26030 return contains(pixel,l,x,y,z,v);
26031 }
26032
26034 template<typename t> bool contains(const T& pixel, t& l) const {
26035 t x,y,z,v;
26036 return contains(pixel,l,x,y,z,v);
26037 }
26038
26040 template<typename t> bool contains(const T& pixel) const {
26041 t l,x,y,z,v;
26042 return contains(pixel,l,x,y,z,v);
26043 }
26044
26046
26047
26049
26050
26051
26053 template<typename t> CImgList<T>& operator=(const CImgList<t>& list) {
26054 return assign(list);
26055 }
26056
26057 CImgList<T>& operator=(const CImgList<T>& list) {
26058 return assign(list);
26059 }
26060
26062 template<typename t> CImgList<T>& operator=(const CImg<t>& img) {
26063 cimglist_for(*this,l) data[l]=img;
26064 return *this;
26065 }
26066
26068 CImgList<T>& operator=(const T val) {
26069 cimglist_for(*this,l) data[l].fill(val);
26070 return *this;
26071 }
26072
26074 CImgList<T> operator+() const {
26075 return CImgList<T>(*this);
26076 }
26077
26079 #ifdef cimg_use_visualcpp6
26080 CImgList<T>& operator+=(const T val) {
26081 #else
26082 template<typename t> CImgList<T>& operator+=(const t val) {
26083 #endif
26084 cimglist_for(*this,l) (*this)[l]+=val;
26085 return *this;
26086 }
26087
26089 template<typename t> CImgList<T>& operator+=(const CImgList<t>& list) {
26090 const unsigned int sizemax = cimg::min(size,list.size);
26091 for (unsigned int l=0; l<sizemax; ++l) (*this)[l]+=list[l];
26092 return *this;
26093 }
26094
26096 CImgList<T>& operator++() {
26097 cimglist_for(*this,l) ++(*this)[l];
26098 return *this;
26099 }
26100
26102 CImgList<T> operator++(int) {
26103 CImgList<T> copy(*this);
26104 ++*this;
26105 return copy;
26106 }
26107
26109 CImgList<T> operator-() const {
26110 CImgList<T> res(size);
26111 cimglist_for(res,l) res[l].assign(-data[l]);
26112 return res;
26113 }
26114
26116 #ifdef cimg_use_visualcpp6
26117 CImgList<T>& operator-=(const T val) {
26118 #else
26119 template<typename t> CImgList<T>& operator-=(const t val) {
26120 #endif
26121 cimglist_for(*this,l) (*this)[l]-=val;
26122 return *this;
26123 }
26124
26126 template<typename t> CImgList<T>& operator-=(const CImgList<t>& list) {
26127 const unsigned int sizemax = min(size,list.size);
26128 for (unsigned int l=0; l<sizemax; ++l) (*this)[l]-=list[l];
26129 return *this;
26130 }
26131
26133 CImgList<T>& operator--() {
26134 cimglist_for(*this,l) --(*this)[l];
26135 return *this;
26136 }
26137
26139 CImgList<T> operator--(int) {
26140 CImgList<T> copy(*this);
26141 --*this;
26142 return copy;
26143 }
26144
26146 #ifdef cimg_use_visualcpp6
26147 CImgList<T>& operator*=(const double val) {
26148 #else
26149 template<typename t> CImgList<T>& operator*=(const t val) {
26150 #endif
26151 cimglist_for(*this,l) (*this)[l]*=val;
26152 return *this;
26153 }
26154
26156 template<typename t> CImgList<T>& operator*=(const CImgList<t>& list) {
26157 const unsigned int N = cimg::min(size,list.size);
26158 for (unsigned int l=0; l<N; ++l) (*this)[l]*=list[l];
26159 return this;
26160 }
26161
26163 #ifdef cimg_use_visualcpp6
26164 CImgList<T>& operator/=(const double val) {
26165 #else
26166 template<typename t> CImgList<T>& operator/=(const t val) {
26167 #endif
26168 cimglist_for(*this,l) (*this)[l]/=val;
26169 return *this;
26170 }
26171
26173 template<typename t> CImgList<T>& operator/=(const CImgList<t>& list) {
26174 const unsigned int N = cimg::min(size,list.size);
26175 for (unsigned int l=0; l<N; ++l) (*this)[l]/=list[l];
26176 return this;
26177 }
26178
26180 const T& max() const {
26181 if (is_empty()) throw CImgInstanceException("CImgList<%s>::max() : Instance image list is empty.",pixel_type());
26182 const T *ptrmax = data->data;
26183 T max_value = *ptrmax;
26184 cimglist_for(*this,l) {
26185 const CImg<T>& img = data[l];
26186 cimg_for(img,ptr,T) if ((*ptr)>max_value) max_value = *(ptrmax=ptr);
26187 }
26188 return *ptrmax;
26189 }
26190
26192 T& max() {
26193 if (is_empty()) throw CImgInstanceException("CImgList<%s>::max() : Instance image list is empty.",pixel_type());
26194 T *ptrmax = data->data;
26195 T max_value = *ptrmax;
26196 cimglist_for(*this,l) {
26197 const CImg<T>& img = data[l];
26198 cimg_for(img,ptr,T) if ((*ptr)>max_value) max_value = *(ptrmax=ptr);
26199 }
26200 return *ptrmax;
26201 }
26202
26204 const T& min() const {
26205 if (is_empty()) throw CImgInstanceException("CImgList<%s>::min() : Instance image list is empty.",pixel_type());
26206 const T *ptrmin = data->data;
26207 T min_value = *ptrmin;
26208 cimglist_for(*this,l) {
26209 const CImg<T>& img = data[l];
26210 cimg_for(img,ptr,T) if ((*ptr)<min_value) min_value = *(ptrmin=ptr);
26211 }
26212 return *ptrmin;
26213 }
26214
26216 T& min() {
26217 if (is_empty()) throw CImgInstanceException("CImgList<%s>::min() : Instance image list is empty.",pixel_type());
26218 T *ptrmin = data->data;
26219 T min_value = *ptrmin;
26220 cimglist_for(*this,l) {
26221 const CImg<T>& img = data[l];
26222 cimg_for(img,ptr,T) if ((*ptr)<min_value) min_value = *(ptrmin=ptr);
26223 }
26224 return *ptrmin;
26225 }
26226
26228 template<typename t> const T& minmax(t& max_val) const {
26229 if (is_empty()) throw CImgInstanceException("CImgList<%s>::minmax() : Instance image list is empty.",pixel_type());
26230 const T *ptrmin = data->data;
26231 T min_value = *ptrmin, max_value = min_value;
26232 cimglist_for(*this,l) {
26233 const CImg<T>& img = data[l];
26234 cimg_for(img,ptr,T) {
26235 const T val = *ptr;
26236 if (val<min_value) { min_value = val; ptrmin = ptr; }
26237 if (val>max_value) max_value = val;
26238 }
26239 }
26240 max_val = (t)max_value;
26241 return *ptrmin;
26242 }
26243
26245 template<typename t> T& minmax(t& max_val) {
26246 if (is_empty()) throw CImgInstanceException("CImgList<%s>::minmax() : Instance image list is empty.",pixel_type());
26247 T *ptrmin = data->data;
26248 T min_value = *ptrmin, max_value = min_value;
26249 cimglist_for(*this,l) {
26250 const CImg<T>& img = data[l];
26251 cimg_for(img,ptr,T) {
26252 const T val = *ptr;
26253 if (val<min_value) { min_value = val; ptrmin = ptr; }
26254 if (val>max_value) max_value = val;
26255 }
26256 }
26257 max_val = (t)max_value;
26258 return *ptrmin;
26259 }
26260
26262 template<typename t> const T& maxmin(t& min_val) const {
26263 if (is_empty()) throw CImgInstanceException("CImgList<%s>::maxmin() : Instance image list is empty.",pixel_type());
26264 const T *ptrmax = data->data;
26265 T min_value = *ptrmax, max_value = min_value;
26266 cimglist_for(*this,l) {
26267 const CImg<T>& img = data[l];
26268 cimg_for(img,ptr,T) {
26269 const T val = *ptr;
26270 if (val>max_value) { max_value = val; ptrmax = ptr; }
26271 if (val<min_value) min_value = val;
26272 }
26273 }
26274 min_val = (t)min_value;
26275 return *ptrmax;
26276 }
26277
26279 template<typename t> T& maxmin(t& min_val) {
26280 if (is_empty()) throw CImgInstanceException("CImgList<%s>::maxmin() : Instance image list is empty.",pixel_type());
26281 T *ptrmax = data->data;
26282 T min_value = *ptrmax, max_value = min_value;
26283 cimglist_for(*this,l) {
26284 const CImg<T>& img = data[l];
26285 cimg_for(img,ptr,T) {
26286 const T val = *ptr;
26287 if (val>max_value) { max_value = val; ptrmax = ptr; }
26288 if (val<min_value) min_value = val;
26289 }
26290 }
26291 min_val = (t)min_value;
26292 return *ptrmax;
26293 }
26294
26296 double mean() const {
26297 if (is_empty()) throw CImgInstanceException("CImgList<%s>::mean() : Instance image list is empty.",pixel_type());
26298 double val = 0;
26299 unsigned int siz = 0;
26300 cimglist_for(*this,l) {
26301 const CImg<T>& img = data[l];
26302 cimg_for(img,ptr,T) val+=(double)*ptr;
26303 siz+=img.size();
26304 }
26305 return val/siz;
26306 }
26307
26309 double variance() {
26310 if (is_empty())
26311 throw CImgInstanceException("CImgList<%s>::variance() : Instance image list is empty.",pixel_type());
26312 double res = 0;
26313 unsigned int siz = 0;
26314 double S = 0, S2 = 0;
26315 cimglist_for(*this,l) {
26316 const CImg<T>& img = data[l];
26317 cimg_for(img,ptr,T) { const double val = (double)*ptr; S+=val; S2+=val*val; }
26318 siz+=img.size();
26319 }
26320 res = (S2 - S*S/siz)/siz;
26321 return res;
26322 }
26323
26325
26326
26328
26329
26330
26332 CImg<T>& operator[](const unsigned int pos) {
26333 #if cimg_debug>=3
26334 if (pos>=size) {
26335 cimg::warn("CImgList<%s>::operator[] : bad list position %u, in a list of %u images",pixel_type(),pos,size);
26336 return *data;
26337 }
26338 #endif
26339 return data[pos];
26340 }
26341
26342 const CImg<T>& operator[](const unsigned int pos) const {
26343 #if cimg_debug>=3
26344 if (pos>=size) {
26345 cimg::warn("CImgList<%s>::operator[] : bad list position %u, in a list of %u images",pixel_type(),pos,size);
26346 return *data;
26347 }
26348 #endif
26349 return data[pos];
26350 }
26351
26353 CImg<T>& operator()(const unsigned int pos) {
26354 return (*this)[pos];
26355 }
26356
26357 const CImg<T>& operator()(const unsigned int pos) const {
26358 return (*this)[pos];
26359 }
26360
26362 T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0,
26363 const unsigned int z=0, const unsigned int v=0) {
26364 return (*this)[pos](x,y,z,v);
26365 }
26366 const T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0,
26367 const unsigned int z=0, const unsigned int v=0) const {
26368 return (*this)[pos](x,y,z,v);
26369 }
26370
26372 CImg<T>& at(const unsigned int pos) {
26373 if (pos>=size)
26374 throw CImgArgumentException("CImgList<%s>::at() : bad list position %u, in a list of %u images",
26375 pixel_type(),pos,size);
26376 return data[pos];
26377 }
26378
26379 const CImg<T>& at(const unsigned int pos) const {
26380 if (pos>=size)
26381 throw CImgArgumentException("CImgList<%s>::at() : bad list position %u, in a list of %u images",
26382 pixel_type(),pos,size);
26383 return data[pos];
26384 }
26385
26387 CImg<T>& back() {
26388 return (*this)(size-1);
26389 }
26390
26391 const CImg<T>& back() const {
26392 return (*this)(size-1);
26393 }
26394
26396 CImg<T>& front() {
26397 return *data;
26398 }
26399
26400 const CImg<T>& front() const {
26401 return *data;
26402 }
26403
26405 iterator begin() {
26406 return data;
26407 }
26408
26409 const_iterator begin() const {
26410 return data;
26411 }
26412
26414 iterator end() {
26415 return data + size;
26416 }
26417
26418 const_iterator end() const {
26419 return data + size;
26420 }
26421
26423 template<typename t> CImgList<typename cimg::superset<T,t>::type>
26424 get_insert(const CImg<t>& img, const unsigned int pos=~0U, const bool shared=false) const {
26425 typedef typename cimg::superset<T,t>::type restype;
26426 return CImgList<restype>(*this).insert(img,pos,shared);
26427 }
26428
26430 template<typename t> CImgList<T>& insert(const CImg<t>& img, const unsigned int pos, const bool shared) {
26431 const unsigned int npos = pos==~0U?size:pos;
26432 if (npos>size)
26433 throw CImgArgumentException("CImgList<%s>::insert() : Cannot insert at position %u into a list with %u elements",
26434 pixel_type(),npos,size);
26435 if (shared)
26436 throw CImgArgumentException("CImgList<%s>::insert(): Cannot insert a shared image CImg<%s> into a CImgList<%s>",
26437 pixel_type(),img.pixel_type(),pixel_type());
26438 CImg<T> *new_data = (++size>allocsize)?new CImg<T>[allocsize?(allocsize<<=1):(allocsize=1)]:0;
26439 if (!size || !data) {
26440 data = new_data;
26441 *data = img;
26442 } else {
26443 if (new_data) {
26444 if (npos) std::memcpy(new_data,data,sizeof(CImg<T>)*npos);
26445 if (npos!=size-1) std::memcpy(new_data+npos+1,data+npos,sizeof(CImg<T>)*(size-1-npos));
26446 std::memset(data,0,sizeof(CImg<T>)*(size-1));
26447 delete[] data;
26448 data = new_data;
26449 }
26450 else if (npos!=size-1) std::memmove(data+npos+1,data+npos,sizeof(CImg<T>)*(size-1-npos));
26451 data[npos].width = data[npos].height = data[npos].depth = data[npos].dim = 0; data[npos].data = 0;
26452 data[npos] = img;
26453 }
26454 return *this;
26455 }
26456
26457 CImgList<T>& insert(const CImg<T>& img, const unsigned int pos, const bool shared) {
26458 const unsigned int npos = pos==~0U?size:pos;
26459 if (npos>size)
26460 throw CImgArgumentException("CImgList<%s>::insert() : Can't insert at position %u into a list with %u elements",
26461 pixel_type(),npos,size);
26462 CImg<T> *new_data = (++size>allocsize)?new CImg<T>[allocsize?(allocsize<<=1):(allocsize=1)]:0;
26463 if (!size || !data) {
26464 data = new_data;
26465 if (shared && img) {
26466 data->width = img.width; data->height = img.height; data->depth = img.depth; data->dim = img.dim;
26467 data->is_shared = true; data->data = img.data;
26468 } else *data = img;
26469 }
26470 else {
26471 if (new_data) {
26472 if (npos) std::memcpy(new_data,data,sizeof(CImg<T>)*npos);
26473 if (npos!=size-1) std::memcpy(new_data+npos+1,data+npos,sizeof(CImg<T>)*(size-1-npos));
26474 if (shared && img) {
26475 new_data[npos].width = img.width; new_data[npos].height = img.height; new_data[npos].depth = img.depth;
26476 new_data[npos].dim = img.dim; new_data[npos].is_shared = true; new_data[npos].data = img.data;
26477 } else {
26478 new_data[npos].width = new_data[npos].height = new_data[npos].depth = new_data[npos].dim = 0; new_data[npos].data = 0;
26479 new_data[npos] = img;
26480 }
26481 std::memset(data,0,sizeof(CImg<T>)*(size-1));
26482 delete[] data;
26483 data = new_data;
26484 } else {
26485 if (npos!=size-1) std::memmove(data+npos+1,data+npos,sizeof(CImg<T>)*(size-1-npos));
26486 if (shared && img) {
26487 data[npos].width = img.width; data[npos].height = img.height; data[npos].depth = img.depth; data[npos].dim = img.dim;
26488 data[npos].is_shared = true; data[npos].data = img.data;
26489 } else {
26490 data[npos].width = data[npos].height = data[npos].depth = data[npos].dim = 0; data[npos].data = 0;
26491 data[npos] = img;
26492 }
26493 }
26494 }
26495 return *this;
26496 }
26497
26498
26499
26500 template<typename t> CImgList<T>& insert(const CImg<t>& img, const unsigned int pos) {
26501 return insert(img,pos,false);
26502 }
26503
26505 template<typename t> CImgList<T>& insert(const CImg<t>& img) {
26506 return insert(img,~0U,false);
26507 }
26508
26510 template<typename t> CImgList<typename cimg::superset<T,t>::type>
26511 get_insert(const unsigned int n, const CImg<t>& img, const unsigned int pos=~0U, const bool shared=false) const {
26512 typedef typename cimg::superset<T,t>::type restype;
26513 return CImgList<restype>(*this).insert(n,img,pos,shared);
26514 }
26515
26517 template<typename t> CImgList<T>& insert(const unsigned int n, const CImg<t>& img, const unsigned int pos=~0U, const bool shared=false) {
26518 const unsigned int npos = pos==~0U?size:pos;
26519 insert(img,npos,shared);
26520 for (unsigned int i=1; i<n; ++i) insert(data[npos],npos+i,shared);
26521 return *this;
26522 }
26523
26525 template<typename t> CImgList<typename cimg::superset<T,t>::type>
26526 get_insert(const CImgList<t>& list, const unsigned int pos=~0U, int shared=0) const {
26527 typedef typename cimg::superset<T,t>::type restype;
26528 return CImgList<restype>(*this).insert(list,pos,shared);
26529 }
26530
26532 template<typename t> CImgList<T>& insert(const CImgList<t>& list, const unsigned int pos=~0U, const int shared=0) {
26533 const unsigned int npos = pos==~0U?size:pos;
26534 if ((void*)this!=(void*)&list) {
26535 if (shared>=0) cimglist_for(list,l) insert(list[l],npos+l,shared?true:false);
26536 else cimglist_for(list,l) insert(list[l],npos+l,list[l].is_shared);
26537 } else insert(CImgList<T>(list),npos,shared);
26538 return *this;
26539 }
26540
26542 template<typename t> CImgList<typename cimg::superset<T,t>::type>
26543 get_insert(const unsigned int n, const CImgList<t>& list, const unsigned int pos=~0U, const int shared=0) const {
26544 typedef typename cimg::superset<T,t>::type restype;
26545 return CImgList<restype>(*this).insert(n,list,pos,shared);
26546 }
26547
26549 template<typename t> CImgList<T>& insert(const unsigned int n, const CImgList<t>& list, const unsigned int pos=~0U, const int shared=0) {
26550 const unsigned int npos = pos==~0U?size:pos;
26551 for (unsigned int i=0; i<n; ++i) insert(list,npos,shared);
26552 return *this;
26553 }
26554
26556 CImgList<T> get_remove(const unsigned int pos1, const unsigned int pos2) const {
26557 return (+*this).remove(pos1,pos2);
26558 }
26559
26561 CImgList<T>& remove(const unsigned int pos1, const unsigned int pos2) {
26562 const unsigned int
26563 npos1 = pos1<pos2?pos1:pos2,
26564 tpos2 = pos1<pos2?pos2:pos1,
26565 npos2 = tpos2<size?tpos2:size-1;
26566 if (npos1>=size)
26567 cimg::warn("CImgList<%s>::remove() : Cannot remove images from a list (%p,%u), at positions %u->%u.",
26568 pixel_type(),data,size,npos1,tpos2);
26569 else {
26570 if (tpos2>=size)
26571 cimg::warn("CImgList<%s>::remove() : Cannot remove all images from a list (%p,%u), at positions %u->%u.",
26572 pixel_type(),data,size,npos1,tpos2);
26573 for (unsigned int k = npos1; k<=npos2; ++k) data[k].assign();
26574 const unsigned int nb = 1 + npos2 - npos1;
26575 if (!(size-=nb)) return assign();
26576 if (size>(allocsize>>2) || allocsize<=8) {
26577 if (npos1!=size) std::memmove(data+npos1,data+npos2+1,sizeof(CImg<T>)*(size-npos1));
26578 std::memset(data+size,0,sizeof(CImg<T>)*nb);
26579 } else {
26580 allocsize>>=2;
26581 while (allocsize>8 && size<(allocsize>>1)) allocsize>>=1;
26582 CImg<T> *new_data = new CImg<T>[allocsize];
26583 if (npos1) std::memcpy(new_data,data,sizeof(CImg<T>)*npos1);
26584 if (npos1!=size) std::memcpy(new_data+npos1,data+npos2+1,sizeof(CImg<T>)*(size-npos1));
26585 if (size!=allocsize) std::memset(new_data+size,0,sizeof(allocsize-size));
26586 std::memset(data,0,sizeof(CImg<T>)*(size+nb));
26587 delete[] data;
26588 data = new_data;
26589 }
26590 }
26591 return *this;
26592 }
26593
26595 CImgList<T> get_remove(const unsigned int pos) const {
26596 return (+*this).remove(pos);
26597 }
26598
26600 CImgList<T>& remove(const unsigned int pos) {
26601 return remove(pos,pos);
26602 }
26603
26605 CImgList<T> get_remove() const {
26606 return (+*this).remove();
26607 }
26608
26610 CImgList<T>& remove() {
26611 if (size) return remove(size-1);
26612 else cimg::warn("CImgList<%s>::remove() : List is empty",pixel_type());
26613 return *this;
26614 }
26615
26617 CImgList<T> get_reverse() const {
26618 return (+*this).reverse();
26619 }
26620
26622 CImgList<T>& reverse() {
26623 for (unsigned int l=0; l<size/2; ++l) (*this)[l].swap((*this)[size-1-l]);
26624 return *this;
26625 }
26626
26628 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1, const bool shared=false) const {
26629 if (i0>i1 || i1>=size)
26630 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26631 pixel_type(),i0,i1,size,data);
26632 CImgList<T> res(i1-i0+1);
26633 cimglist_for(res,l) res[l].assign((*this)[i0+l],shared);
26634 return res;
26635 }
26636
26638 CImgList<T>& crop(const unsigned int i0, const unsigned int i1, const bool shared=false) {
26639 return get_crop(i0,i1,shared).assign_to(*this);
26640 }
26641
26643 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1,
26644 const int x0, const int y0, const int z0, const int v0,
26645 const int x1, const int y1, const int z1, const int v1) const {
26646 if (i0>i1 || i1>=size)
26647 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26648 pixel_type(),i0,i1,size,data);
26649 CImgList<T> res(i1-i0+1);
26650 cimglist_for(res,l) res[l] = (*this)[i0+l].get_crop(x0,y0,z0,v0,x1,y1,z1,v1);
26651 return res;
26652 }
26653
26655 CImgList<T>& crop(const unsigned int i0, const unsigned int i1,
26656 const int x0, const int y0, const int z0, const int v0,
26657 const int x1, const int y1, const int z1, const int v1) {
26658 return get_crop(i0,i1,x0,y0,z0,v0,x1,y1,z1,v1).assign_to(*this);
26659 }
26660
26662 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1,
26663 const int x0, const int y0, const int z0,
26664 const int x1, const int y1, const int z1) const {
26665 if (i0>i1 || i1>=size)
26666 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26667 pixel_type(),i0,i1,size,data);
26668 CImgList<T> res(i1-i0+1);
26669 cimglist_for(res,l) res[l] = (*this)[i0+l].get_crop(x0,y0,z0,x1,y1,z1);
26670 return res;
26671 }
26672
26674 CImgList<T>& crop(const unsigned int i0, const unsigned int i1,
26675 const int x0, const int y0, const int z0,
26676 const int x1, const int y1, const int z1) {
26677 return get_crop(i0,i1,x0,y0,z0,x1,y1,z1).assign_to(*this);
26678 }
26679
26681 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1,
26682 const int x0, const int y0,
26683 const int x1, const int y1) const {
26684 if (i0>i1 || i1>=size)
26685 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26686 pixel_type(),i0,i1,size,data);
26687 CImgList<T> res(i1-i0+1);
26688 cimglist_for(res,l) res[l] = (*this)[i0+l].get_crop(x0,y0,x1,y1);
26689 return res;
26690 }
26691
26693 CImgList<T>& crop(const unsigned int i0, const unsigned int i1,
26694 const int x0, const int y0,
26695 const int x1, const int y1) {
26696 return get_crop(i0,i1,x0,y0,x1,y1).assign_to(*this);
26697 }
26698
26700 CImgList<T> get_crop(const unsigned int i0, const unsigned int i1,
26701 const int x0, const int x1) const {
26702 if (i0>i1 || i1>=size)
26703 throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)",
26704 pixel_type(),i0,i1,size,data);
26705 CImgList<T> res(i1-i0+1);
26706 cimglist_for(res,l) res[l] = (*this)[i0+l].get_crop(x0,x1);
26707 return res;
26708 }
26709
26711 CImgList<T>& crop(const unsigned int i0, const unsigned int i1,
26712 const int x0, const int x1) {
26713 return get_crop(i0,i1,x0,x1).assign_to(*this);
26714 }
26715
26717 template<typename t> CImgList<T>& operator<<(const CImg<t>& img) {
26718 return insert(img);
26719 }
26720
26722 template<typename t> CImgList<T>& operator<<(const CImgList<t>& list) {
26723 return insert(list);
26724 }
26725
26727 template<typename t> CImgList<T>& operator>>(CImg<t>& img) const {
26728 typedef typename cimg::superset<T,t>::type restype;
26729 return CImgList<restype>(*this).insert(img);
26730 }
26731
26733 template<typename t> CImgList<T>& operator>>(CImgList<t>& list) const {
26734 return list.insert(*this,0);
26735 }
26736
26738 const CImgList<T>& operator>>(CImgDisplay& disp) const {
26739 return display(disp);
26740 }
26741
26743 template<typename t> CImgList<T>& push_back(const CImg<t>& img) {
26744 return insert(img);
26745 }
26746
26748 template<typename t> CImgList<T>& push_front(const CImg<t>& img) {
26749 return insert(img,0);
26750 }
26751
26753 template<typename t> CImgList<T>& push_back(const CImgList<t>& list) {
26754 return insert(list);
26755 }
26756
26758 template<typename t> CImgList<T>& push_front(const CImgList<t>& list) {
26759 return insert(list,0);
26760 }
26761
26763 CImgList<T>& pop_back() {
26764 return remove(size-1);
26765 }
26766
26768 CImgList<T>& pop_front() {
26769 return remove(0);
26770 }
26771
26773 CImgList<T>& erase(const iterator iter) {
26774 return remove(iter-data);
26775 }
26776
26778
26779
26781
26782
26783
26785 CImgList<typename cimg::superset<T,float>::type> get_FFT(const char axe, const bool inverse=false) const {
26786 typedef typename cimg::superset<T,float>::type restype;
26787 return CImgList<restype>(*this).FFT(axe,inverse);
26788 }
26789
26791 CImgList<T>& FFT(const char axe, const bool inverse=false) {
26792 if (is_empty()) throw CImgInstanceException("CImgList<%s>::FFT() : Instance list (%u,%p) is empty",pixel_type(),size,data);
26793 if (!data[0]) throw CImgInstanceException("CImgList<%s>::FFT() : Real part (%u,%u,%u,%u,%p) is empty",
26794 pixel_type(),data[0].width,data[0].height,data[0].depth,data[0].dim,data[0].data);
26795 if (size>2) cimg::warn("CImgList<%s>::FFT() : Instance list (%u,%p) have more than 2 images",pixel_type(),size,data);
26796 if (size==1) insert(CImg<T>(data[0].width,data[0].height,data[0].depth,data[0].dim,0));
26797 CImg<T> &Ir = data[0], &Ii = data[1];
26798 if (Ir.width!=Ii.width || Ir.height!=Ii.height || Ir.depth!=Ii.depth || Ir.dim!=Ii.dim)
26799 throw CImgInstanceException("CImgList<%s>::FFT() : Real part (%u,%u,%u,%u,%p) and imaginary part (%u,%u,%u,%u,%p)"
26800 "have different dimensions",pixel_type(),
26801 Ir.width,Ir.height,Ir.depth,Ir.dim,Ir.data,Ii.width,Ii.height,Ii.depth,Ii.dim,Ii.data);
26802
26803 #ifdef cimg_use_fftw3
26804 fftw_complex *data_in;
26805 fftw_plan data_plan;
26806
26807 switch (cimg::uncase(axe)) {
26808 case 'x': {
26809 data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.width);
26810 data_plan = fftw_plan_dft_1d(Ir.width, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
26811 cimg_forYZV(Ir,y,z,k) {
26812 T *ptrr = Ir.ptr(0,y,z,k), *ptri = Ii.ptr(0,y,z,k);
26813 double *ptrd = (double*)data_in;
26814 cimg_forX(Ir,x) { *(ptrd++) = (double)*(ptrr++); *(ptrd++) = (double)*(ptri++); }
26815 fftw_execute(data_plan);
26816 { cimg_forX(Ir,x) { *(--ptri) = (T)*(--ptrd); *(--ptrr) = (T)*(--ptrd); }}
26817 }
26818 } break;
26819
26820 case 'y': {
26821 data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.height);
26822 data_plan = fftw_plan_dft_1d(Ir.height, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
26823 const unsigned int off = Ir.width;
26824 cimg_forXZV(Ir,x,z,k) {
26825 T *ptrr = Ir.ptr(x,0,z,k), *ptri = Ii.ptr(x,0,z,k);
26826 double *ptrd = (double*)data_in;
26827 cimg_forY(Ir,y) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; }
26828 fftw_execute(data_plan);
26829 { cimg_forY(Ir,y) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }}
26830 }
26831 } break;
26832
26833 case 'z': {
26834 data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.depth);
26835 data_plan = fftw_plan_dft_1d(Ir.depth, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
26836 const unsigned int off = Ir.width*Ir.height;
26837 cimg_forXYV(Ir,x,y,k) {
26838 T *ptrr = Ir.ptr(x,y,0,k), *ptri = Ii.ptr(x,y,0,k);
26839 double *ptrd = (double*)data_in;
26840 cimg_forZ(Ir,z) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; }
26841 fftw_execute(data_plan);
26842 { cimg_forZ(Ir,z) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }}
26843 }
26844 } break;
26845
26846 case 'v': {
26847 data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.dim);
26848 data_plan = fftw_plan_dft_1d(Ir.dim, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
26849 const unsigned int off = Ir.width*Ir.height*Ir.depth;
26850 cimg_forXYZ(Ir,x,y,z) {
26851 T *ptrr = Ir.ptr(x,y,z,0), *ptri = Ii.ptr(x,y,z,0);
26852 double *ptrd = (double*)data_in;
26853 cimg_forV(Ir,k) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; }
26854 fftw_execute(data_plan);
26855 { cimg_forV(Ir,k) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }}
26856 }
26857 } break;
26858 }
26859
26860 fftw_destroy_plan(data_plan);
26861 fftw_free(data_in);
26862 #else
26863 switch (cimg::uncase(axe)) {
26864 case 'x': {
26865 const unsigned int N = Ir.width, N2 = (N>>1);
26866 if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image along 'x' is %d != 2^N",
26867 pixel_type(),N);
26868 for (unsigned int i=0, j=0; i<N2; ++i) {
26869 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));
26870 if (j<N2) {
26871 const unsigned int ri = N-1-i, rj = N-1-j;
26872 cimg::swap(Ir(ri,y,z,v),Ir(rj,y,z,v)); cimg::swap(Ii(ri,y,z,v),Ii(rj,y,z,v));
26873 }}
26874 for (unsigned int m=N, n=N2; (j+=n)>=m; j-=m, m=n, n>>=1);
26875 }
26876 for (unsigned int delta=2; delta<=N; delta<<=1) {
26877 const unsigned int delta2 = (delta>>1);
26878 for (unsigned int i=0; i<N; i+=delta) {
26879 float wr = 1, wi = 0;
26880 const float angle = (float)((inverse?+1:-1)*2*cimg::PI/delta),
26881 ca = (float)std::cos(angle),
26882 sa = (float)std::sin(angle);
26883 for (unsigned int k=0; k<delta2; ++k) {
26884 const unsigned int j = i + k, nj = j + delta2;
26885 cimg_forYZV(Ir,y,z,k) {
26886 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);
26887 const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
26888 nir = (T)(ir - tmpr);
26889 nii = (T)(ii - tmpi);
26890 ir += (T)tmpr;
26891 ii += (T)tmpi;
26892 }
26893 const float nwr = wr*ca-wi*sa;
26894 wi = wi*ca + wr*sa;
26895 wr = nwr;
26896 }
26897 }
26898 }
26899 if (inverse) (*this)/=N;
26900 } break;
26901
26902 case 'y': {
26903 const unsigned int N = Ir.height, N2 = (N>>1);
26904 if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image(s) along 'y' is %d != 2^N",
26905 pixel_type(),N);
26906 for (unsigned int i=0, j=0; i<N2; ++i) {
26907 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));
26908 if (j<N2) {
26909 const unsigned int ri = N-1-i, rj = N-1-j;
26910 cimg::swap(Ir(x,ri,z,v),Ir(x,rj,z,v)); cimg::swap(Ii(x,ri,z,v),Ii(x,rj,z,v));
26911 }}
26912 for (unsigned int m=N, n=N2; (j+=n)>=m; j-=m, m=n, n>>=1);
26913 }
26914 for (unsigned int delta=2; delta<=N; delta<<=1) {
26915 const unsigned int delta2 = (delta>>1);
26916 for (unsigned int i=0; i<N; i+=delta) {
26917 float wr = 1, wi = 0;
26918 const float angle = (float)((inverse?+1:-1)*2*cimg::PI/delta),
26919 ca = (float)std::cos(angle), sa = (float)std::sin(angle);
26920 for (unsigned int k=0; k<delta2; ++k) {
26921 const unsigned int j = i + k, nj = j + delta2;
26922 cimg_forXZV(Ir,x,z,k) {
26923 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);
26924 const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
26925 nir = (T)(ir - tmpr);
26926 nii = (T)(ii - tmpi);
26927 ir += (T)tmpr;
26928 ii += (T)tmpi;
26929 }
26930 const float nwr = wr*ca-wi*sa;
26931 wi = wi*ca + wr*sa;
26932 wr = nwr;
26933 }
26934 }
26935 }
26936 if (inverse) (*this)/=N;
26937 } break;
26938
26939 case 'z': {
26940 const unsigned int N = Ir.depth, N2 = (N>>1);
26941 if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image(s) along 'z' is %d != 2^N",
26942 pixel_type(),N);
26943 for (unsigned int i=0, j=0; i<N2; ++i) {
26944 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));
26945 if (j<N2) {
26946 const unsigned int ri = N-1-i, rj = N-1-j;
26947 cimg::swap(Ir(x,y,ri,v),Ir(x,y,rj,v)); cimg::swap(Ii(x,y,ri,v),Ii(x,y,rj,v));
26948 }}
26949 for (unsigned int m=N, n=N2; (j+=n)>=m; j-=m, m=n, n>>=1);
26950 }
26951 for (unsigned int delta=2; delta<=N; delta<<=1) {
26952 const unsigned int delta2 = (delta>>1);
26953 for (unsigned int i=0; i<N; i+=delta) {
26954 float wr = 1, wi = 0;
26955 const float angle = (float)((inverse?+1:-1)*2*cimg::PI/delta),
26956 ca = (float)std::cos(angle), sa = (float)std::sin(angle);
26957 for (unsigned int k=0; k<delta2; ++k) {
26958 const unsigned int j = i + k, nj = j + delta2;
26959 cimg_forXYV(Ir,x,y,k) {
26960 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);
26961 const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
26962 nir = (T)(ir - tmpr);
26963 nii = (T)(ii - tmpi);
26964 ir += (T)tmpr;
26965 ii += (T)tmpi;
26966 }
26967 const float nwr = wr*ca-wi*sa;
26968 wi = wi*ca + wr*sa;
26969 wr = nwr;
26970 }
26971 }
26972 }
26973 if (inverse) (*this)/=N;
26974 } break;
26975
26976 default: throw CImgArgumentException("CImgList<%s>::FFT() : unknown axe '%c', must be 'x','y' or 'z'");
26977 }
26978 #endif
26979 return *this;
26980 }
26981
26983 CImgList<typename cimg::superset<T,float>::type> get_FFT(const bool inverse=false) const {
26984 typedef typename cimg::superset<T,float>::type restype;
26985 return CImgList<restype>(*this).FFT(inverse);
26986 }
26987
26989 CImgList<T>& FFT(const bool inverse=false) {
26990 if (is_empty()) throw CImgInstanceException("CImgList<%s>::FFT() : Instance list (%u,%p) is empty",pixel_type(),size,data);
26991 if (size>2) cimg::warn("CImgList<%s>::FFT() : Instance list (%u,%p) have more than 2 images",pixel_type(),size,data);
26992 if (size==1) insert(CImg<T>(data->width,data->height,data->depth,data->dim,0));
26993 CImg<T> &Ir = data[0], &Ii = data[1];
26994 if (Ii.width!=Ir.width || Ii.height!=Ir.height || Ii.depth!=Ir.depth || Ii.dim!=Ir.dim)
26995 throw CImgInstanceException("CImgList<%s>::FFT() : Real (%u,%u,%u,%u,%p) and Imaginary (%u,%u,%u,%u,%p) parts "
26996 "of the instance image have different dimensions",
26997 pixel_type(),Ir.width,Ir.height,Ir.depth,Ir.dim,Ir.data,
26998 Ii.width,Ii.height,Ii.depth,Ii.dim,Ii.data);
26999 #ifdef cimg_use_fftw3
27000 fftw_complex *data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.width*Ir.height*Ir.depth);
27001 fftw_plan data_plan;
27002 const unsigned int w = Ir.width, wh = w*Ir.height, whd = wh*Ir.depth;
27003 data_plan = fftw_plan_dft_3d(Ir.width, Ir.height, Ir.depth, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
27004 cimg_forV(Ir,k) {
27005 T *ptrr = Ir.ptr(0,0,0,k), *ptri = Ii.ptr(0,0,0,k);
27006 double *ptrd = (double*)data_in;
27007 cimg_forX(Ir,x) {
27008 cimg_forY(Ir,y) {
27009 cimg_forZ(Ir,z) {
27010 *(ptrd++) = (double)*ptrr;
27011 *(ptrd++) = (double)*ptri;
27012 ptrr+=wh;
27013 ptri+=wh;
27014 }
27015 ptrr-=whd-w;
27016 ptri-=whd-w;
27017 }
27018 ptrr-=wh-1;
27019 ptri-=wh-1;
27020 }
27021 fftw_execute(data_plan);
27022 ptrd = (double*)data_in;
27023 ptrr = Ir.ptr(0,0,0,k);
27024 ptri = Ii.ptr(0,0,0,k);
27025 { cimg_forX(Ir,x) {
27026 cimg_forY(Ir,y) {
27027 cimg_forZ(Ir,z) {
27028 *ptrr = (T)*(ptrd++);
27029 *ptri = (T)*(ptrd++);
27030 ptrr+=wh;
27031 ptri+=wh;
27032 }
27033 ptrr-=whd-w;
27034 ptri-=whd-w;
27035 }
27036 ptrr-=wh-1;
27037 ptri-=wh-1;
27038 }}
27039 }
27040 fftw_destroy_plan(data_plan);
27041 fftw_free(data_in);
27042 #else
27043 if (Ir.depth>1) FFT('z',inverse);
27044 if (Ir.height>1) FFT('y',inverse);
27045 if (Ir.width>1) FFT('x',inverse);
27046 #endif
27047 return *this;
27048 }
27049
27051
27052
27054
27055
27056
27058 const CImgList<T>& print(const char* title=0, const int print_flag=1) const {
27059 if (print_flag>=0) {
27060 char tmp[1024];
27061 std::fprintf(stderr,"%-8s(this=%p) : { size=%u, data=%p }\n",title?title:"CImgList",
27062 (void*)this,size,(void*)data);
27063 switch (print_flag) {
27064 case 1: {
27065 cimglist_for(*this,l)
27066 if (l<4 || l>=size-4) {
27067 std::sprintf(tmp,"%s[%d]",title?title:"CImgList",l);
27068 data[l].print(tmp,print_flag);
27069 } else {
27070 if (l==4) std::fprintf(stderr,"...\n");
27071 }
27072 } break;
27073 default: {
27074 cimglist_for(*this,l) {
27075 std::sprintf(tmp,"%s[%d]",title?title:"CImgList",l);
27076 data[l].print(tmp,print_flag);
27077 }
27078 } break;
27079 }
27080 }
27081 return *this;
27082 }
27083
27085 const CImgList<T>& print(const int print_flag) const {
27086 return print(0,print_flag);
27087 }
27088
27090 static CImgList<T> get_load(const char *const filename) {
27091 return CImgList<T>().load(filename);
27092 }
27093
27095 CImgList<T>& load(const char *const filename) {
27096 const char *ext = cimg::filename_split(filename);
27097 #ifdef cimglist_load_plugin
27098 cimglist_load_plugin(filename);
27099 #endif
27100 #ifdef cimglist_load_plugin1
27101 cimglist_load_plugin1(filename);
27102 #endif
27103 #ifdef cimglist_load_plugin2
27104 cimglist_load_plugin2(filename);
27105 #endif
27106 #ifdef cimglist_load_plugin3
27107 cimglist_load_plugin3(filename);
27108 #endif
27109 #ifdef cimglist_load_plugin4
27110 cimglist_load_plugin4(filename);
27111 #endif
27112 #ifdef cimglist_load_plugin5
27113 cimglist_load_plugin5(filename);
27114 #endif
27115 #ifdef cimglist_load_plugin6
27116 cimglist_load_plugin6(filename);
27117 #endif
27118 #ifdef cimglist_load_plugin7
27119 cimglist_load_plugin7(filename);
27120 #endif
27121 #ifdef cimglist_load_plugin8
27122 cimglist_load_plugin8(filename);
27123 #endif
27124 if (!cimg::strncasecmp(ext,"cimg",4) || !ext[0]) return load_cimg(filename);
27125 if (!cimg::strncasecmp(ext,"rec",3) ||
27126 !cimg::strncasecmp(ext,"par",3)) return load_parrec(filename);
27127 assign(1);
27128 data->load(filename);
27129 return *this;
27130 }
27131
27133 static CImgList<T> get_load_cimg(std::FILE *const file, const char *const filename=0) {
27134 return CImgList<T>().load_cimg(file,filename);
27135 }
27136
27138 CImgList<T>& load_cimg(std::FILE *const file, const char *const filename=0) {
27139 #define cimg_load_cimg_case(Ts,Tss) \
27140 if (!loaded && !cimg::strcasecmp(Ts,str_pixeltype)) { \
27141 for (unsigned int l=0; l<N; ++l) { \
27142 j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++] = (char)i; tmp[j] = '\0'; \
27143 W = H = D = V = 0; \
27144 if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) \
27145 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", \
27146 pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); \
27147 if (W*H*D*V>0) { \
27148 CImg<Tss> raw; \
27149 CImg<T> &img = data[l]; \
27150 img.assign(W,H,D,V); \
27151 T *ptrd = img.data; \
27152 for (int toread = (int)img.size(); toread>0; ) { \
27153 raw.assign(cimg::min(toread,cimg_iobuffer)); \
27154 cimg::fread(raw.data,raw.width,nfile); \
27155 if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); \
27156 toread-=raw.width; \
27157 const Tss *ptrs = raw.data; \
27158 for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); \
27159 } \
27160 } \
27161 } \
27162 loaded = true; \
27163 }
27164 typedef unsigned char uchar;
27165 typedef unsigned short ushort;
27166 typedef unsigned int uint;
27167 typedef unsigned long ulong;
27168 const int cimg_iobuffer = 12*1024*1024;
27169 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
27170 bool loaded = false, endian = cimg::endian();
27171 char tmp[256], str_pixeltype[256], str_endian[256];
27172 unsigned int j, err, N=0, W, H, D, V;
27173 int i;
27174 j = 0; while((i=std::fgetc(nfile))!='\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = '\0';
27175 err = std::sscanf(tmp,"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian);
27176 if (err<2) {
27177 if (!file) cimg::fclose(nfile);
27178 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Unknow CImg RAW header.",
27179 pixel_type(),filename?filename:"(FILE*)");
27180 }
27181 if (!cimg::strncasecmp("little",str_endian,6)) endian = false;
27182 else if (!cimg::strncasecmp("big",str_endian,3)) endian = true;
27183 assign(N);
27184 cimg_load_cimg_case("bool",bool);
27185 cimg_load_cimg_case("unsigned_char",uchar);
27186 cimg_load_cimg_case("uchar",uchar);
27187 cimg_load_cimg_case("char",char);
27188 cimg_load_cimg_case("unsigned_short",ushort);
27189 cimg_load_cimg_case("ushort",ushort);
27190 cimg_load_cimg_case("short",short);
27191 cimg_load_cimg_case("unsigned_int",uint);
27192 cimg_load_cimg_case("uint",uint);
27193 cimg_load_cimg_case("int",int);
27194 cimg_load_cimg_case("unsigned_long",ulong);
27195 cimg_load_cimg_case("ulong",ulong);
27196 cimg_load_cimg_case("long",long);
27197 cimg_load_cimg_case("float",float);
27198 cimg_load_cimg_case("double",double);
27199 if (!loaded) {
27200 if (!file) cimg::fclose(nfile);
27201 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', cannot read images of pixels coded as '%s'.",
27202 pixel_type(),filename?filename:"(FILE*)",str_pixeltype);
27203 }
27204 if (!file) cimg::fclose(nfile);
27205 return *this;
27206 }
27207
27209 static CImgList<T> get_load_cimg(const char *const filename) {
27210 return CImgList<T>().load_cimg(0,filename);
27211 }
27212
27214 CImgList<T>& load_cimg(const char *const filename) {
27215 return load_cimg(0,filename);
27216 }
27217
27219 static CImgList<T> get_load_cimg(std::FILE *const file,
27220 const unsigned int n0, const unsigned int n1,
27221 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27222 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27223 return CImgList<T>().load_cimg(file,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27224 }
27225
27227 CImgList<T>& load_cimg(std::FILE *const file,
27228 const unsigned int n0, const unsigned int n1,
27229 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27230 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27231 return load_cimg(file,0,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27232 }
27233
27235 static CImgList<T> get_load_cimg(const char *const filename,
27236 const unsigned int n0, const unsigned int n1,
27237 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27238 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27239 return CImgList<T>().load_cimg(filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27240 }
27241
27243 CImgList<T>& load_cimg(const char *const filename,
27244 const unsigned int n0, const unsigned int n1,
27245 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27246 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27247 return load_cimg(0,filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27248 }
27249
27251 CImgList<T>& load_cimg(std::FILE *const file, const char *const filename,
27252 const unsigned int n0, const unsigned int n1,
27253 const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0,
27254 const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) {
27255 #define cimg_load_cimg_case2(Ts,Tss) \
27256 if (!loaded && !cimg::strcasecmp(Ts,str_pixeltype)) { \
27257 for (unsigned int l=0; l<=nn1; ++l) { \
27258 j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; \
27259 W = H = D = V = 0; \
27260 if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) \
27261 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", \
27262 pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); \
27263 if (W*H*D*V>0) { \
27264 if (l<n0 || x0>=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(Tss),SEEK_CUR); \
27265 else { \
27266 const unsigned int \
27267 nx1 = x1>=W?W-1:x1, \
27268 ny1 = y1>=H?H-1:y1, \
27269 nz1 = z1>=D?D-1:z1, \
27270 nv1 = v1>=V?V-1:v1; \
27271 CImg<Tss> raw(1+nx1-x0); \
27272 CImg<T> &img = data[l-n0]; \
27273 img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); \
27274 T *ptrd = img.data; \
27275 const unsigned int skipvb = v0*W*H*D*sizeof(Tss); \
27276 if (skipvb) std::fseek(nfile,skipvb,SEEK_CUR); \
27277 for (unsigned int v=1+nv1-v0; v; --v) { \
27278 const unsigned int skipzb = z0*W*H*sizeof(Tss); \
27279 if (skipzb) std::fseek(nfile,skipzb,SEEK_CUR); \
27280 for (unsigned int z=1+nz1-z0; z; --z) { \
27281 const unsigned int skipyb = y0*W*sizeof(Tss); \
27282 if (skipyb) std::fseek(nfile,skipyb,SEEK_CUR); \
27283 for (unsigned int y=1+ny1-y0; y; --y) { \
27284 const unsigned int skipxb = x0*sizeof(Tss); \
27285 if (skipxb) std::fseek(nfile,skipxb,SEEK_CUR); \
27286 cimg::fread(raw.data,raw.width,nfile); \
27287 if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); \
27288 const Tss *ptrs = raw.data; \
27289 for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); \
27290 const unsigned int skipxe = (W-1-nx1)*sizeof(Tss); \
27291 if (skipxe) std::fseek(nfile,skipxe,SEEK_CUR); \
27292 } \
27293 const unsigned int skipye = (H-1-ny1)*W*sizeof(Tss); \
27294 if (skipye) std::fseek(nfile,skipye,SEEK_CUR); \
27295 } \
27296 const unsigned int skipze = (D-1-nz1)*W*H*sizeof(Tss); \
27297 if (skipze) std::fseek(nfile,skipze,SEEK_CUR); \
27298 } \
27299 const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(Tss); \
27300 if (skipve) std::fseek(nfile,skipve,SEEK_CUR); \
27301 } \
27302 } \
27303 } \
27304 loaded = true; \
27305 }
27306 typedef unsigned char uchar;
27307 typedef unsigned short ushort;
27308 typedef unsigned int uint;
27309 typedef unsigned long ulong;
27310 if (n1<n0 || x1<x0 || y1<y0 || z1<z0 || v1<v0)
27311 throw CImgArgumentException("CImgList<%s>::load_cimg() : File '%s', Bad sub-region coordinates [%u->%u] "
27312 "(%u,%u,%u,%u)->(%u,%u,%u,%u).",pixel_type(),filename?filename:"(FILE*)",
27313 n0,n1,x0,y0,z0,v0,x1,y1,z1,v1);
27314 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
27315 bool loaded = false, endian = cimg::endian();
27316 char tmp[256], str_pixeltype[256], str_endian[256];
27317 unsigned int j, err, N, W, H, D, V;
27318 int i;
27319 j = 0; while((i=std::fgetc(nfile))!='\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = '\0';
27320 err = std::sscanf(tmp,"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian);
27321 if (err<2) {
27322 if (!file) cimg::fclose(nfile);
27323 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Unknow CImg RAW header.",
27324 pixel_type(),filename?filename:"(FILE*)");
27325 }
27326 if (!cimg::strncasecmp("little",str_endian,6)) endian = false;
27327 else if (!cimg::strncasecmp("big",str_endian,3)) endian = true;
27328 const unsigned int nn1 = n1>=N?N-1:n1;
27329 assign(1+nn1-n0);
27330 cimg_load_cimg_case2("bool",bool);
27331 cimg_load_cimg_case2("unsigned_char",uchar);
27332 cimg_load_cimg_case2("uchar",uchar);
27333 cimg_load_cimg_case2("char",char);
27334 cimg_load_cimg_case2("unsigned_short",ushort);
27335 cimg_load_cimg_case2("ushort",ushort);
27336 cimg_load_cimg_case2("short",short);
27337 cimg_load_cimg_case2("unsigned_int",uint);
27338 cimg_load_cimg_case2("uint",uint);
27339 cimg_load_cimg_case2("int",int);
27340 cimg_load_cimg_case2("unsigned_long",ulong);
27341 cimg_load_cimg_case2("ulong",ulong);
27342 cimg_load_cimg_case2("long",long);
27343 cimg_load_cimg_case2("float",float);
27344 cimg_load_cimg_case2("double",double);
27345 if (!loaded) {
27346 if (!file) cimg::fclose(nfile);
27347 throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', cannot read images of pixels coded as '%s'.",
27348 pixel_type(),filename?filename:"(FILE*)",str_pixeltype);
27349 }
27350 if (!file) cimg::fclose(nfile);
27351 return *this;
27352 }
27353
27355 static CImgList<T> get_load_parrec(const char *const filename) {
27356 return CImgList<T>().load_parrec(filename);
27357 }
27358
27360 CImgList<T>& load_parrec(const char *const filename) {
27361 char body[1024], filenamepar[1024], filenamerec[1024];
27362 const char *ext = cimg::filename_split(filename,body);
27363 if (!cimg::strncmp(ext,"par",3)) { std::strcpy(filenamepar,filename); std::sprintf(filenamerec,"%s.rec",body); }
27364 if (!cimg::strncmp(ext,"PAR",3)) { std::strcpy(filenamepar,filename); std::sprintf(filenamerec,"%s.REC",body); }
27365 if (!cimg::strncmp(ext,"rec",3)) { std::strcpy(filenamerec,filename); std::sprintf(filenamepar,"%s.par",body); }
27366 if (!cimg::strncmp(ext,"REC",3)) { std::strcpy(filenamerec,filename); std::sprintf(filenamepar,"%s.PAR",body); }
27367 std::FILE *file = cimg::fopen(filenamepar,"r");
27368
27369
27370 CImgList<float> st_slices;
27371 CImgList<unsigned int> st_global;
27372 int err;
27373 char line[256] = { 0 };
27374 do { err=std::fscanf(file,"%255[^\n]%*c",line); } while (err!=EOF && (line[0]=='#' || line[0]=='.'));
27375 do {
27376 unsigned int sn,sizex,sizey,pixsize;
27377 float rs,ri,ss;
27378 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);
27379 if (err==7) {
27380 st_slices.insert(CImg<float>::vector((float)sn,(float)pixsize,(float)sizex,(float)sizey,ri,rs,ss,0));
27381 unsigned int i; for (i=0; i<st_global.size && sn<=st_global[i][2]; ++i);
27382 if (i==st_global.size) st_global.insert(CImg<unsigned int>::vector(sizex,sizey,sn));
27383 else {
27384 CImg<unsigned int> &vec = st_global[i];
27385 if (sizex>vec[0]) vec[0] = sizex;
27386 if (sizey>vec[1]) vec[1] = sizey;
27387 vec[2] = sn;
27388 }
27389 st_slices[st_slices.size-1][7] = (float)i;
27390 }
27391 } while (err==7);
27392
27393
27394 std::FILE *file2 = cimg::fopen(filenamerec,"rb");
27395 { cimglist_for(st_global,l) {
27396 const CImg<unsigned int>& vec = st_global[l];
27397 insert(CImg<T>(vec[0],vec[1],vec[2]));
27398 }}
27399
27400 cimglist_for(st_slices,l) {
27401 const CImg<float>& vec = st_slices[l];
27402 const unsigned int
27403 sn = (unsigned int)vec[0]-1,
27404 pixsize = (unsigned int)vec[1],
27405 sizex = (unsigned int)vec[2],
27406 sizey = (unsigned int)vec[3],
27407 imn = (unsigned int)vec[7];
27408 const float ri = vec[4], rs = vec[5], ss = vec[6];
27409 switch (pixsize) {
27410 case 8: {
27411 CImg<unsigned char> buf(sizex,sizey);
27412 cimg::fread(buf.data,sizex*sizey,file2);
27413 if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey);
27414 CImg<T>& img = (*this)[imn];
27415 cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
27416 } break;
27417 case 16: {
27418 CImg<unsigned short> buf(sizex,sizey);
27419 cimg::fread(buf.data,sizex*sizey,file2);
27420 if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey);
27421 CImg<T>& img = (*this)[imn];
27422 cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
27423 } break;
27424 case 32: {
27425 CImg<unsigned int> buf(sizex,sizey);
27426 cimg::fread(buf.data,sizex*sizey,file2);
27427 if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey);
27428 CImg<T>& img = (*this)[imn];
27429 cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
27430 } break;
27431 default:
27432 cimg::fclose(file);
27433 cimg::fclose(file2);
27434 throw CImgIOException("CImg<%s>::load_parrec() : File '%s', cannot handle image with pixsize = %d bits.",
27435 pixel_type(),filename,pixsize);
27436 break;
27437 }
27438 }
27439 cimg::fclose(file);
27440 cimg::fclose(file2);
27441 if (!size)
27442 throw CImgIOException("CImg<%s>::load_parrec() : File '%s' does not appear to be a valid PAR-REC file.",
27443 pixel_type(),filename);
27444 return *this;
27445 }
27446
27448 static CImgList<T> get_load_yuv(std::FILE *const file, const char *const filename,
27449 const unsigned int sizex, const unsigned int sizey=1,
27450 const unsigned int first_frame=0, const int last_frame=-1,
27451 const bool yuv2rgb=false) {
27452 return CImgList<T>().load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb);
27453 }
27454
27456 CImgList<T>& load_yuv(std::FILE *const file, const char *const filename,
27457 const unsigned int sizex, const unsigned int sizey=1,
27458 const unsigned int first_frame=0, const int last_frame=-1,
27459 const bool yuv2rgb=false) {
27460 if (sizex%2 || sizey%2)
27461 throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', image dimensions along X and Y must be "
27462 "even numbers (given are %ux%u)\n",pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27463 if (!sizex || !sizey)
27464 throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', given image sequence size (%u,%u) is invalid",
27465 pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27466 if (last_frame>0 && first_frame>(unsigned int)last_frame)
27467 throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', given first frame %u is posterior to last frame %d.",
27468 pixel_type(),filename?filename:"(unknown)",first_frame,last_frame);
27469 if (!sizex || !sizey)
27470 throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', given frame size (%u,%u) is invalid.",
27471 pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27472 CImg<unsigned char> tmp(sizex,sizey,1,3), UV(sizex/2,sizey/2,1,2);
27473 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
27474 bool stopflag = false;
27475 int err;
27476 if (first_frame) {
27477 err = std::fseek(nfile,first_frame*(sizex*sizey + sizex*sizey/2),SEEK_CUR);
27478 if (err) {
27479 if (!file) cimg::fclose(nfile);
27480 throw CImgIOException("CImgList<%s>::load_yuv() : File '%s' doesn't contain frame number %u "
27481 "(out of range error).",pixel_type(),filename?filename:"(FILE*)",first_frame);
27482 }
27483 }
27484 unsigned int frame;
27485 for (frame = first_frame; !stopflag && (last_frame<0 || frame<=(unsigned int)last_frame); ++frame) {
27486 tmp.fill(0);
27487
27488 err = (int)std::fread((void*)(tmp.data),1,(size_t)(tmp.width*tmp.height),nfile);
27489 if (err!=(int)(tmp.width*tmp.height)) {
27490 stopflag = true;
27491 if (err>0) cimg::warn("CImgList<%s>::load_yuv() : File '%s' contains incomplete data,"
27492 " or given image dimensions (%u,%u) are incorrect.",
27493 pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27494 } else {
27495 UV.fill(0);
27496
27497 err = (int)std::fread((void*)(UV.data),1,(size_t)(UV.size()),nfile);
27498 if (err!=(int)(UV.size())) {
27499 stopflag = true;
27500 if (err>0) cimg::warn("CImgList<%s>::load_yuv() : File '%s' contains incomplete data,"
27501 " or given image dimensions (%u,%u) are incorrect.",
27502 pixel_type(),filename?filename:"(unknown)",sizex,sizey);
27503 } else {
27504 cimg_forXY(UV,x,y) {
27505 const int x2=2*x, y2=2*y;
27506 tmp(x2,y2,1) = tmp(x2+1,y2,1) = tmp(x2,y2+1,1) = tmp(x2+1,y2+1,1) = UV(x,y,0);
27507 tmp(x2,y2,2) = tmp(x2+1,y2,2) = tmp(x2,y2+1,2) = tmp(x2+1,y2+1,2) = UV(x,y,1);
27508 }
27509 if (yuv2rgb) tmp.YCbCrtoRGB();
27510 insert(tmp);
27511 }
27512 }
27513 }
27514 if (stopflag && last_frame>=0 && frame!=(unsigned int)last_frame)
27515 cimg::warn("CImgList<%s>::load_yuv() : File '%s', frame %d not reached since only %u frames were found in the file.",
27516 pixel_type(),filename?filename:"(unknown)",last_frame,frame-1,filename);
27517 if (!file) cimg::fclose(nfile);
27518 return *this;
27519 }
27520
27522 static CImgList<T> get_load_yuv(const char *const filename,
27523 const unsigned int sizex, const unsigned int sizey=1,
27524 const unsigned int first_frame=0, const int last_frame=-1,
27525 const bool yuv2rgb=false) {
27526 return CImgList<T>().load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb);
27527 }
27528
27530 CImgList<T>& load_yuv(const char *const filename,
27531 const unsigned int sizex, const unsigned int sizey,
27532 const unsigned int first_frame=0, const int last_frame=-1,
27533 const bool yuv2rgb=false) {
27534 return load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb);
27535 }
27536
27538 template<typename tf, typename tc>
27539 static CImgList<T> get_load_off(std::FILE *const file, const char *const filename,
27540 CImgList<tf>& primitives, CImgList<tc>& colors,
27541 const bool invert_faces=false) {
27542 return CImgList<T>().load_off(file,filename,primitives,colors,invert_faces);
27543 }
27544
27546 template<typename tf, typename tc>
27547 CImgList<T>& load_off(std::FILE *const file, const char *const filename,
27548 CImgList<tf>& primitives, CImgList<tc>& colors,
27549 const bool invert_faces=false) {
27550 return assign(CImg<T>::get_load_off(file,filename,primitives,colors,invert_faces).get_split('x'));
27551 }
27552
27554 template<typename tf, typename tc>
27555 static CImgList<T> get_load_off(const char *const filename,
27556 CImgList<tf>& primitives, CImgList<tc>& colors,
27557 const bool invert_faces=false) {
27558 return CImgList<T>().load_off(0,filename,primitives,colors,invert_faces);
27559 }
27560
27562 template<typename tf, typename tc>
27563 CImgList<T>& load_off(const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors,
27564 const bool invert_faces=false) {
27565 return load_off(0,filename,primitives,colors,invert_faces);
27566 }
27567
27569
27572 const CImgList<T>& save(const char *const filename, const int number=-1) const {
27573 if (is_empty()) throw CImgInstanceException("CImgList<%s>::save() : Instance list (%u,%p) is empty (file '%s').",
27574 pixel_type(),size,data,filename);
27575 if (!filename) throw CImgArgumentException("CImg<%s>::save() : Instance list (%u,%p), specified filename is (null).",
27576 pixel_type(),size,data);
27577 const char *ext = cimg::filename_split(filename);
27578 char nfilename[1024];
27579 const char *const fn = (number>=0)?cimg::filename_number(filename,number,6,nfilename):filename;
27580 #ifdef cimglist_save_plugin
27581 cimglist_save_plugin(fn);
27582 #endif
27583 #ifdef cimglist_save_plugin1
27584 cimglist_save_plugin1(fn);
27585 #endif
27586 #ifdef cimglist_save_plugin2
27587 cimglist_save_plugin2(fn);
27588 #endif
27589 #ifdef cimglist_save_plugin3
27590 cimglist_save_plugin3(fn);
27591 #endif
27592 #ifdef cimglist_save_plugin4
27593 cimglist_save_plugin4(fn);
27594 #endif
27595 #ifdef cimglist_save_plugin5
27596 cimglist_save_plugin5(fn);
27597 #endif
27598 #ifdef cimglist_save_plugin6
27599 cimglist_save_plugin6(fn);
27600 #endif
27601 #ifdef cimglist_save_plugin7
27602 cimglist_save_plugin7(fn);
27603 #endif
27604 #ifdef cimglist_save_plugin8
27605 cimglist_save_plugin8(fn);
27606 #endif
27607 if (!cimg::strncasecmp(ext,"cimg",4) || !ext[0]) return save_cimg(fn);
27608 if (!cimg::strncasecmp(ext,"yuv",3)) return save_yuv(fn,true);
27609 if (size==1) data[0].save(fn,-1);
27610 else cimglist_for(*this,l) data[l].save(fn,l);
27611 return *this;
27612 }
27613
27615 const CImgList<T>& save_yuv(std::FILE *const file, const char *const filename=0, const bool rgb2yuv=true) const {
27616 if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_yuv() : Instance list (%u,%p) is empty (file '%s').",
27617 pixel_type(),size,data,filename?filename:"(unknown)");
27618 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_yuv() : Instance list (%u,%p), specified file is (null).",
27619 pixel_type(),size,data);
27620 if ((*this)[0].dimx()%2 || (*this)[0].dimy()%2)
27621 throw CImgInstanceException("CImgList<%s>::save_yuv() : Image dimensions must be even numbers (current are %ux%u, file '%s').",
27622 pixel_type(),(*this)[0].dimx(),(*this)[0].dimy(),filename?filename:"(unknown)");
27623
27624 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
27625 cimglist_for(*this,l) {
27626 CImg<unsigned char> YCbCr((*this)[l]);
27627 if (rgb2yuv) YCbCr.RGBtoYCbCr();
27628 cimg::fwrite(YCbCr.data,YCbCr.width*YCbCr.height,nfile);
27629 cimg::fwrite(YCbCr.get_resize(YCbCr.width/2, YCbCr.height/2,1,3,3).ptr(0,0,0,1),
27630 YCbCr.width*YCbCr.height/2,nfile);
27631 }
27632 if (!file) cimg::fclose(nfile);
27633 return *this;
27634 }
27635
27637 const CImgList<T>& save_yuv(const char *const filename=0, const bool rgb2yuv=true) const {
27638 return save_yuv(0,filename,rgb2yuv);
27639 }
27640
27642
27647 const CImgList<T>& save_cimg(std::FILE *const file, const char *const filename=0) const {
27648 if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_cimg() : Instance list (%u,%p) is empty (file '%s').",
27649 pixel_type(),size,data,filename?filename:"(unknown)");
27650 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance list (%u,%p), specified file is (null).",
27651 pixel_type(),size,data);
27652 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
27653 const char *const ptype = pixel_type(), *const etype = cimg::endian()?"big":"little";
27654 if (!cimg::strncmp(ptype,"unsigned",8)) std::fprintf(nfile,"%u unsigned_%s %s_endian\n",size,ptype+9,etype);
27655 else std::fprintf(nfile,"%u %s %s_endian\n",size,ptype,etype);
27656 cimglist_for(*this,l) {
27657 const CImg<T>& img = data[l];
27658 std::fprintf(nfile,"%u %u %u %u\n",img.width,img.height,img.depth,img.dim);
27659 if (img.data) {
27660 if (cimg::endian()) {
27661 CImg<T> tmp(img);
27662 cimg::endian_swap(tmp.data,tmp.size());
27663 cimg::fwrite(tmp.data,img.width*img.height*img.depth*img.dim,nfile);
27664 } else cimg::fwrite(img.data,img.width*img.height*img.depth*img.dim,nfile);
27665 }
27666 }
27667 if (!file) cimg::fclose(nfile);
27668 return *this;
27669 }
27670
27672 const CImgList<T>& save_cimg(const char *const filename) const {
27673 return save_cimg(0,filename);
27674 }
27675
27676
27677 const CImgList<T>& save_cimg(std::FILE *const file, const char *const filename,
27678 const unsigned int n0,
27679 const unsigned int x0, const unsigned int y0,
27680 const unsigned int z0, const unsigned int v0) const {
27681 #define cimg_save_cimg_case(Ts,Tss) \
27682 if (!saved && !cimg::strcasecmp(Ts,str_pixeltype)) { \
27683 for (unsigned int l=0; l<lmax; ++l) { \
27684 j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; \
27685 W = H = D = V = 0; \
27686 if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) \
27687 throw CImgIOException("CImgList<%s>::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", \
27688 pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); \
27689 if (W*H*D*V>0) { \
27690 if (l<n0 || x0>=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(Tss),SEEK_CUR); \
27691 else { \
27692 const CImg<T>& img = (*this)[l-n0]; \
27693 const T *ptrs = img.data; \
27694 const unsigned int \
27695 x1 = x0 + img.width - 1, \
27696 y1 = y0 + img.height - 1, \
27697 z1 = z0 + img.depth - 1, \
27698 v1 = v0 + img.dim - 1, \
27699 nx1 = x1>=W?W-1:x1, \
27700 ny1 = y1>=H?H-1:y1, \
27701 nz1 = z1>=D?D-1:z1, \
27702 nv1 = v1>=V?V-1:v1; \
27703 CImg<Tss> raw(1+nx1-x0); \
27704 const unsigned int skipvb = v0*W*H*D*sizeof(Tss); \
27705 if (skipvb) std::fseek(nfile,skipvb,SEEK_CUR); \
27706 for (unsigned int v=1+nv1-v0; v; --v) { \
27707 const unsigned int skipzb = z0*W*H*sizeof(Tss); \
27708 if (skipzb) std::fseek(nfile,skipzb,SEEK_CUR); \
27709 for (unsigned int z=1+nz1-z0; z; --z) { \
27710 const unsigned int skipyb = y0*W*sizeof(Tss); \
27711 if (skipyb) std::fseek(nfile,skipyb,SEEK_CUR); \
27712 for (unsigned int y=1+ny1-y0; y; --y) { \
27713 const unsigned int skipxb = x0*sizeof(Tss); \
27714 if (skipxb) std::fseek(nfile,skipxb,SEEK_CUR); \
27715 raw.assign(ptrs, raw.width); \
27716 ptrs+=img.width; \
27717 if (endian) cimg::endian_swap(raw.data,raw.width); \
27718 cimg::fwrite(raw.data,raw.width,nfile); \
27719 const unsigned int skipxe = (W-1-nx1)*sizeof(Tss); \
27720 if (skipxe) std::fseek(nfile,skipxe,SEEK_CUR); \
27721 } \
27722 const unsigned int skipye = (H-1-ny1)*W*sizeof(Tss); \
27723 if (skipye) std::fseek(nfile,skipye,SEEK_CUR); \
27724 } \
27725 const unsigned int skipze = (D-1-nz1)*W*H*sizeof(Tss); \
27726 if (skipze) std::fseek(nfile,skipze,SEEK_CUR); \
27727 } \
27728 const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(Tss); \
27729 if (skipve) std::fseek(nfile,skipve,SEEK_CUR); \
27730 } \
27731 } \
27732 } \
27733 saved = true; \
27734 }
27735 if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_cimg() : Instance list (%u,%p) is empty (file '%s').",
27736 pixel_type(),size,data,filename?filename:"(unknown)");
27737 if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance list (%u,%p), specified file is (null).",
27738 pixel_type(),size,data);
27739 typedef unsigned char uchar;
27740 typedef unsigned short ushort;
27741 typedef unsigned int uint;
27742 typedef unsigned long ulong;
27743 std::FILE *const nfile = file?file:cimg::fopen(filename,"rb+");
27744 bool saved = false, endian = cimg::endian();
27745 char tmp[256], str_pixeltype[256], str_endian[256];
27746 unsigned int j, err, N, W, H, D, V;
27747 int i;
27748 j = 0; while((i=std::fgetc(nfile))!='\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = '\0';
27749 err = std::sscanf(tmp,"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian);
27750 if (err<2) {
27751 if (!file) cimg::fclose(nfile);
27752 throw CImgIOException("CImgList<%s>::save_cimg() : File '%s', Unknow CImg RAW header.",
27753 pixel_type(),filename?filename:"(FILE*)");
27754 }
27755 if (!cimg::strncasecmp("little",str_endian,6)) endian = false;
27756 else if (!cimg::strncasecmp("big",str_endian,3)) endian = true;
27757 const unsigned int lmax = cimg::min(N,n0+size);
27758 cimg_save_cimg_case("bool",bool);
27759 cimg_save_cimg_case("unsigned_char",uchar);
27760 cimg_save_cimg_case("uchar",uchar);
27761 cimg_save_cimg_case("char",char);
27762 cimg_save_cimg_case("unsigned_short",ushort);
27763 cimg_save_cimg_case("ushort",ushort);
27764 cimg_save_cimg_case("short",short);
27765 cimg_save_cimg_case("unsigned_int",uint);
27766 cimg_save_cimg_case("uint",uint);
27767 cimg_save_cimg_case("int",int);
27768 cimg_save_cimg_case("unsigned_long",ulong);
27769 cimg_save_cimg_case("ulong",ulong);
27770 cimg_save_cimg_case("long",long);
27771 cimg_save_cimg_case("float",float);
27772 cimg_save_cimg_case("double",double);
27773 if (!saved) {
27774 if (!file) cimg::fclose(nfile);
27775 throw CImgIOException("CImgList<%s>::save_cimg() : File '%s', cannot save images of pixels coded as '%s'.",
27776 pixel_type(),filename?filename:"(FILE*)",str_pixeltype);
27777 }
27778 if (!file) cimg::fclose(nfile);
27779 return *this;
27780 }
27781
27783 const CImgList<T>& save_cimg(std::FILE *const file,
27784 const unsigned int n0,
27785 const unsigned int x0, const unsigned int y0,
27786 const unsigned int z0, const unsigned int v0) const {
27787 return save_cimg(file,0,n0,x0,y0,z0,v0);
27788 }
27789
27791 const CImgList<T>& save_cimg(const char *const filename,
27792 const unsigned int n0,
27793 const unsigned int x0, const unsigned int y0,
27794 const unsigned int z0, const unsigned int v0) const {
27795 return save_cimg(0,filename,n0,x0,y0,z0,v0);
27796 }
27797
27798
27799 static void save_empty_cimg(std::FILE *const file, const char *const filename,
27800 const unsigned int nb,
27801 const unsigned int dx, const unsigned int dy=1,
27802 const unsigned int dz=1, const unsigned int dv=1) {
27803 std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
27804 const unsigned int siz = dx*dy*dz*dv*sizeof(T);
27805 std::fprintf(nfile,"%u %s\n",nb,pixel_type());
27806 for (unsigned int i=nb; i; --i) {
27807 std::fprintf(nfile,"%u %u %u %u\n",dx,dy,dz,dv);
27808 for (unsigned int off=siz; off; --off) std::fputc(0,nfile);
27809 }
27810 if (!file) cimg::fclose(nfile);
27811 }
27812
27814 static void save_empty_cimg(std::FILE *const file,
27815 const unsigned int nb,
27816 const unsigned int dx, const unsigned int dy=1,
27817 const unsigned int dz=1, const unsigned int dv=1) {
27818 return save_empty_cimg(file,0,nb,dx,dy,dz,dv);
27819 }
27820
27822 static void save_empty_cimg(const char *const filename,
27823 const unsigned int nb,
27824 const unsigned int dx, const unsigned int dy=1,
27825 const unsigned int dz=1, const unsigned int dv=1) {
27826 return save_empty_cimg(0,filename,nb,dx,dy,dz,dv);
27827 }
27828
27830 template<typename tf, typename tc>
27831 const CImgList<T>& save_off(std::FILE *const file, const char *const filename,
27832 const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
27833 get_append('x','y').save_off(file,filename,primitives,colors,invert_faces);
27834 return *this;
27835 }
27836
27838 template<typename tf, typename tc>
27839 const CImgList<T>& save_off(const char *const filename,
27840 const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
27841 return save_off(0,filename,primitives,colors,invert_faces);
27842 }
27843
27844
27845 CImgList<T> get_split(const char axe='x') const {
27846 CImgList<T> res;
27847 cimglist_for(*this,l) res.insert(data[l].get_split(axe));
27848 return res;
27849 }
27850
27852 CImgList<T>& split(const char axe='x') {
27853 return get_split(axe).assign_to(*this);
27854 }
27855
27857
27862 CImg<T> get_append(const char axe='x', const char align='c') const {
27863 if (is_empty()) return CImg<T>();
27864 if (size==1) return (*this)[0];
27865 unsigned int dx = 0, dy = 0, dz = 0, dv = 0, pos = 0;
27866 CImg<T> res;
27867 switch(cimg::uncase(axe)) {
27868 case 'x': {
27869 switch (cimg::uncase(align)) {
27870 case 'x': { dy = dz = dv = 1; cimglist_for(*this,l) dx+=(*this)[l].size(); } break;
27871 case 'y': { dx = size; dz = dv = 1; cimglist_for(*this,l) dy = cimg::max(dy,(unsigned int)(*this)[l].size()); } break;
27872 case 'z': { dx = size; dy = dv = 1; cimglist_for(*this,l) dz = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27873 case 'v': { dx = size; dy = dz = 1; cimglist_for(*this,l) dv = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27874 default:
27875 cimglist_for(*this,l) {
27876 const CImg<T>& img = (*this)[l];
27877 dx += img.width;
27878 dy = cimg::max(dy,img.height);
27879 dz = cimg::max(dz,img.depth);
27880 dv = cimg::max(dv,img.dim);
27881 }
27882 }
27883 res.assign(dx,dy,dz,dv,0);
27884 switch (cimg::uncase(align)) {
27885 case 'x': {
27886 cimglist_for(*this,l) { res.draw_image(CImg<T>((*this)[l],true).unroll('x'),pos,0,0,0); pos+=(*this)[l].size(); }
27887 } break;
27888 case 'y': {
27889 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('y'),pos++,0,0,0);
27890 } break;
27891 case 'z': {
27892 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('z'),pos++,0,0,0);
27893 } break;
27894 case 'v': {
27895 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('v'),pos++,0,0,0);
27896 } break;
27897 case 'p': {
27898 cimglist_for(*this,l) { res.draw_image((*this)[l],pos,0,0,0); pos+=(*this)[l].width; }
27899 } break;
27900 case 'n': {
27901 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; }
27902 } break;
27903 default : {
27904 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; }
27905 } break;
27906 }
27907 } break;
27908
27909 case 'y': {
27910 switch (cimg::uncase(align)) {
27911 case 'x': { dy = size; dz = dv = 1; cimglist_for(*this,l) dx = cimg::max(dx,(unsigned int)(*this)[l].size()); } break;
27912 case 'y': { dx = dz = dv = 1; cimglist_for(*this,l) dy+=(*this)[l].size(); } break;
27913 case 'z': { dy = size; dx = dv = 1; cimglist_for(*this,l) dz = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27914 case 'v': { dy = size; dx = dz = 1; cimglist_for(*this,l) dv = cimg::max(dv,(unsigned int)(*this)[l].size()); } break;
27915 default:
27916 cimglist_for(*this,l) {
27917 const CImg<T>& img = (*this)[l];
27918 dx = cimg::max(dx,img.width);
27919 dy += img.height;
27920 dz = cimg::max(dz,img.depth);
27921 dv = cimg::max(dv,img.dim);
27922 }
27923 }
27924 res.assign(dx,dy,dz,dv,0);
27925 switch (cimg::uncase(align)) {
27926 case 'x': {
27927 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('x'),0,pos++,0,0);
27928 } break;
27929 case 'y': {
27930 cimglist_for(*this,l) { res.draw_image(CImg<T>((*this)[l],true).unroll('y'),0,pos,0,0); pos+=(*this)[l].size(); }
27931 } break;
27932 case 'z': {
27933 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('z'),0,pos++,0,0);
27934 } break;
27935 case 'v': {
27936 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('v'),0,pos++,0,0);
27937 } break;
27938 case 'p': {
27939 cimglist_for(*this,l) { res.draw_image((*this)[l],0,pos,0,0); pos+=(*this)[l].height; }
27940 } break;
27941 case 'n': {
27942 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; }
27943 } break;
27944 default : {
27945 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);
27946 pos+=(*this)[l].height; }
27947 } break;
27948 }
27949 } break;
27950
27951 case 'z': {
27952 switch (cimg::uncase(align)) {
27953 case 'x': { dz = size; dy = dv = 1; cimglist_for(*this,l) dx = cimg::max(dx,(unsigned int)(*this)[l].size()); } break;
27954 case 'y': { dz = size; dx = dv = 1; cimglist_for(*this,l) dy = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27955 case 'z': { dx = dy = dv = 1; cimglist_for(*this,l) dz+=(*this)[l].size(); } break;
27956 case 'v': { dz = size; dx = dz = 1; cimglist_for(*this,l) dv = cimg::max(dv,(unsigned int)(*this)[l].size()); } break;
27957 default :
27958 cimglist_for(*this,l) {
27959 const CImg<T>& img = (*this)[l];
27960 dx = cimg::max(dx,img.width);
27961 dy = cimg::max(dy,img.height);
27962 dz += img.depth;
27963 dv = cimg::max(dv,img.dim);
27964 }
27965 }
27966 res.assign(dx,dy,dz,dv,0);
27967 switch (cimg::uncase(align)) {
27968 case 'x': {
27969 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('x'),0,0,pos++,0);
27970 } break;
27971 case 'y': {
27972 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('y'),0,0,pos++,0);
27973 } break;
27974 case 'z': {
27975 cimglist_for(*this,l) { res.draw_image(CImg<T>((*this)[l],true).unroll('z'),0,0,pos,0); pos+=(*this)[l].size(); }
27976 } break;
27977 case 'v': {
27978 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('v'),0,0,pos++,0);
27979 } break;
27980 case 'p': {
27981 cimglist_for(*this,l) { res.draw_image((*this)[l],0,0,pos,0); pos+=(*this)[l].depth; }
27982 } break;
27983 case 'n': {
27984 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; }
27985 } break;
27986 case 'c': {
27987 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);
27988 pos+=(*this)[l].depth; }
27989 } break;
27990 }
27991 } break;
27992
27993 case 'v': {
27994 switch (cimg::uncase(align)) {
27995 case 'x': { dv = size; dy = dv = 1; cimglist_for(*this,l) dx = cimg::max(dx,(unsigned int)(*this)[l].size()); } break;
27996 case 'y': { dv = size; dx = dv = 1; cimglist_for(*this,l) dy = cimg::max(dz,(unsigned int)(*this)[l].size()); } break;
27997 case 'z': { dv = size; dx = dv = 1; cimglist_for(*this,l) dz = cimg::max(dv,(unsigned int)(*this)[l].size()); } break;
27998 case 'v': { dx = dy = dz = 1; cimglist_for(*this,l) dv+=(*this)[l].size(); } break;
27999 default :
28000 cimglist_for(*this,l) {
28001 const CImg<T>& img = (*this)[l];
28002 dx = cimg::max(dx,img.width);
28003 dy = cimg::max(dy,img.height);
28004 dz = cimg::max(dz,img.depth);
28005 dv += img.dim;
28006 }
28007 }
28008 res.assign(dx,dy,dz,dv,0);
28009 switch (cimg::uncase(align)) {
28010 case 'x': {
28011 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('x'),0,0,0,pos++);
28012 } break;
28013 case 'y': {
28014 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('y'),0,0,0,pos++);
28015 } break;
28016 case 'z': {
28017 cimglist_for(*this,l) res.draw_image(CImg<T>((*this)[l],true).unroll('v'),0,0,0,pos++);
28018 } break;
28019 case 'v': {
28020 cimglist_for(*this,l) { res.draw_image(CImg<T>((*this)[l],true).unroll('z'),0,0,0,pos); pos+=(*this)[l].size(); }
28021 } break;
28022 case 'p': {
28023 cimglist_for(*this,l) { res.draw_image((*this)[l],0,0,0,pos); pos+=(*this)[l].dim; }
28024 } break;
28025 case 'n': {
28026 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; }
28027 } break;
28028 case 'c': {
28029 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);
28030 pos+=(*this)[l].dim; }
28031 } break;
28032 }
28033 } break;
28034 default: throw CImgArgumentException("CImgList<%s>::get_append() : unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe);
28035 }
28036 return res;
28037 }
28038
28039
28040 CImgList<T> get_crop_font() const {
28041 CImgList<T> res;
28042 cimglist_for(*this,l) {
28043 const CImg<T>& letter = (*this)[l];
28044 int xmin = letter.width, xmax = 0;
28045 cimg_forXY(letter,x,y) if (letter(x,y)) { if (x<xmin) xmin=x; if (x>xmax) xmax=x; }
28046 if (xmin>xmax) res.insert(CImg<T>(letter.width,letter.height,1,letter.dim,0));
28047 else res.insert(letter.get_crop(xmin,0,xmax,letter.height-1));
28048 }
28049 res[' '].resize(res['f'].width);
28050 res[' '+256].resize(res['f'].width);
28051 return res;
28052 }
28053
28055 CImgList<T>& crop_font() {
28056 return get_crop_font().assign_to(*this);
28057 }
28058
28059
28060 static CImgList<T> get_font(const unsigned int *const font, const unsigned int w, const unsigned int h,
28061 const unsigned int paddingx, const unsigned int paddingy, const bool variable_size=true) {
28062 CImgList<T> res = CImgList<T>(256,w,h,1,3).insert(CImgList<T>(256,w,h,1,1));
28063 const unsigned int *ptr = font;
28064 unsigned int m = 0, val = 0;
28065 for (unsigned int y=0; y<h; ++y)
28066 for (unsigned int x=0; x<256*w; ++x) {
28067 m>>=1; if (!m) { m = 0x80000000; val = *(ptr++); }
28068 CImg<T>& img = res[x/w], &mask = res[x/w+256];
28069 unsigned int xm = x%w;
28070 img(xm,y,0) = img(xm,y,1) = img(xm,y,2) = mask(xm,y,0) = (T)((val&m)?1:0);
28071 }
28072 if (variable_size) res.crop_font();
28073 if (paddingx || paddingy) cimglist_for(res,l) res[l].resize(res[l].dimx()+paddingx, res[l].dimy()+paddingy,1,-100,0);
28074 return res;
28075 }
28076
28078 CImgList<T>& font(const unsigned int *const font, const unsigned int w, const unsigned int h,
28079 const unsigned int paddingx, const unsigned int paddingy, const bool variable_size=true) {
28080 return get_font(font,w,h,paddingx,paddingy,variable_size).assign_to(*this);
28081 }
28082
28084
28088 static CImgList<T> get_font(const unsigned int font_width, const bool variable_size=true) {
28089 if (font_width<=11) {
28090 static CImgList<T> font7x11, nfont7x11;
28091 if (!variable_size && !font7x11) font7x11 = get_font(cimg::font7x11,7,11,1,0,false);
28092 if (variable_size && !nfont7x11) nfont7x11 = get_font(cimg::font7x11,7,11,1,0,true);
28093 return variable_size?nfont7x11:font7x11;
28094 }
28095 if (font_width<=13) {
28096 static CImgList<T> font10x13, nfont10x13;
28097 if (!variable_size && !font10x13) font10x13 = get_font(cimg::font10x13,10,13,1,0,false);
28098 if (variable_size && !nfont10x13) nfont10x13 = get_font(cimg::font10x13,10,13,1,0,true);
28099 return variable_size?nfont10x13:font10x13;
28100 }
28101 if (font_width<=17) {
28102 static CImgList<T> font8x17, nfont8x17;
28103 if (!variable_size && !font8x17) font8x17 = get_font(cimg::font8x17,8,17,1,0,false);
28104 if (variable_size && !nfont8x17) nfont8x17 = get_font(cimg::font8x17,8,17,1,0,true);
28105 return variable_size?nfont8x17:font8x17;
28106 }
28107 if (font_width<=19) {
28108 static CImgList<T> font10x19, nfont10x19;
28109 if (!variable_size && !font10x19) font10x19 = get_font(cimg::font10x19,10,19,2,0,false);
28110 if (variable_size && !nfont10x19) nfont10x19 = get_font(cimg::font10x19,10,19,2,0,true);
28111 return variable_size?nfont10x19:font10x19;
28112 }
28113 if (font_width<=24) {
28114 static CImgList<T> font12x24, nfont12x24;
28115 if (!variable_size && !font12x24) font12x24 = get_font(cimg::font12x24,12,24,2,0,false);
28116 if (variable_size && !nfont12x24) nfont12x24 = get_font(cimg::font12x24,12,24,2,0,true);
28117 return variable_size?nfont12x24:font12x24;
28118 }
28119 if (font_width<=32) {
28120 static CImgList<T> font16x32, nfont16x32;
28121 if (!variable_size && !font16x32) font16x32 = get_font(cimg::font16x32,16,32,2,0,false);
28122 if (variable_size && !nfont16x32) nfont16x32 = get_font(cimg::font16x32,16,32,2,0,true);
28123 return variable_size?nfont16x32:font16x32;
28124 }
28125 if (font_width<=38) {
28126 static CImgList<T> font19x38, nfont19x38;
28127 if (!variable_size && !font19x38) font19x38 = get_font(cimg::font19x38,19,38,3,0,false);
28128 if (variable_size && !nfont19x38) nfont19x38 = get_font(cimg::font19x38,19,38,3,0,true);
28129 return variable_size?nfont19x38:font19x38;
28130 }
28131 static CImgList<T> font29x57, nfont29x57;
28132 if (!variable_size && !font29x57) font29x57 = get_font(cimg::font29x57,29,57,5,0,false);
28133 if (variable_size && !nfont29x57) nfont29x57 = get_font(cimg::font29x57,29,57,5,0,true);
28134 return variable_size?nfont29x57:font29x57;
28135 }
28136
28138 CImgList<T>& font(const unsigned int font_width, const bool variable_size=true) {
28139 return get_font(font_width,variable_size).assign_to(*this);
28140 }
28141
28143
28152 const CImgList<T>& display(CImgDisplay& disp, const char axe='x', const char align='c') const {
28153 get_append(axe,align).display(disp);
28154 return *this;
28155 }
28156
28158
28171 const CImgList<T>& display(const char* title, const char axe='x', const char align='c',
28172 const int min_size=128, const int max_size=1024, const int print_flag=1) const {
28173
28174 if (is_empty())
28175 throw CImgInstanceException("CImgList<%s>::display() : Instance list (%u,%u) is empty.",
28176 pixel_type(),size,data);
28177 const CImg<T> visu = get_append(axe,align);
28178 CImgDisplay disp;
28179 unsigned int w = visu.width+(visu.depth>1?visu.depth:0), h = visu.height+(visu.depth>1?visu.depth:0), XYZ[3];
28180 print(title,print_flag);
28181 const unsigned int dmin = cimg::min(w,h), minsiz = min_size>=0?min_size:(-min_size)*dmin/100;
28182 if (dmin<minsiz) { w=w*minsiz/dmin; w+=(w==0); h=h*minsiz/dmin; h+=(h==0); }
28183 const unsigned int dmax = cimg::max(w,h), maxsiz = max_size>=0?max_size:(-max_size)*dmax/100;
28184 if (dmax>maxsiz) { w=w*maxsiz/dmax; w+=(w==0); h=h*maxsiz/dmax; h+=(h==0); }
28185 disp.assign(w,h,title,1,3);
28186 XYZ[0] = visu.width/2; XYZ[1] = visu.height/2; XYZ[2] = visu.depth/2;
28187 while (!disp.is_closed && !disp.key) visu.get_coordinates(1,disp,XYZ);
28188 return *this;
28189 }
28190
28192
28204 const CImgList<T>& display(const char axe='x', const char align='c',
28205 const int min_size=128, const int max_size=1024, const int print_flag=1) const {
28206 char title[256] = { 0 };
28207 std::sprintf(title,"CImgList<%s>",pixel_type());
28208 return display(title,axe,align,min_size,max_size,print_flag);
28209 }
28210
28211 };
28212
28213
28214
28215
28216
28217
28218
28219
28220
28221
28222
28223
28224
28225 namespace cimg {
28226
28228
28246 template<typename t>
28247 inline int dialog(const char *title, const char *msg,
28248 const char *button1_txt, const char *button2_txt,
28249 const char *button3_txt, const char *button4_txt,
28250 const char *button5_txt, const char *button6_txt,
28251 const CImg<t>& logo, const bool centering = false) {
28252 #if cimg_display_type!=0
28253 const unsigned char
28254 black[] = { 0,0,0 }, white[] = { 255,255,255 }, gray[] = { 200,200,200 }, gray2[] = { 150,150,150 };
28255
28256
28257 CImgList<unsigned char> buttons, cbuttons, sbuttons;
28258 if (button1_txt) { buttons.insert(CImg<unsigned char>().draw_text(button1_txt,0,0,black,gray,13));
28259 if (button2_txt) { buttons.insert(CImg<unsigned char>().draw_text(button2_txt,0,0,black,gray,13));
28260 if (button3_txt) { buttons.insert(CImg<unsigned char>().draw_text(button3_txt,0,0,black,gray,13));
28261 if (button4_txt) { buttons.insert(CImg<unsigned char>().draw_text(button4_txt,0,0,black,gray,13));
28262 if (button5_txt) { buttons.insert(CImg<unsigned char>().draw_text(button5_txt,0,0,black,gray,13));
28263 if (button6_txt) { buttons.insert(CImg<unsigned char>().draw_text(button6_txt,0,0,black,gray,13));
28264 }}}}}}
28265 if (!buttons.size) throw CImgArgumentException("cimg::dialog() : No buttons have been defined. At least one is necessary");
28266
28267 unsigned int bw = 0, bh = 0;
28268 cimglist_for(buttons,l) { bw = cimg::max(bw,buttons[l].width); bh = cimg::max(bh,buttons[l].height); }
28269 bw+=8; bh+=8;
28270 if (bw<64) bw=64;
28271 if (bw>128) bw=128;
28272 if (bh<24) bh=24;
28273 if (bh>48) bh=48;
28274
28275 CImg<unsigned char> button(bw,bh,1,3);
28276 button.draw_rectangle(0,0,bw-1,bh-1,gray);
28277 button.draw_line(0,0,bw-1,0,white).draw_line(0,bh-1,0,0,white);
28278 button.draw_line(bw-1,0,bw-1,bh-1,black).draw_line(bw-1,bh-1,0,bh-1,black);
28279 button.draw_line(1,bh-2,bw-2,bh-2,gray2).draw_line(bw-2,bh-2,bw-2,1,gray2);
28280 CImg<unsigned char> sbutton(bw,bh,1,3);
28281 sbutton.draw_rectangle(0,0,bw-1,bh-1,gray);
28282 sbutton.draw_line(0,0,bw-1,0,black).draw_line(bw-1,0,bw-1,bh-1,black);
28283 sbutton.draw_line(bw-1,bh-1,0,bh-1,black).draw_line(0,bh-1,0,0,black);
28284 sbutton.draw_line(1,1,bw-2,1,white).draw_line(1,bh-2,1,1,white);
28285 sbutton.draw_line(bw-2,1,bw-2,bh-2,black).draw_line(bw-2,bh-2,1,bh-2,black);
28286 sbutton.draw_line(2,bh-3,bw-3,bh-3,gray2).draw_line(bw-3,bh-3,bw-3,2,gray2);
28287 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);
28288 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);
28289 CImg<unsigned char> cbutton(bw,bh,1,3);
28290 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);
28291 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);
28292 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);
28293
28294 cimglist_for(buttons,ll) {
28295 cbuttons.insert(CImg<unsigned char>(cbutton).draw_image(buttons[ll],1+(bw-buttons[ll].dimx())/2,1+(bh-buttons[ll].dimy())/2));
28296 sbuttons.insert(CImg<unsigned char>(sbutton).draw_image(buttons[ll],(bw-buttons[ll].dimx())/2,(bh-buttons[ll].dimy())/2));
28297 buttons[ll] = CImg<unsigned char>(button).draw_image(buttons[ll],(bw-buttons[ll].dimx())/2,(bh-buttons[ll].dimy())/2);
28298 }
28299
28300 CImg<unsigned char> canvas;
28301 if (msg) canvas = CImg<unsigned char>().draw_text(msg,0,0,black,gray,13);
28302 const unsigned int
28303 bwall = (buttons.size-1)*(12+bw) + bw,
28304 w = cimg::max(196U,36+logo.width+canvas.width, 24+bwall),
28305 h = cimg::max(96U,36+canvas.height+bh,36+logo.height+bh),
28306 lx = 12 + (canvas.data?0:((w-24-logo.width)/2)),
28307 ly = (h-12-bh-logo.height)/2,
28308 tx = lx+logo.width+12,
28309 ty = (h-12-bh-canvas.height)/2,
28310 bx = (w-bwall)/2,
28311 by = h-12-bh;
28312
28313 if (canvas.data)
28314 canvas = CImg<unsigned char>(w,h,1,3).
28315 draw_rectangle(0,0,w-1,h-1,gray).
28316 draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white).
28317 draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black).
28318 draw_image(canvas,tx,ty);
28319 else
28320 canvas = CImg<unsigned char>(w,h,1,3).
28321 draw_rectangle(0,0,w-1,h-1,gray).
28322 draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white).
28323 draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black);
28324 if (logo.data) canvas.draw_image(logo,lx,ly);
28325
28326 unsigned int xbuttons[6];
28327 cimglist_for(buttons,lll) { xbuttons[lll] = bx+(bw+12)*lll; canvas.draw_image(buttons[lll],xbuttons[lll],by); }
28328
28329
28330 CImgDisplay disp(canvas,title?title:" ",0,3,false,centering?true:false);
28331 if (centering) disp.move((CImgDisplay::screen_dimx()-disp.dimx())/2,
28332 (CImgDisplay::screen_dimy()-disp.dimy())/2);
28333 bool stopflag = false, refresh = false;
28334 int oselected = -1, oclicked = -1, selected = -1, clicked = -1;
28335 while (!disp.is_closed && !stopflag) {
28336 if (refresh) {
28337 if (clicked>=0) CImg<unsigned char>(canvas).draw_image(cbuttons[clicked],xbuttons[clicked],by).display(disp);
28338 else {
28339 if (selected>=0) CImg<unsigned char>(canvas).draw_image(sbuttons[selected],xbuttons[selected],by).display(disp);
28340 else canvas.display(disp);
28341 }
28342 refresh = false;
28343 }
28344 disp.wait(15);
28345 if (disp.is_resized) disp.resize(disp);
28346
28347 if (disp.button&1) {
28348 oclicked = clicked;
28349 clicked = -1;
28350 cimglist_for(buttons,l)
28351 if (disp.mouse_y>=(int)by && disp.mouse_y<(int)(by+bh) &&
28352 disp.mouse_x>=(int)xbuttons[l] && disp.mouse_x<(int)(xbuttons[l]+bw)) {
28353 clicked = selected = l;
28354 refresh = true;
28355 }
28356 if (clicked!=oclicked) refresh = true;
28357 } else if (clicked>=0) stopflag = true;
28358
28359 if (disp.key) {
28360 oselected = selected;
28361 switch (disp.key) {
28362 case cimg::keyESC: selected=-1; stopflag=true; break;
28363 case cimg::keyENTER: if (selected<0) selected = 0; stopflag = true; break;
28364 case cimg::keyTAB:
28365 case cimg::keyARROWRIGHT:
28366 case cimg::keyARROWDOWN: selected = (selected+1)%buttons.size; break;
28367 case cimg::keyARROWLEFT:
28368 case cimg::keyARROWUP: selected = (selected+buttons.size-1)%buttons.size; break;
28369 }
28370 disp.key = 0;
28371 if (selected!=oselected) refresh = true;
28372 }
28373 }
28374 if (!disp) selected = -1;
28375 return selected;
28376 #else
28377 std::fprintf(stderr,"<%s>\n\n%s\n\n",title,msg);
28378 return -1+0*(int)(button1_txt-button2_txt+button3_txt-button4_txt+button5_txt-button6_txt+logo.width+(int)centering);
28379 #endif
28380 }
28381
28382 inline int dialog(const char *title, const char *msg,
28383 const char *button1_txt, const char *button2_txt, const char *button3_txt,
28384 const char *button4_txt, const char *button5_txt, const char *button6_txt,
28385 const bool centering) {
28386 return dialog(title,msg,button1_txt,button2_txt,button3_txt,button4_txt,button5_txt,button6_txt,
28387 CImg<unsigned char>::get_logo40x38(),centering);
28388 }
28389
28390
28391
28392 template<typename t> inline int _marching_cubes_indice(const unsigned int edge, const CImg<t>& indices1, const CImg<t>& indices2,
28393 const unsigned int x, const unsigned int y, const unsigned int nx, const unsigned int ny) {
28394 switch (edge) {
28395 case 0: return indices1(x,y,0);
28396 case 1: return indices1(nx,y,1);
28397 case 2: return indices1(x,ny,0);
28398 case 3: return indices1(x,y,1);
28399 case 4: return indices2(x,y,0);
28400 case 5: return indices2(nx,y,1);
28401 case 6: return indices2(x,ny,0);
28402 case 7: return indices2(x,y,1);
28403 case 8: return indices1(x,y,2);
28404 case 9: return indices1(nx,y,2);
28405 case 10: return indices1(nx,ny,2);
28406 case 11: return indices1(x,ny,2);
28407 }
28408 return 0;
28409 }
28410
28412
28413
28414 template<typename tfunc, typename tp, typename tf>
28415 inline void marching_cubes(const tfunc& func, const float isovalue,
28416 const float x0, const float y0, const float z0,
28417 const float x1, const float y1, const float z1,
28418 const float resx, const float resy, const float resz,
28419 CImgList<tp>& points, CImgList<tf>& primitives,
28420 const bool invert_faces) {
28421
28422 static unsigned int edges[256] = {
28423 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
28424 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
28425 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
28426 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
28427 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
28428 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
28429 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
28430 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
28431 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
28432 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
28433 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
28434 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
28435 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
28436 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
28437 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
28438 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000 };
28439
28440 static int triangles[256][16] =
28441 {{-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},
28442 {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},
28443 {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},
28444 {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},
28445 {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},
28446 {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},
28447 {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},
28448 {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},
28449 {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},
28450 {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},
28451 {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},
28452 {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},
28453 {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},
28454 {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},
28455 {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},
28456 {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},
28457 {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},
28458 {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},
28459 {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},
28460 {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},
28461 {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},
28462 {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},
28463 {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},
28464 {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},
28465 {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},
28466 {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},
28467 {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},
28468 {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},
28469 {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},
28470 {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},
28471 {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},
28472 {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},
28473 {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},
28474 {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},
28475 {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},
28476 {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},
28477 {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},
28478 {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},
28479 {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},
28480 {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},
28481 {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},
28482 {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},
28483 {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},
28484 {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},
28485 {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},
28486 {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},
28487 {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},
28488 {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},
28489 {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},
28490 {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},
28491 {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},
28492 {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},
28493 {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},
28494 {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},
28495 {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},
28496 {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},
28497 {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},
28498 {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},
28499 {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},
28500 {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},
28501 {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},
28502 {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},
28503 {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},
28504 {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},
28505 {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},
28506 {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},
28507 {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},
28508 {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},
28509 {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},
28510 {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},
28511 {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},
28512 {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},
28513 {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},
28514 {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},
28515 {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},
28516 {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},
28517 {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},
28518 {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},
28519 {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},
28520 {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},
28521 {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},
28522 {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},
28523 {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},
28524 {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},
28525 {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},
28526 {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},
28527 {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},
28528 {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},
28529 {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},
28530 {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},
28531 {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},
28532 {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},
28533 {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},
28534 {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},
28535 {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},
28536 {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},
28537 {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},
28538 {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},
28539 {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},
28540 {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},
28541 {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},
28542 {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},
28543 {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},
28544 {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},
28545 {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},
28546 {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},
28547 {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},
28548 {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},
28549 {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},
28550 {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},
28551 {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},
28552 {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},
28553 {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},
28554 {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},
28555 {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},
28556 {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},
28557 {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},
28558 {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},
28559 {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},
28560 {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},
28561 {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},
28562 {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},
28563 {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},
28564 {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},
28565 {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},
28566 {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},
28567 {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},
28568 {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}};
28569
28570 const unsigned int
28571 nx = (unsigned int)((x1-x0+1)/resx), nxm1 = nx-1,
28572 ny = (unsigned int)((y1-y0+1)/resy), nym1 = ny-1,
28573 nz = (unsigned int)((z1-z0+1)/resz), nzm1 = nz-1;
28574
28575 if (!nxm1 || !nym1 || !nzm1) return;
28576
28577 CImg<int> indices1(nx,ny,1,3,-1), indices2(indices1);
28578 CImg<float> values1(nx,ny), values2(nx,ny);
28579 float X = 0, Y = 0, Z = 0, nX = 0, nY = 0, nZ = 0;
28580
28581
28582 Y=y0;
28583 cimg_forY(values1,y) {
28584 X = x0;
28585 cimg_forX(values1,x) { values1(x,y) = (float)func(X,Y,z0); X+=resx; }
28586 Y+=resy;
28587 }
28588
28589
28590 Z = z0; nZ = Z + resz;
28591 for (unsigned int zi=0; zi<nzm1; ++zi, Z=nZ, nZ+=resz) {
28592 Y = y0; nY = Y + resy;
28593 indices2.fill(-1);
28594 for (unsigned int yi=0, nyi=1; yi<nym1; ++yi, ++nyi, Y=nY, nY+=resy) {
28595 X = x0; nX = X + resx;
28596 for (unsigned int xi=0, nxi=1; xi<nxm1; ++xi, ++nxi, X=nX, nX+=resx) {
28597
28598
28599 const float
28600 val0 = values1(xi,yi), val1 = values1(nxi,yi), val2 = values1(nxi,nyi), val3 = values1(xi,nyi),
28601 val4 = values2(xi,yi) = (float)func(X,Y,nZ),
28602 val5 = values2(nxi,yi) = (float)func(nX,Y,nZ),
28603 val6 = values2(nxi,nyi) = (float)func(nX,nY,nZ),
28604 val7 = values2(xi,nyi) = (float)func(X,nY,nZ);
28605
28606 const unsigned int configuration =
28607 (val0<isovalue?1:0) | (val1<isovalue?2:0) | (val2<isovalue?4:0) | (val3<isovalue?8:0) |
28608 (val4<isovalue?16:0) | (val5<isovalue?32:0) | (val6<isovalue?64:0) | (val7<isovalue?128:0),
28609 edge = edges[configuration];
28610
28611
28612 if (edge) {
28613 if ((edge&1) && indices1(xi,yi,0)<0) {
28614 const float Xi = X + (isovalue-val0)*resx/(val1-val0);
28615 indices1(xi,yi,0) = points.size;
28616 points.insert(CImg<tp>::vector(Xi,Y,Z));
28617 }
28618 if ((edge&2) && indices1(nxi,yi,1)<0) {
28619 const float Yi = Y + (isovalue-val1)*resy/(val2-val1);
28620 indices1(nxi,yi,1) = points.size;
28621 points.insert(CImg<tp>::vector(nX,Yi,Z));
28622 }
28623 if ((edge&4) && indices1(xi,nyi,0)<0) {
28624 const float Xi = X + (isovalue-val3)*resx/(val2-val3);
28625 indices1(xi,nyi,0) = points.size;
28626 points.insert(CImg<tp>::vector(Xi,nY,Z));
28627 }
28628 if ((edge&8) && indices1(xi,yi,1)<0) {
28629 const float Yi = Y + (isovalue-val0)*resy/(val3-val0);
28630 indices1(xi,yi,1) = points.size;
28631 points.insert(CImg<tp>::vector(X,Yi,Z));
28632 }
28633 if ((edge&16) && indices2(xi,yi,0)<0) {
28634 const float Xi = X + (isovalue-val4)*resx/(val5-val4);
28635 indices2(xi,yi,0) = points.size;
28636 points.insert(CImg<tp>::vector(Xi,Y,nZ));
28637 }
28638 if ((edge&32) && indices2(nxi,yi,1)<0) {
28639 const float Yi = Y + (isovalue-val5)*resy/(val6-val5);
28640 indices2(nxi,yi,1) = points.size;
28641 points.insert(CImg<tp>::vector(nX,Yi,nZ));
28642 }
28643 if ((edge&64) && indices2(xi,nyi,0)<0) {
28644 const float Xi = X + (isovalue-val7)*resx/(val6-val7);
28645 indices2(xi,nyi,0) = points.size;
28646 points.insert(CImg<tp>::vector(Xi,nY,nZ));
28647 }
28648 if ((edge&128) && indices2(xi,yi,1)<0) {
28649 const float Yi = Y + (isovalue-val4)*resy/(val7-val4);
28650 indices2(xi,yi,1) = points.size;
28651 points.insert(CImg<tp>::vector(X,Yi,nZ));
28652 }
28653 if ((edge&256) && indices1(xi,yi,2)<0) {
28654 const float Zi = Z+ (isovalue-val0)*resz/(val4-val0);
28655 indices1(xi,yi,2) = points.size;
28656 points.insert(CImg<tp>::vector(X,Y,Zi));
28657 }
28658 if ((edge&512) && indices1(nxi,yi,2)<0) {
28659 const float Zi = Z + (isovalue-val1)*resz/(val5-val1);
28660 indices1(nxi,yi,2) = points.size;
28661 points.insert(CImg<tp>::vector(nX,Y,Zi));
28662 }
28663 if ((edge&1024) && indices1(nxi,nyi,2)<0) {
28664 const float Zi = Z + (isovalue-val2)*resz/(val6-val2);
28665 indices1(nxi,nyi,2) = points.size;
28666 points.insert(CImg<tp>::vector(nX,nY,Zi));
28667 }
28668 if ((edge&2048) && indices1(xi,nyi,2)<0) {
28669 const float Zi = Z + (isovalue-val3)*resz/(val7-val3);
28670 indices1(xi,nyi,2) = points.size;
28671 points.insert(CImg<tp>::vector(X,nY,Zi));
28672 }
28673
28674
28675 for (int *triangle=triangles[configuration]; *triangle!=-1; ) {
28676 const unsigned int p0 = *(triangle++), p1 = *(triangle++), p2 = *(triangle++);
28677 const tf
28678 i0 = (tf)(_marching_cubes_indice(p0,indices1,indices2,xi,yi,nxi,nyi)),
28679 i1 = (tf)(_marching_cubes_indice(p1,indices1,indices2,xi,yi,nxi,nyi)),
28680 i2 = (tf)(_marching_cubes_indice(p2,indices1,indices2,xi,yi,nxi,nyi));
28681 if (invert_faces) primitives.insert(CImg<tf>::vector(i0,i1,i2));
28682 else primitives.insert(CImg<tf>::vector(i0,i2,i1));
28683 }
28684 }
28685 }
28686 }
28687 cimg::swap(values1,values2);
28688 cimg::swap(indices1,indices2);
28689 }
28690 }
28691
28692
28693 template<typename t> inline int _marching_squares_indice(const unsigned int edge, const CImg<t>& indices1, const CImg<t>& indices2,
28694 const unsigned int x, const unsigned int nx) {
28695 switch (edge) {
28696 case 0: return (int)indices1(x,0);
28697 case 1: return (int)indices1(nx,1);
28698 case 2: return (int)indices2(x,0);
28699 case 3: return (int)indices1(x,1);
28700 }
28701 return 0;
28702 }
28703
28705 template<typename tfunc, typename tp, typename tf>
28706 inline void marching_squares(const tfunc& func, const float isovalue,
28707 const float x0, const float y0,
28708 const float x1, const float y1,
28709 const float resx, const float resy,
28710 CImgList<tp>& points, CImgList<tf>& primitives) {
28711
28712 static unsigned int edges[16] = { 0x0, 0x9, 0x3, 0xa, 0x6, 0xf, 0x5, 0xc, 0xc, 0x5, 0xf, 0x6, 0xa, 0x3, 0x9, 0x0 };
28713 static int segments[16][4] = { { -1,-1,-1,-1 }, { 0,3,-1,-1 }, { 0,1,-1,-1 }, { 1,3,-1,-1 },
28714 { 1,2,-1,-1 }, { 0,1,2,3 }, { 0,2,-1,-1 }, { 2,3,-1,-1 },
28715 { 2,3,-1,-1 }, { 0,2,-1,-1}, { 0,3,1,2 }, { 1,2,-1,-1 },
28716 { 1,3,-1,-1 }, { 0,1,-1,-1}, { 0,3,-1,-1}, { -1,-1,-1,-1 } };
28717 const unsigned int
28718 nx = (unsigned int)((x1-x0+1)/resx), nxm1 = nx-1,
28719 ny = (unsigned int)((y1-y0+1)/resy), nym1 = ny-1;
28720
28721 if (!nxm1 || !nym1) return;
28722
28723 CImg<int> indices1(nx,1,1,2,-1), indices2(nx,1,1,2);
28724 CImg<float> values1(nx), values2(nx);
28725 float X = 0, Y = 0, nX = 0, nY = 0;
28726
28727
28728 cimg_forX(values1,x) { values1(x) = (float)func(X,Y); X+=resx; }
28729
28730
28731 Y = y0; nY = Y + resy;
28732 for (unsigned int yi=0, nyi=1; yi<nym1; ++yi, ++nyi, Y=nY, nY+=resy) {
28733 X = x0; nX = X + resx;
28734 indices2.fill(-1);
28735 for (unsigned int xi=0, nxi=1; xi<nxm1; ++xi, ++nxi, X=nX, nX+=resx) {
28736
28737
28738 const float
28739 val0 = values1(xi), val1 = values1(nxi),
28740 val2 = values2(nxi) = (float)func(nX,nY),
28741 val3 = values2(xi) = (float)func(X,nY);
28742
28743 const unsigned int configuration = (val0<isovalue?1:0) | (val1<isovalue?2:0) | (val2<isovalue?4:0) | (val3<isovalue?8:0),
28744 edge = edges[configuration];
28745
28746
28747 if (edge) {
28748 if ((edge&1) && indices1(xi,0)<0) {
28749 const float Xi = X + (isovalue-val0)*resx/(val1-val0);
28750 indices1(xi,0) = points.size;
28751 points.insert(CImg<tp>::vector(Xi,Y));
28752 }
28753 if ((edge&2) && indices1(nxi,1)<0) {
28754 const float Yi = Y + (isovalue-val1)*resy/(val2-val1);
28755 indices1(nxi,1) = points.size;
28756 points.insert(CImg<tp>::vector(nX,Yi));
28757 }
28758 if ((edge&4) && indices2(xi,0)<0) {
28759 const float Xi = X + (isovalue-val3)*resx/(val2-val3);
28760 indices2(xi,0) = points.size;
28761 points.insert(CImg<tp>::vector(Xi,nY));
28762 }
28763 if ((edge&8) && indices1(xi,1)<0) {
28764 const float Yi = Y + (isovalue-val0)*resy/(val3-val0);
28765 indices1(xi,1) = points.size;
28766 points.insert(CImg<tp>::vector(X,Yi));
28767 }
28768
28769
28770 for (int *segment=segments[configuration]; *segment!=-1; ) {
28771 const unsigned int p0 = *(segment++), p1 = *(segment++);
28772 const tf
28773 i0 = (tf)(_marching_squares_indice(p0,indices1,indices2,xi,nxi)),
28774 i1 = (tf)(_marching_squares_indice(p1,indices1,indices2,xi,nxi));
28775 primitives.insert(CImg<tf>::vector(i0,i1));
28776 }
28777 }
28778 }
28779 values1.swap(values2);
28780 indices1.swap(indices2);
28781 }
28782 }
28783
28784
28785 }
28786
28787
28788 }
28789
28790 #ifdef cimg_use_visualcpp6
28791 #undef std
28792 #endif
28793 #ifdef cimg_redefine_min
28794 #define min(a,b) (((a)<(b))?(a):(b))
28795 #endif
28796 #ifdef cimg_redefine_max
28797 #define max(a,b) (((a)>(b))?(a):(b))
28798 #endif
28799
28800 #endif
28801
28802
28803