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:
parent
37109f225d
commit
43c67a60cc
8 changed files with 56 additions and 118 deletions
|
@ -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
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#define RUBY_OPENCV_CVCHAIN_H
|
#define RUBY_OPENCV_CVCHAIN_H
|
||||||
#include "opencv.h"
|
#include "opencv.h"
|
||||||
|
|
||||||
#define __NAMESPACE_BEGIN_CVCHAIN namespace cCvChain{
|
#define __NAMESPACE_BEGIN_CVCHAIN namespace cCvChain {
|
||||||
#define __NAMESPACE_END_CVCHAIN }
|
#define __NAMESPACE_END_CVCHAIN }
|
||||||
|
|
||||||
__NAMESPACE_BEGIN_OPENCV
|
__NAMESPACE_BEGIN_OPENCV
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,11 +158,11 @@ rb_approx_poly(int argc, VALUE *argv, VALUE self)
|
||||||
approx_poly_option = APPROX_POLY_OPTION(approx_poly_option);
|
approx_poly_option = APPROX_POLY_OPTION(approx_poly_option);
|
||||||
storage = cCvMemStorage::new_object();
|
storage = cCvMemStorage::new_object();
|
||||||
/*
|
/*
|
||||||
CvSeq *contour = cvApproxPoly(CVCONTOUR(self), sizeof(CvContour), CVMEMSTORAGE(storage),
|
CvSeq *contour = cvApproxPoly(CVCONTOUR(self), sizeof(CvContour), CVMEMSTORAGE(storage),
|
||||||
APPROX_POLY_METHOD(approx_poly_option),
|
APPROX_POLY_METHOD(approx_poly_option),
|
||||||
APPROX_POLY_ACCURACY(approx_poly_option),
|
APPROX_POLY_ACCURACY(approx_poly_option),
|
||||||
APPROX_POLY_RECURSIVE(approx_poly_option));
|
APPROX_POLY_RECURSIVE(approx_poly_option));
|
||||||
return cCvSeq::new_sequence(cCvContour::rb_class(), contour, cCvPoint::rb_class(), storage);
|
return cCvSeq::new_sequence(cCvContour::rb_class(), contour, cCvPoint::rb_class(), storage);
|
||||||
*/
|
*/
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
@ -270,8 +262,7 @@ 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;
|
||||||
else if (measure_dist == Qfalse)
|
else if (measure_dist == Qfalse)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#define RUBY_OPENCV_CVCONTOUR_H
|
#define RUBY_OPENCV_CVCONTOUR_H
|
||||||
#include "opencv.h"
|
#include "opencv.h"
|
||||||
|
|
||||||
#define __NAMESPACE_BEGIN_CVCONTOUR namespace cCvContour{
|
#define __NAMESPACE_BEGIN_CVCONTOUR namespace cCvContour {
|
||||||
#define __NAMESPACE_END_CVCONTOUR }
|
#define __NAMESPACE_END_CVCONTOUR }
|
||||||
|
|
||||||
__NAMESPACE_BEGIN_OPENCV
|
__NAMESPACE_BEGIN_OPENCV
|
||||||
|
|
|
@ -39,10 +39,10 @@ CVMEMSTORAGE(VALUE object)
|
||||||
inline VALUE
|
inline VALUE
|
||||||
CHECK_CVMEMSTORAGE(VALUE object)
|
CHECK_CVMEMSTORAGE(VALUE object)
|
||||||
{
|
{
|
||||||
if(rb_obj_is_kind_of(object, cCvMemStorage::rb_class()))
|
if (rb_obj_is_kind_of(object, cCvMemStorage::rb_class()))
|
||||||
return object;
|
return object;
|
||||||
else{
|
else {
|
||||||
if(!NIL_P(object))
|
if (!NIL_P(object))
|
||||||
rb_warn("invalid CvMemStorage object given. allocate new memory storage automatically.");
|
rb_warn("invalid CvMemStorage object given. allocate new memory storage automatically.");
|
||||||
return cCvMemStorage::new_object();
|
return cCvMemStorage::new_object();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,15 +59,24 @@ 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()
|
||||||
{
|
{
|
||||||
if(rb_klass)
|
if (rb_klass)
|
||||||
return;
|
return;
|
||||||
/*
|
/*
|
||||||
* opencv = rb_define_module("OpenCV");
|
* opencv = rb_define_module("OpenCV");
|
||||||
|
@ -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) {
|
rb_scan_args(argc, argv, "11", &klass, &storage_value);
|
||||||
storage_value = CHECK_CVMEMSTORAGE(storage_value);
|
|
||||||
storage = CVMEMSTORAGE(storage_value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
storage = rb_cvCreateMemStorage(0);
|
|
||||||
|
|
||||||
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,46 +586,20 @@ 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
|
||||||
auto_extend(VALUE object)
|
auto_extend(VALUE object)
|
||||||
{
|
{
|
||||||
CvSeq *seq = CVSEQ(object);
|
CvSeq *seq = CVSEQ(object);
|
||||||
if(CV_IS_SEQ_POINT_SET(seq)){
|
if (CV_IS_SEQ_POINT_SET(seq)) {
|
||||||
rb_extend_object(object, mPointSet::rb_module());
|
rb_extend_object(object, mPointSet::rb_module());
|
||||||
}
|
}
|
||||||
return object;
|
return object;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include "opencv.h"
|
#include "opencv.h"
|
||||||
|
|
||||||
#define __NAMESPACE_BEGIN_CVSEQ namespace cCvSeq{
|
#define __NAMESPACE_BEGIN_CVSEQ namespace cCvSeq {
|
||||||
#define __NAMESPACE_END_CVSEQ }
|
#define __NAMESPACE_END_CVSEQ }
|
||||||
|
|
||||||
__NAMESPACE_BEGIN_OPENCV
|
__NAMESPACE_BEGIN_OPENCV
|
||||||
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue