rixmap 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/src/rixmapcore.hxx CHANGED
@@ -20,8 +20,15 @@ extern VALUE cRixmapImageLine;
20
20
  // コアAPI関数プロトタイプ
21
21
  //----------------------------------------------------------------------------//
22
22
  extern void RixmapCore_Init();
23
+ extern VALUE RixmapPalette_NewInstance(size_t size = 256);
24
+ extern VALUE RixmapPalette_NewRedScaleInstance();
25
+ extern VALUE RixmapPalette_NewGreenScaleInstance();
26
+ extern VALUE RixmapPalette_NewBlueScaleInstance();
27
+ extern VALUE RixmapPalette_NewGrayScaleInstance();
28
+ extern VALUE RixmapImage_NewInstance(Rixmap::Mode mode, int32_t width, int32_t height, VALUE options = Qnil);
29
+ extern VALUE RixmapImageLine_NewInstance(VALUE image, int32_t lineno);
23
30
 
24
31
 
25
32
  //============================================================================//
26
- // $Id: rixmapcore.hxx,v add33526d522 2014/04/19 16:27:29 chikuchikugonzalez $
33
+ // $Id: rixmapcore.hxx,v 753dbf70cab3 2014/05/16 16:13:38 chikuchikugonzalez $
27
34
  // vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
@@ -0,0 +1,687 @@
1
+ // -*- coding: utf-8 -*-
2
+ /**
3
+ * Rixmap変形処理実装
4
+ */
5
+ #include "rixmapdeformation.hxx"
6
+
7
+ //----------------------------------------------------------------------------//
8
+ // グローバル変数実体
9
+ //----------------------------------------------------------------------------//
10
+ VALUE mRixmapDeformer = Qnil;
11
+ VALUE cRixmapBaseDeformer = Qnil;
12
+ VALUE cRixmapAffineDeformer = Qnil;
13
+ VALUE cRixmapAffineMatrix = Qnil;
14
+
15
+ //VALUE cRixmapAffinePoint = Qnil;
16
+ //VALUE cRixmapAffineCenter = Qnil;
17
+ //VALUE cRixmapAffineScale = Qnil;
18
+ //VALUE cRixmapAffineTranslation = Qnil;
19
+
20
+ //----------------------------------------------------------------------------//
21
+ // 変換系クラス実装
22
+ //----------------------------------------------------------------------------//
23
+ /* Rixmap::Deformer::BaseDeformer {{{ */
24
+ static void BaseDeformer_Free(Rixmap::DeformerData* data) {
25
+ rixmap_xdelete(data);
26
+ }
27
+
28
+ static VALUE BaseDeformer_Alloc(VALUE klass) {
29
+ Rixmap::DeformerData* data = rixmap_xnew<Rixmap::DeformerData>();
30
+ return Data_Wrap_Struct(klass, RIXMAP_DEFAULT_MARK, BaseDeformer_Free, data);
31
+ }
32
+
33
+ /**
34
+ * @overload initialize(ipo = nil)
35
+ * 変形処理ベースを初期化します.
36
+ *
37
+ * @param [Symbol,String,Integer,nil] ipo 補間処理方法 (Default: nil)
38
+ * @return [void]
39
+ */
40
+ static VALUE BaseDeformer_initialize(int argc, VALUE* argv, VALUE self) {
41
+ VALUE argIPO = Qnil;
42
+ rb_scan_args(argc, argv, "01", &argIPO);
43
+ rb_funcall(self, rb_intern("interpolator="), 1, argIPO);
44
+ return self;
45
+ }
46
+
47
+ /**
48
+ * 画素補間処理方法を返します.
49
+ *
50
+ * @return [Integer] 画素補間処理方法.
51
+ */
52
+ static VALUE BaseDeformer_getInterpolator(VALUE self) {
53
+ Rixmap::DeformerData* _this = rixmap_unwrap<Rixmap::DeformerData>(self);
54
+ switch (_this->getInterpolation()) {
55
+ case Rixmap::Interpolation::BICUBIC:
56
+ return INT2FIX(static_cast<int>(_this->getInterpolation()));
57
+
58
+ default:
59
+ return Qnil;
60
+ }
61
+ }
62
+
63
+ /**
64
+ * 画素補間処理方法を設定します.
65
+ *
66
+ * @param [Symbol,String,Integer,nil] ipo 画素補間処理方法.
67
+ * @return [void]
68
+ */
69
+ static VALUE BaseDeformer_setInterpolator(VALUE self, VALUE argIPO) {
70
+ Rixmap::DeformerData* _this = rixmap_unwrap<Rixmap::DeformerData>(self);
71
+ if (NIL_P(argIPO)) {
72
+ _this->setInterpolation(Rixmap::Interpolation::NONE);
73
+ } else if (RB_TYPE_P(argIPO, T_FIXNUM)) {
74
+ Rixmap::Interpolation ipo = static_cast<Rixmap::Interpolation>(FIX2INT(argIPO));
75
+ switch (ipo) {
76
+ case Rixmap::Interpolation::BICUBIC:
77
+ _this->setInterpolation(ipo);
78
+ break;
79
+
80
+ default:
81
+ _this->setInterpolation(Rixmap::Interpolation::NONE);
82
+ break;
83
+ }
84
+ } else {
85
+ VALUE strIPO = rb_str_new_cstr("IPO_");
86
+ strIPO = rb_str_concat(strIPO, rb_funcall(rb_String(argIPO), rb_intern("upcase"), 0));
87
+ if (rb_const_defined(mRixmapDeformer, rb_intern_str(strIPO))) {
88
+ VALUE objIPO = rb_const_get(mRixmapDeformer, rb_intern_str(strIPO));
89
+ _this->setInterpolation(static_cast<Rixmap::Interpolation>(NUM2INT(rb_Integer(objIPO))));
90
+ } else {
91
+ _this->setInterpolation(Rixmap::Interpolation::NONE);
92
+ }
93
+ }
94
+ return argIPO;
95
+ }
96
+
97
+ /**
98
+ * @overload deform(image, *args)
99
+ * 変形処理を実行します.
100
+ * @param [Rixmap::Image] image 変形する画像
101
+ * @return [Rixmap::Image] 変形された画像
102
+ */
103
+ static VALUE BaseDeformer_deform(int argc, VALUE* argv, VALUE self) {
104
+ rb_raise(rb_eNotImpError, "%s#%s is not implemented", rb_obj_classname(self), rb_id2name(rb_frame_this_func()));
105
+ }
106
+
107
+ /**
108
+ * オブジェクトとしての文字列表現を返します.
109
+ *
110
+ * @return [String] 文字列表現
111
+ */
112
+ static VALUE BaseDeformer_inspect(VALUE self) {
113
+ Rixmap::DeformerData* _this = rixmap_unwrap<Rixmap::DeformerData>(self);
114
+ return rb_enc_sprintf(
115
+ rb_usascii_encoding(),
116
+ "#<%s:%p ipo=%d>",
117
+ rb_obj_classname(self), reinterpret_cast<void*>(self),
118
+ static_cast<int>(_this->getInterpolation()));
119
+ }
120
+ /* }}} */
121
+ /* Rixmap::Deformer::AffineDeformer {{{ */
122
+ static void AffineDeformer_Free(Rixmap::AffineDeformerData* data) {
123
+ rixmap_xdelete(data);
124
+ }
125
+
126
+ static VALUE AffineDeformer_Alloc(VALUE klass) {
127
+ Rixmap::AffineDeformerData* data = rixmap_xnew<Rixmap::AffineDeformerData>();
128
+ return Data_Wrap_Struct(klass, RIXMAP_DEFAULT_MARK, AffineDeformer_Free, data);
129
+ }
130
+
131
+ /**
132
+ *
133
+ * @overload initialize(matrix=nil, ipo=nil)
134
+ * アフィン変換による変形処理実装オブジェクトを初期化します.
135
+ * @param [Rixmap::Deformer::AffineMatrix] matrix アフィン変換パラメータ
136
+ * @param [Symbol,String,Integer,nil] ipo 補間処理方法
137
+ * @return [void]
138
+ * @see {BaseDeformer#initialize}
139
+ */
140
+ static VALUE AffineDeformer_initialize(int argc, VALUE* argv, VALUE self) {
141
+ VALUE argMatrix = Qnil, argIPO = Qnil;
142
+ rb_scan_args(argc, argv, "02", &argMatrix, &argIPO);
143
+
144
+ // 自分を初期化
145
+ if (NIL_P(argMatrix)) {
146
+ rb_iv_set(self, "@matrix", rb_class_new_instance(0, NULL, cRixmapAffineMatrix));
147
+ } else {
148
+ rb_iv_set(self, "@matrix", argMatrix);
149
+ }
150
+
151
+ // 親を初期化
152
+ {
153
+ VALUE sargs[1] = {argIPO};
154
+ rb_call_super(1, sargs);
155
+ }
156
+
157
+ return self;
158
+ }
159
+
160
+ /**
161
+ * @overload deform(image, fit=false)
162
+ * アフィン変換による変形処理を実行します.
163
+ *
164
+ * @param [Rixmap::Image] image 対象画像
165
+ * @param [Boolean] fit trueの場合は変形後の画像サイズに合うように画像自体を拡大します.
166
+ * @return [Rixmap::Image] 変形後画像
167
+ */
168
+ static VALUE AffineDeformer_deform(int argc, VALUE* argv, VALUE self) {
169
+ // パラメータ処理
170
+ VALUE argImage = Qnil, argFit = Qnil;
171
+ rb_scan_args(argc, argv, "11", &argImage, &argFit);
172
+
173
+ // 自分ポインタ
174
+ Rixmap::AffineDeformerData* _this = rixmap_unwrap<Rixmap::AffineDeformerData>(self);
175
+
176
+ // 対象画像
177
+ Rixmap::ImageData* srcImage = rixmap_unwrap<Rixmap::ImageData>(argImage);
178
+
179
+ // 補間処理方法
180
+ Rixmap::Interpolator* ipo = NULL;
181
+ switch (_this->getInterpolation()) {
182
+ case Rixmap::Interpolation::BICUBIC:
183
+ ipo = new Rixmap::BicubicInterpolator(srcImage);
184
+ break;
185
+
186
+ default:
187
+ ipo = new Rixmap::NOPInterpolator(srcImage);
188
+ break;
189
+ }
190
+
191
+ // 画像サイズ調整フラグをC++型に展開
192
+ bool fit = false;
193
+ if (RTEST(argFit)) {
194
+ fit = true;
195
+ }
196
+
197
+ try {
198
+ // アフィン変換パラメータ
199
+ VALUE matrixObject = rb_iv_get(self, "@matrix");
200
+ Rixmap::AffineMatrix* matrix = rixmap_unwrap<Rixmap::AffineMatrix>(matrixObject);
201
+
202
+ // 画像サイズ調整
203
+ int32_t newWidth = srcImage->getWidth();
204
+ int32_t newHeight = srcImage->getHeight();
205
+ int32_t newXOffset = 0;
206
+ int32_t newYOffset = 0;
207
+
208
+ if (fit) { // サイズ調整有
209
+ matrix->matrixize();
210
+
211
+ // 座標点を取得
212
+ Rixmap::Point srcPoints[4] = {
213
+ {0.0, 0.0},
214
+ {0.0, static_cast<double>(srcImage->getHeight())},
215
+ {static_cast<double>(srcImage->getWidth()), 0.0},
216
+ {static_cast<double>(srcImage->getWidth()), static_cast<double>(srcImage->getHeight())}
217
+ };
218
+ Rixmap::Point dstPoint;
219
+
220
+ int32_t left = INT32_MAX;
221
+ int32_t right = INT32_MIN;
222
+ int32_t top = INT32_MAX;
223
+ int32_t bottom = INT32_MIN;
224
+ for (int i = 0; i < 4; i++) {
225
+ matrix->deform(srcPoints[i], dstPoint);
226
+ if (dstPoint.x < left) {
227
+ left = lround(std::floor(dstPoint.x));
228
+ }
229
+ if (dstPoint.x > right) {
230
+ right = lround(std::ceil(dstPoint.x));
231
+ }
232
+ if (dstPoint.y < top) {
233
+ top = lround(std::floor(dstPoint.y));
234
+ }
235
+ if (dstPoint.y > bottom) {
236
+ bottom = lround(std::ceil(dstPoint.y));
237
+ }
238
+ }
239
+
240
+ // サイズへ
241
+ newWidth = (right - left);
242
+ newHeight = (bottom - top);
243
+ newXOffset = left;
244
+ newYOffset = top;
245
+ } else { // サイズ調整なし
246
+ // DO NOTHING
247
+ }
248
+
249
+ // 保存先画像を作成
250
+ VALUE dstImageObject = RixmapImage_NewInstance(ipo->getPreferredMode(), newWidth, newHeight, srcImage->getMetadata());
251
+ Rixmap::ImageData* dstImage = rixmap_unwrap<Rixmap::ImageData>(dstImageObject);
252
+
253
+ // 移動先チャンネルリスト
254
+ const Rixmap::ChannelArray& channels = dstImage->getModeInfo().getChannels();
255
+
256
+ // 変換処理
257
+ matrix->matrixize();
258
+ Rixmap::Point src; // 変形前 (元画像) 座標格納先
259
+ Rixmap::Point dst; // 変形後 (返却用画像) 座標格納先
260
+ for (int32_t dstY = 0; dstY < dstImage->getHeight(); dstY++) {
261
+ for (int32_t dstX = 0; dstX < dstImage->getWidth(); dstX++) {
262
+ // 変換前座標を取得
263
+ dst.x = static_cast<double>(dstX + newXOffset);
264
+ dst.y = static_cast<double>(dstY + newYOffset);
265
+ matrix->inverse(dst, src);
266
+
267
+ // 補間処理
268
+ ipo->calculate(src.x, src.y);
269
+
270
+ // ピクセルデータを取り込む
271
+ for (auto it = channels.begin(); it != channels.end(); it++) {
272
+ uint8_t byte = ipo->get(*it);
273
+ dstImage->set(*it, dstX, dstY, byte);
274
+ }
275
+ }
276
+ }
277
+
278
+ return dstImageObject;
279
+ } catch (const std::exception& e) {
280
+ if (ipo != NULL) {
281
+ delete ipo;
282
+ }
283
+ rb_raise(rb_eRuntimeError, e.what());
284
+ }
285
+ }
286
+ /* }}} */
287
+ /* Rixmap::Deformer::AffineMatrix {{{ */
288
+ static void AffineMatrix_Free(Rixmap::AffineMatrixData* data) {
289
+ rixmap_xdelete(data);
290
+ }
291
+
292
+ static VALUE AffineMatrix_Alloc(VALUE klass) {
293
+ Rixmap::AffineMatrixData* data = rixmap_xnew<Rixmap::AffineMatrixData>();
294
+ return Data_Wrap_Struct(klass, RIXMAP_DEFAULT_MARK, AffineMatrix_Free, data);
295
+ }
296
+
297
+ /**
298
+ * アフィン変換パラメータを初期化します.
299
+ *
300
+ * @param [Hash] params 初期化パラメータ
301
+ * @option params [Array<Integer>] :center 変換中心点 (Default: [0, 0]. つまりは左上)
302
+ * @option params [Array<Integer>] :scale 拡大率 (Default: [1.0, 1.0])
303
+ * @option params [Array<Integer>] :translation 平行移動量 (Default: [0.0, 0.0])
304
+ * @option params [Float] :angle 回転角度
305
+ * @option params [Symbol] :skew 剪断変形方向. `:horizontal`, `:vertical`, `:both` のいずれか.
306
+ * @return [void]
307
+ */
308
+ static VALUE AffineMatrix_initialize(int argc, VALUE* argv, VALUE self) {
309
+ // 引数解析
310
+ VALUE argParams = Qnil;
311
+ rb_scan_args(argc, argv, "01", &argParams);
312
+
313
+ VALUE objParams = Qnil;
314
+ if (!NIL_P(argParams)) {
315
+ #if HAVE_RB_HASH
316
+ objParams = rb_Hash(argParams);
317
+ #else
318
+ objParams = rb_hash_new();
319
+ #endif
320
+ } else {
321
+ objParams = rb_hash_new();
322
+ }
323
+
324
+ VALUE keys = rb_funcall(objParams, rb_intern("keys"), 0);
325
+ long nkey = RARRAY_LEN(keys);
326
+ for (long i = 0; i < nkey; i++) {
327
+ VALUE key = rb_ary_entry(keys, i);
328
+ VALUE val = rb_hash_lookup(objParams, key);
329
+
330
+ // インスタンスメソッドを呼び出し
331
+ rb_funcall(self, rb_intern_str(rb_String(key)), 1, val);
332
+ }
333
+
334
+ return self;
335
+ }
336
+
337
+ /**
338
+ * アフィン変換パラメータの複製を初期化します.
339
+ *
340
+ * @param [Object] object 複製元オブジェクト
341
+ * @return [void]
342
+ */
343
+ static VALUE AffineMatrix_initializeCopy(VALUE self, VALUE argObject) {
344
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
345
+ Rixmap::AffineMatrixData* _that = rixmap_unwrap<Rixmap::AffineMatrixData>(argObject);
346
+
347
+ *_this = *_that;
348
+
349
+ return self;
350
+ }
351
+
352
+ /**
353
+ * 変換中心点を取得します.
354
+ *
355
+ * @return [Array<Float>] 中心点
356
+ */
357
+ static VALUE AffineMatrix_getCenter(VALUE self) {
358
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
359
+ VALUE items = rb_ary_new();
360
+ rb_ary_store(items, 0, DBL2NUM(_this->getCenter().x));
361
+ rb_ary_store(items, 1, DBL2NUM(_this->getCenter().y));
362
+ return items;
363
+ }
364
+
365
+ /**
366
+ * 変換中心点を設定します.
367
+ *
368
+ * @param [Array<Float>] point 中心点
369
+ * @return [void]
370
+ */
371
+ static VALUE AffineMatrix_setCenter(VALUE self, VALUE argPoint) {
372
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
373
+ VALUE items = rb_Array(argPoint);
374
+ double x = NUM2DBL(rb_Float(rb_ary_entry(items, 0)));
375
+ double y = NUM2DBL(rb_Float(rb_ary_entry(items, 1)));
376
+ _this->setCenter(x, y);
377
+ return argPoint;
378
+ }
379
+
380
+ /**
381
+ * 拡大率を取得します.
382
+ *
383
+ * @return [Array<Float>] 拡大率
384
+ */
385
+ static VALUE AffineMatrix_getScale(VALUE self) {
386
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
387
+ VALUE items = rb_ary_new();
388
+ rb_ary_store(items, 0, DBL2NUM(_this->getScale().x));
389
+ rb_ary_store(items, 1, DBL2NUM(_this->getScale().y));
390
+ return items;
391
+ }
392
+
393
+ /**
394
+ * 拡大率を設定します.
395
+ *
396
+ * @param [Array<Float>] scale 拡大率
397
+ */
398
+ static VALUE AffineMatrix_setScale(VALUE self, VALUE argScale) {
399
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
400
+ VALUE items = rb_Array(argScale);
401
+ _this->setScale(NUM2DBL(rb_Float(rb_ary_entry(items, 0))), NUM2DBL(rb_Float(rb_ary_entry(items, 1))));
402
+ return argScale;
403
+ }
404
+
405
+ /**
406
+ * 平行移動量を取得します.
407
+ *
408
+ * @return [Array<Float>] 平行移動量
409
+ */
410
+ static VALUE AffineMatrix_getTranslation(VALUE self) {
411
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
412
+ VALUE items = rb_ary_new();
413
+ rb_ary_store(items, 0, DBL2NUM(_this->getTranslation().x));
414
+ rb_ary_store(items, 1, DBL2NUM(_this->getTranslation().y));
415
+ return items;
416
+ }
417
+
418
+ /**
419
+ * 平行移動量を設定します.
420
+ *
421
+ * @param [Array<Float>] trans 平行移動量
422
+ * @return [void]
423
+ */
424
+ static VALUE AffineMatrix_setTranslation(VALUE self, VALUE argTrans) {
425
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
426
+ VALUE items = rb_Array(argTrans);
427
+ _this->setTranslation(NUM2DBL(rb_Float(rb_ary_entry(items, 0))), NUM2DBL(rb_Float(rb_ary_entry(items, 1))));
428
+ return argTrans;
429
+ }
430
+
431
+ /**
432
+ * 回転角度をラジアンで取得します.
433
+ *
434
+ * @return [Float] 回転角度
435
+ */
436
+ static VALUE AffineMatrix_getAngle(VALUE self) {
437
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
438
+ return DBL2NUM(_this->getAngle());
439
+ }
440
+
441
+ /**
442
+ * 回転角度を設定します.
443
+ *
444
+ * @param [Float] angle 回転角度 (ラジアン)
445
+ * @return [void]
446
+ */
447
+ static VALUE AffineMatrix_setAngle(VALUE self, VALUE argAngle) {
448
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
449
+ _this->setAngle(NUM2DBL(rb_Float(argAngle)));
450
+ return argAngle;
451
+ }
452
+
453
+ /**
454
+ * 剪断変形方向を取得します.
455
+ *
456
+ * @return [Integer] 剪断変形方向定数値
457
+ */
458
+ static VALUE AffineMatrix_getSkew(VALUE self) {
459
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
460
+ switch (_this->getSkew()) {
461
+ case Rixmap::SkewDeformation::HORIZONTAL:
462
+ case Rixmap::SkewDeformation::VERTICAL:
463
+ case Rixmap::SkewDeformation::BOTH:
464
+ return INT2FIX(static_cast<int>(_this->getSkew()));
465
+
466
+ default:
467
+ return Qnil;
468
+ }
469
+ }
470
+
471
+ /**
472
+ * 剪断変形方向を設定します.
473
+ *
474
+ * @param [Symbol,String,Integer,nil] skew 剪断変形方向
475
+ * @return [void]
476
+ */
477
+ static VALUE AffineMatrix_setSkew(VALUE self, VALUE argSkew) {
478
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
479
+ if (NIL_P(argSkew)) {
480
+ _this->setSkew(Rixmap::SkewDeformation::NONE);
481
+ } else if (RB_TYPE_P(argSkew, T_FIXNUM)) {
482
+ Rixmap::SkewDeformation skew = static_cast<Rixmap::SkewDeformation>(FIX2INT(argSkew));
483
+ switch (skew) {
484
+ case Rixmap::SkewDeformation::HORIZONTAL:
485
+ case Rixmap::SkewDeformation::VERTICAL:
486
+ case Rixmap::SkewDeformation::BOTH:
487
+ _this->setSkew(skew);
488
+ break;
489
+
490
+ default:
491
+ _this->setSkew(Rixmap::SkewDeformation::NONE);
492
+ break;
493
+ }
494
+ } else {
495
+ VALUE strSkew = rb_sprintf("SKEW_");
496
+ strSkew = rb_str_concat(strSkew, rb_funcall(rb_String(argSkew), rb_intern("upcase"), 0, NULL));
497
+ if (rb_const_defined(mRixmapDeformer, rb_intern_str(strSkew))) {
498
+ VALUE objSkew = rb_const_get(mRixmapDeformer, rb_intern_str(strSkew));
499
+ _this->setSkew(static_cast<Rixmap::SkewDeformation>(NUM2INT(rb_Integer(objSkew))));
500
+ } else {
501
+ _this->setSkew(Rixmap::SkewDeformation::NONE);
502
+ }
503
+ }
504
+
505
+ return argSkew;
506
+ }
507
+
508
+ /**
509
+ * オブジェクトとしての文字列表現を返します.
510
+ *
511
+ * @return [String] 文字列表現
512
+ */
513
+ static VALUE AffineMatrix_inspect(VALUE self) {
514
+ Rixmap::AffineMatrixData* _this = rixmap_unwrap<Rixmap::AffineMatrixData>(self);
515
+ return rb_enc_sprintf(
516
+ rb_usascii_encoding(),
517
+ "#<%s:%p scale=[%f, %f], trans=[%f, %f], center=[%f, %f], angle=%f, skew=%d>",
518
+ rb_obj_classname(self), reinterpret_cast<void*>(self),
519
+ _this->getScale().x, _this->getScale().y,
520
+ _this->getTranslation().x, _this->getTranslation().y,
521
+ _this->getCenter().x, _this->getCenter().y,
522
+ _this->getAngle(),
523
+ static_cast<int>(_this->getSkew()));
524
+ }
525
+ /* }}} */
526
+ ///* Rixmap::Deformer::AffineMatrix::Point {{{ */
527
+ ///**
528
+ // * @overload initialize(x=0.0, y=0.0)
529
+ // * 座標オブジェクトを初期化します.
530
+ // * @param [Float] x X軸方向データ
531
+ // * @param [Float] y Y軸方向データ
532
+ // * @return [void]
533
+ // */
534
+ //static VALUE AffinePoint_initialize(int argc, VALUE* argv, VALUE self) {
535
+ // VALUE argX = Qnil, argY = Qnil;
536
+ // rb_scan_args(argc, argv, "02", &argX, &argY);
537
+ //
538
+ // if (NIL_P(argX)) {
539
+ // rb_iv_set(self, "@x", DBL2NUM(0.0));
540
+ // } else {
541
+ // rb_iv_set(self, "@x", rb_Float(argX));
542
+ // }
543
+ // if (NIL_P(argY)) {
544
+ // rb_iv_set(self, "@y", DBL2NUM(0.0));
545
+ // } else {
546
+ // rb_iv_set(self, "@y", DBL2NUM(argY));
547
+ // }
548
+ //
549
+ // return self;
550
+ //}
551
+ //
552
+ ///**
553
+ // * 座標オブジェクトの複製を初期化します.
554
+ // *
555
+ // * @param [Object] object 複製元
556
+ // * @return [void]
557
+ // */
558
+ //static VALUE AffinePoint_initializeCopy(VALUE self, VALUE argObject) {
559
+ // rb_iv_set(self, "@x", rb_iv_get(argObject, "@x"));
560
+ // rb_iv_set(self, "@y", rb_iv_get(argObject, "@y"));
561
+ // return self;
562
+ //}
563
+ ///* }}} */
564
+
565
+ //----------------------------------------------------------------------------//
566
+ // 内部API実装
567
+ //----------------------------------------------------------------------------//
568
+ /**
569
+ * 変形処理モジュール定義
570
+ */
571
+ void RixmapDeformation_Init() {
572
+ /**
573
+ * Document-module: Rixmap::Deformer
574
+ *
575
+ * 変形処理実装モジュール.
576
+ */
577
+ mRixmapDeformer = rb_define_module_under(mRixmap, "Deformer");
578
+
579
+ /** バイキュービック補間処理定数 */
580
+ rb_define_const(mRixmapDeformer, "IPO_BICUBIC", INT2FIX(static_cast<int>(Rixmap::Interpolation::BICUBIC)));
581
+
582
+ /** 横方向剪断変形定数 */
583
+ rb_define_const(mRixmapDeformer, "SKEW_HORIZONTAL", INT2FIX(static_cast<int>(Rixmap::SkewDeformation::HORIZONTAL)));
584
+
585
+ /** 縦方向剪断変形定数 */
586
+ rb_define_const(mRixmapDeformer, "SKEW_VERTICAL", INT2FIX(static_cast<int>(Rixmap::SkewDeformation::VERTICAL)));
587
+
588
+ /** 両方向剪断変形定数 */
589
+ rb_define_const(mRixmapDeformer, "SKEW_BOTH", INT2FIX(static_cast<int>(Rixmap::SkewDeformation::BOTH)));
590
+
591
+ /**
592
+ * Document-class: Rixmap::Deformer::BaseDeformer
593
+ *
594
+ * 画像変形処理のベースクラス.
595
+ */
596
+ cRixmapBaseDeformer = rb_define_class_under(mRixmapDeformer, "BaseDeformer", rb_cObject);
597
+ rb_define_alloc_func(cRixmapBaseDeformer, BaseDeformer_Alloc);
598
+ rb_define_private_method(cRixmapBaseDeformer, "initialize", RUBY_METHOD_FUNC(BaseDeformer_initialize), -1);
599
+ rb_define_method(cRixmapBaseDeformer, "interpolator", RUBY_METHOD_FUNC(BaseDeformer_getInterpolator), 0);
600
+ rb_define_method(cRixmapBaseDeformer, "interpolator=", RUBY_METHOD_FUNC(BaseDeformer_setInterpolator), 1);
601
+ rb_define_method(cRixmapBaseDeformer, "deform", RUBY_METHOD_FUNC(BaseDeformer_deform), -1);
602
+ rb_define_method(cRixmapBaseDeformer, "inspect", RUBY_METHOD_FUNC(BaseDeformer_inspect), 0);
603
+ rb_alias(cRixmapBaseDeformer, rb_intern("ipo"), rb_intern("interpolator"));
604
+ rb_alias(cRixmapBaseDeformer, rb_intern("ipo="), rb_intern("interpolator="));
605
+
606
+ /**
607
+ * Document-class: Rixmap::Deformer::AffineDeformer
608
+ *
609
+ * アフィン変換による変形処理実装.
610
+ */
611
+ cRixmapAffineDeformer = rb_define_class_under(mRixmapDeformer, "AffineDeformer", cRixmapBaseDeformer);
612
+ rb_define_alloc_func(cRixmapAffineDeformer, AffineDeformer_Alloc);
613
+ rb_define_private_method(cRixmapAffineDeformer, "initialize", RUBY_METHOD_FUNC(AffineDeformer_initialize), -1);
614
+ rb_define_method(cRixmapAffineDeformer, "deform", RUBY_METHOD_FUNC(AffineDeformer_deform), -1);
615
+ rb_define_attr(cRixmapAffineDeformer, "matrix", 1, 1);
616
+
617
+ /**
618
+ * Document-class: Rixmap::Deformer::AffineMatrix
619
+ *
620
+ * アフィン変換用パラメータクラス.
621
+ */
622
+ cRixmapAffineMatrix = rb_define_class_under(mRixmapDeformer, "AffineMatrix", rb_cObject);
623
+ rb_define_alloc_func(cRixmapAffineMatrix, AffineMatrix_Alloc);
624
+ rb_define_private_method(cRixmapAffineMatrix, "initialize", RUBY_METHOD_FUNC(AffineMatrix_initialize), -1);
625
+ rb_define_private_method(cRixmapAffineMatrix, "initialize_copy", RUBY_METHOD_FUNC(AffineMatrix_initializeCopy), 1);
626
+ rb_define_method(cRixmapAffineMatrix, "center", RUBY_METHOD_FUNC(AffineMatrix_getCenter), 0);
627
+ rb_define_method(cRixmapAffineMatrix, "center=", RUBY_METHOD_FUNC(AffineMatrix_setCenter), 1);
628
+ rb_define_method(cRixmapAffineMatrix, "scale", RUBY_METHOD_FUNC(AffineMatrix_getScale), 0);
629
+ rb_define_method(cRixmapAffineMatrix, "scale=", RUBY_METHOD_FUNC(AffineMatrix_setScale), 1);
630
+ rb_define_method(cRixmapAffineMatrix, "translation", RUBY_METHOD_FUNC(AffineMatrix_getTranslation), 0);
631
+ rb_define_method(cRixmapAffineMatrix, "translation=", RUBY_METHOD_FUNC(AffineMatrix_setTranslation), 1);
632
+ rb_define_method(cRixmapAffineMatrix, "angle", RUBY_METHOD_FUNC(AffineMatrix_getAngle), 0);
633
+ rb_define_method(cRixmapAffineMatrix, "angle=", RUBY_METHOD_FUNC(AffineMatrix_setAngle), 1);
634
+ rb_define_method(cRixmapAffineMatrix, "skew", RUBY_METHOD_FUNC(AffineMatrix_getSkew), 0);
635
+ rb_define_method(cRixmapAffineMatrix, "skew=", RUBY_METHOD_FUNC(AffineMatrix_setSkew), 1);
636
+ rb_define_method(cRixmapAffineMatrix, "inspect", RUBY_METHOD_FUNC(AffineMatrix_inspect), 0);
637
+ rb_alias(cRixmapAffineMatrix, rb_intern("trans"), rb_intern("translation"));
638
+ rb_alias(cRixmapAffineMatrix, rb_intern("trans="), rb_intern("translation="));
639
+
640
+ // /**
641
+ // * Document-class: Rixmap::Deformer::AffineMatrix::Point
642
+ // *
643
+ // * アフィン変換用座標構造体.
644
+ // * FIXME 外出しするかも
645
+ // */
646
+ // cRixmapAffinePoint = rb_define_class_under(cRixmapAffineMatrix, "Point", rb_cObject);
647
+ // rb_define_private_method(cRixmapAffinePoint, "initialize", RUBY_METHOD_FUNC(AffinePoint_initialize), -1);
648
+ // rb_define_private_method(cRixmapAffinePoint, "initialize_copy", RUBY_METHOD_FUNC(AffinePoint_initializeCopy), 1);
649
+ // rb_define_attr(cRixmapAffinePoint, "x", 1, 1);
650
+ // rb_define_attr(cRixmapAffinePoint, "y", 1, 1);
651
+ //
652
+ // /**
653
+ // * Document-class: Rixmap::Deformer::AffineMatrix::Center
654
+ // *
655
+ // * アフィン変換用中央座標構造体.
656
+ // */
657
+ // cRixmapAffineCenter = rb_define_class_under(cRixmapAffineMatrix, "Center", cRixmapAffinePoint);
658
+ //
659
+ // /**
660
+ // * Document-class: Rixmap::Deformer::AffineMatrix::Scale
661
+ // *
662
+ // * アフィン変換用拡大率構造体.
663
+ // */
664
+ // cRixmapAffineScale = rb_define_class_under(cRixmapAffineMatrix, "Scale", cRixmapAffinePoint);
665
+ //
666
+ // /**
667
+ // * Document-class: Rixmap::Deformer::AffineMatrix::Translation
668
+ // *
669
+ // * アフィン変換用平行移動量構造体.
670
+ // */
671
+ // cRixmapAffineTranslation = rb_define_class_under(cRixmapAffineMatrix, "Translation", cRixmapAffinePoint);
672
+
673
+ // GCから保護しておく
674
+ rb_global_variable(&mRixmapDeformer);
675
+ rb_global_variable(&cRixmapBaseDeformer);
676
+ rb_global_variable(&cRixmapAffineDeformer);
677
+ rb_global_variable(&cRixmapAffineMatrix);
678
+ // rb_global_variable(&cRixmapAffinePoint);
679
+ // rb_global_variable(&cRixmapAffineCenter);
680
+ // rb_global_variable(&cRixmapAffineScale);
681
+ // rb_global_variable(&cRixmapAffineTranslation);
682
+ }
683
+
684
+
685
+ //============================================================================//
686
+ // $Id: rixmapdeformation.cxx,v 753dbf70cab3 2014/05/16 16:13:38 chikuchikugonzalez $
687
+ // vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker: