rixmap 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,113 @@
1
+ // -*- coding: utf-8 -*-
2
+ /**
3
+ * Ruby関係のユーティリティ関数提供ヘッダ.
4
+ * ファイル名は Ruby Laser (http://ja.wikipedia.org/wiki/%E3%83%AB%E3%83%93%E3%83%BC%E3%83%AC%E3%83%BC%E3%82%B6%E3%83%BC) から.
5
+ *
6
+ * (なんとなくいい名前なかったんだよ(´・ω・`) )
7
+ */
8
+ #pragma once
9
+ #ifndef CHOLLAS_RASER_HXX
10
+ #define CHOLLAS_RASER_HXX
11
+ #include <stdexcept> // C++標準例外
12
+ #include <new> // 配置new
13
+
14
+ namespace chollas {
15
+ namespace raser {
16
+ /**
17
+ * Rubyでの配置newユーティリティ関数実装.
18
+ * C++11の可変長引数テンプレートを使っているので、コンパイラにC++11実装が必須になりました.
19
+ *
20
+ * `ruby_xmalloc` を使用してメモリ確保をしたのち、指定された引数でコンストラクタを呼び出します.
21
+ * コンストラクタから例外が発生した場合は確保したメモリを解放して、Ruby例外を出します.
22
+ *
23
+ * 解放には `chollas::raser::xdelete` を使ってください.
24
+ *
25
+ * 使用例:
26
+ * class Hello {
27
+ * publci:
28
+ * Hello(const char* msg) {}
29
+ * };
30
+ * Hello* h = raser::xnew<Hello>("hello, world!");
31
+ *
32
+ * @param [class] CLASS 確保するクラスの型
33
+ * @param [typename...] PARAMS コンストラクタ引数の型を表す型リスト.
34
+ * @param [PARAMS...] params コンストラクタへ渡す引数
35
+ * @return [CLASS*] 確保されたT型のポインタ. `ruby_xmalloc`を使っているため、
36
+ * 確保できない場合は例外が発生します.
37
+ * また、コンストラクタ内で例外が発生した場合はRuby例外に変換するため、
38
+ * この関数から戻ってきた場合は常に確保に成功しているハズ
39
+ * FIXME コピーコンストラクタがないクラスとかだと失敗する模様
40
+ */
41
+ template<class CLASS, typename... PARAMS> static inline CLASS* xnew(PARAMS... params) {
42
+ // Ruby用確保関数を使い、メモリ確保を確実にする
43
+ // (メモリ不足時はNoMemoryErrorが発生する)
44
+ void* mem = ::ruby_xmalloc(sizeof(CLASS));
45
+ //CLASS* ptr = reinterpret_cast<CLASS*>(::ruby_xmalloc(sizeof(CLASS)));
46
+ try {
47
+ // 配置newで↑で確保したメモリ上にオブジェクトを構築
48
+ CLASS* ptr = new(mem) CLASS(params...);
49
+ return ptr;
50
+ //return new(ptr) CLASS(params...);
51
+ } catch (const std::exception& e) {
52
+ // C++例外時はメモリを開放する
53
+ ::ruby_xfree(mem);
54
+
55
+ // Ruby例外を出す
56
+ rb_raise(rb_eRuntimeError, e.what());
57
+ } catch (...) {
58
+ // C++標準例外以外もRuby例外にする (情報なし)
59
+ ::ruby_xfree(mem);
60
+ rb_raise(rb_eRuntimeError, "unknown exception occurred");
61
+ }
62
+
63
+ // ここって来ることあるかな( ・ω・)モニュ?
64
+ if (mem != NULL) {
65
+ ::ruby_xfree(mem);
66
+ }
67
+ rb_raise(rb_eRuntimeError, "illegal operation occurred (fatal)");
68
+ }
69
+
70
+ /**
71
+ * `chollas::raser::xnew`で確保したオブジェクトの解放関数.
72
+ * デストラクタを呼び出したのちに `::ruby_xfree` でメモリを解放します.
73
+ *
74
+ * @param [class] CLASS クラス型
75
+ * @param [CLASS*] ptr オブジェクトのポインタ
76
+ * @return [void]
77
+ * @see http://stackoverflow.com/questions/13210757/how-to-call-destructor-of-type-in-template
78
+ */
79
+ template<class CLASS> static inline void xdelete(CLASS* ptr) {
80
+ if (ptr != NULL) {
81
+ try {
82
+ ptr->~CLASS();
83
+ ::ruby_xfree(ptr);
84
+ } catch (const std::exception& e) {
85
+ ::ruby_xfree(ptr);
86
+ rb_raise(rb_eRuntimeError, e.what());
87
+ } catch (...) {
88
+ ::ruby_xfree(ptr);
89
+ rb_raise(rb_eRuntimeError, "unknown exception occurred");
90
+ }
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Rubyオブジェクトに包まれているCレベル構造体またはクラスのポインタを取得します.
96
+ *
97
+ * @param [typename] T C構造体型
98
+ * @param [VALUE] obj Rubyオブジェクトを表すVALUE
99
+ * @return [T*] 構造体へのポインタ
100
+ */
101
+ template<typename T> static inline T* unwrap(VALUE obj) {
102
+ T* ptr = NULL;
103
+ Data_Get_Struct(obj, T, ptr);
104
+ return ptr;
105
+ }
106
+ } // chollas::raser
107
+ } // chollas
108
+
109
+
110
+ #endif // CHOLLAS_RASER_HXX
111
+ //============================================================================//
112
+ // $Id$
113
+ // vim: set sts=4 ts=4 sw=4 expandtab filetype=cpp:
@@ -0,0 +1,58 @@
1
+ // -*- coding: utf-8 -*-
2
+ /**
3
+ * ユーティリティ関数とかの断片実装.
4
+ * カテゴリー分けしてないコードを置いとく場所です.
5
+ */
6
+ #pragma once
7
+ #ifndef CHOLLAS_UTILITIES_HXX
8
+ #define CHOLLAS_UTILITIES_HXX
9
+ #include <algorithm>
10
+ #include <string>
11
+ #include <cctype>
12
+
13
+ namespace chollas {
14
+ /**
15
+ * 数値を指定した範囲内に収まるように丸めます.
16
+ * | min (v < min)
17
+ * range2range(v, min, max) = | v (min <= v && v <= max)
18
+ * | max (max < v)
19
+ *
20
+ * @param [long] value 丸める対象.
21
+ * @param [long] minValue 範囲の最小値.
22
+ * @param [long] maxValue 範囲の最大値.
23
+ * @
24
+ */
25
+ static inline long round2range(long value, long minValue, long maxValue) {
26
+ if (value < minValue) {
27
+ return minValue;
28
+ } else if (value > maxValue) {
29
+ return maxValue;
30
+ } else {
31
+ return value;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * 文字列を破壊的に大文字化します.
37
+ *
38
+ * @param [std::string&] text 対象文字列
39
+ */
40
+ static inline void strtoupper(std::string& text) {
41
+ std::transform(text.begin(), text.end(), text.begin(), ::toupper);
42
+ }
43
+
44
+ /**
45
+ * 文字列を破壊的に小文字化します.
46
+ *
47
+ * @param [std::string&] text 対象文字列
48
+ */
49
+ static inline void strtolower(std::string& text) {
50
+ std::transform(text.begin(), text.end(), text.begin(), ::tolower);
51
+ }
52
+ }
53
+
54
+
55
+ #endif // CHOLLAS_UTILITIES_HXX
56
+ //============================================================================//
57
+ // $Id$
58
+ // vim: set sts=4 ts=4 sw=4 expandtab filetype=cpp:
data/src/extconf.rb ADDED
@@ -0,0 +1,47 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'mkmf'
3
+
4
+ # コンパイラオプション
5
+ if $mswin
6
+ $CFLAGS << ' -EHsc -D_XKEYCHECK_H'
7
+ $CPPFLAGS << ' -EHsc -D_XKEYCHECK_H'
8
+ else
9
+ $CFLAGS << ' -std=gnu++0x -O3'
10
+ $CPPFLAGS << ' -std=gnu++0x -O3'
11
+ $warnflags.slice!(/-Wdeclaration-after-statement/)
12
+ $warnflags.slice!(/-Wimplicit-function-declaration/)
13
+
14
+ # Ruby2.0 + DevKit 4.7 でやると実行時にDevKitのパスが通ってないといけない問題対策
15
+ $LDFLAGS << ' -static-libstdc++ -static-libgcc'
16
+
17
+ # 環境検査 (for GCC)
18
+ unless have_macro('__STDC_CONSTANT_MACROS')
19
+ $CFLAGS << ' -D__STDC_CONSTANT_MACROS'
20
+ $CPPFLAGS << ' -D__STDC_CONSTANT_MACROS'
21
+ end
22
+ unless have_macro('__STDC_LIMIT_MACROS')
23
+ $CFLAGS << ' -D__STDC_LIMIT_MACROS'
24
+ $CPPFLAGS << ' -D__STDC_LIMIT_MACROS'
25
+ end
26
+
27
+ # C++コンパイラ用依存関係解決対応
28
+ # via http://comments.gmane.org/gmane.comp.lang.ruby.japanese/6204
29
+ RbConfig::CONFIG['CPP'] = "#{RbConfig::CONFIG['CXX']} -E"
30
+ end
31
+
32
+ # 実装状況チェック
33
+ unless have_func('lround')
34
+ if have_func('lround', 'math.h')
35
+ $defs << "-DREQUIRE_MATH_H"
36
+ end
37
+ end
38
+ have_func('rb_Hash', 'ruby.h')
39
+
40
+ # Makefileの出力
41
+ create_header('config.h')
42
+ create_makefile("#{RUBY_PLATFORM}/rixmap")
43
+
44
+
45
+ #==============================================================================#
46
+ # $Id: extconf.rb,v 66c8edefa6c0 2014/04/20 14:22:54 chikuchikugonzalez $
47
+ # vim: set sts=2 ts=2 sw=2 expandtab:
@@ -0,0 +1,19 @@
1
+ // -*- coding: utf-8 -*-
2
+ /**
3
+ * バイナリ配列クラスデータ.
4
+ * 単なるstd::deque<uint8_t>のtypedefです.
5
+ */
6
+ #pragma once
7
+ #include "common.hxx"
8
+
9
+ namespace Rixmap {
10
+ /**
11
+ * バイナリ配列クラスデータ.
12
+ */
13
+ typedef std::deque<uint8_t> BinaryData;
14
+ }
15
+
16
+
17
+ //============================================================================//
18
+ // $Id: binary.hxx,v bb1f88e64282 2014/04/20 13:54:13 chikuchikugonzalez $
19
+ // vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
@@ -0,0 +1,42 @@
1
+ // -*- coding: utf-8 -*-
2
+ /**
3
+ * チャンネル情報クラスデータ定義ヘッダ.
4
+ */
5
+ #pragma once
6
+ #include "common.hxx"
7
+
8
+ namespace Rixmap {
9
+
10
+ // チャンネル番号定数値
11
+ //const int16_t CHANNEL_INDEX_LUMINANCE = 1;
12
+ //const int16_t CHANNEL_INDEX_RED = 1;
13
+ //const int16_t CHANNEL_INDEX_GREEN = 2;
14
+ //const int16_t CHANNEL_INDEX_BLUE = 3;
15
+ //const int16_t CHANNEL_INDEX_ALPHA = 0;
16
+ //const int16_t CHANNEL_INDEX_PALETTE = 0;
17
+ //const int16_t CHANNEL_INDEX_COUNT = 4;
18
+
19
+ /**
20
+ * チャンネル種別.
21
+ */
22
+ enum class Channel : char {
23
+ NONE = '\0',
24
+ PALETTE = 'P', // パレットインデックス (FIXME 名前変えるべきかな)
25
+ LUMINANCE = 'L', // 輝度 (Luminanceだって)
26
+ RED = 'R', // 赤要素
27
+ GREEN = 'G', // 緑要素
28
+ BLUE = 'B', // 青要素
29
+ ALPHA = 'A', // 透明度
30
+ };
31
+
32
+ }
33
+
34
+ //----------------------------------------------------------------------------//
35
+ // マクロ定義
36
+ //----------------------------------------------------------------------------//
37
+ //#define CHANNEL2INDEX(type) ::Rixmap::ChannelInfo::Type2Index((type))
38
+
39
+
40
+ //============================================================================//
41
+ // $Id: channel.hxx,v 8870c1d9926f 2014/03/18 16:09:35 chikuchikugonzalez $
42
+ // vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
@@ -0,0 +1,222 @@
1
+ // -*- coding: utf-8 -*-
2
+ /**
3
+ * RGBカラー情報クラスデータ定義ヘッダ
4
+ */
5
+ #pragma once
6
+ #include "common.hxx"
7
+
8
+ namespace Rixmap {
9
+ // 前方宣言
10
+ class ColorData;
11
+
12
+ #pragma pack(push, 1)
13
+ /**
14
+ * RGBAカラークラス.
15
+ */
16
+ class Color {
17
+ // フレンドクラス設定
18
+ friend class ColorData;
19
+
20
+ private: // 非公開メンバ
21
+ union {
22
+ uint32_t _value;
23
+ struct {
24
+ uint8_t _red; // 赤要素
25
+ uint8_t _green; // 緑要素
26
+ uint8_t _blue; // 青要素
27
+ uint8_t _alpha; // 透明度
28
+ };
29
+ };
30
+
31
+ public: // コンストラクタ
32
+ /**
33
+ * デフォルトコンストラクタ.
34
+ */
35
+ Color() : _red(0), _green(0), _blue(0), _alpha(255) {}
36
+
37
+ /**
38
+ * 要素指定型コンストラクタ.
39
+ */
40
+ Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) : _red(r), _green(g), _blue(b), _alpha(a) {}
41
+
42
+ /**
43
+ * コピーコンストラクタ.
44
+ */
45
+ Color(const Color& c) : _value(c._value) {}
46
+
47
+ /**
48
+ * デストラクタ.
49
+ */
50
+ ~Color() {}
51
+
52
+ public: // プロパティメンバ関数
53
+ inline uint8_t getRed() const { return this->_red; }
54
+ inline uint8_t getGreen() const { return this->_green; }
55
+ inline uint8_t getBlue() const { return this->_blue; }
56
+ inline uint8_t getAlpha() const { return this->_alpha; }
57
+ inline uint32_t getValue() const { return this->_value; }
58
+
59
+ public: // メンバ関数
60
+ inline int getLuminance() const {
61
+ int r = static_cast<int>(this->_red);
62
+ int g = static_cast<int>(this->_green);
63
+ int b = static_cast<int>(this->_blue);
64
+ return ROUND2BYTE(lround((r + g + b) / 3.0));
65
+ }
66
+
67
+ /**
68
+ * 指定した色との距離を計算します.
69
+ * 現在の実装では透明度を無視しています.
70
+ */
71
+ inline double distance(const Color& c) const {
72
+ // MinGW x86-64のRubyだとpowがマクロ定義されているため、std::powが動かなくなる問題の対策
73
+ using namespace std;
74
+ double dr = sqrt(pow((static_cast<int>(c._red) - static_cast<int>(this->_red)), 2.0));
75
+ double dg = sqrt(pow((static_cast<int>(c._green) - static_cast<int>(this->_green)), 2.0));
76
+ double db = sqrt(pow((static_cast<int>(c._blue) - static_cast<int>(this->_blue)), 2.0));
77
+ return sqrt((dr + dg + db));
78
+ }
79
+
80
+ public: // 演算子オーバーロード
81
+ /**
82
+ * 代入演算子定義
83
+ */
84
+ inline Color& operator=(const Color& c) {
85
+ this->_value = c._value;
86
+ return *this;
87
+ }
88
+
89
+ /**
90
+ * 配列アクセス
91
+ */
92
+ inline uint8_t operator[](size_t offset) const {
93
+ switch (offset) {
94
+ case 0: return this->_red;
95
+ case 1: return this->_green;
96
+ case 2: return this->_blue;
97
+ case 3: return this->_alpha;
98
+ default: return 0;
99
+ }
100
+ // TODO 範囲外扱いの場合は例外のほうがいいだろか( ・ω・)?
101
+ }
102
+
103
+ /**
104
+ * 配列アクセス with Channel
105
+ */
106
+ inline uint8_t operator[](Channel channel) const {
107
+ switch (channel) {
108
+ case Channel::RED: return this->_red;
109
+ case Channel::GREEN: return this->_green;
110
+ case Channel::BLUE: return this->_blue;
111
+ case Channel::ALPHA: return this->_alpha;
112
+ case Channel::LUMINANCE: return this->getLuminance();
113
+ default: return 0;
114
+ }
115
+ }
116
+
117
+ /**
118
+ * 等値比較演算子
119
+ */
120
+ inline bool operator==(const Color& c) { return (this->_value == c._value); }
121
+ inline bool operator!=(const Color& c) { return (this->_value != c._value); }
122
+ friend bool operator==(const Color& lhs, const Color& rhs);
123
+ friend bool operator!=(const Color& lhs, const Color& rhs);
124
+ };
125
+ #pragma pack(pop)
126
+
127
+ /*
128
+ * グローバル演算子オーバーロード for Color
129
+ */
130
+ inline bool operator==(const Color& lhs, const Color& rhs) { return (lhs._value == rhs._value); }
131
+ inline bool operator!=(const Color& lhs, const Color& rhs) { return (lhs._value != rhs._value); }
132
+
133
+ /**
134
+ * Ruby用RGBAカラークラスデータ.
135
+ */
136
+ class ColorData {
137
+ private: // 非公開メンバ
138
+ Color _color; // 保持するカラーデータ
139
+
140
+ public: // コンストラクタ定義
141
+ /**
142
+ * デフォルトコンストラクタ
143
+ */
144
+ ColorData() : _color(0, 0, 0, 255) {}
145
+
146
+ /**
147
+ * 各要素値指定
148
+ */
149
+ ColorData(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) : _color(r, g, b, a) {}
150
+
151
+ /**
152
+ * カラーインスタンスから.
153
+ */
154
+ ColorData(const Color& color) : _color(color) {}
155
+
156
+ /**
157
+ * コピーコンストラクタ
158
+ */
159
+ ColorData(const ColorData& data) : _color(data._color) {}
160
+
161
+ /**
162
+ * デストラクタ.
163
+ */
164
+ ~ColorData() {}
165
+
166
+ public: // プロパティメンバ関数
167
+ /**
168
+ * 内部カラーデータを返します.
169
+ */
170
+ inline const Color& getColor() const { return this->_color; }
171
+
172
+ /**
173
+ * 内部カラーデータを更新します.
174
+ * Ruby側コンストラクタ以外では呼び出さないでくだしあ
175
+ */
176
+ inline void setColor(const Color& color) { this->_color = color; }
177
+
178
+ inline uint8_t getRed() const { return this->_color._red; }
179
+ inline uint8_t getGreen() const { return this->_color._green; }
180
+ inline uint8_t getBlue() const { return this->_color._blue; }
181
+ inline uint8_t getAlpha() const { return this->_color._alpha; }
182
+ inline uint32_t getValue() const { return this->_color._value; }
183
+
184
+ public: // メンバ関数
185
+ inline int getLuminance() const { return this->_color.getLuminance(); }
186
+
187
+ public: // 演算子オーバーロード
188
+ inline ColorData& operator=(const Color& c) {
189
+ this->_color = c;
190
+ return *this;
191
+ }
192
+
193
+ inline ColorData& operator=(const ColorData& d) {
194
+ this->_color = d._color;
195
+ return *this;
196
+ }
197
+
198
+ inline uint8_t operator[](size_t offset) const { return this->_color[offset]; }
199
+
200
+ inline bool operator==(const Color& c) { return (this->_color == c); }
201
+ inline bool operator!=(const Color& c) { return (this->_color != c); }
202
+ inline bool operator==(const ColorData& d) { return (this->_color == d._color); }
203
+ inline bool operator!=(const ColorData& d) { return (this->_color != d._color); }
204
+ friend bool operator==(const ColorData& lhs, const ColorData& rhs);
205
+ friend bool operator!=(const ColorData& lhs, const ColorData& rhs);
206
+ friend bool operator==(const ColorData& lhs, const Color& rhs);
207
+ friend bool operator!=(const ColorData& lhs, const Color& rhs);
208
+ };
209
+
210
+ /*
211
+ * グローバル演算子オーバーロード for ColorData
212
+ */
213
+ inline bool operator==(const ColorData& lhs, const ColorData& rhs) { return (lhs._color == rhs._color); }
214
+ inline bool operator!=(const ColorData& lhs, const ColorData& rhs) { return (lhs._color != rhs._color); }
215
+ inline bool operator==(const ColorData& lhs, const Color& rhs) { return (lhs._color == rhs); }
216
+ inline bool operator!=(const ColorData& lhs, const Color& rhs) { return (lhs._color != rhs); }
217
+ }
218
+
219
+
220
+ //============================================================================//
221
+ // $Id: color.hxx,v 66c8edefa6c0 2014/04/20 14:22:54 chikuchikugonzalez $
222
+ // vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
@@ -0,0 +1,58 @@
1
+ // -*- coding: utf-8 -*-
2
+ /**
3
+ * ライブラリ用ヘルパー関数定義ヘッダ.
4
+ * マクロによるショートカットとか定義しておきます.
5
+ */
6
+ #pragma once
7
+ #include <stdexcept>
8
+ #include <sstream>
9
+ #include <string>
10
+ #include <vector>
11
+ #include <deque>
12
+ #include <map>
13
+ #include <tuple>
14
+ #include <cstdint>
15
+ #include <cstring>
16
+ #include <cctype>
17
+ #include <cfloat>
18
+ #if REQUIRE_MATH_H
19
+ # include <math.h>
20
+ #endif
21
+ #include <ruby.h>
22
+ #include <ruby/encoding.h>
23
+ #include "../chollas/raser.hxx"
24
+ #include "../chollas/utilities.hxx"
25
+
26
+ /**
27
+ * Ruby側で提供していてほしいけど提供してないのでこっちで定義する
28
+ */
29
+ #define RIXMAP_DEFAULT_MARK ((RUBY_DATA_FUNC) 0)
30
+ #define RIXMAP_DEFAULT_FREE RUBY_DEFAULT_FREE
31
+
32
+ /**
33
+ * メモリ関係関数のショートカット.
34
+ */
35
+ #define rixmap_xnew ::chollas::raser::xnew
36
+ #define rixmap_xdelete ::chollas::raser::xdelete
37
+ #define rixmap_unwrap ::chollas::raser::unwrap
38
+
39
+ /**
40
+ * 値丸め関数マクロ
41
+ */
42
+ #define ROUND2RANGE(value, minValue, maxValue) chollas::round2range((value), (minValue), (maxValue))
43
+ #define ROUND2BYTE(value) chollas::round2range((value), 0, UINT8_MAX)
44
+
45
+ /**
46
+ * 共通データ構造定義
47
+ */
48
+ namespace Rixmap {
49
+
50
+ // 全体で使いそうな構造体とかはここへ
51
+ typedef std::vector<uint8_t> ByteBuffer;
52
+ typedef std::vector<char> CharBuffer;
53
+ }
54
+
55
+
56
+ //============================================================================//
57
+ // $Id: common.hxx,v 66c8edefa6c0 2014/04/20 14:22:54 chikuchikugonzalez $
58
+ // vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker: