namespace std __attribute__ ((__visibility__ ("default"))) { } typedef long int ptrdiff_t; typedef long unsigned int size_t; namespace std __attribute__ ((__visibility__ ("default"))) { using ::ptrdiff_t; using ::size_t; } extern "C" { typedef unsigned char __u_char; typedef unsigned short int __u_short; typedef unsigned int __u_int; typedef unsigned long int __u_long; typedef signed char __int8_t; typedef unsigned char __uint8_t; typedef signed short int __int16_t; typedef unsigned short int __uint16_t; typedef signed int __int32_t; typedef unsigned int __uint32_t; typedef signed long int __int64_t; typedef unsigned long int __uint64_t; typedef long int __quad_t; typedef unsigned long int __u_quad_t; typedef unsigned long int __dev_t; typedef unsigned int __uid_t; typedef unsigned int __gid_t; typedef unsigned long int __ino_t; typedef unsigned long int __ino64_t; typedef unsigned int __mode_t; typedef unsigned long int __nlink_t; typedef long int __off_t; typedef long int __off64_t; typedef int __pid_t; typedef struct { int __val[2]; } __fsid_t; typedef long int __clock_t; typedef unsigned long int __rlim_t; typedef unsigned long int __rlim64_t; typedef unsigned int __id_t; typedef long int __time_t; typedef unsigned int __useconds_t; typedef long int __suseconds_t; typedef int __daddr_t; typedef long int __swblk_t; typedef int __key_t; typedef int __clockid_t; typedef void * __timer_t; typedef long int __blksize_t; typedef long int __blkcnt_t; typedef long int __blkcnt64_t; typedef unsigned long int __fsblkcnt_t; typedef unsigned long int __fsblkcnt64_t; typedef unsigned long int __fsfilcnt_t; typedef unsigned long int __fsfilcnt64_t; typedef long int __ssize_t; typedef __off64_t __loff_t; typedef __quad_t *__qaddr_t; typedef char *__caddr_t; typedef long int __intptr_t; typedef unsigned int __socklen_t; struct _IO_FILE; typedef struct _IO_FILE FILE; typedef struct _IO_FILE __FILE; typedef struct { int __count; union { unsigned int __wch; char __wchb[4]; } __value; } __mbstate_t; typedef struct { __off_t __pos; __mbstate_t __state; } _G_fpos_t; typedef struct { __off64_t __pos; __mbstate_t __state; } _G_fpos64_t; typedef int _G_int16_t __attribute__ ((__mode__ (__HI__))); typedef int _G_int32_t __attribute__ ((__mode__ (__SI__))); typedef unsigned int _G_uint16_t __attribute__ ((__mode__ (__HI__))); typedef unsigned int _G_uint32_t __attribute__ ((__mode__ (__SI__))); typedef __builtin_va_list __gnuc_va_list; struct _IO_jump_t; struct _IO_FILE; typedef void _IO_lock_t; struct _IO_marker { struct _IO_marker *_next; struct _IO_FILE *_sbuf; int _pos; }; enum __codecvt_result { __codecvt_ok, __codecvt_partial, __codecvt_error, __codecvt_noconv }; struct _IO_FILE { int _flags; char* _IO_read_ptr; char* _IO_read_end; char* _IO_read_base; char* _IO_write_base; char* _IO_write_ptr; char* _IO_write_end; char* _IO_buf_base; char* _IO_buf_end; char *_IO_save_base; char *_IO_backup_base; char *_IO_save_end; struct _IO_marker *_markers; struct _IO_FILE *_chain; int _fileno; int _flags2; __off_t _old_offset; unsigned short _cur_column; signed char _vtable_offset; char _shortbuf[1]; _IO_lock_t *_lock; __off64_t _offset; void *__pad1; void *__pad2; void *__pad3; void *__pad4; size_t __pad5; int _mode; char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; }; struct _IO_FILE_plus; extern struct _IO_FILE_plus _IO_2_1_stdin_; extern struct _IO_FILE_plus _IO_2_1_stdout_; extern struct _IO_FILE_plus _IO_2_1_stderr_; typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); typedef __ssize_t __io_write_fn (void *__cookie, __const char *__buf, size_t __n); typedef int __io_seek_fn (void *__cookie, __off64_t *__pos, int __w); typedef int __io_close_fn (void *__cookie); typedef __io_read_fn cookie_read_function_t; typedef __io_write_fn cookie_write_function_t; typedef __io_seek_fn cookie_seek_function_t; typedef __io_close_fn cookie_close_function_t; typedef struct { __io_read_fn *read; __io_write_fn *write; __io_seek_fn *seek; __io_close_fn *close; } _IO_cookie_io_functions_t; typedef _IO_cookie_io_functions_t cookie_io_functions_t; struct _IO_cookie_file; extern void _IO_cookie_init (struct _IO_cookie_file *__cfile, int __read_write, void *__cookie, _IO_cookie_io_functions_t __fns); extern "C" { extern int __underflow (_IO_FILE *); extern int __uflow (_IO_FILE *); extern int __overflow (_IO_FILE *, int); extern int _IO_getc (_IO_FILE *__fp); extern int _IO_putc (int __c, _IO_FILE *__fp); extern int _IO_feof (_IO_FILE *__fp) throw (); extern int _IO_ferror (_IO_FILE *__fp) throw (); extern int _IO_peekc_locked (_IO_FILE *__fp); extern void _IO_flockfile (_IO_FILE *) throw (); extern void _IO_funlockfile (_IO_FILE *) throw (); extern int _IO_ftrylockfile (_IO_FILE *) throw (); extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict, __gnuc_va_list, int *__restrict); extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict, __gnuc_va_list); extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t); extern size_t _IO_sgetn (_IO_FILE *, void *, size_t); extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int); extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int); extern void _IO_free_backup_area (_IO_FILE *) throw (); } typedef __gnuc_va_list va_list; typedef _G_fpos_t fpos_t; typedef _G_fpos64_t fpos64_t; extern struct _IO_FILE *stdin; extern struct _IO_FILE *stdout; extern struct _IO_FILE *stderr; extern int remove (__const char *__filename) throw (); extern int rename (__const char *__old, __const char *__new) throw (); extern int renameat (int __oldfd, __const char *__old, int __newfd, __const char *__new) throw (); extern FILE *tmpfile (void) ; extern FILE *tmpfile64 (void) ; extern char *tmpnam (char *__s) throw () ; extern char *tmpnam_r (char *__s) throw () ; extern char *tempnam (__const char *__dir, __const char *__pfx) throw () __attribute__ ((__malloc__)) ; extern int fclose (FILE *__stream); extern int fflush (FILE *__stream); extern int fflush_unlocked (FILE *__stream); extern int fcloseall (void); extern FILE *fopen (__const char *__restrict __filename, __const char *__restrict __modes) ; extern FILE *freopen (__const char *__restrict __filename, __const char *__restrict __modes, FILE *__restrict __stream) ; extern FILE *fopen64 (__const char *__restrict __filename, __const char *__restrict __modes) ; extern FILE *freopen64 (__const char *__restrict __filename, __const char *__restrict __modes, FILE *__restrict __stream) ; extern FILE *fdopen (int __fd, __const char *__modes) throw () ; extern FILE *fopencookie (void *__restrict __magic_cookie, __const char *__restrict __modes, _IO_cookie_io_functions_t __io_funcs) throw () ; extern FILE *fmemopen (void *__s, size_t __len, __const char *__modes) throw () ; extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) throw () ; extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) throw (); extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, int __modes, size_t __n) throw (); extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf, size_t __size) throw (); extern void setlinebuf (FILE *__stream) throw (); extern int fprintf (FILE *__restrict __stream, __const char *__restrict __format, ...); extern int printf (__const char *__restrict __format, ...); extern int sprintf (char *__restrict __s, __const char *__restrict __format, ...) throw (); extern int vfprintf (FILE *__restrict __s, __const char *__restrict __format, __gnuc_va_list __arg); extern int vprintf (__const char *__restrict __format, __gnuc_va_list __arg); extern int vsprintf (char *__restrict __s, __const char *__restrict __format, __gnuc_va_list __arg) throw (); extern int snprintf (char *__restrict __s, size_t __maxlen, __const char *__restrict __format, ...) throw () __attribute__ ((__format__ (__printf__, 3, 4))); extern int vsnprintf (char *__restrict __s, size_t __maxlen, __const char *__restrict __format, __gnuc_va_list __arg) throw () __attribute__ ((__format__ (__printf__, 3, 0))); extern int vasprintf (char **__restrict __ptr, __const char *__restrict __f, __gnuc_va_list __arg) throw () __attribute__ ((__format__ (__printf__, 2, 0))) ; extern int __asprintf (char **__restrict __ptr, __const char *__restrict __fmt, ...) throw () __attribute__ ((__format__ (__printf__, 2, 3))) ; extern int asprintf (char **__restrict __ptr, __const char *__restrict __fmt, ...) throw () __attribute__ ((__format__ (__printf__, 2, 3))) ; extern int vdprintf (int __fd, __const char *__restrict __fmt, __gnuc_va_list __arg) __attribute__ ((__format__ (__printf__, 2, 0))); extern int dprintf (int __fd, __const char *__restrict __fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); extern int fscanf (FILE *__restrict __stream, __const char *__restrict __format, ...) ; extern int scanf (__const char *__restrict __format, ...) ; extern int sscanf (__const char *__restrict __s, __const char *__restrict __format, ...) throw (); extern int vfscanf (FILE *__restrict __s, __const char *__restrict __format, __gnuc_va_list __arg) __attribute__ ((__format__ (__scanf__, 2, 0))) ; extern int vscanf (__const char *__restrict __format, __gnuc_va_list __arg) __attribute__ ((__format__ (__scanf__, 1, 0))) ; extern int vsscanf (__const char *__restrict __s, __const char *__restrict __format, __gnuc_va_list __arg) throw () __attribute__ ((__format__ (__scanf__, 2, 0))); extern int fgetc (FILE *__stream); extern int getc (FILE *__stream); extern int getchar (void); extern int getc_unlocked (FILE *__stream); extern int getchar_unlocked (void); extern int fgetc_unlocked (FILE *__stream); extern int fputc (int __c, FILE *__stream); extern int putc (int __c, FILE *__stream); extern int putchar (int __c); extern int fputc_unlocked (int __c, FILE *__stream); extern int putc_unlocked (int __c, FILE *__stream); extern int putchar_unlocked (int __c); extern int getw (FILE *__stream); extern int putw (int __w, FILE *__stream); extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) ; extern char *gets (char *__s) ; extern char *fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) ; extern __ssize_t __getdelim (char **__restrict __lineptr, size_t *__restrict __n, int __delimiter, FILE *__restrict __stream) ; extern __ssize_t getdelim (char **__restrict __lineptr, size_t *__restrict __n, int __delimiter, FILE *__restrict __stream) ; extern __ssize_t getline (char **__restrict __lineptr, size_t *__restrict __n, FILE *__restrict __stream) ; extern int fputs (__const char *__restrict __s, FILE *__restrict __stream); extern int puts (__const char *__s); extern int ungetc (int __c, FILE *__stream); extern size_t fread (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) ; extern size_t fwrite (__const void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __s) ; extern int fputs_unlocked (__const char *__restrict __s, FILE *__restrict __stream); extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) ; extern size_t fwrite_unlocked (__const void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) ; extern int fseek (FILE *__stream, long int __off, int __whence); extern long int ftell (FILE *__stream) ; extern void rewind (FILE *__stream); extern int fseeko (FILE *__stream, __off_t __off, int __whence); extern __off_t ftello (FILE *__stream) ; extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos); extern int fsetpos (FILE *__stream, __const fpos_t *__pos); extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence); extern __off64_t ftello64 (FILE *__stream) ; extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos); extern int fsetpos64 (FILE *__stream, __const fpos64_t *__pos); extern void clearerr (FILE *__stream) throw (); extern int feof (FILE *__stream) throw () ; extern int ferror (FILE *__stream) throw () ; extern void clearerr_unlocked (FILE *__stream) throw (); extern int feof_unlocked (FILE *__stream) throw () ; extern int ferror_unlocked (FILE *__stream) throw () ; extern void perror (__const char *__s); extern int sys_nerr; extern __const char *__const sys_errlist[]; extern int _sys_nerr; extern __const char *__const _sys_errlist[]; extern int fileno (FILE *__stream) throw () ; extern int fileno_unlocked (FILE *__stream) throw () ; extern FILE *popen (__const char *__command, __const char *__modes) ; extern int pclose (FILE *__stream); extern char *ctermid (char *__s) throw (); extern char *cuserid (char *__s); struct obstack; extern int obstack_printf (struct obstack *__restrict __obstack, __const char *__restrict __format, ...) throw () __attribute__ ((__format__ (__printf__, 2, 3))); extern int obstack_vprintf (struct obstack *__restrict __obstack, __const char *__restrict __format, __gnuc_va_list __args) throw () __attribute__ ((__format__ (__printf__, 2, 0))); extern void flockfile (FILE *__stream) throw (); extern int ftrylockfile (FILE *__stream) throw () ; extern void funlockfile (FILE *__stream) throw (); extern __inline __attribute__ ((__gnu_inline__)) int vprintf (__const char *__restrict __fmt, __gnuc_va_list __arg) { return vfprintf (stdout, __fmt, __arg); } extern __inline __attribute__ ((__gnu_inline__)) int getchar (void) { return _IO_getc (stdin); } extern __inline __attribute__ ((__gnu_inline__)) int fgetc_unlocked (FILE *__fp) { return (__builtin_expect (((__fp)->_IO_read_ptr >= (__fp)->_IO_read_end), 0) ? __uflow (__fp) : *(unsigned char *) (__fp)->_IO_read_ptr++); } extern __inline __attribute__ ((__gnu_inline__)) int getc_unlocked (FILE *__fp) { return (__builtin_expect (((__fp)->_IO_read_ptr >= (__fp)->_IO_read_end), 0) ? __uflow (__fp) : *(unsigned char *) (__fp)->_IO_read_ptr++); } extern __inline __attribute__ ((__gnu_inline__)) int getchar_unlocked (void) { return (__builtin_expect (((stdin)->_IO_read_ptr >= (stdin)->_IO_read_end), 0) ? __uflow (stdin) : *(unsigned char *) (stdin)->_IO_read_ptr++); } extern __inline __attribute__ ((__gnu_inline__)) int putchar (int __c) { return _IO_putc (__c, stdout); } extern __inline __attribute__ ((__gnu_inline__)) int fputc_unlocked (int __c, FILE *__stream) { return (__builtin_expect (((__stream)->_IO_write_ptr >= (__stream)->_IO_write_end), 0) ? __overflow (__stream, (unsigned char) (__c)) : (unsigned char) (*(__stream)->_IO_write_ptr++ = (__c))); } extern __inline __attribute__ ((__gnu_inline__)) int putc_unlocked (int __c, FILE *__stream) { return (__builtin_expect (((__stream)->_IO_write_ptr >= (__stream)->_IO_write_end), 0) ? __overflow (__stream, (unsigned char) (__c)) : (unsigned char) (*(__stream)->_IO_write_ptr++ = (__c))); } extern __inline __attribute__ ((__gnu_inline__)) int putchar_unlocked (int __c) { return (__builtin_expect (((stdout)->_IO_write_ptr >= (stdout)->_IO_write_end), 0) ? __overflow (stdout, (unsigned char) (__c)) : (unsigned char) (*(stdout)->_IO_write_ptr++ = (__c))); } extern __inline __attribute__ ((__gnu_inline__)) __ssize_t getline (char **__lineptr, size_t *__n, FILE *__stream) { return __getdelim (__lineptr, __n, '\n', __stream); } extern __inline __attribute__ ((__gnu_inline__)) int feof_unlocked (FILE *__stream) throw () { return (((__stream)->_flags & 0x10) != 0); } extern __inline __attribute__ ((__gnu_inline__)) int ferror_unlocked (FILE *__stream) throw () { return (((__stream)->_flags & 0x20) != 0); } } namespace std __attribute__ ((__visibility__ ("default"))) { using ::FILE; using ::fpos_t; using ::clearerr; using ::fclose; using ::feof; using ::ferror; using ::fflush; using ::fgetc; using ::fgetpos; using ::fgets; using ::fopen; using ::fprintf; using ::fputc; using ::fputs; using ::fread; using ::freopen; using ::fscanf; using ::fseek; using ::fsetpos; using ::ftell; using ::fwrite; using ::getc; using ::getchar; using ::gets; using ::perror; using ::printf; using ::putc; using ::putchar; using ::puts; using ::remove; using ::rename; using ::rewind; using ::scanf; using ::setbuf; using ::setvbuf; using ::sprintf; using ::sscanf; using ::tmpfile; using ::tmpnam; using ::ungetc; using ::vfprintf; using ::vprintf; using ::vsprintf; } namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { using ::snprintf; using ::vfscanf; using ::vscanf; using ::vsnprintf; using ::vsscanf; } namespace std __attribute__ ((__visibility__ ("default"))) { using ::__gnu_cxx::snprintf; using ::__gnu_cxx::vfscanf; using ::__gnu_cxx::vscanf; using ::__gnu_cxx::vsnprintf; using ::__gnu_cxx::vsscanf; } extern "C" { union wait { int w_status; struct { unsigned int __w_termsig:7; unsigned int __w_coredump:1; unsigned int __w_retcode:8; unsigned int:16; } __wait_terminated; struct { unsigned int __w_stopval:8; unsigned int __w_stopsig:8; unsigned int:16; } __wait_stopped; }; typedef struct { int quot; int rem; } div_t; typedef struct { long int quot; long int rem; } ldiv_t; __extension__ typedef struct { long long int quot; long long int rem; } lldiv_t; extern size_t __ctype_get_mb_cur_max (void) throw () ; extern double atof (__const char *__nptr) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; extern int atoi (__const char *__nptr) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; extern long int atol (__const char *__nptr) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; __extension__ extern long long int atoll (__const char *__nptr) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; extern double strtod (__const char *__restrict __nptr, char **__restrict __endptr) throw () __attribute__ ((__nonnull__ (1))) ; extern float strtof (__const char *__restrict __nptr, char **__restrict __endptr) throw () __attribute__ ((__nonnull__ (1))) ; extern long double strtold (__const char *__restrict __nptr, char **__restrict __endptr) throw () __attribute__ ((__nonnull__ (1))) ; extern long int strtol (__const char *__restrict __nptr, char **__restrict __endptr, int __base) throw () __attribute__ ((__nonnull__ (1))) ; extern unsigned long int strtoul (__const char *__restrict __nptr, char **__restrict __endptr, int __base) throw () __attribute__ ((__nonnull__ (1))) ; __extension__ extern long long int strtoq (__const char *__restrict __nptr, char **__restrict __endptr, int __base) throw () __attribute__ ((__nonnull__ (1))) ; __extension__ extern unsigned long long int strtouq (__const char *__restrict __nptr, char **__restrict __endptr, int __base) throw () __attribute__ ((__nonnull__ (1))) ; __extension__ extern long long int strtoll (__const char *__restrict __nptr, char **__restrict __endptr, int __base) throw () __attribute__ ((__nonnull__ (1))) ; __extension__ extern unsigned long long int strtoull (__const char *__restrict __nptr, char **__restrict __endptr, int __base) throw () __attribute__ ((__nonnull__ (1))) ; typedef struct __locale_struct { struct locale_data *__locales[13]; const unsigned short int *__ctype_b; const int *__ctype_tolower; const int *__ctype_toupper; const char *__names[13]; } *__locale_t; extern long int strtol_l (__const char *__restrict __nptr, char **__restrict __endptr, int __base, __locale_t __loc) throw () __attribute__ ((__nonnull__ (1, 4))) ; extern unsigned long int strtoul_l (__const char *__restrict __nptr, char **__restrict __endptr, int __base, __locale_t __loc) throw () __attribute__ ((__nonnull__ (1, 4))) ; __extension__ extern long long int strtoll_l (__const char *__restrict __nptr, char **__restrict __endptr, int __base, __locale_t __loc) throw () __attribute__ ((__nonnull__ (1, 4))) ; __extension__ extern unsigned long long int strtoull_l (__const char *__restrict __nptr, char **__restrict __endptr, int __base, __locale_t __loc) throw () __attribute__ ((__nonnull__ (1, 4))) ; extern double strtod_l (__const char *__restrict __nptr, char **__restrict __endptr, __locale_t __loc) throw () __attribute__ ((__nonnull__ (1, 3))) ; extern float strtof_l (__const char *__restrict __nptr, char **__restrict __endptr, __locale_t __loc) throw () __attribute__ ((__nonnull__ (1, 3))) ; extern long double strtold_l (__const char *__restrict __nptr, char **__restrict __endptr, __locale_t __loc) throw () __attribute__ ((__nonnull__ (1, 3))) ; extern __inline __attribute__ ((__gnu_inline__)) double atof (__const char *__nptr) throw () { return strtod (__nptr, (char **) __null); } extern __inline __attribute__ ((__gnu_inline__)) int atoi (__const char *__nptr) throw () { return (int) strtol (__nptr, (char **) __null, 10); } extern __inline __attribute__ ((__gnu_inline__)) long int atol (__const char *__nptr) throw () { return strtol (__nptr, (char **) __null, 10); } __extension__ extern __inline __attribute__ ((__gnu_inline__)) long long int atoll (__const char *__nptr) throw () { return strtoll (__nptr, (char **) __null, 10); } extern char *l64a (long int __n) throw () ; extern long int a64l (__const char *__s) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) ; extern "C" { typedef __u_char u_char; typedef __u_short u_short; typedef __u_int u_int; typedef __u_long u_long; typedef __quad_t quad_t; typedef __u_quad_t u_quad_t; typedef __fsid_t fsid_t; typedef __loff_t loff_t; typedef __ino_t ino_t; typedef __ino64_t ino64_t; typedef __dev_t dev_t; typedef __gid_t gid_t; typedef __mode_t mode_t; typedef __nlink_t nlink_t; typedef __uid_t uid_t; typedef __off_t off_t; typedef __off64_t off64_t; typedef __pid_t pid_t; typedef __id_t id_t; typedef __ssize_t ssize_t; typedef __daddr_t daddr_t; typedef __caddr_t caddr_t; typedef __key_t key_t; typedef __clock_t clock_t; typedef __time_t time_t; typedef __clockid_t clockid_t; typedef __timer_t timer_t; typedef __useconds_t useconds_t; typedef __suseconds_t suseconds_t; typedef unsigned long int ulong; typedef unsigned short int ushort; typedef unsigned int uint; typedef int int8_t __attribute__ ((__mode__ (__QI__))); typedef int int16_t __attribute__ ((__mode__ (__HI__))); typedef int int32_t __attribute__ ((__mode__ (__SI__))); typedef int int64_t __attribute__ ((__mode__ (__DI__))); typedef unsigned int u_int8_t __attribute__ ((__mode__ (__QI__))); typedef unsigned int u_int16_t __attribute__ ((__mode__ (__HI__))); typedef unsigned int u_int32_t __attribute__ ((__mode__ (__SI__))); typedef unsigned int u_int64_t __attribute__ ((__mode__ (__DI__))); typedef int register_t __attribute__ ((__mode__ (__word__))); typedef int __sig_atomic_t; typedef struct { unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))]; } __sigset_t; typedef __sigset_t sigset_t; struct timespec { __time_t tv_sec; long int tv_nsec; }; struct timeval { __time_t tv_sec; __suseconds_t tv_usec; }; typedef long int __fd_mask; typedef struct { __fd_mask fds_bits[1024 / (8 * sizeof (__fd_mask))]; } fd_set; typedef __fd_mask fd_mask; extern "C" { extern int select (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, struct timeval *__restrict __timeout); extern int pselect (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, const struct timespec *__restrict __timeout, const __sigset_t *__restrict __sigmask); } __extension__ extern unsigned int gnu_dev_major (unsigned long long int __dev) throw (); __extension__ extern unsigned int gnu_dev_minor (unsigned long long int __dev) throw (); __extension__ extern unsigned long long int gnu_dev_makedev (unsigned int __major, unsigned int __minor) throw (); __extension__ extern __inline __attribute__ ((__gnu_inline__)) unsigned int gnu_dev_major (unsigned long long int __dev) throw () { return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff); } __extension__ extern __inline __attribute__ ((__gnu_inline__)) unsigned int gnu_dev_minor (unsigned long long int __dev) throw () { return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); } __extension__ extern __inline __attribute__ ((__gnu_inline__)) unsigned long long int gnu_dev_makedev (unsigned int __major, unsigned int __minor) throw () { return ((__minor & 0xff) | ((__major & 0xfff) << 8) | (((unsigned long long int) (__minor & ~0xff)) << 12) | (((unsigned long long int) (__major & ~0xfff)) << 32)); } typedef __blksize_t blksize_t; typedef __blkcnt_t blkcnt_t; typedef __fsblkcnt_t fsblkcnt_t; typedef __fsfilcnt_t fsfilcnt_t; typedef __blkcnt64_t blkcnt64_t; typedef __fsblkcnt64_t fsblkcnt64_t; typedef __fsfilcnt64_t fsfilcnt64_t; typedef unsigned long int pthread_t; typedef union { char __size[56]; long int __align; } pthread_attr_t; typedef struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __pthread_list_t; typedef union { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; int __spins; __pthread_list_t __list; } __data; char __size[40]; long int __align; } pthread_mutex_t; typedef union { char __size[4]; int __align; } pthread_mutexattr_t; typedef union { struct { int __lock; unsigned int __futex; __extension__ unsigned long long int __total_seq; __extension__ unsigned long long int __wakeup_seq; __extension__ unsigned long long int __woken_seq; void *__mutex; unsigned int __nwaiters; unsigned int __broadcast_seq; } __data; char __size[48]; __extension__ long long int __align; } pthread_cond_t; typedef union { char __size[4]; int __align; } pthread_condattr_t; typedef unsigned int pthread_key_t; typedef int pthread_once_t; typedef union { struct { int __lock; unsigned int __nr_readers; unsigned int __readers_wakeup; unsigned int __writer_wakeup; unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; int __writer; int __shared; unsigned long int __pad1; unsigned long int __pad2; unsigned int __flags; } __data; char __size[56]; long int __align; } pthread_rwlock_t; typedef union { char __size[8]; long int __align; } pthread_rwlockattr_t; typedef volatile int pthread_spinlock_t; typedef union { char __size[32]; long int __align; } pthread_barrier_t; typedef union { char __size[4]; int __align; } pthread_barrierattr_t; } extern long int random (void) throw (); extern void srandom (unsigned int __seed) throw (); extern char *initstate (unsigned int __seed, char *__statebuf, size_t __statelen) throw () __attribute__ ((__nonnull__ (2))); extern char *setstate (char *__statebuf) throw () __attribute__ ((__nonnull__ (1))); struct random_data { int32_t *fptr; int32_t *rptr; int32_t *state; int rand_type; int rand_deg; int rand_sep; int32_t *end_ptr; }; extern int random_r (struct random_data *__restrict __buf, int32_t *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); extern int srandom_r (unsigned int __seed, struct random_data *__buf) throw () __attribute__ ((__nonnull__ (2))); extern int initstate_r (unsigned int __seed, char *__restrict __statebuf, size_t __statelen, struct random_data *__restrict __buf) throw () __attribute__ ((__nonnull__ (2, 4))); extern int setstate_r (char *__restrict __statebuf, struct random_data *__restrict __buf) throw () __attribute__ ((__nonnull__ (1, 2))); extern int rand (void) throw (); extern void srand (unsigned int __seed) throw (); extern int rand_r (unsigned int *__seed) throw (); extern double drand48 (void) throw (); extern double erand48 (unsigned short int __xsubi[3]) throw () __attribute__ ((__nonnull__ (1))); extern long int lrand48 (void) throw (); extern long int nrand48 (unsigned short int __xsubi[3]) throw () __attribute__ ((__nonnull__ (1))); extern long int mrand48 (void) throw (); extern long int jrand48 (unsigned short int __xsubi[3]) throw () __attribute__ ((__nonnull__ (1))); extern void srand48 (long int __seedval) throw (); extern unsigned short int *seed48 (unsigned short int __seed16v[3]) throw () __attribute__ ((__nonnull__ (1))); extern void lcong48 (unsigned short int __param[7]) throw () __attribute__ ((__nonnull__ (1))); struct drand48_data { unsigned short int __x[3]; unsigned short int __old_x[3]; unsigned short int __c; unsigned short int __init; unsigned long long int __a; }; extern int drand48_r (struct drand48_data *__restrict __buffer, double *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); extern int erand48_r (unsigned short int __xsubi[3], struct drand48_data *__restrict __buffer, double *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); extern int lrand48_r (struct drand48_data *__restrict __buffer, long int *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); extern int nrand48_r (unsigned short int __xsubi[3], struct drand48_data *__restrict __buffer, long int *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); extern int mrand48_r (struct drand48_data *__restrict __buffer, long int *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); extern int jrand48_r (unsigned short int __xsubi[3], struct drand48_data *__restrict __buffer, long int *__restrict __result) throw () __attribute__ ((__nonnull__ (1, 2))); extern int srand48_r (long int __seedval, struct drand48_data *__buffer) throw () __attribute__ ((__nonnull__ (2))); extern int seed48_r (unsigned short int __seed16v[3], struct drand48_data *__buffer) throw () __attribute__ ((__nonnull__ (1, 2))); extern int lcong48_r (unsigned short int __param[7], struct drand48_data *__buffer) throw () __attribute__ ((__nonnull__ (1, 2))); extern void *malloc (size_t __size) throw () __attribute__ ((__malloc__)) ; extern void *calloc (size_t __nmemb, size_t __size) throw () __attribute__ ((__malloc__)) ; extern void *realloc (void *__ptr, size_t __size) throw () __attribute__ ((__warn_unused_result__)); extern void free (void *__ptr) throw (); extern void cfree (void *__ptr) throw (); extern "C" { extern void *alloca (size_t __size) throw (); } extern void *valloc (size_t __size) throw () __attribute__ ((__malloc__)) ; extern int posix_memalign (void **__memptr, size_t __alignment, size_t __size) throw () __attribute__ ((__nonnull__ (1))) ; extern void abort (void) throw () __attribute__ ((__noreturn__)); extern int atexit (void (*__func) (void)) throw () __attribute__ ((__nonnull__ (1))); extern int on_exit (void (*__func) (int __status, void *__arg), void *__arg) throw () __attribute__ ((__nonnull__ (1))); extern void exit (int __status) throw () __attribute__ ((__noreturn__)); extern void _Exit (int __status) throw () __attribute__ ((__noreturn__)); extern char *getenv (__const char *__name) throw () __attribute__ ((__nonnull__ (1))) ; extern char *__secure_getenv (__const char *__name) throw () __attribute__ ((__nonnull__ (1))) ; extern int putenv (char *__string) throw () __attribute__ ((__nonnull__ (1))); extern int setenv (__const char *__name, __const char *__value, int __replace) throw () __attribute__ ((__nonnull__ (2))); extern int unsetenv (__const char *__name) throw (); extern int clearenv (void) throw (); extern char *mktemp (char *__template) throw () __attribute__ ((__nonnull__ (1))) ; extern int mkstemp (char *__template) __attribute__ ((__nonnull__ (1))) ; extern int mkstemp64 (char *__template) __attribute__ ((__nonnull__ (1))) ; extern char *mkdtemp (char *__template) throw () __attribute__ ((__nonnull__ (1))) ; extern int mkostemp (char *__template, int __flags) __attribute__ ((__nonnull__ (1))) ; extern int mkostemp64 (char *__template, int __flags) __attribute__ ((__nonnull__ (1))) ; extern int system (__const char *__command) ; extern char *canonicalize_file_name (__const char *__name) throw () __attribute__ ((__nonnull__ (1))) ; extern char *realpath (__const char *__restrict __name, char *__restrict __resolved) throw () ; typedef int (*__compar_fn_t) (__const void *, __const void *); typedef __compar_fn_t comparison_fn_t; extern void *bsearch (__const void *__key, __const void *__base, size_t __nmemb, size_t __size, __compar_fn_t __compar) __attribute__ ((__nonnull__ (1, 2, 5))) ; extern void qsort (void *__base, size_t __nmemb, size_t __size, __compar_fn_t __compar) __attribute__ ((__nonnull__ (1, 4))); extern int abs (int __x) throw () __attribute__ ((__const__)) ; extern long int labs (long int __x) throw () __attribute__ ((__const__)) ; __extension__ extern long long int llabs (long long int __x) throw () __attribute__ ((__const__)) ; extern div_t div (int __numer, int __denom) throw () __attribute__ ((__const__)) ; extern ldiv_t ldiv (long int __numer, long int __denom) throw () __attribute__ ((__const__)) ; __extension__ extern lldiv_t lldiv (long long int __numer, long long int __denom) throw () __attribute__ ((__const__)) ; extern char *ecvt (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign) throw () __attribute__ ((__nonnull__ (3, 4))) ; extern char *fcvt (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign) throw () __attribute__ ((__nonnull__ (3, 4))) ; extern char *gcvt (double __value, int __ndigit, char *__buf) throw () __attribute__ ((__nonnull__ (3))) ; extern char *qecvt (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign) throw () __attribute__ ((__nonnull__ (3, 4))) ; extern char *qfcvt (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign) throw () __attribute__ ((__nonnull__ (3, 4))) ; extern char *qgcvt (long double __value, int __ndigit, char *__buf) throw () __attribute__ ((__nonnull__ (3))) ; extern int ecvt_r (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len) throw () __attribute__ ((__nonnull__ (3, 4, 5))); extern int fcvt_r (double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len) throw () __attribute__ ((__nonnull__ (3, 4, 5))); extern int qecvt_r (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len) throw () __attribute__ ((__nonnull__ (3, 4, 5))); extern int qfcvt_r (long double __value, int __ndigit, int *__restrict __decpt, int *__restrict __sign, char *__restrict __buf, size_t __len) throw () __attribute__ ((__nonnull__ (3, 4, 5))); extern int mblen (__const char *__s, size_t __n) throw () ; extern int mbtowc (wchar_t *__restrict __pwc, __const char *__restrict __s, size_t __n) throw () ; extern int wctomb (char *__s, wchar_t __wchar) throw () ; extern size_t mbstowcs (wchar_t *__restrict __pwcs, __const char *__restrict __s, size_t __n) throw (); extern size_t wcstombs (char *__restrict __s, __const wchar_t *__restrict __pwcs, size_t __n) throw (); extern int rpmatch (__const char *__response) throw () __attribute__ ((__nonnull__ (1))) ; extern int getsubopt (char **__restrict __optionp, char *__const *__restrict __tokens, char **__restrict __valuep) throw () __attribute__ ((__nonnull__ (1, 2, 3))) ; extern void setkey (__const char *__key) throw () __attribute__ ((__nonnull__ (1))); extern int posix_openpt (int __oflag) ; extern int grantpt (int __fd) throw (); extern int unlockpt (int __fd) throw (); extern char *ptsname (int __fd) throw () ; extern int ptsname_r (int __fd, char *__buf, size_t __buflen) throw () __attribute__ ((__nonnull__ (2))); extern int getpt (void); extern int getloadavg (double __loadavg[], int __nelem) throw () __attribute__ ((__nonnull__ (1))); } namespace std __attribute__ ((__visibility__ ("default"))) { using ::div_t; using ::ldiv_t; using ::abort; using ::abs; using ::atexit; using ::atof; using ::atoi; using ::atol; using ::bsearch; using ::calloc; using ::div; using ::exit; using ::free; using ::getenv; using ::labs; using ::ldiv; using ::malloc; using ::mblen; using ::mbstowcs; using ::mbtowc; using ::qsort; using ::rand; using ::realloc; using ::srand; using ::strtod; using ::strtol; using ::strtoul; using ::system; using ::wcstombs; using ::wctomb; inline long abs(long __i) { return labs(__i); } inline ldiv_t div(long __i, long __j) { return ldiv(__i, __j); } } namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { using ::lldiv_t; using ::_Exit; inline long long abs(long long __x) { return __x >= 0 ? __x : -__x; } using ::llabs; inline lldiv_t div(long long __n, long long __d) { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } using ::lldiv; using ::atoll; using ::strtoll; using ::strtoull; using ::strtof; using ::strtold; } namespace std __attribute__ ((__visibility__ ("default"))) { using ::__gnu_cxx::lldiv_t; using ::__gnu_cxx::_Exit; using ::__gnu_cxx::abs; using ::__gnu_cxx::llabs; using ::__gnu_cxx::div; using ::__gnu_cxx::lldiv; using ::__gnu_cxx::atoll; using ::__gnu_cxx::strtof; using ::__gnu_cxx::strtoll; using ::__gnu_cxx::strtoull; using ::__gnu_cxx::strtold; } namespace std __attribute__ ((__visibility__ ("default"))) { using ::va_list; } extern "C" { extern void *memcpy (void *__restrict __dest, __const void *__restrict __src, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern void *memmove (void *__dest, __const void *__src, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern void *memccpy (void *__restrict __dest, __const void *__restrict __src, int __c, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern void *memset (void *__s, int __c, size_t __n) throw () __attribute__ ((__nonnull__ (1))); extern int memcmp (__const void *__s1, __const void *__s2, size_t __n) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern void *memchr (__const void *__s, int __c, size_t __n) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern void *rawmemchr (__const void *__s, int __c) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern void *memrchr (__const void *__s, int __c, size_t __n) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern char *strcpy (char *__restrict __dest, __const char *__restrict __src) throw () __attribute__ ((__nonnull__ (1, 2))); extern char *strncpy (char *__restrict __dest, __const char *__restrict __src, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern char *strcat (char *__restrict __dest, __const char *__restrict __src) throw () __attribute__ ((__nonnull__ (1, 2))); extern char *strncat (char *__restrict __dest, __const char *__restrict __src, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern int strcmp (__const char *__s1, __const char *__s2) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern int strncmp (__const char *__s1, __const char *__s2, size_t __n) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern int strcoll (__const char *__s1, __const char *__s2) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern size_t strxfrm (char *__restrict __dest, __const char *__restrict __src, size_t __n) throw () __attribute__ ((__nonnull__ (2))); extern int strcoll_l (__const char *__s1, __const char *__s2, __locale_t __l) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 3))); extern size_t strxfrm_l (char *__dest, __const char *__src, size_t __n, __locale_t __l) throw () __attribute__ ((__nonnull__ (2, 4))); extern char *strdup (__const char *__s) throw () __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1))); extern char *strndup (__const char *__string, size_t __n) throw () __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1))); extern char *strchr (__const char *__s, int __c) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern char *strrchr (__const char *__s, int __c) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern char *strchrnul (__const char *__s, int __c) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern size_t strcspn (__const char *__s, __const char *__reject) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern size_t strspn (__const char *__s, __const char *__accept) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern char *strpbrk (__const char *__s, __const char *__accept) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern char *strstr (__const char *__haystack, __const char *__needle) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern char *strtok (char *__restrict __s, __const char *__restrict __delim) throw () __attribute__ ((__nonnull__ (2))); extern char *__strtok_r (char *__restrict __s, __const char *__restrict __delim, char **__restrict __save_ptr) throw () __attribute__ ((__nonnull__ (2, 3))); extern char *strtok_r (char *__restrict __s, __const char *__restrict __delim, char **__restrict __save_ptr) throw () __attribute__ ((__nonnull__ (2, 3))); extern char *strcasestr (__const char *__haystack, __const char *__needle) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern void *memmem (__const void *__haystack, size_t __haystacklen, __const void *__needle, size_t __needlelen) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 3))); extern void *__mempcpy (void *__restrict __dest, __const void *__restrict __src, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern void *mempcpy (void *__restrict __dest, __const void *__restrict __src, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern size_t strlen (__const char *__s) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern size_t strnlen (__const char *__string, size_t __maxlen) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern char *strerror (int __errnum) throw (); extern char *strerror_r (int __errnum, char *__buf, size_t __buflen) throw () __attribute__ ((__nonnull__ (2))); extern char *strerror_l (int __errnum, __locale_t __l) throw (); extern void __bzero (void *__s, size_t __n) throw () __attribute__ ((__nonnull__ (1))); extern void bcopy (__const void *__src, void *__dest, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern void bzero (void *__s, size_t __n) throw () __attribute__ ((__nonnull__ (1))); extern int bcmp (__const void *__s1, __const void *__s2, size_t __n) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern char *index (__const char *__s, int __c) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern char *rindex (__const char *__s, int __c) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))); extern int ffs (int __i) throw () __attribute__ ((__const__)); extern int ffsl (long int __l) throw () __attribute__ ((__const__)); __extension__ extern int ffsll (long long int __ll) throw () __attribute__ ((__const__)); extern int strcasecmp (__const char *__s1, __const char *__s2) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern int strncasecmp (__const char *__s1, __const char *__s2, size_t __n) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern int strcasecmp_l (__const char *__s1, __const char *__s2, __locale_t __loc) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 3))); extern int strncasecmp_l (__const char *__s1, __const char *__s2, size_t __n, __locale_t __loc) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 4))); extern char *strsep (char **__restrict __stringp, __const char *__restrict __delim) throw () __attribute__ ((__nonnull__ (1, 2))); extern int strverscmp (__const char *__s1, __const char *__s2) throw () __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2))); extern char *strsignal (int __sig) throw (); extern char *__stpcpy (char *__restrict __dest, __const char *__restrict __src) throw () __attribute__ ((__nonnull__ (1, 2))); extern char *stpcpy (char *__restrict __dest, __const char *__restrict __src) throw () __attribute__ ((__nonnull__ (1, 2))); extern char *__stpncpy (char *__restrict __dest, __const char *__restrict __src, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern char *stpncpy (char *__restrict __dest, __const char *__restrict __src, size_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern char *strfry (char *__string) throw () __attribute__ ((__nonnull__ (1))); extern void *memfrob (void *__s, size_t __n) throw () __attribute__ ((__nonnull__ (1))); extern char *basename (__const char *__filename) throw () __attribute__ ((__nonnull__ (1))); } namespace std __attribute__ ((__visibility__ ("default"))) { using ::memchr; using ::memcmp; using ::memcpy; using ::memmove; using ::memset; using ::strcat; using ::strcmp; using ::strcoll; using ::strcpy; using ::strcspn; using ::strerror; using ::strlen; using ::strncat; using ::strncmp; using ::strncpy; using ::strspn; using ::strtok; using ::strxfrm; inline void* memchr(void* __p, int __c, size_t __n) { return memchr(const_cast(__p), __c, __n); } using ::strchr; inline char* strchr(char* __s1, int __n) { return __builtin_strchr(const_cast(__s1), __n); } using ::strpbrk; inline char* strpbrk(char* __s1, const char* __s2) { return __builtin_strpbrk(const_cast(__s1), __s2); } using ::strrchr; inline char* strrchr(char* __s1, int __n) { return __builtin_strrchr(const_cast(__s1), __n); } using ::strstr; inline char* strstr(char* __s1, const char* __s2) { return __builtin_strstr(const_cast(__s1), __s2); } } namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { template class __normal_iterator; } namespace std __attribute__ ((__visibility__ ("default"))) { struct __true_type { }; struct __false_type { }; template struct __truth_type { typedef __false_type __type; }; template<> struct __truth_type { typedef __true_type __type; }; template struct __traitor { enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; typedef typename __truth_type<__value>::__type __type; }; template struct __are_same { enum { __value = 0 }; typedef __false_type __type; }; template struct __are_same<_Tp, _Tp> { enum { __value = 1 }; typedef __true_type __type; }; template struct __is_void { enum { __value = 0 }; typedef __false_type __type; }; template<> struct __is_void { enum { __value = 1 }; typedef __true_type __type; }; template struct __is_integer { enum { __value = 0 }; typedef __false_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer { enum { __value = 1 }; typedef __true_type __type; }; template struct __is_floating { enum { __value = 0 }; typedef __false_type __type; }; template<> struct __is_floating { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_floating { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_floating { enum { __value = 1 }; typedef __true_type __type; }; template struct __is_pointer { enum { __value = 0 }; typedef __false_type __type; }; template struct __is_pointer<_Tp*> { enum { __value = 1 }; typedef __true_type __type; }; template struct __is_normal_iterator { enum { __value = 0 }; typedef __false_type __type; }; template struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, _Container> > { enum { __value = 1 }; typedef __true_type __type; }; template struct __is_arithmetic : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > { }; template struct __is_fundamental : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > { }; template struct __is_scalar : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > { }; template struct __is_char { enum { __value = 0 }; typedef __false_type __type; }; template<> struct __is_char { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_char { enum { __value = 1 }; typedef __true_type __type; }; template struct __is_byte { enum { __value = 0 }; typedef __false_type __type; }; template<> struct __is_byte { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_byte { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_byte { enum { __value = 1 }; typedef __true_type __type; }; template struct __is_move_iterator { enum { __value = 0 }; typedef __false_type __type; }; } namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { template struct __enable_if { }; template struct __enable_if { typedef _Tp __type; }; template struct __conditional_type { typedef _Iftrue __type; }; template struct __conditional_type { typedef _Iffalse __type; }; template struct __add_unsigned { private: typedef __enable_if::__value, _Tp> __if_type; public: typedef typename __if_type::__type __type; }; template<> struct __add_unsigned { typedef unsigned char __type; }; template<> struct __add_unsigned { typedef unsigned char __type; }; template<> struct __add_unsigned { typedef unsigned short __type; }; template<> struct __add_unsigned { typedef unsigned int __type; }; template<> struct __add_unsigned { typedef unsigned long __type; }; template<> struct __add_unsigned { typedef unsigned long long __type; }; template<> struct __add_unsigned; template<> struct __add_unsigned; template struct __remove_unsigned { private: typedef __enable_if::__value, _Tp> __if_type; public: typedef typename __if_type::__type __type; }; template<> struct __remove_unsigned { typedef signed char __type; }; template<> struct __remove_unsigned { typedef signed char __type; }; template<> struct __remove_unsigned { typedef short __type; }; template<> struct __remove_unsigned { typedef int __type; }; template<> struct __remove_unsigned { typedef long __type; }; template<> struct __remove_unsigned { typedef long long __type; }; template<> struct __remove_unsigned; template<> struct __remove_unsigned; template inline bool __is_null_pointer(_Type* __ptr) { return __ptr == 0; } template inline bool __is_null_pointer(_Type) { return false; } template::__value> struct __promote { typedef double __type; }; template struct __promote<_Tp, false> { typedef _Tp __type; }; template struct __promote_2 { private: typedef typename __promote<_Tp>::__type __type1; typedef typename __promote<_Up>::__type __type2; public: typedef __typeof__(__type1() + __type2()) __type; }; template struct __promote_3 { private: typedef typename __promote<_Tp>::__type __type1; typedef typename __promote<_Up>::__type __type2; typedef typename __promote<_Vp>::__type __type3; public: typedef __typeof__(__type1() + __type2() + __type3()) __type; }; template struct __promote_4 { private: typedef typename __promote<_Tp>::__type __type1; typedef typename __promote<_Up>::__type __type2; typedef typename __promote<_Vp>::__type __type3; typedef typename __promote<_Wp>::__type __type4; public: typedef __typeof__(__type1() + __type2() + __type3() + __type4()) __type; }; } extern "C" { typedef float float_t; typedef double double_t; extern double acos (double __x) throw (); extern double __acos (double __x) throw (); extern double asin (double __x) throw (); extern double __asin (double __x) throw (); extern double atan (double __x) throw (); extern double __atan (double __x) throw (); extern double atan2 (double __y, double __x) throw (); extern double __atan2 (double __y, double __x) throw (); extern double cos (double __x) throw (); extern double __cos (double __x) throw (); extern double sin (double __x) throw (); extern double __sin (double __x) throw (); extern double tan (double __x) throw (); extern double __tan (double __x) throw (); extern double cosh (double __x) throw (); extern double __cosh (double __x) throw (); extern double sinh (double __x) throw (); extern double __sinh (double __x) throw (); extern double tanh (double __x) throw (); extern double __tanh (double __x) throw (); extern void sincos (double __x, double *__sinx, double *__cosx) throw (); extern void __sincos (double __x, double *__sinx, double *__cosx) throw (); extern double acosh (double __x) throw (); extern double __acosh (double __x) throw (); extern double asinh (double __x) throw (); extern double __asinh (double __x) throw (); extern double atanh (double __x) throw (); extern double __atanh (double __x) throw (); extern double exp (double __x) throw (); extern double __exp (double __x) throw (); extern double frexp (double __x, int *__exponent) throw (); extern double __frexp (double __x, int *__exponent) throw (); extern double ldexp (double __x, int __exponent) throw (); extern double __ldexp (double __x, int __exponent) throw (); extern double log (double __x) throw (); extern double __log (double __x) throw (); extern double log10 (double __x) throw (); extern double __log10 (double __x) throw (); extern double modf (double __x, double *__iptr) throw (); extern double __modf (double __x, double *__iptr) throw (); extern double exp10 (double __x) throw (); extern double __exp10 (double __x) throw (); extern double pow10 (double __x) throw (); extern double __pow10 (double __x) throw (); extern double expm1 (double __x) throw (); extern double __expm1 (double __x) throw (); extern double log1p (double __x) throw (); extern double __log1p (double __x) throw (); extern double logb (double __x) throw (); extern double __logb (double __x) throw (); extern double exp2 (double __x) throw (); extern double __exp2 (double __x) throw (); extern double log2 (double __x) throw (); extern double __log2 (double __x) throw (); extern double pow (double __x, double __y) throw (); extern double __pow (double __x, double __y) throw (); extern double sqrt (double __x) throw (); extern double __sqrt (double __x) throw (); extern double hypot (double __x, double __y) throw (); extern double __hypot (double __x, double __y) throw (); extern double cbrt (double __x) throw (); extern double __cbrt (double __x) throw (); extern double ceil (double __x) throw () __attribute__ ((__const__)); extern double __ceil (double __x) throw () __attribute__ ((__const__)); extern double fabs (double __x) throw () __attribute__ ((__const__)); extern double __fabs (double __x) throw () __attribute__ ((__const__)); extern double floor (double __x) throw () __attribute__ ((__const__)); extern double __floor (double __x) throw () __attribute__ ((__const__)); extern double fmod (double __x, double __y) throw (); extern double __fmod (double __x, double __y) throw (); extern int __isinf (double __value) throw () __attribute__ ((__const__)); extern int __finite (double __value) throw () __attribute__ ((__const__)); extern int isinf (double __value) throw () __attribute__ ((__const__)); extern int finite (double __value) throw () __attribute__ ((__const__)); extern double drem (double __x, double __y) throw (); extern double __drem (double __x, double __y) throw (); extern double significand (double __x) throw (); extern double __significand (double __x) throw (); extern double copysign (double __x, double __y) throw () __attribute__ ((__const__)); extern double __copysign (double __x, double __y) throw () __attribute__ ((__const__)); extern double nan (__const char *__tagb) throw () __attribute__ ((__const__)); extern double __nan (__const char *__tagb) throw () __attribute__ ((__const__)); extern int __isnan (double __value) throw () __attribute__ ((__const__)); extern int isnan (double __value) throw () __attribute__ ((__const__)); extern double j0 (double) throw (); extern double __j0 (double) throw (); extern double j1 (double) throw (); extern double __j1 (double) throw (); extern double jn (int, double) throw (); extern double __jn (int, double) throw (); extern double y0 (double) throw (); extern double __y0 (double) throw (); extern double y1 (double) throw (); extern double __y1 (double) throw (); extern double yn (int, double) throw (); extern double __yn (int, double) throw (); extern double erf (double) throw (); extern double __erf (double) throw (); extern double erfc (double) throw (); extern double __erfc (double) throw (); extern double lgamma (double) throw (); extern double __lgamma (double) throw (); extern double tgamma (double) throw (); extern double __tgamma (double) throw (); extern double gamma (double) throw (); extern double __gamma (double) throw (); extern double lgamma_r (double, int *__signgamp) throw (); extern double __lgamma_r (double, int *__signgamp) throw (); extern double rint (double __x) throw (); extern double __rint (double __x) throw (); extern double nextafter (double __x, double __y) throw () __attribute__ ((__const__)); extern double __nextafter (double __x, double __y) throw () __attribute__ ((__const__)); extern double nexttoward (double __x, long double __y) throw () __attribute__ ((__const__)); extern double __nexttoward (double __x, long double __y) throw () __attribute__ ((__const__)); extern double remainder (double __x, double __y) throw (); extern double __remainder (double __x, double __y) throw (); extern double scalbn (double __x, int __n) throw (); extern double __scalbn (double __x, int __n) throw (); extern int ilogb (double __x) throw (); extern int __ilogb (double __x) throw (); extern double scalbln (double __x, long int __n) throw (); extern double __scalbln (double __x, long int __n) throw (); extern double nearbyint (double __x) throw (); extern double __nearbyint (double __x) throw (); extern double round (double __x) throw () __attribute__ ((__const__)); extern double __round (double __x) throw () __attribute__ ((__const__)); extern double trunc (double __x) throw () __attribute__ ((__const__)); extern double __trunc (double __x) throw () __attribute__ ((__const__)); extern double remquo (double __x, double __y, int *__quo) throw (); extern double __remquo (double __x, double __y, int *__quo) throw (); extern long int lrint (double __x) throw (); extern long int __lrint (double __x) throw (); extern long long int llrint (double __x) throw (); extern long long int __llrint (double __x) throw (); extern long int lround (double __x) throw (); extern long int __lround (double __x) throw (); extern long long int llround (double __x) throw (); extern long long int __llround (double __x) throw (); extern double fdim (double __x, double __y) throw (); extern double __fdim (double __x, double __y) throw (); extern double fmax (double __x, double __y) throw (); extern double __fmax (double __x, double __y) throw (); extern double fmin (double __x, double __y) throw (); extern double __fmin (double __x, double __y) throw (); extern int __fpclassify (double __value) throw () __attribute__ ((__const__)); extern int __signbit (double __value) throw () __attribute__ ((__const__)); extern double fma (double __x, double __y, double __z) throw (); extern double __fma (double __x, double __y, double __z) throw (); extern double scalb (double __x, double __n) throw (); extern double __scalb (double __x, double __n) throw (); extern float acosf (float __x) throw (); extern float __acosf (float __x) throw (); extern float asinf (float __x) throw (); extern float __asinf (float __x) throw (); extern float atanf (float __x) throw (); extern float __atanf (float __x) throw (); extern float atan2f (float __y, float __x) throw (); extern float __atan2f (float __y, float __x) throw (); extern float cosf (float __x) throw (); extern float __cosf (float __x) throw (); extern float sinf (float __x) throw (); extern float __sinf (float __x) throw (); extern float tanf (float __x) throw (); extern float __tanf (float __x) throw (); extern float coshf (float __x) throw (); extern float __coshf (float __x) throw (); extern float sinhf (float __x) throw (); extern float __sinhf (float __x) throw (); extern float tanhf (float __x) throw (); extern float __tanhf (float __x) throw (); extern void sincosf (float __x, float *__sinx, float *__cosx) throw (); extern void __sincosf (float __x, float *__sinx, float *__cosx) throw (); extern float acoshf (float __x) throw (); extern float __acoshf (float __x) throw (); extern float asinhf (float __x) throw (); extern float __asinhf (float __x) throw (); extern float atanhf (float __x) throw (); extern float __atanhf (float __x) throw (); extern float expf (float __x) throw (); extern float __expf (float __x) throw (); extern float frexpf (float __x, int *__exponent) throw (); extern float __frexpf (float __x, int *__exponent) throw (); extern float ldexpf (float __x, int __exponent) throw (); extern float __ldexpf (float __x, int __exponent) throw (); extern float logf (float __x) throw (); extern float __logf (float __x) throw (); extern float log10f (float __x) throw (); extern float __log10f (float __x) throw (); extern float modff (float __x, float *__iptr) throw (); extern float __modff (float __x, float *__iptr) throw (); extern float exp10f (float __x) throw (); extern float __exp10f (float __x) throw (); extern float pow10f (float __x) throw (); extern float __pow10f (float __x) throw (); extern float expm1f (float __x) throw (); extern float __expm1f (float __x) throw (); extern float log1pf (float __x) throw (); extern float __log1pf (float __x) throw (); extern float logbf (float __x) throw (); extern float __logbf (float __x) throw (); extern float exp2f (float __x) throw (); extern float __exp2f (float __x) throw (); extern float log2f (float __x) throw (); extern float __log2f (float __x) throw (); extern float powf (float __x, float __y) throw (); extern float __powf (float __x, float __y) throw (); extern float sqrtf (float __x) throw (); extern float __sqrtf (float __x) throw (); extern float hypotf (float __x, float __y) throw (); extern float __hypotf (float __x, float __y) throw (); extern float cbrtf (float __x) throw (); extern float __cbrtf (float __x) throw (); extern float ceilf (float __x) throw () __attribute__ ((__const__)); extern float __ceilf (float __x) throw () __attribute__ ((__const__)); extern float fabsf (float __x) throw () __attribute__ ((__const__)); extern float __fabsf (float __x) throw () __attribute__ ((__const__)); extern float floorf (float __x) throw () __attribute__ ((__const__)); extern float __floorf (float __x) throw () __attribute__ ((__const__)); extern float fmodf (float __x, float __y) throw (); extern float __fmodf (float __x, float __y) throw (); extern int __isinff (float __value) throw () __attribute__ ((__const__)); extern int __finitef (float __value) throw () __attribute__ ((__const__)); extern int isinff (float __value) throw () __attribute__ ((__const__)); extern int finitef (float __value) throw () __attribute__ ((__const__)); extern float dremf (float __x, float __y) throw (); extern float __dremf (float __x, float __y) throw (); extern float significandf (float __x) throw (); extern float __significandf (float __x) throw (); extern float copysignf (float __x, float __y) throw () __attribute__ ((__const__)); extern float __copysignf (float __x, float __y) throw () __attribute__ ((__const__)); extern float nanf (__const char *__tagb) throw () __attribute__ ((__const__)); extern float __nanf (__const char *__tagb) throw () __attribute__ ((__const__)); extern int __isnanf (float __value) throw () __attribute__ ((__const__)); extern int isnanf (float __value) throw () __attribute__ ((__const__)); extern float j0f (float) throw (); extern float __j0f (float) throw (); extern float j1f (float) throw (); extern float __j1f (float) throw (); extern float jnf (int, float) throw (); extern float __jnf (int, float) throw (); extern float y0f (float) throw (); extern float __y0f (float) throw (); extern float y1f (float) throw (); extern float __y1f (float) throw (); extern float ynf (int, float) throw (); extern float __ynf (int, float) throw (); extern float erff (float) throw (); extern float __erff (float) throw (); extern float erfcf (float) throw (); extern float __erfcf (float) throw (); extern float lgammaf (float) throw (); extern float __lgammaf (float) throw (); extern float tgammaf (float) throw (); extern float __tgammaf (float) throw (); extern float gammaf (float) throw (); extern float __gammaf (float) throw (); extern float lgammaf_r (float, int *__signgamp) throw (); extern float __lgammaf_r (float, int *__signgamp) throw (); extern float rintf (float __x) throw (); extern float __rintf (float __x) throw (); extern float nextafterf (float __x, float __y) throw () __attribute__ ((__const__)); extern float __nextafterf (float __x, float __y) throw () __attribute__ ((__const__)); extern float nexttowardf (float __x, long double __y) throw () __attribute__ ((__const__)); extern float __nexttowardf (float __x, long double __y) throw () __attribute__ ((__const__)); extern float remainderf (float __x, float __y) throw (); extern float __remainderf (float __x, float __y) throw (); extern float scalbnf (float __x, int __n) throw (); extern float __scalbnf (float __x, int __n) throw (); extern int ilogbf (float __x) throw (); extern int __ilogbf (float __x) throw (); extern float scalblnf (float __x, long int __n) throw (); extern float __scalblnf (float __x, long int __n) throw (); extern float nearbyintf (float __x) throw (); extern float __nearbyintf (float __x) throw (); extern float roundf (float __x) throw () __attribute__ ((__const__)); extern float __roundf (float __x) throw () __attribute__ ((__const__)); extern float truncf (float __x) throw () __attribute__ ((__const__)); extern float __truncf (float __x) throw () __attribute__ ((__const__)); extern float remquof (float __x, float __y, int *__quo) throw (); extern float __remquof (float __x, float __y, int *__quo) throw (); extern long int lrintf (float __x) throw (); extern long int __lrintf (float __x) throw (); extern long long int llrintf (float __x) throw (); extern long long int __llrintf (float __x) throw (); extern long int lroundf (float __x) throw (); extern long int __lroundf (float __x) throw (); extern long long int llroundf (float __x) throw (); extern long long int __llroundf (float __x) throw (); extern float fdimf (float __x, float __y) throw (); extern float __fdimf (float __x, float __y) throw (); extern float fmaxf (float __x, float __y) throw (); extern float __fmaxf (float __x, float __y) throw (); extern float fminf (float __x, float __y) throw (); extern float __fminf (float __x, float __y) throw (); extern int __fpclassifyf (float __value) throw () __attribute__ ((__const__)); extern int __signbitf (float __value) throw () __attribute__ ((__const__)); extern float fmaf (float __x, float __y, float __z) throw (); extern float __fmaf (float __x, float __y, float __z) throw (); extern float scalbf (float __x, float __n) throw (); extern float __scalbf (float __x, float __n) throw (); extern long double acosl (long double __x) throw (); extern long double __acosl (long double __x) throw (); extern long double asinl (long double __x) throw (); extern long double __asinl (long double __x) throw (); extern long double atanl (long double __x) throw (); extern long double __atanl (long double __x) throw (); extern long double atan2l (long double __y, long double __x) throw (); extern long double __atan2l (long double __y, long double __x) throw (); extern long double cosl (long double __x) throw (); extern long double __cosl (long double __x) throw (); extern long double sinl (long double __x) throw (); extern long double __sinl (long double __x) throw (); extern long double tanl (long double __x) throw (); extern long double __tanl (long double __x) throw (); extern long double coshl (long double __x) throw (); extern long double __coshl (long double __x) throw (); extern long double sinhl (long double __x) throw (); extern long double __sinhl (long double __x) throw (); extern long double tanhl (long double __x) throw (); extern long double __tanhl (long double __x) throw (); extern void sincosl (long double __x, long double *__sinx, long double *__cosx) throw (); extern void __sincosl (long double __x, long double *__sinx, long double *__cosx) throw (); extern long double acoshl (long double __x) throw (); extern long double __acoshl (long double __x) throw (); extern long double asinhl (long double __x) throw (); extern long double __asinhl (long double __x) throw (); extern long double atanhl (long double __x) throw (); extern long double __atanhl (long double __x) throw (); extern long double expl (long double __x) throw (); extern long double __expl (long double __x) throw (); extern long double frexpl (long double __x, int *__exponent) throw (); extern long double __frexpl (long double __x, int *__exponent) throw (); extern long double ldexpl (long double __x, int __exponent) throw (); extern long double __ldexpl (long double __x, int __exponent) throw (); extern long double logl (long double __x) throw (); extern long double __logl (long double __x) throw (); extern long double log10l (long double __x) throw (); extern long double __log10l (long double __x) throw (); extern long double modfl (long double __x, long double *__iptr) throw (); extern long double __modfl (long double __x, long double *__iptr) throw (); extern long double exp10l (long double __x) throw (); extern long double __exp10l (long double __x) throw (); extern long double pow10l (long double __x) throw (); extern long double __pow10l (long double __x) throw (); extern long double expm1l (long double __x) throw (); extern long double __expm1l (long double __x) throw (); extern long double log1pl (long double __x) throw (); extern long double __log1pl (long double __x) throw (); extern long double logbl (long double __x) throw (); extern long double __logbl (long double __x) throw (); extern long double exp2l (long double __x) throw (); extern long double __exp2l (long double __x) throw (); extern long double log2l (long double __x) throw (); extern long double __log2l (long double __x) throw (); extern long double powl (long double __x, long double __y) throw (); extern long double __powl (long double __x, long double __y) throw (); extern long double sqrtl (long double __x) throw (); extern long double __sqrtl (long double __x) throw (); extern long double hypotl (long double __x, long double __y) throw (); extern long double __hypotl (long double __x, long double __y) throw (); extern long double cbrtl (long double __x) throw (); extern long double __cbrtl (long double __x) throw (); extern long double ceill (long double __x) throw () __attribute__ ((__const__)); extern long double __ceill (long double __x) throw () __attribute__ ((__const__)); extern long double fabsl (long double __x) throw () __attribute__ ((__const__)); extern long double __fabsl (long double __x) throw () __attribute__ ((__const__)); extern long double floorl (long double __x) throw () __attribute__ ((__const__)); extern long double __floorl (long double __x) throw () __attribute__ ((__const__)); extern long double fmodl (long double __x, long double __y) throw (); extern long double __fmodl (long double __x, long double __y) throw (); extern int __isinfl (long double __value) throw () __attribute__ ((__const__)); extern int __finitel (long double __value) throw () __attribute__ ((__const__)); extern int isinfl (long double __value) throw () __attribute__ ((__const__)); extern int finitel (long double __value) throw () __attribute__ ((__const__)); extern long double dreml (long double __x, long double __y) throw (); extern long double __dreml (long double __x, long double __y) throw (); extern long double significandl (long double __x) throw (); extern long double __significandl (long double __x) throw (); extern long double copysignl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double __copysignl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double nanl (__const char *__tagb) throw () __attribute__ ((__const__)); extern long double __nanl (__const char *__tagb) throw () __attribute__ ((__const__)); extern int __isnanl (long double __value) throw () __attribute__ ((__const__)); extern int isnanl (long double __value) throw () __attribute__ ((__const__)); extern long double j0l (long double) throw (); extern long double __j0l (long double) throw (); extern long double j1l (long double) throw (); extern long double __j1l (long double) throw (); extern long double jnl (int, long double) throw (); extern long double __jnl (int, long double) throw (); extern long double y0l (long double) throw (); extern long double __y0l (long double) throw (); extern long double y1l (long double) throw (); extern long double __y1l (long double) throw (); extern long double ynl (int, long double) throw (); extern long double __ynl (int, long double) throw (); extern long double erfl (long double) throw (); extern long double __erfl (long double) throw (); extern long double erfcl (long double) throw (); extern long double __erfcl (long double) throw (); extern long double lgammal (long double) throw (); extern long double __lgammal (long double) throw (); extern long double tgammal (long double) throw (); extern long double __tgammal (long double) throw (); extern long double gammal (long double) throw (); extern long double __gammal (long double) throw (); extern long double lgammal_r (long double, int *__signgamp) throw (); extern long double __lgammal_r (long double, int *__signgamp) throw (); extern long double rintl (long double __x) throw (); extern long double __rintl (long double __x) throw (); extern long double nextafterl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double __nextafterl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double nexttowardl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double __nexttowardl (long double __x, long double __y) throw () __attribute__ ((__const__)); extern long double remainderl (long double __x, long double __y) throw (); extern long double __remainderl (long double __x, long double __y) throw (); extern long double scalbnl (long double __x, int __n) throw (); extern long double __scalbnl (long double __x, int __n) throw (); extern int ilogbl (long double __x) throw (); extern int __ilogbl (long double __x) throw (); extern long double scalblnl (long double __x, long int __n) throw (); extern long double __scalblnl (long double __x, long int __n) throw (); extern long double nearbyintl (long double __x) throw (); extern long double __nearbyintl (long double __x) throw (); extern long double roundl (long double __x) throw () __attribute__ ((__const__)); extern long double __roundl (long double __x) throw () __attribute__ ((__const__)); extern long double truncl (long double __x) throw () __attribute__ ((__const__)); extern long double __truncl (long double __x) throw () __attribute__ ((__const__)); extern long double remquol (long double __x, long double __y, int *__quo) throw (); extern long double __remquol (long double __x, long double __y, int *__quo) throw (); extern long int lrintl (long double __x) throw (); extern long int __lrintl (long double __x) throw (); extern long long int llrintl (long double __x) throw (); extern long long int __llrintl (long double __x) throw (); extern long int lroundl (long double __x) throw (); extern long int __lroundl (long double __x) throw (); extern long long int llroundl (long double __x) throw (); extern long long int __llroundl (long double __x) throw (); extern long double fdiml (long double __x, long double __y) throw (); extern long double __fdiml (long double __x, long double __y) throw (); extern long double fmaxl (long double __x, long double __y) throw (); extern long double __fmaxl (long double __x, long double __y) throw (); extern long double fminl (long double __x, long double __y) throw (); extern long double __fminl (long double __x, long double __y) throw (); extern int __fpclassifyl (long double __value) throw () __attribute__ ((__const__)); extern int __signbitl (long double __value) throw () __attribute__ ((__const__)); extern long double fmal (long double __x, long double __y, long double __z) throw (); extern long double __fmal (long double __x, long double __y, long double __z) throw (); extern long double scalbl (long double __x, long double __n) throw (); extern long double __scalbl (long double __x, long double __n) throw (); extern int signgam; enum { FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_NORMAL }; typedef enum { _IEEE_ = -1, _SVID_, _XOPEN_, _POSIX_, _ISOC_ } _LIB_VERSION_TYPE; extern _LIB_VERSION_TYPE _LIB_VERSION; struct __exception { int type; char *name; double arg1; double arg2; double retval; }; extern int matherr (struct __exception *__exc) throw (); extern __inline __attribute__ ((__gnu_inline__)) int __signbitf (float __x) throw () { __extension__ union { float __f; int __i; } __u = { __f: __x }; return __u.__i < 0; } extern __inline __attribute__ ((__gnu_inline__)) int __signbit (double __x) throw () { __extension__ union { double __d; int __i[2]; } __u = { __d: __x }; return __u.__i[1] < 0; } extern __inline __attribute__ ((__gnu_inline__)) int __signbitl (long double __x) throw () { __extension__ union { long double __l; int __i[3]; } __u = { __l: __x }; return (__u.__i[2] & 0x8000) != 0; } } namespace std __attribute__ ((__visibility__ ("default"))) { template _Tp __cmath_power(_Tp, unsigned int); template inline _Tp __pow_helper(_Tp __x, int __n) { return __n < 0 ? _Tp(1)/__cmath_power(__x, -__n) : __cmath_power(__x, __n); } inline double abs(double __x) { return __builtin_fabs(__x); } inline float abs(float __x) { return __builtin_fabsf(__x); } inline long double abs(long double __x) { return __builtin_fabsl(__x); } using ::acos; inline float acos(float __x) { return __builtin_acosf(__x); } inline long double acos(long double __x) { return __builtin_acosl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type acos(_Tp __x) { return __builtin_acos(__x); } using ::asin; inline float asin(float __x) { return __builtin_asinf(__x); } inline long double asin(long double __x) { return __builtin_asinl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type asin(_Tp __x) { return __builtin_asin(__x); } using ::atan; inline float atan(float __x) { return __builtin_atanf(__x); } inline long double atan(long double __x) { return __builtin_atanl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type atan(_Tp __x) { return __builtin_atan(__x); } using ::atan2; inline float atan2(float __y, float __x) { return __builtin_atan2f(__y, __x); } inline long double atan2(long double __y, long double __x) { return __builtin_atan2l(__y, __x); } template inline typename __gnu_cxx::__promote_2< typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value, _Tp>::__type, _Up>::__type atan2(_Tp __y, _Up __x) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return atan2(__type(__y), __type(__x)); } using ::ceil; inline float ceil(float __x) { return __builtin_ceilf(__x); } inline long double ceil(long double __x) { return __builtin_ceill(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type ceil(_Tp __x) { return __builtin_ceil(__x); } using ::cos; inline float cos(float __x) { return __builtin_cosf(__x); } inline long double cos(long double __x) { return __builtin_cosl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cos(_Tp __x) { return __builtin_cos(__x); } using ::cosh; inline float cosh(float __x) { return __builtin_coshf(__x); } inline long double cosh(long double __x) { return __builtin_coshl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cosh(_Tp __x) { return __builtin_cosh(__x); } using ::exp; inline float exp(float __x) { return __builtin_expf(__x); } inline long double exp(long double __x) { return __builtin_expl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type exp(_Tp __x) { return __builtin_exp(__x); } using ::fabs; inline float fabs(float __x) { return __builtin_fabsf(__x); } inline long double fabs(long double __x) { return __builtin_fabsl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type fabs(_Tp __x) { return __builtin_fabs(__x); } using ::floor; inline float floor(float __x) { return __builtin_floorf(__x); } inline long double floor(long double __x) { return __builtin_floorl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type floor(_Tp __x) { return __builtin_floor(__x); } using ::fmod; inline float fmod(float __x, float __y) { return __builtin_fmodf(__x, __y); } inline long double fmod(long double __x, long double __y) { return __builtin_fmodl(__x, __y); } using ::frexp; inline float frexp(float __x, int* __exp) { return __builtin_frexpf(__x, __exp); } inline long double frexp(long double __x, int* __exp) { return __builtin_frexpl(__x, __exp); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type frexp(_Tp __x, int* __exp) { return __builtin_frexp(__x, __exp); } using ::ldexp; inline float ldexp(float __x, int __exp) { return __builtin_ldexpf(__x, __exp); } inline long double ldexp(long double __x, int __exp) { return __builtin_ldexpl(__x, __exp); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type ldexp(_Tp __x, int __exp) { return __builtin_ldexp(__x, __exp); } using ::log; inline float log(float __x) { return __builtin_logf(__x); } inline long double log(long double __x) { return __builtin_logl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log(_Tp __x) { return __builtin_log(__x); } using ::log10; inline float log10(float __x) { return __builtin_log10f(__x); } inline long double log10(long double __x) { return __builtin_log10l(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log10(_Tp __x) { return __builtin_log10(__x); } using ::modf; inline float modf(float __x, float* __iptr) { return __builtin_modff(__x, __iptr); } inline long double modf(long double __x, long double* __iptr) { return __builtin_modfl(__x, __iptr); } using ::pow; inline float pow(float __x, float __y) { return __builtin_powf(__x, __y); } inline long double pow(long double __x, long double __y) { return __builtin_powl(__x, __y); } inline double pow(double __x, int __i) { return __builtin_powi(__x, __i); } inline float pow(float __x, int __n) { return __builtin_powif(__x, __n); } inline long double pow(long double __x, int __n) { return __builtin_powil(__x, __n); } template inline typename __gnu_cxx::__promote_2< typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value, _Tp>::__type, _Up>::__type pow(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return pow(__type(__x), __type(__y)); } using ::sin; inline float sin(float __x) { return __builtin_sinf(__x); } inline long double sin(long double __x) { return __builtin_sinl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sin(_Tp __x) { return __builtin_sin(__x); } using ::sinh; inline float sinh(float __x) { return __builtin_sinhf(__x); } inline long double sinh(long double __x) { return __builtin_sinhl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sinh(_Tp __x) { return __builtin_sinh(__x); } using ::sqrt; inline float sqrt(float __x) { return __builtin_sqrtf(__x); } inline long double sqrt(long double __x) { return __builtin_sqrtl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sqrt(_Tp __x) { return __builtin_sqrt(__x); } using ::tan; inline float tan(float __x) { return __builtin_tanf(__x); } inline long double tan(long double __x) { return __builtin_tanl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tan(_Tp __x) { return __builtin_tan(__x); } using ::tanh; inline float tanh(float __x) { return __builtin_tanhf(__x); } inline long double tanh(long double __x) { return __builtin_tanhl(__x); } template inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tanh(_Tp __x) { return __builtin_tanh(__x); } } namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { template inline int __capture_fpclassify(_Tp __f) { return (sizeof (__f) == sizeof (float) ? __fpclassifyf (__f) : sizeof (__f) == sizeof (double) ? __fpclassify (__f) : __fpclassifyl (__f)); } } namespace std __attribute__ ((__visibility__ ("default"))) { template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type fpclassify(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return ::__gnu_cxx::__capture_fpclassify(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isfinite(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isfinite(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isinf(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isinf(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isnan(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isnan(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isnormal(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isnormal(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type signbit(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_signbit(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isgreater(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isgreater(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isgreaterequal(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isgreaterequal(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isless(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isless(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type islessequal(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_islessequal(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type islessgreater(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_islessgreater(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isunordered(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isunordered(__type(__f1), __type(__f2)); } } namespace std __attribute__ ((__visibility__ ("default"))) { template inline _Tp __cmath_power(_Tp __x, unsigned int __n) { _Tp __y = __n % 2 ? __x : _Tp(1); while (__n >>= 1) { __x = __x * __x; if (__n % 2) __y = __y * __x; } return __y; } } extern "C" { struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; long int tm_gmtoff; __const char *tm_zone; }; struct itimerspec { struct timespec it_interval; struct timespec it_value; }; struct sigevent; extern clock_t clock (void) throw (); extern time_t time (time_t *__timer) throw (); extern double difftime (time_t __time1, time_t __time0) throw () __attribute__ ((__const__)); extern time_t mktime (struct tm *__tp) throw (); extern size_t strftime (char *__restrict __s, size_t __maxsize, __const char *__restrict __format, __const struct tm *__restrict __tp) throw (); extern char *strptime (__const char *__restrict __s, __const char *__restrict __fmt, struct tm *__tp) throw (); extern size_t strftime_l (char *__restrict __s, size_t __maxsize, __const char *__restrict __format, __const struct tm *__restrict __tp, __locale_t __loc) throw (); extern char *strptime_l (__const char *__restrict __s, __const char *__restrict __fmt, struct tm *__tp, __locale_t __loc) throw (); extern struct tm *gmtime (__const time_t *__timer) throw (); extern struct tm *localtime (__const time_t *__timer) throw (); extern struct tm *gmtime_r (__const time_t *__restrict __timer, struct tm *__restrict __tp) throw (); extern struct tm *localtime_r (__const time_t *__restrict __timer, struct tm *__restrict __tp) throw (); extern char *asctime (__const struct tm *__tp) throw (); extern char *ctime (__const time_t *__timer) throw (); extern char *asctime_r (__const struct tm *__restrict __tp, char *__restrict __buf) throw (); extern char *ctime_r (__const time_t *__restrict __timer, char *__restrict __buf) throw (); extern char *__tzname[2]; extern int __daylight; extern long int __timezone; extern char *tzname[2]; extern void tzset (void) throw (); extern int daylight; extern long int timezone; extern int stime (__const time_t *__when) throw (); extern time_t timegm (struct tm *__tp) throw (); extern time_t timelocal (struct tm *__tp) throw (); extern int dysize (int __year) throw () __attribute__ ((__const__)); extern int nanosleep (__const struct timespec *__requested_time, struct timespec *__remaining); extern int clock_getres (clockid_t __clock_id, struct timespec *__res) throw (); extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) throw (); extern int clock_settime (clockid_t __clock_id, __const struct timespec *__tp) throw (); extern int clock_nanosleep (clockid_t __clock_id, int __flags, __const struct timespec *__req, struct timespec *__rem); extern int clock_getcpuclockid (pid_t __pid, clockid_t *__clock_id) throw (); extern int timer_create (clockid_t __clock_id, struct sigevent *__restrict __evp, timer_t *__restrict __timerid) throw (); extern int timer_delete (timer_t __timerid) throw (); extern int timer_settime (timer_t __timerid, int __flags, __const struct itimerspec *__restrict __value, struct itimerspec *__restrict __ovalue) throw (); extern int timer_gettime (timer_t __timerid, struct itimerspec *__value) throw (); extern int timer_getoverrun (timer_t __timerid) throw (); extern int getdate_err; extern struct tm *getdate (__const char *__string); extern int getdate_r (__const char *__restrict __string, struct tm *__restrict __resbufp); } namespace std __attribute__ ((__visibility__ ("default"))) { using ::clock_t; using ::time_t; using ::tm; using ::clock; using ::difftime; using ::mktime; using ::time; using ::asctime; using ::ctime; using ::gmtime; using ::localtime; using ::strftime; } extern "C" { struct timezone { int tz_minuteswest; int tz_dsttime; }; typedef struct timezone *__restrict __timezone_ptr_t; extern int gettimeofday (struct timeval *__restrict __tv, __timezone_ptr_t __tz) throw () __attribute__ ((__nonnull__ (1))); extern int settimeofday (__const struct timeval *__tv, __const struct timezone *__tz) throw () __attribute__ ((__nonnull__ (1))); extern int adjtime (__const struct timeval *__delta, struct timeval *__olddelta) throw (); enum __itimer_which { ITIMER_REAL = 0, ITIMER_VIRTUAL = 1, ITIMER_PROF = 2 }; struct itimerval { struct timeval it_interval; struct timeval it_value; }; typedef int __itimer_which_t; extern int getitimer (__itimer_which_t __which, struct itimerval *__value) throw (); extern int setitimer (__itimer_which_t __which, __const struct itimerval *__restrict __new, struct itimerval *__restrict __old) throw (); extern int utimes (__const char *__file, __const struct timeval __tvp[2]) throw () __attribute__ ((__nonnull__ (1))); extern int lutimes (__const char *__file, __const struct timeval __tvp[2]) throw () __attribute__ ((__nonnull__ (1))); extern int futimes (int __fd, __const struct timeval __tvp[2]) throw (); extern int futimesat (int __fd, __const char *__file, __const struct timeval __tvp[2]) throw (); } extern "C" { typedef __intptr_t intptr_t; typedef __socklen_t socklen_t; extern int access (__const char *__name, int __type) throw () __attribute__ ((__nonnull__ (1))); extern int euidaccess (__const char *__name, int __type) throw () __attribute__ ((__nonnull__ (1))); extern int eaccess (__const char *__name, int __type) throw () __attribute__ ((__nonnull__ (1))); extern int faccessat (int __fd, __const char *__file, int __type, int __flag) throw () __attribute__ ((__nonnull__ (2))) ; extern __off_t lseek (int __fd, __off_t __offset, int __whence) throw (); extern __off64_t lseek64 (int __fd, __off64_t __offset, int __whence) throw (); extern int close (int __fd); extern ssize_t read (int __fd, void *__buf, size_t __nbytes) ; extern ssize_t write (int __fd, __const void *__buf, size_t __n) ; extern ssize_t pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset) ; extern ssize_t pwrite (int __fd, __const void *__buf, size_t __n, __off_t __offset) ; extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) ; extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n, __off64_t __offset) ; extern int pipe (int __pipedes[2]) throw () ; extern unsigned int alarm (unsigned int __seconds) throw (); extern unsigned int sleep (unsigned int __seconds); extern __useconds_t ualarm (__useconds_t __value, __useconds_t __interval) throw (); extern int usleep (__useconds_t __useconds); extern int pause (void); extern int chown (__const char *__file, __uid_t __owner, __gid_t __group) throw () __attribute__ ((__nonnull__ (1))) ; extern int fchown (int __fd, __uid_t __owner, __gid_t __group) throw () ; extern int lchown (__const char *__file, __uid_t __owner, __gid_t __group) throw () __attribute__ ((__nonnull__ (1))) ; extern int fchownat (int __fd, __const char *__file, __uid_t __owner, __gid_t __group, int __flag) throw () __attribute__ ((__nonnull__ (2))) ; extern int chdir (__const char *__path) throw () __attribute__ ((__nonnull__ (1))) ; extern int fchdir (int __fd) throw () ; extern char *getcwd (char *__buf, size_t __size) throw () ; extern char *get_current_dir_name (void) throw (); extern char *getwd (char *__buf) throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__deprecated__)) ; extern int dup (int __fd) throw () ; extern int dup2 (int __fd, int __fd2) throw (); extern char **__environ; extern char **environ; extern int execve (__const char *__path, char *__const __argv[], char *__const __envp[]) throw () __attribute__ ((__nonnull__ (1))); extern int fexecve (int __fd, char *__const __argv[], char *__const __envp[]) throw (); extern int execv (__const char *__path, char *__const __argv[]) throw () __attribute__ ((__nonnull__ (1))); extern int execle (__const char *__path, __const char *__arg, ...) throw () __attribute__ ((__nonnull__ (1))); extern int execl (__const char *__path, __const char *__arg, ...) throw () __attribute__ ((__nonnull__ (1))); extern int execvp (__const char *__file, char *__const __argv[]) throw () __attribute__ ((__nonnull__ (1))); extern int execlp (__const char *__file, __const char *__arg, ...) throw () __attribute__ ((__nonnull__ (1))); extern int nice (int __inc) throw () ; extern void _exit (int __status) __attribute__ ((__noreturn__)); enum { _PC_LINK_MAX, _PC_MAX_CANON, _PC_MAX_INPUT, _PC_NAME_MAX, _PC_PATH_MAX, _PC_PIPE_BUF, _PC_CHOWN_RESTRICTED, _PC_NO_TRUNC, _PC_VDISABLE, _PC_SYNC_IO, _PC_ASYNC_IO, _PC_PRIO_IO, _PC_SOCK_MAXBUF, _PC_FILESIZEBITS, _PC_REC_INCR_XFER_SIZE, _PC_REC_MAX_XFER_SIZE, _PC_REC_MIN_XFER_SIZE, _PC_REC_XFER_ALIGN, _PC_ALLOC_SIZE_MIN, _PC_SYMLINK_MAX, _PC_2_SYMLINKS }; enum { _SC_ARG_MAX, _SC_CHILD_MAX, _SC_CLK_TCK, _SC_NGROUPS_MAX, _SC_OPEN_MAX, _SC_STREAM_MAX, _SC_TZNAME_MAX, _SC_JOB_CONTROL, _SC_SAVED_IDS, _SC_REALTIME_SIGNALS, _SC_PRIORITY_SCHEDULING, _SC_TIMERS, _SC_ASYNCHRONOUS_IO, _SC_PRIORITIZED_IO, _SC_SYNCHRONIZED_IO, _SC_FSYNC, _SC_MAPPED_FILES, _SC_MEMLOCK, _SC_MEMLOCK_RANGE, _SC_MEMORY_PROTECTION, _SC_MESSAGE_PASSING, _SC_SEMAPHORES, _SC_SHARED_MEMORY_OBJECTS, _SC_AIO_LISTIO_MAX, _SC_AIO_MAX, _SC_AIO_PRIO_DELTA_MAX, _SC_DELAYTIMER_MAX, _SC_MQ_OPEN_MAX, _SC_MQ_PRIO_MAX, _SC_VERSION, _SC_PAGESIZE, _SC_RTSIG_MAX, _SC_SEM_NSEMS_MAX, _SC_SEM_VALUE_MAX, _SC_SIGQUEUE_MAX, _SC_TIMER_MAX, _SC_BC_BASE_MAX, _SC_BC_DIM_MAX, _SC_BC_SCALE_MAX, _SC_BC_STRING_MAX, _SC_COLL_WEIGHTS_MAX, _SC_EQUIV_CLASS_MAX, _SC_EXPR_NEST_MAX, _SC_LINE_MAX, _SC_RE_DUP_MAX, _SC_CHARCLASS_NAME_MAX, _SC_2_VERSION, _SC_2_C_BIND, _SC_2_C_DEV, _SC_2_FORT_DEV, _SC_2_FORT_RUN, _SC_2_SW_DEV, _SC_2_LOCALEDEF, _SC_PII, _SC_PII_XTI, _SC_PII_SOCKET, _SC_PII_INTERNET, _SC_PII_OSI, _SC_POLL, _SC_SELECT, _SC_UIO_MAXIOV, _SC_IOV_MAX = _SC_UIO_MAXIOV, _SC_PII_INTERNET_STREAM, _SC_PII_INTERNET_DGRAM, _SC_PII_OSI_COTS, _SC_PII_OSI_CLTS, _SC_PII_OSI_M, _SC_T_IOV_MAX, _SC_THREADS, _SC_THREAD_SAFE_FUNCTIONS, _SC_GETGR_R_SIZE_MAX, _SC_GETPW_R_SIZE_MAX, _SC_LOGIN_NAME_MAX, _SC_TTY_NAME_MAX, _SC_THREAD_DESTRUCTOR_ITERATIONS, _SC_THREAD_KEYS_MAX, _SC_THREAD_STACK_MIN, _SC_THREAD_THREADS_MAX, _SC_THREAD_ATTR_STACKADDR, _SC_THREAD_ATTR_STACKSIZE, _SC_THREAD_PRIORITY_SCHEDULING, _SC_THREAD_PRIO_INHERIT, _SC_THREAD_PRIO_PROTECT, _SC_THREAD_PROCESS_SHARED, _SC_NPROCESSORS_CONF, _SC_NPROCESSORS_ONLN, _SC_PHYS_PAGES, _SC_AVPHYS_PAGES, _SC_ATEXIT_MAX, _SC_PASS_MAX, _SC_XOPEN_VERSION, _SC_XOPEN_XCU_VERSION, _SC_XOPEN_UNIX, _SC_XOPEN_CRYPT, _SC_XOPEN_ENH_I18N, _SC_XOPEN_SHM, _SC_2_CHAR_TERM, _SC_2_C_VERSION, _SC_2_UPE, _SC_XOPEN_XPG2, _SC_XOPEN_XPG3, _SC_XOPEN_XPG4, _SC_CHAR_BIT, _SC_CHAR_MAX, _SC_CHAR_MIN, _SC_INT_MAX, _SC_INT_MIN, _SC_LONG_BIT, _SC_WORD_BIT, _SC_MB_LEN_MAX, _SC_NZERO, _SC_SSIZE_MAX, _SC_SCHAR_MAX, _SC_SCHAR_MIN, _SC_SHRT_MAX, _SC_SHRT_MIN, _SC_UCHAR_MAX, _SC_UINT_MAX, _SC_ULONG_MAX, _SC_USHRT_MAX, _SC_NL_ARGMAX, _SC_NL_LANGMAX, _SC_NL_MSGMAX, _SC_NL_NMAX, _SC_NL_SETMAX, _SC_NL_TEXTMAX, _SC_XBS5_ILP32_OFF32, _SC_XBS5_ILP32_OFFBIG, _SC_XBS5_LP64_OFF64, _SC_XBS5_LPBIG_OFFBIG, _SC_XOPEN_LEGACY, _SC_XOPEN_REALTIME, _SC_XOPEN_REALTIME_THREADS, _SC_ADVISORY_INFO, _SC_BARRIERS, _SC_BASE, _SC_C_LANG_SUPPORT, _SC_C_LANG_SUPPORT_R, _SC_CLOCK_SELECTION, _SC_CPUTIME, _SC_THREAD_CPUTIME, _SC_DEVICE_IO, _SC_DEVICE_SPECIFIC, _SC_DEVICE_SPECIFIC_R, _SC_FD_MGMT, _SC_FIFO, _SC_PIPE, _SC_FILE_ATTRIBUTES, _SC_FILE_LOCKING, _SC_FILE_SYSTEM, _SC_MONOTONIC_CLOCK, _SC_MULTI_PROCESS, _SC_SINGLE_PROCESS, _SC_NETWORKING, _SC_READER_WRITER_LOCKS, _SC_SPIN_LOCKS, _SC_REGEXP, _SC_REGEX_VERSION, _SC_SHELL, _SC_SIGNALS, _SC_SPAWN, _SC_SPORADIC_SERVER, _SC_THREAD_SPORADIC_SERVER, _SC_SYSTEM_DATABASE, _SC_SYSTEM_DATABASE_R, _SC_TIMEOUTS, _SC_TYPED_MEMORY_OBJECTS, _SC_USER_GROUPS, _SC_USER_GROUPS_R, _SC_2_PBS, _SC_2_PBS_ACCOUNTING, _SC_2_PBS_LOCATE, _SC_2_PBS_MESSAGE, _SC_2_PBS_TRACK, _SC_SYMLOOP_MAX, _SC_STREAMS, _SC_2_PBS_CHECKPOINT, _SC_V6_ILP32_OFF32, _SC_V6_ILP32_OFFBIG, _SC_V6_LP64_OFF64, _SC_V6_LPBIG_OFFBIG, _SC_HOST_NAME_MAX, _SC_TRACE, _SC_TRACE_EVENT_FILTER, _SC_TRACE_INHERIT, _SC_TRACE_LOG, _SC_LEVEL1_ICACHE_SIZE, _SC_LEVEL1_ICACHE_ASSOC, _SC_LEVEL1_ICACHE_LINESIZE, _SC_LEVEL1_DCACHE_SIZE, _SC_LEVEL1_DCACHE_ASSOC, _SC_LEVEL1_DCACHE_LINESIZE, _SC_LEVEL2_CACHE_SIZE, _SC_LEVEL2_CACHE_ASSOC, _SC_LEVEL2_CACHE_LINESIZE, _SC_LEVEL3_CACHE_SIZE, _SC_LEVEL3_CACHE_ASSOC, _SC_LEVEL3_CACHE_LINESIZE, _SC_LEVEL4_CACHE_SIZE, _SC_LEVEL4_CACHE_ASSOC, _SC_LEVEL4_CACHE_LINESIZE, _SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50, _SC_RAW_SOCKETS }; enum { _CS_PATH, _CS_V6_WIDTH_RESTRICTED_ENVS, _CS_GNU_LIBC_VERSION, _CS_GNU_LIBPTHREAD_VERSION, _CS_LFS_CFLAGS = 1000, _CS_LFS_LDFLAGS, _CS_LFS_LIBS, _CS_LFS_LINTFLAGS, _CS_LFS64_CFLAGS, _CS_LFS64_LDFLAGS, _CS_LFS64_LIBS, _CS_LFS64_LINTFLAGS, _CS_XBS5_ILP32_OFF32_CFLAGS = 1100, _CS_XBS5_ILP32_OFF32_LDFLAGS, _CS_XBS5_ILP32_OFF32_LIBS, _CS_XBS5_ILP32_OFF32_LINTFLAGS, _CS_XBS5_ILP32_OFFBIG_CFLAGS, _CS_XBS5_ILP32_OFFBIG_LDFLAGS, _CS_XBS5_ILP32_OFFBIG_LIBS, _CS_XBS5_ILP32_OFFBIG_LINTFLAGS, _CS_XBS5_LP64_OFF64_CFLAGS, _CS_XBS5_LP64_OFF64_LDFLAGS, _CS_XBS5_LP64_OFF64_LIBS, _CS_XBS5_LP64_OFF64_LINTFLAGS, _CS_XBS5_LPBIG_OFFBIG_CFLAGS, _CS_XBS5_LPBIG_OFFBIG_LDFLAGS, _CS_XBS5_LPBIG_OFFBIG_LIBS, _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS, _CS_POSIX_V6_ILP32_OFF32_CFLAGS, _CS_POSIX_V6_ILP32_OFF32_LDFLAGS, _CS_POSIX_V6_ILP32_OFF32_LIBS, _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS, _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS, _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS, _CS_POSIX_V6_ILP32_OFFBIG_LIBS, _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS, _CS_POSIX_V6_LP64_OFF64_CFLAGS, _CS_POSIX_V6_LP64_OFF64_LDFLAGS, _CS_POSIX_V6_LP64_OFF64_LIBS, _CS_POSIX_V6_LP64_OFF64_LINTFLAGS, _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS, _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS, _CS_POSIX_V6_LPBIG_OFFBIG_LIBS, _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS }; extern long int pathconf (__const char *__path, int __name) throw () __attribute__ ((__nonnull__ (1))); extern long int fpathconf (int __fd, int __name) throw (); extern long int sysconf (int __name) throw (); extern size_t confstr (int __name, char *__buf, size_t __len) throw (); extern __pid_t getpid (void) throw (); extern __pid_t getppid (void) throw (); extern __pid_t getpgrp (void) throw (); extern __pid_t __getpgid (__pid_t __pid) throw (); extern __pid_t getpgid (__pid_t __pid) throw (); extern int setpgid (__pid_t __pid, __pid_t __pgid) throw (); extern int setpgrp (void) throw (); extern __pid_t setsid (void) throw (); extern __pid_t getsid (__pid_t __pid) throw (); extern __uid_t getuid (void) throw (); extern __uid_t geteuid (void) throw (); extern __gid_t getgid (void) throw (); extern __gid_t getegid (void) throw (); extern int getgroups (int __size, __gid_t __list[]) throw () ; extern int group_member (__gid_t __gid) throw (); extern int setuid (__uid_t __uid) throw (); extern int setreuid (__uid_t __ruid, __uid_t __euid) throw (); extern int seteuid (__uid_t __uid) throw (); extern int setgid (__gid_t __gid) throw (); extern int setregid (__gid_t __rgid, __gid_t __egid) throw (); extern int setegid (__gid_t __gid) throw (); extern int getresuid (__uid_t *__ruid, __uid_t *__euid, __uid_t *__suid) throw (); extern int getresgid (__gid_t *__rgid, __gid_t *__egid, __gid_t *__sgid) throw (); extern int setresuid (__uid_t __ruid, __uid_t __euid, __uid_t __suid) throw (); extern int setresgid (__gid_t __rgid, __gid_t __egid, __gid_t __sgid) throw (); extern __pid_t fork (void) throw (); extern __pid_t vfork (void) throw (); extern char *ttyname (int __fd) throw (); extern int ttyname_r (int __fd, char *__buf, size_t __buflen) throw () __attribute__ ((__nonnull__ (2))) ; extern int isatty (int __fd) throw (); extern int ttyslot (void) throw (); extern int link (__const char *__from, __const char *__to) throw () __attribute__ ((__nonnull__ (1, 2))) ; extern int linkat (int __fromfd, __const char *__from, int __tofd, __const char *__to, int __flags) throw () __attribute__ ((__nonnull__ (2, 4))) ; extern int symlink (__const char *__from, __const char *__to) throw () __attribute__ ((__nonnull__ (1, 2))) ; extern ssize_t readlink (__const char *__restrict __path, char *__restrict __buf, size_t __len) throw () __attribute__ ((__nonnull__ (1, 2))) ; extern int symlinkat (__const char *__from, int __tofd, __const char *__to) throw () __attribute__ ((__nonnull__ (1, 3))) ; extern ssize_t readlinkat (int __fd, __const char *__restrict __path, char *__restrict __buf, size_t __len) throw () __attribute__ ((__nonnull__ (2, 3))) ; extern int unlink (__const char *__name) throw () __attribute__ ((__nonnull__ (1))); extern int unlinkat (int __fd, __const char *__name, int __flag) throw () __attribute__ ((__nonnull__ (2))); extern int rmdir (__const char *__path) throw () __attribute__ ((__nonnull__ (1))); extern __pid_t tcgetpgrp (int __fd) throw (); extern int tcsetpgrp (int __fd, __pid_t __pgrp_id) throw (); extern char *getlogin (void); extern int getlogin_r (char *__name, size_t __name_len) __attribute__ ((__nonnull__ (1))); extern int setlogin (__const char *__name) throw () __attribute__ ((__nonnull__ (1))); extern "C" { extern char *optarg; extern int optind; extern int opterr; extern int optopt; extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) throw (); } extern int gethostname (char *__name, size_t __len) throw () __attribute__ ((__nonnull__ (1))); extern int sethostname (__const char *__name, size_t __len) throw () __attribute__ ((__nonnull__ (1))) ; extern int sethostid (long int __id) throw () ; extern int getdomainname (char *__name, size_t __len) throw () __attribute__ ((__nonnull__ (1))) ; extern int setdomainname (__const char *__name, size_t __len) throw () __attribute__ ((__nonnull__ (1))) ; extern int vhangup (void) throw (); extern int revoke (__const char *__file) throw () __attribute__ ((__nonnull__ (1))) ; extern int profil (unsigned short int *__sample_buffer, size_t __size, size_t __offset, unsigned int __scale) throw () __attribute__ ((__nonnull__ (1))); extern int acct (__const char *__name) throw (); extern char *getusershell (void) throw (); extern void endusershell (void) throw (); extern void setusershell (void) throw (); extern int daemon (int __nochdir, int __noclose) throw () ; extern int chroot (__const char *__path) throw () __attribute__ ((__nonnull__ (1))) ; extern char *getpass (__const char *__prompt) __attribute__ ((__nonnull__ (1))); extern int fsync (int __fd); extern long int gethostid (void); extern void sync (void) throw (); extern int getpagesize (void) throw () __attribute__ ((__const__)); extern int getdtablesize (void) throw (); extern int truncate (__const char *__file, __off_t __length) throw () __attribute__ ((__nonnull__ (1))) ; extern int truncate64 (__const char *__file, __off64_t __length) throw () __attribute__ ((__nonnull__ (1))) ; extern int ftruncate (int __fd, __off_t __length) throw () ; extern int ftruncate64 (int __fd, __off64_t __length) throw () ; extern int brk (void *__addr) throw () ; extern void *sbrk (intptr_t __delta) throw (); extern long int syscall (long int __sysno, ...) throw (); extern int lockf (int __fd, int __cmd, __off_t __len) ; extern int lockf64 (int __fd, int __cmd, __off64_t __len) ; extern int fdatasync (int __fildes); extern char *crypt (__const char *__key, __const char *__salt) throw () __attribute__ ((__nonnull__ (1, 2))); extern void encrypt (char *__block, int __edflag) throw () __attribute__ ((__nonnull__ (1))); extern void swab (__const void *__restrict __from, void *__restrict __to, ssize_t __n) throw () __attribute__ ((__nonnull__ (1, 2))); extern char *ctermid (char *__s) throw (); } typedef unsigned long XID; typedef unsigned long Mask; typedef unsigned long Atom; typedef unsigned long VisualID; typedef unsigned long Time; typedef XID Window; typedef XID Drawable; typedef XID Font; typedef XID Pixmap; typedef XID Cursor; typedef XID Colormap; typedef XID GContext; typedef XID KeySym; typedef unsigned char KeyCode; extern int _Xmblen( char *str, int len ); typedef char *XPointer; typedef struct _XExtData { int number; struct _XExtData *next; int (*free_private)( struct _XExtData *extension ); XPointer private_data; } XExtData; typedef struct { int extension; int major_opcode; int first_event; int first_error; } XExtCodes; typedef struct { int depth; int bits_per_pixel; int scanline_pad; } XPixmapFormatValues; typedef struct { int function; unsigned long plane_mask; unsigned long foreground; unsigned long background; int line_width; int line_style; int cap_style; int join_style; int fill_style; int fill_rule; int arc_mode; Pixmap tile; Pixmap stipple; int ts_x_origin; int ts_y_origin; Font font; int subwindow_mode; int graphics_exposures; int clip_x_origin; int clip_y_origin; Pixmap clip_mask; int dash_offset; char dashes; } XGCValues; typedef struct _XGC *GC; typedef struct { XExtData *ext_data; VisualID visualid; int c_class; unsigned long red_mask, green_mask, blue_mask; int bits_per_rgb; int map_entries; } Visual; typedef struct { int depth; int nvisuals; Visual *visuals; } Depth; struct _XDisplay; typedef struct { XExtData *ext_data; struct _XDisplay *display; Window root; int width, height; int mwidth, mheight; int ndepths; Depth *depths; int root_depth; Visual *root_visual; GC default_gc; Colormap cmap; unsigned long white_pixel; unsigned long black_pixel; int max_maps, min_maps; int backing_store; int save_unders; long root_input_mask; } Screen; typedef struct { XExtData *ext_data; int depth; int bits_per_pixel; int scanline_pad; } ScreenFormat; typedef struct { Pixmap background_pixmap; unsigned long background_pixel; Pixmap border_pixmap; unsigned long border_pixel; int bit_gravity; int win_gravity; int backing_store; unsigned long backing_planes; unsigned long backing_pixel; int save_under; long event_mask; long do_not_propagate_mask; int override_redirect; Colormap colormap; Cursor cursor; } XSetWindowAttributes; typedef struct { int x, y; int width, height; int border_width; int depth; Visual *visual; Window root; int c_class; int bit_gravity; int win_gravity; int backing_store; unsigned long backing_planes; unsigned long backing_pixel; int save_under; Colormap colormap; int map_installed; int map_state; long all_event_masks; long your_event_mask; long do_not_propagate_mask; int override_redirect; Screen *screen; } XWindowAttributes; typedef struct { int family; int length; char *address; } XHostAddress; typedef struct { int typelength; int valuelength; char *type; char *value; } XServerInterpretedAddress; typedef struct _XImage { int width, height; int xoffset; int format; char *data; int byte_order; int bitmap_unit; int bitmap_bit_order; int bitmap_pad; int depth; int bytes_per_line; int bits_per_pixel; unsigned long red_mask; unsigned long green_mask; unsigned long blue_mask; XPointer obdata; struct funcs { struct _XImage *(*create_image)( struct _XDisplay* , Visual* , unsigned int , int , int , char* , unsigned int , unsigned int , int , int ); int (*destroy_image) (struct _XImage *); unsigned long (*get_pixel) (struct _XImage *, int, int); int (*put_pixel) (struct _XImage *, int, int, unsigned long); struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int); int (*add_pixel) (struct _XImage *, long); } f; } XImage; typedef struct { int x, y; int width, height; int border_width; Window sibling; int stack_mode; } XWindowChanges; typedef struct { unsigned long pixel; unsigned short red, green, blue; char flags; char pad; } XColor; typedef struct { short x1, y1, x2, y2; } XSegment; typedef struct { short x, y; } XPoint; typedef struct { short x, y; unsigned short width, height; } XRectangle; typedef struct { short x, y; unsigned short width, height; short angle1, angle2; } XArc; typedef struct { int key_click_percent; int bell_percent; int bell_pitch; int bell_duration; int led; int led_mode; int key; int auto_repeat_mode; } XKeyboardControl; typedef struct { int key_click_percent; int bell_percent; unsigned int bell_pitch, bell_duration; unsigned long led_mask; int global_auto_repeat; char auto_repeats[32]; } XKeyboardState; typedef struct { Time time; short x, y; } XTimeCoord; typedef struct { int max_keypermod; KeyCode *modifiermap; } XModifierKeymap; typedef struct _XDisplay Display; struct _XPrivate; struct _XrmHashBucketRec; typedef struct { XExtData *ext_data; struct _XPrivate *private1; int fd; int private2; int proto_major_version; int proto_minor_version; char *vendor; XID private3; XID private4; XID private5; int private6; XID (*resource_alloc)( struct _XDisplay* ); int byte_order; int bitmap_unit; int bitmap_pad; int bitmap_bit_order; int nformats; ScreenFormat *pixmap_format; int private8; int release; struct _XPrivate *private9, *private10; int qlen; unsigned long last_request_read; unsigned long request; XPointer private11; XPointer private12; XPointer private13; XPointer private14; unsigned max_request_size; struct _XrmHashBucketRec *db; int (*private15)( struct _XDisplay* ); char *display_name; int default_screen; int nscreens; Screen *screens; unsigned long motion_buffer; unsigned long private16; int min_keycode; int max_keycode; XPointer private17; XPointer private18; int private19; char *xdefaults; } *_XPrivDisplay; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; Window root; Window subwindow; Time time; int x, y; int x_root, y_root; unsigned int state; unsigned int keycode; int same_screen; } XKeyEvent; typedef XKeyEvent XKeyPressedEvent; typedef XKeyEvent XKeyReleasedEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; Window root; Window subwindow; Time time; int x, y; int x_root, y_root; unsigned int state; unsigned int button; int same_screen; } XButtonEvent; typedef XButtonEvent XButtonPressedEvent; typedef XButtonEvent XButtonReleasedEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; Window root; Window subwindow; Time time; int x, y; int x_root, y_root; unsigned int state; char is_hint; int same_screen; } XMotionEvent; typedef XMotionEvent XPointerMovedEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; Window root; Window subwindow; Time time; int x, y; int x_root, y_root; int mode; int detail; int same_screen; int focus; unsigned int state; } XCrossingEvent; typedef XCrossingEvent XEnterWindowEvent; typedef XCrossingEvent XLeaveWindowEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; int mode; int detail; } XFocusChangeEvent; typedef XFocusChangeEvent XFocusInEvent; typedef XFocusChangeEvent XFocusOutEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; char key_vector[32]; } XKeymapEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; int x, y; int width, height; int count; } XExposeEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Drawable drawable; int x, y; int width, height; int count; int major_code; int minor_code; } XGraphicsExposeEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Drawable drawable; int major_code; int minor_code; } XNoExposeEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; int state; } XVisibilityEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window parent; Window window; int x, y; int width, height; int border_width; int override_redirect; } XCreateWindowEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window event; Window window; } XDestroyWindowEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window event; Window window; int from_configure; } XUnmapEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window event; Window window; int override_redirect; } XMapEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window parent; Window window; } XMapRequestEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window event; Window window; Window parent; int x, y; int override_redirect; } XReparentEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window event; Window window; int x, y; int width, height; int border_width; Window above; int override_redirect; } XConfigureEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window event; Window window; int x, y; } XGravityEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; int width, height; } XResizeRequestEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window parent; Window window; int x, y; int width, height; int border_width; Window above; int detail; unsigned long value_mask; } XConfigureRequestEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window event; Window window; int place; } XCirculateEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window parent; Window window; int place; } XCirculateRequestEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; Atom atom; Time time; int state; } XPropertyEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; Atom selection; Time time; } XSelectionClearEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window owner; Window requestor; Atom selection; Atom target; Atom property; Time time; } XSelectionRequestEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window requestor; Atom selection; Atom target; Atom property; Time time; } XSelectionEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; Colormap colormap; int c_new; int state; } XColormapEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; Atom message_type; int format; union { char b[20]; short s[10]; long l[5]; } data; } XClientMessageEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; int request; int first_keycode; int count; } XMappingEvent; typedef struct { int type; Display *display; XID resourceid; unsigned long serial; unsigned char error_code; unsigned char request_code; unsigned char minor_code; } XErrorEvent; typedef struct { int type; unsigned long serial; int send_event; Display *display; Window window; } XAnyEvent; typedef union _XEvent { int type; XAnyEvent xany; XKeyEvent xkey; XButtonEvent xbutton; XMotionEvent xmotion; XCrossingEvent xcrossing; XFocusChangeEvent xfocus; XExposeEvent xexpose; XGraphicsExposeEvent xgraphicsexpose; XNoExposeEvent xnoexpose; XVisibilityEvent xvisibility; XCreateWindowEvent xcreatewindow; XDestroyWindowEvent xdestroywindow; XUnmapEvent xunmap; XMapEvent xmap; XMapRequestEvent xmaprequest; XReparentEvent xreparent; XConfigureEvent xconfigure; XGravityEvent xgravity; XResizeRequestEvent xresizerequest; XConfigureRequestEvent xconfigurerequest; XCirculateEvent xcirculate; XCirculateRequestEvent xcirculaterequest; XPropertyEvent xproperty; XSelectionClearEvent xselectionclear; XSelectionRequestEvent xselectionrequest; XSelectionEvent xselection; XColormapEvent xcolormap; XClientMessageEvent xclient; XMappingEvent xmapping; XErrorEvent xerror; XKeymapEvent xkeymap; long pad[24]; } XEvent; typedef struct { short lbearing; short rbearing; short width; short ascent; short descent; unsigned short attributes; } XCharStruct; typedef struct { Atom name; unsigned long card32; } XFontProp; typedef struct { XExtData *ext_data; Font fid; unsigned direction; unsigned min_char_or_byte2; unsigned max_char_or_byte2; unsigned min_byte1; unsigned max_byte1; int all_chars_exist; unsigned default_char; int n_properties; XFontProp *properties; XCharStruct min_bounds; XCharStruct max_bounds; XCharStruct *per_char; int ascent; int descent; } XFontStruct; typedef struct { char *chars; int nchars; int delta; Font font; } XTextItem; typedef struct { unsigned char byte1; unsigned char byte2; } XChar2b; typedef struct { XChar2b *chars; int nchars; int delta; Font font; } XTextItem16; typedef union { Display *display; GC gc; Visual *visual; Screen *screen; ScreenFormat *pixmap_format; XFontStruct *font; } XEDataObject; typedef struct { XRectangle max_ink_extent; XRectangle max_logical_extent; } XFontSetExtents; typedef struct _XOM *XOM; typedef struct _XOC *XOC, *XFontSet; typedef struct { char *chars; int nchars; int delta; XFontSet font_set; } XmbTextItem; typedef struct { wchar_t *chars; int nchars; int delta; XFontSet font_set; } XwcTextItem; typedef struct { int charset_count; char **charset_list; } XOMCharSetList; typedef enum { XOMOrientation_LTR_TTB, XOMOrientation_RTL_TTB, XOMOrientation_TTB_LTR, XOMOrientation_TTB_RTL, XOMOrientation_Context } XOrientation; typedef struct { int num_orientation; XOrientation *orientation; } XOMOrientation; typedef struct { int num_font; XFontStruct **font_struct_list; char **font_name_list; } XOMFontInfo; typedef struct _XIM *XIM; typedef struct _XIC *XIC; typedef void (*XIMProc)( XIM, XPointer, XPointer ); typedef int (*XICProc)( XIC, XPointer, XPointer ); typedef void (*XIDProc)( Display*, XPointer, XPointer ); typedef unsigned long XIMStyle; typedef struct { unsigned short count_styles; XIMStyle *supported_styles; } XIMStyles; typedef void *XVaNestedList; typedef struct { XPointer client_data; XIMProc callback; } XIMCallback; typedef struct { XPointer client_data; XICProc callback; } XICCallback; typedef unsigned long XIMFeedback; typedef struct _XIMText { unsigned short length; XIMFeedback *feedback; int encoding_is_wchar; union { char *multi_byte; wchar_t *wide_char; } string; } XIMText; typedef unsigned long XIMPreeditState; typedef struct _XIMPreeditStateNotifyCallbackStruct { XIMPreeditState state; } XIMPreeditStateNotifyCallbackStruct; typedef unsigned long XIMResetState; typedef unsigned long XIMStringConversionFeedback; typedef struct _XIMStringConversionText { unsigned short length; XIMStringConversionFeedback *feedback; int encoding_is_wchar; union { char *mbs; wchar_t *wcs; } string; } XIMStringConversionText; typedef unsigned short XIMStringConversionPosition; typedef unsigned short XIMStringConversionType; typedef unsigned short XIMStringConversionOperation; typedef enum { XIMForwardChar, XIMBackwardChar, XIMForwardWord, XIMBackwardWord, XIMCaretUp, XIMCaretDown, XIMNextLine, XIMPreviousLine, XIMLineStart, XIMLineEnd, XIMAbsolutePosition, XIMDontChange } XIMCaretDirection; typedef struct _XIMStringConversionCallbackStruct { XIMStringConversionPosition position; XIMCaretDirection direction; XIMStringConversionOperation operation; unsigned short factor; XIMStringConversionText *text; } XIMStringConversionCallbackStruct; typedef struct _XIMPreeditDrawCallbackStruct { int caret; int chg_first; int chg_length; XIMText *text; } XIMPreeditDrawCallbackStruct; typedef enum { XIMIsInvisible, XIMIsPrimary, XIMIsSecondary } XIMCaretStyle; typedef struct _XIMPreeditCaretCallbackStruct { int position; XIMCaretDirection direction; XIMCaretStyle style; } XIMPreeditCaretCallbackStruct; typedef enum { XIMTextType, XIMBitmapType } XIMStatusDataType; typedef struct _XIMStatusDrawCallbackStruct { XIMStatusDataType type; union { XIMText *text; Pixmap bitmap; } data; } XIMStatusDrawCallbackStruct; typedef struct _XIMHotKeyTrigger { KeySym keysym; int modifier; int modifier_mask; } XIMHotKeyTrigger; typedef struct _XIMHotKeyTriggers { int num_hot_key; XIMHotKeyTrigger *key; } XIMHotKeyTriggers; typedef unsigned long XIMHotKeyState; typedef struct { unsigned short count_values; char **supported_values; } XIMValuesList; extern "C" { extern int _Xdebug; extern XFontStruct *XLoadQueryFont( Display* , const char* ); extern XFontStruct *XQueryFont( Display* , XID ); extern XTimeCoord *XGetMotionEvents( Display* , Window , Time , Time , int* ); extern XModifierKeymap *XDeleteModifiermapEntry( XModifierKeymap* , KeyCode , int ); extern XModifierKeymap *XGetModifierMapping( Display* ); extern XModifierKeymap *XInsertModifiermapEntry( XModifierKeymap* , KeyCode , int ); extern XModifierKeymap *XNewModifiermap( int ); extern XImage *XCreateImage( Display* , Visual* , unsigned int , int , int , char* , unsigned int , unsigned int , int , int ); extern int XInitImage( XImage* ); extern XImage *XGetImage( Display* , Drawable , int , int , unsigned int , unsigned int , unsigned long , int ); extern XImage *XGetSubImage( Display* , Drawable , int , int , unsigned int , unsigned int , unsigned long , int , XImage* , int , int ); extern Display *XOpenDisplay( const char* ); extern void XrmInitialize( void ); extern char *XFetchBytes( Display* , int* ); extern char *XFetchBuffer( Display* , int* , int ); extern char *XGetAtomName( Display* , Atom ); extern int XGetAtomNames( Display* , Atom* , int , char** ); extern char *XGetDefault( Display* , const char* , const char* ); extern char *XDisplayName( const char* ); extern char *XKeysymToString( KeySym ); extern int (*XSynchronize( Display* , int ))( Display* ); extern int (*XSetAfterFunction( Display* , int (*) ( Display* ) ))( Display* ); extern Atom XInternAtom( Display* , const char* , int ); extern int XInternAtoms( Display* , char** , int , int , Atom* ); extern Colormap XCopyColormapAndFree( Display* , Colormap ); extern Colormap XCreateColormap( Display* , Window , Visual* , int ); extern Cursor XCreatePixmapCursor( Display* , Pixmap , Pixmap , XColor* , XColor* , unsigned int , unsigned int ); extern Cursor XCreateGlyphCursor( Display* , Font , Font , unsigned int , unsigned int , XColor const * , XColor const * ); extern Cursor XCreateFontCursor( Display* , unsigned int ); extern Font XLoadFont( Display* , const char* ); extern GC XCreateGC( Display* , Drawable , unsigned long , XGCValues* ); extern GContext XGContextFromGC( GC ); extern void XFlushGC( Display* , GC ); extern Pixmap XCreatePixmap( Display* , Drawable , unsigned int , unsigned int , unsigned int ); extern Pixmap XCreateBitmapFromData( Display* , Drawable , const char* , unsigned int , unsigned int ); extern Pixmap XCreatePixmapFromBitmapData( Display* , Drawable , char* , unsigned int , unsigned int , unsigned long , unsigned long , unsigned int ); extern Window XCreateSimpleWindow( Display* , Window , int , int , unsigned int , unsigned int , unsigned int , unsigned long , unsigned long ); extern Window XGetSelectionOwner( Display* , Atom ); extern Window XCreateWindow( Display* , Window , int , int , unsigned int , unsigned int , unsigned int , int , unsigned int , Visual* , unsigned long , XSetWindowAttributes* ); extern Colormap *XListInstalledColormaps( Display* , Window , int* ); extern char **XListFonts( Display* , const char* , int , int* ); extern char **XListFontsWithInfo( Display* , const char* , int , int* , XFontStruct** ); extern char **XGetFontPath( Display* , int* ); extern char **XListExtensions( Display* , int* ); extern Atom *XListProperties( Display* , Window , int* ); extern XHostAddress *XListHosts( Display* , int* , int* ); extern KeySym XKeycodeToKeysym( Display* , KeyCode , int ); extern KeySym XLookupKeysym( XKeyEvent* , int ); extern KeySym *XGetKeyboardMapping( Display* , KeyCode , int , int* ); extern KeySym XStringToKeysym( const char* ); extern long XMaxRequestSize( Display* ); extern long XExtendedMaxRequestSize( Display* ); extern char *XResourceManagerString( Display* ); extern char *XScreenResourceString( Screen* ); extern unsigned long XDisplayMotionBufferSize( Display* ); extern VisualID XVisualIDFromVisual( Visual* ); extern int XInitThreads( void ); extern void XLockDisplay( Display* ); extern void XUnlockDisplay( Display* ); extern XExtCodes *XInitExtension( Display* , const char* ); extern XExtCodes *XAddExtension( Display* ); extern XExtData *XFindOnExtensionList( XExtData** , int ); extern XExtData **XEHeadOfExtensionList( XEDataObject ); extern Window XRootWindow( Display* , int ); extern Window XDefaultRootWindow( Display* ); extern Window XRootWindowOfScreen( Screen* ); extern Visual *XDefaultVisual( Display* , int ); extern Visual *XDefaultVisualOfScreen( Screen* ); extern GC XDefaultGC( Display* , int ); extern GC XDefaultGCOfScreen( Screen* ); extern unsigned long XBlackPixel( Display* , int ); extern unsigned long XWhitePixel( Display* , int ); extern unsigned long XAllPlanes( void ); extern unsigned long XBlackPixelOfScreen( Screen* ); extern unsigned long XWhitePixelOfScreen( Screen* ); extern unsigned long XNextRequest( Display* ); extern unsigned long XLastKnownRequestProcessed( Display* ); extern char *XServerVendor( Display* ); extern char *XDisplayString( Display* ); extern Colormap XDefaultColormap( Display* , int ); extern Colormap XDefaultColormapOfScreen( Screen* ); extern Display *XDisplayOfScreen( Screen* ); extern Screen *XScreenOfDisplay( Display* , int ); extern Screen *XDefaultScreenOfDisplay( Display* ); extern long XEventMaskOfScreen( Screen* ); extern int XScreenNumberOfScreen( Screen* ); typedef int (*XErrorHandler) ( Display* , XErrorEvent* ); extern XErrorHandler XSetErrorHandler ( XErrorHandler ); typedef int (*XIOErrorHandler) ( Display* ); extern XIOErrorHandler XSetIOErrorHandler ( XIOErrorHandler ); extern XPixmapFormatValues *XListPixmapFormats( Display* , int* ); extern int *XListDepths( Display* , int , int* ); extern int XReconfigureWMWindow( Display* , Window , int , unsigned int , XWindowChanges* ); extern int XGetWMProtocols( Display* , Window , Atom** , int* ); extern int XSetWMProtocols( Display* , Window , Atom* , int ); extern int XIconifyWindow( Display* , Window , int ); extern int XWithdrawWindow( Display* , Window , int ); extern int XGetCommand( Display* , Window , char*** , int* ); extern int XGetWMColormapWindows( Display* , Window , Window** , int* ); extern int XSetWMColormapWindows( Display* , Window , Window* , int ); extern void XFreeStringList( char** ); extern int XSetTransientForHint( Display* , Window , Window ); extern int XActivateScreenSaver( Display* ); extern int XAddHost( Display* , XHostAddress* ); extern int XAddHosts( Display* , XHostAddress* , int ); extern int XAddToExtensionList( struct _XExtData** , XExtData* ); extern int XAddToSaveSet( Display* , Window ); extern int XAllocColor( Display* , Colormap , XColor* ); extern int XAllocColorCells( Display* , Colormap , int , unsigned long* , unsigned int , unsigned long* , unsigned int ); extern int XAllocColorPlanes( Display* , Colormap , int , unsigned long* , int , int , int , int , unsigned long* , unsigned long* , unsigned long* ); extern int XAllocNamedColor( Display* , Colormap , const char* , XColor* , XColor* ); extern int XAllowEvents( Display* , int , Time ); extern int XAutoRepeatOff( Display* ); extern int XAutoRepeatOn( Display* ); extern int XBell( Display* , int ); extern int XBitmapBitOrder( Display* ); extern int XBitmapPad( Display* ); extern int XBitmapUnit( Display* ); extern int XCellsOfScreen( Screen* ); extern int XChangeActivePointerGrab( Display* , unsigned int , Cursor , Time ); extern int XChangeGC( Display* , GC , unsigned long , XGCValues* ); extern int XChangeKeyboardControl( Display* , unsigned long , XKeyboardControl* ); extern int XChangeKeyboardMapping( Display* , int , int , KeySym* , int ); extern int XChangePointerControl( Display* , int , int , int , int , int ); extern int XChangeProperty( Display* , Window , Atom , Atom , int , int , const unsigned char* , int ); extern int XChangeSaveSet( Display* , Window , int ); extern int XChangeWindowAttributes( Display* , Window , unsigned long , XSetWindowAttributes* ); extern int XCheckIfEvent( Display* , XEvent* , int (*) ( Display* , XEvent* , XPointer ) , XPointer ); extern int XCheckMaskEvent( Display* , long , XEvent* ); extern int XCheckTypedEvent( Display* , int , XEvent* ); extern int XCheckTypedWindowEvent( Display* , Window , int , XEvent* ); extern int XCheckWindowEvent( Display* , Window , long , XEvent* ); extern int XCirculateSubwindows( Display* , Window , int ); extern int XCirculateSubwindowsDown( Display* , Window ); extern int XCirculateSubwindowsUp( Display* , Window ); extern int XClearArea( Display* , Window , int , int , unsigned int , unsigned int , int ); extern int XClearWindow( Display* , Window ); extern int XCloseDisplay( Display* ); extern int XConfigureWindow( Display* , Window , unsigned int , XWindowChanges* ); extern int XConnectionNumber( Display* ); extern int XConvertSelection( Display* , Atom , Atom , Atom , Window , Time ); extern int XCopyArea( Display* , Drawable , Drawable , GC , int , int , unsigned int , unsigned int , int , int ); extern int XCopyGC( Display* , GC , unsigned long , GC ); extern int XCopyPlane( Display* , Drawable , Drawable , GC , int , int , unsigned int , unsigned int , int , int , unsigned long ); extern int XDefaultDepth( Display* , int ); extern int XDefaultDepthOfScreen( Screen* ); extern int XDefaultScreen( Display* ); extern int XDefineCursor( Display* , Window , Cursor ); extern int XDeleteProperty( Display* , Window , Atom ); extern int XDestroyWindow( Display* , Window ); extern int XDestroySubwindows( Display* , Window ); extern int XDoesBackingStore( Screen* ); extern int XDoesSaveUnders( Screen* ); extern int XDisableAccessControl( Display* ); extern int XDisplayCells( Display* , int ); extern int XDisplayHeight( Display* , int ); extern int XDisplayHeightMM( Display* , int ); extern int XDisplayKeycodes( Display* , int* , int* ); extern int XDisplayPlanes( Display* , int ); extern int XDisplayWidth( Display* , int ); extern int XDisplayWidthMM( Display* , int ); extern int XDrawArc( Display* , Drawable , GC , int , int , unsigned int , unsigned int , int , int ); extern int XDrawArcs( Display* , Drawable , GC , XArc* , int ); extern int XDrawImageString( Display* , Drawable , GC , int , int , const char* , int ); extern int XDrawImageString16( Display* , Drawable , GC , int , int , const XChar2b* , int ); extern int XDrawLine( Display* , Drawable , GC , int , int , int , int ); extern int XDrawLines( Display* , Drawable , GC , XPoint* , int , int ); extern int XDrawPoint( Display* , Drawable , GC , int , int ); extern int XDrawPoints( Display* , Drawable , GC , XPoint* , int , int ); extern int XDrawRectangle( Display* , Drawable , GC , int , int , unsigned int , unsigned int ); extern int XDrawRectangles( Display* , Drawable , GC , XRectangle* , int ); extern int XDrawSegments( Display* , Drawable , GC , XSegment* , int ); extern int XDrawString( Display* , Drawable , GC , int , int , const char* , int ); extern int XDrawString16( Display* , Drawable , GC , int , int , const XChar2b* , int ); extern int XDrawText( Display* , Drawable , GC , int , int , XTextItem* , int ); extern int XDrawText16( Display* , Drawable , GC , int , int , XTextItem16* , int ); extern int XEnableAccessControl( Display* ); extern int XEventsQueued( Display* , int ); extern int XFetchName( Display* , Window , char** ); extern int XFillArc( Display* , Drawable , GC , int , int , unsigned int , unsigned int , int , int ); extern int XFillArcs( Display* , Drawable , GC , XArc* , int ); extern int XFillPolygon( Display* , Drawable , GC , XPoint* , int , int , int ); extern int XFillRectangle( Display* , Drawable , GC , int , int , unsigned int , unsigned int ); extern int XFillRectangles( Display* , Drawable , GC , XRectangle* , int ); extern int XFlush( Display* ); extern int XForceScreenSaver( Display* , int ); extern int XFree( void* ); extern int XFreeColormap( Display* , Colormap ); extern int XFreeColors( Display* , Colormap , unsigned long* , int , unsigned long ); extern int XFreeCursor( Display* , Cursor ); extern int XFreeExtensionList( char** ); extern int XFreeFont( Display* , XFontStruct* ); extern int XFreeFontInfo( char** , XFontStruct* , int ); extern int XFreeFontNames( char** ); extern int XFreeFontPath( char** ); extern int XFreeGC( Display* , GC ); extern int XFreeModifiermap( XModifierKeymap* ); extern int XFreePixmap( Display* , Pixmap ); extern int XGeometry( Display* , int , const char* , const char* , unsigned int , unsigned int , unsigned int , int , int , int* , int* , int* , int* ); extern int XGetErrorDatabaseText( Display* , const char* , const char* , const char* , char* , int ); extern int XGetErrorText( Display* , int , char* , int ); extern int XGetFontProperty( XFontStruct* , Atom , unsigned long* ); extern int XGetGCValues( Display* , GC , unsigned long , XGCValues* ); extern int XGetGeometry( Display* , Drawable , Window* , int* , int* , unsigned int* , unsigned int* , unsigned int* , unsigned int* ); extern int XGetIconName( Display* , Window , char** ); extern int XGetInputFocus( Display* , Window* , int* ); extern int XGetKeyboardControl( Display* , XKeyboardState* ); extern int XGetPointerControl( Display* , int* , int* , int* ); extern int XGetPointerMapping( Display* , unsigned char* , int ); extern int XGetScreenSaver( Display* , int* , int* , int* , int* ); extern int XGetTransientForHint( Display* , Window , Window* ); extern int XGetWindowProperty( Display* , Window , Atom , long , long , int , Atom , Atom* , int* , unsigned long* , unsigned long* , unsigned char** ); extern int XGetWindowAttributes( Display* , Window , XWindowAttributes* ); extern int XGrabButton( Display* , unsigned int , unsigned int , Window , int , unsigned int , int , int , Window , Cursor ); extern int XGrabKey( Display* , int , unsigned int , Window , int , int , int ); extern int XGrabKeyboard( Display* , Window , int , int , int , Time ); extern int XGrabPointer( Display* , Window , int , unsigned int , int , int , Window , Cursor , Time ); extern int XGrabServer( Display* ); extern int XHeightMMOfScreen( Screen* ); extern int XHeightOfScreen( Screen* ); extern int XIfEvent( Display* , XEvent* , int (*) ( Display* , XEvent* , XPointer ) , XPointer ); extern int XImageByteOrder( Display* ); extern int XInstallColormap( Display* , Colormap ); extern KeyCode XKeysymToKeycode( Display* , KeySym ); extern int XKillClient( Display* , XID ); extern int XLookupColor( Display* , Colormap , const char* , XColor* , XColor* ); extern int XLowerWindow( Display* , Window ); extern int XMapRaised( Display* , Window ); extern int XMapSubwindows( Display* , Window ); extern int XMapWindow( Display* , Window ); extern int XMaskEvent( Display* , long , XEvent* ); extern int XMaxCmapsOfScreen( Screen* ); extern int XMinCmapsOfScreen( Screen* ); extern int XMoveResizeWindow( Display* , Window , int , int , unsigned int , unsigned int ); extern int XMoveWindow( Display* , Window , int , int ); extern int XNextEvent( Display* , XEvent* ); extern int XNoOp( Display* ); extern int XParseColor( Display* , Colormap , const char* , XColor* ); extern int XParseGeometry( const char* , int* , int* , unsigned int* , unsigned int* ); extern int XPeekEvent( Display* , XEvent* ); extern int XPeekIfEvent( Display* , XEvent* , int (*) ( Display* , XEvent* , XPointer ) , XPointer ); extern int XPending( Display* ); extern int XPlanesOfScreen( Screen* ); extern int XProtocolRevision( Display* ); extern int XProtocolVersion( Display* ); extern int XPutBackEvent( Display* , XEvent* ); extern int XPutImage( Display* , Drawable , GC , XImage* , int , int , int , int , unsigned int , unsigned int ); extern int XQLength( Display* ); extern int XQueryBestCursor( Display* , Drawable , unsigned int , unsigned int , unsigned int* , unsigned int* ); extern int XQueryBestSize( Display* , int , Drawable , unsigned int , unsigned int , unsigned int* , unsigned int* ); extern int XQueryBestStipple( Display* , Drawable , unsigned int , unsigned int , unsigned int* , unsigned int* ); extern int XQueryBestTile( Display* , Drawable , unsigned int , unsigned int , unsigned int* , unsigned int* ); extern int XQueryColor( Display* , Colormap , XColor* ); extern int XQueryColors( Display* , Colormap , XColor* , int ); extern int XQueryExtension( Display* , const char* , int* , int* , int* ); extern int XQueryKeymap( Display* , char [32] ); extern int XQueryPointer( Display* , Window , Window* , Window* , int* , int* , int* , int* , unsigned int* ); extern int XQueryTextExtents( Display* , XID , const char* , int , int* , int* , int* , XCharStruct* ); extern int XQueryTextExtents16( Display* , XID , const XChar2b* , int , int* , int* , int* , XCharStruct* ); extern int XQueryTree( Display* , Window , Window* , Window* , Window** , unsigned int* ); extern int XRaiseWindow( Display* , Window ); extern int XReadBitmapFile( Display* , Drawable , const char* , unsigned int* , unsigned int* , Pixmap* , int* , int* ); extern int XReadBitmapFileData( const char* , unsigned int* , unsigned int* , unsigned char** , int* , int* ); extern int XRebindKeysym( Display* , KeySym , KeySym* , int , const unsigned char* , int ); extern int XRecolorCursor( Display* , Cursor , XColor* , XColor* ); extern int XRefreshKeyboardMapping( XMappingEvent* ); extern int XRemoveFromSaveSet( Display* , Window ); extern int XRemoveHost( Display* , XHostAddress* ); extern int XRemoveHosts( Display* , XHostAddress* , int ); extern int XReparentWindow( Display* , Window , Window , int , int ); extern int XResetScreenSaver( Display* ); extern int XResizeWindow( Display* , Window , unsigned int , unsigned int ); extern int XRestackWindows( Display* , Window* , int ); extern int XRotateBuffers( Display* , int ); extern int XRotateWindowProperties( Display* , Window , Atom* , int , int ); extern int XScreenCount( Display* ); extern int XSelectInput( Display* , Window , long ); extern int XSendEvent( Display* , Window , int , long , XEvent* ); extern int XSetAccessControl( Display* , int ); extern int XSetArcMode( Display* , GC , int ); extern int XSetBackground( Display* , GC , unsigned long ); extern int XSetClipMask( Display* , GC , Pixmap ); extern int XSetClipOrigin( Display* , GC , int , int ); extern int XSetClipRectangles( Display* , GC , int , int , XRectangle* , int , int ); extern int XSetCloseDownMode( Display* , int ); extern int XSetCommand( Display* , Window , char** , int ); extern int XSetDashes( Display* , GC , int , const char* , int ); extern int XSetFillRule( Display* , GC , int ); extern int XSetFillStyle( Display* , GC , int ); extern int XSetFont( Display* , GC , Font ); extern int XSetFontPath( Display* , char** , int ); extern int XSetForeground( Display* , GC , unsigned long ); extern int XSetFunction( Display* , GC , int ); extern int XSetGraphicsExposures( Display* , GC , int ); extern int XSetIconName( Display* , Window , const char* ); extern int XSetInputFocus( Display* , Window , int , Time ); extern int XSetLineAttributes( Display* , GC , unsigned int , int , int , int ); extern int XSetModifierMapping( Display* , XModifierKeymap* ); extern int XSetPlaneMask( Display* , GC , unsigned long ); extern int XSetPointerMapping( Display* , const unsigned char* , int ); extern int XSetScreenSaver( Display* , int , int , int , int ); extern int XSetSelectionOwner( Display* , Atom , Window , Time ); extern int XSetState( Display* , GC , unsigned long , unsigned long , int , unsigned long ); extern int XSetStipple( Display* , GC , Pixmap ); extern int XSetSubwindowMode( Display* , GC , int ); extern int XSetTSOrigin( Display* , GC , int , int ); extern int XSetTile( Display* , GC , Pixmap ); extern int XSetWindowBackground( Display* , Window , unsigned long ); extern int XSetWindowBackgroundPixmap( Display* , Window , Pixmap ); extern int XSetWindowBorder( Display* , Window , unsigned long ); extern int XSetWindowBorderPixmap( Display* , Window , Pixmap ); extern int XSetWindowBorderWidth( Display* , Window , unsigned int ); extern int XSetWindowColormap( Display* , Window , Colormap ); extern int XStoreBuffer( Display* , const char* , int , int ); extern int XStoreBytes( Display* , const char* , int ); extern int XStoreColor( Display* , Colormap , XColor* ); extern int XStoreColors( Display* , Colormap , XColor* , int ); extern int XStoreName( Display* , Window , const char* ); extern int XStoreNamedColor( Display* , Colormap , const char* , unsigned long , int ); extern int XSync( Display* , int ); extern int XTextExtents( XFontStruct* , const char* , int , int* , int* , int* , XCharStruct* ); extern int XTextExtents16( XFontStruct* , const XChar2b* , int , int* , int* , int* , XCharStruct* ); extern int XTextWidth( XFontStruct* , const char* , int ); extern int XTextWidth16( XFontStruct* , const XChar2b* , int ); extern int XTranslateCoordinates( Display* , Window , Window , int , int , int* , int* , Window* ); extern int XUndefineCursor( Display* , Window ); extern int XUngrabButton( Display* , unsigned int , unsigned int , Window ); extern int XUngrabKey( Display* , int , unsigned int , Window ); extern int XUngrabKeyboard( Display* , Time ); extern int XUngrabPointer( Display* , Time ); extern int XUngrabServer( Display* ); extern int XUninstallColormap( Display* , Colormap ); extern int XUnloadFont( Display* , Font ); extern int XUnmapSubwindows( Display* , Window ); extern int XUnmapWindow( Display* , Window ); extern int XVendorRelease( Display* ); extern int XWarpPointer( Display* , Window , Window , int , int , unsigned int , unsigned int , int , int ); extern int XWidthMMOfScreen( Screen* ); extern int XWidthOfScreen( Screen* ); extern int XWindowEvent( Display* , Window , long , XEvent* ); extern int XWriteBitmapFile( Display* , const char* , Pixmap , unsigned int , unsigned int , int , int ); extern int XSupportsLocale (void); extern char *XSetLocaleModifiers( const char* ); extern XOM XOpenOM( Display* , struct _XrmHashBucketRec* , const char* , const char* ); extern int XCloseOM( XOM ); extern char *XSetOMValues( XOM , ... ) __attribute__ ((__sentinel__(0))); extern char *XGetOMValues( XOM , ... ) __attribute__ ((__sentinel__(0))); extern Display *XDisplayOfOM( XOM ); extern char *XLocaleOfOM( XOM ); extern XOC XCreateOC( XOM , ... ) __attribute__ ((__sentinel__(0))); extern void XDestroyOC( XOC ); extern XOM XOMOfOC( XOC ); extern char *XSetOCValues( XOC , ... ) __attribute__ ((__sentinel__(0))); extern char *XGetOCValues( XOC , ... ) __attribute__ ((__sentinel__(0))); extern XFontSet XCreateFontSet( Display* , const char* , char*** , int* , char** ); extern void XFreeFontSet( Display* , XFontSet ); extern int XFontsOfFontSet( XFontSet , XFontStruct*** , char*** ); extern char *XBaseFontNameListOfFontSet( XFontSet ); extern char *XLocaleOfFontSet( XFontSet ); extern int XContextDependentDrawing( XFontSet ); extern int XDirectionalDependentDrawing( XFontSet ); extern int XContextualDrawing( XFontSet ); extern XFontSetExtents *XExtentsOfFontSet( XFontSet ); extern int XmbTextEscapement( XFontSet , const char* , int ); extern int XwcTextEscapement( XFontSet , const wchar_t* , int ); extern int Xutf8TextEscapement( XFontSet , const char* , int ); extern int XmbTextExtents( XFontSet , const char* , int , XRectangle* , XRectangle* ); extern int XwcTextExtents( XFontSet , const wchar_t* , int , XRectangle* , XRectangle* ); extern int Xutf8TextExtents( XFontSet , const char* , int , XRectangle* , XRectangle* ); extern int XmbTextPerCharExtents( XFontSet , const char* , int , XRectangle* , XRectangle* , int , int* , XRectangle* , XRectangle* ); extern int XwcTextPerCharExtents( XFontSet , const wchar_t* , int , XRectangle* , XRectangle* , int , int* , XRectangle* , XRectangle* ); extern int Xutf8TextPerCharExtents( XFontSet , const char* , int , XRectangle* , XRectangle* , int , int* , XRectangle* , XRectangle* ); extern void XmbDrawText( Display* , Drawable , GC , int , int , XmbTextItem* , int ); extern void XwcDrawText( Display* , Drawable , GC , int , int , XwcTextItem* , int ); extern void Xutf8DrawText( Display* , Drawable , GC , int , int , XmbTextItem* , int ); extern void XmbDrawString( Display* , Drawable , XFontSet , GC , int , int , const char* , int ); extern void XwcDrawString( Display* , Drawable , XFontSet , GC , int , int , const wchar_t* , int ); extern void Xutf8DrawString( Display* , Drawable , XFontSet , GC , int , int , const char* , int ); extern void XmbDrawImageString( Display* , Drawable , XFontSet , GC , int , int , const char* , int ); extern void XwcDrawImageString( Display* , Drawable , XFontSet , GC , int , int , const wchar_t* , int ); extern void Xutf8DrawImageString( Display* , Drawable , XFontSet , GC , int , int , const char* , int ); extern XIM XOpenIM( Display* , struct _XrmHashBucketRec* , char* , char* ); extern int XCloseIM( XIM ); extern char *XGetIMValues( XIM , ... ) __attribute__ ((__sentinel__(0))); extern char *XSetIMValues( XIM , ... ) __attribute__ ((__sentinel__(0))); extern Display *XDisplayOfIM( XIM ); extern char *XLocaleOfIM( XIM ); extern XIC XCreateIC( XIM , ... ) __attribute__ ((__sentinel__(0))); extern void XDestroyIC( XIC ); extern void XSetICFocus( XIC ); extern void XUnsetICFocus( XIC ); extern wchar_t *XwcResetIC( XIC ); extern char *XmbResetIC( XIC ); extern char *Xutf8ResetIC( XIC ); extern char *XSetICValues( XIC , ... ) __attribute__ ((__sentinel__(0))); extern char *XGetICValues( XIC , ... ) __attribute__ ((__sentinel__(0))); extern XIM XIMOfIC( XIC ); extern int XFilterEvent( XEvent* , Window ); extern int XmbLookupString( XIC , XKeyPressedEvent* , char* , int , KeySym* , int* ); extern int XwcLookupString( XIC , XKeyPressedEvent* , wchar_t* , int , KeySym* , int* ); extern int Xutf8LookupString( XIC , XKeyPressedEvent* , char* , int , KeySym* , int* ); extern XVaNestedList XVaCreateNestedList( int , ... ) __attribute__ ((__sentinel__(0))); extern int XRegisterIMInstantiateCallback( Display* , struct _XrmHashBucketRec* , char* , char* , XIDProc , XPointer ); extern int XUnregisterIMInstantiateCallback( Display* , struct _XrmHashBucketRec* , char* , char* , XIDProc , XPointer ); typedef void (*XConnectionWatchProc)( Display* , XPointer , int , int , XPointer* ); extern int XInternalConnectionNumbers( Display* , int** , int* ); extern void XProcessInternalConnection( Display* , int ); extern int XAddConnectionWatch( Display* , XConnectionWatchProc , XPointer ); extern void XRemoveConnectionWatch( Display* , XConnectionWatchProc , XPointer ); extern void XSetAuthorization( char * , int , char * , int ); extern int _Xmbtowc( wchar_t * , char * , int ); extern int _Xwctomb( char * , wchar_t ); } typedef struct { long flags; int x, y; int width, height; int min_width, min_height; int max_width, max_height; int width_inc, height_inc; struct { int x; int y; } min_aspect, max_aspect; int base_width, base_height; int win_gravity; } XSizeHints; typedef struct { long flags; int input; int initial_state; Pixmap icon_pixmap; Window icon_window; int icon_x, icon_y; Pixmap icon_mask; XID window_group; } XWMHints; typedef struct { unsigned char *value; Atom encoding; int format; unsigned long nitems; } XTextProperty; typedef enum { XStringStyle, XCompoundTextStyle, XTextStyle, XStdICCTextStyle, XUTF8StringStyle } XICCEncodingStyle; typedef struct { int min_width, min_height; int max_width, max_height; int width_inc, height_inc; } XIconSize; typedef struct { char *res_name; char *res_class; } XClassHint; typedef struct _XComposeStatus { XPointer compose_ptr; int chars_matched; } XComposeStatus; typedef struct _XRegion *Region; typedef struct { Visual *visual; VisualID visualid; int screen; int depth; int c_class; unsigned long red_mask; unsigned long green_mask; unsigned long blue_mask; int colormap_size; int bits_per_rgb; } XVisualInfo; typedef struct { Colormap colormap; unsigned long red_max; unsigned long red_mult; unsigned long green_max; unsigned long green_mult; unsigned long blue_max; unsigned long blue_mult; unsigned long base_pixel; VisualID visualid; XID killid; } XStandardColormap; typedef int XContext; extern "C" { extern XClassHint *XAllocClassHint ( void ); extern XIconSize *XAllocIconSize ( void ); extern XSizeHints *XAllocSizeHints ( void ); extern XStandardColormap *XAllocStandardColormap ( void ); extern XWMHints *XAllocWMHints ( void ); extern int XClipBox( Region , XRectangle* ); extern Region XCreateRegion( void ); extern const char *XDefaultString (void); extern int XDeleteContext( Display* , XID , XContext ); extern int XDestroyRegion( Region ); extern int XEmptyRegion( Region ); extern int XEqualRegion( Region , Region ); extern int XFindContext( Display* , XID , XContext , XPointer* ); extern int XGetClassHint( Display* , Window , XClassHint* ); extern int XGetIconSizes( Display* , Window , XIconSize** , int* ); extern int XGetNormalHints( Display* , Window , XSizeHints* ); extern int XGetRGBColormaps( Display* , Window , XStandardColormap** , int* , Atom ); extern int XGetSizeHints( Display* , Window , XSizeHints* , Atom ); extern int XGetStandardColormap( Display* , Window , XStandardColormap* , Atom ); extern int XGetTextProperty( Display* , Window , XTextProperty* , Atom ); extern XVisualInfo *XGetVisualInfo( Display* , long , XVisualInfo* , int* ); extern int XGetWMClientMachine( Display* , Window , XTextProperty* ); extern XWMHints *XGetWMHints( Display* , Window ); extern int XGetWMIconName( Display* , Window , XTextProperty* ); extern int XGetWMName( Display* , Window , XTextProperty* ); extern int XGetWMNormalHints( Display* , Window , XSizeHints* , long* ); extern int XGetWMSizeHints( Display* , Window , XSizeHints* , long* , Atom ); extern int XGetZoomHints( Display* , Window , XSizeHints* ); extern int XIntersectRegion( Region , Region , Region ); extern void XConvertCase( KeySym , KeySym* , KeySym* ); extern int XLookupString( XKeyEvent* , char* , int , KeySym* , XComposeStatus* ); extern int XMatchVisualInfo( Display* , int , int , int , XVisualInfo* ); extern int XOffsetRegion( Region , int , int ); extern int XPointInRegion( Region , int , int ); extern Region XPolygonRegion( XPoint* , int , int ); extern int XRectInRegion( Region , int , int , unsigned int , unsigned int ); extern int XSaveContext( Display* , XID , XContext , const char* ); extern int XSetClassHint( Display* , Window , XClassHint* ); extern int XSetIconSizes( Display* , Window , XIconSize* , int ); extern int XSetNormalHints( Display* , Window , XSizeHints* ); extern void XSetRGBColormaps( Display* , Window , XStandardColormap* , int , Atom ); extern int XSetSizeHints( Display* , Window , XSizeHints* , Atom ); extern int XSetStandardProperties( Display* , Window , const char* , const char* , Pixmap , char** , int , XSizeHints* ); extern void XSetTextProperty( Display* , Window , XTextProperty* , Atom ); extern void XSetWMClientMachine( Display* , Window , XTextProperty* ); extern int XSetWMHints( Display* , Window , XWMHints* ); extern void XSetWMIconName( Display* , Window , XTextProperty* ); extern void XSetWMName( Display* , Window , XTextProperty* ); extern void XSetWMNormalHints( Display* , Window , XSizeHints* ); extern void XSetWMProperties( Display* , Window , XTextProperty* , XTextProperty* , char** , int , XSizeHints* , XWMHints* , XClassHint* ); extern void XmbSetWMProperties( Display* , Window , const char* , const char* , char** , int , XSizeHints* , XWMHints* , XClassHint* ); extern void Xutf8SetWMProperties( Display* , Window , const char* , const char* , char** , int , XSizeHints* , XWMHints* , XClassHint* ); extern void XSetWMSizeHints( Display* , Window , XSizeHints* , Atom ); extern int XSetRegion( Display* , GC , Region ); extern void XSetStandardColormap( Display* , Window , XStandardColormap* , Atom ); extern int XSetZoomHints( Display* , Window , XSizeHints* ); extern int XShrinkRegion( Region , int , int ); extern int XStringListToTextProperty( char** , int , XTextProperty* ); extern int XSubtractRegion( Region , Region , Region ); extern int XmbTextListToTextProperty( Display* display, char** list, int count, XICCEncodingStyle style, XTextProperty* text_prop_return ); extern int XwcTextListToTextProperty( Display* display, wchar_t** list, int count, XICCEncodingStyle style, XTextProperty* text_prop_return ); extern int Xutf8TextListToTextProperty( Display* display, char** list, int count, XICCEncodingStyle style, XTextProperty* text_prop_return ); extern void XwcFreeStringList( wchar_t** list ); extern int XTextPropertyToStringList( XTextProperty* , char*** , int* ); extern int XmbTextPropertyToTextList( Display* display, const XTextProperty* text_prop, char*** list_return, int* count_return ); extern int XwcTextPropertyToTextList( Display* display, const XTextProperty* text_prop, wchar_t*** list_return, int* count_return ); extern int Xutf8TextPropertyToTextList( Display* display, const XTextProperty* text_prop, char*** list_return, int* count_return ); extern int XUnionRectWithRegion( XRectangle* , Region , Region ); extern int XUnionRegion( Region , Region , Region ); extern int XWMGeometry( Display* , int , const char* , const char* , unsigned int , XSizeHints* , int* , int* , int* , int* , int* ); extern int XXorRegion( Region , Region , Region ); } struct sched_param { int __sched_priority; }; extern "C" { extern int clone (int (*__fn) (void *__arg), void *__child_stack, int __flags, void *__arg, ...) throw (); extern int unshare (int __flags) throw (); extern int sched_getcpu (void) throw (); } struct __sched_param { int __sched_priority; }; typedef unsigned long int __cpu_mask; typedef struct { __cpu_mask __bits[1024 / (8 * sizeof (__cpu_mask))]; } cpu_set_t; extern "C" { extern int __sched_cpucount (size_t __setsize, const cpu_set_t *__setp) throw (); extern cpu_set_t *__sched_cpualloc (size_t __count) throw () ; extern void __sched_cpufree (cpu_set_t *__set) throw (); } extern "C" { extern int sched_setparam (__pid_t __pid, __const struct sched_param *__param) throw (); extern int sched_getparam (__pid_t __pid, struct sched_param *__param) throw (); extern int sched_setscheduler (__pid_t __pid, int __policy, __const struct sched_param *__param) throw (); extern int sched_getscheduler (__pid_t __pid) throw (); extern int sched_yield (void) throw (); extern int sched_get_priority_max (int __algorithm) throw (); extern int sched_get_priority_min (int __algorithm) throw (); extern int sched_rr_get_interval (__pid_t __pid, struct timespec *__t) throw (); extern int sched_setaffinity (__pid_t __pid, size_t __cpusetsize, __const cpu_set_t *__cpuset) throw (); extern int sched_getaffinity (__pid_t __pid, size_t __cpusetsize, cpu_set_t *__cpuset) throw (); } extern "C" { } typedef long int __jmp_buf[8]; enum { PTHREAD_CREATE_JOINABLE, PTHREAD_CREATE_DETACHED }; enum { PTHREAD_MUTEX_TIMED_NP, PTHREAD_MUTEX_RECURSIVE_NP, PTHREAD_MUTEX_ERRORCHECK_NP, PTHREAD_MUTEX_ADAPTIVE_NP , PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP, PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP }; enum { PTHREAD_MUTEX_STALLED_NP, PTHREAD_MUTEX_ROBUST_NP }; enum { PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, PTHREAD_PRIO_PROTECT }; enum { PTHREAD_RWLOCK_PREFER_READER_NP, PTHREAD_RWLOCK_PREFER_WRITER_NP, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP }; enum { PTHREAD_INHERIT_SCHED, PTHREAD_EXPLICIT_SCHED }; enum { PTHREAD_SCOPE_SYSTEM, PTHREAD_SCOPE_PROCESS }; enum { PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED }; struct _pthread_cleanup_buffer { void (*__routine) (void *); void *__arg; int __canceltype; struct _pthread_cleanup_buffer *__prev; }; enum { PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE }; enum { PTHREAD_CANCEL_DEFERRED, PTHREAD_CANCEL_ASYNCHRONOUS }; extern "C" { extern int pthread_create (pthread_t *__restrict __newthread, __const pthread_attr_t *__restrict __attr, void *(*__start_routine) (void *), void *__restrict __arg) throw () __attribute__ ((__nonnull__ (1, 3))); extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__)); extern int pthread_join (pthread_t __th, void **__thread_return); extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) throw (); extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return, __const struct timespec *__abstime); extern int pthread_detach (pthread_t __th) throw (); extern pthread_t pthread_self (void) throw () __attribute__ ((__const__)); extern int pthread_equal (pthread_t __thread1, pthread_t __thread2) throw (); extern int pthread_attr_init (pthread_attr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_attr_destroy (pthread_attr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_attr_getdetachstate (__const pthread_attr_t *__attr, int *__detachstate) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_attr_setdetachstate (pthread_attr_t *__attr, int __detachstate) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_attr_getguardsize (__const pthread_attr_t *__attr, size_t *__guardsize) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_attr_setguardsize (pthread_attr_t *__attr, size_t __guardsize) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_attr_getschedparam (__const pthread_attr_t *__restrict __attr, struct sched_param *__restrict __param) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr, __const struct sched_param *__restrict __param) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_attr_getschedpolicy (__const pthread_attr_t *__restrict __attr, int *__restrict __policy) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_attr_getinheritsched (__const pthread_attr_t *__restrict __attr, int *__restrict __inherit) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_attr_setinheritsched (pthread_attr_t *__attr, int __inherit) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_attr_getscope (__const pthread_attr_t *__restrict __attr, int *__restrict __scope) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_attr_getstackaddr (__const pthread_attr_t *__restrict __attr, void **__restrict __stackaddr) throw () __attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__deprecated__)); extern int pthread_attr_setstackaddr (pthread_attr_t *__attr, void *__stackaddr) throw () __attribute__ ((__nonnull__ (1))) __attribute__ ((__deprecated__)); extern int pthread_attr_getstacksize (__const pthread_attr_t *__restrict __attr, size_t *__restrict __stacksize) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_attr_setstacksize (pthread_attr_t *__attr, size_t __stacksize) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_attr_getstack (__const pthread_attr_t *__restrict __attr, void **__restrict __stackaddr, size_t *__restrict __stacksize) throw () __attribute__ ((__nonnull__ (1, 2, 3))); extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr, size_t __stacksize) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_attr_setaffinity_np (pthread_attr_t *__attr, size_t __cpusetsize, __const cpu_set_t *__cpuset) throw () __attribute__ ((__nonnull__ (1, 3))); extern int pthread_attr_getaffinity_np (__const pthread_attr_t *__attr, size_t __cpusetsize, cpu_set_t *__cpuset) throw () __attribute__ ((__nonnull__ (1, 3))); extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) throw () __attribute__ ((__nonnull__ (2))); extern int pthread_setschedparam (pthread_t __target_thread, int __policy, __const struct sched_param *__param) throw () __attribute__ ((__nonnull__ (3))); extern int pthread_getschedparam (pthread_t __target_thread, int *__restrict __policy, struct sched_param *__restrict __param) throw () __attribute__ ((__nonnull__ (2, 3))); extern int pthread_setschedprio (pthread_t __target_thread, int __prio) throw (); extern int pthread_getconcurrency (void) throw (); extern int pthread_setconcurrency (int __level) throw (); extern int pthread_yield (void) throw (); extern int pthread_setaffinity_np (pthread_t __th, size_t __cpusetsize, __const cpu_set_t *__cpuset) throw () __attribute__ ((__nonnull__ (3))); extern int pthread_getaffinity_np (pthread_t __th, size_t __cpusetsize, cpu_set_t *__cpuset) throw () __attribute__ ((__nonnull__ (3))); extern int pthread_once (pthread_once_t *__once_control, void (*__init_routine) (void)) __attribute__ ((__nonnull__ (1, 2))); extern int pthread_setcancelstate (int __state, int *__oldstate); extern int pthread_setcanceltype (int __type, int *__oldtype); extern int pthread_cancel (pthread_t __th); extern void pthread_testcancel (void); typedef struct { struct { __jmp_buf __cancel_jmp_buf; int __mask_was_saved; } __cancel_jmp_buf[1]; void *__pad[4]; } __pthread_unwind_buf_t __attribute__ ((__aligned__)); struct __pthread_cleanup_frame { void (*__cancel_routine) (void *); void *__cancel_arg; int __do_it; int __cancel_type; }; class __pthread_cleanup_class { void (*__cancel_routine) (void *); void *__cancel_arg; int __do_it; int __cancel_type; public: __pthread_cleanup_class (void (*__fct) (void *), void *__arg) : __cancel_routine (__fct), __cancel_arg (__arg), __do_it (1) { } ~__pthread_cleanup_class () { if (__do_it) __cancel_routine (__cancel_arg); } void __setdoit (int __newval) { __do_it = __newval; } void __defer () { pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &__cancel_type); } void __restore () const { pthread_setcanceltype (__cancel_type, 0); } }; struct __jmp_buf_tag; extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) throw (); extern int pthread_mutex_init (pthread_mutex_t *__mutex, __const pthread_mutexattr_t *__mutexattr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutex_destroy (pthread_mutex_t *__mutex) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutex_trylock (pthread_mutex_t *__mutex) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutex_lock (pthread_mutex_t *__mutex) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex, __const struct timespec *__restrict __abstime) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutex_getprioceiling (__const pthread_mutex_t * __restrict __mutex, int *__restrict __prioceiling) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict __mutex, int __prioceiling, int *__restrict __old_ceiling) throw () __attribute__ ((__nonnull__ (1, 3))); extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutexattr_getpshared (__const pthread_mutexattr_t * __restrict __attr, int *__restrict __pshared) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr, int __pshared) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict __attr, int *__restrict __kind) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutexattr_getprotocol (__const pthread_mutexattr_t * __restrict __attr, int *__restrict __protocol) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr, int __protocol) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutexattr_getprioceiling (__const pthread_mutexattr_t * __restrict __attr, int *__restrict __prioceiling) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t *__attr, int __prioceiling) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_mutexattr_getrobust_np (__const pthread_mutexattr_t *__attr, int *__robustness) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr, int __robustness) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock, __const pthread_rwlockattr_t *__restrict __attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock, __const struct timespec *__restrict __abstime) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock, __const struct timespec *__restrict __abstime) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlockattr_getpshared (__const pthread_rwlockattr_t * __restrict __attr, int *__restrict __pshared) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr, int __pshared) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_rwlockattr_getkind_np (__const pthread_rwlockattr_t * __restrict __attr, int *__restrict __pref) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr, int __pref) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_cond_init (pthread_cond_t *__restrict __cond, __const pthread_condattr_t *__restrict __cond_attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_cond_destroy (pthread_cond_t *__cond) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_cond_signal (pthread_cond_t *__cond) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_cond_broadcast (pthread_cond_t *__cond) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_cond_wait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex) __attribute__ ((__nonnull__ (1, 2))); extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex, __const struct timespec *__restrict __abstime) __attribute__ ((__nonnull__ (1, 2, 3))); extern int pthread_condattr_init (pthread_condattr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_condattr_destroy (pthread_condattr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_condattr_getpshared (__const pthread_condattr_t * __restrict __attr, int *__restrict __pshared) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_condattr_setpshared (pthread_condattr_t *__attr, int __pshared) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_condattr_getclock (__const pthread_condattr_t * __restrict __attr, __clockid_t *__restrict __clock_id) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_condattr_setclock (pthread_condattr_t *__attr, __clockid_t __clock_id) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_spin_destroy (pthread_spinlock_t *__lock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_spin_lock (pthread_spinlock_t *__lock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_spin_trylock (pthread_spinlock_t *__lock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_spin_unlock (pthread_spinlock_t *__lock) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier, __const pthread_barrierattr_t *__restrict __attr, unsigned int __count) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_barrier_destroy (pthread_barrier_t *__barrier) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_barrier_wait (pthread_barrier_t *__barrier) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_barrierattr_getpshared (__const pthread_barrierattr_t * __restrict __attr, int *__restrict __pshared) throw () __attribute__ ((__nonnull__ (1, 2))); extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr, int __pshared) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_key_create (pthread_key_t *__key, void (*__destr_function) (void *)) throw () __attribute__ ((__nonnull__ (1))); extern int pthread_key_delete (pthread_key_t __key) throw (); extern void *pthread_getspecific (pthread_key_t __key) throw (); extern int pthread_setspecific (pthread_key_t __key, __const void *__pointer) throw () ; extern int pthread_getcpuclockid (pthread_t __thread_id, __clockid_t *__clock_id) throw () __attribute__ ((__nonnull__ (2))); extern int pthread_atfork (void (*__prepare) (void), void (*__parent) (void), void (*__child) (void)) throw (); extern __inline __attribute__ ((__gnu_inline__)) int pthread_equal (pthread_t __thread1, pthread_t __thread2) throw () { return __thread1 == __thread2; } } namespace cimg_library { template struct CImg; template struct CImgList; struct CImgDisplay; struct CImgException; namespace cimg { inline void info(); inline unsigned int& exception_mode(); inline int dialog(const char *title, const char *msg, const char *button1_txt="OK", const char *button2_txt=0, const char *button3_txt=0, const char *button4_txt=0, const char *button5_txt=0, const char *button6_txt=0, const bool centering=false); template inline void marching_cubes(const tfunc& func, const float isovalue, const float x0, const float y0, const float z0, const float x1, const float y1, const float z1, const float resx, const float resy, const float resz, CImgList& points, CImgList& primitives, const bool invert_faces=false); template inline void marching_squares(const tfunc& func, const float isovalue, const float x0, const float y0, const float x1, const float y1, const float resx, const float resy, CImgList& points, CImgList& primitives); } struct CImgException { char message[1024]; CImgException() { message[0]='\0'; } CImgException(const char *format, ...) { std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(message,format,ap); __builtin_va_end(ap); if (cimg::exception_mode()>=1) { if (cimg::exception_mode()>=2 && true) { try { cimg::dialog("CImgException",message,"Abort"); } catch (CImgException&) { std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgException",message); } } else std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgException",message); } if (cimg::exception_mode()>=3) cimg_library::cimg::info();; } }; struct CImgInstanceException : public CImgException { CImgInstanceException(const char *format, ...) { std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(message,format,ap); __builtin_va_end(ap); if (cimg::exception_mode()>=1) { if (cimg::exception_mode()>=2 && true) { try { cimg::dialog("CImgInstanceException",message,"Abort"); } catch (CImgException&) { std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgInstanceException",message); } } else std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgInstanceException",message); } if (cimg::exception_mode()>=3) cimg_library::cimg::info();; } }; struct CImgArgumentException : public CImgException { CImgArgumentException(const char *format, ...) { std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(message,format,ap); __builtin_va_end(ap); if (cimg::exception_mode()>=1) { if (cimg::exception_mode()>=2 && true) { try { cimg::dialog("CImgArgumentException",message,"Abort"); } catch (CImgException&) { std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgArgumentException",message); } } else std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgArgumentException",message); } if (cimg::exception_mode()>=3) cimg_library::cimg::info();; } }; struct CImgIOException : public CImgException { CImgIOException(const char *format, ...) { std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(message,format,ap); __builtin_va_end(ap); if (cimg::exception_mode()>=1) { if (cimg::exception_mode()>=2 && true) { try { cimg::dialog("CImgIOException",message,"Abort"); } catch (CImgException&) { std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgIOException",message); } } else std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgIOException",message); } if (cimg::exception_mode()>=3) cimg_library::cimg::info();; } }; struct CImgDisplayException : public CImgException { CImgDisplayException(const char *format, ...) { std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(message,format,ap); __builtin_va_end(ap); if (cimg::exception_mode()>=1) { if (cimg::exception_mode()>=2 && false) { try { cimg::dialog("CImgDisplayException",message,"Abort"); } catch (CImgException&) { std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgDisplayException",message); } } else std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgDisplayException",message); } if (cimg::exception_mode()>=3) cimg_library::cimg::info();; } }; struct CImgWarningException : public CImgException { CImgWarningException(const char *format, ...) { std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(message,format,ap); __builtin_va_end(ap); if (cimg::exception_mode()>=1) { if (cimg::exception_mode()>=2 && false) { try { cimg::dialog("CImgWarningException",message,"Abort"); } catch (CImgException&) { std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgWarningException",message); } } else std::fprintf(stderr,"\n# %s :\n%s\n\n","CImgWarningException",message); } if (cimg::exception_mode()>=3) cimg_library::cimg::info();; } }; namespace cimg { template struct type { static const char* string() { static const char* s[] = { "unknown", "unknown8", "unknown16", "unknown24", "unknown32", "unknown40", "unknown48", "unknown56", "unknown64", "unknown72", "unknown80", "unknown88", "unknown96", "unknown104", "unknown112", "unknown120", "unknown128" }; return s[(sizeof(T)<17)?sizeof(T):0]; } static bool is_float() { return false; } static T min() { return (T)-1>0?(T)0:(T)-1<<(8*sizeof(T)-1); } static T max() { return (T)-1>0?(T)-1:~((T)-1<<(8*sizeof(T)-1)); } static const char* format() { return "%s"; } static const char* format(const T val) { static const char *s = "unknown"; return s; } }; template<> struct type { static const char* string() { static const char *const s = "bool"; return s; } static bool is_float() { return false; } static bool min() { return false; } static bool max() { return true; } static const char* format() { return "%s"; } static const char* format(const bool val) { static const char* s[] = { "false", "true" }; return s[val?1:0]; } }; template<> struct type { static const char* string() { static const char *const s = "unsigned char"; return s; } static bool is_float() { return false; } static unsigned char min() { return 0; } static unsigned char max() { return (unsigned char)~0U; } static const char* format() { return "%u"; } static unsigned int format(const unsigned char val) { return (unsigned int)val; } }; template<> struct type { static const char* string() { static const char *const s = "char"; return s; } static bool is_float() { return false; } static char min() { return (char)(-1L<<(8*sizeof(char)-1)); } static char max() { return ~((char)(-1L<<(8*sizeof(char)-1))); } static const char* format() { return "%d"; } static int format(const char val) { return (int)val; } }; template<> struct type { static const char* string() { static const char *const s = "unsigned short"; return s; } static bool is_float() { return false; } static unsigned short min() { return 0; } static unsigned short max() { return (unsigned short)~0U; } static const char* format() { return "%u"; } static unsigned int format(const unsigned short val) { return (unsigned int)val; } }; template<> struct type { static const char* string() { static const char *const s = "short"; return s; } static bool is_float() { return false; } static short min() { return (short)(-1L<<(8*sizeof(short)-1)); } static short max() { return ~((short)(-1L<<(8*sizeof(short)-1))); } static const char* format() { return "%d"; } static int format(const short val) { return (int)val; } }; template<> struct type { static const char* string() { static const char *const s = "unsigned int"; return s; } static bool is_float() { return false; } static unsigned int min() { return 0; } static unsigned int max() { return (unsigned int)~0U; } static const char* format() { return "%u"; } static unsigned int format(const unsigned int val) { return val; } }; template<> struct type { static const char* string() { static const char *const s = "int"; return s; } static bool is_float() { return false; } static int min() { return (int)(-1L<<(8*sizeof(int)-1)); } static int max() { return ~((int)(-1L<<(8*sizeof(int)-1))); } static const char* format() { return "%d"; } static int format(const int val) { return val; } }; template<> struct type { static const char* string() { static const char *const s = "unsigned long"; return s; } static bool is_float() { return false; } static unsigned long min() { return 0; } static unsigned long max() { return (unsigned long)~0UL; } static const char* format() { return "%lu"; } static unsigned long format(const unsigned long val) { return val; } }; template<> struct type { static const char* string() { static const char *const s = "long"; return s; } static bool is_float() { return false; } static long min() { return (long)(-1L<<(8*sizeof(long)-1)); } static long max() { return ~((long)(-1L<<(8*sizeof(long)-1))); } static const char* format() { return "%ld"; } static long format(const long val) { return val; } }; template<> struct type { static const char* string() { static const char *const s = "float"; return s; } static bool is_float() { return true; } static float min() { return -3.4E38f; } static float max() { return 3.4E38f; } static const char* format() { return "%g"; } static double format(const float val) { return (double)val; } }; template<> struct type { static const char* string() { static const char *const s = "double"; return s; } static bool is_float() { return true; } static double min() { return -1.7E308; } static double max() { return 1.7E308; } static const char* format() { return "%g"; } static double format(const double val) { return val; } }; template struct superset { typedef T type; }; template<> struct superset { typedef unsigned char type; }; template<> struct superset { typedef char type; }; template<> struct superset { typedef unsigned short type; }; template<> struct superset { typedef short type; }; template<> struct superset { typedef unsigned int type; }; template<> struct superset { typedef int type; }; template<> struct superset { typedef unsigned long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef float type; }; template<> struct superset { typedef double type; }; template<> struct superset { typedef short type; }; template<> struct superset { typedef unsigned short type; }; template<> struct superset { typedef short type; }; template<> struct superset { typedef unsigned int type; }; template<> struct superset { typedef int type; }; template<> struct superset { typedef unsigned long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef float type; }; template<> struct superset { typedef double type; }; template<> struct superset { typedef short type; }; template<> struct superset { typedef int type; }; template<> struct superset { typedef short type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef int type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef float type; }; template<> struct superset { typedef double type; }; template<> struct superset { typedef int type; }; template<> struct superset { typedef int type; }; template<> struct superset { typedef unsigned int type; }; template<> struct superset { typedef int type; }; template<> struct superset { typedef unsigned long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef float type; }; template<> struct superset { typedef double type; }; template<> struct superset { typedef int type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef int type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef float type; }; template<> struct superset { typedef double type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef unsigned long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef float type; }; template<> struct superset { typedef double type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef float type; }; template<> struct superset { typedef double type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef long type; }; template<> struct superset { typedef float type; }; template<> struct superset { typedef double type; }; template<> struct superset { typedef float type; }; template<> struct superset { typedef double type; }; template<> struct superset { typedef double type; }; template struct superset2 { typedef typename superset::type>::type type; }; template struct superset3 { typedef typename superset::type>::type type; }; template struct last { typedef t2 type; }; struct X11info { volatile unsigned int nb_wins; pthread_t* event_thread; CImgDisplay* wins[1024]; Display* display; unsigned int nb_bits; GC* gc; bool blue_first; bool byte_order; bool shm_enabled; X11info():nb_wins(0),event_thread(0),display(0), nb_bits(0),gc(0),blue_first(false),byte_order(false),shm_enabled(false) { } }; inline X11info& X11attr() { static X11info val; return val; } inline unsigned int& exception_mode() { static unsigned int mode = 1; return mode; } const char t_normal[] = { 0x1b,'[','0',';','0',';','0','m','\0' }; const char t_red[] = { 0x1b,'[','4',';','3','1',';','5','9','m','\0' }; const char t_bold[] = { 0x1b,'[','1','m','\0' }; const char t_purple[] = { 0x1b,'[','0',';','3','5',';','5','9','m','\0' }; const unsigned int keyESC = 0xff1b; const unsigned int keyF1 = 0xffbe; const unsigned int keyF2 = 0xffbf; const unsigned int keyF3 = 0xffc0; const unsigned int keyF4 = 0xffc1; const unsigned int keyF5 = 0xffc2; const unsigned int keyF6 = 0xffc3; const unsigned int keyF7 = 0xffc4; const unsigned int keyF8 = 0xffc5; const unsigned int keyF9 = 0xffc6; const unsigned int keyF10 = 0xffc7; const unsigned int keyF11 = 0xffc8; const unsigned int keyF12 = 0xffc9; const unsigned int keyPAUSE = 0xff13; const unsigned int key1 = 0x0031; const unsigned int key2 = 0x0032; const unsigned int key3 = 0x0033; const unsigned int key4 = 0x0034; const unsigned int key5 = 0x0035; const unsigned int key6 = 0x0036; const unsigned int key7 = 0x0037; const unsigned int key8 = 0x0038; const unsigned int key9 = 0x0039; const unsigned int key0 = 0x0030; const unsigned int keyBACKSPACE = 0xff08; const unsigned int keyINSERT = 0xff63; const unsigned int keyHOME = 0xff50; const unsigned int keyPAGEUP = 0xff55; const unsigned int keyTAB = 0xff09; const unsigned int keyQ = 0x0071; const unsigned int keyW = 0x0077; const unsigned int keyE = 0x0065; const unsigned int keyR = 0x0072; const unsigned int keyT = 0x0074; const unsigned int keyY = 0x0079; const unsigned int keyU = 0x0075; const unsigned int keyI = 0x0069; const unsigned int keyO = 0x006f; const unsigned int keyP = 0x0070; const unsigned int keyDELETE = 0xffff; const unsigned int keyEND = 0xff57; const unsigned int keyPAGEDOWN = 0xff56; const unsigned int keyCAPSLOCK = 0xffe5; const unsigned int keyA = 0x0061; const unsigned int keyS = 0x0073; const unsigned int keyD = 0x0064; const unsigned int keyF = 0x0066; const unsigned int keyG = 0x0067; const unsigned int keyH = 0x0068; const unsigned int keyJ = 0x006a; const unsigned int keyK = 0x006b; const unsigned int keyL = 0x006c; const unsigned int keyENTER = 0xff0d; const unsigned int keySHIFTLEFT = 0xffe1; const unsigned int keyZ = 0x007a; const unsigned int keyX = 0x0078; const unsigned int keyC = 0x0063; const unsigned int keyV = 0x0076; const unsigned int keyB = 0x0062; const unsigned int keyN = 0x006e; const unsigned int keyM = 0x006d; const unsigned int keySHIFTRIGHT = 0xffe2; const unsigned int keyARROWUP = 0xff52; const unsigned int keyCTRLLEFT = 0xffe3; const unsigned int keyAPPLEFT = 0xffeb; const unsigned int keySPACE = 0x0020; const unsigned int keyALTGR = 0xffea; const unsigned int keyAPPRIGHT = 0xffec; const unsigned int keyMENU = 0xff67; const unsigned int keyCTRLRIGHT = 0xffe4; const unsigned int keyARROWLEFT = 0xff51; const unsigned int keyARROWDOWN = 0xff54; const unsigned int keyARROWRIGHT = 0xff53; const unsigned int keyPAD0 = 0xffb0; const unsigned int keyPAD1 = 0xffb1; const unsigned int keyPAD2 = 0xffb2; const unsigned int keyPAD3 = 0xffb3; const unsigned int keyPAD4 = 0xffb4; const unsigned int keyPAD5 = 0xffb5; const unsigned int keyPAD6 = 0xffb6; const unsigned int keyPAD7 = 0xffb7; const unsigned int keyPAD8 = 0xffb8; const unsigned int keyPAD9 = 0xffb9; const unsigned int keyPADADD = 0xffab; const unsigned int keyPADSUB = 0xffad; const unsigned int keyPADMUL = 0xffaa; const unsigned int keyPADDIV = 0xffaf; const double valuePI = 3.14159265358979323846; const unsigned int font7x11[7*11*256/32] = { 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x90,0x0,0x7f0000,0x40000,0x0,0x0,0x4010c0a4,0x82000040,0x11848402,0x18480050,0x80430292,0x8023,0x9008000, 0x40218140,0x4000040,0x21800402,0x18000051,0x1060500,0x8083,0x10000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x24002,0x4031,0x80000000,0x10000, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x81c0400,0x40020000,0x80070080,0x40440e00,0x0,0x0,0x1,0x88180000,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x200000,0x0,0x0,0x80000,0x0,0x0,0x20212140,0x5000020,0x22400204,0x240000a0,0x40848500,0x4044,0x80010038,0x20424285,0xa000020, 0x42428204,0x2428e0a0,0x82090a14,0x4104,0x85022014,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10240a7,0x88484040,0x40800000,0x270c3,0x87811e0e, 0x7c70e000,0x78,0x3c23c1ef,0x1f3e1e89,0xf1c44819,0xa23cf0f3,0xc3cff120,0xc18307f4,0x4040400,0x20000,0x80080080,0x40200,0x0, 0x40000,0x2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8188,0x50603800,0xf3c00000,0x1c004003,0xc700003e,0x18180,0xc993880,0x10204081, 0x2071ef9,0xf3e7cf9f,0x3e7c7911,0xe3c78f1e,0x7d1224,0x48906048,0x0,0x4000000,0x0,0x9000,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x10240aa,0x14944080,0x23610000,0x68940,0x40831010,0x8891306,0x802044,0x44522208,0x90202088,0x40448819,0xb242890a,0x24011111, 0x49448814,0x4040a00,0xe2c3c7,0x8e3f3cb9,0xc1c44216,0xee38b0f2,0xe78f9120,0xc18507e2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x101c207,0x88a04001,0x9c00000,0x2200a041,0x8200113a,0x8240,0x50a3110,0x2850a142,0x850c2081,0x2040204,0x8104592,0x142850a1, 0x42cd1224,0x4888bc48,0x70e1c387,0xe3b3c70,0xe1c38e1c,0x38707171,0xc3870e1c,0x10791224,0x48906c41,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x10003ee,0x15140080,0x21810000,0x48840,0x40851020,0x8911306,0x31fd804,0x9c522408,0x90204088,0x4045081a,0xba42890a,0x24011111, 0x49285024,0x2041b00,0x132408,0x910844c8,0x4044821b,0x7244c913,0x24041111,0x49488822,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x28204,0x85006001,0x6a414000,0x3a004043,0xc700113a,0x8245,0x50a3a00,0x2850a142,0x850c4081,0x2040204,0x81045d2,0x142850a1, 0x24951224,0x48852250,0x8102040,0x81054089,0x12244204,0x8108992,0x24489122,0x991224,0x4888b222,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x1000143,0xa988080,0x2147c01f,0x88840,0x83091c2c,0x1070f000,0xc000608,0xa48bc408,0x9e3c46f8,0x40460816,0xaa42f10b,0xc3811111, 0x35102044,0x1041100,0xf22408,0x9f084488,0x40470212,0x62448912,0x6041111,0x55308846,0x8061c80,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x1028704,0x8f805801,0x4be28fdf,0x220001f0,0x111a,0x60000182,0x82c5c710,0x44891224,0x489640f1,0xe3c78204,0x810e552,0x142850a1, 0x18a51224,0x48822250,0x78f1e3c7,0x8f1f40f9,0xf3e7c204,0x8108912,0x24489122,0x7ea91224,0x4888a222,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x10007e2,0x85648080,0x20010000,0x88841,0x8f8232,0x20881000,0xc1fc610,0xbefa2408,0x90204288,0x40450816,0xa642810a,0x4041110a, 0x36282084,0x1042080,0x1122408,0x90084488,0x40450212,0x62448912,0x184110a,0x55305082,0x8042700,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x1028207,0x82004801,0x68050040,0x1c000040,0x110a,0x60000001,0x45484d10,0x7cf9f3e7,0xcf944081,0x2040204,0x8104532,0x142850a1, 0x18a51224,0x48822248,0x89122448,0x91244081,0x2040204,0x8108912,0x24489122,0xc91224,0x48852214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x282, 0x89630080,0x20010c00,0x30108842,0x810222,0x20882306,0x3001800,0x408a2208,0x90202288,0x40448814,0xa642810a,0x2041110a,0x26442104, 0x840000,0x1122408,0x90084488,0x40448212,0x62448912,0x84130a,0x36485102,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x101c208,0x4f802801, 0x8028040,0x40,0x130a,0x2,0x85e897a0,0x44891224,0x489c2081,0x2040204,0x8104532,0x142850a1,0x24cd1224,0x48823c44,0x89122448, 0x91244081,0x2040204,0x8108912,0x24489122,0xc93264,0xc9852214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100028f,0x109f0080,0x20010c00, 0x303071f3,0xc7011c1c,0x4071c306,0x802010,0x3907c1ef,0x1f201e89,0xf3844f90,0xa23c80f2,0x17810e04,0x228223f4,0x840000,0xfbc3c7, 0x8f083c88,0x40444212,0x6238f0f2,0x7039d04,0x228423e2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1008780,0x2201800,0xf0014000,0x1f0, 0x1d0a,0x5,0x851e140,0x83060c18,0x30671ef9,0xf3e7cf9f,0x3e7c7911,0xe3c78f1e,0x42f8e1c3,0x8702205c,0x7cf9f3e7,0xcf9b3c78,0xf1e3c204, 0x8107111,0xc3870e1c,0x10f1d3a7,0x4e823c08,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x40,0x40000400,0x200000,0x0,0x2,0x0,0x0,0x0,0x0,0x18, 0x0,0x4,0x44007f,0x0,0x400,0x400000,0x8010,0x0,0x6002,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x200800,0x0,0x0,0x100a, 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, 0x400000,0x0,0x4,0x0,0x0,0x0,0x0,0xc,0x0,0x7,0x3c0000,0x0,0x3800,0x3800000,0x8010,0x0,0x1c001,0x881c0000,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x207000,0x0,0x0,0x100a,0xc00000,0x3c,0x0,0xc00,0x0,0x0,0x0,0x0,0x0,0x0,0x1800,0x0,0x0,0x0,0x0,0x1c2070 }; const unsigned int font10x13[256*10*13/32] = { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,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, 0x68000300,0x801,0xc00010,0x100c000,0x68100,0x100c0680,0x2,0x403000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x58120480,0x402,0x1205008,0x2012050,0x58080,0x20120581,0x40000001,0x804812,0x2000000,0x0,0x300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x7010,0x7000000,0x8000200,0x20000,0xc0002000,0x8008,0x0,0x0,0x0,0x0,0x808,0x4000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x80000000,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x480,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x80100c0,0x68000480,0x1001, 0xc00010,0x1018000,0x68100,0x100c0680,0x4,0x403000,0x1020000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140,0x28081883,0x200801, 0x2a00000,0x10,0x1c0201c0,0x70040f80,0xc0f81c07,0x0,0x70,0x3e0303c0,0x3c3c0f83,0xe03c2107,0xe08810,0x18c31070,0x3c0703c0, 0x783e0842,0x22222208,0x83e04010,0x1008000,0x4000200,0x20001,0x2002,0x408008,0x0,0x0,0x100000,0x0,0x1008,0x2000000,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20080,0x38000880,0x8078140f,0x81c00000,0x3e000,0xc020180,0x60080001,0xe0000002,0xc00042,0x108e2010, 0xc0300c0,0x300c0303,0xf83c3e0f,0x83e0f81c,0x701c070,0x3c0c41c0,0x701c0701,0xc0001d08,0x42108421,0x8820088,0x4020120,0x58140480, 0x802,0x1205008,0x3014050,0xc058080,0x20120581,0x40000002,0x804814,0x2020050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140, 0x281e2484,0x80200801,0x1c02000,0x10,0x22060220,0x880c0801,0x82208,0x80000001,0x20008,0x41030220,0x40220802,0x402102,0x209010, 0x18c31088,0x22088220,0x80080842,0x22222208,0x80204010,0x1014000,0x200,0x20001,0x2000,0x8008,0x0,0x0,0x100000,0x0,0x1008, 0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40000500,0x80800010,0x40200000,0x41000,0x12020040,0x10000003,0xa0000006, 0x12000c4,0x31014000,0xc0300c0,0x300c0302,0x80402008,0x2008008,0x2008020,0x220c4220,0x88220882,0x20002208,0x42108421,0x8820088, 0x0,0x300,0x0,0x0,0x0,0x14000000,0x0,0x200200,0x0,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xfc282504,0x80001000, 0x82a02000,0x20,0x22020020,0x8140802,0x102208,0x80801006,0x18008,0x9c848220,0x80210802,0x802102,0x20a010,0x15429104,0x22104220, 0x80080842,0x22221405,0x404008,0x1022000,0x703c0,0x381e0701,0xc0783c02,0xc09008,0x1d83c070,0x3c078140,0x381c0882,0x21242208, 0x81e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0,0x40220500,0x80800027,0x20e02800,0x9c800,0x12020040, 0x20000883,0xa0200002,0x120a044,0x11064010,0x12048120,0x48120484,0x80802008,0x2008008,0x2008020,0x210a4411,0x4411044,0x10884508, 0x42108421,0x503c0b0,0x1c0701c0,0x701c0707,0x70381c07,0x1c07008,0x2008020,0x20f01c0,0x701c0701,0xc0201c08,0x82208822,0x883c088, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x50281903,0x20001000,0x80802000,0x20,0x22020040,0x30240f03,0xc0101c08,0x80801018, 0x1fc06010,0xa48483c0,0x80210f03,0xe0803f02,0x20c010,0x15429104,0x22104220,0x70080841,0x41540805,0x804008,0x1041000,0x8220, 0x40220881,0x882202,0x40a008,0x12422088,0x22088180,0x40100882,0x21241408,0x80201008,0x2031000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x20280,0x401c0200,0x700028,0x21205000,0x92800,0xc1fc080,0x10000883,0xa0200002,0x1205049,0x12c19010,0x12048120,0x48120484, 0xf0803c0f,0x3c0f008,0x2008020,0x790a4411,0x4411044,0x10504908,0x42108421,0x5022088,0x2008020,0x8020080,0x88402208,0x82208808, 0x2008020,0x1e088220,0x88220882,0x20002608,0x82208822,0x8822088,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x501c0264, 0xa0001000,0x8001fc00,0x7000020,0x22020080,0x83e0082,0x20202207,0x80000020,0x1020,0xa4848220,0x80210802,0x9c2102,0x20c010, 0x12425104,0x3c1043c0,0x8080841,0x41540802,0x804008,0x1000000,0x78220,0x40220f81,0x882202,0x40c008,0x12422088,0x22088100, 0x60100881,0x41540805,0x406008,0x1849000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0xf0140200,0x880028,0x20e0a03f,0x709c800, 0x201c0,0x60000881,0xa0000007,0xc0284b,0x122eb020,0x12048120,0x48120487,0x80802008,0x2008008,0x2008020,0x21094411,0x4411044, 0x10204908,0x42108421,0x2022088,0x1e0781e0,0x781e0787,0xf8403e0f,0x83e0f808,0x2008020,0x22088220,0x88220882,0x21fc2a08,0x82208822, 0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0xf80a0294,0x40001000,0x80002000,0x20,0x22020100,0x8040082,0x20202200, 0x80000018,0x1fc06020,0xa48fc220,0x80210802,0x842102,0x20a010,0x12425104,0x20104240,0x8080841,0x41541402,0x1004008,0x1000000, 0x88220,0x40220801,0x882202,0x40a008,0x12422088,0x22088100,0x18100881,0x41540805,0x801008,0x2046000,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x20280,0x401c0f80,0x80880028,0x20005001,0x94800,0x20000,0x880,0xa0000000,0x5015,0x4215040,0x3f0fc3f0,0xfc3f0fc8, 0x80802008,0x2008008,0x2008020,0x21094411,0x4411044,0x10505108,0x42108421,0x203c088,0x22088220,0x88220888,0x80402008,0x2008008, 0x2008020,0x22088220,0x88220882,0x20002a08,0x82208822,0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa00a0494,0x60001000, 0x80002004,0x8020,0x22020200,0x88040882,0x20402201,0x801006,0x18000,0x9f084220,0x40220802,0x442102,0x209010,0x10423088,0x20088220, 0x8080840,0x80882202,0x2004008,0x1000000,0x88220,0x40220881,0x882202,0x409008,0x12422088,0x22088100,0x8100880,0x80881402, 0x1001008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0x40220200,0x80700027,0x20002801,0x92800,0x1fc000,0x980, 0xa0000000,0xa017,0x84417840,0x21084210,0x84210848,0x80402008,0x2008008,0x2008020,0x2208c220,0x88220882,0x20882208,0x42108421, 0x2020088,0x22088220,0x88220888,0xc8402208,0x82208808,0x2008020,0x22088220,0x88220882,0x20203208,0x82208822,0x2022020,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xa03c0463,0x90000801,0x2004,0x8040,0x1c0703e0,0x70040701,0xc0401c06,0x801001,0x20020, 0x400843c0,0x3c3c0f82,0x3c2107,0x1c0881e,0x10423070,0x20070210,0xf0080780,0x80882202,0x3e04004,0x1000000,0x783c0,0x381e0701, 0x782202,0x408808,0x12422070,0x3c078100,0x700c0780,0x80882202,0x1e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0, 0xf8000200,0x80080010,0x40000001,0x41000,0x0,0xe80,0xa0000000,0x21,0x8e21038,0x21084210,0x84210848,0xf83c3e0f,0x83e0f81c, 0x701c070,0x3c08c1c0,0x701c0701,0xc0005c07,0x81e0781e,0x20200b0,0x1e0781e0,0x781e0787,0x30381c07,0x1c07008,0x2008020,0x1c0881c0, 0x701c0701,0xc0201c07,0x81e0781e,0x203c020,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,0x801,0x4,0x40,0x0,0x0,0x0,0x1000, 0x0,0x3c000000,0x0,0x0,0x0,0x0,0x10000,0x0,0x0,0x4004,0x1000000,0x0,0x0,0x80000,0x400000,0x0,0x20008000,0x0,0x4,0x1008,0x2000000, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x8008000f,0x80000000,0x3e000,0x0,0x800,0xa0000400,0x0,0x0,0x0,0x0,0x80000,0x0, 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, 0x402,0x8,0x40,0x0,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x0,0x7004,0x70000fc,0x0,0x0,0x700000,0x800000,0x0,0x20008000, 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, 0x300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x4020040 }; const unsigned int font8x17[8*17*256/32] = { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x2400,0x2400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20081834,0x1c0000,0x20081800,0x20081800,0x342008, 0x18340000,0x200818,0x80000,0x0,0x180000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4200000,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x380000,0x4000,0x2000c00,0x40100840,0x70000000,0x0,0x0,0x1c,0x10700000,0x7,0x0, 0x1800,0x1800,0x0,0x0,0x0,0x14,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1010242c,0x14140000,0x10102414,0x10102414,0x2c1010,0x242c1400, 0x101024,0x14100038,0x0,0x240000,0x0,0x0,0x30000000,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x12,0x0,0x8100000,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x80000,0x10004000,0x2001000,0x40000040,0x10000000,0x0,0x0,0x10,0x10100000,0x4, 0x0,0x18000000,0x0,0x0,0x0,0x34002400,0x2400,0x0,0x0,0x0,0x3c,0x0,0x8000000,0x0,0x60607800,0x0,0x140000,0x0,0x0,0x0,0x0,0x0, 0x44,0x10081834,0x240000,0x10081800,0x10081800,0x1c341008,0x18340000,0x100818,0x84000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102812, 0x8601c10,0x8100800,0x2,0x1c383e3e,0x67e1e7f,0x3e3c0000,0x38,0x1e087e1e,0x7c7f7f1e,0x417c1c42,0x4063611c,0x7e1c7e3e,0xfe414181, 0x63827f10,0x40081000,0x8004000,0x2001000,0x40000040,0x10000000,0x0,0x10000000,0x10,0x10100000,0x3c000008,0x0,0x24003e00, 0x3f007f00,0x0,0x0,0x2ce91800,0x1882,0x10101c,0xc2103c,0x143c3c00,0x3c00,0x18003c3c,0x10001f00,0x181c00,0x20200810,0x8080808, 0x8083e1e,0x7f7f7f7f,0x7c7c7c7c,0x7c611c1c,0x1c1c1c00,0x1e414141,0x41824044,0x810242c,0x14180000,0x8102414,0x8102414,0x382c0810, 0x242c1400,0x81024,0x14104014,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102816,0x3e902010,0x10084910,0x4,0x22084343,0xa402102,0x41620000, 0x44,0x33144121,0x42404021,0x41100444,0x40636122,0x43224361,0x10416381,0x22440310,0x20082800,0x4000,0x2001000,0x40000040, 0x10000000,0x0,0x10000000,0x10,0x10100000,0x24000008,0x0,0x606100,0x68000300,0x8106c,0x34000000,0x4f0000,0x44,0x101020,0x441040, 0x420200,0x4200,0x24000404,0x7d00,0x82200,0x20203010,0x14141414,0x14082821,0x40404040,0x10101010,0x42612222,0x22222200,0x23414141, 0x41447e48,0x0,0x0,0x0,0x0,0x4000000,0x18,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10287f,0x49902010,0x10083e10,0x4,0x41080101, 0x1a404002,0x41411818,0x1004004,0x21144140,0x41404040,0x41100448,0x40555141,0x41414140,0x10412281,0x14280610,0x20084400,0x1c7c1c, 0x3e3c7c3a,0x5c703844,0x107f5c3c,0x7c3e3c3c,0x7e424281,0x66427e10,0x10100000,0x40100008,0x1010,0xa04000,0x48100610,0x100c3024, 0x24000000,0x4f3c00,0x2c107e28,0x3820,0x42281060,0x9d1e12,0xbd00,0x24100818,0x427d00,0x82248,0x20200800,0x14141414,0x14142840, 0x40404040,0x10101010,0x41514141,0x41414142,0x43414141,0x41284350,0x1c1c1c1c,0x1c1c6c1c,0x3c3c3c3c,0x70707070,0x3c5c3c3c, 0x3c3c3c18,0x3e424242,0x42427c42,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102824,0x48623010,0x10081c10,0x8,0x41080103,0x127c5e04, 0x41411818,0xe7f3808,0x4f144140,0x41404040,0x41100450,0x40555141,0x41414160,0x1041225a,0x1c280410,0x1008c600,0x226622,0x66661066, 0x62100848,0x10496266,0x66663242,0x10426681,0x24220260,0x100c0000,0xf8280008,0x1010,0x606000,0x48280428,0x28042014,0x48000000, 0x494200,0x52280228,0x105420,0x3cee1058,0xa12236,0xa500,0x18101004,0x427d00,0x8226c,0x76767e10,0x14141414,0x14142840,0x40404040, 0x10101010,0x41514141,0x41414124,0x45414141,0x41284150,0x22222222,0x22221222,0x66666666,0x10101010,0x66626666,0x66666600, 0x66424242,0x42226622,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100024,0x381c4900,0x10086bfe,0x8,0x4908021c,0x22036304,0x3e630000, 0x70000710,0x51227e40,0x417f7f43,0x7f100470,0x40554941,0x43417e3e,0x1041225a,0x8100810,0x10080000,0x24240,0x42421042,0x42100850, 0x10494242,0x42422040,0x1042245a,0x18240410,0x10103900,0x407c003e,0x1818,0x1c3e10,0x4f7c087c,0x7c002010,0x48000000,0x4008, 0x527c0410,0x105078,0x2410104c,0xa13e6c,0x7f00b900,0xfe3c3c,0x421d18,0x1c1c36,0x38383810,0x22222222,0x22144e40,0x7f7f7f7f, 0x10101010,0xf1494141,0x41414118,0x49414141,0x4110435c,0x2020202,0x2021240,0x42424242,0x10101010,0x42424242,0x424242ff,0x4e424242, 0x42244224,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000fe,0xe664d00,0x10080810,0x380010,0x41080c03,0x42014108,0x633d0000,0x70000710, 0x51224140,0x41404041,0x41100448,0x40494541,0x7e414203,0x1041145a,0x14101010,0x10080000,0x3e4240,0x427e1042,0x42100870,0x10494242, 0x4242203c,0x1042245a,0x18241810,0x10104600,0xf8f60008,0x1010,0x600320,0x48f610f6,0xf6000000,0x187eff,0x3c04,0x5ef61810,0x105020, 0x24fe0064,0x9d006c,0x138ad00,0x100000,0x420518,0x36,0xc0c0c020,0x22222222,0x22224840,0x40404040,0x10101010,0x41454141,0x41414118, 0x51414141,0x41107e46,0x3e3e3e3e,0x3e3e7e40,0x7e7e7e7e,0x10101010,0x42424242,0x42424200,0x5a424242,0x42244224,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x28,0x9094500,0x10080010,0x10,0x41081801,0x7f014118,0x41010000,0xe7f3800,0x513e4140,0x41404041,0x41100444, 0x40414541,0x40414101,0x10411466,0x36103010,0x8080000,0x424240,0x42401042,0x42100848,0x10494242,0x42422002,0x10423c5a,0x18142010, 0x10100000,0x407c0010,0x1010,0x260140,0x487c307c,0x7c000000,0x180000,0x202,0x507c2010,0x105020,0x3c10003c,0x423e36,0x1004200, 0x100000,0x420500,0x3e6c,0x41e0440,0x3e3e3e3e,0x3e3e7840,0x40404040,0x10101010,0x41454141,0x41414124,0x61414141,0x41104042, 0x42424242,0x42425040,0x40404040,0x10101010,0x42424242,0x42424218,0x72424242,0x42144214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100048, 0x49096200,0x8100010,0x18001810,0x22082043,0x2432310,0x61421818,0x1004010,0x4f634121,0x42404021,0x41104444,0x40414322,0x40234143, 0x10411466,0x22106010,0x8080000,0x466622,0x66621066,0x42100844,0x10494266,0x66662042,0x10461824,0x24184010,0x10100000,0x24381010, 0x34001018,0xda4320,0x68386038,0x38000000,0x0,0x4204,0x50384010,0x105420,0x4210100c,0x3c0012,0x3c00,0x0,0x460500,0x48,0xc020c44, 0x63636363,0x63228821,0x40404040,0x10101010,0x42432222,0x22222242,0x62414141,0x41104042,0x46464646,0x46465022,0x62626262, 0x10101010,0x66426666,0x66666618,0x66464646,0x46186618,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100048,0x3e063d00,0x8100000,0x18001820, 0x1c3e7f3e,0x23c1e20,0x3e3c1818,0x10,0x20417e1e,0x7c7f401e,0x417c3842,0x7f41431c,0x401e40be,0x103e0866,0x41107f10,0x4080000, 0x3a5c1c,0x3a3c103a,0x427c0842,0xe49423c,0x7c3e203c,0xe3a1824,0x66087e10,0x10100000,0x3c103010,0x245a1010,0x5a3e10,0x3f107f10, 0x10000000,0x0,0x3c08,0x2e107e10,0x1038fc,0x101004,0x0,0x0,0xfe0000,0x7f0500,0x0,0x14041438,0x41414141,0x41418e1e,0x7f7f7f7f, 0x7c7c7c7c,0x7c431c1c,0x1c1c1c00,0xbc3e3e3e,0x3e10405c,0x3a3a3a3a,0x3a3a6e1c,0x3c3c3c3c,0x7c7c7c7c,0x3c423c3c,0x3c3c3c00, 0x7c3a3a3a,0x3a087c08,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x4200000,0x10000020,0x0,0x0,0x10,0x0,0x30000000,0x0, 0x0,0x0,0x60000,0x0,0x1c,0x4380000,0x0,0x2,0x800,0x0,0x40020000,0x0,0x8000c,0x10600000,0x2010,0x48000000,0x240000,0x0,0x0, 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, 0x84008,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x0,0x20000040,0x0,0x0,0x20,0x0,0x1e000000,0x0,0x0,0x0,0x20000,0x0, 0x0,0x2000000,0x0,0x26,0x800,0x0,0x40020000,0x0,0x100000,0x10000000,0x2030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x1000,0x0, 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, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 }; const unsigned int font10x19[10*19*256/32] = { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x180181c0,0xe81b0300,0x1801,0x81c06c18,0x181c06c,0xe8180,0x181c0e81,0xb0000006,0x60701b,0x1800000,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0xc030360,0xb81b0480,0xc03,0x3606c0c,0x303606c,0xb80c0,0x30360b81,0xb0000003,0xc0d81b,0x3000000,0x0, 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, 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, 0x22000,0x0,0x0,0x0,0x0,0x0,0x0,0x30000,0x0,0xe0,0x38078000,0x0,0x480,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3000c080,0x480,0x3000, 0xc0800030,0xc08000,0x300,0xc080000,0xc,0x302000,0xc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x41c01,0xe020060c, 0x800000,0x4,0x1e0703e0,0xf8060fc1,0xe1fe1e07,0x80000000,0x78,0x307e0,0x3c7c1fe7,0xf83c408f,0x80f10440,0x18660878,0x7e0787e0, 0x78ff9024,0xa0140a0,0x27f83840,0x700e000,0x18000400,0x8000,0x70004002,0x410078,0x0,0x0,0x0,0x0,0x1808,0xc000000,0xf000000, 0xe000000,0x1400,0x1e0001f,0x8007f800,0x0,0x0,0x3a3b,0x61400000,0x14202,0x20000,0x38002020,0x3c1b00,0x3e00000,0xf8,0x1c0001c0, 0x78060001,0xf800000e,0x1e00020,0x8004020,0xc0300c0,0x300c0301,0xf83c7f9f,0xe7f9fe3e,0xf83e0f8,0x7c1821e0,0x781e0781,0xe0001f10, 0x24090240,0xa02400f8,0x18018140,0xe81b0480,0x1801,0x81406c18,0x181406c,0x190e8180,0x18140e81,0xb0000006,0x60501b,0x184006c, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x26042202,0x200c06,0x800000,0x8,0x210d0611,0x40e0803,0x10026188,0x40000000, 0x8c,0xf030418,0xc6431004,0xc64082,0x110840,0x18660884,0x41084410,0x8c081024,0xa012110,0x40082020,0x101b000,0xc000400,0x8000, 0x80004002,0x410008,0x0,0x0,0x100000,0x0,0x2008,0x2000000,0x18800000,0x10000000,0x2200,0x2300024,0x800,0x0,0x0,0x2e13,0x60800000, 0x8104,0x20040,0x64001040,0x80401b07,0x80100000,0x1e000,0x22000020,0x40c0003,0xc8000002,0x3300020,0x8004020,0xc0300c0,0x300c0301, 0x40c64010,0x4010008,0x2008020,0x43182210,0x84210842,0x10002190,0x24090240,0x9044018c,0xc030220,0xb81b0300,0xc03,0x2206c0c, 0x302206c,0x1e0b80c0,0x30220b81,0xb0000003,0xc0881b,0x304006c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x241f2202, 0x200802,0x4900000,0x8,0x21010408,0x20a0802,0x44090,0x20000000,0x4,0x11878408,0x80411004,0x804082,0x111040,0x1ce50986,0x40986409, 0x81022,0x12012108,0x80102020,0x1031800,0x400,0x8000,0x80004000,0x10008,0x0,0x0,0x100000,0x0,0x2008,0x2000000,0x10000000, 0x10000000,0x18,0x4000044,0x1000,0x30180,0xd81b0000,0x13,0xe0000000,0x88,0x40,0x400018c0,0x80400018,0x61f00000,0x61800,0x22020020, 0x4000007,0xc8000002,0x2100020,0x8038000,0x1e0781e0,0x781e0301,0x40804010,0x4010008,0x2008020,0x41142619,0x86619866,0x18002190, 0x24090240,0x8887e104,0x0,0x0,0x0,0x0,0x0,0x2000000,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x2434a202, 0x200802,0x3e00000,0x10,0x40810008,0x21a0804,0x44090,0x20000000,0x80040004,0x20848409,0x409004,0x1004082,0x112040,0x14a50902, 0x40902409,0x81022,0x11321208,0x80202010,0x1060c00,0x7c5e0,0x781e8783,0xf07a5f0e,0x1c10808,0xfc5f078,0x5e07a170,0x7c7e1024, 0xa016190,0x27f82008,0x2000000,0x20000000,0x10000000,0x80200024,0x4000044,0x2000,0x18180,0xc8320000,0x12,0xa1f00037,0x7f888, 0x1e0,0x40410880,0x80600017,0xa2100000,0x5e800,0x22020040,0x38001027,0xc8000002,0x2100020,0x8004020,0x12048120,0x48120482, 0x41004010,0x4010008,0x2008020,0x40942409,0x2409024,0x9044390,0x24090240,0x88841918,0x1f07c1f0,0x7c1f07c3,0x70781e07,0x81e07838, 0xe0380e0,0x1f17c1e0,0x781e0781,0xe0001f90,0x24090240,0x9025e102,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0xff241c41, 0x1001,0x1c02000,0x10,0x40810008,0x6120f85,0xe0086190,0x20c03007,0x8007800c,0x27848419,0x409004,0x1004082,0x114040,0x14a48902, 0x40902409,0x81022,0x11321205,0x602010,0x1000000,0x86610,0x84218840,0x80866182,0x411008,0x9261884,0x61086189,0x82101022,0x12012108, 0x40082008,0x2000000,0x20030000,0x20000000,0x80200024,0x4000044,0x3006030,0xc018100,0x4c260000,0x12,0x26080048,0x83000850, 0x20250,0x403e0500,0x8078002c,0x12302200,0x92400,0x1c0200c0,0x4001027,0xc8000002,0x3308820,0x8004020,0x12048120,0x48120482, 0x41004010,0x4010008,0x2008020,0x40922409,0x2409024,0x8884690,0x24090240,0x85040920,0x21886218,0x86218860,0x88842108,0x42108408, 0x2008020,0x21186210,0x84210842,0x10302190,0x24090240,0x88461084,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x4c240182, 0x80001001,0x6b02000,0x20,0x4c810010,0x78220846,0x10081e10,0x20c0301c,0x1fe0e018,0x4d8487e1,0x409fe7,0xf9007f82,0x11a040, 0x13248902,0x41102418,0xe0081022,0x11320c05,0x402008,0x1000000,0x2409,0x409020,0x81024082,0x412008,0x9240902,0x40902101,0x101022, 0x11321208,0x40102008,0x2000000,0x7e0c8000,0xfc000003,0xf0fc0018,0x43802047,0x8c8040c8,0x32008300,0x44240000,0x0,0x4000048, 0x8c801050,0x20440,0x40221dc0,0x808c0028,0x11d0667f,0x8009c400,0x1fc180,0x4001023,0xc8300002,0x1e0ccfb,0x3ec7b020,0x12048120, 0x48120482,0x79007f9f,0xe7f9fe08,0x2008020,0xf0922409,0x2409024,0x8504490,0x24090240,0x85040920,0x802008,0x2008020,0x89004090, 0x24090208,0x2008020,0x40902409,0x2409024,0x8304390,0x24090240,0x88440884,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000, 0x481c0606,0xc8001001,0x802000,0x20,0x4c810020,0x4220024,0x8102108,0x60000070,0x3820,0x48884419,0x409004,0x10e4082,0x112040, 0x13244902,0x7e1027e0,0x3c081021,0x21320c02,0x802008,0x1000000,0x7e409,0x409020,0x81024082,0x414008,0x9240902,0x40902101, 0x80101022,0x11320c08,0x40202008,0x2038800,0x200bc000,0x20000000,0x80200003,0x80f04044,0xbc080bc,0x2f000200,0x0,0x0,0x6001048, 0x8bc02020,0x20441,0xf8220200,0x80820028,0x1000cc00,0x80094400,0x201e0,0x78001021,0xc830000f,0x8000663c,0xf03c0c0,0x21084210, 0x84210846,0x41004010,0x4010008,0x2008020,0x40912409,0x2409024,0x8204890,0x24090240,0x82040930,0x1f87e1f8,0x7e1f87e0,0x89004090, 0x24090208,0x2008020,0x40902409,0x2409024,0x8004690,0x24090240,0x88440884,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000, 0x480719c4,0x48001001,0x81fc00,0x7800020,0x40810040,0x2420024,0x8104087,0xa0000070,0x3820,0x48884409,0x409004,0x1024082,0x111040, 0x13244902,0x40102410,0x2081021,0x214a1202,0x1802008,0x1000000,0x182409,0x409fe0,0x81024082,0x41a008,0x9240902,0x40902100, 0xf8101021,0x214a0c04,0x80c0c008,0x1847000,0x7c1ee000,0x20000000,0x8020000c,0x8c044,0x1ee181ee,0x7b800000,0x707,0xf3ff0000, 0x3e0084f,0x9ee0c020,0x20440,0x40221fc0,0xc2002c,0x13f11000,0x87892400,0x20000,0x1020,0x48000000,0x3f011c6,0x31cc6180,0x21084210, 0x84210844,0x41004010,0x4010008,0x2008020,0x40912409,0x2409024,0x8505090,0x24090240,0x8204191c,0x60982609,0x82609823,0xf9007f9f, 0xe7f9fe08,0x2008020,0x40902409,0x2409024,0x9fe4c90,0x24090240,0x84840848,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xfe048224, 0x28001001,0x2000,0x40,0x40810080,0x27f8024,0x8104080,0x2000001c,0x1fe0e020,0x488fc409,0x409004,0x1024082,0x110840,0x10242902, 0x40102408,0x2081021,0x214a1202,0x1002004,0x1000000,0x102409,0x409000,0x81024082,0x411008,0x9240902,0x40902100,0x6101021, 0x214a0c04,0x81002008,0x2000000,0x201dc000,0x20000000,0x80200000,0x98044,0x1dc101dc,0x77000000,0x700,0x0,0x180448,0x1dc10020, 0x20440,0x403e0200,0x620017,0xa000cc00,0x80052800,0x20000,0x1020,0x48000000,0x6606,0x206100,0x3f0fc3f0,0xfc3f0fc7,0xc1004010, 0x4010008,0x2008020,0x4090a409,0x2409024,0x8886090,0x24090240,0x8207e106,0x40902409,0x2409024,0x81004010,0x4010008,0x2008020, 0x40902409,0x2409024,0x8005890,0x24090240,0x84840848,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x98048224,0x30001001,0x2000, 0x40,0x21010100,0x2020024,0x8204080,0x40000007,0x80078000,0x48884408,0x80411004,0x824082,0x110840,0x10242986,0x40086409,0x2081021, 0xe14a2102,0x2002004,0x1000000,0x106409,0x409000,0x81024082,0x410808,0x9240902,0x40902100,0x2101021,0x214a1202,0x82002008, 0x2000000,0x300f8000,0x20000000,0x80fc001d,0xe4088044,0xf8200f8,0x3e000000,0x300,0x0,0x80c48,0xf820020,0x20640,0x40410200, 0x803c0018,0x60006600,0x61800,0x0,0x1020,0x48000000,0xcc0a,0x20a100,0x21084210,0x84210844,0x40804010,0x4010008,0x2008020, 0x4110a619,0x86619866,0x19046110,0x24090240,0x82040102,0x41906419,0x6419064,0x81004010,0x4010008,0x2008020,0x40902409,0x2409024, 0x8307090,0x24090240,0x82840828,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x90248222,0x30000802,0x200c,0xc080,0x21010301, 0x4021042,0x10202108,0xc0c03000,0x80040020,0x4d902418,0xc6431004,0xc24082,0x6210440,0x10241884,0x40084409,0x86080840,0xc0842102, 0x4002002,0x1000000,0x18e610,0x84218820,0x80864082,0x410408,0x9240884,0x61086101,0x6101860,0xc0842103,0x4002008,0x2000000, 0x10850180,0x20330000,0x80200013,0x26184024,0x5040050,0x14000000,0x0,0x0,0x4180848,0x85040020,0x20350,0x40000200,0x800c0007, 0x80002200,0x1e000,0x0,0x1860,0x48000000,0x880a,0x40a188,0x40902409,0x2409028,0x40c64010,0x4010008,0x2008020,0x43106210,0x84210842, 0x10006108,0x42108421,0x2040102,0x6398e639,0x8e6398e4,0x88842088,0x22088208,0x2008020,0x21102210,0x84210842,0x10306118,0x66198661, 0x83061030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0x901f01c1,0xe8000802,0xc,0xc080,0x1e07c7f8,0xf8020f81,0xe0401e07, 0x80c03000,0x20,0x279027e0,0x3c7c1fe4,0x3c408f,0x83c1027f,0x90241878,0x4007c404,0xf8080780,0xc0844082,0x7f82002,0x1000000, 0xfa5e0,0x781e87c0,0x807a409f,0xc0410207,0x9240878,0x5e07a100,0xf80e0fa0,0xc0846183,0x7f82008,0x2000000,0xf020100,0x40321360, 0x80200014,0xa3e0201f,0x8207f820,0x8000000,0x0,0x0,0x3e01037,0x207f820,0x201e1,0xfc000200,0x80040000,0x0,0x0,0x1fc000,0x17b0, 0x48000000,0x12,0xc120f0,0x40902409,0x2409028,0x783c7f9f,0xe7f9fe3e,0xf83e0f8,0x7c1061e0,0x781e0781,0xe000be07,0x81e0781e, 0x204017c,0x3e8fa3e8,0xfa3e8fa3,0x70781f07,0xc1f07c7f,0x1fc7f1fc,0x1e1021e0,0x781e0781,0xe0007e0f,0xa3e8fa3e,0x8305e030,0x0, 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, 0x0,0x0,0x2001,0x1000000,0x0,0x0,0x20000,0x400000,0x0,0x40002000,0x0,0x1,0x2008,0x2000000,0x100,0x40240000,0x80200008,0x40000000, 0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x80040000,0x0,0x0,0x0,0x1000,0x48000000,0x1f,0x181f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x6000,0x0,0x10000000,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x3800,0x7000000,0x0,0x0,0x840000,0x400000,0x0,0x40002000, 0x0,0x2,0x2008,0x2000000,0x200,0x40440000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x80780000,0x0,0x0,0x0,0x1000,0x48000400, 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, 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, 0x780000,0x3800000,0x0,0x40002000,0x0,0xe,0x1808,0xc000000,0x3,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000, 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, 0x0,0x0,0x0,0x0,0x0,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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 }; const unsigned int font12x24[12*24*256/32] = { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc001806,0xc81980,0x60000000,0xc001806,0x1980c00,0x18060198,0xc80c, 0x180600,0xc8198000,0xc001,0x80601980,0x18000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x600300f,0x1301980,0x90000000,0x600300f,0x1980600,0x300f0198,0x13006,0x300f01,0x30198000,0x6003, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x80000000,0x90000000,0x3006019,0x80000300,0x60198000,0x3,0x601980,0x0,0x3006,0x1980000,0x60000000,0x0,0x0,0xe0000000,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0xc800019,0x80000000,0x198000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x1001,0x420000,0x0,0x0,0x90000000, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000c06,0xc80001,0x10000000,0x18000c06,0x1800,0xc060000,0xc818,0xc0600,0xc8000000, 0x18000,0xc0600000,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80660207,0x800f8060,0x300c004,0x0,0x6, 0xe00703f,0x3f00383,0xf80f07fc,0x1f01f000,0x0,0xf8,0x607f,0x7c7e07,0xfe7fe0f8,0x6063fc1f,0x86066007,0xe7060f0,0x7f80f07f, 0x81f8fff6,0x6606c03,0x70ee077f,0xe0786000,0xf0070000,0xc000060,0xc0,0x3e000,0x60006003,0x600fc00,0x0,0x0,0x0,0x0,0x0,0x3c0603, 0xc0000000,0x7800000,0xf0000,0x0,0xf00001f,0x80001fe0,0x7fe000,0x0,0x0,0x0,0x168fe609,0x0,0x90e07,0x6000,0x3c000e,0x70000f8, 0x1980001f,0x0,0x1f8,0xf00000f,0xf00180,0xfe000,0xe00e,0x1001,0x20060,0x6006006,0x600600,0x600fe07c,0x7fe7fe7f,0xe7fe3fc3, 0xfc3fc3fc,0x7e07060f,0xf00f00,0xf00f0000,0xf360660,0x6606606e,0x76001e0,0xc00180f,0x1681981,0x10000000,0xc00180f,0x1980c00, 0x180f0198,0x3801680c,0x180f01,0x68198000,0xc001,0x80f01980,0x18600198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019, 0x8044020c,0xc01f8060,0x2004004,0x0,0xc,0x3f81f07f,0x87f80383,0xf81f87fc,0x3f83f800,0x0,0x1fc,0x780607f,0x81fe7f87,0xfe7fe1fc, 0x6063fc1f,0x860c6007,0xe7061f8,0x7fc1f87f,0xc3fcfff6,0x6606c03,0x30c6067f,0xe0783000,0xf00d8000,0x6000060,0xc0,0x7e000,0x60006003, 0x600fc00,0x0,0x0,0xc00,0x0,0x0,0x7c0603,0xe0000000,0xfc00000,0x1f0000,0x0,0x900003f,0xc0003fe0,0x7fe000,0x0,0x0,0x0,0x1302660f, 0x0,0xf0606,0x6004,0x7e0006,0x60601f8,0x19800001,0x80000000,0x1f8,0x19800010,0x81080300,0x3f2000,0x2011,0x1001,0x1c0060,0x6006006, 0x600600,0x601fe1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f87061f,0x81f81f81,0xf81f8000,0x3fa60660,0x66066066,0x66003f0,0x6003009, 0x1301981,0x10000000,0x6003009,0x1980600,0x30090198,0x1f013006,0x300901,0x30198000,0x6003,0x901980,0x30600198,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc0f8c,0xc0180060,0x6006044,0x40000000,0xc,0x3181b041,0xc41c0783,0x388018, 0x71c71800,0x0,0x106,0x18c0f061,0xc38261c6,0x600384,0x60606001,0x86186007,0xe78630c,0x60e30c60,0xe7040606,0x630cc03,0x39c30c00, 0xc0603000,0x3018c000,0x3000060,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600,0x60000000,0x18400000,0x180000, 0x0,0x19800070,0x40003600,0xc000,0x0,0x0,0x0,0x25a06,0x0,0x6030c,0x4,0xe20007,0xe060180,0xf000,0x80000000,0xf0000,0x10800000, 0x80080600,0x7f2000,0x2020,0x80001001,0x20000,0xf00f00f,0xf00f00,0x601b0382,0x60060060,0x6000600,0x60060060,0x61c78630,0xc30c30c3, 0xc30c000,0x30e60660,0x66066063,0xc600738,0x3006019,0x80000000,0xe0000000,0x3006019,0x80000300,0x60198000,0x3e000003,0x601980, 0x0,0x3006,0x1980000,0x60600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc1fcc,0xc0180060,0x6006035,0x80000000, 0x18,0x71c03000,0xc00c0583,0x300018,0x60c60c00,0x0,0x6,0x3060f060,0xc30060c6,0x600300,0x60606001,0x86306007,0x9e78670e,0x60670e60, 0x66000606,0x630c606,0x19830c01,0xc0601800,0x30306000,0x60,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600, 0x60000000,0x18000000,0x300000,0x0,0x78060,0x6600,0x1c000,0x300c,0x39819c0,0x0,0x25a00,0x0,0x30c,0x4,0xc00003,0xc060180,0x30c1f, 0x80000000,0x30c000,0x10800001,0x80700000,0x7f2000,0x2020,0x80001001,0x20060,0xf00f00f,0xf00f00,0xf01b0300,0x60060060,0x6000600, 0x60060060,0x60c78670,0xe70e70e7,0xe70e000,0x70c60660,0x66066063,0xc7f8618,0x0,0x0,0x0,0x0,0x0,0x0,0x7000000,0x0,0x0,0x0, 0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x87ff3a4c,0xc0180060,0x400600e,0x600000,0x18,0x60c03000, 0xc00c0d83,0x700018,0x60c60c00,0x20,0x400006,0x3060f060,0xc6006066,0x600600,0x60606001,0x86606006,0x966c6606,0x60660660,0x66000606, 0x630c666,0xf019801,0x80601800,0x30603000,0x1f06f,0xf01ec0,0xf03fe1ec,0x6703e01f,0x61c0c06,0xdc6701f0,0x6f01ec0c,0xe1f87fc6, 0xc60cc03,0x71c60c7f,0xc0600600,0x60000000,0x30000000,0x300000,0x40040,0x88060,0x6600,0x18000,0x300c,0x1981980,0x0,0x2421f, 0x80003ce0,0x7fc198,0x601f,0xc02021,0x980600c0,0x40230,0x80000000,0x402000,0x19806003,0x80006,0xc7f2000,0x2020,0x80001001, 0x420060,0xf00f00f,0xf00f00,0xf01b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x6606208,0x60e60660,0x66066061, 0x987fc670,0x1f01f01f,0x1f01f01,0xf039c0f0,0xf00f00f,0xf03e03,0xe03e03e0,0x1f06701f,0x1f01f01,0xf01f0060,0x1e660c60,0xc60c60c6, 0xc6f060c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x7ff3207,0x8c0c0000,0xc00300e,0x600000,0x30,0x60c03000, 0xc01c0983,0xf0600030,0x31860c06,0x6001e0,0x78000e,0x23e1f861,0xc6006066,0x600600,0x60606001,0x86c06006,0x966c6606,0x60660660, 0xe7000606,0x630c666,0xf01f803,0x600c00,0x30000000,0x3f87f,0x83f83fc3,0xf83fe3fc,0x7f83e01f,0x6380c07,0xfe7f83f8,0x7f83fc0d, 0xf3fc7fc6,0xc71cc03,0x3183187f,0xc0600600,0x60000000,0xff806000,0x300000,0x40040,0x88070,0x6600,0x60030060,0x6001818,0x1883180, 0x0,0x2423f,0xc0007ff0,0x607fc1f8,0x603f,0x80c01fc1,0xf80601e0,0x5f220,0x80420000,0x5f2000,0xf006006,0x80006,0xc7f2000,0x2020, 0x82107c07,0xc03c0060,0x1f81f81f,0x81f81f80,0xf03b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x660671c,0x61660660, 0x66066061,0xf860e6c0,0x3f83f83f,0x83f83f83,0xf87fe3f8,0x3f83f83f,0x83f83e03,0xe03e03e0,0x3f87f83f,0x83f83f83,0xf83f8060, 0x3fc60c60,0xc60c60c3,0x187f8318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x883200,0x300c0000,0xc003035,0x80600000, 0x30,0x66c03001,0xc0f81983,0xf86f0030,0x1f071c06,0x600787,0xfe1e001c,0x6261987f,0x86006067,0xfe7fc600,0x7fe06001,0x87c06006, 0xf6646606,0x60e6067f,0xc3e00606,0x61986f6,0x600f007,0x600c00,0x30000000,0x21c71,0x830831c3,0x1c06031c,0x71c06003,0x6700c06, 0x6671c318,0x71831c0f,0x16040c06,0xc318606,0x1b031803,0x80600600,0x60000000,0x30009000,0x300000,0x40040,0x7003e,0x67e0,0x90070090, 0x9001818,0x8c3100,0x0,0x60,0x4000e730,0x900380f0,0x6034,0x80c018c7,0xfe060338,0xb0121,0x80c60000,0x909000,0x6008,0x1080006, 0xc3f2000,0x2011,0x3180060,0x60060e0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0x60664660,0x66066066, 0x66063b8,0x62660660,0x66066060,0xf06066c0,0x21c21c21,0xc21c21c2,0x1c466308,0x31c31c31,0xc31c0600,0x60060060,0x31871c31,0x83183183, 0x18318000,0x71860c60,0xc60c60c3,0x18718318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1981a00,0xe03e0000,0xc003044, 0x40600000,0x60,0x66c03001,0x80f03182,0x1c7f8030,0x3f83fc06,0x601e07,0xfe078038,0x6661987f,0x86006067,0xfe7fc61e,0x7fe06001, 0x87e06006,0x66666606,0x7fc6067f,0x81f80606,0x61986f6,0x6006006,0x600600,0x30000000,0xc60,0xc60060c6,0xc06060c,0x60c06003, 0x6e00c06,0x6660c60c,0x60c60c0e,0x6000c06,0xc318666,0x1f031803,0x600600,0x603c2000,0x30016800,0x1fe0000,0x1f81f8,0x1c1f,0x804067e1, 0x68060168,0x16800810,0xc42300,0x0,0x60,0x20c331,0x68030060,0x6064,0x3fc1040,0xf006031c,0xa011e,0x818c7fe0,0x909000,0x7fe1f, 0x80f00006,0xc0f2060,0xf80e,0x18c0780,0x780781c0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0xfc666660, 0x66066066,0x66061f0,0x66660660,0x66066060,0x606066e0,0xc00c00,0xc00c00c0,0xc066600,0x60c60c60,0xc60c0600,0x60060060,0x60c60c60, 0xc60c60c6,0xc60c000,0x61c60c60,0xc60c60c3,0x1860c318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1980f81,0x80373000, 0xc003004,0x7fe0001,0xf0000060,0x60c03003,0x183180,0xc71c060,0x3181ec00,0x7000,0xe070,0x66619860,0xc6006066,0x60061e,0x60606001, 0x87606006,0x66626606,0x7f860661,0xc01c0606,0x6198696,0xf00600e,0x600600,0x30000000,0x1fc60,0xc60060c7,0xfc06060c,0x60c06003, 0x7c00c06,0x6660c60c,0x60c60c0c,0x7f00c06,0xc3b8666,0xe01b007,0x3c00600,0x3c7fe000,0xff03ec00,0x1fe0000,0x40040,0xe001,0xc0806603, 0xec0e03ec,0x3ec00010,0x0,0x60000000,0x7f,0x10c3f3,0xec070060,0x6064,0x3fc1040,0x6000030c,0xa0100,0x3187fe1,0xf09f1000,0x7fe00, 0x6,0xc012060,0x0,0xc63c03,0xc03c0380,0x19819819,0x81981981,0x98330600,0x60060060,0x6000600,0x60060060,0xfc662660,0x66066066, 0x66060e0,0x6c660660,0x66066060,0x6060e630,0x1fc1fc1f,0xc1fc1fc1,0xfc3fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6, 0xc60c7fe,0x62c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe02c6,0x3c633000,0xc003004, 0x7fe0001,0xf00000c0,0x60c03006,0xc6180,0xc60c060,0x60c00c00,0x7000,0xe060,0x66639c60,0x66006066,0x600606,0x60606001,0x86306006, 0x66636606,0x60060660,0xc0060606,0x61f8696,0xf00600c,0x600300,0x30000000,0x3fc60,0xc60060c7,0xfc06060c,0x60c06003,0x7c00c06, 0x6660c60c,0x60c60c0c,0x1f80c06,0xc1b0666,0xe01b00e,0x3c00600,0x3c43c000,0x3007de00,0x600000,0x40040,0x30000,0x61006607,0xde0c07de, 0x7de00000,0x0,0xf07fefff,0x1f,0x8008c3f7,0xde0e0060,0x6064,0xc01047,0xfe00018c,0xb013f,0x86300061,0xf0911000,0x6000,0x6, 0xc012060,0x3f,0x8063c0cc,0x3cc0c700,0x39c39c39,0xc39c39c1,0x98630600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066, 0x66061f0,0x78660660,0x66066060,0x607fc618,0x3fc3fc3f,0xc3fc3fc3,0xfc7fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6, 0xc60c7fe,0x64c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe0260,0x6661b000,0xc003000, 0x600000,0xc0,0x60c0300c,0xc7fe0,0xc60c060,0x60c01c00,0x1e07,0xfe078060,0x6663fc60,0x66006066,0x600606,0x60606001,0x86386006, 0x6636606,0x60060660,0xe0060606,0x60f039c,0x1b806018,0x600300,0x30000000,0x70c60,0xc60060c6,0x6060c,0x60c06003,0x7600c06, 0x6660c60c,0x60c60c0c,0x1c0c06,0xc1b03fc,0xe01f01c,0xe00600,0x70000000,0x3007fc00,0x600000,0x40040,0x0,0x62006607,0xfc1807fc, 0x7fc00000,0x0,0xf0000000,0x1,0xc004c307,0xfc1c0060,0x6064,0xc018c0,0x600000d8,0x5f200,0x3180060,0x50a000,0x6000,0x6,0xc012000, 0x0,0xc601c0,0x4201c600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066,0x66063b8, 0x70660660,0x66066060,0x607f860c,0x70c70c70,0xc70c70c7,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000, 0x68c60c60,0xc60c60c1,0xf060c1f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3300260,0x6661e000,0xc003000,0x600000, 0x180,0x71c03018,0xc7fe0,0xc60c0c0,0x60c01800,0x787,0xfe1e0060,0x6663fc60,0x630060c6,0x600306,0x60606001,0x86186006,0x661e70e, 0x60070c60,0x60060606,0x60f039c,0x19806038,0x600180,0x30000000,0x60c60,0xc60060c6,0x6060c,0x60c06003,0x6700c06,0x6660c60c, 0x60c60c0c,0xc0c06,0xc1b039c,0x1f00e018,0x600600,0x60000000,0x1803f800,0x600000,0x40040,0x39e00,0x63006603,0xf83803f8,0x3f800000, 0x0,0x60000000,0x0,0xc00cc303,0xf8180060,0x6064,0xc01fc0,0x60060070,0x40200,0x18c0060,0x402000,0x6000,0x6,0xc012000,0x0,0x18c0140, 0x2014600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0300,0x60060060,0x6000600,0x60060060,0x60c61e70,0xe70e70e7,0xe70e71c,0x60e60660,0x66066060, 0x6060060c,0x60c60c60,0xc60c60c6,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000,0x70c60c60,0xc60c60c0, 0xe060c0e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x33022e0,0x6670c000,0xc003000,0x600600,0x60180,0x31803030, 0x41c0184,0x1831c0c0,0x71c23806,0x6001e0,0x780000,0x62630c60,0xe38261c6,0x600386,0x60606043,0x860c6006,0x661e30c,0x60030c60, 0x740e0607,0xe0f039c,0x31c06030,0x600180,0x30000000,0x61c71,0x830831c3,0x406031c,0x60c06003,0x6300c06,0x6660c318,0x71831c0c, 0x41c0c07,0x1c0e039c,0x1b00e030,0x600600,0x60000000,0x1c41b00e,0x601cc0,0x401f8,0x45240,0xe1803601,0xb03001b0,0x1b000000, 0x0,0x0,0x41,0xc008e711,0xb0300060,0x6034,0x80c02020,0x60060030,0x30c00,0xc60000,0x30c000,0x0,0x7,0x1c012000,0x0,0x3180240, 0x6024608,0x30c30c30,0xc30c30c3,0xc630382,0x60060060,0x6000600,0x60060060,0x61c61e30,0xc30c30c3,0xc30c208,0x70c70e70,0xe70e70e0, 0x6060068c,0x61c61c61,0xc61c61c6,0x1cc62308,0x30430430,0x43040600,0x60060060,0x31860c31,0x83183183,0x18318060,0x31c71c71, 0xc71c71c0,0xe07180e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2203fc0,0x663f6000,0x6006000,0x600600,0x60300, 0x3f81fe7f,0xc7f80187,0xf83f80c0,0x3f83f006,0x600020,0x400060,0x33e6067f,0xc1fe7f87,0xfe6001fe,0x6063fc7f,0x60e7fe6,0x660e3f8, 0x6001f860,0x37fc0603,0xfc06030c,0x30c0607f,0xe06000c0,0x30000000,0x7fc7f,0x83f83fc3,0xfc0603fc,0x60c7fe03,0x61807c6,0x6660c3f8, 0x7f83fc0c,0x7f80fc3,0xfc0e039c,0x3180607f,0xc0600600,0x60000000,0xfc0e00c,0x601986,0x66040040,0x4527f,0xc0803fe0,0xe07fe0e0, 0xe000000,0x0,0x0,0x7f,0x80107ff0,0xe07fc060,0x603f,0x83fe0000,0x60060018,0xf000,0x420000,0xf0000,0x7fe00,0x7,0xfe012000, 0x0,0x2100640,0xc0643f8,0x60660660,0x66066067,0xec3e1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f860e3f,0x83f83f83,0xf83f8000, 0x5fc3fc3f,0xc3fc3fc0,0x606006fc,0x7fc7fc7f,0xc7fc7fc7,0xfcffe3f8,0x3fc3fc3f,0xc3fc7fe7,0xfe7fe7fe,0x3f860c3f,0x83f83f83, 0xf83f8060,0x7f83fc3f,0xc3fc3fc0,0x607f8060,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2201f80,0x3c1e7000,0x6006000, 0x600,0x60300,0xe01fe7f,0xc3f00183,0xe01f0180,0x1f01e006,0x600000,0x60,0x3006067f,0x807c7e07,0xfe6000f8,0x6063fc3e,0x6067fe6, 0x660e0f0,0x6000f060,0x3bf80601,0xf806030c,0x60e0607f,0xe06000c0,0x30000000,0x1ec6f,0xf01ec0,0xf80601ec,0x60c7fe03,0x61c03c6, 0x6660c1f0,0x6f01ec0c,0x3f007c1,0xcc0e030c,0x71c0c07f,0xc0600600,0x60000000,0x7804018,0xe01186,0x66040040,0x39e3f,0x80401fe0, 0x407fe040,0x4000000,0x0,0x0,0x3f,0x203ce0,0x407fc060,0x601f,0x3fe0000,0x60060018,0x0,0x0,0x0,0x7fe00,0x6,0xe6012000,0x0, 0x7e0,0x1807e1f0,0x60660660,0x66066066,0x6c3e07c,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7e060e0f,0xf00f00,0xf00f0000,0x8f01f81f, 0x81f81f80,0x60600670,0x1ec1ec1e,0xc1ec1ec1,0xec79c0f0,0xf80f80f,0x80f87fe7,0xfe7fe7fe,0x1f060c1f,0x1f01f01,0xf01f0000,0x4f01cc1c, 0xc1cc1cc0,0xc06f00c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x6006000,0x600,0x600,0x0,0x0,0x0,0x0, 0x600000,0x0,0x18000000,0x0,0x0,0x0,0x0,0x0,0x1800,0x0,0x0,0x0,0x600060,0x30000000,0x0,0x0,0xc,0x3,0x0,0x0,0x60000c00,0x0, 0x0,0xc000,0x600600,0x60000000,0x18,0xc03100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f8,0x0,0x0,0x0,0x0,0x6, 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, 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, 0x0,0x1c000000,0x0,0x0,0x0,0x0,0x0,0xc00,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x21c,0x3,0x0,0x0,0x60000c00,0x0,0x0,0xc000, 0x7c0603,0xe0000000,0x10,0xc02300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f0,0x0,0x0,0x0,0x0,0x6,0x12000,0x1000000, 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, 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, 0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x3f8,0x3e,0x0,0x0,0x60000c00,0x0,0x0,0x38000,0x3c0603,0xc0000000, 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, 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, 0x0,0x0,0x0,0x0,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, 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, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 }; const unsigned int font16x32[16*32*256/32] = { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70000e0,0x3c00730,0xe7001c0,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0x730,0x70000e0,0x3c00730, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x18001c0,0x6600ff0,0xe7003e0,0x0,0x18001c0,0x6600e70,0x18001c0,0x6600e70,0xff0,0x18001c0,0x6600ff0,0xe700000,0x180, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,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, 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, 0xc300ce0,0xe700630,0x0,0x1c00380,0xc300e70,0x1c00380,0xc300e70,0xce0,0x1c00380,0xc300ce0,0xe700000,0x1c0,0x3800c30,0xe700380, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0xc300000,0x0,0xc300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x700000,0x0,0x0,0x0,0x7c007c00,0x3e000000, 0x0,0x0,0x630,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe000070,0x1800000,0xc60,0x0,0xe000070,0x1800000,0xe000070, 0x1800000,0x0,0xe000070,0x1800000,0x0,0xe00,0x700180,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x3f0,0xfc0,0x0,0x7000000,0x38000000,0x1c0000,0xfc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x7c, 0x1801f00,0x0,0x0,0x1c,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7300000,0x6600000,0x0,0x6600000,0x0,0x0,0x0,0x0,0xe700000, 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, 0xf80,0x70000e0,0x3c00730,0xe700c60,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0xe000730,0x70000e0,0x3c00730,0xe700000,0x700, 0xe003c0,0xe7000e0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300000,0x803c00,0x7c00180, 0xc00300,0x1000000,0x0,0x1c,0x3c007c0,0xfc007e0,0xe01ff8,0x3f03ffc,0x7e007c0,0x0,0x0,0x7c0,0x1c0,0x7f8003f0,0x7f007ff8,0x7ff803f0, 0x70381ffc,0xff0700e,0x7000783c,0x783807c0,0x7fc007c0,0x7fc00fc0,0x7fff7038,0x700ee007,0x780f780f,0x7ffc03f0,0x70000fc0,0x3c00000, 0x3000000,0x38000000,0x1c0000,0x1fc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x1801f80,0x0,0x1f80000, 0x7e,0x0,0x0,0x2400000,0xfc00000,0x7ff0000,0x7ffc0000,0x0,0x0,0x0,0x0,0xf30fb0c,0x2400000,0x0,0x240780f,0x1c0,0xfc,0x780f, 0x18003f0,0xe700000,0x7c00000,0x0,0xff0,0x3c00000,0x78007c0,0xc00000,0xff80000,0xf80,0x7c00000,0xc000c00,0x18001c0,0x1c001c0, 0x1c001c0,0x1c003e0,0x7fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007838,0x7c007c0,0x7c007c0,0x7c00000,0x7c67038, 0x70387038,0x7038780f,0x70001fe0,0x30000c0,0x2400f30,0xe700c60,0x0,0x30000c0,0x2400e70,0x30000c0,0x2400e70,0xf700f30,0x30000c0, 0x2400f30,0xe700000,0x300,0xc00240,0xe7000c0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0, 0x630018c,0x807e00,0xfe00180,0xc00300,0x1000000,0x0,0x38,0xff01fc0,0x3ff01ff0,0x1e01ff8,0x7f83ffc,0x1ff80ff0,0x0,0x0,0xff0, 0x1f003e0,0x7fe00ff8,0x7fc07ff8,0x7ff80ff8,0x70381ffc,0xff0701c,0x7000783c,0x78381ff0,0x7fe01ff0,0x7fe01ff0,0x7fff7038,0x781ee007, 0x3c1e380e,0x7ffc0380,0x380001c0,0x3c00000,0x1800000,0x38000000,0x1c0000,0x3c00000,0x380001c0,0xe01c00,0x3800000,0x0,0x0, 0x0,0x7000000,0x0,0x0,0x1e0,0x18003c0,0x0,0x3fc0000,0x70,0x0,0x0,0x6600000,0x1ff00000,0x1fff0000,0x7ffc0000,0x0,0x0,0x0,0x0, 0xcf0239c,0x3c00000,0x0,0x3c0380e,0x1c0,0x2001fe,0x380e,0x18007f8,0xe700000,0x8600000,0x0,0xff0,0x7e00000,0x8c00870,0x1800000, 0x1ff80000,0x180,0xc600000,0xc000c00,0x38001c0,0x3e003e0,0x3e003e0,0x3e001c0,0x7fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc, 0x7fc07838,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x1fec7038,0x70387038,0x7038380e,0x70003ce0,0x1800180,0x6600cf0,0xe7007c0,0x0, 0x1800180,0x6600e70,0x1800180,0x6600e70,0x7c00cf0,0x1800180,0x6600cf0,0xe700000,0x180,0x1800660,0xe700180,0x38000e70,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630030c,0x3f0e700,0x1e200180,0x1800180,0x21100000,0x0, 0x38,0x1e7819c0,0x38781038,0x1e01c00,0xf080038,0x1c381c38,0x0,0x0,0x1878,0x7fc03e0,0x70e01e18,0x70e07000,0x70001e18,0x703801c0, 0x707038,0x70007c7c,0x7c381c70,0x70701c70,0x70703830,0x1c07038,0x381ce007,0x1c1c3c1e,0x3c0380,0x380001c0,0x7e00000,0xc00000, 0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0,0x70c0000,0xe0, 0x0,0x0,0xc300000,0x38300000,0x3c700000,0x3c0000,0x0,0x0,0x0,0x0,0xce022f4,0x1800000,0x0,0x1803c1e,0x1c0,0x2003c2,0x3c1e, 0x1800e08,0x7e0,0x300000,0x0,0x7e00000,0xe700000,0x600030,0x3000000,0x3f980000,0x180,0x18200000,0xc000c00,0x1e0001c0,0x3e003e0, 0x3e003e0,0x3e003e0,0xfe01e18,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70e07c38,0x1c701c70,0x1c701c70,0x1c700000,0x3c787038, 0x70387038,0x70383c1e,0x70003870,0xc00300,0xc300ce0,0x380,0x0,0xc00300,0xc300000,0xc00300,0xc300000,0xfc00ce0,0xc00300,0xc300ce0, 0x0,0xc0,0x3000c30,0x300,0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630031c,0xff8c300, 0x1c000180,0x1800180,0x39380000,0x0,0x70,0x1c3801c0,0x203c001c,0x3e01c00,0x1c000038,0x381c3838,0x0,0x0,0x1038,0xe0e03e0,0x70703c08, 0x70707000,0x70003808,0x703801c0,0x707070,0x70007c7c,0x7c383838,0x70383838,0x70387010,0x1c07038,0x381c700e,0x1e3c1c1c,0x780380, 0x1c0001c0,0xe700000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0, 0x0,0xe000000,0xe0,0x0,0x1000100,0x3800,0x70100000,0x38700000,0x780000,0x1c0,0x7801ce0,0xe380000,0x0,0x2264,0x0,0x0,0x1c1c, 0x0,0x200780,0x1c1c,0x1800c00,0x1818,0x7f00000,0x0,0x18180000,0xc300000,0x600070,0x0,0x7f980000,0x180,0x18300000,0xc000c00, 0x3000000,0x3e003e0,0x3e003e0,0x3e003e0,0xee03c08,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838, 0x38380000,0x38387038,0x70387038,0x70381c1c,0x7fc03870,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xbc00000,0x0,0x0,0x0,0x0,0x0,0x0, 0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0xe88c300,0x1c000180,0x38001c0, 0xfe00180,0x0,0x70,0x1c3801c0,0x1c001c,0x6e01c00,0x1c000078,0x381c3818,0x0,0x40000,0x40000038,0x1c0607e0,0x70703800,0x70707000, 0x70003800,0x703801c0,0x7070e0,0x70007c7c,0x7c383838,0x70383838,0x70387000,0x1c07038,0x381c700e,0xf780e38,0x700380,0x1c0001c0, 0x1c380000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0, 0xe000000,0xe0,0x0,0x1000100,0x4400,0x70000000,0x38700000,0x700000,0xe0,0x7001c70,0xe380000,0x0,0x2264,0x0,0x0,0xe38,0x0, 0x200700,0xe38,0x1800c00,0x300c,0xc300000,0x0,0x300c0000,0xc300180,0x6003c0,0x0,0x7f980000,0x180,0x18300000,0xc000c00,0x1800000, 0x7e007e0,0x7e007e0,0x7e003e0,0xee03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838,0x38380000, 0x38387038,0x70387038,0x70380e38,0x7ff039f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e00000,0x0,0x0,0x0,0x40000,0x0,0x0,0x38000000, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0x1c80e700,0x1c000180,0x38001c0,0x3800180, 0x0,0xe0,0x381c01c0,0x1c001c,0x6e01c00,0x38000070,0x381c381c,0x0,0x3c0000,0x78000078,0x38030770,0x70707800,0x70387000,0x70007000, 0x703801c0,0x7071c0,0x7000745c,0x7638701c,0x7038701c,0x70387000,0x1c07038,0x1c38718e,0x7700f78,0xf00380,0xe0001c0,0x381c0000, 0x7e0,0x39e003e0,0x79c03f0,0x3ffc079c,0x39e01fc0,0xfe01c1e,0x3807778,0x39e007e0,0x39e0079c,0x73c07e0,0x7ff83838,0x701ce007, 0x783c701c,0x1ffc01c0,0x18001c0,0x0,0x1c000100,0xe0,0x0,0x1000100,0x4200,0x70000000,0x70700100,0xf00100,0x10000e0,0x7000c70, 0xc700000,0x0,0x2204,0x7e00000,0x1e380100,0x1ffc0f78,0x0,0xf80700,0xf78,0x1800e00,0x63e6,0x18300000,0x0,0x6fe60000,0xe700180, 0xc00060,0x3838,0x7f980000,0x180,0x18300000,0xc000c00,0x18001c0,0x7700770,0x7700770,0x77007f0,0xee07800,0x70007000,0x70007000, 0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1008,0x707c7038,0x70387038,0x70380f78,0x707039c0,0x7e007e0,0x7e007e0, 0x7e007e0,0x1f3c03e0,0x3f003f0,0x3f003f0,0x1fc01fc0,0x1fc01fc0,0x7f039e0,0x7e007e0,0x7e007e0,0x7e00380,0x7ce3838,0x38383838, 0x3838701c,0x39e0701c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6307fff,0x1c807e0c,0xe000180, 0x30000c0,0x3800180,0x0,0xe0,0x381c01c0,0x1c001c,0xce01fe0,0x38000070,0x381c381c,0x3800380,0xfc0000,0x7e0000f0,0x30030770, 0x70707000,0x70387000,0x70007000,0x703801c0,0x707380,0x700076dc,0x7638701c,0x7038701c,0x70387800,0x1c07038,0x1c3873ce,0x7f00770, 0xe00380,0xe0001c0,0x700e0000,0x1ff8,0x3ff00ff0,0xffc0ff8,0x3ffc0ffc,0x3bf01fc0,0xfe01c3c,0x3807f78,0x3bf00ff0,0x3ff00ffc, 0x77e0ff0,0x7ff83838,0x3838e007,0x3c783838,0x1ffc01c0,0x18001c0,0x0,0x7ff00380,0x1e0,0x0,0x1000100,0x4200,0x78000000,0x70700380, 0xe00380,0x3800060,0xe000e30,0x1c600000,0x0,0x2204,0xff00000,0x7f7c0380,0x1ffc0770,0x1c0,0x3fc0700,0x18040770,0x1800780,0x4e12, 0x18300104,0x0,0x4c320000,0x7e00180,0x1c00030,0x3838,0x7f980000,0x180,0x18302080,0xc000c00,0x18001c0,0x7700770,0x7700770, 0x7700770,0x1ee07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c381c,0x705c7038,0x70387038, 0x70380770,0x70383b80,0x1ff81ff8,0x1ff81ff8,0x1ff81ff8,0x3fbe0ff0,0xff80ff8,0xff80ff8,0x1fc01fc0,0x1fc01fc0,0xff83bf0,0xff00ff0, 0xff00ff0,0xff00380,0xffc3838,0x38383838,0x38383838,0x3ff03838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x1c0,0x7fff,0x1c803c38,0xf000000,0x70000e0,0xfe00180,0x0,0x1c0,0x381c01c0,0x3c0078,0xce01ff0,0x39e000f0,0x1c38381c,0x3800380, 0x3e07ffc,0xf8001f0,0x307b0770,0x70e07000,0x70387000,0x70007000,0x703801c0,0x707700,0x700076dc,0x7638701c,0x7038701c,0x70387e00, 0x1c07038,0x1c3873ce,0x3e007f0,0x1e00380,0x70001c0,0x0,0x1038,0x3c381e18,0x1c7c1e3c,0x3801e3c,0x3c7801c0,0xe01c78,0x380739c, 0x3c781c38,0x3c381c3c,0x7c21e10,0x7003838,0x3838700e,0x1ef03838,0x3c01c0,0x18001c0,0x0,0x7fe007c0,0x1c0,0x0,0x1000100,0x6400, 0x7e000000,0x707007c0,0x1e007c0,0x7c00070,0xe000638,0x18600000,0x0,0x0,0x1e100000,0x73ce07c0,0x3c07f0,0x1c0,0x7240700,0x1ddc3ffe, 0x1800de0,0x8c01,0x1870030c,0x0,0x8c310000,0x3c00180,0x3800030,0x3838,0x7f980000,0x180,0x183030c0,0xc000c00,0x430001c0,0x7700770, 0x7700770,0x7700770,0x1ce07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1c38,0x70dc7038, 0x70387038,0x703807f0,0x70383b80,0x10381038,0x10381038,0x10381038,0x21e71e18,0x1e3c1e3c,0x1e3c1e3c,0x1c001c0,0x1c001c0,0x1e383c78, 0x1c381c38,0x1c381c38,0x1c380380,0x1c383838,0x38383838,0x38383838,0x3c383838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0x1e8000e0,0x1f000000,0x70000e0,0x39380180,0x0,0x1c0,0x3b9c01c0,0x3c07f0,0x18e01078,0x3bf800e0, 0x7e0383c,0x3800380,0x1f807ffc,0x3f001c0,0x61ff0e38,0x7fc07000,0x70387ff0,0x7ff07000,0x7ff801c0,0x707f00,0x7000729c,0x7338701c, 0x7070701c,0x70703fc0,0x1c07038,0x1e7873ce,0x1c003e0,0x3c00380,0x70001c0,0x0,0x1c,0x3c381c00,0x1c3c1c1c,0x3801c3c,0x383801c0, 0xe01cf0,0x380739c,0x38381c38,0x3c381c3c,0x7801c00,0x7003838,0x3838700e,0xfe03c78,0x7801c0,0x18001c0,0x0,0x1c000c20,0xff8, 0x0,0x1ff01ff0,0x3818,0x3fc00100,0x707e0c20,0x3c00c20,0xc200030,0xc000618,0x18c00000,0x0,0x0,0x1c000080,0xe1ce0c20,0x7803e0, 0x1c0,0xe200700,0xff83ffe,0x1801878,0x9801,0x1cf0071c,0x7ffc0000,0x8c310000,0x7ffe,0x7000030,0x3838,0x3f980380,0x180,0xc6038e0, 0x7f9c7f9c,0x3e1c01c0,0xe380e38,0xe380e38,0xe380f78,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0,0x1c001c0,0xfe387338,0x701c701c, 0x701c701c,0x701c0e70,0x719c7038,0x70387038,0x703803e0,0x70383b80,0x1c001c,0x1c001c,0x1c001c,0xe71c00,0x1c1c1c1c,0x1c1c1c1c, 0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380000,0x3c383838,0x38383838,0x38383c78,0x3c383c78,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0xf800380,0x3f830000,0x70000e0,0x31080180,0x0,0x380,0x3b9c01c0, 0x7807e0,0x38e00038,0x3c3800e0,0xff01c3c,0x3800380,0x7c000000,0x7c03c0,0x61870e38,0x7fc07000,0x70387ff0,0x7ff070fc,0x7ff801c0, 0x707f80,0x7000739c,0x7338701c,0x7ff0701c,0x7fe00ff0,0x1c07038,0xe7073ce,0x1c003e0,0x3800380,0x38001c0,0x0,0x1c,0x381c3800, 0x381c380e,0x380381c,0x383801c0,0xe01de0,0x380739c,0x3838381c,0x381c381c,0x7001e00,0x7003838,0x1c70718e,0x7e01c70,0xf00380, 0x18001e0,0x1e000000,0x1c001bb0,0xff8,0x0,0x1000100,0xe0,0xff00300,0x707e1bb0,0x3801bb0,0x1bb00010,0x8000308,0x30c00000,0x0, 0x0,0x1e0000c0,0xe1ce1bb0,0xf003e0,0x1c0,0x1c203ff8,0x63003e0,0x180181c,0x9801,0xfb00e38,0x7ffc0000,0x8fc10000,0x7ffe,0xe000860, 0x3838,0x1f980380,0x180,0x7c01c70,0x1f001f0,0x1f003c0,0xe380e38,0xe380e38,0xe380e38,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0, 0x1c001c0,0xfe387338,0x701c701c,0x701c701c,0x701c07e0,0x731c7038,0x70387038,0x703803e0,0x70383980,0x1c001c,0x1c001c,0x1c001c, 0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x387c3838,0x38383838,0x38381c70, 0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc30,0x7f00e00,0x33c30000,0x70000e0,0x1007ffe, 0x0,0x380,0x3b9c01c0,0xf00078,0x30e0001c,0x3c1c01c0,0x1c381fdc,0x0,0x70000000,0x1c0380,0x63030e38,0x70707000,0x70387000,0x700070fc, 0x703801c0,0x707b80,0x7000739c,0x7338701c,0x7fc0701c,0x7fc001f0,0x1c07038,0xe703e5c,0x3e001c0,0x7800380,0x38001c0,0x0,0x7fc, 0x381c3800,0x381c380e,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7001fc0,0x7003838,0x1c70718e,0x7c01c70, 0xe01f00,0x180007c,0x7f8c0000,0x7fc03fb8,0x1c0,0x0,0x1000100,0x700,0x1f00600,0x70703fb8,0x7803fb8,0x3fb80000,0x8000000,0x180, 0x0,0x0,0x1fc00060,0xe1ce3fb8,0xe001c0,0x1c0,0x1c203ff8,0xc1801c0,0x180c,0x9801,0x1c70,0xc0000,0x8cc10000,0x180,0xfe007c0, 0x3838,0x7980380,0xff0,0xe38,0x3e003e00,0x3e000380,0xe380e38,0xe380e38,0xe380e38,0x38e07000,0x70007000,0x70007000,0x1c001c0, 0x1c001c0,0x70387338,0x701c701c,0x701c701c,0x701c03c0,0x731c7038,0x70387038,0x703801c0,0x703838e0,0x7fc07fc,0x7fc07fc,0x7fc07fc, 0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x38dc3838,0x38383838,0x38381c70, 0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc60,0xf83878,0x71e30000,0x70000e0,0x1007ffe, 0x7f0,0x380,0x381c01c0,0x1e0003c,0x60e0001c,0x381c01c0,0x381c079c,0x0,0x7c000000,0x7c0380,0x63031c1c,0x70307000,0x70387000, 0x7000701c,0x703801c0,0x7071c0,0x7000739c,0x71b8701c,0x7000701c,0x71e00078,0x1c07038,0xe703e7c,0x7e001c0,0xf000380,0x38001c0, 0x0,0x1ffc,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fc0,0x380739c,0x3838381c,0x381c381c,0x7000ff0,0x7003838,0x1ef03bdc, 0x3800ee0,0x1e01f00,0x180007c,0x61fc0000,0x7fc07f3c,0x1c0,0x0,0x1000100,0x1800,0x780c00,0x70707f3c,0xf007f3c,0x7f3c0000,0x0, 0x3c0,0x3ffcffff,0x0,0xff00030,0xe1fe7f3c,0x1e001c0,0x1c0,0x1c200700,0xc183ffe,0xe0c,0x9801,0x1ff038e0,0xc07f0,0x8c610000, 0x180,0x0,0x3838,0x1980380,0x0,0x1ff0071c,0xe000e000,0xe0000f80,0x1c1c1c1c,0x1c1c1c1c,0x1c1c1e38,0x38e07000,0x70007000,0x70007000, 0x1c001c0,0x1c001c0,0x703871b8,0x701c701c,0x701c701c,0x701c03c0,0x761c7038,0x70387038,0x703801c0,0x70703870,0x1ffc1ffc,0x1ffc1ffc, 0x1ffc1ffc,0xfff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x389c3838,0x38383838, 0x38380ee0,0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xfffc,0xbc60fc,0x70e30000,0x70000e0, 0x180,0x7f0,0x700,0x381c01c0,0x3e0001c,0x7ffc001c,0x381c03c0,0x381c001c,0x0,0x1f807ffc,0x3f00380,0x63031ffc,0x70387000,0x70387000, 0x7000701c,0x703801c0,0x7071e0,0x7000701c,0x71b8701c,0x7000701c,0x70f00038,0x1c07038,0x7e03e7c,0x77001c0,0xe000380,0x1c001c0, 0x0,0x3c1c,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x70003f8,0x7003838,0xee03bdc, 0x3c00ee0,0x3c00380,0x18000e0,0xf00000,0x1c007e7c,0x3c0,0x0,0x1000100,0x0,0x381800,0x70707e7c,0xe007e7c,0x7e7c0000,0x0,0x7c0, 0x0,0x0,0x3f80018,0xe1fe7e7c,0x3c001c0,0x1c0,0x1c200700,0xc183ffe,0xf0c,0x8c01,0x38e0,0xc07f0,0x8c710000,0x180,0x0,0x3838, 0x1980000,0x0,0x71c,0x7000f0,0x700f00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x3fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0, 0x703871b8,0x701c701c,0x701c701c,0x701c07e0,0x7c1c7038,0x70387038,0x703801c0,0x7ff03838,0x3c1c3c1c,0x3c1c3c1c,0x3c1c3c1c, 0x3fff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x391c3838,0x38383838,0x38380ee0, 0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfffc,0x9c01ce,0x70f60000,0x70000e0,0x180, 0x0,0x700,0x381c01c0,0x780001c,0x7ffc001c,0x381c0380,0x381c003c,0x0,0x3e07ffc,0xf800380,0x63031ffc,0x70387000,0x70387000, 0x7000701c,0x703801c0,0x7070f0,0x7000701c,0x71b8701c,0x7000701c,0x70700038,0x1c07038,0x7e03e7c,0xf7801c0,0x1e000380,0x1c001c0, 0x0,0x381c,0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7000078,0x7003838,0xee03a5c, 0x7c00fe0,0x78001c0,0x18001c0,0x0,0x1c003ef8,0x380,0x0,0x1000100,0x810,0x383000,0x70703ef8,0x1e003ef8,0x3ef80000,0x0,0x7c0, 0x0,0x0,0x78000c,0xe1c03ef8,0x78001c0,0x1c0,0x1c200700,0x63001c0,0x18003f8,0x4e12,0x1c70,0xc0000,0x4c320000,0x180,0x0,0x3838, 0x1980000,0x0,0xe38,0x700118,0x701e00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x7fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0, 0x703871b8,0x701c701c,0x701c701c,0x701c0e70,0x7c1c7038,0x70387038,0x703801c0,0x7fc0381c,0x381c381c,0x381c381c,0x381c381c, 0x78e03800,0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x3b1c3838,0x38383838,0x38380fe0, 0x381c0fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1860,0x9c0186,0x707e0000,0x30000c0,0x180, 0x0,0xe00,0x183801c0,0xf00001c,0xe0001c,0x181c0380,0x381c0038,0x0,0xfc0000,0x7e000000,0x61873c1e,0x70383800,0x70707000,0x7000381c, 0x703801c0,0x707070,0x7000701c,0x70f83838,0x70003838,0x70780038,0x1c07038,0x7e03c3c,0xe3801c0,0x1c000380,0xe001c0,0x0,0x381c, 0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01ef0,0x380739c,0x3838381c,0x381c381c,0x7000038,0x7003838,0xfe03e7c,0xfe007c0, 0x70001c0,0x18001c0,0x0,0xe001ff0,0x380,0x0,0x1000100,0x162c,0x381800,0x30701ff0,0x1c001ff0,0x1ff00000,0x0,0x3c0,0x0,0x0, 0x380018,0xe1c01ff0,0x70001c0,0x1c0,0x1c200700,0xff801c0,0x18000f0,0x63e6,0xe38,0x0,0x6c3e0000,0x0,0x0,0x3838,0x1980000,0x0, 0x1c70,0xf0000c,0xf01c00,0x3c1e3c1e,0x3c1e3c1e,0x3c1e3c1c,0x70e03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x707070f8, 0x38383838,0x38383838,0x38381c38,0x38387038,0x70387038,0x703801c0,0x7000381c,0x381c381c,0x381c381c,0x381c381c,0x70e03800, 0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0380,0x3e1c3838,0x38383838,0x383807c0,0x381c07c0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18c0,0x9c0186,0x783c0000,0x38001c0,0x180,0x3800000, 0x3800e00,0x1c3801c0,0x1e00003c,0xe00038,0x1c1c0780,0x381c0038,0x3800380,0x3c0000,0x78000000,0x61ff380e,0x70383808,0x70707000, 0x7000381c,0x703801c0,0x40707078,0x7000701c,0x70f83838,0x70003838,0x70384038,0x1c07038,0x7e03c3c,0x1e3c01c0,0x3c000380,0xe001c0, 0x0,0x383c,0x3c381c00,0x1c3c1c00,0x3801c3c,0x383801c0,0xe01c78,0x380739c,0x38381c38,0x3c381c3c,0x7000038,0x7003878,0x7c01e78, 0x1ef007c0,0xf0001c0,0x18001c0,0x0,0xe000ee0,0x7800380,0xe380000,0x1001ff0,0x2242,0x40380c00,0x38700ee0,0x3c000ee0,0xee00000, 0x0,0x0,0x0,0x0,0x380030,0xe1c00ee0,0xf0001c0,0x1c0,0xe200700,0xdd801c0,0x1800038,0x300c,0x71c,0x0,0x300c0000,0x0,0x0,0x3838, 0x1980000,0x0,0x38e0,0xb0000c,0xb01c08,0x380e380e,0x380e380e,0x380e380e,0x70e03808,0x70007000,0x70007000,0x1c001c0,0x1c001c0, 0x707070f8,0x38383838,0x38383838,0x3838381c,0x38387038,0x70387038,0x703801c0,0x7000381c,0x383c383c,0x383c383c,0x383c383c, 0x70e01c00,0x1c001c00,0x1c001c00,0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383878,0x38783878,0x387807c0, 0x3c3807c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x18c0,0x10b801ce,0x3c3e0000,0x38001c0,0x180, 0x3800000,0x3801c00,0x1e7801c0,0x3c002078,0xe02078,0x1c380700,0x1c3810f0,0x3800380,0x40000,0x40000380,0x307b380e,0x70701e18, 0x70e07000,0x70001c1c,0x703801c0,0x60e0703c,0x7000701c,0x70f83c78,0x70003c70,0x703c70f0,0x1c03870,0x3c01c3c,0x3c1c01c0,0x78000380, 0x7001c0,0x0,0x3c7c,0x3c381e18,0x1c7c1e0c,0x3801c3c,0x383801c0,0xe01c38,0x3c0739c,0x38381c38,0x3c381c3c,0x7001078,0x7803c78, 0x7c01c38,0x1c780380,0x1e0001c0,0x18001c0,0x0,0x70c06c0,0x7000380,0xe300000,0x1000100,0x2142,0x70f00600,0x3c7006c0,0x780006c0, 0x6c00000,0x0,0x0,0x0,0x0,0x10780060,0x73e206c0,0x1e0001c0,0x1c0,0x7240700,0x180c01c0,0x1800018,0x1818,0x30c,0x0,0x18180000, 0x0,0x0,0x3c78,0x1980000,0x0,0x30c0,0x130000c,0x1301c18,0x380e380e,0x380e380e,0x380e380e,0x70e01e18,0x70007000,0x70007000, 0x1c001c0,0x1c001c0,0x70e070f8,0x3c783c78,0x3c783c78,0x3c781008,0x7c783870,0x38703870,0x387001c0,0x70003a3c,0x3c7c3c7c,0x3c7c3c7c, 0x3c7c3c7c,0x79f11e18,0x1e0c1e0c,0x1e0c1e0c,0x1c001c0,0x1c001c0,0x1c783838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383c78,0x3c783c78, 0x3c780380,0x3c380380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x38c0,0x1ff800fc,0x1fee0000, 0x1800180,0x180,0x3800000,0x3801c00,0xff01ffc,0x3ffc3ff0,0xe03ff0,0xff00700,0x1ff81fe0,0x3800380,0x0,0x380,0x3000780f,0x7ff00ff8, 0x7fc07ff8,0x70000ffc,0x70381ffc,0x7fe0701c,0x7ff8701c,0x70781ff0,0x70001ff0,0x701c7ff0,0x1c01fe0,0x3c01c38,0x380e01c0,0x7ffc0380, 0x7001c0,0x0,0x1fdc,0x3ff00ff0,0xffc0ffc,0x3800fdc,0x38383ffe,0xe01c3c,0x1fc739c,0x38380ff0,0x3ff00ffc,0x7001ff0,0x3f81fb8, 0x7c01c38,0x3c3c0380,0x1ffc01c0,0x18001c0,0x0,0x3fc0380,0x7000380,0xc70718c,0x1000100,0x2244,0x7ff00200,0x1fff0380,0x7ffc0380, 0x3800000,0x0,0x0,0x0,0x0,0x1ff000c0,0x7f7e0380,0x1ffc01c0,0x1c0,0x3fc3ffe,0x1c0,0x1800018,0x7e0,0x104,0x0,0x7e00000,0x7ffe, 0x0,0x3fde,0x1980000,0x0,0x2080,0x3300018,0x3300ff0,0x780f780f,0x780f780f,0x780f780e,0xf0fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc, 0x1ffc1ffc,0x7fc07078,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x7ff01fe0,0x1fe01fe0,0x1fe001c0,0x70003bf8,0x1fdc1fdc,0x1fdc1fdc, 0x1fdc1fdc,0x3fbf0ff0,0xffc0ffc,0xffc0ffc,0x3ffe3ffe,0x3ffe3ffe,0xff03838,0xff00ff0,0xff00ff0,0xff00000,0x3ff01fb8,0x1fb81fb8, 0x1fb80380,0x3ff00380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x31c0,0x7e00078,0x7cf0000,0x1800180, 0x0,0x3800000,0x3803800,0x3c01ffc,0x3ffc0fe0,0xe01fc0,0x3e00e00,0x7e00f80,0x3800380,0x0,0x380,0x18007007,0x7fc003f0,0x7f007ff8, 0x700003f0,0x70381ffc,0x3f80701e,0x7ff8701c,0x707807c0,0x700007c0,0x701e1fc0,0x1c00fc0,0x3c01818,0x780f01c0,0x7ffc0380,0x3801c0, 0x0,0xf9c,0x39e003e0,0x79c03f0,0x380079c,0x38383ffe,0xe01c1e,0x7c739c,0x383807e0,0x39e0079c,0x7000fc0,0x1f80f38,0x3801c38, 0x781e0380,0x1ffc01c0,0x18001c0,0x0,0x1f80100,0xe000700,0x1c60718c,0x1000100,0x1e3c,0x1fc00100,0x7ff0100,0x7ffc0100,0x1000000, 0x0,0x0,0x0,0x0,0xfc00080,0x3e3c0100,0x1ffc01c0,0x1c0,0xf83ffe,0x1c0,0x1800838,0x0,0x0,0x0,0x0,0x7ffe,0x0,0x3b9e,0x1980000, 0x0,0x0,0x2300038,0x23003e0,0x70077007,0x70077007,0x70077007,0xe0fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007078, 0x7c007c0,0x7c007c0,0x7c00000,0xc7c00fc0,0xfc00fc0,0xfc001c0,0x700039f0,0xf9c0f9c,0xf9c0f9c,0xf9c0f9c,0x1f1e03e0,0x3f003f0, 0x3f003f0,0x3ffe3ffe,0x3ffe3ffe,0x7e03838,0x7e007e0,0x7e007e0,0x7e00000,0x63e00f38,0xf380f38,0xf380380,0x39e00380,0x0,0x0, 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, 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, 0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1c0,0x18001c0,0x0,0x0,0xe000700,0x18600000,0x1000100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800ff0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0x1800000,0x0,0x6300070,0x6300000,0x0, 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, 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, 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, 0x0,0x0,0x1c,0x0,0xe00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1e0,0x18003c0,0x0,0x0,0xc000700,0x18c00000,0x1000000,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x18007e0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0xc00000, 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, 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, 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, 0x3f0,0xfc0,0x0,0x0,0x0,0x0,0x838,0x0,0x1e00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0xf00,0xfc,0x1801f80,0x0,0x0,0x8008e00,0x30c00000, 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, 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, 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, 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, 0x0,0x0,0xff0,0x0,0x1fc00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x3e00,0x7c,0x1801f00,0x0,0x0,0x800fe00,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x7c00000,0x0,0x3001fc,0x300000, 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, 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, 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, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0 }; const unsigned int font19x38[19*38*256/32] = { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 0x1e00000,0x3,0x80000700,0x3c00000,0x380000,0x70003c00,0x0,0xe1800e,0x1c00,0xf000e18,0x0,0x0,0x700000e0,0x780000,0x7000,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0000e,0x7e003,0xe60071c0,0x7f80000,0x1,0xc0000e00,0x7e0038e,0x1c0000, 0xe0007e00,0x38e00000,0xf98007,0x3800,0x1f800f98,0x1c70000,0x0,0x380001c0,0xfc0071,0xc000e000,0x0,0x0,0x0,0x0,0x3e00000,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0001c,0xe7006,0x7c0071c0,0xe180000,0x0,0xe0001c00,0xe70038e,0xe0001,0xc000e700,0x38e00000, 0x19f0003,0x80007000,0x39c019f0,0x1c70000,0x0,0x1c000380,0x1ce0071,0xc001c000,0x0,0x0,0x0,0x0,0x7f00000,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,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, 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, 0x0,0x0,0x700038,0x1c3806,0x3c0071c0,0xc0c0000,0x0,0x70003800,0x1c38038e,0x70003,0x8001c380,0x38e00000,0x18f0001,0xc000e000, 0x70e018f0,0x1c70000,0x0,0xe000700,0x3870071,0xc0038000,0x0,0x0,0x0,0x0,0xe380000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 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, 0xe,0x380,0x1800000,0xe00000,0x38001800,0x0,0x38,0xe00,0x6000000,0x0,0x1,0xc0000070,0x300000,0x3800,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 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, 0x0,0x0,0xc3000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800000,0x0,0x0,0x0,0xe0,0x1c000f,0xc0000000,0x0,0x0, 0x0,0xc0c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7000007,0x3c003,0xc6000000,0xc180000,0x7,0x700, 0x3c00000,0x700000,0x70003c00,0x0,0xf1801c,0x1c00,0xf000f18,0x0,0x0,0xe00000e0,0x780000,0x7000,0x0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x7,0xe000001c,0x1c00,0x1c00700,0x7fc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf800e,0x3e0000,0x0,0x0,0x0,0x1e00000,0x0,0x1, 0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7cc00,0x660,0x0,0x0,0x66000000,0x0,0x0,0x0,0x0,0x7,0x1c000000,0x0,0x0,0x0,0x3fe00000, 0x0,0x0,0x7000000,0x0,0x0,0x0,0x3e0,0x7c001f,0xe0000000,0x0,0x0,0x0,0xe1c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x1f80,0x380000e,0x7e007,0xe60071c0,0xc180000,0x3,0x80000e00,0x7e0038e,0x380000,0xe0007e00,0x38e00f00,0x1f9800e, 0x3800,0x1f801f98,0x1c70000,0x0,0x700001c0,0xfc0071,0xc000e007,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0x61c00600,0x1e00007e,0x70000,0x18003000,0x1800000,0x0,0x0,0x1c01f0,0x7e003f,0xc003f800, 0x1e03ffc,0x7f01ff,0xfc03f000,0x7e000000,0x0,0x0,0xfc0,0x1e,0x7fe000,0x7e03fe00,0x3fff07ff,0xe007e038,0x383ffe0,0xff81c01, 0xe1c000f8,0xf8f00e0,0xfc01ffc,0x3f00ff,0xc000fe07,0xfffc7007,0x1c007700,0x73c01ef,0x78ffff,0xfe0380,0xfe000,0x38000000,0x1800000, 0x700000,0x38,0x1f,0xe000001c,0x1c00,0x1c00700,0x7fc0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x3f800e,0x3f8000,0x0,0xfc0000, 0x0,0x7f00000,0x0,0x1,0x98000000,0x7f00000,0x3ffe00,0xffff0,0x0,0x0,0x0,0x0,0x0,0xcf81f,0xee3807e0,0x0,0x0,0x7e03c01e,0x1c, 0x0,0x1f800000,0xf0078038,0xfc007,0x1c000000,0xfe00000,0x0,0x0,0x3fe000f0,0xf,0xc001f800,0x6000000,0xffc000,0x0,0x1c0007e0, 0x360,0x6c0010,0x70000700,0xf0001e,0x3c000,0x78000f00,0x7f800ff,0xf007e01f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83fc0, 0x7807007,0xe000fc00,0x1f8003f0,0x7e0000,0x1f867,0x70e00e,0x1c01c380,0x38f00787,0x3fe0,0x180000c,0x66006,0x7c0071c0,0xe380000, 0x1,0x80000c00,0x660038e,0x180000,0xc0006600,0x38e0078e,0x19f0006,0x3000,0x198019f0,0x1c70000,0x0,0x30000180,0xcc0071,0xc000c007, 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, 0x38003800,0x1800000,0x0,0x0,0x3807fc,0x1fe00ff,0xf00ffe00,0x3e03ffc,0xff81ff,0xfc07fc01,0xff800000,0x0,0x0,0x3fe0,0xfe001e, 0x7ff801,0xff83ff80,0x3fff07ff,0xe01ff838,0x383ffe0,0xff81c03,0xc1c000f8,0xf8f80e0,0x3ff01fff,0xffc0ff,0xf003ff87,0xfffc7007, 0x1e00f700,0x71c03c7,0x70ffff,0xfe01c0,0xfe000,0x7c000000,0xc00000,0x700000,0x38,0x3f,0xe000001c,0x1c00,0x1c00700,0x7fc0000, 0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x3f800e,0x3f8000,0x0,0x3fe0000,0x0,0xff00000,0x0,0x3,0xc000000,0x1ffc0000,0xfffe00, 0xffff0,0x0,0x0,0x0,0x0,0x0,0xc781f,0xee3803c0,0x0,0x0,0x3c01c01c,0x1c,0xc000,0x7fc00000,0x70070038,0x3fe007,0x1c000000,0x1ff80000, 0x0,0x0,0x3fe003fc,0x1f,0xe003fc00,0xc000000,0x3ffc000,0x0,0x7c000ff0,0x60,0xc0000,0x30000700,0xf0001e,0x3c000,0x78000f00, 0x3f000ff,0xf01ff81f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ff8,0x7c0701f,0xf803ff00,0x7fe00ffc,0x1ff8000,0x7fe67, 0x70e00e,0x1c01c380,0x38700707,0x7ff0,0xc00018,0xc3006,0x3c0071c0,0x7f00000,0x0,0xc0001800,0xc30038e,0xc0001,0x8000c300,0x38e003fc, 0x18f0003,0x6000,0x30c018f0,0x1c70000,0x0,0x18000300,0x1860071,0xc0018007,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xe1801fc0,0x618001ff,0x70000,0x30001800,0x21840000,0x0,0x0,0x380ffe,0x1fe00ff, 0xfc0fff00,0x3e03ffc,0x1ff81ff,0xfc0ffe03,0xffc00000,0x0,0x0,0x7ff0,0x3ff803f,0x7ffc03,0xffc3ffc0,0x3fff07ff,0xe03ffc38,0x383ffe0, 0xff81c07,0x81c000f8,0xf8f80e0,0x7ff81fff,0x81ffe0ff,0xf80fff87,0xfffc7007,0xe00e700,0x70e0387,0x80f0ffff,0xe001c0,0xe000, 0xfe000000,0xe00000,0x700000,0x38,0x3c,0x1c,0x1c00,0x1c00700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x78000e,0x3c000, 0x0,0x7ff0000,0x0,0xf100000,0x0,0x7,0xe000000,0x7ffc0000,0x1fffe00,0xffff0,0x0,0x0,0x0,0x0,0x0,0x3,0xf780180,0x0,0x0,0x1801e03c, 0x1c,0xc000,0xffc00000,0x780f0038,0x786000,0x7f00,0x18380000,0x0,0xfe00,0x30c,0x10,0x70020e00,0x1c000000,0x7f8c000,0x0,0x6c001c38, 0x60,0xc0000,0x70000700,0x1f8003f,0x7e000,0xfc001f80,0x3f000ff,0xf03ffc1f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ffc, 0x7c0703f,0xfc07ff80,0xfff01ffe,0x3ffc000,0xffec7,0x70e00e,0x1c01c380,0x38780f07,0xf070,0xe00038,0x1c3800,0x0,0x3e00000,0x0, 0xe0003800,0x1c380000,0xe0003,0x8001c380,0x3e0,0x3,0x8000e000,0x70e00000,0x0,0x0,0x1c000700,0x3870000,0x38007,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xe3807ff0,0xc0c003c1,0x70000,0x70001c00, 0x718e0000,0x0,0x0,0x700f1e,0x1ce00c0,0x3c0c0f80,0x7e03800,0x3e08000,0x381e0f03,0xc1e00000,0x0,0x0,0x7078,0x783c03f,0x701e07, 0xc1c383e0,0x38000700,0x7c1c38,0x3801c00,0x381c0f,0x1c000fc,0x1f8f80e0,0x78781c07,0x81e1e0e0,0x780f0180,0xe007007,0xe00e380, 0xe0f0783,0x80e0000e,0xe000e0,0xe001,0xef000000,0x0,0x700000,0x38,0x38,0x1c,0x0,0x700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000, 0x0,0x0,0x0,0x70000e,0x1c000,0x0,0xf830000,0x0,0x1e000000,0x0,0x0,0x10000,0x780c0000,0x3e38000,0xe0,0x0,0x0,0x0,0x0,0x0,0x3, 0xd580000,0x0,0x0,0xe038,0x1c,0xc000,0xf0400000,0x380e0038,0x702000,0x1ffc0,0xc0000,0x0,0x3ff80,0x606,0x0,0x30000600,0x0, 0x7f8c000,0x0,0xc001818,0x60,0xc0003,0xe0000700,0x1f8003f,0x7e000,0xfc001f80,0x73801ee,0x7c1c1c,0x38000,0x70000e00,0xe0001, 0xc0003800,0x700383e,0x7c0703c,0x3c078780,0xf0f01e1e,0x3c3c000,0xf0f87,0x70e00e,0x1c01c380,0x38380e07,0xe038,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xc380fff0,0xc0c00380,0x70000,0x70001c00,0x3dbc0070,0x0,0x0,0x701e0f,0xe0000,0x1e000380, 0x6e03800,0x7800000,0x781c0707,0x80e00000,0x0,0x0,0x4038,0xe00c03f,0x700e07,0x4380f0,0x38000700,0x700438,0x3801c00,0x381c0e, 0x1c000ec,0x1b8fc0e0,0xf03c1c03,0xc3c0f0e0,0x3c1e0000,0xe007007,0xe00e380,0xe070703,0xc1e0001e,0xe000e0,0xe001,0xc7000000, 0x0,0x700000,0x38,0x38,0x1c,0x0,0x700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x70000e,0x1c000,0x0,0xe010000,0x0, 0x1c000000,0x10,0x20000,0x6c000,0xf0000000,0x3838000,0x1e0,0x0,0xf000f,0xf1e00,0x78f00000,0x0,0x3,0xdd80000,0x0,0x0,0xf078, 0x0,0xc001,0xe0000000,0x1c1c0038,0x700000,0x3c1e0,0xc0000,0x0,0x783c0,0x606,0x0,0x30000e00,0x0,0xff8c000,0x0,0xc00300c,0x60, 0xc0003,0xe0000000,0x1f8003f,0x7e000,0xfc001f80,0x73801ce,0x70041c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700380f,0x7e07078, 0x1e0f03c1,0xe0783c0f,0x781e000,0x1c0787,0x70e00e,0x1c01c380,0x383c1e07,0xff00e038,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x878, 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, 0x1c7000,0xc301e630,0xc0c00380,0x70000,0xe0000e00,0xff00070,0x0,0x0,0xe01c07,0xe0000,0xe000380,0xce03800,0x7000000,0x701c0707, 0x600000,0x0,0x4000010,0x38,0x1c00e07f,0x80700e0e,0x38070,0x38000700,0xe00038,0x3801c00,0x381c1c,0x1c000ec,0x1b8ec0e0,0xe01c1c01, 0xc38070e0,0x1c1c0000,0xe007007,0x701c380,0xe078e01,0xc1c0003c,0xe00070,0xe003,0x83800000,0x7f,0x71f000,0x3e003e38,0x3f007ff, 0xe01f1c1c,0x7801fc00,0x3fc00701,0xe01c0077,0x8f071e00,0xf801c7c,0x7c700e,0x3e01fc03,0xfff8380e,0xe007700,0x73c0787,0x387ffc, 0x70000e,0x1c000,0x0,0xe000000,0x0,0x1c000000,0x10,0x20000,0xc2000,0xe0000000,0x3838000,0x3c0,0x0,0xf000f,0x78e00,0x70e00000, 0x0,0x3,0xc980fe0,0x1f0,0xf8000007,0xffc07070,0x0,0x3f801,0xc0000000,0x1e3c0038,0x700000,0x70070,0x7fc0000,0x0,0xe00e0,0x606, 0x1c0000,0x70007c00,0x380e,0xff8c000,0x0,0xc00300c,0x60,0xc0000,0x70000000,0x3fc007f,0x800ff001,0xfe003fc0,0x73801ce,0xe0001c, 0x38000,0x70000e00,0xe0001,0xc0003800,0x7003807,0x7607070,0xe0e01c1,0xc0383807,0x700e000,0x1c0387,0x70e00e,0x1c01c380,0x381c1c07, 0xffc0e0f8,0x3f8007f,0xfe001,0xfc003f80,0x7f007e3,0xe003e001,0xf8003f00,0x7e000fc,0xfe001f,0xc003f800,0x7f00003c,0x38f0007, 0xc000f800,0x1f0003e0,0x7c0007,0x8003f0c3,0x80e0701c,0xe0381c0,0x70700387,0x1f01c00e,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c701f,0xfff1c600,0xc0c00380,0x70000,0xe0000e00,0x3c00070,0x0,0x0,0xe03c07, 0x800e0000,0xe000380,0x1ce03800,0x7000000,0x701c0707,0x7003c0,0x780000,0x3c00001e,0x38,0x18006073,0x80700e0e,0x38070,0x38000700, 0xe00038,0x3801c00,0x381c38,0x1c000ee,0x3b8ee0e1,0xe01e1c01,0xc78078e0,0x1c1c0000,0xe007007,0x701c387,0xe03de00,0xe3800038, 0xe00070,0xe007,0x1c00000,0x1ff,0xc077f801,0xff807fb8,0xff807ff,0xe03fdc1d,0xfc01fc00,0x3fc00703,0xc01c007f,0xdf877f00,0x3fe01dfe, 0xff700e,0xff07ff03,0xfff8380e,0x700f700,0x71e0f03,0x80707ffc,0x70000e,0x1c000,0x0,0x1c000008,0x0,0x1c000000,0x10,0x20000, 0x82000,0xe0000000,0x7038000,0x80000380,0x2000040,0x7000e,0x38700,0xf1e00000,0x0,0x3,0xc183ff8,0x3fd,0xfc008007,0xffc038e0, 0x0,0xffc01,0xc0008008,0xe380038,0x380000,0xe3e38,0x1ffc0040,0x80000000,0x1cfc70,0x606,0x1c0000,0xe0007c00,0x380e,0xff8c000, 0x0,0xc00300c,0x8100060,0xc0000,0x30000700,0x39c0073,0x800e7001,0xce0039c0,0x73801ce,0xe0001c,0x38000,0x70000e00,0xe0001, 0xc0003800,0x7003807,0x77070f0,0xf1e01e3,0xc03c7807,0x8f00f080,0x83c0787,0x70e00e,0x1c01c380,0x380e3807,0xffe0e1c0,0xffe01ff, 0xc03ff807,0xff00ffe0,0x1ffc0ff7,0xf01ff807,0xfc00ff80,0x1ff003fe,0xfe001f,0xc003f800,0x7f0003fc,0x3bf801f,0xf003fe00,0x7fc00ff8, 0x1ff0007,0x8007fd83,0x80e0701c,0xe0381c0,0x70380707,0x7f80e01c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x1c,0x1c701f,0xfff1c600,0x618081c0,0x70000,0xe0000e00,0x3c00070,0x0,0x0,0xe03803,0x800e0000,0xe000380,0x18e03800, 0xf000000,0xf01c0707,0x7003c0,0x780000,0xfc00001f,0x80000078,0x301e6073,0x80700e1c,0x38038,0x38000700,0x1c00038,0x3801c00, 0x381c70,0x1c000e6,0x338ee0e1,0xc00e1c01,0xc70038e0,0x1c1c0000,0xe007007,0x701c387,0xe01dc00,0xf7800078,0xe00070,0xe00e,0xe00000, 0x3ff,0xe07ffc03,0xffc0fff8,0x1ffc07ff,0xe07ffc1d,0xfe01fc00,0x3fc00707,0x801c007f,0xdf877f80,0x7ff01fff,0x1fff00e,0xff07ff03, 0xfff8380e,0x700e380,0xe0e0e03,0x80707ffc,0x70000e,0x1c000,0x0,0x7ffc001c,0x0,0x1c000000,0x10,0x20000,0x82000,0xe0000000, 0x7038001,0xc0000780,0x70000e0,0x3800e,0x38700,0xe1c00000,0x0,0x3,0xc183ff8,0x7ff,0xfc01c007,0xffc03de0,0x0,0x1ffc01,0xc001c01c, 0xf780038,0x3c0000,0xcff18,0x380c00c1,0x80000000,0x18fe30,0x30c,0x1c0001,0xc0000e00,0x380e,0xff8c000,0x0,0xc00300c,0xc180060, 0xc0000,0x30000700,0x39c0073,0x800e7001,0xce0039c0,0xe1c038e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x877070e0, 0x71c00e3,0x801c7003,0x8e0071c0,0x1c380fc7,0x70e00e,0x1c01c380,0x380f7807,0x1e0e380,0x1fff03ff,0xe07ffc0f,0xff81fff0,0x3ffe0fff, 0xf03ffc0f,0xfe01ffc0,0x3ff807ff,0xfe001f,0xc003f800,0x7f0007fe,0x3bfc03f,0xf807ff00,0xffe01ffc,0x3ff8007,0x800fff83,0x80e0701c, 0xe0381c0,0x70380707,0xffc0e01c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c701f, 0xfff1c600,0x7f8381e0,0x70000,0xc0000600,0xff00070,0x0,0x0,0x1c03803,0x800e0000,0xe000f00,0x38e03fe0,0xe000000,0xe00e0e07, 0x7003c0,0x780007,0xf0ffff87,0xf00000f0,0x307fe0f3,0xc0703c1c,0x38038,0x38000700,0x1c00038,0x3801c00,0x381ce0,0x1c000e6,0x338e70e1, 0xc00e1c01,0xc70038e0,0x3c1e0000,0xe007007,0x783c38f,0x8e01fc00,0x770000f0,0xe00038,0xe01c,0x700000,0x381,0xe07c1e07,0xc0c1e0f8, 0x3c1e0038,0xf07c1f,0xe001c00,0x1c0070f,0x1c0079,0xf3c7c380,0xf0781f07,0x83c1f00f,0xc10f0300,0x1c00380e,0x700e380,0xe0f1e03, 0xc0f00078,0x70000e,0x1c000,0x0,0xfff8003e,0x0,0x3c000000,0x10,0x20000,0xc6000,0xf0000000,0x7038003,0xe0000f00,0xf8001f0, 0x3801c,0x18300,0xe1800000,0x0,0x3,0xc187818,0x70f,0x9e03e000,0x7801dc0,0x1c,0x3cc401,0xc000efb8,0x7f7f0038,0x3f0000,0x1ce11c, 0x300c01c3,0x80000000,0x38c638,0x3fc,0x1c0003,0x80000600,0x380e,0xff8c000,0x0,0xc00300c,0xe1c0060,0xc0010,0x70000700,0x79e00f3, 0xc01e7803,0xcf0079e0,0xe1c038e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x873870e0,0x71c00e3,0x801c7003, 0x8e0070e0,0x38381dc7,0x70e00e,0x1c01c380,0x38077007,0xf0e700,0x1c0f0381,0xe0703c0e,0x781c0f0,0x381e083e,0x787c0c1e,0xf03c1e0, 0x783c0f07,0x800e0001,0xc0003800,0x7000fff,0x3e1c078,0x3c0f0781,0xe0f03c1e,0x783c000,0x1e0f03,0x80e0701c,0xe0381c0,0x70380f07, 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, 0xc0000700,0x3dbc0070,0x0,0x0,0x1c03803,0x800e0000,0x1e01fe00,0x70e03ff8,0xe3e0001,0xe007fc07,0x80f003c0,0x78001f,0xc0ffff81, 0xfc0001e0,0x30e1e0e1,0xc07ff81c,0x38038,0x3ffe07ff,0xc1c0003f,0xff801c00,0x381de0,0x1c000e7,0x738e70e1,0xc00e1c03,0xc70038e0, 0x780f8000,0xe007007,0x383838d,0x8e00f800,0x7f0000e0,0xe00038,0xe000,0x0,0x200,0xf0780e07,0x8041c078,0x380e0038,0xe03c1e, 0xf001c00,0x1c0071e,0x1c0070,0xe1c783c0,0xe0381e03,0x8380f00f,0xe0000,0x1c00380e,0x381c380,0xe07bc01,0xc0e00078,0x70000e, 0x1c000,0x0,0x1c000061,0x0,0x38000000,0x10,0x20000,0x7c000,0x7c000000,0x703fc06,0x10000e00,0x18400308,0x1801c,0x1c381,0xc3800000, 0x0,0x0,0x7000,0xe0f,0xe061000,0x7801fc0,0x1c,0x38c001,0xc0007ff0,0x7fff0038,0x77c000,0x19c00c,0x301c0387,0x0,0x30c618,0xf0, 0x1c0007,0x600,0x380e,0x7f8c007,0x80000000,0xc001818,0x70e03fc,0x387f871f,0xe0e00700,0x70e00e1,0xc01c3803,0x870070e0,0xe1c038f, 0xe1c0001f,0xff03ffe0,0x7ffc0fff,0x800e0001,0xc0003800,0x7003803,0x873870e0,0x71c00e3,0x801c7003,0x8e007070,0x703839c7,0x70e00e, 0x1c01c380,0x3807f007,0x70e700,0x10078200,0xf0401e08,0x3c10078,0x200f001c,0x3878041c,0x70380e0,0x701c0e03,0x800e0001,0xc0003800, 0x7001e0f,0x3c1e070,0x1c0e0381,0xc070380e,0x701c000,0x1c0f03,0x80e0701c,0xe0381c0,0x701c0e07,0x80e07038,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0x8600e600,0x7803f0,0x1,0xc0000700,0x718e0070,0x0,0x0,0x38038c3, 0x800e0000,0x3c01f800,0x60e03ffc,0xeff8001,0xc001f003,0xc1f003c0,0x7800fe,0xffff80,0x3f8003c0,0x60c0e0e1,0xc07fe01c,0x38038, 0x3ffe07ff,0xc1c07e3f,0xff801c00,0x381fe0,0x1c000e3,0x638e30e1,0xc00e1c07,0x870038ff,0xf00ff800,0xe007007,0x38381cd,0x9c007000, 0x3e0001e0,0xe0001c,0xe000,0x0,0x0,0x70780f0f,0x3c078,0x70070038,0x1e03c1c,0x7001c00,0x1c0073c,0x1c0070,0xe1c701c1,0xe03c1e03, 0xc780f00f,0xe0000,0x1c00380e,0x381c387,0xe03f801,0xc0e000f0,0x70000e,0x1c007,0xe0100000,0x1c0000cd,0x80000003,0xffc00000, 0x3ff,0x807ff000,0xe0,0x7fc00060,0x703fc0c,0xd8001e00,0x3360066c,0x1c018,0xc181,0x83000000,0x0,0x0,0x7000,0x300e07,0xe0cd800, 0xf000f80,0x1c,0x78c00f,0xff0038e0,0x3e00038,0xe1e000,0x19800c,0x383c070e,0x7fffc00,0x30fc18,0x0,0xffff80e,0x20e00,0x380e, 0x7f8c007,0x80000000,0xc001c38,0x38703ff,0xf87fff0f,0xcfe00f00,0x70e00e1,0xc01c3803,0x870070e0,0x1e1e078f,0xe1c0001f,0xff03ffe0, 0x7ffc0fff,0x800e0001,0xc0003800,0x700ff83,0x871870e0,0x71c00e3,0x801c7003,0x8e007038,0xe03871c7,0x70e00e,0x1c01c380,0x3803e007, 0x70e700,0x38000,0x70000e00,0x1c00038,0x7001c,0x38f00038,0x3870070,0xe00e1c01,0xc00e0001,0xc0003800,0x7001c07,0x380e0f0,0x1e1e03c3, 0xc078780f,0xf01e000,0x3c0f03,0x80e0701c,0xe0381c0,0x701c0e07,0x80f07038,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0x8600ff00,0x1e00778,0x38000001,0xc0000700,0x21843fff,0xe0000000,0x0,0x38039e3,0x800e0000, 0x7c01fe00,0xe0e0203e,0xeffc001,0xc00ffe03,0xff700000,0x7f0,0x0,0x7f00380,0x618060e1,0xc07ffc1c,0x38038,0x3ffe07ff,0xc1c07e3f, 0xff801c00,0x381ff0,0x1c000e3,0x638e38e1,0xc00e1fff,0x870038ff,0xc003fe00,0xe007007,0x38381cd,0x9c00f800,0x3e0003c0,0xe0001c, 0xe000,0x0,0x0,0x7070070e,0x38038,0x70070038,0x1c01c1c,0x7001c00,0x1c00778,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0xfc000, 0x1c00380e,0x381c3c7,0x1e01f001,0xe1e001e0,0xf0000e,0x1e01f,0xf8300000,0x1c00019c,0xc0000003,0xffc00000,0x10,0x20000,0x700, 0x1ff000c0,0x703fc19,0xcc003c00,0x67300ce6,0xc038,0xc181,0x83000000,0x0,0x0,0x7e00,0x180e07,0xe19cc00,0x1e000f80,0x1c,0x70c00f, 0xff007070,0x3e00038,0xe0f000,0x19800c,0x1fec0e1c,0x7fffc00,0x30f818,0x0,0xffff81f,0xf003fc00,0x380e,0x3f8c007,0x80000000, 0x7f800ff0,0x1c3803f,0xe007fc00,0xff800e00,0x70e00e1,0xc01c3803,0x870070e0,0x1c0e070f,0xe1c0001f,0xff03ffe0,0x7ffc0fff,0x800e0001, 0xc0003800,0x700ff83,0x871c70e0,0x71c00e3,0x801c7003,0x8e00701d,0xc038e1c7,0x70e00e,0x1c01c380,0x3803e007,0x70e3c0,0x38000, 0x70000e00,0x1c00038,0x7001c,0x38e00038,0x3870070,0xe00e1c01,0xc00e0001,0xc0003800,0x7003c07,0x8380e0e0,0xe1c01c3,0x80387007, 0xe00e1ff,0xfe381b83,0x80e0701c,0xe0381c0,0x701e1e07,0x707878,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x1c,0x3,0xe007fe0,0x7800e3c,0x38000001,0xc0000700,0x1803fff,0xe0000000,0x0,0x70039c3,0x800e0000,0xf8000f80, 0xc0e0000e,0xf83c003,0xc01e0f01,0xff700000,0x7c0,0x0,0x1f00780,0x618061c0,0xe0701e1c,0x38038,0x38000700,0x1c07e38,0x3801c00, 0x381e78,0x1c000e3,0xe38e18e1,0xc00e1fff,0x70038ff,0xe0007f80,0xe007007,0x1c701dd,0x9c00f800,0x1c000780,0xe0000e,0xe000,0x0, 0x7f,0xf070070e,0x38038,0x7fff0038,0x1c01c1c,0x7001c00,0x1c007f8,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x7fc00,0x1c00380e, 0x1c381c7,0x1c01f000,0xe1c001c0,0xfe0000e,0xfe1f,0xfff00000,0x7ff003fc,0xe0000003,0xffc00000,0x10,0x20000,0x3800,0x3fc0180, 0x703803f,0xce007800,0xff381fe7,0x30,0x0,0xc0,0x0,0x0,0x3fe0,0xc0e07,0xfe3fce00,0x1c000700,0x1c,0x70c00f,0xff006030,0x1c00000, 0xe07800,0x19800c,0xfcc1c38,0x7fffc00,0x30d818,0x0,0xffff81f,0xf001f800,0x380e,0xf8c007,0x80000000,0x7f8007e0,0xe1c3fe,0x7fc00f, 0xf8001e00,0xe0701c0,0xe0381c07,0x380e070,0x1c0e070e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700ff83,0x870c70e0, 0x71c00e3,0x801c7003,0x8e00700f,0x8038c1c7,0x70e00e,0x1c01c380,0x3801c007,0xf0e3e0,0x3ff807f,0xf00ffe01,0xffc03ff8,0x7ff03ff, 0xf8e0003f,0xff87fff0,0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e1ff,0xfe383383,0x80e0701c, 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, 0x3c1e1c1c,0x38000001,0xc0000700,0x1803fff,0xe0000007,0xf8000000,0x7003803,0x800e0001,0xf0000381,0xc0e00007,0xf01e003,0x801c0700, 0x7c700000,0x7c0,0x0,0x1f00700,0x618061c0,0xe0700e1c,0x38038,0x38000700,0x1c00e38,0x3801c00,0x381e38,0x1c000e1,0xc38e1ce1, 0xc00e1ffc,0x70038e0,0xf0000780,0xe007007,0x1c701dd,0xdc01fc00,0x1c000780,0xe0000e,0xe000,0x0,0x1ff,0xf070070e,0x38038,0x7fff0038, 0x1c01c1c,0x7001c00,0x1c007f8,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x3ff00,0x1c00380e,0x1c381cd,0x9c00e000,0xe1c003c0, 0xf80000e,0x3e18,0x3ff00000,0xffe007fd,0xf0000000,0x38000000,0x10,0x20000,0x1c000,0x3c0300,0x703807f,0xdf007801,0xff7c3fef, 0x80000000,0x0,0x3e0,0x7ffe7ff,0xff000000,0x1ff8,0x60e07,0xfe7fdf00,0x3c000700,0x1c,0x70c001,0xc0006030,0x7fff0000,0xf03800, 0x19800c,0x1c38,0x1c07,0xf830cc18,0x0,0x1c0000,0x0,0x380e,0x18c007,0x80000000,0x0,0xe1cfe0,0x1fc003f,0x80003c00,0xe0701c0, 0xe0381c07,0x380e070,0x1c0e070e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x870e70e0,0x71c00e3,0x801c7003, 0x8e007007,0x3981c7,0x70e00e,0x1c01c380,0x3801c007,0x1e0e0f8,0xfff81ff,0xf03ffe07,0xffc0fff8,0x1fff07ff,0xf8e0003f,0xff87fff0, 0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e1ff,0xfe386383,0x80e0701c,0xe0381c0,0x700e1c07, 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, 0xc0000700,0x70,0x7,0xf8000000,0xe003803,0x800e0003,0xe00001c3,0x80e00007,0xe00e007,0x80380380,0x700000,0x7f0,0x0,0x7f00700, 0x618061ff,0xe070071c,0x38038,0x38000700,0x1c00e38,0x3801c00,0x381c3c,0x1c000e1,0xc38e1ce1,0xc00e1c00,0x70038e0,0x700003c0, 0xe007007,0x1c701d8,0xdc03dc00,0x1c000f00,0xe00007,0xe000,0x0,0x3ff,0xf070070e,0x38038,0x7fff0038,0x1c01c1c,0x7001c00,0x1c007fc, 0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x3f00,0x1c00380e,0x1c381cd,0x9c01f000,0x73800780,0xfe0000e,0xfe10,0x7c00000,0x1c000ffb, 0xf8000000,0x38000000,0x10,0x20000,0x20000,0x1e0700,0x70380ff,0xbf80f003,0xfefe7fdf,0xc0000000,0x0,0x3f0,0x7ffe7ff,0xff000000, 0x1f8,0x30e07,0xfeffbf80,0x78000700,0x1c,0x70c001,0xc0006030,0x7fff0000,0x783800,0x1ce11c,0xe1c,0x1c07,0xf838ce38,0x0,0x1c0000, 0x0,0x380e,0x18c000,0x0,0x0,0x1c38c00,0x1800030,0x7800,0xfff01ff,0xe03ffc07,0xff80fff0,0x3fff0ffe,0x1c0001c,0x38000,0x70000e00, 0xe0001,0xc0003800,0x7003803,0x870e70e0,0x71c00e3,0x801c7003,0x8e00700f,0x803b81c7,0x70e00e,0x1c01c380,0x3801c007,0xffe0e03c, 0x1fff83ff,0xf07ffe0f,0xffc1fff8,0x3fff0fff,0xf8e0003f,0xff87fff0,0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3, 0x80387007,0xe00e000,0x38c383,0x80e0701c,0xe0381c0,0x70073807,0x701ce0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f,0xffc0063c,0x40619c0f,0x30000001,0xc0000700,0x70,0x7,0xf8000000,0xe003803,0x800e0007,0xc00001c3, 0xfffc0007,0xe00e007,0x380380,0xf00000,0xfe,0xffff80,0x3f800700,0x618063ff,0xf070071c,0x38038,0x38000700,0x1c00e38,0x3801c00, 0x381c1e,0x1c000e0,0x38e0ee1,0xc00e1c00,0x70038e0,0x380001c0,0xe007007,0x1ef01d8,0xdc038e00,0x1c001e00,0xe00007,0xe000,0x0, 0x7c0,0x7070070e,0x38038,0x70000038,0x1c01c1c,0x7001c00,0x1c0079e,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x780,0x1c00380e, 0xe701cd,0x9c01f000,0x73800f00,0xe0000e,0xe000,0x0,0x1c0007f7,0xf0000000,0x70000000,0x10,0x20000,0x0,0xe0e00,0x703807f,0x7f01e001, 0xfdfc3fbf,0x80000000,0x0,0x7f0,0x0,0x0,0x3c,0x18e07,0x7f7f00,0xf0000700,0x1c,0x70c001,0xc0007070,0x1c00000,0x3e7000,0xcff18, 0x3ffc070e,0x1c07,0xf818c630,0x0,0x1c0000,0x0,0x380e,0x18c000,0x0,0x3ffc,0x3870000,0xe000fc00,0x380f000,0x1fff83ff,0xf07ffe0f, 0xffc1fff8,0x3fff0ffe,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x870770e0,0x71c00e3,0x801c7003,0x8e00701d, 0xc03f01c7,0x70e00e,0x1c01c380,0x3801c007,0xffc0e01c,0x3e0387c0,0x70f80e1f,0x1c3e038,0x7c071e1c,0xe00038,0x70000,0xe0001c00, 0xe0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e000,0x398383,0x80e0701c,0xe0381c0,0x70073807,0x701ce0, 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, 0x70,0x0,0x0,0x1c003c07,0x800e000f,0x1c3,0xfffc0007,0xe00e007,0x380380,0xe00000,0x1f,0xc0ffff81,0xfc000700,0x618063ff,0xf070070e, 0x38070,0x38000700,0xe00e38,0x3801c00,0x381c0e,0x1c000e0,0x38e0ee1,0xe01e1c00,0x78078e0,0x380001c0,0xe007007,0xee01f8,0xfc078f00, 0x1c001c00,0xe00003,0x8000e000,0x0,0x700,0x7070070e,0x38038,0x70000038,0x1c01c1c,0x7001c00,0x1c0070e,0x1c0070,0xe1c701c1, 0xc01c1c01,0xc700700e,0x380,0x1c00380e,0xe700ed,0xb803f800,0x77800f00,0x70000e,0x1c000,0x0,0xe0003f7,0xe0000000,0x70000000, 0x10,0x20000,0x1c0e0,0xe1c00,0x703803f,0x7e01c000,0xfdf81fbf,0x0,0x0,0x3f0,0x0,0x0,0x1c,0x1ce07,0x3f7e00,0xf0000700,0x1c, 0x70c001,0xc00038e0,0x1c00038,0xf7000,0xe3e38,0x3ffc0387,0x1c00,0x1cc770,0x0,0x1c0000,0x0,0x380e,0x18c000,0x0,0x3ffc,0x70e0001, 0xe001fe00,0x780e000,0x1fff83ff,0xf07ffe0f,0xffc1fff8,0x3fff0ffe,0xe0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003807, 0x70770f0,0xf1e01e3,0xc03c7807,0x8f00f038,0xe03e03c7,0x70e00e,0x1c01c380,0x3801c007,0xff00e00e,0x38038700,0x70e00e1c,0x1c38038, 0x70071c1c,0xe00038,0x70000,0xe0001c00,0xe0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e000,0x3b0383,0x80e0701c, 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, 0xc0de03,0xe0000001,0xc0000700,0x70,0x0,0x0,0x1c001c07,0xe001e,0x1c3,0xfffc0007,0x600e00e,0x380380,0xe00000,0x7,0xf0ffff87, 0xf0000000,0x60c0e380,0x7070070e,0x38070,0x38000700,0xe00e38,0x3801c00,0x381c0f,0x1c000e0,0x38e06e0,0xe01c1c00,0x38070e0, 0x1c0001c0,0xe007007,0xee00f8,0xf80f0700,0x1c003c00,0xe00003,0x8000e000,0x0,0x700,0x70780f0f,0x3c078,0x70000038,0x1e03c1c, 0x7001c00,0x1c0070f,0x1c0070,0xe1c701c1,0xe03c1e03,0xc780f00e,0x380,0x1c00380e,0xe700f8,0xf807bc00,0x3f001e00,0x70000e,0x1c000, 0x0,0xe0001ff,0xc0000000,0x70000000,0x10,0x20000,0x33110,0xe0e00,0x383801f,0xfc03c000,0x7ff00ffe,0x0,0x0,0x3e0,0x0,0x0,0x1c, 0x38e07,0x1ffc01,0xe0000700,0x1c,0x78c001,0xc0007ff0,0x1c00038,0x7c000,0x70070,0x1c3,0x80001c00,0xe00e0,0x0,0x1c0000,0x0, 0x380e,0x18c000,0x0,0x0,0xe1c0001,0xe0010700,0x780e000,0x1c038380,0x70700e0e,0x1c1c038,0x78070e0e,0xe0001c,0x38000,0x70000e00, 0xe0001,0xc0003800,0x7003807,0x7037070,0xe0e01c1,0xc0383807,0x700e070,0x701c0387,0x70e00e,0x1c01c380,0x3801c007,0xe00e,0x38038700, 0x70e00e1c,0x1c38038,0x70071c1c,0xf00038,0x70000,0xe0001c00,0xe0001,0xc0003800,0x7003c07,0x8380e0f0,0x1e1e03c3,0xc078780f, 0xf01e007,0x803e0783,0x80e0701c,0xe0381c0,0x7003f007,0x80f00fc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x6,0x1800061c,0xc0de01,0xc0000000,0xc0000e00,0x70,0xf0000,0x3c00,0x38001c0f,0xe003c,0x3c0,0xe0000e,0x701e00e, 0x3c0780,0x1e003c0,0x780000,0xfc00001f,0x80000000,0x60e1e780,0x78700f07,0x4380f0,0x38000700,0xf00e38,0x3801c00,0xc0781c07, 0x81c000e0,0x38e07e0,0xe03c1c00,0x380f0e0,0x1e0003c0,0xe00780f,0xee00f0,0x780e0780,0x1c007800,0xe00001,0xc000e000,0x0,0x700, 0xf0780e07,0x8041c078,0x38020038,0xe03c1c,0x7001c00,0x1c00707,0x801c0070,0xe1c701c0,0xe0381e03,0x8380f00e,0x80380,0x1c003c1e, 0x7e00f8,0xf80f1e00,0x3f003c00,0x70000e,0x1c000,0x0,0xf0100f7,0x80078000,0x700078f0,0x10,0x7ff000,0x61208,0x1e0700,0x383800f, 0x78078000,0x3de007bc,0x0,0x0,0x0,0x0,0x0,0x401c,0x70e0f,0xf7803,0xc0000700,0x1c,0x38c001,0xc000efb8,0x1c00038,0x1e000,0x3c1e0, 0xc1,0x80000000,0x783c0,0x0,0x0,0x0,0x3c1e,0x18c000,0x0,0x0,0xc180003,0x60000300,0xd80e010,0x3c03c780,0x78f00f1e,0x1e3c03c, 0x70039c0e,0x70041c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700380f,0x703f070,0x1e0e03c1,0xc078380f,0x701e0e0,0x381c0787, 0x80f0f01e,0x1e03c3c0,0x7801c007,0xe00e,0x38078700,0xf0e01e1c,0x3c38078,0x700f1c1c,0x78041c,0x1038020,0x70040e00,0x800e0001, 0xc0003800,0x7001c07,0x380e070,0x1c0e0381,0xc070380e,0x701c007,0x801e0703,0xc1e0783c,0xf0781e0,0xf003f007,0x80e00fc0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xe,0x1801867c,0xc0cf83,0xe0000000,0xe0000e00, 0x70,0xf0000,0x3c00,0x38000f1e,0xe0070,0x180780,0xe0603e,0x783c01e,0x1e0f01,0x7c003c0,0x780000,0x3c00001e,0x700,0x307fe700, 0x38701e07,0xc1c383e0,0x38000700,0x7c1e38,0x3801c00,0xe0f01c03,0x81c000e0,0x38e03e0,0x78781c00,0x1e1e0e0,0xe180780,0xe003c1e, 0x7c00f0,0x781e03c0,0x1c007000,0xe00001,0xc000e000,0x0,0x783,0xf07c1e07,0xc0c1e0f8,0x3e0e0038,0xf07c1c,0x7001c00,0x1c00703, 0xc01e0070,0xe1c701c0,0xf0781f07,0x83c1f00e,0xe0f80,0x1e003c3e,0x7e00f8,0xf80e0e00,0x3f003800,0x70000e,0x1c000,0x0,0x7830077, 0xf0000,0x700078f0,0x10,0x20000,0x41208,0xc03c0380,0x3c38007,0x70070000,0x1dc003b8,0x0,0x0,0x0,0x0,0x0,0x707c,0x6070f,0x86077003, 0x80000700,0x1c,0x3ec401,0xc001c01c,0x1c00038,0xf000,0x1ffc0,0x40,0x80000000,0x3ff80,0x0,0x0,0x0,0x3e3e,0x18c000,0x0,0x0, 0x8100006,0x60000300,0x1980f070,0x3801c700,0x38e0071c,0xe3801c,0x70039c0e,0x7c1c1c,0x38000,0x70000e00,0xe0001,0xc0003800, 0x700383e,0x701f03c,0x3c078780,0xf0f01e1e,0x3c3c1c0,0x1c3f0f03,0xc1e0783c,0xf0781e0,0xf001c007,0xe81e,0x3c1f8783,0xf0f07e1e, 0xfc3c1f8,0x783f1e3e,0x187c0c1f,0x703e0e0,0x7c1c0f83,0x800e0001,0xc0003800,0x7001e0f,0x380e078,0x3c0f0781,0xe0f03c1e,0x783c007, 0x801e0f03,0xc3e0787c,0xf0f81e1,0xf003f007,0xc1e00fc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x1c,0xe,0x3801fff8,0x6187ff,0xe0000000,0xe0000e00,0x70,0xf0000,0x3c00,0x38000ffe,0x1fff0ff,0xfe1fff80,0xe07ffc,0x3ffc01c, 0x1fff01,0xff8003c0,0x780000,0x4000010,0x700,0x301e6700,0x387ffe03,0xffc3ffc0,0x3fff0700,0x3ffe38,0x383ffe0,0xfff01c03,0xc1fff8e0, 0x38e03e0,0x7ff81c00,0x1ffe0e0,0xf1fff80,0xe003ffe,0x7c00f0,0x781c01c0,0x1c00ffff,0xe00001,0xc000e000,0x0,0x3ff,0x707ffc03, 0xffc0fff8,0x1ffe0038,0x7ffc1c,0x707fff0,0x1c00701,0xc00ff070,0xe1c701c0,0x7ff01fff,0x1fff00e,0xfff00,0xff81fee,0x7e00f0, 0x781e0f00,0x1e007ffc,0x70000e,0x1c000,0x0,0x3ff003e,0xf0000,0xe00070e0,0x60830010,0x20000,0x41208,0xfffc01c0,0x1fffe03,0xe00ffff0, 0xf8001f0,0x0,0x0,0x0,0x0,0x0,0x7ff8,0xc07fd,0xfe03e007,0xffc00700,0x1c,0x1ffc1f,0xffc08008,0x1c00038,0x7000,0x7f00,0x0,0x0, 0xfe00,0x0,0xffff800,0x0,0x3ff7,0x8018c000,0x0,0x0,0x6,0x60000700,0x19807ff0,0x3801c700,0x38e0071c,0xe3801c,0x70039c0f,0xf03ffc1f, 0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ffc,0x701f03f,0xfc07ff80,0xfff01ffe,0x3ffc080,0x83fff03,0xffe07ffc,0xfff81ff, 0xf001c007,0xeffc,0x1ffb83ff,0x707fee0f,0xfdc1ffb8,0x3ff70ff7,0xf83ffc0f,0xff01ffe0,0x3ffc07ff,0x83fff87f,0xff0fffe1,0xfffc0ffe, 0x380e03f,0xf807ff00,0xffe01ffc,0x3ff8007,0x803ffe01,0xfee03fdc,0x7fb80ff,0x7001e007,0xffc00780,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xc,0x3801fff0,0x7f83fe,0x70000000,0xe0000e00,0x0,0xf0000,0x3c00,0x700007fc, 0x1fff0ff,0xfe1ffe00,0xe07ff8,0x1ff801c,0xffe01,0xff0003c0,0x780000,0x0,0x700,0x38000f00,0x3c7ffc01,0xff83ff80,0x3fff0700, 0x1ffc38,0x383ffe0,0x7fe01c01,0xe1fff8e0,0x38e03e0,0x3ff01c00,0xffc0e0,0x71fff00,0xe001ffc,0x7c00f0,0x783c01e0,0x1c00ffff, 0xe00000,0xe000e000,0x0,0x1ff,0x7077f801,0xff807fb8,0xffc0038,0x3fdc1c,0x707fff0,0x1c00701,0xe007f070,0xe1c701c0,0x3fe01dfe, 0xff700e,0x7fe00,0xff80fee,0x3c0070,0x703c0780,0x1e007ffc,0x70000e,0x1c000,0x0,0x1fe001c,0xe0000,0xe000e1c0,0x71c78010,0x20000, 0x21318,0xfff800c0,0xfffe01,0xc00ffff0,0x70000e0,0x0,0x0,0x0,0x0,0x0,0x3ff0,0x1803fd,0xfe01c007,0xffc00700,0x1c,0xffc1f,0xffc00000, 0x1c00038,0x7000,0x0,0x0,0x0,0x0,0x0,0xffff800,0x0,0x3ff7,0x8018c000,0x0,0x0,0xc,0x60000e00,0x31803fe0,0x7801ef00,0x3de007bc, 0xf7801e,0xf003fc0f,0xf01ff81f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ff8,0x701f01f,0xf803ff00,0x7fe00ffc,0x1ff8000, 0x67fe01,0xffc03ff8,0x7ff00ff,0xe001c007,0xeff8,0xffb81ff,0x703fee07,0xfdc0ffb8,0x1ff70ff7,0xf81ff807,0xfe00ffc0,0x1ff803ff, 0x3fff87f,0xff0fffe1,0xfffc07fc,0x380e01f,0xf003fe00,0x7fc00ff8,0x1ff0000,0x37fc00,0xfee01fdc,0x3fb807f,0x7001e007,0x7f800780, 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, 0x0,0xe0000,0x3c00,0x700001f0,0x1fff0ff,0xfe07f800,0xe01fe0,0x7e0038,0x3f800,0xfc0003c0,0x700000,0x0,0x700,0x18000e00,0x1c7ff000, 0x7e03fe00,0x3fff0700,0x7f038,0x383ffe0,0x1f801c00,0xf1fff8e0,0x38e01e0,0xfc01c00,0x3f80e0,0x787fc00,0xe0007f0,0x7c00f0,0x387800f0, 0x1c00ffff,0xe00000,0xe000e000,0x0,0xfc,0x7071f000,0x3f003e38,0x3f00038,0x1f1c1c,0x707fff0,0x1c00700,0xf003f070,0xe1c701c0, 0x1f801c7c,0x7c700e,0x1f800,0x3f8078e,0x3c0070,0x707803c0,0x1c007ffc,0x70000e,0x1c000,0x0,0x7c0008,0x1e0000,0xe000e1c0,0x71c30010, 0x20000,0x1e1f0,0x3fe00020,0x3ffe00,0x800ffff0,0x2000040,0x0,0x0,0x0,0x0,0x0,0xfc0,0x3001f0,0x78008007,0xffc00700,0x1c,0x3f81f, 0xffc00000,0x1c00038,0x407000,0x0,0x0,0x0,0x0,0x0,0xffff800,0x0,0x39c7,0x18c000,0x0,0x0,0x18,0x60001c00,0x61801f80,0x7000ee00, 0x1dc003b8,0x77000e,0xe001f80f,0xf007e01f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83fc0,0x700f007,0xe000fc00,0x1f8003f0, 0x7e0000,0xe1f800,0x7f000fe0,0x1fc003f,0x8001c007,0xe7f0,0x7e380fc,0x701f8e03,0xf1c07e38,0xfc703c1,0xe003f001,0xf8003f00, 0x7e000fc,0x3fff87f,0xff0fffe1,0xfffc03f8,0x380e00f,0xc001f800,0x3f0007e0,0xfc0000,0x61f800,0x78e00f1c,0x1e3803c,0x7001c007, 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, 0x1c0000,0x0,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0, 0x0,0x0,0x0,0x0,0xe00000,0x7000e000,0x0,0x0,0x0,0x0,0x0,0x1c00,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x1c000000, 0x70000e,0x1c000,0x0,0x0,0x1c0000,0xe000c180,0x10,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000, 0x0,0x38,0x70e000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x2000,0x0,0x1f,0xf8003800,0x7fe00000,0x0,0x0,0x0,0x0,0x4000, 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, 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, 0x0,0x1c0000,0x0,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0xe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e000, 0x0,0x0,0x0,0x0,0x0,0xe00000,0x7000e000,0x0,0x0,0x0,0x0,0x0,0x1c00,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x1c000000, 0x70000e,0x1c000,0x0,0x0,0x1c0001,0xe001c380,0x10,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000, 0x0,0x38,0x7fe000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x3000,0x0,0x1f,0xf8007000,0x7fe00000,0x0,0x0,0x0,0x0,0x6000, 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, 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, 0x0,0x380000,0x1,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00000,0x0,0x0,0x3c18000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf000, 0x0,0x0,0x0,0x0,0x0,0xfe0000,0x380fe000,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x38000000, 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, 0x38,0x1f8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x1800,0x0,0x0,0x6000e000,0x1800000,0x0,0x0,0x0,0x0,0x3000,0x0, 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, 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, 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, 0x0,0x0,0x0,0xfe0000,0xfe000,0x0,0x0,0x0,0x0,0x0,0x607800,0x0,0x3c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x78000000, 0x3f800e,0x3f8000,0x0,0x0,0x300043,0xc0018200,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000, 0x0,0x38,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x11800,0x0,0x0,0x6001ff00,0x1800000,0x0,0x0,0x0,0x0,0x23000,0x0,0x0, 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, 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, 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, 0xfe000,0x0,0x0,0x0,0x0,0x0,0x7ff000,0x0,0x7f800000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xf8000000,0x3f800e,0x3f8000,0x0, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x7f000000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xf0000000,0xf800e,0x3e0000,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x1fc000,0x0,0x7e000000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xc0000000,0xe,0x0, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 }; const unsigned int font29x57[29*57*256/32] = { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 0xc0000000,0x0,0x7c00,0xf80,0x7e000,0x0,0x7c00000,0xf80000,0x7e000000,0x0,0x0,0x1f00,0x3e0,0x1f800,0x0,0x0,0x0,0x3,0xe0000000, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,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, 0x1f0000,0x7e00000,0xf838001f,0xf80001f,0xf0000000,0x0,0x3e00,0x1f00,0x7e000,0x3e1f000,0x3e00000,0x1f00000,0x7e00003e,0x1f000000, 0x3e0,0xe0000f80,0x7c0,0x1f800,0x3e0e00,0x7c3e000,0x0,0x1,0xf0000000,0xf800003f,0x1f0f,0x800001f0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0000,0x1e0000,0xff00001,0xfe38001f,0xf80003f, 0xf8000000,0x0,0x1e00,0x1e00,0xff000,0x3e1f000,0x1e00000,0x1e00000,0xff00003e,0x1f000000,0x7f8,0xe0000780,0x780,0x3fc00,0x7f8e00, 0x7c3e000,0x0,0x0,0xf0000000,0xf000007f,0x80001f0f,0x800001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000,0x3c0000,0x1e780003,0xfff8001f,0xf80003c,0x78000000,0x0,0xf00,0x3c00,0x1e7800, 0x3e1f000,0xf00000,0x3c00001,0xe780003e,0x1f000000,0xfff,0xe00003c0,0xf00,0x79e00,0xfffe00,0x7c3e000,0x0,0x0,0x78000001,0xe00000f3, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 0x0,0x78000,0x780000,0x3c3c0003,0x8ff0001f,0xf800078,0x3c000000,0x0,0x780,0x7800,0x3c3c00,0x3e1f000,0x780000,0x7800003,0xc3c0003e, 0x1f000000,0xe3f,0xc00001e0,0x1e00,0xf0f00,0xe3fc00,0x7c3e000,0x0,0x0,0x3c000003,0xc00001e1,0xe0001f0f,0x80000780,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,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,0xfc00,0x7e000,0xfe000,0x0,0x3c000,0xf00000,0x781e0003, 0x83e0001f,0xf800070,0x1c000000,0x0,0x3c0,0xf000,0x781e00,0x3e1f000,0x3c0000,0xf000007,0x81e0003e,0x1f000000,0xe0f,0x800000f0, 0x3c00,0x1e0780,0xe0f800,0x7c3e000,0x0,0x0,0x1e000007,0x800003c0,0xf0001f0f,0x80000f00,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf8000000, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00000,0x3e000,0x3e00000,0x0,0x78,0x3c000000,0x0,0x1f000,0x3e0, 0x3e000,0x0,0x1f000000,0x3e0000,0x3e000000,0x0,0x0,0x7c00,0xf8,0xf800,0x0,0x0,0x0,0xf,0x80000000,0x1f00001f,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,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x781c0000,0x38,0xe000000,0x0,0x0,0x380e0,0x0, 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, 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, 0x0,0x0,0xf80000,0x7c000,0x3e00000,0xf0380000,0x70,0x1c000000,0x0,0xf800,0x7c0,0x3e000,0x0,0xf800000,0x7c0000,0x3e000000, 0x0,0x3c0,0xe0003e00,0x1f0,0xf800,0x3c0e00,0x0,0x0,0x7,0xc0000000,0x3e00001f,0x0,0x7c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,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, 0xf8,0xf8000,0x1c000,0x0,0x0,0x0,0x0,0x1f,0xc0000000,0x1ff8,0xff00,0x0,0x0,0x3fe000,0x0,0x1fc00001,0xfe000000,0x0,0x0,0x0, 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, 0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x780000,0x1,0xe0000000,0x0,0x780000,0x3,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000, 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, 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, 0x0,0x0,0x1ff,0x1f0f8,0x0,0xff000,0x0,0x0,0x0,0x3f,0xff00000f,0x80000000,0xfe0,0x3f80,0xf00,0x0,0x0,0x0,0x1,0xf8000003,0xe0000000, 0x1c00,0xe000,0xe00,0x0,0x0,0x0,0x0,0x0,0x3c,0x78000000,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000, 0x7f0000,0x0,0x1fc07000,0x0,0x0,0x0,0x0,0x0,0x3f800,0x780000,0x78000,0x7f00001,0xfc38001f,0xf800070,0x1c000000,0x0,0x7800, 0x780,0x7f000,0x3e1f000,0x7800000,0x780000,0x7f00003e,0x1f0003f0,0x7f0,0xe0001e00,0x1e0,0x1fc00,0x7f0e00,0x7c3e000,0x0,0x3, 0xc0000000,0x3c00003f,0x80001f0f,0x80000078,0x1e0000,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,0x0,0x0,0x780000,0x3c1e0000,0x1e078000,0x30000000,0x3ff,0xc00001e0,0xf0, 0x78000,0x1c000,0x0,0x0,0x0,0x0,0x1e0007f,0xf000007e,0x1ffff,0x7ffe0,0x1f80,0x3ffff80,0xfff803,0xfffff800,0xfff80007,0xff800000, 0x0,0x0,0x0,0x0,0x1ffe00,0x0,0xfe0003,0xfff80000,0x3ffe01ff,0xe00003ff,0xffe01fff,0xff0003ff,0xe01e0007,0x803ffff0,0xfff80, 0x3c000fc0,0x7800001f,0x8003f07e,0x1e000f,0xfe0007ff,0xf00003ff,0x8007ffe0,0x1fff8,0x7fffffe,0xf0003c1,0xe000079e,0xf1f,0x1f3e0, 0x1f01ff,0xfff8003f,0xf003c000,0x7fe0,0x3f00,0x0,0x3c0000,0x1,0xe0000000,0x0,0x780000,0xf,0xfe000000,0x78000,0x3c00,0xf000, 0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xfc0000f0,0x3fe00,0x0,0x0,0xfff00,0x0,0x0,0x3fe000, 0x0,0x0,0x0,0x1dc0,0x0,0x3fff00,0x0,0x3ffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff1c07ff,0x3c0f001e,0x3c000000, 0x0,0x0,0x1e3c0,0xf80007c,0x0,0x780000,0x0,0xfff8000,0x3e00,0x1f00000,0x7ff,0xc001f0f8,0x0,0x3ffc00,0x0,0x0,0x0,0x3f,0xff00003f, 0xe0000000,0x3ff8,0xffe0,0x1e00,0x0,0xfffc00,0x0,0x7,0xf800000f,0xf8000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000, 0x3f800001,0xfc00003f,0xf80000ff,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc, 0xfc00,0x3c001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x0,0x7ff8f0f0,0x3c0780,0x1e03c00,0xf01e000,0x783e0001,0xf01e0000,0xffe00, 0x3c0000,0xf0000,0x7700001,0xfe38001f,0xf800070,0x1c000000,0x0,0x3c00,0xf00,0x77000,0x3e1f000,0x3c00000,0xf00000,0x7700003e, 0x1f0000f8,0xc0007f8,0xe0000f00,0x3c0,0x1dc00,0x7f8e00,0x7c3e000,0x0,0x1,0xe0000000,0x7800003b,0x80001f0f,0x800000f0,0x1e0000, 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, 0x0,0x0,0x780000,0x3c1e0000,0x1e070000,0x300001f0,0x7ff,0xc00001e0,0x1e0,0x7c000,0x1c000,0x0,0x0,0x0,0x0,0x3c000ff,0xf80007fe, 0x3ffff,0x801ffff8,0x1f80,0x3ffff80,0x3fff803,0xfffff801,0xfffc000f,0xffc00000,0x0,0x0,0x0,0x0,0x7fff80,0x0,0xfe0003,0xffff0000, 0xffff01ff,0xfc0003ff,0xffe01fff,0xff000fff,0xf01e0007,0x803ffff0,0xfff80,0x3c001f80,0x7800001f,0xc007f07e,0x1e001f,0xff0007ff, 0xfc0007ff,0xc007fffc,0x3fffc,0x7fffffe,0xf0003c1,0xf0000f9e,0xf0f,0x8003e1e0,0x1e01ff,0xfff8003f,0xf001e000,0x7fe0,0x3f00, 0x0,0x1e0000,0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x1fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x3de0,0x0,0x7fff80,0x0,0xfffff80, 0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe7bc07ff,0x3e1f000f,0x78000000,0x0,0x0,0xf780,0x7800078,0x0,0x780000,0x180000, 0x1fff8000,0x1e00,0x1e0003c,0xfff,0xc001f0f8,0x0,0x7ffe00,0x0,0x0,0x0,0x3f,0xff00007f,0xf0000000,0x3ffc,0xfff0,0x3c00,0x0, 0x7fffc00,0x0,0x7,0xf800003f,0xfe000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xe00001ff, 0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000fc00,0x3c003ffe,0x1fff0, 0xfff80,0x7ffc00,0x3ffe000,0x0,0xfffce0f0,0x3c0780,0x1e03c00,0xf01e000,0x781e0001,0xe01e0000,0x3fff00,0x1e0000,0x1e0000,0xf780003, 0xcf78001f,0xf800078,0x3c000000,0x0,0x1e00,0x1e00,0xf7800,0x3e1f000,0x1e00000,0x1e00000,0xf780003e,0x1f0000fc,0x7c000f3d, 0xe0000780,0x780,0x3de00,0xf3de00,0x7c3e000,0x0,0x0,0xf0000000,0xf000007b,0xc0001f0f,0x800001e0,0x1e0000,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,0x0,0x0,0x780000, 0x3c1e0000,0x1e0f0000,0x300007fc,0xfff,0xc00001e0,0x1e0,0x3c000,0x1c000,0x0,0x0,0x0,0x0,0x3c001ff,0xfc001ffe,0x3ffff,0xc01ffffc, 0x3f80,0x3ffff80,0x7fff803,0xfffff803,0xfffe001f,0xffe00000,0x0,0x0,0x0,0x0,0xffff80,0x7f800,0xfe0003,0xffff8001,0xffff01ff, 0xff0003ff,0xffe01fff,0xff001fff,0xf01e0007,0x803ffff0,0xfff80,0x3c003f00,0x7800001f,0xc007f07f,0x1e003f,0xff8007ff,0xff000fff, 0xe007ffff,0x7fffc,0x7fffffe,0xf0003c0,0xf0000f1e,0xf07,0x8003c1f0,0x3e01ff,0xfff8003f,0xf001e000,0x7fe0,0x7f80,0x0,0xe0000, 0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0, 0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x3fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x78f0,0x0,0xffff80,0x0,0x3fffff80,0x1f, 0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc7f80070,0x3e1f0007,0x70000000,0x0,0x0,0x7700,0x7c000f8,0x0,0x780000,0x180000, 0x3fff8000,0x1f00,0x3e0003c,0x1f03,0xc001f0f8,0x0,0x703f00,0x0,0x0,0x0,0x3f,0xff0000f0,0xf8000000,0x303e,0xc0f8,0x7800,0x0, 0xffffc00,0x0,0x7,0x3800003e,0x3e000000,0x1c00,0xe000,0x3c00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00000f,0xe00001ff, 0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000fe00,0x3c007fff,0x3fff8, 0x1fffc0,0xfffe00,0x7fff000,0x1,0xffffc0f0,0x3c0780,0x1e03c00,0xf01e000,0x781f0003,0xe01e0000,0x3fff80,0xe0000,0x3c0000,0x1e3c0003, 0x8ff0001f,0xf80003c,0x78000000,0x0,0xe00,0x3c00,0x1e3c00,0x3e1f000,0xe00000,0x3c00001,0xe3c0003e,0x1f00007f,0xf8000e3f,0xc0000380, 0xf00,0x78f00,0xe3fc00,0x7c3e000,0x0,0x0,0x70000001,0xe00000f1,0xe0001f0f,0x800003c0,0x1e0000,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,0x0,0x0,0x780000,0x3c1e0000,0x3c0f0000, 0x30000ffe,0xf80,0xc00001e0,0x3c0,0x1e000,0x101c040,0x0,0x0,0x0,0x0,0x78003f0,0x7e001ffe,0x3f807,0xe01f00fe,0x3f80,0x3ffff80, 0x7e01803,0xfffff007,0xe03f003f,0x3f00000,0x0,0x0,0x0,0x0,0xfc0fc0,0x3ffe00,0xfe0003,0xffffc003,0xf81f01ff,0xff8003ff,0xffe01fff, 0xff003f01,0xf01e0007,0x803ffff0,0xfff80,0x3c007e00,0x7800001f,0xc007f07f,0x1e007e,0xfc007ff,0xff801f83,0xf007ffff,0x800fc07c, 0x7fffffe,0xf0003c0,0xf0000f0f,0x1e07,0xc007c0f8,0x7c01ff,0xfff8003c,0xf000,0x1e0,0xffc0,0x0,0xf0000,0x1,0xe0000000,0x0,0x780000, 0x3e,0x0,0x78000,0x3c00,0xf000,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0x800000f0,0x1f80, 0x0,0x0,0x7e0780,0x0,0x0,0x1f82000,0x0,0x0,0x0,0x7070,0x0,0x1f80f80,0x0,0x7fffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x1,0xc3f80070,0x3f3f0007,0xf0000000,0x0,0x0,0x7f00,0x3e001f0,0x0,0x780000,0x180000,0x7f018000,0xf80,0x7c0003c,0x3e00, 0x4001f0f8,0xfe00,0x400f00,0x0,0x0,0x0,0x7f000000,0xe0,0x38000000,0x1e,0x38,0x7800,0x0,0x1ffe1c00,0x0,0x0,0x38000078,0xf000000, 0x1c00,0xe000,0x7f800,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xf00001ff,0xffc03f81,0xf007ffff,0xc03ffffe, 0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf800fe00,0x3c00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800, 0x3,0xf07fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x780f8007,0xc01e0000,0x7e0fc0,0xf0000,0x3c0000,0x1c1c0003,0x87f0001f,0xf80003f, 0xf8000000,0x0,0xf00,0x3c00,0x1c1c00,0x3e1f000,0xf00000,0x3c00001,0xc1c0003e,0x1f00003f,0xc0000e1f,0xc00003c0,0xf00,0x70700, 0xe1fc00,0x7c3e000,0x0,0x0,0x78000001,0xe00000e0,0xe0001f0f,0x800003c0,0x1e0000,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,0x0,0x0,0x780000,0x3c1e0000,0x3c0f0001,0xff801e0f, 0x1f00,0x1e0,0x3c0,0x1e000,0x3c1c1e0,0x0,0x0,0x0,0x0,0x78007c0,0x1f001f9e,0x3c001,0xf010003e,0x7780,0x3c00000,0xf800000,0xf007, 0xc01f007c,0x1f80000,0x0,0x0,0x0,0x0,0xe003e0,0x7fff00,0x1ef0003,0xc007e007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x301e0007, 0x80007800,0x780,0x3c00fc00,0x7800001f,0xe00ff07f,0x1e00f8,0x3e00780,0x1fc03e00,0xf807801f,0xc01f001c,0xf000,0xf0003c0,0xf0000f0f, 0x1e03,0xc00f8078,0x780000,0xf0003c,0xf000,0x1e0,0x1f3e0,0x0,0x78000,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0, 0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0xf0,0xf80,0x0,0x0,0xf80180,0x0,0x0,0x1e00000, 0x0,0x0,0x0,0xe038,0x0,0x3e00380,0x0,0xfe0f0000,0x0,0xf0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc0f00070,0x3b370003,0xe0000000, 0x0,0x0,0x3e00,0x1e001e0,0x0,0x780000,0x180000,0x7c000000,0x780,0x780003c,0x3c00,0x0,0x7ffc0,0x780,0x0,0x0,0x3,0xffe00000, 0x1c0,0x3c000000,0xe,0x38,0xf000,0x0,0x3ffe1c00,0x0,0x0,0x38000078,0xf000000,0x1c00,0xe000,0x7f000,0xf000,0x3de000,0x1ef0000, 0xf780000,0x7bc00003,0xde00001e,0xf00003e7,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001, 0xe0001e03,0xfc00fe00,0x3c01f007,0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x7,0xc01f80f0,0x3c0780,0x1e03c00,0xf01e000,0x78078007, 0x801e0000,0x7803c0,0x78000,0x780000,0x380e0003,0x81e00000,0x1f,0xf0000000,0x0,0x780,0x7800,0x380e00,0x0,0x780000,0x7800003, 0x80e00000,0x1ff,0x80000e07,0x800001e0,0x1e00,0xe0380,0xe07800,0x0,0x0,0x0,0x3c000003,0xc00001c0,0x70000000,0x780,0x1e0000, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x3c0e0007,0xfff01c07,0x1e00,0x1e0,0x780,0xf000,0x3e1c3e0,0x0,0x0,0x0,0x0,0xf0007c0,0x1f00181e,0x20000, 0xf000001f,0xf780,0x3c00000,0x1f000000,0x1f00f,0x800f8078,0xf80000,0x0,0x0,0x0,0x0,0x8003e0,0x1fc0f80,0x1ef0003,0xc001e007, 0x800101e0,0x7e003c0,0x1e00,0x7800,0x101e0007,0x80007800,0x780,0x3c00f800,0x7800001e,0xe00ef07f,0x801e00f0,0x1e00780,0x7c03c00, 0x78078007,0xc01e0004,0xf000,0xf0003c0,0x78001e0f,0x1e03,0xe00f807c,0xf80000,0x1f0003c,0x7800,0x1e0,0x3e1f0,0x0,0x3c000,0x1, 0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0, 0x1e,0xf0,0x780,0x0,0x0,0x1f00080,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x1e03c,0x0,0x3c00080,0x0,0xf80f0000,0x0,0x1f0000,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x3bf70003,0xe0000000,0x0,0x0,0x3e00,0x1f003e0,0x0,0x780000,0x180000,0x78000000,0x7c0,0xf80003c, 0x3c00,0x0,0x1f01f0,0x780,0x0,0x0,0xf,0x80f80000,0x1c0,0x1c000000,0xe,0x38,0x1e000,0x0,0x7ffe1c00,0x0,0x0,0x380000f0,0x7800000, 0x1c00,0xe000,0x7fc00,0xf000,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x80007800,0x10078000,0x3c0000, 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00ff00,0x3c01e003,0xc00f001e,0x7800f0,0x3c00780,0x1e003c00, 0x7,0x800f00f0,0x3c0780,0x1e03c00,0xf01e000,0x7807c00f,0x801e0000,0xf803c0,0x3c000,0xf00000,0x780f0000,0x0,0x7,0xc0000000, 0x0,0x3c0,0xf000,0x780f00,0x0,0x3c0000,0xf000007,0x80f00000,0x7ff,0xc0000000,0xf0,0x3c00,0x1e03c0,0x0,0x0,0x0,0x0,0x1e000007, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c1e001f,0xfff03803,0x80001e00,0x1e0,0x780,0xf000,0xf9cf80, 0x0,0x0,0x0,0x0,0xf000780,0xf00001e,0x0,0xf800000f,0xe780,0x3c00000,0x1e000000,0x1e00f,0x78078,0x7c0000,0x0,0x0,0x0,0x0,0x1e0, 0x3f003c0,0x1ef0003,0xc000f00f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780,0x3c01f000,0x7800001e,0xe00ef07f, 0x801e01f0,0x1e00780,0x3c07c00,0x78078003,0xc03e0000,0xf000,0xf0003c0,0x78001e0f,0x1e01,0xf01f003c,0xf00000,0x3e0003c,0x7800, 0x1e0,0x7c0f8,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000, 0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,0x0,0x0,0x3c00000,0x0,0x8,0x40,0x0,0x7e0000,0x7c00000,0x1,0xf00f0000, 0x0,0x3e0000,0x0,0x3f,0xfc0,0xfc3f0,0xfc3f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0,0xf003c0,0x0,0x0,0x180000,0xf8000000, 0x3c0,0xf00003c,0x3c00,0x0,0x3c0078,0x7ff80,0x0,0x0,0x1e,0x3c0000,0x1c0,0x1c000000,0xe,0xf0,0x0,0x0,0x7ffe1c00,0x0,0x0,0x380000f0, 0x7800000,0x1c00,0xe000,0x3c00,0x0,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x8000f800,0x78000,0x3c0000, 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00ff00,0x3c03e003,0xc01f001e,0xf800f0,0x7c00780,0x3e003c00, 0xf,0x800f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803c00f,0x1fffc0,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x781e003f,0xfff03803, 0x80001e00,0x1e0,0xf80,0xf000,0x3dde00,0x0,0x0,0x0,0x0,0xf000f00,0x780001e,0x0,0x7800000f,0x1e780,0x3c00000,0x3e000000,0x3e00f, 0x780f0,0x7c0000,0x0,0x0,0x0,0x0,0x1e0,0x7c001e0,0x3ef8003,0xc000f00f,0x1e0,0xf003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780, 0x3c03e000,0x7800001e,0xf01ef07b,0xc01e01e0,0xf00780,0x3e07800,0x3c078003,0xe03c0000,0xf000,0xf0003c0,0x78001e0f,0x1e00,0xf01e003e, 0x1f00000,0x3c0003c,0x7800,0x1e0,0x78078,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000, 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, 0xe70000,0x7800000,0x1,0xe00f0000,0x0,0x3c0000,0x0,0x3f,0xfc0,0xfc1f0,0x1f83f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0, 0xf807c0,0x0,0x0,0x180000,0xf0000000,0x3e0,0x1f00003c,0x3e00,0x0,0x70001c,0x3fff80,0x0,0x0,0x38,0xe0000,0x1c0,0x1c000078, 0x1c,0x1fe0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x7df000,0x3ef8000,0x1f7c0000,0xfbe00007, 0xdf00003c,0x780003c7,0x8000f000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f780, 0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0xf80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803e01f,0x1ffff8,0xf001e0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x781e003e,0x30703803,0x80001e00,0x1e0,0xf00,0x7800,0xff800,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e, 0x0,0x7800000f,0x3c780,0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x2000000,0x800000,0x1e0,0x78000e0,0x3c78003, 0xc000f01e,0x1e0,0xf803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x701cf07b,0xc01e01e0,0xf00780,0x1e07800, 0x3c078001,0xe03c0000,0xf000,0xf0003c0,0x7c003e0f,0x1e00,0xf83e001e,0x1e00000,0x7c0003c,0x3c00,0x1e0,0xf807c,0x0,0x0,0x1fe0001, 0xe1fc0000,0x7f00003,0xf8780007,0xf000003c,0x7f0,0x783f0,0x0,0x0,0x7800000,0x1e00000,0x3e0f8000,0xfc00007,0xf8000007,0xf00001fc, 0xf,0xc0003fc0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x3c00000,0x0,0x0,0x3c00000,0x0,0x18,0xc0,0x0,0x1818000, 0x7800000,0x1,0xe00f0000,0x0,0x7c0000,0x0,0x1f,0x80001f80,0x7c1f8,0x1f83e0,0x0,0x0,0x0,0x70,0x38c70007,0xf8000000,0x7f03, 0xf0000000,0x0,0x780780,0x0,0x0,0xfe0000,0xf0000000,0x1e0,0x1e00003c,0x3f00,0x0,0xe07f0e,0x7fff80,0x0,0x0,0x70,0x70000,0x1c0, 0x1c000078,0x3c,0x1fc0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x78f000,0x3c78000,0x1e3c0000, 0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00, 0xf80f780,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0x1f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801e01e,0x1ffffc, 0xf007e0,0x3fc000,0x1fe0000,0xff00000,0x7f800003,0xfc00001f,0xe0000fc0,0xfc00007f,0xfe0,0x7f00,0x3f800,0x1fc000,0x0,0x0,0x0, 0x1,0xf000001f,0x80000ff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x1f80000,0x1fc1e000,0x0,0x0,0x0,0x0,0x1e1fc0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,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, 0x781c007c,0x30003803,0x80001f00,0x1e0,0xf00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e,0x0,0x7800000f,0x3c780, 0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x1e000000,0xf00000,0x3e0,0xf0000e0,0x3c78003,0xc000f01e,0x1e0,0x7803c0, 0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c0f8000,0x7800001e,0x701cf079,0xe01e01e0,0xf00780,0x1e07800,0x3c078001,0xe03c0000, 0xf000,0xf0003c0,0x3c003c0f,0x3e00,0x787c001f,0x3e00000,0xf80003c,0x3c00,0x1e0,0x1f003e,0x0,0x0,0x1fffc001,0xe7ff0000,0x3ffe000f, 0xfe78003f,0xfc001fff,0xfe001ffc,0xf0078ffc,0x1ffc00,0x7ff000,0x7800f80,0x1e0000f,0x7f1fc01e,0x3ff0001f,0xfe00079f,0xfc0007ff, 0x3c003c7f,0xf001fff8,0x1fffff0,0x3c003c0,0xf0000f1e,0xf1f,0x7c1f0,0x1f00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3c00000,0x100000, 0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7800000,0x1,0xe00f0000,0x1000000,0xf80000,0x40000002,0xf,0x80001f00,0x7e0f8,0x1f07c0, 0x0,0x0,0x0,0x70,0x38c7003f,0xff000000,0xff8f,0xf8000100,0xffffe,0x7c0f80,0x0,0x0,0x3ffc000,0xf0000020,0x1001f0,0x3c00003c, 0x1f80,0x0,0x1c3ffc7,0x7c0780,0x0,0x0,0xe3,0xff038000,0xe0,0x38000078,0x78,0x1ff0,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0, 0x7800000,0x1c00,0xe000,0xe00,0xf000,0x78f000,0x3c78000,0x1e3c0000,0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000, 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00, 0x4000200f,0x3f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801f03e,0x1ffffe,0xf01fe0,0x3fff800,0x1fffc000,0xfffe0007,0xfff0003f, 0xff8001ff,0xfc003ff3,0xfe0003ff,0xe0007ff8,0x3ffc0,0x1ffe00,0xfff000,0x3ff80001,0xffc0000f,0xfe00007f,0xf000003f,0xf8003c7f, 0xe0003ffc,0x1ffe0,0xfff00,0x7ff800,0x3ffc000,0x1f80000,0xfff1c03c,0x3c01e0,0x1e00f00,0xf007800,0x781f0001,0xf01e7ff0,0x7c0007c, 0x0,0x0,0x0,0x0,0x0,0x0,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, 0x3c1e003f,0xfffff078,0x30003803,0x80000f00,0x1e0,0x1f00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x3c000f00,0x780001e,0x0,0x7800000f, 0x78780,0x3c00000,0x3c000000,0x7c00f,0x780f0,0x3c0007,0xe000003f,0x0,0xfe000000,0xfe0000,0x3c0,0x1f000070,0x7c7c003,0xc000f01e, 0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c1f0000,0x7800001e,0x783cf079,0xe01e03c0,0xf00780,0x1e0f000,0x3c078001, 0xe03c0000,0xf000,0xf0003c0,0x3c003c07,0x81f03c00,0x7c7c000f,0x87c00000,0xf00003c,0x1e00,0x1e0,0x3e001f,0x0,0x0,0x3fffe001, 0xefff8000,0x7fff001f,0xff78007f,0xfe001fff,0xfe003ffe,0xf0079ffe,0x1ffc00,0x7ff000,0x7801f00,0x1e0000f,0xffbfe01e,0x7ff8003f, 0xff0007bf,0xfe000fff,0xbc003cff,0xf803fffc,0x1fffff0,0x3c003c0,0x78001e1e,0xf0f,0x800f80f0,0x1e00ff,0xffe0001e,0xf0,0x780, 0x0,0x0,0x3c00000,0x380000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1008000,0x7800000,0x3,0xe00f0000,0x3800000,0xf00000,0xe0000007, 0xf,0x80001f00,0x3e0f8,0x1e07c0,0x0,0x0,0x0,0x70,0x3807007f,0xff800000,0x1ffdf,0xfc000380,0xffffe,0x3e1f00,0x0,0x0,0xfffe000, 0xf0000030,0x3800f8,0x7c00003c,0xfc0,0x0,0x18780c3,0xf00780,0x80100,0x0,0xc3,0xffc18000,0xf0,0x78000078,0xf0,0xf0,0x0,0x3c003c0, 0xfffe1c00,0x0,0x0,0x380000f0,0x7800801,0x1c00,0xe000,0x1e00,0xf000,0xf8f800,0x7c7c000,0x3e3e0001,0xf1f0000f,0x8f80007c,0x7c000787, 0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078001,0xe03c000f, 0x1e00078,0xf0003c0,0x78001e00,0xe000701f,0x3fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x7800f87c,0x1e007f,0xf07e00,0x7fffc00,0x3fffe001, 0xffff000f,0xfff8007f,0xffc003ff,0xfe007ff7,0xff0007ff,0xf000fffc,0x7ffe0,0x3fff00,0x1fff800,0x3ff80001,0xffc0000f,0xfe00007f, 0xf00000ff,0xf8003cff,0xf0007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x1f80001,0xfffb803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001, 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, 0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e003f,0xfffff078,0x30001c07,0xf80,0x1e0,0x1e00,0x3c00,0xff800,0x1e0000,0x0,0x0,0x0,0x3c001e00, 0x3c0001e,0x0,0x7800001e,0x70780,0x3c00000,0x78000000,0x78007,0x800f00f0,0x3e0007,0xe000003f,0x3,0xfe000000,0xff8000,0x7c0, 0x1e000070,0x783c003,0xc001f01e,0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c3e0000,0x7800001e,0x3838f079, 0xe01e03c0,0x780780,0x1e0f000,0x1e078001,0xe03c0000,0xf000,0xf0003c0,0x3c007c07,0x81f03c00,0x3ef80007,0x87800000,0x1f00003c, 0x1e00,0x1e0,0x7c000f,0x80000000,0x0,0x3ffff001,0xffffc000,0xffff003f,0xff7800ff,0xff001fff,0xfe007ffe,0xf007bffe,0x1ffc00, 0x7ff000,0x7803e00,0x1e0000f,0xffffe01e,0xfff8007f,0xff8007ff,0xff001fff,0xbc003dff,0xf807fffc,0x1fffff0,0x3c003c0,0x78001e0f, 0x1e07,0xc01f00f0,0x1e00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7c00000,0x7c0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1018000,0x7800000, 0x3,0xc00f0000,0x7c00000,0x1f00001,0xf000000f,0x80000007,0xc0003e00,0x1e07c,0x3e0780,0x0,0x0,0x0,0x70,0x380700ff,0xff800000, 0x3ffff,0xfe0007c0,0xffffe,0x1e1e00,0x0,0x780000,0x1fffe000,0xf0000078,0x7c0078,0x7800003c,0xff0,0x0,0x38e0003,0x80f00780, 0x180300,0x0,0x1c3,0x81e1c000,0x7f,0xf0000078,0x1e0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800c01,0x80001c00, 0xe000,0x603e00,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x7800078,0x3c000f87,0x8001e000,0x78000,0x3c0000,0x1e00000, 0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f01,0xf000f81e, 0x7bc0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007878,0x1e001f,0xf0f800,0x7fffe00,0x3ffff001,0xffff800f,0xfffc007f,0xffe003ff, 0xff007fff,0xff800fff,0xf001fffe,0xffff0,0x7fff80,0x3fffc00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00001ff,0xfc003dff,0xf000ffff, 0x7fff8,0x3fffc0,0x1fffe00,0xffff000,0x1f80003,0xffff803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001,0xe01ffffc,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,0x0,0x0,0x0,0x0,0x0,0x780000, 0x3c1e003f,0xfffff078,0x30001e0f,0x300780,0x1e0,0x1e00,0x3c00,0x3dde00,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf800003e, 0xf0780,0x3dfc000,0x783f8000,0xf8007,0xc01f00f0,0x3e0007,0xe000003f,0x1f,0xfc000000,0x7ff000,0xf80,0x3e007c70,0x783c003,0xc001e03c, 0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007,0x80007800,0x780,0x3c7c0000,0x7800001e,0x3878f078,0xf01e03c0,0x780780,0x1e0f000,0x1e078001, 0xe03e0000,0xf000,0xf0003c0,0x1e007807,0x83f03c00,0x3ef00007,0xcf800000,0x3e00003c,0xf00,0x1e0,0xf80007,0xc0000000,0x0,0x3e01f801, 0xfe07e001,0xf80f007e,0x7f801f8,0x1f801fff,0xfe00fc0f,0xf007f83f,0x1ffc00,0x7ff000,0x7807c00,0x1e0000f,0x87e1e01f,0xe0fc00fc, 0xfc007f8,0x1f803f03,0xfc003df0,0x3807e03c,0x1fffff0,0x3c003c0,0x78003e0f,0x1e03,0xe03e00f8,0x3e00ff,0xffe0001e,0xf0,0x780, 0x0,0x0,0x7800000,0xfe0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7c00000,0x3,0xc00f0000,0xfe00000,0x3e00003,0xf800001f, 0xc0000007,0xc0003e00,0x1e03c,0x3c0f80,0x0,0x0,0x0,0x70,0x380700fc,0x7800000,0x7c1fe,0x3e000fe0,0xffffe,0x1f3e00,0x0,0x780000, 0x3f98e000,0xf000003c,0xfcf8007c,0xf800003c,0x3ffc,0x0,0x31c0001,0x80f00f80,0x380700,0x0,0x183,0x80e0c000,0x3f,0xe0000078, 0x3c0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x38000078,0xf000e01,0xc003ffe0,0x1fff00,0x7ffc00,0xf000,0xf07800,0x783c000,0x3c1e0001, 0xe0f0000f,0x7800078,0x3c000f07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00, 0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf801f01e,0xf3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007cf8, 0x1e000f,0x80f0f000,0x7c03f00,0x3e01f801,0xf00fc00f,0x807e007c,0x3f003e0,0x1f80707f,0x8f801f80,0xf003f03f,0x1f81f8,0xfc0fc0, 0x7e07e00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00003ff,0xfc003fc1,0xf801f81f,0x800fc0fc,0x7e07e0,0x3f03f00,0x1f81f800,0x1f80007, 0xe07f003c,0x3c01e0,0x1e00f00,0xf007800,0x780f8003,0xe01fe07e,0x3e000f8,0x0,0x0,0x0,0x0,0x0,0x0,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,0x3f,0xfffff078,0x30000ffe,0x1f007c0,0x0,0x1e00, 0x3c00,0xf9cf80,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf00000fc,0x1e0780,0x3fff800,0x78ffe000,0xf0003,0xe03e00f0, 0x3e0007,0xe000003f,0x7f,0xe01fffff,0xf00ffc00,0x1f80,0x3c01ff70,0x783c003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007, 0x80007800,0x780,0x3cfc0000,0x7800001e,0x3c78f078,0xf01e03c0,0x780780,0x3e0f000,0x1e078003,0xc01f0000,0xf000,0xf0003c0,0x1e007807, 0x83f83c00,0x1ff00003,0xcf000000,0x3e00003c,0xf00,0x1e0,0x0,0x0,0x0,0x20007801,0xfc03e003,0xe003007c,0x3f803e0,0x7c0003c, 0xf807,0xf007e00f,0x3c00,0xf000,0x780f800,0x1e0000f,0x87e1f01f,0x803c00f8,0x7c007f0,0xf803e01,0xfc003f80,0x80f8004,0x3c000, 0x3c003c0,0x3c003c0f,0x1e03,0xe03e0078,0x3c0000,0x7c0001e,0xf0,0x780,0x0,0x0,0x3ffff800,0x1ff0000,0x0,0x7800000,0x0,0x18, 0xc0,0x0,0x1818000,0x3e00000,0x3,0xc00f0000,0x1ff00000,0x3e00007,0xfc00003f,0xe0000003,0xc0003c00,0xf03c,0x3c0f00,0x0,0x0, 0x0,0x70,0x380701f0,0x800000,0x780fc,0x1e001ff0,0x7c,0xf3c00,0x0,0x780000,0x7e182000,0xf000001f,0xfff00ffc,0xffc0003c,0x3cfe, 0x0,0x31c0001,0x80f01f80,0x780f00,0x0,0x183,0x80e0c000,0xf,0x80000078,0x780,0x38,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x38000078, 0xf000f01,0xe003ffe0,0x1fff00,0x7ff800,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x78000f8,0x3e000f07,0x8003c000,0x78000, 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0, 0x78000f00,0x7c03e01e,0x1e3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78003cf0,0x1e0007,0x80f1e000,0x4000f00,0x20007801,0x3c008, 0x1e0040,0xf00200,0x780403f,0x7803e00,0x3007c00f,0x803e007c,0x1f003e0,0xf801f00,0x780000,0x3c00000,0x1e000000,0xf00007f0, 0x3e003f00,0x7801f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e003c,0x3c01e0,0x1e00f00,0xf007800,0x78078003, 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, 0x0,0x0,0x0,0x0,0x0,0x780000,0x0,0xf078007c,0x300007fc,0x7e00fe0,0x0,0x1e00,0x3c00,0x3e1c3e0,0x1e0000,0x0,0x0,0x0,0xf0001e00, 0x3c0001e,0x1,0xf000fff8,0x1e0780,0x3fffe00,0x79fff000,0x1f0001,0xfffc00f0,0x7e0007,0xe000003f,0x3ff,0x801fffff,0xf003ff80, 0x3f00,0x3c03fff0,0xf01e003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3df80000,0x7800001e, 0x1c70f078,0x781e03c0,0x780780,0x3c0f000,0x1e078007,0xc01f8000,0xf000,0xf0003c0,0x1e007807,0x83f83c00,0xfe00003,0xff000000, 0x7c00003c,0x780,0x1e0,0x0,0x0,0x0,0x7c01,0xf801f007,0xc00100f8,0x1f803c0,0x3c0003c,0x1f003,0xf007c00f,0x80003c00,0xf000, 0x783f000,0x1e0000f,0x3c0f01f,0x3e01f0,0x3e007e0,0x7c07c00,0xfc003f00,0xf0000,0x3c000,0x3c003c0,0x3c003c0f,0x1e01,0xf07c007c, 0x7c0000,0xfc0001e,0xf0,0x780,0x0,0x0,0x3ffff000,0x3838000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0xff0000,0x3f00000,0x3,0xc00fff00, 0x38380000,0x7c0000e,0xe000070,0x70000001,0xe0003c00,0xf01e,0x780e00,0x0,0x0,0x0,0x0,0x1e0,0x0,0x780f8,0xf003838,0xfc,0xffc00, 0x0,0x780000,0x7c180000,0xf000000f,0xffe00fff,0xffc0003c,0x783f,0x80000000,0x6380000,0xc0f83f80,0xf81f00,0x0,0x303,0x80e06000, 0x0,0x78,0xf00,0x78,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x3800003c,0x3e000f81,0xf003ffe0,0x1fff00,0x1fc000,0xf000,0x1e03c00, 0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e000f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000, 0x3c000001,0xe0001e00,0x3c0f0f0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3e07c01e,0x1e3c0f0,0x3c0780,0x1e03c00, 0xf01e000,0x78003ff0,0x1e0007,0x80f1e000,0xf80,0x7c00,0x3e000,0x1f0000,0xf80000,0x7c0001e,0x3c07c00,0x10078007,0x803c003c, 0x1e001e0,0xf000f00,0x780000,0x3c00000,0x1e000000,0xf00007c0,0x1e003e00,0x7c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00, 0xf,0x801f003c,0x3c01e0,0x1e00f00,0xf007800,0x7807c007,0xc01f801f,0x1f001f0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0xe078003c,0x300001f0,0x3f801ff0,0x0, 0x3c00,0x1e00,0x3c1c1e0,0x1e0000,0x0,0x0,0x0,0xf0001e0f,0x3c0001e,0x3,0xe000fff0,0x3c0780,0x3ffff00,0x7bfff800,0x1e0000,0x7ff00078, 0x7e0007,0xe000003f,0x1ffc,0x1fffff,0xf0007ff0,0x7e00,0x3c07c3f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000, 0x1fffff,0x80007800,0x780,0x3ffc0000,0x7800001e,0x1ef0f078,0x781e03c0,0x780780,0x7c0f000,0x1e07801f,0x800ff000,0xf000,0xf0003c0, 0xf00f807,0x83b83c00,0xfc00001,0xfe000000,0xf800003c,0x780,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0xc00000f0,0xf80780,0x3c0003c, 0x1e001,0xf007c007,0x80003c00,0xf000,0x787e000,0x1e0000f,0x3c0f01f,0x1e01e0,0x1e007c0,0x3c07800,0x7c003f00,0xf0000,0x3c000, 0x3c003c0,0x3e007c07,0x80003c00,0xf8f8003c,0x780000,0xf80001e,0xf0,0x780,0x0,0x0,0x7ffff000,0x601c000,0x3,0xffff0000,0x0, 0xfff,0xf8007fff,0xc0000000,0x7e003c,0x1fe0000,0xc0003,0xc00fff00,0x601c0000,0xf800018,0x70000c0,0x38000001,0xe0007800,0x701e, 0x701e00,0x0,0x0,0x0,0x0,0x1e0,0x6,0x700f8,0xf00601c,0xf8,0x7f800,0x0,0x780000,0xf8180000,0xf000000f,0x87c00fff,0xffc0003c, 0xf01f,0xc0000000,0x6380000,0xc07ff780,0x1f03e03,0xfffffe00,0x303,0x81c06000,0x0,0x1ffff,0xfe001e00,0x180f8,0x0,0x3c003c0, 0x3ffe1c00,0x3f00000,0x0,0x3800003f,0xfe0007c0,0xf8000000,0x18000000,0xc0000006,0x1f000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e, 0x3c000f0,0x1e001f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f0f0, 0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f0f801e,0x3c3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007, 0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07c00,0xf0007,0x8078003c,0x3c001e0,0x1e000f00,0x780000,0x3c00000, 0x1e000000,0xf0000f80,0x1f003e00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0xf,0x3f003c,0x3c01e0,0x1e00f00,0xf007800, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe078003f,0xb0000000,0xfc003cf0,0x0,0x3c00,0x1e00,0x101c040,0x1e0000,0x0,0x0,0x1, 0xe0001e1f,0x83c0001e,0x7,0xe000fff0,0x3c0780,0x3c03f80,0x7fc0fc00,0x1e0000,0xfff80078,0xfe0007,0xe000003f,0x7fe0,0x1fffff, 0xf0000ffc,0xfc00,0x780f81f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3ffc0000, 0x7800001e,0x1ef0f078,0x3c1e03c0,0x780780,0x1fc0f000,0x1e07ffff,0x7ff00,0xf000,0xf0003c0,0xf00f007,0xc3b87c00,0x7c00001,0xfe000000, 0xf800003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0x800000f0,0xf80780,0x1e0003c,0x1e001,0xf0078007,0x80003c00,0xf000,0x78fc000, 0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,0x3c07800,0x7c003e00,0xf0000,0x3c000,0x3c003c0,0x1e007807,0x80003c00,0x7df0003c,0x780000, 0x1f00001e,0xf0,0x780,0x0,0x0,0x7800000,0xe7ce000,0x3,0xffff0000,0x0,0xfff,0xf8007fff,0xc0000000,0x1f0,0xffe000,0x1c0003, 0xc00fff00,0xe7ce0000,0xf800039,0xf38001cf,0x9c000000,0xe0007800,0x780e,0x701c00,0x0,0x0,0x0,0x0,0x1e0,0x7,0xf0078,0xf00e7ce, 0x1f0,0x7f800,0x0,0x780000,0xf0180000,0xf000000e,0x1c0001f,0xe000003c,0xf007,0xe0000000,0x6380000,0xc03fe780,0x3e07c03,0xfffffe00, 0x303,0xffc06000,0x0,0x1ffff,0xfe003ffe,0x1fff0,0x0,0x3c003c0,0x1ffe1c00,0x3f00000,0x7,0xffc0001f,0xfc0003e0,0x7c000001,0xfc00000f, 0xe000007f,0x1e000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0, 0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e, 0x783c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007,0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07800, 0xf0003,0xc078001e,0x3c000f0,0x1e000780,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c03c003,0xc01e001e,0xf000f0, 0x7800780,0x3c003c00,0xf,0x7f003c,0x3c01e0,0x1e00f00,0xf007800,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe070001f,0xf8000007, 0xf0007cf8,0x7800000,0x3c00,0x1e00,0x1c000,0x1e0000,0x0,0x0,0x1,0xe0001e1f,0x83c0001e,0xf,0xc000fff8,0x780780,0x2000f80,0x7f803e00, 0x3e0003,0xfffe007c,0x1fe0000,0x0,0x3ff00,0x0,0x1ff,0x8001f000,0x780f00f0,0x1f00f003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff, 0xfe03c00f,0xf81fffff,0x80007800,0x780,0x3ffe0000,0x7800001e,0xee0f078,0x3c1e03c0,0x7807ff,0xff80f000,0x1e07fffe,0x3ffe0, 0xf000,0xf0003c0,0xf00f003,0xc7bc7800,0xfc00000,0xfc000001,0xf000003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xe000f80f,0x800001e0, 0xf80f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x79f8000,0x1e0000f,0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003e00, 0xf0000,0x3c000,0x3c003c0,0x1e007807,0x81e03c00,0x7df0003e,0xf80000,0x3e00003e,0xf0,0x7c0,0xfc000,0x80000000,0x7800000,0x1e7cf000, 0x3,0xffff0000,0x0,0x18,0xc0,0x0,0xf80,0x7ffc00,0x380003,0xc00fff01,0xe7cf0000,0x1f000079,0xf3c003cf,0x9e000000,0xe0007000, 0x380e,0xe01c00,0x0,0x0,0x0,0x0,0x1e0,0x3,0x800f0078,0xf01e7cf,0x3e0,0x3f000,0x0,0x780000,0xf018001f,0xfff8001e,0x1e0000f, 0xc000003c,0xf003,0xe0000000,0x6380000,0xc00fc780,0x7c0f803,0xfffffe00,0x303,0xfe006000,0x0,0x1ffff,0xfe003ffe,0x1ffe0,0x0, 0x3c003c0,0xffe1c00,0x3f00000,0x7,0xffc00007,0xf00001f0,0x3e00001f,0xfc0000ff,0xe00007ff,0x3e000,0x3e01e00,0x1f00f000,0xf8078007, 0xc03c003e,0x1e001e0,0xf001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8, 0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000fc0, 0x1e0007,0x80f1f000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c0f800,0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000, 0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1e,0xf7803c,0x3c01e0,0x1e00f00, 0xf007800,0x7803e00f,0x801e000f,0x80f803e0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x1,0xe0f0000f,0xff00001f,0x8000f87c,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80, 0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x1f,0x800000fe,0xf00780,0x7c0,0x7f001e00,0x3c0007,0xe03f003f,0x3fe0000,0x0,0x3fc00,0x0, 0x7f,0x8001e000,0x781f00f0,0x1e00f003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3f9f0000,0x7800001e, 0xfe0f078,0x3c1e03c0,0x7807ff,0xff00f000,0x1e07fff8,0xfff8,0xf000,0xf0003c0,0xf81f003,0xc7bc7800,0xfe00000,0x78000003,0xe000003c, 0x1e0,0x1e0,0x0,0x0,0x0,0x1fffc01,0xe000780f,0x1e0,0x780f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7bf0000,0x1e0000f, 0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xf8000,0x3c000,0x3c003c0,0x1f00f807,0x81f03c00,0x3fe0001e,0xf00000,0x7c00007c, 0xf0,0x3e0,0x3ff801,0x80000000,0x7800000,0x3cfcf800,0x3,0xffff0000,0x0,0x18,0xc0,0x0,0x7c00,0x1fff00,0x700003,0xc00f0003, 0xcfcf8000,0x3e0000f3,0xf3e0079f,0x9f000000,0xf000,0x1000,0x0,0x0,0x0,0x0,0x0,0x1f0,0x1,0xc00f0078,0xf03cfcf,0x800007c0,0x1e000, 0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x8000003c,0xf001,0xf0000000,0x6380000,0xc0000000,0xf81f003,0xfffffe00,0x303, 0x87006000,0x0,0x1ffff,0xfe003ffe,0x7f00,0x0,0x3c003c0,0x3fe1c00,0x3f00000,0x7,0xffc00000,0xf8,0x1f0001ff,0xf0000fff,0x80007ffc, 0xfc000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf001e07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000, 0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3fc001e,0x1e03c0f0,0x3c0780, 0x1e03c00,0xf01e000,0x78000780,0x1e0007,0x80f0fc00,0x3fff80,0x1fffc00,0xfffe000,0x7fff0003,0xfff8001f,0xffc0001e,0x3c0f000, 0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000,0x3c00000,0x1e000000,0xf0001e00,0xf803c00,0x3c078001,0xe03c000f,0x1e00078, 0xf0003c0,0x78001e07,0xfffffe1e,0x1e7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801e00f,0x1e0007,0x807803c0,0x0,0x0,0x0,0x0,0x0, 0x0,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, 0xffc0007e,0xf03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x3f,0x3e,0xf00780,0x3c0,0x7e001e00, 0x7c000f,0x800f001f,0xffde0000,0x0,0x3e000,0x0,0xf,0x8003e000,0x781e0070,0x1e00f003,0xc001f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f, 0xf81e0007,0x80007800,0x780,0x3f1f0000,0x7800001e,0x7c0f078,0x1e1e03c0,0x7807ff,0xfc00f000,0x1e07fffe,0xffc,0xf000,0xf0003c0, 0x781e003,0xc71c7800,0x1ff00000,0x78000003,0xe000003c,0x1e0,0x1e0,0x0,0x0,0x0,0xffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c, 0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7f000,0x3c000, 0x3c003c0,0xf00f007,0xc1f07c00,0x1fc0001f,0x1f00000,0xfc000ff8,0xf0,0x1ff,0xfffe07,0x80000000,0x7800000,0x7ffcfc00,0x0,0xf000000, 0x0,0x18,0xc0,0x0,0x3e000,0x1ff80,0xe00003,0xc00f0007,0xffcfc000,0x3e0001ff,0xf3f00fff,0x9f800000,0x6000,0x0,0x0,0x7c000, 0x0,0x0,0x0,0xfe,0x0,0xe00f007f,0xff07ffcf,0xc0000fc0,0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x80000000,0xf800, 0xf0000000,0x6380000,0xc0000000,0x1f03c000,0x1e00,0x303,0x83806000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xfe1c00,0x3f00000,0x0, 0x0,0x3c,0xf801fff,0xfff8,0x7ffc0,0x1f8000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf003c07,0x8003c000,0x78000, 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0, 0x78000f00,0x1f8001e,0x1e03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e000f,0x80f0ff00,0x1ffff80,0xffffc00,0x7fffe003, 0xffff001f,0xfff800ff,0xffc007ff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00, 0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x3c7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801f01f, 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, 0x0,0x0,0x0,0x0,0x780000,0x3,0xc0f00000,0xfff003f0,0x1f00f03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x7ff80000,0x3, 0xc0001e0f,0x3c0001e,0x7e,0x1f,0x1e00780,0x3e0,0x7e000f00,0x78000f,0x7800f,0xff9e0000,0x0,0x3fc00,0x0,0x7f,0x8003c000,0x781e0070, 0x3e00f803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3e0f8000,0x7800001e,0x7c0f078,0x1e1e03c0, 0x7807ff,0xf000f000,0x1e07807f,0xfe,0xf000,0xf0003c0,0x781e003,0xc71c7800,0x3ef00000,0x78000007,0xc000003c,0x1e0,0x1e0,0x0, 0x0,0x0,0x1ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e, 0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7ff80,0x3c000,0x3c003c0,0xf00f003,0xc1f07800,0x1fc0000f,0x1e00000,0xf8000ff0,0xf0, 0xff,0xffffff,0x80000000,0x3fffc000,0xfff9fe00,0x0,0xf000000,0x0,0x18,0xc0,0x0,0x1f0000,0x1fc0,0x1c00003,0xc00f000f,0xff9fe000, 0x7c0003ff,0xe7f81fff,0x3fc00000,0x0,0x0,0x0,0xfe000,0x1ffffc0f,0xfffffc00,0x0,0xff,0xf0000000,0x700f007f,0xff0fff9f,0xe0000f80, 0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00fff,0xffc00000,0xf800,0xf0000000,0x6380000,0xc0ffff80,0x3e078000,0x1e00,0x7ff80303, 0x83c06000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000,0x0,0x7f,0xff00001e,0x7c1fff0,0xfff80,0x7ffc00,0x3f0000,0x7c01f00, 0x3e00f801,0xf007c00f,0x803e007c,0x1f003e0,0xf803c07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001, 0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f8001e,0x3c03c0f0,0x3c0780,0x1e03c00,0xf01e000, 0x78000780,0x1e001f,0xf07f80,0x3ffff80,0x1ffffc00,0xffffe007,0xffff003f,0xfff801ff,0xffc03fff,0xffc0f000,0x1fffff,0xc0fffffe, 0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07, 0xfffffe1e,0x787803c,0x3c01e0,0x1e00f00,0xf007800,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x3ff80fc0,0x7fc1e01f, 0x7800000,0x3c00,0x1e00,0x0,0x7fffff80,0x0,0x7ff80000,0x7,0x80001e00,0x3c0001e,0xfc,0xf,0x1e00780,0x1e0,0x7c000f00,0x78000f, 0x78007,0xff1e0000,0x0,0x3ff00,0x0,0x1ff,0x8003c000,0x781e0070,0x3c007803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007, 0x80007800,0x780,0x3c07c000,0x7800001e,0x7c0f078,0xf1e03c0,0x780780,0xf000,0x1e07801f,0x3e,0xf000,0xf0003c0,0x781e003,0xcf1c7800, 0x3cf80000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0,0x0,0x0,0x3ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007, 0x80003c00,0xf000,0x7ff8000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3fff0,0x3c000,0x3c003c0,0xf81f003, 0xc3b87800,0xf80000f,0x1e00001,0xf0000ff0,0xf0,0xff,0xf03fff,0x80000000,0x3fff8001,0xfff1ff00,0x0,0xf000000,0x0,0x18,0xc0, 0x0,0x380000,0x7c0,0x3c00003,0xc00f001f,0xff1ff000,0xf80007ff,0xc7fc3ffe,0x3fe00000,0x0,0x0,0x0,0x1ff000,0x7ffffe1f,0xffffff00, 0x0,0x7f,0xfe000000,0x780f007f,0xff1fff1f,0xf0001f00,0x1e000,0x0,0x780001,0xe0180000,0xf000001c,0xe00fff,0xffc00000,0x7c00, 0xf0000000,0x31c0001,0x80ffff80,0x3e078000,0x1e00,0x7ff80183,0x81c0c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000, 0x0,0x7f,0xff00001e,0x7c7ff03,0xc03ff8fe,0x1ffc0f0,0x7e0000,0x7800f00,0x3c007801,0xe003c00f,0x1e0078,0xf003c0,0x7803c07,0x8003c000, 0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c, 0xf0001e0,0x78000f00,0x3fc001e,0x7803c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e007f,0xf03fe0,0x7ffff80,0x3ffffc01, 0xffffe00f,0xffff007f,0xfff803ff,0xffc07fff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000, 0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x707803c,0x3c01e0,0x1e00f00,0xf007800, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x30f81f00,0xffe1e00f,0x87800000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000, 0x7,0x80001e00,0x3c0001e,0x1f8,0x7,0x83c00780,0x1e0,0x7c000f00,0xf8001e,0x3c001,0xfc1e0000,0x0,0x7fe0,0x0,0xffc,0x3c000,0x781e0070, 0x3ffff803,0xc000783c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x380f078,0xf1e03c0, 0x780780,0xf000,0x1e07800f,0x8000001e,0xf000,0xf0003c0,0x3c3c003,0xcf1e7800,0x7c780000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0, 0x0,0x0,0x7f003c01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7f7c000,0x1e0000f,0x3c0f01e, 0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfff8,0x3c000,0x3c003c0,0x781e003,0xc3b87800,0x1fc00007,0x83e00003,0xe0000ff8,0xf0, 0x1ff,0xc007fe,0x0,0x7fff8001,0xffe3ff00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x3c0,0x7800003,0xc00f001f,0xfe3ff000,0xf80007ff, 0x8ffc3ffc,0x7fe00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x1f,0xff000000,0x3c0f007f,0xff1ffe3f,0xf0003e00,0x1e000,0x0,0x780001, 0xe0180000,0xf000001e,0x1e00fff,0xffc00000,0x3f00,0xf0000000,0x31c0001,0x80ffff80,0x1f03c000,0x1e00,0x7ff80183,0x81c0c000, 0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x7f,0xff00003c,0xf87f007,0xc03f83ff,0x81fc01f0,0x7c0000,0x7ffff00,0x3ffff801, 0xffffc00f,0xfffe007f,0xfff003ff,0xff807fff,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001, 0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf003c0f0,0x3c0780,0x1e03c00,0xf01e000, 0x78000780,0x1ffffe,0xf00ff0,0xfe00780,0x7f003c03,0xf801e01f,0xc00f00fe,0x7807f0,0x3c0ffff,0xffc0f000,0x1fffff,0xc0fffffe, 0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00, 0x1e,0xf07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783e,0x1e0007,0x801e0f80,0x0,0x0,0x0,0x0,0x0,0x0,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,0x1ff,0xffff8000,0x307c0801,0xe1f1e00f,0x87000000, 0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000,0xf,0x1e00,0x3c0001e,0x3f0,0x7,0x83fffffc,0x1e0,0x7c000f00,0xf0001e,0x3c000,0x3e0000, 0x0,0x1ffc,0x1fffff,0xf0007ff0,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x3c000,0x781e0007,0x80007800, 0x780,0x3c03e000,0x7800001e,0xf078,0x79e03c0,0x780780,0xf000,0x1e078007,0x8000000f,0xf000,0xf0003c0,0x3c3c001,0xee0ef000, 0xf87c0000,0x7800001f,0x3c,0x78,0x1e0,0x0,0x0,0x0,0x7c003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00, 0xf000,0x7e3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x1ffc,0x3c000,0x3c003c0,0x781e003,0xe3b8f800, 0x1fc00007,0x83c00007,0xc00000fc,0xf0,0x3e0,0x8001f8,0x0,0x7800000,0xffc7fe00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0, 0xf000003,0xc00f000f,0xfc7fe001,0xf00003ff,0x1ff81ff8,0xffc00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x3,0xff800000,0x1e0f0078, 0xffc7f,0xe0007c00,0x1e000,0x0,0x780001,0xe0180000,0xf000000e,0x1c00007,0x80000000,0x1f81,0xe0000000,0x38e0003,0x80000000, 0xf81f000,0x1e00,0x7ff801c3,0x80e1c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf8,0x1f070007,0xc03803ff,0xc1c001f0, 0xf80000,0xfffff00,0x7ffff803,0xffffc01f,0xfffe00ff,0xfff007ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000, 0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f00f,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e,0xf003c0f0, 0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1ffffc,0xf003f8,0xf800780,0x7c003c03,0xe001e01f,0xf00f8,0x7807c0,0x3c0fc1e,0xf000, 0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078, 0xf0003c0,0x78001e00,0x1e,0x1e07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783c,0x1e0007,0x801e0f00,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,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, 0xc071e007,0xcf000000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0xf,0xf00,0x780001e,0x7e0,0x7,0x83fffffc,0x1e0,0x7c000f00,0x1f0001e, 0x3c000,0x3c0000,0x0,0x3ff,0x801fffff,0xf003ff80,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007, 0x80007800,0x780,0x3c01f000,0x7800001e,0xf078,0x79e03c0,0xf00780,0xf000,0x3e078007,0xc000000f,0xf000,0xf0003c0,0x3c3c001, 0xee0ef000,0xf03e0000,0x7800003e,0x3c,0x78,0x1e0,0x0,0x0,0x0,0xf8003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007, 0x80003c00,0xf000,0x7c3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfc,0x3c000,0x3c003c0,0x3c3e001,0xe7b8f000, 0x3fe00007,0xc7c0000f,0xc000003e,0xf0,0x7c0,0x0,0x0,0x7c00000,0x7fcffc00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0,0x1e000003, 0xc00f0007,0xfcffc003,0xe00001ff,0x3ff00ff9,0xff800000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x1f800000,0xf0f0078,0x7fcff, 0xc000fc00,0x1e000,0x0,0x780001,0xe0180000,0xf000000f,0x87c00007,0x80000000,0xfe3,0xe0000000,0x18780c3,0x0,0x7c0f800,0x1e00, 0xc3,0x80e18000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x1f0,0x3e00000f,0xc0000303,0xe00003f0,0xf00000,0xfffff80, 0x7ffffc03,0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000, 0x3c000001,0xe0001e00,0x780f00f,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1f0f801f,0xe00780f0,0x3c0780,0x1e03c00, 0xf01e000,0x78000780,0x1ffff8,0xf000f8,0x1f000780,0xf8003c07,0xc001e03e,0xf01f0,0x780f80,0x3c1f01e,0xf000,0x1e0000,0xf00000, 0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00, 0x1e,0x3c07803c,0x3c01e0,0x1e00f00,0xf007800,0x78007c7c,0x1e0007,0x801f1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x81c00000,0x303c0003,0x8039e003,0xef000000, 0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0xfc0,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000, 0x0,0x7f,0xe01fffff,0xf00ffc00,0x3c000,0x781f00f0,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007,0x80007800, 0x780,0x3c01f000,0x7800001e,0xf078,0x7de01e0,0xf00780,0x7800,0x3c078003,0xc000000f,0xf000,0xf0003c0,0x3e7c001,0xee0ef001, 0xf01e0000,0x7800003e,0x3c,0x3c,0x1e0,0x0,0x0,0x0,0xf0003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00, 0xf000,0x781f000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0x7df00003, 0xc780000f,0x8000003e,0xf0,0x780,0x0,0x0,0x3c00000,0x3fcff800,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x1f00fc,0x1e0,0x1e000001, 0xe00f0003,0xfcff8003,0xe00000ff,0x3fe007f9,0xff000000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x7c00000,0xf0f0078,0x3fcff,0x8000f800, 0x1e000,0x0,0x780001,0xe0180000,0xf000001f,0xffe00007,0x8000003c,0x7ff,0xc0000000,0x1c3ffc7,0x0,0x3e07c00,0x1e00,0xe3,0x80738000, 0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x3e0,0x7c00001d,0xc0000001,0xe0000770,0x1f00000,0xfffff80,0x7ffffc03, 0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001, 0xe0001e00,0x780f00f,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0x3e07c01f,0xc00780f0,0x3c0780,0x1e03c00,0xf01e000, 0x78000780,0x1fffc0,0xf0007c,0x1e000780,0xf0003c07,0x8001e03c,0xf01e0,0x780f00,0x3c1e01e,0xf000,0x1e0000,0xf00000,0x7800000, 0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1e,0x7807803c, 0x3c01e0,0x1e00f00,0xf007800,0x78003c78,0x1e0007,0x800f1e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x83c00000,0x303c0003,0x8039e001,0xee000000,0x1e00,0x3c00, 0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0x1f80,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000,0x0,0x1f,0xfc1fffff, 0xf07ff000,0x0,0x780f00f0,0x78003c03,0xc000781e,0x1e0,0xf803c0,0x1e00,0x1e000,0x781e0007,0x80007800,0x780,0x3c00f800,0x7800001e, 0xf078,0x3de01e0,0xf00780,0x7800,0x3c078003,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfe0ff003,0xe01f0000,0x7800007c,0x3c,0x3c, 0x1e0,0x0,0x0,0x0,0xf0007c01,0xe000f80f,0x800001e0,0xf80f00,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x780f800,0x1e0000f, 0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003c00,0x1e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0xf8f80003,0xe780001f,0x1e, 0xf0,0x780,0x0,0x0,0x3c00000,0x1ffff000,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x3bc1de,0x1e0,0xf000001,0xe00f0001,0xffff0007,0xc000007f, 0xffc003ff,0xfe000000,0x0,0x0,0x0,0xfe000,0x0,0x0,0x0,0x0,0x3c00000,0x1e0f0078,0x1ffff,0x1f000,0x1e000,0x0,0x780000,0xf0180000, 0xf000001f,0xfff00007,0x8000003c,0x1ff,0x80000000,0xe0ff0e,0x0,0x1f03e00,0x1e00,0x70,0x70000,0x0,0x78,0x0,0x0,0x0,0x3c003c0, 0xe1c00,0x0,0x0,0x0,0x7c0,0xf8000019,0xc0000000,0xe0000670,0x1e00000,0xf000780,0x78003c03,0xc001e01e,0xf00f0,0x780780,0x3c0f807, 0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf80f007,0xbc03c001,0xe01e000f, 0xf00078,0x78003c0,0x3c001e00,0x7c03e00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80, 0xf0007c07,0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0xf800,0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000, 0xf0001e00,0x7803c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1f8001f,0xf00f803c,0x3c01e0,0x1e00f00,0xf007800, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x3c00000,0x303c0003,0x8039f001,0xfe000000,0x1e00,0x3c00,0x0,0x1e0000,0x0,0x0,0x3c,0xf00, 0x780001e,0x3f00,0x7,0x80000780,0x3e0,0x3e000f00,0x3c0001e,0x3c000,0x7c0000,0x0,0x3,0xfe000000,0xff8000,0x0,0x3c0f81f0,0xf0001e03, 0xc000780f,0x1e0,0xf003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x780,0x3c007c00,0x7800001e,0xf078,0x3de01e0,0xf00780,0x7800, 0x3c078001,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfc07f003,0xe00f0000,0x78000078,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01, 0xf000f007,0x800000f0,0xf80780,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0, 0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78001,0xe71df000,0xf8f80001,0xef80003e,0x1e,0xf0,0x780,0x0,0x0,0x3c00000, 0xfffe000,0x0,0x3e000000,0x0,0x18,0x7fff,0xc0000000,0x60c306,0x1e0,0x7800001,0xe00f0000,0xfffe0007,0x8000003f,0xff8001ff, 0xfc000000,0x0,0x0,0x0,0x7c000,0x0,0x0,0x0,0x0,0x3c00000,0x3c0f0078,0xfffe,0x3e000,0x1e000,0x0,0x780000,0xf0180000,0xf000003c, 0xfcf80007,0x8000003c,0x7f,0x0,0x70001c,0x0,0xf81f00,0x0,0x38,0xe0000,0x0,0x0,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf81, 0xf0000039,0xc0000000,0xe0000e70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,0x8000f000,0x78000, 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f007,0xbc03c001,0xe01e000f,0xf00078,0x78003c0, 0x3c001e00,0xf801f00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07,0x8003e03c, 0x1f01e0,0xf80f00,0x7c1e01e,0x7800,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00, 0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xe00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef8,0x1f000f, 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, 0x0,0x0,0xf,0x3c00000,0x307c0003,0x8038f000,0xfc000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e00003c,0x780,0xf00001e, 0x7e00,0xf,0x80000780,0x3c0,0x3e001e00,0x3c0001f,0x7c000,0x780007,0xe000003f,0x0,0xfe000000,0xfe0000,0x0,0x3c07c3f0,0xf0001e03, 0xc000f80f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x4000f80,0x3c003c00,0x7800001e,0xf078,0x1fe01f0,0x1f00780, 0x7c00,0x7c078001,0xf000001f,0xf000,0xf0003c0,0x1e78001,0xfc07f007,0xc00f8000,0x780000f8,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01, 0xf000f007,0xc00000f0,0xf80780,0x3c,0x1f003,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0, 0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78000,0xfe0fe001,0xf07c0001,0xef00007c,0x1e,0xf0,0x780,0x0,0x0,0x1e00000, 0x7cfc000,0xfc00000,0x3c00000f,0xc3f00000,0x18,0x7fff,0xc0000000,0x406303,0x3e0,0x3c00001,0xf00f0000,0x7cfc000f,0x8000001f, 0x3f0000f9,0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x780700f8,0x7cfc,0x7c000,0x1e000,0x0,0x780000,0xf8180000, 0xf0000070,0x3c0007,0x8000003c,0x3f,0x80000000,0x3c0078,0x0,0x780f00,0x0,0x1e,0x3c0000,0x0,0x0,0x0,0x0,0x0,0x3e007c0,0xe1c00, 0x0,0x0,0x0,0xf01,0xe0000071,0xc0000000,0xe0001c70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007, 0x8000f800,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00f003,0xfc03e003,0xe01f001f, 0xf800f8,0x7c007c0,0x3e003e01,0xf000f80f,0xf00f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07, 0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0x7c00,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00, 0xf003c00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xc00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef0, 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, 0x0,0x0,0x0,0x0,0x780000,0xf,0x3800040,0x30780003,0x8038f800,0x78000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078, 0x780,0x1f00001e,0xfc00,0x20001f,0x780,0x80007c0,0x1f001e00,0x7c0000f,0x78000,0xf80007,0xe000003f,0x0,0x1e000000,0xf00000, 0x3c000,0x3c03fff0,0xf0001e03,0xc001f007,0x800101e0,0x7e003c0,0x1e00,0x7800,0x781e0007,0x80007800,0x6000f00,0x3c003e00,0x7800001e, 0xf078,0x1fe00f0,0x1e00780,0x3c00,0x78078000,0xf020001e,0xf000,0x7800780,0xff0001,0xfc07f00f,0x8007c000,0x780001f0,0x3c,0xf, 0x1e0,0x0,0x0,0x0,0xf800fc01,0xf801f007,0xc00100f8,0x1f807c0,0x40003c,0xf807,0xf0078007,0x80003c00,0xf000,0x7803e00,0x1f0000f, 0x3c0f01e,0x1e01f0,0x3e007e0,0x7c07c00,0xfc003c00,0x1e,0x3e000,0x3e007c0,0x1ff8000,0xfe0fe003,0xe03e0001,0xff0000fc,0x1e, 0xf0,0x780,0x0,0x0,0x1f00080,0x3cf8000,0xfc00000,0x3c00001f,0x83f00000,0x18,0xc0,0x0,0xc06203,0x40003c0,0x1c00000,0xf80f0000, 0x3cf8001f,0xf,0x3e000079,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x700780fc,0x3cf8,0xfc000,0x1e000,0x0,0x780000, 0x7c180000,0xf0000020,0x100007,0x8000003c,0xf,0x80000000,0x1f01f0,0x0,0x380700,0x0,0xf,0x80f80000,0x0,0x0,0x0,0x0,0x0,0x3e007c0, 0xe1c00,0x0,0x0,0x0,0xe01,0xc0000071,0xc0000001,0xc0001c70,0x1e00040,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007, 0x80007800,0x10078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00f003,0xfc01e003,0xc00f001e, 0x7800f0,0x3c00780,0x1e003c00,0xe000700f,0x800f0078,0x7803c0,0x3c01e00,0x1e00f000,0xf0000780,0x1e0000,0xf0003c,0x1f001f80, 0xf800fc07,0xc007e03e,0x3f01f0,0x1f80f80,0xfc1e01f,0x7c00,0x100f8000,0x807c0004,0x3e00020,0x1f000100,0x780000,0x3c00000,0x1e000000, 0xf0000f80,0x1f003c00,0x3c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00,0x1f8000f,0x801f003e,0x7c01f0,0x3e00f80,0x1f007c00, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0xf,0x7800078,0x31f80001,0xc070fc00,0xfc000000,0x1e00,0x7c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078, 0x7c0,0x1f00001e,0x1f000,0x38003f,0x780,0xe000f80,0x1f803e00,0x780000f,0x800f8000,0x1f00007,0xe000003f,0x0,0x2000000,0x800000, 0x3c000,0x3e01ff71,0xf0001f03,0xc007f007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x781e0007,0x80007800,0x7801f00,0x3c001f00,0x7800001e, 0xf078,0xfe00f8,0x3e00780,0x3e00,0xf8078000,0xf838003e,0xf000,0x7c00f80,0xff0000,0xfc07e00f,0x8003c000,0x780001e0,0x3c,0xf, 0x1e0,0x0,0x0,0x0,0xf801fc01,0xfc03e003,0xe003007c,0x3f803e0,0x1c0003c,0xfc0f,0xf0078007,0x80003c00,0xf000,0x7801f00,0xf8000f, 0x3c0f01e,0x1e00f8,0x7c007f0,0xf803e01,0xfc003c00,0x8003e,0x1f000,0x1e00fc0,0xff0000,0xfe0fe007,0xc01f0000,0xfe0000f8,0x1e, 0xf0,0x780,0x0,0x0,0xf80180,0x1cf0000,0x1f800000,0x3c00001f,0x83e00000,0x18,0xc0,0x0,0xc06203,0x70007c0,0xe00000,0x7e0f0000, 0x1cf0001e,0x7,0x3c000039,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x7c00000,0xe00780fc,0x2001cf0,0xf8000,0x1e000,0x0, 0x780000,0x7e182000,0xf0000000,0x7,0x8000003c,0x7,0xc0000000,0x7ffc0,0x0,0x180300,0x0,0x3,0xffe00000,0x0,0x0,0x0,0x0,0x0, 0x3f00fc0,0xe1c00,0x0,0x0,0x0,0xc01,0x800000e1,0xc0000003,0xc0003870,0x1f001c0,0x3e0003e1,0xf0001f0f,0x8000f87c,0x7c3e0,0x3e1f00, 0x1f1e007,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e03,0xfc00f001,0xfc01f007, 0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x4000201f,0xc01f007c,0xf803e0,0x7c01f00,0x3e00f801,0xf0000780,0x1e0000,0xf0007c, 0x1f003f80,0xf801fc07,0xc00fe03e,0x7f01f0,0x3f80f80,0x1fc1f03f,0x803e00,0x3007c003,0x803e001c,0x1f000e0,0xf800700,0x780000, 0x3c00000,0x1e000000,0xf00007c0,0x3e003c00,0x3c01f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e001e,0xfc00f0, 0x7e00780,0x3f003c01,0xf8000fe0,0x1fc03e,0x3f800,0x0,0x0,0x0,0x0,0x0,0x0,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,0xfff00001,0xe0f07f03,0xfe000000,0xf00,0x7800,0x0, 0x1e0000,0xfc0000,0x0,0x7e0000f0,0x3f0,0x7e000fff,0xfc03ffff,0xf83f00fe,0x780,0xfc03f80,0xfc0fc00,0xf800007,0xe03f0018,0x7e00007, 0xe000003f,0x0,0x0,0x0,0x3c000,0x1e007c71,0xe0000f03,0xffffe003,0xf01f01ff,0xff8003ff,0xffe01e00,0x3f01,0xf81e0007,0x803ffff0, 0x7e03f00,0x3c000f00,0x7ffffe1e,0xf078,0xfe007e,0xfc00780,0x1f83,0xf0078000,0x783f00fe,0xf000,0x3f03f00,0xff0000,0xfc07e01f, 0x3e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7e07fc01,0xfe07e001,0xf80f007e,0x7f801f8,0xfc0003c,0x7ffe,0xf0078007, 0x807ffffe,0xf000,0x7801f00,0xfff00f,0x3c0f01e,0x1e00fc,0xfc007f8,0x1f803f03,0xfc003c00,0xf80fc,0x1fff0,0x1f83fc0,0xff0000, 0xfc07e007,0xc01f0000,0xfe0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfe0780,0xfe0000,0x1f000000,0x3c00001f,0x7c00e03,0x81c00018, 0xc0,0x0,0x406203,0x7e01fc0,0x700000,0x7fffff80,0xfe0003f,0xffffc003,0xf800001f,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0, 0x1f800001,0xc007c1fe,0x6000fe0,0x1ffffe,0x1e000,0x0,0x780000,0x3f98e03f,0xffff8000,0x7,0x8000003c,0x7,0xc0000000,0xfe00, 0x0,0x80100,0x0,0x0,0x7f000000,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3f83fe8,0xe1c00,0x0,0x0,0x0,0x801,0xc1,0xc0000007,0x80003070, 0xfc0fc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc03f01,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003, 0xffff001f,0xfff800ff,0xffc01fff,0xf800f001,0xfc00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800,0x1f,0xf07e003f,0x3f001f8, 0x1f800fc0,0xfc007e07,0xe0000780,0x1e0000,0xf301f8,0xfc0ff80,0x7e07fc03,0xf03fe01f,0x81ff00fc,0xff807e0,0x7fc0f87f,0x81801f80, 0xf003f01f,0x801f80fc,0xfc07e0,0x7e03f00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff807e0,0x7e003c00,0x3c01f81f,0x800fc0fc,0x7e07e0, 0x3f03f00,0x1f81f800,0x1f8000f,0xe07e001f,0x83fc00fc,0x1fe007e0,0xff003f07,0xf8000fe0,0x1fe07e,0x3f800,0x0,0x0,0x0,0x0,0x0, 0x0,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, 0xffe00000,0xffe03fff,0xdf000000,0xf00,0x7800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0x1ff,0xfc000fff,0xfc03ffff,0xf83ffffc,0x780, 0xfffff00,0x7fff800,0xf000007,0xffff001f,0xffe00007,0xe000003f,0x0,0x0,0x0,0x3c000,0x1e000001,0xe0000f03,0xffffc001,0xffff01ff, 0xff0003ff,0xffe01e00,0x1fff,0xf81e0007,0x803ffff0,0x7fffe00,0x3c000f80,0x7ffffe1e,0xf078,0xfe003f,0xff800780,0xfff,0xf0078000, 0x7c3ffffc,0xf000,0x3ffff00,0xff0000,0xf803e01e,0x1e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7fffbc01,0xffffc000, 0xffff003f,0xfff800ff,0xffc0003c,0x3ffe,0xf0078007,0x807ffffe,0xf000,0x7800f80,0x7ff00f,0x3c0f01e,0x1e007f,0xff8007ff,0xff001fff, 0xbc003c00,0xffffc,0x1fff0,0x1fffbc0,0xff0000,0x7c07c00f,0x800f8000,0x7e0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7fff80,0x7c0000, 0x1f000000,0x3c00001e,0x7c00f07,0xc1e00018,0xc0,0x0,0x60e303,0x7ffff80,0x380000,0x3fffff80,0x7c0003f,0xffffc001,0xf000000f, 0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff800003,0x8003ffff,0xfe0007c0,0x1ffffe,0x1e000,0x0,0x780000,0x1fffe03f,0xffff8000, 0x7,0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3fffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x1c1, 0xc000000f,0x7070,0x7fffc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0, 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000f001,0xfc007fff,0x3fff8,0x1fffc0,0xfffe00,0x7fff000,0x3b,0xfffc003f, 0xfff001ff,0xff800fff,0xfc007fff,0xe0000780,0x1e0000,0xf3fff8,0xffff780,0x7fffbc03,0xfffde01f,0xffef00ff,0xff7807ff,0xfbc0ffff, 0xff800fff,0xf001ffff,0x800ffffc,0x7fffe0,0x3ffff00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff803ff,0xfc003c00,0x3c00ffff,0x7fff8, 0x3fffc0,0x1fffe00,0xffff000,0x1f,0xfffc001f,0xffbc00ff,0xfde007ff,0xef003fff,0x780007e0,0x1ffffc,0x1f800,0x0,0x0,0x0,0x0, 0x0,0x0,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, 0xffc00000,0x7fc01fff,0x9f800000,0xf80,0xf800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0xff,0xf8000fff,0xfc03ffff,0xf83ffff8,0x780, 0xffffe00,0x7fff000,0xf000003,0xfffe001f,0xffc00007,0xe000003f,0x0,0x0,0x0,0x3c000,0xf000003,0xe0000f83,0xffff0000,0xffff01ff, 0xfc0003ff,0xffe01e00,0xfff,0xf01e0007,0x803ffff0,0x7fffc00,0x3c0007c0,0x7ffffe1e,0xf078,0x7e003f,0xff000780,0x7ff,0xe0078000, 0x3c3ffff8,0xf000,0x1fffe00,0x7e0000,0xf803e03e,0x1f000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x3fff3c01,0xefff8000, 0x7ffe001f,0xff78007f,0xff80003c,0x1ffc,0xf0078007,0x807ffffe,0xf000,0x78007c0,0x3ff00f,0x3c0f01e,0x1e003f,0xff0007bf,0xfe000fff, 0xbc003c00,0xffff8,0xfff0,0xfff3c0,0x7e0000,0x7c07c01f,0x7c000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3fff80,0x380000, 0x3e000000,0x7c00003e,0x7801f07,0xc1e00018,0xc0,0x0,0x39c1ce,0x7ffff00,0x1c0000,0xfffff80,0x380003f,0xffffc000,0xe0000007, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff000007,0x1ffcf,0xfe000380,0x1ffffe,0x1e000,0x0,0x780000,0xfffe03f,0xffff8000,0x7, 0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x381, 0xc000001e,0xe070,0x7fff80,0x7c0001f3,0xe0000f9f,0x7cf8,0x3e7c0,0x1f3e00,0xfbe007,0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0, 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000f000,0xfc007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x79,0xfff8001f, 0xffe000ff,0xff0007ff,0xf8003fff,0xc0000780,0x1e0000,0xf3fff0,0x7ffe780,0x3fff3c01,0xfff9e00f,0xffcf007f,0xfe7803ff,0xf3c07ff3, 0xff8007ff,0xe000ffff,0x7fff8,0x3fffc0,0x1fffe00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff801ff,0xf8003c00,0x3c007ffe,0x3fff0, 0x1fff80,0xfffc00,0x7ffe000,0x1d,0xfff8000f,0xff3c007f,0xf9e003ff,0xcf001ffe,0x780007c0,0x1efff8,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,0x0,0x0,0x0,0x0,0x780000,0x1e,0xf000003, 0xfe000000,0x1f000fff,0xfc00000,0x780,0xf000,0x0,0x0,0xf80000,0x0,0x7e0001e0,0x7f,0xf0000fff,0xfc03ffff,0xf81ffff0,0x780, 0x7fff800,0x1ffe000,0x1f000000,0xfff8001f,0xff000007,0xe000003e,0x0,0x0,0x0,0x3c000,0xf800003,0xc0000783,0xfff80000,0x3ffe01ff, 0xe00003ff,0xffe01e00,0x7ff,0xc01e0007,0x803ffff0,0x3fff800,0x3c0003c0,0x7ffffe1e,0xf078,0x7e000f,0xfe000780,0x3ff,0xc0078000, 0x3e1fffe0,0xf000,0x7ff800,0x7e0000,0xf803e07c,0xf800,0x780003ff,0xfffc003c,0x3,0xc00001e0,0x0,0x0,0x0,0xffe3c01,0xe7ff0000, 0x3ffc000f,0xfe78003f,0xfe00003c,0x7f0,0xf0078007,0x807ffffe,0xf000,0x78003e0,0xff00f,0x3c0f01e,0x1e001f,0xfe00079f,0xfc0007ff, 0x3c003c00,0x7ffe0,0x1ff0,0x7fe3c0,0x7e0000,0x7c07c03e,0x3e000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfff00,0x100000, 0x3e000000,0x7800003c,0xf800f07,0xc1e00018,0xc0,0x0,0x1f80fc,0x3fffc00,0xc0000,0x3ffff80,0x100003f,0xffffc000,0x40000002, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xfc000006,0xff87,0xfc000100,0x1ffffe,0x1e000,0x0,0x780000,0x3ffc03f,0xffff8000,0x7, 0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dff9f8,0xe1c00,0x0,0x0,0x0,0x0,0x3ff, 0xf800003c,0xfffe,0x1ffe00,0x780000f3,0xc000079e,0x3cf0,0x1e780,0xf3c00,0x7bc007,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0, 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc,0xf000,0xfc001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x70,0xfff00007, 0xff80003f,0xfc0001ff,0xe0000fff,0x780,0x1e0000,0xf3ffe0,0x1ffc780,0xffe3c00,0x7ff1e003,0xff8f001f,0xfc7800ff,0xe3c03fe1, 0xff0003ff,0xc0007ffc,0x3ffe0,0x1fff00,0xfff800,0xfffffc07,0xffffe03f,0xffff01ff,0xfff800ff,0xf0003c00,0x3c003ffc,0x1ffe0, 0xfff00,0x7ff800,0x3ffc000,0x38,0xfff00007,0xfe3c003f,0xf1e001ff,0x8f000ffc,0x780007c0,0x1e7ff0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000, 0x1fc,0x0,0x780,0xf000,0x0,0x0,0x1f80000,0x0,0x1e0,0x1f,0xc0000000,0x0,0x1ff80,0x0,0xffc000,0x7f8000,0x0,0x3fe00007,0xfc000000, 0x7e,0x0,0x0,0x0,0x0,0x7c00000,0x0,0x0,0xff00000,0x0,0x0,0xfe,0x0,0x0,0x3fc000,0x0,0x0,0x0,0x3,0xf8000000,0xff,0xc0000000, 0x1ff00,0x0,0x1fe000,0x0,0x0,0x0,0x0,0x3c,0x3,0xc00001e0,0x0,0x0,0x0,0x3f80000,0x1fc0000,0x7f00003,0xf8000007,0xf0000000, 0x0,0xf0000000,0x0,0xf000,0x0,0x0,0x0,0x7,0xf8000787,0xf00001fc,0x3c000000,0x7f80,0x0,0x1f8000,0x0,0x0,0x0,0x7c000000,0x1e, 0xf0,0x780,0x0,0x0,0x3fc00,0x0,0x3c000000,0x7800003c,0xf000601,0xc00018,0xc0,0x0,0x0,0x3fe000,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xf0000000,0x7e03,0xf0000000,0x0,0x0,0x0,0x0,0xfe0000,0x0,0x0,0x3c,0x2007,0x80000000,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c7e0f0,0xe1c00,0x0,0x3800000,0x0,0x0,0x3ff,0xf8000078,0xfffe,0x7f800,0x0,0x0,0x0,0x0, 0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000,0x7f0000,0x70,0x3fc00001,0xfe00000f,0xf000007f, 0x800003fc,0x0,0x0,0xff00,0x7f0000,0x3f80000,0x1fc00000,0xfe000007,0xf000003f,0x80001f80,0xfc00007f,0xfe0,0x7f00,0x3f800, 0x1fc000,0x0,0x0,0x0,0x3f,0xc0000000,0xff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x78,0x3fc00001,0xf800000f,0xc000007e,0x3f0,0x7c0, 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, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x78000000,0x1e,0xf0,0x780,0x0,0x0,0x0,0x0,0x3c000000,0x78000078,0xf000000,0x18,0xc0,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,0x0,0x0,0x3c,0x3c0f,0x80000000, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0x1800000,0x0,0x0,0x3ff,0xf80000f0,0xfffe,0x0,0x0,0x0,0x0, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,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,0x3c0,0x1e000,0x0,0x0,0x1f00000,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0x1f80000, 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, 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, 0x1f,0xf0,0xf80,0x0,0x0,0x0,0x0,0x78000000,0xf8000078,0x1e000000,0x8,0x40,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,0x0,0x0,0x3c,0x3fff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 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, 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, 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, 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, 0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x1f,0x800000f0,0x1f80,0x0,0x0,0x0,0x0, 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, 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, 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, 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, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4003,0xe0000000,0x0,0x1f000,0x0,0x0, 0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x1,0xf0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0x70000001,0xf00000e0, 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, 0x0,0x0,0x3c,0xff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0xe00000,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,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,0x0,0x0,0x0,0x1f00,0x1e0000, 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, 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, 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, 0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780f,0xc0000000,0x0,0x3e000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0, 0x0,0x0,0x0,0x0,0x3,0xe0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0xf0000103,0xe0000000,0x0,0x0,0x0,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,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x21e00000,0x0,0x0,0x1,0xc00003ff,0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10f, 0x0,0x0,0x0,0x0,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, 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, 0x0,0x0,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, 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, 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, 0x0,0x0,0x7fff,0xc0000000,0x0,0x3ffe000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0xe0000000,0x7,0xfc0000f0, 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, 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, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fff,0x80000000,0x0,0x3ffc000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0, 0x0,0x0,0x0,0x0,0x7f,0xc0000000,0x0,0xfc0000f0,0x3f000,0x0,0x0,0x0,0x0,0x1ff,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0x80000000,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x80000000,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0x0,0x3f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fc,0x0, 0x0,0x0,0x0,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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,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,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 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, 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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,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, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 }; const unsigned char logo40x38[4576] = { 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 200,200,200,91,49,124,118,124,71,32,124,95,49,56,114,52,82,121,0}; inline void warn(const char *format, ...) { if (cimg::exception_mode()>=1) { char message[8192]; std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(message,format,ap); __builtin_va_end(ap); std::fprintf(stderr,"\n %s\n",message); } } inline int xln(const int x) { return x>0?(int)(1+std::log10((double)x)):1; } inline char uncase(const char x) { return (char)((x<'A'||x>'Z')?x:x-'A'+'a'); } inline float atof(const char *str) { float x = 0,y = 1; if (!str) return 0; else { std::sscanf(str,"%g/%g",&x,&y); return x/y; } } inline int strlen(const char *s) { if (s) { int k; for (k=0; s[k]; ++k) ; return k; } return -1; } inline int strncmp(const char *s1, const char *s2, const int l) { if (s1 && s2) { int n = 0; for (int k=0; k=0 && s[l]!=c; --l) ; return l; } return -1; } inline const char* basename(const char *s) { return (1!=2)?(s?s+1+cimg::strfind(s,'/'):0):(s?s+1+cimg::strfind(s,'\\'):0); } inline bool endian() { const int x=1; return ((unsigned char*)&x)[0]?false:true; } inline unsigned long time() { struct timeval st_time; gettimeofday(&st_time,0); return (unsigned long)(st_time.tv_usec/1000 + st_time.tv_sec*1000); } inline void sleep(const unsigned int milliseconds) { struct timespec tv; tv.tv_sec = milliseconds/1000; tv.tv_nsec = (milliseconds%1000)*1000000; nanosleep(&tv,0); } inline unsigned int wait(const unsigned int milliseconds, unsigned long& timer) { if (!timer) timer = cimg::time(); const unsigned long current_time = cimg::time(); if (current_time>=timer+milliseconds) { timer = current_time; return 0; } const unsigned long time_diff = timer + milliseconds - current_time; timer = current_time + time_diff; cimg::sleep(time_diff); return (unsigned int)time_diff; } inline unsigned int wait(const unsigned int milliseconds) { static unsigned long timer = 0; if (!timer) timer = cimg::time(); return wait(milliseconds,timer); } inline void srand() { static bool first_time = true; if (first_time) { std::srand(cimg::time()); unsigned char *const rand_mem = new unsigned char[1+std::rand()%2048]; std::srand((unsigned int)(std::rand() + (unsigned long)rand_mem)); delete[] rand_mem; first_time = false; } } inline const char* filenamerand() { static char id[9] = { 0,0,0,0,0,0,0,0,0 }; cimg::srand(); for (unsigned int k=0; k<8; k++) { const int v = (int)std::rand()%3; id[k] = (char)(v==0?('0'+(std::rand()%10)):(v==1?('a'+(std::rand()%26)):('A'+(std::rand()%26)))); } return id; } inline void system(const char *command, const char *module_name=0) { std::system(command); command = module_name = 0; } inline void winformat_string(char *const) {} inline const char* imagemagick_path() { static char *st_imagemagick_path = 0; if (!st_imagemagick_path) { st_imagemagick_path = new char[1024]; std::memset(st_imagemagick_path,0,1024); bool path_found = false; std::FILE *file = 0; if (!path_found) { std::sprintf(st_imagemagick_path,"./convert"); if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; } } if (!path_found) std::strcpy(st_imagemagick_path,"convert"); winformat_string(st_imagemagick_path); } return st_imagemagick_path; } inline const char* graphicsmagick_path() { static char *st_graphicsmagick_path = 0; if (!st_graphicsmagick_path) { st_graphicsmagick_path = new char[1024]; std::memset(st_graphicsmagick_path,0,1024); bool path_found = false; std::FILE *file = 0; if (!path_found) { std::sprintf(st_graphicsmagick_path,"./gm"); if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; } } if (!path_found) std::strcpy(st_graphicsmagick_path,"gm"); winformat_string(st_graphicsmagick_path); } return st_graphicsmagick_path; } inline const char* medcon_path() { static char *st_medcon_path = 0; if (!st_medcon_path) { st_medcon_path = new char[1024]; std::memset(st_medcon_path,0,1024); bool path_found = false; std::FILE *file = 0; if (!path_found) { std::sprintf(st_medcon_path,"./medcon"); if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; } } if (!path_found) std::strcpy(st_medcon_path,"medcon"); winformat_string(st_medcon_path); } return st_medcon_path; } inline const char* temporary_path() { static char *st_temporary_path = 0; if (!st_temporary_path) { st_temporary_path = new char[1024]; std::memset(st_temporary_path,0,1024); bool path_found = false; char tmp[1024], filetmp[512]; std::FILE *file = 0; std::sprintf(filetmp,"%s.tmp",cimg::filenamerand()); char *tmpPath = getenv("TMP"); if (tmpPath==__null) { tmpPath = getenv("TEMP"); winformat_string(tmpPath); } if (tmpPath!=__null) if (!path_found) { std::sprintf(st_temporary_path,"%s",tmpPath); std::sprintf(tmp,"%s%s%s",st_temporary_path,1==2?"\\":"/",filetmp); if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; } }; if (!path_found) { std::sprintf(st_temporary_path,"%s","/tmp"); std::sprintf(tmp,"%s%s%s",st_temporary_path,1==2?"\\":"/",filetmp); if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; } }; if (!path_found) { std::sprintf(st_temporary_path,"%s","/var/tmp"); std::sprintf(tmp,"%s%s%s",st_temporary_path,1==2?"\\":"/",filetmp); if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; } }; if (!path_found) { st_temporary_path[0]='\0'; std::strcpy(tmp,filetmp); if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; } } if (!path_found) throw CImgIOException("cimg::temporary_path() : Unable to find a temporary path accessible for writing\n" "you have to set the macro 'cimg_temporary_path' to a valid path where you have writing access :\n" "#define cimg_temporary_path \"path\" (before including 'CImg.h')"); } return st_temporary_path; } inline const char *filename_split(const char *const filename, char *const body=0) { if (!filename) { if (body) body[0]='\0'; return 0; } int l = cimg::strfind(filename,'.'); if (l>=0) { if (body) { std::strncpy(body,filename,l); body[l]='\0'; }} else { if (body) std::strcpy(body,filename); l=(int)std::strlen(filename)-1; } return filename+l+1; } inline char* filename_number(const char *const filename, const int number, const unsigned int n, char *const string) { if (!filename) { if (string) string[0]='\0'; return 0; } char format[1024],body[1024]; const char *ext = cimg::filename_split(filename,body); if (n>0) std::sprintf(format,"%s_%%.%ud.%s",body,n,ext); else std::sprintf(format,"%s_%%d.%s",body,ext); std::sprintf(string,format,number); return string; } inline std::FILE *fopen(const char *const path, const char *const mode) { if(!path || !mode) throw CImgArgumentException("cimg::fopen() : File '%s' cannot be opened with mode '%s'.", path?path:"(null)",mode?mode:"(null)"); if (path[0]=='-') return (mode[0]=='r')?stdin:stdout; std::FILE *dest = std::fopen(path,mode); if (!dest) throw CImgIOException("cimg::fopen() : File '%s' cannot be opened%s", path,mode[0]=='r'?" for reading.":(mode[0]=='w'?" for writing.":"."),path); return dest; } inline int fclose(std::FILE *file) { if (!file) warn("cimg::fclose() : Can't close (null) file"); if (!file || file==stdin || file==stdout) return 0; const int errn = std::fclose(file); if (errn!=0) warn("cimg::fclose() : Error %d during file closing",errn); return errn; } template inline int fread(T *const ptr, const unsigned int nmemb, std::FILE *stream) { if (!ptr || nmemb<=0 || !stream) throw CImgArgumentException("cimg::fread() : Can't read %u x %u bytes of file pointer '%p' in buffer '%p'", nmemb,sizeof(T),stream,ptr); const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T); unsigned int toread = nmemb, alread = 0, ltoread = 0, lalread = 0; do { ltoread = (toread*sizeof(T))0); if (toread>0) warn("cimg::fread() : File reading problems, only %u/%u elements read",alread,nmemb); return alread; } template inline int fwrite(const T *ptr, const unsigned int nmemb, std::FILE *stream) { if (!ptr || !stream) throw CImgArgumentException("cimg::fwrite() : Can't write %u x %u bytes of file pointer '%p' from buffer '%p'", nmemb,sizeof(T),stream,ptr); if (nmemb<=0) return 0; const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T); unsigned int towrite = nmemb, alwrite = 0, ltowrite = 0, lalwrite = 0; do { ltowrite = (towrite*sizeof(T))0); if (towrite>0) warn("cimg::fwrite() : File writing problems, only %u/%u elements written",alwrite,nmemb); return alwrite; } template inline void swap(T& a, T& b) { T t = a; a = b; b = t; } template inline void swap(T1& a1, T1& b1, T2& a2, T2& b2) { cimg::swap(a1,b1); cimg::swap(a2,b2); } template inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3) { cimg::swap(a1,b1,a2,b2); cimg::swap(a3,b3); } template inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4) { cimg::swap(a1,b1,a2,b2,a3,b3); cimg::swap(a4,b4); } template inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5) { cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4); cimg::swap(a5,b5); } template 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) { cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5); cimg::swap(a6,b6); } template 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, T7& a7, T7& b7) { cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6); cimg::swap(a7,b7); } template 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, T7& a7, T7& b7, T8& a8, T8& b8) { cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6,a7,b7); cimg::swap(a8,b8); } template inline void endian_swap(T* const buffer, const unsigned int size) { switch (sizeof(T)) { case 1: break; case 2: { for (unsigned short *ptr = (unsigned short*)buffer+size; ptr>(unsigned short*)buffer; ) { const unsigned short val = *(--ptr); *ptr = (unsigned short)((val>>8)|((val<<8))); } } break; case 4: { for (unsigned int *ptr = (unsigned int*)buffer+size; ptr>(unsigned int*)buffer; ) { const unsigned int val = *(--ptr); *ptr = (val>>24)|((val>>8)&0xff00)|((val<<8)&0xff0000)|(val<<24); } } break; default: { for (T* ptr = buffer+size; ptr>buffer; ) { unsigned char *pb = (unsigned char*)(--ptr), *pe = pb + sizeof(T); for (int i=0; i<(int)sizeof(T)/2; ++i) cimg::swap(*(pb++),*(--pe)); } break; } } } template inline T& endian_swap(T& a) { endian_swap(&a,1); return a; } inline const char* option(const char *const name, const int argc, char **argv, const char *defaut, const char *const usage=0) { static bool first = true, visu = false; const char *res = 0; if (first) { first=false; visu = (cimg::option("-h",argc,argv,(char*)0)!=0); visu |= (cimg::option("-help",argc,argv,(char*)0)!=0); visu |= (cimg::option("--help",argc,argv,(char*)0)!=0); } if (!name && visu) { if (usage) { std::fprintf(stderr,"\n %s%s%s",cimg::t_red,cimg::basename(argv[0]),cimg::t_normal); std::fprintf(stderr," : %s",usage); std::fprintf(stderr," (%s, %s)\n\n","Jun 4 2008","19:16:48"); } if (defaut) std::fprintf(stderr,"%s\n",defaut); } if (name) { if (argc>0) { int k = 0; while (k inline const T rol(const T a, const unsigned int n=1) { return n?(T)((a<>((sizeof(T)<<3)-n))):a; } template inline const T ror(const T a, const unsigned int n=1) { return n?(T)((a>>n)|(a<<((sizeof(T)<<3)-n))):a; } template inline T abs(const T a) { return a>=0?a:-a; } inline bool abs(const bool a) { return a; } inline unsigned char abs(const unsigned char a) { return a; } inline unsigned short abs(const unsigned short a) { return a; } inline unsigned int abs(const unsigned int a) { return a; } inline unsigned long abs(const unsigned long a) { return a; } inline double abs(const double a) { return std::fabs(a); } inline float abs(const float a) { return (float)std::fabs((double)a); } inline int abs(const int a) { return std::abs(a); } template inline T sqr(const T val) { return val*val; } template inline typename cimg::superset::type min(const t1& a, const t2& b) { typedef typename cimg::superset::type restype; return (restype)(a<=b?a:b); } template inline typename cimg::superset2::type min(const t1& a, const t2& b, const t3& c) { typedef typename cimg::superset2::type restype; return (restype)cimg::min(cimg::min(a,b),c); } template inline typename cimg::superset3::type min(const t1& a, const t2& b, const t3& c, const t4& d) { typedef typename cimg::superset3::type restype; return (restype)cimg::min(cimg::min(a,b,c),d); } template inline typename cimg::superset::type max(const t1& a, const t2& b) { typedef typename cimg::superset::type restype; return (restype)(a>=b?a:b); } template inline typename cimg::superset2::type max(const t1& a, const t2& b, const t3& c) { typedef typename cimg::superset2::type restype; return (restype)cimg::max(cimg::max(a,b),c); } template inline typename cimg::superset3::type max(const t1& a, const t2& b, const t3& c, const t4& d) { typedef typename cimg::superset3::type restype; return (restype)cimg::max(cimg::max(a,b,c),d); } template inline T sign(const T x) { return (x<0)?(T)(-1):(x==0?(T)0:(T)1); } template inline unsigned long nearest_pow2(const T x) { unsigned long i=1; while (x>i) i<<=1; return i; } template inline T mod(const T& x, const T& m) { const double dx = (double)x, dm = (double)m; if (x<0) { return (T)(dm+dx+dm*std::floor(-dx/dm)); } return (T)(dx-dm*std::floor(dx/dm)); } inline int mod(const char x, const char m) { return x>=0?x%m:(x%m?m+x%m:0); } inline int mod(const short x, const short m) { return x>=0?x%m:(x%m?m+x%m:0); } inline int mod(const int x, const int m) { return x>=0?x%m:(x%m?m+x%m:0); } inline int mod(const long x, const long m) { return x>=0?x%m:(x%m?m+x%m:0); } inline int mod(const unsigned char x, const unsigned char m) { return x%m; } inline int mod(const unsigned short x, const unsigned short m) { return x%m; } inline int mod(const unsigned int x, const unsigned int m) { return x%m; } inline int mod(const unsigned long x, const unsigned long m) { return x%m; } template inline T minmod(const T a, const T b) { return a*b<=0?0:(a>0?(a=1.0); return x1*std::sqrt((-2*std::log(w))/w); } inline double round(const double x, const double y, const unsigned int round_type=0) { if (y<=0) return x; const double delta = cimg::mod(x,y); if (delta==0.0) return x; const double backward = x - delta, forward = backward + y; return round_type==1?backward:(round_type==2?forward:(2*deltaabsb) { const double tmp = absb/absa; return absa*std::sqrt(1.0+tmp*tmp); } else { const double tmp = absa/absb; return (absb==0?0:absb*std::sqrt(1.0+tmp*tmp)); } } inline void info() { char tmp[1024] = { 0 }; std::fprintf(stderr,"\n %sCImg Library %d.%d.%d%s, compiled %s ( %s ) with the following flags :\n\n", cimg::t_red,128/100,(128%100)/10,128%10,cimg::t_normal,"Jun 4 2008","19:16:48"); std::fprintf(stderr," > CPU endianness : %s%s Endian%s\n", cimg::t_bold, cimg::endian()?"Big":"Little", cimg::t_normal); std::fprintf(stderr," > Operating System : %s%-13s%s %s('cimg_OS'=%d)%s\n", cimg::t_bold, 1==1?"Unix":(1==2?"Windows":"Unknow"), cimg::t_normal,cimg::t_purple, 1, cimg::t_normal); std::fprintf(stderr," > Display type : %s%-13s%s %s('cimg_display_type'=%d)%s\n", cimg::t_bold, 1==0?"No display": (1==1?"X11": (1==2?"Windows GDI": (1==3?"Carbon":"Unknow"))), cimg::t_normal,cimg::t_purple, 1, cimg::t_normal); std::fprintf(stderr," > Color terminal : %s%-13s%s %s('cimg_color_terminal' %s)%s\n", cimg::t_bold, "Yes",cimg::t_normal,cimg::t_purple,"defined", cimg::t_normal); std::fprintf(stderr," > Debug messages : %s%-13s%s %s('cimg_debug'=%d)%s\n", cimg::t_bold, 1==0?"No":(1==1 || 1==2?"Yes":(1==3?"Yes+":"Unknown")), cimg::t_normal,cimg::t_purple, 1, cimg::t_normal); std::fprintf(stderr," > Using XShm for X11 : %s%-13s%s %s('cimg_use_xshm' %s)%s\n", cimg::t_bold, "No",cimg::t_normal,cimg::t_purple,"undefined", cimg::t_normal); std::fprintf(stderr," > Using XRand for X11 : %s%-13s%s %s('cimg_use_xrandr' %s)%s\n", cimg::t_bold, "No",cimg::t_normal,cimg::t_purple,"undefined", cimg::t_normal); std::fprintf(stderr," > Using OpenMP : %s%-13s%s %s('cimg_use_openmp' %s)%s\n", cimg::t_bold, "No",cimg::t_normal,cimg::t_purple,"undefined", cimg::t_normal); std::fprintf(stderr," > Using PNG library : %s%-13s%s %s('cimg_use_png' %s)%s\n", cimg::t_bold, "No",cimg::t_normal,cimg::t_purple,"undefined", cimg::t_normal); std::fprintf(stderr," > Using JPEG library : %s%-13s%s %s('cimg_use_jpeg' %s)%s\n", cimg::t_bold, "No",cimg::t_normal,cimg::t_purple,"undefined", cimg::t_normal); std::fprintf(stderr," > Using TIFF library : %s%-13s%s %s('cimg_use_tiff' %s)%s\n", cimg::t_bold, "No",cimg::t_normal,cimg::t_purple,"undefined", cimg::t_normal); std::fprintf(stderr," > Using Magick++ library : %s%-13s%s %s('cimg_use_magick' %s)%s\n", cimg::t_bold, "No",cimg::t_normal,cimg::t_purple,"undefined", cimg::t_normal); std::fprintf(stderr," > Using FFTW3 library : %s%-13s%s %s('cimg_use_fftw3' %s)%s\n", cimg::t_bold, "No",cimg::t_normal,cimg::t_purple,"undefined", cimg::t_normal); std::fprintf(stderr," > Using LAPACK library : %s%-13s%s %s('cimg_use_lapack' %s)%s\n", cimg::t_bold, "No",cimg::t_normal,cimg::t_purple,"undefined", cimg::t_normal); std::sprintf(tmp,"\"%.1020s\"",cimg::imagemagick_path()); std::fprintf(stderr," > Path of ImageMagick : %s%-13s%s %s('cimg_imagemagick_path'%s)%s\n", cimg::t_bold, tmp, cimg::t_normal, cimg::t_purple," undefined", cimg::t_normal); std::sprintf(tmp,"\"%.1020s\"",cimg::graphicsmagick_path()); std::fprintf(stderr," > Path of GraphicsMagick : %s%-13s%s %s('cimg_graphicsmagick_path'%s)%s\n", cimg::t_bold, tmp, cimg::t_normal, cimg::t_purple," undefined", cimg::t_normal); std::sprintf(tmp,"\"%.1020s\"",cimg::medcon_path()); std::fprintf(stderr," > Path of 'medcon' : %s%-13s%s %s('cimg_medcon_path'%s)%s\n", cimg::t_bold, tmp, cimg::t_normal, cimg::t_purple," undefined", cimg::t_normal); std::sprintf(tmp,"\"%.1020s\"",cimg::temporary_path()); std::fprintf(stderr," > Temporary path : %s%-13s%s %s('cimg_temporary_path'%s)%s\n", cimg::t_bold, tmp, cimg::t_normal, cimg::t_purple," undefined", cimg::t_normal); std::fprintf(stderr,"\n"); } } template inline CImg::type> operator+(const CImg& img, const t2 val) { typedef typename cimg::superset::type restype; return CImg(img,false)+=val; } template inline CImg::type> operator+(const t1 val, const CImg& img) { return img+val; } template inline CImgList::type> operator+(const CImgList& list, const t2 val) { typedef typename cimg::superset::type restype; return CImgList(list)+=val; } template inline CImgList::type> operator+(const t1 val, const CImgList& list) { return list+val; } template inline CImg::type> operator+(const CImg& img1, const CImg& img2) { typedef typename cimg::superset::type restype; return CImg(img1,false)+=img2; } template inline CImgList::type> operator+(const CImg& img, const CImgList& list) { typedef typename cimg::superset::type restype; return CImgList(list)+=img; } template inline CImgList::type> operator+(const CImgList& list, const CImg& img) { return img+list; } template inline CImgList::type> operator+(const CImgList& list1, const CImgList& list2) { typedef typename cimg::superset::type restype; return CImgList(list1)+=list2; } template inline CImg::type> operator-(const CImg& img, const t2 val) { typedef typename cimg::superset::type restype; return CImg(img,false)-=val; } template inline CImg::type> operator-(const t1 val, const CImg& img) { typedef typename cimg::superset::type restype; return CImg(img.width,img.height,img.depth,img.dim,(restype)val)-=img; } template inline CImgList::type> operator-(const CImgList& list, const t2 val) { typedef typename cimg::superset::type restype; return CImgList(list)-=val; } template inline CImgList::type> operator-(const t1 val, const CImgList& list) { typedef typename cimg::superset::type restype; CImgList res(list.size); for (unsigned int l=0; l<(res).size; ++l) res[l] = val-list[l]; return res; } template inline CImg::type> operator-(const CImg& img1, const CImg& img2) { typedef typename cimg::superset::type restype; return CImg(img1,false)-=img2; } template inline CImgList::type> operator-(const CImg& img, const CImgList& list) { typedef typename cimg::superset::type restype; CImgList res(list.size); for (unsigned int l=0; l<(res).size; ++l) res[l] = img-list[l]; return res; } template inline CImgList::type> operator-(const CImgList& list, const CImg& img) { typedef typename cimg::superset::type restype; return CImgList(list)-=img; } template inline CImgList::type> operator-(const CImgList& list1, const CImgList& list2) { typedef typename cimg::superset::type restype; return CImgList(list1)-=list2; } template inline CImg::type> operator*(const CImg& img, const t2 val) { typedef typename cimg::superset::type restype; return CImg(img,false)*=val; } template inline CImg::type> operator*(const t1 val, const CImg& img) { return img*val; } template inline CImgList::type> operator*(const CImgList& list, const t2 val) { typedef typename cimg::superset::type restype; return CImgList(list)*=val; } template inline CImgList::type> operator*(const t1 val, const CImgList& list) { return list*val; } template inline CImg::type> operator*(const CImg& img1, const CImg& img2) { typedef typename cimg::superset::type restype; if (img1.width!=img2.height) throw CImgArgumentException("operator*() : can't multiply a matrix (%ux%u) by a matrix (%ux%u)", img1.width,img1.height,img2.width,img2.height); CImg res(img2.width,img1.height); restype val; for (int j = 0; j<(int)((res).height); ++j) for (int i = 0; i<(int)((res).width); ++i) { val = 0; for (int k = 0; k<(int)((img1).width); ++k) val+=img1(k,j)*img2(i,k); res(i,j) = val; } return res; } template inline CImgList::type> operator*(const CImg& img, const CImgList& list) { typedef typename cimg::superset::type restype; CImgList res(list.size); for (unsigned int l=0; l<(res).size; ++l) res[l] = img*list[l]; return res; } template inline CImgList::type> operator*(const CImgList& list, const CImg& img) { typedef typename cimg::superset::type restype; CImgList res(list.size); for (unsigned int l=0; l<(res).size; ++l) res[l] = list[l]*img; return res; } template inline CImgList::type> operator*(const CImgList& list1, const CImgList& list2) { typedef typename cimg::superset::type restype; CImgList res(cimg::min(list1.size,list2.size)); for (unsigned int l=0; l<(res).size; ++l) res[l] = list1[l]*list2[l]; return res; } template inline CImg::type> operator/(const CImg& img, const t2 val) { typedef typename cimg::superset::type restype; return CImg(img,false)/=val; } template inline CImg::type> operator/(const t1 val, CImg& img) { return val*img.get_invert(); } template inline CImgList::type> operator/(const CImgList& list, const t2 val) { typedef typename cimg::superset::type restype; return CImgList(list)/=val; } template inline CImgList::type> operator/(const t1 val, const CImgList& list) { typedef typename cimg::superset::type restype; CImgList res(list.size); for (unsigned int l=0; l<(res).size; ++l) res[l] = val/list[l]; return res; } template inline CImg::type> operator/(const CImg& img1, const CImg& img2) { typedef typename cimg::superset::type restype; return CImg(img1,false)*=img2.get_invert(); } template inline CImg::type> operator/(const CImg& img, const CImgList& list) { typedef typename cimg::superset::type restype; CImgList res(list.size); for (unsigned int l=0; l<(res).size; ++l) res[l] = img/list[l]; return res; } template inline CImgList::type> operator/(const CImgList& list, const CImg& img) { typedef typename cimg::superset::type restype; return CImgList(list)/=img; } template inline CImgList::type> operator/(const CImgList& list1, const CImgList& list2) { typedef typename cimg::superset::type restype; return CImgList(list1)/=list2; } template inline CImg apply(const CImg& instance, t& func) { return instance.get_apply(func); } template inline CImg::type> mul(const CImg& instance, const CImg& img) { return instance.get_mul(img); } template inline CImg::type> div(const CImg& instance, const CImg& img) { return instance.get_div(img); } template inline CImg::type> max(const CImg& instance, const CImg& img) { return instance.get_max(img); } template inline CImg max(const CImg& instance, const T val) { return instance.get_max(val); } template inline CImg::type> min(const CImg& instance, const CImg& img) { return instance.get_min(img); } template inline CImg::type> stats(const CImg& instance) { return instance.get_stats(); } template inline CImg min(const CImg& instance, const T val) { return instance.get_min(val); } template inline CImg::type> sqr(const CImg& instance) { return instance.get_sqr(); } template inline CImg::type> sqrt(const CImg& instance) { return instance.get_sqrt(); } template inline CImg::type> exp(const CImg& instance) { return instance.get_exp(); } template inline CImg::type> log(const CImg& instance) { return instance.get_log(); } template inline CImg::type> log10(const CImg& instance) { return instance.get_log10(); } template inline CImg::type> pow(const CImg& instance, const double p) { return instance.get_pow(p); } template inline CImg::type> pow(const CImg& instance, const CImg& img) { return instance.get_pow(img); } template inline CImg::type> abs(const CImg& instance) { return instance.get_abs(); } template inline CImg::type> cos(const CImg& instance) { return instance.get_cos(); } template inline CImg::type> sin(const CImg& instance) { return instance.get_sin(); } template inline CImg::type> tan(const CImg& instance) { return instance.get_tan(); } template inline CImg::type> acos(const CImg& instance) { return instance.get_acos(); } template inline CImg::type> asin(const CImg& instance) { return instance.get_asin(); } template inline CImg::type> atan(const CImg& instance) { return instance.get_atan(); } template inline CImg round(const CImg& instance, const float x, const unsigned int round_type=0) { return instance.get_round(x,round_type); } template inline CImg rand(const CImg& instance, const T val_min, const T val_max) { return instance.get_rand(val_min,val_max); } template inline CImg fill(const CImg& instance, const T val) { return instance.get_fill(val); } template inline CImg fill(const CImg& instance, const T val0, const T val1) { return instance.get_fill(val0,val1); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2) { return instance.get_fill(val0,val1,val2); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3) { return instance.get_fill(val0,val1,val2,val3); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4) { return instance.get_fill(val0,val1,val2,val3,val4); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5) { return instance.get_fill(val0,val1,val2,val3,val4,val5); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12, const T val13) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12, const T val13, const T val14) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14); } template inline CImg fill(const CImg& instance, const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12, const T val13, const T val14, const T val15) { return instance.get_fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14,val15); } template inline CImg fill(const CImg& instance, const int val0, ...) { CImg res(instance,false); va_list ap; __builtin_va_start(ap,val0); res.template _fill(val0,ap); __builtin_va_end(ap); return res; } template inline CImg fill(const CImg& instance, const double val0, ...) { CImg res(instance,false); va_list ap; __builtin_va_start(ap,val0); res.template _fill(val0,ap); __builtin_va_end(ap); return res; } template inline CImg normalize(const CImg& instance, const T a, const T b) { return instance.get_normalize(a,b); } template inline CImg cut(const CImg& instance, const T a, const T b) { return instance.get_cut(a,b); } template inline CImg quantize(const CImg& instance, const unsigned int n=256, const bool keep_range=true) { return instance.get_quantize(n,keep_range); } template inline CImg threshold(const CImg& instance, const T thres) { return instance.get_threshold(thres); } template inline CImg rotate(const CImg& instance, const float angle, const unsigned int cond=3) { return instance.get_rotate(angle,cond); } template inline CImg rotate(const CImg& instance, const float angle, const float cx, const float cy, const float zoom=1, const unsigned int cond=3) { return instance.get_rotate(angle,cx,cy,zoom,cond); } template inline CImg resize(const CImg& instance, const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100, const int interp=1, const int border_condition=-1, const bool center=false) { return instance.get_resize(pdx,pdy,pdz,pdv,interp,border_condition,center); } template inline CImg resize(const CImg& instance, const CImg& src, const int interp=1, const int border_condition=-1, const bool center=false) { return instance.get_resize(src,interp,border_condition,center); } template inline CImg resize(const CImg& instance, const CImgDisplay& disp, const int interp=1, const int border_condition=-1, const bool center=false) { return instance.get_resize(disp,interp,border_condition,center); } template inline CImg permute_axes(const CImg& instance, const char *permut="vxyz") { return instance.get_permute_axes(instance,permut); } template inline CImg resize_halfXY(const CImg& instance) { return instance.get_resize_halfXY(); } template inline CImg crop(const CImg& instance, const int x0, const int y0, const int z0, const int v0, const int x1, const int y1, const int z1, const int v1, const bool border_condition=false) { return instance.get_crop(x0,y0,z0,v0,x1,y1,z1,v1,border_condition); } template inline CImg crop(const CImg& instance, const int x0, const int y0, const int z0, const int x1, const int y1, const int z1, const bool border_condition=false) { return instance.get_crop(x0,y0,z0,x1,y1,z1,border_condition); } template inline CImg crop(const CImg& instance, const int x0, const int y0, const int x1, const int y1, const bool border_condition=false) { return instance.get_crop(x0,y0,x1,y1,border_condition); } template inline CImg crop(const CImg& instance, const int x0, const int x1, const bool border_condition=false) { return instance.get_crop(x0,x1,border_condition); } template inline CImg columns(const CImg& instance, const unsigned int x0, const unsigned int x1) { return instance.get_columns(x0,x1); } template inline CImg column(const CImg& instance, const unsigned int x0) { return instance.get_column(x0); } template inline CImg lines(const CImg& instance, const unsigned int y0, const unsigned int y1) { return instance.get_lines(y0,y1); } template inline CImg line(const CImg& instance, const unsigned int y0) { return instance.get_line(y0); } template inline CImg slices(const CImg& instance, const unsigned int z0, const unsigned int z1) { return instance.get_slices(z0,z1); } template inline CImg slice(const CImg& instance, const unsigned int z0) { return instance.get_slice(z0); } template inline CImg channels(const CImg& instance, const unsigned int v0, const unsigned int v1) { return instance.get_channels(v0,v1); } template inline CImg channel(const CImg& instance, const unsigned int v0) { return instance.get_channel(v0); } template inline CImg shared_points(CImg& instance, const unsigned int x0, const unsigned int x1, const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) { return instance.get_shared_points(x0,x1,y0,z0,v0); } template inline CImg shared_points(const CImg& instance, const unsigned int x0, const unsigned int x1, const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) { return instance.get_shared_points(x0,x1,y0,z0,v0); } template inline CImg shared_lines(CImg& instance, const unsigned int y0, const unsigned int y1, const unsigned int z0=0, const unsigned int v0=0) { return instance.get_shared_lines(y0,y1,z0,v0); } template inline CImg shared_lines(const CImg& instance, const unsigned int y0, const unsigned int y1, const unsigned int z0=0, const unsigned int v0=0) { return instance.get_shared_lines(y0,y1,z0,v0); } template inline CImg shared_line(CImg& instance, const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) { return instance.get_shared_line(y0,z0,v0); } template inline CImg shared_line(const CImg& instance, const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) { return instance.get_shared_line(y0,z0,v0); } template inline CImg shared_planes(CImg& instance, const unsigned int z0, const unsigned int z1, const unsigned int v0=0) { return instance.get_shared_planes(z0,z1,v0); } template inline CImg shared_planes(const CImg& instance, const unsigned int z0, const unsigned int z1, const unsigned int v0=0) { return instance.get_shared_planes(z0,z1,v0); } template inline CImg shared_plane(CImg& instance, const unsigned int z0, const unsigned int v0=0) { return instance.get_shared_plane(z0,v0); } template inline CImg shared_plane(const CImg& instance, const unsigned int z0, const unsigned int v0=0) { return instance.get_shared_plane(z0,v0); } template inline CImg shared_channels(CImg& instance, const unsigned int v0, const unsigned int v1) { return instance.get_shared_channels(v0,v1); } template inline CImg shared_channels(const CImg& instance, const unsigned int v0, const unsigned int v1) { return instance.get_shared_channels(v0,v1); } template inline CImg shared_channel(CImg& instance, const unsigned int v0) { return instance.get_shared_channel(v0); } template inline CImg shared_channel(const CImg& instance, const unsigned int v0) { return instance.get_shared_channel(v0); } template inline CImg shared(CImg& instance) { return instance.get_shared(); } template inline CImg shared(const CImg& instance) { return instance.get_shared(); } template inline CImg mirror(const CImg& instance, const char axe='x') { return instance.get_mirror(axe); } template inline CImg translate(const CImg& instance, const int deltax, const int deltay=0, const int deltaz=0, const int deltav=0, const int border_condition=0) { return instance.get_translate(deltax,deltay,deltaz,deltav,border_condition); } template inline CImg projections2d(const CImg& instance, const unsigned int x0, const unsigned int y0, const unsigned int z0, const int dx=-100, const int dy=-100, const int dz=-100) { return instance.get_projections2d(x0,y0,z0,dx,dy,dz); } template inline CImg::type> histogram(const CImg& instance, const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) { return instance.get_histogram(nblevels,val_min,val_max); } template inline CImg equalize_histogram(const CImg& instance, const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) { return instance.get_equalize_histogram(nblevels,val_min,val_max); } template inline CImg::type> label_regions(const CImg& instance) { return instance.get_label_regions(); } template inline CImg::type> norm_pointwise(const CImg& instance, int norm_type=2) { return instance.get_norm_pointwise(norm_type); } template inline CImg::type> orientation_pointwise(const CImg& instance) { return instance.get_orientation_pointwise(); } template inline CImgList split(const CImg& instance, const char axe='x', const unsigned int nb=0) { return instance.get_split(axe,nb); } template inline CImg append(const CImg& instance, const CImg& img, const char axis='x', const char align='c') { return instance.get_append(img,axis,align); } template inline CImgList::type> gradientXY(const CImg& instance, const int scheme=0) { return instance.get_gradientXY(scheme); } template inline CImgList::type> gradientXYZ(const CImg& instance, const int scheme=0) { return instance.get_gradientXYZ(scheme); } template inline CImg::type> structure_tensorXY(const CImg& instance, const int scheme=1) { return instance.get_structure_tensorXY(scheme); } template inline CImg::type> structure_tensorXYZ(const CImg& instance, const int scheme=1) { return instance.get_structure_tensorXYZ(scheme); } template inline CImg::type> distance_function(const CImg& instance, const unsigned int nb_iter=100, const float band_size=0.0f, const float precision=0.5f) { return instance.get_distance_function(nb_iter,band_size,precision); } template inline CImg::type> dijkstra(const CImg& instance, const unsigned int starting_node, const unsigned int ending_node, CImg& previous) { return instance.get_dijkstra(starting_node,ending_node,previous); } template inline CImg::type> dijkstra(const CImg& instance, const unsigned int starting_node, const unsigned int ending_node=~0U) { return instance.get_dijkstra(starting_node,ending_node); } template inline CImg RGBtoLUT(const CImg& instance, const CImg& palette, const bool dithering=true, const bool indexing=false) { return instance.get_RGBtoLUT(palette,dithering,indexing); } template inline CImg RGBtoLUT(const CImg& instance, const bool dithering=true, const bool indexing=false) { return instance.get_RGBtoLUT(dithering,indexing); } template inline CImg LUTtoRGB(const CImg& instance, const CImg& palette) { return instance.get_LUTtoRGB(palette); } template inline CImg LUTtoRGB(const CImg& instance) { return instance.get_LUTtoRGB(); } template inline CImg::type> RGBtoHSV(const CImg& instance) { return instance.get_RGBtoHSV(); } template inline CImg HSVtoRGB(const CImg& instance) { return instance.get_HSVtoRGB(); } template inline CImg::type> RGBtoHSL(const CImg& instance) { return instance.get_RGBtoHSL(); } template inline CImg HSLtoRGB(const CImg& instance) { return instance.get_HSLtoRGB(); } template inline CImg::type> RGBtoHSI(const CImg& instance) { return instance.get_RGBtoHSI(); } template inline CImg HSItoRGB(const CImg& instance) { return instance.get_HSItoRGB(); } template inline CImg RGBtoYCbCr(const CImg& instance) { return instance.get_RGBtoYCbCr(); } template inline CImg YCbCrtoRGB(const CImg& instance) { return instance.get_YCbCrtoRGB(); } template inline CImg::type> RGBtoYUV(const CImg& instance) { return instance.get_RGBtoYUV(); } template inline CImg YUVtoRGB(const CImg& instance) { return instance.get_YUVtoRGB(); } template inline CImg::type> RGBtoXYZ(const CImg& instance) { return instance.get_RGBtoXYZ(); } template inline CImg XYZtoRGB(const CImg& instance) { return instance.get_XYZtoRGB(); } template inline CImg XYZtoLab(const CImg& instance) { return instance.get_XYZtoLab(); } template inline CImg LabtoXYZ(const CImg& instance) { return instance.get_LabtoXYZ(); } template inline CImg XYZtoxyY(const CImg& instance) { return instance.get_XYZtoxyY(); } template inline CImg xyYtoXYZ(const CImg& instance) { return instance.get_xyYtoXYZ(); } template inline CImg RGBtoLab(const CImg& instance) { return instance.get_RGBtoLab(); } template inline CImg LabtoRGB(const CImg& instance) { return instance.get_LabtoRGB(); } template inline CImg RGBtoxyY(const CImg& instance) { return instance.get_RGBtoxyY(); } template inline CImg xyYtoRGB(const CImg& instance) { return instance.get_xyYtoRGB(); } template inline CImg RGBtoBayer(const CImg& instance, const bool even_mode=true) { return instance.get_RGBtoBayer(even_mode); } template inline CImg BayertoRGB(const CImg& instance, const unsigned int interpolation_type=3, const bool even_mode=true) { return instance.get_BayertoRGB(interpolation_type,even_mode); } template inline CImg::type> correlate(const CImg& instance, const CImg& mask, const unsigned int cond=1, const bool weighted_correl=false) { return instance.get_correlate(mask,cond,weighted_correl); } template inline CImg::type> convolve(const CImg& instance, const CImg& mask, const unsigned int cond=1, const bool weighted_convol=false) { return instance.get_convolve(mask,cond,weighted_convol); } template inline CImg::type> erode(const CImg& instance, const CImg& mask, const unsigned int cond=1, const bool weighted_erosion=false) { return instance.get_erode(mask,cond,weighted_erosion); } template inline CImg erode(const CImg& instance, const unsigned int n, const unsigned int cond=1) { return instance.get_erode(n,cond); } template inline CImg::type> dilate(const CImg& instance, const CImg& mask, const unsigned int cond=1, const bool weighted_dilatation=false) { return instance.get_dilate(mask,cond,weighted_dilatation); } template inline CImg dilate(const CImg& instance, const unsigned int n, const unsigned int cond=1) { return instance.get_dilate(n,cond); } template inline CImg noise(const CImg& instance, const double sigma=-20, const unsigned int ntype=0) { return instance.get_noise(sigma,ntype); } template inline CImg::type> deriche(const CImg& instance, const float sigma, const int order=0, const char axe='x', const bool cond=true) { return instance.get_deriche(sigma,order,axe,cond); } template inline CImg::type> blur(const CImg& instance, const float sigmax, const float sigmay, const float sigmaz, const bool cond=true) { return instance.get_blur(sigmax,sigmay,sigmaz,cond); } template inline CImg::type> blur(const CImg& instance, const float sigma, const bool cond=true) { return instance.get_blur(sigma,cond); } template inline CImg blur_anisotropic(const CImg& instance, const CImg& G, const float amplitude=60.0f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true) { return instance.get_blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx); } template inline CImg blur_anisotropic(const CImg& instance, const CImg& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f, const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true, const float geom_factor=1.0f) { return instance.get_blur_anisotropic(mask,amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor); } template inline CImg blur_anisotropic(const CImg& instance, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f, const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true, const float geom_factor=1.0f) { return instance.get_blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor); } template inline CImg blur_bilateral(const CImg& instance, const float sigmax, const float sigmay, const float sigmaz, const float sigmar, const int bgridx, const int bgridy, const int bgridz, const int bgridr, const bool interpolation=true) { return instance.get_blur_bilateral(sigmax,sigmay,sigmaz,sigmar,bgridx,bgridy,bgridz,bgridr,interpolation); } template inline CImg blur_bilateral(const CImg& instance, const float sigmas, const float sigmar, const int bgrids=-33, const int bgridr=32, const bool interpolation=true) { return instance.get_blur_bilateral(sigmas,sigmar,bgrids,bgridr,interpolation); } template inline CImg blur_patch(const CImg& instance, const unsigned int patch_size=3, const float sigma_p=10.0f, const float sigma_s=10.0f, const unsigned int lookup_size=4, const bool fast_approx=true) { return instance.get_blur_patch(patch_size,sigma_p,sigma_s,lookup_size,fast_approx); } template inline CImgList::type> FFT(const CImg& instance, const char axe, const bool invert=false) { return instance.get_FFT(axe,invert); } template inline CImgList::type> FFT(const CImg& instance, const bool invert=false) { return instance.get_FFT(invert); } template inline CImg blur_median(const CImg& instance, const unsigned int n=3) { return instance.get_blur_median(n); } template inline CImg sharpen(const CImg& instance, const float amplitude=50.0f, const float edge=1.0f, const float alpha=0.0f, const float sigma=0.0f) { return instance.get_sharpen(amplitude,edge,alpha,sigma); } template inline CImg::type> haar(const CImg& instance, const char axis, const bool invert=false, const unsigned int nb_scales=1) { return instance.get_haar(axis,invert,nb_scales); } template inline CImg::type> haar(const CImg& instance, const bool invert=false, const unsigned int nb_scales=1) { return instance.get_haar(invert,nb_scales); } template inline CImg::type> displacement_field(const CImg& instance, const CImg& target, const float smooth=0.1f, const float precision=0.1f, const unsigned int nb_scales=0, const unsigned int itermax=10000) { return instance.get_displacement_field(target,smooth,precision,nb_scales,itermax); } template inline CImg matrix(const CImg& instance) { return instance.get_matrix(); } template inline CImg tensor(const CImg& instance) { return instance.get_tensor(); } template inline CImg unroll(const CImg& instance, const char axe='x') { return instance.get_unroll(axe); } template inline CImg diagonal(const CImg& instance) { return instance.get_diagonal(); } template inline CImg identity_matrix(const CImg& instance) { return instance.get_identity_matrix(); } template inline CImg sequence(const CImg& instance, const T a0, const T a1) { return instance.get_sequence(a0,a1); } template inline CImg vector_at(const CImg& instance, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) { return instance.get_vector_at(x,y,z); } template inline CImg matrix_at(const CImg& instance, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) { return instance.get_matrix_at(x,y,z); } template inline CImg tensor_at(const CImg& instance, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) { return instance.get_tensor_at(x,y,z); } template inline CImg transpose(const CImg& instance) { return instance.get_transpose(); } template inline CImg::type> invert(const CImg& instance, const bool use_LU=true) { return instance.get_invert(use_LU); } template inline CImg::type> pseudoinvert(const CImg& instance) { return instance.get_pseudoinvert(); } template inline CImg::type> cross(const CImg& instance, const CImg& img) { return instance.get_cross(img); } template inline CImgList::type> SVD(const CImg& instance, const bool sorting=true) { return instance.get_SVD(sorting); } template inline CImg::type> solve(const CImg& instance, const CImg& A) { return instance.get_solve(A); } template inline CImgList::type> eigen(const CImg& instance) { return instance.get_eigen(); } template inline CImgList::type> symmetric_eigen(const CImg& instance) { return instance.get_symmetric_eigen(); } template inline CImg sort(const CImg& instance, CImg& permutations, const bool increasing=true) { return instance.get_sort(permutations,increasing); } template inline CImg sort(const CImg& instance, const bool increasing=true) { return instance.get_sort(increasing); } template inline CImg permute(const CImg& instance, const CImg& permutation) { return instance.get_permute(permutation); } template inline CImg::type> coordinates(const CImg& instance, const int coords_type, CImgDisplay &disp, unsigned int *const XYZ=0, const unsigned char *const color=0) { return instance.get_coordinates(coords_type,disp,XYZ,color); } template inline CImgList::type> insert(const CImgList& instance, const CImg& img, const unsigned int pos=~0U, const bool shared=false) { return instance.get_insert(img,pos,shared); } template inline CImgList::type> insert(const CImgList& instance, const unsigned int n, const CImg& img, const unsigned int pos=~0U, const bool shared=false) { return instance.get_insert(n,img,pos,shared); } template inline CImgList::type> insert(const CImgList& instance, const CImgList& list, const unsigned int pos=~0U, int shared=0) { return instance.get_insert(list,pos,shared); } template inline CImgList::type> insert(const CImgList& instance, const unsigned int n, const CImgList& list, const unsigned int pos=~0U, const int shared=0) { return instance.insert(n,list,pos,shared); } template inline CImgList remove(const CImgList& instance, const unsigned int pos) { return instance.get_remove(pos); } template inline CImgList remove(const CImgList& instance) { return instance.get_remove(); } template inline CImgList reverse(const CImgList& instance) { return instance.get_reverse(); } template inline CImgList crop(const CImgList& instance, const unsigned int i0, const unsigned int i1, const bool shared=false) { return instance.get_crop(i0,i1,shared); } template inline CImgList crop(const CImgList& instance, const unsigned int i0, const unsigned int i1, const int x0, const int y0, const int z0, const int v0, const int x1, const int y1, const int z1, const int v1) { return instance.get_crop(i0,i1,x0,y0,z0,v0,x1,y1,z1,v1); } template inline CImgList crop(const CImgList& instance, const unsigned int i0, const unsigned int i1, const int x0, const int y0, const int z0, const int x1, const int y1, const int z1) { return instance.get_crop(i0,i1,x0,y0,z0,x1,y1,z1); } template inline CImgList crop(const CImgList& instance, const unsigned int i0, const unsigned int i1, const int x0, const int y0, const int x1, const int y1) { return instance.get_crop(i0,i1,x0,y0,x1,y1); } template inline CImgList crop(const CImgList& instance, const unsigned int i0, const unsigned int i1, const int x0, const int x1) { return instance.get_crop(i0,i1,x0,x1); } template inline CImgList::type> FFT(const CImgList& instance, const char axe, const bool invert=false) { return instance.get_FFT(axe,invert); } template inline CImgList::type> FFT(const CImgList& instance, const bool invert=false) { return instance.get_FFT(invert); } template inline CImgList split(const CImgList& instance, const char axe='x') { return instance.get_split(axe); } template inline CImg append(const CImgList& instance, const char axe='x', const char align='c') { return instance.get_append(axe,align); } template inline CImgList crop_font(const CImgList& instance) { return instance.get_crop_font(); } struct CImgDisplay { unsigned int width; unsigned int height; unsigned int normalization; unsigned int events; char* title; volatile int window_x; volatile int window_y; volatile unsigned int window_width; volatile unsigned int window_height; volatile int mouse_x; volatile int mouse_y; volatile unsigned int buttons[512]; volatile unsigned int& button; volatile int wheel; volatile unsigned int& key; volatile unsigned int keys[512]; volatile unsigned int& released_key; volatile unsigned int released_keys[512]; volatile bool is_closed; volatile bool is_resized; volatile bool is_moved; volatile bool is_event; bool is_fullscreen; float fps_fps, min, max; unsigned long timer, fps_frames, fps_timer; CImgDisplay(): width(0),height(0),normalization(0),events(0),title(0), window_x(0),window_y(0),window_width(0),window_height(0), mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys), is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false), min(0),max(0) {} CImgDisplay(const unsigned int dimw, const unsigned int dimh, const char *title=0, const unsigned int normalization_type=3, const unsigned int events_type=3, const bool fullscreen_flag=false, const bool closed_flag=false): width(0),height(0),normalization(0),events(0),title(0), window_x(0),window_y(0),window_width(0),window_height(0), mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys), is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false), min(0),max(0) { assign(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag); } template CImgDisplay(const CImg& img, const char *title=0, const unsigned int normalization_type=3, const unsigned int events_type=3, const bool fullscreen_flag=false, const bool closed_flag=false): width(0),height(0),normalization(0),events(0),title(0), window_x(0),window_y(0),window_width(0),window_height(0), mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys), is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),min(0),max(0) { assign(img,title,normalization_type,events_type,fullscreen_flag,closed_flag); } template CImgDisplay(const CImgList& list, const char *title=0, const unsigned int normalization_type=3, const unsigned int events_type=3, const bool fullscreen_flag=false, const bool closed_flag=false): width(0),height(0),normalization(0),events(0),title(0), window_x(0),window_y(0),window_width(0),window_height(0), mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys), is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),min(0),max(0) { assign(list,title,normalization_type,events_type,fullscreen_flag,closed_flag); } CImgDisplay(const CImgDisplay& disp): width(0),height(0),normalization(0),events(0),title(0), window_x(0),window_y(0),window_width(0),window_height(0), mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys), is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),min(0),max(0) { assign(disp); } ~CImgDisplay() { assign(); } CImgDisplay& operator=(const CImgDisplay& disp) { return assign(disp); } bool is_empty() const { return (!width || !height); } operator bool() const { return !is_empty(); } int dimx() const { return (int)width; } int dimy() const { return (int)height; } int window_dimx() const { return (int)window_width; } int window_dimy() const { return (int)window_height; } int window_posx() const { return window_x; } int window_posy() const { return window_y; } CImgDisplay& wait(const unsigned int milliseconds) { cimg::wait(milliseconds, timer); return *this; } CImgDisplay& wait() { if (!is_empty()) wait(*this); return *this; } static void wait(CImgDisplay& disp1) { disp1.is_event = 0; while (!disp1.is_event) wait_all(); } static void wait(CImgDisplay& disp1, CImgDisplay& disp2) { disp1.is_event = disp2.is_event = 0; while (!disp1.is_event && !disp2.is_event) wait_all(); } static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3) { disp1.is_event = disp2.is_event = disp3.is_event = 0; while (!disp1.is_event && !disp2.is_event && !disp3.is_event) wait_all(); } static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4) { disp1.is_event = disp2.is_event = disp3.is_event = disp4.is_event = 0; while (!disp1.is_event && !disp2.is_event && !disp3.is_event && !disp4.is_event) wait_all(); } float frames_per_second() { if (!fps_timer) fps_timer = cimg::time(); const float delta = (cimg::time()-fps_timer)/1000.0f; ++fps_frames; if (delta>=1.0f) { fps_fps = fps_frames/delta; fps_frames = 0; fps_timer = cimg::time(); } return fps_fps; } template CImgDisplay& display(const CImgList& list, const char axe='x', const char align='c') { return display(list.get_append(axe,align)); } template CImgDisplay& operator<<(const CImg& img) { return display(img); } template CImgDisplay& operator<<(const CImgList& list) { return display(list); } template CImgDisplay& resize(const CImg& img, const bool redraw=true) { return resize(img.width,img.height,redraw); } CImgDisplay& resize(const CImgDisplay& disp, const bool redraw=true) { return resize(disp.width,disp.height,redraw); } CImgDisplay& resize(const bool redraw=true) { resize(window_width,window_height,redraw); return *this; } template CImgDisplay& display_object3d(const tp& points, const CImgList& primitives, const CImgList& colors, const to& opacities, const bool centering=true, const int render_static=4, const int render_motion=1, const bool double_sided=false, const float focale=500.0f, const float specular_light=0.2f, const float specular_shine=0.1f, const bool display_axes=true, float *const pose_matrix=0) { CImg(width,height,1,3,0).display_object3d(points,primitives,colors,opacities,*this, centering,render_static,render_motion, double_sided,focale,specular_light,specular_shine, display_axes,pose_matrix); return *this; } template CImgDisplay& display_object3d(const tp& points, const CImgList& primitives, const CImgList& colors, const bool centering=true, const int render_static=4, const int render_motion=1, const bool double_sided=false, const float focale=500.0f, const float specular_light=0.2f, const float specular_shine=0.1f, const bool display_axes=true, float *const pose_matrix=0, const float opacity=1.0f) { typedef typename cimg::superset::type to; CImg(width,height,1,3,0).display_object3d(points,primitives,colors, CImg::vector((to)opacity), *this,centering,render_static,render_motion, double_sided,focale,specular_light,specular_shine,display_axes,pose_matrix); return *this; } CImgDisplay& toggle_fullscreen() { return assign(width,height,title,normalization,events,!is_fullscreen,is_closed); } template static void _render_resize(const T *ptrs, const unsigned int ws, const unsigned int hs, t *ptrd, const unsigned int wd, const unsigned int hd) { unsigned int *const offx = new unsigned int[wd], *const offy = new unsigned int[hd+1], *poffx, *poffy; float s, curr, old; s = (float)ws/wd; poffx = offx; curr = 0; for (unsigned int x=0; x=keys; --ptrs) if (*ptrs) { if (remove) *ptrs = 0; return true; } return false; } bool is_key(const unsigned int key1, const bool remove) { for (unsigned int *ptrs=(unsigned int*)keys+512-1; ptrs>=keys; --ptrs) if (*ptrs==key1) { if (remove) *ptrs = 0; return true; } return false; } bool is_key(const unsigned int key1, const unsigned int key2, const bool remove) { const unsigned int seq[] = { key1, key2 }; return is_key(seq,2,remove); } bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3, const bool remove) { const unsigned int seq[] = { key1, key2, key3 }; return is_key(seq,3,remove); } bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3, const unsigned int key4, const bool remove) { const unsigned int seq[] = { key1, key2, key3, key4 }; return is_key(seq,4,remove); } bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3, const unsigned int key4, const unsigned int key5, const bool remove) { const unsigned int seq[] = { key1, key2, key3, key4, key5 }; return is_key(seq,5,remove); } bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3, const unsigned int key4, const unsigned int key5, const unsigned int key6, const bool remove) { const unsigned int seq[] = { key1, key2, key3, key4, key5, key6 }; return is_key(seq,6,remove); } bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3, const unsigned int key4, const unsigned int key5, const unsigned int key6, const unsigned int key7, const bool remove) { const unsigned int seq[] = { key1, key2, key3, key4, key5, key6, key7 }; return is_key(seq,7,remove); } bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3, const unsigned int key4, const unsigned int key5, const unsigned int key6, const unsigned int key7, const unsigned int key8, const bool remove) { const unsigned int seq[] = { key1, key2, key3, key4, key5, key6, key7, key8 }; return is_key(seq,8,remove); } bool is_key(const unsigned int key1, const unsigned int key2, const unsigned int key3, const unsigned int key4, const unsigned int key5, const unsigned int key6, const unsigned int key7, const unsigned int key8, const unsigned int key9, const bool remove) { const unsigned int seq[] = { key1, key2, key3, key4, key5, key6, key7, key8, key9 }; return is_key(seq,9,remove); } bool is_key(const unsigned int *const keyseq, const unsigned int N, const bool remove=true) { if (keyseq && N) { const unsigned int *const ps_end = keyseq+N-1, k = *ps_end, *const pk_end = (unsigned int*)keys+1+512-N; for (unsigned int *pk = (unsigned int*)keys; pkscreens[(((_XPrivDisplay)disp)->default_screen)])->width); XCloseDisplay(disp); } else { res = ((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->width); } return res; } static int screen_dimy() { int res = 0; if (!cimg::X11attr().display) { Display *disp = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0")); if (!disp) throw CImgDisplayException("CImgDisplay::screen_dimy() : Can't open X11 display"); res = ((&((_XPrivDisplay)disp)->screens[(((_XPrivDisplay)disp)->default_screen)])->height); XCloseDisplay(disp); } else { res = ((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->height); } return res; } CImgDisplay& assign() { if (!is_empty()) { XLockDisplay(cimg::X11attr().display); unsigned int i; for (i=0; if.destroy_image))((image))); data = 0; image = 0; if (cimg::X11attr().nb_bits==8) XFreeColormap(cimg::X11attr().display,colormap); colormap = 0; XSync(cimg::X11attr().display, 0); if (title) delete[] title; width = height = normalization = events = 0; is_fullscreen = is_resized = is_moved = is_event = false; is_closed = true; title = 0; window_x = window_y = window_width = window_height = mouse_x = mouse_y = wheel = 0; std::memset((void*)buttons,0,512*sizeof(unsigned int)); std::memset((void*)keys,0,512*sizeof(unsigned int)); std::memset((void*)released_keys,0,512*sizeof(unsigned int)); min = max = 0; XUnlockDisplay(cimg::X11attr().display); } return *this; } CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0, const unsigned int normalization_type=3, const unsigned int events_type=3, const bool fullscreen_flag=false, const bool closed_flag=false) { if (!dimw || !dimh) return assign(); _assign(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag); min = max = 0; std::memset(data,0,(cimg::X11attr().nb_bits==8?sizeof(unsigned char): (cimg::X11attr().nb_bits==16?sizeof(unsigned short):sizeof(unsigned int)))*width*height); return paint(); } template CImgDisplay& assign(const CImg& img, const char *title=0, const unsigned int normalization_type=3, const unsigned int events_type=3, const bool fullscreen_flag=false, const bool closed_flag=false) { if (!img) return assign(); CImg tmp; const CImg& nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2)); _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag); if (normalization==2) min = (float)nimg.minmax(max); return render(nimg).paint(); } template CImgDisplay& assign(const CImgList& list, const char *title=0, const unsigned int normalization_type=3, const unsigned int events_type=3, const bool fullscreen_flag=false, const bool closed_flag=false) { if (!list) return assign(); CImg tmp; const CImg img = list.get_append('x','p'), &nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2)); _assign(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag); if (normalization==2) min = (float)nimg.minmax(max); return render(nimg).paint(); } CImgDisplay& assign(const CImgDisplay& win) { if (!win) return assign(); _assign(win.width,win.height,win.title,win.normalization,win.events,win.is_fullscreen,win.is_closed); std::memcpy(data,win.data,(cimg::X11attr().nb_bits==8?sizeof(unsigned char): cimg::X11attr().nb_bits==16?sizeof(unsigned short): sizeof(unsigned int))*width*height); return paint(); } template CImgDisplay& display(const CImg& img) { if (is_empty()) assign(img.width,img.height); return render(img).paint(false); } CImgDisplay& resize(const int nwidth, const int nheight, const bool redraw=true) { if (!nwidth || !nheight) return assign(); if (is_empty()) return assign(cimg::max(nwidth,0),cimg::max(nheight,0)); const unsigned int tmpdimx = (nwidth>0)?nwidth:(-nwidth*width/100), tmpdimy = (nheight>0)?nheight:(-nheight*height/100), dimx = cimg::min(tmpdimx?tmpdimx:1,(unsigned int)screen_dimx()), dimy = cimg::min(tmpdimy?tmpdimy:1,(unsigned int)screen_dimy()); const bool is_disp_different = (width!=dimx || height!=dimy), is_win_different = (window_width!=dimx || window_height!=dimy); if (is_disp_different || is_win_different) { XLockDisplay(cimg::X11attr().display); XResizeWindow(cimg::X11attr().display,window,dimx,dimy); window_width = dimx; window_height = dimy; is_resized = false; if (is_disp_different) { switch (cimg::X11attr().nb_bits) { case 8: { unsigned char foo = 0; _resize(foo,dimx,dimy,redraw); } break; case 16: { unsigned short foo = 0; _resize(foo,dimx,dimy,redraw); } break; default: { unsigned int foo = 0; _resize(foo,dimx,dimy,redraw); } break; } width = dimx; height = dimy; } XUnlockDisplay(cimg::X11attr().display); if (is_fullscreen) move((screen_dimx()-width)/2,(screen_dimy()-height)/2); if (redraw) return paint(); } return *this; } CImgDisplay& move(const int posx, const int posy) { if (is_empty()) return *this; show(); XLockDisplay(cimg::X11attr().display); XMoveWindow(cimg::X11attr().display,window,posx,posy); is_moved = false; window_x = posx; window_y = posy; XUnlockDisplay(cimg::X11attr().display); return paint(); } CImgDisplay& set_mouse(const int posx, const int posy) { if (!is_closed && posx>=0 && posy>=0) { XLockDisplay(cimg::X11attr().display); XWarpPointer(cimg::X11attr().display,0L,window,0,0,0,0,posx,posy); is_moved = false; mouse_x = posx; mouse_y = posy; XSync(cimg::X11attr().display, 0); XUnlockDisplay(cimg::X11attr().display); } return *this; } CImgDisplay& hide_mouse() { if (cimg::X11attr().display) { XLockDisplay(cimg::X11attr().display); const char pix_data[8] = { 0 }; XColor col; col.red = col.green = col.blue = 0; Pixmap pix = XCreateBitmapFromData(cimg::X11attr().display,window,pix_data,8,8); Cursor cur = XCreatePixmapCursor(cimg::X11attr().display,pix,pix,&col,&col,0,0); XFreePixmap(cimg::X11attr().display,pix); XDefineCursor(cimg::X11attr().display,window,cur); XUnlockDisplay(cimg::X11attr().display); } return *this; } CImgDisplay& show_mouse() { if (cimg::X11attr().display) { XLockDisplay(cimg::X11attr().display); XDefineCursor(cimg::X11attr().display,window,0L); XUnlockDisplay(cimg::X11attr().display); } return *this; } static void wait_all() { if (cimg::X11attr().display) { XLockDisplay(cimg::X11attr().display); bool flag = true; XEvent event; while (flag) { for (unsigned int i = 0; iis_event = false; const unsigned int xevent_type = (cimg::X11attr().wins[i]->events)&3, emask = ((xevent_type>=1)?(1L<<15)|(1L<<17):0) | ((xevent_type>=2)?(1L<<2)|(1L<<0)|(1L<<6)|(1L<<5):0) | ((xevent_type>=3)?(1L<<3)|(1L<<1):0); XSelectInput(cimg::X11attr().display,cimg::X11attr().wins[i]->window,emask); } XNextEvent(cimg::X11attr().display, &event); for (unsigned int i = 0; iis_closed && event.xany.window==cimg::X11attr().wins[i]->window) { cimg::X11attr().wins[i]->_handle_events(&event); if (cimg::X11attr().wins[i]->is_event) flag = false; } } XUnlockDisplay(cimg::X11attr().display); } } CImgDisplay& show() { if (is_empty()) return *this; if (is_closed) { XLockDisplay(cimg::X11attr().display); if (is_fullscreen) _init_fullscreen(); _map_window(); is_closed = false; XUnlockDisplay(cimg::X11attr().display); } return paint(); } CImgDisplay& close() { if (is_empty()) return *this; if (!is_closed) { XLockDisplay(cimg::X11attr().display); if (is_fullscreen) _desinit_fullscreen(); XUnmapWindow(cimg::X11attr().display,window); window_x = window_y = -1; is_closed = true; XUnlockDisplay(cimg::X11attr().display); } return *this; } CImgDisplay& set_title(const char *format, ...) { if (is_empty()) return *this; char tmp[1024] = {0}; va_list ap; __builtin_va_start(ap,format); std::vsprintf(tmp,format,ap); __builtin_va_end(ap); if (title) delete[] title; const int s = cimg::strlen(tmp)+1; title = new char[s]; std::memcpy(title,tmp,s*sizeof(char)); XLockDisplay(cimg::X11attr().display); XStoreName(cimg::X11attr().display,window,tmp); XUnlockDisplay(cimg::X11attr().display); return *this; } CImgDisplay& paint(const bool wait_expose=true) { if (is_empty()) return *this; XLockDisplay(cimg::X11attr().display); _paint(wait_expose); XUnlockDisplay(cimg::X11attr().display); return *this; } template CImgDisplay& render(const CImg& img, const bool flag8=false) { if (is_empty()) return *this; if (!img) throw CImgArgumentException("CImgDisplay::_render_image() : Specified input image (%u,%u,%u,%u,%p) is empty.", img.width,img.height,img.depth,img.dim,img.data); if (img.depth!=1) return render(img.get_projections2d(img.width/2,img.height/2,img.depth/2)); if (cimg::X11attr().nb_bits==8 && (img.width!=width || img.height!=height)) return render(img.get_resize(width,height,1,-100,1)); if (cimg::X11attr().nb_bits==8 && !flag8 && img.dim==3) return render(img.get_RGBtoLUT(true),true); const T *data1 = img.data, *data2 = (img.dim>1)?img.ptr(0,0,0,1):data1, *data3 = (img.dim>2)?img.ptr(0,0,0,2):data1; if (cimg::X11attr().blue_first) cimg::swap(data1,data3); XLockDisplay(cimg::X11attr().display); if (!normalization || (normalization==3 && cimg::type::string()==cimg::type::string())) { min = max = 0; switch (cimg::X11attr().nb_bits) { case 8: { _set_colormap(colormap,img.dim); unsigned char *const ndata = (img.width==width && img.height==height)?(unsigned char*)data:new unsigned char[img.width*img.height]; unsigned char *ptrd = (unsigned char*)ndata; switch (img.dim) { case 1: for (unsigned int xy = img.width*img.height; xy>0; --xy) (*ptrd++) = (unsigned char)*(data1++); break; case 2: for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char R = (unsigned char)*(data1++), G = (unsigned char)*(data2++); (*ptrd++) = (R&0xf0) | (G>>4); } break; default: for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char R = (unsigned char)*(data1++), G = (unsigned char)*(data2++), B = (unsigned char)*(data3++); (*ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6); } break; } if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned char*)data,width,height); delete[] ndata; } } break; case 16: { unsigned short *const ndata = (img.width==width && img.height==height)?(unsigned short*)data:new unsigned short[img.width*img.height]; unsigned char *ptrd = (unsigned char*)ndata; const unsigned int M = 248; switch (img.dim) { case 1: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)*(data1++), G = val>>2; *(ptrd++) = val&M | (G>>3); *(ptrd++) = (G<<5) | (G>>1); } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)*(data1++), G = val>>2; *(ptrd++) = (G<<5) | (G>>1); *(ptrd++) = val&M | (G>>3); } break; case 2: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char G = (unsigned char)*(data2++)>>2; *(ptrd++) = (unsigned char)*(data1++)&M | (G>>3); *(ptrd++) = (G<<5); } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char G = (unsigned char)*(data2++)>>2; *(ptrd++) = (G<<5); *(ptrd++) = (unsigned char)*(data1++)&M | (G>>3); } break; default: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char G = (unsigned char)*(data2++)>>2; *(ptrd++) = (unsigned char)*(data1++)&M | (G>>3); *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3); } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char G = (unsigned char)*(data2++)>>2; *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3); *(ptrd++) = (unsigned char)*(data1++)&M | (G>>3); } break; } if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned short*)data,width,height); delete[] ndata; } } break; default: { unsigned int *const ndata = (img.width==width && img.height==height)?(unsigned int*)data:new unsigned int[img.width*img.height]; if (sizeof(int)==4) { unsigned int *ptrd = ndata; switch (img.dim) { case 1: if (cimg::X11attr().byte_order==cimg::endian()) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)*(data1++); *(ptrd++) = (val<<16) | (val<<8) | val; } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)*(data1++)<<8; *(ptrd++) = (val<<16) | (val<<8) | val; } break; case 2: if (cimg::X11attr().byte_order==cimg::endian()) for (unsigned int xy = img.width*img.height; xy>0; --xy) *(ptrd++) = ((unsigned char)*(data1++)<<16) | ((unsigned char)*(data2++)<<8); else for (unsigned int xy = img.width*img.height; xy>0; --xy) *(ptrd++) = ((unsigned char)*(data2++)<<16) | ((unsigned char)*(data1++)<<8); break; default: if (cimg::X11attr().byte_order==cimg::endian()) for (unsigned int xy = img.width*img.height; xy>0; --xy) *(ptrd++) = ((unsigned char)*(data1++)<<16) | ((unsigned char)*(data2++)<<8) | (unsigned char)*(data3++); else for (unsigned int xy = img.width*img.height; xy>0; --xy) *(ptrd++) = ((unsigned char)*(data3++)<<24) | ((unsigned char)*(data2++)<<16) | ((unsigned char)*(data1++)<<8); break; } } else { unsigned char *ptrd = (unsigned char*)ndata; switch (img.dim) { case 1: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { *(ptrd++) = 0; *(ptrd++) = (unsigned char)*(data1++); *(ptrd++) = 0; *(ptrd++) = 0; } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { *(ptrd++) = 0; *(ptrd++) = 0; *(ptrd++) = (unsigned char)*(data1++); *(ptrd++) = 0; } break; case 2: if (cimg::X11attr().byte_order) cimg::swap(data1,data2); for (unsigned int xy = img.width*img.height; xy>0; --xy) { *(ptrd++) = 0; *(ptrd++) = (unsigned char)*(data2++); *(ptrd++) = (unsigned char)*(data1++); *(ptrd++) = 0; } break; default: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { *(ptrd++) = 0; *(ptrd++) = (unsigned char)*(data1++); *(ptrd++) = (unsigned char)*(data2++); *(ptrd++) = (unsigned char)*(data3++); } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { *(ptrd++) = (unsigned char)*(data3++); *(ptrd++) = (unsigned char)*(data2++); *(ptrd++) = (unsigned char)*(data1++); *(ptrd++) = 0; } break; } } if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned int*)data,width,height); delete[] ndata; } } break; }; } else { if (normalization==3) { if (cimg::type::is_float()) min = (float)img.minmax(max); else { min = (float)cimg::type::min(); max = (float)cimg::type::max(); } } else if ((min>max) || normalization==1) min = (float)img.minmax(max); const float delta = max-min, mm = delta?delta:1.0f; switch (cimg::X11attr().nb_bits) { case 8: { _set_colormap(colormap,img.dim); unsigned char *const ndata = (img.width==width && img.height==height)?(unsigned char*)data:new unsigned char[img.width*img.height]; unsigned char *ptrd = (unsigned char*)ndata; switch (img.dim) { case 1: for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char R = (unsigned char)(255*(*(data1++)-min)/mm); *(ptrd++) = R; } break; case 2: for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char R = (unsigned char)(255*(*(data1++)-min)/mm), G = (unsigned char)(255*(*(data2++)-min)/mm); (*ptrd++) = (R&0xf0) | (G>>4); } break; default: for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char R = (unsigned char)(255*(*(data1++)-min)/mm), G = (unsigned char)(255*(*(data2++)-min)/mm), B = (unsigned char)(255*(*(data3++)-min)/mm); *(ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6); } break; } if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned char*)data,width,height); delete[] ndata; } } break; case 16: { unsigned short *const ndata = (img.width==width && img.height==height)?(unsigned short*)data:new unsigned short[img.width*img.height]; unsigned char *ptrd = (unsigned char*)ndata; const unsigned int M = 248; switch (img.dim) { case 1: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)(255*(*(data1++)-min)/mm), G = val>>2; *(ptrd++) = val&M | (G>>3); *(ptrd++) = (G<<5) | (val>>3); } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)(255*(*(data1++)-min)/mm), G = val>>2; *(ptrd++) = (G<<5) | (val>>3); *(ptrd++) = val&M | (G>>3); } break; case 2: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2; *(ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm)&M | (G>>3); *(ptrd++) = (G<<5); } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2; *(ptrd++) = (G<<5); *(ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm)&M | (G>>3); } break; default: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2; *(ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm)&M | (G>>3); *(ptrd++) = (G<<5) | ((unsigned char)(255*(*(data3++)-min)/mm)>>3); } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2; *(ptrd++) = (G<<5) | ((unsigned char)(255*(*(data3++)-min)/mm)>>3); *(ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm)&M | (G>>3); } break; } if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned short*)data,width,height); delete[] ndata; } } break; default: { unsigned int *const ndata = (img.width==width && img.height==height)?(unsigned int*)data:new unsigned int[img.width*img.height]; if (sizeof(int)==4) { unsigned int *ptrd = ndata; switch (img.dim) { case 1: if (cimg::X11attr().byte_order==cimg::endian()) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)(255*(*(data1++)-min)/mm); *(ptrd++) = (val<<16) | (val<<8) | val; } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)(255*(*(data1++)-min)/mm); *(ptrd++) = (val<<24) | (val<<16) | (val<<8); } break; case 2: if (cimg::X11attr().byte_order==cimg::endian()) for (unsigned int xy = img.width*img.height; xy>0; --xy) *(ptrd++) = ((unsigned char)(255*(*(data1++)-min)/mm)<<16) | ((unsigned char)(255*(*(data2++)-min)/mm)<<8); else for (unsigned int xy = img.width*img.height; xy>0; --xy) *(ptrd++) = ((unsigned char)(255*(*(data2++)-min)/mm)<<16) | ((unsigned char)(255*(*(data1++)-min)/mm)<<8); break; default: if (cimg::X11attr().byte_order==cimg::endian()) for (unsigned int xy = img.width*img.height; xy>0; --xy) *(ptrd++) = ((unsigned char)(255*(*(data1++)-min)/mm)<<16) | ((unsigned char)(255*(*(data2++)-min)/mm)<<8) | (unsigned char)(255*(*(data3++)-min)/mm); else for (unsigned int xy = img.width*img.height; xy>0; --xy) *(ptrd++) = ((unsigned char)(255*(*(data3++)-min)/mm)<<24) | ((unsigned char)(255*(*(data2++)-min)/mm)<<16) | ((unsigned char)(255*(*(data1++)-min)/mm)<<8); break; } } else { unsigned char *ptrd = (unsigned char*)ndata; switch (img.dim) { case 1: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)(255*(*(data1++)-min)/mm); (*ptrd++) = 0; (*ptrd++) = val; (*ptrd++) = val; (*ptrd++) = val; } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = (unsigned char)(255*(*(data1++)-min)/mm); (*ptrd++) = val; (*ptrd++) = val; (*ptrd++) = val; (*ptrd++) = 0; } break; case 2: if (cimg::X11attr().byte_order) cimg::swap(data1,data2); for (unsigned int xy = img.width*img.height; xy>0; --xy) { (*ptrd++) = 0; (*ptrd++) = (unsigned char)(255*(*(data2++)-min)/mm); (*ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm); (*ptrd++) = 0; } break; default: if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { (*ptrd++) = 0; (*ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm); (*ptrd++) = (unsigned char)(255*(*(data2++)-min)/mm); (*ptrd++) = (unsigned char)(255*(*(data3++)-min)/mm); } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { (*ptrd++) = (unsigned char)(255*(*(data3++)-min)/mm); (*ptrd++) = (unsigned char)(255*(*(data2++)-min)/mm); (*ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm); (*ptrd++) = 0; } break; } } if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned int*)data,width,height); delete[] ndata; } } break; } } XUnlockDisplay(cimg::X11attr().display); return *this; } template const CImgDisplay& snapshot(CImg& img) const { if (is_empty()) img.assign(); else { img.assign(width,height,1,3); T *data1 = img.ptr(0,0,0,0), *data2 = img.ptr(0,0,0,1), *data3 = img.ptr(0,0,0,2); if (cimg::X11attr().blue_first) cimg::swap(data1,data3); switch (cimg::X11attr().nb_bits) { case 8: { unsigned char *ptrs = (unsigned char*)data; for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val = *(ptrs++); *(data1++) = val&0xe0; *(data2++) = (val&0x1c)<<3; *(data3++) = val<<6; } } break; case 16: { unsigned char *ptrs = (unsigned char*)data; if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned char val0 = *(ptrs++), val1 = *(ptrs++); *(data1++) = val0&0xf8; *(data2++) = (val0<<5) | ((val1&0xe0)>>5); *(data3++) = val1<<3; } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { const unsigned short val0 = *(ptrs++), val1 = *(ptrs++); *(data1++) = val1&0xf8; *(data2++) = (val1<<5) | ((val0&0xe0)>>5); *(data3++) = val0<<3; } } break; default: { unsigned char *ptrs = (unsigned char*)data; if (cimg::X11attr().byte_order) for (unsigned int xy = img.width*img.height; xy>0; --xy) { ++ptrs; *(data1++) = *(ptrs++); *(data2++) = *(ptrs++); *(data3++) = *(ptrs++); } else for (unsigned int xy = img.width*img.height; xy>0; --xy) { *(data3++) = *(ptrs++); *(data2++) = *(ptrs++); *(data1++) = *(ptrs++); ++ptrs; } } break; } } return *this; } static int _assign_xshm(Display *dpy, XErrorEvent *error) { dpy = 0; error = 0; cimg::X11attr().shm_enabled = false; return 0; } void _assign(const unsigned int dimw, const unsigned int dimh, const char *ptitle=0, const unsigned int normalization_type=3, const unsigned int events_type=3, const bool fullscreen_flag=false, const bool closed_flag=false) { const int s = cimg::strlen(ptitle)+1; char *tmp_title = s?new char[s]:0; if (s) std::memcpy(tmp_title,ptitle,s*sizeof(char)); if (!is_empty()) assign(); if (!cimg::X11attr().display) { static bool xinit_threads = false; if (!xinit_threads) { XInitThreads(); xinit_threads = true; } cimg::X11attr().nb_wins = 0; cimg::X11attr().display = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0")); if (!cimg::X11attr().display) throw CImgDisplayException("CImgDisplay::_create_window() : Can't open X11 display"); cimg::X11attr().nb_bits = ((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->root_depth); if (cimg::X11attr().nb_bits!=8 && cimg::X11attr().nb_bits!=16 && cimg::X11attr().nb_bits!=24 && cimg::X11attr().nb_bits!=32) throw CImgDisplayException("CImgDisplay::_create_window() : %u bits mode is not supported " "(only 8, 16, 24 and 32 bits modes are supported)",cimg::X11attr().nb_bits); cimg::X11attr().gc = new GC; *cimg::X11attr().gc = ((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->default_gc); Visual *visual = ((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->root_visual); XVisualInfo vtemplate; vtemplate.visualid = XVisualIDFromVisual(visual); int nb_visuals; XVisualInfo *vinfo = XGetVisualInfo(cimg::X11attr().display,0x1,&vtemplate,&nb_visuals); if (vinfo && vinfo->red_maskblue_mask) cimg::X11attr().blue_first = true; cimg::X11attr().byte_order = (((_XPrivDisplay)cimg::X11attr().display)->byte_order); XFree(vinfo); XLockDisplay(cimg::X11attr().display); cimg::X11attr().event_thread = new pthread_t; pthread_create(cimg::X11attr().event_thread,0,_events_thread,0); } else XLockDisplay(cimg::X11attr().display); width = cimg::min(dimw,(unsigned int)screen_dimx()); height = cimg::min(dimh,(unsigned int)screen_dimy()); normalization = normalization_type%4; events = events_type%4; is_fullscreen = fullscreen_flag; title = tmp_title; window_x = window_y = wheel = 0; mouse_x = mouse_y = -1; std::memset((void*)buttons,0,512*sizeof(unsigned int)); std::memset((void*)keys,0,512*sizeof(unsigned int)); std::memset((void*)released_keys,0,512*sizeof(unsigned int)); is_resized = is_moved = is_event = false; is_closed = closed_flag; fps_timer = fps_frames = timer = 0; fps_fps = 0; if (is_fullscreen) { _init_fullscreen(); const unsigned int sx = screen_dimx(), sy = screen_dimy(); XSetWindowAttributes winattr; winattr.override_redirect = 1; window = XCreateWindow(cimg::X11attr().display, ((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->root), (sx-width)/2,(sy-height)/2, width,height,0,0,1,0L,(1L<<9),&winattr); } else window = XCreateSimpleWindow(cimg::X11attr().display, ((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->root), 0,0,width,height,2,0,0x0L); XStoreName(cimg::X11attr().display,window,title?title:" "); if (cimg::X11attr().nb_bits==8) { colormap = XCreateColormap(cimg::X11attr().display,window,((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->root_visual),1); _set_colormap(colormap,3); XSetWindowColormap(cimg::X11attr().display,window,colormap); } window_width = width; window_height = height; const unsigned int bufsize = width*height*(cimg::X11attr().nb_bits==8?1:(cimg::X11attr().nb_bits==16?2:4)); { data = std::malloc(bufsize); image = XCreateImage(cimg::X11attr().display,((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->root_visual), cimg::X11attr().nb_bits,2,0,(char*)data,width,height,8,0); } if (!is_closed) _map_window(); else { window_x = window_y = cimg::type::min(); } if (events) { wm_delete_window = XInternAtom(cimg::X11attr().display, "WM_DELETE_WINDOW", 0); wm_delete_protocol = XInternAtom(cimg::X11attr().display, "WM_PROTOCOLS", 0); XSetWMProtocols(cimg::X11attr().display, window, &wm_delete_window, 1); if (is_fullscreen) XGrabKeyboard(cimg::X11attr().display, window, 1, 1, 1, 0L); } cimg::X11attr().wins[cimg::X11attr().nb_wins++]=this; XUnlockDisplay(cimg::X11attr().display); } void _map_window() { XWindowAttributes attr; XEvent event; XSelectInput(cimg::X11attr().display,window,(1L<<15) | (1L<<17)); bool exposed = false, mapped = false; XMapRaised(cimg::X11attr().display,window); XSync(cimg::X11attr().display,0); do { XWindowEvent(cimg::X11attr().display,window,(1L<<17) | (1L<<15),&event); switch (event.type) { case 19: mapped = true; break; case 12: exposed = true; break; default: XSync(cimg::X11attr().display, 0); cimg::sleep(10); } } while (!(exposed && mapped)); do { XGetWindowAttributes(cimg::X11attr().display, window, &attr); if (attr.map_state!=2) { XSync(cimg::X11attr().display,0); cimg::sleep(10); } } while (attr.map_state != 2); window_x = attr.x; window_y = attr.y; } void _set_colormap(Colormap& colormap, const unsigned int dim) { XColor palette[256]; switch (dim) { case 1: for (unsigned int index=0; index<256; ++index) { palette[index].pixel = index; palette[index].red = palette[index].green = palette[index].blue = (unsigned short)(index<<8); palette[index].flags = (1<<0) | (1<<1) | (1<<2); } break; case 2: for (unsigned int index=0, r=8; r<256; r+=16) for (unsigned int g=8; g<256; g+=16) { palette[index].pixel = index; palette[index].red = palette[index].blue = (unsigned short)(r<<8); palette[index].green = (unsigned short)(g<<8); palette[index++].flags = (1<<0) | (1<<1) | (1<<2); } break; default: for (unsigned int index=0, r=16; r<256; r+=32) for (unsigned int g=16; g<256; g+=32) for (unsigned int b=32; b<256; b+=64) { palette[index].pixel = index; palette[index].red = (unsigned short)(r<<8); palette[index].green = (unsigned short)(g<<8); palette[index].blue = (unsigned short)(b<<8); palette[index++].flags = (1<<0) | (1<<1) | (1<<2); } break; } XStoreColors(cimg::X11attr().display,colormap,palette,256); } void _paint(const bool wait_expose=true) { if (!is_closed) { if (wait_expose) { static XEvent event; event.xexpose.type = 12; event.xexpose.serial = 0; event.xexpose.send_event = 1; event.xexpose.display = cimg::X11attr().display; event.xexpose.window = window; event.xexpose.x = 0; event.xexpose.y = 0; event.xexpose.width = dimx(); event.xexpose.height = dimy(); event.xexpose.count = 0; XSendEvent(cimg::X11attr().display, window, 0, 0, &event); } else { XPutImage(cimg::X11attr().display,window,*cimg::X11attr().gc,image,0,0,0,0,width,height); XSync(cimg::X11attr().display, 0); } } } template void _resize(T foo, const unsigned int ndimx, const unsigned int ndimy, const bool redraw) { foo = 0; { T *ndata = (T*)std::malloc(ndimx*ndimy*sizeof(T)); if (redraw) _render_resize((T*)data,width,height,ndata,ndimx,ndimy); else std::memset(ndata,0,sizeof(T)*ndimx*ndimy); data = (void*)ndata; ((*((image)->f.destroy_image))((image))); image = XCreateImage(cimg::X11attr().display,((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->root_visual), cimg::X11attr().nb_bits,2,0,(char*)data,ndimx,ndimy,8,0); } } void _init_fullscreen() { background_window = 0; if (is_fullscreen && !is_closed) { const unsigned int sx = screen_dimx(), sy = screen_dimy(); XSetWindowAttributes winattr; winattr.override_redirect = 1; if (sx!=width || sy!=height) { background_window = XCreateWindow(cimg::X11attr().display, ((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->root),0,0, sx,sy,0,0,1,0L,(1L<<9),&winattr); const unsigned int bufsize = sx*sy*(cimg::X11attr().nb_bits==8?1:(cimg::X11attr().nb_bits==16?2:4)); void *background_data = std::malloc(bufsize); std::memset(background_data,0,bufsize); XImage *background_image = XCreateImage(cimg::X11attr().display,((&((_XPrivDisplay)cimg::X11attr().display)->screens[(((_XPrivDisplay)cimg::X11attr().display)->default_screen)])->root_visual), cimg::X11attr().nb_bits,2,0,(char*)background_data,sx,sy,8,0); XEvent event; XSelectInput(cimg::X11attr().display,background_window,(1L<<17)); XMapRaised(cimg::X11attr().display,background_window); do XWindowEvent(cimg::X11attr().display,background_window,(1L<<17),&event); while (event.type!=19); XPutImage(cimg::X11attr().display,background_window,*cimg::X11attr().gc,background_image,0,0,0,0,sx,sy); XWindowAttributes attr; XGetWindowAttributes(cimg::X11attr().display, background_window, &attr); while (attr.map_state != 2) XSync(cimg::X11attr().display, 0); ((*((background_image)->f.destroy_image))((background_image))); } } } void _desinit_fullscreen() { if (is_fullscreen) { XUngrabKeyboard(cimg::X11attr().display,0L); if (background_window) XDestroyWindow(cimg::X11attr().display,background_window); background_window = 0; is_fullscreen = false; } } void _handle_events(const XEvent *const pevent) { XEvent event=*pevent; switch (event.type) { case 33: if ((int)event.xclient.message_type==(int)wm_delete_protocol && (int)event.xclient.data.l[0]==(int)wm_delete_window) { XUnmapWindow(cimg::X11attr().display,window); mouse_x = mouse_y = -1; if (button) { std::memmove((void*)(buttons+1),(void*)buttons,512-1); button = 0; } if (key) { std::memmove((void*)(keys+1),(void*)keys,512-1); key = 0; } if (released_key) { std::memmove((void*)(released_keys+1),(void*)released_keys,512-1); released_key = 0; } is_closed = is_event = true; } break; case 22: { while (XCheckWindowEvent(cimg::X11attr().display,window,(1L<<17),&event)); const unsigned int nw = event.xconfigure.width, nh = event.xconfigure.height; const int nx = event.xconfigure.x, ny = event.xconfigure.y; if (nw && nh && (nw!=window_width || nh!=window_height)) { window_width = nw; window_height = nh; mouse_x = mouse_y = -1; XResizeWindow(cimg::X11attr().display,window,window_width,window_height); is_resized = is_event = true; } if (nx!=window_x || ny!=window_y) { window_x = nx; window_y = ny; is_moved = is_event = true; } } break; case 12: { while (XCheckWindowEvent(cimg::X11attr().display,window,(1L<<15),&event)); _paint(false); if (is_fullscreen) { XWindowAttributes attr; XGetWindowAttributes(cimg::X11attr().display, window, &attr); while (attr.map_state != 2) XSync(cimg::X11attr().display, 0); XSetInputFocus(cimg::X11attr().display, window, 2, 0L); } } break; case 4: { do { switch (event.xbutton.button) { case 1: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button|=1; is_event = true; break; case 2: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button|=4; is_event = true; break; case 3: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button|=2; is_event = true; break; default: break; } } while (XCheckWindowEvent(cimg::X11attr().display,window,(1L<<2),&event)); } break; case 5: { do { switch (event.xbutton.button) { case 1: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button&=~1U; is_event = true; break; case 2: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button&=~4U; is_event = true; break; case 3: std::memmove((void*)(buttons+1),(void*)buttons,512-1); button&=~2U; is_event = true; break; case 4: ++wheel; is_event = true; break; case 5: --wheel; is_event = true; break; default: break; } } while (XCheckWindowEvent(cimg::X11attr().display,window,(1L<<3),&event)); } break; case 2: { char tmp; KeySym ksym; XLookupString(&event.xkey,&tmp,1,&ksym,0); if (key) std::memmove((void*)(keys+1),(void*)keys,512-1); key = (unsigned int)ksym; if (released_key) { std::memmove((void*)(released_keys+1),(void*)released_keys,512-1); released_key = 0; } is_event = true; } break; case 3: { char tmp; KeySym ksym; XLookupString(&event.xkey,&tmp,1,&ksym,0); if (key) { std::memmove((void*)(keys+1),(void*)keys,512-1); key = 0; } if (released_key) std::memmove((void*)(released_keys+1),(void*)released_keys,512-1); released_key = (unsigned int)ksym; is_event = true; } break; case 8: while (XCheckWindowEvent(cimg::X11attr().display,window,(1L<<5),&event)); mouse_x = mouse_y =-1; is_event = true; break; case 6: while (XCheckWindowEvent(cimg::X11attr().display,window,(1L<<6),&event)); mouse_x = event.xmotion.x; mouse_y = event.xmotion.y; if (mouse_x<0 || mouse_y<0 || mouse_x>=dimx() || mouse_y>=dimy()) mouse_x = mouse_y = -1; is_event = true; break; } } static void* _events_thread(void *arg) { arg = 0; XEvent event; pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,0); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0); for (;;) { XLockDisplay(cimg::X11attr().display); for (unsigned int i=0; ievents)&3; const unsigned int emask = ((xevent_type>=1)?(1L<<15)|(1L<<17):0)| ((xevent_type>=2)?(1L<<2)|(1L<<0)|(1L<<6)|(1L<<5):0)| ((xevent_type>=3)?(1L<<3)|(1L<<1):0); XSelectInput(cimg::X11attr().display,cimg::X11attr().wins[i]->window,emask); } bool event_flag = XCheckTypedEvent(cimg::X11attr().display, 33, &event); if (!event_flag) event_flag = XCheckMaskEvent(cimg::X11attr().display, (1L<<15)|(1L<<17)|(1L<<2)| (1L<<0)|(1L<<6)|(1L<<5)|(1L<<3)| (1L<<1),&event); if (event_flag) { for (unsigned int i=0; iis_closed && event.xany.window==cimg::X11attr().wins[i]->window) cimg::X11attr().wins[i]->_handle_events(&event); } XUnlockDisplay(cimg::X11attr().display); pthread_testcancel(); cimg::sleep(7); } return 0; } }; template struct CImg { unsigned int width; unsigned int height; unsigned int depth; unsigned int dim; bool is_shared; T *data; typedef T* iterator; typedef const T* const_iterator; typedef T value_type; struct _greycstoration_params { bool patch_based; float amplitude; float sharpness; float anisotropy; float alpha; float sigma; float gfact; float dl; float da; float gauss_prec; unsigned int interpolation; unsigned int patch_size; float sigma_s; float sigma_p; unsigned int lookup_size; CImg *source; const CImg *mask; CImg *temporary; unsigned long *counter; unsigned int tile; unsigned int tile_border; unsigned int thread; unsigned int nb_threads; bool fast_approx; bool is_running; bool *stop_request; pthread_mutex_t *mutex; _greycstoration_params():patch_based(false),amplitude(0),sharpness(0),anisotropy(0),alpha(0),sigma(0),gfact(1), dl(0),da(0),gauss_prec(0),interpolation(0),patch_size(0), sigma_s(0),sigma_p(0),lookup_size(0),source(0),mask(0),temporary(0),counter(0),tile(0), tile_border(0),thread(0),nb_threads(0),fast_approx(false),is_running(false), stop_request(0), mutex(0) {} }; _greycstoration_params greycstoration_params[16]; bool greycstoration_is_running() const { return greycstoration_params->is_running; } CImg& greycstoration_stop() { if (greycstoration_is_running()) { *(greycstoration_params->stop_request) = true; while (greycstoration_params->is_running) cimg::wait(50); } return *this; } float greycstoration_progress() const { if (!greycstoration_is_running()) return 0.0f; const unsigned long counter = greycstoration_params->counter?*(greycstoration_params->counter):0; const float da = greycstoration_params->da, factor = greycstoration_params->patch_based?1:(1+360/da); float maxcounter = 0; if (greycstoration_params->tile==0) maxcounter = width*height*depth*factor; else { const unsigned int t = greycstoration_params->tile, b = greycstoration_params->tile_border, n = (1+(width-1)/t)*(1+(height-1)/t)*(1+(depth-1)/t); maxcounter = (width*height*depth + n*4*b*(b + t))*factor; } return cimg::min(counter*99.9f/maxcounter,99.9f); } CImg& greycstoration_run(const CImg& mask, const float amplitude=60, const float sharpness=0.7f, const float anisotropy=0.3f, const float alpha=0.6f, const float sigma=1.1f, const float gfact=1.0f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true, const unsigned int tile=0, const unsigned int tile_border=0, const unsigned int nb_threads=1) { if (greycstoration_is_running()) throw CImgInstanceException("CImg::greycstoration_run() : A GREYCstoration thread is already running on" " the instance image (%u,%u,%u,%u,%p).",width,height,depth,dim,data); else { if (!mask.is_empty() && !mask.is_sameXY(*this)) throw CImgArgumentException("CImg<%s>::greycstoration_run() : Given mask (%u,%u,%u,%u,%p) and instance image " "(%u,%u,%u,%u,%p) have different dimensions.", pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data,width,height,depth,dim,data); if (nb_threads>16) cimg::warn("CImg<%s>::greycstoration_run() : Multi-threading mode limited to 16 threads max."); const unsigned int ntile = (tile && (tile1 && tile *const temporary = ntile?new CImg(*this):0; unsigned long *const counter = new unsigned long; *counter = 0; bool *const stop_request = new bool; *stop_request = false; for (unsigned int k=0; k<(nthreads?nthreads:1); k++) { greycstoration_params[k].patch_based = false; greycstoration_params[k].amplitude = amplitude; greycstoration_params[k].sharpness = sharpness; greycstoration_params[k].anisotropy = anisotropy; greycstoration_params[k].alpha = alpha; greycstoration_params[k].sigma = sigma; greycstoration_params[k].gfact = gfact; greycstoration_params[k].dl = dl; greycstoration_params[k].da = da; greycstoration_params[k].gauss_prec = gauss_prec; greycstoration_params[k].interpolation = interpolation; greycstoration_params[k].fast_approx = fast_approx; greycstoration_params[k].source = this; greycstoration_params[k].mask = &mask; greycstoration_params[k].temporary = temporary; greycstoration_params[k].counter = counter; greycstoration_params[k].tile = ntile; greycstoration_params[k].tile_border = tile_border; greycstoration_params[k].thread = k; greycstoration_params[k].nb_threads = nthreads; greycstoration_params[k].is_running = true; greycstoration_params[k].stop_request = stop_request; if (k) greycstoration_params[k].mutex = greycstoration_params[0].mutex; else greycstoration_mutex_create(greycstoration_params[0]); } if (nthreads) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); for (unsigned int k=0; knb_threads; k++) { pthread_t thread; const int err = pthread_create(&thread, &attr, greycstoration_thread, (void*)(greycstoration_params+k)); if (err) throw CImgException("CImg<%s>::greycstoration_run() : pthread_create returned error %d", pixel_type(), err); } } else greycstoration_thread((void*)greycstoration_params); } return *this; } CImg& greycstoration_run(const float amplitude=50, const float sharpness=0.7f, const float anisotropy=0.3f, const float alpha=0.6f, const float sigma=1.1f, const float gfact=1.0f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true, const unsigned int tile=0, const unsigned int tile_border=0, const unsigned int nb_threads=1) { static const CImg empty_mask; return greycstoration_run(empty_mask,amplitude,sharpness,anisotropy,alpha,sigma,gfact,dl,da,gauss_prec, interpolation,fast_approx,tile,tile_border,nb_threads); } CImg& greycstoration_patch_run(const unsigned int patch_size=5, const float sigma_p=10, const float sigma_s=100, const unsigned int lookup_size=20, const bool fast_approx=true, const unsigned int tile=0, const unsigned int tile_border=0, const unsigned int nb_threads=1) { static const CImg empty_mask; if (greycstoration_is_running()) throw CImgInstanceException("CImg::greycstoration_run() : A GREYCstoration thread is already running on" " the instance image (%u,%u,%u,%u,%p).",width,height,depth,dim,data); else { if (nb_threads>16) cimg::warn("CImg<%s>::greycstoration_run() : Multi-threading mode limited to 16 threads max."); const unsigned int ntile = (tile && (tile1 && tile *const temporary = ntile?new CImg(*this):0; unsigned long *const counter = new unsigned long; *counter = 0; bool *const stop_request = new bool; *stop_request = false; for (unsigned int k=0; k<(nthreads?nthreads:1); k++) { greycstoration_params[k].patch_based = true; greycstoration_params[k].patch_size = patch_size; greycstoration_params[k].sigma_s = sigma_s; greycstoration_params[k].sigma_p = sigma_p; greycstoration_params[k].lookup_size = lookup_size; greycstoration_params[k].source = this; greycstoration_params[k].mask = &empty_mask; greycstoration_params[k].temporary = temporary; greycstoration_params[k].counter = counter; greycstoration_params[k].tile = ntile; greycstoration_params[k].tile_border = tile_border; greycstoration_params[k].thread = k; greycstoration_params[k].nb_threads = nthreads; greycstoration_params[k].fast_approx = fast_approx; greycstoration_params[k].is_running = true; greycstoration_params[k].stop_request = stop_request; if (k) greycstoration_params[k].mutex = greycstoration_params[0].mutex; else greycstoration_mutex_create(greycstoration_params[0]); } if (nthreads) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); for (unsigned int k=0; knb_threads; k++) { pthread_t thread; const int err = pthread_create(&thread, &attr, greycstoration_thread, (void*)(greycstoration_params+k)); if (err) throw CImgException("CImg<%s>::greycstoration_run() : pthread_create returned error %d", pixel_type(), err); } } else greycstoration_thread((void*)greycstoration_params); } return *this; } static void greycstoration_mutex_create(_greycstoration_params &p) { if (p.nb_threads>1) { p.mutex = new pthread_mutex_t; pthread_mutex_init(p.mutex,0); } } static void greycstoration_mutex_lock(_greycstoration_params &p) { if (p.nb_threads>1) { if (p.mutex) pthread_mutex_lock(p.mutex); } } static void greycstoration_mutex_unlock(_greycstoration_params &p) { if (p.nb_threads>1) { if (p.mutex) pthread_mutex_unlock(p.mutex); } } static void greycstoration_mutex_destroy(_greycstoration_params &p) { if (p.nb_threads>1) { if (p.mutex) pthread_mutex_destroy(p.mutex); p.mutex = 0; } } static void* greycstoration_thread(void *arg) { _greycstoration_params &p = *(_greycstoration_params*)arg; greycstoration_mutex_lock(p); const CImg &mask = *(p.mask); CImg &source = *(p.source); if (!p.tile) { if (p.patch_based) source.blur_patch(p.patch_size,p.sigma_p,p.sigma_s,p.lookup_size,p.fast_approx); else source.blur_anisotropic(mask,p.amplitude,p.sharpness,p.anisotropy,p.alpha,p.sigma,p.dl,p.da,p.gauss_prec, p.interpolation,p.fast_approx,p.gfact); } else { CImg &temporary = *(p.temporary); const bool threed = (source.depth>1); const unsigned int b = p.tile_border; unsigned int ctile = 0; if (threed) { for (unsigned int z=0; z img = source.get_crop(x-b,y-b,z-b,xe+b,ye+b,ze+b,true); CImg mask_tile = mask.is_empty()?mask:mask.get_crop(x-b,y-b,z-b,xe+b,ye+b,ze+b,true); img.greycstoration_params[0] = p; greycstoration_mutex_unlock(p); if (p.patch_based) img.blur_patch(p.patch_size,p.sigma_p,p.sigma_s,p.lookup_size,p.fast_approx); else img.blur_anisotropic(mask_tile,p.amplitude,p.sharpness,p.anisotropy, p.alpha,p.sigma,p.dl,p.da,p.gauss_prec,p.interpolation,p.fast_approx,p.gfact); greycstoration_mutex_lock(p); temporary.draw_image(img.crop(b,b,b,img.width-b,img.height-b,img.depth-b),x,y,z); } } else { for (unsigned int y=0; y img = source.get_crop(x-b,y-b,xe+b,ye+b,true); CImg mask_tile = mask.is_empty()?mask:mask.get_crop(x-b,y-b,xe+b,ye+b,true); img.greycstoration_params[0] = p; greycstoration_mutex_unlock(p); if (p.patch_based) img.blur_patch(p.patch_size,p.sigma_p,p.sigma_s,p.lookup_size,p.fast_approx); else img.blur_anisotropic(mask_tile,p.amplitude,p.sharpness,p.anisotropy, p.alpha,p.sigma,p.dl,p.da,p.gauss_prec,p.interpolation,p.fast_approx,p.gfact); temporary.draw_image(img.crop(b,b,img.width-b,img.height-b),x,y); greycstoration_mutex_lock(p); } } } greycstoration_mutex_unlock(p); if (!p.thread) { if (p.nb_threads>1) { bool stopflag = true; do { stopflag = true; for (unsigned int k=1; k& assign() { if (data && !is_shared) delete[] data; width = height = depth = dim = 0; is_shared = false; data = 0; return *this; } CImg& clear() { return assign(); } explicit CImg(const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1): is_shared(false) { const unsigned long siz = dx*dy*dz*dv; if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new T[siz]; } else { width = height = depth = dim = 0; data = 0; } } CImg& assign(const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) { const unsigned long siz = dx*dy*dz*dv; if (!siz) return assign(); const unsigned long curr_siz = size(); if (is_shared) { if (siz>curr_siz) throw CImgArgumentException("CImg<%s>::assign() : Cannot assign image (%u,%u,%u,%u) to shared instance image (%u,%u,%u,%u,%p).", pixel_type(),dx,dy,dz,dv,width,height,depth,dim,data); } else { if (siz!=curr_siz) { if (data) delete[] data; data = new T[siz]; } width = dx; height = dy; depth = dz; dim = dv; } return *this; } CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const T val): is_shared(false) { const unsigned long siz = dx*dy*dz*dv; if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new T[siz]; fill(val); } else { width = height = depth = dim = 0; data = 0; } } CImg& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const T val) { return assign(dx,dy,dz,dv).fill(val); } template CImg(const t *const data_buffer, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1, const bool shared=false):is_shared(false) { if (shared) throw CImgArgumentException("CImg<%s>::CImg() : Cannot construct a shared copy from a (%s*) buffer " "(different pixel types).",pixel_type(),CImg::pixel_type()); const unsigned long siz = dx*dy*dz*dv; if (data_buffer && siz) { width = dx; height = dy; depth = dz; dim = dv; data = new T[siz]; const t *ptrs = data_buffer + siz; for (T *ptrd = (*this).data + (*this).size(); (ptrd--)>(*this).data; ) *ptrd = (T)*(--ptrs); } else { width = height = depth = dim = 0; data = 0; } } CImg(const T *const data_buffer, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1, const bool shared=false) { const unsigned long siz = dx*dy*dz*dv; if (data_buffer && siz) { width = dx; height = dy; depth = dz; dim = dv; is_shared = shared; if (is_shared) data = const_cast(data_buffer); else { data = new T[siz]; std::memcpy(data,data_buffer,siz*sizeof(T)); } } else { width = height = depth = dim = 0; is_shared = false; data = 0; } } template CImg& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) { const unsigned long siz = dx*dy*dz*dv; if (!data_buffer || !siz) return assign(); assign(dx,dy,dz,dv); const t *ptrs = data_buffer + siz; for (T *ptrd = (*this).data + (*this).size(); (ptrd--)>(*this).data; ) *ptrd = (T)*(--ptrs); return *this; } CImg& assign(const T *const data_buffer, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) { const unsigned long siz = dx*dy*dz*dv; if (!data_buffer || !siz) return assign(); const unsigned long curr_siz = size(); if (data_buffer==data && siz==curr_siz) return assign(dx,dy,dz,dv); if (is_shared || data_buffer+siz=data+size()) { assign(dx,dy,dz,dv); if (is_shared) std::memmove(data,data_buffer,siz*sizeof(T)); else std::memcpy(data,data_buffer,siz*sizeof(T)); } else { T *new_data = new T[siz]; std::memcpy(new_data,data_buffer,siz*sizeof(T)); delete[] data; data = new_data; width = dx; height = dy; depth = dz; dim = dv; } return *this; } template CImg& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const bool shared) { if (shared) throw CImgArgumentException("CImg<%s>::assign() : Cannot construct a shared copy from a (%s*) buffer " "(different pixel types).",pixel_type(),CImg::pixel_type()); return assign().assign(data_buffer,dx,dy,dz,dv); } CImg& assign(const T *const data_buffer, const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const bool shared) { if (!shared) return assign(data_buffer,dx,dy,dz,dv); const unsigned long siz = dx*dy*dz*dv; if (!data_buffer || !siz) throw CImgArgumentException("CImg<%s>::assign() : Cannot construct a shared copy of an empty image.",pixel_type()); if (!is_shared) { if (data_buffer+siz=data+size()) assign(); else cimg::warn("CImg<%s>::assign() : Create shared version of previous parts of the instance image, possible memory leaks !", pixel_type()); } width = dx; height = dy; depth = dz; dim = dv; is_shared = true; data = const_cast(data_buffer); return *this; } template CImg(const CImg& img):is_shared(false) { const unsigned int siz = img.size(); if (img.data && siz) { width = img.width; height = img.height; depth = img.depth; dim = img.dim; data = new T[siz]; const t *ptrs = img.data + siz; for (T *ptrd = (*this).data + (*this).size(); (ptrd--)>(*this).data; ) *ptrd = (T)*(--ptrs); } else { width = height = depth = dim = 0; data = 0; } } CImg(const CImg& img) { const unsigned int siz = img.size(); if (img.data && siz) { width = img.width; height = img.height; depth = img.depth; dim = img.dim; is_shared = img.is_shared; if (is_shared) data = const_cast(img.data); else { data = new T[siz]; std::memcpy(data,img.data,siz*sizeof(T)); } } else { width = height = depth = dim = 0; is_shared = false; data = 0; } } template CImg& assign(const CImg& img) { return assign(img.data,img.width,img.height,img.depth,img.dim); } template CImg(const CImg& img, const bool shared):is_shared(false) { if (shared) throw CImgArgumentException("CImg<%s>::CImg() : Cannot construct a shared copy from a CImg<%s> image " "(different pixel types).",pixel_type(),CImg::pixel_type()); const unsigned int siz = img.size(); if (img.data && siz) { width = img.width; height = img.height; depth = img.depth; dim = img.dim; data = new T[siz]; const t *ptrs = img.data+siz; for (T *ptrd = (*this).data + (*this).size(); (ptrd--)>(*this).data; ) *ptrd = (T)*(--ptrs); } else { width = height = depth = dim = 0; data = 0; } } CImg(const CImg& img, const bool shared) { const unsigned int siz = img.size(); if (img.data && siz) { width = img.width; height = img.height; depth = img.depth; dim = img.dim; is_shared = shared; if (is_shared) data = const_cast(img.data); else { data = new T[siz]; std::memcpy(data,img.data,siz*sizeof(T)); } } else { width = height = depth = dim = 0; is_shared = false; data = 0; } } template CImg& assign(const CImg& img, const bool shared) { return assign(img.data,img.width,img.height,img.depth,img.dim,shared); } CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const int val0, const int val1, ...):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) { assign(dx,dy,dz,dv); { unsigned int _siz = (unsigned int)dx*dy*dz*dv; if (_siz--) { va_list ap; __builtin_va_start(ap,val1); T *ptrd = (*this).data; *(ptrd++) = (T)val0; if (_siz--) { *(ptrd++) = (T)val1; for (; _siz; --_siz) *(ptrd++) = (T)__builtin_va_arg(ap,int); } __builtin_va_end(ap); }}; } CImg& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const int val0, const int val1, ...) { assign(dx,dy,dz,dv); { unsigned int _siz = (unsigned int)dx*dy*dz*dv; if (_siz--) { va_list ap; __builtin_va_start(ap,val1); T *ptrd = (*this).data; *(ptrd++) = (T)val0; if (_siz--) { *(ptrd++) = (T)val1; for (; _siz; --_siz) *(ptrd++) = (T)__builtin_va_arg(ap,int); } __builtin_va_end(ap); }}; return *this; } CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const double val0, const double val1, ...):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) { assign(dx,dy,dz,dv); { unsigned int _siz = (unsigned int)dx*dy*dz*dv; if (_siz--) { va_list ap; __builtin_va_start(ap,val1); T *ptrd = (*this).data; *(ptrd++) = (T)val0; if (_siz--) { *(ptrd++) = (T)val1; for (; _siz; --_siz) *(ptrd++) = (T)__builtin_va_arg(ap,double); } __builtin_va_end(ap); }}; } CImg& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const double val0, const double val1, ...) { assign(dx,dy,dz,dv); { unsigned int _siz = (unsigned int)dx*dy*dz*dv; if (_siz--) { va_list ap; __builtin_va_start(ap,val1); T *ptrd = (*this).data; *(ptrd++) = (T)val0; if (_siz--) { *(ptrd++) = (T)val1; for (; _siz; --_siz) *(ptrd++) = (T)__builtin_va_arg(ap,double); } __builtin_va_end(ap); }}; return *this; } template CImg(const CImg& img, const char *const dimensions):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) { assign(img,dimensions); } template CImg& assign(const CImg& img, const char *const dimensions) { if (dimensions) { unsigned int siz[4] = { 0,1,1,1 }; const char *s = dimensions; char tmp[256] = { 0 }, c = 0; int val = 0; for (unsigned int k=0; k<4; ++k) { const int err = std::sscanf(s,"%[-0-9]%c",tmp,&c); if (err>=1) { const int err = std::sscanf(s,"%d",&val); if (err==1) { int val2 = val<0?-val:(c=='%'?val:-1); if (val2>=0) { val = (int)((k==0?img.width:(k==1?img.height:(k==2?img.depth:img.dim)))*val2/100); if (c!='%' && !val) val = 1; } siz[k] = val; } s+=cimg::strlen(tmp); if (c=='%') ++s; } if (!err) { if (!cimg::strncasecmp(s,"x",1)) { ++s; siz[k] = img.width; } else if (!cimg::strncasecmp(s,"y",1)) { ++s; siz[k] = img.height; } else if (!cimg::strncasecmp(s,"z",1)) { ++s; siz[k] = img.depth; } else if (!cimg::strncasecmp(s,"v",1)) { ++s; siz[k] = img.dim; } else if (!cimg::strncasecmp(s,"dx",2)) { s+=2; siz[k] = img.width; } else if (!cimg::strncasecmp(s,"dy",2)) { s+=2; siz[k] = img.height; } else if (!cimg::strncasecmp(s,"dz",2)) { s+=2; siz[k] = img.depth; } else if (!cimg::strncasecmp(s,"dv",2)) { s+=2; siz[k] = img.dim; } else if (!cimg::strncasecmp(s,"dimx",4)) { s+=4; siz[k] = img.width; } else if (!cimg::strncasecmp(s,"dimy",4)) { s+=4; siz[k] = img.height; } else if (!cimg::strncasecmp(s,"dimz",4)) { s+=4; siz[k] = img.depth; } else if (!cimg::strncasecmp(s,"dimv",4)) { s+=4; siz[k] = img.dim; } else if (!cimg::strncasecmp(s,"width",5)) { s+=5; siz[k] = img.width; } else if (!cimg::strncasecmp(s,"height",6)) { s+=6; siz[k] = img.height; } else if (!cimg::strncasecmp(s,"depth",5)) { s+=5; siz[k] = img.depth; } else if (!cimg::strncasecmp(s,"dim",3)) { s+=3; siz[k] = img.dim; } else { ++s; --k; } } } return assign(siz[0],siz[1],siz[2],siz[3]); } return assign(); } template CImg(const CImg& img, const char *const dimensions, const T val): width(0),height(0),depth(0),dim(0),is_shared(false),data(0) { assign(img,dimensions).fill(val); } template CImg& assign(const CImg& img, const char *const dimensions, const T val) { return assign(img,dimensions).fill(val); } CImg(const char *const filename):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) { assign(filename); } CImg& assign(const char *const filename) { return load(filename); } CImg(const CImgDisplay &disp):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) { disp.snapshot(*this); } CImg& assign(const CImgDisplay &disp) { disp.snapshot(*this); return *this; } CImg& swap(CImg& img) { cimg::swap(width,img.width); cimg::swap(height,img.height); cimg::swap(depth,img.depth); cimg::swap(dim,img.dim); cimg::swap(data,img.data); cimg::swap(is_shared,img.is_shared); return img; } CImg& transfer_to(CImg& img) { if (is_shared || img.is_shared) { img.assign(*this); assign(); } else { img.assign(); cimg::swap(width,img.width); cimg::swap(height,img.height); cimg::swap(depth,img.depth); cimg::swap(dim,img.dim); cimg::swap(data,img.data); } return img; } template CImg& transfer_to(CImg& img) { img.assign(*this); assign(); return img; } static const char* pixel_type() { return cimg::type::string(); } unsigned long size() const { return width*height*depth*dim; } int dimx() const { return (int)width; } int dimy() const { return (int)height; } int dimz() const { return (int)depth; } int dimv() const { return (int)dim; } template bool is_sameX(const CImg& img) const { return (width==img.width); } bool is_sameX(const CImgDisplay& disp) const { return (width==disp.width); } template bool is_sameY(const CImg& img) const { return (height==img.height); } bool is_sameY(const CImgDisplay& disp) const { return (height==disp.height); } template bool is_sameZ(const CImg& img) const { return (depth==img.depth); } template bool is_sameV(const CImg& img) const { return (dim==img.dim); } template bool is_sameXY(const CImg& img) const { return (is_sameX(img) && is_sameY(img)); } bool is_sameXY(const CImgDisplay& disp) const { return (is_sameX(disp) && is_sameY(disp)); } template bool is_sameXZ(const CImg& img) const { return (is_sameX(img) && is_sameZ(img)); } template bool is_sameXV(const CImg& img) const { return (is_sameX(img) && is_sameV(img)); } template bool is_sameYZ(const CImg& img) const { return (is_sameY(img) && is_sameZ(img)); } template bool is_sameYV(const CImg& img) const { return (is_sameY(img) && is_sameV(img)); } template bool is_sameZV(const CImg& img) const { return (is_sameZ(img) && is_sameV(img)); } template bool is_sameXYZ(const CImg& img) const { return (is_sameXY(img) && is_sameZ(img)); } template bool is_sameXYV(const CImg& img) const { return (is_sameXY(img) && is_sameZ(img)); } template bool is_sameXZV(const CImg& img) const { return (is_sameXY(img) && is_sameZ(img)); } template bool is_sameYZV(const CImg& img) const { return (is_sameXY(img) && is_sameZ(img)); } template bool is_sameXYZV(const CImg& img) const { return (is_sameXYZ(img) && is_sameV(img)); } bool contains(const int x, const int y=0, const int z=0, const int v=0) const { return data && x>=0 && x=0 && y=0 && z=0 && v bool contains(const T& pixel, t& x, t& y, t& z, t& v) const { const T *ptr = &pixel; unsigned long off = (unsigned long)(ptr-data); const unsigned long whz = width*height*depth, wh = width*height; v = (t)(off/whz); off%=whz; z =(t)(off/wh); off%=wh; y = (t)(off/width); x = (t)(off%width); return contains(x,y,z,v); } template bool contains(const T& pixel, t& x, t& y, t& z) const { t v; return contains(pixel,x,y,z,v); } template bool contains(const T& pixel, t& x, t& y) const { t z,v; return contains(pixel,x,y,z,v); } template bool contains(const T& pixel, t& x) const { t y,z,v; return contains(pixel,x,y,z,v); } template bool contains(const T& pixel) const { t x,y,z,v; return contains(pixel,x,y,z,v); } template bool is_overlapping(const CImg& img) const { const unsigned long csiz = size(), isiz = img.size(); return !((void*)(data+csiz)<=(void*)img.data || (void*)data>=(void*)(img.data+isiz)); } bool is_empty() const { return !(data && width && height && depth && dim); } operator bool() const { return !is_empty(); } long offset(const int x, const int y, const int z, const int v) const { return (long)x + (long)y*width + (long)z*width*height + (long)v*width*height*depth; } long offset(const int x, const int y, const int z) const { return (long)x + (long)y*width + (long)z*width*height; } long offset(const int x, const int y) const { return (long)x + (long)y*width; } long offset(const int x) const { return (long)x; } T* ptr(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int v) { return data + (long)x + (long)y*width + (long)z*width*height + (long)v*width*height*depth; } const T* ptr(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int v) const { return data + (long)x + (long)y*width + (long)z*width*height + (long)v*width*height*depth; } T* ptr(const unsigned int x, const unsigned int y, const unsigned int z) { return data + (long)x + (long)y*width + (long)z*width*height; } const T* ptr(const unsigned int x, const unsigned int y, const unsigned int z) const { return data + (long)x + (long)y*width + (long)z*width*height; } T* ptr(const unsigned int x, const unsigned int y) { return data + (long)x + (long)y*width; } const T* ptr(const unsigned int x, const unsigned int y) const { return data + (long)x + (long)y*width; } T* ptr(const unsigned int x) { return data + (long)x; } const T* ptr(const unsigned int x) const { return data + (long)x; } T* ptr() { return data; } const T* ptr() const { return data; } iterator begin() { return data; } const_iterator begin() const { return data; } iterator end() { return data + size(); } const_iterator end() const { return data + size(); } T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int v) { return data[(long)x + (long)y*width + (long)z*width*height + (long)v*width*height*depth]; } const T& operator()(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int v) const { return data[(long)x + (long)y*width + (long)z*width*height + (long)v*width*height*depth]; } T& operator()(const unsigned int x, const unsigned int y, const unsigned int z) { return data[(long)x + (long)y*width + (long)z*width*height]; } const T& operator()(const unsigned int x, const unsigned int y, const unsigned int z) const { return data[(long)x + (long)y*width + (long)z*width*height]; } T& operator()(const unsigned int x, const unsigned int y) { return data[(long)x + (long)y*width]; } const T& operator()(const unsigned int x, const unsigned int y) const { return data[(long)x + (long)y*width]; } T& operator()(const unsigned int x) { return data[(long)x]; } const T& operator()(const unsigned int x) const { return data[(long)x]; } T& at(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) { return (*this)(x,y,z,v); } const T& at(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const { return (*this)(x,y,z,v); } T& operator[](const unsigned long off) { return data[off]; } const T& operator[](const unsigned long off) const { return data[off]; } T& back() { return operator()(size()-1); } const T& back() const { return operator()(size()-1); } T& front() { return *data; } const T& front() const { return *data; } T pix1d(const int x, const int y, const int z, const int v, const T out_val) const { return (x<0 || x>=dimx())?out_val:(*this)(x,y,z,v); } const T& pix1d(const int x, const int y=0, const int z=0, const int v=0) const { return (*this)(x<0?0:(x>=dimx()?dimx()-1:x),y,z,v); } T pix2d(const int x, const int y, const int z, const int v, const T out_val) const { return (x<0 || y<0 || x>=dimx() || y>=dimy())?out_val:(*this)(x,y,z,v); } const T& pix2d(const int x, const int y, const int z=0, const int v=0) const { return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),z,v); } T pix3d(const int x, const int y, const int z, const int v, const T out_val) const { return (x<0 || y<0 || z<0 || x>=dimx() || y>=dimy() || z>=dimz())?out_val:(*this)(x,y,z,v); } const T& pix3d(const int x, const int y, const int z, const int v=0) const { return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y), z<0?0:(z>=dimz()?dimz()-1:z),v); } T pix4d(const int x, const int y, const int z, const int v, const T out_val) const { return (x<0 || y<0 || z<0 || v<0 || x>=dimx() || y>=dimy() || z>=dimz() || v>=dimv())?out_val:(*this)(x,y,z,v); } T pix4d(const int x, const int y, const int z, const int v) const { return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y), z<0?0:(z>=dimz()?dimz()-1:z), v<0?0:(v>=dimv()?dimv()-1:v)); } typename cimg::superset::type linear_pix1d(const float fx, const int y, const int z, const int v, const T out_val) const { typedef typename cimg::superset::type ftype; const int x = (int)fx-(fx>=0?0:1), nx = x+1; const float dx = fx-x; const ftype Ic = (ftype)pix1d(x,y,z,v,out_val), In = (ftype)pix2d(nx,y,z,v,out_val); return Ic + dx*(In-Ic); } typename cimg::superset::type linear_pix1d(const float fx, const int y=0, const int z=0, const int v=0) const { typedef typename cimg::superset::type ftype; const float nfx = fx<0?0:(fx>width-1?width-1:fx); const unsigned int x = (unsigned int)nfx; const float dx = nfx-x; const unsigned int nx = dx>0?x+1:x; const ftype Ic = (ftype)(*this)(x,y,z,v), In = (ftype)(*this)(nx,y,z,v); return Ic + dx*(In-Ic); } typename cimg::superset::type linear_pix2d(const float fx, const float fy, const int z, const int v, const T out_val) const { typedef typename cimg::superset::type ftype; const int x = (int)fx-(fx>=0?0:1), nx = x+1, y = (int)fy-(fy>=0?0:1), ny = y+1; const float dx = fx-x, dy = fy-y; const ftype Icc = (ftype)pix2d(x,y,z,v,out_val), Inc = (ftype)pix2d(nx,y,z,v,out_val), Icn = (ftype)pix2d(x,ny,z,v,out_val), Inn = (ftype)pix2d(nx,ny,z,v,out_val); return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc); } typename cimg::superset::type linear_pix2d(const float fx, const float fy, const int z=0, const int v=0) const { typedef typename cimg::superset::type ftype; const float nfx = fx<0?0:(fx>width-1?width-1:fx), nfy = fy<0?0:(fy>height-1?height-1:fy); const unsigned int x = (unsigned int)nfx, y = (unsigned int)nfy; const float dx = nfx-x, dy = nfy-y; const unsigned int nx = dx>0?x+1:x, ny = dy>0?y+1:y; const ftype Icc = (ftype)(*this)(x,y,z,v), Inc = (ftype)(*this)(nx,y,z,v), Icn = (ftype)(*this)(x,ny,z,v), Inn = (ftype)(*this)(nx,ny,z,v); return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc); } typename cimg::superset::type linear_pix3d(const float fx, const float fy, const float fz, const int v, const T out_val) const { typedef typename cimg::superset::type ftype; const int x = (int)fx-(fx>=0?0:1), nx = x+1, y = (int)fy-(fy>=0?0:1), ny = y+1, z = (int)fz-(fz>=0?0:1), nz = z+1; const float dx = fx-x, dy = fy-y, dz = fz-z; const ftype Iccc = (ftype)pix3d(x,y,z,v,out_val), Incc = (ftype)pix3d(nx,y,z,v,out_val), Icnc = (ftype)pix3d(x,ny,z,v,out_val), Innc = (ftype)pix3d(nx,ny,z,v,out_val), Iccn = (ftype)pix3d(x,y,nz,v,out_val), Incn = (ftype)pix3d(nx,y,nz,v,out_val), Icnn = (ftype)pix3d(x,ny,nz,v,out_val), Innn = (ftype)pix3d(nx,ny,nz,v,out_val); return Iccc + dx*(Incc-Iccc + dy*(Iccc+Innc-Icnc-Incc + dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) + dz*(Iccc+Incn-Iccn-Incc)) + dy*(Icnc-Iccc + dz*(Iccc+Icnn-Iccn-Icnc)) + dz*(Iccn-Iccc); } typename cimg::superset::type linear_pix3d(const float fx, const float fy=0, const float fz=0, const int v=0) const { typedef typename cimg::superset::type ftype; const float nfx = fx<0?0:(fx>width-1?width-1:fx), nfy = fy<0?0:(fy>height-1?height-1:fy), nfz = fz<0?0:(fz>depth-1?depth-1:fz); const unsigned int x = (unsigned int)nfx, y = (unsigned int)nfy, z = (unsigned int)nfz; const float dx = nfx-x, dy = nfy-y, dz = nfz-z; const unsigned int nx = dx>0?x+1:x, ny = dy>0?y+1:y, nz = dz>0?z+1:z; const ftype Iccc = (ftype)(*this)(x,y,z,v), Incc = (ftype)(*this)(nx,y,z,v), Icnc = (ftype)(*this)(x,ny,z,v), Innc = (ftype)(*this)(nx,ny,z,v), Iccn = (ftype)(*this)(x,y,nz,v), Incn = (ftype)(*this)(nx,y,nz,v), Icnn = (ftype)(*this)(x,ny,nz,v), Innn = (ftype)(*this)(nx,ny,nz,v); return Iccc + dx*(Incc-Iccc + dy*(Iccc+Innc-Icnc-Incc + dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) + dz*(Iccc+Incn-Iccn-Incc)) + dy*(Icnc-Iccc + dz*(Iccc+Icnn-Iccn-Icnc)) + dz*(Iccn-Iccc); } typename cimg::superset::type linear_pix4d(const float fx, const float fy, const float fz, const float fv, const T out_val) const { typedef typename cimg::superset::type ftype; const int x = (int)fx-(fx>=0?0:1), nx = x+1, y = (int)fy-(fy>=0?0:1), ny = y+1, z = (int)fz-(fz>=0?0:1), nz = z+1, v = (int)fv-(fv>=0?0:1), nv = v+1; const float dx = fx-x, dy = fy-y, dz = fz-z, dv = fv-v; const ftype Icccc = (ftype)pix4d(x,y,z,v,out_val), Inccc = (ftype)pix4d(nx,y,z,v,out_val), Icncc = (ftype)pix4d(x,ny,z,v,out_val), Inncc = (ftype)pix4d(nx,ny,z,v,out_val), Iccnc = (ftype)pix4d(x,y,nz,v,out_val), Incnc = (ftype)pix4d(nx,y,nz,v,out_val), Icnnc = (ftype)pix4d(x,ny,nz,v,out_val), Innnc = (ftype)pix4d(nx,ny,nz,v,out_val), Icccn = (ftype)pix4d(x,y,z,nv,out_val), Inccn = (ftype)pix4d(nx,y,z,nv,out_val), Icncn = (ftype)pix4d(x,ny,z,nv,out_val), Inncn = (ftype)pix4d(nx,ny,z,nv,out_val), Iccnn = (ftype)pix4d(x,y,nz,nv,out_val), Incnn = (ftype)pix4d(nx,y,nz,nv,out_val), Icnnn = (ftype)pix4d(x,ny,nz,nv,out_val), Innnn = (ftype)pix4d(nx,ny,nz,nv,out_val); return Icccc + dx*(Inccc-Icccc + dy*(Icccc+Inncc-Icncc-Inccc + dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc + dv*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) + dv*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) + dz*(Icccc+Incnc-Iccnc-Inccc + dv*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) + dv*(Icccc+Inccn-Inccc-Icccn)) + dy*(Icncc-Icccc + dz*(Icccc+Icnnc-Iccnc-Icncc + dv*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) + dv*(Icccc+Icncn-Icncc-Icccn)) + dz*(Iccnc-Icccc + dv*(Icccc+Iccnn-Iccnc-Icccn)) + dv*(Icccn-Icccc); } typename cimg::superset::type linear_pix4d(const float fx, const float fy=0, const float fz=0, const float fv=0) const { typedef typename cimg::superset::type ftype; const float nfx = fx<0?0:(fx>width-1?width-1:fx), nfy = fy<0?0:(fy>height-1?height-1:fy), nfz = fz<0?0:(fz>depth-1?depth-1:fz), nfv = fv<0?0:(fv>dim-1?dim-1:fv); const unsigned int x = (unsigned int)nfx, y = (unsigned int)nfy, z = (unsigned int)nfz, v = (unsigned int)nfv; const float dx = nfx-x, dy = nfy-y, dz = nfz-z, dv = nfv-v; const unsigned int nx = dx>0?x+1:x, ny = dy>0?y+1:y, nz = dz>0?z+1:z, nv = dv>0?v+1:v; const ftype Icccc = (ftype)(*this)(x,y,z,v), Inccc = (ftype)(*this)(nx,y,z,v), Icncc = (ftype)(*this)(x,ny,z,v), Inncc = (ftype)(*this)(nx,ny,z,v), Iccnc = (ftype)(*this)(x,y,nz,v), Incnc = (ftype)(*this)(nx,y,nz,v), Icnnc = (ftype)(*this)(x,ny,nz,v), Innnc = (ftype)(*this)(nx,ny,nz,v), Icccn = (ftype)(*this)(x,y,z,nv), Inccn = (ftype)(*this)(nx,y,z,nv), Icncn = (ftype)(*this)(x,ny,z,nv), Inncn = (ftype)(*this)(nx,ny,z,nv), Iccnn = (ftype)(*this)(x,y,nz,nv), Incnn = (ftype)(*this)(nx,y,nz,nv), Icnnn = (ftype)(*this)(x,ny,nz,nv), Innnn = (ftype)(*this)(nx,ny,nz,nv); return Icccc + dx*(Inccc-Icccc + dy*(Icccc+Inncc-Icncc-Inccc + dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc + dv*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) + dv*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) + dz*(Icccc+Incnc-Iccnc-Inccc + dv*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) + dv*(Icccc+Inccn-Inccc-Icccn)) + dy*(Icncc-Icccc + dz*(Icccc+Icnnc-Iccnc-Icncc + dv*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) + dv*(Icccc+Icncn-Icncc-Icccn)) + dz*(Iccnc-Icccc + dv*(Icccc+Iccnn-Iccnc-Icccn)) + dv*(Icccn-Icccc); } typename cimg::superset::type cubic_pix1d(const float fx, const int y, const int z, const int v, const T out_val) const { typedef typename cimg::superset::type ftype; const int x = (int)fx-(fx>=0?0:1), px = x-1, nx = x+1, ax = x+2; const float dx = fx-x; const ftype Ip = (ftype)pix1d(px,y,z,v,out_val), Ic = (ftype)pix1d(x,y,z,v,out_val), In = (ftype)pix1d(nx,y,z,v,out_val), Ia = (ftype)pix1d(ax,y,z,v,out_val), valm = cimg::min(Ip,In,Ic,Ia), valM = cimg::max(Ip,In,Ic,Ia), u0 = Ic - Ip, u1 = Ia - In, a = 2*(Ic-In) + u0 + u1, b = 3*(In-Ic) - 2*u0 - u1, val = a*dx*dx*dx + b*dx*dx + u0*dx + Ic; return valvalM?valM:val); } typename cimg::superset::type cubic_pix1d(const float fx, const int y=0, const int z=0, const int v=0) const { typedef typename cimg::superset::type ftype; const float nfx = fx<0?0:(fx>width-1?width-1:fx); const int x = (int)nfx; const float dx = nfx-x; const int px = x-1<0?0:x-1, nx = dx>0?x+1:x, ax = x+2>=dimx()?dimx()-1:x+2; const ftype Ip = (ftype)(*this)(px,y,z,v), Ic = (ftype)(*this)(x,y,z,v), In = (ftype)(*this)(nx,y,z,v), Ia = (ftype)(*this)(ax,y,z,v), valm = cimg::min(Ip,In,Ic,Ia), valM = cimg::max(Ip,In,Ic,Ia), u0 = Ic - Ip, u1 = Ia - In, a = 2*(Ic-In) + u0 + u1, b = 3*(In-Ic) - 2*u0 - u1, val = a*dx*dx*dx + b*dx*dx + u0*dx + Ic; return valvalM?valM:val); } typename cimg::superset::type cubic_pix2d(const float fx, const float fy, const int z, const int v, const T out_val) const { typedef typename cimg::superset::type ftype; const int x = (int)fx-(fx>=0?0:1), px = x-1, nx = x+1, ax = x+2, y = (int)fy-(fy>=0?0:1), py = y-1, ny = y+1, ay = y+2; const float dx = fx-x, dx2 = dx*dx, dx3 = dx2*dx, dy = fy-y; const ftype Ipp = (ftype)pix2d(px,py,z,v,out_val), Icp = (ftype)pix2d(x,py,z,v,out_val), Inp = (ftype)pix2d(nx,py,z,v,out_val), Iap = (ftype)pix2d(ax,py,z,v,out_val), Ipc = (ftype)pix2d(px,y,z,v,out_val), Icc = (ftype)pix2d(x,y,z,v,out_val), Inc = (ftype)pix2d(nx,y,z,v,out_val), Iac = (ftype)pix2d(ax,y,z,v,out_val), Ipn = (ftype)pix2d(px,ny,z,v,out_val), Icn = (ftype)pix2d(x,ny,z,v,out_val), Inn = (ftype)pix2d(nx,ny,z,v,out_val), Ian = (ftype)pix2d(ax,ny,z,v,out_val), Ipa = (ftype)pix2d(px,ay,z,v,out_val), Ica = (ftype)pix2d(x,ay,z,v,out_val), Ina = (ftype)pix2d(nx,ay,z,v,out_val), Iaa = (ftype)pix2d(ax,ay,z,v,out_val), 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)), 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)), u0p = Icp - Ipp, u1p = Iap - Inp, ap = 2*(Icp-Inp) + u0p + u1p, bp = 3*(Inp-Icp) - 2*u0p - u1p, u0c = Icc - Ipc, u1c = Iac - Inc, ac = 2*(Icc-Inc) + u0c + u1c, bc = 3*(Inc-Icc) - 2*u0c - u1c, u0n = Icn - Ipn, u1n = Ian - Inn, an = 2*(Icn-Inn) + u0n + u1n, bn = 3*(Inn-Icn) - 2*u0n - u1n, u0a = Ica - Ipa, u1a = Iaa - Ina, aa = 2*(Ica-Ina) + u0a + u1a, ba = 3*(Ina-Ica) - 2*u0a - u1a, valp = ap*dx3 + bp*dx2 + u0p*dx + Icp, valc = ac*dx3 + bc*dx2 + u0c*dx + Icc, valn = an*dx3 + bn*dx2 + u0n*dx + Icn, vala = aa*dx3 + ba*dx2 + u0a*dx + Ica, u0 = valc - valp, u1 = vala - valn, a = 2*(valc-valn) + u0 + u1, b = 3*(valn-valc) - 2*u0 - u1, val = a*dy*dy*dy + b*dy*dy + u0*dy + valc; return valvalM?valM:val); } typename cimg::superset::type cubic_pix2d(const float fx, const float fy, const int z=0, const int v=0) const { typedef typename cimg::superset::type ftype; const float nfx = fx<0?0:(fx>width-1?width-1:fx), nfy = fy<0?0:(fy>height-1?height-1:fy); const int x = (int)nfx, y = (int)nfy; const float dx = nfx-x, dx2 = dx*dx, dx3 = dx2*dx, dy = nfy-y; const int px = x-1<0?0:x-1, nx = dx>0?x+1:x, ax = x+2>=dimx()?dimx()-1:x+2, py = y-1<0?0:y-1, ny = dy>0?y+1:y, ay = y+2>=dimy()?dimy()-1:y+2; const ftype Ipp = (ftype)(*this)(px,py,z,v), Icp = (ftype)(*this)(x,py,z,v), Inp = (ftype)(*this)(nx,py,z,v), Iap = (ftype)(*this)(ax,py,z,v), Ipc = (ftype)(*this)(px,y,z,v), Icc = (ftype)(*this)(x,y,z,v), Inc = (ftype)(*this)(nx,y,z,v), Iac = (ftype)(*this)(ax,y,z,v), Ipn = (ftype)(*this)(px,ny,z,v), Icn = (ftype)(*this)(x,ny,z,v), Inn = (ftype)(*this)(nx,ny,z,v), Ian = (ftype)(*this)(ax,ny,z,v), Ipa = (ftype)(*this)(px,ay,z,v), Ica = (ftype)(*this)(x,ay,z,v), Ina = (ftype)(*this)(nx,ay,z,v), Iaa = (ftype)(*this)(ax,ay,z,v), 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)), 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)), u0p = Icp - Ipp, u1p = Iap - Inp, ap = 2*(Icp-Inp) + u0p + u1p, bp = 3*(Inp-Icp) - 2*u0p - u1p, u0c = Icc - Ipc, u1c = Iac - Inc, ac = 2*(Icc-Inc) + u0c + u1c, bc = 3*(Inc-Icc) - 2*u0c - u1c, u0n = Icn - Ipn, u1n = Ian - Inn, an = 2*(Icn-Inn) + u0n + u1n, bn = 3*(Inn-Icn) - 2*u0n - u1n, u0a = Ica - Ipa, u1a = Iaa - Ina, aa = 2*(Ica-Ina) + u0a + u1a, ba = 3*(Ina-Ica) - 2*u0a - u1a, valp = ap*dx3 + bp*dx2 + u0p*dx + Icp, valc = ac*dx3 + bc*dx2 + u0c*dx + Icc, valn = an*dx3 + bn*dx2 + u0n*dx + Icn, vala = aa*dx3 + ba*dx2 + u0a*dx + Ica, u0 = valc - valp, u1 = vala - valn, a = 2*(valc-valn) + u0 + u1, b = 3*(valn-valc) - 2*u0 - u1, val = a*dy*dy*dy + b*dy*dy + u0*dy + valc; return valvalM?valM:val); } const T& max() const { if (is_empty()) throw CImgInstanceException("CImg<%s>::max() : Instance image is empty.",pixel_type()); const T *ptrmax = data; T max_value = *ptrmax; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) if ((*ptr)>max_value) max_value = *(ptrmax=ptr); return *ptrmax; } T& max() { if (is_empty()) throw CImgInstanceException("CImg<%s>::max() : Instance image is empty.",pixel_type()); T *ptrmax = data; T max_value = *ptrmax; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) if ((*ptr)>max_value) max_value = *(ptrmax=ptr); return *ptrmax; } const T& min() const { if (is_empty()) throw CImgInstanceException("CImg<%s>::min() : Instance image is empty.",pixel_type()); const T *ptrmin = data; T min_value = *ptrmin; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) if ((*ptr)::min() : Instance image is empty.",pixel_type()); T *ptrmin = data; T min_value = *ptrmin; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) if ((*ptr) const T& minmax(t& max_val) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::minmax() : Instance image is empty.",pixel_type()); const T *ptrmin = data; T min_value = *ptrmin, max_value = min_value; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; if (valmax_value) max_value = val; } max_val = (t)max_value; return *ptrmin; } template T& minmax(t& max_val) { if (is_empty()) throw CImgInstanceException("CImg<%s>::minmax() : Instance image is empty.",pixel_type()); T *ptrmin = data; T min_value = *ptrmin, max_value = min_value; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; if (valmax_value) max_value = val; } max_val = (t)max_value; return *ptrmin; } template const T& maxmin(t& min_val) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::maxmin() : Instance image is empty.",pixel_type()); const T *ptrmax = data; T max_value = *ptrmax, min_value = max_value; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; if (val>max_value) { max_value = val; ptrmax = ptr; } if (val T& maxmin(t& min_val) { if (is_empty()) throw CImgInstanceException("CImg<%s>::maxmin() : Instance image is empty.",pixel_type()); T *ptrmax = data; T max_value = *ptrmax, min_value = max_value; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; if (val>max_value) { max_value = val; ptrmax = ptr; } if (val::mean() : Instance image is empty.",pixel_type()); double val = 0; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) val+=(double)*ptr; return val/size(); } template double variancemean(const unsigned int variance_method, t& mean) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::variance() : Instance image is empty.",pixel_type()); double variance = 0, average = 0; const unsigned int siz = size(); switch (variance_method) { case 3: { CImg buf(*this); const unsigned int siz2 = siz>>1; { for (double *ptrs = (buf).data + (buf).size(); (ptrs--)>(buf).data; ) { const double val = *ptrs; (*ptrs)*=val; average+=val; }} buf.sort(); double a = 0; const double *ptrs = buf.ptr(); for (unsigned int j=0; j buf(*this); buf.sort(); const unsigned int siz2 = siz>>1; const double med_i = buf[siz2]; for (double *ptrs = (buf).data + (buf).size(); (ptrs--)>(buf).data; ) { const double val = *ptrs; *ptrs = cimg::abs(val-med_i); average+=val; } buf.sort(); const double sig = 1.4828*buf[siz2]; variance = sig*sig; } break; case 1: { double S = 0, S2 = 0; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const double val = (double)*ptr; S+=val; S2+=val*val; } variance = siz>1?(S2 - S*S/siz)/(siz-1):0; average = S; } break; default:{ double S = 0, S2 = 0; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const double val = (double)*ptr; S+=val; S2+=val*val; } variance = (S2 - S*S/siz)/siz; average = S; } break; } mean = (t)(average/siz); return variance; } double variance(const unsigned int variance_method=0) const { double foo; return variancemean(variance_method,foo); } template double MSE(const CImg& img) const { if (img.size()!=size()) throw CImgArgumentException("CImg<%s>::MSE() : Instance image (%u,%u,%u,%u) and given image (%u,%u,%u,%u) have different dimensions.", pixel_type(),width,height,depth,dim,img.width,img.height,img.depth,img.dim); double vMSE = 0; const t* ptr2 = img.end(); for (T *ptr1 = (*this).data + (*this).size(); (ptr1--)>(*this).data; ) { const double diff = (double)*ptr1 - (double)*(--ptr2); vMSE += diff*diff; } vMSE/=img.size(); return vMSE; } template double PSNR(const CImg& img, const double valmax=255.0) const { const double vMSE = std::sqrt(MSE(img)); return (vMSE!=0)?(20*std::log10(valmax/vMSE)):(cimg::type::max()); } double trace() const { if (is_empty()) throw CImgInstanceException("CImg<%s>::trace() : Instance matrix (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data); double res = 0; for (int k = 0; k<(int)((*this).width); ++k) res+=(*this)(k,k); return res; } T median() const { const unsigned int s = size(); const T res = kth_smallest(s>>1); return (s%2)?res:((res+kth_smallest((s>>1)-1))/2); } template double dot(const CImg& img) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::dot() : Instance object (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data); if (!img) throw CImgArgumentException("CImg<%s>::trace() : Specified argument (%u,%u,%u,%u,%p) is empty.", pixel_type(),img.width,img.height,img.depth,img.dim,img.data); const unsigned long nb = cimg::min(size(),img.size()); double res = 0; for (unsigned long off=0; off::det() : Instance matrix (%u,%u,%u,%u,%p) is not square or is empty.", pixel_type(),width,height,depth,dim,data); switch (width) { case 1: return (*this)(0,0); case 2: return (*this)(0,0)*(*this)(1,1)-(*this)(0,1)*(*this)(1,0); case 3: { const double a = data[0], d = data[1], g = data[2], b = data[3], e = data[4], h = data[5], c = data[6], f = data[7], i = data[8]; return i*a*e-a*h*f-i*b*d+b*g*f+c*d*h-c*g*e; } default: { typedef typename cimg::superset::type ftype; CImg lu(*this); CImg indx; bool d; lu._LU(indx,d); double res = d?1.0:-1.0; for (int i = 0; i<(int)((lu).width); ++i) res*=lu(i,i); return res; } } return 0; } double norm(const int norm_type=2) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::norm() : Instance object (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data); double res = 0; switch (norm_type) { case -1: { for (unsigned int off = 0; off<(*this).size(); ++off) { const double tmp = cimg::abs((double)data[off]); if (tmp>res) res = tmp; } return res; } break; case 1 : { for (unsigned int off = 0; off<(*this).size(); ++off) res+=cimg::abs((double)data[off]); return res; } break; default: { return std::sqrt(dot(*this)); } } return 0; } double sum() const { if (is_empty()) throw CImgInstanceException("CImg<%s>::sum() : Instance object (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data); double res = 0; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) res+=*ptr; return res; } const T kth_smallest(const unsigned int k) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::kth_smallest() : Instance image (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data); CImg arr(*this); unsigned long l = 0, ir = size()-1; for (;;) { if (ir<=l+1) { if (ir==l+1 && arr[ir]>1; cimg::swap(arr[mid],arr[l+1]); if (arr[l]>arr[ir]) cimg::swap(arr[l],arr[ir]); if (arr[l+1]>arr[ir]) cimg::swap(arr[l+1],arr[ir]); if (arr[l]>arr[l+1]) cimg::swap(arr[l],arr[l+1]); unsigned long i = l+1, j = ir; const T pivot = arr[l+1]; for (;;) { do ++i; while (arr[i]pivot); if (j=k) ir=j-1; if (j<=k) l=i; } } return 0; } const CImg& print(const char *title=0, const int print_flag=1) const { typedef typename cimg::last::type cdouble; static CImg st; if (print_flag>=0) { const unsigned long msiz = size()*sizeof(T); const unsigned int mdisp = msiz<8*1024?0:(msiz<8*1024*1024?1:2); std::fprintf(stderr,"%-8s(this=%p): { size=(%u,%u,%u,%u) [%lu %s], data=(%s*)%p (%s)", title?title:"CImg",(void*)this, width,height,depth,dim, mdisp==0?msiz:(mdisp==1?(msiz>>10):(msiz>>20)), mdisp==0?"b":(mdisp==1?"Kb":"Mb"), pixel_type(),(void*)data,is_shared?"shared":"not shared"); if (is_empty()) { std::fprintf(stderr,", [Undefined pixel data] }\n"); return *this; } if (print_flag>=1) { st = get_stats(); int xm, ym, zm, vm, xM, yM, zM, vM; contains(data[(int)st(4)],xm,ym,zm,vm); contains(data[(int)st(5)],xM,yM,zM,vM); std::fprintf(stderr,", min=%g, mean=%g [std=%g], max=%g, pmin=(%d,%d,%d,%d), pmax=(%d,%d,%d,%d)", st[0],st[2],std::sqrt(st[3]),st[1],xm,ym,zm,vm,xM,yM,zM,vM); } if (print_flag>=2 || size()<=16) { std::fprintf(stderr," }\n%s = [ ",title?title:"data"); for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { std::fprintf(stderr,cimg::type::format(),cimg::type::format((*this)(x,y,z,k))); std::fprintf(stderr,"%s",((x+1)*(y+1)*(z+1)*(k+1)==(int)size()?" ]\n":(((x+1)%width==0)?" ; ":" "))); } } else std::fprintf(stderr," }\n"); } return *this; } const CImg& print(const int print_flag) const { return print(0,print_flag); } template CImg& operator=(const CImg& img) { return assign(img); } CImg& operator=(const CImg& img) { return assign(img); } CImg& operator=(const T *buf) { return assign(buf,width,height,depth,dim); } CImg& operator=(const T val) { return fill(val); } CImg operator+() const { return CImg(*this,false); } template CImg& operator+=(const t val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)((*ptr)+val); return *this; } template CImg& operator+=(const CImg& img) { if (is_overlapping(img)) return *this+=+img; const unsigned int smin = cimg::min(size(),img.size()); t *ptrs = img.data + smin; for (T *ptrd = data + smin; ptrd>data; --ptrd, (*ptrd)=(T)((*ptrd)+(*(--ptrs)))); return *this; } CImg& operator++() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) ++(*ptr); return *this; } CImg operator++(int) { CImg copy(*this,false); ++*this; return copy; } CImg operator-() const { return CImg(width,height,depth,dim,0)-=*this; } template CImg& operator-=(const t val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)((*ptr)-val); return *this; } template CImg& operator-=(const CImg& img) { if (is_overlapping(img)) return *this-=+img; const unsigned int smin = cimg::min(size(),img.size()); t *ptrs = img.data+smin; for (T *ptrd = data+smin; ptrd>data; --ptrd, (*ptrd) = (T)((*ptrd)-(*(--ptrs)))); return *this; } CImg& operator--() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = *ptr-(T)1; return *this; } CImg operator--(int) { CImg copy(*this,false); --*this; return copy; } template CImg& operator*=(const t val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)((*ptr)*val); return *this; } template CImg& operator*=(const CImg& img) { return ((*this)*img).transfer_to(*this); } template CImg& operator/=(const t val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)((*ptr)/val); return *this; } template CImg& operator/=(const CImg& img) { return assign(*this*img.get_invert()); } template CImg::type> operator%(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this,false)%=img; } CImg operator%(const T val) const { return (+*this)%=val; } CImg& operator%=(const T val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)cimg::mod(*ptr,val); return *this; } template CImg& operator%=(const CImg& img) { if (is_overlapping(img)) return *this%=+img; typedef typename cimg::superset::type btype; const unsigned int smin = cimg::min(size(),img.size()); const t *ptrs = img.data + smin; for (T *ptrd = data + smin; ptrd>data; ) { T& val = *(--ptrd); val = (T)cimg::mod((btype)val,(btype)*(--ptrs)); } return *this; } template CImg::type> operator&(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this,false)&=img; } CImg operator&(const T val) const { return (+*this)&=val; } template CImg& operator&=(const CImg& img) { if (is_overlapping(img)) return *this&=+img; const unsigned int smin = cimg::min(size(),img.size()); const t *ptrs = img.data + smin; for (T *ptrd = data + smin; ptrd>data; ) { T& val = *(--ptrd); val = (T)((unsigned long)val & (unsigned long)*(--ptrs)); } return *this; } CImg& operator&=(const T val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = (T)((unsigned long)*ptr & (unsigned long)val); return *this; } template CImg::type> operator|(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this,false)|=img; } CImg operator|(const T val) const { return (+*this)|=val; } template CImg& operator|=(const CImg& img) { if (is_overlapping(img)) return *this|=+img; const unsigned int smin = cimg::min(size(),img.size()); const t *ptrs = img.data + smin; for (T *ptrd = data + smin; ptrd>data; ) { T& val = *(--ptrd); val = (T)((unsigned long)val | (unsigned long)*(--ptrs)); } return *this; } CImg& operator|=(const T val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = (T)((unsigned long)*ptr | (unsigned long)val); return *this; } template CImg::type> operator^(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this,false)^=img; } CImg operator^(const T val) const { return (+*this)^=val; } template CImg& operator^=(const CImg& img) { if (is_overlapping(img)) return *this^=+img; const unsigned int smin = cimg::min(size(),img.size()); const t *ptrs = img.data + smin; for (T *ptrd = data+smin; ptrd>data; ) { T& val = *(--ptrd); val =(T)((unsigned long)val ^ (unsigned long)*(--ptrs)); } return *this; } CImg& operator^=(const T val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = (T)((unsigned long)*ptr ^ (unsigned long)val); return *this; } CImg operator~() const { CImg res(width,height,depth,dim); const T *ptrs = end(); for (T *ptrd = (res).data + (res).size(); (ptrd--)>(res).data; ) *ptrd = (T)~(unsigned long)*(--ptrs); return res; } CImg& operator<<=(const int n) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = (T)(((long)*ptr)< operator<<(const int n) const { return (+*this)<<=n; } CImg& operator>>=(const int n) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = (T)(((long)*ptr)>>n); return *this; } CImg operator>>(const int n) const { return (+*this)>>=n; } template bool operator==(const CImg& img) const { const unsigned int siz = size(); bool vequal = true; if (siz!=img.size()) return false; t *ptrs = img.data + siz; for (T *ptrd = data + siz; vequal && ptrd>data; vequal = vequal && ((*(--ptrd))==(*(--ptrs)))); return vequal; } template bool operator!=(const CImg& img) const { return !((*this)==img); } template CImgList::type> operator<<(const CImg& img) const { typedef typename cimg::superset::type restype; return CImgList(*this,img); } template CImgList::type> operator<<(const CImgList& list) const { typedef typename cimg::superset::type restype; return CImgList(list).insert(*this,0); } template CImgList::type> operator>>(const CImg& img) const { return (*this)< CImgList& operator>>(const CImgList& list) const { return list.insert(*this,0); } const CImg& operator>>(CImgDisplay& disp) const { return display(disp); } template CImg get_apply(t& func) const { return (+*this).apply(func); } template CImg& apply(t& func) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = func(*ptr); return *this; } template CImg::type> get_mul(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this,false).mul(img); } template CImg& mul(const CImg& img) { if (is_overlapping(img)) return mul(+img); t *ptrs = img.data; T *ptrf = data + cimg::min(size(),img.size()); for (T* ptrd = data; ptrd CImg::type> get_div(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this,false).div(img); } template CImg& div(const CImg& img) { if (is_overlapping(img)) return div(+img); t *ptrs = img.data; T *ptrf = data + cimg::min(size(),img.size()); for (T* ptrd = data; ptrd CImg::type> get_max(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this,false).max(img); } template CImg& max(const CImg& img) { if (is_overlapping(img)) return max(+img); t *ptrs = img.data; T *ptrf = data + cimg::min(size(),img.size()); for (T* ptrd = data; ptrd get_max(const T val) const { return (+*this).max(val); } CImg& max(const T val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = cimg::max(*ptr,val); return *this; } template CImg::type> get_min(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this,false).min(img); } template CImg& min(const CImg& img) { if (is_overlapping(img)) return min(+img); t *ptrs = img.data; T *ptrf = data + cimg::min(size(),img.size()); for (T* ptrd = data; ptrd get_min(const T val) const { return (+*this).min(val); } CImg& min(const T val) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = cimg::min(*ptr,val); return *this; } CImg::type> get_stats() const { typedef typename cimg::last::type restype; return CImg(*this).stats(); } CImg& stats() { if (is_empty()) throw CImgInstanceException("CImg<%s>::stats() : Instance image is empty.",pixel_type()); const unsigned long siz = size(); const T *pm = data, *pM = pm; double S = 0, S2 = 0; T m = *pm, M = m; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; const double fval = (double)val; if (valM) { M = val; pM = ptr; } S+=fval; S2+=fval*fval; } return assign(1,6).fill((T)m,(T)M,(T)(S/siz),(T)((S2-S*S/siz)/siz),(T)(pm-data),(T)(pM-data)); } CImg::type> get_sqr() const { typedef typename cimg::superset::type restype; return CImg(*this,false).sqr(); } CImg& sqr() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; *ptr = (T)(val*val); }; return *this; } CImg::type> get_sqrt() const { typedef typename cimg::superset::type restype; return CImg(*this,false).sqrt(); } CImg& sqrt() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::sqrt((double)(*ptr)); return *this; } CImg::type> get_exp() const { typedef typename cimg::superset::type restype; return CImg(*this,false).exp(); } CImg& exp() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::exp((double)(*ptr)); return *this; } CImg::type> get_log() const { typedef typename cimg::superset::type restype; return CImg(*this,false).log(); } CImg& log() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::log((double)(*ptr)); return *this; } CImg::type> get_log10() const { typedef typename cimg::superset::type restype; return CImg(*this,false).log10(); } CImg& log10() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::log10((double)(*ptr)); return *this; } CImg::type> get_pow(const double p) const { typedef typename cimg::superset::type restype; return CImg(*this,false).pow(p); } CImg& pow(const double p) { if (p==0) return fill(1); if (p==0.5) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; *ptr = (T)std::sqrt((double)val); } return *this; } if (p==1) return *this; if (p==2) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; *ptr = val*val; } return *this; } if (p==3) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; *ptr = val*val*val; } return *this; } if (p==4) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const T val = *ptr; *ptr = val*val*val*val; } return *this; } for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::pow((double)(*ptr),p); return *this; } template CImg::type> get_pow(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this,false).pow(img); } template CImg& pow(const CImg& img) { if (is_overlapping(img)) return pow(+img); t *ptrs = img.data; T *ptrf = data + cimg::min(size(),img.size()); for (T* ptrd = data; ptrd::type> get_abs() const { typedef typename cimg::superset::type restype; return CImg(*this,false).abs(); } CImg& abs() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = cimg::abs(*ptr); return *this; } CImg::type> get_cos() const { typedef typename cimg::superset::type restype; return CImg(*this,false).cos(); } CImg& cos() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::cos((double)(*ptr)); return *this; } CImg::type> get_sin() const { typedef typename cimg::superset::type restype; return CImg(*this,false).sin(); } CImg& sin() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::sin((double)(*ptr)); return *this; } CImg::type> get_tan() const { typedef typename cimg::superset::type restype; return CImg(*this,false).tan(); } CImg& tan() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::tan((double)(*ptr)); return *this; } CImg::type> get_acos() const { typedef typename cimg::superset::type restype; return CImg(*this,false).acos(); } CImg& acos() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::acos((double)(*ptr)); return *this; } CImg::type> get_asin() const { typedef typename cimg::superset::type restype; return CImg(*this,false).asin(); } CImg& asin() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::asin((double)(*ptr)); return *this; } CImg::type> get_atan() const { typedef typename cimg::superset::type restype; return CImg(*this,false).atan(); } CImg& atan() { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)std::atan((double)(*ptr)); return *this; } CImg get_round(const float x, const unsigned int round_type=0) const { return (+*this).round(x,round_type); } CImg& round(const float x, const unsigned int round_type=0) { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) (*ptr) = (T)cimg::round(*ptr,x,round_type); return *this; } CImg get_rand(const T val_min, const T val_max) const { return (+*this).rand(val_min,val_max); } CImg& rand(const T val_min, const T val_max) { const float delta = (float)val_max - (float)val_min; for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = (T)(val_min + cimg::rand()*delta); return *this; } CImg get_fill(const T val) const { return CImg(width,height,depth,dim).fill(val); } CImg& fill(const T val) { if (!is_empty()) { if (val && sizeof(T)!=1) for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = val; else std::memset(data,(int)val,size()*sizeof(T)); } return *this; } CImg get_fill(const T val0, const T val1) const { return CImg(width,height,depth,dim).fill(val0,val1); } CImg& fill(const T val0, const T val1) { if (!is_empty()) { T *ptr, *ptr_end = end()-1; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2) const { return CImg(width,height,depth,dim).fill(val0,val1,val2); } CImg& fill(const T val0, const T val1, const T val2) { if (!is_empty()) { T *ptr, *ptr_end = end()-2; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3); } CImg& fill(const T val0, const T val1, const T val2, const T val3) { if (!is_empty()) { T *ptr, *ptr_end = end()-3; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4) { if (!is_empty()) { T *ptr, *ptr_end = end()-4; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5) { if (!is_empty()) { T *ptr, *ptr_end = end()-5; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6) { if (!is_empty()) { T *ptr, *ptr_end = end()-6; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7) { if (!is_empty()) { T *ptr, *ptr_end = end()-7; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8) { if (!is_empty()) { T *ptr, *ptr_end = end()-8; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9) { if (!is_empty()) { T *ptr, *ptr_end = end()-9; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10) { if (!is_empty()) { T *ptr, *ptr_end = end()-10; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11) { if (!is_empty()) { T *ptr, *ptr_end = end()-11; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12) { if (!is_empty()) { T *ptr, *ptr_end = end()-12; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12, const T val13) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12, const T val13) { if (!is_empty()) { T *ptr, *ptr_end = end()-13; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12, const T val13, const T val14) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12, const T val13, const T val14) { if (!is_empty()) { T *ptr, *ptr_end = end()-14; for (ptr=data; ptr get_fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12, const T val13, const T val14, const T val15) const { return CImg(width,height,depth,dim).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14,val15); } CImg& fill(const T val0, const T val1, const T val2, const T val3, const T val4, const T val5, const T val6, const T val7, const T val8, const T val9, const T val10, const T val11, const T val12, const T val13, const T val14, const T val15) { if (!is_empty()) { T *ptr, *ptr_end = end()-15; for (ptr=data; ptr CImg get_fill(const int val0, ...) const { CImg res(*this,false); va_list ap; __builtin_va_start(ap,val0); res._fill(val0,ap); __builtin_va_end(ap); return res; } template CImg& fill(const int val0, ...) { va_list ap; __builtin_va_start(ap,val0); _fill(val0,ap); __builtin_va_end(ap); return *this; } template CImg get_fill(const double val0, ...) const { CImg res(*this,false); va_list ap; __builtin_va_start(ap,val0); res._fill(val0,ap); __builtin_va_end(ap); return res; } template CImg& fill(const double val0, ...) { va_list ap; __builtin_va_start(ap,val0); _fill(val0,ap); __builtin_va_end(ap); return *this; } template CImg& _fill(const t val0, va_list &ap) { if (N>0 && !is_empty()) { CImg vals(N); T *ptrs = vals.data; *(ptrs++) = (T)val0; for (int i=1; i0; --i) *(ptr++) = *(ptrs++); } return *this; } CImg& fillV(const unsigned int x, const unsigned int y, const unsigned int z, const int a0, ...) { if (x& fillV(const unsigned int x, const unsigned int y, const unsigned int z, const double a0, ...) { if (x& fillZV(const unsigned int x, const unsigned int y, const int a0, ...) { if (x& fillZV(const unsigned int x, const unsigned int y, const double a0, ...) { if (x& fillYZV(const unsigned int x, const int a0, ...) { if (x& fillYZV(const unsigned int x, const double a0, ...) { if (x get_normalize(const T a, const T b) const { return (+*this).normalize(a,b); } CImg& normalize(const T a, const T b) { if (!is_empty()) { typedef typename cimg::superset::type ftype; T m, M = maxmin(m); const ftype fm = (ftype)m, fM = (ftype)M; if (m==M) return fill(0); if (m!=a || M!=b) for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = (T)((*ptr-fm)/(fM-fm)*(b-a)+a); } return *this; } CImg get_cut(const T a, const T b) const { return (+*this).cut(a,b); } CImg& cut(const T a, const T b) { if (!is_empty()) for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = (*ptrb)?b:*ptr); return *this; } CImg get_quantize(const unsigned int n=256, const bool keep_range=true) const { return (+*this).quantize(n,keep_range); } CImg& quantize(const unsigned int n=256, const bool keep_range=true) { if (!is_empty()) { if (!n) throw CImgArgumentException("CImg<%s>::quantize() : Cannot quantize image to 0 values.", pixel_type()); typedef typename cimg::superset::type ftype; ftype m, M = (ftype)maxmin(m), range = M - m; if (range>0) { if (keep_range) for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const unsigned int val = (unsigned int)((*ptr-m)*n/range); *ptr = (T)(m + cimg::min(val,n-1)*range/n); } else for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const unsigned int val = (unsigned int)((*ptr-m)*n/range); *ptr = (T)cimg::min(val,n-1); } } } return *this; } CImg get_threshold(const T thres) const { return (+*this).threshold(thres); } CImg& threshold(const T thres) { if (!is_empty()) for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) *ptr = *ptr<=thres?(T)0:(T)1; return *this; } CImg get_rotate(const float angle, const unsigned int cond=3) const { if (is_empty()) return CImg(); CImg dest; const float nangle = cimg::mod(angle,360.0f), rad = (float)((nangle*cimg::valuePI)/180.0), ca=(float)std::cos(rad), sa=(float)std::sin(rad); if (cond!=1 && cimg::mod(nangle,90.0f)==0) { const int wm1 = dimx()-1, hm1 = dimy()-1; const int iangle = (int)nangle/90; switch (iangle) { case 1: { dest.assign(height,width,depth,dim); for (int v = 0; v<(int)((dest).dim); ++v) for (int z = 0; z<(int)((dest).depth); ++z) for (int y = 0; y<(int)((dest).height); ++y) for (int x = 0; x<(int)((dest).width); ++x) dest(x,y,z,v) = (*this)(y,hm1-x,z,v); } break; case 2: { dest.assign(width,height,depth,dim); for (int v = 0; v<(int)((dest).dim); ++v) for (int z = 0; z<(int)((dest).depth); ++z) for (int y = 0; y<(int)((dest).height); ++y) for (int x = 0; x<(int)((dest).width); ++x) dest(x,y,z,v) = (*this)(wm1-x,hm1-y,z,v); } break; case 3: { dest.assign(height,width,depth,dim); for (int v = 0; v<(int)((dest).dim); ++v) for (int z = 0; z<(int)((dest).depth); ++z) for (int y = 0; y<(int)((dest).height); ++y) for (int x = 0; x<(int)((dest).width); ++x) dest(x,y,z,v) = (*this)(wm1-y,x,z,v); } break; default: return *this; } } else { const float ux = (float)(cimg::abs(width*ca)), uy = (float)(cimg::abs(width*sa)), vx = (float)(cimg::abs(height*sa)), vy = (float)(cimg::abs(height*ca)), w2 = 0.5f*width, h2 = 0.5f*height, dw2 = 0.5f*(ux+vx), dh2 = 0.5f*(uy+vy); dest.assign((int)(ux+vx), (int)(uy+vy),depth,dim); switch (cond) { case 0: { for (int y = 0; y<(int)((dest).height); ++y) for (int x = 0; x<(int)((dest).width); ++x) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) 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); } break; case 1: { for (int y = 0; y<(int)((dest).height); ++y) for (int x = 0; x<(int)((dest).width); ++x) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) dest(x,y,z,v) = (*this)(cimg::mod((int)(w2 + (x-dw2)*ca + (y-dh2)*sa),dimx()), cimg::mod((int)(h2 - (x-dw2)*sa + (y-dh2)*ca),dimy()),z,v); } break; case 2: { for (int y = 0; y<(int)((dest).height); ++y) for (int x = 0; x<(int)((dest).width); ++x) { const float X = w2 + (x-dw2)*ca + (y-dh2)*sa, Y = h2 - (x-dw2)*sa + (y-dh2)*ca; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) dest(x,y,z,v) = (T)linear_pix2d(X,Y,z,v,0); } } break; default: { for (int y = 0; y<(int)((dest).height); ++y) for (int x = 0; x<(int)((dest).width); ++x) { const float X = w2 + (x-dw2)*ca + (y-dh2)*sa, Y = h2 - (x-dw2)*sa + (y-dh2)*ca; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) dest(x,y,z,v) = (T)cubic_pix2d(X,Y,z,v,0); } } break; } } return dest; } CImg& rotate(const float angle, const unsigned int cond=3) { return get_rotate(angle,cond).transfer_to(*this); } CImg get_rotate(const float angle, const float cx, const float cy, const float zoom=1, const unsigned int cond=3) const { if (is_empty()) return CImg(); CImg dest(width,height,depth,dim); const float nangle = cimg::mod(angle,360.0f), rad = (float)((nangle*cimg::valuePI)/180.0), ca=(float)std::cos(rad)/zoom, sa=(float)std::sin(rad)/zoom; if (cond!=1 && zoom==1 && cimg::mod(nangle,90.0f)==0) { const int iangle = (int)nangle/90; switch (iangle) { case 1: { dest.fill(0); const unsigned int xmin = cimg::max(0,(dimx()-dimy())/2), xmax = cimg::min(width,xmin+height), ymin = cimg::max(0,(dimy()-dimx())/2), ymax = cimg::min(height,ymin+width), xoff = xmin + cimg::min(0,(dimx()-dimy())/2), yoff = ymin + cimg::min(0,(dimy()-dimx())/2); for (int v = 0; v<(int)((dest).dim); ++v) for (int z = 0; z<(int)((dest).depth); ++z) for (unsigned int y=ymin; y& rotate(const float angle, const float cx, const float cy, const float zoom=1, const unsigned int cond=3) { return get_rotate(angle,cx,cy,zoom,cond).transfer_to(*this); } CImg get_resize(const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100, const int interp=1, const int border_condition=-1, const bool center=false) const { if (!pdx || !pdy || !pdz || !pdv) return CImg(); const unsigned int tdx = pdx<0?-pdx*width/100:pdx, tdy = pdy<0?-pdy*height/100:pdy, tdz = pdz<0?-pdz*depth/100:pdz, tdv = pdv<0?-pdv*dim/100:pdv, dx = tdx?tdx:1, dy = tdy?tdy:1, dz = tdz?tdz:1, dv = tdv?tdv:1; if (width==dx && height==dy && depth==dz && dim==dv) return +*this; if (is_empty()) return CImg(dx,dy,dz,dv,0); CImg res; switch (interp) { case -1: std::memcpy(res.assign(dx,dy,dz,dv,0).data,data,sizeof(T)*cimg::min(size(),(long unsigned int)dx*dy*dz*dv)); break; case 0: { const unsigned int bx = width-1, by = height-1, bz = depth-1, bv = dim-1; res.assign(dx,dy,dz,dv); switch (border_condition) { case 1: { if (center) { const int x0 = (res.dimx()-dimx())/2, y0 = (res.dimy()-dimy())/2, z0 = (res.dimz()-dimz())/2, v0 = (res.dimv()-dimv())/2, x1 = x0 + (int)bx, y1 = y0 + (int)by, z1 = z0 + (int)bz, v1 = v0 + (int)bv; res.draw_image(*this,x0,y0,z0,v0); for (int v = 0; v<(int)((res).dim); ++v) for (int _n1l = (int)(v<(int)(v0) || v>(int)(v1)), z = 0; z<(int)((res).depth); ++z) for (int _n1k = (int)(z<(int)(z0) || z>(int)(z1)), y = 0; y<(int)((res).height); ++y) for (int _n1j = (int)(y<(int)(y0) || y>(int)(y1)), x = _n1j || _n1k || _n1l?0:(int)(x0)>0?0:(int)(x1)+1; x<(int)((res).width); ++x, x = _n1j || _n1k || _n1l?x:(x==(int)(x0)?(int)(x1)+1:x)) res(x,y,z,v) = pix4d(x-x0,y-y0,z-z0,v-v0); } else { res.draw_image(*this,0,0,0,0); for (int v = 0; v<(int)((res).dim); ++v) for (int _n1l = (int)(v<(int)(0) || v>(int)(bv)), z = 0; z<(int)((res).depth); ++z) for (int _n1k = (int)(z<(int)(0) || z>(int)(bz)), y = 0; y<(int)((res).height); ++y) for (int _n1j = (int)(y<(int)(0) || y>(int)(by)), x = _n1j || _n1k || _n1l?0:(int)(0)>0?0:(int)(bx)+1; x<(int)((res).width); ++x, x = _n1j || _n1k || _n1l?x:(x==(int)(0)?(int)(bx)+1:x)) res(x,y,z,v) = pix4d(x,y,z,v); } } break; case 2 : { const int x0 = (res.dimx()-dimx())/2, y0 = (res.dimy()-dimy())/2, z0 = (res.dimz()-dimz())/2, v0 = (res.dimv()-dimv())/2, nx0 = x0>0?x0-(1+x0/width)*width:x0, ny0 = y0>0?y0-(1+y0/height)*height:y0, nz0 = z0>0?z0-(1+z0/depth)*depth:z0, nv0 = v0>0?v0-(1+v0/dim)*dim:v0; for (int k=nv0; k<(int)dv; k+=dimv()) for (int z=nz0; z<(int)dz; z+=dimz()) for (int y=ny0; y<(int)dy; y+=dimy()) for (int x=nx0; x<(int)dx; x+=dimx()) res.draw_image(*this,x,y,z,k); } break; default: { res.fill(0); if (center) res.draw_image(*this,(res.dimx()-dimx())/2,(res.dimy()-dimy())/2,(res.dimz()-dimz())/2,(res.dimv()-dimv())/2); else res.draw_image(*this,0,0,0,0); } break; } } break; case 1: { res.assign(dx,dy,dz,dv); unsigned int *const offx = new unsigned int[dx], *const offy = new unsigned int[dy+1], *const offz = new unsigned int[dz+1], *const offv = new unsigned int[dv+1], *poffx, *poffy, *poffz, *poffv, curr, old; const unsigned int wh = width*height, whd = width*height*depth, rwh = dx*dy, rwhd = dx*dy*dz; poffx = offx; curr = 0; { for (int x = 0; x<(int)((res).width); ++x) { old=curr; curr=(x+1)*width/dx; *(poffx++) = (unsigned int)curr-(unsigned int)old; }} poffy = offy; curr = 0; { for (int y = 0; y<(int)((res).height); ++y) { old=curr; curr=(y+1)*height/dy; *(poffy++) = width*((unsigned int)curr-(unsigned int)old); }} *poffy=0; poffz = offz; curr = 0; { for (int z = 0; z<(int)((res).depth); ++z) { old=curr; curr=(z+1)*depth/dz; *(poffz++) = wh*((unsigned int)curr-(unsigned int)old); }} *poffz=0; poffv = offv; curr = 0; { for (int k = 0; k<(int)((res).dim); ++k) { old=curr; curr=(k+1)*dim/dv; *(poffv++) = whd*((unsigned int)curr-(unsigned int)old); }} *poffv=0; T *ptrd = res.data; const T* ptrv = data; poffv = offv; for (unsigned int k=0; k::type ftype; bool instance_first = true; if (dx!=width) { CImg tmp(dx,height,depth,dim,0); for (unsigned int a=width*dx, b=width, c=dx, s=0, t=0; a; ) { const unsigned int d = cimg::min(b,c); a-=d; b-=d; c-=d; for (int v = 0; v<(int)((tmp).dim); ++v) for (int z = 0; z<(int)((tmp).depth); ++z) for (int y = 0; y<(int)((tmp).height); ++y) tmp(t,y,z,v)+=(ftype)(*this)(s,y,z,v)*d; if (!b) { for (int v = 0; v<(int)((tmp).dim); ++v) for (int z = 0; z<(int)((tmp).depth); ++z) for (int y = 0; y<(int)((tmp).height); ++y) tmp(t,y,z,v)/=width; ++t; b = width; } if (!c) { ++s; c = dx; } } tmp.transfer_to(res); instance_first = false; } if (dy!=height) { CImg tmp(dx,dy,depth,dim,0); for (unsigned int a=height*dy, b=height, c=dy, s=0, t=0; a; ) { const unsigned int d = cimg::min(b,c); a-=d; b-=d; c-=d; if (instance_first) for (int v = 0; v<(int)((tmp).dim); ++v) for (int z = 0; z<(int)((tmp).depth); ++z) for (int x = 0; x<(int)((tmp).width); ++x) tmp(x,t,z,v)+=(ftype)(*this)(x,s,z,v)*d; else for (int v = 0; v<(int)((tmp).dim); ++v) for (int z = 0; z<(int)((tmp).depth); ++z) for (int x = 0; x<(int)((tmp).width); ++x) tmp(x,t,z,v)+=(ftype)res(x,s,z,v)*d; if (!b) { for (int v = 0; v<(int)((tmp).dim); ++v) for (int z = 0; z<(int)((tmp).depth); ++z) for (int x = 0; x<(int)((tmp).width); ++x) tmp(x,t,z,v)/=height; ++t; b = height; } if (!c) { ++s; c = dy; } } tmp.transfer_to(res); instance_first = false; } if (dz!=depth) { CImg tmp(dx,dy,dz,dim,0); for (unsigned int a=depth*dz, b=depth, c=dz, s=0, t=0; a; ) { const unsigned int d = cimg::min(b,c); a-=d; b-=d; c-=d; if (instance_first) for (int v = 0; v<(int)((tmp).dim); ++v) for (int y = 0; y<(int)((tmp).height); ++y) for (int x = 0; x<(int)((tmp).width); ++x) tmp(x,y,t,v)+=(ftype)(*this)(x,y,s,v)*d; else for (int v = 0; v<(int)((tmp).dim); ++v) for (int y = 0; y<(int)((tmp).height); ++y) for (int x = 0; x<(int)((tmp).width); ++x) tmp(x,y,t,v)+=(ftype)res(x,y,s,v)*d; if (!b) { for (int v = 0; v<(int)((tmp).dim); ++v) for (int y = 0; y<(int)((tmp).height); ++y) for (int x = 0; x<(int)((tmp).width); ++x) tmp(x,y,t,v)/=depth; ++t; b = depth; } if (!c) { ++s; c = dz; } } tmp.transfer_to(res); instance_first = false; } if (dv!=dim) { CImg tmp(dx,dy,dz,dv,0); for (unsigned int a=dim*dv, b=dim, c=dv, s=0, t=0; a; ) { const unsigned int d = cimg::min(b,c); a-=d; b-=d; c-=d; if (instance_first) for (int z = 0; z<(int)((tmp).depth); ++z) for (int y = 0; y<(int)((tmp).height); ++y) for (int x = 0; x<(int)((tmp).width); ++x) tmp(x,y,z,t)+=(ftype)(*this)(x,y,z,s)*d; else for (int z = 0; z<(int)((tmp).depth); ++z) for (int y = 0; y<(int)((tmp).height); ++y) for (int x = 0; x<(int)((tmp).width); ++x) tmp(x,y,z,t)+=(ftype)res(x,y,z,s)*d; if (!b) { for (int z = 0; z<(int)((tmp).depth); ++z) for (int y = 0; y<(int)((tmp).height); ++y) for (int x = 0; x<(int)((tmp).width); ++x) tmp(x,y,z,t)/=dim; ++t; b = dim; } if (!c) { ++s; c = dv; } } tmp.transfer_to(res); instance_first = false; } } break; case 3: { const unsigned int dimmax = cimg::max(dx,dy,dz,dv); const float sx = (border_condition<0 && dx>width )?(dx>1?(width-1.0f)/(dx-1) :0):(float)width/dx, sy = (border_condition<0 && dy>height)?(dy>1?(height-1.0f)/(dy-1):0):(float)height/dy, sz = (border_condition<0 && dz>depth )?(dz>1?(depth-1.0f)/(dz-1) :0):(float)depth/dz, sv = (border_condition<0 && dv>dim )?(dv>1?(dim-1.0f)/(dv-1) :0):(float)dim/dv; unsigned int *const off = new unsigned int[dimmax], *poff; float *const foff = new float[dimmax], *pfoff, old, curr; CImg resx, resy, resz, resv; T *ptrd; if (dx!=width) { if (width==1) resx = get_resize(dx,height,depth,dim,1,0); else { resx.assign(dx,height,depth,dim); curr = old = 0; poff = off; pfoff = foff; for (int x = 0; x<(int)((resx).width); ++x) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sx; *(poff++) = (unsigned int)curr-(unsigned int)old; } ptrd = resx.data; const T *ptrs0 = data; for (int k = 0; k<(int)((resx).dim); ++k) for (int z = 0; z<(int)((resx).depth); ++z) for (int y = 0; y<(int)((resx).height); ++y) { poff = off; pfoff = foff; const T *ptrs = ptrs0, *const ptrsmax = ptrs0 + (width-1); for (int x = 0; x<(int)((resx).width); ++x) { const float alpha = *(pfoff++); const T val1 = *ptrs, val2 = ptrs::type ftype; const float sx = (border_condition<0 && dx>width )?(dx>1?(width-1.0f)/(dx-1) :0):(float)width/dx, sy = (border_condition<0 && dy>height)?(dy>1?(height-1.0f)/(dy-1):0):(float)height/dy, sz = (border_condition<0 && dz>depth )?(dz>1?(depth-1.0f)/(dz-1) :0):(float)depth/dz, sv = (border_condition<0 && dv>dim )?(dv>1?(dim-1.0f)/(dv-1) :0):(float)dim/dv; res.assign(dx,dy,dz,dv); T *ptrd = res.ptr(); float cx, cy, cz, ck = 0; for (int k = 0; k<(int)((res).dim); ++k) { cz = 0; for (int z = 0; z<(int)((res).depth); ++z) { cy = 0; for (int y = 0; y<(int)((res).height); ++y) { cx = 0; for (int x = 0; x<(int)((res).width); ++x) { *(ptrd++) = (T)(border_condition?cubic_pix2d(cx,cy,(int)cz,(int)ck):cubic_pix2d(cx,cy,(int)cz,(int)ck,0)); cx+=sx; } cy+=sy; } cz+=sz; } ck+=sv; } } break; default: throw CImgArgumentException("CImg<%s>::resize() : Invalid interpolation method : %d specified.", pixel_type(),interp); } return res; } CImg& resize(const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100, const int interp=1, const int border_condition=-1, const bool center=false) { if (!pdx || !pdy || !pdz || !pdv) return assign(); const unsigned int dx = pdx<0?-pdx*width/100:pdx, dy = pdy<0?-pdy*height/100:pdy, dz = pdz<0?-pdz*depth/100:pdz, dv = pdv<0?-pdv*dim/100:pdv; if (width==dx && height==dy && depth==dz && dim==dv) return *this; if (interp==-1 && dx*dy*dz*dv==size()) { width = dx; height = dy; depth = dz; dim = dv; return *this; } return get_resize(dx,dy,dz,dv,interp,border_condition,center).transfer_to(*this); } template CImg get_resize(const CImg& src, const int interp=1, const int border_condition=-1, const bool center=false) const { return get_resize(src.width,src.height,src.depth,src.dim,interp,border_condition,center); } template CImg& resize(const CImg& src, const int interp=1, const int border_condition=-1, const bool center=false) { return resize(src.width,src.height,src.depth,src.dim,interp,border_condition,center); } CImg get_resize(const CImgDisplay& disp, const int interp=1, const int border_condition=-1, const bool center=false) const { return get_resize(disp.width,disp.height,depth,dim,interp,border_condition,center); } CImg& resize(const CImgDisplay& disp, const int interp=1, const int border_condition=-1, const bool center=false) { return resize(disp.width,disp.height,depth,dim,interp,border_condition,center); } CImg get_permute_axes(const char *permut="vxyz") const { if (is_empty() || !permut) return (+*this); CImg res; const T* ptr = data; if (!cimg::strncasecmp(permut,"xyzv",4)) return (+*this); if (!cimg::strncasecmp(permut,"xyvz",4)) { res.assign(width,height,dim,depth); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(x,y,v,z) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"xzyv",4)) { res.assign(width,depth,height,dim); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(x,z,y,v) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"xzvy",4)) { res.assign(width,depth,dim,height); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(x,z,v,y) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"xvyz",4)) { res.assign(width,dim,height,depth); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(x,v,y,z) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"xvzy",4)) { res.assign(width,dim,depth,height); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(x,v,z,y) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"yxzv",4)) { res.assign(height,width,depth,dim); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(y,x,z,v) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"yxvz",4)) { res.assign(height,width,dim,depth); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(y,x,v,z) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"yzxv",4)) { res.assign(height,depth,width,dim); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(y,z,x,v) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"yzvx",4)) { res.assign(height,depth,dim,width); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(y,z,v,x) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"yvxz",4)) { res.assign(height,dim,width,depth); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(y,v,x,z) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"yvzx",4)) { res.assign(height,dim,depth,width); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(y,v,z,x) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"zxyv",4)) { res.assign(depth,width,height,dim); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(z,x,y,v) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"zxvy",4)) { res.assign(depth,width,dim,height); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(z,x,v,y) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"zyxv",4)) { res.assign(depth,height,width,dim); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(z,y,x,v) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"zyvx",4)) { res.assign(depth,height,dim,width); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(z,y,v,x) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"zvxy",4)) { res.assign(depth,dim,width,height); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(z,v,x,y) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"zvyx",4)) { res.assign(depth,dim,height,width); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(z,v,y,x) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"vxyz",4)) { res.assign(dim,width,height,depth); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(v,x,y,z) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"vxzy",4)) { res.assign(dim,width,depth,height); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(v,x,z,y) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"vyxz",4)) { res.assign(dim,height,width,depth); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(v,y,x,z) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"vyzx",4)) { res.assign(dim,height,depth,width); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(v,y,z,x) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"vzxy",4)) { res.assign(dim,depth,width,height); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(v,z,x,y) = *(ptr++); return res; } if (!cimg::strncasecmp(permut,"vzyx",4)) { res.assign(dim,depth,height,width); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) res(v,z,y,x) = *(ptr++); return res; } throw CImgArgumentException("CImg<%s>::permute_axes() : Invalid input permutation '%s'.",pixel_type(),permut); return res; } CImg& permute_axes(const char *order="vxyz") { return get_permute_axes(order).transfer_to(*this); } CImg get_resize_halfXY() const { typedef typename cimg::superset::type ftype; if (is_empty()) return CImg(); const ftype mask[9] = { 0.07842776544f, 0.1231940459f, 0.07842776544f, 0.1231940459f, 0.1935127547f, 0.1231940459f, 0.07842776544f, 0.1231940459f, 0.07842776544f }; ftype I[9] = { 0 }; CImg dest(width/2,height/2,depth,dim); for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,k)), (I[3] = I[4] = (*this)(0,y,z,k)), (I[6] = I[7] = (*this)(0,_n1y,z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,z,k)), (I[5] = (*this)(_n1x,y,z,k)), (I[8] = (*this)(_n1x,_n1y,z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) if (x%2 && y%2) dest(x/2,y/2,z,k) = (T) (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] + I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] + I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]); return dest; } CImg& resize_halfXY() { return get_resize_halfXY().transfer_to(*this); } CImg get_mirror(const char axe='x') const { return (+*this).mirror(axe); } CImg& mirror(const char axe='x') { if (!is_empty()) { T *pf, *pb, *buf = 0; switch (cimg::uncase(axe)) { case 'x': { pf = data; pb = ptr(width-1); for (unsigned int yzv=0; yzv::mirror() : unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe); } if (buf) delete[] buf; } return *this; } CImg get_translate(const int deltax, const int deltay=0, const int deltaz=0, const int deltav=0, const int border_condition=0) const { return (+*this).translate(deltax,deltay,deltaz,deltav,border_condition); } CImg& translate(const int deltax, const int deltay=0, const int deltaz=0, const int deltav=0, const int border_condition=0) { if (!is_empty()) { if (deltax) switch (border_condition) { case 0: if (cimg::abs(deltax)>=dimx()) return fill(0); if (deltax>0) for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { std::memmove(ptr(0,y,z,k),ptr(deltax,y,z,k),(width-deltax)*sizeof(T)); std::memset(ptr(width-deltax,y,z,k),0,deltax*sizeof(T)); } else for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { std::memmove(ptr(-deltax,y,z,k),ptr(0,y,z,k),(width+deltax)*sizeof(T)); std::memset(ptr(0,y,z,k),0,-deltax*sizeof(T)); } break; case 1: if (deltax>0) { const int ndeltax = (deltax>=dimx())?width-1:deltax; if (!ndeltax) return *this; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { std::memmove(ptr(0,y,z,k),ptr(ndeltax,y,z,k),(width-ndeltax)*sizeof(T)); T *ptrd = ptr(width-1,y,z,k); const T val = *ptrd; for (int l=0; l=dimx())?width-1:-deltax; if (!ndeltax) return *this; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { std::memmove(ptr(ndeltax,y,z,k),ptr(0,y,z,k),(width-ndeltax)*sizeof(T)); T *ptrd = ptr(0,y,z,k); const T val = *ptrd; for (int l=0; l0) for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { std::memcpy(buf,ptr(0,y,z,k),ndeltax*sizeof(T)); std::memmove(ptr(0,y,z,k),ptr(ndeltax,y,z,k),(width-ndeltax)*sizeof(T)); std::memcpy(ptr(width-ndeltax,y,z,k),buf,ndeltax*sizeof(T)); } else for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { std::memcpy(buf,ptr(width+ndeltax,y,z,k),-ndeltax*sizeof(T)); std::memmove(ptr(-ndeltax,y,z,k),ptr(0,y,z,k),(width+ndeltax)*sizeof(T)); std::memcpy(ptr(0,y,z,k),buf,-ndeltax*sizeof(T)); } delete[] buf; } break; } if (deltay) switch (border_condition) { case 0: if (cimg::abs(deltay)>=dimy()) return fill(0); if (deltay>0) for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) { std::memmove(ptr(0,0,z,k),ptr(0,deltay,z,k),width*(height-deltay)*sizeof(T)); std::memset(ptr(0,height-deltay,z,k),0,width*deltay*sizeof(T)); } else for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) { std::memmove(ptr(0,-deltay,z,k),ptr(0,0,z,k),width*(height+deltay)*sizeof(T)); std::memset(ptr(0,0,z,k),0,-deltay*width*sizeof(T)); } break; case 1: if (deltay>0) { const int ndeltay = (deltay>=dimy())?height-1:deltay; if (!ndeltay) return *this; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) { std::memmove(ptr(0,0,z,k),ptr(0,ndeltay,z,k),width*(height-ndeltay)*sizeof(T)); T *ptrd = ptr(0,height-ndeltay,z,k), *ptrs = ptr(0,height-1,z,k); for (int l=0; l=dimy())?height-1:-deltay; if (!ndeltay) return *this; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) { std::memmove(ptr(0,ndeltay,z,k),ptr(0,0,z,k),width*(height-ndeltay)*sizeof(T)); T *ptrd = ptr(0,1,z,k), *ptrs = ptr(0,0,z,k); for (int l=0; l0) for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) { std::memcpy(buf,ptr(0,0,z,k),width*ndeltay*sizeof(T)); std::memmove(ptr(0,0,z,k),ptr(0,ndeltay,z,k),width*(height-ndeltay)*sizeof(T)); std::memcpy(ptr(0,height-ndeltay,z,k),buf,width*ndeltay*sizeof(T)); } else for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) { std::memcpy(buf,ptr(0,height+ndeltay,z,k),-ndeltay*width*sizeof(T)); std::memmove(ptr(0,-ndeltay,z,k),ptr(0,0,z,k),width*(height+ndeltay)*sizeof(T)); std::memcpy(ptr(0,0,z,k),buf,-ndeltay*width*sizeof(T)); } delete[] buf; } break; } if (deltaz) switch (border_condition) { case 0: if (cimg::abs(deltaz)>=dimz()) return fill(0); if (deltaz>0) for (int k = 0; k<(int)((*this).dim); ++k) { std::memmove(ptr(0,0,0,k),ptr(0,0,deltaz,k),width*height*(depth-deltaz)*sizeof(T)); std::memset(ptr(0,0,depth-deltaz,k),0,width*height*deltaz*sizeof(T)); } else for (int k = 0; k<(int)((*this).dim); ++k) { std::memmove(ptr(0,0,-deltaz,k),ptr(0,0,0,k),width*height*(depth+deltaz)*sizeof(T)); std::memset(ptr(0,0,0,k),0,-deltaz*width*height*sizeof(T)); } break; case 1: if (deltaz>0) { const int ndeltaz = (deltaz>=dimz())?depth-1:deltaz; if (!ndeltaz) return *this; for (int k = 0; k<(int)((*this).dim); ++k) { std::memmove(ptr(0,0,0,k),ptr(0,0,ndeltaz,k),width*height*(depth-ndeltaz)*sizeof(T)); T *ptrd = ptr(0,0,depth-ndeltaz,k), *ptrs = ptr(0,0,depth-1,k); for (int l=0; l=dimz())?depth-1:-deltaz; if (!ndeltaz) return *this; for (int k = 0; k<(int)((*this).dim); ++k) { std::memmove(ptr(0,0,ndeltaz,k),ptr(0,0,0,k),width*height*(depth-ndeltaz)*sizeof(T)); T *ptrd = ptr(0,0,1,k), *ptrs = ptr(0,0,0,k); for (int l=0; l0) for (int k = 0; k<(int)((*this).dim); ++k) { std::memcpy(buf,ptr(0,0,0,k),width*height*ndeltaz*sizeof(T)); std::memmove(ptr(0,0,0,k),ptr(0,0,ndeltaz,k),width*height*(depth-ndeltaz)*sizeof(T)); std::memcpy(ptr(0,0,depth-ndeltaz,k),buf,width*height*ndeltaz*sizeof(T)); } else for (int k = 0; k<(int)((*this).dim); ++k) { std::memcpy(buf,ptr(0,0,depth+ndeltaz,k),-ndeltaz*width*height*sizeof(T)); std::memmove(ptr(0,0,-ndeltaz,k),ptr(0,0,0,k),width*height*(depth+ndeltaz)*sizeof(T)); std::memcpy(ptr(0,0,0,k),buf,-ndeltaz*width*height*sizeof(T)); } delete[] buf; } break; } if (deltav) switch (border_condition) { case 0: if (cimg::abs(deltav)>=dimv()) return fill(0); if (deltav>0) { std::memmove(data,ptr(0,0,0,deltav),width*height*depth*(dim-deltav)*sizeof(T)); std::memset(ptr(0,0,0,dim-deltav),0,width*height*depth*deltav*sizeof(T)); } else for (int k = 0; k<(int)((*this).dim); ++k) { std::memmove(ptr(0,0,0,-deltav),data,width*height*depth*(dim+deltav)*sizeof(T)); std::memset(data,0,-deltav*width*height*depth*sizeof(T)); } break; case 1: if (deltav>0) { const int ndeltav = (deltav>=dimv())?dim-1:deltav; if (!ndeltav) return *this; std::memmove(data,ptr(0,0,0,ndeltav),width*height*depth*(dim-ndeltav)*sizeof(T)); T *ptrd = ptr(0,0,0,dim-ndeltav), *ptrs = ptr(0,0,0,dim-1); for (int l=0; l=dimv())?dim-1:-deltav; if (!ndeltav) return *this; std::memmove(ptr(0,0,0,ndeltav),data,width*height*depth*(dim-ndeltav)*sizeof(T)); T *ptrd = ptr(0,0,0,1); for (int l=0; l0) { std::memcpy(buf,data,width*height*depth*ndeltav*sizeof(T)); std::memmove(data,ptr(0,0,0,ndeltav),width*height*depth*(dim-ndeltav)*sizeof(T)); std::memcpy(ptr(0,0,0,dim-ndeltav),buf,width*height*depth*ndeltav*sizeof(T)); } else { std::memcpy(buf,ptr(0,0,0,dim+ndeltav),-ndeltav*width*height*depth*sizeof(T)); std::memmove(ptr(0,0,0,-ndeltav),data,width*height*depth*(dim+ndeltav)*sizeof(T)); std::memcpy(data,buf,-ndeltav*width*height*depth*sizeof(T)); } delete[] buf; } break; } } return *this; } CImg get_crop(const int x0, const int y0, const int z0, const int v0, const int x1, const int y1, const int z1, const int v1, const bool border_condition=false) const { if (is_empty()) return *this; const int nx0 = x0 dest(1U+nx1-nx0,1U+ny1-ny0,1U+nz1-nz0,1U+nv1-nv0); if (nx0<0 || nx1>=dimx() || ny0<0 || ny1>=dimy() || nz0<0 || nz1>=dimz() || nv0<0 || nv1>=dimv()) { if (border_condition) for (int v = 0; v<(int)((dest).dim); ++v) for (int z = 0; z<(int)((dest).depth); ++z) for (int y = 0; y<(int)((dest).height); ++y) for (int x = 0; x<(int)((dest).width); ++x) dest(x,y,z,v) = pix4d(nx0+x,ny0+y,nz0+z,nv0+v); else dest.fill(0).draw_image(*this,-nx0,-ny0,-nz0,-nv0); } else dest.draw_image(*this,-nx0,-ny0,-nz0,-nv0); return dest; } CImg& crop(const int x0, const int y0, const int z0, const int v0, const int x1, const int y1, const int z1, const int v1, const bool border_condition=false) { return get_crop(x0,y0,z0,v0,x1,y1,z1,v1,border_condition).transfer_to(*this); } CImg get_crop(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1, const bool border_condition=false) const { return get_crop(x0,y0,z0,0,x1,y1,z1,dim-1,border_condition); } CImg& crop(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1, const bool border_condition=false) { return crop(x0,y0,z0,0,x1,y1,z1,dim-1,border_condition); } CImg get_crop(const int x0, const int y0, const int x1, const int y1, const bool border_condition=false) const { return get_crop(x0,y0,0,0,x1,y1,depth-1,dim-1,border_condition); } CImg& crop(const int x0, const int y0, const int x1, const int y1, const bool border_condition=false) { return crop(x0,y0,0,0,x1,y1,depth-1,dim-1,border_condition); } CImg get_crop(const int x0, const int x1, const bool border_condition=false) const { return get_crop(x0,0,0,0,x1,height-1,depth-1,dim-1,border_condition); } CImg& crop(const int x0, const int x1, const bool border_condition=false) { return crop(x0,0,0,0,x1,height-1,depth-1,dim-1,border_condition); } CImg get_columns(const unsigned int x0, const unsigned int x1) const { return get_crop((int)x0,0,0,0,(int)x1,dimy()-1,dimz()-1,dimv()-1); } CImg& columns(const unsigned int x0, const unsigned int x1) { return get_columns(x0,x1).transfer_to(*this); } CImg get_column(const unsigned int x0) const { return get_columns(x0,x0); } CImg& column(const unsigned int x0) { return columns(x0,x0); } CImg get_lines(const unsigned int y0, const unsigned int y1) const { return get_crop(0,(int)y0,0,0,dimx()-1,(int)y1,dimz()-1,dimv()-1); } CImg& lines(const unsigned int y0, const unsigned int y1) { return get_lines(y0,y1).transfer_to(*this); } CImg get_line(const unsigned int y0) const { return get_lines(y0,y0); } CImg& line(const unsigned int y0) { return lines(y0,y0); } CImg get_slices(const unsigned int z0, const unsigned int z1) const { return get_crop(0,0,(int)z0,0,dimx()-1,dimy()-1,(int)z1,dimv()-1); } CImg& slices(const unsigned int z0, const unsigned int z1) { return get_slices(z0,z1).transfer_to(*this); } CImg get_slice(const unsigned int z0) const { return get_slices(z0,z0); } CImg& slice(const unsigned int z0) { return slices(z0,z0); } CImg get_channels(const unsigned int v0, const unsigned int v1) const { return get_crop(0,0,0,(int)v0,dimx()-1,dimy()-1,dimz()-1,(int)v1); } CImg& channels(const unsigned int v0, const unsigned int v1) { return get_channels(v0,v1).transfer_to(*this); } CImg get_channel(const unsigned int v0) const { return get_channels(v0,v0); } CImg& channel(const unsigned int v0) { return channels(v0,v0); } CImg get_shared_points(const unsigned int x0, const unsigned int x1, const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) { const unsigned long beg = offset(x0,y0,z0,v0), end = offset(x1,y0,z0,v0); if (beg>end || beg>=size() || end>=size()) throw CImgArgumentException("CImg<%s>::get_shared_points() : Cannot return a shared-memory subset (%u->%u,%u,%u,%u) from " "a (%u,%u,%u,%u) image.",pixel_type(),x0,x1,y0,z0,v0,width,height,depth,dim); return CImg(data+beg,x1-x0+1,1,1,1,true); } const CImg get_shared_points(const unsigned int x0, const unsigned int x1, const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) const { const unsigned long beg = offset(x0,y0,z0,v0), end = offset(x1,y0,z0,v0); if (beg>end || beg>=size() || end>=size()) throw CImgArgumentException("CImg<%s>::get_shared_points() : Cannot return a shared-memory subset (%u->%u,%u,%u,%u) from " "a (%u,%u,%u,%u) image.",pixel_type(),x0,x1,y0,z0,v0,width,height,depth,dim); return CImg(data+beg,x1-x0+1,1,1,1,true); } CImg get_shared_lines(const unsigned int y0, const unsigned int y1, const unsigned int z0=0, const unsigned int v0=0) { const unsigned long beg = offset(0,y0,z0,v0), end = offset(0,y1,z0,v0); if (beg>end || beg>=size() || end>=size()) throw CImgArgumentException("CImg<%s>::get_shared_lines() : Cannot return a shared-memory subset (0->%u,%u->%u,%u,%u) from " "a (%u,%u,%u,%u) image.",pixel_type(),width-1,y0,y1,z0,v0,width,height,depth,dim); return CImg(data+beg,width,y1-y0+1,1,1,true); } const CImg get_shared_lines(const unsigned int y0, const unsigned int y1, const unsigned int z0=0, const unsigned int v0=0) const { const unsigned long beg = offset(0,y0,z0,v0), end = offset(0,y1,z0,v0); if (beg>end || beg>=size() || end>=size()) throw CImgArgumentException("CImg<%s>::get_shared_lines() : Cannot return a shared-memory subset (0->%u,%u->%u,%u,%u) from " "a (%u,%u,%u,%u) image.",pixel_type(),width-1,y0,y1,z0,v0,width,height,depth,dim); return CImg(data+beg,width,y1-y0+1,1,1,true); } CImg get_shared_line(const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) { return get_shared_lines(y0,y0,z0,v0); } const CImg get_shared_line(const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) const { return get_shared_lines(y0,y0,z0,v0); } CImg get_shared_planes(const unsigned int z0, const unsigned int z1, const unsigned int v0=0) { const unsigned long beg = offset(0,0,z0,v0), end = offset(0,0,z1,v0); if (beg>end || beg>=size() || end>=size()) throw CImgArgumentException("CImg<%s>::get_shared_planes() : Cannot return a shared-memory subset (0->%u,0->%u,%u->%u,%u) from " "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,z0,z1,v0,width,height,depth,dim); return CImg(data+beg,width,height,z1-z0+1,1,true); } const CImg get_shared_planes(const unsigned int z0, const unsigned int z1, const unsigned int v0=0) const { const unsigned long beg = offset(0,0,z0,v0), end = offset(0,0,z1,v0); if (beg>end || beg>=size() || end>=size()) throw CImgArgumentException("CImg<%s>::get_shared_planes() : Cannot return a shared-memory subset (0->%u,0->%u,%u->%u,%u) from " "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,z0,z1,v0,width,height,depth,dim); return CImg(data+beg,width,height,z1-z0+1,1,true); } CImg get_shared_plane(const unsigned int z0, const unsigned int v0=0) { return get_shared_planes(z0,z0,v0); } const CImg get_shared_plane(const unsigned int z0, const unsigned int v0=0) const { return get_shared_planes(z0,z0,v0); } CImg get_shared_channels(const unsigned int v0, const unsigned int v1) { const unsigned long beg = offset(0,0,0,v0), end = offset(0,0,0,v1); if (beg>end || beg>=size() || end>=size()) throw CImgArgumentException("CImg<%s>::get_shared_channels() : Cannot return a shared-memory subset (0->%u,0->%u,0->%u,%u->%u) from " "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,depth-1,v0,v1,width,height,depth,dim); return CImg(data+beg,width,height,depth,v1-v0+1,true); } const CImg get_shared_channels(const unsigned int v0, const unsigned int v1) const { const unsigned long beg = offset(0,0,0,v0), end = offset(0,0,0,v1); if (beg>end || beg>=size() || end>=size()) throw CImgArgumentException("CImg<%s>::get_shared_channels() : Cannot return a shared-memory subset (0->%u,0->%u,0->%u,%u->%u) from " "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,depth-1,v0,v1,width,height,depth,dim); return CImg(data+beg,width,height,depth,v1-v0+1,true); } CImg get_shared_channel(const unsigned int v0) { return get_shared_channels(v0,v0); } const CImg get_shared_channel(const unsigned int v0) const { return get_shared_channels(v0,v0); } CImg get_shared() { return CImg(data,width,height,depth,dim,true); } const CImg get_shared() const { return CImg(data,width,height,depth,dim,true); } CImg get_projections2d(const unsigned int x0, const unsigned int y0, const unsigned int z0, const int dx=-100, const int dy=-100, const int dz=-100) const { if (is_empty()) return CImg(); const unsigned int nx0 = (x0>=width)?width-1:x0, ny0 = (y0>=height)?height-1:y0, nz0 = (z0>=depth)?depth-1:z0; CImg imgxy(width,height,1,dim), imgzy(depth,height,1,dim), imgxz(width,depth,1,dim); { for (int k = 0; k<(int)((*this).dim); ++k) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) imgxy(x,y,k) = (*this)(x,y,nz0,k); } { for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) imgzy(z,y,k) = (*this)(nx0,y,z,k); } { for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int x = 0; x<(int)((*this).width); ++x) imgxz(x,z,k) = (*this)(x,ny0,z,k); } imgxy.resize(dx,dy,1,dim,1); imgzy.resize(dz,dy,1,dim,1); imgxz.resize(dx,dz,1,dim,1); return CImg(imgxy.width+imgzy.width,imgxy.height+imgxz.height,1,dim,0). draw_image(imgxy,0,0). draw_image(imgzy,imgxy.width,0). draw_image(imgxz,0,imgxy.height); } CImg& projections2d(const unsigned int x0, const unsigned int y0, const unsigned int z0, const int dx=-100, const int dy=-100, const int dz=-100) { return get_projections2d(x0,y0,z0,dx,dy,dz).transfer_to(*this); } CImg::type> get_histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) const { typedef typename cimg::last::type ftype; if (is_empty()) return CImg(); if (!nblevels) throw CImgArgumentException("CImg<%s>::get_histogram() : Can't compute an histogram with 0 levels", pixel_type()); T vmin = val_min, vmax = val_max; CImg res(nblevels,1,1,1,0); if (vmin>=vmax && vmin==0) vmin = minmax(vmax); if (vmin(*this).data; ) { const int pos = (int)((*ptr-vmin)*(nblevels-1)/(vmax-vmin)); if (pos>=0 && pos<(int)nblevels) ++res[pos]; } else res[0]+=size(); return res; } CImg& histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) { return get_histogram(nblevels,val_min,val_max).transfer_to(*this); } CImg get_equalize_histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) const { return (+*this).equalize_histogram(nblevels,val_min,val_max); } CImg& equalize_histogram(const unsigned int nblevels=256, const T val_min=(T)0, const T val_max=(T)0) { if (!is_empty()) { T vmin = val_min, vmax = val_max; if (vmin==vmax && vmin==0) vmin = minmax(vmax); if (vmin hist = get_histogram(nblevels,vmin,vmax); float cumul = 0; for (int pos = 0; pos<(int)((hist).width); ++pos) { cumul+=hist[pos]; hist[pos]=cumul; } for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const int pos = (unsigned int)((*ptr-vmin)*(nblevels-1)/(vmax-vmin)); if (pos>=0 && pos<(int)nblevels) *ptr = (T)(vmin + (vmax-vmin)*hist[pos]/size()); } } } return *this; } CImg::type> get_label_regions() const { if (depth>1) throw CImgInstanceException("CImg<%s>::label_regions() : Instance image must be a 2D image"); typedef typename cimg::last::type uitype; CImg res(width,height,depth,1,0); unsigned int label = 1; const unsigned int wh = width*height, siz = width*height*dim; const int W1 = dimx()-1, H1 = dimy()-1; bool flag; for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { bool done = false; if (y) { { flag = true; const T *ptr1 = ptr(x,y) + siz, *ptr2 = ptr(x,y-1) + siz; for (unsigned int i = dim; flag && i; --i) { ptr1-=wh; ptr2-=wh; flag = (*ptr1==*ptr2); } }; if (flag) { const unsigned int lab = (res(x,y) = res(x,y-1)); done = true; if (x && res(x-1,y)!=lab) { { flag = true; const T *ptr1 = ptr(x,y) + siz, *ptr2 = ptr(x-1,y) + siz; for (unsigned int i = dim; flag && i; --i) { ptr1-=wh; ptr2-=wh; flag = (*ptr1==*ptr2); } }; if (flag) { const unsigned int lold = res(x-1,y), *const cptr = res.ptr(x,y); for (unsigned int *ptr = res.ptr(); ptr=0; --y) for (int x=W1; x>=0; --x) { bool done = false; if (ycptr; --ptr) if (*ptr==lold) *ptr = lab; } } } } if (x(res).data; ) if (*ptr==lab) *ptr = label; ++label; } } return (res-=lab0); } CImg& label_regions() { return get_label_regions().transfer_to(*this); } CImg::type> get_norm_pointwise(int norm_type=2) const { typedef typename cimg::superset::type restype; if (is_empty()) return CImg(); CImg res(width,height,depth); switch(norm_type) { case -1: { for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { restype n = 0; for (int v = 0; v<(int)((*this).dim); ++v) { const restype tmp = (restype)cimg::abs((*this)(x,y,z,v)); if (tmp>n) n=tmp; res(x,y,z) = n; } } } break; case 1: { for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { restype n = 0; for (int v = 0; v<(int)((*this).dim); ++v) n+=cimg::abs((*this)(x,y,z,v)); res(x,y,z) = n; } } break; default: { for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { restype n = 0; for (int v = 0; v<(int)((*this).dim); ++v) n+=(*this)(x,y,z,v)*(*this)(x,y,z,v); res(x,y,z) = (restype)std::sqrt((double)n); } } break; } return res; } CImg& norm_pointwise(int norm_type=2) { return get_norm_pointwise(norm_type).transfer_to(*this); } CImg::type> get_orientation_pointwise() const { typedef typename cimg::superset::type restype; if (is_empty()) return CImg(); return CImg(*this,false).orientation_pointwise(); } CImg& orientation_pointwise() { for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { float n = 0.0f; for (int v = 0; v<(int)((*this).dim); ++v) n+=(float)((*this)(x,y,z,v)*(*this)(x,y,z,v)); n = (float)std::sqrt(n); if (n>0) for (int v = 0; v<(int)((*this).dim); ++v) (*this)(x,y,z,v) = (T)((*this)(x,y,z,v)/n); else for (int v = 0; v<(int)((*this).dim); ++v) (*this)(x,y,z,v) = 0; } return *this; } CImgList get_split(const char axe='x', const unsigned int nb=0) const { if (is_empty()) return CImgList(); CImgList res; switch (cimg::uncase(axe)) { case 'x': { if (nb>width) throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'x' into %u images.", pixel_type(),width,height,depth,dim,data,nb); res.assign(nb?nb:width); const unsigned int delta = width/res.size + ((width%res.size)?1:0); unsigned int l,x; for (l=0, x=0; lheight) throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'y' into %u images.", pixel_type(),width,height,depth,dim,data,nb); res.assign(nb?nb:height); const unsigned int delta = height/res.size + ((height%res.size)?1:0); unsigned int l,x; for (l=0, x=0; ldepth) throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'z' into %u images.", pixel_type(),width,height,depth,dim,data,nb); res.assign(nb?nb:depth); const unsigned int delta = depth/res.size + ((depth%res.size)?1:0); unsigned int l,x; for (l=0, x=0; ldim) throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'v' into %u images.", pixel_type(),width,height,depth,dim,data,nb); res.assign(nb?nb:dim); const unsigned int delta = dim/res.size + ((dim%res.size)?1:0); unsigned int l,x; for (l=0, x=0; l::get_split() : Unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe); break; } return res; } CImg get_append(const CImg& img, const char axis='x', const char align='c') const { if (!img) return *this; if (is_empty()) return img; CImgList temp(2); temp[0].width = width; temp[0].height = height; temp[0].depth = depth; temp[0].dim = dim; temp[0].data = data; temp[1].width = img.width; temp[1].height = img.height; temp[1].depth = img.depth; temp[1].dim = img.dim; temp[1].data = img.data; const CImg res = temp.get_append(axis,align); temp[0].width = temp[0].height = temp[0].depth = temp[0].dim = 0; temp[0].data = 0; temp[1].width = temp[1].height = temp[1].depth = temp[1].dim = 0; temp[1].data = 0; return res; } CImg& append(const CImg& img, const char axis='x', const char align='c') { if (!img) return *this; if (is_empty()) return (*this=img); return get_append(img,axis,align).transfer_to(*this); } CImgList::type> get_gradientXY(const int scheme=0) const { typedef typename cimg::superset::type restype; if (is_empty()) return CImgList(2); CImgList res(2,width,height,depth,dim); switch(scheme) { case -1: { restype I[9]; restype& Ipp = I[0]; restype& Icp = I[1]; restype& Inp = I[2]; restype& Ipc = I[3]; restype& Icc = I[4]; restype& Inc = I[5]; restype& Ipn = I[6]; restype& Icn = I[7]; restype& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,k)), (I[3] = I[4] = (*this)(0,y,z,k)), (I[6] = I[7] = (*this)(0,_n1y,z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,z,k)), (I[5] = (*this)(_n1x,y,z,k)), (I[8] = (*this)(_n1x,_n1y,z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { res[0](x,y,z,k) = Icc-Ipc; res[1](x,y,z,k) = Icc-Icp; } } break; case 1: { restype I[4]; restype& Icc = I[0]; restype& Inc = I[1]; restype& Icn = I[2]; restype& Inn = I[3]; Icc = Inc = Icn = Inn = 0; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = (int)( (I[0] = (*this)(0,y,z,k)), (I[2] = (*this)(0,_n1y,z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[1] = (*this)(_n1x,y,z,k)), (I[3] = (*this)(_n1x,_n1y,z,k)),1)) || x==--_n1x; I[0] = I[1], I[2] = I[3], ++x, ++_n1x) { res[0](x,y,0,k) = Inc-Icc; res[1](x,y,z,k) = Icn-Icc; } } break; case 2: { restype I[9]; restype& Ipp = I[0]; restype& Icp = I[1]; restype& Inp = I[2]; restype& Ipc = I[3]; restype& Icc = I[4]; restype& Inc = I[5]; restype& Ipn = I[6]; restype& Icn = I[7]; restype& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; const float a = 1, b = 2; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,k)), (I[3] = I[4] = (*this)(0,y,z,k)), (I[6] = I[7] = (*this)(0,_n1y,z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,z,k)), (I[5] = (*this)(_n1x,y,z,k)), (I[8] = (*this)(_n1x,_n1y,z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { res[0](x,y,z,k) = -a*Ipp-b*Ipc-a*Ipn+a*Inp+b*Inc+a*Inn; res[1](x,y,z,k) = -a*Ipp-b*Icp-a*Inp+a*Ipn+b*Icn+a*Inn; } } break; case 3: { restype I[9]; restype& Ipp = I[0]; restype& Icp = I[1]; restype& Inp = I[2]; restype& Ipc = I[3]; restype& Icc = I[4]; restype& Inc = I[5]; restype& Ipn = I[6]; restype& Icn = I[7]; restype& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; const float a = (float)(0.25*(2-std::sqrt(2.0))), b = (float)(0.5f*(std::sqrt(2.0)-1)); for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,k)), (I[3] = I[4] = (*this)(0,y,z,k)), (I[6] = I[7] = (*this)(0,_n1y,z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,z,k)), (I[5] = (*this)(_n1x,y,z,k)), (I[8] = (*this)(_n1x,_n1y,z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { res[0](x,y,z,k) = -a*Ipp-b*Ipc-a*Ipn+a*Inp+b*Inc+a*Inn; res[1](x,y,z,k) = -a*Ipp-b*Icp-a*Inp+a*Ipn+b*Icn+a*Inn; } } break; case 4: { res[0] = get_deriche(0,1,'x'); res[1] = get_deriche(0,1,'y'); } break; default: { restype I[9]; restype& Ipp = I[0]; restype& Icp = I[1]; restype& Inp = I[2]; restype& Ipc = I[3]; restype& Icc = I[4]; restype& Inc = I[5]; restype& Ipn = I[6]; restype& Icn = I[7]; restype& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,k)), (I[3] = I[4] = (*this)(0,y,z,k)), (I[6] = I[7] = (*this)(0,_n1y,z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,z,k)), (I[5] = (*this)(_n1x,y,z,k)), (I[8] = (*this)(_n1x,_n1y,z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { res[0](x,y,z,k) = 0.5f*(Inc-Ipc); res[1](x,y,z,k) = 0.5f*(Icn-Icp); } } break; } return res; } CImgList::type> get_gradientXYZ(const int scheme=0) const { typedef typename cimg::superset::type restype; if (is_empty()) return CImgList(3); CImgList res(3,width,height,depth,dim); restype I[27]; restype& Ippp = I[0]; restype& Icpp = I[1]; restype& Inpp = I[2]; restype& Ipcp = I[3]; restype& Iccp = I[4]; restype& Incp = I[5]; restype& Ipnp = I[6]; restype& Icnp = I[7]; restype& Innp = I[8]; restype& Ippc = I[9]; restype& Icpc = I[10]; restype& Inpc = I[11]; restype& Ipcc = I[12]; restype& Iccc = I[13]; restype& Incc = I[14]; restype& Ipnc = I[15]; restype& Icnc = I[16]; restype& Innc = I[17]; restype& Ippn = I[18]; restype& Icpn = I[19]; restype& Inpn = I[20]; restype& Ipcn = I[21]; restype& Iccn = I[22]; restype& Incn = I[23]; restype& Ipnn = I[24]; restype& Icnn = I[25]; restype& Innn = I[26]; Ippp = Icpp = Inpp = Ipcp = Iccp = Incp = Ipnp = Icnp = Innp = Ippc = Icpc = Inpc = Ipcc = Iccc = Incc = Ipnc = Icnc = Innc = Ippn = Icpn = Inpn = Ipcn = Iccn = Incn = Ipnn = Icnn = Innn = 0; switch(scheme) { case -1: { for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,k)), (I[3] = I[4] = (*this)(0,y,_p1z,k)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,k)), (I[9] = I[10] = (*this)(0,_p1y,z,k)), (I[12] = I[13] = (*this)(0,y,z,k)), (I[15] = I[16] = (*this)(0,_n1y,z,k)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,k)), (I[21] = I[22] = (*this)(0,y,_n1z,k)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,k)), (I[5] = (*this)(_n1x,y,_p1z,k)), (I[8] = (*this)(_n1x,_n1y,_p1z,k)), (I[11] = (*this)(_n1x,_p1y,z,k)), (I[14] = (*this)(_n1x,y,z,k)), (I[17] = (*this)(_n1x,_n1y,z,k)), (I[20] = (*this)(_n1x,_p1y,_n1z,k)), (I[23] = (*this)(_n1x,y,_n1z,k)), (I[26] = (*this)(_n1x,_n1y,_n1z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) { res[0](x,y,z,k) = Iccc-Ipcc; res[1](x,y,z,k) = Iccc-Icpc; res[2](x,y,z,k) = Iccc-Iccp; } } break; case 1: { for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,k)), (I[3] = I[4] = (*this)(0,y,_p1z,k)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,k)), (I[9] = I[10] = (*this)(0,_p1y,z,k)), (I[12] = I[13] = (*this)(0,y,z,k)), (I[15] = I[16] = (*this)(0,_n1y,z,k)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,k)), (I[21] = I[22] = (*this)(0,y,_n1z,k)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,k)), (I[5] = (*this)(_n1x,y,_p1z,k)), (I[8] = (*this)(_n1x,_n1y,_p1z,k)), (I[11] = (*this)(_n1x,_p1y,z,k)), (I[14] = (*this)(_n1x,y,z,k)), (I[17] = (*this)(_n1x,_n1y,z,k)), (I[20] = (*this)(_n1x,_p1y,_n1z,k)), (I[23] = (*this)(_n1x,y,_n1z,k)), (I[26] = (*this)(_n1x,_n1y,_n1z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) { res[0](x,y,z,k) = Incc-Iccc; res[1](x,y,z,k) = Icnc-Iccc; res[2](x,y,z,k) = Iccn-Iccc; } } break; case 4: { res[0] = get_deriche(0,1,'x'); res[1] = get_deriche(0,1,'y'); res[2] = get_deriche(0,1,'z'); } break; default: { for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,k)), (I[3] = I[4] = (*this)(0,y,_p1z,k)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,k)), (I[9] = I[10] = (*this)(0,_p1y,z,k)), (I[12] = I[13] = (*this)(0,y,z,k)), (I[15] = I[16] = (*this)(0,_n1y,z,k)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,k)), (I[21] = I[22] = (*this)(0,y,_n1z,k)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,k)), (I[5] = (*this)(_n1x,y,_p1z,k)), (I[8] = (*this)(_n1x,_n1y,_p1z,k)), (I[11] = (*this)(_n1x,_p1y,z,k)), (I[14] = (*this)(_n1x,y,z,k)), (I[17] = (*this)(_n1x,_n1y,z,k)), (I[20] = (*this)(_n1x,_p1y,_n1z,k)), (I[23] = (*this)(_n1x,y,_n1z,k)), (I[26] = (*this)(_n1x,_n1y,_n1z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) { res[0](x,y,z,k) = 0.5f*(Incc-Ipcc); res[1](x,y,z,k) = 0.5f*(Icnc-Icpc); res[2](x,y,z,k) = 0.5f*(Iccn-Iccp); } } break; } return res; } CImg::type> get_structure_tensorXY(const int scheme=1) const { typedef typename cimg::superset::type restype; if (is_empty()) return CImg(); CImg res(width,height,depth,3,0); restype I[9]; restype& Ipp = I[0]; restype& Icp = I[1]; restype& Inp = I[2]; restype& Ipc = I[3]; restype& Icc = I[4]; restype& Inc = I[5]; restype& Ipn = I[6]; restype& Icn = I[7]; restype& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; switch (scheme) { case 0: { for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,0,k)), (I[3] = I[4] = (*this)(0,y,0,k)), (I[6] = I[7] = (*this)(0,_n1y,0,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,0,k)), (I[5] = (*this)(_n1x,y,0,k)), (I[8] = (*this)(_n1x,_n1y,0,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { const restype ix = 0.5f*(Inc-Ipc), iy = 0.5f*(Icn-Icp); res(x,y,z,0)+=ix*ix; res(x,y,z,1)+=ix*iy; res(x,y,z,2)+=iy*iy; } } break; default: { for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,0,k)), (I[3] = I[4] = (*this)(0,y,0,k)), (I[6] = I[7] = (*this)(0,_n1y,0,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,0,k)), (I[5] = (*this)(_n1x,y,0,k)), (I[8] = (*this)(_n1x,_n1y,0,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { const restype ixf = Inc-Icc, ixb = Icc-Ipc, iyf = Icn-Icc, iyb = Icc-Icp; res(x,y,z,0) += 0.5f*(ixf*ixf+ixb*ixb); res(x,y,z,1) += 0.25f*(ixf*iyf+ixf*iyb+ixb*iyf+ixb*iyb); res(x,y,z,2) += 0.5f*(iyf*iyf+iyb*iyb); } } break; } return res; } CImg& structure_tensorXY(const int scheme=1) { return get_structure_tensorXY(scheme).transfer_to(*this); } CImg::type> get_structure_tensorXYZ(const int scheme=1) const { typedef typename cimg::superset::type restype; if (is_empty()) return CImg(); CImg res(width,height,depth,6,0); restype I[27]; restype& Ippp = I[0]; restype& Icpp = I[1]; restype& Inpp = I[2]; restype& Ipcp = I[3]; restype& Iccp = I[4]; restype& Incp = I[5]; restype& Ipnp = I[6]; restype& Icnp = I[7]; restype& Innp = I[8]; restype& Ippc = I[9]; restype& Icpc = I[10]; restype& Inpc = I[11]; restype& Ipcc = I[12]; restype& Iccc = I[13]; restype& Incc = I[14]; restype& Ipnc = I[15]; restype& Icnc = I[16]; restype& Innc = I[17]; restype& Ippn = I[18]; restype& Icpn = I[19]; restype& Inpn = I[20]; restype& Ipcn = I[21]; restype& Iccn = I[22]; restype& Incn = I[23]; restype& Ipnn = I[24]; restype& Icnn = I[25]; restype& Innn = I[26]; Ippp = Icpp = Inpp = Ipcp = Iccp = Incp = Ipnp = Icnp = Innp = Ippc = Icpc = Inpc = Ipcc = Iccc = Incc = Ipnc = Icnc = Innc = Ippn = Icpn = Inpn = Ipcn = Iccn = Incn = Ipnn = Icnn = Innn = 0; switch (scheme) { case 0: { for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,k)), (I[3] = I[4] = (*this)(0,y,_p1z,k)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,k)), (I[9] = I[10] = (*this)(0,_p1y,z,k)), (I[12] = I[13] = (*this)(0,y,z,k)), (I[15] = I[16] = (*this)(0,_n1y,z,k)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,k)), (I[21] = I[22] = (*this)(0,y,_n1z,k)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,k)), (I[5] = (*this)(_n1x,y,_p1z,k)), (I[8] = (*this)(_n1x,_n1y,_p1z,k)), (I[11] = (*this)(_n1x,_p1y,z,k)), (I[14] = (*this)(_n1x,y,z,k)), (I[17] = (*this)(_n1x,_n1y,z,k)), (I[20] = (*this)(_n1x,_p1y,_n1z,k)), (I[23] = (*this)(_n1x,y,_n1z,k)), (I[26] = (*this)(_n1x,_n1y,_n1z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) { const restype ix = 0.5f*(Incc-Ipcc), iy = 0.5f*(Icnc-Icpc), iz = 0.5f*(Iccn-Iccp); res(x,y,z,0)+=ix*ix; res(x,y,z,1)+=ix*iy; res(x,y,z,2)+=ix*iz; res(x,y,z,3)+=iy*iy; res(x,y,z,4)+=iy*iz; res(x,y,z,5)+=iz*iz; } } break; default: { for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,k)), (I[3] = I[4] = (*this)(0,y,_p1z,k)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,k)), (I[9] = I[10] = (*this)(0,_p1y,z,k)), (I[12] = I[13] = (*this)(0,y,z,k)), (I[15] = I[16] = (*this)(0,_n1y,z,k)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,k)), (I[21] = I[22] = (*this)(0,y,_n1z,k)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,k)), (I[5] = (*this)(_n1x,y,_p1z,k)), (I[8] = (*this)(_n1x,_n1y,_p1z,k)), (I[11] = (*this)(_n1x,_p1y,z,k)), (I[14] = (*this)(_n1x,y,z,k)), (I[17] = (*this)(_n1x,_n1y,z,k)), (I[20] = (*this)(_n1x,_p1y,_n1z,k)), (I[23] = (*this)(_n1x,y,_n1z,k)), (I[26] = (*this)(_n1x,_n1y,_n1z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) { const restype ixf = Incc-Iccc, ixb = Iccc-Ipcc, iyf = Icnc-Iccc, iyb = Iccc-Icpc, izf = Iccn-Iccc, izb = Iccc-Iccp; res(x,y,z,0) += 0.5f*(ixf*ixf + ixb*ixb); res(x,y,z,1) += 0.25f*(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb); res(x,y,z,2) += 0.25f*(ixf*izf + ixf*izb + ixb*izf + ixb*izb); res(x,y,z,3) += 0.5f*(iyf*iyf + iyb*iyb); res(x,y,z,4) += 0.25f*(iyf*izf + iyf*izb + iyb*izf + iyb*izb); res(x,y,z,5) += 0.5f*(izf*izf + izb*izb); } } break; } return res; } CImg& structure_tensorXYZ(const int scheme=1) { return get_structure_tensorXYZ(scheme).transfer_to(*this); } CImgList::type> get_hessianXY() { typedef typename cimg::superset::type ftype; if (is_empty()) return CImgList(3); CImgList res(3,width,height,depth,dim); ftype I[9]; ftype& Ipp = I[0]; ftype& Icp = I[1]; ftype& Inp = I[2]; ftype& Ipc = I[3]; ftype& Icc = I[4]; ftype& Inc = I[5]; ftype& Ipn = I[6]; ftype& Icn = I[7]; ftype& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,k)), (I[3] = I[4] = (*this)(0,y,z,k)), (I[6] = I[7] = (*this)(0,_n1y,z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,z,k)), (I[5] = (*this)(_n1x,y,z,k)), (I[8] = (*this)(_n1x,_n1y,z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { res[0](x,y,z,k) = Ipc + Inc - 2*Icc; res[1](x,y,z,k) = 0.25f*(Ipp + Inn - Ipn - Inp); res[2](x,y,z,k) = Icp + Icn - 2*Icc; } return res; } CImgList::type> get_hessianXYZ() { typedef typename cimg::superset::type ftype; if (is_empty()) return CImgList(6); CImgList res(6,width,height,depth,dim); ftype I[27]; ftype& Ippp = I[0]; ftype& Icpp = I[1]; ftype& Inpp = I[2]; ftype& Ipcp = I[3]; ftype& Iccp = I[4]; ftype& Incp = I[5]; ftype& Ipnp = I[6]; ftype& Icnp = I[7]; ftype& Innp = I[8]; ftype& Ippc = I[9]; ftype& Icpc = I[10]; ftype& Inpc = I[11]; ftype& Ipcc = I[12]; ftype& Iccc = I[13]; ftype& Incc = I[14]; ftype& Ipnc = I[15]; ftype& Icnc = I[16]; ftype& Innc = I[17]; ftype& Ippn = I[18]; ftype& Icpn = I[19]; ftype& Inpn = I[20]; ftype& Ipcn = I[21]; ftype& Iccn = I[22]; ftype& Incn = I[23]; ftype& Ipnn = I[24]; ftype& Icnn = I[25]; ftype& Innn = I[26]; Ippp = Icpp = Inpp = Ipcp = Iccp = Incp = Ipnp = Icnp = Innp = Ippc = Icpc = Inpc = Ipcc = Iccc = Incc = Ipnc = Icnc = Innc = Ippn = Icpn = Inpn = Ipcn = Iccn = Incn = Ipnn = Icnn = Innn = 0; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,k)), (I[3] = I[4] = (*this)(0,y,_p1z,k)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,k)), (I[9] = I[10] = (*this)(0,_p1y,z,k)), (I[12] = I[13] = (*this)(0,y,z,k)), (I[15] = I[16] = (*this)(0,_n1y,z,k)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,k)), (I[21] = I[22] = (*this)(0,y,_n1z,k)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,k)), (I[5] = (*this)(_n1x,y,_p1z,k)), (I[8] = (*this)(_n1x,_n1y,_p1z,k)), (I[11] = (*this)(_n1x,_p1y,z,k)), (I[14] = (*this)(_n1x,y,z,k)), (I[17] = (*this)(_n1x,_n1y,z,k)), (I[20] = (*this)(_n1x,_p1y,_n1z,k)), (I[23] = (*this)(_n1x,y,_n1z,k)), (I[26] = (*this)(_n1x,_n1y,_n1z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) { res[0](x,y,z,k) = Ipcc + Incc - 2*Iccc; res[1](x,y,z,k) = 0.25f*(Ippc + Innc - Ipnc - Inpc); res[2](x,y,z,k) = 0.25f*(Ipcp + Incn - Ipcn - Incp); res[3](x,y,z,k) = Icpc + Icnc - 2*Iccc; res[4](x,y,z,k) = 0.25f*(Icpp + Icnn - Icpn - Icnp); res[5](x,y,z,k) = Iccn + Iccp - 2*Iccc; } return res; } CImg::type> get_distance_function(const unsigned int nb_iter=100, const float band_size=0.0f, const float precision=0.5f) const { typedef typename cimg::superset::type ftype; return CImg(*this,false).distance_function(nb_iter,band_size,precision); } CImg& distance_function(const unsigned int nb_iter=100, const float band_size=0.0f, const float precision=0.5f) { typedef typename cimg::superset::type ftype; if (is_empty()) return *this; CImg veloc(*this); for (unsigned int iter=0; iter1) { ftype I[27]; ftype& Ippp = I[0]; ftype& Icpp = I[1]; ftype& Inpp = I[2]; ftype& Ipcp = I[3]; ftype& Iccp = I[4]; ftype& Incp = I[5]; ftype& Ipnp = I[6]; ftype& Icnp = I[7]; ftype& Innp = I[8]; ftype& Ippc = I[9]; ftype& Icpc = I[10]; ftype& Inpc = I[11]; ftype& Ipcc = I[12]; ftype& Iccc = I[13]; ftype& Incc = I[14]; ftype& Ipnc = I[15]; ftype& Icnc = I[16]; ftype& Innc = I[17]; ftype& Ippn = I[18]; ftype& Icpn = I[19]; ftype& Inpn = I[20]; ftype& Ipcn = I[21]; ftype& Iccn = I[22]; ftype& Incn = I[23]; ftype& Ipnn = I[24]; ftype& Icnn = I[25]; ftype& Innn = I[26]; Ippp = Icpp = Inpp = Ipcp = Iccp = Incp = Ipnp = Icnp = Innp = Ippc = Icpc = Inpc = Ipcc = Iccc = Incc = Ipnc = Icnc = Innc = Ippn = Icpn = Inpn = Ipcn = Iccn = Incn = Ipnn = Icnn = Innn = 0; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,k)), (I[3] = I[4] = (*this)(0,y,_p1z,k)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,k)), (I[9] = I[10] = (*this)(0,_p1y,z,k)), (I[12] = I[13] = (*this)(0,y,z,k)), (I[15] = I[16] = (*this)(0,_n1y,z,k)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,k)), (I[21] = I[22] = (*this)(0,y,_n1z,k)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,k)), (I[5] = (*this)(_n1x,y,_p1z,k)), (I[8] = (*this)(_n1x,_n1y,_p1z,k)), (I[11] = (*this)(_n1x,_p1y,z,k)), (I[14] = (*this)(_n1x,y,z,k)), (I[17] = (*this)(_n1x,_n1y,z,k)), (I[20] = (*this)(_n1x,_p1y,_n1z,k)), (I[23] = (*this)(_n1x,y,_n1z,k)), (I[26] = (*this)(_n1x,_n1y,_n1z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) if (band_size<=0 || cimg::abs(Iccc)0?Incc-Iccc:Iccc-Ipcc, iy = gy*sgn>0?Icnc-Iccc:Iccc-Icpc, iz = gz*sgn>0?Iccn-Iccc:Iccc-Iccp, ng = 1e-5f+(ftype)std::sqrt(gx*gx+gy*gy+gz*gz), ngx = gx/ng, ngy = gy/ng, ngz = gz/ng; veloc(x,y,z,k) = sgn*(ngx*ix+ngy*iy+ngz*iz-1); } } else { ftype I[9]; ftype& Ipp = I[0]; ftype& Icp = I[1]; ftype& Inp = I[2]; ftype& Ipc = I[3]; ftype& Icc = I[4]; ftype& Inc = I[5]; ftype& Ipn = I[6]; ftype& Icn = I[7]; ftype& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; for (int k = 0; k<(int)((*this).dim); ++k) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,0,k)), (I[3] = I[4] = (*this)(0,y,0,k)), (I[6] = I[7] = (*this)(0,_n1y,0,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,0,k)), (I[5] = (*this)(_n1x,y,0,k)), (I[8] = (*this)(_n1x,_n1y,0,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) if (band_size<=0 || cimg::abs(Icc)0?Inc-Icc:Icc-Ipc, iy = gy*sgn>0?Icn-Icc:Icc-Icp, ng = 1e-5f+(ftype)std::sqrt(gx*gx+gy*gy), ngx = gx/ng, ngy = gy/ng; veloc(x,y,k) = sgn*(ngx*ix+ngy*iy-1); } } float m, M = (float)veloc.maxmin(m), xdt = precision/(float)cimg::max(cimg::abs(m),cimg::abs(M)); *this+=(veloc*=xdt); } return *this; } template static CImg get_dijkstra(const tf& distance, const unsigned int nb_nodes, const unsigned int starting_node, const unsigned int ending_node, CImg& previous) { CImg dist(1,nb_nodes,1,1,cimg::type::max()); dist(starting_node) = 0; previous.assign(1,nb_nodes,1,1,(t)-1); previous(starting_node) = (t)starting_node; typedef typename cimg::last::type uitype; CImg Q(nb_nodes); for (int u = 0; u<(int)((Q).width); ++u) Q(u) = u; cimg::swap(Q(starting_node),Q(0)); unsigned int sizeQ = nb_nodes; while (sizeQ) { const unsigned int umin = Q(0); if (umin==ending_node) sizeQ = 0; else { const T dmin = dist(umin); const T infty = cimg::type::max(); for (unsigned int q=1; qdist(Q(left))) || (rightdist(Q(right)));) { if (right static CImg get_dijkstra(const tf& distance, const unsigned int nb_nodes, const unsigned int starting_node, const unsigned int ending_node=~0U) { typedef typename cimg::last::type uitype; CImg foo; return get_dijkstra(distance,nb_nodes,starting_node,ending_node,foo); } template CImg get_dijkstra(const unsigned int starting_node, const unsigned int ending_node, CImg& previous) const { if (width!=height || depth!=1 || dim!=1) throw CImgInstanceException("CImg<%s>::dijkstra() : Instance image (%u,%u,%u,%u,%p) is not a graph adjacency matrix", pixel_type(),width,height,depth,dim,data); return CImg::get_dijkstra(*this,width,starting_node,ending_node,previous); } template CImg& dijkstra(const unsigned int starting_node, const unsigned int ending_node, CImg& previous) { return get_dijkstra(starting_node,ending_node,previous).transfer_to(*this); } CImg::type> get_dijkstra(const unsigned int starting_node, const unsigned int ending_node=~0U) const { typedef typename cimg::last::type uitype; CImg foo; return get_dijkstra(starting_node,ending_node,foo); } CImg& dijkstra(const unsigned int starting_node, const unsigned int ending_node=~0U) { return get_dijkstra(starting_node,ending_node).transfer_to(*this); } struct _marching_squares_func { const CImg& ref; _marching_squares_func(const CImg& pref):ref(pref) {} float operator()(const float x, const float y) const { return (float)ref((int)x,(int)y); } }; struct _marching_cubes_func { const CImg& ref; _marching_cubes_func(const CImg& pref):ref(pref) {} float operator()(const float x, const float y, const float z) const { return (float)ref((int)x,(int)y,(int)z); } }; struct _marching_squares_func_float { const CImg& ref; _marching_squares_func_float(const CImg& pref):ref(pref) {} float operator()(const float x, const float y) const { return (float)ref.linear_pix2d(x,y); } }; struct _marching_cubes_func_float { const CImg& ref; _marching_cubes_func_float(const CImg& pref):ref(pref) {} float operator()(const float x, const float y, const float z) const { return (float)ref.linear_pix3d(x,y,z); } }; template const CImg& marching_squares(const float isovalue, CImgList& points, CImgList& primitives) const { if (height<=1 || depth>1 || dim>1) throw CImgInstanceException("CImg<%s>::marching_squares() : Instance image (%u,%u,%u,%u,%p) is not a 2D scalar image.", pixel_type(),width,height,depth,dim,data); const _marching_squares_func func(*this); cimg::marching_squares(func,isovalue,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,1.0f,1.0f,points,primitives); return *this; } template const CImg& marching_squares(const float isovalue, const float resx, const float resy, CImgList& points, CImgList& primitives) const { if (height<=1 || depth>1 || dim>1) throw CImgInstanceException("CImg<%s>::marching_squares() : Instance image (%u,%u,%u,%u,%p) is not a 2D scalar image.", pixel_type(),width,height,depth,dim,data); const _marching_squares_func_float func(*this); cimg::marching_squares(func,isovalue,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,resx,resy,points,primitives); return *this; } template const CImg& marching_cubes(const float isovalue, CImgList& points, CImgList& primitives, const bool invert_faces = false) const { if (depth<=1 || dim>1) throw CImgInstanceException("CImg<%s>::marching_cubes() : Instance image (%u,%u,%u,%u,%p) is not a 3D scalar image.", pixel_type(),width,height,depth,dim,data); const _marching_cubes_func func(*this); cimg::marching_cubes(func,isovalue,0.0f,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,dimz()-1.0f, 1.0f,1.0f,1.0f,points,primitives,invert_faces); return *this; } template const CImg& marching_cubes(const float isovalue, const float resx, const float resy, const float resz, CImgList& points, CImgList& primitives, const bool invert_faces = false) const { if (depth<=1 || dim>1) throw CImgInstanceException("CImg<%s>::marching_cubes() : Instance image (%u,%u,%u,%u,%p) is not a 3D scalar image.", pixel_type(),width,height,depth,dim,data); const _marching_cubes_func_float func(*this); cimg::marching_cubes(func,isovalue,0.0f,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,dimz()-1.0f, resx,resy,resz,points,primitives,invert_faces); return *this; } static CImg get_default_LUT8() { static CImg palette; if (!palette) { palette.assign(1,256,1,3); for (unsigned int index=0, r=16; r<256; r+=32) for (unsigned int g=16; g<256; g+=32) for (unsigned int b=32; b<256; b+=64) { palette(0,index,0) = (T)r; palette(0,index,1) = (T)g; palette(0,index++,2) = (T)b; } } return palette; } static CImg get_rainbow_LUT8() { static CImg palette; if (!palette) { typedef typename cimg::superset::type itype; CImg tmp(1,256,1,3,255); tmp.get_shared_channel(0).sequence(0,359); tmp.HSVtoRGB(); palette = tmp; } return palette; } static CImg get_cluster_LUT8() { static const unsigned char pal[] = { 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 23,168,19,50,240,244,185,0,1,144,10,168,31,82,1,13 }; static const CImg palette(pal,256,1,1,3,false); return palette; } template CImg get_RGBtoLUT(const CImg& palette, const bool dithering=true, const bool indexing=false) const { if (is_empty()) return CImg(); if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoLUT() : Input image dimension is dim=%u, " "should be a (R,G,B) image.",pixel_type(),dim); if (palette.data && palette.dim!=3) throw CImgArgumentException("CImg<%s>::RGBtoLUT() : Given palette dimension is dim=%u, " "should be a (R,G,B) palette",pixel_type(),palette.dim); CImg res(width,height,depth,indexing?1:3), pal = palette.data?palette:CImg::get_default_LUT8(); float *line1 = new float[3*width], *line2 = new float[3*width], *pline1 = line1, *pline2 = line2; for (int z = 0; z<(int)((*this).depth); ++z) { float *ptr = pline2; for (int x = 0; x<(int)((*this).width); ++x) { *(ptr++) = (*this)(x,0,z,0); *(ptr++) = (*this)(x,0,z,1); *(ptr++) = (*this)(x,0,z,2); } for (int y = 0; y<(int)((*this).height); ++y) { cimg::swap(pline1,pline2); if (y255?255:R); G = G<0?0:(G>255?255:G); B = B<0?0:(B>255?255:B); int best_index = 0; t Rbest = 0, Gbest = 0, Bbest = 0; if (palette.data) { float min = cimg::type::max(); for (int off = 0; off<(int)((palette).width); ++off) { const t Rp = palette(off,0), Gp = palette(off,1), Bp = palette(off,2); const float error = (float)((Rp-R)*(Rp-R) + (Gp-G)*(Gp-G) + (Bp-B)*(Bp-B)); if (error>3) | ((unsigned char)Bbest>>6); } if (indexing) res(x,y,z) = best_index; else { res(x,y,z,0) = Rbest; res(x,y,z,1) = Gbest; res(x,y,z,2) = Bbest; } if (dithering) { const float dR = (float)(R-Rbest), dG = (float)(G-Gbest), dB = (float)(B-Bbest); if (x0) { *(--ptr2)+= dB*3/16; *(--ptr2)+= dG*3/16; *(--ptr2)+= dR*3/16; ptr2+=3; } if (x& RGBtoLUT(const CImg& palette, const bool dithering=true, const bool indexing=false) { return get_RGBtoLUT(palette,dithering,indexing).transfer_to(*this); } CImg get_RGBtoLUT(const bool dithering=true, const bool indexing=false) const { CImg foo; return get_RGBtoLUT(foo,dithering,indexing); } CImg& RGBtoLUT(const bool dithering=true, const bool indexing=false) { CImg foo; return get_RGBtoLUT(foo,dithering,indexing).transfer_to(*this); } template CImg get_LUTtoRGB(const CImg& palette) const { if (is_empty()) return CImg(); if (dim!=1) throw CImgInstanceException("CImg<%s>::LUTtoRGB() : Input image dimension is dim=%u, " "should be a LUT image",pixel_type(),dim); if (palette.data && palette.dim!=3) throw CImgArgumentException("CImg<%s>::LUTtoRGB() : Given palette dimension is dim=%u, " "should be a (R,G,B) palette",pixel_type(),palette.dim); CImg res(width,height,depth,3); CImg pal = palette.data?palette:CImg::get_default_LUT8(); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const unsigned int index = (unsigned int)(*this)(x,y,z); res(x,y,z,0) = pal(index,0); res(x,y,z,1) = pal(index,1); res(x,y,z,2) = pal(index,2); } return res; } CImg& LUTtoRGB(const CImg& palette) { return get_LUTtoRGB(palette).transfer_to(*this); } CImg get_LUTtoRGB() const { CImg foo; return get_LUTtoRGB(foo); } CImg& LUTtoRGB() { CImg foo; return get_LUTtoRGB(foo).transfer_to(*this); } CImg::type> get_RGBtoHSV() const { typedef typename cimg::superset::type ftype; return CImg(*this).RGBtoHSV(); } CImg& RGBtoHSV() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoHSV() : Input image dimension is dim=%u, " "should be a (R,G,B) image.",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const float R = (float)((*this)(x,y,z,0)), G = (float)((*this)(x,y,z,1)), B = (float)((*this)(x,y,z,2)), nR = (R<0?0:(R>255?255:R))/255.0f, nG = (G<0?0:(G>255?255:G))/255.0f, nB = (B<0?0:(B>255?255:B))/255.0f, m = cimg::min(nR,nG,nB), M = cimg::max(nR,nG,nB); float H = 0, S = 0; if (M!=m) { const float f = (nR==m)?(nG-nB):((nG==m)?(nB-nR):(nR-nG)), i = (nR==m)?3.0f:((nG==m)?5.0f:1.0f); H = (i-f/(M-m)); if (H>=6.0f) H-=6.0f; H*=60; S = (M-m)/M; } (*this)(x,y,z,0) = (T)H; (*this)(x,y,z,1) = (T)S; (*this)(x,y,z,2) = (T)M; } } return *this; } CImg get_HSVtoRGB() const { return (+*this).HSVtoRGB(); } CImg& HSVtoRGB() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::HSVtoRGB() : Input image dimension is dim=%u, " "should be a (H,S,V) image",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { float H = (float)((*this)(x,y,z,0)), S = (float)((*this)(x,y,z,1)), V = (float)((*this)(x,y,z,2)); float R = 0, G = 0, B = 0; if (H==0 && S==0) R = G = B = V; else { H/=60.0f; const int i = (int)std::floor(H); const float f = (i&1)?(H-i):(1.0f-H+i), m = V*(1.0f-S), n = V*(1.0f-S*f); switch(i) { case 6: case 0: R = V; G = n; B = m; break; case 1: R = n; G = V; B = m; break; case 2: R = m; G = V; B = n; break; case 3: R = m; G = n; B = V; break; case 4: R = n; G = m; B = V; break; case 5: R = V; G = m; B = n; break; } } R*=255; G*=255; B*=255; (*this)(x,y,z,0) = (T)(R<0?0:(R>255?255:R)); (*this)(x,y,z,1) = (T)(G<0?0:(G>255?255:G)); (*this)(x,y,z,2) = (T)(B<0?0:(B>255?255:B)); } } return *this; } CImg::type> get_RGBtoHSL() const { typedef typename cimg::superset::type ftype; return CImg(*this).RGBtoHSL(); } CImg& RGBtoHSL() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoHSL() : Input image dimension is dim=%u, " "should be a (R,G,B) image.",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const float R = (float)((*this)(x,y,z,0)), G = (float)((*this)(x,y,z,1)), B = (float)((*this)(x,y,z,2)), nR = (R<0?0:(R>255?255:R))/255.0f, nG = (G<0?0:(G>255?255:G))/255.0f, nB = (B<0?0:(B>255?255:B))/255.0f, m = cimg::min(nR,nG,nB), M = cimg::max(nR,nG,nB), L = 0.5f*(m+M); float H = 0, S = 0; if (M==m) H = S = 0; else { const float f = (nR==m)?(nG-nB):((nG==m)?(nB-nR):(nR-nG)), i = (nR==m)?3.0f:((nG==m)?5.0f:1.0f); H = (i-f/(M-m)); if (H>=6.0f) H-=6.0f; H*=60; S = (L<=0.5f)?((M-m)/(M+m)):((M-m)/(2-M-m)); } (*this)(x,y,z,0) = (T)H; (*this)(x,y,z,1) = (T)S; (*this)(x,y,z,2) = (T)L; } } return *this; } CImg get_HSLtoRGB() const { return (+*this).HSLtoRGB(); } CImg& HSLtoRGB() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::HSLtoRGB() : Input image dimension is dim=%u, " "should be a (H,S,V) image",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { float H = (float)((*this)(x,y,z,0)), S = (float)((*this)(x,y,z,1)), L = (float)((*this)(x,y,z,2)); const float q = L<0.5f?L*(1+S):(L+S-L*S), p = 2*L-q, h = H/360; float tr = h+1.0f/3, tg = h, tb = h-1.0f/3, ntr = tr<0?tr+1:(tr>1?tr-1:tr), ntg = tg<0?tg+1:(tg>1?tg-1:tg), ntb = tb<0?tb+1:(tb>1?tb-1:tb), R = ntr<1.0f/6?p+(q-p)*6*ntr:(ntr<0.5f?q:(ntr<2.0f/3?p+(q-p)*6*(2.0f/3-ntr):p)), G = ntg<1.0f/6?p+(q-p)*6*ntg:(ntg<0.5f?q:(ntg<2.0f/3?p+(q-p)*6*(2.0f/3-ntg):p)), B = ntb<1.0f/6?p+(q-p)*6*ntb:(ntb<0.5f?q:(ntb<2.0f/3?p+(q-p)*6*(2.0f/3-ntb):p)); R*=255; G*=255; B*=255; (*this)(x,y,z,0) = (T)(R<0?0:(R>255?255:R)); (*this)(x,y,z,1) = (T)(G<0?0:(G>255?255:G)); (*this)(x,y,z,2) = (T)(B<0?0:(B>255?255:B)); } } return *this; } CImg::type> get_RGBtoHSI() const { typedef typename cimg::superset::type ftype; return CImg(*this).RGBtoHSI(); } CImg& RGBtoHSI() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoHSI() : Input image dimension is dim=%u, " "should be a (R,G,B) image.",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const float R = (float)((*this)(x,y,z,0)), G = (float)((*this)(x,y,z,1)), B = (float)((*this)(x,y,z,2)), nR = (R<0?0:(R>255?255:R))/255.0f, nG = (G<0?0:(G>255?255:G))/255.0f, nB = (B<0?0:(B>255?255:B))/255.0f, m = cimg::min(nR,nG,nB), theta = std::acos(0.5f*((nR-nG)+(nR-nB))/std::sqrt(std::pow(nR-nG,2)+(nR-nB)*(nG-nB)))*180/cimg::valuePI, sum = nR + nG + nB; float H = 0, S = 0, I = 0; if (theta>0) H = (nB<=nG)?theta:360-theta; if (sum>0) S = 1-3/sum*m; I = sum/3; (*this)(x,y,z,0) = (T)H; (*this)(x,y,z,1) = (T)S; (*this)(x,y,z,2) = (T)I; } } return *this; } CImg get_HSItoRGB() const { return (+*this).HSItoRGB(); } CImg& HSItoRGB() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::HSItoRGB() : Input image dimension is dim=%u, " "should be a (H,S,I) image",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { float H = (float)((*this)(x,y,z,0)), S = (float)((*this)(x,y,z,1)), I = (float)((*this)(x,y,z,2)); float R = 0, G = 0, B = 0, a = I*(1-S); if (H<120) { B = a; R = I*(1+S*std::cos(H*cimg::valuePI/180)/std::cos((60-H)*cimg::valuePI/180)); G = 3*I-(R+B); } else if (H<240) { H-=120; R = a; G = I*(1+S*std::cos(H*cimg::valuePI/180)/std::cos((60-H)*cimg::valuePI/180)); B = 3*I-(R+G); } else { H-=240; G = a; B = I*(1+S*std::cos(H*cimg::valuePI/180)/std::cos((60-H)*cimg::valuePI/180)); R = 3*I-(G+B); } R*=255; G*=255; B*=255; (*this)(x,y,z,0) = (T)(R<0?0:(R>255?255:R)); (*this)(x,y,z,1) = (T)(G<0?0:(G>255?255:G)); (*this)(x,y,z,2) = (T)(B<0?0:(B>255?255:B)); } } return *this; } CImg get_RGBtoYCbCr() const { return (+*this).RGBtoYCbCr(); } CImg& RGBtoYCbCr() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoYCbCr() : Input image dimension is dim=%u, " "should be a (R,G,B) image (dim=3)",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const int R = (int)((*this)(x,y,z,0)), G = (int)((*this)(x,y,z,1)), B = (int)((*this)(x,y,z,2)); const int Y = ((66*R+129*G+25*B+128)>>8) + 16, Cb = ((-38*R-74*G+112*B+128)>>8) + 128, Cr = ((112*R-94*G-18*B+128)>>8) + 128; (*this)(x,y,z,0) = (T)(Y<0?0:(Y>255?255:Y)); (*this)(x,y,z,1) = (T)(Cb<0?0:(Cb>255?255:Cb)); (*this)(x,y,z,2) = (T)(Cr<0?0:(Cr>255?255:Cr)); } } return *this; } CImg get_YCbCrtoRGB() const { return (+*this).YCbCrtoRGB(); } CImg& YCbCrtoRGB() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::YCbCrtoRGB() : Input image dimension is dim=%u, " "should be a (Y,Cb,Cr)_8 image (dim=3)",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const int Y = (int)((*this)(x, y, z, 0)-16), Cb = (int)((*this)(x, y, z, 1)-128), Cr = (int)((*this)(x, y, z, 2)-128); const int R = ((298*Y + 409*Cr + 128) >> 8 ), G = ((298*Y - 100*Cb - 208*Cr + 128) >> 8 ), B = ((298*Y + 516*Cb + 128) >> 8 ); (*this)(x,y,z,0) = (T)(R<0?0:(R>255?255:R)); (*this)(x,y,z,1) = (T)(G<0?0:(G>255?255:G)); (*this)(x,y,z,2) = (T)(B<0?0:(B>255?255:B)); } } return *this; } CImg::type> get_RGBtoYUV() const { typedef typename cimg::superset::type restype; return CImg(*this,false).RGBtoYUV(); } CImg& RGBtoYUV() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoYUV() : Input image dimension is dim=%u, " "should be a (R,G,B) image (dim=3)",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const float R = (*this)(x,y,z,0)/255.0f, G = (*this)(x,y,z,1)/255.0f, B = (*this)(x,y,z,2)/255.0f, Y = (T)(0.299*R + 0.587*G + 0.114*B); (*this)(x,y,z,0) = (T)Y; (*this)(x,y,z,1) = (T)(0.492*(B-Y)); (*this)(x,y,z,2) = (T)(0.877*(R-Y)); } } return *this; } CImg get_YUVtoRGB() const { return (+*this).YUVtoRGB(); } CImg& YUVtoRGB() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::YUVtoRGB() : Input image dimension is dim=%u, " "should be a (Y,U,V) image (dim=3)",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const T Y = (*this)(x,y,z,0), U = (*this)(x,y,z,1), V = (*this)(x,y,z,2); (*this)(x,y,z,0) = (T)((Y + 1.140*V)*255.0f); (*this)(x,y,z,1) = (T)((Y - 0.395*U - 0.581*V)*255.0f); (*this)(x,y,z,2) = (T)((Y + 2.032*U)*255.0f); } } return *this; } CImg::type> get_RGBtoXYZ() const { typedef typename cimg::superset::type restype; return CImg(*this,false).RGBtoXYZ(); } CImg& RGBtoXYZ() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoXYZ() : Input image dimension is dim=%u, " "should be a (R,G,B) image (dim=3)",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const float R = (float)((*this)(x,y,z,0)/255.0f), G = (float)((*this)(x,y,z,1)/255.0f), B = (float)((*this)(x,y,z,2)/255.0f); (*this)(x,y,z,0) = (T)(0.412453*R + 0.357580*G + 0.180423*B); (*this)(x,y,z,1) = (T)(0.212671*R + 0.715160*G + 0.072169*B); (*this)(x,y,z,2) = (T)(0.019334*R + 0.119193*G + 0.950227*B); } } return *this; } CImg get_XYZtoRGB() const { return (+*this).XYZtoRGB(); } CImg& XYZtoRGB() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoRGB() : Input image dimension is dim=%u, " "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const float X = (float)(255.0f*(*this)(x,y,z,0)), Y = (float)(255.0f*(*this)(x,y,z,1)), Z = (float)(255.0f*(*this)(x,y,z,2)); (*this)(x,y,z,0) = (T)(3.240479*X - 1.537150*Y - 0.498535*Z); (*this)(x,y,z,1) = (T)(-0.969256*X + 1.875992*Y + 0.041556*Z); (*this)(x,y,z,2) = (T)(0.055648*X - 0.204043*Y + 1.057311*Z); } } return *this; } CImg get_XYZtoLab() const { return (+*this).XYZtoLab(); } CImg& XYZtoLab() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoLab() : Input image dimension is dim=%u, " "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim); const double Xn = 0.412453 + 0.357580 + 0.180423, Yn = 0.212671 + 0.715160 + 0.072169, Zn = 0.019334 + 0.119193 + 0.950227; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const T X = (*this)(x,y,z,0), Y = (*this)(x,y,z,1), Z = (*this)(x,y,z,2); const double XXn = X/Xn, YYn = Y/Yn, ZZn = Z/Zn, fX = ((XXn)>=0.008856?(std::pow(XXn,1/3.0)):(7.787*(XXn)+16.0/116.0)), fY = ((YYn)>=0.008856?(std::pow(YYn,1/3.0)):(7.787*(YYn)+16.0/116.0)), fZ = ((ZZn)>=0.008856?(std::pow(ZZn,1/3.0)):(7.787*(ZZn)+16.0/116.0)); (*this)(x,y,z,0) = (T)(116*fY-16); (*this)(x,y,z,1) = (T)(500*(fX-fY)); (*this)(x,y,z,2) = (T)(200*(fY-fZ)); } } return *this; } CImg get_LabtoXYZ() const { return (+*this).LabtoXYZ(); } CImg& LabtoXYZ() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::LabtoXYZ() : Input image dimension is dim=%u, " "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim); const double Xn = 0.412453 + 0.357580 + 0.180423, Yn = 0.212671 + 0.715160 + 0.072169, Zn = 0.019334 + 0.119193 + 0.950227; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const T L = (*this)(x,y,z,0), a = (*this)(x,y,z,1), b = (*this)(x,y,z,2); const double cY = (L+16)/116.0, Y = Yn*((cY)>=0.206893?((cY)*(cY)*(cY)):(((cY)-16.0/116.0)/7.787)), pY = std::pow(Y/Yn,1.0/3), cX = a/500+pY, X = Xn*cX*cX*cX, cZ = pY-b/200, Z = Zn*cZ*cZ*cZ; (*this)(x,y,z,0) = (T)(X); (*this)(x,y,z,1) = (T)(Y); (*this)(x,y,z,2) = (T)(Z); } } return *this; } CImg get_XYZtoxyY() const { return (+*this).XYZtoxyY(); } CImg& XYZtoxyY() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoxyY() : Input image dimension is dim=%u, " "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { 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; (*this)(x,y,z,0) = X/nsum; (*this)(x,y,z,1) = Y/nsum; (*this)(x,y,z,2) = Y; } } return *this; } CImg get_xyYtoXYZ() const { return (+*this).xyYtoXYZ(); } CImg& xyYtoXYZ() { if (!is_empty()) { if (dim!=3) throw CImgInstanceException("CImg<%s>::xyYtoXYZ() : Input image dimension is dim=%u, " "should be a (x,y,Y) image (dim=3)",pixel_type(),dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { 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; (*this)(x,y,z,0) = (T)(px*Y/ny); (*this)(x,y,z,1) = Y; (*this)(x,y,z,2) = (T)((1-px-py)*Y/ny); } } return *this; } CImg get_RGBtoLab() const { return (+*this).RGBtoLab(); } CImg& RGBtoLab() { return RGBtoXYZ().XYZtoLab(); } CImg get_LabtoRGB() const { return (+*this).LabtoRGB(); } CImg& LabtoRGB() { return LabtoXYZ().XYZtoRGB(); } CImg get_RGBtoxyY() const { return (+*this).RGBtoxyY(); } CImg& RGBtoxyY() { return RGBtoXYZ().XYZtoxyY(); } CImg get_xyYtoRGB() const { return (+*this).xyYtoRGB(); } CImg& xyYtoRGB() { return xyYtoXYZ().XYZtoRGB(); } CImg get_RGBtoBayer() const { if (is_empty()) return *this; if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoBayer() : Input image dimension is dim=%u, " "should be a (R,G,B) image (dim=3)",pixel_type(),dim); CImg res(width,height,depth,1); const T *pR = ptr(0,0,0,0), *pG = ptr(0,0,0,1), *pB = ptr(0,0,0,2); T *ptrd = res.data; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { if (y%2) { if (x%2) *(ptrd++) = *pB; else *(ptrd++) = *pG; } else { if (x%2) *(ptrd++) = *pG; else *(ptrd++) = *pR; } ++pR; ++pG; ++pB; } return res; } CImg& RGBtoBayer() { return get_RGBtoBayer().transfer_to(*this); } CImg get_BayertoRGB(const unsigned int interpolation_type=3) const { if (is_empty()) return *this; if (dim!=1) throw CImgInstanceException("CImg<%s>::BayertoRGB() : Input image dimension is dim=%u, " "should be a Bayer image (dim=1)",pixel_type(),dim); CImg res(width,height,depth,3); T I[9]; T& Ipp = I[0]; T& Icp = I[1]; T& Inp = I[2]; T& Ipc = I[3]; T& Icc = I[4]; T& Inc = I[5]; T& Ipn = I[6]; T& Icn = I[7]; T& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; T *pR = res.ptr(0,0,0,0), *pG = res.ptr(0,0,0,1), *pB = res.ptr(0,0,0,2); switch(interpolation_type) { case 3: { T R[9]; T& Rpp = R[0]; T& Rcp = R[1]; T& Rnp = R[2]; T& Rpc = R[3]; T& Rcc = R[4]; T& Rnc = R[5]; T& Rpn = R[6]; T& Rcn = R[7]; T& Rnn = R[8]; Rpp = Rcp = Rnp = Rpc = Rcc = Rnc = Rpn = Rcn = Rnn = 0; T G[9]; T& Gpp = G[0]; T& Gcp = G[1]; T& Gnp = G[2]; T& Gpc = G[3]; T& Gcc = G[4]; T& Gnc = G[5]; T& Gpn = G[6]; T& Gcn = G[7]; T& Gnn = G[8]; Gpp = Gcp = Gnp = Gpc = Gcc = Gnc = Gpn = Gcn = Gnn = 0; T B[9]; T& Bpp = B[0]; T& Bcp = B[1]; T& Bnp = B[2]; T& Bpc = B[3]; T& Bcc = B[4]; T& Bnc = B[5]; T& Bpn = B[6]; T& Bcn = B[7]; T& Bnn = B[8]; Bpp = Bcp = Bnp = Bpc = Bcc = Bnc = Bpn = Bcn = Bnn = 0; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x& BayertoRGB(const unsigned int interpolation_type=3) { return get_BayertoRGB(interpolation_type).transfer_to(*this); } template CImg& _draw_scanline(const int x0, const int x1, const int y, const tc *const color, const float opacity=1.0f, const float brightness=1.0f, const bool init=false) { static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); static float nopacity = 0, copacity = 0; static unsigned int whz = 0; static const tc *col = 0; if (init) { nopacity = cimg::abs(opacity); copacity = 1.0f - cimg::max(opacity,0.0f); whz = width*height*depth; } else { const int nx0 = x0>0?x0:0, nx1 = x1=0) { col = color; const unsigned int off = whz-dx-1; T *ptrd = ptr(nx0,y); if (opacity>=1) { if (brightness==1) { if (sizeof(T)!=1) for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)*(col++); for (int x=dx; x>=0; --x) *(ptrd++) = val; ptrd+=off; } else for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)*(col++); std::memset(ptrd,(int)val,dx+1); ptrd+=whz; } } else if (brightness<1) { if (sizeof(T)!=1) for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)(*(col++)*brightness); for (int x=dx; x>=0; --x) *(ptrd++) = val; ptrd+=off; } else for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)(*(col++)*brightness); std::memset(ptrd,(int)val,dx+1); ptrd+=whz; } } else { if (sizeof(T)!=1) for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)((2-brightness)**(col++) + (brightness-1)*maxval); for (int x=dx; x>=0; --x) *(ptrd++) = val; ptrd+=off; } else for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)((2-brightness)**(col++) + (brightness-1)*maxval); std::memset(ptrd,(int)val,dx+1); ptrd+=whz; } } } else { if (brightness==1) { for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)*(col++); for (int x=dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; } ptrd+=off; } } else if (brightness<=1) { for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)(*(col++)*brightness); for (int x=dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; } ptrd+=off; } } else { for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)((2-brightness)**(col++) + (brightness-1)*maxval); for (int x=dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; } ptrd+=off; } } } } } return *this; } template CImg& _draw_scanline(const tc *const color, const float opacity=1.0f) { return _draw_scanline(0,0,0,color,opacity,0,true); } template CImg& draw_point(const int x0, const int y0, const tc *const color, const float opacity=1.0f) { return draw_point(x0,y0,0,color,opacity); } template CImg& draw_point(const int x0, const int y0, const CImg& color, const float opacity=1.0f) { return draw_point(x0,y0,color.data,opacity); } template CImg& draw_point(const int x0, const int y0, const int z0, const tc *const color, const float opacity=1.0f) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_point() : Specified color is (null)",pixel_type()); if (x0>=0 && y0>=0 && z0>=0 && x0=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } } } return *this; } template CImg& draw_point(const int x0, const int y0, const int z0, const CImg& color, const float opacity=1.0f) { return draw_point(x0,y0,z0,color.data,opacity); } template CImg& _draw_point(const t& points, const tc *const color, const float opacity, const unsigned int W, const unsigned int H) { if (points && W && H>1) { if (H==2) for (unsigned int i=0; i CImg& draw_point(const CImgList& points, const tc *const color, const float opacity=1.0f) { unsigned int H = ~0U; for (unsigned int p=0; p<(points).size; ++p) H = cimg::min(H,(unsigned int)(points[p].size())); return _draw_point(points,color,opacity,points.size,H); } template CImg& draw_point(const CImgList& points, const CImg& color, const float opacity=1.0f) { return draw_point(points,color.data,opacity); } template CImg& draw_point(const CImg& points, const tc *const color, const float opacity=1.0f) { return _draw_point(points,color,opacity,points.width,points.height); } template CImg& draw_point(const CImg& points, const CImg& color, const float opacity=1.0f) { return draw_point(points,color.data,opacity); } template CImg& draw_line(const int x0, const int y0, const int x1, const int y1, const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_line() : Specified color is (null)",pixel_type()); static unsigned int hatch = ~0U-(~0U>>1); if (init_hatch) hatch = ~0U-(~0U>>1); const tc* col = color; const bool xdir = x0=dimx()) return *this; if (xleft<0) { yleft-=xleft*(yright-yleft)/(xright-xleft); xleft = 0; } if (xright>=dimx()) { yright-=(xright-dimx())*(yright-yleft)/(xright-xleft); xright = dimx()-1; } if (ydown<0 || yup>=dimy()) return *this; if (yup<0) { xup-=yup*(xdown-xup)/(ydown-yup); yup = 0; } if (ydown>=dimy()) { xdown-=(ydown-dimy())*(xdown-xup)/(ydown-yup); ydown = dimy()-1; } T *ptrd0 = ptr(nx0,ny0,0,0); int dx = xright-xleft, dy = ydown-yup; const bool steep = dy>dx; if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy); const int offx = (nx0=1) { if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; if (pattern&hatch) { for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=wh; } col-=dim; } hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1); ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } else for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=wh; } col-=dim; ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } } else { const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f); if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; if (pattern&hatch) { for (int k = 0; k<(int)((*this).dim); ++k) { const tc& c = *(col++); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } col-=dim; } hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1); ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } else for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; for (int k = 0; k<(int)((*this).dim); ++k) { const tc& c = *(col++); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } col-=dim; ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } } } return *this; } template CImg& draw_line(const int x0, const int y0, const int x1, const int y1, const CImg& color, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_line(x0,y0,x1,y1,color.data,opacity,pattern,init_hatch); } template CImg& draw_line(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1, const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_line() : Specified color is (null)",pixel_type()); static unsigned int hatch = ~0U-(~0U>>1); if (init_hatch) hatch = ~0U-(~0U>>1); const tc *col = color; int nx0 = x0, ny0 = y0, nz0 = z0, nx1 = x1, ny1 = y1, nz1 = z1; if (nx0>nx1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1); if (nx1<0 || nx0>=dimx()) return *this; if (nx0<0) { const int D=1+nx1-nx0; ny0-=nx0*(1+ny1-ny0)/D; nz0-=nx0*(1+nz1-nz0)/D; nx0 = 0; } 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; } if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1); if (ny1<0 || ny0>=dimy()) return *this; if (ny0<0) { const int D=1+ny1-ny0; nx0-=ny0*(1+nx1-nx0)/D; nz0-=ny0*(1+nz1-nz0)/D; ny0 = 0; } 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; } if (nz0>nz1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1); if (nz1<0 || nz0>=dimz()) return *this; if (nz0<0) { const int D=1+nz1-nz0; nx0-=nz0*(1+nx1-nx0)/D; ny0-=nz0*(1+ny1-ny0)/D; nz0 = 0; } 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; } const unsigned int dmax = cimg::max(cimg::abs(nx1-nx0),cimg::abs(ny1-ny0),nz1-nz0), whz = width*height*depth; const float px = (nx1-nx0)/(float)dmax, py = (ny1-ny0)/(float)dmax, pz = (nz1-nz0)/(float)dmax; float x = (float)nx0, y = (float)ny0, z = (float)nz0; if (opacity>=1) for (unsigned int t=0; t<=dmax; ++t) { if (!(~pattern) || (~pattern && pattern&hatch)) { T* ptrd = ptr((unsigned int)x,(unsigned int)y,(unsigned int)z,0); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } col-=dim; } x+=px; y+=py; z+=pz; if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1)); } else { const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); for (unsigned int t=0; t<=dmax; ++t) { if (!(~pattern) || (~pattern && pattern&hatch)) { T* ptrd = ptr((unsigned int)x,(unsigned int)y,(unsigned int)z,0); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } col-=dim; } x+=px; y+=py; z+=pz; if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1)); } } } return *this; } template CImg& draw_line(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1, const CImg& color, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_line(x0,y0,z0,x1,y1,z1,color.data,opacity,pattern,init_hatch); } template CImg& draw_line(const int x0, const int y0, const int x1, const int y1, const CImg& texture, const int tx0, const int ty0, const int tx1, const int ty1, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { if (!is_empty()) { if (!texture || texture.dim::draw_line() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.", pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data); if (is_overlapping(texture)) return draw_line(x0,y0,x1,y1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch); static unsigned int hatch = ~0U-(~0U>>1); if (init_hatch) hatch = ~0U-(~0U>>1); const bool xdir = x0=dimx()) return *this; if (xleft<0) { const int D = xright-xleft; yleft-=xleft*(yright-yleft)/D; txleft-=xleft*(txright-txleft)/D; tyleft-=xleft*(tyright-tyleft)/D; xleft = 0; } if (xright>=dimx()) { const int d = xright-dimx(), D = xright-xleft; yright-=d*(yright-yleft)/D; txright-=d*(txright-txleft)/D; tyright-=d*(tyright-tyleft)/D; xright = dimx()-1; } if (ydown<0 || yup>=dimy()) return *this; if (yup<0) { const int D = ydown-yup; xup-=yup*(xdown-xup)/D; txup-=yup*(txdown-txup)/D; tyup-=yup*(tydown-tyup)/D; yup = 0; } if (ydown>=dimy()) { const int d = ydown-dimy(), D = ydown-yup; xdown-=d*(xdown-xup)/D; txdown-=d*(txdown-txup)/D; tydown-=d*(tydown-tyup)/D; ydown = dimy()-1; } T *ptrd0 = ptr(nx0,ny0,0,0); int dx = xright-xleft, dy = ydown-yup; const bool steep = dy>dx; if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy); const int offx = (nx00?dx:1; if (opacity>=1) { if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; if (pattern&hatch) { const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx; for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = texture(tx,ty,0,k); ptrd+=wh; } } hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1); ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } else for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx; for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = texture(tx,ty,0,k); ptrd+=wh; } ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } } else { const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f); if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; if (pattern&hatch) { const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx; for (int k = 0; k<(int)((*this).dim); ++k) { const T c = (T)texture(tx,ty,0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } } hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1); ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } else for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx; for (int k = 0; k<(int)((*this).dim); ++k) { const T c = (T)texture(tx,ty,0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } } } return *this; } template CImg& draw_line(const int x0, const int y0, const float z0, const int x1, const int y1, const float z1, const CImg& texture, const int tx0, const int ty0, const int tx1, const int ty1, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { if (!is_empty() && z0>0 && z1>0) { if (!texture || texture.dim::draw_line() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.", pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data); if (is_overlapping(texture)) return draw_line(x0,y0,z0,x1,y1,z1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch); static unsigned int hatch = ~0U-(~0U>>1); if (init_hatch) hatch = ~0U-(~0U>>1); const bool xdir = x0=dimx()) return *this; if (xleft<0) { const int D = xright-xleft; yleft-=xleft*(yright-yleft)/D; zleft-=xleft*(zright-zleft)/D; txleft-=xleft*(txright-txleft)/D; tyleft-=xleft*(tyright-tyleft)/D; xleft = 0; } if (xright>=dimx()) { const int d = xright-dimx(), D = xright-xleft; yright-=d*(yright-yleft)/D; zright-=d*(zright-zleft)/D; txright-=d*(txright-txleft)/D; tyright-=d*(tyright-tyleft)/D; xright = dimx()-1; } if (ydown<0 || yup>=dimy()) return *this; if (yup<0) { const int D = ydown-yup; xup-=yup*(xdown-xup)/D; zup-=yup*(zdown-zup)/D; txup-=yup*(txdown-txup)/D; tyup-=yup*(tydown-tyup)/D; yup = 0; } if (ydown>=dimy()) { const int d = ydown-dimy(), D = ydown-yup; xdown-=d*(xdown-xup)/D; zdown-=d*(zdown-zup)/D; txdown-=d*(txdown-txup)/D; tydown-=d*(tydown-tyup)/D; ydown = dimy()-1; } T *ptrd0 = ptr(nx0,ny0,0,0); int dx = xright-xleft, dy = ydown-yup; const bool steep = dy>dx; if (steep) cimg::swap(nx0,ny0,nx1,ny1,dx,dy); const int offx = (nx00?dx:1; if (opacity>=1) { if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; if (pattern&hatch) { const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = texture((int)(tx/z),(int)(ty/z),0,k); ptrd+=wh; } } hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1); ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } else for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = texture((int)(tx/z),(int)(ty/z),0,k); ptrd+=wh; } ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } } else { const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f); if (~pattern) for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; if (pattern&hatch) { const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; for (int k = 0; k<(int)((*this).dim); ++k) { const T c = (T)texture((int)(tx/z),(int)(ty/z),0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } } hatch>>=1; if (!hatch) hatch = ~0U-(~0U>>1); ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } else for (int error=dx>>1, x=0; x<=dx; ++x) { T *ptrd = ptrd0; const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx; for (int k = 0; k<(int)((*this).dim); ++k) { const T c = (T)texture((int)(tx/z),(int)(ty/z),0,k); *ptrd = (T)(c*nopacity + *ptrd*copacity); ptrd+=wh; } ptrd0+=offx; if ((error-=dy)<0) { ptrd0+=offy; error+=dx; } } } } return *this; } template CImg& _draw_line(const t& points, const tc *const color, const float opacity, const unsigned int pattern, const bool init_hatch, const unsigned int W, const unsigned int H) { bool ninit_hatch = init_hatch; if (points && W>1 && H>1) { if (H==2) { const int x0 = (int)points(0,0), y0 = (int)points(0,1); int ox = x0, oy = y0; for (unsigned int i=1; i CImg& draw_line(const CImgList& points, const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { unsigned int H = ~0U; for (unsigned int p=0; p<(points).size; ++p) H = cimg::min(H,(unsigned int)(points[p].size())); return _draw_line(points,color,opacity,pattern,init_hatch,points.size,H); } template CImg& draw_line(const CImgList& points, const CImg& color, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_line(points,color.data,opacity,pattern,init_hatch); } template CImg& draw_line(const CImg& points, const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return _draw_line(points,color,opacity,pattern,init_hatch,points.width,points.height); } template CImg& draw_line(const CImg& points, const CImg& color, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_line(points,color.data,opacity,pattern,init_hatch); } template CImg& _draw_polygon(const t& points, const tc *const color, const float opacity, const unsigned int N) { if (!is_empty() && N>2) { if (!color) throw CImgArgumentException("CImg<%s>::draw_polygon() : Specified color is (null).",pixel_type()); _draw_scanline(color,opacity); int xmin = (int)(~0U>>1), xmax = 0, ymin = (int)(~0U>>1), ymax = 0; { for (unsigned int p = 0; pxmax) xmax = x; if (yymax) ymax = y; }} if (xmax<0 || xmin>=dimx() || ymax<0 || ymin>=dimx()) return *this; const unsigned int nymin = ymin<0?0:(unsigned int)ymin, nymax = ymax>=dimy()?height-1:(unsigned int)ymax, dy = 1 + nymax - nymin; typedef typename cimg::last::type cint; CImg X(1+2*N,dy,1,1,0), tmp; int cx = (int)points(0,0), cy = (int)points(0,1); for (unsigned int cp = 0, p = 0; pay && cy>ny))?1:0; for (int x = cx, y = y0, _sx = 1, _sy = 1, _dx = nx>cx?nx-cx:((_sx=-1),cx-nx), _dy = y1>y0?y1-y0:((_sy=-1),y0-y1), _counter = ((_dx-=_dy?_dy*(_dx/_dy):0),_dy), _err = _dx>>1, _rx = _dy?(nx-cx)/_dy:0; _counter>=countermin; --_counter, y+=_sy, x+=_rx + ((_err-=_dx)<0?_err+=_dy,_sx:0)) if (y>=0 && y<(int)dy) X(++X(0,y),y) = x; cp = np; cx = nx; cy = ny; } else { const int pp = (cp?cp-1:N-1), py = (int)points(pp,1); if ((cy>py && ay>cy) || (cy CImg& draw_polygon(const CImgList& points, const tc *const color, const float opacity=1.0f) { return _draw_polygon(points,color,opacity,points.size); } template CImg& draw_polygon(const CImgList& points, const CImg& color, const float opacity=1.0f) { return draw_polygon(points,color.data,opacity); } template CImg& draw_polygon(const CImg& points, const tc *const color, const float opacity=1.0f) { return _draw_polygon(points,color,opacity,points.width); } template CImg& draw_polygon(const CImg& points, const CImg& color, const float opacity=1.0f) { return draw_polygon(points,color.data,opacity); } template CImg& _draw_polygon(const t& points, const tc *const color, const float opacity, const unsigned int pattern, const unsigned int W, const unsigned int H) { bool ninit_hatch = true; if (points && W>2 && H>1) { if (H==2) { const int x0 = (int)points(0,0), y0 = (int)points(0,1); int ox = x0, oy = y0; for (unsigned int i=1; i CImg& draw_polygon(const CImgList& points, const tc *const color, const float opacity, const unsigned int pattern) { unsigned int H = ~0U; for (unsigned int p=0; p<(points).size; ++p) H = cimg::min(H,(unsigned int)(points[p].size())); return _draw_polygon(points,color,opacity,pattern,points.size,H); } template CImg& draw_polygon(const CImgList& points, const CImg& color, const float opacity, const unsigned int pattern) { return draw_polygon(points,color.data,opacity,pattern); } template CImg& draw_polygon(const CImg& points, const tc *const color, const float opacity, const unsigned int pattern) { return _draw_polygon(points,color,opacity,pattern,points.width,points.height); } template CImg& draw_polygon(const CImg& points, const CImg& color, const float opacity, const unsigned int pattern) { return draw_polygon(points,color.data,opacity,pattern); } template CImg& draw_spline(const int x0, const int y0, const float u0, const float v0, const int x1, const int y1, const float u1, const float v1, const tc *const color, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_spline() : Specified color is (null)",pixel_type()); bool ninit_hatch = init_hatch; const float dx = (float)(x1-x0), dy = (float)(y1-y0), dmax = cimg::max(cimg::abs(dx),cimg::abs(dy)), ax = -2*dx + u0 + u1, bx = 3*dx - 2*u0 - u1, ay = -2*dy + v0 + v1, by = 3*dy - 2*v0 - v1, xprecision = dmax>0?precision/dmax:1.0f, tmax = 1.0f + (dmax>0?xprecision:0.0f); int ox = x0, oy = y0; for (float t=0.0f; t CImg& draw_spline(const int x0, const int y0, const float u0, const float v0, const int x1, const int y1, const float u1, const float v1, const CImg& color, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_spline(x0,y0,u0,v0,x1,y1,u1,v1,color.data,precision,opacity,pattern,init_hatch); } template CImg& draw_spline(const int x0, const int y0, const int z0, const float u0, const float v0, const float w0, const int x1, const int y1, const int z1, const float u1, const float v1, const float w1, const tc *const color, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_spline() : Specified color is (null)",pixel_type()); bool ninit_hatch = init_hatch; const float dx = (float)(x1-x0), dy = (float)(y1-y0), dz = (float)(z1-z0), dmax = cimg::max(cimg::abs(dx),cimg::abs(dy),cimg::abs(dz)), ax = -2*dx + u0 + u1, bx = 3*dx - 2*u0 - u1, ay = -2*dy + v0 + v1, by = 3*dy - 2*v0 - v1, az = -2*dz + w0 + w1, bz = 3*dz - 2*w0 - w1, xprecision = dmax>0?precision/dmax:1.0f, tmax = 1.0f + (dmax>0?xprecision:0.0f); int ox = x0, oy = y0, oz = z0; for (float t=0.0f; t CImg& draw_spline(const int x0, const int y0, const int z0, const float u0, const float v0, const float w0, const int x1, const int y1, const int z1, const float u1, const float v1, const float w1, const CImg& color, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_spline(x0,y0,z0,u0,v0,w0,x1,y1,z1,u1,v1,w1,color.data,precision,opacity,pattern,init_hatch); } template CImg& draw_spline(const int x0, const int y0, const float u0, const float v0, const int x1, const int y1, const float u1, const float v1, const CImg& texture, const int tx0, const int ty0, const int tx1, const int ty1, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { if (!is_empty()) { if (!texture || texture.dim::draw_line() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.", pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data); 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); bool ninit_hatch = true; const float dx = (float)(x1-x0), dy = (float)(y1-y0), dmax = cimg::max(cimg::abs(dx),cimg::abs(dy)), ax = -2*dx + u0 + u1, bx = 3*dx - 2*u0 - u1, ay = -2*dy + v0 + v1, by = 3*dy - 2*v0 - v1, xprecision = dmax>0?precision/dmax:1.0f, tmax = 1.0f + (dmax>0?xprecision:0.0f); int ox = x0, oy = y0, otx = tx0, oty = ty0; for (float t1=0.0f; t1 CImg& _draw_spline(const tp& points, const tt& tangents, const tc *const color, const bool close_set, const float precision, const float opacity, const unsigned int pattern, const bool init_hatch, const unsigned int W, const unsigned int H) { bool ninit_hatch = init_hatch; if (points && tangents && W>1 && H>1) { if (H==2) { const int x0 = (int)points(0,0), y0 = (int)points(0,1); const float u0 = (float)tangents(0,0), v0 = (float)tangents(0,1); int ox = x0, oy = y0; float ou = u0, ov = v0; for (unsigned int i=1; i CImg& _draw_spline(const tp& points, const tc *const color, const bool close_set, const float precision, const float opacity, const unsigned int pattern, const bool init_hatch, const unsigned int W, const unsigned int H) { typedef typename cimg::superset::type ftype; CImg tangents; if (points && W>1 && H>1) { if (H==2) { tangents.assign(W,H); for (unsigned int p=0; p CImg& draw_spline(const CImgList& points, const CImgList& tangents, const tc *const color, const bool close_set=false, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { unsigned int H = ~0U; for (unsigned int p=0; p<(points).size; ++p) H = cimg::min(H,(unsigned int)(points[p].size()),(unsigned int)(tangents[p].size())); return _draw_spline(points,tangents,color,close_set,precision,opacity,pattern,init_hatch,points.size,H); } template CImg& draw_spline(const CImgList& points, const CImgList& tangents, const CImg& color, const bool close_set=false, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_spline(points,tangents,color.data,close_set,precision,opacity,pattern,init_hatch); } template CImg& draw_spline(const CImg& points, const CImg& tangents, const tc *const color, const bool close_set=false, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return _draw_spline(points,tangents,color,close_set,precision,opacity,pattern,init_hatch,points.width,points.height); } template CImg& draw_spline(const CImg& points, const CImg& tangents, const CImg& color, const bool close_set=false, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_spline(points,tangents,color.data,close_set,precision,opacity,pattern,init_hatch); } template CImg& draw_spline(const CImgList& points, const tc *const color, const bool close_set=false, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { unsigned int H = ~0U; for (unsigned int p=0; p<(points).size; ++p) { const unsigned int s = points[p].size(); if (s CImg& draw_spline(const CImgList& points, CImg& color, const bool close_set=false, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_spline(points,color.data,close_set,precision,opacity,pattern,init_hatch); } template CImg& draw_spline(const CImg& points, const tc *const color, const bool close_set=false, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return _draw_spline(points,color,close_set,precision,opacity,pattern,init_hatch,points.width,points.height); } template CImg& draw_spline(const CImg& points, const CImg& color, const bool close_set=false, const float precision=4.0f, const float opacity=1.0f, const unsigned int pattern=~0U, const bool init_hatch=true) { return draw_spline(points,color.data,close_set,precision,opacity,pattern,init_hatch); } template CImg& draw_arrow(const int x0, const int y0, const int x1, const int y1, const tc *const color, const float angle=30, const float length=-10, const float opacity=1.0f, const unsigned int pattern=~0U) { if (!is_empty()) { const float u = (float)(x0-x1), v = (float)(y0-y1), sq = u*u+v*v, deg = (float)(angle*cimg::valuePI/180), ang = (sq>0)?(float)std::atan2(v,u):0.0f, l = (length>=0)?length:-length*(float)std::sqrt(sq)/100; if (sq>0) { const double cl = std::cos(ang-deg), sl = std::sin(ang-deg), cr = std::cos(ang+deg), sr = std::sin(ang+deg); const int xl = x1+(int)(l*cl), yl = y1+(int)(l*sl), xr = x1+(int)(l*cr), yr = y1+(int)(l*sr), xc = x1+(int)((l+1)*(cl+cr))/2, yc = y1+(int)((l+1)*(sl+sr))/2; draw_line(x0,y0,xc,yc,color,opacity,pattern).draw_triangle(x1,y1,xl,yl,xr,yr,color,opacity); } else draw_point(x0,y0,color,opacity); } return *this; } template CImg& draw_arrow(const int x0, const int y0, const int x1, const int y1, const CImg& color, const float angle=30, const float length=-10, const float opacity=1.0f, const unsigned int pattern=~0U) { return draw_arrow(x0,y0,x1,y1,color.data,angle,length,opacity,pattern); } template CImg& draw_image(const CImg& sprite, const int x0, const int y0=0, const int z0=0, const int v0=0, const float opacity=1.0f) { if (!is_empty()) { if (!sprite) throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.", pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data); if (is_overlapping(sprite)) return draw_image(+sprite,x0,y0,z0,v0,opacity); const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0); const int lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0), lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0), lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0), lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0); const t *ptrs = sprite.data - (bx?x0:0) - (by?y0*sprite.dimx():0) - (bz?z0*sprite.dimx()*sprite.dimy():0) - (bv?v0*sprite.dimx()*sprite.dimy()*sprite.dimz():0); const unsigned int offX = width-lX, soffX = sprite.width-lX, offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY), offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0); if (lX>0 && lY>0 && lZ>0 && lV>0) for (int v=0; v=1) for (int x=0; x& draw_image(const CImg& sprite, const int x0, const int y0=0, const int z0=0, const int v0=0, const float opacity=1.0f) { if (!is_empty()) { if (!sprite) throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.", pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data); if (is_overlapping(sprite)) return draw_image(+sprite,x0,y0,z0,v0,opacity); const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0); const int lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0), lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0), lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0), lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0); const T *ptrs = sprite.data - (bx?x0:0) - (by?y0*sprite.dimx():0) - (bz?z0*sprite.dimx()*sprite.dimy():0) - (bv?v0*sprite.dimx()*sprite.dimy()*sprite.dimz():0); const unsigned int offX = width-lX, soffX = sprite.width-lX, offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY), offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ), slX = lX*sizeof(T); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0); if (lX>0 && lY>0 && lZ>0 && lV>0) for (int v=0; v=1) for (int y=0; y CImg& draw_image(const CImg& sprite, const CImg& mask, const int x0, const int y0=0, const int z0=0, const int v0=0, const float mask_valmax=1.0f, const float opacity=1.0f) { if (!is_empty()) { if (!sprite) throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.", pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data); if (!mask) throw CImgArgumentException("CImg<%s>::draw_image() : Specified mask image (%u,%u,%u,%u,%p) is empty.", pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data); if (is_overlapping(sprite)) return draw_image(+sprite,mask,x0,y0,z0,v0,mask_valmax,opacity); if (is_overlapping(mask)) return draw_image(sprite,+mask,x0,y0,z0,v0,mask_valmax,opacity); if (mask.width!=sprite.width || mask.height!=sprite.height || mask.depth!=sprite.depth) throw CImgArgumentException("CImg<%s>::draw_image() : Mask dimension is (%u,%u,%u,%u), while sprite is (%u,%u,%u,%u)", pixel_type(),mask.width,mask.height,mask.depth,mask.dim,sprite.width,sprite.height,sprite.depth,sprite.dim); const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0); const int lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0), lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0), lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0), lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0); const int 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), ssize = mask.dimx()*mask.dimy()*mask.dimz(); const ti *ptrs = sprite.data + coff; const tm *ptrm = mask.data + coff; const unsigned int offX = width-lX, soffX = sprite.width-lX, offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY), offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ); T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0); if (lX>0 && lY>0 && lZ>0 && lV>0) for (int v=0; v& draw_rectangle(const int x0, const int y0, const int z0, const int v0, const int x1, const int y1, const int z1, const int v1, const T val, const float opacity=1.0f) { if (!is_empty()) { const bool bx=(x0=dimx()?dimx()-1-nx1:0) + (nx0<0?nx0:0), lY = (1+ny1-ny0) + (ny1>=dimy()?dimy()-1-ny1:0) + (ny0<0?ny0:0), lZ = (1+nz1-nz0) + (nz1>=dimz()?dimz()-1-nz1:0) + (nz0<0?nz0:0), lV = (1+nv1-nv0) + (nv1>=dimv()?dimv()-1-nv1:0) + (nv0<0?nv0:0); const unsigned int offX = width-lX, offY = width*(height-lY), offZ = width*height*(depth-lZ); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); T *ptrd = ptr(nx0<0?0:nx0,ny0<0?0:ny0,nz0<0?0:nz0,nv0<0?0:nv0); if (lX>0 && lY>0 && lZ>0 && lV>0) for (int v=0; v=1) { if (sizeof(T)!=1) { for (int x=0; x CImg& draw_rectangle(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1, const tc *const color, const float opacity=1.0f) { if (!color) throw CImgArgumentException("CImg<%s>::draw_rectangle : specified color is (null)",pixel_type()); for (int k = 0; k<(int)((*this).dim); ++k) draw_rectangle(x0,y0,z0,k,x1,y1,z1,k,color[k],opacity); return *this; } template CImg& draw_rectangle(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1, const CImg& color, const float opacity=1.0f) { return draw_rectangle(x0,y0,z0,x1,y1,z1,color.data,opacity); } template CImg& draw_rectangle(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1, const tc *const color, const float opacity, const unsigned int pattern) { return draw_line(x0,y0,z0,x1,y0,z0,color,opacity,pattern,true). draw_line(x1,y0,z0,x1,y1,z0,color,opacity,pattern,false). draw_line(x1,y1,z0,x0,y1,z0,color,opacity,pattern,false). draw_line(x0,y1,z0,x0,y0,z0,color,opacity,pattern,false). draw_line(x0,y0,z1,x1,y0,z1,color,opacity,pattern,true). draw_line(x1,y0,z1,x1,y1,z1,color,opacity,pattern,false). draw_line(x1,y1,z1,x0,y1,z1,color,opacity,pattern,false). draw_line(x0,y1,z1,x0,y0,z1,color,opacity,pattern,false). draw_line(x0,y0,z0,x0,y0,z1,color,opacity,pattern,true). draw_line(x1,y0,z0,x1,y0,z1,color,opacity,pattern,true). draw_line(x1,y1,z0,x1,y1,z1,color,opacity,pattern,true). draw_line(x0,y1,z0,x0,y1,z1,color,opacity,pattern,true); } template CImg& draw_rectangle(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1, const CImg& color, const float opacity, const unsigned int pattern) { return draw_rectangle(x0,y0,z0,x1,y1,z1,color.data,opacity,pattern); } template CImg& draw_rectangle(const int x0, const int y0, const int x1, const int y1, const tc *const color, const float opacity=1.0f) { return draw_rectangle(x0,y0,0,x1,y1,depth-1,color,opacity); } template CImg& draw_rectangle(const int x0, const int y0, const int x1, const int y1, const CImg& color, const float opacity=1.0f) { return draw_rectangle(x0,y0,x1,y1,color.data,opacity); } template CImg& draw_rectangle(const int x0, const int y0, const int x1, const int y1, const tc *const color, const float opacity, const unsigned int pattern) { return draw_line(x0,y0,x1,y0,color,opacity,pattern,true). draw_line(x1,y0,x1,y1,color,opacity,pattern,false). draw_line(x1,y1,x0,y1,color,opacity,pattern,false). draw_line(x0,y1,x0,y0,color,opacity,pattern,false); } template CImg& draw_rectangle(const int x0, const int y0, const int x1, const int y1, const CImg& color, const float opacity, const unsigned int pattern) { return draw_rectangle(x0,y0,x1,y1,color.data,opacity,pattern); } template CImg& _draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const tc *const color, const float opacity, const float brightness) { _draw_scanline(color,opacity); const float nbrightness = brightness<0?0:(brightness>2?2:brightness); int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2; if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1); if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2); if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2); if (ny0=0) { if ((nx1-nx0)*(ny2-ny0)-(nx2-nx0)*(ny1-ny0)<0) for (int y = ny0<0?0:ny0, xr = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), xl = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), _sxn=1, _sxr=1, _sxl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dyn = ny2-ny1, _dyr = ny2-ny0, _dyl = ny1-ny0, _counter = (_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errr = _dyr/2, _errl = _dyl/2, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn); _counter>=0; --_counter, ++y, xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), xl+=(y!=ny1)?_rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xl)) _draw_scanline(xl,xr,y,color,opacity,nbrightness); else for (int y = ny0<0?0:ny0, xr = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), xl = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), _sxn=1, _sxr=1, _sxl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dyn = ny2-ny1, _dyr = ny2-ny0, _dyl = ny1-ny0, _counter = (_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errr = _dyr/2, _errl = _dyl/2, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn); _counter>=0; --_counter, ++y, xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), xl+=(y!=ny1)?_rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xl)) _draw_scanline(xr,xl,y,color,opacity,nbrightness); } return *this; } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const tc *const color, const float opacity=1.0f) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type()); _draw_triangle(x0,y0,x1,y1,x2,y2,color,opacity,1.0f); } return *this; } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const CImg& color, const float opacity=1.0f) { return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opacity); } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const tc *const color, const float opacity, const unsigned int pattern) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type()); draw_line(x0,y0,x1,y1,color,opacity,pattern,true). draw_line(x1,y1,x2,y2,color,opacity,pattern,false). draw_line(x2,y2,x0,y0,color,opacity,pattern,false); } return *this; } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const CImg& color, const float opacity, const unsigned int pattern) { return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opacity,pattern); } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const tc *const color, const float brightness0, const float brightness1, const float brightness2, const float opacity=1.0f) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type()); static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); const int whz = width*height*depth, offx = dim*whz-1; int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, nc0 = (int)((brightness0<0?0:(brightness0>2?2:brightness0))*256), nc1 = (int)((brightness1<0?0:(brightness1>2?2:brightness1))*256), nc2 = (int)((brightness2<0?0:(brightness2>2?2:brightness2))*256); if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nc0,nc1); if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nc0,nc2); if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nc1,nc2); if (ny0=0) { for (int y = ny0<0?0:ny0, xright0 = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), cright0 = ny0>=0?nc0:(nc0-ny0*(nc2-nc0)/(ny2-ny0)), xleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), cleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nc1:nc0):(nc0-ny0*(nc1-nc0)/(ny1-ny0))):(nc1-ny1*(nc2-nc1)/(ny2-ny1)), _sxn=1, _scn=1, _sxr=1, _scr=1, _sxl=1, _scl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dcn = nc2>nc1?nc2-nc1:(_scn=-1,nc1-nc2), _dcr = nc2>nc0?nc2-nc0:(_scr=-1,nc0-nc2), _dcl = nc1>nc0?nc1-nc0:(_scl=-1,nc0-nc1), _dyn = ny2-ny1, _dyr = ny2-ny0, _dyl = ny1-ny0, _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, _dcn-=_dyn?_dyn*(_dcn/_dyn):0, _dcr-=_dyr?_dyr*(_dcr/_dyr):0, _dcl-=_dyl?_dyl*(_dcl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errcn = _errn, _errr = _dyr/2, _errcr = _errr, _errl = _dyl/2, _errcl = _errl, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rcn = _dyn?(nc2-nc1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rcr = _dyr?(nc2-nc0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), _rcl = (ny0!=ny1 && ny1>0)?(_dyl?(nc1-nc0)/_dyl:0): (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ); _counter>=0; --_counter, ++y, xright0+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), cright0+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), xleft0+=(y!=ny1)?(cleft0+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cleft0=nc1, _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xleft0)) { int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0; if (xrightcleft?cright-cleft:cleft-cright, rc = dx?(cright-cleft)/dx:0, sc = cright>cleft?1:-1, ndc = dc-(dx?dx*(dc/dx):0); int errc = dx>>1; if (xleft<0 && dx) cleft-=xleft*(cright-cleft)/dx; if (xleft<0) xleft=0; if (xright>=dimx()-1) xright=dimx()-1; T* ptrd = ptr(xleft,y,0,0); if (opacity>=1) for (int x=xleft; x<=xright; ++x) { const tc *col = color; for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(cleft<256?cleft**(col++)/256:((512-cleft)**(col++)+(cleft-256)*maxval)/256); ptrd+=whz; } ptrd-=offx; cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); } else for (int x=xleft; x<=xright; ++x) { const tc *col = color; for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)(cleft<256?cleft**(col++)/256:((512-cleft)**(col++)+(cleft-256)*maxval)/256); *ptrd = (T)(nopacity*val + *ptrd*copacity); ptrd+=whz; } ptrd-=offx; cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); } } } } return *this; } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const CImg& color, const float brightness0, const float brightness1, const float brightness2, const float opacity=1.0f) { return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,brightness0,brightness1,brightness2,opacity); } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const CImg& texture, const int tx0, const int ty0, const int tx1, const int ty1, const int tx2, const int ty2, const float opacity=1.0f, const float brightness=1.0f) { if (!is_empty()) { if (!texture || texture.dim::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.", pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data); if (is_overlapping(texture)) return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness); static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f), nbrightness = brightness<0?0:(brightness>2?2:brightness); const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1; int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2; if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1); if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2); if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2); if (ny0=0) { for (int y = ny0<0?0:ny0, xright0 = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), txright0 = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)), tyright0 = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)), xleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), txleft0 = ny1>=0?(ny0>=0?(ny0==ny1?ntx1:ntx0):(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1)), tyleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nty1:nty0):(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(nty1-ny1*(nty2-nty1)/(ny2-ny1)), _sxn=1, _stxn=1, _styn=1, _sxr=1, _stxr=1, _styr=1, _sxl=1, _stxl=1, _styl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dtxn = ntx2>ntx1?ntx2-ntx1:(_stxn=-1,ntx1-ntx2), _dtxr = ntx2>ntx0?ntx2-ntx0:(_stxr=-1,ntx0-ntx2), _dtxl = ntx1>ntx0?ntx1-ntx0:(_stxl=-1,ntx0-ntx1), _dtyn = nty2>nty1?nty2-nty1:(_styn=-1,nty1-nty2), _dtyr = nty2>nty0?nty2-nty0:(_styr=-1,nty0-nty2), _dtyl = nty1>nty0?nty1-nty0:(_styl=-1,nty0-nty1), _dyn = ny2-ny1, _dyr = ny2-ny0, _dyl = ny1-ny0, _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rtxn = _dyn?(ntx2-ntx1)/_dyn:0, _rtyn = _dyn?(nty2-nty1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rtxr = _dyr?(ntx2-ntx0)/_dyr:0, _rtyr = _dyr?(nty2-nty0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), _rtxl = (ny0!=ny1 && ny1>0)?(_dyl?(ntx1-ntx0)/_dyl:0): (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), _rtyl = (ny0!=ny1 && ny1>0)?(_dyl?(nty1-nty0)/_dyl:0): (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); _counter>=0; --_counter, ++y, xright0+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), txright0+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), tyright0+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), xleft0+=(y!=ny1)?(txleft0+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), tyleft0+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txleft0=ntx1, _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyleft0=nty1, _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xleft0)) { int xleft = xleft0, xright = xright0, txleft = txleft0, txright = txright0, tyleft = tyleft0, tyright = tyright0; if (xrighttxleft?txright-txleft:txleft-txright, dty = tyright>tyleft?tyright-tyleft:tyleft-tyright, rtx = dx?(txright-txleft)/dx:0, rty = dx?(tyright-tyleft)/dx:0, stx = txright>txleft?1:-1, sty = tyright>tyleft?1:-1, ndtx = dtx-(dx?dx*(dtx/dx):0), ndty = dty-(dx?dx*(dty/dx):0); int errtx = dx>>1, errty = errtx; if (xleft<0 && dx) { txleft-=xleft*(txright-txleft)/dx; tyleft-=xleft*(tyright-tyleft)/dx; } if (xleft<0) xleft=0; if (xright>=dimx()-1) xright=dimx()-1; T* ptrd = ptr(xleft,y,0,0); if (opacity>=1) { if (nbrightness==1) for (int x=xleft; x<=xright; ++x) { const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*col; ptrd+=whz; col+=twhz; } ptrd-=offx; txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } else if (nbrightness<1) for (int x=xleft; x<=xright; ++x) { const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(nbrightness**col); ptrd+=whz; col+=twhz; } ptrd-=offx; txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } else for (int x=xleft; x<=xright; ++x) { const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)((2-nbrightness)**(col++) + (nbrightness-1)*maxval); ptrd+=whz; col+=twhz; } ptrd-=offx; txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } } else { if (nbrightness==1) for (int x=xleft; x<=xright; ++x) { const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(nopacity**col + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } else if (nbrightness<1) for (int x=xleft; x<=xright; ++x) { const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(nopacity*nbrightness**col + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } else for (int x=xleft; x<=xright; ++x) { const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)((2-nbrightness)**(col++) + (nbrightness-1)*maxval); *ptrd = (T)(nopacity*val + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } } } } } return *this; } template CImg& draw_triangle(const int x0, const int y0, const float z0, const int x1, const int y1, const float z1, const int x2, const int y2, const float z2, const CImg& texture, const int tx0, const int ty0, const int tx1, const int ty1, const int tx2, const int ty2, const float opacity=1.0f, const float brightness=1.0f) { if (!is_empty() && z0>0 && z1>0 && z2>0) { if (!texture || texture.dim::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.", pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data); 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); static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f), nbrightness = brightness<0?0:(brightness>2?2:brightness); const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1; int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2; float ntx0 = tx0/z0, nty0 = ty0/z0, ntx1 = tx1/z1, nty1 = ty1/z1, ntx2 = tx2/z2, nty2 = ty2/z2, nz0 = 1.0f/z0, nz1 = 1.0f/z1, nz2 = 1.0f/z2; if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1); if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2); if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2); if (ny0=0) { float ptxl = (ntx1-ntx0)/(ny1-ny0), ptxr = (ntx2-ntx0)/(ny2-ny0), ptxn = (ntx2-ntx1)/(ny2-ny1), ptyl = (nty1-nty0)/(ny1-ny0), ptyr = (nty2-nty0)/(ny2-ny0), ptyn = (nty2-nty1)/(ny2-ny1), pzl = (nz1-nz0)/(ny1-ny0), pzr = (nz2-nz0)/(ny2-ny0), pzn = (nz2-nz1)/(ny2-ny1), zr = ny0>=0?nz0:(nz0-ny0*(nz2-nz0)/(ny2-ny0)), txr = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)), tyr = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)), zl = ny1>=0?(ny0>=0?nz0:(nz0-ny0*(nz1-nz0)/(ny1-ny0))):(pzl=pzn,(nz1-ny1*(nz2-nz1)/(ny2-ny1))), txl = ny1>=0?(ny0>=0?ntx0:(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ptxl=ptxn,(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1))), tyl = ny1>=0?(ny0>=0?nty0:(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(ptyl=ptyn,(nty1-ny1*(nty2-nty1)/(ny2-ny1))); for (int y = ny0<0?0:ny0, xright0 = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), xleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), _sxn=1, _sxr=1, _sxl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dyn = ny2-ny1, _dyr = ny2-ny0, _dyl = ny1-ny0, _counter = (_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errr = _dyr/2, _errl = _dyl/2, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn); _counter>=0; --_counter, ++y, xright0+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), xleft0+=(y!=ny1)?_rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xleft0)) { if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; } int xleft = xleft0, xright = xright0; float zleft = zl, zright = zr, txleft = txl, txright = txr, tyleft = tyl, tyright = tyr; if (xright=dimx()-1) xright=dimx()-1; T* ptrd = ptr(xleft,y,0,0); if (opacity>=1) { if (nbrightness==1) for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*col; ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; } else if (nbrightness<1) for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(nbrightness**col); ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; } else for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)((2-nbrightness)**(col++) + (nbrightness-1)*maxval); ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; } } else { if (nbrightness==1) for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(nopacity**col + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; } else if (nbrightness<1) for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(nopacity*nbrightness**col + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; } else for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)((2-nbrightness)**(col++) + (nbrightness-1)*maxval); *ptrd = (T)(nopacity*val + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; } } zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl; } } } return *this; } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const tc *const color, const CImg& light, const int lx0, const int ly0, const int lx1, const int ly1, const int lx2, const int ly2, const float opacity=1.0f) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_triangle : Specified color is (null).",pixel_type()); if (!light) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.", pixel_type(),light.width,light.height,light.depth,light.dim,light.data); if (is_overlapping(light)) return draw_triangle(x0,y0,x1,y1,x2,y2,color,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2; const int whz = width*height*depth, offx = dim*whz-1; if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nlx0,nlx1,nly0,nly1); if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nlx0,nlx2,nly0,nly2); if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nlx1,nlx2,nly1,nly2); if (ny0=0) { for (int y = ny0<0?0:ny0, xright0 = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), lxright0 = ny0>=0?nlx0:(nlx0-ny0*(nlx2-nlx0)/(ny2-ny0)), lyright0 = ny0>=0?nly0:(nly0-ny0*(nly2-nly0)/(ny2-ny0)), xleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), lxleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nlx1:nlx0):(nlx0-ny0*(nlx1-nlx0)/(ny1-ny0))):(nlx1-ny1*(nlx2-nlx1)/(ny2-ny1)), lyleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nly1:nly0):(nly0-ny0*(nly1-nly0)/(ny1-ny0))):(nly1-ny1*(nly2-nly1)/(ny2-ny1)), _sxn=1, _stxn=1, _styn=1, _sxr=1, _stxr=1, _styr=1, _sxl=1, _stxl=1, _styl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dtxn = nlx2>nlx1?nlx2-nlx1:(_stxn=-1,nlx1-nlx2), _dtxr = nlx2>nlx0?nlx2-nlx0:(_stxr=-1,nlx0-nlx2), _dtxl = nlx1>nlx0?nlx1-nlx0:(_stxl=-1,nlx0-nlx1), _dtyn = nly2>nly1?nly2-nly1:(_styn=-1,nly1-nly2), _dtyr = nly2>nly0?nly2-nly0:(_styr=-1,nly0-nly2), _dtyl = nly1>nly0?nly1-nly0:(_styl=-1,nly0-nly1), _dyn = ny2-ny1, _dyr = ny2-ny0, _dyl = ny1-ny0, _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rtxn = _dyn?(nlx2-nlx1)/_dyn:0, _rtyn = _dyn?(nly2-nly1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rtxr = _dyr?(nlx2-nlx0)/_dyr:0, _rtyr = _dyr?(nly2-nly0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), _rtxl = (ny0!=ny1 && ny1>0)?(_dyl?(nlx1-nlx0)/_dyl:0): (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), _rtyl = (ny0!=ny1 && ny1>0)?(_dyl?(nly1-nly0)/_dyl:0): (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); _counter>=0; --_counter, ++y, xright0+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), lxright0+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), lyright0+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), xleft0+=(y!=ny1)?(lxleft0+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), lyleft0+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, lxleft0=nlx1, _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, lyleft0=nly1, _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xleft0)) { int xleft = xleft0, xright = xright0, lxleft = lxleft0, lxright = lxright0, lyleft = lyleft0, lyright = lyright0; if (xrightlxleft?lxright-lxleft:lxleft-lxright, dly = lyright>lyleft?lyright-lyleft:lyleft-lyright, rlx = dx?(lxright-lxleft)/dx:0, rly = dx?(lyright-lyleft)/dx:0, slx = lxright>lxleft?1:-1, sly = lyright>lyleft?1:-1, ndlx = dlx-(dx?dx*(dlx/dx):0), ndly = dly-(dx?dx*(dly/dx):0); int errlx = dx>>1, errly = errlx; if (xleft<0 && dx) { lxleft-=xleft*(lxright-lxleft)/dx; lyleft-=xleft*(lyright-lyleft)/dx; } if (xleft<0) xleft=0; if (xright>=dimx()-1) xright=dimx()-1; T* ptrd = ptr(xleft,y,0,0); if (opacity>=1) for (int x=xleft; x<=xright; ++x) { const t l = light(lxleft,lyleft); const tc *col = color; for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(l<1?l**(col++):((2-l)**(col++)+(l-1)*maxval)); ptrd+=whz; } ptrd-=offx; lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); } else for (int x=xleft; x<=xright; ++x) { const t l = light(lxleft,lyleft); const tc *col = color; for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)(l<1?l**(col++):((2-l)**(col++)+(l-1)*maxval)); *ptrd = (T)(nopacity*val + *ptrd*copacity); ptrd+=whz; } ptrd-=offx; lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); } } } } return *this; } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const CImg& color, const CImg& light, const int lx0, const int ly0, const int lx1, const int ly1, const int lx2, const int ly2, const float opacity=1.0f) { return draw_triangle(x0,y0,x1,y1,x2,y2,color.data,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity); } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const CImg& texture, const int tx0, const int ty0, const int tx1, const int ty1, const int tx2, const int ty2, const float brightness0, const float brightness1, const float brightness2, const float opacity=1) { if (!is_empty()) { if (!texture || texture.dim::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.", pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data); if (is_overlapping(texture)) return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,brightness0,brightness1,brightness2,opacity); static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1; int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2, nc0 = (int)((brightness0<0?0:(brightness0>2?2:brightness0))*256), nc1 = (int)((brightness1<0?0:(brightness1>2?2:brightness1))*256), nc2 = (int)((brightness2<0?0:(brightness2>2?2:brightness2))*256); if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nc0,nc1); if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nc0,nc2); if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nc1,nc2); if (ny0=0) { for (int y = ny0<0?0:ny0, xright0 = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), cright0 = ny0>=0?nc0:(nc0-ny0*(nc2-nc0)/(ny2-ny0)), txright0 = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)), tyright0 = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)), xleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), cleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nc1:nc0):(nc0-ny0*(nc1-nc0)/(ny1-ny0))):(nc1-ny1*(nc2-nc1)/(ny2-ny1)), txleft0 = ny1>=0?(ny0>=0?(ny0==ny1?ntx1:ntx0):(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1)), tyleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nty1:nty0):(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(nty1-ny1*(nty2-nty1)/(ny2-ny1)), _sxn=1, _scn=1, _stxn=1, _styn=1, _sxr=1, _scr=1, _stxr=1, _styr=1, _sxl=1, _scl=1, _stxl=1, _styl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dcn = nc2>nc1?nc2-nc1:(_scn=-1,nc1-nc2), _dcr = nc2>nc0?nc2-nc0:(_scr=-1,nc0-nc2), _dcl = nc1>nc0?nc1-nc0:(_scl=-1,nc0-nc1), _dtxn = ntx2>ntx1?ntx2-ntx1:(_stxn=-1,ntx1-ntx2), _dtxr = ntx2>ntx0?ntx2-ntx0:(_stxr=-1,ntx0-ntx2), _dtxl = ntx1>ntx0?ntx1-ntx0:(_stxl=-1,ntx0-ntx1), _dtyn = nty2>nty1?nty2-nty1:(_styn=-1,nty1-nty2), _dtyr = nty2>nty0?nty2-nty0:(_styr=-1,nty0-nty2), _dtyl = nty1>nty0?nty1-nty0:(_styl=-1,nty0-nty1), _dyn = ny2-ny1, _dyr = ny2-ny0, _dyl = ny1-ny0, _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, _dcn-=_dyn?_dyn*(_dcn/_dyn):0, _dcr-=_dyr?_dyr*(_dcr/_dyr):0, _dcl-=_dyl?_dyl*(_dcl/_dyl):0, _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errcn = _errn, _errtxn = _errn, _errtyn = _errn, _errr = _dyr/2, _errcr = _errr, _errtxr = _errr, _errtyr = _errr, _errl = _dyl/2, _errcl = _errl, _errtxl = _errl, _errtyl = _errl, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rcn = _dyn?(nc2-nc1)/_dyn:0, _rtxn = _dyn?(ntx2-ntx1)/_dyn:0, _rtyn = _dyn?(nty2-nty1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rcr = _dyr?(nc2-nc0)/_dyr:0, _rtxr = _dyr?(ntx2-ntx0)/_dyr:0, _rtyr = _dyr?(nty2-nty0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), _rcl = (ny0!=ny1 && ny1>0)?(_dyl?(nc1-nc0)/_dyl:0): (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ), _rtxl = (ny0!=ny1 && ny1>0)?(_dyl?(ntx1-ntx0)/_dyl:0): (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), _rtyl = (ny0!=ny1 && ny1>0)?(_dyl?(nty1-nty0)/_dyl:0): (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); _counter>=0; --_counter, ++y, xright0+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), cright0+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), txright0+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), tyright0+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), xleft0+=(y!=ny1)?(cleft0+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), txleft0+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), tyleft0+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cleft0=nc1, _errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txleft0=ntx1, _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyleft0=nty1, _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xleft0)) { int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0, txleft = txleft0, txright = txright0, tyleft = tyleft0, tyright = tyright0; if (xrightcleft?cright-cleft:cleft-cright, dtx = txright>txleft?txright-txleft:txleft-txright, dty = tyright>tyleft?tyright-tyleft:tyleft-tyright, rc = dx?(cright-cleft)/dx:0, rtx = dx?(txright-txleft)/dx:0, rty = dx?(tyright-tyleft)/dx:0, sc = cright>cleft?1:-1, stx = txright>txleft?1:-1, sty = tyright>tyleft?1:-1, ndc = dc-(dx?dx*(dc/dx):0), ndtx = dtx-(dx?dx*(dtx/dx):0), ndty = dty-(dx?dx*(dty/dx):0); int errc = dx>>1, errtx = errc, errty = errc; if (xleft<0 && dx) { cleft-=xleft*(cright-cleft)/dx; txleft-=xleft*(txright-txleft)/dx; tyleft-=xleft*(tyright-tyleft)/dx; } if (xleft<0) xleft=0; if (xright>=dimx()-1) xright=dimx()-1; T* ptrd = ptr(xleft,y,0,0); if (opacity>=1) for (int x=xleft; x<=xright; ++x) { const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256); ptrd+=whz; col+=twhz; } ptrd-=offx; cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } else for (int x=xleft; x<=xright; ++x) { const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256); *ptrd = (T)(nopacity*val + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } } } } return *this; } template CImg& draw_triangle(const int x0, const int y0, const float z0, const int x1, const int y1, const float z1, const int x2, const int y2, const float z2, const CImg& texture, const int tx0, const int ty0, const int tx1, const int ty1, const int tx2, const int ty2, const float c0, const float c1, const float c2, const float opacity=1.0f) { if (!is_empty() && z0>0 && z1>0 && z2>0) { if (!texture || texture.dim::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.", pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data); 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); static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1; int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, nc0 = (int)(c0*256), nc1 = (int)(c1*256), nc2 = (int)(c2*256); float ntx0 = tx0/z0, nty0 = ty0/z0, ntx1 = tx1/z1, nty1 = ty1/z1, ntx2 = tx2/z2, nty2 = ty2/z2, nz0 = 1.0f/z0, nz1 = 1.0f/z1, nz2 = 1.0f/z2; if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1,nc0,nc1); if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2,nc0,nc2); if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2,nc1,nc2); if (ny0=0) { float ptxl = (ntx1-ntx0)/(ny1-ny0), ptxr = (ntx2-ntx0)/(ny2-ny0), ptxn = (ntx2-ntx1)/(ny2-ny1), ptyl = (nty1-nty0)/(ny1-ny0), ptyr = (nty2-nty0)/(ny2-ny0), ptyn = (nty2-nty1)/(ny2-ny1), pzl = (nz1-nz0)/(ny1-ny0), pzr = (nz2-nz0)/(ny2-ny0), pzn = (nz2-nz1)/(ny2-ny1), zr = ny0>=0?nz0:(nz0-ny0*(nz2-nz0)/(ny2-ny0)), txr = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)), tyr = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)), zl = ny1>=0?(ny0>=0?nz0:(nz0-ny0*(nz1-nz0)/(ny1-ny0))):(pzl=pzn,(nz1-ny1*(nz2-nz1)/(ny2-ny1))), txl = ny1>=0?(ny0>=0?ntx0:(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ptxl=ptxn,(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1))), tyl = ny1>=0?(ny0>=0?nty0:(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(ptyl=ptyn,(nty1-ny1*(nty2-nty1)/(ny2-ny1))); for (int y = ny0<0?0:ny0, xright0 = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), cright0 = ny0>=0?nc0:(nc0-ny0*(nc2-nc0)/(ny2-ny0)), xleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), cleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nc1:nc0):(nc0-ny0*(nc1-nc0)/(ny1-ny0))):(nc1-ny1*(nc2-nc1)/(ny2-ny1)), _sxn=1, _scn=1, _sxr=1, _scr=1, _sxl=1, _scl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dcn = nc2>nc1?nc2-nc1:(_scn=-1,nc1-nc2), _dcr = nc2>nc0?nc2-nc0:(_scr=-1,nc0-nc2), _dcl = nc1>nc0?nc1-nc0:(_scl=-1,nc0-nc1), _dyn = ny2-ny1, _dyr = ny2-ny0, _dyl = ny1-ny0, _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, _dcn-=_dyn?_dyn*(_dcn/_dyn):0, _dcr-=_dyr?_dyr*(_dcr/_dyr):0, _dcl-=_dyl?_dyl*(_dcl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errcn = _errn, _errr = _dyr/2, _errcr = _errr, _errl = _dyl/2, _errcl = _errl, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rcn = _dyn?(nc2-nc1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rcr = _dyr?(nc2-nc0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), _rcl = (ny0!=ny1 && ny1>0)?(_dyl?(nc1-nc0)/_dyl:0): (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ); _counter>=0; --_counter, ++y, xright0+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), cright0+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), xleft0+=(y!=ny1)?(cleft0+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cleft0=nc1, _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xleft0)) { if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; } int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0; float zleft = zl, zright = zr, txleft = txl, txright = txr, tyleft = tyl, tyright = tyr; if (xrightcleft?cright-cleft:cleft-cright, rc = dx?(cright-cleft)/dx:0, sc = cright>cleft?1:-1, ndc = dc-(dx?dx*(dc/dx):0); const float pentez = (zright-zleft)/dx, pentetx = (txright-txleft)/dx, pentety = (tyright-tyleft)/dx; int errc = dx>>1; if (xleft<0 && dx) { cleft-=xleft*(cright-cleft)/dx; zleft-=xleft*(zright-zleft)/dx; txleft-=xleft*(txright-txleft)/dx; tyleft-=xleft*(tyright-tyleft)/dx; } if (xleft<0) xleft=0; if (xright>=dimx()-1) xright=dimx()-1; T* ptrd = ptr(xleft,y,0,0); if (opacity>=1) for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256); ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); } else for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256); *ptrd = (T)(nopacity*val + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0); } zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl; } } } return *this; } template CImg& draw_triangle(const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, const CImg& texture, const int tx0, const int ty0, const int tx1, const int ty1, const int tx2, const int ty2, const CImg& light, const int lx0, const int ly0, const int lx1, const int ly1, const int lx2, const int ly2, const float opacity=1.0f) { if (!is_empty()) { if (!texture || texture.dim::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.", pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data); if (!light) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.", pixel_type(),light.width,light.height,light.depth,light.dim,light.data); 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); 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); static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1; int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2, nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2; if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1); if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2); if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2); if (ny0=0) { for (int y = ny0<0?0:ny0, xright0 = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), lxright0 = ny0>=0?nlx0:(nlx0-ny0*(nlx2-nlx0)/(ny2-ny0)), lyright0 = ny0>=0?nly0:(nly0-ny0*(nly2-nly0)/(ny2-ny0)), txright0 = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)), tyright0 = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)), xleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), lxleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nlx1:nlx0):(nlx0-ny0*(nlx1-nlx0)/(ny1-ny0))):(nlx1-ny1*(nlx2-nlx1)/(ny2-ny1)), lyleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nly1:nly0):(nly0-ny0*(nly1-nly0)/(ny1-ny0))):(nly1-ny1*(nly2-nly1)/(ny2-ny1)), txleft0 = ny1>=0?(ny0>=0?(ny0==ny1?ntx1:ntx0):(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1)), tyleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nty1:nty0):(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(nty1-ny1*(nty2-nty1)/(ny2-ny1)), _sxn=1, _stxn=1, _styn=1, _slxn=1, _slyn=1, _sxr=1, _stxr=1, _styr=1, _slxr=1, _slyr=1, _sxl=1, _stxl=1, _styl=1, _slxl=1, _slyl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dyn = ny2-ny1, _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dyr = ny2-ny0, _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dyl = ny1-ny0, _dtxn = nlx2>nlx1?nlx2-nlx1:(_stxn=-1,nlx1-nlx2), _dtxr = nlx2>nlx0?nlx2-nlx0:(_stxr=-1,nlx0-nlx2), _dtxl = nlx1>nlx0?nlx1-nlx0:(_stxl=-1,nlx0-nlx1), _dtyn = nly2>nly1?nly2-nly1:(_styn=-1,nly1-nly2), _dtyr = nly2>nly0?nly2-nly0:(_styr=-1,nly0-nly2), _dtyl = nly1>nly0?nly1-nly0:(_styl=-1,nly0-nly1), _dlxn = ntx2>ntx1?ntx2-ntx1:(_slxn=-1,ntx1-ntx2), _dlxr = ntx2>ntx0?ntx2-ntx0:(_slxr=-1,ntx0-ntx2), _dlxl = ntx1>ntx0?ntx1-ntx0:(_slxl=-1,ntx0-ntx1), _dlyn = nty2>nty1?nty2-nty1:(_slyn=-1,nty1-nty2), _dlyr = nty2>nty0?nty2-nty0:(_slyr=-1,nty0-nty2), _dlyl = nty1>nty0?nty1-nty0:(_slyl=-1,nty0-nty1), _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, _dlxn-=_dyn?_dyn*(_dlxn/_dyn):0, _dlxr-=_dyr?_dyr*(_dlxr/_dyr):0, _dlxl-=_dyl?_dyl*(_dlxl/_dyl):0, _dlyn-=_dyn?_dyn*(_dlyn/_dyn):0, _dlyr-=_dyr?_dyr*(_dlyr/_dyr):0, _dlyl-=_dyl?_dyl*(_dlyl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, _errlxn = _errn, _errlyn = _errn, _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, _errlxr = _errr, _errlyr = _errr, _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, _errlxl = _errl, _errlyl = _errl, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rtxn = _dyn?(nlx2-nlx1)/_dyn:0, _rtyn = _dyn?(nly2-nly1)/_dyn:0, _rlxn = _dyn?(ntx2-ntx1)/_dyn:0, _rlyn = _dyn?(nty2-nty1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rtxr = _dyr?(nlx2-nlx0)/_dyr:0, _rtyr = _dyr?(nly2-nly0)/_dyr:0, _rlxr = _dyr?(ntx2-ntx0)/_dyr:0, _rlyr = _dyr?(nty2-nty0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), _rtxl = (ny0!=ny1 && ny1>0)?(_dyl?(nlx1-nlx0)/_dyl:0): (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), _rtyl = (ny0!=ny1 && ny1>0)?(_dyl?(nly1-nly0)/_dyl:0): (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ), _rlxl = (ny0!=ny1 && ny1>0)?(_dyl?(ntx1-ntx0)/_dyl:0): (_errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxn ), _rlyl = (ny0!=ny1 && ny1>0)?(_dyl?(nty1-nty0)/_dyl:0): (_errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyn ); _counter>=0; --_counter, ++y, xright0+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), lxright0+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), lyright0+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), txright0+=_rlxr+((_errlxr-=_dlxr)<0?_errlxr+=_dyr,_slxr:0), tyright0+=_rlyr+((_errlyr-=_dlyr)<0?_errlyr+=_dyr,_slyr:0), xleft0+=(y!=ny1)?(lxleft0+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), lyleft0+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), txleft0+=_rlxl+((_errlxl-=_dlxl)<0?(_errlxl+=_dyl,_slxl):0), tyleft0+=_rlyl+((_errlyl-=_dlyl)<0?(_errlyl+=_dyl,_slyl):0), _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, lxleft0=nlx1, _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, lyleft0=nly1, _errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxl=_rlxn, txleft0=ntx1, _errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyl=_rlyn, tyleft0=nty1, _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xleft0)) { int xleft = xleft0, xright = xright0, lxleft = lxleft0, lxright = lxright0, lyleft = lyleft0, lyright = lyright0, txleft = txleft0, txright = txright0, tyleft = tyleft0, tyright = tyright0; if (xrightlxleft?lxright-lxleft:lxleft-lxright, dly = lyright>lyleft?lyright-lyleft:lyleft-lyright, dtx = txright>txleft?txright-txleft:txleft-txright, dty = tyright>tyleft?tyright-tyleft:tyleft-tyright, rlx = dx?(lxright-lxleft)/dx:0, rly = dx?(lyright-lyleft)/dx:0, rtx = dx?(txright-txleft)/dx:0, rty = dx?(tyright-tyleft)/dx:0, slx = lxright>lxleft?1:-1, sly = lyright>lyleft?1:-1, stx = txright>txleft?1:-1, sty = tyright>tyleft?1:-1, ndlx = dlx-(dx?dx*(dlx/dx):0), ndly = dly-(dx?dx*(dly/dx):0), ndtx = dtx-(dx?dx*(dtx/dx):0), ndty = dty-(dx?dx*(dty/dx):0); int errlx = dx>>1, errly = errlx, errtx = errlx, errty = errlx; if (xleft<0 && dx) { lxleft-=xleft*(lxright-lxleft)/dx; lyleft-=xleft*(lyright-lyleft)/dx; txleft-=xleft*(txright-txleft)/dx; tyleft-=xleft*(tyright-tyleft)/dx; } if (xleft<0) xleft=0; if (xright>=dimx()-1) xright=dimx()-1; T* ptrd = ptr(xleft,y,0,0); if (opacity>=1) for (int x=xleft; x<=xright; ++x) { const tl l = light(lxleft,lyleft); const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval); ptrd+=whz; col+=twhz; } ptrd-=offx; lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } else for (int x=xleft; x<=xright; ++x) { const tl l = light(lxleft,lyleft); const t *col = texture.ptr(txleft,tyleft); for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval); *ptrd = (T)(nopacity*val + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0); tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0); } } } } return *this; } template CImg& draw_triangle(const int x0, const int y0, const float z0, const int x1, const int y1, const float z1, const int x2, const int y2, const float z2, const CImg& texture, const int tx0, const int ty0, const int tx1, const int ty1, const int tx2, const int ty2, const CImg& light, const int lx0, const int ly0, const int lx1, const int ly1, const int lx2, const int ly2, const float opacity=1.0f) { if (!is_empty() && z0>0 && z1>0 && z2>0) { if (!texture || texture.dim::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is not a valid argument.", pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data); if (!light) throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.", pixel_type(),light.width,light.height,light.depth,light.dim,light.data); 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); 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); static const T maxval = (T)cimg::min(cimg::type::max(),cimg::type::max()); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); const int whz = width*height*depth, twhz = texture.width*texture.height*texture.depth, offx = dim*whz-1; int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2, nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2; float ntx0 = tx0/z0, nty0 = ty0/z0, ntx1 = tx1/z1, nty1 = ty1/z1, ntx2 = tx2/z2, nty2 = ty2/z2, nz0 = 1.0f/z0, nz1 = 1.0f/z1, nz2 = 1.0f/z2; if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1,nz0,nz1); if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2,nz0,nz2); if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2,nz1,nz2); if (ny0=0) { float ptxl = (ntx1-ntx0)/(ny1-ny0), ptxr = (ntx2-ntx0)/(ny2-ny0), ptxn = (ntx2-ntx1)/(ny2-ny1), ptyl = (nty1-nty0)/(ny1-ny0), ptyr = (nty2-nty0)/(ny2-ny0), ptyn = (nty2-nty1)/(ny2-ny1), pzl = (nz1-nz0)/(ny1-ny0), pzr = (nz2-nz0)/(ny2-ny0), pzn = (nz2-nz1)/(ny2-ny1), zr = ny0>=0?nz0:(nz0-ny0*(nz2-nz0)/(ny2-ny0)), txr = ny0>=0?ntx0:(ntx0-ny0*(ntx2-ntx0)/(ny2-ny0)), tyr = ny0>=0?nty0:(nty0-ny0*(nty2-nty0)/(ny2-ny0)), zl = ny1>=0?(ny0>=0?nz0:(nz0-ny0*(nz1-nz0)/(ny1-ny0))):(pzl=pzn,(nz1-ny1*(nz2-nz1)/(ny2-ny1))), txl = ny1>=0?(ny0>=0?ntx0:(ntx0-ny0*(ntx1-ntx0)/(ny1-ny0))):(ptxl=ptxn,(ntx1-ny1*(ntx2-ntx1)/(ny2-ny1))), tyl = ny1>=0?(ny0>=0?nty0:(nty0-ny0*(nty1-nty0)/(ny1-ny0))):(ptyl=ptyn,(nty1-ny1*(nty2-nty1)/(ny2-ny1))); for (int y = ny0<0?0:ny0, xright0 = ny0>=0?nx0:(nx0-ny0*(nx2-nx0)/(ny2-ny0)), lxright0 = ny0>=0?nlx0:(nlx0-ny0*(nlx2-nlx0)/(ny2-ny0)), lyright0 = ny0>=0?nly0:(nly0-ny0*(nly2-nly0)/(ny2-ny0)), xleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nx1:nx0):(nx0-ny0*(nx1-nx0)/(ny1-ny0))):(nx1-ny1*(nx2-nx1)/(ny2-ny1)), lxleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nlx1:nlx0):(nlx0-ny0*(nlx1-nlx0)/(ny1-ny0))):(nlx1-ny1*(nlx2-nlx1)/(ny2-ny1)), lyleft0 = ny1>=0?(ny0>=0?(ny0==ny1?nly1:nly0):(nly0-ny0*(nly1-nly0)/(ny1-ny0))):(nly1-ny1*(nly2-nly1)/(ny2-ny1)), _sxn=1, _stxn=1, _styn=1, _sxr=1, _stxr=1, _styr=1, _sxl=1, _stxl=1, _styl=1, _dxn = nx2>nx1?nx2-nx1:(_sxn=-1,nx1-nx2), _dxr = nx2>nx0?nx2-nx0:(_sxr=-1,nx0-nx2), _dxl = nx1>nx0?nx1-nx0:(_sxl=-1,nx0-nx1), _dtxn = nlx2>nlx1?nlx2-nlx1:(_stxn=-1,nlx1-nlx2), _dtxr = nlx2>nlx0?nlx2-nlx0:(_stxr=-1,nlx0-nlx2), _dtxl = nlx1>nlx0?nlx1-nlx0:(_stxl=-1,nlx0-nlx1), _dtyn = nly2>nly1?nly2-nly1:(_styn=-1,nly1-nly2), _dtyr = nly2>nly0?nly2-nly0:(_styr=-1,nly0-nly2), _dtyl = nly1>nly0?nly1-nly0:(_styl=-1,nly0-nly1), _dyn = ny2-ny1, _dyr = ny2-ny0, _dyl = ny1-ny0, _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, _dxr-=_dyr?_dyr*(_dxr/_dyr):0, _dxl-=_dyl?_dyl*(_dxl/_dyl):0, _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, cimg::min((int)(*this).height-y-1,ny2-y)), _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, _rxn = _dyn?(nx2-nx1)/_dyn:0, _rtxn = _dyn?(nlx2-nlx1)/_dyn:0, _rtyn = _dyn?(nly2-nly1)/_dyn:0, _rxr = _dyr?(nx2-nx0)/_dyr:0, _rtxr = _dyr?(nlx2-nlx0)/_dyr:0, _rtyr = _dyr?(nly2-nly0)/_dyr:0, _rxl = (ny0!=ny1 && ny1>0)?(_dyl?(nx1-nx0)/_dyl:0): (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), _rtxl = (ny0!=ny1 && ny1>0)?(_dyl?(nlx1-nlx0)/_dyl:0): (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), _rtyl = (ny0!=ny1 && ny1>0)?(_dyl?(nly1-nly0)/_dyl:0): (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); _counter>=0; --_counter, ++y, xright0+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), lxright0+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), lyright0+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), xleft0+=(y!=ny1)?(lxleft0+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), lyleft0+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, lxleft0=nlx1, _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, lyleft0=nly1, _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, nx1-xleft0)) { if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; } int xleft = xleft0, xright = xright0, lxleft = lxleft0, lxright = lxright0, lyleft = lyleft0, lyright = lyright0; float zleft = zl, zright = zr, txleft = txl, txright = txr, tyleft = tyl, tyright = tyr; if (xrightlxleft?lxright-lxleft:lxleft-lxright, dly = lyright>lyleft?lyright-lyleft:lyleft-lyright, rlx = dx?(lxright-lxleft)/dx:0, rly = dx?(lyright-lyleft)/dx:0, slx = lxright>lxleft?1:-1, sly = lyright>lyleft?1:-1, ndlx = dlx-(dx?dx*(dlx/dx):0), ndly = dly-(dx?dx*(dly/dx):0); const float pentez = (zright-zleft)/dx, pentetx = (txright-txleft)/dx, pentety = (tyright-tyleft)/dx; int errlx = dx>>1, errly = errlx; if (xleft<0 && dx) { zleft-=xleft*(zright-zleft)/dx; lxleft-=xleft*(lxright-lxleft)/dx; lyleft-=xleft*(lyright-lyleft)/dx; txleft-=xleft*(txright-txleft)/dx; tyleft-=xleft*(tyright-tyleft)/dx; } if (xleft<0) xleft=0; if (xright>=dimx()-1) xright=dimx()-1; T* ptrd = ptr(xleft,y,0,0); if (opacity>=1) for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const tl l = light(lxleft,lyleft); const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval); ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); } else for (int x=xleft; x<=xright; ++x) { const float invz = 1.0f/zleft; const tl l = light(lxleft,lyleft); const t *col = texture.ptr((int)(txleft*invz),(int)(tyleft*invz)); for (int k = 0; k<(int)((*this).dim); ++k) { const T val = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval); *ptrd = (T)(nopacity*val + *ptrd*copacity); ptrd+=whz; col+=twhz; } ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety; lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0); lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0); } zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl; } } } return *this; } template CImg& _draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv, const tc *const color, const float opacity, const unsigned int pattern) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_ellipse : Specified color is (null).",pixel_type()); _draw_scanline(color,opacity); const float nr1 = cimg::abs(r1), nr2 = cimg::abs(r2), norm = (float)std::sqrt(ru*ru+rv*rv), u = norm>0?ru/norm:1, v = norm>0?rv/norm:0, rmax = cimg::max(nr1,nr2), l1 = (float)std::pow(rmax/(nr1>0?nr1:1e-6),2), l2 = (float)std::pow(rmax/(nr2>0?nr2:1e-6),2), a = l1*u*u + l2*v*v, b = u*v*(l1-l2), c = l1*v*v + l2*u*u; const int yb = (int)std::sqrt(a*rmax*rmax/(a*c-b*b)), tymin = y0-yb, tymax = y0+yb, ymin = tymin<0?0:tymin, ymax = tymax>=dimy()?height-1:tymax; int oxmin = 0, oxmax = 0; bool first_line = true; for (int y=ymin; y<=ymax; ++y) { const float Y = y-y0 + (y0?(float)std::sqrt(delta)/a:0.0f, bY = b*Y/a, fxmin = x0-0.5f-bY-sdelta, fxmax = x0+0.5f-bY+sdelta; const int xmin = (int)fxmin, xmax = (int)fxmax; if (!pattern) _draw_scanline(xmin,xmax,y,color,opacity); else { if (first_line) { if (y0-yb>=0) _draw_scanline(xmin,xmax,y,color,opacity); else draw_point(xmin,y,color,opacity).draw_point(xmax,y,color,opacity); first_line = false; } else { if (xmin CImg& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv, const tc *const color, const float opacity, const unsigned int pattern) { if (pattern) _draw_ellipse(x0,y0,r1,r2,ru,rv,color,opacity,pattern); return *this; } template CImg& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv, const CImg& color, const float opacity, const unsigned int pattern) { return draw_ellipse(x0,y0,r1,r2,ru,rv,color.data,opacity,pattern); } template CImg& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv, const tc *const color, const float opacity=1.0f) { return _draw_ellipse(x0,y0,r1,r2,ru,rv,color,opacity,0U); } template CImg& draw_ellipse(const int x0, const int y0, const float r1, const float r2, const float ru, const float rv, const CImg& color, const float opacity=1.0f) { return draw_ellipse(x0,y0,r1,r2,ru,rv,color.data,opacity); } template CImg& draw_ellipse(const int x0, const int y0, const CImg &tensor, const tc *const color, const float opacity=1.0f) { CImgList eig = tensor.get_symmetric_eigen(); const CImg &val = eig[0], &vec = eig[1]; return draw_ellipse(x0,y0,val(0),val(1),vec(0,0),vec(0,1),color,opacity); } template CImg& draw_ellipse(const int x0, const int y0, const CImg &tensor, const CImg& color, const float opacity=1.0f) { return draw_ellipse(x0,y0,tensor,color.data,opacity); } template CImg& draw_ellipse(const int x0, const int y0, const CImg &tensor, const tc *const color, const float opacity, const unsigned int pattern) { CImgList eig = tensor.get_symmetric_eigen(); const CImg &val = eig[0], &vec = eig[1]; return draw_ellipse(x0,y0,val(0),val(1),vec(0,0),vec(0,1),color,opacity,pattern); } template CImg& draw_ellipse(const int x0, const int y0, const CImg &tensor, const CImg& color, const float opacity, const unsigned int pattern) { return draw_ellipse(x0,y0,tensor,color.data,opacity,pattern); } template CImg& draw_circle(const int x0, const int y0, int radius, const tc *const color, const float opacity=1.0f) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_circle : Specified color is (null).",pixel_type()); _draw_scanline(color,opacity); if (radius<0 || x0-radius>=dimx() || y0+radius<0 || y0-radius>=dimy()) return *this; if (y0>=0 && y0=0) { const int x1 = x0-x, x2 = x0+x, y1 = y0-y, y2 = y0+y; if (y1>=0 && y1=0 && y2=0 && y1=0 && y2 CImg& draw_circle(const int x0, const int y0, int radius, const CImg& color, const float opacity=1.0f) { return draw_circle(x0,y0,radius,color.data,opacity); } template CImg& draw_circle(const int x0, const int y0, int radius, const tc *const color, const float opacity, const unsigned int) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_circle : Specified color is (null).",pixel_type()); if (radius<0 || x0-radius>=dimx() || y0+radius<0 || y0-radius>=dimy()) return *this; if (!radius) return draw_point(x0,y0,color,opacity); draw_point(x0-radius,y0,color,opacity).draw_point(x0+radius,y0,color,opacity). draw_point(x0,y0-radius,color,opacity).draw_point(x0,y0+radius,color,opacity); if (radius==1) return *this; for (int f=1-radius, ddFx=0, ddFy=-(radius<<1), x=0, y=radius; x=0) { f+=(ddFy+=2); --y; } ++x; ++(f+=(ddFx+=2)); if (x!=y+1) { 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; draw_point(x1,y1,color,opacity).draw_point(x1,y2,color,opacity). draw_point(x2,y1,color,opacity).draw_point(x2,y2,color,opacity); if (x!=y) draw_point(x3,y3,color,opacity).draw_point(x4,y4,color,opacity). draw_point(x4,y3,color,opacity).draw_point(x3,y4,color,opacity); } } } return *this; } template CImg& draw_circle(const int x0, const int y0, int radius, const CImg& color, const float opacity, const unsigned int foo) { return draw_circle(x0,y0,radius,color.data,opacity,foo); } template CImg& draw_text(const char *const text, const int x0, const int y0, const T *const fgcolor, const T *const bgcolor, const CImgList& font, const float opacity=1.0f) { if (!text) throw CImgArgumentException("CImg<%s>::draw_text() : Specified input string is (null).",pixel_type()); if (!font) throw CImgArgumentException("CImg<%s>::draw_text() : Specified font (%u,%p) is empty.", pixel_type(),font.size,font.data); if (is_empty()) { int x = 0, y = 0, w = 0; for (int i=0; iw) w = x; x = 0; break; case '\t': x+=4*font[' '].width; break; default: if (cw) w=x; y+=font[' '].height; } assign(x0+w,y0+y,1,font[' '].dim,0); if (bgcolor) for (int k = 0; k<(int)((*this).dim); ++k) get_shared_channel(k).fill((T)bgcolor[k]); } int x = x0, y = y0; CImg letter; for (int i=0; i& mask = (c+256)<(int)font.size?font[c+256]:font[c]; if (fgcolor) for (unsigned int p=0; p=512) draw_image(letter,mask,x,y,0,0,(T)1,opacity); else draw_image(letter,x,y,0,0,opacity); x+=letter.width; } break; } } return *this; } template CImg& draw_text(const char *const text, const int x0, const int y0, const CImg& fgcolor, const CImg& bgcolor, const CImgList& font, const float opacity=1.0f) { const CImg fgcol(fgcolor), bgcol(bgcolor); return draw_text(text,x0,y0,fgcol.data,bgcol.data,font,opacity); } CImg& draw_text(const char *const text, const int x0, const int y0, const T *const fgcolor, const T *const bgcolor=0, const unsigned int font_size=11, const float opacity=1.0f) { return draw_text(text,x0,y0,fgcolor,bgcolor,CImgList::get_font(font_size),opacity); } template CImg& draw_text(const char *const text, const int x0, const int y0, const CImg& fgcolor, const CImg& bgcolor, const unsigned int font_size=11, const float opacity=1.0f) { const CImg fgcol(fgcolor), bgcol(bgcolor); return draw_text(text,x0,y0,fgcol.data,bgcol.data,font_size,opacity); } CImg& draw_text(const int x0, const int y0, const T *const fgcolor, const T *const bgcolor, const unsigned int font_size, const float opacity, const char *format, ...) { char tmp[2048] = { 0 }; std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(tmp,format,ap); __builtin_va_end(ap); return draw_text(tmp,x0,y0,fgcolor,bgcolor,font_size,opacity); } template CImg& draw_text(const int x0, const int y0, const CImg& fgcolor, const CImg& bgcolor, const unsigned int font_size, const float opacity, const char *format, ...) { char tmp[2048] = { 0 }; std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(tmp,format,ap); __builtin_va_end(ap); return draw_text(tmp,x0,y0,fgcolor,bgcolor,font_size,opacity); } template CImg& draw_text(const int x0, const int y0, const T *const fgcolor, const T *const bgcolor, const CImgList& font, const float opacity, const char *format, ...) { char tmp[2048] = { 0 }; std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(tmp,format,ap); __builtin_va_end(ap); return draw_text(tmp,x0,y0,fgcolor,bgcolor,font,opacity); } template CImg& draw_text(const int x0, const int y0, const CImg& fgcolor, const CImg& bgcolor, const CImgList& font, const float opacity, const char *format, ...) { char tmp[2048] = { 0 }; std::va_list ap; __builtin_va_start(ap,format); std::vsprintf(tmp,format,ap); __builtin_va_end(ap); return draw_text(tmp,x0,y0,fgcolor,bgcolor,font,opacity); } template CImg& draw_quiver(const CImg& flow, const t2 *const color, const unsigned int sampling=25, const float factor=-20, const int quiver_type=0, const float opacity=1.0f, const unsigned int pattern=~0U) { return draw_quiver(flow,CImg(color,dim,1,1,1,true),sampling,factor,quiver_type,opacity,pattern); } template CImg& draw_quiver(const CImg& flow, const CImg& color, const unsigned int sampling=25, const float factor=-20, const int quiver_type=0, const float opacity=1.0f, const unsigned int pattern=~0U) { if (!is_empty()) { if (!flow || flow.dim!=2) throw CImgArgumentException("CImg<%s>::draw_quiver() : Specified flow (%u,%u,%u,%u,%p) has wrong dimensions.", pixel_type(),flow.width,flow.height,flow.depth,flow.dim,flow.data); if (sampling<=0) throw CImgArgumentException("CImg<%s>::draw_quiver() : Incorrect sampling value = %g",pixel_type(),sampling); const bool colorfield = (color.width==flow.width && color.height==flow.height && color.depth==1 && color.dim==dim); if (is_overlapping(flow)) return draw_quiver(+flow,color,sampling,factor,quiver_type,opacity,pattern); float vmax,fact; if (factor<=0) { float m, M = (float)flow.get_norm_pointwise(2).maxmin(m); vmax = (float)cimg::max(cimg::abs(m),cimg::abs(M)); fact = -factor; } else { fact = factor; vmax = 1; } for (unsigned int y=sampling/2; y CImg& draw_graph(const CImg& data, const tc *const color, const unsigned int gtype=1, const double ymin=0, const double ymax=0, const float opacity=1.0f, const unsigned int pattern=~0U) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_graph() : Specified color is (null)",pixel_type()); tc *color1 = new tc[dim], *color2 = new tc[dim]; for (int k = 0; k<(int)((*this).dim); ++k) { color1[k]=(tc)(color[k]*0.6f); color2[k]=(tc)(color[k]*0.3f); } float m = (float)ymin, M = (float)ymax; if (ymin==ymax) m = (float)data.maxmin(M); if (m==M) { --m; ++M; } const float ca = height>1?(float)(M-m)/(height-1):0; const int Y0 = (int)(-m/ca); int pY = 0; bool init_hatch = true; if (gtype<3) for (unsigned int off = 0; off<(data).size(); ++off) { const int Y = (int)((data[off]-m)/ca); switch (gtype) { case 0: { const unsigned int X = off*width/data.size(); draw_point(X,Y,color,opacity); } break; case 1: if (off>0) { draw_line((int)((off-1)*width/data.size()),pY,(int)(off*width/data.size()),Y,color,opacity,pattern,init_hatch); init_hatch = false; } break; case 2: { const unsigned int X = off*width/data.size(), nX = (off+1)*width/data.size()-1; draw_rectangle(X,(int)Y0,nX,Y,color1,opacity); draw_line(X,Y,X,(int)Y0,color2,opacity); draw_line(X,(int)Y0,nX,(int)Y0,Y<=Y0?color2:color,opacity); draw_line(nX,Y,nX,(int)Y0,color,opacity); draw_line(X,Y,nX,Y,Y<=Y0?color:color2,opacity); } break; } pY = Y; } else { const CImg ndata = data.get_shared_points(0,data.size()-1); for (int x = 0; x<(int)((*this).width); ++x) { const int Y = (int)((ndata.cubic_pix1d((float)x*ndata.width/width)-m)/ca); if (x>0) draw_line(x,pY,x+1,Y,color,opacity,pattern,init_hatch); init_hatch = false; pY = Y; } } delete[] color1; delete[] color2; } return *this; } template CImg& draw_graph(const CImg& data, const CImg& color, const unsigned int gtype=1, const double ymin=0, const double ymax=0, const float opacity=1.0f, const unsigned int pattern=~0U) { return draw_graph(data,color.data,gtype,ymin,ymax,opacity,pattern); } template CImg& draw_axis(const CImg& xvalues, const int y, const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U) { if (!is_empty()) { int siz = (int)xvalues.size()-1; if (siz<=0) draw_line(0,y,width-1,y,color,opacity,pattern); else { if (xvalues[0] CImg& draw_axis(const CImg& xvalues, const int y, const CImg& color, const float opacity=1.0f, const unsigned int pattern=~0U) { return draw_axis(xvalues,y,color.data,opacity,pattern); } template CImg& draw_axis(const int x, const CImg& yvalues, const tc *const color, const float opacity=1.0f, const unsigned int pattern=~0U) { if (!is_empty()) { int siz = (int)yvalues.size()-1; if (siz<=0) draw_line(x,0,x,height-1,color,opacity,pattern); else { if (yvalues[0]=dimy()-11?dimy()-11:tmp), xt = x-(int)std::strlen(txt)*7; draw_point(x-1,yi,color,opacity).draw_point(x+1,yi,color,opacity); if (xt>0) draw_text(txt,xt,nyi,color,(tc*)0,11,opacity); else draw_text(txt,x+3,nyi,color,(tc*)0,11,opacity); } } } return *this; } template CImg& draw_axis(const int x, const CImg& yvalues, const CImg& color, const float opacity=1.0f, const unsigned int pattern=~0U) { return draw_axis(x,yvalues,color.data,opacity,pattern); } template CImg& draw_axis(const CImg& xvalues, const CImg& yvalues, const tc *const color, const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) { if (!is_empty()) { const CImg nxvalues(xvalues.data,xvalues.size(),1,1,1,true); const int sizx = (int)xvalues.size()-1, wm1 = (int)(width)-1; if (sizx>0) { float ox = (float)nxvalues[0]; for (unsigned int x=1; x nyvalues(yvalues.data,yvalues.size(),1,1,1,true); const int sizy = (int)yvalues.size()-1, hm1 = (int)(height)-1; if (sizy>0) { float oy = (float)nyvalues[0]; for (unsigned int y=1; y CImg& draw_axis(const CImg& xvalues, const CImg& yvalues, const CImg& color, const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) { return draw_axis(xvalues,yvalues,color.data,opacity,patternx,patterny); } template CImg& draw_axis(const float x0, const float x1, const float y0, const float y1, const tc *const color, const int subdivisionx=-60, const int subdivisiony=-60, const float precisionx=0, const float precisiony=0, const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) { const float dx = cimg::abs(x1-x0), dy = cimg::abs(y1-y0); const float px = (precisionx==0)?(float)std::pow(10.0,(int)std::log10(dx)-2.0):precisionx, py = (precisiony==0)?(float)std::pow(10.0,(int)std::log10(dy)-2.0):precisiony; return draw_axis(CImg::sequence(subdivisionx>0?subdivisionx:1-dimx()/subdivisionx,x0,x1).round(px), CImg::sequence(subdivisiony>0?subdivisiony:1-dimy()/subdivisiony,y0,y1).round(py), color,opacity,patternx,patterny); } template CImg& draw_axis(const float x0, const float x1, const float y0, const float y1, const CImg& color, const int subdivisionx=-60, const int subdivisiony=-60, const float precisionx=0, const float precisiony=0, const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) { return draw_axis(x0,x1,y0,y1,color.data,subdivisionx,subdivisiony,precisionx,precisiony,opacity,patternx,patterny); } template CImg& draw_grid(const CImg& xvalues, const CImg& yvalues, const tc *const color, const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) { if (!is_empty()) { if (xvalues) for (unsigned int x = 0; x<(xvalues).size(); ++x) { const int xi = (int)xvalues[x]; if (xi>=0 && xi=0 && yi CImg& draw_grid(const CImg& xvalues, const CImg& yvalues, const CImg& color, const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) { return draw_grid(xvalues,yvalues,color.data,opacity,patternx,patterny); } template CImg& draw_grid(const float deltax, const float deltay, const float offsetx, const float offsety, const bool invertx, const bool inverty, const tc *const color, const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) { CImg seqx, seqy; if (deltax!=0) { const float dx = deltax>0?deltax:width*-deltax/100; const unsigned int nx = (unsigned int)(width/dx); seqx = CImg::sequence(1+nx,0,(unsigned int)(dx*nx)); if (offsetx) for (unsigned int x = 0; x<(seqx).size(); ++x) seqx(x) = (unsigned int)cimg::mod(seqx(x)+offsetx,(float)width); if (invertx) for (unsigned int x = 0; x<(seqx).size(); ++x) seqx(x) = width-1-seqx(x); } if (deltay!=0) { const float dy = deltay>0?deltay:height*-deltay/100; const unsigned int ny = (unsigned int)(height/dy); seqy = CImg::sequence(1+ny,0,(unsigned int)(dy*ny)); if (offsety) for (unsigned int y = 0; y<(seqy).size(); ++y) seqy(y) = (unsigned int)cimg::mod(seqy(y)+offsety,(float)height); if (inverty) for (unsigned int y = 0; y<(seqy).size(); ++y) seqy(y) = height-1-seqy(y); } return draw_grid(seqx,seqy,color,opacity,patternx,patterny); } template CImg& draw_grid(const float deltax, const float deltay, const float offsetx, const float offsety, const bool invertx, const bool inverty, const CImg& color, const float opacity=1.0f, const unsigned int patternx=~0U, const unsigned int patterny=~0U) { return draw_grid(deltax,deltay,offsetx,offsety,invertx,inverty,color.data,opacity,patternx,patterny); } template CImg& draw_fill(const int x, const int y, const int z, const tc *const color, CImg& region, const float sigma=0, const float opacity=1.0f, const bool high_connexity=false) { if (!color) throw CImgArgumentException("CImg<%s>::draw_fill() : Specified color is (null).",pixel_type()); region.assign(width,height,depth,1,(t)0); if (x>=0 || x=0 || y=0 || z::type itype; const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); const unsigned int whz = width*height*depth, siz = dim*whz, W1 = width-1, H1 = height-1, D1 = depth-1; const bool threed = depth>1; const CImg reference_color = get_vector_at(x,y,z); CImg remaining(3,512,1,1,0); remaining(0,0) = x; remaining(1,0) = y; remaining(2,0) = z; unsigned int posr0 = 0, posr1 = 1; region(x,y,z) = (t)1; const t noregion = ((t)1==(t)2)?(t)0:(t)(-1); if (threed) do { const unsigned int *pcurr = remaining.ptr(0,posr0++), xc = *(pcurr++), yc = *(pcurr++), zc = *(pcurr++); if (posr0>=512) { remaining.translate(0,posr0); posr1-=posr0; posr0 = 0; } bool cont, res; unsigned int nxc = xc; do { { const tc *col = color; T *ptrd = ptr(nxc,yc,zc); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (yc!=0) { const unsigned int tx = nxc, ty = yc-1, tz = zc; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (yc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (zc!=0) { const unsigned int tx = nxc, ty = yc, tz = zc-1; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (zc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (nxc) { --nxc; if (region(nxc,yc,zc)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(nxc,yc,zc) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(nxc,yc,zc) = (t)(cont?1:noregion); }; } else cont = false; } while (cont); nxc = xc; do { if ((++nxc)<=W1) { if (region(nxc,yc,zc)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(nxc,yc,zc) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(nxc,yc,zc) = (t)(cont?1:noregion); }; } else cont = false; if (cont) { { const tc *col = color; T *ptrd = ptr(nxc,yc,zc); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (yc!=0) { const unsigned int tx = nxc, ty = yc-1, tz = zc; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (yc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (zc!=0) { const unsigned int tx = nxc, ty = yc, tz = zc-1; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (zc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; } } while (cont); unsigned int nyc = yc; do { if (nyc) { --nyc; if (region(xc,nyc,zc)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(xc,nyc,zc) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(xc,nyc,zc) = (t)(cont?1:noregion); }; } else cont = false; if (cont) { { const tc *col = color; T *ptrd = ptr(xc,nyc,zc); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (xc!=0) { const unsigned int tx = xc-1, ty = nyc, tz = zc; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (zc!=0) { const unsigned int tx = xc, ty = nyc, tz = zc-1; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (zc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; } } while (cont); nyc = yc; do { if ((++nyc)<=H1) { if (region(xc,nyc,zc)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(xc,nyc,zc) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(xc,nyc,zc) = (t)(cont?1:noregion); }; } else cont = false; if (cont) { { const tc *col = color; T *ptrd = ptr(xc,nyc,zc); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (xc!=0) { const unsigned int tx = xc-1, ty = nyc, tz = zc; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (zc!=0) { const unsigned int tx = xc, ty = nyc, tz = zc-1; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (zc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; } } while (cont); unsigned int nzc = zc; do { if (nzc) { --nzc; if (region(xc,yc,nzc)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(xc,yc,nzc) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(xc,yc,nzc) = (t)(cont?1:noregion); }; } else cont = false; if (cont) { { const tc *col = color; T *ptrd = ptr(xc,yc,nzc); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (xc!=0) { const unsigned int tx = xc-1, ty = yc, tz = nzc; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (yc!=0) { const unsigned int tx = xc, ty = yc-1, tz = nzc; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (yc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; } } while (cont); nzc = zc; do { if ((++nzc)<=D1) { if (region(xc,yc,nzc)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(xc,yc,nzc) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(xc,yc,nzc) = (t)(cont?1:noregion); }; } else cont = false; if (cont) { { const tc *col = color; T *ptrd = ptr(xc,nyc,zc); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (xc!=0) { const unsigned int tx = xc-1, ty = yc, tz = nzc; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (yc!=0) { const unsigned int tx = xc, ty = yc-1, tz = nzc; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (yc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; } } while (cont); } while (posr1>posr0); else do { const unsigned int *pcurr = remaining.ptr(0,posr0++), xc = *(pcurr++), yc = *(pcurr++); if (posr0>=512) { remaining.translate(0,posr0); posr1-=posr0; posr0 = 0; } bool cont, res; unsigned int nxc = xc; do { { const tc *col = color; T *ptrd = ptr(nxc,yc,0); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (yc!=0) { const unsigned int tx = nxc, ty = yc-1, tz = 0; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (yc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (high_connexity) { if ((nxc!=0 && yc!=0)) { const unsigned int tx = nxc-1, ty = yc-1, tz = 0; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((nxc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((nxc!=0 && yc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((nxc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; } if (nxc) { --nxc; if (region(nxc,yc,0)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(nxc,yc,0) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(nxc,yc,0) = (t)(cont?1:noregion); }; } else cont = false; } while (cont); nxc = xc; do { if ((++nxc)<=W1) { if (region(nxc,yc,0)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(nxc,yc,0) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(nxc,yc,0) = (t)(cont?1:noregion); }; } else cont = false; if (cont) { { const tc *col = color; T *ptrd = ptr(nxc,yc,0); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (yc!=0) { const unsigned int tx = nxc, ty = yc-1, tz = 0; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (yc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (high_connexity) { if ((nxc!=0 && yc!=0)) { const unsigned int tx = nxc-1, ty = yc-1, tz = 0; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((nxc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((nxc!=0 && yc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((nxc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; } } } while (cont); unsigned int nyc = yc; do { if (nyc) { --nyc; if (region(xc,nyc,0)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(xc,nyc,0) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(xc,nyc,0) = (t)(cont?1:noregion); }; } else cont = false; if (cont) { { const tc *col = color; T *ptrd = ptr(xc,nyc,0); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (xc!=0) { const unsigned int tx = xc-1, ty = nyc, tz = 0; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (high_connexity) { if ((xc!=0 && nyc!=0)) { const unsigned int tx = xc-1, ty = nyc-1, tz = 0; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((xc!=0 && nyc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; } } } while (cont); nyc = yc; do { if ((++nyc)<=H1) { if (region(xc,nyc,0)) cont = false; else { cont = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(xc,nyc,0) + siz; for (unsigned int i = dim; cont && i; --i) { ptrs-=whz; cont = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(xc,nyc,0) = (t)(cont?1:noregion); }; } else cont = false; if (cont) { { const tc *col = color; T *ptrd = ptr(xc,nyc,0); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)*(col++); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; } }; if (xc!=0) { const unsigned int tx = xc-1, ty = nyc, tz = 0; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if (high_connexity) { if ((xc!=0 && nyc!=0)) { const unsigned int tx = xc-1, ty = nyc-1, tz = 0; if (region(tx,ty,tz)) res = false; else { res = true; const T *reference_col = reference_color.ptr() + dim, *ptrs = ptr(tx,ty,tz) + siz; for (unsigned int i = dim; res && i; --i) { ptrs-=whz; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } region(tx,ty,tz) = (t)(res?1:noregion); }; if (res) { if (posr1>=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((xc!=0 && nyc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; if ((xc=remaining.height) remaining.resize(3,remaining.height<<1,1,1,0); unsigned int *ptrr = remaining.ptr(0,posr1); *(ptrr++) = tx; *(ptrr++) = ty; *(ptrr++) = tz; ++posr1; }; }; } } } while (cont); } while (posr1>posr0); if (noregion) for (t *ptr = (region).data + (region).size(); (ptr--)>(region).data; ) if (*ptr==noregion) *ptr = (t)0; } return *this; } template CImg& draw_fill(const int x, const int y, const int z, const CImg& color, CImg& region, const float sigma=0, const float opacity=1.0f, const bool high_connexity=false) { return draw_fill(x,y,z,color.data,region,sigma,opacity,high_connexity); } template CImg& draw_fill(const int x, const int y, const int z, const tc *const color, const float sigma=0, const float opacity=1.0f, const bool high_connexity=false) { CImg tmp; return draw_fill(x,y,z,color,tmp,sigma,opacity,high_connexity); } template CImg& draw_fill(const int x, const int y, const int z, const CImg& color, const float sigma=0, const float opacity=1.0f, const bool high_connexity=false) { return draw_fill(x,y,z,color.data,sigma,opacity,high_connexity); } template CImg& draw_fill(const int x, const int y, const tc *const color, const float sigma=0, const float opacity=1.0f, const bool high_connexity=false) { CImg tmp; return draw_fill(x,y,0,color,tmp,sigma,opacity,high_connexity); } template CImg& draw_fill(const int x, const int y, const CImg& color, const float sigma=0, const float opacity=1.0f, const bool high_connexity=false) { return draw_fill(x,y,color.data,sigma,opacity,high_connexity); } CImg& draw_plasma(const int x0, const int y0, const int x1, const int y1, const double alpha=1.0, const double beta=1.0, const float opacity=1.0f) { if (!is_empty()) { typedef typename cimg::superset::type ftype; const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); int nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1; if (nx1=dimx()) nx1 = width-1; if (ny0<0) ny0 = 0; if (ny1>=dimy()) ny1 = height-1; const int xc = (nx0+nx1)/2, yc = (ny0+ny1)/2, dx = (xc-nx0), dy = (yc-ny0); const ftype dc = (ftype)(std::sqrt((double)(dx*dx+dy*dy))*alpha + beta); ftype val = 0; for (int k = 0; k<(int)((*this).dim); ++k) { if (opacity>=1) { const ftype val0 = (*this)(nx0,ny0,0,k), val1 = (*this)(nx1,ny0,0,k), val2 = (*this)(nx0,ny1,0,k), val3 = (*this)(nx1,ny1,0,k); (*this)(xc,ny0,0,k) = (T)((val0+val1)/2); (*this)(xc,ny1,0,k) = (T)((val2+val3)/2); (*this)(nx0,yc,0,k) = (T)((val0+val2)/2); (*this)(nx1,yc,0,k) = (T)((val1+val3)/2); do { val = (ftype)(0.25f*((ftype)((*this)(nx0,ny0,0,k)) + (ftype)((*this)(nx1,ny0,0,k)) + (ftype)((*this)(nx1,ny1,0,k)) + (ftype)((*this)(nx0,ny1,0,k))) + dc*cimg::grand()); } while (val<(ftype)cimg::type::min() || val>(ftype)cimg::type::max()); (*this)(xc,yc,0,k) = (T)val; } else { const ftype val0 = (*this)(nx0,ny0,0,k), val1 = (*this)(nx1,ny0,0,k), val2 = (*this)(nx0,ny1,0,k), val3 = (*this)(nx1,ny1,0,k); (*this)(xc,ny0,0,k) = (T)(((val0+val1)*nopacity + copacity*(*this)(xc,ny0,0,k))/2); (*this)(xc,ny1,0,k) = (T)(((val2+val3)*nopacity + copacity*(*this)(xc,ny1,0,k))/2); (*this)(nx0,yc,0,k) = (T)(((val0+val2)*nopacity + copacity*(*this)(nx0,yc,0,k))/2); (*this)(nx1,yc,0,k) = (T)(((val1+val3)*nopacity + copacity*(*this)(nx1,yc,0,k))/2); do { val = (ftype)(0.25f*(((ftype)((*this)(nx0,ny0,0,k)) + (ftype)((*this)(nx1,ny0,0,k)) + (ftype)((*this)(nx1,ny1,0,k)) + (ftype)((*this)(nx0,ny1,0,k))) + dc*cimg::grand())*nopacity + copacity*(*this)(xc,yc,0,k)); } while (val<(ftype)cimg::type::min() || val>(ftype)cimg::type::max()); (*this)(xc,yc,0,k) = (T)val; } } if (xc!=nx0 || yc!=ny0) { draw_plasma(nx0,ny0,xc,yc,alpha,beta,opacity); draw_plasma(xc,ny0,nx1,yc,alpha,beta,opacity); draw_plasma(nx0,yc,xc,ny1,alpha,beta,opacity); draw_plasma(xc,yc,nx1,ny1,alpha,beta,opacity); } } return *this; } CImg& draw_plasma(const double alpha=1.0, const double beta=1.0, const float opacity=1.0f) { return draw_plasma(0,0,width-1,height-1,alpha,beta,opacity); } template CImg& draw_gaussian(const float xc, const double sigma, const tc *const color, const float opacity=1.0f) { if (!is_empty()) { if (!color) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Specified color is (null)",pixel_type()); const double sigma2 = 2*sigma*sigma; const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); const unsigned int whz = width*height*depth; const tc *col = color; for (int x = 0; x<(int)((*this).width); ++x) { const float dx = (x-xc); const double val = std::exp( -dx*dx/sigma2 ); T *ptrd = ptr(x,0,0,0); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whz; } col-=dim; } } return *this; } template CImg& draw_gaussian(const float xc, const double sigma, const CImg& color, const float opacity=1.0f) { return draw_gaussian(xc,sigma,color.data,opacity); } template CImg& draw_gaussian(const float xc, const float yc, const CImg& tensor, const tc *const color, const float opacity=1.0f) { typedef typename cimg::superset::type ftype; if (!is_empty()) { if (tensor.width!=2 || tensor.height!=2 || tensor.depth!=1 || tensor.dim!=1) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Tensor parameter (%u,%u,%u,%u,%p) is not a 2x2 matrix.", pixel_type(),tensor.width,tensor.height,tensor.depth,tensor.dim,tensor.data); if (!color) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Specified color is (null)",pixel_type()); const CImg invT = tensor.get_invert(), invT2 = (invT*invT)/(-2.0); const ftype a = invT2(0,0), b = 2*invT2(1,0), c = invT2(1,1); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); const unsigned int whz = width*height*depth; const tc *col = color; float dy = -yc; for (int y = 0; y<(int)((*this).height); ++y) { float dx = -xc; for (int x = 0; x<(int)((*this).width); ++x) { const float val = (float)std::exp(a*dx*dx + b*dx*dy + c*dy*dy); T *ptrd = ptr(x,y,0,0); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whz; } col-=dim; ++dx; } ++dy; } } return *this; } template CImg& draw_gaussian(const float xc, const float yc, const CImg& tensor, const CImg& color, const float opacity=1.0f) { return draw_gaussian(xc,yc,tensor,color.data,opacity); } template CImg& draw_gaussian(const float xc, const float yc, const float sigma, const tc *const color, const float opacity=1.0f) { return draw_gaussian(xc,yc,CImg::diagonal(sigma,sigma),color,opacity); } template CImg& draw_gaussian(const float xc, const float yc, const float sigma, const CImg& color, const float opacity=1.0f) { return draw_gaussian(xc,yc,sigma,color.data,opacity); } template CImg& draw_gaussian(const float xc, const float yc, const float zc, const CImg& tensor, const tc *const color, const float opacity=1.0f) { if (!is_empty()) { if (tensor.width!=3 || tensor.height!=3 || tensor.depth!=1 || tensor.dim!=1) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Tensor parameter (%u,%u,%u,%u,%p) is not a 3x3 matrix.", pixel_type(),tensor.width,tensor.height,tensor.depth,tensor.dim,tensor.data); const CImg invT = tensor.get_invert(), invT2 = (invT*invT)/(-2.0); 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); const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f); const unsigned int whz = width*height*depth; const tc *col = color; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const float dx = (x-xc), dy = (y-yc), dz = (z-zc); const double val = std::exp(a*dx*dx + b*dx*dy + c*dx*dz + d*dy*dy + e*dy*dz + f*dz*dz); T *ptrd = ptr(x,y,z,0); if (opacity>=1) for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; } else for (int k = 0; k<(int)((*this).dim); ++k) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whz; } col-=dim; } } return *this; } template CImg& draw_gaussian(const float xc, const float yc, const float zc, const CImg& tensor, const CImg& color, const float opacity=1.0f) { return draw_gaussian(xc,yc,zc,tensor,color.data,opacity); } template CImg& draw_gaussian(const float xc, const float yc, const float zc, const double sigma, const tc *const color, const float opacity=1.0f) { return draw_gaussian(xc,yc,zc,CImg::diagonal(sigma,sigma,sigma),color,opacity); } template CImg& draw_gaussian(const float xc, const float yc, const float zc, const double sigma, const CImg& color, const float opacity=1.0f) { return draw_gaussian(xc,yc,zc,sigma,color.data,opacity); } template CImg& draw_object3d(const float X, const float Y, const float Z, const CImg& points, const CImgList& primitives, const CImgList& colors, const CImgList& opacities, const unsigned int render_type=4, const bool double_sided=false, const float focale=500, const float lightx=0, const float lighty=0, const float lightz=-5000, const float specular_light=0.2f, const float specular_shine=0.1f) { static CImg light_texture; if (is_empty() || !points || !primitives) return *this; if (!colors || !opacities) throw CImgArgumentException("CImg<%s>::draw_object3d() : Undefined colors or opacities",pixel_type()); if (points.height<3) return draw_object3d(X,Y,Z,points.get_resize(-100,3,1,1,0),primitives,colors,opacities, render_type,double_sided,focale,lightx,lighty,lightz,specular_light,specular_shine); const float nspec = 1-(specular_light<0?0:(specular_light>1?1:specular_light)), nspec2 = 1+(specular_shine<0?0:specular_shine), nsl1 = (nspec2-1)/cimg::sqr(nspec-1), nsl2 = (1-2*nsl1*nspec), nsl3 = nspec2-nsl1-nsl2; if (render_type==5) { if (colors.size>primitives.size) light_texture.assign(colors[primitives.size])/=255; else { static float olightx = 0, olighty = 0, olightz = 0, ospecular_shine = 0; if (!light_texture || lightx!=olightx || lighty!=olighty || lightz!=olightz || specular_shine!=ospecular_shine) { light_texture.assign(512,512); const float white[] = { 1.0f }, dlx = lightx-X, dly = lighty-Y, dlz = lightz-Z, nl = (float)std::sqrt(dlx*dlx+dly*dly+dlz*dlz), nlx = light_texture.width/2*(1+dlx/nl), nly = light_texture.height/2*(1+dly/nl); light_texture.draw_gaussian(nlx,nly,light_texture.width/3.0f,white); for (int y = 0; y<(int)((light_texture).height); ++y) for (int x = 0; x<(int)((light_texture).width); ++x) { const float factor = light_texture(x,y); if (factor>nspec) light_texture(x,y) = cimg::min(2.0f,nsl1*factor*factor+nsl2*factor+nsl3); } olightx = lightx; olighty = lighty; olightz = lightz; ospecular_shine = specular_shine; } } } CImg projections(points.width,2); for (int l = 0; l<(int)((points).width); ++l) { const float x = (float)points(l,0), y = (float)points(l,1), z = (float)points(l,2); const float projectedz = z + Z + focale; projections(l,1) = Y + focale*y/projectedz; projections(l,0) = X + focale*x/projectedz; } CImg visibles(primitives.size); CImg zrange(primitives.size); unsigned int nb_visibles = 0; const float zmin = -focale+1.5f; { for (unsigned int l=0; l<(primitives).size; ++l) { const CImg& primitive = primitives[l]; switch (primitive.size()) { case 1: { const unsigned int i0 = (unsigned int)primitive(0); const float x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)); if (z0>zmin && x0>=0 && x0=0 && y0zmin && x0+radius>=0 && x0-radius=0 && y0-radiuszmin && z1>zmin && xM>=0 && xm=0 && ymxM) xM = x2; if (y0yM) yM = y2; if (z0>zmin && z1>zmin && z2>zmin && xM>=0 && xm=0 && ymxM) xM = x2; if (x3xM) xM = x3; if (y0yM) yM = y2; if (y3yM) yM = y3; if (z0>zmin && z1>zmin && z2>zmin && z3>zmin && xM>=0 && xm=0 && ym::draw_object3d() : Primitive %u is invalid (size = %u, can be 1,2,3,4,5,6,9 or 12)", pixel_type(),l,primitive.size()); }} } if (nb_visibles<=0) return *this; CImg permutations; CImg(zrange.data,nb_visibles,1,1,1,true).sort(permutations,false); CImg lightprops; switch (render_type) { case 3: { lightprops.assign(nb_visibles); for (int l = 0; l<(int)((lightprops).width); ++l) { const CImg& primitive = primitives(visibles(permutations(l))); const unsigned int psize = primitive.size(); if (psize==3 || psize==4 || psize==9 || psize==12) { const unsigned int i0 = (unsigned int)primitive(0), i1 = (unsigned int)primitive(1), i2 = (unsigned int)primitive(2); const float x0 = (float)points(i0,0), y0 = (float)points(i0,1), z0 = (float)points(i0,2), x1 = (float)points(i1,0), y1 = (float)points(i1,1), z1 = (float)points(i1,2), x2 = (float)points(i2,0), y2 = (float)points(i2,1), z2 = (float)points(i2,2), dx1 = x1-x0, dy1 = y1-y0, dz1 = z1-z0, dx2 = x2-x0, dy2 = y2-y0, dz2 = z2-z0, nx = dy1*dz2-dz1*dy2, ny = dz1*dx2-dx1*dz2, nz = dx1*dy2-dy1*dx2, norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz), lx = X+(x0+x1+x2)/3-lightx, ly = Y+(y0+y1+y2)/3-lighty, lz = Z+(z0+z1+z2)/3-lightz, nl = (float)std::sqrt(1e-5f+lx*lx+ly*ly+lz*lz), factor = cimg::max(cimg::abs(-lx*nx-ly*ny-lz*nz)/(norm*nl),0.0f); lightprops[l] = factor<=nspec?factor:(nsl1*factor*factor + nsl2*factor + nsl3); } else lightprops[l] = 1.0f; } } break; case 4: case 5: { CImg points_normals(points.width,double_sided?7:3,1,1,0); for (unsigned int l=0; l& primitive = primitives[visibles(l)]; const unsigned int psize = primitive.size(); const bool triangle_flag = (psize==3) || (psize==9), rectangle_flag = (psize==4) || (psize==12); if (triangle_flag || rectangle_flag) { const unsigned int i0 = (unsigned int)primitive(0), i1 = (unsigned int)primitive(1), i2 = (unsigned int)primitive(2), i3 = rectangle_flag?(unsigned int)primitive(3):0; const float x0 = (float)points(i0,0), y0 = (float)points(i0,1), z0 = (float)points(i0,2), x1 = (float)points(i1,0), y1 = (float)points(i1,1), z1 = (float)points(i1,2), x2 = (float)points(i2,0), y2 = (float)points(i2,1), z2 = (float)points(i2,2), dx1 = x1-x0, dy1 = y1-y0, dz1 = z1-z0, dx2 = x2-x0, dy2 = y2-y0, dz2 = z2-z0, nnx = dy1*dz2-dz1*dy2, nny = dz1*dx2-dx1*dz2, nnz = dx1*dy2-dy1*dx2, norm = 1e-5f + (float)std::sqrt(nnx*nnx+nny*nny+nnz*nnz), nx = nnx/norm, ny = nny/norm, nz = nnz/norm; if (double_sided) { unsigned int ind = nz>0?3U:0U; const float incr = nz>0?-1.0f:1.0f; points_normals(i0, ind)+=nx; points_normals(i1,ind)+=nx; points_normals(i2,ind)+=nx; points_normals(i0,++ind)+=ny; points_normals(i1,ind)+=ny; points_normals(i2,ind)+=ny; points_normals(i0,++ind)+=nz; points_normals(i1,ind)+=nz; points_normals(i2,ind)+=nz; points_normals(i0,6)+=incr; points_normals(i1,6)+=incr; points_normals(i2,6)+=incr; if (rectangle_flag) { points_normals(i3,ind)+=nz; points_normals(i3,--ind)+=ny; points_normals(i3,--ind)+=nz; points_normals(i3,6)+=incr; } } else { points_normals(i0,0)+=nx; points_normals(i0,1)+=ny; points_normals(i0,2)+=nz; points_normals(i1,0)+=nx; points_normals(i1,1)+=ny; points_normals(i1,2)+=nz; points_normals(i2,0)+=nx; points_normals(i2,1)+=ny; points_normals(i2,2)+=nz; if (rectangle_flag) { points_normals(i3,0)+=nx; points_normals(i3,1)+=ny; points_normals(i3,2)+=nz; } } } } if (double_sided) for (int l = 0; l<(int)((points_normals).width); ++l) if (points_normals(l,6)<0) { points_normals(l,0) = -points_normals(l,3); points_normals(l,1) = -points_normals(l,4); points_normals(l,2) = -points_normals(l,5); } if (render_type==4) { lightprops.assign(points.width); for (int ll = 0; ll<(int)((points).width); ++ll) { const float nx = points_normals(ll,0), ny = points_normals(ll,1), nz = points_normals(ll,2), norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz), lx = (float)(X+points(ll,0)-lightx), ly = (float)(Y+points(ll,1)-lighty), lz = (float)(Z+points(ll,2)-lightz), nl = (float)std::sqrt(1e-5f+lx*lx+ly*ly+lz*lz), factor = cimg::max((-lx*nx-ly*ny-lz*nz)/(norm*nl),0.0f); lightprops[ll] = factor<=nspec?factor:(nsl1*factor*factor + nsl2*factor + nsl3); } } else { const unsigned int lw2 = light_texture.width/2-1, lh2 = light_texture.height/2-1; lightprops.assign(points.width,2); for (int ll = 0; ll<(int)((points).width); ++ll) { const float nx = points_normals(ll,0), ny = points_normals(ll,1), nz = points_normals(ll,2), norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz), nnx = nx/norm, nny = ny/norm; lightprops(ll,0) = lw2*(1+nnx); lightprops(ll,1) = lh2*(1+nny); } } } break; } const unsigned int opacsize = opacities.size; { for (unsigned int l=0; l& primitive = primitives[n_primitive]; const CImg& color = colors[n_primitive%colors.size]; const CImg& opacity = opacities[n_primitive%opacsize]; const float opac = opacity.size()?(float)opacity(0):1.0f; switch (primitive.size()) { case 1: { const unsigned int n0 = (unsigned int)primitive[0]; const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1); if (color.size()==dim) draw_point(x0,y0,color,opac); else { const float z = Z + points(n0,2); const int factor = (int)(focale*100/(z+focale)), sw = color.width*factor/200, sh = color.height*factor/200; if (x0+sw>=0 && x0-sw=0 && y0-sh sprite = color.get_resize(-factor,-factor,1,-100,render_type<=3?1:3); if (opacity.width==color.width && opacity.height==color.height) draw_image(sprite,opacity.get_resize(sprite.width,sprite.height,1,sprite.dim,1),x0-sw,y0-sh,0,0); else draw_image(sprite,x0-sw,y0-sh,0,0,opac); } } } break; case 2: { const unsigned int n0 = (unsigned int)primitive[0], n1 = (unsigned int)primitive[1]; const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), x1 = (int)projections(n1,0), y1 = (int)projections(n1,1); if (render_type) draw_line(x0,y0,x1,y1,color,opac); else draw_point(x0,y0,color,opac).draw_point(x1,y1,color,opac); } break; case 5: { const unsigned int n0 = (unsigned int)primitive[0], n1 = (unsigned int)primitive[1], n2 = (unsigned int)primitive[2]; const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1); int radius; if (n2) radius = (int)(n2*focale/(Z+points(n0,2)+focale)); else { const int x1 = (int)projections(n1,0), y1 = (int)projections(n1,1), deltax = x1-x0, deltay = y1-y0; radius = (int)std::sqrt((float)(deltax*deltax + deltay*deltay)); } switch (render_type) { case 0: draw_point(x0,y0,color,opac); break; case 1: draw_circle(x0,y0,radius,color,opac,~0U); break; default: draw_circle(x0,y0,radius,color,opac); break; } } break; case 6: { const unsigned int n0 = (unsigned int)primitive[0], n1 = (unsigned int)primitive[1], tx0 = (unsigned int)primitive[2], ty0 = (unsigned int)primitive[3], tx1 = (unsigned int)primitive[4], ty1 = (unsigned int)primitive[5]; const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), x1 = (int)projections(n1,0), y1 = (int)projections(n1,1); const float z0 = points(n0,2) + Z + focale, z1 = points(n1,2) + Z + focale; if (render_type) draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac); else draw_point(x0,y0,color.get_vector_at(tx0,ty0),opac). draw_point(x1,y1,color.get_vector_at(tx1,ty1),opac); } break; case 3: { const unsigned int n0 = (unsigned int)primitive[0], n1 = (unsigned int)primitive[1], n2 = (unsigned int)primitive[2]; const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), x1 = (int)projections(n1,0), y1 = (int)projections(n1,1), x2 = (int)projections(n2,0), y2 = (int)projections(n2,1); switch(render_type) { case 0: draw_point(x0,y0,color,opac).draw_point(x1,y1,color,opac).draw_point(x2,y2,color,opac); break; case 1: draw_line(x0,y0,x1,y1,color,opac).draw_line(x0,y0,x2,y2,color,opac). draw_line(x1,y1,x2,y2,color,opac); break; case 2: draw_triangle(x0,y0,x1,y1,x2,y2,color,opac); break; case 3: _draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opac,lightprops(l)); break; case 4: draw_triangle(x0,y0,x1,y1,x2,y2,color,lightprops(n0),lightprops(n1),lightprops(n2),opac); break; case 5: const unsigned int lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1), lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1), lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1); draw_triangle(x0,y0,x1,y1,x2,y2,color,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac); break; } } break; case 4: { const unsigned int n0 = (unsigned int)primitive[0], n1 = (unsigned int)primitive[1], n2 = (unsigned int)primitive[2], n3 = (unsigned int)primitive[3]; const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), x1 = (int)projections(n1,0), y1 = (int)projections(n1,1), x2 = (int)projections(n2,0), y2 = (int)projections(n2,1), x3 = (int)projections(n3,0), y3 = (int)projections(n3,1); switch(render_type) { case 0: draw_point(x0,y0,color,opac).draw_point(x1,y1,color,opac). draw_point(x2,y2,color,opac).draw_point(x3,y3,color,opac); break; case 1: draw_line(x0,y0,x1,y1,color,opac).draw_line(x1,y1,x2,y2,color,opac). draw_line(x2,y2,x3,y3,color,opac).draw_line(x3,y3,x0,y0,color,opac); break; case 2: draw_triangle(x0,y0,x1,y1,x2,y2,color,opac).draw_triangle(x0,y0,x2,y2,x3,y3,color,opac); break; case 3: _draw_triangle(x0,y0,x1,y1,x2,y2,color.data,opac,lightprops(l)). _draw_triangle(x0,y0,x2,y2,x3,y3,color.data,opac,lightprops(l)); break; case 4: { const float lightprop0 = lightprops(n0), lightprop1 = lightprops(n1), lightprop2 = lightprops(n2), lightprop3 = lightprops(n3); draw_triangle(x0,y0,x1,y1,x2,y2,color,lightprop0,lightprop1,lightprop2,opac). draw_triangle(x0,y0,x2,y2,x3,y3,color,lightprop0,lightprop2,lightprop3,opac); } break; case 5: { const unsigned int lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1), lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1), lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1), lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1); draw_triangle(x0,y0,x1,y1,x2,y2,color,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac). draw_triangle(x0,y0,x2,y2,x3,y3,color,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac); } break; } } break; case 9: { const unsigned int n0 = (unsigned int)primitive[0], n1 = (unsigned int)primitive[1], n2 = (unsigned int)primitive[2], tx0 = (unsigned int)primitive[3], ty0 = (unsigned int)primitive[4], tx1 = (unsigned int)primitive[5], ty1 = (unsigned int)primitive[6], tx2 = (unsigned int)primitive[7], ty2 = (unsigned int)primitive[8]; const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), x1 = (int)projections(n1,0), y1 = (int)projections(n1,1), x2 = (int)projections(n2,0), y2 = (int)projections(n2,1); const float z0 = points(n0,2) + Z + focale, z1 = points(n1,2) + Z + focale, z2 = points(n2,2) + Z + focale; switch(render_type) { case 0: draw_point(x0,y0,color.get_vector_at(tx0,ty0),opac). draw_point(x1,y1,color.get_vector_at(tx1,ty1),opac). draw_point(x2,y2,color.get_vector_at(tx2,ty2),opac); break; case 1: draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac). draw_line(x0,y0,z0,x2,y2,z2,color,tx0,ty0,tx2,ty2,opac). draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac); break; case 2: draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac); break; case 3: draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l)); break; case 4: 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); break; case 5: draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture, (unsigned int)lightprops(n0,0), (unsigned int)lightprops(n0,1), (unsigned int)lightprops(n1,0), (unsigned int)lightprops(n1,1), (unsigned int)lightprops(n2,0), (unsigned int)lightprops(n2,1), opac); break; } } break; case 12: { const unsigned int n0 = (unsigned int)primitive[0], n1 = (unsigned int)primitive[1], n2 = (unsigned int)primitive[2], n3 = (unsigned int)primitive[3], tx0 = (unsigned int)primitive[4], ty0 = (unsigned int)primitive[5], tx1 = (unsigned int)primitive[6], ty1 = (unsigned int)primitive[7], tx2 = (unsigned int)primitive[8], ty2 = (unsigned int)primitive[9], tx3 = (unsigned int)primitive[10], ty3 = (unsigned int)primitive[11]; const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1), x1 = (int)projections(n1,0), y1 = (int)projections(n1,1), x2 = (int)projections(n2,0), y2 = (int)projections(n2,1), x3 = (int)projections(n3,0), y3 = (int)projections(n3,1); const float z0 = points(n0,2) + Z + focale, z1 = points(n1,2) + Z + focale, z2 = points(n2,2) + Z + focale, z3 = points(n3,2) + Z + focale; switch(render_type) { case 0: draw_point(x0,y0,color.get_vector_at(tx0,ty0),opac). draw_point(x1,y1,color.get_vector_at(tx1,ty1),opac). draw_point(x2,y2,color.get_vector_at(tx2,ty2),opac). draw_point(x3,y3,color.get_vector_at(tx3,ty3),opac); break; case 1: draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac). draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac). draw_line(x2,y2,z2,x3,y3,z3,color,tx2,ty2,tx3,ty3,opac). draw_line(x3,y3,z3,x0,y0,z0,color,tx3,ty3,tx0,ty0,opac); break; case 2: draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac). draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac); break; case 3: draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l)). draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac,lightprops(l)); break; case 4: { const float lightprop0 = lightprops(n0), lightprop1 = lightprops(n1), lightprop2 = lightprops(n2), lightprop3 = lightprops(n3); draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprop0,lightprop1,lightprop2,opac). draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,lightprop0,lightprop2,lightprop3,opac); } break; case 5: { const unsigned int lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1), lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1), lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1), lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1); 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). 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); } break; } } break; } } } return *this; } template CImg& draw_object3d(const float X, const float Y, const float Z, const CImgList& points, const CImgList& primitives, const CImgList& colors, const CImgList& opacities, const unsigned int render_type=4, const bool double_sided=false, const float focale=500, const float lightx=0, const float lighty=0, const float lightz=-5000, const float specular_light=0.2f, const float specular_shine=0.1f) { if (!points) return *this; CImg npoints(points.size,3,1,1,0); tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2); for (int l = 0; l<(int)((npoints).width); ++l) { const CImg& point = points[l]; const unsigned int siz = point.size(); if (!siz) throw CImgArgumentException("CImg<%s>::draw_object3d() : Given points (size=%u) contains a null element at " "position %u.",pixel_type(),points.size,l); *(ptrZ++) = (siz>2)?point(2):0; *(ptrY++) = (siz>1)?point(1):0; *(ptrX++) = point(0); } return draw_object3d(X,Y,Z,npoints,primitives,colors,opacities, render_type,double_sided,focale,lightx,lighty,lightz,specular_light,specular_shine); } template CImg& draw_object3d(const float X, const float Y, const float Z, const CImg& points, const CImgList& primitives, const CImgList& colors, const CImg& opacities, const unsigned int render_type=4, const bool double_sided=false, const float focale=500, const float lightx=0, const float lighty=0, const float lightz=-5000, const float specular_light=0.2f, const float specular_shine=0.1f) { CImgList nopacities(opacities.size(),1); for (unsigned int l=0; l<(nopacities).size; ++l) nopacities(l,0) = opacities(l); return draw_object3d(X,Y,Z,points,primitives,colors,nopacities, render_type,double_sided,focale,lightx,lighty,lightz,specular_light,specular_shine); } template CImg& draw_object3d(const float X, const float Y, const float Z, const CImgList& points, const CImgList& primitives, const CImgList& colors, const CImg& opacities, const unsigned int render_type=4, const bool double_sided=false, const float focale=500, const float lightx=0, const float lighty=0, const float lightz=-5000, const float specular_light=0.2f, const float specular_shine=0.1f) { CImgList nopacities(opacities.size(),1); { for (unsigned int l=0; l<(nopacities).size; ++l) nopacities(l,0) = opacities(l); } if (!points) return *this; CImg npoints(points.size,3,1,1,0); tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2); for (int l = 0; l<(int)((npoints).width); ++l) { const CImg& point = points[l]; const unsigned int siz = point.size(); if (!siz) throw CImgArgumentException("CImg<%s>::draw_object3d() : Given points (size=%u) contains a null element at " "position %u.",pixel_type(),points.size,l); *(ptrZ++) = (siz>2)?point(2):0; *(ptrY++) = (siz>1)?point(1):0; *(ptrX++) = point(0); } return draw_object3d(X,Y,Z,npoints,primitives,colors,nopacities, render_type,double_sided,focale,lightx,lighty,lightz,specular_light,specular_shine); } template CImg& draw_object3d(const float X, const float Y, const float Z, const tp& points, const CImgList& primitives, const CImgList& colors, const unsigned int render_type=4, const bool double_sided=false, const float focale=500, const float lightx=0, const float lighty=0, const float lightz=-5000, const float specular_light=0.2f, const float specular_shine=0.1f, const float opacity=1.0f) { return draw_object3d(X,Y,Z,points,primitives,colors, CImg(primitives.size,1,1,1,opacity), render_type,double_sided,focale,lightx,lighty,lightz, specular_light,specular_shine); } template CImg::type> get_correlate(const CImg& mask, const unsigned int cond=1, const bool weighted_correl=false) const { typedef typename cimg::superset2::type ftype; if (is_empty()) return CImg(); if (!mask || mask.dim!=1) throw CImgArgumentException("CImg<%s>::correlate() : Specified mask (%u,%u,%u,%u,%p) is not scalar.", pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data); CImg dest(width,height,depth,dim); if (cond && mask.width==mask.height && ((mask.depth==1 && mask.width<=5) || (mask.depth==mask.width && mask.width<=3))) { switch (mask.depth) { case 3: { T I[27] = { 0 }; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,v)), (I[3] = I[4] = (*this)(0,y,_p1z,v)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,v)), (I[9] = I[10] = (*this)(0,_p1y,z,v)), (I[12] = I[13] = (*this)(0,y,z,v)), (I[15] = I[16] = (*this)(0,_n1y,z,v)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,v)), (I[21] = I[22] = (*this)(0,y,_n1z,v)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,v)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,v)), (I[5] = (*this)(_n1x,y,_p1z,v)), (I[8] = (*this)(_n1x,_n1y,_p1z,v)), (I[11] = (*this)(_n1x,_p1y,z,v)), (I[14] = (*this)(_n1x,y,z,v)), (I[17] = (*this)(_n1x,_n1y,z,v)), (I[20] = (*this)(_n1x,_p1y,_n1z,v)), (I[23] = (*this)(_n1x,y,_n1z,v)), (I[26] = (*this)(_n1x,_n1y,_n1z,v)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) dest(x,y,z,v) = (ftype) (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] + I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] + I[18]*mask[18] + I[19]*mask[19] + I[20]*mask[20] + I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] + I[24]*mask[24] + I[25]*mask[25] + I[26]*mask[26]); if (weighted_correl) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,v)), (I[3] = I[4] = (*this)(0,y,_p1z,v)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,v)), (I[9] = I[10] = (*this)(0,_p1y,z,v)), (I[12] = I[13] = (*this)(0,y,z,v)), (I[15] = I[16] = (*this)(0,_n1y,z,v)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,v)), (I[21] = I[22] = (*this)(0,y,_n1z,v)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,v)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,v)), (I[5] = (*this)(_n1x,y,_p1z,v)), (I[8] = (*this)(_n1x,_n1y,_p1z,v)), (I[11] = (*this)(_n1x,_p1y,z,v)), (I[14] = (*this)(_n1x,y,z,v)), (I[17] = (*this)(_n1x,_n1y,z,v)), (I[20] = (*this)(_n1x,_p1y,_n1z,v)), (I[23] = (*this)(_n1x,y,_n1z,v)), (I[26] = (*this)(_n1x,_n1y,_n1z,v)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) { 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] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] + I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15] + I[16]*I[16] + I[17]*I[17] + I[18]*I[18] + I[19]*I[19] + I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] + I[24]*I[24] + I[25]*I[25] + I[26]*I[26]); if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight); } } break; case 2: { T I[8] = { 0 }; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; ++z, ++_n1z) for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = (int)( (I[0] = (*this)(0,y,z,v)), (I[2] = (*this)(0,_n1y,z,v)), (I[4] = (*this)(0,y,_n1z,v)), (I[6] = (*this)(0,_n1y,_n1z,v)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[1] = (*this)(_n1x,y,z,v)), (I[3] = (*this)(_n1x,_n1y,z,v)), (I[5] = (*this)(_n1x,y,_n1z,v)), (I[7] = (*this)(_n1x,_n1y,_n1z,v)),1)) || x==--_n1x; I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], ++x, ++_n1x) dest(x,y,z,v) = (ftype) (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] + I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] + I[6]*mask[6] + I[7]*mask[7]); if (weighted_correl) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; ++z, ++_n1z) for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = (int)( (I[0] = (*this)(0,y,z,v)), (I[2] = (*this)(0,_n1y,z,v)), (I[4] = (*this)(0,y,_n1z,v)), (I[6] = (*this)(0,_n1y,_n1z,v)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[1] = (*this)(_n1x,y,z,v)), (I[3] = (*this)(_n1x,_n1y,z,v)), (I[5] = (*this)(_n1x,y,_n1z,v)), (I[7] = (*this)(_n1x,_n1y,_n1z,v)),1)) || x==--_n1x; I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], ++x, ++_n1x) { 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] + I[6]*I[6] + I[7]*I[7]); if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight); } } break; default: case 1: switch (mask.width) { case 6: { T I[36] = { 0 }; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2, _n3y = 3>=((*this).height)?(int)((*this).height)-1:3; _n3y<(int)((*this).height) || _n2y==--_n3y || _n1y==--_n2y || y==(_n3y = _n2y = --_n1y); _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y, ++_n3y) for (int x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=(*this).width?(int)((*this).width)-1:1, _n2x = 2>=(*this).width?(int)((*this).width)-1:2, _n3x = (int)( (I[0] = I[1] = I[2] = (*this)(0,_p2y,z,v)), (I[6] = I[7] = I[8] = (*this)(0,_p1y,z,v)), (I[12] = I[13] = I[14] = (*this)(0,y,z,v)), (I[18] = I[19] = I[20] = (*this)(0,_n1y,z,v)), (I[24] = I[25] = I[26] = (*this)(0,_n2y,z,v)), (I[30] = I[31] = I[32] = (*this)(0,_n3y,z,v)), (I[3] = (*this)(_n1x,_p2y,z,v)), (I[9] = (*this)(_n1x,_p1y,z,v)), (I[15] = (*this)(_n1x,y,z,v)), (I[21] = (*this)(_n1x,_n1y,z,v)), (I[27] = (*this)(_n1x,_n2y,z,v)), (I[33] = (*this)(_n1x,_n3y,z,v)), (I[4] = (*this)(_n2x,_p2y,z,v)), (I[10] = (*this)(_n2x,_p1y,z,v)), (I[16] = (*this)(_n2x,y,z,v)), (I[22] = (*this)(_n2x,_n1y,z,v)), (I[28] = (*this)(_n2x,_n2y,z,v)), (I[34] = (*this)(_n2x,_n3y,z,v)), 3>=(*this).width?(int)((*this).width)-1:3); (_n3x<(int)((*this).width) && ( (I[5] = (*this)(_n3x,_p2y,z,v)), (I[11] = (*this)(_n3x,_p1y,z,v)), (I[17] = (*this)(_n3x,y,z,v)), (I[23] = (*this)(_n3x,_n1y,z,v)), (I[29] = (*this)(_n3x,_n2y,z,v)), (I[35] = (*this)(_n3x,_n3y,z,v)),1)) || _n2x==--_n3x || _n1x==--_n2x || x==(_n3x = _n2x = --_n1x); I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x, ++_n3x) dest(x,y,z,v) = (ftype) (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] + I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] + I[18]*mask[18] + I[19]*mask[19] + I[20]*mask[20] + I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] + I[24]*mask[24] + I[25]*mask[25] + I[26]*mask[26] + I[27]*mask[27] + I[28]*mask[28] + I[29]*mask[29] + I[30]*mask[30] + I[31]*mask[31] + I[32]*mask[32] + I[33]*mask[33] + I[34]*mask[34] + I[35]*mask[35]); if (weighted_correl) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=(*this).width?(int)((*this).width)-1:1, _n2x = (int)( (I[0] = I[1] = I[2] = (*this)(0,_p2y,z,v)), (I[5] = I[6] = I[7] = (*this)(0,_p1y,z,v)), (I[10] = I[11] = I[12] = (*this)(0,y,z,v)), (I[15] = I[16] = I[17] = (*this)(0,_n1y,z,v)), (I[20] = I[21] = I[22] = (*this)(0,_n2y,z,v)), (I[3] = (*this)(_n1x,_p2y,z,v)), (I[8] = (*this)(_n1x,_p1y,z,v)), (I[13] = (*this)(_n1x,y,z,v)), (I[18] = (*this)(_n1x,_n1y,z,v)), (I[23] = (*this)(_n1x,_n2y,z,v)), 2>=(*this).width?(int)((*this).width)-1:2); (_n2x<(int)((*this).width) && ( (I[4] = (*this)(_n2x,_p2y,z,v)), (I[9] = (*this)(_n2x,_p1y,z,v)), (I[14] = (*this)(_n2x,y,z,v)), (I[19] = (*this)(_n2x,_n1y,z,v)), (I[24] = (*this)(_n2x,_n2y,z,v)),1)) || _n1x==--_n2x || x==(_n2x = --_n1x); I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x) { 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] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] + I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15] + I[16]*I[16] + I[17]*I[17] + I[18]*I[18] + I[19]*I[19] + I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] + I[24]*I[24] + I[25]*I[25] + I[26]*I[26] + I[27]*I[27] + I[28]*I[28] + I[29]*I[29] + I[30]*I[30] + I[31]*I[31] + I[32]*I[32] + I[33]*I[33] + I[34]*I[34] + I[35]*I[35]); if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight); } } break; case 5: { T I[25] = { 0 }; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=(*this).width?(int)((*this).width)-1:1, _n2x = (int)( (I[0] = I[1] = I[2] = (*this)(0,_p2y,z,v)), (I[5] = I[6] = I[7] = (*this)(0,_p1y,z,v)), (I[10] = I[11] = I[12] = (*this)(0,y,z,v)), (I[15] = I[16] = I[17] = (*this)(0,_n1y,z,v)), (I[20] = I[21] = I[22] = (*this)(0,_n2y,z,v)), (I[3] = (*this)(_n1x,_p2y,z,v)), (I[8] = (*this)(_n1x,_p1y,z,v)), (I[13] = (*this)(_n1x,y,z,v)), (I[18] = (*this)(_n1x,_n1y,z,v)), (I[23] = (*this)(_n1x,_n2y,z,v)), 2>=(*this).width?(int)((*this).width)-1:2); (_n2x<(int)((*this).width) && ( (I[4] = (*this)(_n2x,_p2y,z,v)), (I[9] = (*this)(_n2x,_p1y,z,v)), (I[14] = (*this)(_n2x,y,z,v)), (I[19] = (*this)(_n2x,_n1y,z,v)), (I[24] = (*this)(_n2x,_n2y,z,v)),1)) || _n1x==--_n2x || x==(_n2x = --_n1x); I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x) dest(x,y,z,v) = (ftype) (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] + I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] + I[18]*mask[18] + I[19]*mask[19] + I[20]*mask[20] + I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] + I[24]*mask[24]); if (weighted_correl) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=(*this).width?(int)((*this).width)-1:1, _n2x = (int)( (I[0] = I[1] = I[2] = (*this)(0,_p2y,z,v)), (I[5] = I[6] = I[7] = (*this)(0,_p1y,z,v)), (I[10] = I[11] = I[12] = (*this)(0,y,z,v)), (I[15] = I[16] = I[17] = (*this)(0,_n1y,z,v)), (I[20] = I[21] = I[22] = (*this)(0,_n2y,z,v)), (I[3] = (*this)(_n1x,_p2y,z,v)), (I[8] = (*this)(_n1x,_p1y,z,v)), (I[13] = (*this)(_n1x,y,z,v)), (I[18] = (*this)(_n1x,_n1y,z,v)), (I[23] = (*this)(_n1x,_n2y,z,v)), 2>=(*this).width?(int)((*this).width)-1:2); (_n2x<(int)((*this).width) && ( (I[4] = (*this)(_n2x,_p2y,z,v)), (I[9] = (*this)(_n2x,_p1y,z,v)), (I[14] = (*this)(_n2x,y,z,v)), (I[19] = (*this)(_n2x,_n1y,z,v)), (I[24] = (*this)(_n2x,_n2y,z,v)),1)) || _n1x==--_n2x || x==(_n2x = --_n1x); I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x) { 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] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] + I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15] + I[16]*I[16] + I[17]*I[17] + I[18]*I[18] + I[19]*I[19] + I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] + I[24]*I[24]); if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight); } } break; case 4: { T I[16] = { 0 }; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p1x = 0, _n1x = 1>=(*this).width?(int)((*this).width)-1:1, _n2x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,v)), (I[4] = I[5] = (*this)(0,y,z,v)), (I[8] = I[9] = (*this)(0,_n1y,z,v)), (I[12] = I[13] = (*this)(0,_n2y,z,v)), (I[2] = (*this)(_n1x,_p1y,z,v)), (I[6] = (*this)(_n1x,y,z,v)), (I[10] = (*this)(_n1x,_n1y,z,v)), (I[14] = (*this)(_n1x,_n2y,z,v)), 2>=(*this).width?(int)((*this).width)-1:2); (_n2x<(int)((*this).width) && ( (I[3] = (*this)(_n2x,_p1y,z,v)), (I[7] = (*this)(_n2x,y,z,v)), (I[11] = (*this)(_n2x,_n1y,z,v)), (I[15] = (*this)(_n2x,_n2y,z,v)),1)) || _n1x==--_n2x || x==(_n2x = --_n1x); I[0] = I[1], I[1] = I[2], I[2] = I[3], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[14] = I[15], _p1x = x++, ++_n1x, ++_n2x) dest(x,y,z,v) = (ftype) (I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] + I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15]); if (weighted_correl) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p1x = 0, _n1x = 1>=(*this).width?(int)((*this).width)-1:1, _n2x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,v)), (I[4] = I[5] = (*this)(0,y,z,v)), (I[8] = I[9] = (*this)(0,_n1y,z,v)), (I[12] = I[13] = (*this)(0,_n2y,z,v)), (I[2] = (*this)(_n1x,_p1y,z,v)), (I[6] = (*this)(_n1x,y,z,v)), (I[10] = (*this)(_n1x,_n1y,z,v)), (I[14] = (*this)(_n1x,_n2y,z,v)), 2>=(*this).width?(int)((*this).width)-1:2); (_n2x<(int)((*this).width) && ( (I[3] = (*this)(_n2x,_p1y,z,v)), (I[7] = (*this)(_n2x,y,z,v)), (I[11] = (*this)(_n2x,_n1y,z,v)), (I[15] = (*this)(_n2x,_n2y,z,v)),1)) || _n1x==--_n2x || x==(_n2x = --_n1x); I[0] = I[1], I[1] = I[2], I[2] = I[3], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[14] = I[15], _p1x = x++, ++_n1x, ++_n2x) { 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] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] + I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15]); if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight); } } break; case 3: { T I[9] = { 0 }; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,v)), (I[3] = I[4] = (*this)(0,y,z,v)), (I[6] = I[7] = (*this)(0,_n1y,z,v)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,z,v)), (I[5] = (*this)(_n1x,y,z,v)), (I[8] = (*this)(_n1x,_n1y,z,v)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) dest(x,y,z,v) = (ftype) (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] + I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] + I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]); if (weighted_correl) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,z,v)), (I[3] = I[4] = (*this)(0,y,z,v)), (I[6] = I[7] = (*this)(0,_n1y,z,v)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,z,v)), (I[5] = (*this)(_n1x,y,z,v)), (I[8] = (*this)(_n1x,_n1y,z,v)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { 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] + I[6]*I[6] + I[7]*I[7] + I[8]*I[8]); if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight); } } break; case 2: { T I[4] = { 0 }; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = (int)( (I[0] = (*this)(0,y,z,v)), (I[2] = (*this)(0,_n1y,z,v)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[1] = (*this)(_n1x,y,z,v)), (I[3] = (*this)(_n1x,_n1y,z,v)),1)) || x==--_n1x; I[0] = I[1], I[2] = I[3], ++x, ++_n1x) dest(x,y,z,v) = (ftype) (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] + I[3]*mask[3]); if (weighted_correl) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = (int)( (I[0] = (*this)(0,y,z,v)), (I[2] = (*this)(0,_n1y,z,v)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[1] = (*this)(_n1x,y,z,v)), (I[3] = (*this)(_n1x,_n1y,z,v)),1)) || x==--_n1x; I[0] = I[1], I[2] = I[3], ++x, ++_n1x) { const double weight = (double)(I[0]*I[0] + I[1]*I[1] + I[2]*I[2] + I[3]*I[3]); if (weight>0) dest(x,y,z,v)/=(ftype)std::sqrt(weight); } } break; case 1: (dest.assign(*this))*=mask(0); break; } } } else { const int mx2 = mask.dimx()/2, my2 = mask.dimy()/2, mz2 = mask.dimz()/2, mx1 = mx2 - 1 + (mask.dimx()%2), my1 = my2 - 1 + (mask.dimy()%2), mz1 = mz2 - 1 + (mask.dimz()%2), mxe = dimx() - mx2, mye = dimy() - my2, mze = dimz() - mz2; for (int v = 0; v<(int)((*this).dim); ++v) if (!weighted_correl) { for (int z = mz1; z=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { ftype val = 0; for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) val+=pix3d(x+xm,y+ym,z+zm,v)*mask(mx1+xm,my1+ym,mz1+zm); dest(x,y,z,v) = (ftype)val; } else for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { ftype val = 0; for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) val+=pix3d(x+xm,y+ym,z+zm,v,0)*mask(mx1+xm,my1+ym,mz1+zm); dest(x,y,z,v) = (ftype)val; } } else { for (int z = mz1; z0)?(ftype)(val/std::sqrt((double)weight)):0; } if (cond) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { ftype val = 0, weight = 0; for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const ftype cval = (ftype)pix3d(x+xm,y+ym,z+zm,v); val+=cval*mask(mx1+xm,my1+ym,mz1+zm); weight+=cval*cval; } dest(x,y,z,v) = (weight>0)?(ftype)(val/std::sqrt((double)weight)):0; } else for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { ftype val = 0, weight = 0; for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const ftype cval = (ftype)pix3d(x+xm,y+ym,z+zm,v,0); val+=cval*mask(mx1+xm,my1+ym,mz1+zm); weight+=cval*cval; } dest(x,y,z,v) = (weight>0)?(ftype)(val/std::sqrt((double)weight)):0; } } } return dest; } template CImg& correlate(const CImg& mask, const unsigned int cond=1, const bool weighted_correl=false) { return get_correlate(mask,cond,weighted_correl).transfer_to(*this); } template CImg::type> get_convolve(const CImg& mask, const unsigned int cond=1, const bool weighted_convol=false) const { typedef typename cimg::superset2::type ftype; if (is_empty()) return CImg(); if (!mask || mask.dim!=1) throw CImgArgumentException("CImg<%s>::convolve() : Specified mask (%u,%u,%u,%u,%p) is not scalar.", pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data); return get_correlate(CImg(mask.ptr(),mask.size(),1,1,1,true).get_mirror('x').resize(mask,-1),cond,weighted_convol); } template CImg& convolve(const CImg& mask, const unsigned int cond=1, const bool weighted_convol=false) { return get_convolve(mask,cond,weighted_convol).transfer_to(*this); } template CImg::type> get_erode(const CImg& mask, const unsigned int cond=1, const bool weighted_erosion=false) const { typedef typename cimg::superset::type restype; if (is_empty()) return CImg(); if (!mask || mask.dim!=1) throw CImgArgumentException("CImg<%s>::erode() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.", pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data); CImg dest(width,height,depth,dim); const int mx2 = mask.dimx()/2, my2 = mask.dimy()/2, mz2 = mask.dimz()/2, mx1 = mx2 - 1 + (mask.dimx()%2), my1 = my2 - 1 + (mask.dimy()%2), mz1 = mz2 - 1 + (mask.dimz()%2), mxe = dimx() - mx2, mye = dimy() - my2, mze = dimz() - mz2; for (int v = 0; v<(int)((*this).dim); ++v) if (!weighted_erosion) { for (int z = mz1; z::max(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const restype cval = (restype)(*this)(x+xm,y+ym,z+zm,v); if (mask(mx1+xm,my1+ym,mz1+zm) && cval=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { restype min_val = cimg::type::max(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const T cval = (restype)pix3d(x+xm,y+ym,z+zm,v); if (mask(mx1+xm,my1+ym,mz1+zm) && cval=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { restype min_val = cimg::type::max(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const T cval = (restype)pix3d(x+xm,y+ym,z+zm,v,0); if (mask(mx1+xm,my1+ym,mz1+zm) && cval::max(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const t mval = mask(mx1+xm,my1+ym,mz1+zm); const restype cval = (restype)((*this)(x+xm,y+ym,z+zm,v) + mval); if (mval && cval=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { restype min_val = cimg::type::max(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const t mval = mask(mx1+xm,my1+ym,mz1+zm); const restype cval = (restype)(pix3d(x+xm,y+ym,z+zm,v) + mval); if (mval && cval=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { restype min_val = cimg::type::max(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const t mval = mask(mx1+xm,my1+ym,mz1+zm); const restype cval = (restype)(pix3d(x+xm,y+ym,z+zm,v,0) + mval); if (mval && cval CImg& erode(const CImg& mask, const unsigned int cond=1, const bool weighted_erosion=false) { return get_erode(mask,cond,weighted_erosion).transfer_to(*this); } CImg get_erode(const unsigned int n, const unsigned int cond=1) const { static CImg mask; if (n<2) return *this; if (mask.width!=n) mask.assign(n,n,1,1,1); const CImg res = get_erode(mask,cond,false); if (n>20) mask.assign(); return res; } CImg& erode(const unsigned int n, const unsigned int cond=1) { if (n<2) return *this; return get_erode(n,cond).transfer_to(*this); } template CImg::type> get_dilate(const CImg& mask, const unsigned int cond=1, const bool weighted_dilatation=false) const { typedef typename cimg::superset::type restype; if (is_empty()) return CImg(); if (!mask || mask.dim!=1) throw CImgArgumentException("CImg<%s>::dilate() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.", pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data); CImg dest(width,height,depth,dim); const int mx2 = mask.dimx()/2, my2 = mask.dimy()/2, mz2 = mask.dimz()/2, mx1 = mx2 - 1 + (mask.dimx()%2), my1 = my2 - 1 + (mask.dimy()%2), mz1 = mz2 - 1 + (mask.dimz()%2), mxe = dimx() - mx2, mye = dimy() - my2, mze = dimz() - mz2; for (int v = 0; v<(int)((*this).dim); ++v) if (!weighted_dilatation) { for (int z = mz1; z::min(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const restype cval = (restype)(*this)(x+xm,y+ym,z+zm,v); if (mask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval; } dest(x,y,z,v) = max_val; } if (cond) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { restype max_val = cimg::type::min(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const T cval = (restype)pix3d(x+xm,y+ym,z+zm,v); if (mask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval; } dest(x,y,z,v) = max_val; } else for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { restype max_val = cimg::type::min(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const T cval = (restype)pix3d(x+xm,y+ym,z+zm,v,0); if (mask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval; } dest(x,y,z,v) = max_val; } } else { for (int z = mz1; z::min(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const t mval = mask(mx1+xm,my1+ym,mz1+zm); const restype cval = (restype)((*this)(x+xm,y+ym,z+zm,v) - mval); if (mval && cval>max_val) max_val = cval; } dest(x,y,z,v) = max_val; } if (cond) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { restype max_val = cimg::type::min(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const t mval = mask(mx1+xm,my1+ym,mz1+zm); const restype cval = (restype)(pix3d(x+xm,y+ym,z+zm,v) - mval); if (mval && cval>max_val) max_val = cval; } dest(x,y,z,v) = max_val; } else for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x=mye || z=mze)?++x:((x=mxe)?++x:(x=mxe))) { restype max_val = cimg::type::min(); for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) { const t mval = mask(mx1+xm,my1+ym,mz1+zm); const restype cval = (restype)(pix3d(x+xm,y+ym,z+zm,v,0) - mval); if (mval && cval>max_val) max_val = cval; } dest(x,y,z,v) = max_val; } } return dest; } template CImg& dilate(const CImg& mask, const unsigned int cond=1, const bool weighted_dilatation=false) { return get_dilate(mask,cond,weighted_dilatation).transfer_to(*this); } CImg get_dilate(const unsigned int n, const unsigned int cond=1) const { static CImg mask; if (n<2) return *this; if (mask.width!=n) mask.assign(n,n,1,1,1); const CImg res = get_dilate(mask,cond,false); if (n>20) mask.assign(); return res; } CImg& dilate(const unsigned int n, const unsigned int cond=1) { if (n<2) return *this; return get_dilate(n,cond).transfer_to(*this); } CImg get_noise(const double sigma=-20, const unsigned int ntype=0) const { return (+*this).noise(sigma,ntype); } CImg& noise(const double sigma=-20, const unsigned int ntype=0) { if (!is_empty()) { double nsigma = sigma, max = (double)cimg::type::max(), min = (double)cimg::type::min(); typedef typename cimg::superset::type ftype; cimg::srand(); ftype m = 0, M = 0; if (nsigma==0) return *this; if (nsigma<0 || ntype==2) m = (ftype)minmax(M); if (nsigma<0) nsigma = -nsigma*(M-m)/100.0; switch (ntype) { case 0: { for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { double val = *ptr + nsigma*cimg::grand(); if (val>max) val = max; if (val(*this).data; ) { double val = *ptr + nsigma*cimg::crand(); if (val>max) val = max; if (val(*this).data; ) if (cimg::rand()*100(*this).data; ) { const double z = (double)*ptr; if (z<=1.0e-10) *ptr = (T)0; else { if (z>100.0) *ptr = (T)(unsigned int)((std::sqrt(z) * cimg::grand()) + z); else { unsigned int k = 0; const double y = std::exp(-z); for (double s = 1.0; s>=y; ++k) s *= cimg::rand(); *ptr = (T)(k-1); } } } } break; case 4: { const double sqrt2 = (double)std::sqrt(2.0); for (T *ptr = (*this).data + (*this).size(); (ptr--)>(*this).data; ) { const double val0 = (double)*ptr/sqrt2, re = val0 + nsigma*cimg::grand(), im = val0 + nsigma*cimg::grand(); double val = std::sqrt(re*re + im*im); if (val>max) val = max; if (val::type> get_deriche(const float sigma, const int order=0, const char axe='x', const bool cond=true) const { typedef typename cimg::superset::type ftype; return CImg(*this,false).deriche(sigma,order,axe,cond); } CImg& deriche(const float sigma, const int order=0, const char axe='x', const bool cond=true) { typedef typename cimg::superset::type ftype; if (sigma<0) throw CImgArgumentException("CImg<%s>::deriche() : Given filter variance (sigma = %g) is negative",pixel_type(),sigma); if (is_empty() || (sigma<0.1 && !order)) return *this; const float nsigma = sigma<0.1f?0.1f:sigma, alpha = 1.695f/nsigma, ema = (float)std::exp(-alpha), ema2 = (float)std::exp(-2*alpha), b1 = -2*ema, b2 = ema2; float a0 = 0, a1 = 0, a2 = 0, a3 = 0, coefp = 0, coefn = 0; switch (order) { case 0: { const float k = (1-ema)*(1-ema)/(1+2*alpha*ema-ema2); a0 = k; a1 = k*(alpha-1)*ema; a2 = k*(alpha+1)*ema; a3 = -k*ema2; } break; case 1: { const float k = (1-ema)*(1-ema)/ema; a0 = k*ema; a1 = a3 = 0; a2 = -a0; } break; case 2: { const float ea = (float)std::exp(-alpha), k = -(ema2-1)/(2*alpha*ema), kn = (-2*(-1+3*ea-3*ea*ea+ea*ea*ea)/(3*ea+1+3*ea*ea+ea*ea*ea)); a0 = kn; a1 = -kn*(1+k*alpha)*ema; a2 = kn*(1-k*alpha)*ema; a3 = -kn*ema2; } break; default: throw CImgArgumentException("CImg<%s>::deriche() : Given filter order (order = %u) must be 0,1 or 2",pixel_type(),order); break; } coefp = (a0+a1)/(1+b1+b2); coefn = (a2+a3)/(1+b1+b2); switch (cimg::uncase(axe)) { case 'x': { const int N = width, off = 1; CImg Y(N); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { T *ptrX = ptr(0,y,z,v); ftype *ptrY = Y.data, yb = 0, yp = 0; T xp = (T)0; if (cond) { xp = *ptrX; yb = yp = (ftype)(coefp*xp); } for (int m=0; m=0; --n) { const T xc = *(ptrX-=off); const ftype yc = (ftype)(a2*xn + a3*xa - b1*yn - b2*ya); xa = xn; xn = xc; ya = yn; yn = yc; *ptrX = (T)(*(--ptrY)+yc); }; } } break; case 'y': { const int N = height, off = width; CImg Y(N); for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int x = 0; x<(int)((*this).width); ++x) { T *ptrX = ptr(x,0,z,v); ftype *ptrY = Y.data, yb = 0, yp = 0; T xp = (T)0; if (cond) { xp = *ptrX; yb = yp = (ftype)(coefp*xp); } for (int m=0; m=0; --n) { const T xc = *(ptrX-=off); const ftype yc = (ftype)(a2*xn + a3*xa - b1*yn - b2*ya); xa = xn; xn = xc; ya = yn; yn = yc; *ptrX = (T)(*(--ptrY)+yc); }; } } break; case 'z': { const int N = depth, off = width*height; CImg Y(N); for (int v = 0; v<(int)((*this).dim); ++v) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { T *ptrX = ptr(x,y,0,v); ftype *ptrY = Y.data, yb = 0, yp = 0; T xp = (T)0; if (cond) { xp = *ptrX; yb = yp = (ftype)(coefp*xp); } for (int m=0; m=0; --n) { const T xc = *(ptrX-=off); const ftype yc = (ftype)(a2*xn + a3*xa - b1*yn - b2*ya); xa = xn; xn = xc; ya = yn; yn = yc; *ptrX = (T)(*(--ptrY)+yc); }; } } break; case 'v': { const int N = dim, off = width*height*depth; CImg Y(N); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { T *ptrX = ptr(x,y,z,0); ftype *ptrY = Y.data, yb = 0, yp = 0; T xp = (T)0; if (cond) { xp = *ptrX; yb = yp = (ftype)(coefp*xp); } for (int m=0; m=0; --n) { const T xc = *(ptrX-=off); const ftype yc = (ftype)(a2*xn + a3*xa - b1*yn - b2*ya); xa = xn; xn = xc; ya = yn; yn = yc; *ptrX = (T)(*(--ptrY)+yc); }; } } break; } return *this; } CImg::type> get_blur(const float sigmax, const float sigmay, const float sigmaz, const bool cond=true) const { typedef typename cimg::superset::type ftype; return CImg(*this,false).blur(sigmax,sigmay,sigmaz,cond); } CImg& blur(const float sigmax, const float sigmay, const float sigmaz, const bool cond=true) { if (!is_empty()) { if (width>1 && sigmax>0) deriche(sigmax,0,'x',cond); if (height>1 && sigmay>0) deriche(sigmay,0,'y',cond); if (depth>1 && sigmaz>0) deriche(sigmaz,0,'z',cond); } return *this; } CImg::type> get_blur(const float sigma, const bool cond=true) const { typedef typename cimg::superset::type ftype; return CImg(*this,false).blur(sigma,cond); } CImg& blur(const float sigma, const bool cond=true) { return blur(sigma,sigma,sigma,cond); } template CImg get_blur_anisotropic(const CImg& G, const float amplitude=60.0f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true) const { return (+*this).blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx); } template CImg& blur_anisotropic(const CImg& G, const float amplitude=60.0f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true) { typedef typename cimg::superset::type ftype; if (!is_empty() && amplitude>0) { if (!G || (G.dim!=3 && G.dim!=6) || G.width!=width || G.height!=height || G.depth!=depth) throw CImgArgumentException("CImg<%s>::blur_anisotropic() : Specified tensor field (%u,%u,%u,%u) is not valid.", pixel_type(),G.width,G.height,G.depth,G.dim); const float sqrt2amplitude = (float)std::sqrt(2*amplitude); const bool threed = (G.dim>=6); const int dx1 = dimx()-1, dy1 = dimy()-1, dz1 = dimz()-1; CImg dest(width,height,depth,dim,0), W(width,height,depth,threed?4:3), tmp(dim); int N = 0; if (threed) for (float phi=(180%(int)da)/2.0f; phi<=180; phi+=da) { const float phir = (float)(phi*cimg::valuePI/180), datmp = (float)(da/std::cos(phir)), da2 = datmp<1?360.0f:datmp; for (float theta=0; theta<360; (theta+=da2),++N) { const float thetar = (float)(theta*cimg::valuePI/180), vx = (float)(std::cos(thetar)*std::cos(phir)), vy = (float)(std::sin(thetar)*std::cos(phir)), vz = (float)std::sin(phir); const t *pa = G.ptr(0,0,0,0), *pb = G.ptr(0,0,0,1), *pc = G.ptr(0,0,0,2), *pd = G.ptr(0,0,0,3), *pe = G.ptr(0,0,0,4), *pf = G.ptr(0,0,0,5); ftype *pd0 = W.ptr(0,0,0,0), *pd1 = W.ptr(0,0,0,1), *pd2 = W.ptr(0,0,0,2), *pd3 = W.ptr(0,0,0,3); for (int zg = 0; zg<(int)((G).depth); ++zg) for (int yg = 0; yg<(int)((G).height); ++yg) for (int xg = 0; xg<(int)((G).width); ++xg) { const t a = *(pa++), b = *(pb++), c = *(pc++), d = *(pd++), e = *(pe++), f = *(pf++); const float u = (float)(a*vx + b*vy + c*vz), v = (float)(b*vx + d*vy + e*vz), w = (float)(c*vx + e*vy + f*vz), n = (float)std::sqrt(1e-5+u*u+v*v+w*w), dln = dl/n; *(pd0++) = (ftype)(u*dln); *(pd1++) = (ftype)(v*dln); *(pd2++) = (ftype)(w*dln); *(pd3++) = (ftype)n; } for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { tmp.fill(0); const float cu = (float)W(x,y,z,0), cv = (float)W(x,y,z,1), cw = (float)W(x,y,z,2), n = (float)W(x,y,z,3), fsigma = (float)(n*sqrt2amplitude), length = gauss_prec*fsigma, fsigma2 = 2*fsigma*fsigma; float S = 0, pu = cu, pv = cv, pw = cw, X = (float)x, Y = (float)y, Z = (float)z; switch (interpolation) { case 0: { for (float l=0; l=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) { const int cx = (int)(X+0.5f), cy = (int)(Y+0.5f), cz = (int)(Z+0.5f); float u = (float)W(cx,cy,cz,0), v = (float)W(cx,cy,cz,1), w = (float)W(cx,cy,cz,2); if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; } if (fast_approx) { for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)(*this)(cx,cy,cz,k); ++S; } else { const float coef = (float)std::exp(-l*l/fsigma2); for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)(coef*(*this)(cx,cy,cz,k)); S+=coef; } X+=(pu=u); Y+=(pv=v); Z+=(pw=w); } } break; case 1: { for (float l=0; l=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) { const int cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1, cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1, cz = (int)Z, pz = (cz-1<0)?0:cz-1, nz = (cz+1>dz1)?dz1:cz+1; const float curru = (float)W(cx,cy,cz,0), currv = (float)W(cx,cy,cz,1), currw = (float)W(cx,cy,cz,2); { ftype &u = W(px,py,pz,0), &v = W(px,py,pz,1), &w = W(px,py,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,py,pz,0), &v = W(cx,py,pz,1), &w = W(cx,py,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,py,pz,0), &v = W(nx,py,pz,1), &w = W(nx,py,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,cy,pz,0), &v = W(px,cy,pz,1), &w = W(px,cy,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,cy,pz,0), &v = W(cx,cy,pz,1), &w = W(cx,cy,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,cy,pz,0), &v = W(nx,cy,pz,1), &w = W(nx,cy,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,ny,pz,0), &v = W(px,ny,pz,1), &w = W(px,ny,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,ny,pz,0), &v = W(cx,ny,pz,1), &w = W(cx,ny,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,ny,pz,0), &v = W(nx,ny,pz,1), &w = W(nx,ny,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,py,cz,0), &v = W(px,py,cz,1), &w = W(px,py,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,py,cz,0), &v = W(cx,py,cz,1), &w = W(cx,py,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,py,cz,0), &v = W(nx,py,cz,1), &w = W(nx,py,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,cy,cz,0), &v = W(px,cy,cz,1), &w = W(px,cy,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,cy,cz,0), &v = W(nx,cy,cz,1), &w = W(nx,cy,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,ny,cz,0), &v = W(px,ny,cz,1), &w = W(px,ny,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,ny,cz,0), &v = W(cx,ny,cz,1), &w = W(cx,ny,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,ny,cz,0), &v = W(nx,ny,cz,1), &w = W(nx,ny,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,py,nz,0), &v = W(px,py,nz,1), &w = W(px,py,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,py,nz,0), &v = W(cx,py,nz,1), &w = W(cx,py,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,py,nz,0), &v = W(nx,py,nz,1), &w = W(nx,py,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,cy,nz,0), &v = W(px,cy,nz,1), &w = W(px,cy,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,cy,nz,0), &v = W(cx,cy,nz,1), &w = W(cx,cy,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,cy,nz,0), &v = W(nx,cy,nz,1), &w = W(nx,cy,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,ny,nz,0), &v = W(px,ny,nz,1), &w = W(px,ny,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,ny,nz,0), &v = W(cx,ny,nz,1), &w = W(cx,ny,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,ny,nz,0), &v = W(nx,ny,nz,1), &w = W(nx,ny,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; float u = (float)(W.linear_pix3d(X,Y,Z,0)), v = (float)(W.linear_pix3d(X,Y,Z,1)), w = (float)(W.linear_pix3d(X,Y,Z,2)); if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; } if (fast_approx) { for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)linear_pix3d(X,Y,Z,k); ++S; } else { const float coef = (float)std::exp(-l*l/fsigma2); for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)(coef*linear_pix3d(X,Y,Z,k)); S+=coef; } X+=(pu=u); Y+=(pv=v); Z+=(pw=w); } } break; default: { for (float l=0; l=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) { const int cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1, cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1, cz = (int)Z, pz = (cz-1<0)?0:cz-1, nz = (cz+1>dz1)?dz1:cz+1; const float curru = (float)W(cx,cy,cz,0), currv = (float)W(cx,cy,cz,1), currw = (float)W(cx,cy,cz,2); { ftype &u = W(px,py,pz,0), &v = W(px,py,pz,1), &w = W(px,py,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,py,pz,0), &v = W(cx,py,pz,1), &w = W(cx,py,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,py,pz,0), &v = W(nx,py,pz,1), &w = W(nx,py,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,cy,pz,0), &v = W(px,cy,pz,1), &w = W(px,cy,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,cy,pz,0), &v = W(cx,cy,pz,1), &w = W(cx,cy,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,cy,pz,0), &v = W(nx,cy,pz,1), &w = W(nx,cy,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,ny,pz,0), &v = W(px,ny,pz,1), &w = W(px,ny,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,ny,pz,0), &v = W(cx,ny,pz,1), &w = W(cx,ny,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,ny,pz,0), &v = W(nx,ny,pz,1), &w = W(nx,ny,pz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,py,cz,0), &v = W(px,py,cz,1), &w = W(px,py,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,py,cz,0), &v = W(cx,py,cz,1), &w = W(cx,py,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,py,cz,0), &v = W(nx,py,cz,1), &w = W(nx,py,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,cy,cz,0), &v = W(px,cy,cz,1), &w = W(px,cy,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,cy,cz,0), &v = W(nx,cy,cz,1), &w = W(nx,cy,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,ny,cz,0), &v = W(px,ny,cz,1), &w = W(px,ny,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,ny,cz,0), &v = W(cx,ny,cz,1), &w = W(cx,ny,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,ny,cz,0), &v = W(nx,ny,cz,1), &w = W(nx,ny,cz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,py,nz,0), &v = W(px,py,nz,1), &w = W(px,py,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,py,nz,0), &v = W(cx,py,nz,1), &w = W(cx,py,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,py,nz,0), &v = W(nx,py,nz,1), &w = W(nx,py,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,cy,nz,0), &v = W(px,cy,nz,1), &w = W(px,cy,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,cy,nz,0), &v = W(cx,cy,nz,1), &w = W(cx,cy,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,cy,nz,0), &v = W(nx,cy,nz,1), &w = W(nx,cy,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(px,ny,nz,0), &v = W(px,ny,nz,1), &w = W(px,ny,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(cx,ny,nz,0), &v = W(cx,ny,nz,1), &w = W(cx,ny,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; { ftype &u = W(nx,ny,nz,0), &v = W(nx,ny,nz,1), &w = W(nx,ny,nz,2); if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}; const float u0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,0)), v0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,1)), w0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,2)); float u = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,0)), v = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,1)), w = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,2)); if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; } if (fast_approx) { for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)linear_pix3d(X,Y,Z,k); ++S; } else { const float coef = (float)std::exp(-l*l/fsigma2); for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)(coef*linear_pix3d(X,Y,Z,k)); S+=coef; } X+=(pu=u); Y+=(pv=v); Z+=(pw=w); } } break; } if (S>0) for (int k = 0; k<(int)((dest).dim); ++k) dest(x,y,z,k)+=tmp[k]/S; else for (int k = 0; k<(int)((dest).dim); ++k) dest(x,y,z,k)+=(ftype)((*this)(x,y,z,k)); if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; } } } else for (float theta=(360%(int)da)/2.0f; theta<360; (theta+=da),++N) { const float thetar = (float)(theta*cimg::valuePI/180), vx = (float)(std::cos(thetar)), vy = (float)(std::sin(thetar)); const t *pa = G.ptr(0,0,0,0), *pb = G.ptr(0,0,0,1), *pc = G.ptr(0,0,0,2); ftype *pd0 = W.ptr(0,0,0,0), *pd1 = W.ptr(0,0,0,1), *pd2 = W.ptr(0,0,0,2); for (int yg = 0; yg<(int)((G).height); ++yg) for (int xg = 0; xg<(int)((G).width); ++xg) { const t a = *(pa++), b = *(pb++), c = *(pc++); const float u = (float)(a*vx + b*vy), v = (float)(b*vx + c*vy), n = (float)std::sqrt(1e-5+u*u+v*v), dln = dl/n; *(pd0++) = (ftype)(u*dln); *(pd1++) = (ftype)(v*dln); *(pd2++) = (ftype)n; } for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { tmp.fill(0); const float cu = (float)W(x,y,0,0), cv = (float)W(x,y,0,1), n = (float)W(x,y,0,2), fsigma = (float)(n*sqrt2amplitude), length = gauss_prec*fsigma, fsigma2 = 2*fsigma*fsigma; float S = 0, pu = cu, pv = cv, X = (float)x, Y = (float)y; switch (interpolation) { case 0: { for (float l=0; l=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) { const int cx = (int)(X+0.5f), cy = (int)(Y+0.5f); float u = (float)W(cx,cy,0,0), v = (float)W(cx,cy,0,1); if ((pu*u + pv*v)<0) { u=-u; v=-v; } if (fast_approx) { for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)(*this)(cx,cy,0,k); ++S; } else { const float coef = (float)std::exp(-l*l/fsigma2); for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)(coef*(*this)(cx,cy,0,k)); S+=coef; } X+=(pu=u); Y+=(pv=v); } } break; case 1: { for (float l=0; l=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) { const int cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1, cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1; const float curru = (float)W(cx,cy,0,0), currv = (float)W(cx,cy,0,1); { ftype &u = W(px,py,0,0), &v = W(px,py,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(cx,py,0,0), &v = W(cx,py,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(nx,py,0,0), &v = W(nx,py,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(px,cy,0,0), &v = W(px,cy,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(nx,cy,0,0), &v = W(nx,cy,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(px,ny,0,0), &v = W(px,ny,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(cx,ny,0,0), &v = W(cx,ny,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(nx,ny,0,0), &v = W(nx,ny,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; float u = (float)(W.linear_pix2d(X,Y,0,0)), v = (float)(W.linear_pix2d(X,Y,0,1)); if ((pu*u + pv*v)<0) { u=-u; v=-v; } if (fast_approx) { for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)linear_pix2d(X,Y,0,k); ++S; } else { const float coef = (float)std::exp(-l*l/fsigma2); for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)(coef*linear_pix2d(X,Y,0,k)); S+=coef; } X+=(pu=u); Y+=(pv=v); } } break; default: { for (float l=0; l=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) { const int cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1, cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1; const float curru = (float)W(cx,cy,0,0), currv = (float)W(cx,cy,0,1); { ftype &u = W(px,py,0,0), &v = W(px,py,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(cx,py,0,0), &v = W(cx,py,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(nx,py,0,0), &v = W(nx,py,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(px,cy,0,0), &v = W(px,cy,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(nx,cy,0,0), &v = W(nx,cy,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(px,ny,0,0), &v = W(px,ny,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(cx,ny,0,0), &v = W(cx,ny,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; { ftype &u = W(nx,ny,0,0), &v = W(nx,ny,0,1); if (u*curru + v*currv<0) { u=-u; v=-v; }}; const float u0 = (float)(0.5f*W.linear_pix2d(X,Y,0,0)), v0 = (float)(0.5f*W.linear_pix2d(X,Y,0,1)); float u = (float)(W.linear_pix2d(X+u0,Y+v0,0,0)), v = (float)(W.linear_pix2d(X+u0,Y+v0,0,1)); if ((pu*u + pv*v)<0) { u=-u; v=-v; } if (fast_approx) { for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)linear_pix2d(X,Y,0,k); ++S; } else { const float coef = (float)std::exp(-l*l/fsigma2); for (int k = 0; k<(int)((*this).dim); ++k) tmp[k]+=(ftype)(coef*linear_pix2d(X,Y,0,k)); S+=coef; } X+=(pu=u); Y+=(pv=v); } } break; } if (S>0) for (int k = 0; k<(int)((dest).dim); ++k) dest(x,y,0,k)+=tmp[k]/S; else for (int k = 0; k<(int)((dest).dim); ++k) dest(x,y,0,k)+=(ftype)((*this)(x,y,0,k)); if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; } } const ftype *ptrs = dest.data+dest.size(); const T m = cimg::type::min(), M = cimg::type::max(); for (T *ptrd = (*this).data + (*this).size(); (ptrd--)>(*this).data; ) { const ftype val = *(--ptrs)/N; *ptrd = valM?M:(T)val); } } return *this; } template CImg get_blur_anisotropic(const CImg& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f, const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true, const float geom_factor=1.0f) const { return (+*this).blur_anisotropic(mask,amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor); } template CImg& blur_anisotropic(const CImg& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f, const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true, const float geom_factor=1.0f) { if (!is_empty() && amplitude>0) { if (amplitude==0) return *this; if (amplitude<0 || sharpness<0 || anisotropy<0 || anisotropy>1 || alpha<0 || sigma<0 || dl<0 || da<0 || gauss_prec<0) throw CImgArgumentException("CImg<%s>::blur_anisotropic() : Given parameters are amplitude(%g), sharpness(%g), " "anisotropy(%g), alpha(%g), sigma(%g), dl(%g), da(%g), gauss_prec(%g).\n" "Admissible parameters are in the range : amplitude>0, sharpness>0, anisotropy in [0,1], " "alpha>0, sigma>0, dl>0, da>0, gauss_prec>0.", pixel_type(),amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec); const bool threed = (depth>1), no_mask = mask.is_empty(); const float nsharpness = cimg::max(sharpness,1e-5f), power1 = 0.5f*nsharpness, power2 = power1/(1e-7f+1.0f-anisotropy); CImg blurred = CImg(*this,false).blur(alpha); if (geom_factor>0) blurred*=geom_factor; else blurred.normalize(0,-geom_factor); if (threed) { greycstoration_mutex_lock(greycstoration_params[0]);; CImg val(3), vec(3,3), G(blurred.get_structure_tensorXYZ()); if (sigma>0) G.blur(sigma); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { if (no_mask || mask(x,y,z)) { G.get_tensor_at(x,y,z).symmetric_eigen(val,vec); const float l1 = val[2], l2 = val[1], l3 = val[0], ux = vec(0,0), uy = vec(0,1), uz = vec(0,2), vx = vec(1,0), vy = vec(1,1), vz = vec(1,2), wx = vec(2,0), wy = vec(2,1), wz = vec(2,2), n1 = (float)std::pow(1.0f+l1+l2+l3,-power1), n2 = (float)std::pow(1.0f+l1+l2+l3,-power2); G(x,y,z,0) = n1*(ux*ux + vx*vx) + n2*wx*wx; G(x,y,z,1) = n1*(ux*uy + vx*vy) + n2*wx*wy; G(x,y,z,2) = n1*(ux*uz + vx*vz) + n2*wx*wz; G(x,y,z,3) = n1*(uy*uy + vy*vy) + n2*wy*wy; G(x,y,z,4) = n1*(uy*uz + vy*vz) + n2*wy*wz; G(x,y,z,5) = n1*(uz*uz + vz*vz) + n2*wz*wz; } 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; if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; } greycstoration_mutex_unlock(greycstoration_params[0]);; blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx); } else { greycstoration_mutex_lock(greycstoration_params[0]);; CImg val(2), vec(2,2), G(blurred.get_structure_tensorXY()); if (sigma>0) G.blur(sigma); for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { if (no_mask || mask(x,y)) { G.get_tensor_at(x,y).symmetric_eigen(val,vec); const float l1 = val[1], l2 = val[0], ux = vec(1,0), uy = vec(1,1), vx = vec(0,0), vy = vec(0,1), n1 = (float)std::pow(1.0f+l1+l2,-power1), n2 = (float)std::pow(1.0f+l1+l2,-power2); G(x,y,0,0) = n1*ux*ux + n2*vx*vx; G(x,y,0,1) = n1*ux*uy + n2*vx*vy; G(x,y,0,2) = n1*uy*uy + n2*vy*vy; } else G(x,y,0,0) = G(x,y,0,1) = G(x,y,0,2) = 0; if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; } greycstoration_mutex_unlock(greycstoration_params[0]);; blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx); } } return *this; } CImg get_blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f, const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true, const float geom_factor=1.0f) const { return (+*this).blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor); } CImg& blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f, const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true, const float geom_factor=1.0f) { return blur_anisotropic(CImg(),amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor); } CImg get_blur_bilateral(const float sigmax, const float sigmay, const float sigmaz, const float sigmar, const int bgridx, const int bgridy, const int bgridz, const int bgridr, const bool interpolation=true) const { return (+*this).blur_bilateral(sigmax,sigmay,sigmaz,sigmar,bgridx,bgridy,bgridz,bgridr,interpolation); } CImg& blur_bilateral(const float sigmax, const float sigmay, const float sigmaz, const float sigmar, const int bgridx, const int bgridy, const int bgridz, const int bgridr, const bool interpolation=true) { T m, M = maxmin(m); const float range = (float)(1.0f+M-m); const unsigned int bx0 = bgridx>=0?bgridx:width*(-bgridx)/100, by0 = bgridy>=0?bgridy:height*(-bgridy)/100, bz0 = bgridz>=0?bgridz:depth*(-bgridz)/100, br0 = bgridr>=0?bgridr:(int)(-range*bgridr/100), bx = bx0>0?bx0:1, by = by0>0?by0:1, bz = bz0>0?bz0:1, br = br0>0?br0:1; const float nsigmax = sigmax*bx/width, nsigmay = sigmay*by/height, nsigmaz = sigmaz*bz/depth, nsigmar = sigmar*br/range; if (nsigmax>0 || nsigmay>0 || nsigmaz>0 || nsigmar>0) { const bool threed = depth>1; if (threed) { typedef typename cimg::last::type ftype; CImg bgrid(bx,by,bz,br), bgridw(bx,by,bz,br); for (int k = 0; k<(int)((*this).dim); ++k) { bgrid.fill(0); bgridw.fill(0); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const T val = (*this)(x,y,z,k); const int X = x*bx/width, Y = y*by/height, Z = z*bz/depth, R = (int)((val-m)*br/range); bgrid(X,Y,Z,R) = (float)val; bgridw(X,Y,Z,R) = 1; } bgrid.blur(nsigmax,nsigmay,nsigmaz,true).deriche(nsigmar,0,'v',false); bgridw.blur(nsigmax,nsigmay,nsigmaz,true).deriche(nsigmar,0,'v',false); if (interpolation) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const T val = (*this)(x,y,z,k); const float X = (float)x*bx/width, Y = (float)y*by/height, Z = (float)z*bz/depth, R = (val-m)*br/range, bval0 = bgrid.linear_pix4d(X,Y,Z,R), bval1 = bgridw.linear_pix4d(X,Y,Z,R); (*this)(x,y,z,k) = (T)(bval0/bval1); } else for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const T val = (*this)(x,y,z,k); const int X = x*bx/width, Y = y*by/height, Z = z*bz/depth, R = (int)((val-m)*br/range); const float bval0 = bgrid(X,Y,Z,R), bval1 = bgridw(X,Y,Z,R); (*this)(x,y,z,k) = (T)(bval0/bval1); } } } else { typedef typename cimg::last::type ftype; CImg bgrid(bx,by,br,2); for (int k = 0; k<(int)((*this).dim); ++k) { bgrid.fill(0); for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const T val = (*this)(x,y,k); const int X = x*bx/width, Y = y*by/height, R = (int)((val-m)*br/range); bgrid(X,Y,R,0) = (float)val; bgrid(X,Y,R,1) = 1; } bgrid.blur(nsigmax,nsigmay,0,true).blur(0,0,nsigmar,false); if (interpolation) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const T val = (*this)(x,y,k); const float X = (float)x*bx/width, Y = (float)y*by/height, R = (val-m)*br/range, bval0 = bgrid.linear_pix3d(X,Y,R,0), bval1 = bgrid.linear_pix3d(X,Y,R,1); (*this)(x,y,k) = (T)(bval0/bval1); } else for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const T val = (*this)(x,y,k); const int X = x*bx/width, Y = y*by/height, R = (int)((val-m)*br/range); const float bval0 = bgrid(X,Y,R,0), bval1 = bgrid(X,Y,R,1); (*this)(x,y,k) = (T)(bval0/bval1); } } } } return *this; } CImg get_blur_bilateral(const float sigmas, const float sigmar, const int bgrids=-33, const int bgridr=32, const bool interpolation=true) const { return (+*this).blur_bilateral(sigmas,sigmas,sigmas,sigmar,bgrids,bgrids,bgrids,bgridr,interpolation); } CImg& blur_bilateral(const float sigmas, const float sigmar, const int bgrids=-33, const int bgridr=32, const bool interpolation=true) { return blur_bilateral(sigmas,sigmas,sigmas,sigmar,bgrids,bgrids,bgrids,bgridr,interpolation); } CImg get_blur_patch(const unsigned int patch_size=3, const float sigma_p=10.0f, const float sigma_s=10.0f, const unsigned int lookup_size=4, const bool fast_approx=true) const { return (+*this).blur_patch(patch_size,sigma_p,sigma_s,lookup_size,fast_approx); } CImg& blur_patch(const unsigned int patch_size=3, const float sigma_p=10.0f, const float sigma_s=10.0f, const unsigned int lookup_size=4, const bool fast_approx=true) { typedef typename cimg::superset::type ftype; CImg res(width,height,depth,dim,0); CImg P(patch_size*patch_size*dim), Q(P); const float sigma_s2 = sigma_s*sigma_s, sigma_p2 = sigma_p*sigma_p, Pnorm = P.size()*sigma_p2; const int rsize2 = (int)lookup_size/2, rsize1 = rsize2-1+(lookup_size%2); if (depth>1) switch (patch_size) { case 2: if (fast_approx) { { const unsigned int N3 = 2*2*2; for (int z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; ++z, ++_n1z) for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1; _n1x<(int)((*this).width) || x==--_n1x; ++x, ++_n1x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N3*k)[0] = (*this)(x, y, z,k), P.ptr(N3*k)[1] = (*this)(_n1x, y, z,k), P.ptr(N3*k)[2] = (*this)(x,_n1y, z,k), P.ptr(N3*k)[3] = (*this)(_n1x,_n1y, z,k), P.ptr(N3*k)[4] = (*this)(x, y,_n1z,k), P.ptr(N3*k)[5] = (*this)(_n1x, y,_n1z,k), P.ptr(N3*k)[6] = (*this)(x,_n1y,_n1z,k), P.ptr(N3*k)[7] = (*this)(_n1x,_n1y,_n1z,k); const int x0 = x-rsize1, y0 = y-rsize1, z0 = z-rsize1, x1 = x+rsize2, y1 = y+rsize2, z1 = z+rsize2; float sum_weights = 0; for (int r = (int)(z0)<0?0:(int)(z0), _n1r = r+1>=(int)((*this).depth)?(int)((*this).depth)-1:r+1; r<=(int)(z1) && (_n1r<(int)((*this).depth) || r==--_n1r); ++r, ++_n1r) for (int q = (int)(y0)<0?0:(int)(y0), _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1; q<=(int)(y1) && (_n1q<(int)((*this).height) || q==--_n1q); ++q, ++_n1q) for (int p = (int)(x0)<0?0:(int)(x0), _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1; p<=(int)(x1) && (_n1p<(int)((*this).width) || p==--_n1p); ++p, ++_n1p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N3*k)[0] = (*this)(p, q, r,k), Q.ptr(N3*k)[1] = (*this)(_n1p, q, r,k), Q.ptr(N3*k)[2] = (*this)(p,_n1q, r,k), Q.ptr(N3*k)[3] = (*this)(_n1p,_n1q, r,k), Q.ptr(N3*k)[4] = (*this)(p, q,_n1r,k), Q.ptr(N3*k)[5] = (*this)(_n1p, q,_n1r,k), Q.ptr(N3*k)[6] = (*this)(p,_n1q,_n1r,k), Q.ptr(N3*k)[7] = (*this)(_n1p,_n1q,_n1r,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, dz = r-z, alldist = distance2 + (dx*dx+dy*dy+dz*dz)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)+=weight*(*this)(p,q,r,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k) = (*this)(x,y,z,k); }}; } else { { const unsigned int N3 = 2*2*2; for (int z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; ++z, ++_n1z) for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1; _n1x<(int)((*this).width) || x==--_n1x; ++x, ++_n1x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N3*k)[0] = (*this)(x, y, z,k), P.ptr(N3*k)[1] = (*this)(_n1x, y, z,k), P.ptr(N3*k)[2] = (*this)(x,_n1y, z,k), P.ptr(N3*k)[3] = (*this)(_n1x,_n1y, z,k), P.ptr(N3*k)[4] = (*this)(x, y,_n1z,k), P.ptr(N3*k)[5] = (*this)(_n1x, y,_n1z,k), P.ptr(N3*k)[6] = (*this)(x,_n1y,_n1z,k), P.ptr(N3*k)[7] = (*this)(_n1x,_n1y,_n1z,k); const int x0 = x-rsize1, y0 = y-rsize1, z0 = z-rsize1, x1 = x+rsize2, y1 = y+rsize2, z1 = z+rsize2; float sum_weights = 0; for (int r = (int)(z0)<0?0:(int)(z0), _n1r = r+1>=(int)((*this).depth)?(int)((*this).depth)-1:r+1; r<=(int)(z1) && (_n1r<(int)((*this).depth) || r==--_n1r); ++r, ++_n1r) for (int q = (int)(y0)<0?0:(int)(y0), _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1; q<=(int)(y1) && (_n1q<(int)((*this).height) || q==--_n1q); ++q, ++_n1q) for (int p = (int)(x0)<0?0:(int)(x0), _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1; p<=(int)(x1) && (_n1p<(int)((*this).width) || p==--_n1p); ++p, ++_n1p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N3*k)[0] = (*this)(p, q, r,k), Q.ptr(N3*k)[1] = (*this)(_n1p, q, r,k), Q.ptr(N3*k)[2] = (*this)(p,_n1q, r,k), Q.ptr(N3*k)[3] = (*this)(_n1p,_n1q, r,k), Q.ptr(N3*k)[4] = (*this)(p, q,_n1r,k), Q.ptr(N3*k)[5] = (*this)(_n1p, q,_n1r,k), Q.ptr(N3*k)[6] = (*this)(p,_n1q,_n1r,k), Q.ptr(N3*k)[7] = (*this)(_n1p,_n1q,_n1r,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, dz = r-z, alldist = distance2 + (dx*dx+dy*dy+dz*dz)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)+=weight*(*this)(p,q,r,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k) = (*this)(x,y,z,k); }}; } break; case 3: if (fast_approx) { { const unsigned int N3 = 3*3*3; for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1; _n1x<(int)((*this).width) || x==--_n1x; _p1x = x++, ++_n1x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N3*k)[0] = (*this)(_p1x,_p1y,_p1z,k), P.ptr(N3*k)[1] = (*this)(x,_p1y,_p1z,k), P.ptr(N3*k)[2] = (*this)(_n1x,_p1y,_p1z,k), P.ptr(N3*k)[3] = (*this)(_p1x, y,_p1z,k), P.ptr(N3*k)[4] = (*this)(x, y,_p1z,k), P.ptr(N3*k)[5] = (*this)(_n1x, y,_p1z,k), P.ptr(N3*k)[6] = (*this)(_p1x,_n1y,_p1z,k), P.ptr(N3*k)[7] = (*this)(x,_n1y,_p1z,k), P.ptr(N3*k)[8] = (*this)(_n1x,_n1y,_p1z,k), P.ptr(N3*k)[9] = (*this)(_p1x,_p1y, z,k), P.ptr(N3*k)[10] = (*this)(x,_p1y, z,k), P.ptr(N3*k)[11] = (*this)(_n1x,_p1y, z,k), P.ptr(N3*k)[12] = (*this)(_p1x, y, z,k), P.ptr(N3*k)[13] = (*this)(x, y, z,k), P.ptr(N3*k)[14] = (*this)(_n1x, y, z,k), P.ptr(N3*k)[15] = (*this)(_p1x,_n1y, z,k), P.ptr(N3*k)[16] = (*this)(x,_n1y, z,k), P.ptr(N3*k)[17] = (*this)(_n1x,_n1y, z,k), P.ptr(N3*k)[18] = (*this)(_p1x,_p1y,_n1z,k), P.ptr(N3*k)[19] = (*this)(x,_p1y,_n1z,k), P.ptr(N3*k)[20] = (*this)(_n1x,_p1y,_n1z,k), P.ptr(N3*k)[21] = (*this)(_p1x, y,_n1z,k), P.ptr(N3*k)[22] = (*this)(x, y,_n1z,k), P.ptr(N3*k)[23] = (*this)(_n1x, y,_n1z,k), P.ptr(N3*k)[24] = (*this)(_p1x,_n1y,_n1z,k), P.ptr(N3*k)[25] = (*this)(x,_n1y,_n1z,k), P.ptr(N3*k)[26] = (*this)(_n1x,_n1y,_n1z,k); const int x0 = x-rsize1, y0 = y-rsize1, z0 = z-rsize1, x1 = x+rsize2, y1 = y+rsize2, z1 = z+rsize2; float sum_weights = 0; for (int r = (int)(z0)<0?0:(int)(z0), _p1r = r-1<0?0:r-1, _n1r = r+1>=(int)((*this).depth)?(int)((*this).depth)-1:r+1; r<=(int)(z1) && (_n1r<(int)((*this).depth) || r==--_n1r); _p1r = r++, ++_n1r) for (int q = (int)(y0)<0?0:(int)(y0), _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1; q<=(int)(y1) && (_n1q<(int)((*this).height) || q==--_n1q); _p1q = q++, ++_n1q) for (int p = (int)(x0)<0?0:(int)(x0), _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1; p<=(int)(x1) && (_n1p<(int)((*this).width) || p==--_n1p); _p1p = p++, ++_n1p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N3*k)[0] = (*this)(_p1p,_p1q,_p1r,k), Q.ptr(N3*k)[1] = (*this)(p,_p1q,_p1r,k), Q.ptr(N3*k)[2] = (*this)(_n1p,_p1q,_p1r,k), Q.ptr(N3*k)[3] = (*this)(_p1p, q,_p1r,k), Q.ptr(N3*k)[4] = (*this)(p, q,_p1r,k), Q.ptr(N3*k)[5] = (*this)(_n1p, q,_p1r,k), Q.ptr(N3*k)[6] = (*this)(_p1p,_n1q,_p1r,k), Q.ptr(N3*k)[7] = (*this)(p,_n1q,_p1r,k), Q.ptr(N3*k)[8] = (*this)(_n1p,_n1q,_p1r,k), Q.ptr(N3*k)[9] = (*this)(_p1p,_p1q, r,k), Q.ptr(N3*k)[10] = (*this)(p,_p1q, r,k), Q.ptr(N3*k)[11] = (*this)(_n1p,_p1q, r,k), Q.ptr(N3*k)[12] = (*this)(_p1p, q, r,k), Q.ptr(N3*k)[13] = (*this)(p, q, r,k), Q.ptr(N3*k)[14] = (*this)(_n1p, q, r,k), Q.ptr(N3*k)[15] = (*this)(_p1p,_n1q, r,k), Q.ptr(N3*k)[16] = (*this)(p,_n1q, r,k), Q.ptr(N3*k)[17] = (*this)(_n1p,_n1q, r,k), Q.ptr(N3*k)[18] = (*this)(_p1p,_p1q,_n1r,k), Q.ptr(N3*k)[19] = (*this)(p,_p1q,_n1r,k), Q.ptr(N3*k)[20] = (*this)(_n1p,_p1q,_n1r,k), Q.ptr(N3*k)[21] = (*this)(_p1p, q,_n1r,k), Q.ptr(N3*k)[22] = (*this)(p, q,_n1r,k), Q.ptr(N3*k)[23] = (*this)(_n1p, q,_n1r,k), Q.ptr(N3*k)[24] = (*this)(_p1p,_n1q,_n1r,k), Q.ptr(N3*k)[25] = (*this)(p,_n1q,_n1r,k), Q.ptr(N3*k)[26] = (*this)(_n1p,_n1q,_n1r,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, dz = r-z, alldist = distance2 + (dx*dx+dy*dy+dz*dz)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)+=weight*(*this)(p,q,r,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k) = (*this)(x,y,z,k); }}; } else { { const unsigned int N3 = 3*3*3; for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1; _n1x<(int)((*this).width) || x==--_n1x; _p1x = x++, ++_n1x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N3*k)[0] = (*this)(_p1x,_p1y,_p1z,k), P.ptr(N3*k)[1] = (*this)(x,_p1y,_p1z,k), P.ptr(N3*k)[2] = (*this)(_n1x,_p1y,_p1z,k), P.ptr(N3*k)[3] = (*this)(_p1x, y,_p1z,k), P.ptr(N3*k)[4] = (*this)(x, y,_p1z,k), P.ptr(N3*k)[5] = (*this)(_n1x, y,_p1z,k), P.ptr(N3*k)[6] = (*this)(_p1x,_n1y,_p1z,k), P.ptr(N3*k)[7] = (*this)(x,_n1y,_p1z,k), P.ptr(N3*k)[8] = (*this)(_n1x,_n1y,_p1z,k), P.ptr(N3*k)[9] = (*this)(_p1x,_p1y, z,k), P.ptr(N3*k)[10] = (*this)(x,_p1y, z,k), P.ptr(N3*k)[11] = (*this)(_n1x,_p1y, z,k), P.ptr(N3*k)[12] = (*this)(_p1x, y, z,k), P.ptr(N3*k)[13] = (*this)(x, y, z,k), P.ptr(N3*k)[14] = (*this)(_n1x, y, z,k), P.ptr(N3*k)[15] = (*this)(_p1x,_n1y, z,k), P.ptr(N3*k)[16] = (*this)(x,_n1y, z,k), P.ptr(N3*k)[17] = (*this)(_n1x,_n1y, z,k), P.ptr(N3*k)[18] = (*this)(_p1x,_p1y,_n1z,k), P.ptr(N3*k)[19] = (*this)(x,_p1y,_n1z,k), P.ptr(N3*k)[20] = (*this)(_n1x,_p1y,_n1z,k), P.ptr(N3*k)[21] = (*this)(_p1x, y,_n1z,k), P.ptr(N3*k)[22] = (*this)(x, y,_n1z,k), P.ptr(N3*k)[23] = (*this)(_n1x, y,_n1z,k), P.ptr(N3*k)[24] = (*this)(_p1x,_n1y,_n1z,k), P.ptr(N3*k)[25] = (*this)(x,_n1y,_n1z,k), P.ptr(N3*k)[26] = (*this)(_n1x,_n1y,_n1z,k); const int x0 = x-rsize1, y0 = y-rsize1, z0 = z-rsize1, x1 = x+rsize2, y1 = y+rsize2, z1 = z+rsize2; float sum_weights = 0; for (int r = (int)(z0)<0?0:(int)(z0), _p1r = r-1<0?0:r-1, _n1r = r+1>=(int)((*this).depth)?(int)((*this).depth)-1:r+1; r<=(int)(z1) && (_n1r<(int)((*this).depth) || r==--_n1r); _p1r = r++, ++_n1r) for (int q = (int)(y0)<0?0:(int)(y0), _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1; q<=(int)(y1) && (_n1q<(int)((*this).height) || q==--_n1q); _p1q = q++, ++_n1q) for (int p = (int)(x0)<0?0:(int)(x0), _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1; p<=(int)(x1) && (_n1p<(int)((*this).width) || p==--_n1p); _p1p = p++, ++_n1p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N3*k)[0] = (*this)(_p1p,_p1q,_p1r,k), Q.ptr(N3*k)[1] = (*this)(p,_p1q,_p1r,k), Q.ptr(N3*k)[2] = (*this)(_n1p,_p1q,_p1r,k), Q.ptr(N3*k)[3] = (*this)(_p1p, q,_p1r,k), Q.ptr(N3*k)[4] = (*this)(p, q,_p1r,k), Q.ptr(N3*k)[5] = (*this)(_n1p, q,_p1r,k), Q.ptr(N3*k)[6] = (*this)(_p1p,_n1q,_p1r,k), Q.ptr(N3*k)[7] = (*this)(p,_n1q,_p1r,k), Q.ptr(N3*k)[8] = (*this)(_n1p,_n1q,_p1r,k), Q.ptr(N3*k)[9] = (*this)(_p1p,_p1q, r,k), Q.ptr(N3*k)[10] = (*this)(p,_p1q, r,k), Q.ptr(N3*k)[11] = (*this)(_n1p,_p1q, r,k), Q.ptr(N3*k)[12] = (*this)(_p1p, q, r,k), Q.ptr(N3*k)[13] = (*this)(p, q, r,k), Q.ptr(N3*k)[14] = (*this)(_n1p, q, r,k), Q.ptr(N3*k)[15] = (*this)(_p1p,_n1q, r,k), Q.ptr(N3*k)[16] = (*this)(p,_n1q, r,k), Q.ptr(N3*k)[17] = (*this)(_n1p,_n1q, r,k), Q.ptr(N3*k)[18] = (*this)(_p1p,_p1q,_n1r,k), Q.ptr(N3*k)[19] = (*this)(p,_p1q,_n1r,k), Q.ptr(N3*k)[20] = (*this)(_n1p,_p1q,_n1r,k), Q.ptr(N3*k)[21] = (*this)(_p1p, q,_n1r,k), Q.ptr(N3*k)[22] = (*this)(p, q,_n1r,k), Q.ptr(N3*k)[23] = (*this)(_n1p, q,_n1r,k), Q.ptr(N3*k)[24] = (*this)(_p1p,_n1q,_n1r,k), Q.ptr(N3*k)[25] = (*this)(p,_n1q,_n1r,k), Q.ptr(N3*k)[26] = (*this)(_n1p,_n1q,_n1r,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, dz = r-z, alldist = distance2 + (dx*dx+dy*dy+dz*dz)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)+=weight*(*this)(p,q,r,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k) = (*this)(x,y,z,k); }}; } break; default: { const int psize1 = (int)patch_size/2, psize0 = psize1-1+(patch_size%2); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; P = get_crop(x-psize0,y-psize0,z-psize0,x+psize1,y+psize1,z+psize1,true); const int x0 = x-rsize1, y0 = y-rsize1, z0 = z-rsize1, x1 = x+rsize2, y1 = y+rsize2, z1 = z+rsize2; float sum_weights = 0; for (int r = (int)(z0)<0?0:(int)(z0), _maxr = (int)(z1)<(int)((*this).depth)?(int)(z1):(int)((*this).depth)-1; r<=_maxr; ++r) for (int q = (int)(y0)<0?0:(int)(y0), _maxq = (int)(y1)<(int)((*this).height)?(int)(y1):(int)((*this).height)-1; q<=_maxq; ++q) for (int p = (int)(x0)<0?0:(int)(x0), _maxp = (int)(x1)<(int)((*this).width)?(int)(x1):(int)((*this).width)-1; p<=_maxp; ++p) { (Q = get_crop(p-psize0,q-psize0,r-psize0,p+psize1,q+psize1,r+psize1,true))-=P; const float dx = x-p, dy = y-q, dz = z-r, distance2 = Q.pow(2).sum()/Pnorm + (dx*dx + dy*dy + dz*dz)/sigma_s2, weight = std::exp(-distance2); sum_weights+=weight; for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)+=weight*(*this)(p,q,r,k); } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,z,k) = (*this)(x,y,z,k); } } break; } else switch (patch_size) { case 2: if (fast_approx) { { const unsigned int N2 = 2*2; for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1; _n1x<(int)((*this).width) || x==--_n1x; ++x, ++_n1x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(x, y,0,k), P.ptr(N2*k)[1] = (*this)(_n1x, y,0,k), P.ptr(N2*k)[2] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[3] = (*this)(_n1x,_n1y,0,k); const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1; q<=(int)(y1) && (_n1q<(int)((*this).height) || q==--_n1q); ++q, ++_n1q) for (int p = (int)(x0)<0?0:(int)(x0), _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1; p<=(int)(x1) && (_n1p<(int)((*this).width) || p==--_n1p); ++p, ++_n1p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(p, q,0,k), Q.ptr(N2*k)[1] = (*this)(_n1p, q,0,k), Q.ptr(N2*k)[2] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[3] = (*this)(_n1p,_n1q,0,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } else { { const unsigned int N2 = 2*2; for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1; _n1x<(int)((*this).width) || x==--_n1x; ++x, ++_n1x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(x, y,0,k), P.ptr(N2*k)[1] = (*this)(_n1x, y,0,k), P.ptr(N2*k)[2] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[3] = (*this)(_n1x,_n1y,0,k); const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1; q<=(int)(y1) && (_n1q<(int)((*this).height) || q==--_n1q); ++q, ++_n1q) for (int p = (int)(x0)<0?0:(int)(x0), _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1; p<=(int)(x1) && (_n1p<(int)((*this).width) || p==--_n1p); ++p, ++_n1p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(p, q,0,k), Q.ptr(N2*k)[1] = (*this)(_n1p, q,0,k), Q.ptr(N2*k)[2] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[3] = (*this)(_n1p,_n1q,0,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } break; case 3: if (fast_approx) { { const unsigned int N2 = 3*3; for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1; _n1x<(int)((*this).width) || x==--_n1x; _p1x = x++, ++_n1x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[1] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[2] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[3] = (*this)(_p1x, y,0,k), P.ptr(N2*k)[4] = (*this)(x, y,0,k), P.ptr(N2*k)[5] = (*this)(_n1x, y,0,k), P.ptr(N2*k)[6] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[7] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[8] = (*this)(_n1x,_n1y,0,k); const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1; q<=(int)(y1) && (_n1q<(int)((*this).height) || q==--_n1q); _p1q = q++, ++_n1q) for (int p = (int)(x0)<0?0:(int)(x0), _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1; p<=(int)(x1) && (_n1p<(int)((*this).width) || p==--_n1p); _p1p = p++, ++_n1p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[1] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[2] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[3] = (*this)(_p1p, q,0,k), Q.ptr(N2*k)[4] = (*this)(p, q,0,k), Q.ptr(N2*k)[5] = (*this)(_n1p, q,0,k), Q.ptr(N2*k)[6] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[7] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[8] = (*this)(_n1p,_n1q,0,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } else { { const unsigned int N2 = 3*3; for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1; _n1x<(int)((*this).width) || x==--_n1x; _p1x = x++, ++_n1x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[1] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[2] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[3] = (*this)(_p1x, y,0,k), P.ptr(N2*k)[4] = (*this)(x, y,0,k), P.ptr(N2*k)[5] = (*this)(_n1x, y,0,k), P.ptr(N2*k)[6] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[7] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[8] = (*this)(_n1x,_n1y,0,k); const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1; q<=(int)(y1) && (_n1q<(int)((*this).height) || q==--_n1q); _p1q = q++, ++_n1q) for (int p = (int)(x0)<0?0:(int)(x0), _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1; p<=(int)(x1) && (_n1p<(int)((*this).width) || p==--_n1p); _p1p = p++, ++_n1p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[1] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[2] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[3] = (*this)(_p1p, q,0,k), Q.ptr(N2*k)[4] = (*this)(p, q,0,k), Q.ptr(N2*k)[5] = (*this)(_n1p, q,0,k), Q.ptr(N2*k)[6] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[7] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[8] = (*this)(_n1p,_n1q,0,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } break; case 4: if (fast_approx) { { const unsigned int N2 = 4*4; for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2; _n2x<(int)((*this).width) || _n1x==--_n2x || x==(_n2x = --_n1x); _p1x = x++, ++_n1x, ++_n2x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[1] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[2] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[3] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[4] = (*this)(_p1x, y,0,k), P.ptr(N2*k)[5] = (*this)(x, y,0,k), P.ptr(N2*k)[6] = (*this)(_n1x, y,0,k), P.ptr(N2*k)[7] = (*this)(_n2x, y,0,k), P.ptr(N2*k)[8] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[9] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[10] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[11] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[12] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[13] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[14] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[15] = (*this)(_n2x,_n2y,0,k); const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2; q<=(int)(y1) && (_n2q<(int)((*this).height) || _n1q==--_n2q || q==(_n2q = --_n1q)); _p1q = q++, ++_n1q, ++_n2q) for (int p = (int)(x0)<0?0:(int)(x0), _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2; p<=(int)(x1) && (_n2p<(int)((*this).width) || _n1p==--_n2p || p==(_n2p = --_n1p)); _p1p = p++, ++_n1p, ++_n2p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[1] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[2] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[3] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[4] = (*this)(_p1p, q,0,k), Q.ptr(N2*k)[5] = (*this)(p, q,0,k), Q.ptr(N2*k)[6] = (*this)(_n1p, q,0,k), Q.ptr(N2*k)[7] = (*this)(_n2p, q,0,k), Q.ptr(N2*k)[8] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[9] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[10] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[11] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[12] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[13] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[14] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[15] = (*this)(_n2p,_n2q,0,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } else { { const unsigned int N2 = 4*4; for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2; _n2x<(int)((*this).width) || _n1x==--_n2x || x==(_n2x = --_n1x); _p1x = x++, ++_n1x, ++_n2x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[1] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[2] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[3] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[4] = (*this)(_p1x, y,0,k), P.ptr(N2*k)[5] = (*this)(x, y,0,k), P.ptr(N2*k)[6] = (*this)(_n1x, y,0,k), P.ptr(N2*k)[7] = (*this)(_n2x, y,0,k), P.ptr(N2*k)[8] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[9] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[10] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[11] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[12] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[13] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[14] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[15] = (*this)(_n2x,_n2y,0,k); const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2; q<=(int)(y1) && (_n2q<(int)((*this).height) || _n1q==--_n2q || q==(_n2q = --_n1q)); _p1q = q++, ++_n1q, ++_n2q) for (int p = (int)(x0)<0?0:(int)(x0), _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2; p<=(int)(x1) && (_n2p<(int)((*this).width) || _n1p==--_n2p || p==(_n2p = --_n1p)); _p1p = p++, ++_n1p, ++_n2p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[1] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[2] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[3] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[4] = (*this)(_p1p, q,0,k), Q.ptr(N2*k)[5] = (*this)(p, q,0,k), Q.ptr(N2*k)[6] = (*this)(_n1p, q,0,k), Q.ptr(N2*k)[7] = (*this)(_n2p, q,0,k), Q.ptr(N2*k)[8] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[9] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[10] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[11] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[12] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[13] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[14] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[15] = (*this)(_n2p,_n2q,0,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } break; case 5: if (fast_approx) { { const unsigned int N2 = 5*5; for (int y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2; _n2x<(int)((*this).width) || _n1x==--_n2x || x==(_n2x = --_n1x); _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[1] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[2] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[3] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[4] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[5] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[6] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[7] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[8] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[9] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[10] = (*this)(_p2x, y,0,k), P.ptr(N2*k)[11] = (*this)(_p1x, y,0,k), P.ptr(N2*k)[12] = (*this)(x, y,0,k), P.ptr(N2*k)[13] = (*this)(_n1x, y,0,k), P.ptr(N2*k)[14] = (*this)(_n2x, y,0,k), P.ptr(N2*k)[15] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[16] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[17] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[18] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[19] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[20] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[21] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[22] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[23] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[24] = (*this)(_n2x,_n2y,0,k); const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2; q<=(int)(y1) && (_n2q<(int)((*this).height) || _n1q==--_n2q || q==(_n2q = --_n1q)); _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q) for (int p = (int)(x0)<0?0:(int)(x0), _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2; p<=(int)(x1) && (_n2p<(int)((*this).width) || _n1p==--_n2p || p==(_n2p = --_n1p)); _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[1] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[2] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[3] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[4] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[5] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[6] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[7] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[8] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[9] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[10] = (*this)(_p2p, q,0,k), Q.ptr(N2*k)[11] = (*this)(_p1p, q,0,k), Q.ptr(N2*k)[12] = (*this)(p, q,0,k), Q.ptr(N2*k)[13] = (*this)(_n1p, q,0,k), Q.ptr(N2*k)[14] = (*this)(_n2p, q,0,k), Q.ptr(N2*k)[15] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[16] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[17] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[18] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[19] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[20] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[21] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[22] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[23] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[24] = (*this)(_n2p,_n2q,0,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } else { { const unsigned int N2 = 5*5; for (int y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2; _n2x<(int)((*this).width) || _n1x==--_n2x || x==(_n2x = --_n1x); _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[1] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[2] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[3] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[4] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[5] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[6] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[7] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[8] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[9] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[10] = (*this)(_p2x, y,0,k), P.ptr(N2*k)[11] = (*this)(_p1x, y,0,k), P.ptr(N2*k)[12] = (*this)(x, y,0,k), P.ptr(N2*k)[13] = (*this)(_n1x, y,0,k), P.ptr(N2*k)[14] = (*this)(_n2x, y,0,k), P.ptr(N2*k)[15] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[16] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[17] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[18] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[19] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[20] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[21] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[22] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[23] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[24] = (*this)(_n2x,_n2y,0,k); const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2; q<=(int)(y1) && (_n2q<(int)((*this).height) || _n1q==--_n2q || q==(_n2q = --_n1q)); _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q) for (int p = (int)(x0)<0?0:(int)(x0), _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2; p<=(int)(x1) && (_n2p<(int)((*this).width) || _n1p==--_n2p || p==(_n2p = --_n1p)); _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[1] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[2] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[3] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[4] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[5] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[6] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[7] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[8] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[9] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[10] = (*this)(_p2p, q,0,k), Q.ptr(N2*k)[11] = (*this)(_p1p, q,0,k), Q.ptr(N2*k)[12] = (*this)(p, q,0,k), Q.ptr(N2*k)[13] = (*this)(_n1p, q,0,k), Q.ptr(N2*k)[14] = (*this)(_n2p, q,0,k), Q.ptr(N2*k)[15] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[16] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[17] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[18] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[19] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[20] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[21] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[22] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[23] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[24] = (*this)(_n2p,_n2q,0,k); float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } break; case 6: if (fast_approx) { { const unsigned int N2 = 6*6; for (int y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2, _n3y = 3>=((*this).height)?(int)((*this).height)-1:3; _n3y<(int)((*this).height) || _n2y==--_n3y || _n1y==--_n2y || y==(_n3y = _n2y = --_n1y); _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y, ++_n3y) for (int x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2, _n3x = 3>=((*this).width)?(int)((*this).width)-1:3; _n3x<(int)((*this).width) || _n2x==--_n3x || _n1x==--_n2x || x==(_n3x = _n2x = --_n1x); _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x, ++_n3x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[1] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[2] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[3] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[4] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[5] = (*this)(_n3x,_p2y,0,k), P.ptr(N2*k)[6] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[7] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[8] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[9] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[10] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[11] = (*this)(_n3x,_p1y,0,k), P.ptr(N2*k)[12] = (*this)(_p2x,y,0,k), P.ptr(N2*k)[13] = (*this)(_p1x,y,0,k), P.ptr(N2*k)[14] = (*this)(x,y,0,k), P.ptr(N2*k)[15] = (*this)(_n1x,y,0,k), P.ptr(N2*k)[16] = (*this)(_n2x,y,0,k), P.ptr(N2*k)[17] = (*this)(_n3x,y,0,k), P.ptr(N2*k)[18] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[19] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[20] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[21] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[22] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[23] = (*this)(_n3x,_n1y,0,k), P.ptr(N2*k)[24] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[25] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[26] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[27] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[28] = (*this)(_n2x,_n2y,0,k), P.ptr(N2*k)[29] = (*this)(_n3x,_n2y,0,k), P.ptr(N2*k)[30] = (*this)(_p2x,_n3y,0,k), P.ptr(N2*k)[31] = (*this)(_p1x,_n3y,0,k), P.ptr(N2*k)[32] = (*this)(x,_n3y,0,k), P.ptr(N2*k)[33] = (*this)(_n1x,_n3y,0,k), P.ptr(N2*k)[34] = (*this)(_n2x,_n3y,0,k), P.ptr(N2*k)[35] = (*this)(_n3x,_n3y,0,k);; const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2, _n3q = q+3>=(int)((*this).height)?(int)((*this).height)-1:q+3; q<=(int)(y1) && (_n3q<(int)((*this).height) || _n2q==--_n3q || _n1q==--_n2q || q==(_n3q = _n2q = --_n1q)); _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q, ++_n3q) for (int p = (int)(x0)<0?0:(int)(x0), _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2, _n3p = p+3>=(int)((*this).width)?(int)((*this).width)-1:p+3; p<=(int)(x1) && (_n3p<(int)((*this).width) || _n2p==--_n3p || _n1p==--_n2p || p==(_n3p = _n2p = --_n1p)); _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p, ++_n3p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[1] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[2] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[3] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[4] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[5] = (*this)(_n3p,_p2q,0,k), Q.ptr(N2*k)[6] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[7] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[8] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[9] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[10] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[11] = (*this)(_n3p,_p1q,0,k), Q.ptr(N2*k)[12] = (*this)(_p2p,q,0,k), Q.ptr(N2*k)[13] = (*this)(_p1p,q,0,k), Q.ptr(N2*k)[14] = (*this)(p,q,0,k), Q.ptr(N2*k)[15] = (*this)(_n1p,q,0,k), Q.ptr(N2*k)[16] = (*this)(_n2p,q,0,k), Q.ptr(N2*k)[17] = (*this)(_n3p,q,0,k), Q.ptr(N2*k)[18] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[19] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[20] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[21] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[22] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[23] = (*this)(_n3p,_n1q,0,k), Q.ptr(N2*k)[24] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[25] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[26] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[27] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[28] = (*this)(_n2p,_n2q,0,k), Q.ptr(N2*k)[29] = (*this)(_n3p,_n2q,0,k), Q.ptr(N2*k)[30] = (*this)(_p2p,_n3q,0,k), Q.ptr(N2*k)[31] = (*this)(_p1p,_n3q,0,k), Q.ptr(N2*k)[32] = (*this)(p,_n3q,0,k), Q.ptr(N2*k)[33] = (*this)(_n1p,_n3q,0,k), Q.ptr(N2*k)[34] = (*this)(_n2p,_n3q,0,k), Q.ptr(N2*k)[35] = (*this)(_n3p,_n3q,0,k);; float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } else { { const unsigned int N2 = 6*6; for (int y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2, _n3y = 3>=((*this).height)?(int)((*this).height)-1:3; _n3y<(int)((*this).height) || _n2y==--_n3y || _n1y==--_n2y || y==(_n3y = _n2y = --_n1y); _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y, ++_n3y) for (int x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2, _n3x = 3>=((*this).width)?(int)((*this).width)-1:3; _n3x<(int)((*this).width) || _n2x==--_n3x || _n1x==--_n2x || x==(_n3x = _n2x = --_n1x); _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x, ++_n3x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[1] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[2] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[3] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[4] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[5] = (*this)(_n3x,_p2y,0,k), P.ptr(N2*k)[6] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[7] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[8] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[9] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[10] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[11] = (*this)(_n3x,_p1y,0,k), P.ptr(N2*k)[12] = (*this)(_p2x,y,0,k), P.ptr(N2*k)[13] = (*this)(_p1x,y,0,k), P.ptr(N2*k)[14] = (*this)(x,y,0,k), P.ptr(N2*k)[15] = (*this)(_n1x,y,0,k), P.ptr(N2*k)[16] = (*this)(_n2x,y,0,k), P.ptr(N2*k)[17] = (*this)(_n3x,y,0,k), P.ptr(N2*k)[18] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[19] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[20] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[21] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[22] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[23] = (*this)(_n3x,_n1y,0,k), P.ptr(N2*k)[24] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[25] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[26] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[27] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[28] = (*this)(_n2x,_n2y,0,k), P.ptr(N2*k)[29] = (*this)(_n3x,_n2y,0,k), P.ptr(N2*k)[30] = (*this)(_p2x,_n3y,0,k), P.ptr(N2*k)[31] = (*this)(_p1x,_n3y,0,k), P.ptr(N2*k)[32] = (*this)(x,_n3y,0,k), P.ptr(N2*k)[33] = (*this)(_n1x,_n3y,0,k), P.ptr(N2*k)[34] = (*this)(_n2x,_n3y,0,k), P.ptr(N2*k)[35] = (*this)(_n3x,_n3y,0,k);; const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2, _n3q = q+3>=(int)((*this).height)?(int)((*this).height)-1:q+3; q<=(int)(y1) && (_n3q<(int)((*this).height) || _n2q==--_n3q || _n1q==--_n2q || q==(_n3q = _n2q = --_n1q)); _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q, ++_n3q) for (int p = (int)(x0)<0?0:(int)(x0), _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2, _n3p = p+3>=(int)((*this).width)?(int)((*this).width)-1:p+3; p<=(int)(x1) && (_n3p<(int)((*this).width) || _n2p==--_n3p || _n1p==--_n2p || p==(_n3p = _n2p = --_n1p)); _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p, ++_n3p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[1] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[2] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[3] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[4] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[5] = (*this)(_n3p,_p2q,0,k), Q.ptr(N2*k)[6] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[7] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[8] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[9] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[10] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[11] = (*this)(_n3p,_p1q,0,k), Q.ptr(N2*k)[12] = (*this)(_p2p,q,0,k), Q.ptr(N2*k)[13] = (*this)(_p1p,q,0,k), Q.ptr(N2*k)[14] = (*this)(p,q,0,k), Q.ptr(N2*k)[15] = (*this)(_n1p,q,0,k), Q.ptr(N2*k)[16] = (*this)(_n2p,q,0,k), Q.ptr(N2*k)[17] = (*this)(_n3p,q,0,k), Q.ptr(N2*k)[18] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[19] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[20] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[21] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[22] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[23] = (*this)(_n3p,_n1q,0,k), Q.ptr(N2*k)[24] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[25] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[26] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[27] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[28] = (*this)(_n2p,_n2q,0,k), Q.ptr(N2*k)[29] = (*this)(_n3p,_n2q,0,k), Q.ptr(N2*k)[30] = (*this)(_p2p,_n3q,0,k), Q.ptr(N2*k)[31] = (*this)(_p1p,_n3q,0,k), Q.ptr(N2*k)[32] = (*this)(p,_n3q,0,k), Q.ptr(N2*k)[33] = (*this)(_n1p,_n3q,0,k), Q.ptr(N2*k)[34] = (*this)(_n2p,_n3q,0,k), Q.ptr(N2*k)[35] = (*this)(_n3p,_n3q,0,k);; float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } break; case 7: if (fast_approx) { { const unsigned int N2 = 7*7; for (int y = 0, _p3y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2, _n3y = 3>=((*this).height)?(int)((*this).height)-1:3; _n3y<(int)((*this).height) || _n2y==--_n3y || _n1y==--_n2y || y==(_n3y = _n2y = --_n1y); _p3y = _p2y, _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y, ++_n3y) for (int x = 0, _p3x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2, _n3x = 3>=((*this).width)?(int)((*this).width)-1:3; _n3x<(int)((*this).width) || _n2x==--_n3x || _n1x==--_n2x || x==(_n3x = _n2x = --_n1x); _p3x = _p2x, _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x, ++_n3x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p3x,_p3y,0,k), P.ptr(N2*k)[1] = (*this)(_p2x,_p3y,0,k), P.ptr(N2*k)[2] = (*this)(_p1x,_p3y,0,k), P.ptr(N2*k)[3] = (*this)(x,_p3y,0,k), P.ptr(N2*k)[4] = (*this)(_n1x,_p3y,0,k), P.ptr(N2*k)[5] = (*this)(_n2x,_p3y,0,k), P.ptr(N2*k)[6] = (*this)(_n3x,_p3y,0,k), P.ptr(N2*k)[7] = (*this)(_p3x,_p2y,0,k), P.ptr(N2*k)[8] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[9] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[10] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[11] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[12] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[13] = (*this)(_n3x,_p2y,0,k), P.ptr(N2*k)[14] = (*this)(_p3x,_p1y,0,k), P.ptr(N2*k)[15] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[16] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[17] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[18] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[19] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[20] = (*this)(_n3x,_p1y,0,k), P.ptr(N2*k)[21] = (*this)(_p3x,y,0,k), P.ptr(N2*k)[22] = (*this)(_p2x,y,0,k), P.ptr(N2*k)[23] = (*this)(_p1x,y,0,k), P.ptr(N2*k)[24] = (*this)(x,y,0,k), P.ptr(N2*k)[25] = (*this)(_n1x,y,0,k), P.ptr(N2*k)[26] = (*this)(_n2x,y,0,k), P.ptr(N2*k)[27] = (*this)(_n3x,y,0,k), P.ptr(N2*k)[28] = (*this)(_p3x,_n1y,0,k), P.ptr(N2*k)[29] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[30] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[31] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[32] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[33] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[34] = (*this)(_n3x,_n1y,0,k), P.ptr(N2*k)[35] = (*this)(_p3x,_n2y,0,k), P.ptr(N2*k)[36] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[37] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[38] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[39] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[40] = (*this)(_n2x,_n2y,0,k), P.ptr(N2*k)[41] = (*this)(_n3x,_n2y,0,k), P.ptr(N2*k)[42] = (*this)(_p3x,_n3y,0,k), P.ptr(N2*k)[43] = (*this)(_p2x,_n3y,0,k), P.ptr(N2*k)[44] = (*this)(_p1x,_n3y,0,k), P.ptr(N2*k)[45] = (*this)(x,_n3y,0,k), P.ptr(N2*k)[46] = (*this)(_n1x,_n3y,0,k), P.ptr(N2*k)[47] = (*this)(_n2x,_n3y,0,k), P.ptr(N2*k)[48] = (*this)(_n3x,_n3y,0,k);; const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p3q = q-3<0?0:q-3, _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2, _n3q = q+3>=(int)((*this).height)?(int)((*this).height)-1:q+3; q<=(int)(y1) && (_n3q<(int)((*this).height) || _n2q==--_n3q || _n1q==--_n2q || q==(_n3q = _n2q = --_n1q)); _p3q = _p2q, _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q, ++_n3q) for (int p = (int)(x0)<0?0:(int)(x0), _p3p = p-3<0?0:p-3, _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2, _n3p = p+3>=(int)((*this).width)?(int)((*this).width)-1:p+3; p<=(int)(x1) && (_n3p<(int)((*this).width) || _n2p==--_n3p || _n1p==--_n2p || p==(_n3p = _n2p = --_n1p)); _p3p = _p2p, _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p, ++_n3p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p3p,_p3q,0,k), Q.ptr(N2*k)[1] = (*this)(_p2p,_p3q,0,k), Q.ptr(N2*k)[2] = (*this)(_p1p,_p3q,0,k), Q.ptr(N2*k)[3] = (*this)(p,_p3q,0,k), Q.ptr(N2*k)[4] = (*this)(_n1p,_p3q,0,k), Q.ptr(N2*k)[5] = (*this)(_n2p,_p3q,0,k), Q.ptr(N2*k)[6] = (*this)(_n3p,_p3q,0,k), Q.ptr(N2*k)[7] = (*this)(_p3p,_p2q,0,k), Q.ptr(N2*k)[8] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[9] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[10] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[11] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[12] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[13] = (*this)(_n3p,_p2q,0,k), Q.ptr(N2*k)[14] = (*this)(_p3p,_p1q,0,k), Q.ptr(N2*k)[15] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[16] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[17] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[18] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[19] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[20] = (*this)(_n3p,_p1q,0,k), Q.ptr(N2*k)[21] = (*this)(_p3p,q,0,k), Q.ptr(N2*k)[22] = (*this)(_p2p,q,0,k), Q.ptr(N2*k)[23] = (*this)(_p1p,q,0,k), Q.ptr(N2*k)[24] = (*this)(p,q,0,k), Q.ptr(N2*k)[25] = (*this)(_n1p,q,0,k), Q.ptr(N2*k)[26] = (*this)(_n2p,q,0,k), Q.ptr(N2*k)[27] = (*this)(_n3p,q,0,k), Q.ptr(N2*k)[28] = (*this)(_p3p,_n1q,0,k), Q.ptr(N2*k)[29] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[30] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[31] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[32] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[33] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[34] = (*this)(_n3p,_n1q,0,k), Q.ptr(N2*k)[35] = (*this)(_p3p,_n2q,0,k), Q.ptr(N2*k)[36] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[37] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[38] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[39] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[40] = (*this)(_n2p,_n2q,0,k), Q.ptr(N2*k)[41] = (*this)(_n3p,_n2q,0,k), Q.ptr(N2*k)[42] = (*this)(_p3p,_n3q,0,k), Q.ptr(N2*k)[43] = (*this)(_p2p,_n3q,0,k), Q.ptr(N2*k)[44] = (*this)(_p1p,_n3q,0,k), Q.ptr(N2*k)[45] = (*this)(p,_n3q,0,k), Q.ptr(N2*k)[46] = (*this)(_n1p,_n3q,0,k), Q.ptr(N2*k)[47] = (*this)(_n2p,_n3q,0,k), Q.ptr(N2*k)[48] = (*this)(_n3p,_n3q,0,k);; float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } else { { const unsigned int N2 = 7*7; for (int y = 0, _p3y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2, _n3y = 3>=((*this).height)?(int)((*this).height)-1:3; _n3y<(int)((*this).height) || _n2y==--_n3y || _n1y==--_n2y || y==(_n3y = _n2y = --_n1y); _p3y = _p2y, _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y, ++_n3y) for (int x = 0, _p3x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2, _n3x = 3>=((*this).width)?(int)((*this).width)-1:3; _n3x<(int)((*this).width) || _n2x==--_n3x || _n1x==--_n2x || x==(_n3x = _n2x = --_n1x); _p3x = _p2x, _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x, ++_n3x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p3x,_p3y,0,k), P.ptr(N2*k)[1] = (*this)(_p2x,_p3y,0,k), P.ptr(N2*k)[2] = (*this)(_p1x,_p3y,0,k), P.ptr(N2*k)[3] = (*this)(x,_p3y,0,k), P.ptr(N2*k)[4] = (*this)(_n1x,_p3y,0,k), P.ptr(N2*k)[5] = (*this)(_n2x,_p3y,0,k), P.ptr(N2*k)[6] = (*this)(_n3x,_p3y,0,k), P.ptr(N2*k)[7] = (*this)(_p3x,_p2y,0,k), P.ptr(N2*k)[8] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[9] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[10] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[11] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[12] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[13] = (*this)(_n3x,_p2y,0,k), P.ptr(N2*k)[14] = (*this)(_p3x,_p1y,0,k), P.ptr(N2*k)[15] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[16] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[17] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[18] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[19] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[20] = (*this)(_n3x,_p1y,0,k), P.ptr(N2*k)[21] = (*this)(_p3x,y,0,k), P.ptr(N2*k)[22] = (*this)(_p2x,y,0,k), P.ptr(N2*k)[23] = (*this)(_p1x,y,0,k), P.ptr(N2*k)[24] = (*this)(x,y,0,k), P.ptr(N2*k)[25] = (*this)(_n1x,y,0,k), P.ptr(N2*k)[26] = (*this)(_n2x,y,0,k), P.ptr(N2*k)[27] = (*this)(_n3x,y,0,k), P.ptr(N2*k)[28] = (*this)(_p3x,_n1y,0,k), P.ptr(N2*k)[29] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[30] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[31] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[32] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[33] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[34] = (*this)(_n3x,_n1y,0,k), P.ptr(N2*k)[35] = (*this)(_p3x,_n2y,0,k), P.ptr(N2*k)[36] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[37] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[38] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[39] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[40] = (*this)(_n2x,_n2y,0,k), P.ptr(N2*k)[41] = (*this)(_n3x,_n2y,0,k), P.ptr(N2*k)[42] = (*this)(_p3x,_n3y,0,k), P.ptr(N2*k)[43] = (*this)(_p2x,_n3y,0,k), P.ptr(N2*k)[44] = (*this)(_p1x,_n3y,0,k), P.ptr(N2*k)[45] = (*this)(x,_n3y,0,k), P.ptr(N2*k)[46] = (*this)(_n1x,_n3y,0,k), P.ptr(N2*k)[47] = (*this)(_n2x,_n3y,0,k), P.ptr(N2*k)[48] = (*this)(_n3x,_n3y,0,k);; const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p3q = q-3<0?0:q-3, _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2, _n3q = q+3>=(int)((*this).height)?(int)((*this).height)-1:q+3; q<=(int)(y1) && (_n3q<(int)((*this).height) || _n2q==--_n3q || _n1q==--_n2q || q==(_n3q = _n2q = --_n1q)); _p3q = _p2q, _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q, ++_n3q) for (int p = (int)(x0)<0?0:(int)(x0), _p3p = p-3<0?0:p-3, _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2, _n3p = p+3>=(int)((*this).width)?(int)((*this).width)-1:p+3; p<=(int)(x1) && (_n3p<(int)((*this).width) || _n2p==--_n3p || _n1p==--_n2p || p==(_n3p = _n2p = --_n1p)); _p3p = _p2p, _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p, ++_n3p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p3p,_p3q,0,k), Q.ptr(N2*k)[1] = (*this)(_p2p,_p3q,0,k), Q.ptr(N2*k)[2] = (*this)(_p1p,_p3q,0,k), Q.ptr(N2*k)[3] = (*this)(p,_p3q,0,k), Q.ptr(N2*k)[4] = (*this)(_n1p,_p3q,0,k), Q.ptr(N2*k)[5] = (*this)(_n2p,_p3q,0,k), Q.ptr(N2*k)[6] = (*this)(_n3p,_p3q,0,k), Q.ptr(N2*k)[7] = (*this)(_p3p,_p2q,0,k), Q.ptr(N2*k)[8] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[9] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[10] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[11] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[12] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[13] = (*this)(_n3p,_p2q,0,k), Q.ptr(N2*k)[14] = (*this)(_p3p,_p1q,0,k), Q.ptr(N2*k)[15] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[16] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[17] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[18] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[19] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[20] = (*this)(_n3p,_p1q,0,k), Q.ptr(N2*k)[21] = (*this)(_p3p,q,0,k), Q.ptr(N2*k)[22] = (*this)(_p2p,q,0,k), Q.ptr(N2*k)[23] = (*this)(_p1p,q,0,k), Q.ptr(N2*k)[24] = (*this)(p,q,0,k), Q.ptr(N2*k)[25] = (*this)(_n1p,q,0,k), Q.ptr(N2*k)[26] = (*this)(_n2p,q,0,k), Q.ptr(N2*k)[27] = (*this)(_n3p,q,0,k), Q.ptr(N2*k)[28] = (*this)(_p3p,_n1q,0,k), Q.ptr(N2*k)[29] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[30] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[31] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[32] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[33] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[34] = (*this)(_n3p,_n1q,0,k), Q.ptr(N2*k)[35] = (*this)(_p3p,_n2q,0,k), Q.ptr(N2*k)[36] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[37] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[38] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[39] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[40] = (*this)(_n2p,_n2q,0,k), Q.ptr(N2*k)[41] = (*this)(_n3p,_n2q,0,k), Q.ptr(N2*k)[42] = (*this)(_p3p,_n3q,0,k), Q.ptr(N2*k)[43] = (*this)(_p2p,_n3q,0,k), Q.ptr(N2*k)[44] = (*this)(_p1p,_n3q,0,k), Q.ptr(N2*k)[45] = (*this)(p,_n3q,0,k), Q.ptr(N2*k)[46] = (*this)(_n1p,_n3q,0,k), Q.ptr(N2*k)[47] = (*this)(_n2p,_n3q,0,k), Q.ptr(N2*k)[48] = (*this)(_n3p,_n3q,0,k);; float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } break; case 8: if (fast_approx) { { const unsigned int N2 = 8*8; for (int y = 0, _p3y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2, _n3y = 3>=((*this).height)?(int)((*this).height)-1:3, _n4y = 4>=((*this).height)?(int)((*this).height)-1:4; _n4y<(int)((*this).height) || _n3y==--_n4y || _n2y==--_n3y || _n1y==--_n2y || y==(_n4y = _n3y = _n2y = --_n1y); _p3y = _p2y, _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y, ++_n3y, ++_n4y) for (int x = 0, _p3x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2, _n3x = 3>=((*this).width)?(int)((*this).width)-1:3, _n4x = 4>=((*this).width)?(int)((*this).width)-1:4; _n4x<(int)((*this).width) || _n3x==--_n4x || _n2x==--_n3x || _n1x==--_n2x || x==(_n4x = _n3x = _n2x = --_n1x); _p3x = _p2x, _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x, ++_n3x, ++_n4x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p3x,_p3y,0,k), P.ptr(N2*k)[1] = (*this)(_p2x,_p3y,0,k), P.ptr(N2*k)[2] = (*this)(_p1x,_p3y,0,k), P.ptr(N2*k)[3] = (*this)(x,_p3y,0,k), P.ptr(N2*k)[4] = (*this)(_n1x,_p3y,0,k), P.ptr(N2*k)[5] = (*this)(_n2x,_p3y,0,k), P.ptr(N2*k)[6] = (*this)(_n3x,_p3y,0,k), P.ptr(N2*k)[7] = (*this)(_n4x,_p3y,0,k), P.ptr(N2*k)[8] = (*this)(_p3x,_p2y,0,k), P.ptr(N2*k)[9] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[10] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[11] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[12] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[13] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[14] = (*this)(_n3x,_p2y,0,k), P.ptr(N2*k)[15] = (*this)(_n4x,_p2y,0,k), P.ptr(N2*k)[16] = (*this)(_p3x,_p1y,0,k), P.ptr(N2*k)[17] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[18] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[19] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[20] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[21] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[22] = (*this)(_n3x,_p1y,0,k), P.ptr(N2*k)[23] = (*this)(_n4x,_p1y,0,k), P.ptr(N2*k)[24] = (*this)(_p3x,y,0,k), P.ptr(N2*k)[25] = (*this)(_p2x,y,0,k), P.ptr(N2*k)[26] = (*this)(_p1x,y,0,k), P.ptr(N2*k)[27] = (*this)(x,y,0,k), P.ptr(N2*k)[28] = (*this)(_n1x,y,0,k), P.ptr(N2*k)[29] = (*this)(_n2x,y,0,k), P.ptr(N2*k)[30] = (*this)(_n3x,y,0,k), P.ptr(N2*k)[31] = (*this)(_n4x,y,0,k), P.ptr(N2*k)[32] = (*this)(_p3x,_n1y,0,k), P.ptr(N2*k)[33] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[34] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[35] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[36] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[37] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[38] = (*this)(_n3x,_n1y,0,k), P.ptr(N2*k)[39] = (*this)(_n4x,_n1y,0,k), P.ptr(N2*k)[40] = (*this)(_p3x,_n2y,0,k), P.ptr(N2*k)[41] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[42] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[43] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[44] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[45] = (*this)(_n2x,_n2y,0,k), P.ptr(N2*k)[46] = (*this)(_n3x,_n2y,0,k), P.ptr(N2*k)[47] = (*this)(_n4x,_n2y,0,k), P.ptr(N2*k)[48] = (*this)(_p3x,_n3y,0,k), P.ptr(N2*k)[49] = (*this)(_p2x,_n3y,0,k), P.ptr(N2*k)[50] = (*this)(_p1x,_n3y,0,k), P.ptr(N2*k)[51] = (*this)(x,_n3y,0,k), P.ptr(N2*k)[52] = (*this)(_n1x,_n3y,0,k), P.ptr(N2*k)[53] = (*this)(_n2x,_n3y,0,k), P.ptr(N2*k)[54] = (*this)(_n3x,_n3y,0,k), P.ptr(N2*k)[55] = (*this)(_n4x,_n3y,0,k), P.ptr(N2*k)[56] = (*this)(_p3x,_n4y,0,k), P.ptr(N2*k)[57] = (*this)(_p2x,_n4y,0,k), P.ptr(N2*k)[58] = (*this)(_p1x,_n4y,0,k), P.ptr(N2*k)[59] = (*this)(x,_n4y,0,k), P.ptr(N2*k)[60] = (*this)(_n1x,_n4y,0,k), P.ptr(N2*k)[61] = (*this)(_n2x,_n4y,0,k), P.ptr(N2*k)[62] = (*this)(_n3x,_n4y,0,k), P.ptr(N2*k)[63] = (*this)(_n4x,_n4y,0,k);; const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p3q = q-3<0?0:q-3, _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2, _n3q = q+3>=(int)((*this).height)?(int)((*this).height)-1:q+3, _n4q = q+4>=(int)((*this).height)?(int)((*this).height)-1:q+4; q<=(int)(y1) && (_n4q<(int)((*this).height) || _n3q==--_n4q || _n2q==--_n3q || _n1q==--_n2q || q==(_n4q = _n3q = _n2q = --_n1q)); _p3q = _p2q, _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q, ++_n3q, ++_n4q) for (int p = (int)(x0)<0?0:(int)(x0), _p3p = p-3<0?0:p-3, _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2, _n3p = p+3>=(int)((*this).width)?(int)((*this).width)-1:p+3, _n4p = p+4>=(int)((*this).width)?(int)((*this).width)-1:p+4; p<=(int)(x1) && (_n4p<(int)((*this).width) || _n3p==--_n4p || _n2p==--_n3p || _n1p==--_n2p || p==(_n4p = _n3p = _n2p = --_n1p)); _p3p = _p2p, _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p, ++_n3p, ++_n4p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p3p,_p3q,0,k), Q.ptr(N2*k)[1] = (*this)(_p2p,_p3q,0,k), Q.ptr(N2*k)[2] = (*this)(_p1p,_p3q,0,k), Q.ptr(N2*k)[3] = (*this)(p,_p3q,0,k), Q.ptr(N2*k)[4] = (*this)(_n1p,_p3q,0,k), Q.ptr(N2*k)[5] = (*this)(_n2p,_p3q,0,k), Q.ptr(N2*k)[6] = (*this)(_n3p,_p3q,0,k), Q.ptr(N2*k)[7] = (*this)(_n4p,_p3q,0,k), Q.ptr(N2*k)[8] = (*this)(_p3p,_p2q,0,k), Q.ptr(N2*k)[9] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[10] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[11] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[12] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[13] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[14] = (*this)(_n3p,_p2q,0,k), Q.ptr(N2*k)[15] = (*this)(_n4p,_p2q,0,k), Q.ptr(N2*k)[16] = (*this)(_p3p,_p1q,0,k), Q.ptr(N2*k)[17] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[18] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[19] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[20] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[21] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[22] = (*this)(_n3p,_p1q,0,k), Q.ptr(N2*k)[23] = (*this)(_n4p,_p1q,0,k), Q.ptr(N2*k)[24] = (*this)(_p3p,q,0,k), Q.ptr(N2*k)[25] = (*this)(_p2p,q,0,k), Q.ptr(N2*k)[26] = (*this)(_p1p,q,0,k), Q.ptr(N2*k)[27] = (*this)(p,q,0,k), Q.ptr(N2*k)[28] = (*this)(_n1p,q,0,k), Q.ptr(N2*k)[29] = (*this)(_n2p,q,0,k), Q.ptr(N2*k)[30] = (*this)(_n3p,q,0,k), Q.ptr(N2*k)[31] = (*this)(_n4p,q,0,k), Q.ptr(N2*k)[32] = (*this)(_p3p,_n1q,0,k), Q.ptr(N2*k)[33] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[34] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[35] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[36] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[37] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[38] = (*this)(_n3p,_n1q,0,k), Q.ptr(N2*k)[39] = (*this)(_n4p,_n1q,0,k), Q.ptr(N2*k)[40] = (*this)(_p3p,_n2q,0,k), Q.ptr(N2*k)[41] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[42] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[43] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[44] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[45] = (*this)(_n2p,_n2q,0,k), Q.ptr(N2*k)[46] = (*this)(_n3p,_n2q,0,k), Q.ptr(N2*k)[47] = (*this)(_n4p,_n2q,0,k), Q.ptr(N2*k)[48] = (*this)(_p3p,_n3q,0,k), Q.ptr(N2*k)[49] = (*this)(_p2p,_n3q,0,k), Q.ptr(N2*k)[50] = (*this)(_p1p,_n3q,0,k), Q.ptr(N2*k)[51] = (*this)(p,_n3q,0,k), Q.ptr(N2*k)[52] = (*this)(_n1p,_n3q,0,k), Q.ptr(N2*k)[53] = (*this)(_n2p,_n3q,0,k), Q.ptr(N2*k)[54] = (*this)(_n3p,_n3q,0,k), Q.ptr(N2*k)[55] = (*this)(_n4p,_n3q,0,k), Q.ptr(N2*k)[56] = (*this)(_p3p,_n4q,0,k), Q.ptr(N2*k)[57] = (*this)(_p2p,_n4q,0,k), Q.ptr(N2*k)[58] = (*this)(_p1p,_n4q,0,k), Q.ptr(N2*k)[59] = (*this)(p,_n4q,0,k), Q.ptr(N2*k)[60] = (*this)(_n1p,_n4q,0,k), Q.ptr(N2*k)[61] = (*this)(_n2p,_n4q,0,k), Q.ptr(N2*k)[62] = (*this)(_n3p,_n4q,0,k), Q.ptr(N2*k)[63] = (*this)(_n4p,_n4q,0,k);; float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } else { { const unsigned int N2 = 8*8; for (int y = 0, _p3y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2, _n3y = 3>=((*this).height)?(int)((*this).height)-1:3, _n4y = 4>=((*this).height)?(int)((*this).height)-1:4; _n4y<(int)((*this).height) || _n3y==--_n4y || _n2y==--_n3y || _n1y==--_n2y || y==(_n4y = _n3y = _n2y = --_n1y); _p3y = _p2y, _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y, ++_n3y, ++_n4y) for (int x = 0, _p3x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=((*this).width)?(int)((*this).width)-1:2, _n3x = 3>=((*this).width)?(int)((*this).width)-1:3, _n4x = 4>=((*this).width)?(int)((*this).width)-1:4; _n4x<(int)((*this).width) || _n3x==--_n4x || _n2x==--_n3x || _n1x==--_n2x || x==(_n4x = _n3x = _n2x = --_n1x); _p3x = _p2x, _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x, ++_n3x, ++_n4x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p3x,_p3y,0,k), P.ptr(N2*k)[1] = (*this)(_p2x,_p3y,0,k), P.ptr(N2*k)[2] = (*this)(_p1x,_p3y,0,k), P.ptr(N2*k)[3] = (*this)(x,_p3y,0,k), P.ptr(N2*k)[4] = (*this)(_n1x,_p3y,0,k), P.ptr(N2*k)[5] = (*this)(_n2x,_p3y,0,k), P.ptr(N2*k)[6] = (*this)(_n3x,_p3y,0,k), P.ptr(N2*k)[7] = (*this)(_n4x,_p3y,0,k), P.ptr(N2*k)[8] = (*this)(_p3x,_p2y,0,k), P.ptr(N2*k)[9] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[10] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[11] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[12] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[13] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[14] = (*this)(_n3x,_p2y,0,k), P.ptr(N2*k)[15] = (*this)(_n4x,_p2y,0,k), P.ptr(N2*k)[16] = (*this)(_p3x,_p1y,0,k), P.ptr(N2*k)[17] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[18] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[19] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[20] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[21] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[22] = (*this)(_n3x,_p1y,0,k), P.ptr(N2*k)[23] = (*this)(_n4x,_p1y,0,k), P.ptr(N2*k)[24] = (*this)(_p3x,y,0,k), P.ptr(N2*k)[25] = (*this)(_p2x,y,0,k), P.ptr(N2*k)[26] = (*this)(_p1x,y,0,k), P.ptr(N2*k)[27] = (*this)(x,y,0,k), P.ptr(N2*k)[28] = (*this)(_n1x,y,0,k), P.ptr(N2*k)[29] = (*this)(_n2x,y,0,k), P.ptr(N2*k)[30] = (*this)(_n3x,y,0,k), P.ptr(N2*k)[31] = (*this)(_n4x,y,0,k), P.ptr(N2*k)[32] = (*this)(_p3x,_n1y,0,k), P.ptr(N2*k)[33] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[34] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[35] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[36] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[37] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[38] = (*this)(_n3x,_n1y,0,k), P.ptr(N2*k)[39] = (*this)(_n4x,_n1y,0,k), P.ptr(N2*k)[40] = (*this)(_p3x,_n2y,0,k), P.ptr(N2*k)[41] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[42] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[43] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[44] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[45] = (*this)(_n2x,_n2y,0,k), P.ptr(N2*k)[46] = (*this)(_n3x,_n2y,0,k), P.ptr(N2*k)[47] = (*this)(_n4x,_n2y,0,k), P.ptr(N2*k)[48] = (*this)(_p3x,_n3y,0,k), P.ptr(N2*k)[49] = (*this)(_p2x,_n3y,0,k), P.ptr(N2*k)[50] = (*this)(_p1x,_n3y,0,k), P.ptr(N2*k)[51] = (*this)(x,_n3y,0,k), P.ptr(N2*k)[52] = (*this)(_n1x,_n3y,0,k), P.ptr(N2*k)[53] = (*this)(_n2x,_n3y,0,k), P.ptr(N2*k)[54] = (*this)(_n3x,_n3y,0,k), P.ptr(N2*k)[55] = (*this)(_n4x,_n3y,0,k), P.ptr(N2*k)[56] = (*this)(_p3x,_n4y,0,k), P.ptr(N2*k)[57] = (*this)(_p2x,_n4y,0,k), P.ptr(N2*k)[58] = (*this)(_p1x,_n4y,0,k), P.ptr(N2*k)[59] = (*this)(x,_n4y,0,k), P.ptr(N2*k)[60] = (*this)(_n1x,_n4y,0,k), P.ptr(N2*k)[61] = (*this)(_n2x,_n4y,0,k), P.ptr(N2*k)[62] = (*this)(_n3x,_n4y,0,k), P.ptr(N2*k)[63] = (*this)(_n4x,_n4y,0,k);; const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p3q = q-3<0?0:q-3, _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2, _n3q = q+3>=(int)((*this).height)?(int)((*this).height)-1:q+3, _n4q = q+4>=(int)((*this).height)?(int)((*this).height)-1:q+4; q<=(int)(y1) && (_n4q<(int)((*this).height) || _n3q==--_n4q || _n2q==--_n3q || _n1q==--_n2q || q==(_n4q = _n3q = _n2q = --_n1q)); _p3q = _p2q, _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q, ++_n3q, ++_n4q) for (int p = (int)(x0)<0?0:(int)(x0), _p3p = p-3<0?0:p-3, _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2, _n3p = p+3>=(int)((*this).width)?(int)((*this).width)-1:p+3, _n4p = p+4>=(int)((*this).width)?(int)((*this).width)-1:p+4; p<=(int)(x1) && (_n4p<(int)((*this).width) || _n3p==--_n4p || _n2p==--_n3p || _n1p==--_n2p || p==(_n4p = _n3p = _n2p = --_n1p)); _p3p = _p2p, _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p, ++_n3p, ++_n4p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p3p,_p3q,0,k), Q.ptr(N2*k)[1] = (*this)(_p2p,_p3q,0,k), Q.ptr(N2*k)[2] = (*this)(_p1p,_p3q,0,k), Q.ptr(N2*k)[3] = (*this)(p,_p3q,0,k), Q.ptr(N2*k)[4] = (*this)(_n1p,_p3q,0,k), Q.ptr(N2*k)[5] = (*this)(_n2p,_p3q,0,k), Q.ptr(N2*k)[6] = (*this)(_n3p,_p3q,0,k), Q.ptr(N2*k)[7] = (*this)(_n4p,_p3q,0,k), Q.ptr(N2*k)[8] = (*this)(_p3p,_p2q,0,k), Q.ptr(N2*k)[9] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[10] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[11] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[12] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[13] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[14] = (*this)(_n3p,_p2q,0,k), Q.ptr(N2*k)[15] = (*this)(_n4p,_p2q,0,k), Q.ptr(N2*k)[16] = (*this)(_p3p,_p1q,0,k), Q.ptr(N2*k)[17] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[18] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[19] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[20] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[21] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[22] = (*this)(_n3p,_p1q,0,k), Q.ptr(N2*k)[23] = (*this)(_n4p,_p1q,0,k), Q.ptr(N2*k)[24] = (*this)(_p3p,q,0,k), Q.ptr(N2*k)[25] = (*this)(_p2p,q,0,k), Q.ptr(N2*k)[26] = (*this)(_p1p,q,0,k), Q.ptr(N2*k)[27] = (*this)(p,q,0,k), Q.ptr(N2*k)[28] = (*this)(_n1p,q,0,k), Q.ptr(N2*k)[29] = (*this)(_n2p,q,0,k), Q.ptr(N2*k)[30] = (*this)(_n3p,q,0,k), Q.ptr(N2*k)[31] = (*this)(_n4p,q,0,k), Q.ptr(N2*k)[32] = (*this)(_p3p,_n1q,0,k), Q.ptr(N2*k)[33] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[34] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[35] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[36] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[37] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[38] = (*this)(_n3p,_n1q,0,k), Q.ptr(N2*k)[39] = (*this)(_n4p,_n1q,0,k), Q.ptr(N2*k)[40] = (*this)(_p3p,_n2q,0,k), Q.ptr(N2*k)[41] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[42] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[43] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[44] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[45] = (*this)(_n2p,_n2q,0,k), Q.ptr(N2*k)[46] = (*this)(_n3p,_n2q,0,k), Q.ptr(N2*k)[47] = (*this)(_n4p,_n2q,0,k), Q.ptr(N2*k)[48] = (*this)(_p3p,_n3q,0,k), Q.ptr(N2*k)[49] = (*this)(_p2p,_n3q,0,k), Q.ptr(N2*k)[50] = (*this)(_p1p,_n3q,0,k), Q.ptr(N2*k)[51] = (*this)(p,_n3q,0,k), Q.ptr(N2*k)[52] = (*this)(_n1p,_n3q,0,k), Q.ptr(N2*k)[53] = (*this)(_n2p,_n3q,0,k), Q.ptr(N2*k)[54] = (*this)(_n3p,_n3q,0,k), Q.ptr(N2*k)[55] = (*this)(_n4p,_n3q,0,k), Q.ptr(N2*k)[56] = (*this)(_p3p,_n4q,0,k), Q.ptr(N2*k)[57] = (*this)(_p2p,_n4q,0,k), Q.ptr(N2*k)[58] = (*this)(_p1p,_n4q,0,k), Q.ptr(N2*k)[59] = (*this)(p,_n4q,0,k), Q.ptr(N2*k)[60] = (*this)(_n1p,_n4q,0,k), Q.ptr(N2*k)[61] = (*this)(_n2p,_n4q,0,k), Q.ptr(N2*k)[62] = (*this)(_n3p,_n4q,0,k), Q.ptr(N2*k)[63] = (*this)(_n4p,_n4q,0,k);; float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } break; case 9: if (fast_approx) { { const unsigned int N2 = 9*9; for (int y = 0, _p4y = 0, _p3y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=(int)((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=(int)((*this).height)?(int)((*this).height)-1:2, _n3y = 3>=(int)((*this).height)?(int)((*this).height)-1:3, _n4y = 4>=(int)((*this).height)?(int)((*this).height)-1:4; _n4y<(int)((*this).height) || _n3y==--_n4y || _n2y==--_n3y || _n1y==--_n2y || y==(_n4y = _n3y = _n2y = --_n1y); _p4y = _p3y, _p3y = _p2y, _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y, ++_n3y, ++_n4y) for (int x = 0, _p4x = 0, _p3x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=(int)((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=(int)((*this).width)?(int)((*this).width)-1:2, _n3x = 3>=(int)((*this).width)?(int)((*this).width)-1:3, _n4x = 4>=(int)((*this).width)?(int)((*this).width)-1:4; _n4x<(int)((*this).width) || _n3x==--_n4x || _n2x==--_n3x || _n1x==--_n2x || x==(_n4x = _n3x = _n2x = --_n1x); _p4x = _p3x, _p3x = _p2x, _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x, ++_n3x, ++_n4x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p4x,_p4y,0,k), P.ptr(N2*k)[1] = (*this)(_p3x,_p4y,0,k), P.ptr(N2*k)[2] = (*this)(_p2x,_p4y,0,k), P.ptr(N2*k)[3] = (*this)(_p1x,_p4y,0,k), P.ptr(N2*k)[4] = (*this)(x,_p4y,0,k), P.ptr(N2*k)[5] = (*this)(_n1x,_p4y,0,k), P.ptr(N2*k)[6] = (*this)(_n2x,_p4y,0,k), P.ptr(N2*k)[7] = (*this)(_n3x,_p4y,0,k), P.ptr(N2*k)[8] = (*this)(_n4x,_p4y,0,k), P.ptr(N2*k)[9] = (*this)(_p4x,_p3y,0,k), P.ptr(N2*k)[10] = (*this)(_p3x,_p3y,0,k), P.ptr(N2*k)[11] = (*this)(_p2x,_p3y,0,k), P.ptr(N2*k)[12] = (*this)(_p1x,_p3y,0,k), P.ptr(N2*k)[13] = (*this)(x,_p3y,0,k), P.ptr(N2*k)[14] = (*this)(_n1x,_p3y,0,k), P.ptr(N2*k)[15] = (*this)(_n2x,_p3y,0,k), P.ptr(N2*k)[16] = (*this)(_n3x,_p3y,0,k), P.ptr(N2*k)[17] = (*this)(_n4x,_p3y,0,k), P.ptr(N2*k)[18] = (*this)(_p4x,_p2y,0,k), P.ptr(N2*k)[19] = (*this)(_p3x,_p2y,0,k), P.ptr(N2*k)[20] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[21] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[22] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[23] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[24] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[25] = (*this)(_n3x,_p2y,0,k), P.ptr(N2*k)[26] = (*this)(_n4x,_p2y,0,k), P.ptr(N2*k)[27] = (*this)(_p4x,_p1y,0,k), P.ptr(N2*k)[28] = (*this)(_p3x,_p1y,0,k), P.ptr(N2*k)[29] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[30] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[31] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[32] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[33] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[34] = (*this)(_n3x,_p1y,0,k), P.ptr(N2*k)[35] = (*this)(_n4x,_p1y,0,k), P.ptr(N2*k)[36] = (*this)(_p4x,y,0,k), P.ptr(N2*k)[37] = (*this)(_p3x,y,0,k), P.ptr(N2*k)[38] = (*this)(_p2x,y,0,k), P.ptr(N2*k)[39] = (*this)(_p1x,y,0,k), P.ptr(N2*k)[40] = (*this)(x,y,0,k), P.ptr(N2*k)[41] = (*this)(_n1x,y,0,k), P.ptr(N2*k)[42] = (*this)(_n2x,y,0,k), P.ptr(N2*k)[43] = (*this)(_n3x,y,0,k), P.ptr(N2*k)[44] = (*this)(_n4x,y,0,k), P.ptr(N2*k)[45] = (*this)(_p4x,_n1y,0,k), P.ptr(N2*k)[46] = (*this)(_p3x,_n1y,0,k), P.ptr(N2*k)[47] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[48] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[49] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[50] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[51] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[52] = (*this)(_n3x,_n1y,0,k), P.ptr(N2*k)[53] = (*this)(_n4x,_n1y,0,k), P.ptr(N2*k)[54] = (*this)(_p4x,_n2y,0,k), P.ptr(N2*k)[55] = (*this)(_p3x,_n2y,0,k), P.ptr(N2*k)[56] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[57] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[58] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[59] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[60] = (*this)(_n2x,_n2y,0,k), P.ptr(N2*k)[61] = (*this)(_n3x,_n2y,0,k), P.ptr(N2*k)[62] = (*this)(_n4x,_n2y,0,k), P.ptr(N2*k)[63] = (*this)(_p4x,_n3y,0,k), P.ptr(N2*k)[64] = (*this)(_p3x,_n3y,0,k), P.ptr(N2*k)[65] = (*this)(_p2x,_n3y,0,k), P.ptr(N2*k)[66] = (*this)(_p1x,_n3y,0,k), P.ptr(N2*k)[67] = (*this)(x,_n3y,0,k), P.ptr(N2*k)[68] = (*this)(_n1x,_n3y,0,k), P.ptr(N2*k)[69] = (*this)(_n2x,_n3y,0,k), P.ptr(N2*k)[70] = (*this)(_n3x,_n3y,0,k), P.ptr(N2*k)[71] = (*this)(_n4x,_n3y,0,k), P.ptr(N2*k)[72] = (*this)(_p4x,_n4y,0,k), P.ptr(N2*k)[73] = (*this)(_p3x,_n4y,0,k), P.ptr(N2*k)[74] = (*this)(_p2x,_n4y,0,k), P.ptr(N2*k)[75] = (*this)(_p1x,_n4y,0,k), P.ptr(N2*k)[76] = (*this)(x,_n4y,0,k), P.ptr(N2*k)[77] = (*this)(_n1x,_n4y,0,k), P.ptr(N2*k)[78] = (*this)(_n2x,_n4y,0,k), P.ptr(N2*k)[79] = (*this)(_n3x,_n4y,0,k), P.ptr(N2*k)[80] = (*this)(_n4x,_n4y,0,k);; const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p4q = q-4<0?0:q-4, _p3q = q-3<0?0:q-3, _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2, _n3q = q+3>=(int)((*this).height)?(int)((*this).height)-1:q+3, _n4q = q+4>=(int)((*this).height)?(int)((*this).height)-1:q+4; q<=(int)(y1) && (_n4q<(int)((*this).height) || _n3q==--_n4q || _n2q==--_n3q || _n1q==--_n2q || q==(_n4q = _n3q = _n2q = --_n1q)); _p4q = _p3q, _p3q = _p2q, _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q, ++_n3q, ++_n4q) for (int p = (int)(x0)<0?0:(int)(x0), _p4p = p-4<0?0:p-4, _p3p = p-3<0?0:p-3, _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2, _n3p = p+3>=(int)((*this).width)?(int)((*this).width)-1:p+3, _n4p = p+4>=(int)((*this).width)?(int)((*this).width)-1:p+4; p<=(int)(x1) && (_n4p<(int)((*this).width) || _n3p==--_n4p || _n2p==--_n3p || _n1p==--_n2p || p==(_n4p = _n3p = _n2p = --_n1p)); _p4p = _p3p, _p3p = _p2p, _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p, ++_n3p, ++_n4p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p4p,_p4q,0,k), Q.ptr(N2*k)[1] = (*this)(_p3p,_p4q,0,k), Q.ptr(N2*k)[2] = (*this)(_p2p,_p4q,0,k), Q.ptr(N2*k)[3] = (*this)(_p1p,_p4q,0,k), Q.ptr(N2*k)[4] = (*this)(p,_p4q,0,k), Q.ptr(N2*k)[5] = (*this)(_n1p,_p4q,0,k), Q.ptr(N2*k)[6] = (*this)(_n2p,_p4q,0,k), Q.ptr(N2*k)[7] = (*this)(_n3p,_p4q,0,k), Q.ptr(N2*k)[8] = (*this)(_n4p,_p4q,0,k), Q.ptr(N2*k)[9] = (*this)(_p4p,_p3q,0,k), Q.ptr(N2*k)[10] = (*this)(_p3p,_p3q,0,k), Q.ptr(N2*k)[11] = (*this)(_p2p,_p3q,0,k), Q.ptr(N2*k)[12] = (*this)(_p1p,_p3q,0,k), Q.ptr(N2*k)[13] = (*this)(p,_p3q,0,k), Q.ptr(N2*k)[14] = (*this)(_n1p,_p3q,0,k), Q.ptr(N2*k)[15] = (*this)(_n2p,_p3q,0,k), Q.ptr(N2*k)[16] = (*this)(_n3p,_p3q,0,k), Q.ptr(N2*k)[17] = (*this)(_n4p,_p3q,0,k), Q.ptr(N2*k)[18] = (*this)(_p4p,_p2q,0,k), Q.ptr(N2*k)[19] = (*this)(_p3p,_p2q,0,k), Q.ptr(N2*k)[20] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[21] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[22] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[23] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[24] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[25] = (*this)(_n3p,_p2q,0,k), Q.ptr(N2*k)[26] = (*this)(_n4p,_p2q,0,k), Q.ptr(N2*k)[27] = (*this)(_p4p,_p1q,0,k), Q.ptr(N2*k)[28] = (*this)(_p3p,_p1q,0,k), Q.ptr(N2*k)[29] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[30] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[31] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[32] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[33] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[34] = (*this)(_n3p,_p1q,0,k), Q.ptr(N2*k)[35] = (*this)(_n4p,_p1q,0,k), Q.ptr(N2*k)[36] = (*this)(_p4p,q,0,k), Q.ptr(N2*k)[37] = (*this)(_p3p,q,0,k), Q.ptr(N2*k)[38] = (*this)(_p2p,q,0,k), Q.ptr(N2*k)[39] = (*this)(_p1p,q,0,k), Q.ptr(N2*k)[40] = (*this)(p,q,0,k), Q.ptr(N2*k)[41] = (*this)(_n1p,q,0,k), Q.ptr(N2*k)[42] = (*this)(_n2p,q,0,k), Q.ptr(N2*k)[43] = (*this)(_n3p,q,0,k), Q.ptr(N2*k)[44] = (*this)(_n4p,q,0,k), Q.ptr(N2*k)[45] = (*this)(_p4p,_n1q,0,k), Q.ptr(N2*k)[46] = (*this)(_p3p,_n1q,0,k), Q.ptr(N2*k)[47] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[48] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[49] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[50] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[51] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[52] = (*this)(_n3p,_n1q,0,k), Q.ptr(N2*k)[53] = (*this)(_n4p,_n1q,0,k), Q.ptr(N2*k)[54] = (*this)(_p4p,_n2q,0,k), Q.ptr(N2*k)[55] = (*this)(_p3p,_n2q,0,k), Q.ptr(N2*k)[56] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[57] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[58] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[59] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[60] = (*this)(_n2p,_n2q,0,k), Q.ptr(N2*k)[61] = (*this)(_n3p,_n2q,0,k), Q.ptr(N2*k)[62] = (*this)(_n4p,_n2q,0,k), Q.ptr(N2*k)[63] = (*this)(_p4p,_n3q,0,k), Q.ptr(N2*k)[64] = (*this)(_p3p,_n3q,0,k), Q.ptr(N2*k)[65] = (*this)(_p2p,_n3q,0,k), Q.ptr(N2*k)[66] = (*this)(_p1p,_n3q,0,k), Q.ptr(N2*k)[67] = (*this)(p,_n3q,0,k), Q.ptr(N2*k)[68] = (*this)(_n1p,_n3q,0,k), Q.ptr(N2*k)[69] = (*this)(_n2p,_n3q,0,k), Q.ptr(N2*k)[70] = (*this)(_n3p,_n3q,0,k), Q.ptr(N2*k)[71] = (*this)(_n4p,_n3q,0,k), Q.ptr(N2*k)[72] = (*this)(_p4p,_n4q,0,k), Q.ptr(N2*k)[73] = (*this)(_p3p,_n4q,0,k), Q.ptr(N2*k)[74] = (*this)(_p2p,_n4q,0,k), Q.ptr(N2*k)[75] = (*this)(_p1p,_n4q,0,k), Q.ptr(N2*k)[76] = (*this)(p,_n4q,0,k), Q.ptr(N2*k)[77] = (*this)(_n1p,_n4q,0,k), Q.ptr(N2*k)[78] = (*this)(_n2p,_n4q,0,k), Q.ptr(N2*k)[79] = (*this)(_n3p,_n4q,0,k), Q.ptr(N2*k)[80] = (*this)(_n4p,_n4q,0,k);; float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = ((alldist)>3?0:1); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } else { { const unsigned int N2 = 9*9; for (int y = 0, _p4y = 0, _p3y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=(int)((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=(int)((*this).height)?(int)((*this).height)-1:2, _n3y = 3>=(int)((*this).height)?(int)((*this).height)-1:3, _n4y = 4>=(int)((*this).height)?(int)((*this).height)-1:4; _n4y<(int)((*this).height) || _n3y==--_n4y || _n2y==--_n3y || _n1y==--_n2y || y==(_n4y = _n3y = _n2y = --_n1y); _p4y = _p3y, _p3y = _p2y, _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y, ++_n3y, ++_n4y) for (int x = 0, _p4x = 0, _p3x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=(int)((*this).width)?(int)((*this).width)-1:1, _n2x = 2>=(int)((*this).width)?(int)((*this).width)-1:2, _n3x = 3>=(int)((*this).width)?(int)((*this).width)-1:3, _n4x = 4>=(int)((*this).width)?(int)((*this).width)-1:4; _n4x<(int)((*this).width) || _n3x==--_n4x || _n2x==--_n3x || _n1x==--_n2x || x==(_n4x = _n3x = _n2x = --_n1x); _p4x = _p3x, _p3x = _p2x, _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x, ++_n3x, ++_n4x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; for (int k = 0; k<(int)((*this).dim); ++k) P.ptr(N2*k)[0] = (*this)(_p4x,_p4y,0,k), P.ptr(N2*k)[1] = (*this)(_p3x,_p4y,0,k), P.ptr(N2*k)[2] = (*this)(_p2x,_p4y,0,k), P.ptr(N2*k)[3] = (*this)(_p1x,_p4y,0,k), P.ptr(N2*k)[4] = (*this)(x,_p4y,0,k), P.ptr(N2*k)[5] = (*this)(_n1x,_p4y,0,k), P.ptr(N2*k)[6] = (*this)(_n2x,_p4y,0,k), P.ptr(N2*k)[7] = (*this)(_n3x,_p4y,0,k), P.ptr(N2*k)[8] = (*this)(_n4x,_p4y,0,k), P.ptr(N2*k)[9] = (*this)(_p4x,_p3y,0,k), P.ptr(N2*k)[10] = (*this)(_p3x,_p3y,0,k), P.ptr(N2*k)[11] = (*this)(_p2x,_p3y,0,k), P.ptr(N2*k)[12] = (*this)(_p1x,_p3y,0,k), P.ptr(N2*k)[13] = (*this)(x,_p3y,0,k), P.ptr(N2*k)[14] = (*this)(_n1x,_p3y,0,k), P.ptr(N2*k)[15] = (*this)(_n2x,_p3y,0,k), P.ptr(N2*k)[16] = (*this)(_n3x,_p3y,0,k), P.ptr(N2*k)[17] = (*this)(_n4x,_p3y,0,k), P.ptr(N2*k)[18] = (*this)(_p4x,_p2y,0,k), P.ptr(N2*k)[19] = (*this)(_p3x,_p2y,0,k), P.ptr(N2*k)[20] = (*this)(_p2x,_p2y,0,k), P.ptr(N2*k)[21] = (*this)(_p1x,_p2y,0,k), P.ptr(N2*k)[22] = (*this)(x,_p2y,0,k), P.ptr(N2*k)[23] = (*this)(_n1x,_p2y,0,k), P.ptr(N2*k)[24] = (*this)(_n2x,_p2y,0,k), P.ptr(N2*k)[25] = (*this)(_n3x,_p2y,0,k), P.ptr(N2*k)[26] = (*this)(_n4x,_p2y,0,k), P.ptr(N2*k)[27] = (*this)(_p4x,_p1y,0,k), P.ptr(N2*k)[28] = (*this)(_p3x,_p1y,0,k), P.ptr(N2*k)[29] = (*this)(_p2x,_p1y,0,k), P.ptr(N2*k)[30] = (*this)(_p1x,_p1y,0,k), P.ptr(N2*k)[31] = (*this)(x,_p1y,0,k), P.ptr(N2*k)[32] = (*this)(_n1x,_p1y,0,k), P.ptr(N2*k)[33] = (*this)(_n2x,_p1y,0,k), P.ptr(N2*k)[34] = (*this)(_n3x,_p1y,0,k), P.ptr(N2*k)[35] = (*this)(_n4x,_p1y,0,k), P.ptr(N2*k)[36] = (*this)(_p4x,y,0,k), P.ptr(N2*k)[37] = (*this)(_p3x,y,0,k), P.ptr(N2*k)[38] = (*this)(_p2x,y,0,k), P.ptr(N2*k)[39] = (*this)(_p1x,y,0,k), P.ptr(N2*k)[40] = (*this)(x,y,0,k), P.ptr(N2*k)[41] = (*this)(_n1x,y,0,k), P.ptr(N2*k)[42] = (*this)(_n2x,y,0,k), P.ptr(N2*k)[43] = (*this)(_n3x,y,0,k), P.ptr(N2*k)[44] = (*this)(_n4x,y,0,k), P.ptr(N2*k)[45] = (*this)(_p4x,_n1y,0,k), P.ptr(N2*k)[46] = (*this)(_p3x,_n1y,0,k), P.ptr(N2*k)[47] = (*this)(_p2x,_n1y,0,k), P.ptr(N2*k)[48] = (*this)(_p1x,_n1y,0,k), P.ptr(N2*k)[49] = (*this)(x,_n1y,0,k), P.ptr(N2*k)[50] = (*this)(_n1x,_n1y,0,k), P.ptr(N2*k)[51] = (*this)(_n2x,_n1y,0,k), P.ptr(N2*k)[52] = (*this)(_n3x,_n1y,0,k), P.ptr(N2*k)[53] = (*this)(_n4x,_n1y,0,k), P.ptr(N2*k)[54] = (*this)(_p4x,_n2y,0,k), P.ptr(N2*k)[55] = (*this)(_p3x,_n2y,0,k), P.ptr(N2*k)[56] = (*this)(_p2x,_n2y,0,k), P.ptr(N2*k)[57] = (*this)(_p1x,_n2y,0,k), P.ptr(N2*k)[58] = (*this)(x,_n2y,0,k), P.ptr(N2*k)[59] = (*this)(_n1x,_n2y,0,k), P.ptr(N2*k)[60] = (*this)(_n2x,_n2y,0,k), P.ptr(N2*k)[61] = (*this)(_n3x,_n2y,0,k), P.ptr(N2*k)[62] = (*this)(_n4x,_n2y,0,k), P.ptr(N2*k)[63] = (*this)(_p4x,_n3y,0,k), P.ptr(N2*k)[64] = (*this)(_p3x,_n3y,0,k), P.ptr(N2*k)[65] = (*this)(_p2x,_n3y,0,k), P.ptr(N2*k)[66] = (*this)(_p1x,_n3y,0,k), P.ptr(N2*k)[67] = (*this)(x,_n3y,0,k), P.ptr(N2*k)[68] = (*this)(_n1x,_n3y,0,k), P.ptr(N2*k)[69] = (*this)(_n2x,_n3y,0,k), P.ptr(N2*k)[70] = (*this)(_n3x,_n3y,0,k), P.ptr(N2*k)[71] = (*this)(_n4x,_n3y,0,k), P.ptr(N2*k)[72] = (*this)(_p4x,_n4y,0,k), P.ptr(N2*k)[73] = (*this)(_p3x,_n4y,0,k), P.ptr(N2*k)[74] = (*this)(_p2x,_n4y,0,k), P.ptr(N2*k)[75] = (*this)(_p1x,_n4y,0,k), P.ptr(N2*k)[76] = (*this)(x,_n4y,0,k), P.ptr(N2*k)[77] = (*this)(_n1x,_n4y,0,k), P.ptr(N2*k)[78] = (*this)(_n2x,_n4y,0,k), P.ptr(N2*k)[79] = (*this)(_n3x,_n4y,0,k), P.ptr(N2*k)[80] = (*this)(_n4x,_n4y,0,k);; const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _p4q = q-4<0?0:q-4, _p3q = q-3<0?0:q-3, _p2q = q-2<0?0:q-2, _p1q = q-1<0?0:q-1, _n1q = q+1>=(int)((*this).height)?(int)((*this).height)-1:q+1, _n2q = q+2>=(int)((*this).height)?(int)((*this).height)-1:q+2, _n3q = q+3>=(int)((*this).height)?(int)((*this).height)-1:q+3, _n4q = q+4>=(int)((*this).height)?(int)((*this).height)-1:q+4; q<=(int)(y1) && (_n4q<(int)((*this).height) || _n3q==--_n4q || _n2q==--_n3q || _n1q==--_n2q || q==(_n4q = _n3q = _n2q = --_n1q)); _p4q = _p3q, _p3q = _p2q, _p2q = _p1q, _p1q = q++, ++_n1q, ++_n2q, ++_n3q, ++_n4q) for (int p = (int)(x0)<0?0:(int)(x0), _p4p = p-4<0?0:p-4, _p3p = p-3<0?0:p-3, _p2p = p-2<0?0:p-2, _p1p = p-1<0?0:p-1, _n1p = p+1>=(int)((*this).width)?(int)((*this).width)-1:p+1, _n2p = p+2>=(int)((*this).width)?(int)((*this).width)-1:p+2, _n3p = p+3>=(int)((*this).width)?(int)((*this).width)-1:p+3, _n4p = p+4>=(int)((*this).width)?(int)((*this).width)-1:p+4; p<=(int)(x1) && (_n4p<(int)((*this).width) || _n3p==--_n4p || _n2p==--_n3p || _n1p==--_n2p || p==(_n4p = _n3p = _n2p = --_n1p)); _p4p = _p3p, _p3p = _p2p, _p2p = _p1p, _p1p = p++, ++_n1p, ++_n2p, ++_n3p, ++_n4p) { for (int k = 0; k<(int)((*this).dim); ++k) Q.ptr(N2*k)[0] = (*this)(_p4p,_p4q,0,k), Q.ptr(N2*k)[1] = (*this)(_p3p,_p4q,0,k), Q.ptr(N2*k)[2] = (*this)(_p2p,_p4q,0,k), Q.ptr(N2*k)[3] = (*this)(_p1p,_p4q,0,k), Q.ptr(N2*k)[4] = (*this)(p,_p4q,0,k), Q.ptr(N2*k)[5] = (*this)(_n1p,_p4q,0,k), Q.ptr(N2*k)[6] = (*this)(_n2p,_p4q,0,k), Q.ptr(N2*k)[7] = (*this)(_n3p,_p4q,0,k), Q.ptr(N2*k)[8] = (*this)(_n4p,_p4q,0,k), Q.ptr(N2*k)[9] = (*this)(_p4p,_p3q,0,k), Q.ptr(N2*k)[10] = (*this)(_p3p,_p3q,0,k), Q.ptr(N2*k)[11] = (*this)(_p2p,_p3q,0,k), Q.ptr(N2*k)[12] = (*this)(_p1p,_p3q,0,k), Q.ptr(N2*k)[13] = (*this)(p,_p3q,0,k), Q.ptr(N2*k)[14] = (*this)(_n1p,_p3q,0,k), Q.ptr(N2*k)[15] = (*this)(_n2p,_p3q,0,k), Q.ptr(N2*k)[16] = (*this)(_n3p,_p3q,0,k), Q.ptr(N2*k)[17] = (*this)(_n4p,_p3q,0,k), Q.ptr(N2*k)[18] = (*this)(_p4p,_p2q,0,k), Q.ptr(N2*k)[19] = (*this)(_p3p,_p2q,0,k), Q.ptr(N2*k)[20] = (*this)(_p2p,_p2q,0,k), Q.ptr(N2*k)[21] = (*this)(_p1p,_p2q,0,k), Q.ptr(N2*k)[22] = (*this)(p,_p2q,0,k), Q.ptr(N2*k)[23] = (*this)(_n1p,_p2q,0,k), Q.ptr(N2*k)[24] = (*this)(_n2p,_p2q,0,k), Q.ptr(N2*k)[25] = (*this)(_n3p,_p2q,0,k), Q.ptr(N2*k)[26] = (*this)(_n4p,_p2q,0,k), Q.ptr(N2*k)[27] = (*this)(_p4p,_p1q,0,k), Q.ptr(N2*k)[28] = (*this)(_p3p,_p1q,0,k), Q.ptr(N2*k)[29] = (*this)(_p2p,_p1q,0,k), Q.ptr(N2*k)[30] = (*this)(_p1p,_p1q,0,k), Q.ptr(N2*k)[31] = (*this)(p,_p1q,0,k), Q.ptr(N2*k)[32] = (*this)(_n1p,_p1q,0,k), Q.ptr(N2*k)[33] = (*this)(_n2p,_p1q,0,k), Q.ptr(N2*k)[34] = (*this)(_n3p,_p1q,0,k), Q.ptr(N2*k)[35] = (*this)(_n4p,_p1q,0,k), Q.ptr(N2*k)[36] = (*this)(_p4p,q,0,k), Q.ptr(N2*k)[37] = (*this)(_p3p,q,0,k), Q.ptr(N2*k)[38] = (*this)(_p2p,q,0,k), Q.ptr(N2*k)[39] = (*this)(_p1p,q,0,k), Q.ptr(N2*k)[40] = (*this)(p,q,0,k), Q.ptr(N2*k)[41] = (*this)(_n1p,q,0,k), Q.ptr(N2*k)[42] = (*this)(_n2p,q,0,k), Q.ptr(N2*k)[43] = (*this)(_n3p,q,0,k), Q.ptr(N2*k)[44] = (*this)(_n4p,q,0,k), Q.ptr(N2*k)[45] = (*this)(_p4p,_n1q,0,k), Q.ptr(N2*k)[46] = (*this)(_p3p,_n1q,0,k), Q.ptr(N2*k)[47] = (*this)(_p2p,_n1q,0,k), Q.ptr(N2*k)[48] = (*this)(_p1p,_n1q,0,k), Q.ptr(N2*k)[49] = (*this)(p,_n1q,0,k), Q.ptr(N2*k)[50] = (*this)(_n1p,_n1q,0,k), Q.ptr(N2*k)[51] = (*this)(_n2p,_n1q,0,k), Q.ptr(N2*k)[52] = (*this)(_n3p,_n1q,0,k), Q.ptr(N2*k)[53] = (*this)(_n4p,_n1q,0,k), Q.ptr(N2*k)[54] = (*this)(_p4p,_n2q,0,k), Q.ptr(N2*k)[55] = (*this)(_p3p,_n2q,0,k), Q.ptr(N2*k)[56] = (*this)(_p2p,_n2q,0,k), Q.ptr(N2*k)[57] = (*this)(_p1p,_n2q,0,k), Q.ptr(N2*k)[58] = (*this)(p,_n2q,0,k), Q.ptr(N2*k)[59] = (*this)(_n1p,_n2q,0,k), Q.ptr(N2*k)[60] = (*this)(_n2p,_n2q,0,k), Q.ptr(N2*k)[61] = (*this)(_n3p,_n2q,0,k), Q.ptr(N2*k)[62] = (*this)(_n4p,_n2q,0,k), Q.ptr(N2*k)[63] = (*this)(_p4p,_n3q,0,k), Q.ptr(N2*k)[64] = (*this)(_p3p,_n3q,0,k), Q.ptr(N2*k)[65] = (*this)(_p2p,_n3q,0,k), Q.ptr(N2*k)[66] = (*this)(_p1p,_n3q,0,k), Q.ptr(N2*k)[67] = (*this)(p,_n3q,0,k), Q.ptr(N2*k)[68] = (*this)(_n1p,_n3q,0,k), Q.ptr(N2*k)[69] = (*this)(_n2p,_n3q,0,k), Q.ptr(N2*k)[70] = (*this)(_n3p,_n3q,0,k), Q.ptr(N2*k)[71] = (*this)(_n4p,_n3q,0,k), Q.ptr(N2*k)[72] = (*this)(_p4p,_n4q,0,k), Q.ptr(N2*k)[73] = (*this)(_p3p,_n4q,0,k), Q.ptr(N2*k)[74] = (*this)(_p2p,_n4q,0,k), Q.ptr(N2*k)[75] = (*this)(_p1p,_n4q,0,k), Q.ptr(N2*k)[76] = (*this)(p,_n4q,0,k), Q.ptr(N2*k)[77] = (*this)(_n1p,_n4q,0,k), Q.ptr(N2*k)[78] = (*this)(_n2p,_n4q,0,k), Q.ptr(N2*k)[79] = (*this)(_n3p,_n4q,0,k), Q.ptr(N2*k)[80] = (*this)(_n4p,_n4q,0,k);; float distance2 = 0; const T *pQ = Q.end(); for (T *pP = (P).data + (P).size(); (pP--)>(P).data; ) { const float dI = (float)*pP-(float)*(--pQ); distance2+=dI*dI; } distance2/=Pnorm; const float dx = p-x, dy = q-y, alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = std::exp(-(alldist)); sum_weights+=weight; { for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)+=weight*(*this)(p,q,k); } } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,k) = (*this)(x,y,k); }}; } break; default: { const int psize1 = (int)patch_size/2, psize0 = psize1-1+(patch_size%2); for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { if (!*(greycstoration_params->stop_request)) ++(*greycstoration_params->counter); else return *this;; P = get_crop(x-psize0,y-psize0,x+psize1,y+psize1,true); const int x0 = x-rsize1, y0 = y-rsize1, x1 = x+rsize2, y1 = y+rsize2; float sum_weights = 0; for (int q = (int)(y0)<0?0:(int)(y0), _maxq = (int)(y1)<(int)((*this).height)?(int)(y1):(int)((*this).height)-1; q<=_maxq; ++q) for (int p = (int)(x0)<0?0:(int)(x0), _maxp = (int)(x1)<(int)((*this).width)?(int)(x1):(int)((*this).width)-1; p<=_maxp; ++p) { (Q = get_crop(p-psize0,q-psize0,p+psize1,q+psize1,true))-=P; const float dx = x-p, dy = y-q, distance2 = Q.pow(2).sum()/Pnorm + (dx*dx + dy*dy)/sigma_s2, weight = std::exp(-distance2); sum_weights+=weight; for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,0,k)+=weight*(*this)(p,q,0,k); } if (sum_weights>0) for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,0,k)/=sum_weights; else for (int k = 0; k<(int)((*this).dim); ++k) res(x,y,0,k) = (*this)(x,y,0,k); } } break; } return res.transfer_to(*this); } CImgList::type> get_FFT(const char axe, const bool invert=false) const { typedef typename cimg::superset::type restype; return CImgList(*this).FFT(axe,invert); } CImgList::type> get_FFT(const bool invert=false) const { typedef typename cimg::superset::type restype; return CImgList(*this).FFT(invert); } CImg get_blur_median(const unsigned int n=3) { CImg res(width,height,depth,dim); if (!n || n==1) return *this; const int hl=n/2, hr=hl-1+n%2; if (res.depth!=1) { CImg vois; for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const int x0 = x - hl, y0 = y - hl, z0 = z-hl, x1 = x + hr, y1 = y + hr, z1 = z+hr, nx0 = x0<0?0:x0, ny0 = y0<0?0:y0, nz0 = z0<0?0:z0, nx1 = x1>=dimx()?dimx()-1:x1, ny1 = y1>=dimy()?dimy()-1:y1, nz1 = z1>=dimz()?dimz()-1:z1; vois = get_crop(nx0,ny0,nz0,k,nx1,ny1,nz1,k); res(x,y,z,k) = vois.median(); } } else { if (res.height!=1) switch (n) { case 3: { T I[9] = { 0 }; T J[9]; T& Jpp = J[0]; T& Jcp = J[1]; T& Jnp = J[2]; T& Jpc = J[3]; T& Jcc = J[4]; T& Jnc = J[5]; T& Jpn = J[6]; T& Jcn = J[7]; T& Jnn = J[8]; Jpp = Jcp = Jnp = Jpc = Jcc = Jnc = Jpn = Jcn = Jnn = 0; for (int k = 0; k<(int)((*this).dim); ++k) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,0,k)), (I[3] = I[4] = (*this)(0,y,0,k)), (I[6] = I[7] = (*this)(0,_n1y,0,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,0,k)), (I[5] = (*this)(_n1x,y,0,k)), (I[8] = (*this)(_n1x,_n1y,0,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { std::memcpy(J,I,9*sizeof(T)); if ((Jcp)>(Jnp)) cimg::swap(Jcp,Jnp); if ((Jcc)>(Jnc)) cimg::swap(Jcc,Jnc); if ((Jcn)>(Jnn)) cimg::swap(Jcn,Jnn); if ((Jpp)>(Jcp)) cimg::swap(Jpp,Jcp); if ((Jpc)>(Jcc)) cimg::swap(Jpc,Jcc); if ((Jpn)>(Jcn)) cimg::swap(Jpn,Jcn); if ((Jcp)>(Jnp)) cimg::swap(Jcp,Jnp); if ((Jcc)>(Jnc)) cimg::swap(Jcc,Jnc); if ((Jcn)>(Jnn)) cimg::swap(Jcn,Jnn); if ((Jpp)>(Jpc)) cimg::swap(Jpp,Jpc); if ((Jnc)>(Jnn)) cimg::swap(Jnc,Jnn); if ((Jcc)>(Jcn)) cimg::swap(Jcc,Jcn); if ((Jpc)>(Jpn)) cimg::swap(Jpc,Jpn); if ((Jcp)>(Jcc)) cimg::swap(Jcp,Jcc); if ((Jnp)>(Jnc)) cimg::swap(Jnp,Jnc); if ((Jcc)>(Jcn)) cimg::swap(Jcc,Jcn); if ((Jcc)>(Jnp)) cimg::swap(Jcc,Jnp); if ((Jpn)>(Jcc)) cimg::swap(Jpn,Jcc); if ((Jcc)>(Jnp)) cimg::swap(Jcc,Jnp); res(x,y,0,k) = Jcc; } } break; case 5: { T I[25] = { 0 }; T J[25]; T& Jbb = J[0]; T& Jpb = J[1]; T& Jcb = J[2]; T& Jnb = J[3]; T& Jab = J[4]; T& Jbp = J[5]; T& Jpp = J[6]; T& Jcp = J[7]; T& Jnp = J[8]; T& Jap = J[9]; T& Jbc = J[10]; T& Jpc = J[11]; T& Jcc = J[12]; T& Jnc = J[13]; T& Jac = J[14]; T& Jbn = J[15]; T& Jpn = J[16]; T& Jcn = J[17]; T& Jnn = J[18]; T& Jan = J[19]; T& Jba = J[20]; T& Jpa = J[21]; T& Jca = J[22]; T& Jna = J[23]; T& Jaa = J[24]; Jbb = Jpb = Jcb = Jnb = Jab = Jbp = Jpp = Jcp = Jnp = Jap = Jbc = Jpc = Jcc = Jnc = Jac = Jbn = Jpn = Jcn = Jnn = Jan = Jba = Jpa = Jca = Jna = Jaa = 0; for (int k = 0; k<(int)((*this).dim); ++k) for (int y = 0, _p2y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1, _n2y = 2>=((*this).height)?(int)((*this).height)-1:2; _n2y<(int)((*this).height) || _n1y==--_n2y || y==(_n2y = --_n1y); _p2y = _p1y, _p1y = y++, ++_n1y, ++_n2y) for (int x = 0, _p2x = 0, _p1x = 0, _n1x = 1>=(*this).width?(int)((*this).width)-1:1, _n2x = (int)( (I[0] = I[1] = I[2] = (*this)(0,_p2y,0,k)), (I[5] = I[6] = I[7] = (*this)(0,_p1y,0,k)), (I[10] = I[11] = I[12] = (*this)(0,y,0,k)), (I[15] = I[16] = I[17] = (*this)(0,_n1y,0,k)), (I[20] = I[21] = I[22] = (*this)(0,_n2y,0,k)), (I[3] = (*this)(_n1x,_p2y,0,k)), (I[8] = (*this)(_n1x,_p1y,0,k)), (I[13] = (*this)(_n1x,y,0,k)), (I[18] = (*this)(_n1x,_n1y,0,k)), (I[23] = (*this)(_n1x,_n2y,0,k)), 2>=(*this).width?(int)((*this).width)-1:2); (_n2x<(int)((*this).width) && ( (I[4] = (*this)(_n2x,_p2y,0,k)), (I[9] = (*this)(_n2x,_p1y,0,k)), (I[14] = (*this)(_n2x,y,0,k)), (I[19] = (*this)(_n2x,_n1y,0,k)), (I[24] = (*this)(_n2x,_n2y,0,k)),1)) || _n1x==--_n2x || x==(_n2x = --_n1x); I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], _p2x = _p1x, _p1x = x++, ++_n1x, ++_n2x) { std::memcpy(J,I,25*sizeof(T)); if ((Jbb)>(Jpb)) cimg::swap(Jbb,Jpb); if ((Jnb)>(Jab)) cimg::swap(Jnb,Jab); if ((Jcb)>(Jab)) cimg::swap(Jcb,Jab); if ((Jcb)>(Jnb)) cimg::swap(Jcb,Jnb); if ((Jpp)>(Jcp)) cimg::swap(Jpp,Jcp); if ((Jbp)>(Jcp)) cimg::swap(Jbp,Jcp); if ((Jbp)>(Jpp)) cimg::swap(Jbp,Jpp); if ((Jap)>(Jbc)) cimg::swap(Jap,Jbc); if ((Jnp)>(Jbc)) cimg::swap(Jnp,Jbc); if ((Jnp)>(Jap)) cimg::swap(Jnp,Jap); if ((Jcc)>(Jnc)) cimg::swap(Jcc,Jnc); if ((Jpc)>(Jnc)) cimg::swap(Jpc,Jnc); if ((Jpc)>(Jcc)) cimg::swap(Jpc,Jcc); if ((Jbn)>(Jpn)) cimg::swap(Jbn,Jpn); if ((Jac)>(Jpn)) cimg::swap(Jac,Jpn); if ((Jac)>(Jbn)) cimg::swap(Jac,Jbn); if ((Jnn)>(Jan)) cimg::swap(Jnn,Jan); if ((Jcn)>(Jan)) cimg::swap(Jcn,Jan); if ((Jcn)>(Jnn)) cimg::swap(Jcn,Jnn); if ((Jpa)>(Jca)) cimg::swap(Jpa,Jca); if ((Jba)>(Jca)) cimg::swap(Jba,Jca); if ((Jba)>(Jpa)) cimg::swap(Jba,Jpa); if ((Jna)>(Jaa)) cimg::swap(Jna,Jaa); if ((Jcb)>(Jbp)) cimg::swap(Jcb,Jbp); if ((Jnb)>(Jpp)) cimg::swap(Jnb,Jpp); if ((Jbb)>(Jpp)) cimg::swap(Jbb,Jpp); if ((Jbb)>(Jnb)) cimg::swap(Jbb,Jnb); if ((Jab)>(Jcp)) cimg::swap(Jab,Jcp); if ((Jpb)>(Jcp)) cimg::swap(Jpb,Jcp); if ((Jpb)>(Jab)) cimg::swap(Jpb,Jab); if ((Jpc)>(Jac)) cimg::swap(Jpc,Jac); if ((Jnp)>(Jac)) cimg::swap(Jnp,Jac); if ((Jnp)>(Jpc)) cimg::swap(Jnp,Jpc); if ((Jcc)>(Jbn)) cimg::swap(Jcc,Jbn); if ((Jap)>(Jbn)) cimg::swap(Jap,Jbn); if ((Jap)>(Jcc)) cimg::swap(Jap,Jcc); if ((Jnc)>(Jpn)) cimg::swap(Jnc,Jpn); if ((Jbc)>(Jpn)) cimg::swap(Jbc,Jpn); if ((Jbc)>(Jnc)) cimg::swap(Jbc,Jnc); if ((Jba)>(Jna)) cimg::swap(Jba,Jna); if ((Jcn)>(Jna)) cimg::swap(Jcn,Jna); if ((Jcn)>(Jba)) cimg::swap(Jcn,Jba); if ((Jpa)>(Jaa)) cimg::swap(Jpa,Jaa); if ((Jnn)>(Jaa)) cimg::swap(Jnn,Jaa); if ((Jnn)>(Jpa)) cimg::swap(Jnn,Jpa); if ((Jan)>(Jca)) cimg::swap(Jan,Jca); if ((Jnp)>(Jcn)) cimg::swap(Jnp,Jcn); if ((Jap)>(Jnn)) cimg::swap(Jap,Jnn); if ((Jbb)>(Jnn)) cimg::swap(Jbb,Jnn); if ((Jbb)>(Jap)) cimg::swap(Jbb,Jap); if ((Jbc)>(Jan)) cimg::swap(Jbc,Jan); if ((Jpb)>(Jan)) cimg::swap(Jpb,Jan); if ((Jpb)>(Jbc)) cimg::swap(Jpb,Jbc); if ((Jpc)>(Jba)) cimg::swap(Jpc,Jba); if ((Jcb)>(Jba)) cimg::swap(Jcb,Jba); if ((Jcb)>(Jpc)) cimg::swap(Jcb,Jpc); if ((Jcc)>(Jpa)) cimg::swap(Jcc,Jpa); if ((Jnb)>(Jpa)) cimg::swap(Jnb,Jpa); if ((Jnb)>(Jcc)) cimg::swap(Jnb,Jcc); if ((Jnc)>(Jca)) cimg::swap(Jnc,Jca); if ((Jab)>(Jca)) cimg::swap(Jab,Jca); if ((Jab)>(Jnc)) cimg::swap(Jab,Jnc); if ((Jac)>(Jna)) cimg::swap(Jac,Jna); if ((Jbp)>(Jna)) cimg::swap(Jbp,Jna); if ((Jbp)>(Jac)) cimg::swap(Jbp,Jac); if ((Jbn)>(Jaa)) cimg::swap(Jbn,Jaa); if ((Jpp)>(Jaa)) cimg::swap(Jpp,Jaa); if ((Jpp)>(Jbn)) cimg::swap(Jpp,Jbn); if ((Jcp)>(Jpn)) cimg::swap(Jcp,Jpn); if ((Jcp)>(Jan)) cimg::swap(Jcp,Jan); if ((Jnc)>(Jpa)) cimg::swap(Jnc,Jpa); if ((Jbn)>(Jna)) cimg::swap(Jbn,Jna); if ((Jcp)>(Jnc)) cimg::swap(Jcp,Jnc); if ((Jcp)>(Jbn)) cimg::swap(Jcp,Jbn); if ((Jpb)>(Jap)) cimg::swap(Jpb,Jap); if ((Jnb)>(Jpc)) cimg::swap(Jnb,Jpc); if ((Jbp)>(Jcn)) cimg::swap(Jbp,Jcn); if ((Jpc)>(Jcn)) cimg::swap(Jpc,Jcn); if ((Jap)>(Jcn)) cimg::swap(Jap,Jcn); if ((Jab)>(Jbc)) cimg::swap(Jab,Jbc); if ((Jpp)>(Jcc)) cimg::swap(Jpp,Jcc); if ((Jcp)>(Jac)) cimg::swap(Jcp,Jac); if ((Jab)>(Jpp)) cimg::swap(Jab,Jpp); if ((Jab)>(Jcp)) cimg::swap(Jab,Jcp); if ((Jcc)>(Jac)) cimg::swap(Jcc,Jac); if ((Jbc)>(Jac)) cimg::swap(Jbc,Jac); if ((Jpp)>(Jcp)) cimg::swap(Jpp,Jcp); if ((Jbc)>(Jcc)) cimg::swap(Jbc,Jcc); if ((Jpp)>(Jbc)) cimg::swap(Jpp,Jbc); if ((Jpp)>(Jcn)) cimg::swap(Jpp,Jcn); if ((Jcc)>(Jcn)) cimg::swap(Jcc,Jcn); if ((Jcp)>(Jcn)) cimg::swap(Jcp,Jcn); if ((Jcp)>(Jbc)) cimg::swap(Jcp,Jbc); if ((Jcc)>(Jnn)) cimg::swap(Jcc,Jnn); if ((Jcp)>(Jcc)) cimg::swap(Jcp,Jcc); if ((Jbc)>(Jnn)) cimg::swap(Jbc,Jnn); if ((Jcc)>(Jba)) cimg::swap(Jcc,Jba); if ((Jbc)>(Jba)) cimg::swap(Jbc,Jba); if ((Jbc)>(Jcc)) cimg::swap(Jbc,Jcc); res(x,y,0,k) = Jcc; } } break; default: { CImg vois; for (int k = 0; k<(int)((*this).dim); ++k) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { const int x0 = x - hl, y0 = y - hl, x1 = x + hr, y1 = y + hr, nx0 = x0<0?0:x0, ny0 = y0<0?0:y0, nx1 = x1>=dimx()?dimx()-1:x1, ny1 = y1>=dimy()?dimy()-1:y1; vois = get_crop(nx0,ny0,0,k,nx1,ny1,0,k); res(x,y,0,k) = vois.median(); } } break; } else switch (n) { case 2: { T I[4] = { 0 }; for (int k = 0; k<(int)((*this).dim); ++k) for (int y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; ++y, ++_n1y) for (int x = 0, _n1x = (int)( (I[0] = (*this)(0,y,0,k)), (I[2] = (*this)(0,_n1y,0,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[1] = (*this)(_n1x,y,0,k)), (I[3] = (*this)(_n1x,_n1y,0,k)),1)) || x==--_n1x; I[0] = I[1], I[2] = I[3], ++x, ++_n1x) res(x,0,0,k) = (T)(0.5f*(I[0]+I[1])); } break; case 3: { T I[9] = { 0 }; for (int k = 0; k<(int)((*this).dim); ++k) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,0,k)), (I[3] = I[4] = (*this)(0,y,0,k)), (I[6] = I[7] = (*this)(0,_n1y,0,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,0,k)), (I[5] = (*this)(_n1x,y,0,k)), (I[8] = (*this)(_n1x,_n1y,0,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { res(x,0,0,k) = I[3] vois; for (int k = 0; k<(int)((*this).dim); ++k) for (int x = 0; x<(int)((*this).width); ++x) { const int x0 = x - hl, x1 = x + hr, nx0 = x0<0?0:x0, nx1 = x1>=dimx()?dimx()-1:x1; vois = get_crop(nx0,0,0,k,nx1,0,0,k); res(x,0,0,k) = vois.median(); } } break; } } return res; } CImg& blur_median(const unsigned int n=3) { return get_blur_median(n).transfer_to(*this); } CImg get_sharpen(const float amplitude=50.0f, const float edge=1.0f, const float alpha=0.0f, const float sigma=0.0f) const { return (+*this).sharpen(amplitude,edge,alpha,sigma); } CImg& sharpen(const float amplitude=50.0f, const float edge=1.0f, const float alpha=0.0f, const float sigma=0.0f) { if (is_empty()) return *this; const bool threed = (depth>1); const float nedge = 0.5f*edge; typedef typename cimg::superset::type ftype; CImg val, vec, veloc(width,height,depth,dim); if (threed) { CImg G = (alpha>0?get_blur(alpha).get_structure_tensorXYZ():get_structure_tensorXYZ()); if (sigma>0) G.blur(sigma); float I[27]; float& Ippp = I[0]; float& Icpp = I[1]; float& Inpp = I[2]; float& Ipcp = I[3]; float& Iccp = I[4]; float& Incp = I[5]; float& Ipnp = I[6]; float& Icnp = I[7]; float& Innp = I[8]; float& Ippc = I[9]; float& Icpc = I[10]; float& Inpc = I[11]; float& Ipcc = I[12]; float& Iccc = I[13]; float& Incc = I[14]; float& Ipnc = I[15]; float& Icnc = I[16]; float& Innc = I[17]; float& Ippn = I[18]; float& Icpn = I[19]; float& Inpn = I[20]; float& Ipcn = I[21]; float& Iccn = I[22]; float& Incn = I[23]; float& Ipnn = I[24]; float& Icnn = I[25]; float& Innn = I[26]; Ippp = Icpp = Inpp = Ipcp = Iccp = Incp = Ipnp = Icnp = Innp = Ippc = Icpc = Inpc = Ipcc = Iccc = Incc = Ipnc = Icnc = Innc = Ippn = Icpn = Inpn = Ipcn = Iccn = Incn = Ipnn = Icnn = Innn = 0; for (int z = 0; z<(int)((G).depth); ++z) for (int y = 0; y<(int)((G).height); ++y) for (int x = 0; x<(int)((G).width); ++x) { G.get_tensor_at(x,y,z).symmetric_eigen(val,vec); G(x,y,z,0) = vec(0,0); G(x,y,z,1) = vec(0,1); G(x,y,z,2) = vec(0,2); G(x,y,z,3) = 1.0f-(float)std::pow((float)(1+val[0]+val[1]+val[2]),-nedge); } for (int k = 0; k<(int)((*this).dim); ++k) for (int z = 0, _p1z = 0, _n1z = 1>=((*this).depth)?(int)((*this).depth)-1:1; _n1z<(int)((*this).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,_p1z,k)), (I[3] = I[4] = (*this)(0,y,_p1z,k)), (I[6] = I[7] = (*this)(0,_n1y,_p1z,k)), (I[9] = I[10] = (*this)(0,_p1y,z,k)), (I[12] = I[13] = (*this)(0,y,z,k)), (I[15] = I[16] = (*this)(0,_n1y,z,k)), (I[18] = I[19] = (*this)(0,_p1y,_n1z,k)), (I[21] = I[22] = (*this)(0,y,_n1z,k)), (I[24] = I[25] = (*this)(0,_n1y,_n1z,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,_p1z,k)), (I[5] = (*this)(_n1x,y,_p1z,k)), (I[8] = (*this)(_n1x,_n1y,_p1z,k)), (I[11] = (*this)(_n1x,_p1y,z,k)), (I[14] = (*this)(_n1x,y,z,k)), (I[17] = (*this)(_n1x,_n1y,z,k)), (I[20] = (*this)(_n1x,_p1y,_n1z,k)), (I[23] = (*this)(_n1x,y,_n1z,k)), (I[26] = (*this)(_n1x,_n1y,_n1z,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], _p1x = x++, ++_n1x) { const float u = G(x,y,z,0), v = G(x,y,z,1), w = G(x,y,z,2), amp = G(x,y,z,3), ixx = Incc+Ipcc-2*Iccc, ixy = 0.25f*(Innc+Ippc-Inpc-Ipnc), ixz = 0.25f*(Incn+Ipcp-Incp-Ipcn), iyy = Icnc+Icpc-2*Iccc, iyz = 0.25f*(Icnn+Icpp-Icnp-Icpn), izz = Iccn+Iccp-2*Iccc, ixf = Incc-Iccc, ixb = Iccc-Ipcc, iyf = Icnc-Iccc, iyb = Iccc-Icpc, izf = Iccn-Iccc, izb = Iccc-Iccp, itt = u*u*ixx + v*v*iyy + w*w*izz + 2*u*v*ixy + 2*u*w*ixz + 2*v*w*iyz, it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb) + w*cimg::minmod(izf,izb); veloc(x,y,z,k) = -amp*cimg::sign(itt)*cimg::abs(it); } } else { CImg G = (alpha>0?get_blur(alpha).get_structure_tensorXY():get_structure_tensorXY()); if (sigma>0) G.blur(sigma); float I[9]; float& Ipp = I[0]; float& Icp = I[1]; float& Inp = I[2]; float& Ipc = I[3]; float& Icc = I[4]; float& Inc = I[5]; float& Ipn = I[6]; float& Icn = I[7]; float& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; for (int y = 0; y<(int)((G).height); ++y) for (int x = 0; x<(int)((G).width); ++x) { G.get_tensor_at(x,y).symmetric_eigen(val,vec); G(x,y,0) = vec(0,0); G(x,y,1) = vec(0,1); G(x,y,2) = 1.0f-(float)std::pow((float)(1+val[0]+val[1]),-nedge); } for (int k = 0; k<(int)((*this).dim); ++k) for (int y = 0, _p1y = 0, _n1y = 1>=((*this).height)?(int)((*this).height)-1:1; _n1y<(int)((*this).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (I[0] = I[1] = (*this)(0,_p1y,0,k)), (I[3] = I[4] = (*this)(0,y,0,k)), (I[6] = I[7] = (*this)(0,_n1y,0,k)), 1>=(*this).width?(int)((*this).width)-1:1); (_n1x<(int)((*this).width) && ( (I[2] = (*this)(_n1x,_p1y,0,k)), (I[5] = (*this)(_n1x,y,0,k)), (I[8] = (*this)(_n1x,_n1y,0,k)),1)) || x==--_n1x; I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], _p1x = x++, ++_n1x) { const float u = G(x,y,0), v = G(x,y,1), amp = G(x,y,2), ixx = Inc+Ipc-2*Icc, ixy = 0.25f*(Inn+Ipp-Inp-Ipn), iyy = Icn+Icp-2*Icc, ixf = Inc-Icc, ixb = Icc-Ipc, iyf = Icn-Icc, iyb = Icc-Icp, itt = u*u*ixx + v*v*iyy + 2*u*v*ixy, it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb); veloc(x,y,k) = -amp*cimg::sign(itt)*cimg::abs(it); } } float m, M = (float)veloc.maxmin(m); const float vmax = (float)cimg::max(cimg::abs(m),cimg::abs(M)); if (vmax!=0) { veloc*=amplitude/vmax; (*this)+=veloc; } return *this; } CImg::type> get_haar(const char axis, const bool invert=false, const unsigned int nb_scales=1) const { if (is_empty() || !nb_scales) return *this; typedef typename cimg::superset::type ftype; CImg res; if (nb_scales==1) { switch (cimg::uncase(axis)) { case 'x': { const unsigned int w = width/2; if (w) { if (w%2) throw CImgInstanceException("CImg<%s>::haar() : Sub-image width = %u is not even at a particular scale (=%u).",pixel_type(),w); res.assign(width,height,depth,dim); if (invert) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { for (unsigned int x=0, xw=w, x2=0; x::haar() : Sub-image height = %u is not even at a particular scale.",pixel_type(),h); res.assign(width,height,depth,dim); if (invert) for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int x = 0; x<(int)((*this).width); ++x) { for (unsigned int y=0, yh=h, y2=0; y::haar() : Sub-image depth = %u is not even at a particular scale.",pixel_type(),d); res.assign(width,height,depth,dim); if (invert) for (int v = 0; v<(int)((*this).dim); ++v) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { for (unsigned int z=0, zd=d, z2=0; z::haar() : Unknown axis '%c'.",pixel_type(),axis); break; } } else { if (invert) { res.assign(*this); switch (cimg::uncase(axis)) { case 'x': { unsigned int w = width; for (unsigned int s=1; w && s::haar() : Unknown axis '%c'.",pixel_type(),axis); break; } } else { res = get_haar(axis,false,1); switch (cimg::uncase(axis)) { case 'x': { for (unsigned int s=1, w=width/2; w && s::haar() : Unknown axis '%c'.",pixel_type(),axis); break; } } } return res; } CImg& haar(const char axis, const bool invert=false, const unsigned int nb_scales=1) { return get_haar(axis,invert,nb_scales).transfer_to(*this); } CImg::type> get_haar(const bool invert=false, const unsigned int nb_scales=1) const { typedef typename cimg::superset::type ftype; CImg res; if (nb_scales==1) { if (width>1) get_haar('x',invert,1).transfer_to(res); if (height>1) { if (res) res.get_haar('y',invert,1).transfer_to(res); else get_haar('y',invert,1).transfer_to(res); } if (depth>1) { if (res) res.get_haar('z',invert,1).transfer_to(res); else get_haar('z',invert,1).transfer_to(res); } if (res) return res; } else { if (invert) { res.assign(*this); if (width>1) { if (height>1) { if (depth>1) { unsigned int w = width, h = height, d = depth; for (unsigned int s=1; w && h && d && s1) { unsigned int w = width, d = depth; for (unsigned int s=1; w && d && s1) { if (depth>1) { unsigned int h = height, d = depth; for (unsigned int s=1; h && d && s1) { unsigned int d = depth; for (unsigned int s=1; d && s1) { if (height>1) { if (depth>1) for (unsigned int s=1, w=width/2, h=height/2, d=depth/2; w && h && d && s1) for (unsigned int s=1, w=width/2, d=depth/2; w && d && s1) { if (depth>1) for (unsigned int s=1, h=height/2, d=depth/2; h && d && s1) for (unsigned int s=1, d=depth/2; d && s& haar(const bool invert=false, const unsigned int nb_scales=1) { return get_haar(invert,nb_scales).transfer_to(*this); } CImg::type> get_displacement_field(const CImg& target, const float smoothness=0.1f, const float precision=0.1f, const unsigned int nb_scales=0, const unsigned int itermax=10000) const { typedef typename cimg::superset::type ftype; if (is_empty() || !target) return *this; if (!is_sameXYZV(target)) throw CImgArgumentException("CImg<%s>::displacement_field() : Instance image (%u,%u,%u,%u,%p) and target image (%u,%u,%u,%u,%p) " "have different size.",pixel_type(),width,height,depth,dim,data, target.width,target.height,target.depth,target.dim,target.data); if (smoothness<0) throw CImgArgumentException("CImg<%s>::displacement_field() : Smoothness parameter %g is negative.",pixel_type(),smoothness); if (precision<0) throw CImgArgumentException("CImg<%s>::displacement_field() : Precision parameter %g is negative.",pixel_type(),precision); const unsigned int nscales = nb_scales>0?nb_scales:(unsigned int)(2*std::log((double)(cimg::max(width,height,depth)))); ftype m1, M1 = maxmin(m1), m2, M2 = target.maxmin(m2); const ftype factor = cimg::max(cimg::abs(m1),cimg::abs(M1),cimg::abs(m2),cimg::abs(M2)); CImg U0; const bool threed = (depth>1); for (int scale=(int)nscales-1; scale>=0; --scale) { const float sfactor = (float)std::pow(1.5f,(float)scale), sprecision = (float)(precision/std::pow(2.25,1+scale)); const int sw = (int)(width/sfactor), sh = (int)(height/sfactor), sd = (int)(depth/sfactor), swidth = sw?sw:1, sheight = sh?sh:1, sdepth = sd?sd:1; CImg I1 = get_resize(swidth,sheight,sdepth,-100,2), I2 = target.get_resize(swidth,sheight,sdepth,-100,2); I1/=factor; I2/=factor; CImg U; if (U0) U = (U0*=1.5f).get_resize(I1.dimx(),I1.dimy(),I1.dimz(),-100,3); else U.assign(I1.dimx(),I1.dimy(),I1.dimz(),threed?3:2,0); CImg veloc(U); float dt = 2.0f, Energy = cimg::type::max(); const CImgList dI = threed?I2.get_gradientXYZ():I2.get_gradientXY(); for (unsigned int iter=0; iter=((U).depth)?(int)((U).depth)-1:1; _n1z<(int)((U).depth) || z==--_n1z; _p1z = z++, ++_n1z) for (int y = 0, _p1y = 0, _n1y = 1>=((U).height)?(int)((U).height)-1:1; _n1y<(int)((U).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = 1>=((U).width)?(int)((U).width)-1:1; _n1x<(int)((U).width) || x==--_n1x; _p1x = x++, ++_n1x) { const float X = x + U(x,y,z,0), Y = y + U(x,y,z,1), Z = z + U(x,y,z,2); for (int k = 0; k<(int)((U).dim); ++k) { const float Ux = 0.5f*(U(_n1x,y,z,k) - U(_p1x,y,z,k)), Uy = 0.5f*(U(x,_n1y,z,k) - U(x,_p1y,z,k)), Uz = 0.5f*(U(x,y,_n1z,k) - U(x,y,_p1z,k)), Uxx = U(_n1x,y,z,k) + U(_p1x,y,z,k) - 2*U(x,y,z,k), Uyy = U(x,_n1y,z,k) + U(x,_p1y,z,k) - 2*U(x,y,z,k), Uzz = U(x,y,_n1z,k) + U(x,y,_n1z,k) - 2*U(x,y,z,k); nEnergy += smoothness*(Ux*Ux + Uy*Uy + Uz*Uz); float deltaIgrad = 0; for (int i = 0; i<(int)((I1).dim); ++i) { const float deltaIi = (float)(I2.linear_pix3d(X,Y,Z,i) - I1(x,y,z,i)); nEnergy += deltaIi*deltaIi/2; deltaIgrad+=-deltaIi*dI[k].linear_pix3d(X,Y,Z,i); } veloc(x,y,z,k) = deltaIgrad + smoothness*(Uxx + Uyy + Uzz); } } } else { ftype I[9]; ftype& Ipp = I[0]; ftype& Icp = I[1]; ftype& Inp = I[2]; ftype& Ipc = I[3]; ftype& Icc = I[4]; ftype& Inc = I[5]; ftype& Ipn = I[6]; ftype& Icn = I[7]; ftype& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; for (int y = 0, _p1y = 0, _n1y = 1>=((U).height)?(int)((U).height)-1:1; _n1y<(int)((U).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = 1>=((U).width)?(int)((U).width)-1:1; _n1x<(int)((U).width) || x==--_n1x; _p1x = x++, ++_n1x) { const float X = x + U(x,y,0), Y = y + U(x,y,1); for (int k = 0; k<(int)((U).dim); ++k) { const float Ux = 0.5f*(U(_n1x,y,k) - U(_p1x,y,k)), Uy = 0.5f*(U(x,_n1y,k) - U(x,_p1y,k)), Uxx = U(_n1x,y,k) + U(_p1x,y,k) - 2*U(x,y,k), Uyy = U(x,_n1y,k) + U(x,_p1y,k) - 2*U(x,y,k); nEnergy += smoothness*(Ux*Ux + Uy*Uy); float deltaIgrad = 0; for (int i = 0; i<(int)((I1).dim); ++i) { const float deltaIi = (float)(I2.linear_pix2d(X,Y,i) - I1(x,y,i)); nEnergy += deltaIi*deltaIi/2; deltaIgrad+=-deltaIi*dI[k].linear_pix2d(X,Y,i); } veloc(x,y,k) = deltaIgrad + smoothness*(Uxx + Uyy); } } } const float vmax = cimg::max(cimg::abs(veloc.min()), cimg::abs(veloc.max())); U+=(veloc*=dt/vmax); if (cimg::abs(nEnergy-Energy)& displacement_field(const CImg& target, const float smooth=0.1f, const float precision=0.1f, const unsigned int nb_scales=0, const unsigned int itermax=10000) { return get_displacement_field(target,smooth,precision,nb_scales,itermax).transfer_to(*this); } static CImg vector(const T a0) { static CImg r(1,1); r[0] = a0; return r; } static CImg vector(const T a0, const T a1) { static CImg r(1,2); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; return r; } static CImg vector(const T a0, const T a1, const T a2) { static CImg r(1,3); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3) { static CImg r(1,4); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4) { static CImg r(1,5); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5) { static CImg r(1,6); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6) { static CImg r(1,7); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7) { static CImg r(1,8); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8) { static CImg r(1,9); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8, const T a9) { static CImg r(1,10); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8, const T a9, const T a10) { static CImg r(1,11); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8, const T a9, const T a10, const T a11) { static CImg r(1,12); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8, const T a9, const T a10, const T a11, const T a12) { static CImg r(1,13); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8, const T a9, const T a10, const T a11, const T a12, const T a13) { static CImg r(1,14); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8, const T a9, const T a10, const T a11, const T a12, const T a13, const T a14) { static CImg r(1,15); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; return r; } static CImg vector(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8, const T a9, const T a10, const T a11, const T a12, const T a13, const T a14, const T a15) { static CImg r(1,16); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15; return r; } template static CImg vector(const int a0, const int a1, ...) { CImg res(1,N); { unsigned int _siz = (unsigned int)N; if (_siz--) { va_list ap; __builtin_va_start(ap,a1); T *ptrd = (res).data; *(ptrd++) = (T)a0; if (_siz--) { *(ptrd++) = (T)a1; for (; _siz; --_siz) *(ptrd++) = (T)__builtin_va_arg(ap,int); } __builtin_va_end(ap); }}; return res; } template static CImg vector(const double a0, const double a1, ...) { CImg res(1,N); { unsigned int _siz = (unsigned int)N; if (_siz--) { va_list ap; __builtin_va_start(ap,a1); T *ptrd = (res).data; *(ptrd++) = (T)a0; if (_siz--) { *(ptrd++) = (T)a1; for (; _siz; --_siz) *(ptrd++) = (T)__builtin_va_arg(ap,double); } __builtin_va_end(ap); }}; return res; } static CImg matrix(const T a0) { return vector(a0); } static CImg matrix(const T a0, const T a1, const T a2, const T a3) { static CImg r(2,2); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; return r; } static CImg matrix(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8) { static CImg r(3,3); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; return r; } static CImg matrix(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8, const T a9, const T a10, const T a11, const T a12, const T a13, const T a14, const T a15) { static CImg r(4,4); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15; return r; } static CImg matrix(const T a0, const T a1, const T a2, const T a3, const T a4, const T a5, const T a6, const T a7, const T a8, const T a9, const T a10, const T a11, const T a12, const T a13, const T a14, const T a15, const T a16, const T a17, const T a18, const T a19, const T a20, const T a21, const T a22, const T a23, const T a24) { static CImg r(5,5); T *ptr = r.data; *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15; *(ptr++) = a16; *(ptr++) = a17; *(ptr++) = a18; *(ptr++) = a19; *(ptr++) = a20; *(ptr++) = a21; *(ptr++) = a22; *(ptr++) = a23; *(ptr++) = a24; return r; } template static CImg matrix(const int a0, const int a1, ...) { CImg res(M,N); { unsigned int _siz = (unsigned int)M*N; if (_siz--) { va_list ap; __builtin_va_start(ap,a1); T *ptrd = (res).data; *(ptrd++) = (T)a0; if (_siz--) { *(ptrd++) = (T)a1; for (; _siz; --_siz) *(ptrd++) = (T)__builtin_va_arg(ap,int); } __builtin_va_end(ap); }}; return res; } template static CImg matrix(const double a0, const double a1, ...) { CImg res(M,N); { unsigned int _siz = (unsigned int)M*N; if (_siz--) { va_list ap; __builtin_va_start(ap,a1); T *ptrd = (res).data; *(ptrd++) = (T)a0; if (_siz--) { *(ptrd++) = (T)a1; for (; _siz; --_siz) *(ptrd++) = (T)__builtin_va_arg(ap,double); } __builtin_va_end(ap); }}; return res; } static CImg tensor(const T a1) { return matrix(a1); } static CImg tensor(const T a1, const T a2, const T a3) { return matrix(a1,a2,a2,a3); } static CImg tensor(const T a1, const T a2, const T a3, const T a4, const T a5, const T a6) { return matrix(a1,a2,a3,a2,a4,a5,a3,a5,a6); } static CImg diagonal(const T a0) { return matrix(a0); } static CImg diagonal(const T a0, const T a1) { return matrix(a0,0,0,a1); } static CImg diagonal(const T a0, const T a1, const T a2) { return matrix(a0,0,0,0,a1,0,0,0,a2); } static CImg diagonal(const T a0, const T a1, const T a2, const T a3) { return matrix(a0,0,0,0,0,a1,0,0,0,0,a2,0,0,0,0,a3); } static CImg diagonal(const T a0, const T a1, const T a2, const T a3, const T a4) { 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); } template static CImg diagonal(const int a0, ...) { CImg res; if (N>0) { res.assign(N,N,1,1,0); va_list ap; __builtin_va_start(ap,a0); res[0] = (T)a0; for (int i=1; i static CImg diagonal(const double a0, ...) { CImg res; if (N>0) { res.assign(N,N,1,1,0); va_list ap; __builtin_va_start(ap,a0); res[0] = (T)a0; for (int i=1; i identity_matrix(const unsigned int N) { CImg res(N,N,1,1,0); for (int x = 0; x<(int)((res).width); ++x) res(x,x) = 1; return res; } static CImg sequence(const unsigned int N, const T a0, const T a1) { if (N) return CImg(1,N).sequence(a0,a1); return CImg(); } static CImg rotation_matrix(const float x, const float y, const float z, const float w, const bool quaternion_data=false) { float X,Y,Z,W; if (!quaternion_data) { const float norm = (float)std::sqrt(x*x + y*y + z*z), nx = norm>0?x/norm:0, ny = norm>0?y/norm:0, nz = norm>0?z/norm:1, nw = norm>0?w:0, sina = (float)std::sin(nw/2), cosa = (float)std::cos(nw/2); X = nx*sina; Y = ny*sina; Z = nz*sina; W = cosa; } else { const float norm = (float)std::sqrt(x*x + y*y + z*z + w*w); if (norm>0) { X = x/norm; Y = y/norm; Z = z/norm; W = w/norm; } else { X = Y = Z = 0; W = 1; } } 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; return CImg::matrix((T)(1-2*(yy+zz)), (T)(2*(xy+zw)), (T)(2*(xz-yw)), (T)(2*(xy-zw)), (T)(1-2*(xx+zz)), (T)(2*(yz+xw)), (T)(2*(xz+yw)), (T)(2*(yz-xw)), (T)(1-2*(xx+yy))); } CImg get_vector_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const { static CImg dest; if (dest.height!=dim) dest.assign(1,dim); const unsigned int whz = width*height*depth; const T *ptrs = ptr(x,y,z); T *ptrd = dest.data; for (int k = 0; k<(int)((*this).dim); ++k) { *(ptrd++) = *ptrs; ptrs+=whz; } return dest; } template CImg& set_vector_at(const CImg& vec, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) { if (x get_matrix_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const { const int n = (int)std::sqrt((double)dim); CImg dest(n,n); for (int k = 0; k<(int)((*this).dim); ++k) dest[k]=(*this)(x,y,z,k); return dest; } template CImg& set_matrix_at(const CImg& mat, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) { return set_vector_at(mat,x,y,z); } CImg get_tensor_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const { if (dim==6) return tensor((*this)(x,y,z,0),(*this)(x,y,z,1),(*this)(x,y,z,2), (*this)(x,y,z,3),(*this)(x,y,z,4),(*this)(x,y,z,5)); if (dim==3) return tensor((*this)(x,y,z,0),(*this)(x,y,z,1),(*this)(x,y,z,2)); return tensor((*this)(x,y,z,0)); } template CImg& set_tensor_at(const CImg& ten, const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) { if (ten.height==2) { (*this)(x,y,z,0) = (T)ten[0]; (*this)(x,y,z,1) = (T)ten[1]; (*this)(x,y,z,2) = (T)ten[3]; } else { (*this)(x,y,z,0) = (T)ten[0]; (*this)(x,y,z,1) = (T)ten[1]; (*this)(x,y,z,2) = (T)ten[2]; (*this)(x,y,z,3) = (T)ten[4]; (*this)(x,y,z,4) = (T)ten[5]; (*this)(x,y,z,5) = (T)ten[8]; } return *this; } CImg get_vector() const { return get_unroll('y'); } CImg& vector() { return unroll('y'); } CImg get_matrix() const { return (+*this).matrix(); } CImg& matrix() { const unsigned int siz = size(); switch (siz) { case 1: break; case 4: width = height = 2; break; case 9: width = height = 3; break; case 16: width = height = 4; break; case 25: width = height = 5; break; case 36: width = height = 6; break; case 49: width = height = 7; break; case 64: width = height = 8; break; case 81: width = height = 9; break; case 100: width = height = 10; break; default: { unsigned int i = 11, i2 = i*i; while (i2::matrix() : Image size = %u is not a square number",pixel_type(),siz); } break; } return *this; } CImg get_tensor() const { CImg res; const unsigned int siz = size(); switch (siz) { case 1: break; case 3: res.assign(2,2); res(0,0) = (*this)(0); res(1,0) = res(0,1) = (*this)(1); res(1,1) = (*this)(2); break; case 6: res.assign(3,3); res(0,0) = (*this)(0); res(1,0) = res(0,1) = (*this)(1); res(2,0) = res(0,2) = (*this)(2); res(1,1) = (*this)(3); res(2,1) = res(1,2) = (*this)(4); res(2,2) = (*this)(5); break; default: throw CImgInstanceException("CImg<%s>::tensor() : Wrong vector dimension = %u in instance image.", pixel_type(), dim); break; } return res; } CImg& tensor() { return get_tensor().transfer_to(*this); } CImg get_unroll(const char axe='x') const { return (+*this).unroll(axe); } CImg& unroll(const char axe='x') { const unsigned int siz = size(); if (siz) switch (axe) { case 'x': width = siz; height=depth=dim=1; break; case 'y': height = siz; width=depth=dim=1; break; case 'z': depth = siz; width=height=dim=1; break; case 'v': dim = siz; width=height=depth=1; break; default: throw CImgArgumentException("CImg<%s>::unroll() : Given axe is '%c' which is not 'x','y','z' or 'v'", pixel_type(),axe); } return *this; } CImg get_diagonal() const { if (is_empty()) return CImg(); CImg res(size(),size(),1,1,0); for (unsigned int off = 0; off<(*this).size(); ++off) res(off,off) = (*this)(off); return res; } CImg& diagonal() { return get_diagonal().transfer_to(*this); } CImg get_identity_matrix() const { return identity_matrix(cimg::max(width,height)); } CImg& identity_matrix() { return identity_matrix(cimg::max(width,height)).transfer_to(*this); } CImg get_sequence(const T a0, const T a1) const { return (+*this).sequence(a0,a1); } CImg& sequence(const T a0, const T a1) { if (!is_empty()) { const unsigned int siz = size()-1; const float delta = (float)((float)a1-a0); T* ptr = data; for (unsigned int l = 0; l<(*this).size(); ++l) *(ptr++) = (T)(a0 + delta*l/siz); } return *this; } CImg get_transpose() const { return get_permute_axes("yxzv"); } CImg& transpose() { if (width==1) { width=height; height=1; return *this; } if (height==1) { height=width; width=1; return *this; } if (width==height) { for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x=y; x::type> get_invert(const bool use_LU=true) const { typedef typename cimg::superset::type restype; return CImg(*this,false).invert(use_LU); } CImg& invert(const bool use_LU=true) { if (!is_empty()) { if (width!=height || depth!=1 || dim!=1) throw CImgInstanceException("CImg<%s>::invert() : Instance matrix (%u,%u,%u,%u,%p) is not square.", pixel_type(),width,height,depth,dim,data); const double dete = width>3?-1.0:det(); if (dete!=0.0 && width==2) { const double a = data[0], c = data[1], b = data[2], d = data[3]; data[0] = (T)(d/dete); data[1] = (T)(-c/dete); data[2] = (T)(-b/dete); data[3] = (T)(a/dete); } else if (dete!=0.0 && width==3) { const double a = data[0], d = data[1], g = data[2], b = data[3], e = data[4], h = data[5], c = data[6], f = data[7], i = data[8]; data[0] = (T)((i*e-f*h)/dete), data[1] = (T)((g*f-i*d)/dete), data[2] = (T)((d*h-g*e)/dete); data[3] = (T)((h*c-i*b)/dete), data[4] = (T)((i*a-c*g)/dete), data[5] = (T)((g*b-a*h)/dete); data[6] = (T)((b*f-e*c)/dete), data[7] = (T)((d*c-a*f)/dete), data[8] = (T)((a*e-d*b)/dete); } else { typedef typename cimg::superset::type ftype; if (use_LU) { CImg A(*this), indx, col(1,width); bool d; A._LU(indx,d); for (int j = 0; j<(int)((*this).width); ++j) { col.fill(0); col(j) = 1; col._solve(A,indx); for (int i = 0; i<(int)((*this).width); ++i) (*this)(j,i) = (T)col(i); } } else { CImg U(width,width), S(1,width), V(width,width); SVD(U,S,V,false); U.transpose(); for (int k = 0; k<(int)((S).height); ++k) if (S[k]!=0) S[k]=1/S[k]; S.diagonal(); *this = V*S*U; } } } return *this; } CImg::type> get_pseudoinvert() const { typedef typename cimg::superset::type restype; CImg U, S, V; SVD(U,S,V); for (int x = 0; x<(int)((V).width); ++x) { const float s = S(x), invs = s!=0.0f?1.0f/s:0.0f; for (int y = 0; y<(int)((V).height); ++y) V(x,y)*=invs; } return V*U.transpose(); } CImg& pseudoinvert() { return get_pseudoinvert().transfer_to(*this); } template CImg::type> get_cross(const CImg& img) const { typedef typename cimg::superset::type restype; return CImg(*this).cross(img); } template CImg& cross(const CImg& img) { if (width!=1 || height<3 || img.width!=1 || img.height<3) throw CImgInstanceException("CImg<%s>::cross() : Arguments (%u,%u,%u,%u,%p) and (%u,%u,%u,%u,%p) must be both 3d vectors.", pixel_type(),width,height,depth,dim,data,img.width,img.height,img.depth,img.dim,img.data); const T x = (*this)[0], y = (*this)[1], z = (*this)[2]; (*this)[0] = (T)(y*img[2]-z*img[1]); (*this)[1] = (T)(z*img[0]-x*img[2]); (*this)[2] = (T)(x*img[1]-y*img[0]); return *this; } template CImg::type> get_solve(const CImg& A) const { typedef typename cimg::superset2::type restype; return CImg(*this,false).solve(A); } template CImg& solve(const CImg& A) { if (width!=1 || depth!=1 || dim!=1 || height!=A.height || A.depth!=1 || A.dim!=1) throw CImgArgumentException("CImg<%s>::solve() : Instance matrix size is (%u,%u,%u,%u) while " "size of given matrix A is (%u,%u,%u,%u).", pixel_type(),width,height,depth,dim,A.width,A.height,A.depth,A.dim); typedef typename cimg::superset2::type ftype; if (A.width==A.height) { CImg lu(A); CImg indx; bool d; lu._LU(indx,d); _solve(lu,indx); } else assign(A.get_pseudoinvert()*(*this)); return *this; } template CImg& _solve(const CImg& A, const CImg& indx) { typedef typename cimg::superset2::type ftype; const int N = size(); int ii = -1; ftype sum; for (int i=0; i=0) for (int j=ii; j<=i-1; ++j) sum-=A(j,i)*(*this)(j); else if (sum!=0) ii=i; (*this)(i) = (T)sum; } { for (int i=N-1; i>=0; --i) { sum = (*this)(i); for (int j=i+1; j CImg get_sort(CImg& permutations, const bool increasing=true) const { return (+*this).sort(permutations,increasing); } template CImg& sort(CImg& permutations, const bool increasing=true) { if (is_empty()) permutations.assign(); else { if (permutations.size()!=size()) permutations.assign(size()); for (unsigned int off = 0; off<(permutations).size(); ++off) permutations[off] = (t)off; _quicksort(0,size()-1,permutations,increasing); } return *this; } CImg get_sort(const bool increasing=true) const { return (+*this).sort(increasing); } CImg& sort(const bool increasing=true) { CImg foo; return sort(foo,increasing); } template CImg& _quicksort(const int min, const int max, CImg& permutations, const bool increasing) { if (min(*this)[mid]) { cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); } if ((*this)[mid]>(*this)[max]) { cimg::swap((*this)[max],(*this)[mid]); cimg::swap(permutations[max],permutations[mid]); } if ((*this)[min]>(*this)[mid]) { cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); } } else { if ((*this)[min]<(*this)[mid]) { cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); } if ((*this)[mid]<(*this)[max]) { cimg::swap((*this)[max],(*this)[mid]); cimg::swap(permutations[max],permutations[mid]); } if ((*this)[min]<(*this)[mid]) { cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); } } if (max-min>=3) { const T pivot = (*this)[mid]; int i = min, j = max; if (increasing) { do { while ((*this)[i]pivot) --j; if (i<=j) { cimg::swap((*this)[i],(*this)[j]); cimg::swap(permutations[i++],permutations[j--]); } } while (i<=j); } else { do { while ((*this)[i]>pivot) ++i; while ((*this)[j] CImg get_permute(const CImg& permutation) const { if (permutation.size()!=size()) throw CImgArgumentException("CImg<%s>::permute() : Instance image (%u,%u,%u,%u,%p) and permutation (%u,%u,%u,%u,%p)" "have different sizes.",pixel_type(), width,height,depth,dim,data, permutation.width,permutation.height,permutation.depth,permutation.dim,permutation.data); CImg res(width,height,depth,dim); const t *p = permutation.ptr(permutation.size()); for (T *ptr = (res).data + (res).size(); (ptr--)>(res).data; ) *ptr = (*this)[*(--p)]; return res; } template CImg& permute(const CImg& permutation) { return get_permute(permutation).transfer_to(*this); } template const CImg& SVD(CImg& U, CImg& S, CImg& V, const bool sorting=true, const unsigned int max_iter=40, const float lambda=0) const { if (is_empty()) { U.assign(); S.assign(); V.assign(); } else { U = *this; if (lambda!=0.0f) { const unsigned int delta = cimg::min(U.width,U.height); for (unsigned int i=0; i rv1(width); t anorm = 0, c, f, g = 0, h, s, scale = 0; int l = 0, nm = 0; for (int i = 0; i<(int)((U).width); ++i) { l = i+1; rv1[i] = scale*g; g = s = scale = 0; if (i=0?-1:1)*std::sqrt(s)); h=f*g-s; U(i,i) = f-g; for (int j=l; j=0?-1:1)*std::sqrt(s)); h = f*g-s; U(l,i) = f-g; { for (int k=l; k=0; --i) { if (i=0; --i) { l = i+1; g = S[i]; for (int j=l; j=0; --k) { for (unsigned int its=0; its=1; --l) { nm = l-1; if ((cimg::abs(rv1[l])+anorm)==anorm) { flag = false; break; } if ((cimg::abs(S[nm])+anorm)==anorm) break; } if (flag) { c = 0; s = 1; for (int i=l; i<=k; ++i) { f = s*rv1[i]; rv1[i] = c*rv1[i]; if ((cimg::abs(f)+anorm)==anorm) break; g = S[i]; h = (t)cimg::pythagore(f,g); S[i] = h; h = 1/h; c = g*h; s = -f*h; for (int j = 0; j<(int)((U).height); ++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; } } } const t z = S[k]; if (l==k) { if (z<0) { S[k] = -z; for (int j = 0; j<(int)((U).width); ++j) V(k,j) = -V(k,j); } break; } nm = k-1; t x = S[l], y = S[nm]; g = rv1[nm]; h = rv1[k]; f = ((y-z)*(y+z)+(g-h)*(g+h))/(2*h*y); g = (t)cimg::pythagore(f,1.0); f = ((x-z)*(x+z)+h*((y/(f+ (f>=0?g:-g)))-h))/x; c = s = 1; for (int j=l; j<=nm; ++j) { const int i = j+1; g = rv1[i]; h = s*g; g = c*g; t y = S[i]; t z = (t)cimg::pythagore(f,h); rv1[j] = z; c = f/z; s = h/z; f = x*c+g*s; g = g*c-x*s; h = y*s; y*=c; for (int jj = 0; jj<(int)((U).width); ++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; } z = (t)cimg::pythagore(f,h); S[j] = z; if (z) { z = 1/z; c = f*z; s = h*z; } f = c*g+s*y; x = c*y-s*g; { for (int jj = 0; jj<(int)((U).height); ++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; }} } rv1[l] = 0; rv1[k]=f; S[k]=x; } } if (sorting) { CImg permutations(width); CImg tmp(width); S.sort(permutations,false); for (int k = 0; k<(int)((U).height); ++k) { for (int x = 0; x<(int)((permutations).width); ++x) tmp(x) = U(permutations(x),k); std::memcpy(U.ptr(0,k),tmp.data,sizeof(t)*width); } { for (int k = 0; k<(int)((V).height); ++k) { for (int x = 0; x<(int)((permutations).width); ++x) tmp(x) = V(permutations(x),k); std::memcpy(V.ptr(0,k),tmp.data,sizeof(t)*width); }} } } return *this; } template const CImg& SVD(CImgList& USV) const { if (USV.size<3) USV.assign(3); return SVD(USV[0],USV[1],USV[2]); } CImgList::type> get_SVD(const bool sorting=true) const { typedef typename cimg::superset::type restype; CImgList res(3); SVD(res[0],res[1],res[2],sorting); return res; } template CImg& _LU(CImg& indx, bool& d) { typedef typename cimg::superset::type ftype; const int N = dimx(); int imax = 0; CImg vv(N); indx.assign(N); d = true; for (int i = 0; i<(int)((*this).width); ++i) { ftype vmax = 0; for (int j = 0; j<(int)((*this).width); ++j) { const ftype tmp = cimg::abs((*this)(j,i)); if (tmp>vmax) vmax = tmp; } if (vmax==0) { indx.fill(0); return fill(0); } vv[i] = 1/vmax; } for (int j = 0; j<(int)((*this).width); ++j) { for (int i=0; i=vmax) { vmax=tmp; imax=i; } }} if (j!=imax) { for (int k = 0; k<(int)((*this).width); ++k) cimg::swap((*this)(k,imax),(*this)(k,j)); d =!d; vv[imax] = vv[j]; } indx[j] = (t)imax; if ((*this)(j,j)==0) (*this)(j,j) = (T)1e-20; if (j::type> get_eigen() const { typedef typename cimg::superset::type restype; CImgList res(2); eigen(res[0],res[1]); return res; } template const CImg& eigen(CImg& val, CImg &vec) const { if (is_empty()) { val.assign(); vec.assign(); } else { if (width!=height || depth>1 || dim>1) throw CImgInstanceException("CImg<%s>::eigen() : Instance object (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data); if (val.size()::eigen() : Complex eigenvalues",pixel_type()); f = std::sqrt(f); const double l1 = 0.5*(e-f), l2 = 0.5*(e+f); const double theta1 = std::atan2(l2-a,b), theta2 = std::atan2(l1-a,b); val[0]=(t)l2; val[1]=(t)l1; vec(0,0) = (t)std::cos(theta1); vec(0,1) = (t)std::sin(theta1); vec(1,0) = (t)std::cos(theta2); vec(1,1) = (t)std::sin(theta2); } break; default: throw CImgInstanceException("CImg<%s>::eigen() : Eigenvalues computation of general matrices is limited" "to 2x2 matrices (given is %ux%u)", pixel_type(),width,height); } } return *this; } CImgList::type> get_symmetric_eigen() const { typedef typename cimg::superset::type restype; CImgList res(2); symmetric_eigen(res[0],res[1]); return res; } template const CImg& symmetric_eigen(CImg& val, CImg& vec) const { if (is_empty()) { val.assign(); vec.assign(); } else { if (width!=height || depth>1 || dim>1) throw CImgInstanceException("CImg<%s>::eigen() : Instance object (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data); if (val.size() V(width,width); SVD(vec,val,V,false); bool ambiguous = false; float eig = 0; for (int p = 0; p<(int)((val).height); ++p) { if (val[p]>eig) eig = (float)val[p]; t scal = 0; for (int y = 0; y<(int)((vec).height); ++y) scal+=vec(p,y)*V(p,y); if (cimg::abs(scal)<0.9f) ambiguous = true; if (scal<0) val[p] = -val[p]; } if (ambiguous) { (eig*=2)++; SVD(vec,val,V,false,40,eig); val-=eig; } CImg permutations(width); CImg tmp(width); val.sort(permutations,false); for (int k = 0; k<(int)((vec).height); ++k) { for (int x = 0; x<(int)((permutations).width); ++x) tmp(x) = vec(permutations(x),k); std::memcpy(vec.ptr(0,k),tmp.data,sizeof(t)*width); } } return *this; } const CImg& display(CImgDisplay& disp) const { disp.display(*this); return *this; } const CImg& display(const char *const title, const int min_size=128, const int max_size=1024, const int print_flag=1) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::display() : Instance image (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data); CImgDisplay disp; unsigned int w = width+(depth>1?depth:0), h = height+(depth>1?depth:0), XYZ[3]; print(title,print_flag); const unsigned int dmin = cimg::min(w,h), minsiz = min_size>=0?min_size:(-min_size)*dmin/100; if (dmin=0?max_size:(-max_size)*dmax/100; if (dmax>maxsiz) { w=w*maxsiz/dmax; w+=(w==0); h=h*maxsiz/dmax; h+=(h==0); } disp.assign(w,h,title,1,3); XYZ[0] = width/2; XYZ[1] = height/2; XYZ[2] = depth/2; while (!disp.is_closed && !disp.key) get_coordinates(1,disp,XYZ); return *this; } const CImg& display(const int min_size=128, const int max_size=1024, const int print_flag=1) const { char title[256] = { 0 }; std::sprintf(title,"CImg<%s>",pixel_type()); return display(title,min_size,max_size,print_flag); } CImg::type> get_coordinates(const int coords_type, CImgDisplay &disp, unsigned int *const XYZ=0, const unsigned char *const color=0) const { typedef typename cimg::last::type uchar; if (is_empty()) throw CImgInstanceException("CImg<%s>::get_coordinates() : Instance image (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data); const unsigned int old_events = disp.events, old_normalization = disp.normalization, hatch = 0x55555555; bool old_is_resized = disp.is_resized; disp.events = 3; disp.normalization = 0; disp.show().key = 0; unsigned char fgcolor[] = { 255,255,105 }, bgcolor[] = { 0,0,0 }; if (color) std::memcpy(fgcolor,color,sizeof(unsigned char)*cimg::min(3,dimv())); int area = 0, clicked_area = 0, phase = 0, X0 = (int)((XYZ?XYZ[0]:width/2)%width), Y0 = (int)((XYZ?XYZ[1]:height/2)%height), Z0 = (int)((XYZ?XYZ[2]:depth/2)%depth), X1 =-1, Y1 = -1, Z1 = -1, X = -1, Y = -1, Z = -1, oX = X, oY = Y, oZ = Z; unsigned int old_button = 0, key = 0; bool shape_selected = false, text_down = false; CImg visu, visu0; char text[1024] = { 0 }; while (!key && !disp.is_closed && !shape_selected) { oX = X; oY = Y; oZ = Z; int mx = disp.mouse_x, my = disp.mouse_y; const int mX = mx*(width+(depth>1?depth:0))/disp.width, mY = my*(height+(depth>1?depth:0))/disp.height; area = 0; if (mX=dimy()) { area = 2; X = mX; Z = mY-height; Y = phase?Y1:Y0; } if (mX>=dimx() && mY=2) { switch (clicked_area) { case 1: Z1 = Z; break; case 2: Y1 = Y; break; case 3: X1 = X; break; } } if (disp.button&2) { if (phase) { X1 = X; Y1 = Y; Z1 = Z; } else { X0 = X; Y0 = Y; Z0 = Z; } } if (disp.button&4) { oX = X = X0; oY = Y = Y0; oZ = Z = Z0; phase = 0; visu.assign(); } if (disp.wheel) { switch (area) { case 1: if (phase) Z = (Z1+=disp.wheel); else Z = (Z0+=disp.wheel); break; case 2: if (phase) Y = (Y1+=disp.wheel); else Y = (Y0+=disp.wheel); break; case 3: if (phase) X = (X1+=disp.wheel); else X = (X0+=disp.wheel); break; default: break; } disp.wheel = 0; } if ((disp.button&1)!=old_button) { switch (phase++) { case 0: X0 = X1 = X; Y0 = Y1 = Y; Z0 = Z1 = Z; clicked_area = area; break; case 1: X1 = X; Y1 = Y; Z1 = Z; break; default: break; } old_button = disp.button&1; } if (depth>1 && (X!=oX || Y!=oY || Z!=oZ)) visu0.assign(); } if (phase) { if (!coords_type) shape_selected = phase?true:false; else { if (depth>1) shape_selected = (phase==3)?true:false; else shape_selected = (phase==2)?true:false; } } if (X0<0) X0 = 0; if (X0>=dimx()) X0 = dimx()-1; if (Y0<0) Y0 = 0; if (Y0>=dimy()) Y0 = dimy()-1; if (Z0<0) Z0 = 0; if (Z0>=dimz()) Z0 = dimz()-1; if (X1<1) X1 = 0; if (X1>=dimx()) X1 = dimx()-1; if (Y1<0) Y1 = 0; if (Y1>=dimy()) Y1 = dimy()-1; if (Z1<0) Z1 = 0; if (Z1>=dimz()) Z1 = dimz()-1; if (oX!=X || oY!=Y || oZ!=Z || !visu0) { if (!visu0) { typedef typename cimg::superset::type nT; CImg tmp, tmp0; if (depth!=1) { tmp0 = (!phase)?get_projections2d(X0,Y0,Z0):get_projections2d(X1,Y1,Z1); tmp = tmp0.get_channels(0,cimg::min(2U,dim-1)); } else tmp = get_channels(0,cimg::min(2U,dim-1)); switch (old_normalization) { case 0: visu0 = tmp; break; case 3: if (cimg::type::is_float()) visu0 = tmp.normalize(0,(T)255); else { const float m = (float)cimg::type::min(), M = (float)cimg::type::max(); visu0.assign(tmp.width,tmp.height,1,tmp.dim); unsigned char *ptrd = visu0.end(); for (nT *ptrs = (tmp).data + (tmp).size(); (ptrs--)>(tmp).data; ) *(--ptrd) = (unsigned char)((*ptrs-m)*255.0f/(M-m)); } break; default: visu0 = tmp.normalize(0,255); break; } visu0.resize(disp); } visu = visu0; if (!color) { if (visu.mean()<200) { fgcolor[0] = fgcolor[1] = fgcolor[2] = 255; bgcolor[0] = bgcolor[1] = bgcolor[2] = 0; } else { fgcolor[0] = fgcolor[1] = fgcolor[2] = 0; bgcolor[0] = bgcolor[1] = bgcolor[2] = 255; } } const int d = (depth>1)?depth:0; if (phase) switch (coords_type) { case 1: { const int x0 =(int)((X0+0.5f)*disp.width/(width+d)), y0 = (int)((Y0+0.5f)*disp.height/(height+d)), x1 =(int)((X1+0.5f)*disp.width/(width+d)), y1 = (int)((Y1+0.5f)*disp.height/(height+d)); visu.draw_arrow(x0,y0,x1,y1,fgcolor,30.0f,5.0f,1.0f,hatch); if (d) { const int zx0 = (int)((width+Z0+0.5f)*disp.width/(width+d)), zx1 = (int)((width+Z1+0.5f)*disp.width/(width+d)), zy0 = (int)((height+Z0+0.5f)*disp.height/(height+d)), zy1 = (int)((height+Z1+0.5f)*disp.height/(height+d)); 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); } } break; case 2: { const int x0=(X0=visu.dimy()-11) text_down = false; if (!coords_type || !phase) { if (X>=0 && Y>=0 && Z>=0 && X1) std::sprintf(text,"Point (%d,%d,%d)={ ",X,Y,Z); else std::sprintf(text,"Point (%d,%d)={ ",X,Y); char *ctext = text + cimg::strlen(text), *const ltext = text + 512; for (unsigned int k=0; k::format(),cimg::type::format((*this)(X,Y,Z,k))); ctext = text + cimg::strlen(text); *(ctext++) = ' '; *ctext = '\0'; } std::sprintf(text + cimg::strlen(text),"}"); } } else switch (coords_type) { case 1: { const double dX=(double)(X0-X1), dY=(double)(Y0-Y1), dZ=(double)(Z0-Z1), norm = std::sqrt(dX*dX+dY*dY+dZ*dZ); if (depth>1) std::sprintf(text,"Vect (%d,%d,%d)-(%d,%d,%d), norm=%g",X0,Y0,Z0,X1,Y1,Z1,norm); else std::sprintf(text,"Vect (%d,%d)-(%d,%d), norm=%g",X0,Y0,X1,Y1,norm); } break; case 2: if (depth>1) std::sprintf(text,"Box (%d,%d,%d)-(%d,%d,%d), Size=(%d,%d,%d)", X01) std::sprintf(text,"Ellipse (%d,%d,%d)-(%d,%d,%d), Radii=(%d,%d,%d)", X0,Y0,Z0,X1,Y1,Z1,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1),1+cimg::abs(Z0-Z1)); else std::sprintf(text,"Ellipse (%d,%d)-(%d,%d), Radii=(%d,%d)", X0,Y0,X1,Y1,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1)); break; } if (phase || (mx>=0 && my>=0)) visu.draw_text(text,0,text_down?visu.dimy()-11:0,fgcolor,bgcolor,11,0.7f); disp.display(visu).wait(25); } else if (!shape_selected) disp.wait(); if (disp.is_resized) { disp.resize(false); old_is_resized = true; disp.is_resized = false; visu0.assign(); } } typedef typename cimg::last::type restype; CImg res(1,6,1,1,(restype)-1); if (XYZ) { XYZ[0] = (unsigned int)X0; XYZ[1] = (unsigned int)Y0; XYZ[2] = (unsigned int)Z0; } if (shape_selected) { if (coords_type==2) { if (X0>X1) cimg::swap(X0,X1); if (Y0>Y1) cimg::swap(Y0,Y1); if (Z0>Z1) cimg::swap(Z0,Z1); } if (X1<0 || Y1<0 || Z1<0) X0 = Y0 = Z0 = X1 = Y1 = Z1 = -1; switch(coords_type) { case 1: case 2: res[3] = (restype)X1; res[4] = (restype)Y1; res[5] = (restype)Z1; default: res[0] = (restype)X0; res[1] = (restype)Y0; res[2] = (restype)Z0; } } disp.button = 0; disp.events = old_events; disp.normalization = old_normalization; disp.is_resized = old_is_resized; disp.key = key; return res; } CImg::type> get_coordinates(const int coords_type=0, unsigned int *const XYZ=0, const unsigned char *const color=0) const { unsigned int w = width + (depth>1?depth:0), h = height + (depth>1?depth:0); const unsigned int dmin = cimg::min(w,h), minsiz = 256; if (dminmaxsiz) { w=w*maxsiz/dmax; h=h*maxsiz/dmax; } CImgDisplay disp(w,h," ",1,3); return get_coordinates(coords_type,disp,XYZ,color); } CImg& coordinates(const int coords_type=0,unsigned int *const XYZ=0, const unsigned char *const color=0) { return get_coordinates(coords_type,XYZ,color).transfer_to(*this); } template const CImg& display_object3d(const CImg& points, const CImgList& primitives, const CImgList& colors, const CImgList& opacities, CImgDisplay& disp, const bool centering=true, const int render_static=4, const int render_motion=1, const bool double_sided=false, const float focale=500.0f, const float specular_light=0.2f, const float specular_shine=0.1f, const bool display_axes=true, float *const pose_matrix=0) const { if (!points || !primitives || !opacities) throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (%u), primitives (%u) or opacities (%u) are empty.", pixel_type(),points.size()/3,primitives.size,opacities.size); if (is_empty()) return CImg(disp.width,disp.height,1,colors[0].size(),0). display_object3d(points,primitives,colors,opacities,disp,centering, render_static,render_motion,double_sided,focale,specular_light,specular_shine, display_axes,pose_matrix); if (points.height<3) return display_object3d(points.get_resize(-100,3,1,1,0),primitives,colors,opacities,disp, centering,render_static,render_motion,double_sided,focale,specular_light,specular_shine, display_axes,pose_matrix); CImg pose, rot_mat, centered_points = centering?CImg(points.width,3):CImg(), rotated_points(points.width,3), bbox_points, rotated_bbox_points, axes_points, rotated_axes_points; CImgList bbox_opacities, axes_opacities; CImgList bbox_colors, axes_colors; CImgList bbox_primitives, axes_primitives; float dx = 0, dy = 0, dz = 0, ratio = 1; T minval = (T)0, maxval = (T)255; if (disp.normalization) minval = colors.minmax(maxval); const float meanval = (float)mean(); bool color_model = true; if (cimg::abs(meanval-minval)>cimg::abs(meanval-maxval)) color_model = false; const CImg bgcolor(1,1,1,dim,color_model?minval:maxval), fgcolor(1,1,1,dim,color_model?maxval:minval); float xm, xM = (float)points.get_shared_line(0).maxmin(xm), ym, yM = (float)points.get_shared_line(1).maxmin(ym), zm, zM = (float)points.get_shared_line(2).maxmin(zm), delta = cimg::max(xM-xm,yM-ym,zM-zm); if (display_axes) { axes_points.assign(7,3); rotated_axes_points.assign(7,3); axes_opacities.assign(3,1,1,1,1,1.0f); axes_colors.assign(3,dim,1,1,1,fgcolor[0]); axes_points(0,0) = 0; axes_points(0,1) = 0; axes_points(0,2) = 0; axes_points(1,0) = 20; axes_points(1,1) = 0; axes_points(1,2) = 0; axes_points(2,0) = 0; axes_points(2,1) = 20; axes_points(2,2) = 0; axes_points(3,0) = 0; axes_points(3,1) = 0; axes_points(3,2) = 20; axes_points(4,0) = 22; axes_points(4,1) = -6; axes_points(4,2) = 0; axes_points(5,0) = -6; axes_points(5,1) = 22; axes_points(5,2) = 0; axes_points(6,0) = -6; axes_points(6,1) = -6; axes_points(6,2) = 22; axes_primitives.insert(CImg::vector(0,1)); axes_primitives.insert(CImg::vector(0,2)); axes_primitives.insert(CImg::vector(0,3)); } CImg visu0(*this), visu; bool init = true, clicked = false, redraw = true; unsigned int key = 0; int x0 = 0, y0 = 0, x1 = 0, y1 = 0; const unsigned int old_events = disp.events; disp.show().button = disp.key = 0; disp.events = 3; while (!disp.is_closed && !key) { if (init) { ratio = delta>0?(2.0f*cimg::min(disp.width,disp.height)/(3.0f*delta)):0; dx = 0.5f*(xM+xm); dy = 0.5f*(yM+ym); dz = 0.5f*(zM+zm); if (centering) { for (int l = 0; l<(int)((centered_points).width); ++l) { centered_points(l,0) = (float)((points(l,0)-dx)*ratio); centered_points(l,1) = (float)((points(l,1)-dy)*ratio); centered_points(l,2) = (float)((points(l,2)-dz)*ratio); } } if (render_static<0 || render_motion<0) { bbox_colors.assign(12,dim,1,1,1,fgcolor[0]); bbox_primitives.assign(12,1,2); bbox_points.assign(8,3); rotated_bbox_points.assign(8,3); bbox_points(0,0) = xm; bbox_points(0,1) = ym; bbox_points(0,2) = zm; bbox_points(1,0) = xM; bbox_points(1,1) = ym; bbox_points(1,2) = zm; bbox_points(2,0) = xM; bbox_points(2,1) = yM; bbox_points(2,2) = zm; bbox_points(3,0) = xm; bbox_points(3,1) = yM; bbox_points(3,2) = zm; bbox_points(4,0) = xm; bbox_points(4,1) = ym; bbox_points(4,2) = zM; bbox_points(5,0) = xM; bbox_points(5,1) = ym; bbox_points(5,2) = zM; bbox_points(6,0) = xM; bbox_points(6,1) = yM; bbox_points(6,2) = zM; bbox_points(7,0) = xm; bbox_points(7,1) = yM; bbox_points(7,2) = zM; bbox_primitives[0].fill(0,1); bbox_primitives[1].fill(1,2); bbox_primitives[2].fill(2,3); bbox_primitives[3].fill(3,0); bbox_primitives[4].fill(4,5); bbox_primitives[5].fill(5,6); bbox_primitives[6].fill(6,7); bbox_primitives[7].fill(7,4); bbox_primitives[8].fill(0,4); bbox_primitives[9].fill(1,5); bbox_primitives[10].fill(2,6); bbox_primitives[11].fill(3,7); bbox_opacities.assign(bbox_primitives.size,1,1,1,1,1.0f); } if (!pose) { if (pose_matrix) pose = CImg(pose_matrix,4,4,1,1,false); else pose = CImg::identity_matrix(4); } init = false; redraw = true; } if (redraw) { const float r00 = pose(0,0), r10 = pose(1,0), r20 = pose(2,0), r30 = pose(3,0), r01 = pose(0,1), r11 = pose(1,1), r21 = pose(2,1), r31 = pose(3,1), r02 = pose(0,2), r12 = pose(1,2), r22 = pose(2,2), r32 = pose(3,2); if ((clicked && render_motion>=0) || (!clicked && render_static>=0)) { if (centering) for (int l = 0; l<(int)((centered_points).width); ++l) { const float x = centered_points(l,0), y = centered_points(l,1), z = centered_points(l,2); rotated_points(l,0) = r00*x + r10*y + r20*z + r30; rotated_points(l,1) = r01*x + r11*y + r21*z + r31; rotated_points(l,2) = r02*x + r12*y + r22*z + r32; } else for (int l = 0; l<(int)((points).width); ++l) { const float x = (float)points(l,0), y = (float)points(l,1), z = (float)points(l,2); rotated_points(l,0) = r00*x + r10*y + r20*z + r30; rotated_points(l,1) = r01*x + r11*y + r21*z + r31; rotated_points(l,2) = r02*x + r12*y + r22*z + r32; } } else { if (!centering) for (int l = 0; l<(int)((bbox_points).width); ++l) { const float x = bbox_points(l,0), y = bbox_points(l,1), z = bbox_points(l,2); rotated_bbox_points(l,0) = r00*x + r10*y + r20*z + r30; rotated_bbox_points(l,1) = r01*x + r11*y + r21*z + r31; rotated_bbox_points(l,2) = r02*x + r12*y + r22*z + r32; } else for (int l = 0; l<(int)((bbox_points).width); ++l) { const float x = (bbox_points(l,0)-dx)*ratio, y = (bbox_points(l,1)-dy)*ratio, z = (bbox_points(l,2)-dz)*ratio; rotated_bbox_points(l,0) = r00*x + r10*y + r20*z + r30; rotated_bbox_points(l,1) = r01*x + r11*y + r21*z + r31; rotated_bbox_points(l,2) = r02*x + r12*y + r22*z + r32; } } visu = visu0; if ((clicked && render_motion<0) || (!clicked && render_static<0)) visu.draw_object3d(visu.width/2.0f, visu.height/2.0f, 0, rotated_bbox_points,bbox_primitives,bbox_colors,bbox_opacities,1, false,focale,visu.dimx()/2.0f,visu.dimy()/2.0f,-5000.0f,specular_light,0.2f); else visu.draw_object3d(visu.width/2.0f, visu.height/2.0f, 0, rotated_points,primitives,colors,opacities,clicked?render_motion:render_static, double_sided,focale,visu.dimx()/2.0f,visu.dimy()/2.0f,-5000.0f,specular_light,specular_shine); if (display_axes) { const float Xaxes = 25.0f, Yaxes = visu.height-35.0f; for (int l = 0; l<(int)((axes_points).width); ++l) { const float x = axes_points(l,0), y = axes_points(l,1), z = axes_points(l,2); rotated_axes_points(l,0) = r00*x + r10*y + r20*z; rotated_axes_points(l,1) = r01*x + r11*y + r21*z; rotated_axes_points(l,2) = r02*x + r12*y + r22*z; } axes_opacities(0,0) = (rotated_axes_points(1,2)>0)?0.5f:1.0f; axes_opacities(1,0) = (rotated_axes_points(2,2)>0)?0.5f:1.0f; axes_opacities(2,0) = (rotated_axes_points(3,2)>0)?0.5f:1.0f; visu.draw_object3d(Xaxes,Yaxes,0,rotated_axes_points,axes_primitives,axes_colors,axes_opacities,1,false,focale,0,0,0,0). 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)). 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)). 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)); } visu.display(disp); if (!clicked || render_motion==render_static) redraw = false; } disp.wait(); if ((disp.button || disp.wheel) && disp.mouse_x>=0 && disp.mouse_y>=0) { redraw = true; if (!clicked) { x0 = x1 = disp.mouse_x; y0 = y1 = disp.mouse_y; if (!disp.wheel) clicked = true; } else { x1 = disp.mouse_x; y1 = disp.mouse_y; } if (disp.button&1) { const float R = 0.45f*cimg::min(disp.width,disp.height), R2 = R*R, u0 = (float)(x0-disp.dimx()/2), v0 = (float)(y0-disp.dimy()/2), u1 = (float)(x1-disp.dimx()/2), v1 = (float)(y1-disp.dimy()/2), n0 = (float)std::sqrt(u0*u0+v0*v0), n1 = (float)std::sqrt(u1*u1+v1*v1), nu0 = n0>R?(u0*R/n0):u0, nv0 = n0>R?(v0*R/n0):v0, nw0 = (float)std::sqrt(cimg::max(0.0f,R2-nu0*nu0-nv0*nv0)), nu1 = n1>R?(u1*R/n1):u1, nv1 = n1>R?(v1*R/n1):v1, nw1 = (float)std::sqrt(cimg::max(0.0f,R2-nu1*nu1-nv1*nv1)), u = nv0*nw1-nw0*nv1, v = nw0*nu1-nu0*nw1, w = nv0*nu1-nu0*nv1, n = (float)std::sqrt(u*u+v*v+w*w), alpha = (float)std::asin(n/R2); rot_mat = CImg::rotation_matrix(u,v,w,alpha); rot_mat *= pose.get_crop(0,0,2,2); pose.draw_image(rot_mat,0,0); x0=x1; y0=y1; } if (disp.button&2) { pose(3,2)+=(y1-y0); x0 = x1; y0 = y1; } if (disp.wheel) { pose(3,2)-=15*disp.wheel; disp.wheel = 0; } if (disp.button&4) { pose(3,0)+=(x1-x0); pose(3,1)+=(y1-y0); x0 = x1; y0 = y1; } if ((disp.button&1) && (disp.button&2)) { init = true; disp.button = 0; x0 = x1; y0 = y1; pose = CImg::identity_matrix(4); } } else if (clicked) { x0 = x1; y0 = y1; clicked = false; redraw = true; } key = disp.key; if (key && key!=cimg::keyCTRLLEFT && key!=cimg::keyCTRLRIGHT) { if (disp.is_key(cimg::keyCTRLLEFT,true) || disp.is_key(cimg::keyCTRLRIGHT,true)) { switch (key) { case cimg::keyD: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-200,-200); disp.is_resized = true; break; case cimg::keyC: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-50,-50); disp.is_resized = true; break; case cimg::keyR: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(*this); disp.is_resized = true; break; case cimg::keyF: disp.resize(disp.screen_dimx(),disp.screen_dimy()).toggle_fullscreen().is_resized = true; break; case cimg::keyS: { static unsigned int snap_number = 0; char filename[32] = { 0 }; std::FILE *file; do { std::sprintf(filename,"CImg_%.4u.bmp",snap_number++); if ((file=std::fopen(filename,"r"))!=0) std::fclose(file); } while (file); (+visu).draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Saving snapshot...",filename).display(disp); visu.save(filename); visu.draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Snapshot '%s' saved.",filename).display(disp); } break; case cimg::keyO: { static unsigned int snap_number = 0; char filename[32] = { 0 }; std::FILE *file; do { std::sprintf(filename,"CImg_%.4u.off",snap_number++); if ((file=std::fopen(filename,"r"))!=0) std::fclose(file); } while (file); visu.draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Saving object...",filename).display(disp); points.save_off(filename,primitives,colors); visu.draw_text(2,2,fgcolor,bgcolor,11,1.0f,"Object '%s' saved.",filename).display(disp); } break; } disp.key = key = 0; } } else key = 0; if (disp.is_resized) { disp.resize(false); visu0 = get_resize(disp,1); redraw = true; } } if (pose_matrix) std::memcpy(pose_matrix,pose.data,16*sizeof(float)); disp.events = old_events; disp.button = 0; return *this; } template const CImg& display_object3d(const CImgList& points, const CImgList& primitives, const CImgList& colors, const CImgList& opacities, CImgDisplay &disp, const bool centering=true, const int render_static=4, const int render_motion=1, const bool double_sided=false, const float focale=500.0f, const float specular_light=0.2f, const float specular_shine=0.1f, const bool display_axes=true, float *const pose_matrix=0) const { CImg npoints(points.size,3,1,1,0); tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2); for (int l = 0; l<(int)((npoints).width); ++l) { const CImg& point = points[l]; const unsigned int siz = point.size(); if (!siz) throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (size=%u) contains a null element at " "position %u.",pixel_type(),points.size,l); *(ptrZ++) = (siz>2)?point(2):0; *(ptrY++) = (siz>1)?point(1):0; *(ptrX++) = point(0); } return display_object3d(npoints,primitives,colors,opacities,disp,centering, render_static,render_motion,double_sided,focale,specular_light,specular_shine, display_axes,pose_matrix); } template const CImg& display_object3d(const CImg& points, const CImgList& primitives, const CImgList& colors, const CImg& opacities, CImgDisplay& disp, const bool centering=true, const int render_static=4, const int render_motion=1, const bool double_sided=false, const float focale=500.0f, const float specular_light=0.2f, const float specular_shine=0.1f, const bool display_axes=true, float *const pose_matrix=0) const { CImgList nopacities(opacities.size(),1); for (unsigned int l=0; l<(nopacities).size; ++l) nopacities(l,0) = opacities(l); return display_object3d(points,primitives,colors,nopacities,disp,centering, render_static,render_motion,double_sided,focale,specular_light,specular_shine, display_axes,pose_matrix); } template const CImg& display_object3d(const CImgList& points, const CImgList& primitives, const CImgList& colors, const CImg& opacities, CImgDisplay& disp, const bool centering=true, const int render_static=4, const int render_motion=1, const bool double_sided=false, const float focale=500.0f, const float specular_light=0.2f, const float specular_shine=0.1f, const bool display_axes=true, float *const pose_matrix=0) const { CImgList nopacities(opacities.size(),1); for (unsigned int l=0; l<(nopacities).size; ++l) nopacities(l,0) = opacities(l); if (!points) throw CImgArgumentException("CImg<%s>::display_object3d() : Given points are empty.", pixel_type()); CImg npoints(points.size,3,1,1,0); tp *ptrX = npoints.data, *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2); { for (int l = 0; l<(int)((npoints).width); ++l) { const CImg& point = points[l]; const unsigned int siz = point.size(); if (!siz) throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (size=%u) contains a null element at " "position %u.",pixel_type(),points.size,l); *(ptrZ++) = (siz>2)?point(2):0; *(ptrY++) = (siz>1)?point(1):0; *(ptrX++) = point(0); } } return display_object3d(npoints,primitives,colors,nopacities,disp,centering, render_static,render_motion,double_sided,focale,specular_light,specular_shine, display_axes,pose_matrix); } template const CImg& display_object3d(const tp& points, const CImgList& primitives, const CImgList& colors, const to& opacities, const bool centering=true, const int render_static=4, const int render_motion=1, const bool double_sided=false, const float focale=500.0f, const float specular_light=0.2f, const float specular_shine=0.1f, const bool display_axes=true, float *const pose_matrix=0) const { CImgDisplay disp(width,height,0,0); return display_object3d(points,primitives,colors,opacities,disp,centering, render_static,render_motion,double_sided,focale,specular_light,specular_shine, display_axes,pose_matrix); } template const CImg& display_object3d(const tp& points, const CImgList& primitives, const CImgList& colors, const bool centering=true, const int render_static=4, const int render_motion=1, const bool double_sided=false, const float focale=500.0f, const float specular_light=0.2f, const float specular_shine=0.1f, const bool display_axes=true, float *const pose_matrix=0, const float opacity=1.0f) const { CImgDisplay disp(width,height," ",0); return display_object3d(points,primitives,colors,CImg::vector(opacity), disp,centering,render_static,render_motion,double_sided, focale,specular_light,specular_shine,display_axes,pose_matrix); } template const CImg& display_object3d(const tp& points, const CImgList& primitives, const CImgList& colors, CImgDisplay &disp, const bool centering=true, const int render_static=4, const int render_motion=1, const bool double_sided=false, const float focale=500.0f, const float specular_light=0.2f, const float specular_shine=0.1f, const bool display_axes=true, float *const pose_matrix=0, const float opacity=1.0f) const { return display_object3d(points,primitives,colors,CImg::vector(opacity), disp,centering,render_static,render_motion,double_sided, focale,specular_light,specular_shine,display_axes,pose_matrix); } static CImg get_load(const char *const filename) { return CImg().load(filename); } CImg& load(const char *const filename) { const char *ext = cimg::filename_split(filename); if (!cimg::strncasecmp(ext,"asc",3)) return load_ascii(filename); if (!cimg::strncasecmp(ext,"dlm",3) || !cimg::strncasecmp(ext,"txt",3)) return load_dlm(filename); if (!cimg::strncasecmp(ext,"inr",3)) return load_inr(filename); if (!cimg::strncasecmp(ext,"hdr",3) || !cimg::strncasecmp(ext,"nii",3)) return load_analyze(filename); if (!cimg::strncasecmp(ext,"par",3) || !cimg::strncasecmp(ext,"rec",3)) return load_parrec(filename); if (!cimg::strncasecmp(ext,"pan",3)) return load_pandore(filename); if (!cimg::strncasecmp(ext,"bmp",3)) return load_bmp(filename); if (!cimg::strncasecmp(ext,"png",3)) return load_png(filename); if (!cimg::strncasecmp(ext,"tif",3)) return load_tiff(filename); if (!cimg::strncasecmp(ext,"jpg",3) || !cimg::strncasecmp(ext,"jpeg",4)) return load_jpeg(filename); if (!cimg::strncasecmp(ext,"ppm",3) || !cimg::strncasecmp(ext,"pgm",3) || !cimg::strncasecmp(ext,"pnm",3)) return load_pnm(filename); if (!cimg::strncasecmp(ext,"cimg",4) || ext[0]=='\0') return load_cimg(filename); if (!cimg::strncasecmp(ext,"dcm",3) || !cimg::strncasecmp(ext,"dicom",5)) return load_dicom(filename); if (!cimg::strncasecmp(ext,"avi",3) || !cimg::strncasecmp(ext,"mov",3) || !cimg::strncasecmp(ext,"mpg",3) || !cimg::strncasecmp(ext,"mpeg",4)) return load_ffmpeg(filename); return load_other(filename); } static CImg get_load_ascii(std::FILE *const file, const char *const filename=0) { return CImg().load_ascii(file,filename); } CImg& load_ascii(std::FILE *const file, const char *const filename=0) { std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); char line[256] = { 0 }; std::fscanf(nfile,"%255[^\n]",line); unsigned int off, dx = 0, dy = 1, dz = 1, dv = 1; int err = 1; std::sscanf(line,"%u %u %u %u",&dx,&dy,&dz,&dv); if (!dx || !dy || !dz || !dv) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_ascii() : File '%s' is not a valid .ASC file.\n" "Specified image dimensions are (%u,%u,%u,%u).", pixel_type(),filename?filename:"(FILE*)",dx,dy,dz,dv); } assign(dx,dy,dz,dv); const unsigned int siz = size(); double val; T *ptr = data; for (off=0; off::load_ascii() : File '%s', only %u/%u values read.", pixel_type(),filename?filename:"(FILE*)",off,siz); if (!file) cimg::fclose(nfile); return *this; } static CImg get_load_ascii(const char *const filename) { return CImg().load_ascii(0,filename); } CImg& load_ascii(const char *const filename) { return load_ascii(0,filename); } static CImg get_load_dlm(std::FILE *const file, const char *const filename=0) { return CImg().load_dlm(file,filename); } CImg& load_dlm(std::FILE *const file, const char *const filename=0) { std::FILE *const nfile = file?file:cimg::fopen(filename,"r"); assign(256,256); char c, delimiter[256] = { 0 }, tmp[256]; unsigned int cdx = 0, dx = 0, dy = 0; int oerr = 0, err; double val; while ((err = std::fscanf(nfile,"%lf%255[^0-9.eE+-]",&val,delimiter))!=(-1)) { oerr = err; if (err>0) (*this)(cdx++,dy) = (T)val; if (cdx>=width) resize(width+256,1,1,1,0); c = 0; if (!std::sscanf(delimiter,"%255[^\n]%c",tmp,&c) || c=='\n') { dx = cimg::max(cdx,dx); ++dy; if (dy>=height) resize(width,height+256,1,1,0); cdx = 0; } } if (cdx && oerr==1) { dx=cdx; ++dy; } if (!dx || !dy) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_dlm() : File '%s' is not a valid DLM file.\n" "Specified image dimensions are (%u,%u).", pixel_type(),filename?filename:"(FILE*)",dx,dy); } resize(dx,dy,1,1,0); if (!file) cimg::fclose(nfile); return *this; } static CImg get_load_dlm(const char *const filename) { return CImg().load_dlm(0,filename); } CImg& load_dlm(const char *const filename) { return load_dlm(0,filename); } static CImg get_load_pnm(std::FILE *const file, const char *const filename=0) { return CImg().load_pnm(file, filename); } CImg& load_pnm(std::FILE *const file, const char *const filename=0) { std::FILE *const nfile=file?file:cimg::fopen(filename,"rb"); unsigned int ppm_type, W, H, colormax=255; char item[1024] = { 0 }; int err, rval, gval, bval; const int cimg_iobuffer = 12*1024*1024; while ((err=std::fscanf(nfile,"%1023[^\n]",item))!=(-1) && (item[0]=='#' || !err)) std::fgetc(nfile); if(std::sscanf(item," P%u",&ppm_type)!=1) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_pnm() : File '%s', PNM header 'P?' not found.", pixel_type(),filename?filename:"(FILE*)"); } while ((err=std::fscanf(nfile," %1023[^\n]",item))!=(-1) && (item[0]=='#' || !err)) std::fgetc(nfile); if ((err=std::sscanf(item," %u %u %u",&W,&H,&colormax))<2) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_pnm() : File '%s', WIDTH and HEIGHT fields are not defined in PNM header.", pixel_type(),filename?filename:"(FILE*)"); } if (err==2) { while ((err=std::fscanf(nfile," %1023[^\n]",item))!=(-1) && (item[0]=='#' || !err)) std::fgetc(nfile); if (std::sscanf(item,"%u",&colormax)!=1) cimg::warn("CImg<%s>::load_pnm() : File '%s', COLORMAX field is not defined in PNM header.", pixel_type(),filename?filename:"(FILE*)"); } std::fgetc(nfile); assign(); switch (ppm_type) { case 2: { assign(W,H,1,1); T* rdata = data; for (unsigned int off = 0; off<(*this).size(); ++off) { std::fscanf(nfile,"%d",&rval); *(rdata++) = (T)rval; } } break; case 3: { assign(W,H,1,3); T *rdata = ptr(0,0,0,0), *gdata = ptr(0,0,0,1), *bdata = ptr(0,0,0,2); for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { std::fscanf(nfile,"%d %d %d",&rval,&gval,&bval); *(rdata++) = (T)rval; *(gdata++) = (T)gval; *(bdata++) = (T)bval; } } break; case 5: { if (colormax<256) { CImg raw; assign(W,H,1,1); T *ptrd = ptr(0,0,0,0); for (int toread = (int)size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); toread-=raw.width; const unsigned char *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } else { CImg raw; assign(W,H,1,1); T *ptrd = ptr(0,0,0,0); for (int toread = (int)size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer/2)); cimg::fread(raw.data,raw.width,nfile); toread-=raw.width; const unsigned short *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } break; case 6: { if (colormax<256) { CImg raw; assign(W,H,1,3); T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1), *ptr_b = ptr(0,0,0,2); for (int toread = (int)size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); toread-=raw.width; const unsigned char *ptrs = raw.data; for (unsigned int off = raw.width/3; off; --off) { *(ptr_r++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_b++) = (T)*(ptrs++); } } } else { CImg raw; assign(W,H,1,3); T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1), *ptr_b = ptr(0,0,0,2); for (int toread = (int)size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer/2)); cimg::fread(raw.data,raw.width,nfile); if (!cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const unsigned short *ptrs = raw.data; for (unsigned int off = raw.width/3; off; --off) { *(ptr_r++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_b++) = (T)*(ptrs++); } } } } break; default: if (!file) cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_pnm() : File '%s', PPM type 'P%d' not supported.", pixel_type(),filename?filename:"(FILE*)",ppm_type); } if (!file) cimg::fclose(nfile); return *this; } static CImg get_load_pnm(const char *const filename) { return get_load_pnm(0,filename); } CImg& load_pnm(const char *const filename) { return load_pnm(0,filename); } static CImg get_load_bmp(std::FILE *const file, const char *const filename=0) { return CImg().load_bmp(file,filename); } CImg& load_bmp(std::FILE *const file, const char *const filename=0) { std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); unsigned char header[64]; cimg::fread(header,54,nfile); if (header[0]!='B' || header[1]!='M') { if (!file) cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_bmp() : File '%s' is not a valid BMP file.", pixel_type(),filename?filename:"(FILE*)"); } assign(); int file_size = header[0x02] + (header[0x03]<<8) + (header[0x04]<<16) + (header[0x05]<<24), offset = header[0x0A] + (header[0x0B]<<8) + (header[0x0C]<<16) + (header[0x0D]<<24), dx = header[0x12] + (header[0x13]<<8) + (header[0x14]<<16) + (header[0x15]<<24), dy = header[0x16] + (header[0x17]<<8) + (header[0x18]<<16) + (header[0x19]<<24), compression = header[0x1E] + (header[0x1F]<<8) + (header[0x20]<<16) + (header[0x21]<<24), nb_colors = header[0x2E] + (header[0x2F]<<8) + (header[0x30]<<16) + (header[0x31]<<24), bpp = header[0x1C] + (header[0x1D]<<8), *palette = 0; const int dx_bytes = (bpp==1)?(dx/8+(dx%8?1:0)):((bpp==4)?(dx/2+(dx%2?1:0)):(dx*bpp/8)), align = (4-dx_bytes%4)%4, buf_size = cimg::min(cimg::abs(dy)*(dx_bytes+align),file_size-offset); if (bpp<16) { if (!nb_colors) nb_colors=1<0) std::fseek(nfile,xoffset,1); unsigned char *buffer = new unsigned char[buf_size], *ptrs = buffer; cimg::fread(buffer,buf_size,nfile); if (!file) cimg::fclose(nfile); if (compression) { delete[] buffer; if (file) { throw CImgIOException("CImg<%s>::load_bmp() : Not able to read a compressed BMP file using a *FILE input",pixel_type()); } else return load_other(filename); } assign(dx,cimg::abs(dy),1,3); switch (bpp) { case 1: { for (int y=height-1; y>=0; --y) { unsigned char mask = 0x80, val = 0; for (int x = 0; x<(int)((*this).width); ++x) { if (mask==0x80) val = *(ptrs++); const unsigned char *col = (unsigned char*)(palette+(val&mask?1:0)); (*this)(x,y,2) = (T)*(col++); (*this)(x,y,1) = (T)*(col++); (*this)(x,y,0) = (T)*(col++); mask = cimg::ror(mask); } ptrs+=align; } } break; case 4: { for (int y=height-1; y>=0; --y) { unsigned char mask = 0xF0, val = 0; for (int x = 0; x<(int)((*this).width); ++x) { if (mask==0xF0) val = *(ptrs++); const unsigned char color = (unsigned char)((mask<16)?(val&mask):((val&mask)>>4)); unsigned char *col = (unsigned char*)(palette+color); (*this)(x,y,2) = (T)*(col++); (*this)(x,y,1) = (T)*(col++); (*this)(x,y,0) = (T)*(col++); mask = cimg::ror(mask,4); } ptrs+=align; } } break; case 8: { for (int y=height-1; y>=0; --y) { for (int x = 0; x<(int)((*this).width); ++x) { const unsigned char *col = (unsigned char*)(palette+*(ptrs++)); (*this)(x,y,2) = (T)*(col++); (*this)(x,y,1) = (T)*(col++); (*this)(x,y,0) = (T)*(col++); } ptrs+=align; } } break; case 16: { for (int y=height-1; y>=0; --y) { for (int x = 0; x<(int)((*this).width); ++x) { const unsigned char c1 = *(ptrs++), c2 = *(ptrs++); const unsigned short col = (unsigned short)(c1|(c2<<8)); (*this)(x,y,2) = (T)(col&0x1F); (*this)(x,y,1) = (T)((col>>5)&0x1F); (*this)(x,y,0) = (T)((col>>10)&0x1F); } ptrs+=align; } } break; case 24: { for (int y=height-1; y>=0; --y) { for (int x = 0; x<(int)((*this).width); ++x) { (*this)(x,y,2) = (T)*(ptrs++); (*this)(x,y,1) = (T)*(ptrs++); (*this)(x,y,0) = (T)*(ptrs++); } ptrs+=align; } } break; case 32: { for (int y=height-1; y>=0; --y) { for (int x = 0; x<(int)((*this).width); ++x) { (*this)(x,y,2) = (T)*(ptrs++); (*this)(x,y,1) = (T)*(ptrs++); (*this)(x,y,0) = (T)*(ptrs++); ++ptrs; } ptrs+=align; } } break; } if (palette) delete[] palette; delete[] buffer; if (dy<0) mirror('y'); return *this; } static CImg get_load_bmp(const char *const filename) { return CImg().load_bmp(0,filename); } CImg& load_bmp(const char *const filename) { return load_bmp(0,filename); } static CImg get_load_png(std::FILE *const file, const char *const filename=0) { return CImg().load_png(file,filename); } CImg& load_png(std::FILE *const file, const char *const filename=0) { if (file) throw CImgIOException("CImg<%s>::load_png() : File '(FILE*)' cannot be read without using libpng.",pixel_type()); else return load_other(filename); } static CImg get_load_png(const char *const filename) { return CImg().load_png(0,filename); } CImg& load_png(const char *const filename) { return load_png(0,filename); } static CImg get_load_tiff(const char *const filename, const unsigned int first_frame=0, const unsigned int last_frame=~0U) { return CImg().load_tiff(filename,first_frame,last_frame); } CImg& load_tiff(const char *const filename, const unsigned int first_frame=0, const unsigned int last_frame=~0U) { if (first_frame>last_frame) throw CImgArgumentException("CImg<%s>::load_tiff() : File '%s', specified first frame = %u is higher than last frame = %u.", pixel_type(),first_frame,last_frame); if (first_frame || last_frame!=~0U) throw CImgArgumentException("CImg<%s>::load_tiff() : File '%s', reading sub-images from a tiff file requires the use of libtiff.\n" "('cimg_use_tiff' must be defined).",pixel_type(),filename); return load_other(filename); } static CImg get_load_jpeg(std::FILE *const file, const char *const filename=0) { return CImg().load_jpeg(file,filename); } CImg& load_jpeg(std::FILE *const file, const char *const filename=0) { if (file) throw CImgIOException("CImg<%s>::load_jpeg() : File '(FILE*)' cannot be read without using libjpeg.", pixel_type()); else return load_other(filename); } static CImg get_load_jpeg(const char *const filename) { return CImg().load_jpeg(0,filename); } CImg& load_jpeg(const char *const filename) { return load_jpeg(0,filename); } static CImg get_load_magick(const char *const filename) { return CImg().load_magick(filename); } CImg& load_magick(const char *const filename) { throw CImgIOException("CImg<%s>::load_magick() : File '%s', Magick++ has not been linked during compilation.", pixel_type(),filename?filename:"(null)"); return *this; } static CImg get_load_raw(std::FILE *const file, const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int sizez=1, const unsigned int sizev=1, const bool multiplexed=false, const bool endian_swap=false) { return CImg().load_raw(file,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap); } CImg& load_raw(std::FILE *const file, const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int sizez=1, const unsigned int sizev=1, const bool multiplexed = false, const bool endian_swap = false) { assign(sizex,sizey,sizez,sizev,0); const unsigned int siz = size(); if (siz) { std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); if (!multiplexed) { cimg::fread(data,siz,nfile); if (endian_swap) cimg::endian_swap(data,siz); } else { CImg buf(1,1,1,sizev); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { cimg::fread(buf.data,sizev,nfile); if (endian_swap) cimg::endian_swap(buf.data,sizev); set_vector_at(buf,x,y,z); } } if (!file) cimg::fclose(nfile); } return *this; } static CImg get_load_raw(const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int sizez=1, const unsigned int sizev=1, const bool multiplexed = false, const bool endian_swap = false) { return CImg().load_raw(0,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap); } CImg& load_raw(const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int sizez=1, const unsigned int sizev=1, const bool multiplexed = false, const bool endian_swap = false) { return load_raw(0,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap); } static CImg get_load_rgba(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) { return CImg().load_rgba(file,filename,dimw,dimh); } CImg& load_rgba(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) { const int cimg_iobuffer = 12*1024*1024; std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); CImg raw; assign(dimw,dimh,1,4); 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); for (int toread = (int)size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); toread-=raw.width; const unsigned char *ptrs = raw.data; for (unsigned int off = raw.width/4; off; --off) { *(ptr_r++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_b++) = (T)*(ptrs++); *(ptr_a++) = (T)*(ptrs++); } } if (!file) cimg::fclose(nfile); return *this; } static CImg get_load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh) { return CImg().load_rgba(0,filename,dimw,dimh); } CImg& load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh) { return load_rgba(0,filename,dimw,dimh); } static CImg get_load_rgb(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) { return CImg().load_rgb(file,filename,dimw,dimh); } CImg& load_rgb(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) { const int cimg_iobuffer = 12*1024*1024; std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); CImg raw; assign(dimw,dimh,1,3); T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1), *ptr_b = ptr(0,0,0,2); for (int toread = (int)size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); toread-=raw.width; const unsigned char *ptrs = raw.data; for (unsigned int off = raw.width/3; off; --off) { *(ptr_r++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_b++) = (T)*(ptrs++); } } if (!file) cimg::fclose(nfile); return *this; } static CImg get_load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh) { return CImg().load_rgb(0,filename,dimw,dimh); } CImg& load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh) { return load_rgb(0,filename,dimw,dimh); } static CImg get_load_inr(std::FILE *const file, const char *const filename=0, float *voxsize=0) { return CImg().load_inr(file,filename,voxsize); } CImg& load_inr(std::FILE *const file, const char *const filename=0, float *const voxsize=0) { std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); int fopt[8], endian=cimg::endian()?1:0; bool loaded = false; if (voxsize) voxsize[0]=voxsize[1]=voxsize[2]=1; _load_inr(nfile,fopt,voxsize); assign(fopt[0],fopt[1],fopt[2],fopt[3]); if (!loaded && fopt[6]==8 && fopt[4]==0 && fopt[5]==0) { unsigned char *xval, *val = new unsigned char[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded && fopt[6]==8 && fopt[4]==0 && fopt[5]==1) { char *xval, *val = new char[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded && fopt[6]==16 && fopt[4]==0 && fopt[5]==0) { unsigned short *xval, *val = new unsigned short[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded && fopt[6]==16 && fopt[4]==0 && fopt[5]==1) { short *xval, *val = new short[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded && fopt[6]==32 && fopt[4]==0 && fopt[5]==0) { unsigned int *xval, *val = new unsigned int[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded && fopt[6]==32 && fopt[4]==0 && fopt[5]==1) { int *xval, *val = new int[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded && fopt[6]==32 && fopt[4]==1 && fopt[5]==0) { float *xval, *val = new float[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded && fopt[6]==32 && fopt[4]==1 && fopt[5]==1) { float *xval, *val = new float[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded && fopt[6]==64 && fopt[4]==1 && fopt[5]==0) { double *xval, *val = new double[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded && fopt[6]==64 && fopt[4]==1 && fopt[5]==1) { double *xval, *val = new double[fopt[0]*fopt[3]]; for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { cimg::fread(val,fopt[0]*fopt[3],nfile); if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); xval = val; for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) (*this)(x,y,z,k) = (T)*(xval++); } delete[] val; loaded = true; }; if (!loaded) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_inr() : File '%s', cannot read images of the type specified in the file", pixel_type(),filename?filename:"(FILE*)"); } if (!file) cimg::fclose(nfile); return *this; } static void _load_inr(std::FILE *file, int out[8], float *const voxsize=0) { char item[1024], tmp1[64], tmp2[64]; out[0] = out[1] = out[2] = out[3] = out[5] = 1; out[4] = out[6] = out[7] = -1; std::fscanf(file,"%63s",item); if(cimg::strncasecmp(item,"#INRIMAGE-4#{",13)!=0) throw CImgIOException("CImg<%s>::load_inr() : File does not appear to be a valid INR file.\n" "(INRIMAGE-4 identifier not found)",pixel_type()); while (std::fscanf(file," %63[^\n]%*c",item)!=(-1) && cimg::strncmp(item,"##}",3)) { std::sscanf(item," XDIM%*[^0-9]%d",out); std::sscanf(item," YDIM%*[^0-9]%d",out+1); std::sscanf(item," ZDIM%*[^0-9]%d",out+2); std::sscanf(item," VDIM%*[^0-9]%d",out+3); std::sscanf(item," PIXSIZE%*[^0-9]%d",out+6); if (voxsize) { std::sscanf(item," VX%*[^0-9.eE+-]%f",voxsize); std::sscanf(item," VY%*[^0-9.eE+-]%f",voxsize+1); std::sscanf(item," VZ%*[^0-9.eE+-]%f",voxsize+2); } if (std::sscanf(item," CPU%*[ =]%s",tmp1)) out[7]=cimg::strncasecmp(tmp1,"sun",3)?0:1; switch(std::sscanf(item," TYPE%*[ =]%s %s",tmp1,tmp2)) { case 0: break; case 2: out[5] = cimg::strncasecmp(tmp1,"unsigned",8)?1:0; std::strcpy(tmp1,tmp2); case 1: if (!cimg::strncasecmp(tmp1,"int",3) || !cimg::strncasecmp(tmp1,"fixed",5)) out[4] = 0; if (!cimg::strncasecmp(tmp1,"float",5) || !cimg::strncasecmp(tmp1,"double",6)) out[4] = 1; if (!cimg::strncasecmp(tmp1,"packed",6)) out[4] = 2; if (out[4]>=0) break; default: throw CImgIOException("cimg::inr_header_read() : Invalid TYPE '%s'",tmp2); } } if(out[0]<0 || out[1]<0 || out[2]<0 || out[3]<0) throw CImgIOException("CImg<%s>::load_inr() : Bad dimensions in .inr file = ( %d , %d , %d , %d )", pixel_type(),out[0],out[1],out[2],out[3]); if(out[4]<0 || out[5]<0) throw CImgIOException("CImg<%s>::load_inr() : TYPE is not fully defined",pixel_type()); if(out[6]<0) throw CImgIOException("CImg<%s>::load_inr() : PIXSIZE is not fully defined",pixel_type()); if(out[7]<0) throw CImgIOException("CImg<%s>::load_inr() : Big/Little Endian coding type is not defined",pixel_type()); } static CImg get_load_inr(const char *const filename, float *const voxsize=0) { return CImg().load_inr(0,filename,voxsize); } CImg& load_inr(const char *const filename, float *const voxsize=0) { return load_inr(0,filename,voxsize); } static CImg get_load_pandore(std::FILE *const file, const char *const filename=0) { return CImg().load_pandore(file,filename); } CImg& load_pandore(std::FILE *const file, const char *const filename) { std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; char tmp[32]; cimg::fread(tmp,12,nfile); if (cimg::strncasecmp("PANDORE",tmp,7)) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_pandore() : File '%s' is not a valid PANDORE file.\n" "(PANDORE identifier not found).",pixel_type(),filename?filename:"(FILE*)"); } unsigned int imageid,dims[8]; int ptbuf[4]; cimg::fread(&imageid,1,nfile); const bool endian = (imageid>255); if (endian) cimg::endian_swap(imageid); cimg::fread(tmp,20,nfile); switch (imageid) { case 2: { cimg::fread(dims,2,nfile); if (endian) cimg::endian_swap(dims,2); assign(dims[1],1,1,1); const unsigned int siz = size(); uchar *buffer = new uchar[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 3: { cimg::fread(dims,2,nfile); if (endian) cimg::endian_swap(dims,2); assign(dims[1],1,1,1); const unsigned int siz = size(); long *buffer = new long[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 4: { cimg::fread(dims,2,nfile); if (endian) cimg::endian_swap(dims,2); assign(dims[1],1,1,1); const unsigned int siz = size(); float *buffer = new float[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 5: { cimg::fread(dims,3,nfile); if (endian) cimg::endian_swap(dims,3); assign(dims[2],dims[1],1,1); const unsigned int siz = size(); uchar *buffer = new uchar[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 6: { cimg::fread(dims,3,nfile); if (endian) cimg::endian_swap(dims,3); assign(dims[2],dims[1],1,1); const unsigned int siz = size(); long *buffer = new long[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 7: { cimg::fread(dims,3,nfile); if (endian) cimg::endian_swap(dims,3); assign(dims[2],dims[1],1,1); const unsigned int siz = size(); float *buffer = new float[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 8: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[3],dims[2],dims[1],1); const unsigned int siz = size(); uchar *buffer = new uchar[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 9: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[3],dims[2],dims[1],1); const unsigned int siz = size(); long *buffer = new long[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 10: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[3],dims[2],dims[1],1); const unsigned int siz = size(); float *buffer = new float[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 11: { cimg::fread(dims,3,nfile); if (endian) cimg::endian_swap(dims,3); assign(dims[1],1,1,1); const unsigned siz = size(); if (dims[2]<256) { unsigned char *buffer = new unsigned char[siz]; cimg::fread(buffer,siz,nfile); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } else { if (dims[2]<65536) { unsigned short *buffer = new unsigned short[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } else { unsigned int *buffer = new unsigned int[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } } } break; case 12: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[2],dims[1],1,1); const unsigned int siz = size(); if (dims[3]<256) { unsigned char *buffer = new unsigned char[siz]; cimg::fread(buffer,siz,nfile); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } else { if (dims[3]<65536) { unsigned short *buffer = new unsigned short[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } else { unsigned long *buffer = new unsigned long[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } } } break; case 13: { cimg::fread(dims,5,nfile); if (endian) cimg::endian_swap(dims,5); assign(dims[3],dims[2],dims[1],1); const unsigned int siz = size(); if (dims[4]<256) { unsigned char *buffer = new unsigned char[siz]; cimg::fread(buffer,siz,nfile); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } else { if (dims[4]<65536) { unsigned short *buffer = new unsigned short[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } else { unsigned int *buffer = new unsigned int[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } } } break; case 16: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[2],dims[1],1,3); const unsigned int siz = size(); uchar *buffer = new uchar[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 17: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[2],dims[1],1,3); const unsigned int siz = size(); long *buffer = new long[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 18: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[2],dims[1],1,3); const unsigned int siz = size(); float *buffer = new float[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 19: { cimg::fread(dims,5,nfile); if (endian) cimg::endian_swap(dims,5); assign(dims[3],dims[2],dims[1],3); const unsigned int siz = size(); uchar *buffer = new uchar[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 20: { cimg::fread(dims,5,nfile); if (endian) cimg::endian_swap(dims,5); assign(dims[3],dims[2],dims[1],3); const unsigned int siz = size(); long *buffer = new long[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 21: { cimg::fread(dims,5,nfile); if (endian) cimg::endian_swap(dims,5); assign(dims[3],dims[2],dims[1],3); const unsigned int siz = size(); float *buffer = new float[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 22: { cimg::fread(dims,2,nfile); if (endian) cimg::endian_swap(dims,2); assign(dims[1],1,1,dims[0]); const unsigned int siz = size(); uchar *buffer = new uchar[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 23: { cimg::fread(dims,2,nfile); if (endian) cimg::endian_swap(dims,2); assign(dims[1],1,1,dims[0]); const unsigned int siz = size(); long *buffer = new long[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 24: { cimg::fread(dims,2,nfile); if (endian) cimg::endian_swap(dims,2); assign(dims[1],1,1,dims[0]); const unsigned int siz = size(); ulong *buffer = new ulong[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 25: { cimg::fread(dims,2,nfile); if (endian) cimg::endian_swap(dims,2); assign(dims[1],1,1,dims[0]); const unsigned int siz = size(); float *buffer = new float[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 26: { cimg::fread(dims,3,nfile); if (endian) cimg::endian_swap(dims,3); assign(dims[2],dims[1],1,dims[0]); const unsigned int siz = size(); uchar *buffer = new uchar[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 27: { cimg::fread(dims,3,nfile); if (endian) cimg::endian_swap(dims,3); assign(dims[2],dims[1],1,dims[0]); const unsigned int siz = size(); long *buffer = new long[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 28: { cimg::fread(dims,3,nfile); if (endian) cimg::endian_swap(dims,3); assign(dims[2],dims[1],1,dims[0]); const unsigned int siz = size(); ulong *buffer = new ulong[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 29: { cimg::fread(dims,3,nfile); if (endian) cimg::endian_swap(dims,3); assign(dims[2],dims[1],1,dims[0]); const unsigned int siz = size(); float *buffer = new float[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 30: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[3],dims[2],dims[1],dims[0]); const unsigned int siz = size(); uchar *buffer = new uchar[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 31: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[3],dims[2],dims[1],dims[0]); const unsigned int siz = size(); long *buffer = new long[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 32: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[3],dims[2],dims[1],dims[0]); const unsigned int siz = size(); ulong *buffer = new ulong[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 33: { cimg::fread(dims,4,nfile); if (endian) cimg::endian_swap(dims,4); assign(dims[3],dims[2],dims[1],dims[0]); const unsigned int siz = size(); float *buffer = new float[siz]; cimg::fread(buffer,siz,nfile); if (endian) cimg::endian_swap(buffer,siz); T *ptrd = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(ptrd++) = (T)*(buffer++); buffer-=siz; delete[] buffer; } break;; case 34: cimg::fread(ptbuf,1,nfile); if (endian) cimg::endian_swap(ptbuf,1); assign(1); (*this)(0) = (T)ptbuf[0]; break; case 35: cimg::fread(ptbuf,2,nfile); if (endian) cimg::endian_swap(ptbuf,2); assign(2); (*this)(0) = (T)ptbuf[1]; (*this)(1) = (T)ptbuf[0]; break; case 36: cimg::fread(ptbuf,3,nfile); if (endian) cimg::endian_swap(ptbuf,3); assign(3); (*this)(0) = (T)ptbuf[2]; (*this)(1) = (T)ptbuf[1]; (*this)(2) = (T)ptbuf[0]; break; default: if (!file) cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_pandore() : File '%s', cannot read images with ID_type=%u", pixel_type(),filename?filename:"(FILE*)",imageid); } if (!file) cimg::fclose(nfile); return *this; } static CImg get_load_pandore(const char *const filename) { return CImg().load_pandore(0,filename); } CImg& load_pandore(const char *const filename) { return load_pandore(0,filename); } static CImg get_load_analyze(const char *const filename, float *const voxsize=0) { return CImg().load_analyze(filename,voxsize); } CImg& load_analyze(const char *const filename, float *const voxsize=0) { std::FILE *file_header = 0, *file = 0; bool error_file = false; char body[1024]; const char *ext = cimg::filename_split(filename,body); if (!cimg::strncasecmp(ext,"nii",3)) file_header = cimg::fopen(filename,"rb"); else { if (!cimg::strncasecmp(ext,"hdr",3) || !cimg::strncasecmp(ext,"img",3)) { std::sprintf(body+cimg::strlen(body),".hdr"); file_header = cimg::fopen(body,"rb"); if (!file_header) error_file = true; else { std::sprintf(body+cimg::strlen(body)-3,"img"); file = cimg::fopen(body,"rb"); if (!file) { cimg::fclose(file_header); error_file = true; } } } } if (error_file) throw CImgIOException("CImg<%s>::load_analyze() : Filename '%s', not recognized as an Analyze 7.5 or NIFTI file.", pixel_type(),filename); bool endian = false; unsigned int header_size; cimg::fread(&header_size,1,file_header); if (header_size>=4096) { endian = true; cimg::endian_swap(header_size); } unsigned char *header = new unsigned char[header_size]; cimg::fread(header+4,header_size-4,file_header); if (file) cimg::fclose(file_header); if (endian) { cimg::endian_swap((short*)(header+40),5); cimg::endian_swap((short*)(header+70),1); cimg::endian_swap((short*)(header+72),1); cimg::endian_swap((float*)(header+76),4); cimg::endian_swap((float*)(header+112),1); } unsigned short *dim = (unsigned short*)(header+40), dimx=1, dimy=1, dimz=1, dimv=1; if (!dim[0]) cimg::warn("CImg<%s>::load_analyze() : Specified image has zero dimensions.",pixel_type()); if (dim[0]>4) cimg::warn("CImg<%s>::load_analyze() : Number of image dimension is %d, reading only the 4 first dimensions", pixel_type(),dim[0]); if (dim[0]>=1) dimx = dim[1]; if (dim[0]>=2) dimy = dim[2]; if (dim[0]>=3) dimz = dim[3]; if (dim[0]>=4) dimv = dim[4]; float scalefactor = *(float*)(header+112); if (scalefactor==0) scalefactor=1; const unsigned short datatype = *(short*)(header+70); if (voxsize) { const float *vsize = (float*)(header+76); voxsize[0] = vsize[1]; voxsize[1] = vsize[2]; voxsize[2] = vsize[3]; } delete[] header; std::FILE *nfile = file?file:file_header; assign(dimx,dimy,dimz,dimv); switch (datatype) { case 2: { unsigned char *buffer = new unsigned char[dimx*dimy*dimz*dimv]; cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile); for (unsigned int off = 0; off<(*this).size(); ++off) data[off] = (T)(buffer[off]*scalefactor); delete[] buffer; } break; case 4: { short *buffer = new short[dimx*dimy*dimz*dimv]; cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile); if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv); for (unsigned int off = 0; off<(*this).size(); ++off) data[off] = (T)(buffer[off]*scalefactor); delete[] buffer; } break; case 8: { int *buffer = new int[dimx*dimy*dimz*dimv]; cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile); if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv); for (unsigned int off = 0; off<(*this).size(); ++off) data[off] = (T)(buffer[off]*scalefactor); delete[] buffer; } break; case 16: { float *buffer = new float[dimx*dimy*dimz*dimv]; cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile); if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv); for (unsigned int off = 0; off<(*this).size(); ++off) data[off] = (T)(buffer[off]*scalefactor); delete[] buffer; } break; case 64: { double *buffer = new double[dimx*dimy*dimz*dimv]; cimg::fread(buffer,dimx*dimy*dimz*dimv,nfile); if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv); for (unsigned int off = 0; off<(*this).size(); ++off) data[off] = (T)(buffer[off]*scalefactor); delete[] buffer; } break; default: cimg::fclose(nfile); throw CImgIOException("CImg<%s>::load_analyze() : File '%s, cannot read images with 'datatype = %d'", pixel_type(),filename,datatype); } cimg::fclose(nfile); return *this; } template static CImg get_load_off(const char *const filename, CImgList& primitives, CImgList& colors, const bool invert_faces=false) { return CImg().load_off(filename,primitives,colors,invert_faces); } template CImg& load_off(const char *const filename, CImgList& primitives, CImgList& colors, const bool invert_faces=false) { std::FILE *file=cimg::fopen(filename,"r"); unsigned int nb_points = 0, nb_primitives = 0, nb_read = 0; char line[256] = { 0 }; int err; do { err = std::fscanf(file,"%255[^\n] ",line); } while (!err || (err==1 && line[0]=='#')); if (cimg::strncasecmp(line,"OFF",3) && cimg::strncasecmp(line,"COFF",4)) { cimg::fclose(file); throw CImgIOException("CImg<%s>::load_off() : File '%s', keyword 'OFF' not found.",pixel_type(),filename); } do { err = std::fscanf(file,"%255[^\n] ",line); } while (!err || (err==1 && line[0]=='#')); if ((err = std::sscanf(line,"%u%u%*[^\n] ",&nb_points,&nb_primitives))!=2) { cimg::fclose(file); throw CImgIOException("CImg<%s>::load_off() : File '%s', invalid vertices/primitives numbers.",pixel_type(),filename); } assign(nb_points,3); float X = 0, Y = 0, Z = 0; for (int l = 0; l<(int)((*this).width); ++l) { do { err = std::fscanf(file,"%255[^\n] ",line); } while (!err || (err==1 && line[0]=='#')); if ((err = std::sscanf(line,"%f%f%f%*[^\n] ",&X,&Y,&Z))!=3) { cimg::fclose(file); throw CImgIOException("CImg<%s>::load_off() : File '%s', cannot read point %u/%u.\n",pixel_type(),filename,l+1,nb_points); } (*this)(l,0) = (T)X; (*this)(l,1) = (T)Y; (*this)(l,2) = (T)Z; } primitives.assign(); colors.assign(); bool stopflag = false; while (!stopflag) { float c0 = 0.7f, c1 = 0.7f, c2 = 0.7f; unsigned int prim = 0, i0 = 0, i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0; line[0]='\0'; if ((err = std::fscanf(file,"%u",&prim))!=1) stopflag=true; else { ++nb_read; switch (prim) { case 1: { if ((err = std::fscanf(file,"%u%255[^\n] ",&i0,line))<2) { cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.", pixel_type(),filename,nb_read,nb_primitives); std::fscanf(file,"%*[^\n] "); } else { std::sscanf(line,"%f%f%f",&c0,&c1,&c2); primitives.insert(CImg::vector(i0)); colors.insert(CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255))); } } break; case 2: { if ((err = std::fscanf(file,"%u%u%255[^\n] ",&i0,&i1,line))<2) { cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.", pixel_type(),filename,nb_read,nb_primitives); std::fscanf(file,"%*[^\n] "); } else { std::sscanf(line,"%f%f%f",&c0,&c1,&c2); primitives.insert(CImg::vector(i0,i1)); colors.insert(CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255))); } } break; case 3: { if ((err = std::fscanf(file,"%u%u%u%255[^\n] ",&i0,&i1,&i2,line))<3) { cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.", pixel_type(),filename,nb_read,nb_primitives); std::fscanf(file,"%*[^\n] "); } else { std::sscanf(line,"%f%f%f",&c0,&c1,&c2); if (invert_faces) primitives.insert(CImg::vector(i0,i1,i2)); else primitives.insert(CImg::vector(i0,i2,i1)); colors.insert(CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255))); } } break; case 4: { if ((err = std::fscanf(file,"%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,line))<4) { cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.", pixel_type(),filename,nb_read,nb_primitives); std::fscanf(file,"%*[^\n] "); } else { std::sscanf(line,"%f%f%f",&c0,&c1,&c2); if (invert_faces) primitives.insert(CImg::vector(i0,i1,i2,i3)); else primitives.insert(CImg::vector(i0,i3,i2,i1)); colors.insert(CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255))); } } break; case 5: { if ((err = std::fscanf(file,"%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,line))<5) { cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.", pixel_type(),filename,nb_read,nb_primitives); std::fscanf(file,"%*[^\n] "); } else { std::sscanf(line,"%f%f%f",&c0,&c1,&c2); if (invert_faces) { primitives.insert(CImg::vector(i0,i1,i2,i3)); primitives.insert(CImg::vector(i0,i3,i4)); } else { primitives.insert(CImg::vector(i0,i3,i2,i1)); primitives.insert(CImg::vector(i0,i4,i3)); } colors.insert(2,CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255))); ++nb_primitives; } } break; case 6: { if ((err = std::fscanf(file,"%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,line))<6) { cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.", pixel_type(),filename,nb_read,nb_primitives); std::fscanf(file,"%*[^\n] "); } else { std::sscanf(line,"%f%f%f",&c0,&c1,&c2); if (invert_faces) { primitives.insert(CImg::vector(i0,i1,i2,i3)); primitives.insert(CImg::vector(i0,i3,i4,i5)); } else { primitives.insert(CImg::vector(i0,i3,i2,i1)); primitives.insert(CImg::vector(i0,i5,i4,i3)); } colors.insert(2,CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255))); ++nb_primitives; } } break; case 7: { if ((err = std::fscanf(file,"%u%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,&i6,line))<7) { cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.", pixel_type(),filename,nb_read,nb_primitives); std::fscanf(file,"%*[^\n] "); } else { std::sscanf(line,"%f%f%f",&c0,&c1,&c2); if (invert_faces) { primitives.insert(CImg::vector(i0,i1,i3,i4)); primitives.insert(CImg::vector(i0,i4,i5,i6)); primitives.insert(CImg::vector(i1,i2,i3)); } else { primitives.insert(CImg::vector(i0,i4,i3,i1)); primitives.insert(CImg::vector(i0,i6,i5,i4)); primitives.insert(CImg::vector(i3,i2,i1)); } colors.insert(2,CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255))); ++(++nb_primitives); } } break; case 8: { 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) { cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u.", pixel_type(),filename,nb_read,nb_primitives); std::fscanf(file,"%*[^\n] "); } else { std::sscanf(line,"%f%f%f",&c0,&c1,&c2); if (invert_faces) { primitives.insert(CImg::vector(i0,i1,i2,i3)); primitives.insert(CImg::vector(i0,i3,i4,i5)); primitives.insert(CImg::vector(i0,i5,i6,i7)); } else { primitives.insert(CImg::vector(i0,i3,i2,i1)); primitives.insert(CImg::vector(i0,i5,i4,i3)); primitives.insert(CImg::vector(i0,i7,i6,i5)); } colors.insert(2,CImg::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255))); ++(++nb_primitives); } } break; default: cimg::warn("CImg<%s>::load_off() : File '%s', invalid primitive %u/%u (%u vertices).", pixel_type(),filename,nb_read,nb_primitives,prim); std::fscanf(file,"%*[^\n] "); break; } } } cimg::fclose(file); if (primitives.size!=nb_primitives) cimg::warn("CImg<%s>::load_off() : File '%s', read only %u primitives instead of %u as claimed in the header.", pixel_type(),filename,primitives.size,nb_primitives); return *this; } static CImg get_load_dicom(const char *const filename) { return CImg().load_dicom(filename); } CImg& load_dicom(const char *const filename) { char command[1024], filetmp[512], body[512]; cimg::fclose(cimg::fopen(filename,"r")); std::FILE *file; do { std::sprintf(filetmp,"%s.hdr",cimg::filenamerand()); if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file); } while (file); std::sprintf(command,"%s -w -c anlz -o %s -f %s",cimg::medcon_path(),filetmp,filename); cimg::system(command); cimg::filename_split(filetmp,body); std::sprintf(command,"m000-%s.hdr",body); file = std::fopen(command,"rb"); if (!file) { throw CImgIOException("CImg<%s>::load_dicom() : Failed to open image '%s'.\n\n" "Path of 'medcon' : \"%s\"\n" "Path of temporary filename : \"%s\"", pixel_type(),filename,cimg::medcon_path(),filetmp); } else cimg::fclose(file); load_analyze(command); std::remove(command); std::sprintf(command,"m000-%s.img",body); std::remove(command); return *this; } static CImg get_load_imagemagick(const char *const filename) { return CImg().load_imagemagick(filename); } CImg& load_imagemagick(const char *const filename) { char command[1024], filetmp[512]; std::FILE *file = 0; do { std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),1==2?"\\":"/",cimg::filenamerand()); if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file); } while (file); std::sprintf(command,"%s \"%s\" %s",cimg::imagemagick_path(),filename,filetmp); cimg::system(command,cimg::imagemagick_path()); if (!(file = std::fopen(filetmp,"rb"))) { cimg::fclose(cimg::fopen(filename,"r")); throw CImgIOException("CImg<%s>::load_imagemagick() : Failed to open image '%s'.\n\n" "Path of 'ImageMagick's convert' : \"%s\"\n" "Path of temporary filename : \"%s\"", pixel_type(),filename,cimg::imagemagick_path(),filetmp); } else cimg::fclose(file); load_pnm(filetmp); std::remove(filetmp); return *this; } static CImg get_load_graphicsmagick(const char *const filename) { return CImg().load_graphicsmagick(filename); } CImg& load_graphicsmagick(const char *const filename) { char command[1024], filetmp[512]; std::FILE *file = 0; do { std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),1==2?"\\":"/",cimg::filenamerand()); if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file); } while (file); std::sprintf(command,"%s convert \"%s\" %s",cimg::graphicsmagick_path(),filename,filetmp); cimg::system(command,cimg::graphicsmagick_path()); if (!(file = std::fopen(filetmp,"rb"))) { cimg::fclose(cimg::fopen(filename,"r")); throw CImgIOException("CImg<%s>::load_graphicsmagick() : Failed to open image '%s'.\n\n" "Path of 'GraphicsMagick's gm' : \"%s\"\n" "Path of temporary filename : \"%s\"", pixel_type(),filename,cimg::graphicsmagick_path(),filetmp); } else cimg::fclose(file); load_pnm(filetmp); std::remove(filetmp); return *this; } static CImg get_load_other(const char *const filename) { return CImg().load_other(filename); } CImg& load_other(const char *const filename) { const unsigned int odebug = cimg::exception_mode(); cimg::exception_mode() = 0; try { load_magick(filename); } catch (CImgException&) { try { load_imagemagick(filename); } catch (CImgException&) { try { load_graphicsmagick(filename); } catch (CImgException&) { assign(); } } } cimg::exception_mode() = odebug; if (is_empty()) throw CImgIOException("CImg<%s>::load_other() : Failed to open image '%s'.\n" "Check you have either the ImageMagick or GraphicsMagick package installed.", pixel_type(),filename); return *this; } static CImg get_load_parrec(const char *const filename, const char axis='v', const char align='p') { return CImg().load_parrec(filename,axis,align); } CImg& load_parrec(const char *const filename, const char axis='v', const char align='p') { CImgList list; list.load_parrec(filename); if (list.size==1) return list[0].transfer_to(*this); return assign(list.get_append(axis,align)); } static CImg get_load_cimg(std::FILE *const file, const char axis='z', const char align='p') { return CImg().load_cimg(file,axis,align); } CImg& load_cimg(std::FILE *const file, const char axis='z', const char align='p') { CImgList list; list.load_cimg(file); if (list.size==1) return list[0].transfer_to(*this); return assign(list.get_append(axis,align)); } static CImg get_load_cimg(const char *const filename, const char axis='z', const char align='p') { return CImg().load_cimg(filename,axis,align); } CImg& load_cimg(const char *const filename, const char axis='z', const char align='p') { CImgList list; list.load_cimg(filename); if (list.size==1) return list[0].transfer_to(*this); return assign(list.get_append(axis,align)); } static CImg get_load_cimg(std::FILE *const file, const unsigned int n0, const unsigned int n1, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0, const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1, const char axis='z', const char align='p') { return CImg().load_cimg(file,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1,axis,align); } CImg& load_cimg(std::FILE *const file, const unsigned int n0, const unsigned int n1, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0, const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1, const char axis='z', const char align='p') { CImgList list; list.load_cimg(file,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1); if (list.size==1) return list[0].transfer_to(*this); return assign(list.get_append(axis,align)); } static CImg get_load_cimg(const char *const filename, const unsigned int n0, const unsigned int n1, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0, const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1, const char axis='z', const char align='p') { return CImg().load_cimg(filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1,axis,align); } CImg& load_cimg(const char *const filename, const unsigned int n0, const unsigned int n1, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0, const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1, const char axis='z', const char align='p') { CImgList list; list.load_cimg(filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1); if (list.size==1) return list[0].transfer_to(*this); return assign(list.get_append(axis,align)); } static CImg get_load_yuv(std::FILE *const file, const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int first_frame=0, const int last_frame=-1, const bool yuv2rgb = false, const char axis='z', const char align='p') { return CImgList().load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb).get_append(axis,align); } CImg& load_yuv(std::FILE *const file, const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int first_frame=0, const int last_frame=-1, const bool yuv2rgb = false, const char axis='z', const char align='p') { return get_load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb,axis,align).transfer_to(*this); } static CImg get_load_yuv(const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int first_frame=0, const int last_frame=-1, const bool yuv2rgb = false, const char axis='z', const char align='p') { return CImgList().load_yuv(filename,sizex,sizey,first_frame,last_frame,yuv2rgb).get_append(axis,align); } CImg& load_yuv(const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int first_frame=0, const int last_frame=-1, const bool yuv2rgb = false, const char axis='z', const char align='p') { return get_load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb,axis,align).transfer_to(*this); } static CImg get_load_ffmpeg(const char *const filename, const char axis='z', const char align='p') { return CImgList().load_ffmpeg(filename).get_append(axis,align); } CImg& load_ffmpeg(const char *const filename, const char axis='z', const char align='p') { return get_load_ffmpeg(filename,axis,align).transfer_to(*this); } const CImg& save(const char *const filename, const int number=-1) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename); if (!filename) throw CImgArgumentException("CImg<%s>::save() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).", pixel_type(),width,height,depth,dim,data); const char *ext = cimg::filename_split(filename); char nfilename[1024]; const char *const fn = (number>=0)?cimg::filename_number(filename,number,6,nfilename):filename; if (!cimg::strncasecmp(ext,"asc",3)) return save_ascii(fn); if (!cimg::strncasecmp(ext,"dlm",3) || !cimg::strncasecmp(ext,"txt",3)) return save_dlm(fn); if (!cimg::strncasecmp(ext,"inr",3)) return save_inr(fn); if (!cimg::strncasecmp(ext,"hdr",3) || !cimg::strncasecmp(ext,"nii",3)) return save_analyze(fn); if (!cimg::strncasecmp(ext,"dcm",3)) return save_dicom(fn); if (!cimg::strncasecmp(ext,"pan",3)) return save_pandore(fn); if (!cimg::strncasecmp(ext,"bmp",3)) return save_bmp(fn); if (!cimg::strncasecmp(ext,"png",3)) return save_png(fn); if (!cimg::strncasecmp(ext,"tif",3)) return save_tiff(fn); if (!cimg::strncasecmp(ext,"jpg",3) || !cimg::strncasecmp(ext,"jpeg",4)) return save_jpeg(fn); if (!cimg::strncasecmp(ext,"rgba",4)) return save_rgba(fn); if (!cimg::strncasecmp(ext,"rgb",3)) return save_rgb(fn); if (!cimg::strncasecmp(ext,"raw",3)) return save_raw(fn); if (!cimg::strncasecmp(ext,"cimg",4) || ext[0]=='\0') return save_cimg(fn); if (!cimg::strncasecmp(ext,"pgm",3) || !cimg::strncasecmp(ext,"ppm",3) || !cimg::strncasecmp(ext,"pnm",3)) return save_pnm(fn); if (!cimg::strncasecmp(ext,"yuv",3)) return save_yuv(fn,true); if (!cimg::strncasecmp(ext,"avi",3) || !cimg::strncasecmp(ext,"mov",3) || !cimg::strncasecmp(ext,"mpg",3) || !cimg::strncasecmp(ext,"mpeg",4)) return save_ffmpeg(fn); return save_other(fn); } const CImg& save_ascii(std::FILE *const file, const char *const filename=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_ascii() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_ascii() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); std::FILE *const nfile = file?file:cimg::fopen(filename,"w"); std::fprintf(nfile,"%u %u %u %u\n",width,height,depth,dim); const T* ptrs = data; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { for (int x = 0; x<(int)((*this).width); ++x) std::fprintf(nfile,"%g ",(double)*(ptrs++)); std::fputc('\n',nfile); } if (!file) cimg::fclose(nfile); return *this; } const CImg& save_ascii(const char *const filename) const { return save_ascii(0,filename); } const CImg& save_dlm(std::FILE *const file, const char *const filename=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); if (depth>1) cimg::warn("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is volumetric. Pixel values along Z will be unrolled (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (dim>1) cimg::warn("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is multispectral. Pixel values along V will be unrolled (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); std::FILE *const nfile = file?file:cimg::fopen(filename,"w"); const T* ptrs = data; for (int v = 0; v<(int)((*this).dim); ++v) for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) { for (int x = 0; x<(int)((*this).width); ++x) std::fprintf(nfile,"%g%s",(double)*(ptrs++),(x==dimx()-1)?"":","); std::fputc('\n',nfile); } if (!file) cimg::fclose(nfile); return *this; } const CImg& save_dlm(const char *const filename) const { return save_dlm(0,filename); } const CImg& save_pnm(std::FILE *const file, const char *const filename=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); double stmin, stmax = (double)maxmin(stmin); if (depth>1) cimg::warn("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (dim>3) 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').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); 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)"); std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); const T *ptrR = ptr(0,0,0,0), *ptrG = (dim>=2)?ptr(0,0,0,1):0, *ptrB = (dim>=3)?ptr(0,0,0,2):0; const unsigned int buf_size = width*height*(dim==1?1:3); std::fprintf(nfile,"P%c\n# CREATOR: CImg : Original size=%ux%ux%ux%u\n%u %u\n%u\n", (dim==1?'5':'6'),width,height,depth,dim,width,height,stmax<256?255:65535); switch(dim) { case 1: { if (stmax<256) { unsigned char *ptrd = new unsigned char[buf_size], *xptrd = ptrd; for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) *(xptrd++) = (unsigned char)*(ptrR++); cimg::fwrite(ptrd,buf_size,nfile); delete[] ptrd; } else { unsigned short *ptrd = new unsigned short[buf_size], *xptrd = ptrd; for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) *(xptrd++) = (unsigned short)*(ptrR++); if (!cimg::endian()) cimg::endian_swap(ptrd,buf_size); cimg::fwrite(ptrd,buf_size,nfile); delete[] ptrd; } } break; case 2: { if (stmax<256) { unsigned char *ptrd = new unsigned char[buf_size], *xptrd = ptrd; for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { *(xptrd++) = (unsigned char)*(ptrR++); *(xptrd++) = (unsigned char)*(ptrG++); *(xptrd++) = 0; } cimg::fwrite(ptrd,buf_size,nfile); delete[] ptrd; } else { unsigned short *ptrd = new unsigned short[buf_size], *xptrd = ptrd; for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { *(xptrd++) = (unsigned short)*(ptrR++); *(xptrd++) = (unsigned short)*(ptrG++); *(xptrd++) = 0; } if (!cimg::endian()) cimg::endian_swap(ptrd,buf_size); cimg::fwrite(ptrd,buf_size,nfile); delete[] ptrd; } } break; default: { if (stmax<256) { unsigned char *ptrd = new unsigned char[buf_size], *xptrd = ptrd; for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { *(xptrd++) = (unsigned char)*(ptrR++); *(xptrd++) = (unsigned char)*(ptrG++); *(xptrd++) = (unsigned char)*(ptrB++); } cimg::fwrite(ptrd,buf_size,nfile); delete[] ptrd; } else { unsigned short *ptrd = new unsigned short[buf_size], *xptrd = ptrd; for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { *(xptrd++) = (unsigned short)*(ptrR++); *(xptrd++) = (unsigned short)*(ptrG++); *(xptrd++) = (unsigned short)*(ptrB++); } if (!cimg::endian()) cimg::endian_swap(ptrd,buf_size); cimg::fwrite(ptrd,buf_size,nfile); delete[] ptrd; } } break; } if (!file) cimg::fclose(nfile); return *this; } const CImg& save_pnm(const char *const filename) const { return save_pnm(0,filename); } const CImg& save_dicom(const char *const filename) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_dicom() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename); if (!filename) throw CImgArgumentException("CImg<%s>::save_dicom() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).", pixel_type(),width,height,depth,dim,data); char command[1024], filetmp[512], body[512]; std::FILE *file; do { std::sprintf(filetmp,"%s.hdr",cimg::filenamerand()); if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file); } while (file); save_analyze(filetmp); std::sprintf(command,"%s -w -c dicom -o %s -f %s",cimg::medcon_path(),filename,filetmp); cimg::system(command); std::remove(filetmp); cimg::filename_split(filetmp,body); std::sprintf(filetmp,"%s.img",body); std::remove(filetmp); std::sprintf(command,"m000-%s",filename); file = std::fopen(command,"rb"); if (!file) { cimg::fclose(cimg::fopen(filename,"r")); throw CImgIOException("CImg<%s>::save_dicom() : Failed to save image '%s'.\n\n" "Path of 'medcon' : \"%s\"\n" "Path of temporary filename : \"%s\"", pixel_type(),filename,cimg::medcon_path(),filetmp); } else cimg::fclose(file); std::rename(command,filename); return *this; } const CImg& save_analyze(const char *const filename, const float *const voxsize=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_analyze() : File '%s', instance image (%u,%u,%u,%u,%p) is empty.", pixel_type(),width,height,depth,dim,data,filename); if (!filename) throw CImgArgumentException("CImg<%s>::save_analyze() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).", pixel_type(),width,height,depth,dim,data); std::FILE *file; char header[348], hname[1024], iname[1024]; const char *ext = cimg::filename_split(filename); short datatype=-1; std::memset(header,0,348); if (!ext[0]) { std::sprintf(hname,"%s.hdr",filename); std::sprintf(iname,"%s.img",filename); } if (!cimg::strncasecmp(ext,"hdr",3)) { std::strcpy(hname,filename); std::strcpy(iname,filename); std::sprintf(iname+cimg::strlen(iname)-3,"img"); } if (!cimg::strncasecmp(ext,"img",3)) { std::strcpy(hname,filename); std::strcpy(iname,filename); std::sprintf(hname+cimg::strlen(iname)-3,"hdr"); } if (!cimg::strncasecmp(ext,"nii",3)) { std::strcpy(hname,filename); iname[0] = 0; } ((int*)(header))[0] = 348; std::sprintf(header+4,"CImg"); std::sprintf(header+14," "); ((short*)(header+36))[0] = 4096; ((char*)(header+38))[0] = 114; ((short*)(header+40))[0] = 4; ((short*)(header+40))[1] = width; ((short*)(header+40))[2] = height; ((short*)(header+40))[3] = depth; ((short*)(header+40))[4] = dim; if (!cimg::strcasecmp(pixel_type(),"bool")) datatype = 2; if (!cimg::strcasecmp(pixel_type(),"unsigned char")) datatype = 2; if (!cimg::strcasecmp(pixel_type(),"char")) datatype = 2; if (!cimg::strcasecmp(pixel_type(),"unsigned short")) datatype = 4; if (!cimg::strcasecmp(pixel_type(),"short")) datatype = 4; if (!cimg::strcasecmp(pixel_type(),"unsigned int")) datatype = 8; if (!cimg::strcasecmp(pixel_type(),"int")) datatype = 8; if (!cimg::strcasecmp(pixel_type(),"unsigned long")) datatype = 8; if (!cimg::strcasecmp(pixel_type(),"long")) datatype = 8; if (!cimg::strcasecmp(pixel_type(),"float")) datatype = 16; if (!cimg::strcasecmp(pixel_type(),"double")) datatype = 64; if (datatype<0) throw CImgIOException("CImg<%s>::save_analyze() : Cannot save image '%s' since pixel type (%s)" "is not handled in Analyze7.5 specifications.\n", pixel_type(),filename,pixel_type()); ((short*)(header+70))[0] = datatype; ((short*)(header+72))[0] = sizeof(T); ((float*)(header+112))[0] = 1; ((float*)(header+76))[0] = 0; if (voxsize) { ((float*)(header+76))[1] = voxsize[0]; ((float*)(header+76))[2] = voxsize[1]; ((float*)(header+76))[3] = voxsize[2]; } else ((float*)(header+76))[1] = ((float*)(header+76))[2] = ((float*)(header+76))[3] = 1; file = cimg::fopen(hname,"wb"); cimg::fwrite(header,348,file); if (iname[0]) { cimg::fclose(file); file = cimg::fopen(iname,"wb"); } cimg::fwrite(data,size(),file); cimg::fclose(file); return *this; } const CImg& save_cimg(std::FILE *const file, const char *const filename=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_cimg() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); CImgList tmp(1); tmp[0].width = width; tmp[0].height = height; tmp[0].depth = depth; tmp[0].dim = dim; tmp[0].data = data; tmp.save_cimg(file,filename); tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0; tmp[0].data = 0; return *this; } const CImg& save_cimg(const char *const filename) const { return save_cimg(0,filename); } const CImg& save_cimg(std::FILE *const file, const unsigned int n0, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0) const { CImgList tmp(1); tmp[0].width = width; tmp[0].height = height; tmp[0].depth = depth; tmp[0].dim = dim; tmp[0].data = data; tmp.save_cimg(file,n0,x0,y0,z0,v0); tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0; tmp[0].data = 0; return *this; } const CImg& save_cimg(const char *const filename, const unsigned int n0, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0) const { CImgList tmp(1); tmp[0].width = width; tmp[0].height = height; tmp[0].depth = depth; tmp[0].dim = dim; tmp[0].data = data; tmp.save_cimg(filename,n0,x0,y0,z0,v0); tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0; tmp[0].data = 0; return *this; } static void save_empty_cimg(std::FILE *const file, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) { return CImgList::save_empty_cimg(file,1,dx,dy,dz,dv); } static void save_empty_cimg(const char *const filename, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) { return CImgList::save_empty_cimg(filename,1,dx,dy,dz,dv); } const CImg& save_raw(std::FILE *const file, const char *const filename=0, const bool multiplexed=false) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_raw() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_raw() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); if (!multiplexed) cimg::fwrite(data,size(),nfile); else { CImg buf(dim); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) { for (int k = 0; k<(int)((*this).dim); ++k) buf[k] = (*this)(x,y,z,k); cimg::fwrite(buf.data,dim,nfile); } } if (!file) cimg::fclose(nfile); return *this; } const CImg& save_raw(const char *const filename=0, const bool multiplexed=false) const { return save_raw(0,filename,multiplexed); } const CImg& save_imagemagick(const char *const filename, const unsigned int quality=100) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_imagemagick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s')", pixel_type(),width,height,depth,dim,data,filename); if (!filename) throw CImgArgumentException("CImg<%s>::save_imagemagick() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).", pixel_type(),width,height,depth,dim,data); char command[1024],filetmp[512]; std::FILE *file; do { if (dim==1) std::sprintf(filetmp,"%s%s%s.pgm",cimg::temporary_path(),1==2?"\\":"/",cimg::filenamerand()); else std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),1==2?"\\":"/",cimg::filenamerand()); if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file); } while (file); save_pnm(filetmp); std::sprintf(command,"%s -quality %u%% %s \"%s\"",cimg::imagemagick_path(),quality,filetmp,filename); cimg::system(command); file = std::fopen(filename,"rb"); if (!file) throw CImgIOException("CImg<%s>::save_imagemagick() : Failed to save image '%s'.\n\n" "Path of 'convert' : \"%s\"\n" "Path of temporary filename : \"%s\"\n", pixel_type(),filename,cimg::imagemagick_path(),filetmp); if (file) cimg::fclose(file); std::remove(filetmp); return *this; } const CImg& save_graphicsmagick(const char *const filename, const unsigned int quality=100) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_graphicsmagick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s')", pixel_type(),width,height,depth,dim,data,filename); if (!filename) throw CImgArgumentException("CImg<%s>::save_graphicsmagick() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).", pixel_type(),width,height,depth,dim,data); char command[1024],filetmp[512]; std::FILE *file; do { if (dim==1) std::sprintf(filetmp,"%s%s%s.pgm",cimg::temporary_path(),1==2?"\\":"/",cimg::filenamerand()); else std::sprintf(filetmp,"%s%s%s.ppm",cimg::temporary_path(),1==2?"\\":"/",cimg::filenamerand()); if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file); } while (file); save_pnm(filetmp); std::sprintf(command,"%s -quality %u%% %s \"%s\"",cimg::graphicsmagick_path(),quality,filetmp,filename); cimg::system(command); file = std::fopen(filename,"rb"); if (!file) throw CImgIOException("CImg<%s>::save_graphicsmagick() : Failed to save image '%s'.\n\n" "Path of 'gm' : \"%s\"\n" "Path of temporary filename : \"%s\"\n", pixel_type(),filename,cimg::graphicsmagick_path(),filetmp); if (file) cimg::fclose(file); std::remove(filetmp); return *this; } const CImg& save_other(const char *const filename, const unsigned int quality=100) const { const unsigned int odebug = cimg::exception_mode(); bool is_saved = true; cimg::exception_mode() = 0; try { save_magick(filename); } catch (CImgException&) { try { save_imagemagick(filename,quality); } catch (CImgException&) { try { save_graphicsmagick(filename,quality); } catch (CImgException&) { is_saved = false; } } } cimg::exception_mode() = odebug; if (!is_saved) throw CImgIOException("CImg<%s>::save_other() : File '%s' cannot be saved.\n" "Check you have either the ImageMagick or GraphicsMagick package installed.", pixel_type(),filename); return *this; } const CImg& save_inr(std::FILE *const file, const char *const filename=0, const float *const voxsize=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_inr() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!filename) throw CImgArgumentException("CImg<%s>::save_inr() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); int inrpixsize=-1; const char *inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0"; if (!cimg::strcasecmp(pixel_type(),"unsigned char")) { inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; } if (!cimg::strcasecmp(pixel_type(),"char")) { inrtype = "fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; } if (!cimg::strcasecmp(pixel_type(),"unsigned short")) { inrtype = "unsigned fixed\nPIXSIZE=16 bits\nSCALE=2**0";inrpixsize = 2; } if (!cimg::strcasecmp(pixel_type(),"short")) { inrtype = "fixed\nPIXSIZE=16 bits\nSCALE=2**0"; inrpixsize = 2; } if (!cimg::strcasecmp(pixel_type(),"unsigned int")) { inrtype = "unsigned fixed\nPIXSIZE=32 bits\nSCALE=2**0";inrpixsize = 4; } if (!cimg::strcasecmp(pixel_type(),"int")) { inrtype = "fixed\nPIXSIZE=32 bits\nSCALE=2**0"; inrpixsize = 4; } if (!cimg::strcasecmp(pixel_type(),"float")) { inrtype = "float\nPIXSIZE=32 bits"; inrpixsize = 4; } if (!cimg::strcasecmp(pixel_type(),"double")) { inrtype = "float\nPIXSIZE=64 bits"; inrpixsize = 8; } if (inrpixsize<=0) throw CImgIOException("CImg<%s>::save_inr() : Don't know how to save images of '%s'",pixel_type(),pixel_type()); std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); char header[257]; int err = std::sprintf(header,"#INRIMAGE-4#{\nXDIM=%u\nYDIM=%u\nZDIM=%u\nVDIM=%u\n",width,height,depth,dim); if (voxsize) err += std::sprintf(header+err,"VX=%g\nVY=%g\nVZ=%g\n",voxsize[0],voxsize[1],voxsize[2]); err += std::sprintf(header+err,"TYPE=%s\nCPU=%s\n",inrtype,cimg::endian()?"sun":"decm"); std::memset(header+err,'\n',252-err); std::memcpy(header+252,"##}\n",4); cimg::fwrite(header,256,nfile); for (int z = 0; z<(int)((*this).depth); ++z) for (int y = 0; y<(int)((*this).height); ++y) for (int x = 0; x<(int)((*this).width); ++x) for (int k = 0; k<(int)((*this).dim); ++k) cimg::fwrite(&((*this)(x,y,z,k)),1,nfile); if (!file) cimg::fclose(nfile); return *this; } const CImg& save_inr(const char *const filename, const float *const voxsize=0) const { return save_inr(0,filename,voxsize); } unsigned int _save_pandore_header_length(unsigned int id, unsigned int *dims, const unsigned int colorspace=0) const { unsigned int nbdims = 0; if (id==2 || id==3 || id==4) { dims[0] = 1; dims[1] = width; nbdims = 2; } if (id==5 || id==6 || id==7) { dims[0] = 1; dims[1] = height; dims[2] = width; nbdims=3; } if (id==8 || id==9 || id==10) { dims[0] = dim; dims[1] = depth; dims[2] = height; dims[3] = width; nbdims = 4; } if (id==16 || id==17 || id==18) { dims[0] = 3; dims[1] = height; dims[2] = width; dims[3] = colorspace; nbdims = 4; } if (id==19 || id==20 || id==21) { dims[0] = 3; dims[1] = depth; dims[2] = height; dims[3] = width; dims[4] = colorspace; nbdims = 5; } if (id==22 || id==23 || id==25) { dims[0] = dim; dims[1] = width; nbdims = 2; } if (id==26 || id==27 || id==29) { dims[0] = dim; dims[1] = height; dims[2] = width; nbdims=3; } if (id==30 || id==31 || id==33) { dims[0] = dim; dims[1] = depth; dims[2] = height; dims[3] = width; nbdims = 4; } return nbdims; } const CImg& save_pandore(std::FILE *const file, const char *const filename=0, const unsigned int colorspace=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_pandore() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_pandore() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); unsigned char header[36] = { 'P','A','N','D','O','R','E','0','4',0,0,0, 0,0,0,0, 'C','I','m','g',0,0,0,0,0, 'N','o',' ','d','a','t','e',0,0,0, 0 }; unsigned int nbdims,dims[5]; bool saved=false; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("unsigned char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=2),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (2==2 || 2==5 || 2==8 || 2==16 || 2==19 || 2==22 || 2==26 || 2==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (2==3 || 2==6 || 2==9 || 2==17 || 2==20 || 2==23 || 2==27 || 2==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (2==4 || 2==7 || 2==10 || 2==18 || 2==21 || 2==25 || 2==29 || 2==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=3),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (3==2 || 3==5 || 3==8 || 3==16 || 3==19 || 3==22 || 3==26 || 3==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==3 || 3==6 || 3==9 || 3==17 || 3==20 || 3==23 || 3==27 || 3==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==4 || 3==7 || 3==10 || 3==18 || 3==21 || 3==25 || 3==29 || 3==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=3),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (3==2 || 3==5 || 3==8 || 3==16 || 3==19 || 3==22 || 3==26 || 3==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==3 || 3==6 || 3==9 || 3==17 || 3==20 || 3==23 || 3==27 || 3==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==4 || 3==7 || 3==10 || 3==18 || 3==21 || 3==25 || 3==29 || 3==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("unsigned short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=3),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (3==2 || 3==5 || 3==8 || 3==16 || 3==19 || 3==22 || 3==26 || 3==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==3 || 3==6 || 3==9 || 3==17 || 3==20 || 3==23 || 3==27 || 3==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==4 || 3==7 || 3==10 || 3==18 || 3==21 || 3==25 || 3==29 || 3==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("unsigned int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=3),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (3==2 || 3==5 || 3==8 || 3==16 || 3==19 || 3==22 || 3==26 || 3==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==3 || 3==6 || 3==9 || 3==17 || 3==20 || 3==23 || 3==27 || 3==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==4 || 3==7 || 3==10 || 3==18 || 3==21 || 3==25 || 3==29 || 3==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=3),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (3==2 || 3==5 || 3==8 || 3==16 || 3==19 || 3==22 || 3==26 || 3==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==3 || 3==6 || 3==9 || 3==17 || 3==20 || 3==23 || 3==27 || 3==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==4 || 3==7 || 3==10 || 3==18 || 3==21 || 3==25 || 3==29 || 3==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("unsigned long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=4),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (4==2 || 4==5 || 4==8 || 4==16 || 4==19 || 4==22 || 4==26 || 4==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (4==3 || 4==6 || 4==9 || 4==17 || 4==20 || 4==23 || 4==27 || 4==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (4==4 || 4==7 || 4==10 || 4==18 || 4==21 || 4==25 || 4==29 || 4==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=3),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (3==2 || 3==5 || 3==8 || 3==16 || 3==19 || 3==22 || 3==26 || 3==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==3 || 3==6 || 3==9 || 3==17 || 3==20 || 3==23 || 3==27 || 3==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (3==4 || 3==7 || 3==10 || 3==18 || 3==21 || 3==25 || 3==29 || 3==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("float",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=4),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (4==2 || 4==5 || 4==8 || 4==16 || 4==19 || 4==22 || 4==26 || 4==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (4==3 || 4==6 || 4==9 || 4==17 || 4==20 || 4==23 || 4==27 || 4==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (4==4 || 4==7 || 4==10 || 4==18 || 4==21 || 4==25 || 4==29 || 4==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("double",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=4),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (4==2 || 4==5 || 4==8 || 4==16 || 4==19 || 4==22 || 4==26 || 4==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (4==3 || 4==6 || 4==9 || 4==17 || 4==20 || 4==23 || 4==27 || 4==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (4==4 || 4==7 || 4==10 || 4==18 || 4==21 || 4==25 || 4==29 || 4==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("unsigned char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=5),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (5==2 || 5==5 || 5==8 || 5==16 || 5==19 || 5==22 || 5==26 || 5==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (5==3 || 5==6 || 5==9 || 5==17 || 5==20 || 5==23 || 5==27 || 5==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (5==4 || 5==7 || 5==10 || 5==18 || 5==21 || 5==25 || 5==29 || 5==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=6),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (6==2 || 6==5 || 6==8 || 6==16 || 6==19 || 6==22 || 6==26 || 6==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==3 || 6==6 || 6==9 || 6==17 || 6==20 || 6==23 || 6==27 || 6==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==4 || 6==7 || 6==10 || 6==18 || 6==21 || 6==25 || 6==29 || 6==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=6),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (6==2 || 6==5 || 6==8 || 6==16 || 6==19 || 6==22 || 6==26 || 6==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==3 || 6==6 || 6==9 || 6==17 || 6==20 || 6==23 || 6==27 || 6==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==4 || 6==7 || 6==10 || 6==18 || 6==21 || 6==25 || 6==29 || 6==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("unsigned short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=6),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (6==2 || 6==5 || 6==8 || 6==16 || 6==19 || 6==22 || 6==26 || 6==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==3 || 6==6 || 6==9 || 6==17 || 6==20 || 6==23 || 6==27 || 6==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==4 || 6==7 || 6==10 || 6==18 || 6==21 || 6==25 || 6==29 || 6==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("unsigned int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=6),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (6==2 || 6==5 || 6==8 || 6==16 || 6==19 || 6==22 || 6==26 || 6==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==3 || 6==6 || 6==9 || 6==17 || 6==20 || 6==23 || 6==27 || 6==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==4 || 6==7 || 6==10 || 6==18 || 6==21 || 6==25 || 6==29 || 6==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=6),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (6==2 || 6==5 || 6==8 || 6==16 || 6==19 || 6==22 || 6==26 || 6==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==3 || 6==6 || 6==9 || 6==17 || 6==20 || 6==23 || 6==27 || 6==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==4 || 6==7 || 6==10 || 6==18 || 6==21 || 6==25 || 6==29 || 6==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("unsigned long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=7),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (7==2 || 7==5 || 7==8 || 7==16 || 7==19 || 7==22 || 7==26 || 7==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (7==3 || 7==6 || 7==9 || 7==17 || 7==20 || 7==23 || 7==27 || 7==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (7==4 || 7==7 || 7==10 || 7==18 || 7==21 || 7==25 || 7==29 || 7==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=6),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (6==2 || 6==5 || 6==8 || 6==16 || 6==19 || 6==22 || 6==26 || 6==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==3 || 6==6 || 6==9 || 6==17 || 6==20 || 6==23 || 6==27 || 6==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (6==4 || 6==7 || 6==10 || 6==18 || 6==21 || 6==25 || 6==29 || 6==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("float",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=7),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (7==2 || 7==5 || 7==8 || 7==16 || 7==19 || 7==22 || 7==26 || 7==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (7==3 || 7==6 || 7==9 || 7==17 || 7==20 || 7==23 || 7==27 || 7==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (7==4 || 7==7 || 7==10 || 7==18 || 7==21 || 7==25 || 7==29 || 7==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (1?(1==dim):true) && !strcmp("double",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=7),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (7==2 || 7==5 || 7==8 || 7==16 || 7==19 || 7==22 || 7==26 || 7==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (7==3 || 7==6 || 7==9 || 7==17 || 7==20 || 7==23 || 7==27 || 7==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (7==4 || 7==7 || 7==10 || 7==18 || 7==21 || 7==25 || 7==29 || 7==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("unsigned char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=8),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (8==2 || 8==5 || 8==8 || 8==16 || 8==19 || 8==22 || 8==26 || 8==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (8==3 || 8==6 || 8==9 || 8==17 || 8==20 || 8==23 || 8==27 || 8==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (8==4 || 8==7 || 8==10 || 8==18 || 8==21 || 8==25 || 8==29 || 8==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=9),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (9==2 || 9==5 || 9==8 || 9==16 || 9==19 || 9==22 || 9==26 || 9==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==3 || 9==6 || 9==9 || 9==17 || 9==20 || 9==23 || 9==27 || 9==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==4 || 9==7 || 9==10 || 9==18 || 9==21 || 9==25 || 9==29 || 9==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=9),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (9==2 || 9==5 || 9==8 || 9==16 || 9==19 || 9==22 || 9==26 || 9==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==3 || 9==6 || 9==9 || 9==17 || 9==20 || 9==23 || 9==27 || 9==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==4 || 9==7 || 9==10 || 9==18 || 9==21 || 9==25 || 9==29 || 9==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("unsigned short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=9),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (9==2 || 9==5 || 9==8 || 9==16 || 9==19 || 9==22 || 9==26 || 9==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==3 || 9==6 || 9==9 || 9==17 || 9==20 || 9==23 || 9==27 || 9==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==4 || 9==7 || 9==10 || 9==18 || 9==21 || 9==25 || 9==29 || 9==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("unsigned int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=9),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (9==2 || 9==5 || 9==8 || 9==16 || 9==19 || 9==22 || 9==26 || 9==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==3 || 9==6 || 9==9 || 9==17 || 9==20 || 9==23 || 9==27 || 9==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==4 || 9==7 || 9==10 || 9==18 || 9==21 || 9==25 || 9==29 || 9==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=9),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (9==2 || 9==5 || 9==8 || 9==16 || 9==19 || 9==22 || 9==26 || 9==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==3 || 9==6 || 9==9 || 9==17 || 9==20 || 9==23 || 9==27 || 9==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==4 || 9==7 || 9==10 || 9==18 || 9==21 || 9==25 || 9==29 || 9==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("unsigned long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=10),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (10==2 || 10==5 || 10==8 || 10==16 || 10==19 || 10==22 || 10==26 || 10==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (10==3 || 10==6 || 10==9 || 10==17 || 10==20 || 10==23 || 10==27 || 10==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (10==4 || 10==7 || 10==10 || 10==18 || 10==21 || 10==25 || 10==29 || 10==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=9),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (9==2 || 9==5 || 9==8 || 9==16 || 9==19 || 9==22 || 9==26 || 9==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==3 || 9==6 || 9==9 || 9==17 || 9==20 || 9==23 || 9==27 || 9==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (9==4 || 9==7 || 9==10 || 9==18 || 9==21 || 9==25 || 9==29 || 9==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("float",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=10),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (10==2 || 10==5 || 10==8 || 10==16 || 10==19 || 10==22 || 10==26 || 10==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (10==3 || 10==6 || 10==9 || 10==17 || 10==20 || 10==23 || 10==27 || 10==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (10==4 || 10==7 || 10==10 || 10==18 || 10==21 || 10==25 || 10==29 || 10==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (1?(1==dim):true) && !strcmp("double",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=10),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (10==2 || 10==5 || 10==8 || 10==16 || 10==19 || 10==22 || 10==26 || 10==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (10==3 || 10==6 || 10==9 || 10==17 || 10==20 || 10==23 || 10==27 || 10==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (10==4 || 10==7 || 10==10 || 10==18 || 10==21 || 10==25 || 10==29 || 10==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("unsigned char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=16),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (16==2 || 16==5 || 16==8 || 16==16 || 16==19 || 16==22 || 16==26 || 16==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (16==3 || 16==6 || 16==9 || 16==17 || 16==20 || 16==23 || 16==27 || 16==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (16==4 || 16==7 || 16==10 || 16==18 || 16==21 || 16==25 || 16==29 || 16==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=17),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (17==2 || 17==5 || 17==8 || 17==16 || 17==19 || 17==22 || 17==26 || 17==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==3 || 17==6 || 17==9 || 17==17 || 17==20 || 17==23 || 17==27 || 17==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==4 || 17==7 || 17==10 || 17==18 || 17==21 || 17==25 || 17==29 || 17==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=17),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (17==2 || 17==5 || 17==8 || 17==16 || 17==19 || 17==22 || 17==26 || 17==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==3 || 17==6 || 17==9 || 17==17 || 17==20 || 17==23 || 17==27 || 17==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==4 || 17==7 || 17==10 || 17==18 || 17==21 || 17==25 || 17==29 || 17==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("unsigned short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=17),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (17==2 || 17==5 || 17==8 || 17==16 || 17==19 || 17==22 || 17==26 || 17==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==3 || 17==6 || 17==9 || 17==17 || 17==20 || 17==23 || 17==27 || 17==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==4 || 17==7 || 17==10 || 17==18 || 17==21 || 17==25 || 17==29 || 17==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("unsigned int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=17),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (17==2 || 17==5 || 17==8 || 17==16 || 17==19 || 17==22 || 17==26 || 17==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==3 || 17==6 || 17==9 || 17==17 || 17==20 || 17==23 || 17==27 || 17==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==4 || 17==7 || 17==10 || 17==18 || 17==21 || 17==25 || 17==29 || 17==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=17),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (17==2 || 17==5 || 17==8 || 17==16 || 17==19 || 17==22 || 17==26 || 17==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==3 || 17==6 || 17==9 || 17==17 || 17==20 || 17==23 || 17==27 || 17==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==4 || 17==7 || 17==10 || 17==18 || 17==21 || 17==25 || 17==29 || 17==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("unsigned long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=18),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (18==2 || 18==5 || 18==8 || 18==16 || 18==19 || 18==22 || 18==26 || 18==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (18==3 || 18==6 || 18==9 || 18==17 || 18==20 || 18==23 || 18==27 || 18==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (18==4 || 18==7 || 18==10 || 18==18 || 18==21 || 18==25 || 18==29 || 18==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=17),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (17==2 || 17==5 || 17==8 || 17==16 || 17==19 || 17==22 || 17==26 || 17==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==3 || 17==6 || 17==9 || 17==17 || 17==20 || 17==23 || 17==27 || 17==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (17==4 || 17==7 || 17==10 || 17==18 || 17==21 || 17==25 || 17==29 || 17==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("float",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=18),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (18==2 || 18==5 || 18==8 || 18==16 || 18==19 || 18==22 || 18==26 || 18==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (18==3 || 18==6 || 18==9 || 18==17 || 18==20 || 18==23 || 18==27 || 18==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (18==4 || 18==7 || 18==10 || 18==18 || 18==21 || 18==25 || 18==29 || 18==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (3?(3==dim):true) && !strcmp("double",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=18),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (18==2 || 18==5 || 18==8 || 18==16 || 18==19 || 18==22 || 18==26 || 18==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (18==3 || 18==6 || 18==9 || 18==17 || 18==20 || 18==23 || 18==27 || 18==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (18==4 || 18==7 || 18==10 || 18==18 || 18==21 || 18==25 || 18==29 || 18==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("unsigned char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=19),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (19==2 || 19==5 || 19==8 || 19==16 || 19==19 || 19==22 || 19==26 || 19==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (19==3 || 19==6 || 19==9 || 19==17 || 19==20 || 19==23 || 19==27 || 19==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (19==4 || 19==7 || 19==10 || 19==18 || 19==21 || 19==25 || 19==29 || 19==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=20),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (20==2 || 20==5 || 20==8 || 20==16 || 20==19 || 20==22 || 20==26 || 20==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==3 || 20==6 || 20==9 || 20==17 || 20==20 || 20==23 || 20==27 || 20==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==4 || 20==7 || 20==10 || 20==18 || 20==21 || 20==25 || 20==29 || 20==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=20),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (20==2 || 20==5 || 20==8 || 20==16 || 20==19 || 20==22 || 20==26 || 20==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==3 || 20==6 || 20==9 || 20==17 || 20==20 || 20==23 || 20==27 || 20==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==4 || 20==7 || 20==10 || 20==18 || 20==21 || 20==25 || 20==29 || 20==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("unsigned short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=20),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (20==2 || 20==5 || 20==8 || 20==16 || 20==19 || 20==22 || 20==26 || 20==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==3 || 20==6 || 20==9 || 20==17 || 20==20 || 20==23 || 20==27 || 20==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==4 || 20==7 || 20==10 || 20==18 || 20==21 || 20==25 || 20==29 || 20==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("unsigned int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=20),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (20==2 || 20==5 || 20==8 || 20==16 || 20==19 || 20==22 || 20==26 || 20==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==3 || 20==6 || 20==9 || 20==17 || 20==20 || 20==23 || 20==27 || 20==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==4 || 20==7 || 20==10 || 20==18 || 20==21 || 20==25 || 20==29 || 20==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=20),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (20==2 || 20==5 || 20==8 || 20==16 || 20==19 || 20==22 || 20==26 || 20==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==3 || 20==6 || 20==9 || 20==17 || 20==20 || 20==23 || 20==27 || 20==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==4 || 20==7 || 20==10 || 20==18 || 20==21 || 20==25 || 20==29 || 20==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("unsigned long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=21),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (21==2 || 21==5 || 21==8 || 21==16 || 21==19 || 21==22 || 21==26 || 21==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (21==3 || 21==6 || 21==9 || 21==17 || 21==20 || 21==23 || 21==27 || 21==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (21==4 || 21==7 || 21==10 || 21==18 || 21==21 || 21==25 || 21==29 || 21==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=20),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (20==2 || 20==5 || 20==8 || 20==16 || 20==19 || 20==22 || 20==26 || 20==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==3 || 20==6 || 20==9 || 20==17 || 20==20 || 20==23 || 20==27 || 20==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (20==4 || 20==7 || 20==10 || 20==18 || 20==21 || 20==25 || 20==29 || 20==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("float",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=21),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (21==2 || 21==5 || 21==8 || 21==16 || 21==19 || 21==22 || 21==26 || 21==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (21==3 || 21==6 || 21==9 || 21==17 || 21==20 || 21==23 || 21==27 || 21==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (21==4 || 21==7 || 21==10 || 21==18 || 21==21 || 21==25 || 21==29 || 21==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (3?(3==dim):true) && !strcmp("double",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=21),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (21==2 || 21==5 || 21==8 || 21==16 || 21==19 || 21==22 || 21==26 || 21==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (21==3 || 21==6 || 21==9 || 21==17 || 21==20 || 21==23 || 21==27 || 21==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (21==4 || 21==7 || 21==10 || 21==18 || 21==21 || 21==25 || 21==29 || 21==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("unsigned char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=22),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (22==2 || 22==5 || 22==8 || 22==16 || 22==19 || 22==22 || 22==26 || 22==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (22==3 || 22==6 || 22==9 || 22==17 || 22==20 || 22==23 || 22==27 || 22==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (22==4 || 22==7 || 22==10 || 22==18 || 22==21 || 22==25 || 22==29 || 22==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=23),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (23==2 || 23==5 || 23==8 || 23==16 || 23==19 || 23==22 || 23==26 || 23==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==3 || 23==6 || 23==9 || 23==17 || 23==20 || 23==23 || 23==27 || 23==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==4 || 23==7 || 23==10 || 23==18 || 23==21 || 23==25 || 23==29 || 23==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=23),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (23==2 || 23==5 || 23==8 || 23==16 || 23==19 || 23==22 || 23==26 || 23==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==3 || 23==6 || 23==9 || 23==17 || 23==20 || 23==23 || 23==27 || 23==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==4 || 23==7 || 23==10 || 23==18 || 23==21 || 23==25 || 23==29 || 23==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("unsigned short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=23),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (23==2 || 23==5 || 23==8 || 23==16 || 23==19 || 23==22 || 23==26 || 23==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==3 || 23==6 || 23==9 || 23==17 || 23==20 || 23==23 || 23==27 || 23==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==4 || 23==7 || 23==10 || 23==18 || 23==21 || 23==25 || 23==29 || 23==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("unsigned int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=23),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (23==2 || 23==5 || 23==8 || 23==16 || 23==19 || 23==22 || 23==26 || 23==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==3 || 23==6 || 23==9 || 23==17 || 23==20 || 23==23 || 23==27 || 23==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==4 || 23==7 || 23==10 || 23==18 || 23==21 || 23==25 || 23==29 || 23==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=23),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (23==2 || 23==5 || 23==8 || 23==16 || 23==19 || 23==22 || 23==26 || 23==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==3 || 23==6 || 23==9 || 23==17 || 23==20 || 23==23 || 23==27 || 23==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==4 || 23==7 || 23==10 || 23==18 || 23==21 || 23==25 || 23==29 || 23==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("unsigned long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=25),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (25==2 || 25==5 || 25==8 || 25==16 || 25==19 || 25==22 || 25==26 || 25==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (25==3 || 25==6 || 25==9 || 25==17 || 25==20 || 25==23 || 25==27 || 25==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (25==4 || 25==7 || 25==10 || 25==18 || 25==21 || 25==25 || 25==29 || 25==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=23),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (23==2 || 23==5 || 23==8 || 23==16 || 23==19 || 23==22 || 23==26 || 23==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==3 || 23==6 || 23==9 || 23==17 || 23==20 || 23==23 || 23==27 || 23==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (23==4 || 23==7 || 23==10 || 23==18 || 23==21 || 23==25 || 23==29 || 23==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("float",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=25),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (25==2 || 25==5 || 25==8 || 25==16 || 25==19 || 25==22 || 25==26 || 25==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (25==3 || 25==6 || 25==9 || 25==17 || 25==20 || 25==23 || 25==27 || 25==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (25==4 || 25==7 || 25==10 || 25==18 || 25==21 || 25==25 || 25==29 || 25==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (1?(1==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("double",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=25),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (25==2 || 25==5 || 25==8 || 25==16 || 25==19 || 25==22 || 25==26 || 25==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (25==3 || 25==6 || 25==9 || 25==17 || 25==20 || 25==23 || 25==27 || 25==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (25==4 || 25==7 || 25==10 || 25==18 || 25==21 || 25==25 || 25==29 || 25==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("unsigned char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=26),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (26==2 || 26==5 || 26==8 || 26==16 || 26==19 || 26==22 || 26==26 || 26==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (26==3 || 26==6 || 26==9 || 26==17 || 26==20 || 26==23 || 26==27 || 26==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (26==4 || 26==7 || 26==10 || 26==18 || 26==21 || 26==25 || 26==29 || 26==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=27),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (27==2 || 27==5 || 27==8 || 27==16 || 27==19 || 27==22 || 27==26 || 27==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==3 || 27==6 || 27==9 || 27==17 || 27==20 || 27==23 || 27==27 || 27==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==4 || 27==7 || 27==10 || 27==18 || 27==21 || 27==25 || 27==29 || 27==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=27),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (27==2 || 27==5 || 27==8 || 27==16 || 27==19 || 27==22 || 27==26 || 27==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==3 || 27==6 || 27==9 || 27==17 || 27==20 || 27==23 || 27==27 || 27==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==4 || 27==7 || 27==10 || 27==18 || 27==21 || 27==25 || 27==29 || 27==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("unsigned short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=27),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (27==2 || 27==5 || 27==8 || 27==16 || 27==19 || 27==22 || 27==26 || 27==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==3 || 27==6 || 27==9 || 27==17 || 27==20 || 27==23 || 27==27 || 27==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==4 || 27==7 || 27==10 || 27==18 || 27==21 || 27==25 || 27==29 || 27==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("unsigned int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=27),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (27==2 || 27==5 || 27==8 || 27==16 || 27==19 || 27==22 || 27==26 || 27==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==3 || 27==6 || 27==9 || 27==17 || 27==20 || 27==23 || 27==27 || 27==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==4 || 27==7 || 27==10 || 27==18 || 27==21 || 27==25 || 27==29 || 27==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=27),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (27==2 || 27==5 || 27==8 || 27==16 || 27==19 || 27==22 || 27==26 || 27==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==3 || 27==6 || 27==9 || 27==17 || 27==20 || 27==23 || 27==27 || 27==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==4 || 27==7 || 27==10 || 27==18 || 27==21 || 27==25 || 27==29 || 27==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("unsigned long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=29),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (29==2 || 29==5 || 29==8 || 29==16 || 29==19 || 29==22 || 29==26 || 29==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (29==3 || 29==6 || 29==9 || 29==17 || 29==20 || 29==23 || 29==27 || 29==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (29==4 || 29==7 || 29==10 || 29==18 || 29==21 || 29==25 || 29==29 || 29==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=27),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (27==2 || 27==5 || 27==8 || 27==16 || 27==19 || 27==22 || 27==26 || 27==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==3 || 27==6 || 27==9 || 27==17 || 27==20 || 27==23 || 27==27 || 27==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (27==4 || 27==7 || 27==10 || 27==18 || 27==21 || 27==25 || 27==29 || 27==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("float",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=29),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (29==2 || 29==5 || 29==8 || 29==16 || 29==19 || 29==22 || 29==26 || 29==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (29==3 || 29==6 || 29==9 || 29==17 || 29==20 || 29==23 || 29==27 || 29==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (29==4 || 29==7 || 29==10 || 29==18 || 29==21 || 29==25 || 29==29 || 29==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (1?(1==depth):true) && (0?(0==dim):true) && !strcmp("double",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=29),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (29==2 || 29==5 || 29==8 || 29==16 || 29==19 || 29==22 || 29==26 || 29==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (29==3 || 29==6 || 29==9 || 29==17 || 29==20 || 29==23 || 29==27 || 29==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (29==4 || 29==7 || 29==10 || 29==18 || 29==21 || 29==25 || 29==29 || 29==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("unsigned char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=30),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (30==2 || 30==5 || 30==8 || 30==16 || 30==19 || 30==22 || 30==26 || 30==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (30==3 || 30==6 || 30==9 || 30==17 || 30==20 || 30==23 || 30==27 || 30==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (30==4 || 30==7 || 30==10 || 30==18 || 30==21 || 30==25 || 30==29 || 30==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("char",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=31),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (31==2 || 31==5 || 31==8 || 31==16 || 31==19 || 31==22 || 31==26 || 31==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==3 || 31==6 || 31==9 || 31==17 || 31==20 || 31==23 || 31==27 || 31==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==4 || 31==7 || 31==10 || 31==18 || 31==21 || 31==25 || 31==29 || 31==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=31),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (31==2 || 31==5 || 31==8 || 31==16 || 31==19 || 31==22 || 31==26 || 31==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==3 || 31==6 || 31==9 || 31==17 || 31==20 || 31==23 || 31==27 || 31==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==4 || 31==7 || 31==10 || 31==18 || 31==21 || 31==25 || 31==29 || 31==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("unsigned short",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=31),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (31==2 || 31==5 || 31==8 || 31==16 || 31==19 || 31==22 || 31==26 || 31==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==3 || 31==6 || 31==9 || 31==17 || 31==20 || 31==23 || 31==27 || 31==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==4 || 31==7 || 31==10 || 31==18 || 31==21 || 31==25 || 31==29 || 31==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("unsigned int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=31),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (31==2 || 31==5 || 31==8 || 31==16 || 31==19 || 31==22 || 31==26 || 31==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==3 || 31==6 || 31==9 || 31==17 || 31==20 || 31==23 || 31==27 || 31==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==4 || 31==7 || 31==10 || 31==18 || 31==21 || 31==25 || 31==29 || 31==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("int",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=31),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (31==2 || 31==5 || 31==8 || 31==16 || 31==19 || 31==22 || 31==26 || 31==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==3 || 31==6 || 31==9 || 31==17 || 31==20 || 31==23 || 31==27 || 31==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==4 || 31==7 || 31==10 || 31==18 || 31==21 || 31==25 || 31==29 || 31==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("unsigned long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=33),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (33==2 || 33==5 || 33==8 || 33==16 || 33==19 || 33==22 || 33==26 || 33==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (33==3 || 33==6 || 33==9 || 33==17 || 33==20 || 33==23 || 33==27 || 33==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (33==4 || 33==7 || 33==10 || 33==18 || 33==21 || 33==25 || 33==29 || 33==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("long",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=31),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (31==2 || 31==5 || 31==8 || 31==16 || 31==19 || 31==22 || 31==26 || 31==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==3 || 31==6 || 31==9 || 31==17 || 31==20 || 31==23 || 31==27 || 31==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (31==4 || 31==7 || 31==10 || 31==18 || 31==21 || 31==25 || 31==29 || 31==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("float",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=33),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (33==2 || 33==5 || 33==8 || 33==16 || 33==19 || 33==22 || 33==26 || 33==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (33==3 || 33==6 || 33==9 || 33==17 || 33==20 || 33==23 || 33==27 || 33==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (33==4 || 33==7 || 33==10 || 33==18 || 33==21 || 33==25 || 33==29 || 33==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!saved && (0?(0==height):true) && (0?(0==depth):true) && (0?(0==dim):true) && !strcmp("double",pixel_type())) { unsigned int *iheader = (unsigned int*)(header+12); nbdims = _save_pandore_header_length((*iheader=33),dims,colorspace); cimg::fwrite(header,36,nfile); cimg::fwrite(dims,nbdims,nfile); if (33==2 || 33==5 || 33==8 || 33==16 || 33==19 || 33==22 || 33==26 || 33==30) { unsigned char *buffer = new unsigned char[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (unsigned char)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (33==3 || 33==6 || 33==9 || 33==17 || 33==20 || 33==23 || 33==27 || 33==31) { unsigned long *buffer = new unsigned long[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (long)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } if (33==4 || 33==7 || 33==10 || 33==18 || 33==21 || 33==25 || 33==29 || 33==33) { float *buffer = new float[size()]; const T *ptrs = data; for (unsigned int off = 0; off<(*this).size(); ++off) *(buffer++) = (float)(*(ptrs++)); buffer-=size(); cimg::fwrite(buffer,size(),nfile); delete[] buffer; } saved = true; }; if (!file) cimg::fclose(nfile); return *this; } const CImg& save_pandore(const char *const filename=0, const unsigned int colorspace=0) const { return save_pandore(0,filename,colorspace); } const CImg& save_yuv(std::FILE *const file, const char *const filename=0, const bool rgb2yuv=true) const { get_split('z').save_yuv(file,filename,rgb2yuv); return *this; } const CImg& save_yuv(const char *const filename, const bool rgb2yuv=true) const { return save_yuv(0,filename,rgb2yuv); } const CImg& save_ffmpeg(const char *const filename, const char *const codec="mpeg2video") const { get_split('z').save_ffmpeg(filename,codec); return *this; } const CImg& save_bmp(std::FILE *const file, const char *const filename=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); if (depth>1) cimg::warn("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (dim>3) 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').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); unsigned char header[54] = { 0 }, align_buf[4] = { 0 }; const unsigned int align = (4-(3*width)%4)%4, buf_size = (3*width+align)*dimy(), file_size = 54+buf_size; header[0] = 'B'; header[1] = 'M'; header[0x02] = file_size&0xFF; header[0x03] = (file_size>>8)&0xFF; header[0x04] = (file_size>>16)&0xFF; header[0x05] = (file_size>>24)&0xFF; header[0x0A] = 0x36; header[0x0E] = 0x28; header[0x12] = width&0xFF; header[0x13] = (width>>8)&0xFF; header[0x14] = (width>>16)&0xFF; header[0x15] = (width>>24)&0xFF; header[0x16] = height&0xFF; header[0x17] = (height>>8)&0xFF; header[0x18] = (height>>16)&0xFF; header[0x19] = (height>>24)&0xFF; header[0x1A] = 1; header[0x1B] = 0; header[0x1C] = 24; header[0x1D] = 0; header[0x22] = buf_size&0xFF; header[0x23] = (buf_size>>8)&0xFF; header[0x24] = (buf_size>>16)&0xFF; header[0x25] = (buf_size>>24)&0xFF; header[0x27] = 0x1; header[0x2B] = 0x1; cimg::fwrite(header,54,nfile); const T *pR = ptr(0,height-1,0,0), *pG = (dim>=2)?ptr(0,height-1,0,1):0, *pB = (dim>=3)?ptr(0,height-1,0,2):0; switch (dim) { case 1: { for (int y = 0; y<(int)((*this).height); ++y) { for (int x = 0; x<(int)((*this).width); ++x) { const unsigned char val = (unsigned char)*(pR++); std::fputc(val,nfile); std::fputc(val,nfile); std::fputc(val,nfile); } cimg::fwrite(align_buf,align,nfile); pR-=2*width; }} break; case 2: { for (int y = 0; y<(int)((*this).height); ++y) { for (int x = 0; x<(int)((*this).width); ++x) { std::fputc(0,nfile); std::fputc((unsigned char)(*(pG++)),nfile); std::fputc((unsigned char)(*(pR++)),nfile); } cimg::fwrite(align_buf,align,nfile); pR-=2*width; pG-=2*width; }} break; default: { for (int y = 0; y<(int)((*this).height); ++y) { for (int x = 0; x<(int)((*this).width); ++x) { std::fputc((unsigned char)(*(pB++)),nfile); std::fputc((unsigned char)(*(pG++)),nfile); std::fputc((unsigned char)(*(pR++)),nfile); } cimg::fwrite(align_buf,align,nfile); pR-=2*width; pG-=2*width; pB-=2*width; }} break; } if (!file) cimg::fclose(nfile); return *this; } const CImg& save_bmp(const char *const filename) const { return save_bmp(0,filename); } const CImg& save_png(std::FILE *const file, const char *const filename=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!filename) throw CImgArgumentException("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).", pixel_type(),width,height,depth,dim,data); if (depth>1) cimg::warn("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file) return save_other(filename); else throw CImgIOException("CImg<%s>::save_png() : Cannot save a PNG image in a *FILE output. You must use 'libpng' to do this instead.", pixel_type()); } const CImg& save_png(const char *const filename) const { return save_png(0,filename); } const CImg& save_tiff(const char *const filename) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_tiff() : File '%s', instance image (%u,%u,%u,%u,%p) is empty.", pixel_type(),filename,width,height,depth,dim,data); if (!filename) throw CImgArgumentException("CImg<%s>::save_tiff() : Specified filename is (null) for instance image (%u,%u,%u,%u,%p).", pixel_type(),width,height,depth,dim,data); return save_other(filename); return *this; } const CImg& save_jpeg(std::FILE *const file, const char *const filename=0, const unsigned int quality=100) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).", pixel_type(),width,height,depth,dim,data); if (depth>1) cimg::warn("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file) return save_other(filename,quality); else throw CImgIOException("CImg<%s>::save_jpeg() : Cannot save a JPEG image in a *FILE output. Use libjpeg instead.", pixel_type()); } const CImg& save_jpeg(const char *const filename, const unsigned int quality=100) const { return save_jpeg(0,filename,quality); } const CImg& save_magick(const char *const filename) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_magick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data); if (!filename) throw CImgArgumentException("CImg<%s>::save_magick() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); throw CImgIOException("CImg<%s>::save_magick() : File '%s', Magick++ library has not been linked.", pixel_type(),filename); return *this; } const CImg& save_rgba(std::FILE *const file, const char *const filename=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); if (dim!=4) cimg::warn("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p) has not exactly 4 channels (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); const unsigned int wh = width*height; unsigned char *buffer = new unsigned char[4*wh], *nbuffer=buffer; const T *ptr1 = ptr(0,0,0,0), *ptr2 = dim>1?ptr(0,0,0,1):0, *ptr3 = dim>2?ptr(0,0,0,2):0, *ptr4 = dim>3?ptr(0,0,0,3):0; switch (dim) { case 1: { for (unsigned int k=0; k& save_rgba(const char *const filename) const { return save_rgba(0,filename); } const CImg& save_rgb(std::FILE *const file, const char *const filename=0) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p), specified file is (null).", pixel_type(),width,height,depth,dim,data); if (dim!=3) cimg::warn("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p) has not exactly 3 channels (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); const unsigned int wh = width*height; unsigned char *buffer = new unsigned char[3*wh], *nbuffer=buffer; const T *ptr1 = ptr(0,0,0,0), *ptr2 = dim>1?ptr(0,0,0,1):0, *ptr3 = dim>2?ptr(0,0,0,2):0; switch (dim) { case 1: { for (unsigned int k=0; k& save_rgb(const char *const filename) const { return save_rgb(0,filename); } template const CImg& save_off(std::FILE *const file, const char *const filename, const CImgList& primitives, const CImgList& colors, const bool invert_faces=false) const { if (is_empty()) throw CImgInstanceException("CImg<%s>::save_off() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').", pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_off() : Specified filename is (null).",pixel_type()); if (height<3) return get_resize(-100,3,1,1,0).save_off(file,filename,primitives,colors,invert_faces); std::FILE *const nfile = file?file:cimg::fopen(filename,"w"); std::fprintf(nfile,"OFF\n%u %u %u\n",width,primitives.size,3*primitives.size); for (int i = 0; i<(int)((*this).width); ++i) std::fprintf(nfile,"%f %f %f\n",(float)((*this)(i,0)),(float)((*this)(i,1)),(float)((*this)(i,2))); for (unsigned int l=0; l<(primitives).size; ++l) { const unsigned int prim = primitives[l].size(); const bool textured = (prim>4); const CImg& color = colors[l]; const unsigned int s = textured?color.dimv():color.size(); const float r = textured?(s>0?(float)(color.get_shared_channel(0).mean()/255.0f):1.0f):(s>0?(float)(color(0)/255.0f):1.0f), g = textured?(s>1?(float)(color.get_shared_channel(1).mean()/255.0f):r) :(s>1?(float)(color(1)/255.0f):r), b = textured?(s>2?(float)(color.get_shared_channel(2).mean()/255.0f):r) :(s>2?(float)(color(2)/255.0f):r); switch (prim) { case 1: std::fprintf(nfile,"1 %u %f %f %f\n",(unsigned int)primitives(l,0),r,g,b); break; case 2: case 6: std::fprintf(nfile,"2 %u %u %f %f %f\n",(unsigned int)primitives(l,0),(unsigned int)primitives(l,1),r,g,b); break; case 3: case 9: if (invert_faces) 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); else 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); break; case 4: case 12: if (invert_faces) std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n", (unsigned int)primitives(l,0),(unsigned int)primitives(l,1),(unsigned int)primitives(l,2),(unsigned int)primitives(l,3),r,g,b); else std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n", (unsigned int)primitives(l,0),(unsigned int)primitives(l,3),(unsigned int)primitives(l,2),(unsigned int)primitives(l,1),r,g,b); break; } } if (!file) cimg::fclose(nfile); return *this; } template const CImg& save_off(const char *const filename, const CImgList& primitives, const CImgList& colors, const bool invert_faces=false) const { return save_off(0,filename,primitives,colors,invert_faces); } static CImg get_logo40x38() { static bool first_time = true; static CImg res(40,38,1,3); if (first_time) { const unsigned char *ptrs = cimg::logo40x38; T *ptr1 = res.ptr(0,0,0,0), *ptr2 = res.ptr(0,0,0,1), *ptr3 = res.ptr(0,0,0,2); for (unsigned int off = 0; off struct CImgList { unsigned int size; unsigned int allocsize; CImg *data; typedef CImg* iterator; typedef const CImg* const_iterator; typedef T value_type; CImgList(): size(0),allocsize(0),data(0) {} ~CImgList() { if (data) delete[] data; } CImgList& assign() { if (data) delete[] data; size = allocsize = 0; data = 0; return *this; } CImgList& clear() { return assign(); } template CImgList(const CImgList& list): size(0),allocsize(0),data(0) { assign(list); } CImgList(const CImgList& list): size(0),allocsize(0),data(0) { assign(list.size); for (unsigned int l=0; l<(*this).size; ++l) (*this)[l].assign(list[l],list[l].is_shared); } template CImgList(const CImgList& list, const bool shared): size(0),allocsize(0),data(0) { assign(list,shared?1:0); } CImgList(const CImgList& list, const bool shared): size(0),allocsize(0),data(0) { assign(list,shared?1:0); } template CImgList& assign(const CImgList& list, const int shared=0) { assign(list.size); if (shared>=0) for (unsigned int l=0; l<(*this).size; ++l) (*this)[l].assign(list[l],shared?true:false); else for (unsigned int l=0; l<(*this).size; ++l) (*this)[l].assign(list[l],list[l].is_shared); return *this; } explicit CImgList(const unsigned int n): size(n) { data = new CImg[allocsize=cimg::nearest_pow2(n)]; } CImgList& assign(const unsigned int n) { if (n) { if (allocsize(n<<2)) { if (data) delete[] data; data = new CImg[allocsize=cimg::nearest_pow2(n)]; } size = n; } else return assign(); return *this; } CImgList(const unsigned int n, const unsigned int width, const unsigned int height=1, const unsigned int depth=1, const unsigned int dim=1): size(0),allocsize(0),data(0) { assign(n,width,height,depth,dim); } CImgList& assign(const unsigned int n, const unsigned int width, const unsigned int height=1, const unsigned int depth=1, const unsigned int dim=1) { const unsigned int siz = width*height*depth*dim; if (n && siz) { assign(n); for (unsigned int l=0; l<(*this).size; ++l) data[l].assign(width,height,depth,dim); } else return assign(); return *this; } CImgList(const unsigned int n, const unsigned int width, const unsigned int height, const unsigned int depth, const unsigned int dim, const T val): size(0),allocsize(0),data(0) { assign(n,width,height,depth,dim,val); } CImgList& assign(const unsigned int n, const unsigned int width, const unsigned int height, const unsigned int depth, const unsigned int dim, const T val) { assign(n,width,height,depth,dim); for (unsigned int l=0; l<(*this).size; ++l) data[l].fill(val); return *this; } CImgList(const unsigned int n, const unsigned int width, const unsigned int height, const unsigned int depth, const unsigned int dim, const int val0, const int val1, ...): size(0),allocsize(0),data(0) { assign(n,width,height,depth,dim); const unsigned int siz = width*height*depth*dim, nsiz = siz*n; T *ptrd = data->data; va_list ap; __builtin_va_start(ap,val1); for (unsigned int l=0, s=0, i=0; i& assign(const unsigned int n, const unsigned int width, const unsigned int height, const unsigned int depth, const unsigned int dim, const int val0, const int val1, ...) { assign(n,width,height,depth,dim); const unsigned int siz = width*height*depth*dim, nsiz = siz*n; T *ptrd = data->data; va_list ap; __builtin_va_start(ap,val1); for (unsigned int l=0, s=0, i=0; idata; va_list ap; __builtin_va_start(ap,val1); for (unsigned int l=0, s=0, i=0; i& assign(const unsigned int n, const unsigned int width, const unsigned int height, const unsigned int depth, const unsigned int dim, const double val0, const double val1, ...) { assign(n,width,height,depth,dim); const unsigned int siz = width*height*depth*dim, nsiz = siz*n; T *ptrd = data->data; va_list ap; __builtin_va_start(ap,val1); for (unsigned int l=0, s=0, i=0; i CImgList(const unsigned int n, const CImg& img, const bool shared=false): size(0),allocsize(0),data(0) { assign(n,img,shared); } template CImgList& assign(const unsigned int n, const CImg& img, const bool shared=false) { assign(n); for (unsigned int l=0; l<(*this).size; ++l) data[l].assign(img,shared); return *this; } template explicit CImgList(const CImg& img, const bool shared=false): size(0),allocsize(0),data(0) { assign(img,shared); } template CImgList& assign(const CImg& img, const bool shared=false) { return assign(1,img,shared); } template CImgList(const CImg& img1, const CImg& img2, const bool shared=false): size(0),allocsize(0),data(0) { assign(img1,img2,shared); } template CImgList& assign(const CImg& img1, const CImg& img2, const bool shared=false) { assign(2); data[0].assign(img1,shared); data[1].assign(img2,shared); return *this; } template CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const bool shared=false): size(0),allocsize(0),data(0) { assign(img1,img2,img3,shared); } template CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const bool shared=false) { assign(3); data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); return *this; } template CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const bool shared=false): size(0),allocsize(0),data(0) { assign(img1,img2,img3,img4,shared); } template CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const bool shared=false) { assign(4); data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared); return *this; } template CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const CImg& img5, const bool shared=false): size(0),allocsize(0),data(0) { assign(img1,img2,img3,img4,img5,shared); } template CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const CImg& img5, const bool shared=false) { assign(5); data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared); data[4].assign(img5,shared); return *this; } template CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const CImg& img5, const CImg& img6, const bool shared=false): size(0),allocsize(0),data(0) { assign(img1,img2,img3,img4,img5,img6,shared); } template CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const CImg& img5, const CImg& img6, const bool shared=false) { assign(6); data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared); data[4].assign(img5,shared); data[5].assign(img6,shared); return *this; } template CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const CImg& img5, const CImg& img6, const CImg& img7, const bool shared=false): size(0),allocsize(0),data(0) { assign(img1,img2,img3,img4,img5,img6,img7,shared); } template CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const CImg& img5, const CImg& img6, const CImg& img7, const bool shared=false) { assign(7); data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared); data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared); return *this; } template CImgList(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const CImg& img5, const CImg& img6, const CImg& img7, const CImg& img8, const bool shared=false): size(0),allocsize(0),data(0) { assign(img1,img2,img3,img4,img5,img6,img7,img8,shared); } template CImgList& assign(const CImg& img1, const CImg& img2, const CImg& img3, const CImg& img4, const CImg& img5, const CImg& img6, const CImg& img7, const CImg& img8, const bool shared=false) { assign(8); data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared); data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared); data[7].assign(img8,shared); return *this; } CImgList(const char *const filename): size(0),allocsize(0),data(0) { assign(filename); } CImgList& assign(const char *const filename) { return load(filename); } CImgList& swap(CImgList& list) { cimg::swap(size,list.size); cimg::swap(allocsize,list.allocsize); cimg::swap(data,list.data); return list; } CImgList& transfer_to(CImgList& list) { return swap(list); } template CImgList& transfer_to(CImgList& list) { return list.assign(*this); } static const char* pixel_type() { return cimg::type::string(); } bool is_empty() const { return (!data || !size); } operator bool() const { return !is_empty(); } bool contains(const int k) const { return data && k<(int)size; } bool contains(const int k, const int x, const int y=0, const int z=0, const int v=0) const { return contains(k) && data[k].contains(x,y,z,v); } template bool contains(const T& pixel, t& l, t& x, t&y, t& z, t& v) const { const T *ptr = &pixel; for (unsigned int i=0; i<(*this).size; ++i) if (data[i].contains(pixel,x,y,z,v)) { l = (t)i; return true; } return false; } template bool contains(const T& pixel, t& l, t& x, t&y, t& z) const { t v; return contains(pixel,l,x,y,z,v); } template bool contains(const T& pixel, t& l, t& x, t&y) const { t z,v; return contains(pixel,l,x,y,z,v); } template bool contains(const T& pixel, t& l, t& x) const { t y,z,v; return contains(pixel,l,x,y,z,v); } template bool contains(const T& pixel, t& l) const { t x,y,z,v; return contains(pixel,l,x,y,z,v); } template bool contains(const T& pixel) const { t l,x,y,z,v; return contains(pixel,l,x,y,z,v); } template CImgList& operator=(const CImgList& list) { return assign(list); } CImgList& operator=(const CImgList& list) { return assign(list); } template CImgList& operator=(const CImg& img) { for (unsigned int l=0; l<(*this).size; ++l) data[l]=img; return *this; } CImgList& operator=(const T val) { for (unsigned int l=0; l<(*this).size; ++l) data[l].fill(val); return *this; } CImgList operator+() const { return CImgList(*this); } template CImgList& operator+=(const t val) { for (unsigned int l=0; l<(*this).size; ++l) (*this)[l]+=val; return *this; } template CImgList& operator+=(const CImgList& list) { const unsigned int sizemax = cimg::min(size,list.size); for (unsigned int l=0; l& operator++() { for (unsigned int l=0; l<(*this).size; ++l) ++(*this)[l]; return *this; } CImgList operator++(int) { CImgList copy(*this); ++*this; return copy; } CImgList operator-() const { CImgList res(size); for (unsigned int l=0; l<(res).size; ++l) res[l].assign(-data[l]); return res; } template CImgList& operator-=(const t val) { for (unsigned int l=0; l<(*this).size; ++l) (*this)[l]-=val; return *this; } template CImgList& operator-=(const CImgList& list) { const unsigned int sizemax = min(size,list.size); for (unsigned int l=0; l& operator--() { for (unsigned int l=0; l<(*this).size; ++l) --(*this)[l]; return *this; } CImgList operator--(int) { CImgList copy(*this); --*this; return copy; } template CImgList& operator*=(const t val) { for (unsigned int l=0; l<(*this).size; ++l) (*this)[l]*=val; return *this; } template CImgList& operator*=(const CImgList& list) { const unsigned int N = cimg::min(size,list.size); for (unsigned int l=0; l CImgList& operator/=(const t val) { for (unsigned int l=0; l<(*this).size; ++l) (*this)[l]/=val; return *this; } template CImgList& operator/=(const CImgList& list) { const unsigned int N = cimg::min(size,list.size); for (unsigned int l=0; l::max() : Instance image list is empty.",pixel_type()); const T *ptrmax = data->data; T max_value = *ptrmax; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) if ((*ptr)>max_value) max_value = *(ptrmax=ptr); } return *ptrmax; } T& max() { if (is_empty()) throw CImgInstanceException("CImgList<%s>::max() : Instance image list is empty.",pixel_type()); T *ptrmax = data->data; T max_value = *ptrmax; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) if ((*ptr)>max_value) max_value = *(ptrmax=ptr); } return *ptrmax; } const T& min() const { if (is_empty()) throw CImgInstanceException("CImgList<%s>::min() : Instance image list is empty.",pixel_type()); const T *ptrmin = data->data; T min_value = *ptrmin; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) if ((*ptr)::min() : Instance image list is empty.",pixel_type()); T *ptrmin = data->data; T min_value = *ptrmin; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) if ((*ptr) const T& minmax(t& max_val) const { if (is_empty()) throw CImgInstanceException("CImgList<%s>::minmax() : Instance image list is empty.",pixel_type()); const T *ptrmin = data->data; T min_value = *ptrmin, max_value = min_value; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) { const T val = *ptr; if (valmax_value) max_value = val; } } max_val = (t)max_value; return *ptrmin; } template T& minmax(t& max_val) { if (is_empty()) throw CImgInstanceException("CImgList<%s>::minmax() : Instance image list is empty.",pixel_type()); T *ptrmin = data->data; T min_value = *ptrmin, max_value = min_value; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) { const T val = *ptr; if (valmax_value) max_value = val; } } max_val = (t)max_value; return *ptrmin; } template const T& maxmin(t& min_val) const { if (is_empty()) throw CImgInstanceException("CImgList<%s>::maxmin() : Instance image list is empty.",pixel_type()); const T *ptrmax = data->data; T min_value = *ptrmax, max_value = min_value; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) { const T val = *ptr; if (val>max_value) { max_value = val; ptrmax = ptr; } if (val T& maxmin(t& min_val) { if (is_empty()) throw CImgInstanceException("CImgList<%s>::maxmin() : Instance image list is empty.",pixel_type()); T *ptrmax = data->data; T min_value = *ptrmax, max_value = min_value; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) { const T val = *ptr; if (val>max_value) { max_value = val; ptrmax = ptr; } if (val::mean() : Instance image list is empty.",pixel_type()); double val = 0; unsigned int siz = 0; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) val+=(double)*ptr; siz+=img.size(); } return val/siz; } double variance() { if (is_empty()) throw CImgInstanceException("CImgList<%s>::variance() : Instance image list is empty.",pixel_type()); double res = 0; unsigned int siz = 0; double S = 0, S2 = 0; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; for (T *ptr = (img).data + (img).size(); (ptr--)>(img).data; ) { const double val = (double)*ptr; S+=val; S2+=val*val; } siz+=img.size(); } res = (S2 - S*S/siz)/siz; return res; } CImg& operator[](const unsigned int pos) { return data[pos]; } const CImg& operator[](const unsigned int pos) const { return data[pos]; } CImg& operator()(const unsigned int pos) { return (*this)[pos]; } const CImg& operator()(const unsigned int pos) const { return (*this)[pos]; } T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) { return (*this)[pos](x,y,z,v); } const T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const { return (*this)[pos](x,y,z,v); } CImg& at(const unsigned int pos) { if (pos>=size) throw CImgArgumentException("CImgList<%s>::at() : bad list position %u, in a list of %u images", pixel_type(),pos,size); return data[pos]; } const CImg& at(const unsigned int pos) const { if (pos>=size) throw CImgArgumentException("CImgList<%s>::at() : bad list position %u, in a list of %u images", pixel_type(),pos,size); return data[pos]; } CImg& back() { return (*this)(size-1); } const CImg& back() const { return (*this)(size-1); } CImg& front() { return *data; } const CImg& front() const { return *data; } iterator begin() { return data; } const_iterator begin() const { return data; } iterator end() { return data + size; } const_iterator end() const { return data + size; } template CImgList::type> get_insert(const CImg& img, const unsigned int pos=~0U, const bool shared=false) const { typedef typename cimg::superset::type restype; return CImgList(*this).insert(img,pos,shared); } template CImgList& insert(const CImg& img, const unsigned int pos, const bool shared) { const unsigned int npos = pos==~0U?size:pos; if (npos>size) throw CImgArgumentException("CImgList<%s>::insert() : Cannot insert at position %u into a list with %u elements", pixel_type(),npos,size); if (shared) throw CImgArgumentException("CImgList<%s>::insert(): Cannot insert a shared image CImg<%s> into a CImgList<%s>", pixel_type(),img.pixel_type(),pixel_type()); CImg *new_data = (++size>allocsize)?new CImg[allocsize?(allocsize<<=1):(allocsize=1)]:0; if (!size || !data) { data = new_data; *data = img; } else { if (new_data) { if (npos) std::memcpy(new_data,data,sizeof(CImg)*npos); if (npos!=size-1) std::memcpy(new_data+npos+1,data+npos,sizeof(CImg)*(size-1-npos)); std::memset(data,0,sizeof(CImg)*(size-1)); delete[] data; data = new_data; } else if (npos!=size-1) std::memmove(data+npos+1,data+npos,sizeof(CImg)*(size-1-npos)); data[npos].width = data[npos].height = data[npos].depth = data[npos].dim = 0; data[npos].data = 0; data[npos] = img; } return *this; } CImgList& insert(const CImg& img, const unsigned int pos, const bool shared) { const unsigned int npos = pos==~0U?size:pos; if (npos>size) throw CImgArgumentException("CImgList<%s>::insert() : Can't insert at position %u into a list with %u elements", pixel_type(),npos,size); CImg *new_data = (++size>allocsize)?new CImg[allocsize?(allocsize<<=1):(allocsize=1)]:0; if (!size || !data) { data = new_data; if (shared && img) { data->width = img.width; data->height = img.height; data->depth = img.depth; data->dim = img.dim; data->is_shared = true; data->data = img.data; } else *data = img; } else { if (new_data) { if (npos) std::memcpy(new_data,data,sizeof(CImg)*npos); if (npos!=size-1) std::memcpy(new_data+npos+1,data+npos,sizeof(CImg)*(size-1-npos)); if (shared && img) { new_data[npos].width = img.width; new_data[npos].height = img.height; new_data[npos].depth = img.depth; new_data[npos].dim = img.dim; new_data[npos].is_shared = true; new_data[npos].data = img.data; } else { new_data[npos].width = new_data[npos].height = new_data[npos].depth = new_data[npos].dim = 0; new_data[npos].data = 0; new_data[npos] = img; } std::memset(data,0,sizeof(CImg)*(size-1)); delete[] data; data = new_data; } else { if (npos!=size-1) std::memmove(data+npos+1,data+npos,sizeof(CImg)*(size-1-npos)); if (shared && img) { data[npos].width = img.width; data[npos].height = img.height; data[npos].depth = img.depth; data[npos].dim = img.dim; data[npos].is_shared = true; data[npos].data = img.data; } else { data[npos].width = data[npos].height = data[npos].depth = data[npos].dim = 0; data[npos].data = 0; data[npos] = img; } } } return *this; } template CImgList& insert(const CImg& img, const unsigned int pos) { return insert(img,pos,false); } template CImgList& insert(const CImg& img) { return insert(img,~0U,false); } template CImgList::type> get_insert(const unsigned int n, const CImg& img, const unsigned int pos=~0U, const bool shared=false) const { typedef typename cimg::superset::type restype; return CImgList(*this).insert(n,img,pos,shared); } template CImgList& insert(const unsigned int n, const CImg& img, const unsigned int pos=~0U, const bool shared=false) { const unsigned int npos = pos==~0U?size:pos; insert(img,npos,shared); for (unsigned int i=1; i CImgList::type> get_insert(const CImgList& list, const unsigned int pos=~0U, int shared=0) const { typedef typename cimg::superset::type restype; return CImgList(*this).insert(list,pos,shared); } template CImgList& insert(const CImgList& list, const unsigned int pos=~0U, const int shared=0) { const unsigned int npos = pos==~0U?size:pos; if ((void*)this!=(void*)&list) { if (shared>=0) for (unsigned int l=0; l<(list).size; ++l) insert(list[l],npos+l,shared?true:false); else for (unsigned int l=0; l<(list).size; ++l) insert(list[l],npos+l,list[l].is_shared); } else insert(CImgList(list),npos,shared); return *this; } template CImgList::type> get_insert(const unsigned int n, const CImgList& list, const unsigned int pos=~0U, const int shared=0) const { typedef typename cimg::superset::type restype; return CImgList(*this).insert(n,list,pos,shared); } template CImgList& insert(const unsigned int n, const CImgList& list, const unsigned int pos=~0U, const int shared=0) { const unsigned int npos = pos==~0U?size:pos; for (unsigned int i=0; i get_remove(const unsigned int pos1, const unsigned int pos2) const { return (+*this).remove(pos1,pos2); } CImgList& remove(const unsigned int pos1, const unsigned int pos2) { const unsigned int npos1 = pos1=size) cimg::warn("CImgList<%s>::remove() : Cannot remove images from a list (%p,%u), at positions %u->%u.", pixel_type(),data,size,npos1,tpos2); else { if (tpos2>=size) cimg::warn("CImgList<%s>::remove() : Cannot remove all images from a list (%p,%u), at positions %u->%u.", pixel_type(),data,size,npos1,tpos2); for (unsigned int k = npos1; k<=npos2; ++k) data[k].assign(); const unsigned int nb = 1 + npos2 - npos1; if (!(size-=nb)) return assign(); if (size>(allocsize>>2) || allocsize<=8) { if (npos1!=size) std::memmove(data+npos1,data+npos2+1,sizeof(CImg)*(size-npos1)); std::memset(data+size,0,sizeof(CImg)*nb); } else { allocsize>>=2; while (allocsize>8 && size<(allocsize>>1)) allocsize>>=1; CImg *new_data = new CImg[allocsize]; if (npos1) std::memcpy(new_data,data,sizeof(CImg)*npos1); if (npos1!=size) std::memcpy(new_data+npos1,data+npos2+1,sizeof(CImg)*(size-npos1)); if (size!=allocsize) std::memset(new_data+size,0,sizeof(allocsize-size)); std::memset(data,0,sizeof(CImg)*(size+nb)); delete[] data; data = new_data; } } return *this; } CImgList get_remove(const unsigned int pos) const { return (+*this).remove(pos); } CImgList& remove(const unsigned int pos) { return remove(pos,pos); } CImgList get_remove() const { return (+*this).remove(); } CImgList& remove() { if (size) return remove(size-1); else cimg::warn("CImgList<%s>::remove() : List is empty",pixel_type()); return *this; } CImgList get_reverse() const { return (+*this).reverse(); } CImgList& reverse() { for (unsigned int l=0; l get_crop(const unsigned int i0, const unsigned int i1, const bool shared=false) const { if (i0>i1 || i1>=size) throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)", pixel_type(),i0,i1,size,data); CImgList res(i1-i0+1); for (unsigned int l=0; l<(res).size; ++l) res[l].assign((*this)[i0+l],shared); return res; } CImgList& crop(const unsigned int i0, const unsigned int i1, const bool shared=false) { return get_crop(i0,i1,shared).transfer_to(*this); } CImgList get_crop(const unsigned int i0, const unsigned int i1, const int x0, const int y0, const int z0, const int v0, const int x1, const int y1, const int z1, const int v1) const { if (i0>i1 || i1>=size) throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)", pixel_type(),i0,i1,size,data); CImgList res(i1-i0+1); for (unsigned int l=0; l<(res).size; ++l) res[l] = (*this)[i0+l].get_crop(x0,y0,z0,v0,x1,y1,z1,v1); return res; } CImgList& crop(const unsigned int i0, const unsigned int i1, const int x0, const int y0, const int z0, const int v0, const int x1, const int y1, const int z1, const int v1) { return get_crop(i0,i1,x0,y0,z0,v0,x1,y1,z1,v1).transfer_to(*this); } CImgList get_crop(const unsigned int i0, const unsigned int i1, const int x0, const int y0, const int z0, const int x1, const int y1, const int z1) const { if (i0>i1 || i1>=size) throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)", pixel_type(),i0,i1,size,data); CImgList res(i1-i0+1); for (unsigned int l=0; l<(res).size; ++l) res[l] = (*this)[i0+l].get_crop(x0,y0,z0,x1,y1,z1); return res; } CImgList& crop(const unsigned int i0, const unsigned int i1, const int x0, const int y0, const int z0, const int x1, const int y1, const int z1) { return get_crop(i0,i1,x0,y0,z0,x1,y1,z1).transfer_to(*this); } CImgList get_crop(const unsigned int i0, const unsigned int i1, const int x0, const int y0, const int x1, const int y1) const { if (i0>i1 || i1>=size) throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)", pixel_type(),i0,i1,size,data); CImgList res(i1-i0+1); for (unsigned int l=0; l<(res).size; ++l) res[l] = (*this)[i0+l].get_crop(x0,y0,x1,y1); return res; } CImgList& crop(const unsigned int i0, const unsigned int i1, const int x0, const int y0, const int x1, const int y1) { return get_crop(i0,i1,x0,y0,x1,y1).transfer_to(*this); } CImgList get_crop(const unsigned int i0, const unsigned int i1, const int x0, const int x1) const { if (i0>i1 || i1>=size) throw CImgArgumentException("CImgList<%s>::crop() : Cannot crop a sub-list (%u->%u) from a list (%u,%p)", pixel_type(),i0,i1,size,data); CImgList res(i1-i0+1); for (unsigned int l=0; l<(res).size; ++l) res[l] = (*this)[i0+l].get_crop(x0,x1); return res; } CImgList& crop(const unsigned int i0, const unsigned int i1, const int x0, const int x1) { return get_crop(i0,i1,x0,x1).transfer_to(*this); } template CImgList& operator<<(const CImg& img) { return insert(img); } template CImgList& operator<<(const CImgList& list) { return insert(list); } template CImgList& operator>>(CImg& img) const { typedef typename cimg::superset::type restype; return CImgList(*this).insert(img); } template CImgList& operator>>(CImgList& list) const { return list.insert(*this,0); } const CImgList& operator>>(CImgDisplay& disp) const { return display(disp); } template CImgList& push_back(const CImg& img) { return insert(img); } template CImgList& push_front(const CImg& img) { return insert(img,0); } template CImgList& push_back(const CImgList& list) { return insert(list); } template CImgList& push_front(const CImgList& list) { return insert(list,0); } CImgList& pop_back() { return remove(size-1); } CImgList& pop_front() { return remove(0); } CImgList& erase(const iterator iter) { return remove(iter-data); } CImgList::type> get_FFT(const char axe, const bool invert=false) const { typedef typename cimg::superset::type restype; return CImgList(*this).FFT(axe,invert); } CImgList& FFT(const char axe, const bool invert=false) { if (is_empty()) throw CImgInstanceException("CImgList<%s>::FFT() : Instance list (%u,%p) is empty",pixel_type(),size,data); if (!data[0]) throw CImgInstanceException("CImgList<%s>::FFT() : Real part (%u,%u,%u,%u,%p) is empty", pixel_type(),data[0].width,data[0].height,data[0].depth,data[0].dim,data[0].data); if (size>2) cimg::warn("CImgList<%s>::FFT() : Instance list (%u,%p) have more than 2 images",pixel_type(),size,data); if (size==1) insert(CImg(data[0].width,data[0].height,data[0].depth,data[0].dim,0)); CImg &Ir = data[0], &Ii = data[1]; if (Ir.width!=Ii.width || Ir.height!=Ii.height || Ir.depth!=Ii.depth || Ir.dim!=Ii.dim) throw CImgInstanceException("CImgList<%s>::FFT() : Real part (%u,%u,%u,%u,%p) and imaginary part (%u,%u,%u,%u,%p)" "have different dimensions",pixel_type(), Ir.width,Ir.height,Ir.depth,Ir.dim,Ir.data,Ii.width,Ii.height,Ii.depth,Ii.dim,Ii.data); switch (cimg::uncase(axe)) { case 'x': { const unsigned int N = Ir.width, N2 = (N>>1); if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image along 'x' is %d != 2^N", pixel_type(),N); for (unsigned int i=0, j=0; ii) for (int v = 0; v<(int)((Ir).dim); ++v) for (int z = 0; z<(int)((Ir).depth); ++z) for (int y = 0; y<(int)((Ir).height); ++y) { cimg::swap(Ir(i,y,z,v),Ir(j,y,z,v)); cimg::swap(Ii(i,y,z,v),Ii(j,y,z,v)); if (j=m; j-=m, m=n, n>>=1); } for (unsigned int delta=2; delta<=N; delta<<=1) { const unsigned int delta2 = (delta>>1); for (unsigned int i=0; i>1); if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image(s) along 'y' is %d != 2^N", pixel_type(),N); for (unsigned int i=0, j=0; ii) for (int v = 0; v<(int)((Ir).dim); ++v) for (int z = 0; z<(int)((Ir).depth); ++z) for (int x = 0; x<(int)((Ir).width); ++x) { cimg::swap(Ir(x,i,z,v),Ir(x,j,z,v)); cimg::swap(Ii(x,i,z,v),Ii(x,j,z,v)); if (j=m; j-=m, m=n, n>>=1); } for (unsigned int delta=2; delta<=N; delta<<=1) { const unsigned int delta2 = (delta>>1); for (unsigned int i=0; i>1); if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image(s) along 'z' is %d != 2^N", pixel_type(),N); for (unsigned int i=0, j=0; ii) for (int v = 0; v<(int)((Ir).dim); ++v) for (int y = 0; y<(int)((Ir).height); ++y) for (int x = 0; x<(int)((Ir).width); ++x) { cimg::swap(Ir(x,y,i,v),Ir(x,y,j,v)); cimg::swap(Ii(x,y,i,v),Ii(x,y,j,v)); if (j=m; j-=m, m=n, n>>=1); } for (unsigned int delta=2; delta<=N; delta<<=1) { const unsigned int delta2 = (delta>>1); for (unsigned int i=0; i::FFT() : unknown axe '%c', must be 'x','y' or 'z'"); } return *this; } CImgList::type> get_FFT(const bool invert=false) const { typedef typename cimg::superset::type restype; return CImgList(*this).FFT(invert); } CImgList& FFT(const bool invert=false) { if (is_empty()) throw CImgInstanceException("CImgList<%s>::FFT() : Instance list (%u,%p) is empty",pixel_type(),size,data); if (size>2) cimg::warn("CImgList<%s>::FFT() : Instance list (%u,%p) have more than 2 images",pixel_type(),size,data); if (size==1) insert(CImg(data->width,data->height,data->depth,data->dim,0)); CImg &Ir = data[0], &Ii = data[1]; if (Ii.width!=Ir.width || Ii.height!=Ir.height || Ii.depth!=Ir.depth || Ii.dim!=Ir.dim) throw CImgInstanceException("CImgList<%s>::FFT() : Real (%u,%u,%u,%u,%p) and Imaginary (%u,%u,%u,%u,%p) parts " "of the instance image have different dimensions", pixel_type(),Ir.width,Ir.height,Ir.depth,Ir.dim,Ir.data, Ii.width,Ii.height,Ii.depth,Ii.dim,Ii.data); if (Ir.depth>1) FFT('z',invert); if (Ir.height>1) FFT('y',invert); if (Ir.width>1) FFT('x',invert); return *this; } const CImgList& print(const char* title=0, const int print_flag=1) const { if (print_flag>=0) { char tmp[1024]; std::fprintf(stderr,"%-8s(this=%p) : { size=%u, data=%p }\n",title?title:"CImgList", (void*)this,size,(void*)data); switch (print_flag) { case 1: { for (unsigned int l=0; l<(*this).size; ++l) if (l<4 || l>=size-4) { std::sprintf(tmp,"%s[%d]",title?title:"CImgList",l); data[l].print(tmp,print_flag); } else { if (l==4) std::fprintf(stderr,"...\n"); } } break; default: { for (unsigned int l=0; l<(*this).size; ++l) { std::sprintf(tmp,"%s[%d]",title?title:"CImgList",l); data[l].print(tmp,print_flag); } } break; } } return *this; } const CImgList& print(const int print_flag) const { return print(0,print_flag); } static CImgList get_load(const char *const filename) { return CImgList().load(filename); } CImgList& load(const char *const filename) { const char *ext = cimg::filename_split(filename); if (!cimg::strncasecmp(ext,"tif",3) || !cimg::strncasecmp(ext,"tiff",4)) return load_tiff(filename); if (!cimg::strncasecmp(ext,"cimg",4) || !ext[0]) return load_cimg(filename); if (!cimg::strncasecmp(ext,"rec",3) || !cimg::strncasecmp(ext,"par",3)) return load_parrec(filename); if (!cimg::strncasecmp(ext,"avi",3) || !cimg::strncasecmp(ext,"mov",3) || !cimg::strncasecmp(ext,"mpg",3) || !cimg::strncasecmp(ext,"mpeg",4)) return load_ffmpeg(filename); assign(1); data->load(filename); return *this; } static CImgList get_load_cimg(std::FILE *const file, const char *const filename=0) { return CImgList().load_cimg(file,filename); } CImgList& load_cimg(std::FILE *const file, const char *const filename=0) { typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; const int cimg_iobuffer = 12*1024*1024; std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); bool loaded = false, endian = cimg::endian(); char tmp[256], str_pixeltype[256], str_endian[256]; unsigned int j, err, N=0, W, H, D, V; int i; j = 0; while((i=std::fgetc(nfile))!='\n' && i!=(-1) && j<256) tmp[j++] = (char)i; tmp[j] = '\0'; err = std::sscanf(tmp,"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian); if (err<2) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Unknow CImg RAW header.", pixel_type(),filename?filename:"(FILE*)"); } if (!cimg::strncasecmp("little",str_endian,6)) endian = false; else if (!cimg::strncasecmp("big",str_endian,3)) endian = true; assign(N); if (!loaded && !cimg::strcasecmp("bool",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const bool *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("unsigned_char",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const uchar *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("uchar",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const uchar *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("char",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const char *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("unsigned_short",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const ushort *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("ushort",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const ushort *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("short",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const short *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("unsigned_int",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const uint *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("uint",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const uint *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("int",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const int *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("unsigned_long",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const ulong *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("ulong",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const ulong *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("long",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const long *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("float",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const float *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("double",str_pixeltype)) { for (unsigned int l=0; l::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { CImg raw; CImg &img = data[l]; img.assign(W,H,D,V); T *ptrd = img.data; for (int toread = (int)img.size(); toread>0; ) { raw.assign(cimg::min(toread,cimg_iobuffer)); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); toread-=raw.width; const double *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); } } } loaded = true; }; if (!loaded) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', cannot read images of pixels coded as '%s'.", pixel_type(),filename?filename:"(FILE*)",str_pixeltype); } if (!file) cimg::fclose(nfile); return *this; } static CImgList get_load_cimg(const char *const filename) { return CImgList().load_cimg(0,filename); } CImgList& load_cimg(const char *const filename) { return load_cimg(0,filename); } static CImgList get_load_cimg(std::FILE *const file, const unsigned int n0, const unsigned int n1, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0, const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) { return CImgList().load_cimg(file,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1); } CImgList& load_cimg(std::FILE *const file, const unsigned int n0, const unsigned int n1, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0, const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) { return load_cimg(file,0,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1); } static CImgList get_load_cimg(const char *const filename, const unsigned int n0, const unsigned int n1, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0, const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) { return CImgList().load_cimg(filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1); } CImgList& load_cimg(const char *const filename, const unsigned int n0, const unsigned int n1, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0, const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) { return load_cimg(0,filename,n0,n1,x0,y0,z0,v0,x1,y1,z1,v1); } CImgList& load_cimg(std::FILE *const file, const char *const filename, const unsigned int n0, const unsigned int n1, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0, const unsigned int x1, const unsigned int y1, const unsigned int z1, const unsigned int v1) { typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; if (n1::load_cimg() : File '%s', Bad sub-region coordinates [%u->%u] " "(%u,%u,%u,%u)->(%u,%u,%u,%u).",pixel_type(),filename?filename:"(FILE*)", n0,n1,x0,y0,z0,v0,x1,y1,z1,v1); std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); bool loaded = false, endian = cimg::endian(); char tmp[256], str_pixeltype[256], str_endian[256]; unsigned int j, err, N, W, H, D, V; int i; j = 0; while((i=std::fgetc(nfile))!='\n' && i!=(-1) && j<256) tmp[j++] = (char)i; tmp[j] = '\0'; err = std::sscanf(tmp,"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian); if (err<2) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Unknow CImg RAW header.", pixel_type(),filename?filename:"(FILE*)"); } if (!cimg::strncasecmp("little",str_endian,6)) endian = false; else if (!cimg::strncasecmp("big",str_endian,3)) endian = true; const unsigned int nn1 = n1>=N?N-1:n1; assign(1+nn1-n0); if (!loaded && !cimg::strcasecmp("bool",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(bool),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(bool); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(bool); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(bool); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(bool); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const bool *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(bool); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(bool); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(bool); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(bool); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("unsigned_char",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(uchar),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(uchar); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(uchar); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(uchar); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(uchar); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const uchar *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(uchar); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(uchar); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(uchar); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(uchar); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("uchar",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(uchar),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(uchar); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(uchar); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(uchar); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(uchar); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const uchar *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(uchar); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(uchar); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(uchar); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(uchar); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("char",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(char),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(char); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(char); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(char); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(char); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const char *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(char); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(char); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(char); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(char); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("unsigned_short",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(ushort),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(ushort); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(ushort); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(ushort); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(ushort); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const ushort *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(ushort); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(ushort); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(ushort); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(ushort); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("ushort",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(ushort),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(ushort); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(ushort); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(ushort); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(ushort); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const ushort *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(ushort); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(ushort); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(ushort); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(ushort); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("short",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(short),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(short); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(short); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(short); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(short); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const short *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(short); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(short); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(short); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(short); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("unsigned_int",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(uint),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(uint); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(uint); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(uint); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(uint); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const uint *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(uint); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(uint); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(uint); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(uint); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("uint",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(uint),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(uint); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(uint); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(uint); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(uint); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const uint *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(uint); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(uint); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(uint); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(uint); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("int",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(int),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(int); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(int); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(int); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(int); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const int *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(int); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(int); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(int); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(int); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("unsigned_long",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(ulong),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(ulong); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(ulong); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(ulong); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(ulong); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const ulong *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(ulong); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(ulong); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(ulong); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(ulong); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("ulong",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(ulong),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(ulong); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(ulong); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(ulong); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(ulong); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const ulong *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(ulong); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(ulong); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(ulong); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(ulong); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("long",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(long),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(long); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(long); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(long); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(long); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const long *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(long); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(long); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(long); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(long); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("float",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(float),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(float); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(float); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(float); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(float); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const float *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(float); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(float); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(float); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(float); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded && !cimg::strcasecmp("double",str_pixeltype)) { for (unsigned int l=0; l<=nn1; ++l) { j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; W = H = D = V = 0; if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&V)!=4) throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(double),1); else { const unsigned int nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); CImg &img = data[l-n0]; img.assign(1+nx1-x0,1+ny1-y0,1+nz1-z0,1+nv1-v0); T *ptrd = img.data; const unsigned int skipvb = v0*W*H*D*sizeof(double); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(double); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(double); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(double); if (skipxb) std::fseek(nfile,skipxb,1); cimg::fread(raw.data,raw.width,nfile); if (endian!=cimg::endian()) cimg::endian_swap(raw.data,raw.width); const double *ptrs = raw.data; for (unsigned int off = raw.width; off; --off) *(ptrd++) = (T)*(ptrs++); const unsigned int skipxe = (W-1-nx1)*sizeof(double); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(double); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(double); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(double); if (skipve) std::fseek(nfile,skipve,1); } } } loaded = true; }; if (!loaded) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImgList<%s>::load_cimg() : File '%s', cannot read images of pixels coded as '%s'.", pixel_type(),filename?filename:"(FILE*)",str_pixeltype); } if (!file) cimg::fclose(nfile); return *this; } static CImgList get_load_parrec(const char *const filename) { return CImgList().load_parrec(filename); } CImgList& load_parrec(const char *const filename) { char body[1024], filenamepar[1024], filenamerec[1024]; const char *ext = cimg::filename_split(filename,body); if (!cimg::strncmp(ext,"par",3)) { std::strcpy(filenamepar,filename); std::sprintf(filenamerec,"%s.rec",body); } if (!cimg::strncmp(ext,"PAR",3)) { std::strcpy(filenamepar,filename); std::sprintf(filenamerec,"%s.REC",body); } if (!cimg::strncmp(ext,"rec",3)) { std::strcpy(filenamerec,filename); std::sprintf(filenamepar,"%s.par",body); } if (!cimg::strncmp(ext,"REC",3)) { std::strcpy(filenamerec,filename); std::sprintf(filenamepar,"%s.PAR",body); } std::FILE *file = cimg::fopen(filenamepar,"r"); CImgList st_slices; CImgList st_global; int err; char line[256] = { 0 }; do { err=std::fscanf(file,"%255[^\n]%*c",line); } while (err!=(-1) && (line[0]=='#' || line[0]=='.')); do { unsigned int sn,sizex,sizey,pixsize; float rs,ri,ss; 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); if (err==7) { st_slices.insert(CImg::vector((float)sn,(float)pixsize,(float)sizex,(float)sizey,ri,rs,ss,0)); unsigned int i; for (i=0; i::vector(sizex,sizey,sn)); else { CImg &vec = st_global[i]; if (sizex>vec[0]) vec[0] = sizex; if (sizey>vec[1]) vec[1] = sizey; vec[2] = sn; } st_slices[st_slices.size-1][7] = (float)i; } } while (err==7); std::FILE *file2 = cimg::fopen(filenamerec,"rb"); { for (unsigned int l=0; l<(st_global).size; ++l) { const CImg& vec = st_global[l]; insert(CImg(vec[0],vec[1],vec[2])); }} for (unsigned int l=0; l<(st_slices).size; ++l) { const CImg& vec = st_slices[l]; const unsigned int sn = (unsigned int)vec[0]-1, pixsize = (unsigned int)vec[1], sizex = (unsigned int)vec[2], sizey = (unsigned int)vec[3], imn = (unsigned int)vec[7]; const float ri = vec[4], rs = vec[5], ss = vec[6]; switch (pixsize) { case 8: { CImg buf(sizex,sizey); cimg::fread(buf.data,sizex*sizey,file2); if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey); CImg& img = (*this)[imn]; for (int y = 0; y<(int)((img).height); ++y) for (int x = 0; x<(int)((img).width); ++x) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss)); } break; case 16: { CImg buf(sizex,sizey); cimg::fread(buf.data,sizex*sizey,file2); if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey); CImg& img = (*this)[imn]; for (int y = 0; y<(int)((img).height); ++y) for (int x = 0; x<(int)((img).width); ++x) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss)); } break; case 32: { CImg buf(sizex,sizey); cimg::fread(buf.data,sizex*sizey,file2); if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey); CImg& img = (*this)[imn]; for (int y = 0; y<(int)((img).height); ++y) for (int x = 0; x<(int)((img).width); ++x) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss)); } break; default: cimg::fclose(file); cimg::fclose(file2); throw CImgIOException("CImg<%s>::load_parrec() : File '%s', cannot handle image with pixsize = %d bits.", pixel_type(),filename,pixsize); break; } } cimg::fclose(file); cimg::fclose(file2); if (!size) throw CImgIOException("CImg<%s>::load_parrec() : File '%s' does not appear to be a valid PAR-REC file.", pixel_type(),filename); return *this; } static CImgList get_load_yuv(std::FILE *const file, const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int first_frame=0, const int last_frame=-1, const bool yuv2rgb=false) { return CImgList().load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb); } CImgList& load_yuv(std::FILE *const file, const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int first_frame=0, const int last_frame=-1, const bool yuv2rgb=false) { if (sizex%2 || sizey%2) throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', image dimensions along X and Y must be " "even numbers (given are %ux%u)\n",pixel_type(),filename?filename:"(unknown)",sizex,sizey); if (!sizex || !sizey) throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', given image sequence size (%u,%u) is invalid", pixel_type(),filename?filename:"(unknown)",sizex,sizey); if (last_frame>0 && first_frame>(unsigned int)last_frame) throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', given first frame %u is posterior to last frame %d.", pixel_type(),filename?filename:"(unknown)",first_frame,last_frame); if (!sizex || !sizey) throw CImgArgumentException("CImgList<%s>::load_yuv() : File '%s', given frame size (%u,%u) is invalid.", pixel_type(),filename?filename:"(unknown)",sizex,sizey); CImg tmp(sizex,sizey,1,3), UV(sizex/2,sizey/2,1,2); std::FILE *const nfile = file?file:cimg::fopen(filename,"rb"); bool stopflag = false; int err; if (first_frame) { err = std::fseek(nfile,first_frame*(sizex*sizey + sizex*sizey/2),1); if (err) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImgList<%s>::load_yuv() : File '%s' doesn't contain frame number %u " "(out of range error).",pixel_type(),filename?filename:"(FILE*)",first_frame); } } unsigned int frame; for (frame = first_frame; !stopflag && (last_frame<0 || frame<=(unsigned int)last_frame); ++frame) { tmp.fill(0); err = (int)std::fread((void*)(tmp.data),1,(size_t)(tmp.width*tmp.height),nfile); if (err!=(int)(tmp.width*tmp.height)) { stopflag = true; if (err>0) cimg::warn("CImgList<%s>::load_yuv() : File '%s' contains incomplete data," " or given image dimensions (%u,%u) are incorrect.", pixel_type(),filename?filename:"(unknown)",sizex,sizey); } else { UV.fill(0); err = (int)std::fread((void*)(UV.data),1,(size_t)(UV.size()),nfile); if (err!=(int)(UV.size())) { stopflag = true; if (err>0) cimg::warn("CImgList<%s>::load_yuv() : File '%s' contains incomplete data," " or given image dimensions (%u,%u) are incorrect.", pixel_type(),filename?filename:"(unknown)",sizex,sizey); } else { for (int y = 0; y<(int)((UV).height); ++y) for (int x = 0; x<(int)((UV).width); ++x) { const int x2=2*x, y2=2*y; tmp(x2,y2,1) = tmp(x2+1,y2,1) = tmp(x2,y2+1,1) = tmp(x2+1,y2+1,1) = UV(x,y,0); tmp(x2,y2,2) = tmp(x2+1,y2,2) = tmp(x2,y2+1,2) = tmp(x2+1,y2+1,2) = UV(x,y,1); } if (yuv2rgb) tmp.YCbCrtoRGB(); insert(tmp); } } } if (stopflag && last_frame>=0 && frame!=(unsigned int)last_frame) cimg::warn("CImgList<%s>::load_yuv() : File '%s', frame %d not reached since only %u frames were found in the file.", pixel_type(),filename?filename:"(unknown)",last_frame,frame-1,filename); if (!file) cimg::fclose(nfile); return *this; } static CImgList get_load_yuv(const char *const filename, const unsigned int sizex, const unsigned int sizey=1, const unsigned int first_frame=0, const int last_frame=-1, const bool yuv2rgb=false) { return CImgList().load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb); } CImgList& load_yuv(const char *const filename, const unsigned int sizex, const unsigned int sizey, const unsigned int first_frame=0, const int last_frame=-1, const bool yuv2rgb=false) { return load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb); } static CImgList get_load_ffmpeg(const char *const filename) { return CImgList().load_ffmpeg(filename); } CImgList& load_ffmpeg(const char *const filename) { char command[1024], filetmp[512], filetmp2[512]; std::FILE *file = 0; do { std::sprintf(filetmp,"%s%s%s",cimg::temporary_path(),1==2?"\\":"/",cimg::filenamerand()); std::sprintf(filetmp2,"%s_000001.ppm",filetmp); if ((file=std::fopen(filetmp2,"rb"))!=0) std::fclose(file); } while (file); std::sprintf(filetmp2,"%s_%%6d.ppm",filetmp); std::sprintf(command,"ffmpeg -i \"%s\" %s >/dev/null 2>&1",filename,filetmp2); cimg::system(command,0); const unsigned int odebug = cimg::exception_mode(); cimg::exception_mode() = 0; assign(); unsigned int i = 1; for (bool stopflag = false; !stopflag; ++i) { std::sprintf(filetmp2,"%s_%.6u.ppm",filetmp,i); CImg img; try { img.load_pnm(filetmp2); } catch (CImgException&) { stopflag = true; } if (img) { insert(img); std::remove(filetmp2); } } cimg::exception_mode() = odebug; if (is_empty()) throw CImgIOException("CImgList<%s>::load_ffmpeg() : Failed to open image sequence '%s'.\n" "Check the filename and if the 'ffmpeg' tool is installed on your system.", pixel_type(),filename); return *this; } template static CImgList get_load_off(std::FILE *const file, const char *const filename, CImgList& primitives, CImgList& colors, const bool invert_faces=false) { return CImgList().load_off(file,filename,primitives,colors,invert_faces); } template CImgList& load_off(std::FILE *const file, const char *const filename, CImgList& primitives, CImgList& colors, const bool invert_faces=false) { return assign(CImg::get_load_off(file,filename,primitives,colors,invert_faces).get_split('x')); } template static CImgList get_load_off(const char *const filename, CImgList& primitives, CImgList& colors, const bool invert_faces=false) { return CImgList().load_off(0,filename,primitives,colors,invert_faces); } template CImgList& load_off(const char *const filename, CImgList& primitives, CImgList& colors, const bool invert_faces=false) { return load_off(0,filename,primitives,colors,invert_faces); } CImgList get_load_tiff(const char *const filename, const unsigned int first_frame=0, const unsigned int last_frame=~0U) const { return CImgList().load_tiff(filename,first_frame,last_frame); } CImgList& load_tiff(const char *const filename, const unsigned int first_frame=0, const unsigned int last_frame=~0U) { if (first_frame>last_frame) throw CImgArgumentException("CImg<%s>::load_tiff() : File '%s', specified first frame = %u is higher than last frame = %u.", pixel_type(),first_frame,last_frame); if (first_frame || last_frame!=~0U) throw CImgArgumentException("CImgList<%s>::load_tiff() : File '%s', reading sub-images from a tiff file requires the use of libtiff.\n" "('cimg_use_tiff' must be defined).",pixel_type(),filename); return assign(CImg::get_load_tiff(filename)); } const CImgList& save(const char *const filename, const int number=-1) const { if (is_empty()) throw CImgInstanceException("CImgList<%s>::save() : Instance list (%u,%p) is empty (file '%s').", pixel_type(),size,data,filename); if (!filename) throw CImgArgumentException("CImg<%s>::save() : Instance list (%u,%p), specified filename is (null).", pixel_type(),size,data); const char *ext = cimg::filename_split(filename); char nfilename[1024]; const char *const fn = (number>=0)?cimg::filename_number(filename,number,6,nfilename):filename; if (!cimg::strncasecmp(ext,"cimg",4) || !ext[0]) return save_cimg(fn); if (!cimg::strncasecmp(ext,"yuv",3)) return save_yuv(fn,true); if (!cimg::strncasecmp(ext,"avi",3) || !cimg::strncasecmp(ext,"mov",3) || !cimg::strncasecmp(ext,"mpg",3) || !cimg::strncasecmp(ext,"mpeg",4)) return save_ffmpeg(fn); if (size==1) data[0].save(fn,-1); else for (unsigned int l=0; l<(*this).size; ++l) data[l].save(fn,l); return *this; } const CImgList& save_yuv(std::FILE *const file, const char *const filename=0, const bool rgb2yuv=true) const { if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_yuv() : Instance list (%u,%p) is empty (file '%s').", pixel_type(),size,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_yuv() : Instance list (%u,%p), specified file is (null).", pixel_type(),size,data); if ((*this)[0].dimx()%2 || (*this)[0].dimy()%2) throw CImgInstanceException("CImgList<%s>::save_yuv() : Image dimensions must be even numbers (current are %ux%u, file '%s').", pixel_type(),(*this)[0].dimx(),(*this)[0].dimy(),filename?filename:"(unknown)"); std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); for (unsigned int l=0; l<(*this).size; ++l) { CImg YCbCr((*this)[l]); if (rgb2yuv) YCbCr.RGBtoYCbCr(); cimg::fwrite(YCbCr.data,YCbCr.width*YCbCr.height,nfile); cimg::fwrite(YCbCr.get_resize(YCbCr.width/2, YCbCr.height/2,1,3,3).ptr(0,0,0,1), YCbCr.width*YCbCr.height/2,nfile); } if (!file) cimg::fclose(nfile); return *this; } const CImgList& save_yuv(const char *const filename=0, const bool rgb2yuv=true) const { return save_yuv(0,filename,rgb2yuv); } const CImgList& save_ffmpeg(const char *const filename, const char *const codec="mpeg2video") const { char command[1024], filetmp[512], filetmp2[512]; std::FILE *file = 0; for (unsigned int ll=0; ll<(*this).size; ++ll) if (!data[ll].is_sameXYZ(data[0])) throw CImgInstanceException("CImgList<%s>::save_ffmpeg() : All images of the sequence must be of the same dimension (file '%s').", pixel_type(),filename); do { std::sprintf(filetmp,"%s%s%s",cimg::temporary_path(),1==2?"\\":"/",cimg::filenamerand()); std::sprintf(filetmp2,"%s_000001.ppm",filetmp); if ((file=std::fopen(filetmp2,"rb"))!=0) std::fclose(file); } while (file); for (unsigned int l=0; l<(*this).size; ++l) { std::sprintf(filetmp2,"%s_%.6u.ppm",filetmp,l+1); if (data[l].depth>1 || data[l].dim!=3) data[l].get_resize(-100,-100,1,3).save_pnm(filetmp2); else data[l].save_pnm(filetmp2); } std::sprintf(command,"ffmpeg -i %s_%%6d.ppm -vcodec %s -sameq -y \"%s\" >/dev/null 2>&1",filetmp,codec,filename); cimg::system(command); file = std::fopen(filename,"rb"); if (!file) throw CImgIOException("CImg<%s>::save_ffmpeg() : Failed to save image sequence '%s'.\n\n", pixel_type(),filename); else cimg::fclose(file); for (unsigned int lll=0; lll<(*this).size; ++lll) { std::sprintf(filetmp2,"%s_%.6u.ppm",filetmp,lll+1); std::remove(filetmp2); } return *this; } const CImgList& save_cimg(std::FILE *const file, const char *const filename=0) const { if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_cimg() : Instance list (%u,%p) is empty (file '%s').", pixel_type(),size,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance list (%u,%p), specified file is (null).", pixel_type(),size,data); std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); const char *const ptype = pixel_type(), *const etype = cimg::endian()?"big":"little"; if (!cimg::strncmp(ptype,"unsigned",8)) std::fprintf(nfile,"%u unsigned_%s %s_endian\n",size,ptype+9,etype); else std::fprintf(nfile,"%u %s %s_endian\n",size,ptype,etype); for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = data[l]; std::fprintf(nfile,"%u %u %u %u\n",img.width,img.height,img.depth,img.dim); if (img.data) { if (cimg::endian()) { CImg tmp(img); cimg::endian_swap(tmp.data,tmp.size()); cimg::fwrite(tmp.data,img.width*img.height*img.depth*img.dim,nfile); } else cimg::fwrite(img.data,img.width*img.height*img.depth*img.dim,nfile); } } if (!file) cimg::fclose(nfile); return *this; } const CImgList& save_cimg(const char *const filename) const { return save_cimg(0,filename); } const CImgList& save_cimg(std::FILE *const file, const char *const filename, const unsigned int n0, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0) const { if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_cimg() : Instance list (%u,%p) is empty (file '%s').", pixel_type(),size,data,filename?filename:"(unknown)"); if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance list (%u,%p), specified file is (null).", pixel_type(),size,data); typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; std::FILE *const nfile = file?file:cimg::fopen(filename,"rb+"); bool saved = false, endian = cimg::endian(); char tmp[256], str_pixeltype[256], str_endian[256]; unsigned int j, err, N, W, H, D, V; int i; j = 0; while((i=std::fgetc(nfile))!='\n' && i!=(-1) && j<256) tmp[j++] = (char)i; tmp[j] = '\0'; err = std::sscanf(tmp,"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian); if (err<2) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImgList<%s>::save_cimg() : File '%s', Unknow CImg RAW header.", pixel_type(),filename?filename:"(FILE*)"); } if (!cimg::strncasecmp("little",str_endian,6)) endian = false; else if (!cimg::strncasecmp("big",str_endian,3)) endian = true; const unsigned int lmax = cimg::min(N,n0+size); if (!saved && !cimg::strcasecmp("bool",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(bool),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(bool); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(bool); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(bool); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(bool); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(bool); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(bool); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(bool); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(bool); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("unsigned_char",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(uchar),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(uchar); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(uchar); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(uchar); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(uchar); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(uchar); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(uchar); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(uchar); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(uchar); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("uchar",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(uchar),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(uchar); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(uchar); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(uchar); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(uchar); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(uchar); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(uchar); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(uchar); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(uchar); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("char",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(char),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(char); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(char); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(char); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(char); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(char); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(char); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(char); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(char); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("unsigned_short",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(ushort),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(ushort); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(ushort); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(ushort); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(ushort); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(ushort); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(ushort); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(ushort); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(ushort); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("ushort",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(ushort),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(ushort); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(ushort); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(ushort); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(ushort); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(ushort); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(ushort); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(ushort); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(ushort); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("short",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(short),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(short); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(short); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(short); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(short); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(short); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(short); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(short); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(short); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("unsigned_int",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(uint),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(uint); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(uint); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(uint); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(uint); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(uint); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(uint); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(uint); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(uint); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("uint",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(uint),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(uint); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(uint); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(uint); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(uint); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(uint); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(uint); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(uint); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(uint); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("int",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(int),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(int); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(int); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(int); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(int); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(int); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(int); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(int); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(int); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("unsigned_long",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(ulong),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(ulong); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(ulong); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(ulong); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(ulong); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(ulong); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(ulong); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(ulong); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(ulong); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("ulong",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(ulong),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(ulong); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(ulong); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(ulong); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(ulong); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(ulong); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(ulong); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(ulong); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(ulong); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("long",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(long),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(long); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(long); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(long); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(long); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(long); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(long); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(long); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(long); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("float",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(float),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(float); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(float); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(float); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(float); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(float); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(float); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(float); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(float); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved && !cimg::strcasecmp("double",str_pixeltype)) { for (unsigned int l=0; l::save_cimg() : File '%s', Image %u has an invalid size (%u,%u,%u,%u)\n", pixel_type(), filename?filename:("(FILE*)"), W, H, D, V); if (W*H*D*V>0) { if (l=W || y0>=H || z0>=D || v0>=D) std::fseek(nfile,W*H*D*V*sizeof(double),1); else { const CImg& img = (*this)[l-n0]; const T *ptrs = img.data; const unsigned int x1 = x0 + img.width - 1, y1 = y0 + img.height - 1, z1 = z0 + img.depth - 1, v1 = v0 + img.dim - 1, nx1 = x1>=W?W-1:x1, ny1 = y1>=H?H-1:y1, nz1 = z1>=D?D-1:z1, nv1 = v1>=V?V-1:v1; CImg raw(1+nx1-x0); const unsigned int skipvb = v0*W*H*D*sizeof(double); if (skipvb) std::fseek(nfile,skipvb,1); for (unsigned int v=1+nv1-v0; v; --v) { const unsigned int skipzb = z0*W*H*sizeof(double); if (skipzb) std::fseek(nfile,skipzb,1); for (unsigned int z=1+nz1-z0; z; --z) { const unsigned int skipyb = y0*W*sizeof(double); if (skipyb) std::fseek(nfile,skipyb,1); for (unsigned int y=1+ny1-y0; y; --y) { const unsigned int skipxb = x0*sizeof(double); if (skipxb) std::fseek(nfile,skipxb,1); raw.assign(ptrs, raw.width); ptrs+=img.width; if (endian) cimg::endian_swap(raw.data,raw.width); cimg::fwrite(raw.data,raw.width,nfile); const unsigned int skipxe = (W-1-nx1)*sizeof(double); if (skipxe) std::fseek(nfile,skipxe,1); } const unsigned int skipye = (H-1-ny1)*W*sizeof(double); if (skipye) std::fseek(nfile,skipye,1); } const unsigned int skipze = (D-1-nz1)*W*H*sizeof(double); if (skipze) std::fseek(nfile,skipze,1); } const unsigned int skipve = (V-1-nv1)*W*H*D*sizeof(double); if (skipve) std::fseek(nfile,skipve,1); } } } saved = true; }; if (!saved) { if (!file) cimg::fclose(nfile); throw CImgIOException("CImgList<%s>::save_cimg() : File '%s', cannot save images of pixels coded as '%s'.", pixel_type(),filename?filename:"(FILE*)",str_pixeltype); } if (!file) cimg::fclose(nfile); return *this; } const CImgList& save_cimg(std::FILE *const file, const unsigned int n0, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0) const { return save_cimg(file,0,n0,x0,y0,z0,v0); } const CImgList& save_cimg(const char *const filename, const unsigned int n0, const unsigned int x0, const unsigned int y0, const unsigned int z0, const unsigned int v0) const { return save_cimg(0,filename,n0,x0,y0,z0,v0); } static void save_empty_cimg(std::FILE *const file, const char *const filename, const unsigned int nb, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) { std::FILE *const nfile = file?file:cimg::fopen(filename,"wb"); const unsigned int siz = dx*dy*dz*dv*sizeof(T); std::fprintf(nfile,"%u %s\n",nb,pixel_type()); for (unsigned int i=nb; i; --i) { std::fprintf(nfile,"%u %u %u %u\n",dx,dy,dz,dv); for (unsigned int off=siz; off; --off) std::fputc(0,nfile); } if (!file) cimg::fclose(nfile); } static void save_empty_cimg(std::FILE *const file, const unsigned int nb, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) { return save_empty_cimg(file,0,nb,dx,dy,dz,dv); } static void save_empty_cimg(const char *const filename, const unsigned int nb, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) { return save_empty_cimg(0,filename,nb,dx,dy,dz,dv); } template const CImgList& save_off(std::FILE *const file, const char *const filename, const CImgList& primitives, const CImgList& colors, const bool invert_faces=false) const { get_append('x','y').save_off(file,filename,primitives,colors,invert_faces); return *this; } template const CImgList& save_off(const char *const filename, const CImgList& primitives, const CImgList& colors, const bool invert_faces=false) const { return save_off(0,filename,primitives,colors,invert_faces); } CImgList get_split(const char axe='x') const { CImgList res; for (unsigned int l=0; l<(*this).size; ++l) res.insert(data[l].get_split(axe)); return res; } CImgList& split(const char axe='x') { return get_split(axe).transfer_to(*this); } CImg get_append(const char axe='x', const char align='c') const { if (is_empty()) return CImg(); if (size==1) return +((*this)[0]); unsigned int dx = 0, dy = 0, dz = 0, dv = 0, pos = 0; CImg res; switch(cimg::uncase(axe)) { case 'x': { switch (cimg::uncase(align)) { case 'x': { dy = dz = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dx+=(*this)[l].size(); } break; case 'y': { dx = size; dz = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dy = cimg::max(dy,(unsigned int)(*this)[l].size()); } break; case 'z': { dx = size; dy = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dz = cimg::max(dz,(unsigned int)(*this)[l].size()); } break; case 'v': { dx = size; dy = dz = 1; for (unsigned int l=0; l<(*this).size; ++l) dv = cimg::max(dz,(unsigned int)(*this)[l].size()); } break; default: for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = (*this)[l]; dx += img.width; dy = cimg::max(dy,img.height); dz = cimg::max(dz,img.depth); dv = cimg::max(dv,img.dim); } } res.assign(dx,dy,dz,dv,0); switch (cimg::uncase(align)) { case 'x': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image(CImg((*this)[l],true).unroll('x'),pos,0,0,0); pos+=(*this)[l].size(); } } break; case 'y': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('y'),pos++,0,0,0); } break; case 'z': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('z'),pos++,0,0,0); } break; case 'v': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('v'),pos++,0,0,0); } break; case 'p': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],pos,0,0,0); pos+=(*this)[l].width; } } break; case 'n': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],pos,dy-(*this)[l].height,dz-(*this)[l].depth,dv-(*this)[l].dim); pos+=(*this)[l].width; } } break; default : { for (unsigned int l=0; l<(*this).size; ++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; } } break; } } break; case 'y': { switch (cimg::uncase(align)) { case 'x': { dy = size; dz = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dx = cimg::max(dx,(unsigned int)(*this)[l].size()); } break; case 'y': { dx = dz = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dy+=(*this)[l].size(); } break; case 'z': { dy = size; dx = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dz = cimg::max(dz,(unsigned int)(*this)[l].size()); } break; case 'v': { dy = size; dx = dz = 1; for (unsigned int l=0; l<(*this).size; ++l) dv = cimg::max(dv,(unsigned int)(*this)[l].size()); } break; default: for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = (*this)[l]; dx = cimg::max(dx,img.width); dy += img.height; dz = cimg::max(dz,img.depth); dv = cimg::max(dv,img.dim); } } res.assign(dx,dy,dz,dv,0); switch (cimg::uncase(align)) { case 'x': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('x'),0,pos++,0,0); } break; case 'y': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image(CImg((*this)[l],true).unroll('y'),0,pos,0,0); pos+=(*this)[l].size(); } } break; case 'z': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('z'),0,pos++,0,0); } break; case 'v': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('v'),0,pos++,0,0); } break; case 'p': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],0,pos,0,0); pos+=(*this)[l].height; } } break; case 'n': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],dx-(*this)[l].width,pos,dz-(*this)[l].depth,dv-(*this)[l].dim); pos+=(*this)[l].height; } } break; default : { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],(dx-(*this)[l].width)/2,pos,(dz-(*this)[l].depth)/2,(dv-(*this)[l].dim)/2); pos+=(*this)[l].height; } } break; } } break; case 'z': { switch (cimg::uncase(align)) { case 'x': { dz = size; dy = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dx = cimg::max(dx,(unsigned int)(*this)[l].size()); } break; case 'y': { dz = size; dx = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dy = cimg::max(dz,(unsigned int)(*this)[l].size()); } break; case 'z': { dx = dy = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dz+=(*this)[l].size(); } break; case 'v': { dz = size; dx = dz = 1; for (unsigned int l=0; l<(*this).size; ++l) dv = cimg::max(dv,(unsigned int)(*this)[l].size()); } break; default : for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = (*this)[l]; dx = cimg::max(dx,img.width); dy = cimg::max(dy,img.height); dz += img.depth; dv = cimg::max(dv,img.dim); } } res.assign(dx,dy,dz,dv,0); switch (cimg::uncase(align)) { case 'x': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('x'),0,0,pos++,0); } break; case 'y': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('y'),0,0,pos++,0); } break; case 'z': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image(CImg((*this)[l],true).unroll('z'),0,0,pos,0); pos+=(*this)[l].size(); } } break; case 'v': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('v'),0,0,pos++,0); } break; case 'p': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],0,0,pos,0); pos+=(*this)[l].depth; } } break; case 'n': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],dx-(*this)[l].width,dy-(*this)[l].height,pos,dv-(*this)[l].dim); pos+=(*this)[l].depth; } } break; case 'c': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],(dx-(*this)[l].width)/2,(dy-(*this)[l].height)/2,pos,(dv-(*this)[l].dim)/2); pos+=(*this)[l].depth; } } break; } } break; case 'v': { switch (cimg::uncase(align)) { case 'x': { dv = size; dy = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dx = cimg::max(dx,(unsigned int)(*this)[l].size()); } break; case 'y': { dv = size; dx = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dy = cimg::max(dz,(unsigned int)(*this)[l].size()); } break; case 'z': { dv = size; dx = dv = 1; for (unsigned int l=0; l<(*this).size; ++l) dz = cimg::max(dv,(unsigned int)(*this)[l].size()); } break; case 'v': { dx = dy = dz = 1; for (unsigned int l=0; l<(*this).size; ++l) dv+=(*this)[l].size(); } break; default : for (unsigned int l=0; l<(*this).size; ++l) { const CImg& img = (*this)[l]; dx = cimg::max(dx,img.width); dy = cimg::max(dy,img.height); dz = cimg::max(dz,img.depth); dv += img.dim; } } res.assign(dx,dy,dz,dv,0); switch (cimg::uncase(align)) { case 'x': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('x'),0,0,0,pos++); } break; case 'y': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('y'),0,0,0,pos++); } break; case 'z': { for (unsigned int l=0; l<(*this).size; ++l) res.draw_image(CImg((*this)[l],true).unroll('v'),0,0,0,pos++); } break; case 'v': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image(CImg((*this)[l],true).unroll('z'),0,0,0,pos); pos+=(*this)[l].size(); } } break; case 'p': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],0,0,0,pos); pos+=(*this)[l].dim; } } break; case 'n': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],dx-(*this)[l].width,dy-(*this)[l].height,dz-(*this)[l].depth,pos); pos+=(*this)[l].dim; } } break; case 'c': { for (unsigned int l=0; l<(*this).size; ++l) { res.draw_image((*this)[l],(dx-(*this)[l].width)/2,(dy-(*this)[l].height)/2,(dz-(*this)[l].depth)/2,pos); pos+=(*this)[l].dim; } } break; } } break; default: throw CImgArgumentException("CImgList<%s>::get_append() : unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe); } return res; } CImgList get_crop_font() const { CImgList res; for (unsigned int l=0; l<(*this).size; ++l) { const CImg& letter = (*this)[l]; int xmin = letter.width, xmax = 0; for (int y = 0; y<(int)((letter).height); ++y) for (int x = 0; x<(int)((letter).width); ++x) if (letter(x,y)) { if (xxmax) xmax=x; } if (xmin>xmax) res.insert(CImg(letter.width,letter.height,1,letter.dim,0)); else res.insert(letter.get_crop(xmin,0,xmax,letter.height-1)); } res[' '].resize(res['f'].width); res[' '+256].resize(res['f'].width); return res; } CImgList& crop_font() { return get_crop_font().transfer_to(*this); } static CImgList get_font(const unsigned int *const font, const unsigned int w, const unsigned int h, const unsigned int paddingx, const unsigned int paddingy, const bool variable_size=true) { CImgList res = CImgList(256,w,h,1,3).insert(CImgList(256,w,h,1,1)); const unsigned int *ptr = font; unsigned int m = 0, val = 0; for (unsigned int y=0; y>=1; if (!m) { m = 0x80000000; val = *(ptr++); } CImg& img = res[x/w], &mask = res[x/w+256]; unsigned int xm = x%w; img(xm,y,0) = img(xm,y,1) = img(xm,y,2) = mask(xm,y,0) = (T)((val&m)?1:0); } if (variable_size) res.crop_font(); if (paddingx || paddingy) for (unsigned int l=0; l<(res).size; ++l) res[l].resize(res[l].dimx()+paddingx, res[l].dimy()+paddingy,1,-100,0); return res; } CImgList& font(const unsigned int *const font, const unsigned int w, const unsigned int h, const unsigned int paddingx, const unsigned int paddingy, const bool variable_size=true) { return get_font(font,w,h,paddingx,paddingy,variable_size).transfer_to(*this); } static CImgList get_font(const unsigned int font_width, const bool variable_size=true) { if (font_width<=11) { static CImgList font7x11, nfont7x11; if (!variable_size && !font7x11) font7x11 = get_font(cimg::font7x11,7,11,1,0,false); if (variable_size && !nfont7x11) nfont7x11 = get_font(cimg::font7x11,7,11,1,0,true); return variable_size?nfont7x11:font7x11; } if (font_width<=13) { static CImgList font10x13, nfont10x13; if (!variable_size && !font10x13) font10x13 = get_font(cimg::font10x13,10,13,1,0,false); if (variable_size && !nfont10x13) nfont10x13 = get_font(cimg::font10x13,10,13,1,0,true); return variable_size?nfont10x13:font10x13; } if (font_width<=17) { static CImgList font8x17, nfont8x17; if (!variable_size && !font8x17) font8x17 = get_font(cimg::font8x17,8,17,1,0,false); if (variable_size && !nfont8x17) nfont8x17 = get_font(cimg::font8x17,8,17,1,0,true); return variable_size?nfont8x17:font8x17; } if (font_width<=19) { static CImgList font10x19, nfont10x19; if (!variable_size && !font10x19) font10x19 = get_font(cimg::font10x19,10,19,2,0,false); if (variable_size && !nfont10x19) nfont10x19 = get_font(cimg::font10x19,10,19,2,0,true); return variable_size?nfont10x19:font10x19; } if (font_width<=24) { static CImgList font12x24, nfont12x24; if (!variable_size && !font12x24) font12x24 = get_font(cimg::font12x24,12,24,2,0,false); if (variable_size && !nfont12x24) nfont12x24 = get_font(cimg::font12x24,12,24,2,0,true); return variable_size?nfont12x24:font12x24; } if (font_width<=32) { static CImgList font16x32, nfont16x32; if (!variable_size && !font16x32) font16x32 = get_font(cimg::font16x32,16,32,2,0,false); if (variable_size && !nfont16x32) nfont16x32 = get_font(cimg::font16x32,16,32,2,0,true); return variable_size?nfont16x32:font16x32; } if (font_width<=38) { static CImgList font19x38, nfont19x38; if (!variable_size && !font19x38) font19x38 = get_font(cimg::font19x38,19,38,3,0,false); if (variable_size && !nfont19x38) nfont19x38 = get_font(cimg::font19x38,19,38,3,0,true); return variable_size?nfont19x38:font19x38; } static CImgList font29x57, nfont29x57; if (!variable_size && !font29x57) font29x57 = get_font(cimg::font29x57,29,57,5,0,false); if (variable_size && !nfont29x57) nfont29x57 = get_font(cimg::font29x57,29,57,5,0,true); return variable_size?nfont29x57:font29x57; } CImgList& font(const unsigned int font_width, const bool variable_size=true) { return get_font(font_width,variable_size).transfer_to(*this); } const CImgList& display(CImgDisplay& disp, const char axe='x', const char align='c') const { get_append(axe,align).display(disp); return *this; } const CImgList& display(const char* title, const char axe='x', const char align='c', const int min_size=128, const int max_size=1024, const int print_flag=1) const { if (is_empty()) throw CImgInstanceException("CImgList<%s>::display() : Instance list (%u,%u) is empty.", pixel_type(),size,data); const CImg visu = get_append(axe,align); CImgDisplay disp; unsigned int w = visu.width+(visu.depth>1?visu.depth:0), h = visu.height+(visu.depth>1?visu.depth:0), XYZ[3]; print(title,print_flag); const unsigned int dmin = cimg::min(w,h), minsiz = min_size>=0?min_size:(-min_size)*dmin/100; if (dmin=0?max_size:(-max_size)*dmax/100; if (dmax>maxsiz) { w=w*maxsiz/dmax; w+=(w==0); h=h*maxsiz/dmax; h+=(h==0); } disp.assign(w,h,title,1,3); XYZ[0] = visu.width/2; XYZ[1] = visu.height/2; XYZ[2] = visu.depth/2; while (!disp.is_closed && !disp.key) visu.get_coordinates(1,disp,XYZ); return *this; } const CImgList& display(const char axe='x', const char align='c', const int min_size=128, const int max_size=1024, const int print_flag=1) const { char title[256] = { 0 }; std::sprintf(title,"CImgList<%s>",pixel_type()); return display(title,axe,align,min_size,max_size,print_flag); } }; namespace cimg { template inline int dialog(const char *title, const char *msg, const char *button1_txt, const char *button2_txt, const char *button3_txt, const char *button4_txt, const char *button5_txt, const char *button6_txt, const CImg& logo, const bool centering = false) { const unsigned char black[] = { 0,0,0 }, white[] = { 255,255,255 }, gray[] = { 200,200,200 }, gray2[] = { 150,150,150 }; CImgList buttons, cbuttons, sbuttons; if (button1_txt) { buttons.insert(CImg().draw_text(button1_txt,0,0,black,gray,13)); if (button2_txt) { buttons.insert(CImg().draw_text(button2_txt,0,0,black,gray,13)); if (button3_txt) { buttons.insert(CImg().draw_text(button3_txt,0,0,black,gray,13)); if (button4_txt) { buttons.insert(CImg().draw_text(button4_txt,0,0,black,gray,13)); if (button5_txt) { buttons.insert(CImg().draw_text(button5_txt,0,0,black,gray,13)); if (button6_txt) { buttons.insert(CImg().draw_text(button6_txt,0,0,black,gray,13)); }}}}}} if (!buttons.size) throw CImgArgumentException("cimg::dialog() : No buttons have been defined. At least one is necessary"); unsigned int bw = 0, bh = 0; for (unsigned int l=0; l<(buttons).size; ++l) { bw = cimg::max(bw,buttons[l].width); bh = cimg::max(bh,buttons[l].height); } bw+=8; bh+=8; if (bw<64) bw=64; if (bw>128) bw=128; if (bh<24) bh=24; if (bh>48) bh=48; CImg button(bw,bh,1,3); button.draw_rectangle(0,0,bw-1,bh-1,gray); button.draw_line(0,0,bw-1,0,white).draw_line(0,bh-1,0,0,white); button.draw_line(bw-1,0,bw-1,bh-1,black).draw_line(bw-1,bh-1,0,bh-1,black); button.draw_line(1,bh-2,bw-2,bh-2,gray2).draw_line(bw-2,bh-2,bw-2,1,gray2); CImg sbutton(bw,bh,1,3); sbutton.draw_rectangle(0,0,bw-1,bh-1,gray); sbutton.draw_line(0,0,bw-1,0,black).draw_line(bw-1,0,bw-1,bh-1,black); sbutton.draw_line(bw-1,bh-1,0,bh-1,black).draw_line(0,bh-1,0,0,black); sbutton.draw_line(1,1,bw-2,1,white).draw_line(1,bh-2,1,1,white); sbutton.draw_line(bw-2,1,bw-2,bh-2,black).draw_line(bw-2,bh-2,1,bh-2,black); sbutton.draw_line(2,bh-3,bw-3,bh-3,gray2).draw_line(bw-3,bh-3,bw-3,2,gray2); 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); 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); CImg cbutton(bw,bh,1,3); 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); 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); 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); for (unsigned int ll=0; ll<(buttons).size; ++ll) { cbuttons.insert(CImg(cbutton).draw_image(buttons[ll],1+(bw-buttons[ll].dimx())/2,1+(bh-buttons[ll].dimy())/2)); sbuttons.insert(CImg(sbutton).draw_image(buttons[ll],(bw-buttons[ll].dimx())/2,(bh-buttons[ll].dimy())/2)); buttons[ll] = CImg(button).draw_image(buttons[ll],(bw-buttons[ll].dimx())/2,(bh-buttons[ll].dimy())/2); } CImg canvas; if (msg) canvas = CImg().draw_text(msg,0,0,black,gray,13); const unsigned int bwall = (buttons.size-1)*(12+bw) + bw, w = cimg::max(196U,36+logo.width+canvas.width, 24+bwall), h = cimg::max(96U,36+canvas.height+bh,36+logo.height+bh), lx = 12 + (canvas.data?0:((w-24-logo.width)/2)), ly = (h-12-bh-logo.height)/2, tx = lx+logo.width+12, ty = (h-12-bh-canvas.height)/2, bx = (w-bwall)/2, by = h-12-bh; if (canvas.data) canvas = CImg(w,h,1,3). draw_rectangle(0,0,w-1,h-1,gray). draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white). draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black). draw_image(canvas,tx,ty); else canvas = CImg(w,h,1,3). draw_rectangle(0,0,w-1,h-1,gray). draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white). draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black); if (logo.data) canvas.draw_image(logo,lx,ly); unsigned int xbuttons[6]; for (unsigned int lll=0; lll<(buttons).size; ++lll) { xbuttons[lll] = bx+(bw+12)*lll; canvas.draw_image(buttons[lll],xbuttons[lll],by); } CImgDisplay disp(canvas,title?title:" ",0,3,false,centering?true:false); if (centering) disp.move((CImgDisplay::screen_dimx()-disp.dimx())/2, (CImgDisplay::screen_dimy()-disp.dimy())/2); bool stopflag = false, refresh = false; int oselected = -1, oclicked = -1, selected = -1, clicked = -1; while (!disp.is_closed && !stopflag) { if (refresh) { if (clicked>=0) CImg(canvas).draw_image(cbuttons[clicked],xbuttons[clicked],by).display(disp); else { if (selected>=0) CImg(canvas).draw_image(sbuttons[selected],xbuttons[selected],by).display(disp); else canvas.display(disp); } refresh = false; } disp.wait(15); if (disp.is_resized) disp.resize(disp); if (disp.button&1) { oclicked = clicked; clicked = -1; for (unsigned int l=0; l<(buttons).size; ++l) if (disp.mouse_y>=(int)by && disp.mouse_y<(int)(by+bh) && disp.mouse_x>=(int)xbuttons[l] && disp.mouse_x<(int)(xbuttons[l]+bw)) { clicked = selected = l; refresh = true; } if (clicked!=oclicked) refresh = true; } else if (clicked>=0) stopflag = true; if (disp.key) { oselected = selected; switch (disp.key) { case cimg::keyESC: selected=-1; stopflag=true; break; case cimg::keyENTER: if (selected<0) selected = 0; stopflag = true; break; case cimg::keyTAB: case cimg::keyARROWRIGHT: case cimg::keyARROWDOWN: selected = (selected+1)%buttons.size; break; case cimg::keyARROWLEFT: case cimg::keyARROWUP: selected = (selected+buttons.size-1)%buttons.size; break; } disp.key = 0; if (selected!=oselected) refresh = true; } } if (!disp) selected = -1; return selected; } inline int dialog(const char *title, const char *msg, const char *button1_txt, const char *button2_txt, const char *button3_txt, const char *button4_txt, const char *button5_txt, const char *button6_txt, const bool centering) { return dialog(title,msg,button1_txt,button2_txt,button3_txt,button4_txt,button5_txt,button6_txt, CImg::get_logo40x38(),centering); } template inline int _marching_cubes_indice(const unsigned int edge, const CImg& indices1, const CImg& indices2, const unsigned int x, const unsigned int y, const unsigned int nx, const unsigned int ny) { switch (edge) { case 0: return indices1(x,y,0); case 1: return indices1(nx,y,1); case 2: return indices1(x,ny,0); case 3: return indices1(x,y,1); case 4: return indices2(x,y,0); case 5: return indices2(nx,y,1); case 6: return indices2(x,ny,0); case 7: return indices2(x,y,1); case 8: return indices1(x,y,2); case 9: return indices1(nx,y,2); case 10: return indices1(nx,ny,2); case 11: return indices1(x,ny,2); } return 0; } template inline void marching_cubes(const tfunc& func, const float isovalue, const float x0, const float y0, const float z0, const float x1, const float y1, const float z1, const float resx, const float resy, const float resz, CImgList& points, CImgList& primitives, const bool invert_faces) { static unsigned int edges[256] = { 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000 }; static int triangles[256][16] = {{-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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}}; const unsigned int nx = (unsigned int)((x1-x0+1)/resx), nxm1 = nx-1, ny = (unsigned int)((y1-y0+1)/resy), nym1 = ny-1, nz = (unsigned int)((z1-z0+1)/resz), nzm1 = nz-1; if (!nxm1 || !nym1 || !nzm1) return; CImg indices1(nx,ny,1,3,-1), indices2(indices1); CImg values1(nx,ny), values2(nx,ny); float X = 0, Y = 0, Z = 0, nX = 0, nY = 0, nZ = 0; Y=y0; for (int y = 0; y<(int)((values1).height); ++y) { X = x0; for (int x = 0; x<(int)((values1).width); ++x) { values1(x,y) = (float)func(X,Y,z0); X+=resx; } Y+=resy; } Z = z0; nZ = Z + resz; for (unsigned int zi=0; zi::vector(Xi,Y,Z)); } if ((edge&2) && indices1(nxi,yi,1)<0) { const float Yi = Y + (isovalue-val1)*resy/(val2-val1); indices1(nxi,yi,1) = points.size; points.insert(CImg::vector(nX,Yi,Z)); } if ((edge&4) && indices1(xi,nyi,0)<0) { const float Xi = X + (isovalue-val3)*resx/(val2-val3); indices1(xi,nyi,0) = points.size; points.insert(CImg::vector(Xi,nY,Z)); } if ((edge&8) && indices1(xi,yi,1)<0) { const float Yi = Y + (isovalue-val0)*resy/(val3-val0); indices1(xi,yi,1) = points.size; points.insert(CImg::vector(X,Yi,Z)); } if ((edge&16) && indices2(xi,yi,0)<0) { const float Xi = X + (isovalue-val4)*resx/(val5-val4); indices2(xi,yi,0) = points.size; points.insert(CImg::vector(Xi,Y,nZ)); } if ((edge&32) && indices2(nxi,yi,1)<0) { const float Yi = Y + (isovalue-val5)*resy/(val6-val5); indices2(nxi,yi,1) = points.size; points.insert(CImg::vector(nX,Yi,nZ)); } if ((edge&64) && indices2(xi,nyi,0)<0) { const float Xi = X + (isovalue-val7)*resx/(val6-val7); indices2(xi,nyi,0) = points.size; points.insert(CImg::vector(Xi,nY,nZ)); } if ((edge&128) && indices2(xi,yi,1)<0) { const float Yi = Y + (isovalue-val4)*resy/(val7-val4); indices2(xi,yi,1) = points.size; points.insert(CImg::vector(X,Yi,nZ)); } if ((edge&256) && indices1(xi,yi,2)<0) { const float Zi = Z+ (isovalue-val0)*resz/(val4-val0); indices1(xi,yi,2) = points.size; points.insert(CImg::vector(X,Y,Zi)); } if ((edge&512) && indices1(nxi,yi,2)<0) { const float Zi = Z + (isovalue-val1)*resz/(val5-val1); indices1(nxi,yi,2) = points.size; points.insert(CImg::vector(nX,Y,Zi)); } if ((edge&1024) && indices1(nxi,nyi,2)<0) { const float Zi = Z + (isovalue-val2)*resz/(val6-val2); indices1(nxi,nyi,2) = points.size; points.insert(CImg::vector(nX,nY,Zi)); } if ((edge&2048) && indices1(xi,nyi,2)<0) { const float Zi = Z + (isovalue-val3)*resz/(val7-val3); indices1(xi,nyi,2) = points.size; points.insert(CImg::vector(X,nY,Zi)); } for (int *triangle=triangles[configuration]; *triangle!=-1; ) { const unsigned int p0 = *(triangle++), p1 = *(triangle++), p2 = *(triangle++); const tf i0 = (tf)(_marching_cubes_indice(p0,indices1,indices2,xi,yi,nxi,nyi)), i1 = (tf)(_marching_cubes_indice(p1,indices1,indices2,xi,yi,nxi,nyi)), i2 = (tf)(_marching_cubes_indice(p2,indices1,indices2,xi,yi,nxi,nyi)); if (invert_faces) primitives.insert(CImg::vector(i0,i1,i2)); else primitives.insert(CImg::vector(i0,i2,i1)); } } } } cimg::swap(values1,values2); cimg::swap(indices1,indices2); } } template inline int _marching_squares_indice(const unsigned int edge, const CImg& indices1, const CImg& indices2, const unsigned int x, const unsigned int nx) { switch (edge) { case 0: return (int)indices1(x,0); case 1: return (int)indices1(nx,1); case 2: return (int)indices2(x,0); case 3: return (int)indices1(x,1); } return 0; } template inline void marching_squares(const tfunc& func, const float isovalue, const float x0, const float y0, const float x1, const float y1, const float resx, const float resy, CImgList& points, CImgList& primitives) { static unsigned int edges[16] = { 0x0, 0x9, 0x3, 0xa, 0x6, 0xf, 0x5, 0xc, 0xc, 0x5, 0xf, 0x6, 0xa, 0x3, 0x9, 0x0 }; static int segments[16][4] = { { -1,-1,-1,-1 }, { 0,3,-1,-1 }, { 0,1,-1,-1 }, { 1,3,-1,-1 }, { 1,2,-1,-1 }, { 0,1,2,3 }, { 0,2,-1,-1 }, { 2,3,-1,-1 }, { 2,3,-1,-1 }, { 0,2,-1,-1}, { 0,3,1,2 }, { 1,2,-1,-1 }, { 1,3,-1,-1 }, { 0,1,-1,-1}, { 0,3,-1,-1}, { -1,-1,-1,-1 } }; const unsigned int nx = (unsigned int)((x1-x0+1)/resx), nxm1 = nx-1, ny = (unsigned int)((y1-y0+1)/resy), nym1 = ny-1; if (!nxm1 || !nym1) return; CImg indices1(nx,1,1,2,-1), indices2(nx,1,1,2); CImg values1(nx), values2(nx); float X = 0, Y = 0, nX = 0, nY = 0; for (int x = 0; x<(int)((values1).width); ++x) { values1(x) = (float)func(X,Y); X+=resx; } Y = y0; nY = Y + resy; for (unsigned int yi=0, nyi=1; yi::vector(Xi,Y)); } if ((edge&2) && indices1(nxi,1)<0) { const float Yi = Y + (isovalue-val1)*resy/(val2-val1); indices1(nxi,1) = points.size; points.insert(CImg::vector(nX,Yi)); } if ((edge&4) && indices2(xi,0)<0) { const float Xi = X + (isovalue-val3)*resx/(val2-val3); indices2(xi,0) = points.size; points.insert(CImg::vector(Xi,nY)); } if ((edge&8) && indices1(xi,1)<0) { const float Yi = Y + (isovalue-val0)*resy/(val3-val0); indices1(xi,1) = points.size; points.insert(CImg::vector(X,Yi)); } for (int *segment=segments[configuration]; *segment!=-1; ) { const unsigned int p0 = *(segment++), p1 = *(segment++); const tf i0 = (tf)(_marching_squares_indice(p0,indices1,indices2,xi,nxi)), i1 = (tf)(_marching_squares_indice(p1,indices1,indices2,xi,nxi)); primitives.insert(CImg::vector(i0,i1)); } } } values1.swap(values2); indices1.swap(indices2); } } } } using namespace cimg_library; void get_geom(const char *geom, int &geom_w, int &geom_h) { char tmp[16]; std::sscanf(geom,"%d%7[^0-9]%d%7[^0-9]",&geom_w,tmp,&geom_h,tmp+1); if (tmp[0]=='%') geom_w=-geom_w; if (tmp[1]=='%') geom_h=-geom_h; } template void greycstoration(int argc, char **argv, T pixel_type) { pixel_type = (T)0; cimg_library::cimg::option((char*)0,argc,argv,(char*)0," Open Source Algorithms for Image Denoising and Interpolation."); cimg_library::cimg::option((char*)0,argc,argv,"-------------------------------------------------------------------------\n" " GREYCstoration v2.8, by David Tschumperle. \n" " ------------------------------------------------------------------------\n" " This program allows to denoise, inpaint and resize 2D color images. \n" " It is the result of the research work done in the IMAGE group of the \n" " GREYC Lab (CNRS, UMR 6072) (http://www.greyc.ensicaen.fr/EquipeImage/) \n" " by David Tschumperle (http://www.greyc.ensicaen.fr/~dtschump/). This \n" " program has been primarily released to help people processing image data\n" " and to allow comparisons between regularization algorithms. This is an \n" " open source software, distributed within the CImg Library package \n" " (http://cimg.sourceforge.net), and submitted to the CeCILL License. If \n" " you are interested to distribute it in a closed-source product, please \n" " read the licence file carefully. If you are using 'GREYCstored' images \n" " in your own publications, be kind to reference the GREYCstoration web \n" " site or the related scientific papers. More informations available at : \n" " ** http://www.greyc.ensicaen.fr/~dtschump/greycstoration/ ** \n" "-------------------------------------------------------------------------\n",(char*)0); cimg_library::cimg::option((char*)0,argc,argv," + Global parameters\n -----------------------",(char*)0); const char *restore_mode = cimg_library::cimg::option("-restore",argc,argv,(char*)0,"Restore image specified after '-restore'"); const char *inpaint_mode = cimg_library::cimg::option("-inpaint",argc,argv,(char*)0,"Inpaint image specified after '-inpaint'"); const char *resize_mode = cimg_library::cimg::option("-resize",argc,argv,(char*)0,"Resize image specified after '-resize'"); const char *clean_mode = cimg_library::cimg::option("-clean",argc,argv,(char*)0,"Clean image specified after '-clean'"); const char *reference_image = cimg_library::cimg::option("-ref",argc,argv,(char*)0,"Reference image to compare with"); cimg_library::cimg::option("-bits",argc,argv,8,"Define input value type (8='uchar', 16='ushort', 32='float')"); const unsigned int value_factor = cimg_library::cimg::option("-fact",argc,argv,0,"Define input value factor (0=auto)"); const float noise_g = cimg_library::cimg::option("-ng",argc,argv,0.0f,"Add Gaussian noise before denoising"); const float noise_u = cimg_library::cimg::option("-nu",argc,argv,0.0f,"Add Uniform noise before denoising"); const float noise_s = cimg_library::cimg::option("-ns",argc,argv,0.0f,"Add Salt&Pepper noise before denoising"); const unsigned int color_base = cimg_library::cimg::option("-cbase",argc,argv,0,"Processed color base (0=RGB, 1=YCbCr)"); const char *channel_range = cimg_library::cimg::option("-crange",argc,argv,(char*)0,"Processed channels (ex: '0-2')"); const unsigned int saving_step = cimg_library::cimg::option("-save",argc,argv,0,"Iteration saving step (>=0)"); const bool visu = cimg_library::cimg::option("-visu",argc,argv,1?true:false,"Enable/Disable visualization windows (0 or 1)"); const char *file_o = cimg_library::cimg::option("-o",argc,argv,(char*)0,"Filename of output image"); const bool append_result = cimg_library::cimg::option("-append",argc,argv,false,"Append images in output file"); const bool verbose = cimg_library::cimg::option("-verbose",argc,argv,true,"Verbose mode"); const unsigned int jpg_quality = cimg_library::cimg::option("-quality",argc,argv,100,"Output compression quality (if JPEG format)"); unsigned int nb_iterations = cimg_library::cimg::option("-iter",argc,argv,(restore_mode||clean_mode)?1:(inpaint_mode?1000:3),"Number of iterations (>0)"); const float sdt = cimg_library::cimg::option("-sharp",argc,argv,(restore_mode||clean_mode)?0.0f:(inpaint_mode?0.0f:10.0f),"Sharpening strength (activate sharpening filter, >=0)"); const float sp = cimg_library::cimg::option("-se",argc,argv,(restore_mode||clean_mode)?0.5f:(inpaint_mode?0.5f:3.0f),"Sharpening edge threshold (>=0)"); const unsigned int tile_size = cimg_library::cimg::option("-tile",argc,argv,512,"Activate tiled mode and set tile size (>=0)"); const unsigned int tile_border = cimg_library::cimg::option("-btile",argc,argv,4,"Size of tile borders (>=0)"); const unsigned int nb_threads = cimg_library::cimg::option("-threads",argc,argv,1,"Number of threads used (*experimental*, tile mode only, >0)"); const bool fast_approx = cimg_library::cimg::option("-fast",argc,argv,true,"Try faster algorithm (true or false)"); float amplitude = 0, sharpness = 0, anisotropy = 0, alpha = 0, sigma = 0, gauss_prec = 0, dl = 0, da = 0, sigma_s = 0, sigma_p = 0; unsigned int interpolation = 0, patch_size = 0, lookup_size = 0; if (argc==1 || (!restore_mode && !inpaint_mode && !resize_mode && !clean_mode) || (restore_mode && inpaint_mode) || (restore_mode && resize_mode) || (restore_mode && clean_mode) || (inpaint_mode && resize_mode) || (inpaint_mode && clean_mode)) { std::fprintf(stderr,"\n%s : You must specify (only) one of the '-restore', '-inpaint', '-resize' or '-clean' options.\n" "(try option '-h', '-h -restore','-h -inpaint', '-h -resize' or '-h -clean' to get options relative to specific actions\n\n", cimg::basename(argv[0])); std::exit(0); } CImg img0, img, imgr; CImg mask; CImgDisplay disp; if (restore_mode) { cimg_library::cimg::option((char*)0,argc,argv,"\n + Restoration mode parameters\n ---------------------------",(char*)0); amplitude = cimg_library::cimg::option("-dt",argc,argv,40.0f,"Regularization strength per iteration (>=0)"); sharpness = cimg_library::cimg::option("-p",argc,argv,0.9f,"Contour preservation (>=0)"); anisotropy = cimg_library::cimg::option("-a",argc,argv,0.15f,"Smoothing anisotropy (0<=a<=1)"); alpha = cimg_library::cimg::option("-alpha",argc,argv,0.6f,"Noise scale (>=0)"); sigma = cimg_library::cimg::option("-sigma",argc,argv,1.1f,"Geometry regularity (>=0)"); gauss_prec = cimg_library::cimg::option("-prec",argc,argv,2.0f,"Computation precision (>0)"); dl = cimg_library::cimg::option("-dl",argc,argv,0.8f,"Spatial integration step (0<=dl<=1)"); da = cimg_library::cimg::option("-da",argc,argv,30.0f,"Angular integration step (0<=da<=90)"); interpolation = cimg_library::cimg::option("-interp",argc,argv,0,"Interpolation type (0=Nearest-neighbor, 1=Linear, 2=Runge-Kutta)"); if (verbose) std::fprintf(stderr,"- Image Restoration mode\n"); if (!cimg::strcmp("-restore",restore_mode)) { std::fprintf(stderr,"%s : You must specify a valid input image filename after the '-restore' flag.\n\n",cimg::basename(argv[0])); std::exit(0); } if (verbose) std::fprintf(stderr,"- Load input image '%s'...",cimg::basename(restore_mode)); img.load(restore_mode); if (verbose) std::fprintf(stderr,"\r- Input image : '%s' (size %dx%d, value range [%g,%g])\n", cimg::basename(restore_mode),img.dimx(),img.dimy(),(double)img.min(),(double)img.max()); if (noise_g || noise_u || noise_s) { img0 = img; img.noise(noise_g,0).noise(noise_u,1).noise(noise_s,2); if (verbose) std::fprintf(stderr,"\r- Noisy image : value range [%g,%g], PSNR Noisy / Original : %g\n",(double)img.min(),(double)img.max(),img.PSNR(img0)); } } if (inpaint_mode) { cimg_library::cimg::option((char*)0,argc,argv,"\n + Inpainting mode parameters\n --------------------------",(char*)0); const char *file_m = cimg_library::cimg::option("-m",argc,argv,(char*)0,"Input inpainting mask"); const unsigned int dilate = cimg_library::cimg::option("-dilate",argc,argv,0,"Inpainting mask dilatation (>=0)"); const unsigned int init = cimg_library::cimg::option("-init",argc,argv,4,"Inpainting init (0=black, 1=white, 2=noise, 3=unchanged, 4=smart)"); amplitude = cimg_library::cimg::option("-dt",argc,argv,20.0f,"Regularization strength per iteration (>=0)"); sharpness = cimg_library::cimg::option("-p",argc,argv,0.3f,"Contour preservation (>=0)"); anisotropy = cimg_library::cimg::option("-a",argc,argv,1.0f,"Smoothing anisotropy (0<=a<=1)"); alpha = cimg_library::cimg::option("-alpha",argc,argv,0.8f,"Noise scale (>=0)"); sigma = cimg_library::cimg::option("-sigma",argc,argv,2.0f,"Geometry regularity (>=0)"); gauss_prec = cimg_library::cimg::option("-prec",argc,argv,2.0f,"Computation precision (>0)"); dl = cimg_library::cimg::option("-dl",argc,argv,0.8f,"Spatial integration step (0<=dl<=1)"); da = cimg_library::cimg::option("-da",argc,argv,30.0f,"Angular integration step (0<=da<=90)"); interpolation = cimg_library::cimg::option("-interp",argc,argv,0,"Interpolation type (0=Nearest-neighbor, 1=Linear, 2=Runge-Kutta)"); if (verbose) std::fprintf(stderr,"- Image Inpainting mode\n"); if (!cimg::strcmp("-inpaint",inpaint_mode)) { std::fprintf(stderr,"%s : You must specify a valid input image filename after the '-inpaint' flag.\n\n",cimg::basename(argv[0])); std::exit(0); } if (verbose) std::fprintf(stderr,"- Load input image '%s'...",cimg::basename(inpaint_mode)); img.load(inpaint_mode); if (verbose) std::fprintf(stderr,"\r- Input image : '%s' (size %dx%d, value range [%g,%g])\n", cimg::basename(inpaint_mode),img.dimx(),img.dimy(),(double)img.min(),(double)img.max()); if (noise_g || noise_u || noise_s) { img0 = img; img.noise(noise_g,0).noise(noise_u,1).noise(noise_s,2); if (verbose) std::fprintf(stderr,"\r- Noisy image : value range [%g,%g], PSNR Noisy / Original : %g\n",(double)img.min(),(double)img.max(),img.PSNR(img0)); } if (!file_m) { std::fprintf(stderr,"%s : You need to specify a valid inpainting mask filename after the '-m' flag.\n\n",cimg::basename(argv[0])); std::exit(0); } if (cimg::strncasecmp("block",file_m,5)) { if (verbose) std::fprintf(stderr,"- Load inpainting mask '%s'...",cimg::basename(file_m)); mask.load(file_m); if (verbose) std::fprintf(stderr,"\r- Inpainting mask : '%s' (size %dx%d)\n",cimg::basename(file_m),mask.dimx(),mask.dimy()); } else { unsigned int l = 16; std::sscanf(file_m,"block%u",&l); mask.assign(img.dimx()/l,img.dimy()/l); for (int y = 0; y<(int)((mask).height); ++y) for (int x = 0; x<(int)((mask).width); ++x) mask(x,y) = (x+y)%2; img0 = img; } mask.resize(img.dimx(),img.dimy(),1,1); if (dilate) mask.dilate(dilate); switch (init) { case 0 : { for (int k = 0; k<(int)((img).dim); ++k) for (int y = 0; y<(int)((img).height); ++y) for (int x = 0; x<(int)((img).width); ++x) if (mask(x,y)) img(x,y,k) = 0; } break; case 1 : { for (int k = 0; k<(int)((img).dim); ++k) for (int y = 0; y<(int)((img).height); ++y) for (int x = 0; x<(int)((img).width); ++x) if (mask(x,y)) img(x,y,k) = 255; } break; case 2 : { for (int k = 0; k<(int)((img).dim); ++k) for (int y = 0; y<(int)((img).height); ++y) for (int x = 0; x<(int)((img).width); ++x) if (mask(x,y)) img(x,y,k) = (T)(255*cimg::rand()); } break; case 3 : break; default: { typedef unsigned char uchar; CImg tmask(mask), ntmask(tmask); uchar M[9]; uchar& Mpp = M[0]; uchar& Mcp = M[1]; uchar& Mnp = M[2]; uchar& Mpc = M[3]; uchar& Mcc = M[4]; uchar& Mnc = M[5]; uchar& Mpn = M[6]; uchar& Mcn = M[7]; uchar& Mnn = M[8]; Mpp = Mcp = Mnp = Mpc = Mcc = Mnc = Mpn = Mcn = Mnn = 0; Mpp = Mnp = Mpn = Mnn = 0; T I[9]; T& Ipp = I[0]; T& Icp = I[1]; T& Inp = I[2]; T& Ipc = I[3]; T& Icc = I[4]; T& Inc = I[5]; T& Ipn = I[6]; T& Icn = I[7]; T& Inn = I[8]; Ipp = Icp = Inp = Ipc = Icc = Inc = Ipn = Icn = Inn = 0; Ipp = Inp = Icc = Ipn = Inn = 0; while (ntmask.max()>0) { for (int y = 0, _p1y = 0, _n1y = 1>=((tmask).height)?(int)((tmask).height)-1:1; _n1y<(int)((tmask).height) || y==--_n1y; _p1y = y++, ++_n1y) for (int x = 0, _p1x = 0, _n1x = (int)( (M[0] = M[1] = (tmask)(0,_p1y,0,0)), (M[3] = M[4] = (tmask)(0,y,0,0)), (M[6] = M[7] = (tmask)(0,_n1y,0,0)), 1>=(tmask).width?(int)((tmask).width)-1:1); (_n1x<(int)((tmask).width) && ( (M[2] = (tmask)(_n1x,_p1y,0,0)), (M[5] = (tmask)(_n1x,y,0,0)), (M[8] = (tmask)(_n1x,_n1y,0,0)),1)) || x==--_n1x; M[0] = M[1], M[1] = M[2], M[3] = M[4], M[4] = M[5], M[6] = M[7], M[7] = M[8], _p1x = x++, ++_n1x) if (Mcc && (!Mpc || !Mnc || !Mcp || !Mcn)) { const float ccp = Mcp?0.0f:1.0f, cpc = Mpc?0.0f:1.0f, cnc = Mnc?0.0f:1.0f, ccn = Mcn?0.0f:1.0f, csum = ccp + cpc + cnc + ccn; for (int k = 0; k<(int)((img).dim); ++k) { I[0] = (img)(_p1x,_p1y,0,k), I[1] = (img)(x,_p1y,0,k), I[2] = (img)(_n1x,_p1y,0,k), I[3] = (img)(_p1x, y,0,k), I[4] = (img)(x, y,0,k), I[5] = (img)(_n1x, y,0,k), I[6] = (img)(_p1x,_n1y,0,k), I[7] = (img)(x,_n1y,0,k), I[8] = (img)(_n1x,_n1y,0,k); img(x,y,k) = (T)((ccp*Icp + cpc*Ipc + cnc*Inc + ccn*Icn)/csum); } ntmask(x,y) = 0; } tmask = ntmask; } } break; } } if (resize_mode) { cimg_library::cimg::option((char*)0,argc,argv,"\n + Resizing mode parameters\n ------------------------",(char*)0); const char *geom0 = cimg_library::cimg::option("-g0",argc,argv,(char*)0,"Input image geometry"); const char *geom = cimg_library::cimg::option("-g",argc,argv,(char*)0,"Output image geometry"); const bool anchor = cimg_library::cimg::option("-anchor",argc,argv,true,"Anchor original pixels (keep their original values)"); const unsigned int init = cimg_library::cimg::option("-init",argc,argv,3,"Initial estimate (1=block, 3=linear, 4=Moving average, 5=bicubic)"); amplitude = cimg_library::cimg::option("-dt",argc,argv,20.0f,"Regularization strength per iteration (>=0)"); sharpness = cimg_library::cimg::option("-p",argc,argv,0.2f,"Contour preservation (>=0)"); anisotropy = cimg_library::cimg::option("-a",argc,argv,0.9f,"Smoothing anisotropy (0<=a<=1)"); alpha = cimg_library::cimg::option("-alpha",argc,argv,0.1f,"Noise scale (>=0)"); sigma = cimg_library::cimg::option("-sigma",argc,argv,1.5f,"Geometry regularity (>=0)"); gauss_prec = cimg_library::cimg::option("-prec",argc,argv,2.0f,"Computation precision (>0)"); dl = cimg_library::cimg::option("-dl",argc,argv,0.8f,"Spatial integration step (0<=dl<=1)"); da = cimg_library::cimg::option("-da",argc,argv,30.0f,"Angular integration step (0<=da<=90)"); interpolation = cimg_library::cimg::option("-interp",argc,argv,0,"Interpolation type (0=Nearest-neighbor, 1=Linear, 2=Runge-Kutta)"); if (verbose) std::fprintf(stderr,"- Image Resizing mode\n"); if (!geom && !geom0) { std::fprintf(stderr,"%s : You need to specify an output geometry or an input geometry (option -g or -g0).\n\n",cimg::basename(argv[0])); std::exit(0); } if (!cimg::strcmp("-resize",resize_mode)) { std::fprintf(stderr,"%s : You must specify a valid input image filename after the '-resize' flag.\n\n",cimg::basename(argv[0])); std::exit(0); } if (verbose) std::fprintf(stderr,"- Load input image '%s'...",cimg::basename(resize_mode)); img.load(resize_mode); if (verbose) std::fprintf(stderr,"\r- Input image : '%s' (size %dx%d, value range [%g,%g])\n", cimg::basename(resize_mode),img.dimx(),img.dimy(),(double)img.min(),(double)img.max()); if (noise_g || noise_u || noise_s) { img0 = img; img.noise(noise_g,0).noise(noise_u,1).noise(noise_s,2); if (verbose) std::fprintf(stderr,"\r- Noisy image : value range [%g,%g], PSNR Noisy / Original : %g\n",(double)img.min(),(double)img.max(),img.PSNR(img0)); } int w, h; if (geom0) { int w0, h0; get_geom(geom0,w0,h0); w0 = w0>0?w0:-w0*img.dimx()/100; h0 = h0>0?h0:-h0*img.dimy()/100; if (verbose) std::fprintf(stderr,"- Reducing geometry to %dx%d using %s interpolation.\n",w0,h0,init==1?"bloc":(init==3?"linear":(init==5?"bicubic":"moving average"))); img0.assign(img); w = img.dimx(); h = img.dimy(); img.resize(w0,h0,-100,-100,5); } if (geom) { get_geom(geom,w,h); w = w>0?w:-w*img.dimx()/100; h = h>0?h:-h*img.dimy()/100; } mask.assign(img.dimx(),img.dimy(),1,1,255); if (!anchor) mask.resize(w,h,1,1,1); else mask = !mask.resize(w,h,1,1,4); img.resize(w,h,1,-100,init); if (img0) { if (verbose) std::fprintf(stderr,"\r- PSNR Original / Thumbnail : %g\n",img.PSNR(img0)); } } if (clean_mode) { cimg_library::cimg::option((char*)0,argc,argv,"\n + Cleaning mode parameters\n ------------------------",(char*)0); patch_size = cimg_library::cimg::option("-p",argc,argv,4,"Patch size (>0)"); sigma_s = cimg_library::cimg::option("-ss",argc,argv,15.0f,"Spatial sigma (>0)"); sigma_p = cimg_library::cimg::option("-sp",argc,argv,10.0f,"Patch sigma (>0)"); lookup_size = cimg_library::cimg::option("-r",argc,argv,7,"Size of the lookup region (>0)"); if (verbose) std::fprintf(stderr,"- Image Cleaning mode\n"); if (!cimg::strcmp("-clean",clean_mode)) { std::fprintf(stderr,"%s : You must specify a valid input image filename after the '-clean' flag.\n\n",cimg::basename(argv[0])); std::exit(0); } if (verbose) std::fprintf(stderr,"- Load input image '%s'...",cimg::basename(clean_mode)); img.load(clean_mode); if (verbose) std::fprintf(stderr,"\r- Input image : '%s' (size %dx%d, value range [%g,%g])\n", cimg::basename(clean_mode),img.dimx(),img.dimy(),(double)img.min(),(double)img.max()); if (noise_g || noise_u || noise_s) { img0 = img; img.noise(noise_g,0).noise(noise_u,1).noise(noise_s,2); if (verbose) std::fprintf(stderr,"\r- Noisy image : value range [%g,%g], PSNR Noisy / Original : %g\n",(double)img.min(),(double)img.max(),img.PSNR(img0)); } } if (reference_image) { if (verbose) std::fprintf(stderr,"- Load reference image '%s'...",cimg::basename(reference_image)); imgr.load(reference_image); if (verbose) std::fprintf(stderr,"\r- Reference image : '%s' (size %dx%d, value range [%g,%g])", cimg::basename(reference_image),imgr.dimx(),imgr.dimy(),(double)imgr.min(),(double)imgr.max()); if (img0) { imgr.resize(img0); if (verbose) std::fprintf(stderr,", PSNR Reference / Original : %g dB\n",imgr.PSNR(img0)); } else { imgr.resize(img); if (verbose) std::fprintf(stderr,"\n"); } } CImg dest(img); unsigned int crange_beg = 0, crange_end = dest.dimv()-1U; if (color_base) dest.RGBtoYCbCr(); if (channel_range) std::sscanf(channel_range,"%u%*c%u",&crange_beg,&crange_end); if (verbose) std::fprintf(stderr,"- Color base : %s, Channels range : %u-%u\n",color_base?"YCbCr":"RGB",crange_beg,crange_end); if (!visu && !append_result) img.assign(); if (visu) { const int sx = 2*CImgDisplay::screen_dimx()/3, sy = 2*CImgDisplay::screen_dimy()/3; int nwidth = dest.dimx(), nheight = dest.dimy(); if (nwidth>sx) { nheight = nheight*sx/nwidth; nwidth = sx; } if (nheight>sy) { nwidth = nwidth*sy/nheight; nheight = sy; } disp.assign(nwidth,nheight,"GREYCstoration"); if (color_base) dest.get_YCbCrtoRGB().display(disp); else dest.display(disp); } const float gfact = (value_factor>0)?value_factor:((sizeof(T)==2)?1.0f/256:1.0f); bool stop_all = false; for (unsigned int iter=0; iter dest_range = dest.get_shared_channels(crange_beg,crange_end); if (restore_mode) dest_range.greycstoration_run(amplitude,sharpness,anisotropy,alpha,sigma,gfact,dl,da,gauss_prec, interpolation,fast_approx,tile_size,tile_border,nb_threads); if (clean_mode) dest_range.greycstoration_patch_run(patch_size,sigma_s,sigma_p,lookup_size, tile_size,tile_border,nb_threads,fast_approx); if (inpaint_mode || resize_mode) dest_range.greycstoration_run(mask,amplitude,sharpness,anisotropy,alpha,sigma,gfact,dl,da,gauss_prec, interpolation,fast_approx,tile_size,tile_border,nb_threads); do { const unsigned int progress = (unsigned int)dest_range.greycstoration_progress(); if (verbose) std::fprintf(stderr,"\r- Processing : Iteration %u/%u (%u%%)\t\t",1+iter,nb_iterations,progress); if (disp) { if (disp.is_resized) disp.resize(); disp.set_title("Processing : Iteration %u/%u (%u%%)",1+iter,nb_iterations,progress); if (disp.is_closed || disp.key==cimg::keyQ || disp.key==cimg::keyESC) { dest_range.greycstoration_stop(); stop_iteration = true; iter = nb_iterations-1; } } cimg::wait(200); } while (dest_range.greycstoration_is_running()); if (!stop_iteration && sdt>0) dest_range.sharpen(sdt,sp,alpha/3,sigma/3); dest_range.cut(cimg::type::min(),cimg::type::max()); CImg tmp_rgb = color_base?dest.get_YCbCrtoRGB():CImg(), &dest_rgb = color_base?tmp_rgb:dest; if (disp && visu) dest_rgb.display(disp); if (file_o && saving_step && !(iter%saving_step)) dest_rgb.save(file_o,iter); if (iter==nb_iterations-1) { if (verbose) std::fprintf(stderr,"\r- Processing : Done ! \n"); if (img0) { if (verbose) std::fprintf(stderr,"- PSNR Restored / Original : %g dB\n",dest_rgb.PSNR(img0)); } if (disp) { static bool first_time = true; if (first_time) { first_time = false; if (verbose) std::fprintf(stderr, "- GREYCstoration interface :\n" " > You can now zoom to a particular rectangular region,\n" " or press one of the following key on the display window :\n" " SPACE : Swap views.\n" " S : Save a snapshot of the current image.\n" " I : Run another iteration.\n" " Q : Quit GREYCstoration.\n"); } CImgList visu; visu.insert(img0,~0,true).insert(img,~0,true).insert(dest_rgb,~0,true).insert(imgr,~0U,true); const char *titles[4] = { "original", "noisy", "restored", "reference"}; unsigned int visupos = 2; CImgDisplay dispz; CImg zoom; int snb = 0; bool stop_interact = false; while (!stop_interact) { disp.show().set_title("GREYCstoration (%s)",titles[visupos]); const CImg s = visu(visupos).get_coordinates(2,disp); if (disp.is_closed) stop_interact = true; switch (disp.key) { case cimg::keySPACE: do { visupos = (visupos+1)%visu.size; } while (!visu(visupos)); break; case cimg::keyBACKSPACE: do { visupos = (visupos-1+visu.size)%visu.size; } while (!visu(visupos)); break; case cimg::keyQ: stop_interact = stop_all = true; break; case cimg::keyI: stop_interact = true; if (verbose) std::fprintf(stderr,"- Perform iteration %u...\n",++nb_iterations); dest_rgb.display(disp); break; case cimg::keyS: if (!snb) { if (!append_result) dest_rgb.save(file_o?file_o:"GREYCstoration.bmp"); else CImgList(img,dest_rgb).get_append('x').save(file_o?file_o:"GREYCstoration.bmp"); } if (zoom) zoom.save(file_o?file_o:"GREYCstoration.bmp",snb); if (verbose) std::fprintf(stderr,"- Snapshot %u : '%s' saved\n",snb++,file_o?file_o:"GREYCstoration.bmp"); break; } disp.key = 0; if (disp.is_resized) disp.resize().display(visu(visupos)); if (dispz && dispz.is_resized) dispz.resize().display(zoom); if (dispz && dispz.is_closed) dispz.assign(); if (s[0]>=0 && s[1]>=0 && s[3]>=0 && s[4]>=0) { const int x0 = s[0], y0 = s[1], x1 = s[3], y1 = s[4]; if (cimg::abs(x0-x1)>4 && cimg::abs(y0-y1)>4) { CImgList tmp(img.get_crop(x0,y0,x1,y1), dest_rgb.get_crop(x0,y0,x1,y1)); if (img0) tmp.insert(img0.get_crop(x0,y0,x1,y1),0); if (imgr) tmp.insert(imgr.get_crop(x0,y0,x1,y1)); zoom = tmp.get_append('x','c'); if (!dispz) { const int sx = 5*CImgDisplay::screen_dimx()/6, sy = 5*CImgDisplay::screen_dimy()/6; int nwidth = zoom.dimx(), nheight = zoom.dimy(); if (nwidth>nheight) { nheight = nheight*sx/nwidth; nwidth = sx; } else { nwidth = nwidth*sy/nheight; nheight = sy; } dispz.assign(zoom.get_resize(nwidth,nheight)); dispz.set_title("GREYCstoration (zoom) : - %s %s %s %s", img0?"original -":"", img?"noisy -":"", dest?"restored -":"", imgr?"reference -":""); } else dispz.resize(dispz.dimx(),dispz.dimx()*zoom.dimy()/zoom.dimx(),false); dispz.display(zoom).show(); } } } } } } if (file_o) { CImg tmp_rgb = color_base?dest.get_YCbCrtoRGB():CImg(), &dest_rgb = color_base?tmp_rgb:dest; if (jpg_quality) { if (verbose) std::fprintf(stderr,"\n- Saving output image '%s' (JPEG quality = %u%%)\n",file_o,jpg_quality); if (!append_result) dest_rgb.save_jpeg(file_o,jpg_quality); else CImgList(img,dest_rgb).get_append('x').save_jpeg(file_o,jpg_quality); } else { if (verbose) std::fprintf(stderr,"\n- Saving output image '%s'\n",file_o); if (!append_result) dest_rgb.save(file_o); else CImgList(img,dest_rgb).get_append('x').save(file_o); } } if (verbose) std::fprintf(stderr,"\n- Quit\n\n"); } int main(int argc,char **argv) { switch (cimg_library::cimg::option("-bits",argc,argv,8,0)) { case 32: { float pixel_type = 0; greycstoration(argc,argv,pixel_type); } break; case 16: { unsigned short pixel_type = 0; greycstoration(argc,argv,pixel_type); } break; default: { unsigned char pixel_type = 0; greycstoration(argc,argv,pixel_type); } break; } return 0; }