rixmap 0.1.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.
- checksums.yaml +7 -0
- data/LICENSE.txt +38 -0
- data/README.markdown +74 -0
- data/Rakefile +156 -0
- data/lib/rixmap/format/bmp.rb +326 -0
- data/lib/rixmap/format/pcx.rb +438 -0
- data/lib/rixmap/format/png/chunk.rb +239 -0
- data/lib/rixmap/format/png/imageio.rb +288 -0
- data/lib/rixmap/format/png.rb +78 -0
- data/lib/rixmap/format/xpm.rb +446 -0
- data/lib/rixmap/format.rb +10 -0
- data/lib/rixmap/version.rb +26 -0
- data/lib/rixmap.rb +24 -0
- data/spec/binary_spec.rb +12 -0
- data/spec/color_spec.rb +76 -0
- data/spec/image_spec.rb +297 -0
- data/spec/mode_spec.rb +71 -0
- data/spec/palette_spec.rb +77 -0
- data/src/chollas/LICENSE.txt +38 -0
- data/src/chollas/README.md +23 -0
- data/src/chollas/alloc.hxx +62 -0
- data/src/chollas/endian.hxx +42 -0
- data/src/chollas/raser.hxx +113 -0
- data/src/chollas/utilities.hxx +58 -0
- data/src/extconf.rb +47 -0
- data/src/rixmap/binary.hxx +19 -0
- data/src/rixmap/channel.hxx +42 -0
- data/src/rixmap/color.hxx +222 -0
- data/src/rixmap/common.hxx +58 -0
- data/src/rixmap/image.hxx +371 -0
- data/src/rixmap/mode.hxx +351 -0
- data/src/rixmap/palette.hxx +220 -0
- data/src/rixmap.hxx +19 -0
- data/src/rixmapcore.cxx +3209 -0
- data/src/rixmapcore.hxx +27 -0
- data/src/rixmapio.cxx +652 -0
- data/src/rixmapio.hxx +25 -0
- data/src/rixmapmain.cxx +24 -0
- data/test/test_bmp.rb +139 -0
- data/test/test_pcx.rb +172 -0
- data/test/test_png.rb +136 -0
- data/test/test_xpm.rb +73 -0
- metadata +128 -0
data/src/rixmapcore.hxx
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
// -*- coding: utf-8 -*-
|
2
|
+
/**
|
3
|
+
* Rixmapコア部分用ヘッダ
|
4
|
+
*/
|
5
|
+
#pragma once
|
6
|
+
#include "rixmap.hxx"
|
7
|
+
|
8
|
+
//----------------------------------------------------------------------------//
|
9
|
+
// グローバル変数宣言
|
10
|
+
//----------------------------------------------------------------------------//
|
11
|
+
extern VALUE mRixmap;
|
12
|
+
extern VALUE cRixmapBinary;
|
13
|
+
extern VALUE cRixmapMode;
|
14
|
+
extern VALUE cRixmapColor;
|
15
|
+
extern VALUE cRixmapPalette;
|
16
|
+
extern VALUE cRixmapImage;
|
17
|
+
extern VALUE cRixmapImageLine;
|
18
|
+
|
19
|
+
//----------------------------------------------------------------------------//
|
20
|
+
// コアAPI関数プロトタイプ
|
21
|
+
//----------------------------------------------------------------------------//
|
22
|
+
extern void RixmapCore_Init();
|
23
|
+
|
24
|
+
|
25
|
+
//============================================================================//
|
26
|
+
// $Id: rixmapcore.hxx,v add33526d522 2014/04/19 16:27:29 chikuchikugonzalez $
|
27
|
+
// vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
|
data/src/rixmapio.cxx
ADDED
@@ -0,0 +1,652 @@
|
|
1
|
+
// -*- coding: utf-8 -*-
|
2
|
+
#include "rixmapio.hxx"
|
3
|
+
|
4
|
+
//----------------------------------------------------------------------------//
|
5
|
+
// C++用グローバルオブジェクト
|
6
|
+
//----------------------------------------------------------------------------//
|
7
|
+
|
8
|
+
//----------------------------------------------------------------------------//
|
9
|
+
// グローバルオブジェクト実体
|
10
|
+
//----------------------------------------------------------------------------//
|
11
|
+
VALUE mRixmapImageIO = Qnil;
|
12
|
+
VALUE cRixmapImageIOInfo = Qnil;
|
13
|
+
VALUE cRixmapBaseImageIO = Qnil;
|
14
|
+
VALUE mRixmapFormat = Qnil;
|
15
|
+
|
16
|
+
//----------------------------------------------------------------------------//
|
17
|
+
// IO系実装
|
18
|
+
//----------------------------------------------------------------------------//
|
19
|
+
/* Rixmap::ImageIO {{{ */
|
20
|
+
/**
|
21
|
+
* 画像入出力実装クラスを登録します.
|
22
|
+
*
|
23
|
+
* @overload register(name, klass, extensions=[])
|
24
|
+
* @param [Symbol,String] name 画像入出力実装名. `:BMP` とか.
|
25
|
+
* @param [Class] klass 画像入出力の実装クラス.
|
26
|
+
* @param [Array<String>] extensions 実装クラスに対応するファイル名拡張子リスト.
|
27
|
+
* @return [void]
|
28
|
+
*
|
29
|
+
* @overload register(name, info)
|
30
|
+
* @param [Symbol,String] name 画像入出力実装名
|
31
|
+
* @param [Rixmap::ImageIO::ImageIOInfo] info 画像入出力実装情報.
|
32
|
+
* @return [void]
|
33
|
+
*/
|
34
|
+
static VALUE ImageIO_Register(int argc, VALUE* argv, VALUE klass) {
|
35
|
+
VALUE argName, arg1, arg2;
|
36
|
+
rb_scan_args(argc, argv, "21", &argName, &arg1, &arg2);
|
37
|
+
|
38
|
+
// 名前を大文字化
|
39
|
+
VALUE strName = rb_funcall(rb_String(argName), rb_intern("upcase"), 0);
|
40
|
+
if (RSTRING_LEN(strName) == 0) {
|
41
|
+
rb_raise(rb_eArgError, "empty name is not valid");
|
42
|
+
}
|
43
|
+
VALUE symName = ID2SYM(rb_intern_str(strName));
|
44
|
+
|
45
|
+
// 引数で変更
|
46
|
+
VALUE info = Qnil;
|
47
|
+
if (RB_TYPE_P(arg1, T_CLASS)) {
|
48
|
+
// klass
|
49
|
+
VALUE objExts = Qnil;
|
50
|
+
if (NIL_P(arg2)) {
|
51
|
+
objExts = rb_ary_new();
|
52
|
+
} else {
|
53
|
+
objExts = rb_Array(arg2);
|
54
|
+
}
|
55
|
+
VALUE params[2] = {
|
56
|
+
arg1, objExts
|
57
|
+
};
|
58
|
+
info = rb_class_new_instance(2, params, cRixmapImageIOInfo);
|
59
|
+
} else if (RTEST(rb_obj_is_kind_of(arg1, cRixmapImageIOInfo))) {
|
60
|
+
// iio info
|
61
|
+
info = rb_obj_clone(arg1);
|
62
|
+
} else {
|
63
|
+
rb_raise(rb_eArgError, "unknown imageio type: %s", rb_obj_classname(arg1));
|
64
|
+
}
|
65
|
+
|
66
|
+
// レジストリへ入れる
|
67
|
+
VALUE registry = rb_iv_get(klass, "@registry");
|
68
|
+
OBJ_FREEZE(info);
|
69
|
+
rb_hash_aset(registry, symName, info);
|
70
|
+
|
71
|
+
return info;
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* 画像入出力実装のインスタンスを作成します.
|
76
|
+
*
|
77
|
+
* @overload new(name, *params)
|
78
|
+
* @param [Symbol,String] name 画像入出力実装名.
|
79
|
+
* @param [Object...] params 実装クラスのコンストラクタに渡される引数.
|
80
|
+
* @return [Object] 実装クラスインスタンス.
|
81
|
+
*/
|
82
|
+
static VALUE ImageIO_New(int argc, VALUE* argv, VALUE klass) {
|
83
|
+
VALUE argName, argParams;
|
84
|
+
rb_scan_args(argc, argv, "1*", &argName, &argParams);
|
85
|
+
|
86
|
+
// キー名を作成
|
87
|
+
VALUE strName = rb_String(argName);
|
88
|
+
VALUE symName = ID2SYM(rb_intern_str(rb_funcall(strName, rb_intern("upcase"), 0)));
|
89
|
+
|
90
|
+
// レジストリから取得
|
91
|
+
VALUE registry = rb_iv_get(klass, "@registry");
|
92
|
+
VALUE info = rb_hash_lookup(registry, symName);
|
93
|
+
|
94
|
+
// オブジェクトを作成
|
95
|
+
if (NIL_P(info)) {
|
96
|
+
rb_raise(rb_eNotImpError, "Image-IO for %s is not implemented.", StringValueCStr(strName));
|
97
|
+
}
|
98
|
+
VALUE klsIIO = rb_funcall(info, rb_intern("imageio"), 0);
|
99
|
+
if (NIL_P(klsIIO)) {
|
100
|
+
rb_raise(rb_eNotImpError, "Image-IO for %s is not implemented.", StringValueCStr(strName));
|
101
|
+
}
|
102
|
+
long nparam = RARRAY_LEN(argParams);
|
103
|
+
VALUE* params = RARRAY_PTR(argParams);
|
104
|
+
VALUE iio = rb_class_new_instance(nparam, params, klsIIO);
|
105
|
+
|
106
|
+
return iio;
|
107
|
+
}
|
108
|
+
|
109
|
+
/**
|
110
|
+
* 指定した名前に対応する画像入出力実装情報を返します.
|
111
|
+
*
|
112
|
+
* @param [Symbol,String] name 実装名
|
113
|
+
* @return [Rixmap::ImageIO::ImageIOInfo] 実装情報
|
114
|
+
*/
|
115
|
+
static VALUE ImageIO_Get(VALUE klass, VALUE argName) {
|
116
|
+
// キー名を作成
|
117
|
+
VALUE strName = rb_String(argName);
|
118
|
+
VALUE symName = ID2SYM(rb_intern_str(rb_funcall(strName, rb_intern("upcase"), 0)));
|
119
|
+
|
120
|
+
// レジストリから取得
|
121
|
+
VALUE registry = rb_iv_get(klass, "@registry");
|
122
|
+
VALUE info = rb_hash_lookup(registry, symName);
|
123
|
+
|
124
|
+
// 見つからなかった場合はnilになる
|
125
|
+
return info;
|
126
|
+
}
|
127
|
+
|
128
|
+
/**
|
129
|
+
* 指定したファイル名に最初にマッチした画像入出力実装情報を返します.
|
130
|
+
*
|
131
|
+
* @param [String] filename ファイル名パターン.
|
132
|
+
* @return [Rixmap::ImageIO::ImageIOInfo] 実装情報. 見つからない場合はnil.
|
133
|
+
* @see {Rixmap::ImageIO.findall}
|
134
|
+
*/
|
135
|
+
static VALUE ImageIO_Find(VALUE klass, VALUE argFileName) {
|
136
|
+
// ファイル名を文字列にしておく
|
137
|
+
VALUE strFileName = rb_String(argFileName);
|
138
|
+
|
139
|
+
// レジストリ
|
140
|
+
VALUE registry = rb_iv_get(klass, "@registry");
|
141
|
+
|
142
|
+
// 登録済みキーリストをすべて取得
|
143
|
+
VALUE allKeys = rb_funcall(registry, rb_intern("keys"), 0);
|
144
|
+
|
145
|
+
// キーでループする
|
146
|
+
long nkey = RARRAY_LEN(allKeys);
|
147
|
+
for (long i = 0; i < nkey; i++) {
|
148
|
+
VALUE tblKey = rb_ary_entry(allKeys, i);
|
149
|
+
VALUE tblVal = rb_hash_lookup(registry, tblKey);
|
150
|
+
|
151
|
+
if (!NIL_P(tblVal) && RTEST(rb_obj_is_kind_of(tblVal, cRixmapImageIOInfo))) {
|
152
|
+
VALUE iioInfo = tblVal; // 変数名だけ変えておく
|
153
|
+
|
154
|
+
// 拡張子をチェック
|
155
|
+
if (RTEST(rb_funcall(iioInfo, rb_intern("match?"), 1, strFileName))) {
|
156
|
+
// TODO 複数のフォーマットで同じ拡張子に対応している場合
|
157
|
+
return iioInfo;
|
158
|
+
}
|
159
|
+
} else {
|
160
|
+
// TODO warningぐらい出しておく?
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
// 見つからなかったらnil
|
165
|
+
return Qnil;
|
166
|
+
}
|
167
|
+
|
168
|
+
/**
|
169
|
+
* 指定したファイル名にマッチするすべての画像入出力情報を返します.
|
170
|
+
*
|
171
|
+
* @param [String] filename ファイル名
|
172
|
+
* @return [Array<Rixmap::ImageIO::ImageIOInfo>] 実装情報配列. 見つからない場合は空配列になります.
|
173
|
+
* @see {Rixmap::ImageIO.find}
|
174
|
+
*/
|
175
|
+
static VALUE ImageIO_FindAll(VALUE klass, VALUE argFileName) {
|
176
|
+
// ファイル名を文字列にしておく
|
177
|
+
VALUE strFileName = rb_String(argFileName);
|
178
|
+
|
179
|
+
// レジストリ
|
180
|
+
VALUE registry = rb_iv_get(klass, "@registry");
|
181
|
+
|
182
|
+
// 登録済みキーリストをすべて取得
|
183
|
+
VALUE allKeys = rb_funcall(registry, rb_intern("keys"), 0);
|
184
|
+
|
185
|
+
// キーでループする
|
186
|
+
VALUE aryInfo = rb_ary_new();
|
187
|
+
long nkey = RARRAY_LEN(allKeys);
|
188
|
+
for (long i = 0; i < nkey; i++) {
|
189
|
+
VALUE tblKey = rb_ary_entry(allKeys, i);
|
190
|
+
VALUE tblVal = rb_hash_lookup(registry, tblKey);
|
191
|
+
|
192
|
+
if (!NIL_P(tblVal) && RTEST(rb_obj_is_kind_of(tblVal, cRixmapImageIOInfo))) {
|
193
|
+
VALUE iioInfo = tblVal; // 変数名だけ変えておく
|
194
|
+
|
195
|
+
// 拡張子をチェック
|
196
|
+
if (RTEST(rb_funcall(iioInfo, rb_intern("match?"), 1, strFileName))) {
|
197
|
+
// 配列に追加
|
198
|
+
rb_ary_push(aryInfo, iioInfo);
|
199
|
+
}
|
200
|
+
} else {
|
201
|
+
// TODO warningぐらい出しておく?
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
// 見つからなかったら空配列
|
206
|
+
return aryInfo;
|
207
|
+
}
|
208
|
+
/* }}} */
|
209
|
+
/* Rixmap::ImageIO::ImageIOInfo {{{ */
|
210
|
+
/**
|
211
|
+
* 画像入出力情報クラスを初期化します.
|
212
|
+
*
|
213
|
+
* @overload initialize(klass, extensions = [])
|
214
|
+
* @param [Class] klass ImageIO実装クラス
|
215
|
+
* @param [Array] extensions 画像の拡張子リスト
|
216
|
+
* @return [void]
|
217
|
+
*/
|
218
|
+
static VALUE ImageIOInfo_initialize(int argc, VALUE* argv, VALUE self) {
|
219
|
+
VALUE argKlass, argExtensions;
|
220
|
+
rb_scan_args(argc, argv, "11", &argKlass, &argExtensions);
|
221
|
+
|
222
|
+
VALUE objIOClass = argKlass;
|
223
|
+
VALUE objExtensions = Qnil;
|
224
|
+
if (NIL_P(argExtensions)) {
|
225
|
+
objExtensions = rb_ary_new();
|
226
|
+
} else {
|
227
|
+
objExtensions = rb_Array(argExtensions);
|
228
|
+
}
|
229
|
+
|
230
|
+
rb_iv_set(self, "@imageio", objIOClass);
|
231
|
+
rb_iv_set(self, "@extensions", objExtensions);
|
232
|
+
|
233
|
+
return self;
|
234
|
+
}
|
235
|
+
|
236
|
+
/**
|
237
|
+
* 指定したファイル名の拡張子をこの情報クラスの拡張子リストと比較して、
|
238
|
+
* マッチしたものが見つかった場合はtrueを返します.
|
239
|
+
*
|
240
|
+
* @param [String] filename ファイル名
|
241
|
+
* @return [Boolean] 拡張子リストとマッチしたものがあるばあいはtrue
|
242
|
+
*/
|
243
|
+
static VALUE ImageIOInfo_isMatchFileName(VALUE self, VALUE argFileName) {
|
244
|
+
// 型チェック
|
245
|
+
VALUE objExtensions = rb_iv_get(self, "@extensions");
|
246
|
+
if (NIL_P(objExtensions)) {
|
247
|
+
rb_warning("extensions is null");
|
248
|
+
return Qfalse;
|
249
|
+
}
|
250
|
+
if (!RB_TYPE_P(objExtensions, T_ARRAY)) {
|
251
|
+
rb_warning("extensions is not array");
|
252
|
+
return Qfalse;
|
253
|
+
}
|
254
|
+
|
255
|
+
// ファイル名
|
256
|
+
VALUE objFileName = rb_funcall(rb_String(argFileName), rb_intern("downcase"), 0);
|
257
|
+
|
258
|
+
// マッチをとる
|
259
|
+
long next = RARRAY_LEN(objExtensions);
|
260
|
+
for (long i = 0; i < next; i++) {
|
261
|
+
VALUE objExt = rb_funcall(rb_String(rb_ary_entry(objExtensions, i)), rb_intern("downcase"), 0);
|
262
|
+
if (RTEST(rb_funcall(objFileName, rb_intern("end_with?"), 1, objExt))) {
|
263
|
+
return Qtrue;
|
264
|
+
}
|
265
|
+
}
|
266
|
+
return Qfalse;
|
267
|
+
}
|
268
|
+
/* }}} */
|
269
|
+
/* Rixmap::ImageIO::BaseImageIO {{{ */
|
270
|
+
/**
|
271
|
+
* 画像の先頭バイトからその画像がこのクラスで読み込めるかを判定します.
|
272
|
+
*
|
273
|
+
* @param [String] magic マジックバイトデータ
|
274
|
+
* @return [Boolean] 読み込める形式の場合はtrue
|
275
|
+
*/
|
276
|
+
static VALUE BaseImageIO_IsReadableStatic(VALUE klass, VALUE argMagic) {
|
277
|
+
return Qfalse;
|
278
|
+
}
|
279
|
+
|
280
|
+
/**
|
281
|
+
* 指定画像がこのクラスで書き込めるかを判定します.
|
282
|
+
*
|
283
|
+
* @param [Rixmap::Image] image 判定対象画像
|
284
|
+
* @return [Boolean] 書き込める形式の場合はtrue
|
285
|
+
*/
|
286
|
+
static VALUE BaseImageIO_IsWritableStatic(VALUE klass, VALUE argImage) {
|
287
|
+
return Qfalse;
|
288
|
+
}
|
289
|
+
|
290
|
+
/**
|
291
|
+
* 画像入出力実装クラスを初期化します.
|
292
|
+
*
|
293
|
+
* オプションパラメータが指定されている場合は、キーをインスタンス変数名として値を設定していきます.
|
294
|
+
*
|
295
|
+
* @overload initialize(options={})
|
296
|
+
* @param [Hash] options オプションパラメータ.
|
297
|
+
* @return [void]
|
298
|
+
*/
|
299
|
+
static VALUE BaseImageIO_initialize(int argc, VALUE* argv, VALUE self) {
|
300
|
+
VALUE argOptions = Qnil;
|
301
|
+
rb_scan_args(argc, argv, "01", &argOptions);
|
302
|
+
|
303
|
+
VALUE objOptions = Qnil;
|
304
|
+
if (NIL_P(argOptions)) {
|
305
|
+
objOptions = rb_hash_new();
|
306
|
+
} else {
|
307
|
+
if (RB_TYPE_P(argOptions, T_HASH)) {
|
308
|
+
objOptions = argOptions;
|
309
|
+
} else {
|
310
|
+
#if HAVE_RB_HASH
|
311
|
+
objOptions = rb_Hash(argOptions);
|
312
|
+
#else
|
313
|
+
objOptions = rb_hash_new();
|
314
|
+
#endif
|
315
|
+
}
|
316
|
+
}
|
317
|
+
|
318
|
+
VALUE keys = rb_funcall(objOptions, rb_intern("keys"), 0);
|
319
|
+
VALUE ivPrefix = rb_str_new_cstr("@");
|
320
|
+
long nkey = RARRAY_LEN(keys);
|
321
|
+
for (long i = 0; i < nkey; i++) {
|
322
|
+
VALUE key = rb_ary_entry(keys, i);
|
323
|
+
VALUE val = rb_hash_lookup(objOptions, key);
|
324
|
+
VALUE strKey = rb_String(key);
|
325
|
+
VALUE ivName = rb_str_dup(ivPrefix);
|
326
|
+
rb_str_concat(ivName, strKey);
|
327
|
+
rb_ivar_set(self, rb_intern_str(ivName), val);
|
328
|
+
}
|
329
|
+
|
330
|
+
return self;
|
331
|
+
}
|
332
|
+
|
333
|
+
/**
|
334
|
+
* 画像の先頭バイトからその画像がこのオブジェクトで読み込めるかどうかを判定します.
|
335
|
+
*
|
336
|
+
* @param [String] magic マジックバイトデータ
|
337
|
+
* @return [Boolean] 読み込める場合はtrue
|
338
|
+
* @see BaseImageIO.readable?
|
339
|
+
*/
|
340
|
+
static VALUE BaseImageIO_isReadable(VALUE self, VALUE argMagic) {
|
341
|
+
VALUE klass = rb_obj_class(self);
|
342
|
+
return rb_funcall(klass, rb_intern("readable?"), 1, argMagic);
|
343
|
+
}
|
344
|
+
|
345
|
+
/**
|
346
|
+
* 画像がこのオブジェクトで書き込めるかを判定します.
|
347
|
+
*
|
348
|
+
* @param [Rixmap::Image] image 判定対象画像
|
349
|
+
* @return [Boolean] 書き込める形式の場合はtrue
|
350
|
+
* @see BaseImageIO.writable?
|
351
|
+
*/
|
352
|
+
static VALUE BaseImageIO_isWritable(VALUE self, VALUE argImage) {
|
353
|
+
VALUE klass = rb_obj_class(self);
|
354
|
+
return rb_funcall(klass, rb_intern("writable?"), 1, argImage);
|
355
|
+
}
|
356
|
+
|
357
|
+
/**
|
358
|
+
* 画像をバイト列へと変換します.
|
359
|
+
*
|
360
|
+
* 変換処理は各フォーマット毎にサブクラスで実装してください.
|
361
|
+
*
|
362
|
+
* @overload encode(image, options={})
|
363
|
+
* @param [Rixmap::Image] image 変換対象の画像.
|
364
|
+
* @param [Hash] options 実行時のオプションパラメータ.
|
365
|
+
* @return [String] 画像データを含むバイト列
|
366
|
+
* @raise NotImplementedError バイト列への変換処理が実装されていない場合.
|
367
|
+
*/
|
368
|
+
static VALUE BaseImageIO_encode(int argc, VALUE* argv, VALUE self) {
|
369
|
+
rb_raise(rb_eNotImpError, "%s#%s is not implemented", rb_obj_classname(self), rb_id2name(rb_frame_this_func()));
|
370
|
+
}
|
371
|
+
|
372
|
+
/**
|
373
|
+
* バイト列から画像を復元します.
|
374
|
+
*
|
375
|
+
* 復元処理は各フォーマット毎にサブクラスで実装してください.
|
376
|
+
*
|
377
|
+
* @overload decode(data, options={})
|
378
|
+
* @param [String] data 画像データが入っているバイト列データ.
|
379
|
+
* @param [Hash] options 実行時オプションパラメータ.
|
380
|
+
* @return [Rixmap::Image] 復元された画像オブジェクト
|
381
|
+
* @raise NotImplementedError バイト列からの復元処理が実装されていない場合.
|
382
|
+
*/
|
383
|
+
static VALUE BaseImageIO_decode(int argc, VALUE* argv, VALUE self) {
|
384
|
+
rb_raise(rb_eNotImpError, "%s#%s is not implemented", rb_obj_classname(self), rb_id2name(rb_frame_this_func()));
|
385
|
+
}
|
386
|
+
|
387
|
+
/**
|
388
|
+
* 指定したパスへ画像を書き出します.
|
389
|
+
*
|
390
|
+
* @overload save(path, image, options={})
|
391
|
+
* @param [String] path 書き込み先ファイルパス
|
392
|
+
* @param [Rixmap::Image] image 書き込む画像オブジェクト.
|
393
|
+
* @param [Hash] options 実行時オプションパラメータ.
|
394
|
+
* @option options [Integer] :offset ファイルの書き込み開始位置 (バイト数)
|
395
|
+
* @return [Integer] 書き込んだバイト数
|
396
|
+
* @see #encode
|
397
|
+
*/
|
398
|
+
static VALUE BaseImageIO_save(int argc, VALUE* argv, VALUE self) {
|
399
|
+
VALUE argPath, argImage, argOptions;
|
400
|
+
rb_scan_args(argc, argv, "21", &argPath, &argImage, &argOptions);
|
401
|
+
|
402
|
+
// 型チェックとか
|
403
|
+
if (!RTEST(rb_obj_is_kind_of(argImage, cRixmapImage))) {
|
404
|
+
rb_raise(rb_eArgError, "unexpected type of image: %s", rb_obj_classname(argImage));
|
405
|
+
}
|
406
|
+
VALUE objPath = rb_String(argPath);
|
407
|
+
VALUE objImage = argImage;
|
408
|
+
VALUE objOptions = Qnil;
|
409
|
+
if (RB_TYPE_P(argOptions, T_HASH)) {
|
410
|
+
objOptions = argOptions;
|
411
|
+
} else {
|
412
|
+
objOptions = rb_hash_new();
|
413
|
+
}
|
414
|
+
|
415
|
+
// 画像のエンコード
|
416
|
+
// TODO ここで発生する例外の処理
|
417
|
+
VALUE objData = rb_funcall(self, rb_intern("encode"), 2, objImage, objOptions);
|
418
|
+
|
419
|
+
// ファイルの書き込み位置を確認
|
420
|
+
VALUE optFileOffset = rb_hash_lookup(objOptions, ID2SYM(rb_intern("offset")));
|
421
|
+
VALUE objFileOffset = Qnil;
|
422
|
+
if (NIL_P(optFileOffset)) {
|
423
|
+
objFileOffset = INT2FIX(0);
|
424
|
+
} else {
|
425
|
+
objFileOffset = rb_Integer(optFileOffset);
|
426
|
+
}
|
427
|
+
|
428
|
+
// 書き込み
|
429
|
+
VALUE klsIO = rb_path2class("IO");
|
430
|
+
VALUE objWroteBytes = rb_funcall(klsIO, rb_intern("binwrite"), 2, objPath, objData, objFileOffset);
|
431
|
+
|
432
|
+
// 戻す
|
433
|
+
return objWroteBytes;
|
434
|
+
}
|
435
|
+
|
436
|
+
/**
|
437
|
+
* 指定したストリームへ画像を書き込みます.
|
438
|
+
*
|
439
|
+
* @overload write(io, image, options={})
|
440
|
+
* @param [IO,StringIO] io 出力用に開かれているストリームオブジェクト
|
441
|
+
* @param [Rixmap::Image] image 対象画像オブジェクト
|
442
|
+
* @param [Hash] options 実行時オプションパラメータ
|
443
|
+
* @return [Integer] 書き込んだバイト数
|
444
|
+
* @see #encode
|
445
|
+
*/
|
446
|
+
static VALUE BaseImageIO_write(int argc, VALUE* argv, VALUE self) {
|
447
|
+
VALUE argIO, argImage, argOptions;
|
448
|
+
rb_scan_args(argc, argv, "21", &argIO, &argImage, &argOptions);
|
449
|
+
|
450
|
+
// 型チェックとか
|
451
|
+
if (!RTEST(rb_obj_is_kind_of(argImage, cRixmapImage))) {
|
452
|
+
rb_raise(rb_eArgError, "unexpected type of image: %s", rb_obj_classname(argImage));
|
453
|
+
}
|
454
|
+
VALUE objIO = argIO; // TODO 型チェックする
|
455
|
+
VALUE objImage = argImage;
|
456
|
+
VALUE objOptions = Qnil;
|
457
|
+
if (RB_TYPE_P(argOptions, T_HASH)) {
|
458
|
+
objOptions = argOptions;
|
459
|
+
} else {
|
460
|
+
objOptions = rb_hash_new();
|
461
|
+
}
|
462
|
+
|
463
|
+
// 画像のエンコード
|
464
|
+
// TODO ここで発生する例外の処理
|
465
|
+
VALUE objData = rb_funcall(self, rb_intern("encode"), 2, objImage, objOptions);
|
466
|
+
|
467
|
+
// FIXME ここまで #save と同じなのをどうにかしたいよね
|
468
|
+
|
469
|
+
// 書き込む
|
470
|
+
VALUE objWroteBytes = rb_funcall(objIO, rb_intern("write"), 1, objData);
|
471
|
+
|
472
|
+
// 戻る
|
473
|
+
return objWroteBytes;
|
474
|
+
}
|
475
|
+
|
476
|
+
/**
|
477
|
+
* 指定したパスから画像を読み込みます.
|
478
|
+
*
|
479
|
+
* @overload open(path, options={})
|
480
|
+
* @param [String] path ファイルパス
|
481
|
+
* @param [Hash] options 実行時オプションパラメータ
|
482
|
+
* @option options [Integer] :length 読み込むファイルの長さ (バイト数)
|
483
|
+
* @option options [Integer] :offset 読み込むファイルの位置
|
484
|
+
* @return [Rixmap::Image] 読み込まれた画像
|
485
|
+
* @see #decode
|
486
|
+
*/
|
487
|
+
static VALUE BaseImageIO_open(int argc, VALUE* argv, VALUE self) {
|
488
|
+
VALUE argPath, argOptions;
|
489
|
+
rb_scan_args(argc, argv, "11", &argPath, &argOptions);
|
490
|
+
|
491
|
+
// 型チェックすべきか
|
492
|
+
VALUE objPath = rb_String(argPath);
|
493
|
+
VALUE objOptions = Qnil;
|
494
|
+
if (RB_TYPE_P(argOptions, T_HASH)) {
|
495
|
+
objOptions = argOptions;
|
496
|
+
} else {
|
497
|
+
objOptions = rb_hash_new();
|
498
|
+
}
|
499
|
+
|
500
|
+
// オプションパラメータ
|
501
|
+
VALUE optLength = rb_hash_lookup(objOptions, ID2SYM("length"));
|
502
|
+
VALUE optOffset = rb_hash_lookup(objOptions, ID2SYM("offset"));
|
503
|
+
VALUE objOffset = Qnil;
|
504
|
+
if (NIL_P(optOffset)) {
|
505
|
+
objOffset = INT2FIX(0);
|
506
|
+
} else {
|
507
|
+
objOffset = rb_Integer(optOffset);
|
508
|
+
}
|
509
|
+
|
510
|
+
// バイト列を取得
|
511
|
+
VALUE klsIO = rb_path2class("IO");
|
512
|
+
VALUE objBytes = rb_funcall(klsIO, rb_intern("binread"), 3, objPath, optLength, objOffset);
|
513
|
+
|
514
|
+
// 画像を復元
|
515
|
+
// TODO ココで発生する例外対処
|
516
|
+
VALUE objImage = rb_funcall(self, rb_intern("decode"), 2, objBytes, objOptions);
|
517
|
+
|
518
|
+
// 戻る
|
519
|
+
return objImage;
|
520
|
+
}
|
521
|
+
|
522
|
+
/**
|
523
|
+
* 指定されたストリームから画像を読み込みます.
|
524
|
+
*
|
525
|
+
* @overload read(io, options={})
|
526
|
+
* @param [IO,StringIO] io 読み込み用に開かれているストリームオブジェクト
|
527
|
+
* @param [Hash] options 実行時オプションパラメータ
|
528
|
+
* @option options [Integer] :length 読み込むバイト数
|
529
|
+
* @return [Rixmap::Image] 読み込まれた画像
|
530
|
+
* @see #decode
|
531
|
+
*/
|
532
|
+
static VALUE BaseImageIO_read(int argc, VALUE* argv, VALUE self) {
|
533
|
+
VALUE argIO, argOptions;
|
534
|
+
rb_scan_args(argc, argv, "11", &argIO, &argOptions);
|
535
|
+
|
536
|
+
// 型チェック…?
|
537
|
+
VALUE objIO = argIO;
|
538
|
+
VALUE objOptions = Qnil;
|
539
|
+
if (RB_TYPE_P(argOptions, T_HASH)) {
|
540
|
+
objOptions = argOptions;
|
541
|
+
} else {
|
542
|
+
objOptions = rb_hash_new();
|
543
|
+
}
|
544
|
+
|
545
|
+
// オプションパラメータ
|
546
|
+
VALUE optLength = rb_hash_lookup(objOptions, ID2SYM("length"));
|
547
|
+
|
548
|
+
// 読み込む
|
549
|
+
VALUE objBytes = rb_funcall(objIO, rb_intern("read"), 1, optLength);
|
550
|
+
|
551
|
+
// 復元
|
552
|
+
VALUE objImage = rb_funcall(self, rb_intern("decode"), 2, objBytes, objOptions);
|
553
|
+
|
554
|
+
// 戻る
|
555
|
+
return objImage;
|
556
|
+
}
|
557
|
+
/* }}} */
|
558
|
+
|
559
|
+
//----------------------------------------------------------------------------//
|
560
|
+
// 内部API実装
|
561
|
+
//----------------------------------------------------------------------------//
|
562
|
+
/**
|
563
|
+
* 初期化処理
|
564
|
+
*/
|
565
|
+
void RixmapIO_Init() {
|
566
|
+
/**
|
567
|
+
* Document-module: Rixmap::ImageIO
|
568
|
+
*
|
569
|
+
* IO系クラス定義モジュール.
|
570
|
+
*/
|
571
|
+
mRixmapImageIO = rb_define_module_under(mRixmap, "ImageIO");
|
572
|
+
rb_define_singleton_method(mRixmapImageIO, "register", RUBY_METHOD_FUNC(ImageIO_Register), -1);
|
573
|
+
rb_define_singleton_method(mRixmapImageIO, "new", RUBY_METHOD_FUNC(ImageIO_New), -1);
|
574
|
+
rb_define_singleton_method(mRixmapImageIO, "get", RUBY_METHOD_FUNC(ImageIO_Get), 1);
|
575
|
+
rb_define_singleton_method(mRixmapImageIO, "find", RUBY_METHOD_FUNC(ImageIO_Find), 1);
|
576
|
+
rb_define_singleton_method(mRixmapImageIO, "findall", RUBY_METHOD_FUNC(ImageIO_FindAll), 1);
|
577
|
+
rb_iv_set(mRixmapImageIO, "@registry", rb_hash_new());
|
578
|
+
|
579
|
+
/**
|
580
|
+
* Document-class: Rixmap::ImageIO::ImageIOInfo
|
581
|
+
*
|
582
|
+
* IOクラス実装情報クラス.
|
583
|
+
* {Rixmap::ImageIO}モジュールの内部で使用しています.
|
584
|
+
*/
|
585
|
+
cRixmapImageIOInfo = rb_define_class_under(mRixmapImageIO, "ImageIOInfo", rb_cObject);
|
586
|
+
rb_define_private_method(cRixmapImageIOInfo, "initialize", RUBY_METHOD_FUNC(ImageIOInfo_initialize), -1);
|
587
|
+
rb_define_attr(cRixmapImageIOInfo, "imageio", 1, 1);
|
588
|
+
rb_define_attr(cRixmapImageIOInfo, "extensions", 1, 1);
|
589
|
+
rb_define_method(cRixmapImageIOInfo, "match?", RUBY_METHOD_FUNC(ImageIOInfo_isMatchFileName), 1);
|
590
|
+
|
591
|
+
/**
|
592
|
+
* Document-class: Rixmap::ImageIO::BaseImageIO
|
593
|
+
*
|
594
|
+
* 画像入出力処理のベースクラス.
|
595
|
+
*/
|
596
|
+
cRixmapBaseImageIO = rb_define_class_under(mRixmapImageIO, "BaseImageIO", rb_cObject);
|
597
|
+
rb_define_singleton_method(cRixmapBaseImageIO, "readable?", RUBY_METHOD_FUNC(BaseImageIO_IsReadableStatic), 1);
|
598
|
+
rb_define_singleton_method(cRixmapBaseImageIO, "writable?", RUBY_METHOD_FUNC(BaseImageIO_IsWritableStatic), 1);
|
599
|
+
rb_define_private_method(cRixmapBaseImageIO, "initialize", RUBY_METHOD_FUNC(BaseImageIO_initialize), -1);
|
600
|
+
rb_define_method(cRixmapBaseImageIO, "readable?", RUBY_METHOD_FUNC(BaseImageIO_isReadable), 1);
|
601
|
+
rb_define_method(cRixmapBaseImageIO, "writable?", RUBY_METHOD_FUNC(BaseImageIO_isWritable), 1);
|
602
|
+
rb_define_method(cRixmapBaseImageIO, "encode", RUBY_METHOD_FUNC(BaseImageIO_encode), -1);
|
603
|
+
rb_define_method(cRixmapBaseImageIO, "decode", RUBY_METHOD_FUNC(BaseImageIO_decode), -1);
|
604
|
+
rb_define_method(cRixmapBaseImageIO, "save", RUBY_METHOD_FUNC(BaseImageIO_save), -1);
|
605
|
+
rb_define_method(cRixmapBaseImageIO, "write", RUBY_METHOD_FUNC(BaseImageIO_write), -1);
|
606
|
+
rb_define_method(cRixmapBaseImageIO, "open", RUBY_METHOD_FUNC(BaseImageIO_open), -1);
|
607
|
+
rb_define_method(cRixmapBaseImageIO, "read", RUBY_METHOD_FUNC(BaseImageIO_read), -1);
|
608
|
+
|
609
|
+
/**
|
610
|
+
* Document-module: Rixmap::Format
|
611
|
+
*
|
612
|
+
* 各種フォーマット実装モジュール.
|
613
|
+
*/
|
614
|
+
mRixmapFormat = rb_define_module_under(mRixmap, "Format");
|
615
|
+
|
616
|
+
// グローバル変数を保存
|
617
|
+
rb_global_variable(&mRixmapImageIO);
|
618
|
+
rb_global_variable(&cRixmapImageIOInfo);
|
619
|
+
rb_global_variable(&cRixmapBaseImageIO);
|
620
|
+
rb_global_variable(&mRixmapFormat);
|
621
|
+
}
|
622
|
+
|
623
|
+
/**
|
624
|
+
* 指定したフォーマット名でImageIOへklassを登録します.
|
625
|
+
*
|
626
|
+
* @param [const char*] name フォーマット名
|
627
|
+
* @param [VALUE] klass フォーマット実装クラスオブジェクト
|
628
|
+
* @param [int] num 拡張子の実装数
|
629
|
+
* @param [const char*...] ... 拡張子リスト
|
630
|
+
*/
|
631
|
+
void RixmapIO_RegisterImageIO(const char* name, volatile VALUE klass, int num, ...) {
|
632
|
+
volatile VALUE objName = rb_str_new_cstr(name);
|
633
|
+
volatile VALUE aryExts = rb_ary_new();
|
634
|
+
|
635
|
+
// 拡張子リストを処理.
|
636
|
+
// 可変長引数から取得する.
|
637
|
+
va_list vargs;
|
638
|
+
va_start(vargs, num);
|
639
|
+
for (int i = 0; i < num; i++) {
|
640
|
+
const char* ext = va_arg(vargs, const char*);
|
641
|
+
rb_ary_push(aryExts, rb_str_new_cstr(ext));
|
642
|
+
}
|
643
|
+
va_end(vargs);
|
644
|
+
|
645
|
+
// ImageIO.registerを呼び出す
|
646
|
+
rb_funcall(mRixmapImageIO, rb_intern("register"), 3, objName, klass, aryExts);
|
647
|
+
}
|
648
|
+
|
649
|
+
|
650
|
+
//============================================================================//
|
651
|
+
// $Id: rixmapio.cxx,v 66c8edefa6c0 2014/04/20 14:22:54 chikuchikugonzalez $
|
652
|
+
// vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
|
data/src/rixmapio.hxx
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
// -*- coding: utf-8 -*-
|
2
|
+
/**
|
3
|
+
* Rixmapの入出力関係ヘッダ
|
4
|
+
*/
|
5
|
+
#pragma once
|
6
|
+
#include "rixmapcore.hxx"
|
7
|
+
|
8
|
+
//----------------------------------------------------------------------------//
|
9
|
+
// グローバル変数宣言
|
10
|
+
//----------------------------------------------------------------------------//
|
11
|
+
extern VALUE mRixmapImageIO;
|
12
|
+
extern VALUE cRixmapImageIOInfo;
|
13
|
+
extern VALUE cRixmapBaseImageIO;
|
14
|
+
extern VALUE mRixmapFormat;
|
15
|
+
|
16
|
+
//----------------------------------------------------------------------------//
|
17
|
+
// コアAPI関数プロトタイプ
|
18
|
+
//----------------------------------------------------------------------------//
|
19
|
+
extern void RixmapIO_Init();
|
20
|
+
extern void RixmapIO_RegisterImageIO(const char* name, volatile VALUE klass, int num, ...);
|
21
|
+
|
22
|
+
|
23
|
+
//============================================================================//
|
24
|
+
// $Id: rixmapio.hxx,v bb1f88e64282 2014/04/20 13:54:13 chikuchikugonzalez $
|
25
|
+
// vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
|