Skip to content

Commit c5c3ec4

Browse files
committed
Merge pull request opencv#8655 from alalek:fix_bug_persistence_raw_io
2 parents 62e9bed + 75f2824 commit c5c3ec4

File tree

2 files changed

+73
-18
lines changed

2 files changed

+73
-18
lines changed

modules/core/src/persistence.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4907,7 +4907,7 @@ cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader,
49074907
{
49084908
char* data0 = (char*)_data;
49094909
int fmt_pairs[CV_FS_MAX_FMT_PAIRS*2], k = 0, fmt_pair_count;
4910-
int i = 0, offset = 0, count = 0;
4910+
int i = 0, count = 0;
49114911

49124912
CV_CHECK_FILE_STORAGE( fs );
49134913

@@ -4918,9 +4918,11 @@ cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader,
49184918
CV_Error( CV_StsBadSize, "The readed sequence is a scalar, thus len must be 1" );
49194919

49204920
fmt_pair_count = icvDecodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS );
4921+
size_t step = ::icvCalcStructSize(dt, 0);
49214922

49224923
for(;;)
49234924
{
4925+
int offset = 0;
49244926
for( k = 0; k < fmt_pair_count; k++ )
49254927
{
49264928
int elem_type = fmt_pairs[k*2+1];
@@ -5038,6 +5040,7 @@ cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader,
50385040

50395041
offset = (int)(data - data0);
50405042
}
5043+
data0 += step;
50415044
}
50425045

50435046
end_loop:

modules/core/test/test_io.cpp

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -614,13 +614,41 @@ struct data_t
614614
typedef float f;
615615
typedef double d;
616616

617-
u u1 ;u u2 ; i i1 ;
618-
i i2 ;i i3 ;
619-
d d1 ;
620-
d d2 ;
621-
i i4 ;
622-
623-
static inline const char * signature() { return "2u3i2di"; }
617+
/*0x00*/ u u1 ;u u2 ; i i1 ;
618+
/*0x08*/ i i2 ;i i3 ;
619+
/*0x10*/ d d1 ;
620+
/*0x18*/ d d2 ;
621+
/*0x20*/ i i4 ;i required_alignment_field_for_linux32;
622+
/*
623+
* OpenCV persistence.cpp stuff expects: sizeof(data_t) = alignSize(36, sizeof(largest type = double)) = 40
624+
* Some compilers on some archs returns sizeof(data_t) = 36 due struct packaging UB
625+
*/
626+
627+
static inline const char * signature() {
628+
if (sizeof(data_t) != 40)
629+
{
630+
printf("sizeof(data_t)=%d, u1=%p u2=%p i1=%p i2=%p i3=%p d1=%p d2=%p i4=%p\n", (int)sizeof(data_t),
631+
&(((data_t*)0)->u1),
632+
&(((data_t*)0)->u2),
633+
&(((data_t*)0)->i1),
634+
&(((data_t*)0)->i2),
635+
&(((data_t*)0)->i3),
636+
&(((data_t*)0)->d1),
637+
&(((data_t*)0)->d2),
638+
&(((data_t*)0)->i4)
639+
);
640+
}
641+
CV_Assert(sizeof(data_t) == 40);
642+
CV_Assert((size_t)&(((data_t*)0)->u1) == 0x0);
643+
CV_Assert((size_t)&(((data_t*)0)->u2) == 0x1);
644+
CV_Assert((size_t)&(((data_t*)0)->i1) == 0x4);
645+
CV_Assert((size_t)&(((data_t*)0)->i2) == 0x8);
646+
CV_Assert((size_t)&(((data_t*)0)->i3) == 0xc);
647+
CV_Assert((size_t)&(((data_t*)0)->d1) == 0x10);
648+
CV_Assert((size_t)&(((data_t*)0)->d2) == 0x18);
649+
CV_Assert((size_t)&(((data_t*)0)->i4) == 0x20);
650+
return "2u3i2di";
651+
}
624652
};
625653

626654
TEST(Core_InputOutput, filestorage_base64_basic)
@@ -718,16 +746,24 @@ TEST(Core_InputOutput, filestorage_base64_basic)
718746
fs.release();
719747
}
720748

721-
for (int i = 0; i < 1000; i++) {
722-
// TODO: Solve this bug in `cvReadRawData`
723-
//EXPECT_EQ(rawdata[i].u1, 1);
724-
//EXPECT_EQ(rawdata[i].u2, 2);
725-
//EXPECT_EQ(rawdata[i].i1, 1);
726-
//EXPECT_EQ(rawdata[i].i2, 2);
727-
//EXPECT_EQ(rawdata[i].i3, 3);
728-
//EXPECT_EQ(rawdata[i].d1, 0.1);
729-
//EXPECT_EQ(rawdata[i].d2, 0.2);
730-
//EXPECT_EQ(rawdata[i].i4, i);
749+
int errors = 0;
750+
for (int i = 0; i < 1000; i++)
751+
{
752+
EXPECT_EQ((int)rawdata[i].u1, 1);
753+
EXPECT_EQ((int)rawdata[i].u2, 2);
754+
EXPECT_EQ((int)rawdata[i].i1, 1);
755+
EXPECT_EQ((int)rawdata[i].i2, 2);
756+
EXPECT_EQ((int)rawdata[i].i3, 3);
757+
EXPECT_EQ(rawdata[i].d1, 0.1);
758+
EXPECT_EQ(rawdata[i].d2, 0.2);
759+
EXPECT_EQ((int)rawdata[i].i4, i);
760+
if (::testing::Test::HasNonfatalFailure())
761+
{
762+
printf("i = %d\n", i);
763+
errors++;
764+
}
765+
if (errors >= 3)
766+
break;
731767
}
732768

733769
EXPECT_TRUE(no_type_id);
@@ -741,9 +777,25 @@ TEST(Core_InputOutput, filestorage_base64_basic)
741777
EXPECT_EQ(_2d_in.cols , _2d_out.cols);
742778
EXPECT_EQ(_2d_in.dims , _2d_out.dims);
743779
EXPECT_EQ(_2d_in.depth(), _2d_out.depth());
780+
781+
errors = 0;
744782
for(int i = 0; i < _2d_out.rows; ++i)
783+
{
745784
for (int j = 0; j < _2d_out.cols; ++j)
785+
{
746786
EXPECT_EQ(_2d_in.at<cv::Vec3b>(i, j), _2d_out.at<cv::Vec3b>(i, j));
787+
if (::testing::Test::HasNonfatalFailure())
788+
{
789+
printf("i = %d, j = %d\n", i, j);
790+
errors++;
791+
}
792+
if (errors >= 3)
793+
{
794+
i = _2d_out.rows;
795+
break;
796+
}
797+
}
798+
}
747799

748800
EXPECT_EQ(_nd_in.rows , _nd_out.rows);
749801
EXPECT_EQ(_nd_in.cols , _nd_out.cols);

0 commit comments

Comments
 (0)