rixmap 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: