1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00

fixed double free bug of sequences

This commit is contained in:
ser1zw 2011-08-04 03:09:30 +09:00
parent 37109f225d
commit 43c67a60cc
8 changed files with 56 additions and 118 deletions

View file

@ -67,18 +67,8 @@ define_ruby_class()
VALUE VALUE
rb_allocate(VALUE klass) rb_allocate(VALUE klass)
{ {
CvChain *ptr = ALLOC(CvChain); CvChain *ptr;
return Data_Wrap_Struct(klass, 0, cvchain_free, ptr); return Data_Make_Struct(klass, CvChain, 0, 0, ptr);
}
void
cvchain_free(void *ptr)
{
if (ptr) {
CvChain *chain = (CvChain*)ptr;
if (chain->storage)
cvReleaseMemStorage(&(chain->storage));
}
} }
VALUE VALUE

View file

@ -22,7 +22,6 @@ VALUE rb_class();
void define_ruby_class(); void define_ruby_class();
VALUE rb_allocate(VALUE klass); VALUE rb_allocate(VALUE klass);
void cvchain_free(void *ptr);
VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_initialize(int argc, VALUE *argv, VALUE self);
VALUE rb_origin(VALUE self); VALUE rb_origin(VALUE self);

View file

@ -55,25 +55,11 @@ define_ruby_class()
rb_define_method(rb_klass, "contour", RUBY_METHOD_FUNC(rb_contour), 0); rb_define_method(rb_klass, "contour", RUBY_METHOD_FUNC(rb_contour), 0);
} }
void
cvconnectedcomp_free(void *ptr)
{
if (ptr) {
CvConnectedComp* connected_comp = (CvConnectedComp*)ptr;
if (connected_comp->contour) {
CvContour *contour = (CvContour*)connected_comp->contour;
if (contour->storage)
cvReleaseMemStorage(&(contour->storage));
}
free(ptr);
}
}
VALUE VALUE
rb_allocate(VALUE klass) rb_allocate(VALUE klass)
{ {
CvConnectedComp *ptr; CvConnectedComp *ptr;
return Data_Make_Struct(klass, CvConnectedComp, 0, cvconnectedcomp_free, ptr); return Data_Make_Struct(klass, CvConnectedComp, 0, -1, ptr);
} }
VALUE VALUE

View file

@ -80,39 +80,31 @@ define_ruby_class()
VALUE VALUE
rb_allocate(VALUE klass) rb_allocate(VALUE klass)
{ {
CvContour *ptr = ALLOC(CvContour); CvContour *ptr;
return Data_Wrap_Struct(klass, 0, cvcontour_free, ptr); return Data_Make_Struct(klass, CvContour, mark_root_object, unresist_object, ptr);
}
void
cvcontour_free(void *ptr)
{
if (ptr) {
CvContour *contour = (CvContour*)ptr;
if (contour->storage)
cvReleaseMemStorage(&(contour->storage));
}
} }
VALUE VALUE
rb_initialize(int argc, VALUE *argv, VALUE self) rb_initialize(int argc, VALUE *argv, VALUE self)
{ {
CvMemStorage *storage; VALUE storage;
VALUE storage_value; rb_scan_args(argc, argv, "01", &storage);
if (rb_scan_args(argc, argv, "01", &storage_value) > 0) {
storage_value = CHECK_CVMEMSTORAGE(storage_value);
storage = CVMEMSTORAGE(storage_value);
}
else
storage = rb_cvCreateMemStorage(0);
if (NIL_P(storage))
storage = cCvMemStorage::new_object(0);
else
storage = CHECK_CVMEMSTORAGE(storage);
CvContour* contour = (CvContour*)DATA_PTR(self);
try { try {
DATA_PTR(self) = (CvContour*)cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvContour), contour = (CvContour*)cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvContour),
sizeof(CvPoint), storage); sizeof(CvPoint), CVMEMSTORAGE(storage));
} }
catch (cv::Exception& e) { catch (cv::Exception& e) {
raise_cverror(e); raise_cverror(e);
} }
resist_root_object((CvSeq*)contour, storage);
return self; return self;
} }
@ -270,7 +262,6 @@ VALUE
rb_point_polygon_test(VALUE self, VALUE point, VALUE measure_dist) rb_point_polygon_test(VALUE self, VALUE point, VALUE measure_dist)
{ {
int measure_dist_flag; int measure_dist_flag;
double dist;
if (measure_dist == Qtrue) if (measure_dist == Qtrue)
measure_dist_flag = 1; measure_dist_flag = 1;
@ -279,6 +270,7 @@ rb_point_polygon_test(VALUE self, VALUE point, VALUE measure_dist)
else else
measure_dist_flag = NUM2INT(measure_dist); measure_dist_flag = NUM2INT(measure_dist);
double dist = Qnil;
try { try {
dist = cvPointPolygonTest(CVARR(self), VALUE_TO_CVPOINT2D32F(point), measure_dist_flag); dist = cvPointPolygonTest(CVARR(self), VALUE_TO_CVPOINT2D32F(point), measure_dist_flag);
} }

View file

@ -59,11 +59,20 @@ seqblock_class(void *ptr)
} }
void void
resist_class_information_of_sequence(CvSeq *seq, VALUE klass) register_elem_class(CvSeq *seq, VALUE klass)
{ {
st_insert(seqblock_klass_table, (st_data_t)seq, (st_data_t)klass); st_insert(seqblock_klass_table, (st_data_t)seq, (st_data_t)klass);
} }
void
unregister_elem_class(void *ptr)
{
if (ptr) {
st_delete(seqblock_klass_table, (st_data_t*)&ptr, NULL);
unresist_object(ptr);
}
}
void void
define_ruby_class() define_ruby_class()
{ {
@ -111,18 +120,7 @@ VALUE
rb_allocate(VALUE klass) rb_allocate(VALUE klass)
{ {
CvSeq *ptr = ALLOC(CvSeq); CvSeq *ptr = ALLOC(CvSeq);
return Data_Wrap_Struct(klass, 0, cvseq_free, ptr); return Data_Wrap_Struct(klass, 0, unregister_elem_class, ptr);
}
void
cvseq_free(void *ptr)
{
if (ptr) {
CvSeq *seq = (CvSeq*)ptr;
st_delete(seqblock_klass_table, (st_data_t*)&ptr, NULL);
if (seq->storage)
cvReleaseMemStorage(&(seq->storage));
}
} }
/* /*
@ -138,15 +136,8 @@ VALUE
rb_initialize(int argc, VALUE *argv, VALUE self) rb_initialize(int argc, VALUE *argv, VALUE self)
{ {
VALUE klass, storage_value; VALUE klass, storage_value;
CvMemStorage *storage;
if (rb_scan_args(argc, argv, "11", &klass, &storage_value) > 1) {
storage_value = CHECK_CVMEMSTORAGE(storage_value);
storage = CVMEMSTORAGE(storage_value);
}
else
storage = rb_cvCreateMemStorage(0);
rb_scan_args(argc, argv, "11", &klass, &storage_value);
if (!rb_obj_is_kind_of(klass, rb_cClass)) if (!rb_obj_is_kind_of(klass, rb_cClass))
raise_typeerror(klass, rb_cClass); raise_typeerror(klass, rb_cClass);
@ -171,14 +162,22 @@ rb_initialize(int argc, VALUE *argv, VALUE self)
rb_raise(rb_eArgError, "unsupport %s class for sequence-block.", rb_class2name(klass)); rb_raise(rb_eArgError, "unsupport %s class for sequence-block.", rb_class2name(klass));
CvSeq* seq = NULL; CvSeq* seq = NULL;
if (NIL_P(storage_value)) {
storage_value = cCvMemStorage::new_object(0);
}
else {
storage_value = CHECK_CVMEMSTORAGE(storage_value);
}
try { try {
seq = cvCreateSeq(type, sizeof(CvSeq), size, storage); seq = cvCreateSeq(type, sizeof(CvSeq), size, CVMEMSTORAGE(storage_value));
} }
catch (cv::Exception& e) { catch (cv::Exception& e) {
raise_cverror(e); raise_cverror(e);
} }
DATA_PTR(self) = seq; DATA_PTR(self) = seq;
resist_class_information_of_sequence(seq, klass); register_elem_class(seq, klass);
resist_root_object(seq, storage_value);
return self; return self;
} }
@ -587,39 +586,13 @@ rb_remove(VALUE self, VALUE index)
return self; return self;
} }
/*
VALUE
new_object(CvSeq *seq, VALUE klass)
{
VALUE storage = cCvMemStorage::new_object();
VALUE object = REFER_OBJECT(rb_klass, seq, storage);
st_insert(seqblock_klass, (st_data_t)seq, (st_data_t)klass);
return object;
}
VALUE
new_object(CvSeq *seq, VALUE klass, VALUE storage)
{
VALUE object = REFER_OBJECT(rb_klass, seq, storage);
st_insert(seqblock_klass, (st_data_t)seq, (st_data_t)klass);
return object;
}
*/
void
unresist_cvseq(void *ptr)
{
if (ptr)
st_delete(seqblock_klass_table, (st_data_t*)&ptr, NULL);
}
VALUE VALUE
new_sequence(VALUE klass, CvSeq *seq, VALUE element_klass, VALUE storage) new_sequence(VALUE klass, CvSeq *seq, VALUE element_klass, VALUE storage)
{ {
resist_root_object(seq, storage); resist_root_object(seq, storage);
if (!NIL_P(element_klass)) if (!NIL_P(element_klass))
resist_class_information_of_sequence(seq, element_klass); register_elem_class(seq, element_klass);
return Data_Wrap_Struct(klass, mark_root_object, unresist_cvseq, seq); return Data_Wrap_Struct(klass, mark_root_object, unregister_elem_class, seq);
} }
VALUE VALUE

View file

@ -24,8 +24,6 @@ void define_ruby_class();
VALUE seqblock_class(void *ptr); VALUE seqblock_class(void *ptr);
VALUE rb_allocate(VALUE klass); VALUE rb_allocate(VALUE klass);
void free(void *ptr);
void resist_class_information_of_sequence(CvSeq *seq, VALUE klass);
VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_initialize(int argc, VALUE *argv, VALUE self);
VALUE rb_total(VALUE self); VALUE rb_total(VALUE self);