Skip to content

Commit f40d9d7

Browse files
committed
Merge branch 'develop'
2 parents f017d0c + 52410fc commit f40d9d7

File tree

13 files changed

+188
-91
lines changed

13 files changed

+188
-91
lines changed

DEVELOPERS_NOTE.md

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
* [hoe](https://github.com/seattlerb/hoe)
1515
* [hoe-gemspec](https://github.com/flavorjones/hoe-gemspec)
1616
* [rake-compiler](https://github.com/luislavena/rake-compiler)
17-
* [gem-compile](https://github.com/frsyuki/gem-compile)
1817

1918

2019
## Create ruby-opencv gem
2120
Run the following commands.
22-
When you use mingw32, use **MSYS console**, or when you use mswin32,
21+
When you use mingw32, use **MSYS console**, or when you use mswin32,
2322
use [**Visual Studio Command Prompt**](http://msdn.microsoft.com/en-us/library/ms229859.aspx)
2423
instead of cmd.exe.
2524

@@ -32,16 +31,34 @@ $ git ls-files > Manifest.txt
3231
$ rake gem:spec
3332
$ rake gem
3433
```
35-
**ruby-opencv-x.y.z.gem** will be created in pkg/ directory.
34+
**ruby-opencv-x.y.z.gem** will be created in **pkg** directory.
3635

37-
To create pre-build binaries, run the following commands in Windows.
36+
To create pre-build binaries, create a config file firstly:
3837

38+
```yml
39+
# config.yml
40+
platform: mingw32
41+
rubies:
42+
- C:/ruby-1.9.3-p392-mingw32/bin/ruby.exe
43+
- C:/ruby-2.0.0-p0-mingw32/bin/ruby.exe
44+
extopts:
45+
- --with-opencv-include=C:/opencv/build/include
46+
- --with-opencv-lib=C:/opencv/build/x86/mingw/lib
3947
```
40-
$ cd pkg
41-
$ gem compile ruby-opencv-*.gem
48+
49+
Entries are below:
50+
51+
- **platform**: Target platform (e.g. mingw32, mswin32)
52+
- **rubies**: Array of target versions of ruby's paths (You can create fat gems if you specify multiple versions of ruby)
53+
- **extopts**: Array of options to be passed to **extconf.rb**
54+
55+
Then, run the following command:
56+
57+
```
58+
$ rake gem:precompile CONFIG=config.yml
4259
```
4360

44-
**ruby-opencv-x.y.z-x86-mingw32.gem** will be created when you use mingw32, or
61+
**ruby-opencv-x.y.z-mingw32.gem** will be created when you use mingw32, or
4562
**ruby-opencv-x.y.z-x86-mswin32.gem** when you use mswin32.
4663

4764

Gemfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@ group :development do
44
gem "hoe"
55
gem "hoe-gemspec"
66
gem "rake-compiler"
7-
gem "gem-compile"
87
end
98

Manifest.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ License.txt
66
Manifest.txt
77
README.md
88
Rakefile
9+
config.yml
910
examples/alpha_blend.rb
1011
examples/box.png
1112
examples/box_in_scene.png

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
An OpenCV wrapper for Ruby.
44

55
* Web site: <https://github.com/ruby-opencv/ruby-opencv>
6-
* Ruby 1.9.3, 2.0.0 and OpenCV 2.4.4 are supported.
6+
* Ruby 1.9.3, 2.0.0 and OpenCV 2.4.5 are supported.
77

88
## Requirement
99

Rakefile

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# -*- mode: ruby; coding: utf-8 -*-
22
require 'rubygems'
3-
require './lib/opencv/psyched_yaml'
3+
require "rubygems/ext"
4+
require "rubygems/installer"
45
require 'hoe'
56
require 'rake/extensiontask'
7+
require 'fileutils'
8+
require './lib/opencv/psyched_yaml'
9+
10+
SO_FILE = 'opencv.so'
611

712
Hoe.plugin :gemspec
813

@@ -16,19 +21,70 @@ hoespec = Hoe.spec 'ruby-opencv' do |s|
1621

1722
s.readme_file = 'README.md'
1823
s.history_file = 'History.txt'
24+
1925
s.spec_extras = { :extensions => ['ext/opencv/extconf.rb'] }
26+
2027
s.test_globs = ['test/test_*.rb']
2128
s.urls = ['https://github.com/ruby-opencv/ruby-opencv/']
2229

2330
s.extra_dev_deps << ['rake-compiler', '>= 0'] << ['hoe-gemspec']
2431

2532
Rake::ExtensionTask.new('opencv', spec) do |ext|
26-
ext.lib_dir = File.join('lib', 'opencv')
33+
ext.lib_dir = 'lib'
2734
end
2835
end
2936

3037
hoespec.spec.files.delete('.gemtest')
3138

3239
Rake::Task[:test].prerequisites << :compile
3340

41+
desc 'Create a pre-compiled gem'
42+
task 'gem:precompile' => ['gem'] do
43+
tmp_dir = Dir.mktmpdir('tmp', '.')
44+
gemfile = Dir.glob("pkg/*.gem")[0]
45+
target_dir = File.join(tmp_dir, File.basename(gemfile, '.gem'))
46+
47+
installer = Gem::Installer.new(gemfile)
48+
installer.unpack(target_dir)
49+
50+
gemspec = installer.spec
51+
extension = gemspec.extensions[0]
52+
gemspec.extensions.clear
53+
54+
config = ENV['CONFIG'] ? YAML.load_file(ENV['CONFIG']) : {}
55+
rubies = config['rubies'] || [Gem.ruby]
56+
args = config['extopts'] || []
57+
gemspec.platform = config['platform'] || Gem::Platform::CURRENT
58+
59+
multi = rubies.size > 1
60+
rubies.each { |ruby|
61+
lib_dir = 'lib'
62+
if multi
63+
major, minor, _ = `#{ruby} -e "print RUBY_VERSION"`.chomp.split('.')
64+
lib_dir = File.join(lib_dir, [major, minor].join('.'))
65+
end
66+
67+
make_cmd = (`#{ruby} -e "print RUBY_PLATFORM"` =~ /mswin/) ? 'nmake' : 'make'
68+
Dir.chdir(target_dir) {
69+
cmd = [ruby, extension, *args].join(' ')
70+
results = []
71+
Gem::Ext::ExtConfBuilder.run(cmd, results)
72+
Gem::Ext::ExtConfBuilder.make('', results)
73+
74+
FileUtils.mkdir_p lib_dir
75+
FileUtils.mv SO_FILE, lib_dir
76+
sh "#{make_cmd} clean"
77+
}
78+
79+
gemspec.files << File.join(lib_dir, SO_FILE)
80+
}
81+
82+
Dir.chdir(target_dir) {
83+
gemfile = Gem::Package.build(gemspec)
84+
FileUtils.mv gemfile, File.dirname(__FILE__)
85+
}
86+
87+
FileUtils.rm_rf tmp_dir
88+
end
89+
3490
# vim: syntax=ruby

config.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
platform: mingw32
2+
rubies:
3+
- C:/ruby-1.9.3-p392-mingw32/bin/ruby.exe
4+
- C:/ruby-2.0.0-p0-mingw32/bin/ruby.exe
5+
extopts:
6+
- --with-opencv-include=C:/opencv/build/include
7+
- --with-opencv-lib=C:/opencv/build/x86/mingw/lib

ext/opencv/cvcapture.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -187,21 +187,25 @@ VALUE
187187
rb_retrieve(VALUE self)
188188
{
189189
VALUE image = Qnil;
190+
IplImage *frame = NULL;
190191
try {
191-
IplImage *frame = cvRetrieveFrame(CVCAPTURE(self));
192-
if (!frame)
192+
if (!(frame = cvRetrieveFrame(CVCAPTURE(self)))) {
193193
return Qnil;
194-
image = cIplImage::new_object(cvSize(frame->width, frame->height),
195-
CV_MAKETYPE(CV_8U, frame->nChannels));
196-
if (frame->origin == IPL_ORIGIN_TL)
194+
}
195+
image = cIplImage::new_object(frame->width, frame->height,
196+
CV_MAKETYPE(IPL2CV_DEPTH(frame->depth), frame->nChannels));
197+
if (frame->origin == IPL_ORIGIN_TL) {
197198
cvCopy(frame, CVARR(image));
198-
else
199+
}
200+
else {
199201
cvFlip(frame, CVARR(image));
202+
}
200203
}
201204
catch (cv::Exception& e) {
202205
raise_cverror(e);
203206
}
204207
return image;
208+
205209
}
206210

207211
/*
@@ -214,16 +218,19 @@ VALUE
214218
rb_query(VALUE self)
215219
{
216220
VALUE image = Qnil;
221+
IplImage *frame = NULL;
217222
try {
218-
IplImage *frame = cvQueryFrame(CVCAPTURE(self));
219-
if (!frame)
223+
if (!(frame = cvQueryFrame(CVCAPTURE(self)))) {
220224
return Qnil;
221-
image = cIplImage::new_object(cvSize(frame->width, frame->height),
222-
CV_MAKETYPE(CV_8U, frame->nChannels));
223-
if (frame->origin == IPL_ORIGIN_TL)
225+
}
226+
image = cIplImage::new_object(frame->width, frame->height,
227+
CV_MAKETYPE(IPL2CV_DEPTH(frame->depth), frame->nChannels));
228+
if (frame->origin == IPL_ORIGIN_TL) {
224229
cvCopy(frame, CVARR(image));
225-
else
230+
}
231+
else {
226232
cvFlip(frame, CVARR(image));
233+
}
227234
}
228235
catch (cv::Exception& e) {
229236
raise_cverror(e);

ext/opencv/cvutils.cpp

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -37,60 +37,60 @@ raise_compatible_typeerror(VALUE object, const char* expected_class_name)
3737

3838
/*
3939
* Allocates a memory buffer
40-
* When memory allocation is failed, run GC and retry it
40+
* see cv::fastMalloc()
4141
*/
4242
void*
43-
rb_cvAlloc(size_t size)
43+
rbFastMalloc(size_t size)
4444
{
45-
void* ptr = NULL;
46-
try {
47-
ptr = cvAlloc(size);
45+
uchar* udata = (uchar*)xmalloc(size + sizeof(void*) + CV_MALLOC_ALIGN);
46+
if(!udata) {
47+
rb_raise(rb_eNoMemError, "Failed to allocate memory");
4848
}
49-
catch(cv::Exception& e) {
50-
if (e.code != CV_StsNoMem)
51-
rb_raise(rb_eRuntimeError, "%s", e.what());
49+
uchar** adata = cv::alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN);
50+
adata[-1] = udata;
51+
return adata;
52+
}
5253

53-
rb_gc_start();
54-
try {
55-
ptr = cvAlloc(size);
56-
}
57-
catch (cv::Exception& e) {
58-
if (e.code == CV_StsNoMem)
59-
rb_raise(rb_eNoMemError, "%s", e.what());
60-
else
61-
rb_raise(rb_eRuntimeError, "%s", e.what());
62-
}
63-
}
64-
return ptr;
54+
/*
55+
* Allocates a memory buffer
56+
* When memory allocation is failed, run GC and retry it
57+
*/
58+
void*
59+
rb_cvAlloc(size_t size)
60+
{
61+
return rbFastMalloc(size);
6562
}
6663

6764
/*
6865
* Creates CvMat and underlying data
6966
* When memory allocation is failed, run GC and retry it
7067
*/
7168
CvMat*
72-
rb_cvCreateMat(int height, int width, int type)
69+
rb_cvCreateMat(int rows, int cols, int type)
7370
{
74-
CvMat* ptr = NULL;
71+
CvMat* mat = NULL;
7572
try {
76-
ptr = cvCreateMat(height, width, type);
73+
mat = cvCreateMatHeader(rows, cols, type);
74+
if (mat) {
75+
// see OpenCV's cvCreateData()
76+
size_t step = mat->step;
77+
size_t total_size = step * mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
78+
79+
mat->refcount = (int*)rbFastMalloc(total_size);
80+
mat->data.ptr = (uchar*)cvAlignPtr(mat->refcount + 1, CV_MALLOC_ALIGN);
81+
*mat->refcount = 1;
82+
}
83+
else {
84+
rb_raise(rb_eRuntimeError, "Failed to create mat header");
85+
}
7786
}
7887
catch(cv::Exception& e) {
79-
if (e.code != CV_StsNoMem)
80-
rb_raise(rb_eRuntimeError, "%s", e.what());
81-
82-
rb_gc_start();
83-
try {
84-
ptr = cvCreateMat(height, width, type);
85-
}
86-
catch (cv::Exception& e) {
87-
if (e.code == CV_StsNoMem)
88-
rb_raise(rb_eNoMemError, "%s", e.what());
89-
else
90-
rb_raise(rb_eRuntimeError, "%s", e.what());
88+
if (mat) {
89+
cvReleaseMat(&mat);
9190
}
91+
rb_raise(rb_eRuntimeError, "%s", e.what());
9292
}
93-
return ptr;
93+
return mat;
9494
}
9595

9696
/*
@@ -102,22 +102,20 @@ rb_cvCreateImage(CvSize size, int depth, int channels)
102102
{
103103
IplImage* ptr = NULL;
104104
try {
105-
ptr = cvCreateImage(size, depth, channels);
105+
ptr = cvCreateImageHeader(size, depth, channels);
106+
if (ptr) {
107+
// see OpenCV's cvCreateData()
108+
ptr->imageData = ptr->imageDataOrigin = (char*)rbFastMalloc((size_t)ptr->imageSize);
109+
}
110+
else {
111+
rb_raise(rb_eRuntimeError, "Failed to create image header");
112+
}
106113
}
107114
catch(cv::Exception& e) {
108-
if (e.code != CV_StsNoMem)
109-
rb_raise(rb_eRuntimeError, "%s", e.what());
110-
111-
rb_gc_start();
112-
try {
113-
ptr = cvCreateImage(size, depth, channels);
114-
}
115-
catch (cv::Exception& e) {
116-
if (e.code == CV_StsNoMem)
117-
rb_raise(rb_eNoMemError, "%s", e.what());
118-
else
119-
rb_raise(rb_eRuntimeError, "%s", e.what());
115+
if (ptr) {
116+
cvReleaseImage(&ptr);
120117
}
118+
rb_raise(rb_eRuntimeError, "%s", e.what());
121119
}
122120
return ptr;
123121
}

ext/opencv/cvutils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <ruby.h>
1212
#include "opencv2/core/core_c.h"
1313
#include "opencv2/core/core.hpp"
14+
#include "opencv2/core/internal.hpp"
1415
#include "opencv2/imgproc/imgproc_c.h"
1516
#include "opencv2/imgproc/imgproc.hpp"
1617

ext/opencv/extconf.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ def cv_version_suffix(incdir)
55
major, minor, subminor = nil, nil, nil
66
open("#{incdir}/opencv2/core/version.hpp", 'r') { |f|
77
f.read.lines.each { |line|
8-
major = $1.to_s if line =~ /\A#define\s+CV_MAJOR_VERSION\s+(\d+)\s*\Z/
9-
minor = $1.to_s if line =~ /\A#define\s+CV_MINOR_VERSION\s+(\d+)\s*\Z/
10-
subminor = $1.to_s if line =~ /\A#define\s+CV_SUBMINOR_VERSION\s+(\d+)\s*\Z/
8+
major = $1.to_s if line =~ /\A#define\s+(?:CV_VERSION_EPOCH|CV_MAJOR_VERSION)\s+(\d+)\s*\Z/
9+
minor = $1.to_s if line =~ /\A#define\s+(?:CV_VERSION_MAJOR|CV_MINOR_VERSION)\s+(\d+)\s*\Z/
10+
subminor = $1.to_s if line =~ /\A#define\s+(?:CV_VERSION_MINOR|CV_SUBMINOR_VERSION)\s+(\d+)\s*\Z/
1111
}
1212
}
1313
major + minor + subminor
@@ -70,8 +70,10 @@ def cv_version_suffix(incdir)
7070
}
7171
have_header("stdarg.h")
7272

73-
$warnflags.slice!('-Wdeclaration-after-statement')
74-
$warnflags.slice!('-Wimplicit-function-declaration')
73+
if $warnflags
74+
$warnflags.slice!('-Wdeclaration-after-statement')
75+
$warnflags.slice!('-Wimplicit-function-declaration')
76+
end
7577

7678
# Quick fix for 1.8.7
7779
$CFLAGS << " -I#{File.dirname(__FILE__)}/ext/opencv"

0 commit comments

Comments
 (0)