diff --git a/CImg.h b/CImg.h index 63b21266..b345c9de 100644 --- a/CImg.h +++ b/CImg.h @@ -54,7 +54,7 @@ // Set version number of the library. #ifndef cimg_version -#define cimg_version 333 +#define cimg_version 334 /*----------------------------------------------------------- # @@ -16997,6 +16997,7 @@ namespace cimg_library { #define _cimg_mp_return(x) { *se = saved_char; s_op = previous_s_op; ss_op = previous_ss_op; return x; } #define _cimg_mp_return_nan() _cimg_mp_return(_cimg_mp_slot_nan) #define _cimg_mp_const_scalar(val) _cimg_mp_return(const_scalar((double)(val))) +#define _cimg_mp_copy(x) _cimg_mp_return(copy(x)); #define _cimg_mp_scalar0(op) _cimg_mp_return(scalar0(op)) #define _cimg_mp_scalar1(op,i1) _cimg_mp_return(scalar1(op,i1)) #define _cimg_mp_scalar2(op,i1,i2) _cimg_mp_return(scalar2(op,i1,i2)) @@ -17751,7 +17752,7 @@ namespace cimg_library { if (arg1==~0U) { // Create new variable if (_cimg_mp_is_vector(arg3)) { // Vector variable - arg1 = is_sth || is_comp_vector(arg3)?arg3:vector_copy(arg3); + arg1 = is_sth || is_comp_vector(arg3)?arg3:copy(arg3); set_reserved_vector(arg1); // Prevent from being used in further optimization } else { // Scalar variable if (is_const) arg1 = arg3; @@ -17967,16 +17968,11 @@ namespace cimg_library { else CImg::vector((ulongT)mp_complex_pow_vv,arg1,arg1,arg2).move_to(code); } else { // Complex **= scalar - if (*ps=='*') { - if (arg2==1) _cimg_mp_return(arg1); - self_vector_s(arg1,mp_self_mul,arg2); - } else if (*ps=='/') { - if (arg2==1) _cimg_mp_return(arg1); - self_vector_s(arg1,mp_self_div,arg2); - } else { - if (arg2==1) _cimg_mp_return(arg1); - CImg::vector((ulongT)mp_complex_pow_vs,arg1,arg1,arg2).move_to(code); - } + if (arg2==1) _cimg_mp_return(arg1); + if (*ps=='*') self_vector_s(arg1,mp_self_mul,arg2); + else if (*ps=='/') self_vector_s(arg1,mp_self_div,arg2); + else if (arg2==2) CImg::vector((ulongT)mp_complex_sqr,arg1,arg1 + 1,arg1 + 2).move_to(code); + else CImg::vector((ulongT)mp_complex_pow_vs,arg1,arg1,arg2).move_to(code); } if (*ref==4) { // Image value (vector): I/J[_#ind,off] **= value @@ -18047,10 +18043,8 @@ namespace cimg_library { if ((op==mp_self_mul || op==mp_self_div) && arg2==1) _cimg_mp_return(arg1); // Apply operator on a copy to prevent modifying a constant or a variable. - if (*ref && (_cimg_mp_is_const_scalar(arg1) || _cimg_mp_is_vector(arg1) || _cimg_mp_is_reserved(arg1))) { - if (_cimg_mp_is_vector(arg1)) arg1 = vector_copy(arg1); - else arg1 = scalar1(mp_copy,arg1); - } + if (*ref && (_cimg_mp_is_const_scalar(arg1) || _cimg_mp_is_vector(arg1) || _cimg_mp_is_reserved(arg1))) + arg1 = copy(arg1); if (*ref==1) { // Vector value (scalar): V[k] += scalar _cimg_mp_check_type(arg2,2,1,0); @@ -18202,16 +18196,15 @@ namespace cimg_library { _cimg_mp_op("Operator '||'"); arg1 = compile(ss,s,depth1,0,block_flags); _cimg_mp_check_type(arg1,1,1,0); - if (arg1>0 && arg1<=16) _cimg_mp_return(1); + if (_cimg_mp_is_const_scalar(arg1) && mem[arg1]) _cimg_mp_return(1); p2 = code._width; arg2 = compile(s + 2,se,depth1,0,block_flags); _cimg_mp_check_type(arg2,2,1,0); if (_cimg_mp_is_const_scalar(arg1) && _cimg_mp_is_const_scalar(arg2)) _cimg_mp_const_scalar(mem[arg1] || mem[arg2]); - if (!arg1) _cimg_mp_return(arg2); + if (!arg1) _cimg_mp_copy(arg2); pos = scalar(); - CImg::vector((ulongT)mp_logical_or,pos,arg1,arg2,code._width - p2). - move_to(code,p2); + CImg::vector((ulongT)mp_logical_or,pos,arg1,arg2,code._width - p2).move_to(code,p2); return_new_comp = true; _cimg_mp_return(pos); } @@ -18227,7 +18220,7 @@ namespace cimg_library { _cimg_mp_check_type(arg2,2,1,0); if (_cimg_mp_is_const_scalar(arg1) && _cimg_mp_is_const_scalar(arg2)) _cimg_mp_const_scalar(mem[arg1] && mem[arg2]); - if (arg1>0 && arg1<=16) _cimg_mp_return(arg2); + if (_cimg_mp_is_const_scalar(arg1) && mem[arg1]) _cimg_mp_copy(arg2); pos = scalar(); CImg::vector((ulongT)mp_logical_and,pos,arg1,arg2,code._width - p2). move_to(code,p2); @@ -18243,17 +18236,17 @@ namespace cimg_library { _cimg_mp_check_type(arg2,2,3,_cimg_mp_size(arg1)); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_bitwise_or,arg1,arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) { - if (!arg2) _cimg_mp_return(arg1); + if (!arg2) _cimg_mp_copy(arg1); _cimg_mp_vector2_vs(mp_bitwise_or,arg1,arg2); } if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) { - if (!arg1) _cimg_mp_return(arg2); + if (!arg1) _cimg_mp_copy(arg2); _cimg_mp_vector2_sv(mp_bitwise_or,arg1,arg2); } if (_cimg_mp_is_const_scalar(arg1) && _cimg_mp_is_const_scalar(arg2)) _cimg_mp_const_scalar((longT)mem[arg1] | (longT)mem[arg2]); - if (!arg2) _cimg_mp_return(arg1); - if (!arg1) _cimg_mp_return(arg2); + if (!arg2) _cimg_mp_copy(arg1); + if (!arg1) _cimg_mp_copy(arg2); _cimg_mp_scalar2(mp_bitwise_or,arg1,arg2); } @@ -18381,7 +18374,7 @@ namespace cimg_library { if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_bitwise_left_shift,arg1,arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) { - if (!arg2) _cimg_mp_return(arg1); + if (!arg2) _cimg_mp_copy(arg1); _cimg_mp_vector2_vs(mp_bitwise_left_shift,arg1,arg2); } if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) @@ -18389,7 +18382,7 @@ namespace cimg_library { if (_cimg_mp_is_const_scalar(arg1) && _cimg_mp_is_const_scalar(arg2)) _cimg_mp_const_scalar((longT)mem[arg1]<<(unsigned int)mem[arg2]); if (!arg1) _cimg_mp_return(0); - if (!arg2) _cimg_mp_return(arg1); + if (!arg2) _cimg_mp_copy(arg1); _cimg_mp_scalar2(mp_bitwise_left_shift,arg1,arg2); } @@ -18402,7 +18395,7 @@ namespace cimg_library { if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_bitwise_right_shift,arg1,arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) { - if (!arg2) _cimg_mp_return(arg1); + if (!arg2) _cimg_mp_copy(arg1); _cimg_mp_vector2_vs(mp_bitwise_right_shift,arg1,arg2); } if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) @@ -18410,7 +18403,7 @@ namespace cimg_library { if (_cimg_mp_is_const_scalar(arg1) && _cimg_mp_is_const_scalar(arg2)) _cimg_mp_const_scalar((longT)mem[arg1]>>(unsigned int)mem[arg2]); if (!arg1) _cimg_mp_return(0); - if (!arg2) _cimg_mp_return(arg1); + if (!arg2) _cimg_mp_copy(arg1); _cimg_mp_scalar2(mp_bitwise_right_shift,arg1,arg2); } @@ -18424,8 +18417,8 @@ namespace cimg_library { arg1 = compile(ss,s,depth1,0,block_flags); arg2 = compile(s + 1,se,depth1,0,block_flags); _cimg_mp_check_type(arg2,2,3,_cimg_mp_size(arg1)); - if (!arg2) _cimg_mp_return(arg1); - if (!arg1) _cimg_mp_return(arg2); + if (!arg2) _cimg_mp_copy(arg1); + if (!arg1) _cimg_mp_copy(arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_add,arg1,arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_add,arg1,arg2); if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_add,arg1,arg2); @@ -18457,7 +18450,7 @@ namespace cimg_library { arg1 = compile(ss,s,depth1,0,block_flags); arg2 = compile(s + 1,se,depth1,0,block_flags); _cimg_mp_check_type(arg2,2,3,_cimg_mp_size(arg1)); - if (!arg2) _cimg_mp_return(arg1); + if (!arg2) _cimg_mp_copy(arg1); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_sub,arg1,arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_sub,arg1,arg2); if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) { @@ -18490,8 +18483,8 @@ namespace cimg_library { arg2 = compile(s + 2,se,depth1,0,block_flags); _cimg_mp_check_type(arg1,1,3,2); _cimg_mp_check_type(arg2,2,3,2); - if (arg2==1) _cimg_mp_return(arg1); - if (arg1==1) _cimg_mp_return(arg2); + if (arg2==1) _cimg_mp_copy(arg1); + if (arg1==1) _cimg_mp_copy(arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) { pos = vector(2); CImg::vector((ulongT)mp_complex_mul,pos,arg1,arg2).move_to(code); @@ -18513,7 +18506,7 @@ namespace cimg_library { arg2 = compile(s + 2,se,depth1,0,block_flags); _cimg_mp_check_type(arg1,1,3,2); _cimg_mp_check_type(arg2,2,3,2); - if (arg2==1) _cimg_mp_return(arg1); + if (arg2==1) _cimg_mp_copy(arg1); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) { pos = vector(2); CImg::vector((ulongT)mp_complex_div_vv,pos,arg1,arg2).move_to(code); @@ -18545,8 +18538,8 @@ namespace cimg_library { _cimg_mp_return(pos); } _cimg_mp_check_type(arg2,2,3,_cimg_mp_size(arg1)); - if (arg2==1) _cimg_mp_return(arg1); - if (arg1==1) _cimg_mp_return(arg2); + if (arg2==1) _cimg_mp_copy(arg1); + if (arg1==1) _cimg_mp_copy(arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_mul,arg1,arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_mul,arg1,arg2); if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_mul,arg1,arg2); @@ -18573,7 +18566,7 @@ namespace cimg_library { arg1 = compile(ss,s,depth1,0,block_flags); arg2 = compile(s + 1,se,depth1,0,block_flags); _cimg_mp_check_type(arg2,2,3,_cimg_mp_size(arg1)); - if (arg2==1) _cimg_mp_return(arg1); + if (arg2==1) _cimg_mp_copy(arg1); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_div,arg1,arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_div,arg1,arg2); if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_div,arg1,arg2); @@ -18641,16 +18634,21 @@ namespace cimg_library { arg2 = compile(s + 2,se,depth1,0,block_flags); _cimg_mp_check_type(arg1,1,3,2); _cimg_mp_check_type(arg2,2,3,2); - if (arg2==1) _cimg_mp_return(arg1); + if (arg2==1) _cimg_mp_copy(arg1); pos = vector(2); - if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) - CImg::vector((ulongT)mp_complex_pow_vv,pos,arg1,arg2).move_to(code); - else if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) - CImg::vector((ulongT)mp_complex_pow_vs,pos,arg1,arg2).move_to(code); - else if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) - CImg::vector((ulongT)mp_complex_pow_sv,pos,arg1,arg2).move_to(code); - else - CImg::vector((ulongT)mp_complex_pow_ss,pos,arg1,arg2).move_to(code); + if (arg2==2) { + if (_cimg_mp_is_scalar(arg1)) CImg::vector((ulongT)mp_complex_sqr,pos,arg1,0).move_to(code); + else CImg::vector((ulongT)mp_complex_sqr,pos,arg1 + 1,arg1 + 2).move_to(code); + } else { + if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) + CImg::vector((ulongT)mp_complex_pow_vv,pos,arg1,arg2).move_to(code); + else if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) + CImg::vector((ulongT)mp_complex_pow_vs,pos,arg1,arg2).move_to(code); + else if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) + CImg::vector((ulongT)mp_complex_pow_sv,pos,arg1,arg2).move_to(code); + else + CImg::vector((ulongT)mp_complex_pow_ss,pos,arg1,arg2).move_to(code); + } return_new_comp = true; _cimg_mp_return(pos); } @@ -18661,7 +18659,7 @@ namespace cimg_library { arg1 = compile(ss,s,depth1,0,block_flags); arg2 = compile(s + 1,se,depth1,0,block_flags); _cimg_mp_check_type(arg2,2,3,_cimg_mp_size(arg1)); - if (arg2==1) _cimg_mp_return(arg1); + if (arg2==1) _cimg_mp_copy(arg1); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_vv(mp_pow,arg1,arg2); if (_cimg_mp_is_vector(arg1) && _cimg_mp_is_scalar(arg2)) _cimg_mp_vector2_vs(mp_pow,arg1,arg2); if (_cimg_mp_is_scalar(arg1) && _cimg_mp_is_vector(arg2)) _cimg_mp_vector2_sv(mp_pow,arg1,arg2); @@ -18713,16 +18711,11 @@ namespace cimg_library { compile(ss,se2,depth1,ref,block_flags); // Variable slot // Apply operator on a copy to prevent modifying a constant or a variable. - if (*ref && (_cimg_mp_is_const_scalar(arg1) || _cimg_mp_is_vector(arg1) || _cimg_mp_is_reserved(arg1))) { - if (_cimg_mp_is_vector(arg1)) arg1 = vector_copy(arg1); - else arg1 = scalar1(mp_copy,arg1); - } + if (*ref && (_cimg_mp_is_const_scalar(arg1) || _cimg_mp_is_vector(arg1) || _cimg_mp_is_reserved(arg1))) + arg1 = copy(arg1); if (is_sth) pos = arg1; // Determine return index, depending on pre/post action - else { - if (_cimg_mp_is_vector(arg1)) pos = vector_copy(arg1); - else pos = scalar1(mp_copy,arg1); - } + else pos = copy(arg1); if (*ref==1) { // Vector value (scalar): V[k]++ arg3 = ref[1]; // Vector slot @@ -19457,6 +19450,17 @@ namespace cimg_library { _cimg_mp_return(pos); } + if (!std::strncmp(ss,"csqr(",5)) { // Complex square + _cimg_mp_op("Function 'csqr()'"); + arg1 = compile(ss5,se1,depth1,0,block_flags); + _cimg_mp_check_type(arg1,0,3,2); + pos = vector(2); + if (_cimg_mp_is_scalar(arg1)) CImg::vector((ulongT)mp_complex_sqr,pos,arg1,0).move_to(code); + else CImg::vector((ulongT)mp_complex_sqr,pos,arg1 + 1,arg1 + 2).move_to(code); + return_new_comp = true; + _cimg_mp_return(pos); + } + if (!std::strncmp(ss,"csqrt(",6)) { // Complex square root _cimg_mp_op("Function 'csqrt()'"); arg1 = compile(ss6,se1,depth1,0,block_flags); @@ -21331,8 +21335,8 @@ namespace cimg_library { arg3 = s2::vector((ulongT)mp_vector_reverse,pos,arg1,p1).move_to(code); @@ -24108,13 +24112,16 @@ namespace cimg_library { return pos; } - // Insert new copy of specified vector in memory. - unsigned int vector_copy(const unsigned int arg) { - const unsigned int - siz = _cimg_mp_size(arg), - pos = vector(siz); - CImg::vector((ulongT)mp_vector_copy,pos,arg,siz).move_to(code); - return pos; + // Insert copy of specified argument in memory. + unsigned int copy(const unsigned int arg) { + const unsigned int siz = _cimg_mp_size(arg); + if (siz) { // Vector + const unsigned int pos = vector(siz); + CImg::vector((ulongT)mp_vector_copy,pos,arg,siz).move_to(code); + return pos; + } + if (_cimg_mp_is_const_scalar(arg)) return arg; // Const scalar + return scalar1(mp_copy,arg); // Scalar } // Set reserved status to all values of a vector. @@ -24763,6 +24770,14 @@ namespace cimg_library { return cimg::type::nan(); } + static double mp_complex_sqr(_cimg_math_parser& mp) { + const double real = _mp_arg(2), imag = _mp_arg(3); + double *ptrd = &_mp_arg(1) + 1; + ptrd[0] = cimg::sqr(real) - cimg::sqr(imag); + ptrd[1] = 2*real*imag; + return cimg::type::nan(); + } + static double mp_complex_sqrt(_cimg_math_parser& mp) { const double real = _mp_arg(2), imag = _mp_arg(3), diff --git a/html/header.html b/html/header.html index e5e2405b..fcb7e248 100644 --- a/html/header.html +++ b/html/header.html @@ -23,7 +23,7 @@
Logo

- Latest stable version: 3.3.2        Current pre-release: 3.3.3 (2023/11/24) + Latest stable version: 3.3.3


diff --git a/html/header_doxygen.html b/html/header_doxygen.html index 636cebaa..aa26bd04 100644 --- a/html/header_doxygen.html +++ b/html/header_doxygen.html @@ -26,7 +26,7 @@
Logo

- Latest stable version: 3.3.2        Current pre-release: 3.3.3 (2023/11/24) + Latest stable version: 3.3.3