@@ -710,51 +710,58 @@ double cv::norm( InputArray _src, int normType, InputArray _mask )
710710 result;
711711 result.d = 0 ;
712712 NAryMatIterator it (arrays, ptrs);
713- int j, total = (int )it.size , blockSize = total, intSumBlockSize = 0 , count = 0 ;
714- bool blockSum = (normType == NORM_L1 && depth <= CV_16S) ||
715- ((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S);
716- int isum = 0 ;
717- int *ibuf = &result.i ;
718- size_t esz = 0 ;
719-
720- if ( blockSum )
721- {
722- intSumBlockSize = (normType == NORM_L1 && depth <= CV_8S ? (1 << 23 ) : (1 << 15 ))/cn;
723- blockSize = std::min (blockSize, intSumBlockSize);
724- ibuf = &isum;
725- esz = src.elemSize ();
726- }
713+ CV_CheckLT ((size_t )it.size , (size_t )INT_MAX, " " );
727714
728- for ( size_t i = 0 ; i < it.nplanes ; i++, ++it )
715+ if ((normType == NORM_L1 && depth <= CV_16S) ||
716+ ((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S))
729717 {
730- for ( j = 0 ; j < total; j += blockSize )
718+ // special case to handle "integer" overflow in accumulator
719+ const size_t esz = src.elemSize ();
720+ const int total = (int )it.size ;
721+ const int intSumBlockSize = (normType == NORM_L1 && depth <= CV_8S ? (1 << 23 ) : (1 << 15 ))/cn;
722+ const int blockSize = std::min (total, intSumBlockSize);
723+ int isum = 0 ;
724+ int count = 0 ;
725+
726+ for (size_t i = 0 ; i < it.nplanes ; i++, ++it)
731727 {
732- int bsz = std::min (total - j, blockSize);
733- func ( ptrs[0 ], ptrs[1 ], (uchar*)ibuf, bsz, cn );
734- count += bsz;
735- if ( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
728+ for (int j = 0 ; j < total; j += blockSize)
736729 {
737- result.d += isum;
738- isum = 0 ;
739- count = 0 ;
730+ int bsz = std::min (total - j, blockSize);
731+ func (ptrs[0 ], ptrs[1 ], (uchar*)&isum, bsz, cn);
732+ count += bsz;
733+ if (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total))
734+ {
735+ result.d += isum;
736+ isum = 0 ;
737+ count = 0 ;
738+ }
739+ ptrs[0 ] += bsz*esz;
740+ if (ptrs[1 ])
741+ ptrs[1 ] += bsz;
740742 }
741- ptrs[0 ] += bsz*esz;
742- if ( ptrs[1 ] )
743- ptrs[1 ] += bsz;
743+ }
744+ }
745+ else
746+ {
747+ // generic implementation
748+ for (size_t i = 0 ; i < it.nplanes ; i++, ++it)
749+ {
750+ func (ptrs[0 ], ptrs[1 ], (uchar*)&result, (int )it.size , cn);
744751 }
745752 }
746753
747754 if ( normType == NORM_INF )
748755 {
749756 if ( depth == CV_64F )
750- ;
757+ return result. d ;
751758 else if ( depth == CV_32F )
752- result. d = result.f ;
759+ return result.f ;
753760 else
754- result. d = result.i ;
761+ return result.i ;
755762 }
756763 else if ( normType == NORM_L2 )
757- result. d = std::sqrt (result.d );
764+ return std::sqrt (result.d );
758765
759766 return result.d ;
760767}
@@ -1170,52 +1177,59 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m
11701177 result;
11711178 result.d = 0 ;
11721179 NAryMatIterator it (arrays, ptrs);
1173- int j, total = (int )it.size , blockSize = total, intSumBlockSize = 0 , count = 0 ;
1174- bool blockSum = (normType == NORM_L1 && depth <= CV_16S) ||
1175- ((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S);
1176- unsigned isum = 0 ;
1177- unsigned *ibuf = &result.u ;
1178- size_t esz = 0 ;
1179-
1180- if ( blockSum )
1181- {
1182- intSumBlockSize = normType == NORM_L1 && depth <= CV_8S ? (1 << 23 ) : (1 << 15 );
1183- blockSize = std::min (blockSize, intSumBlockSize);
1184- ibuf = &isum;
1185- esz = src1.elemSize ();
1186- }
1180+ CV_CheckLT ((size_t )it.size , (size_t )INT_MAX, " " );
11871181
1188- for ( size_t i = 0 ; i < it.nplanes ; i++, ++it )
1182+ if ((normType == NORM_L1 && depth <= CV_16S) ||
1183+ ((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S))
11891184 {
1190- for ( j = 0 ; j < total; j += blockSize )
1185+ // special case to handle "integer" overflow in accumulator
1186+ const size_t esz = src1.elemSize ();
1187+ const int total = (int )it.size ;
1188+ const int intSumBlockSize = normType == NORM_L1 && depth <= CV_8S ? (1 << 23 ) : (1 << 15 );
1189+ const int blockSize = std::min (total, intSumBlockSize);
1190+ int isum = 0 ;
1191+ int count = 0 ;
1192+
1193+ for (size_t i = 0 ; i < it.nplanes ; i++, ++it)
11911194 {
1192- int bsz = std::min (total - j, blockSize);
1193- func ( ptrs[0 ], ptrs[1 ], ptrs[2 ], (uchar*)ibuf, bsz, cn );
1194- count += bsz;
1195- if ( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
1195+ for (int j = 0 ; j < total; j += blockSize)
11961196 {
1197- result.d += isum;
1198- isum = 0 ;
1199- count = 0 ;
1197+ int bsz = std::min (total - j, blockSize);
1198+ func (ptrs[0 ], ptrs[1 ], ptrs[2 ], (uchar*)&isum, bsz, cn);
1199+ count += bsz;
1200+ if (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total))
1201+ {
1202+ result.d += isum;
1203+ isum = 0 ;
1204+ count = 0 ;
1205+ }
1206+ ptrs[0 ] += bsz*esz;
1207+ ptrs[1 ] += bsz*esz;
1208+ if (ptrs[2 ])
1209+ ptrs[2 ] += bsz;
12001210 }
1201- ptrs[0 ] += bsz*esz;
1202- ptrs[1 ] += bsz*esz;
1203- if ( ptrs[2 ] )
1204- ptrs[2 ] += bsz;
1211+ }
1212+ }
1213+ else
1214+ {
1215+ // generic implementation
1216+ for (size_t i = 0 ; i < it.nplanes ; i++, ++it)
1217+ {
1218+ func (ptrs[0 ], ptrs[1 ], ptrs[2 ], (uchar*)&result, (int )it.size , cn);
12051219 }
12061220 }
12071221
12081222 if ( normType == NORM_INF )
12091223 {
12101224 if ( depth == CV_64F )
1211- ;
1225+ return result. d ;
12121226 else if ( depth == CV_32F )
1213- result. d = result.f ;
1227+ return result.f ;
12141228 else
1215- result. d = result.u ;
1229+ return result.u ;
12161230 }
12171231 else if ( normType == NORM_L2 )
1218- result. d = std::sqrt (result.d );
1232+ return std::sqrt (result.d );
12191233
12201234 return result.d ;
12211235}
0 commit comments