Newer
Older
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
int p, q;
if (is_symmetric) for (p = 0, q = l - 1; p<q && (signed char)str[p]<=' ' && (signed char)str[q]<=' '; ) {
--q; ++p; if (!is_iterative) break;
} else {
for (p = 0; p<l && (signed char)str[p]<=' '; ) { ++p; if (!is_iterative) break; }
for (q = l - 1; q>p && (signed char)str[q]<=' '; ) { --q; if (!is_iterative) break; }
}
const int n = q - p + 1;
if (n!=l) { std::memmove(str,str + p,(unsigned int)n); str[n] = 0; return true; }
return false;
}
//! Replace reserved characters (for Windows filename) by another character.
/**
\param[in,out] str C-string to work with (modified at output).
\param[in] c Replacement character.
**/
inline void strwindows_reserved(char *const str, const char c='_') {
for (char *s = str; *s; ++s) {
const char i = *s;
if (i=='<' || i=='>' || i==':' || i=='\"' || i=='/' || i=='\\' || i=='|' || i=='?' || i=='*') *s = c;
}
}
//! Replace escape sequences in C-strings by their binary ascii values.
/**
\param[in,out] str C-string to work with (modified at output).
**/
inline void strunescape(char *const str) {
#define cimg_strunescape(ci,co) case ci : *nd = co; ++ns; break;
unsigned int val = 0;
for (char *ns = str, *nd = str; *ns || (bool)(*nd=0); ++nd) if (*ns=='\\') switch (*(++ns)) {
cimg_strunescape('a','\a');
cimg_strunescape('b','\b');
cimg_strunescape('e',0x1B);
cimg_strunescape('f','\f');
cimg_strunescape('n','\n');
cimg_strunescape('r','\r');
cimg_strunescape('t','\t');
cimg_strunescape('v','\v');
cimg_strunescape('\\','\\');
cimg_strunescape('\'','\'');
cimg_strunescape('\"','\"');
cimg_strunescape('\?','\?');
case 0 : *nd = 0; break;
case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' :
cimg_sscanf(ns,"%o",&val); while (*ns>='0' && *ns<='7') ++ns;
*nd = (char)val; break;
case 'x' :
cimg_sscanf(++ns,"%x",&val);
while ((*ns>='0' && *ns<='9') || (*ns>='a' && *ns<='f') || (*ns>='A' && *ns<='F')) ++ns;
*nd = (char)val; break;
default : *nd = *(ns++);
} else *nd = *(ns++);
}
// Return a temporary string describing the size of a memory buffer.
inline const char *strbuffersize(const cimg_ulong size);
// Return string that identifies the running OS.
inline const char *stros() {
#if defined(linux) || defined(__linux) || defined(__linux__)
static const char *const str = "Linux";
#elif defined(sun) || defined(__sun)
static const char *const str = "Sun OS";
#elif defined(BSD) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined (__DragonFly__)
static const char *const str = "BSD";
#elif defined(sgi) || defined(__sgi)
static const char *const str = "Irix";
#elif defined(__MACOSX__) || defined(__APPLE__)
static const char *const str = "Mac OS";
#elif defined(unix) || defined(__unix) || defined(__unix__)
static const char *const str = "Generic Unix";
#elif defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || \
defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
static const char *const str = "Windows";
#else
const char
*const _str1 = std::getenv("OSTYPE"),
*const _str2 = _str1?_str1:std::getenv("OS"),
*const str = _str2?_str2:"Unknown OS";
#endif
return str;
}
//! Return the basename of a filename.
inline const char* basename(const char *const s, const char separator=cimg_file_separator) {
const char *p = 0, *np = s;
while (np>=s && (p=np)) np = std::strchr(np,separator) + 1;
return p;
}
// Return a random filename.
inline const char* filenamerand() {
cimg::mutex(6);
static char randomid[9];
cimg::srand();
for (unsigned int k = 0; k<8; ++k) {
const int v = (int)cimg::rand(65535)%3;
randomid[k] = (char)(v==0?('0' + ((int)cimg::rand(65535)%10)):
(v==1?('a' + ((int)cimg::rand(65535)%26)):
('A' + ((int)cimg::rand(65535)%26))));
}
cimg::mutex(6,0);
return randomid;
}
// Convert filename as a Windows-style filename (short path name).
inline void winformat_string(char *const str) {
if (str && *str) {
#if cimg_OS==2
char *const nstr = new char[MAX_PATH];
if (GetShortPathNameA(str,nstr,MAX_PATH)) std::strcpy(str,nstr);
delete[] nstr;
#endif
}
}
// Open a file (with wide character support on Windows).
inline std::FILE *win_fopen(const char *const path, const char *const mode);
//! Open a file.
/**
\param path Path of the filename to open.
\param mode C-string describing the opening mode.
\return Opened file.
\note Same as <tt>std::fopen()</tt> but throw a \c CImgIOException when
the specified file cannot be opened, instead of returning \c 0.
**/
inline std::FILE *fopen(const char *const path, const char *const mode) {
if (!path)
throw CImgArgumentException("cimg::fopen(): Specified file path is (null).");
if (!mode)
throw CImgArgumentException("cimg::fopen(): File '%s', specified mode is (null).",
path);
std::FILE *res = 0;
if (*path=='-' && (!path[1] || path[1]=='.')) {
res = (*mode=='r')?cimg::_stdin():cimg::_stdout();
#if cimg_OS==2
if (*mode && mode[1]=='b') { // Force stdin/stdout to be in binary mode.
#ifdef __BORLANDC__
if (setmode(_fileno(res),0x8000)==-1) res = 0;
#else
if (_setmode(_fileno(res),0x8000)==-1) res = 0;
#endif
}
#endif
} else res = std_fopen(path,mode);
if (!res) throw CImgIOException("cimg::fopen(): Failed to open file '%s' with mode '%s'.",
path,mode);
return res;
}
//! Close a file.
/**
\param file File to close.
\return \c 0 if file has been closed properly, something else otherwise.
\note Same as <tt>std::fclose()</tt> but display a warning message if
the file has not been closed properly.
**/
inline int fclose(std::FILE *file) {
if (!file) { warn("cimg::fclose(): Specified file is (null)."); return 0; }
if (file==cimg::_stdin(false) || file==cimg::_stdout(false)) return 0;
const int errn = std::fclose(file);
if (errn!=0) warn("cimg::fclose(): Error code %d returned during file closing.",
errn);
return errn;
}
//! Version of 'fseek()' that supports >=64bits offsets everywhere (for Windows).
inline int fseek(FILE *stream, cimg_long offset, int origin) {
#if cimg_OS==2
return _fseeki64(stream,(__int64)offset,origin);
#else
return std::fseek(stream,offset,origin);
#endif
}
//! Version of 'ftell()' that supports >=64bits offsets everywhere (for Windows).
inline cimg_long ftell(FILE *stream) {
#if cimg_OS==2
return (cimg_long)_ftelli64(stream);
#else
return (cimg_long)std::ftell(stream);
#endif
}
//! Check if a path is a directory.
/**
\param path Specified path to test.
**/
inline bool is_directory(const char *const path) {
if (!path || !*path) return false;
#if cimg_OS==1
struct stat st_buf;
return (!stat(path,&st_buf) && S_ISDIR(st_buf.st_mode));
#elif cimg_OS==2
const unsigned int res = (unsigned int)GetFileAttributesA(path);
return res==INVALID_FILE_ATTRIBUTES?false:(res&16);
#else
return false;
#endif
}
//! Check if a path is a file.
/**
\param path Specified path to test.
**/
inline bool is_file(const char *const path) {
if (!path || !*path) return false;
std::FILE *const file = std_fopen(path,"rb");
if (!file) return false;
std::fclose(file);
return !is_directory(path);
}
//! Get last write time of a given file or directory.
/**
\param path Specified path to get attributes from.
\param attr Type of requested time attribute.
Can be { 0=year | 1=month | 2=day | 3=day of week | 4=hour | 5=minute | 6=second }
\return -1 if requested attribute could not be read.
**/
inline int fdate(const char *const path, const unsigned int attr) {
int res = -1;
if (!path || !*path || attr>6) return -1;
cimg::mutex(6);
#if cimg_OS==2
HANDLE file = CreateFileA(path,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if (file!=INVALID_HANDLE_VALUE) {
FILETIME _ft;
SYSTEMTIME ft;
if (GetFileTime(file,0,0,&_ft) && FileTimeToSystemTime(&_ft,&ft))
res = (int)(attr==0?ft.wYear:attr==1?ft.wMonth:attr==2?ft.wDay:attr==3?ft.wDayOfWeek:
attr==4?ft.wHour:attr==5?ft.wMinute:ft.wSecond);
CloseHandle(file);
}
#elif cimg_OS==1
struct stat st_buf;
if (!stat(path,&st_buf)) {
const time_t _ft = st_buf.st_mtime;
const struct tm& ft = *std::localtime(&_ft);
res = (int)(attr==0?ft.tm_year + 1900:attr==1?ft.tm_mon + 1:attr==2?ft.tm_mday:attr==3?ft.tm_wday:
attr==4?ft.tm_hour:attr==5?ft.tm_min:ft.tm_sec);
}
#endif
cimg::mutex(6,0);
return res;
}
//! Get current local time.
/**
\param attr Type of requested time attribute.
Can be { 0=year | 1=month | 2=day | 3=day of week | 4=hour | 5=minute | 6=second }
**/
inline int date(const unsigned int attr) {
int res;
cimg::mutex(6);
#if cimg_OS==2
SYSTEMTIME st;
GetLocalTime(&st);
res = (int)(attr==0?st.wYear:attr==1?st.wMonth:attr==2?st.wDay:attr==3?st.wDayOfWeek:
attr==4?st.wHour:attr==5?st.wMinute:st.wSecond);
#else
time_t _st;
std::time(&_st);
struct tm *st = std::localtime(&_st);
res = (int)(attr==0?st->tm_year + 1900:attr==1?st->tm_mon + 1:attr==2?st->tm_mday:attr==3?st->tm_wday:
attr==4?st->tm_hour:attr==5?st->tm_min:st->tm_sec);
#endif
cimg::mutex(6,0);
return res;
}
// Get/set path to store temporary files.
inline const char* temporary_path(const char *const user_path=0, const bool reinit_path=false);
// Get/set path to the <i>Program Files/</i> directory (Windows only).
#if cimg_OS==2
inline const char* programfiles_path(const char *const user_path=0, const bool reinit_path=false);
#endif
// Get/set path to the ImageMagick's \c convert binary.
inline const char* imagemagick_path(const char *const user_path=0, const bool reinit_path=false);
// Get/set path to the GraphicsMagick's \c gm binary.
inline const char* graphicsmagick_path(const char *const user_path=0, const bool reinit_path=false);
// Get/set path to the XMedcon's \c medcon binary.
inline const char* medcon_path(const char *const user_path=0, const bool reinit_path=false);
// Get/set path to the FFMPEG's \c ffmpeg binary.
inline const char *ffmpeg_path(const char *const user_path=0, const bool reinit_path=false);
// Get/set path to the \c gzip binary.
inline const char *gzip_path(const char *const user_path=0, const bool reinit_path=false);
// Get/set path to the \c gunzip binary.
inline const char *gunzip_path(const char *const user_path=0, const bool reinit_path=false);
// Get/set path to the \c dcraw binary.
inline const char *dcraw_path(const char *const user_path=0, const bool reinit_path=false);
// Get/set path to the \c wget binary.
inline const char *wget_path(const char *const user_path=0, const bool reinit_path=false);
// Get/set path to the \c curl binary.
inline const char *curl_path(const char *const user_path=0, const bool reinit_path=false);
//! Split filename into two C-strings \c body and \c extension.
/**
filename and body must not overlap!
**/
inline const char *split_filename(const char *const filename, char *const body=0) {
if (!filename) { if (body) *body = 0; return 0; }
const char *p = 0; for (const char *np = filename; np>=filename && (p=np); np = std::strchr(np,'.') + 1) {}
if (p==filename) {
if (body) std::strcpy(body,filename);
return filename + std::strlen(filename);
}
const unsigned int l = (unsigned int)(p - filename - 1);
if (body) { if (l) std::memcpy(body,filename,l); body[l] = 0; }
return p;
}
//! Generate a numbered version of a filename.
inline char* number_filename(const char *const filename, const int number,
const unsigned int digits, char *const str) {
if (!filename) { if (str) *str = 0; return 0; }
char *const format = new char[1024], *const body = new char[1024];
const char *const ext = cimg::split_filename(filename,body);
if (*ext) cimg_snprintf(format,1024,"%%s_%%.%ud.%%s",digits);
else cimg_snprintf(format,1024,"%%s_%%.%ud",digits);
cimg_sprintf(str,format,body,number,ext);
delete[] format; delete[] body;
return str;
}
//! Read data from file.
/**
\param[out] ptr Pointer to memory buffer that will contain the binary data read from file.
\param nmemb Number of elements to read.
\param stream File to read data from.
\return Number of read elements.
\note Same as <tt>std::fread()</tt> but may display warning message if all elements could not be read.
**/
template<typename T>
inline size_t fread(T *const ptr, const size_t nmemb, std::FILE *stream) {
if (!ptr || !stream)
throw CImgArgumentException("cimg::fread(): Invalid reading request of %u %s%s from file %p to buffer %p.",
nmemb,cimg::type<T>::string(),nmemb>1?"s":"",stream,ptr);
if (!nmemb) return 0;
const size_t wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
size_t to_read = nmemb, al_read = 0, l_to_read = 0, l_al_read = 0;
do {
l_to_read = (to_read*sizeof(T))<wlimitT?to_read:wlimit;
l_al_read = std::fread((void*)(ptr + al_read),sizeof(T),l_to_read,stream);
al_read+=l_al_read;
to_read-=l_al_read;
} while (l_to_read==l_al_read && to_read>0);
if (to_read>0)
warn("cimg::fread(): Only %lu/%lu elements could be read from file.",
(unsigned long)al_read,(unsigned long)nmemb);
return al_read;
}
//! Write data to file.
/**
\param ptr Pointer to memory buffer containing the binary data to write on file.
\param nmemb Number of elements to write.
\param[out] stream File to write data on.
\return Number of written elements.
\note Similar to <tt>std::fwrite</tt> but may display warning messages if all elements could not be written.
**/
template<typename T>
inline size_t fwrite(const T *ptr, const size_t nmemb, std::FILE *stream) {
if (!ptr || !stream)
throw CImgArgumentException("cimg::fwrite(): Invalid writing request of %u %s%s from buffer %p to file %p.",
nmemb,cimg::type<T>::string(),nmemb>1?"s":"",ptr,stream);
if (!nmemb) return 0;
const size_t wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
size_t to_write = nmemb, al_write = 0, l_to_write = 0, l_al_write = 0;
do {
l_to_write = (to_write*sizeof(T))<wlimitT?to_write:wlimit;
l_al_write = std::fwrite((void*)(ptr + al_write),sizeof(T),l_to_write,stream);
al_write+=l_al_write;
to_write-=l_al_write;
} while (l_to_write==l_al_write && to_write>0);
if (to_write>0)
warn("cimg::fwrite(): Only %lu/%lu elements could be written in file.",
(unsigned long)al_write,(unsigned long)nmemb);
return al_write;
}
//! Create an empty file.
/**
\param file Input file (can be \c 0 if \c filename is set).
\param filename Filename, as a C-string (can be \c 0 if \c file is set).
**/
inline void fempty(std::FILE *const file, const char *const filename) {
if (!file && !filename)
throw CImgArgumentException("cimg::fempty(): Specified filename is (null).");
std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
if (!file) cimg::fclose(nfile);
}
// Try to guess format from an image file.
inline const char *ftype(std::FILE *const file, const char *const filename);
// Load file from network as a local temporary file.
inline char *load_network(const char *const url, char *const filename_local,
const unsigned int timeout=0, const bool try_fallback=false,
const char *const referer=0);
//! Return options specified on the command line.
inline const char* option(const char *const name, const int argc, const char *const *const argv,
const char *const defaut, const char *const usage, const bool reset_static) {
static bool first = true, visu = false;
if (reset_static) { first = true; return 0; }
const char *res = 0;
if (first) {
first = false;
visu = cimg::option("-h",argc,argv,(char*)0,(char*)0,false)!=0;
visu |= cimg::option("-help",argc,argv,(char*)0,(char*)0,false)!=0;
visu |= cimg::option("--help",argc,argv,(char*)0,(char*)0,false)!=0;
}
if (!name && visu) {
if (usage) {
std::fprintf(cimg::output(),"\n %s%s%s",cimg::t_red,cimg::basename(argv[0]),cimg::t_normal);
std::fprintf(cimg::output(),": %s",usage);
std::fprintf(cimg::output()," (%s, %s)\n\n",cimg_date,cimg_time);
}
if (defaut) std::fprintf(cimg::output(),"%s\n",defaut);
}
if (name) {
if (argc>0) {
int k = 0;
while (k<argc && std::strcmp(argv[k],name)) ++k;
res = (k++==argc?defaut:(k==argc?argv[--k]:argv[k]));
} else res = defaut;
if (visu && usage) std::fprintf(cimg::output()," %s%-16s%s %-24s %s%s%s\n",
cimg::t_bold,name,cimg::t_normal,res?res:"0",
cimg::t_green,usage,cimg::t_normal);
}
return res;
}
inline const char* option(const char *const name, const int argc, const char *const *const argv,
const char *const defaut, const char *const usage=0) {
return option(name,argc,argv,defaut,usage,false);
}
inline bool option(const char *const name, const int argc, const char *const *const argv,
const bool defaut, const char *const usage=0) {
const char *const s = cimg::option(name,argc,argv,(char*)0);
const bool res = s?(cimg::strcasecmp(s,"false") && cimg::strcasecmp(s,"off") && cimg::strcasecmp(s,"0")):defaut;
cimg::option(name,0,0,res?"true":"false",usage);
return res;
}
inline int option(const char *const name, const int argc, const char *const *const argv,
const int defaut, const char *const usage=0) {
const char *const s = cimg::option(name,argc,argv,(char*)0);
const int res = s?std::atoi(s):defaut;
char *const tmp = new char[256];
cimg_snprintf(tmp,256,"%d",res);
cimg::option(name,0,0,tmp,usage);
delete[] tmp;
return res;
}
inline char option(const char *const name, const int argc, const char *const *const argv,
const char defaut, const char *const usage=0) {
const char *const s = cimg::option(name,argc,argv,(char*)0);
const char res = s?*s:defaut;
char tmp[8];
*tmp = res; tmp[1] = 0;
cimg::option(name,0,0,tmp,usage);
return res;
}
inline float option(const char *const name, const int argc, const char *const *const argv,
const float defaut, const char *const usage=0) {
const char *const s = cimg::option(name,argc,argv,(char*)0);
const float res = s?(float)cimg::atof(s):defaut;
char *const tmp = new char[256];
cimg_snprintf(tmp,256,"%g",res);
cimg::option(name,0,0,tmp,usage);
delete[] tmp;
return res;
}
inline double option(const char *const name, const int argc, const char *const *const argv,
const double defaut, const char *const usage=0) {
const char *const s = cimg::option(name,argc,argv,(char*)0);
const double res = s?cimg::atof(s):defaut;
char *const tmp = new char[256];
cimg_snprintf(tmp,256,"%g",res);
cimg::option(name,0,0,tmp,usage);
delete[] tmp;
return res;
}
//! Print information about \CImg environement variables.
/**
\note Output is done on the default output stream.
**/
inline void info() {
std::fprintf(cimg::output(),"\n %s%sCImg Library %u.%u.%u%s, compiled %s ( %s ) with the following flags:\n\n",
cimg::t_red,cimg::t_bold,cimg_version/100,(cimg_version/10)%10,cimg_version%10,
cimg::t_normal,cimg_date,cimg_time);
std::fprintf(cimg::output()," > Operating System: %s%-13s%s %s('cimg_OS'=%d)%s\n",
cimg::t_bold,
cimg_OS==1?"Unix":(cimg_OS==2?"Windows":"Unknow"),
cimg::t_normal,cimg::t_green,
cimg_OS,
cimg::t_normal);
std::fprintf(cimg::output()," > CPU endianness: %s%s Endian%s\n",
cimg::t_bold,
cimg::endianness()?"Big":"Little",
cimg::t_normal);
std::fprintf(cimg::output()," > Verbosity mode: %s%-13s%s %s('cimg_verbosity'=%d)%s\n",
cimg::t_bold,
cimg_verbosity==0?"Quiet":
cimg_verbosity==1?"Console":
cimg_verbosity==2?"Dialog":
cimg_verbosity==3?"Console+Warnings":"Dialog+Warnings",
cimg::t_normal,cimg::t_green,
cimg_verbosity,
cimg::t_normal);
std::fprintf(cimg::output()," > Stricts warnings: %s%-13s%s %s('cimg_strict_warnings' %s)%s\n",
cimg::t_bold,
#ifdef cimg_strict_warnings
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
std::fprintf(cimg::output()," > Support for C++11: %s%-13s%s %s('cimg_use_cpp11'=%d)%s\n",
cimg::t_bold,
cimg_use_cpp11?"Yes":"No",
cimg::t_normal,cimg::t_green,
(int)cimg_use_cpp11,
cimg::t_normal);
std::fprintf(cimg::output()," > Using VT100 messages: %s%-13s%s %s('cimg_use_vt100' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_vt100
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
std::fprintf(cimg::output()," > Display type: %s%-13s%s %s('cimg_display'=%d)%s\n",
cimg::t_bold,
cimg_display==0?"No display":cimg_display==1?"X11":cimg_display==2?"Windows GDI":"Unknown",
cimg::t_normal,cimg::t_green,
(int)cimg_display,
cimg::t_normal);
#if cimg_display==1
std::fprintf(cimg::output()," > Using XShm for X11: %s%-13s%s %s('cimg_use_xshm' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_xshm
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
std::fprintf(cimg::output()," > Using XRand for X11: %s%-13s%s %s('cimg_use_xrandr' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_xrandr
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
#endif
std::fprintf(cimg::output()," > Using OpenMP: %s%-13s%s %s('cimg_use_openmp' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_openmp
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
std::fprintf(cimg::output()," > Using PNG library: %s%-13s%s %s('cimg_use_png' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_png
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
std::fprintf(cimg::output()," > Using JPEG library: %s%-13s%s %s('cimg_use_jpeg' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_jpeg
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
std::fprintf(cimg::output()," > Using TIFF library: %s%-13s%s %s('cimg_use_tiff' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_tiff
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
std::fprintf(cimg::output()," > Using Magick++ library: %s%-13s%s %s('cimg_use_magick' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_magick
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
std::fprintf(cimg::output()," > Using FFTW3 library: %s%-13s%s %s('cimg_use_fftw3' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_fftw3
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
std::fprintf(cimg::output()," > Using LAPACK library: %s%-13s%s %s('cimg_use_lapack' %s)%s\n",
cimg::t_bold,
#ifdef cimg_use_lapack
"Yes",cimg::t_normal,cimg::t_green,"defined",
#else
"No",cimg::t_normal,cimg::t_green,"undefined",
#endif
cimg::t_normal);
char *const tmp = new char[1024];
cimg_snprintf(tmp,1024,"\"%.1020s\"",cimg::imagemagick_path());
std::fprintf(cimg::output()," > Path of ImageMagick: %s%-13s%s\n",
cimg::t_bold,
tmp,
cimg::t_normal);
cimg_snprintf(tmp,1024,"\"%.1020s\"",cimg::graphicsmagick_path());
std::fprintf(cimg::output()," > Path of GraphicsMagick: %s%-13s%s\n",
cimg::t_bold,
tmp,
cimg::t_normal);
cimg_snprintf(tmp,1024,"\"%.1020s\"",cimg::medcon_path());
std::fprintf(cimg::output()," > Path of 'medcon': %s%-13s%s\n",
cimg::t_bold,
tmp,
cimg::t_normal);
cimg_snprintf(tmp,1024,"\"%.1020s\"",cimg::temporary_path());
std::fprintf(cimg::output()," > Temporary path: %s%-13s%s\n",
cimg::t_bold,
tmp,
cimg::t_normal);
std::fprintf(cimg::output(),"\n");
delete[] tmp;
}
// Declare LAPACK function signatures if LAPACK support is enabled.
#ifdef cimg_use_lapack
template<typename T>
inline void getrf(int &N, T *lapA, int *IPIV, int &INFO) {
dgetrf_(&N,&N,lapA,&N,IPIV,&INFO);
}
inline void getrf(int &N, float *lapA, int *IPIV, int &INFO) {
sgetrf_(&N,&N,lapA,&N,IPIV,&INFO);
}
template<typename T>
inline void getri(int &N, T *lapA, int *IPIV, T* WORK, int &LWORK, int &INFO) {
dgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO);
}
inline void getri(int &N, float *lapA, int *IPIV, float* WORK, int &LWORK, int &INFO) {
sgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO);
}
template<typename T>
inline void gesvd(char &JOB, int &M, int &N, T *lapA, int &MN,
T *lapS, T *lapU, T *lapV, T *WORK, int &LWORK, int &INFO) {
dgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO);
}
inline void gesvd(char &JOB, int &M, int &N, float *lapA, int &MN,
float *lapS, float *lapU, float *lapV, float *WORK, int &LWORK, int &INFO) {
sgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO);
}
template<typename T>
inline void getrs(char &TRANS, int &N, T *lapA, int *IPIV, T *lapB, int &INFO) {
int one = 1;
dgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO);
}
inline void getrs(char &TRANS, int &N, float *lapA, int *IPIV, float *lapB, int &INFO) {
int one = 1;
sgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO);
}
template<typename T>
inline void syev(char &JOB, char &UPLO, int &N, T *lapA, T *lapW, T *WORK, int &LWORK, int &INFO) {
dsyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO);
}
inline void syev(char &JOB, char &UPLO, int &N, float *lapA, float *lapW, float *WORK, int &LWORK, int &INFO) {
ssyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO);
}
template<typename T>
inline void sgels(char & TRANS, int &M, int &N, int &NRHS, T* lapA, int &LDA,
T* lapB, int &LDB, T* WORK, int &LWORK, int &INFO){
dgels_(&TRANS, &M, &N, &NRHS, lapA, &LDA, lapB, &LDB, WORK, &LWORK, &INFO);
}
inline void sgels(char & TRANS, int &M, int &N, int &NRHS, float* lapA, int &LDA,
float* lapB, int &LDB, float* WORK, int &LWORK, int &INFO){
sgels_(&TRANS, &M, &N, &NRHS, lapA, &LDA, lapB, &LDB, WORK, &LWORK, &INFO);
}
#endif
// End of the 'cimg' namespace
}
/*------------------------------------------------
#
#
# Definition of mathematical operators and
# external functions.
#
#
-------------------------------------------------*/
#define _cimg_create_ext_operators(typ) \
template<typename T> \
inline CImg<typename cimg::superset<T,typ>::type> operator+(const typ val, const CImg<T>& img) { \
return img + val; \
} \
template<typename T> \
inline CImg<typename cimg::superset<T,typ>::type> operator-(const typ val, const CImg<T>& img) { \
typedef typename cimg::superset<T,typ>::type Tt; \
return CImg<Tt>(img._width,img._height,img._depth,img._spectrum,val)-=img; \
} \
template<typename T> \
inline CImg<typename cimg::superset<T,typ>::type> operator*(const typ val, const CImg<T>& img) { \
return img*val; \
} \
template<typename T> \
inline CImg<typename cimg::superset<T,typ>::type> operator/(const typ val, const CImg<T>& img) { \
return val*img.get_invert(); \
} \
template<typename T> \
inline CImg<typename cimg::superset<T,typ>::type> operator&(const typ val, const CImg<T>& img) { \
return img & val; \
} \
template<typename T> \
inline CImg<typename cimg::superset<T,typ>::type> operator|(const typ val, const CImg<T>& img) { \
return img | val; \
} \
template<typename T> \
inline CImg<typename cimg::superset<T,typ>::type> operator^(const typ val, const CImg<T>& img) { \
return img ^ val; \
} \
template<typename T> \
inline bool operator==(const typ val, const CImg<T>& img) { \
return img == val; \
} \
template<typename T> \
inline bool operator!=(const typ val, const CImg<T>& img) { \
return img != val; \
}
_cimg_create_ext_operators(bool)
_cimg_create_ext_operators(unsigned char)
_cimg_create_ext_operators(char)
_cimg_create_ext_operators(signed char)
_cimg_create_ext_operators(unsigned short)
_cimg_create_ext_operators(short)
_cimg_create_ext_operators(unsigned int)
_cimg_create_ext_operators(int)
_cimg_create_ext_operators(cimg_uint64)
_cimg_create_ext_operators(cimg_int64)
_cimg_create_ext_operators(float)
_cimg_create_ext_operators(double)
_cimg_create_ext_operators(long double)
template<typename T>
inline CImg<_cimg_Tfloat> operator+(const char *const expression, const CImg<T>& img) {
return img + expression;
}
template<typename T>
inline CImg<_cimg_Tfloat> operator-(const char *const expression, const CImg<T>& img) {
return CImg<_cimg_Tfloat>(img,false).fill(expression,true)-=img;
}
template<typename T>
inline CImg<_cimg_Tfloat> operator*(const char *const expression, const CImg<T>& img) {
return img*expression;
}
template<typename T>
inline CImg<_cimg_Tfloat> operator/(const char *const expression, const CImg<T>& img) {
return expression*img.get_invert();
}
template<typename T>
inline CImg<T> operator&(const char *const expression, const CImg<T>& img) {
return img & expression;
}
template<typename T>
inline CImg<T> operator|(const char *const expression, const CImg<T>& img) {
return img | expression;
}
template<typename T>
inline CImg<T> operator^(const char *const expression, const CImg<T>& img) {
return img ^ expression;
}
template<typename T>
inline bool operator==(const char *const expression, const CImg<T>& img) {
return img==expression;
}
template<typename T>
inline bool operator!=(const char *const expression, const CImg<T>& img) {
return img!=expression;
}
template<typename T>
inline CImg<_cimg_Tfloat> sqr(const CImg<T>& instance) {
return instance.get_sqr();
}
template<typename T>
inline CImg<_cimg_Tfloat> sqrt(const CImg<T>& instance) {
return instance.get_sqrt();
}
template<typename T>
inline CImg<_cimg_Tfloat> exp(const CImg<T>& instance) {
return instance.get_exp();
}
template<typename T>
inline CImg<_cimg_Tfloat> log(const CImg<T>& instance) {
return instance.get_log();
}
template<typename T>
inline CImg<_cimg_Tfloat> log2(const CImg<T>& instance) {
return instance.get_log2();
}
template<typename T>
inline CImg<_cimg_Tfloat> log10(const CImg<T>& instance) {
return instance.get_log10();
}
template<typename T>
inline CImg<_cimg_Tfloat> abs(const CImg<T>& instance) {
return instance.get_abs();
}
template<typename T>
inline CImg<_cimg_Tfloat> sign(const CImg<T>& instance) {
return instance.get_sign();
}
template<typename T>
inline CImg<_cimg_Tfloat> cos(const CImg<T>& instance) {
return instance.get_cos();
}
template<typename T>
inline CImg<_cimg_Tfloat> sin(const CImg<T>& instance) {
return instance.get_sin();
}
template<typename T>
inline CImg<_cimg_Tfloat> sinc(const CImg<T>& instance) {
return instance.get_sinc();
}
template<typename T>
inline CImg<_cimg_Tfloat> tan(const CImg<T>& instance) {
return instance.get_tan();
}
template<typename T>
inline CImg<_cimg_Tfloat> acos(const CImg<T>& instance) {
return instance.get_acos();
}
template<typename T>
inline CImg<_cimg_Tfloat> asin(const CImg<T>& instance) {
return instance.get_asin();
}
template<typename T>
inline CImg<_cimg_Tfloat> atan(const CImg<T>& instance) {
return instance.get_atan();
}
template<typename T>
inline CImg<_cimg_Tfloat> cosh(const CImg<T>& instance) {
return instance.get_cosh();
}
template<typename T>
inline CImg<_cimg_Tfloat> sinh(const CImg<T>& instance) {
return instance.get_sinh();
}
template<typename T>
inline CImg<_cimg_Tfloat> tanh(const CImg<T>& instance) {
return instance.get_tanh();
}
template<typename T>
inline CImg<T> transpose(const CImg<T>& instance) {
return instance.get_transpose();
}
template<typename T>
inline CImg<_cimg_Tfloat> invert(const CImg<T>& instance) {
return instance.get_invert();
}
template<typename T>
inline CImg<_cimg_Tfloat> pseudoinvert(const CImg<T>& instance) {
return instance.get_pseudoinvert();
}
/*-----------------------------------
#
# Define the CImgDisplay structure
#
----------------------------------*/
//! Allow the creation of windows, display images on them and manage user events (keyboard, mouse and windows events).
/**
CImgDisplay methods rely on a low-level graphic library to perform: it can be either \b X-Window
(X11, for Unix-based systems) or \b GDI32 (for Windows-based systems).
If both libraries are missing, CImgDisplay will not be able to display images on screen, and will enter
a minimal mode where warning messages will be outputed each time the program is trying to call one of the
CImgDisplay method.
The configuration variable \c cimg_display tells about the graphic library used.
It is set automatically by \CImg when one of these graphic libraries has been detected.
But, you can override its value if necessary. Valid choices are:
- 0: Disable display capabilities.
- 1: Use \b X-Window (X11) library.
- 2: Use \b GDI32 library.
Remember to link your program against \b X11 or \b GDI32 libraries if you use CImgDisplay.
**/
struct CImgDisplay {
cimg_ulong _timer, _fps_frames, _fps_timer;
unsigned int _width, _height, _normalization;
float _fps_fps, _min, _max;
bool _is_fullscreen;
char *_title;
unsigned int _window_width, _window_height, _button, *_keys, *_released_keys;
int _window_x, _window_y, _mouse_x, _mouse_y, _wheel;
bool _is_closed, _is_resized, _is_moved, _is_event,
_is_keyESC, _is_keyF1, _is_keyF2, _is_keyF3, _is_keyF4, _is_keyF5, _is_keyF6, _is_keyF7,
_is_keyF8, _is_keyF9, _is_keyF10, _is_keyF11, _is_keyF12, _is_keyPAUSE, _is_key1, _is_key2,
_is_key3, _is_key4, _is_key5, _is_key6, _is_key7, _is_key8, _is_key9, _is_key0,
_is_keyBACKSPACE, _is_keyINSERT, _is_keyHOME, _is_keyPAGEUP, _is_keyTAB, _is_keyQ, _is_keyW, _is_keyE,
_is_keyR, _is_keyT, _is_keyY, _is_keyU, _is_keyI, _is_keyO, _is_keyP, _is_keyDELETE,
_is_keyEND, _is_keyPAGEDOWN, _is_keyCAPSLOCK, _is_keyA, _is_keyS, _is_keyD, _is_keyF, _is_keyG,
_is_keyH, _is_keyJ, _is_keyK, _is_keyL, _is_keyENTER, _is_keySHIFTLEFT, _is_keyZ, _is_keyX,
_is_keyC, _is_keyV, _is_keyB, _is_keyN, _is_keyM, _is_keySHIFTRIGHT, _is_keyARROWUP, _is_keyCTRLLEFT,
_is_keyAPPLEFT, _is_keyALT, _is_keySPACE, _is_keyALTGR, _is_keyAPPRIGHT, _is_keyMENU, _is_keyCTRLRIGHT,
_is_keyARROWLEFT, _is_keyARROWDOWN, _is_keyARROWRIGHT, _is_keyPAD0, _is_keyPAD1, _is_keyPAD2, _is_keyPAD3,
_is_keyPAD4, _is_keyPAD5, _is_keyPAD6, _is_keyPAD7, _is_keyPAD8, _is_keyPAD9, _is_keyPADADD, _is_keyPADSUB,
_is_keyPADMUL, _is_keyPADDIV;
//@}
//---------------------------