Skip to content

Commit 754baa2

Browse files
committed
.
2 parents 68880cb + a5fbe92 commit 754baa2

File tree

1 file changed

+90
-57
lines changed

1 file changed

+90
-57
lines changed

CImg.h

Lines changed: 90 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -20995,7 +20995,7 @@ namespace cimg_library {
2099520995
s1 = ++s0; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1;
2099620996
p1 = compile(s0,s1++,depth1,0,block_flags);
2099720997
_cimg_mp_check_notnan_index(p1,s0);
20998-
} else { p1 = 11; s1 = s0; }
20998+
} else { p1 = 11; s1 = s0; } // Default: #-1
2099920999
_cimg_mp_check_list();
2100021000
_cimg_mp_check_const_scalar(p1,1,1);
2100121001
p3 = (unsigned int)cimg::mod((int)mem[p1],imglist.width());
@@ -21014,52 +21014,64 @@ namespace cimg_library {
2101421014
s1 = ++s0; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1;
2101521015
p1 = compile(s0,s1++,depth1,0,block_flags);
2101621016
_cimg_mp_check_notnan_index(p1,s0);
21017-
} else { p1 = 11; s1 = s0; }
21017+
} else { p1 = 11; s1 = s0; } // Default: #-1
2101821018
_cimg_mp_check_list();
2101921019
CImg<ulongT>::vector((ulongT)mp_da_freeze,_cimg_mp_slot_nan,p1).move_to(code);
2102021020
_cimg_mp_return_nan();
2102121021
}
2102221022

2102321023
if (!std::strncmp(ss,"da_insert(",10) ||
21024+
!std::strncmp(ss,"da_insert_n(",12) ||
2102421025
!std::strncmp(ss,"da_push(",8) ||
21025-
!std::strncmp(ss,"da_push_heap(",13)) { // Insert element(s) in a dynamic array
21026+
!std::strncmp(ss,"da_push_n(",10) ||
21027+
!std::strncmp(ss,"da_push_heap(",13) ||
21028+
!std::strncmp(ss,"da_push_heap_n(",15)) { // Insert element(s) in a dynamic array
2102621029
if (!is_inside_critical) is_parallelizable = false;
21027-
const bool is_push = *ss3=='p', is_push_heap = *ss7=='_';
21028-
_cimg_mp_op(is_push_heap?"Function 'da_push_heap()'":
21029-
is_push?"Function 'da_push()'":"Function 'da_insert()'");
21030-
s0 = ss + (is_push_heap?13:is_push?8:10);
21030+
const bool
21031+
is_push_heap = *ss3=='p' && *ss7=='_' && *ss8=='h',
21032+
is_push = !is_push_heap && *ss3=='p',
21033+
is_insert = !is_push_heap && !is_push,
21034+
is_n = is_push_heap?ss[12]=='_':is_push?*ss7=='_':ss[9]=='_';
21035+
_cimg_mp_op(is_push_heap?(is_n?"Function 'da_push_heap_n()'":"Function 'da_push_heap()'"):
21036+
is_push?(is_n?"Function 'da_push_n()'":"Function 'da_push()'"):
21037+
(is_n?"Function 'da_insert_n()'":"Function 'da_insert()'"));
21038+
s0 = ss + (is_push_heap?13:is_push?8:10) + (is_n?2:0);
2103121039
if (*s0=='#') { // Index specified
2103221040
s1 = ++s0; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1;
2103321041
p1 = compile(s0,s1++,depth1,0,block_flags);
2103421042
_cimg_mp_check_notnan_index(p1,s0);
21035-
} else { p1 = 11; s1 = s0; }
21043+
} else { p1 = 11; s1 = s0; } // Default: #-1
2103621044
_cimg_mp_check_list();
21037-
if (!is_push) {
21045+
if (is_n) {
2103821046
s0 = s1; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1;
21039-
arg1 = compile(s0,s1++,depth1,0,block_flags); // Position
21040-
} else if (is_push_heap) arg1 = ~0U - 1;
21041-
else arg1 = ~0U;
21042-
CImg<ulongT>::vector((ulongT)mp_da_insert_or_push,_cimg_mp_slot_nan,p1,arg1,0,0).move_to(l_opcode);
21043-
p3 = p1==~0U?2:3;
21047+
arg1 = compile(s0,s1++,depth1,0,block_flags); // Count
21048+
} else arg1 = ~0U;
21049+
if (is_insert) {
21050+
s0 = s1; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1;
21051+
arg2 = compile(s0,s1++,depth1,0,block_flags); // Position
21052+
} else if (is_push_heap) arg2 = ~0U - 1;
21053+
else arg2 = ~0U;
21054+
CImg<ulongT>::vector((ulongT)mp_da_insert_or_push_n,_cimg_mp_slot_nan,p1,arg1,arg2,0,0).move_to(l_opcode);
21055+
pos = (p1==~0U?2:3) + (is_n?1:0) + (is_insert?1:0);
2104421056
p1 = ~0U;
2104521057
for (s = s1; s<se; ++s) {
2104621058
ns = s; while (ns<se && (*ns!=',' || level[ns - expr._data]!=clevel1) &&
2104721059
(*ns!=')' || level[ns - expr._data]!=clevel)) ++ns;
21048-
arg2 = compile(s,ns,depth1,0,block_flags); // Element
21049-
p2 = size(arg2);
21050-
if (p1==~0U) p1 = p2;
21060+
arg3 = compile(s,ns,depth1,0,block_flags); // Element
21061+
p3 = size(arg3);
21062+
if (p1==~0U) p1 = p3;
2105121063
else {
21052-
if (!p1) _cimg_mp_check_type(arg2,p3,1,0);
21053-
else _cimg_mp_check_type(arg2,p3,2,p1);
21064+
if (!p1) _cimg_mp_check_type(arg3,pos,1,0);
21065+
else _cimg_mp_check_type(arg3,pos,2,p1);
2105421066
}
21055-
CImg<ulongT>::vector(arg2).move_to(l_opcode);
21067+
CImg<ulongT>::vector(arg3).move_to(l_opcode);
2105621068
s = ns;
21057-
++p3;
21069+
++pos;
2105821070
}
21059-
if (p1==~0U) compile(++s1,se1,depth1,0,block_flags); // Missing element -> error
21071+
if (p1==~0U && !is_n) compile(++s1,se1,depth1,0,block_flags); // Missing element -> error, if !is_n
2106021072
(l_opcode>'y').move_to(opcode);
21061-
opcode[4] = p1;
21062-
opcode[5] = opcode._height;
21073+
opcode[5] = p1;
21074+
opcode[6] = opcode._height;
2106321075
opcode.move_to(code);
2106421076
_cimg_mp_return_nan();
2106521077
}
@@ -21071,7 +21083,7 @@ namespace cimg_library {
2107121083
s0 = ss + 11; while (s0<se1 && (*s0!=',' || level[s0 - expr._data]!=clevel1)) ++s0;
2107221084
p1 = compile(ss + 11,s0++,depth1,0,block_flags);
2107321085
_cimg_mp_check_notnan_index(p1,ss + 11);
21074-
} else { p1 = 11; s0 = ss + 10; }
21086+
} else { p1 = 11; s0 = ss + 10; } // Default: #-1
2107521087
_cimg_mp_check_list();
2107621088

2107721089
arg1 = arg2 = ~0U;
@@ -21091,7 +21103,7 @@ namespace cimg_library {
2109121103
s0 = ss + 9; while (s0<se1 && (*s0!=',' || level[s0 - expr._data]!=clevel1)) ++s0;
2109221104
p1 = compile(ss + 9,s0++,depth1,0,block_flags);
2109321105
_cimg_mp_check_notnan_index(p1,ss + 9);
21094-
} else { p1 = 11; s0 = ss + 8; }
21106+
} else { p1 = 11; s0 = ss + 8; } // Default: #-1
2109521107
_cimg_mp_check_list();
2109621108
_cimg_mp_scalar1(da_size,p1);
2109721109
}
@@ -26568,25 +26580,34 @@ namespace cimg_library {
2656826580
return cimg::type<double>::nan();
2656926581
}
2657026582

26571-
static double mp_da_insert_or_push(_cimg_math_parser& mp) {
26572-
const bool is_push_heap = mp.opcode[3]==~0U - 1, is_push = mp.opcode[3]>=~0U - 1;
26573-
const char *const s_op = is_push_heap?"da_push_heap":is_push?"da_push":"da_insert";
26583+
static double mp_da_insert_or_push_n(_cimg_math_parser& mp) {
26584+
const unsigned int count = (unsigned int)(mp.opcode[3]==~0U?1:std::max(_mp_arg(3),0.));
26585+
if (!count) return cimg::type<double>::nan();
26586+
const bool
26587+
is_n = mp.opcode[3]!=~0U,
26588+
is_push_heap = mp.opcode[4]==~0U - 1,
26589+
is_push = mp.opcode[4]>=~0U - 1;
26590+
const char *const s_op =
26591+
is_push_heap?(is_n?"da_push_heap_n":"da_push_heap"):
26592+
is_push?(is_n?"da_push_n":"da_push"):
26593+
(is_n?"da_insert_n":"da_insert");
26594+
const unsigned int ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.imglist.width());
26595+
CImg<T> &img = mp.imglist[ind];
2657426596
mp_check_list(mp,s_op);
2657526597
const unsigned int
26576-
dim = (unsigned int)mp.opcode[4],
26577-
_dim = std::max(1U,dim),
26578-
nb_elts = (unsigned int)mp.opcode[5] - 6,
26579-
ind = (unsigned int)cimg::mod((int)_mp_arg(2),mp.imglist.width());
26580-
CImg<T> &img = mp.imglist[ind];
26598+
dim = (unsigned int)(mp.opcode[5]==~0U?img._spectrum:mp.opcode[5]),
26599+
dim1 = std::max(1U,dim),
26600+
nb_elts = (unsigned int)mp.opcode[6] - 7,
26601+
nb_elts1 = std::max(1U,nb_elts);
2658126602
const int
2658226603
siz = img?(int)cimg::float2uint(img[img._height - 1]):0,
26583-
pos0 = is_push?siz:(int)_mp_arg(3),
26604+
pos0 = is_push?siz:(int)_mp_arg(4),
2658426605
pos = pos0<0?pos0 + siz:pos0;
2658526606

26586-
if (img && _dim!=img._spectrum)
26607+
if (img && dim1!=img._spectrum)
2658726608
throw CImgArgumentException("[" cimg_appname "_math_parser] CImg<%s>: Function '%s()': "
2658826609
"Element to insert has invalid size %u (should be %u).",
26589-
mp.imgout.pixel_type(),s_op,_dim,img._spectrum);
26610+
mp.imgout.pixel_type(),s_op,dim1,img._spectrum);
2659026611
if (img && (img._width!=1 || img._depth!=1 || siz<0 || siz>img.height() - 1))
2659126612
throw CImgArgumentException("[" cimg_appname "_math_parser] CImg<%s>: Function '%s()': "
2659226613
"Specified image #%u of size (%d,%d,%d,%d) cannot be used as dynamic array%s.",
@@ -26598,31 +26619,42 @@ namespace cimg_library {
2659826619
"Invalid position %d (not in range -%d...%d).",
2659926620
mp.imgout.pixel_type(),s_op,pos0,siz,siz);
2660026621

26601-
if (siz + nb_elts + 1>=img._height) // Increase size of dynamic array, if necessary
26602-
img.resize(1,2*siz + nb_elts + 1,1,_dim,0);
26622+
if (siz + count*nb_elts1 + 1>=img._height) // Increase size of dynamic array, if necessary
26623+
img.resize(1,2*siz + count*nb_elts1 + 1,1,dim1,0);
2660326624

2660426625
if (pos!=siz) // Move existing data in dynamic array
26605-
cimg_forC(img,c) std::memmove(img.data(0,pos + nb_elts,0,c),img.data(0,pos,0,c),(siz - pos)*sizeof(T));
26606-
26607-
if (!dim) // Scalar or vector1() elements
26608-
for (unsigned int k = 0; k<nb_elts; ++k) {
26609-
int index = pos + k;
26610-
img[index] = (T)_mp_arg(6 + k);
26611-
if (is_push_heap) while (index>0) { // Heapify-up
26626+
cimg_forC(img,c) std::memmove(img.data(0,pos + count*nb_elts1,0,c),img.data(0,pos,0,c),(siz - pos)*sizeof(T));
26627+
26628+
if (dim1==1) { // Scalar or vector1() elements
26629+
if (nb_elts) {
26630+
for (unsigned int k = 0; k<nb_elts; ++k) img[pos + k] = (T)_mp_arg(7 + k);
26631+
if (count>1)
26632+
for (unsigned int k = 1; k<count; ++k) std::memcpy(&img[pos + k*nb_elts],&img[pos],nb_elts*sizeof(T));
26633+
} else std::memset(&img[pos],0,count*sizeof(T));
26634+
if (is_push_heap) for (unsigned int k = 0; k<nb_elts; ++k) {
26635+
int index = pos + k;
26636+
while (index>0) { // Heapify-up
2661226637
const int index_parent = (index - 1)/2;
2661326638
if (img[index]<img[index_parent]) {
2661426639
cimg::swap(img[index],img[index_parent]);
2661526640
index = index_parent; }
2661626641
else break;
2661726642
}
26618-
}
26619-
else // vectorN() elements, with N>1
26620-
for (unsigned int k = 0; k<nb_elts; ++k) {
26621-
int index = pos + k;
26622-
const double *const ptrs = &_mp_arg(6 + k) + 1;
26623-
T *ptrd = img.data(0,index);
26624-
cimg_forC(img,c) { *ptrd = ptrs[c]; ptrd+=img._height; }
26625-
if (is_push_heap) while (index>0) { // Heapify-up
26643+
}
26644+
} else { // vectorN() elements, with N>1
26645+
if (nb_elts) {
26646+
for (unsigned int k = 0; k<nb_elts; ++k) {
26647+
T *ptrd = img.data(0,pos + k);
26648+
const double *const ptrs = &_mp_arg(7 + k) + 1;
26649+
cimg_forC(img,c) { *ptrd = ptrs[c]; ptrd+=img._height; }
26650+
}
26651+
if (count>1)
26652+
cimg_forC(img,c) for (unsigned int k = 1; k<count; ++k)
26653+
std::memcpy(img.data(0,pos + k*nb_elts,0,c),img.data(0,pos,0,c),nb_elts*sizeof(T));
26654+
} else cimg_forC(img,c) std::memset(img.data(0,pos,0,c),0,count*sizeof(T));
26655+
if (is_push_heap) for (unsigned int k = 0; k<nb_elts; ++k) {
26656+
int index = pos + k;
26657+
while (index>0) { // Heapify-up
2662626658
const int index_parent = (index - 1)/2;
2662726659
if (img[index]<img[index_parent]) {
2662826660
T *ptr0 = img.data(0,index), *ptr1 = img.data(0,index_parent);
@@ -26631,8 +26663,9 @@ namespace cimg_library {
2663126663
}
2663226664
else break;
2663326665
}
26634-
}
26635-
img[img._height - 1] = cimg::uint2float(siz + nb_elts,(T)0);
26666+
}
26667+
}
26668+
img[img._height - 1] = cimg::uint2float(siz + count*nb_elts1,(T)0);
2663626669
return cimg::type<double>::nan();
2663726670
}
2663826671

@@ -26769,7 +26802,7 @@ namespace cimg_library {
2676926802
_mp_debug(complex_sqrt): _mp_debug(complex_tan): _mp_debug(complex_tanh): _mp_debug(continue):
2677026803
_mp_debug(convolve): _mp_debug(copy): _mp_debug(correlate): _mp_debug(cos): _mp_debug(cosh): _mp_debug(cov):
2677126804
_mp_debug(critical): _mp_debug(cross): _mp_debug(cumulate): _mp_debug(cut):
26772-
_mp_debug(da_back_or_pop): _mp_debug(da_freeze): _mp_debug(da_insert_or_push):
26805+
_mp_debug(da_back_or_pop): _mp_debug(da_freeze): _mp_debug(da_insert_or_push_n):
2677326806
_mp_debug(da_remove): _mp_debug(da_size): _mp_debug(date): _mp_debug(debug): _mp_debug(decrement):
2677426807
_mp_debug(deg2rad): _mp_debug(det): _mp_debug(diag): _mp_debug(div): _mp_debug(do): _mp_debug(dot):
2677526808
_mp_debug(echo): _mp_debug(ellipse): _mp_debug(epoch): _mp_debug(eq): _mp_debug(equalize):

0 commit comments

Comments
 (0)