rixmap 0.2.1 → 0.3.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 +4 -4
- data/Rakefile +3 -1
- data/lib/rixmap/format/bmp.rb +4 -1
- data/lib/rixmap/format/png/chunk.rb +178 -7
- data/lib/rixmap/format/png/imageio.rb +75 -7
- data/lib/rixmap/version.rb +3 -3
- data/spec/palette_spec.rb +19 -1
- data/src/rixmap/channel.hxx +106 -1
- data/src/rixmap/color.hxx +84 -14
- data/src/rixmap/image.hxx +205 -25
- data/src/rixmap/interpolator.hxx +29 -12
- data/src/rixmapcore.cxx +275 -210
- data/src/rixmapdeformation.cxx +4 -82
- data/src/rixmaphelper.cxx +501 -0
- data/src/rixmaphelper.hxx +82 -0
- data/src/rixmappool.cxx +65 -0
- data/src/rixmappool.hxx +69 -0
- data/test/test_png.rb +18 -5
- metadata +8 -3
- data/src/rixmap/helper.hxx +0 -347
@@ -0,0 +1,82 @@
|
|
1
|
+
// -*- coding: utf-8 -*-
|
2
|
+
/**
|
3
|
+
* Rixmap実装用ヘルパー関数.
|
4
|
+
*/
|
5
|
+
#pragma once
|
6
|
+
#include "rixmap.hxx"
|
7
|
+
#include "rixmapcore.hxx"
|
8
|
+
#include "rixmappool.hxx"
|
9
|
+
|
10
|
+
namespace Rixmap {
|
11
|
+
|
12
|
+
/**
|
13
|
+
* ヘルパー関数名前空間
|
14
|
+
*/
|
15
|
+
namespace Helper {
|
16
|
+
/**
|
17
|
+
* パレットデータを更新します.
|
18
|
+
*
|
19
|
+
* @param [Rixmap::PaletteData*] palette
|
20
|
+
* @param [long] offset
|
21
|
+
* @param [VALUE] object
|
22
|
+
* @return [bool] 更新できた場合はtrue. 更新できなかった場合はfalse
|
23
|
+
*/
|
24
|
+
bool UpdatePalette(Rixmap::PaletteData* palette, long offset, VALUE object);
|
25
|
+
|
26
|
+
/**
|
27
|
+
* 'RGBA'などのレイアウトデータをRixmap::ChannelArrayに格納します.
|
28
|
+
* レイアウトデータがnilの場合はfalseを返します.
|
29
|
+
*/
|
30
|
+
bool LayoutChannels(VALUE layout, Rixmap::ChannelArray& channels);
|
31
|
+
|
32
|
+
/**
|
33
|
+
* ピクセルを取得します.
|
34
|
+
*/
|
35
|
+
VALUE GetPixel(Rixmap::ImageData* image, int32_t xpos, int32_t ypos);
|
36
|
+
|
37
|
+
/**
|
38
|
+
* ピクセルを更新します.
|
39
|
+
*/
|
40
|
+
void UpdatePixel(Rixmap::ImageData* image, int32_t xpos, int32_t ypos, VALUE pixel);
|
41
|
+
|
42
|
+
/**
|
43
|
+
* スキャンラインから指定したチャンネルのバンドデータを取得します.
|
44
|
+
*/
|
45
|
+
VALUE GetBand(Rixmap::ImageLineData* line, Rixmap::Channel channel);
|
46
|
+
|
47
|
+
/**
|
48
|
+
* スキャンライン内の指定チャンネルデータを更新します.
|
49
|
+
*/
|
50
|
+
bool UpdateBand(Rixmap::ImageLineData* line, Rixmap::Channel channel, VALUE argBand);
|
51
|
+
|
52
|
+
/**
|
53
|
+
* 画像形式変換処理クラスオブジェクトを取得します.
|
54
|
+
*/
|
55
|
+
Rixmap::Converter* GetImageConverter(const Rixmap::Mode input, const Rixmap::Mode output);
|
56
|
+
|
57
|
+
/**
|
58
|
+
* 画像形式と背景色オブジェクトからRubyオブジェクトを取得します.
|
59
|
+
*/
|
60
|
+
VALUE GetBackgroundValue(const Rixmap::ImageData& image, const Rixmap::BackgroundColor& bg);
|
61
|
+
|
62
|
+
/**
|
63
|
+
* 背景色データからRixmap::Colorオブジェクトを作成します.
|
64
|
+
*/
|
65
|
+
VALUE GetBackgroundAsColor(const Rixmap::ImageData& image, const Rixmap::BackgroundColor& bg);
|
66
|
+
|
67
|
+
/**
|
68
|
+
* 画像形式に応じて適切に変換しつつ、背景色を設定します.
|
69
|
+
*/
|
70
|
+
bool SetBackgroundValue(const Rixmap::ImageData& image, Rixmap::BackgroundColor& bg, VALUE value);
|
71
|
+
|
72
|
+
/**
|
73
|
+
* 画像の基本情報以外の情報をHashで取得します.
|
74
|
+
*/
|
75
|
+
VALUE GetImageMetadata(const Rixmap::ImageData& image);
|
76
|
+
} /* Rixmap::Helper */
|
77
|
+
} /* Rixmap */
|
78
|
+
|
79
|
+
|
80
|
+
//============================================================================//
|
81
|
+
// $Id: rixmaphelper.hxx,v 5590f3c64493 2014/05/31 14:59:34 chikuchikugonzalez $
|
82
|
+
// vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
|
data/src/rixmappool.cxx
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
// -*- coding: utf-8 -*-
|
2
|
+
/**
|
3
|
+
* Rixmapオブジェクトプール実装
|
4
|
+
*/
|
5
|
+
#include "rixmappool.hxx"
|
6
|
+
#include "rixmapcore.hxx"
|
7
|
+
|
8
|
+
/* RixmapModePool {{{ */
|
9
|
+
std::map<Rixmap::Mode, VALUE> RixmapModePool::_pool;
|
10
|
+
|
11
|
+
VALUE RixmapModePool::Get(Rixmap::Mode mode) {
|
12
|
+
auto found = _pool.find(mode);
|
13
|
+
if (found != _pool.end()) {
|
14
|
+
return found->second;
|
15
|
+
} else {
|
16
|
+
volatile VALUE instance = rb_obj_alloc(cRixmapMode);
|
17
|
+
Rixmap::ModeData* data = rixmap_unwrap<Rixmap::ModeData>(instance);
|
18
|
+
data->setMode(mode);
|
19
|
+
|
20
|
+
rb_gc_register_mark_object(instance);
|
21
|
+
_pool[mode] = instance;
|
22
|
+
|
23
|
+
return instance;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
void RixmapModePool::Remove(Rixmap::Mode mode) {
|
28
|
+
auto found = _pool.find(mode);
|
29
|
+
if (found != _pool.end()) {
|
30
|
+
_pool.erase(found);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
/* }}} */
|
34
|
+
|
35
|
+
/* RixmapColorPool {{{ */
|
36
|
+
std::map<uint32_t, VALUE> RixmapColorPool::_pool;
|
37
|
+
|
38
|
+
VALUE RixmapColorPool::Get(const Rixmap::Color& color) {
|
39
|
+
uint32_t value = color.getValue();
|
40
|
+
auto found = _pool.find(value);
|
41
|
+
if (found != _pool.end()) {
|
42
|
+
return found->second;
|
43
|
+
} else {
|
44
|
+
volatile VALUE instance = rb_obj_alloc(cRixmapColor);
|
45
|
+
Rixmap::ColorData* data = rixmap_unwrap<Rixmap::ColorData>(instance);
|
46
|
+
*data = color;
|
47
|
+
rb_gc_register_mark_object(instance);
|
48
|
+
_pool[value] = instance;
|
49
|
+
return instance;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
void RixmapColorPool::Remove(const Rixmap::Color& color) {
|
54
|
+
uint32_t value = color.getValue();
|
55
|
+
auto found = _pool.find(value);
|
56
|
+
if (found != _pool.end()) {
|
57
|
+
_pool.erase(found);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
/* }}} */
|
61
|
+
|
62
|
+
|
63
|
+
//============================================================================//
|
64
|
+
// $Id: rixmappool.cxx,v 5590f3c64493 2014/05/31 14:59:34 chikuchikugonzalez $
|
65
|
+
// vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
|
data/src/rixmappool.hxx
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
// -*- coding: utf-8 -*-
|
2
|
+
/**
|
3
|
+
* Rixmapオブジェクトプールヘッダ
|
4
|
+
*/
|
5
|
+
#pragma once
|
6
|
+
#include "rixmap.hxx"
|
7
|
+
|
8
|
+
/**
|
9
|
+
* 画像形式オブジェクトプール定義
|
10
|
+
*/
|
11
|
+
class RixmapModePool {
|
12
|
+
private: // 非公開クラスメンバ
|
13
|
+
static std::map<Rixmap::Mode, VALUE> _pool;
|
14
|
+
|
15
|
+
public: // 公開クラスメンバ関数
|
16
|
+
/**
|
17
|
+
* 画像形式定数からオブジェクトを取得します.
|
18
|
+
* 必要があれば作成します.
|
19
|
+
*/
|
20
|
+
static VALUE Get(Rixmap::Mode mode);
|
21
|
+
|
22
|
+
/**
|
23
|
+
* 画像形式定数にマッチしたオブジェクトをプールから削除します.
|
24
|
+
*/
|
25
|
+
static void Remove(Rixmap::Mode mode);
|
26
|
+
|
27
|
+
|
28
|
+
//---- 以下はインスタンスを作らせないための処置 ----//
|
29
|
+
|
30
|
+
private: // 非公開コンストラクタ
|
31
|
+
RixmapModePool() {}
|
32
|
+
|
33
|
+
public: // 仮想デストラクタ
|
34
|
+
virtual ~RixmapModePool() = 0;
|
35
|
+
};
|
36
|
+
|
37
|
+
/**
|
38
|
+
* カラーオブジェクトプール定義
|
39
|
+
*/
|
40
|
+
class RixmapColorPool {
|
41
|
+
private: // 非公開クラスメンバ
|
42
|
+
static std::map<uint32_t, VALUE> _pool;
|
43
|
+
|
44
|
+
public: // 公開クラスメンバ関数
|
45
|
+
/**
|
46
|
+
* カラークラスインスタンスからオブジェクトを取得します.
|
47
|
+
* 必要があればオブジェクトを作成します.
|
48
|
+
*/
|
49
|
+
static VALUE Get(const Rixmap::Color& color);
|
50
|
+
|
51
|
+
/**
|
52
|
+
* カラークラスインスタンスにマッチしたオブジェクトを削除します.
|
53
|
+
*/
|
54
|
+
static void Remove(const Rixmap::Color& color);
|
55
|
+
|
56
|
+
|
57
|
+
//---- 以下はインスタンスを作らせないための処置 ----//
|
58
|
+
|
59
|
+
private: // 非公開コンストラクタ
|
60
|
+
RixmapColorPool() {}
|
61
|
+
|
62
|
+
public: // 仮想デストラクタ
|
63
|
+
virtual ~RixmapColorPool() = 0;
|
64
|
+
};
|
65
|
+
|
66
|
+
|
67
|
+
//============================================================================//
|
68
|
+
// $Id: rixmappool.hxx,v 5590f3c64493 2014/05/31 14:59:34 chikuchikugonzalez $
|
69
|
+
// vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
|
data/test/test_png.rb
CHANGED
@@ -27,6 +27,7 @@ class TestPNGIndexedImage < MiniTest::Unit::TestCase
|
|
27
27
|
n += 1
|
28
28
|
end
|
29
29
|
end
|
30
|
+
@image.transparent = 0
|
30
31
|
end
|
31
32
|
|
32
33
|
# 通常IO
|
@@ -94,6 +95,7 @@ class TestPNGRGBImage < MiniTest::Unit::TestCase
|
|
94
95
|
@image[i, j] = [r, g, b]
|
95
96
|
end
|
96
97
|
end
|
98
|
+
@image.transparent = [255, 0, 0]
|
97
99
|
end
|
98
100
|
|
99
101
|
# 通常IO
|
@@ -107,24 +109,35 @@ end
|
|
107
109
|
|
108
110
|
class TestPNGRGBAImage < MiniTest::Unit::TestCase
|
109
111
|
def setup()
|
110
|
-
@
|
112
|
+
@image1 = Rixmap::Image.new(Rixmap::RGBA, 256, 256)
|
111
113
|
256.times do |i|
|
112
114
|
256.times do |j|
|
113
115
|
r = (255 - (Math.sqrt((255 - i) ** 2 + j ** 2)))
|
114
116
|
g = (255 - (Math.sqrt((255 - i) ** 2 + (255 - j) ** 2)))
|
115
117
|
b = (255 - (Math.sqrt(i ** 2 + j ** 2)))
|
116
118
|
a = (255 - (Math.sqrt(i ** 2 + (255 - j) ** 2)))
|
117
|
-
@
|
119
|
+
@image1[i, j] = [r, g, b, a]
|
118
120
|
end
|
119
121
|
end
|
122
|
+
|
123
|
+
@image2 = @image1.clone
|
124
|
+
@image2.background = [255, 0, 255]
|
120
125
|
end
|
121
126
|
|
122
127
|
# 通常IO
|
123
128
|
def test_normal()
|
124
129
|
iio = Rixmap::ImageIO.new(:PNG)
|
125
|
-
iio.save('rgba.png', @
|
130
|
+
iio.save('rgba.png', @image1)
|
126
131
|
img = iio.open('rgba.png')
|
127
|
-
assert_equal(@
|
132
|
+
assert_equal(@image1, img)
|
133
|
+
end
|
134
|
+
|
135
|
+
# 背景色付
|
136
|
+
def test_bgcolor()
|
137
|
+
iio = Rixmap::ImageIO.new(:PNG)
|
138
|
+
iio.save('rgba2.png', @image2)
|
139
|
+
img = iio.open('rgba2.png')
|
140
|
+
assert_equal(@image2, img)
|
128
141
|
end
|
129
142
|
|
130
143
|
# TODO 圧縮版を作る
|
@@ -132,5 +145,5 @@ end
|
|
132
145
|
|
133
146
|
|
134
147
|
#==============================================================================#
|
135
|
-
# $Id: test_png.rb,v
|
148
|
+
# $Id: test_png.rb,v a60a21c75463 2014/05/30 17:04:13 chikuchikugonzalez $
|
136
149
|
# vim: set sts=2 ts=2 sw=2 expandtab:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rixmap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- chikuchikugonzalez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yard
|
@@ -67,26 +67,31 @@ extensions:
|
|
67
67
|
extra_rdoc_files:
|
68
68
|
- src/rixmapcore.cxx
|
69
69
|
- src/rixmapdeformation.cxx
|
70
|
+
- src/rixmaphelper.cxx
|
70
71
|
- src/rixmapio.cxx
|
71
72
|
- src/rixmapmain.cxx
|
73
|
+
- src/rixmappool.cxx
|
72
74
|
- README.markdown
|
73
75
|
- LICENSE.txt
|
74
76
|
files:
|
75
77
|
- src/rixmapcore.cxx
|
76
78
|
- src/rixmapdeformation.cxx
|
79
|
+
- src/rixmaphelper.cxx
|
77
80
|
- src/rixmapio.cxx
|
78
81
|
- src/rixmapmain.cxx
|
82
|
+
- src/rixmappool.cxx
|
79
83
|
- src/rixmap.hxx
|
80
84
|
- src/rixmapcore.hxx
|
81
85
|
- src/rixmapdeformation.hxx
|
86
|
+
- src/rixmaphelper.hxx
|
82
87
|
- src/rixmapio.hxx
|
88
|
+
- src/rixmappool.hxx
|
83
89
|
- src/rixmap/binary.hxx
|
84
90
|
- src/rixmap/channel.hxx
|
85
91
|
- src/rixmap/color.hxx
|
86
92
|
- src/rixmap/common.hxx
|
87
93
|
- src/rixmap/converter.hxx
|
88
94
|
- src/rixmap/deformer.hxx
|
89
|
-
- src/rixmap/helper.hxx
|
90
95
|
- src/rixmap/image.hxx
|
91
96
|
- src/rixmap/interpolator.hxx
|
92
97
|
- src/rixmap/mode.hxx
|
data/src/rixmap/helper.hxx
DELETED
@@ -1,347 +0,0 @@
|
|
1
|
-
// -*- coding: utf-8 -*-
|
2
|
-
/**
|
3
|
-
* Rixmap実装時のヘルパー関数定義.
|
4
|
-
* 一応グローバルに使えるようなものを定義しておきます.
|
5
|
-
*
|
6
|
-
* ※ API系列とはまた別
|
7
|
-
*/
|
8
|
-
#pragma once
|
9
|
-
#include "common.hxx"
|
10
|
-
#include "color.hxx"
|
11
|
-
#include "palette.hxx"
|
12
|
-
#include "image.hxx"
|
13
|
-
#include "converter.hxx"
|
14
|
-
#include "interpolator.hxx"
|
15
|
-
|
16
|
-
namespace Rixmap {
|
17
|
-
|
18
|
-
/**
|
19
|
-
* ヘルパー関数名前空間
|
20
|
-
*/
|
21
|
-
namespace Helper {
|
22
|
-
/**
|
23
|
-
* パレットデータを更新します.
|
24
|
-
*
|
25
|
-
* @param [Rixmap::PaletteData*] palette
|
26
|
-
* @param [long] offset
|
27
|
-
* @param [VALUE] object
|
28
|
-
* @return [bool] 更新できた場合はtrue. 更新できなかった場合はfalse
|
29
|
-
*/
|
30
|
-
static bool UpdatePalette(Rixmap::PaletteData* palette, long offset, VALUE object) {
|
31
|
-
Rixmap::Color color(0, 0, 0, 255);
|
32
|
-
|
33
|
-
// カラーオブジェクトを解析
|
34
|
-
if (RB_TYPE_P(object, T_STRING)) {
|
35
|
-
// Color.newを使ってオブジェクトを構築
|
36
|
-
VALUE objColor = rb_funcall(cRixmapColor, rb_intern("new"), 1, object);
|
37
|
-
Rixmap::ColorData* data = rixmap_unwrap<Rixmap::ColorData>(objColor);
|
38
|
-
color = data->getColor();
|
39
|
-
} else if (RTEST(rb_obj_is_kind_of(object, cRixmapColor))) {
|
40
|
-
// Rixmap::Colorそのもの
|
41
|
-
Rixmap::ColorData* data = rixmap_unwrap<Rixmap::ColorData>(object);
|
42
|
-
color = data->getColor();
|
43
|
-
} else {
|
44
|
-
// 配列から
|
45
|
-
VALUE aryColor = rb_Array(object);
|
46
|
-
long arylen = RARRAY_LEN(aryColor);
|
47
|
-
VALUE* aryptr = RARRAY_PTR(aryColor);
|
48
|
-
VALUE objColor = rb_funcall2(cRixmapColor, rb_intern("new"), arylen, aryptr);
|
49
|
-
Rixmap::ColorData* data = rixmap_unwrap<Rixmap::ColorData>(objColor);
|
50
|
-
color = data->getColor();
|
51
|
-
}
|
52
|
-
|
53
|
-
// 範囲チェック && 更新
|
54
|
-
// FIXME unsignedからsignedへの変換になってる
|
55
|
-
//long length = static_cast<long>(palette->getSize());
|
56
|
-
try {
|
57
|
-
palette->set(offset, color);
|
58
|
-
return true;
|
59
|
-
} catch (const std::out_of_range& e) {
|
60
|
-
// ( ´゚д゚`)エー
|
61
|
-
rb_warning(e.what());
|
62
|
-
return false;
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
|
-
/**
|
67
|
-
* ピクセルを取得します.
|
68
|
-
*/
|
69
|
-
static VALUE GetPixel(Rixmap::ImageData* image, int32_t xpos, int32_t ypos) {
|
70
|
-
// TODO imageがNULLの時対策
|
71
|
-
|
72
|
-
// 範囲チェック
|
73
|
-
if (image->isOutside(xpos, ypos)) {
|
74
|
-
// 範囲外はnil
|
75
|
-
return Qnil;
|
76
|
-
}
|
77
|
-
|
78
|
-
const Rixmap::ChannelArray& channels = image->getModeInfo().getChannels();
|
79
|
-
size_t nchannel = channels.size();
|
80
|
-
|
81
|
-
if (nchannel == 0) {
|
82
|
-
// ない場合はnil
|
83
|
-
return Qnil;
|
84
|
-
} else if (nchannel == 1) {
|
85
|
-
// 一つの場合は整数値で返す
|
86
|
-
Rixmap::Channel channel = channels.at(0);
|
87
|
-
uint8_t value = image->get(channel, xpos, ypos);
|
88
|
-
return INT2FIX(value);
|
89
|
-
} else {
|
90
|
-
// それ以外は配列で返す
|
91
|
-
VALUE pixel = rb_ary_new2(nchannel);
|
92
|
-
for (size_t i = 0; i < nchannel; i++) {
|
93
|
-
Rixmap::Channel channel = channels.at(i);
|
94
|
-
uint8_t value = image->get(channel, xpos, ypos);
|
95
|
-
rb_ary_store(pixel, i, INT2FIX(value));
|
96
|
-
}
|
97
|
-
return pixel;
|
98
|
-
}
|
99
|
-
}
|
100
|
-
|
101
|
-
/**
|
102
|
-
* ピクセルを更新します.
|
103
|
-
*/
|
104
|
-
static void UpdatePixel(Rixmap::ImageData* image, int32_t xpos, int32_t ypos, VALUE pixel) {
|
105
|
-
// TODO imageがNULLの時対策
|
106
|
-
const Rixmap::ModeInfo& mode = image->getModeInfo();
|
107
|
-
|
108
|
-
// 範囲チェック
|
109
|
-
if (image->isInside(xpos, ypos)) {
|
110
|
-
if (RB_TYPE_P(pixel, T_ARRAY)) {
|
111
|
-
// 配列
|
112
|
-
const Rixmap::ChannelArray& channels = mode.getChannels();
|
113
|
-
for (size_t i = 0; i < channels.size(); i++) {
|
114
|
-
Rixmap::Channel channel = channels.at(i);
|
115
|
-
VALUE objItem = rb_ary_entry(pixel, i);
|
116
|
-
if (!NIL_P(objItem)) {
|
117
|
-
int value = ROUND2BYTE(NUM2INT(rb_Integer(objItem)));
|
118
|
-
image->set(channel, xpos, ypos, static_cast<uint8_t>(value));
|
119
|
-
}
|
120
|
-
}
|
121
|
-
} else if (RB_TYPE_P(pixel, T_FIXNUM) || RB_TYPE_P(pixel, T_FLOAT)) {
|
122
|
-
//} else if (RB_TYPE_P(pixel, T_FIXNUM) /* || RB_TYPE_P(pixel, T_BIGNUM) */) {
|
123
|
-
// 数値
|
124
|
-
int value = ROUND2BYTE(NUM2INT(rb_Integer(pixel)));
|
125
|
-
const Rixmap::ChannelArray& channels = mode.getChannels();
|
126
|
-
for (auto it = channels.begin(); it != channels.end(); it++) {
|
127
|
-
image->set(*it, xpos, ypos, static_cast<uint8_t>(value));
|
128
|
-
}
|
129
|
-
} else if (RTEST(rb_obj_is_kind_of(pixel, cRixmapColor))) {
|
130
|
-
// カラーオブジェクト
|
131
|
-
Rixmap::ColorData* col = rixmap_unwrap<Rixmap::ColorData>(pixel);
|
132
|
-
switch (mode.getType()) {
|
133
|
-
case Rixmap::MODE_TYPE_INDEXED:
|
134
|
-
{
|
135
|
-
const Rixmap::PaletteData* pal = image->getPaletteData();
|
136
|
-
size_t off = 0;
|
137
|
-
if (pal == NULL) {
|
138
|
-
off = 0;
|
139
|
-
} else {
|
140
|
-
off = pal->closest(col->getColor());
|
141
|
-
}
|
142
|
-
image->set(Rixmap::Channel::PALETTE, xpos, ypos, static_cast<uint8_t>(off));
|
143
|
-
}
|
144
|
-
break;
|
145
|
-
|
146
|
-
case Rixmap::MODE_TYPE_GRAYSCALE:
|
147
|
-
image->set(Rixmap::Channel::LUMINANCE, xpos, ypos, col->getLuminance());
|
148
|
-
break;
|
149
|
-
|
150
|
-
case Rixmap::MODE_TYPE_RGB:
|
151
|
-
image->set(Rixmap::Channel::RED, xpos, ypos, col->getRed());
|
152
|
-
image->set(Rixmap::Channel::GREEN, xpos, ypos, col->getGreen());
|
153
|
-
image->set(Rixmap::Channel::BLUE, xpos, ypos, col->getBlue());
|
154
|
-
break;
|
155
|
-
|
156
|
-
default:
|
157
|
-
// DO NOTHING
|
158
|
-
break;
|
159
|
-
}
|
160
|
-
|
161
|
-
if (mode.hasAlpha()) {
|
162
|
-
image->set(Rixmap::Channel::ALPHA, xpos, ypos, col->getAlpha());
|
163
|
-
}
|
164
|
-
} else {
|
165
|
-
// 非対応(`・ω・´)
|
166
|
-
rb_raise(rb_eArgError, "unexpected pixel data type: %s", rb_obj_classname(pixel));
|
167
|
-
}
|
168
|
-
} else {
|
169
|
-
// 範囲外は何もしないお
|
170
|
-
rb_warning("point (%d, %d) is outside of image", xpos, ypos);
|
171
|
-
}
|
172
|
-
}
|
173
|
-
|
174
|
-
/**
|
175
|
-
* スキャンラインから指定したチャンネルのバンドデータを取得します.
|
176
|
-
*/
|
177
|
-
static VALUE GetBand(Rixmap::ImageLineData* line, Rixmap::Channel channel) {
|
178
|
-
if (line->isValid()) {
|
179
|
-
Rixmap::ImageData* parent = line->getImageData();
|
180
|
-
const Rixmap::ModeInfo& mode = parent->getModeInfo();
|
181
|
-
if (mode.has(channel)) {
|
182
|
-
int32_t length = line->getLength();
|
183
|
-
int32_t lineno = line->getLineNumber();
|
184
|
-
uint8_t* band = parent->get(channel, lineno);
|
185
|
-
VALUE bytes = rb_ary_new2(length);
|
186
|
-
for (int32_t i = 0; i < length; i++) {
|
187
|
-
rb_ary_store(bytes, i, INT2FIX(band[i]));
|
188
|
-
}
|
189
|
-
return bytes;
|
190
|
-
} else {
|
191
|
-
return Qnil;
|
192
|
-
}
|
193
|
-
} else {
|
194
|
-
return Qnil;
|
195
|
-
}
|
196
|
-
}
|
197
|
-
|
198
|
-
/**
|
199
|
-
* スキャンライン内の指定チャンネルデータを更新します.
|
200
|
-
*/
|
201
|
-
static bool UpdateBand(Rixmap::ImageLineData* line, Rixmap::Channel channel, VALUE argBand) {
|
202
|
-
if (line->isValid()) {
|
203
|
-
Rixmap::ImageData* parent = line->getImageData();
|
204
|
-
const Rixmap::ModeInfo& mode = parent->getModeInfo();
|
205
|
-
int32_t lineLength = line->getLength();
|
206
|
-
int32_t lineno = line->getLineNumber();
|
207
|
-
if (mode.has(channel)) {
|
208
|
-
// 型ごとにチェックして処理
|
209
|
-
if (RB_TYPE_P(argBand, T_ARRAY)) {
|
210
|
-
// 配列の場合はいったん全要素を調べる
|
211
|
-
long aryLength = RARRAY_LEN(argBand);
|
212
|
-
int32_t length = (aryLength < lineLength) ? aryLength : lineLength;
|
213
|
-
for (int32_t i = 0; i < length; i++) {
|
214
|
-
VALUE item = rb_ary_entry(argBand, i);
|
215
|
-
if (!RB_TYPE_P(item, T_FIXNUM)) {
|
216
|
-
rb_raise(rb_eArgError, "unexpected band data type in line data: %s", rb_obj_classname(item));
|
217
|
-
}
|
218
|
-
}
|
219
|
-
|
220
|
-
// OK
|
221
|
-
for (int32_t i = 0; i < length; i++) {
|
222
|
-
VALUE item = rb_ary_entry(argBand, i);
|
223
|
-
int byte = FIX2INT(item);
|
224
|
-
parent->set(channel, i, lineno, static_cast<uint8_t>(byte));
|
225
|
-
}
|
226
|
-
} else {
|
227
|
-
VALUE objBand = rb_String(argBand);
|
228
|
-
long nbyte = RSTRING_LEN(objBand);
|
229
|
-
char* bytes = StringValuePtr(objBand);
|
230
|
-
int32_t length = (nbyte < lineLength) ? nbyte : lineLength;
|
231
|
-
for (int32_t i = 0; i < length; i++) {
|
232
|
-
parent->set(channel, i, lineno, static_cast<uint8_t>(bytes[i]));
|
233
|
-
}
|
234
|
-
}
|
235
|
-
return true;
|
236
|
-
} else {
|
237
|
-
rb_warning("channel %c is not supported of this line", static_cast<char>(channel));
|
238
|
-
return false;
|
239
|
-
}
|
240
|
-
} else {
|
241
|
-
rb_warning("line is not valid");
|
242
|
-
return false;
|
243
|
-
}
|
244
|
-
}
|
245
|
-
|
246
|
-
/**
|
247
|
-
* 画像形式変換処理クラスオブジェクトを取得します.
|
248
|
-
*/
|
249
|
-
static Rixmap::Converter* GetImageConverter(const Rixmap::Mode input, const Rixmap::Mode output) {
|
250
|
-
// コンバータオブジェクト
|
251
|
-
// FIXME これ大丈夫かしら
|
252
|
-
static Rixmap::RGB2GrayScaleConverter rgb2gray;
|
253
|
-
static Rixmap::RGB2IndexConverter rgb2index;
|
254
|
-
static Rixmap::GrayScale2RGBConverter gray2rgb;
|
255
|
-
static Rixmap::GrayScale2IndexConverter gray2index;
|
256
|
-
static Rixmap::Index2RGBConverter index2rgb;
|
257
|
-
static Rixmap::Index2GrayScaleConverter index2gray;
|
258
|
-
|
259
|
-
// チャンネル増減
|
260
|
-
static Rixmap::RGB2RGBConverter rgb2rgb;
|
261
|
-
static Rixmap::GrayScale2RGBConverter gray2gray;
|
262
|
-
static Rixmap::Index2IndexConverter index2index;
|
263
|
-
|
264
|
-
// 判別処理
|
265
|
-
switch (input) {
|
266
|
-
case Rixmap::Mode::INDEXED:
|
267
|
-
switch (output) {
|
268
|
-
case Rixmap::Mode::INDEXED:
|
269
|
-
return &index2index;
|
270
|
-
|
271
|
-
case Rixmap::Mode::RGB:
|
272
|
-
case Rixmap::Mode::RGBA:
|
273
|
-
return &index2rgb;
|
274
|
-
|
275
|
-
case Rixmap::Mode::GRAYSCALE:
|
276
|
-
case Rixmap::Mode::GRAYALPHA:
|
277
|
-
return &index2gray;
|
278
|
-
|
279
|
-
default:
|
280
|
-
// 何もできない
|
281
|
-
// (警告抑制)
|
282
|
-
break;
|
283
|
-
}
|
284
|
-
break;
|
285
|
-
|
286
|
-
case Rixmap::Mode::RGB:
|
287
|
-
case Rixmap::Mode::RGBA:
|
288
|
-
switch (output) {
|
289
|
-
case Rixmap::Mode::RGB:
|
290
|
-
case Rixmap::Mode::RGBA:
|
291
|
-
return &rgb2rgb;
|
292
|
-
|
293
|
-
case Rixmap::Mode::GRAYSCALE:
|
294
|
-
case Rixmap::Mode::GRAYALPHA:
|
295
|
-
return &rgb2gray;
|
296
|
-
|
297
|
-
case Rixmap::Mode::INDEXED:
|
298
|
-
return &rgb2index;
|
299
|
-
|
300
|
-
default:
|
301
|
-
// 何もできない
|
302
|
-
// (警告抑制)
|
303
|
-
break;
|
304
|
-
}
|
305
|
-
break;
|
306
|
-
|
307
|
-
case Rixmap::Mode::GRAYSCALE:
|
308
|
-
case Rixmap::Mode::GRAYALPHA:
|
309
|
-
switch (output) {
|
310
|
-
case Rixmap::Mode::GRAYSCALE:
|
311
|
-
case Rixmap::Mode::GRAYALPHA:
|
312
|
-
return &gray2gray;
|
313
|
-
|
314
|
-
case Rixmap::Mode::RGB:
|
315
|
-
case Rixmap::Mode::RGBA:
|
316
|
-
return &gray2rgb;
|
317
|
-
|
318
|
-
case Rixmap::Mode::INDEXED:
|
319
|
-
return &gray2index;
|
320
|
-
|
321
|
-
default:
|
322
|
-
// 何もできない
|
323
|
-
// (警告抑制)
|
324
|
-
break;
|
325
|
-
}
|
326
|
-
break;
|
327
|
-
|
328
|
-
default:
|
329
|
-
// 何もできない
|
330
|
-
// (警告抑制)
|
331
|
-
break;
|
332
|
-
}
|
333
|
-
|
334
|
-
// 見つからない
|
335
|
-
std::ostringstream err;
|
336
|
-
err << "image converter between "
|
337
|
-
<< Rixmap::ModeInfo::GetModeName(input) << " and "
|
338
|
-
<< Rixmap::ModeInfo::GetModeName(output) << " is not implemented.";
|
339
|
-
throw std::invalid_argument(err.str());
|
340
|
-
}
|
341
|
-
} /* Rixmap::Helper */
|
342
|
-
} /* Rixmap */
|
343
|
-
|
344
|
-
|
345
|
-
//============================================================================//
|
346
|
-
// $Id: helper.hxx,v 753dbf70cab3 2014/05/16 16:13:38 chikuchikugonzalez $
|
347
|
-
// vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
|