@@ -23659,29 +23659,34 @@ namespace cimg_library {
2365923659 if (!std::strncmp(ss,"sort(",5)) { // Sort vector
2366023660 _cimg_mp_op("Function 'sort()'");
2366123661 s1 = ss5; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1;
23662- arg1 = compile(ss5,s1,depth1,0,block_flags);
23663- arg2 = arg4 = 1; arg3 = ~0U; arg5 = 0 ;
23662+ arg1 = compile(ss5,s1,depth1,0,block_flags); // X
23663+ arg2 = arg5 = 1; arg3 = arg6 = 0; arg4 = ~0U ;
2366423664 if (s1<se1) {
2366523665 s0 = ++s1; while (s0<se1 && (*s0!=',' || level[s0 - expr._data]!=clevel1)) ++s0;
23666- arg2 = compile(s1,s0,depth1,0,block_flags);
23666+ arg2 = compile(s1,s0,depth1,0,block_flags); // is_increasing
2366723667 if (s0<se1) {
2366823668 s1 = ++s0; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1;
23669- arg3 = compile(s0,s1,depth1,0,block_flags);
23669+ arg3 = compile(s0,s1,depth1,0,block_flags); // starting_index
2367023670 if (s1<se1) {
2367123671 s0 = ++s1; while (s0<se1 && (*s0!=',' || level[s0 - expr._data]!=clevel1)) ++s0;
23672- arg4 = compile(s1,s0,depth1,0,block_flags);
23673- arg5 = s0<se1?compile(++s0,se1,depth1,0,block_flags):0;
23672+ arg4 = compile(s1,s0,depth1,0,block_flags); // nb_elt
23673+ if (s0<se1) {
23674+ s1 = ++s0; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1;
23675+ arg5 = compile(s0,s1,depth1,0,block_flags); // size_elt
23676+ arg6 = s1<se1?compile(++s1,se1,depth1,0,block_flags):0; // sort_index
23677+ }
2367423678 }
2367523679 }
2367623680 }
2367723681 _cimg_mp_check_type(arg1,1,2,0);
2367823682 _cimg_mp_check_type(arg2,2,1,0);
23679- if (arg3!=~0U) _cimg_mp_check_type(arg3,3,1,0);
23680- _cimg_mp_check_type(arg4,4,1,0);
23683+ _cimg_mp_check_type(arg3,3,1,0);
23684+ if (arg4!=~0U) _cimg_mp_check_type(arg4,4,1,0);
2368123685 _cimg_mp_check_type(arg5,5,1,0);
23686+ _cimg_mp_check_type(arg6,6,1,0);
2368223687 p1 = size(arg1);
2368323688 pos = vector(p1);
23684- CImg<ulongT>::vector((ulongT)mp_sort,pos,arg1,p1,arg2,arg3,arg4,arg5).move_to(code);
23689+ CImg<ulongT>::vector((ulongT)mp_sort,pos,arg1,p1,arg2,arg3,arg4,arg5,arg6 ).move_to(code);
2368523690 return_comp = true;
2368623691 _cimg_mp_return(pos);
2368723692 }
@@ -29519,21 +29524,31 @@ namespace cimg_library {
2951929524 static double mp_sort(_cimg_math_parser& mp) {
2952029525 double *const ptrd = &_mp_arg(1) + 1;
2952129526 const double *const ptrs = &_mp_arg(2) + 1;
29527+ const int
29528+ siz = (int)mp.opcode[3],
29529+ starting_index = (int)_mp_arg(5),
29530+ nb_elts = mp.opcode[6]==~0U?siz:(int)_mp_arg(6),
29531+ siz_elt = (int)_mp_arg(7),
29532+ sort_index = (int)_mp_arg(8),
29533+ end_index = starting_index + nb_elts*siz_elt;
2952229534 const bool is_increasing = (bool)_mp_arg(4);
29523- const unsigned int
29524- siz = (unsigned int)mp.opcode[3],
29525- nb_elts = mp.opcode[5]==~0U?siz:(unsigned int)_mp_arg(5),
29526- siz_elt = (unsigned int)_mp_arg(6),
29527- sort_index = std::min((unsigned int)_mp_arg(7),siz_elt - 1);
29528- const ulongT sn = siz_elt*nb_elts;
29529- if (sn>siz || siz_elt<1)
29535+
29536+ if (starting_index<0 || nb_elts<0 || siz_elt<=0 || sort_index<0 || sort_index>=siz_elt || end_index>siz)
2953029537 throw CImgArgumentException("[" cimg_appname "_math_parser] CImg<%s>: Function 'sort()': "
29531- "Arguments 'nb_elts=%g' and 'siz_elt=%g' are invalid "
29532- "for sorting a vector of size %u.",
29533- mp.imgin.pixel_type(),_mp_arg(5),_mp_arg(6),siz);
29534- CImg<doubleT>(ptrd,siz_elt,nb_elts,1,1,true) = CImg<doubleT>(ptrs,siz_elt,nb_elts,1,1,true).
29535- shift(-(int)sort_index,0,0,0,2).get_sort(is_increasing,siz_elt>1?'y':0).shift((int)sort_index,0,0,0,2);
29536- if (sn<siz) CImg<doubleT>(ptrd + sn,siz - sn,1,1,1,true) = CImg<doubleT>(ptrs + sn,siz - sn,1,1,1,true);
29538+ "Invalid arguments 'starting_index=%g', 'nb_elts=%g', 'siz_elt=%g' and "
29539+ "'sort_index=%g', for sorting a vector of size %u.",
29540+ mp.imgin.pixel_type(),_mp_arg(5),_mp_arg(6),_mp_arg(7),_mp_arg(8),siz);
29541+ if (nb_elts) {
29542+ if (starting_index>0) // Recopy left side
29543+ std::memcpy(ptrd,ptrs,starting_index*sizeof(double));
29544+ if (end_index<siz) // Recopy right side
29545+ std::memcpy(ptrd + end_index,ptrs + end_index,(siz - end_index)*sizeof(double));
29546+
29547+ // Sort region.
29548+ CImg<doubleT>(ptrd + starting_index,siz_elt,nb_elts,1,1,true) =
29549+ CImg<doubleT>(ptrs + starting_index,siz_elt,nb_elts,1,1,true).
29550+ shift(-(int)sort_index,0,0,0,2).get_sort(is_increasing,siz_elt>1?'y':0).shift((int)sort_index,0,0,0,2);
29551+ }
2953729552 return cimg::type<double>::nan();
2953829553 }
2953929554
0 commit comments