Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
dtschump committed Jan 29, 2024
2 parents dcefc6e + 50bc5f7 commit bc9ee24
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 68 deletions.
147 changes: 81 additions & 66 deletions CImg.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

// Set version number of the library.
#ifndef cimg_version
#define cimg_version 333
#define cimg_version 334

/*-----------------------------------------------------------
#
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -17967,16 +17968,11 @@ namespace cimg_library {
else
CImg<ulongT>::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<ulongT>::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<ulongT>::vector((ulongT)mp_complex_sqr,arg1,arg1 + 1,arg1 + 2).move_to(code);
else CImg<ulongT>::vector((ulongT)mp_complex_pow_vs,arg1,arg1,arg2).move_to(code);
}

if (*ref==4) { // Image value (vector): I/J[_#ind,off] **= value
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<ulongT>::vector((ulongT)mp_logical_or,pos,arg1,arg2,code._width - p2).
move_to(code,p2);
CImg<ulongT>::vector((ulongT)mp_logical_or,pos,arg1,arg2,code._width - p2).move_to(code,p2);
return_new_comp = true;
_cimg_mp_return(pos);
}
Expand All @@ -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<ulongT>::vector((ulongT)mp_logical_and,pos,arg1,arg2,code._width - p2).
move_to(code,p2);
Expand All @@ -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);
}

Expand Down Expand Up @@ -18381,15 +18374,15 @@ 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))
_cimg_mp_vector2_sv(mp_bitwise_left_shift,arg1,arg2);
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);
}

Expand All @@ -18402,15 +18395,15 @@ 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))
_cimg_mp_vector2_sv(mp_bitwise_right_shift,arg1,arg2);
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);
}

Expand All @@ -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);
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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<ulongT>::vector((ulongT)mp_complex_mul,pos,arg1,arg2).move_to(code);
Expand All @@ -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<ulongT>::vector((ulongT)mp_complex_div_vv,pos,arg1,arg2).move_to(code);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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<ulongT>::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<ulongT>::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<ulongT>::vector((ulongT)mp_complex_pow_sv,pos,arg1,arg2).move_to(code);
else
CImg<ulongT>::vector((ulongT)mp_complex_pow_ss,pos,arg1,arg2).move_to(code);
if (arg2==2) {
if (_cimg_mp_is_scalar(arg1)) CImg<ulongT>::vector((ulongT)mp_complex_sqr,pos,arg1,0).move_to(code);
else CImg<ulongT>::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<ulongT>::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<ulongT>::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<ulongT>::vector((ulongT)mp_complex_pow_sv,pos,arg1,arg2).move_to(code);
else
CImg<ulongT>::vector((ulongT)mp_complex_pow_ss,pos,arg1,arg2).move_to(code);
}
return_new_comp = true;
_cimg_mp_return(pos);
}
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<ulongT>::vector((ulongT)mp_complex_sqr,pos,arg1,0).move_to(code);
else CImg<ulongT>::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);
Expand Down Expand Up @@ -21331,8 +21335,8 @@ namespace cimg_library {
arg3 = s2<se1?compile(++s2,se1,depth1,0,block_flags):16; // Default value is 0.5
_cimg_mp_check_type(arg3,3,1,0);
if (_cimg_mp_is_const_scalar(arg3)) { // Optimize constant cases
if (!arg3) _cimg_mp_return(arg1);
if (arg3==1) _cimg_mp_return(arg2);
if (!arg3) _cimg_mp_copy(arg1);
if (arg3==1) _cimg_mp_copy(arg2);
if (_cimg_mp_is_const_scalar(arg1) && _cimg_mp_is_const_scalar(arg2)) {
const double t = mem[arg3];
_cimg_mp_const_scalar(mem[arg1]*(1-t) + mem[arg2]*t);
Expand Down Expand Up @@ -22118,7 +22122,7 @@ namespace cimg_library {
if (!std::strncmp(ss,"reverse(",8)) { // Vector reverse
_cimg_mp_op("Function 'reverse()'");
arg1 = compile(ss8,se1,depth1,0,block_flags);
if (!_cimg_mp_is_vector(arg1)) _cimg_mp_return(arg1);
if (!_cimg_mp_is_vector(arg1)) _cimg_mp_copy(arg1);
p1 = _cimg_mp_size(arg1);
pos = vector(p1);
CImg<ulongT>::vector((ulongT)mp_vector_reverse,pos,arg1,p1).move_to(code);
Expand Down Expand Up @@ -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<ulongT>::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<ulongT>::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.
Expand Down Expand Up @@ -24763,6 +24770,14 @@ namespace cimg_library {
return cimg::type<double>::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<double>::nan();
}

static double mp_complex_sqrt(_cimg_math_parser& mp) {
const double
real = _mp_arg(2), imag = _mp_arg(3),
Expand Down
2 changes: 1 addition & 1 deletion html/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<div class="header">
<a href="index.html"><img alt="Logo" src="img/logo_header.jpg" class="center_image" style="margin-top:1em;"/></a>
<h2 style="padding-bottom: 1em">
Latest stable version: <b><a href="http://cimg.eu/files/CImg_.zip">3.3.2</a></b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Current pre-release: <b><a href="http://cimg.eu/files/CImg_latest.zip">3.3.3</a></b> (2023/11/24)
Latest stable version: <b><a href="http://cimg.eu/files/CImg_.zip">3.3.3</a></b>
</h2>

<hr/>
Expand Down
2 changes: 1 addition & 1 deletion html/header_doxygen.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<div class="header">
<a href="../index.html"><img alt="Logo" src="../img/logo_header.jpg" class="center_image" style="margin-top:1em;"/></a>
<h2 style="padding-bottom: 1em">
Latest stable version: <b><a href="http://cimg.eu/files/CImg_.zip">3.3.2</a></b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Current pre-release: <b><a href="http://cimg.eu/files/CImg_latest.zip">3.3.3</a></b> (2023/11/24)
Latest stable version: <b><a href="http://cimg.eu/files/CImg_.zip">3.3.3</a></b>
</h2>

<hr/>
Expand Down

0 comments on commit bc9ee24

Please sign in to comment.