rixmap 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 74d87da8ef09dd6ee5469552b8baa9a576cb4da1
4
- data.tar.gz: 24e2a21db530cdddf6a65e99feb1656e5b745eb0
3
+ metadata.gz: 68d917985e256067776c2d3b2f43bfda3444e235
4
+ data.tar.gz: ea89aa3ffc196d656afaebdb5dd499b4964c2db5
5
5
  SHA512:
6
- metadata.gz: 2f70fb1617536f2dbb4b010e46608b0c8189ac4277a212002d6a5fd8f2255534784262dc3d5427775f3f369a5e3b734af774abe62fe49df75f49d4fccd9333fa
7
- data.tar.gz: b893adf73dd5fd5e550da4f6526e56322c75935acadeace954b80c04848272c3086f81999896a0222893120ffe31564f6826312648b91dd09ca227b8de071d69
6
+ metadata.gz: 66ec63d02d19613561de02e14d9b3a9e669c0011008a58550344deb93e48daa5db8b8cea1c6b78554968a774233ab9302a0ff8636ac85e263826d19ef3a03524
7
+ data.tar.gz: 3da6eedc56945bdd2ffe1a343498f87c828171f34d9619366b99c063860ca0aa98aa9ae66f8758aa1614eeee4cbbcd60eb3b6a7d2a1887ed5916dc43e501218c
data/Rakefile CHANGED
@@ -109,7 +109,7 @@ if defined?(YARD::Rake::YardocTask)
109
109
  yd.options << '--charset=utf-8'
110
110
  yd.options << '--output-dir=doc'
111
111
  yd.options << '--no-cache'
112
- #yd.options << '--debug'
112
+ yd.options << '--debug'
113
113
  #yd.options << '--single-db'
114
114
  #yd.options << '--one-file'
115
115
  end
@@ -152,5 +152,5 @@ end
152
152
 
153
153
 
154
154
  #==============================================================================#
155
- # $Id: Rakefile,v 431aac54543a 2014/04/20 15:12:27 chikuchikugonzalez $
155
+ # $Id: Rakefile,v f933bbbed93e 2014/04/21 14:36:01 chikuchikugonzalez $
156
156
  # vim: set sts=2 ts=2 sw=2 expandtab:
@@ -86,10 +86,17 @@ module Rixmap
86
86
  @template = "CCCCssssssa48xCSSssx54"
87
87
  end
88
88
 
89
+ # 文字列からPCXヘッダデータを復元します.
90
+ #
91
+ # @param [String] data ヘッダ文字列
92
+ # @return [void]
89
93
  def unpack(data)
90
94
  @magic, @version, @encoding, @bit_width, @left, @top, @right, @bottom, @dpi_x, @dpi_y, @palette, @bit_planes, @line_width, @colortype, @screen_x, @screen_y = data.unpack(@template)
91
95
  end
92
96
 
97
+ # 設定されてる属性値をPCXヘッダバイナリ文字列にエンコードします.
98
+ #
99
+ # @return [String] PCXヘッダバイナリ文字列
93
100
  def pack()
94
101
  return [@magic, @version, @encoding, @bit_width, @left, @top, @right, @bottom, @dpi_x, @dpi_y, @palette, @bit_planes, @line_width, @colortype, @screen_x, @screen_y].pack(@template)
95
102
  end
@@ -434,5 +441,5 @@ end
434
441
 
435
442
 
436
443
  #==============================================================================#
437
- # $Id: pcx.rb,v 57b1fb2cd6a6 2014/04/20 12:21:27 chikuchikugonzalez $
444
+ # $Id: pcx.rb,v f933bbbed93e 2014/04/21 14:36:01 chikuchikugonzalez $
438
445
  # vim: set sts=2 ts=2 sw=2 expandtab:
@@ -8,62 +8,62 @@ module Rixmap
8
8
  module PNG
9
9
 
10
10
  # PNGシグネチャ
11
- FILE_SIGNATURE = "\x89PNG\r\n\x1A\n".force_encoding(Encoding::BINARY)
11
+ FILE_SIGNATURE = "\x89PNG\r\n\x1A\n".force_encoding(Encoding::BINARY).freeze
12
12
 
13
13
  # PNGシグネチャサイズ
14
- FILE_SIGNATURE_SIZE = 8
14
+ FILE_SIGNATURE_SIZE = 8.freeze
15
15
 
16
16
  # グレースケール形式
17
17
  #
18
18
  # ビット幅は 1, 2, 4, 8, 16
19
- COLORTYPE_GRAYSCALE = 0x00
19
+ COLORTYPE_GRAYSCALE = 0x00.freeze
20
20
 
21
21
  # RGBトゥルーカラー形式
22
22
  #
23
23
  # ビット幅は 8, 16
24
- COLORTYPE_TRUECOLOR = 0x02
24
+ COLORTYPE_TRUECOLOR = 0x02.freeze
25
25
 
26
26
  # インデックスカラー形式
27
27
  #
28
28
  # ビット幅は 1, 2, 4, 8
29
- COLORTYPE_INDEXED = 0x03
29
+ COLORTYPE_INDEXED = 0x03.freeze
30
30
 
31
31
  # グレースケール形式 with 透明度
32
32
  #
33
33
  # ビット幅は 8, 16
34
- COLORTYPE_GRAYSCALE_WITH_ALPHA = 0x04
34
+ COLORTYPE_GRAYSCALE_WITH_ALPHA = 0x04.freeze
35
35
 
36
36
  # RGBトゥルーカラー形式 with 透明度
37
37
  #
38
38
  # ビット幅は 8, 16
39
- COLORTYPE_TRUECOLOR_WITH_ALPHA = 0x06
39
+ COLORTYPE_TRUECOLOR_WITH_ALPHA = 0x06.freeze
40
40
 
41
41
  # Deflate圧縮メソッド
42
- COMPRESSION_DEFLATE = 0x00
42
+ COMPRESSION_DEFLATE = 0x00.freeze
43
43
 
44
44
  # 基本のフィルタタイプ
45
- FILTER_ADAPTIVE = 0x00
45
+ FILTER_ADAPTIVE = 0x00.freeze
46
46
 
47
47
  # インターレースなし
48
- INTERLACE_NONE = 0x00
48
+ INTERLACE_NONE = 0x00.freeze
49
49
 
50
50
  # Adam7インターレース
51
- INTERLACE_ADAM7 = 0x01
51
+ INTERLACE_ADAM7 = 0x01.freeze
52
52
 
53
53
  # なにもしない基本フィルタ
54
- ADAPTIVEFILTER_NONE = 0x00
54
+ ADAPTIVEFILTER_NONE = 0x00.freeze
55
55
 
56
56
  # 左側差分基本フィルタ
57
- ADAPTIVEFILTER_SUB = 0x01
57
+ ADAPTIVEFILTER_SUB = 0x01.freeze
58
58
 
59
59
  # 上側差分基本フィルタ
60
- ADAPTIVEFILTER_UP = 0x02
60
+ ADAPTIVEFILTER_UP = 0x02.freeze
61
61
 
62
62
  # 平均基本フィルタ
63
- ADAPTIVEFILTER_AVERAGE = 0x03
63
+ ADAPTIVEFILTER_AVERAGE = 0x03.freeze
64
64
 
65
65
  # 周辺から近い色をとって、その差分をとるようなの
66
- ADAPTIVEFILTER_PEATH = 0x04
66
+ ADAPTIVEFILTER_PEATH = 0x04.freeze
67
67
  end
68
68
 
69
69
  end
@@ -74,5 +74,5 @@ require_relative 'png/imageio'
74
74
 
75
75
 
76
76
  #==============================================================================#
77
- # $Id: png.rb,v 57b1fb2cd6a6 2014/04/20 12:21:27 chikuchikugonzalez $
77
+ # $Id: png.rb,v f933bbbed93e 2014/04/21 14:36:01 chikuchikugonzalez $
78
78
  # vim: set sts=2 ts=2 sw=2 expandtab:
@@ -10,13 +10,15 @@ module Rixmap
10
10
  # スキャンライン用フィルタ実装.
11
11
  #
12
12
  # @see http://www.milk-island.net/document/png/#9Filters
13
+ # FIXME これ超重い気がする
13
14
  class AdaptiveFilter
14
15
  # デフォルトフィルタ実装を初期化します.
15
16
  #
16
17
  # @param [Rixmap::Mode] mode 画像形式
17
18
  def initialize(mode)
18
- @prev = nil
19
+ @prev = Rixmap::Binary.new()
19
20
  @mode = mode
21
+ @size = mode.channels.size
20
22
  end
21
23
 
22
24
  # フィルタ関数
@@ -26,15 +28,52 @@ module Rixmap
26
28
  # @return [Array] フィルタ処理後スキャンライン
27
29
  def filt(line, method = ADAPTIVEFILTER_NONE)
28
30
  base_line = Rixmap::Binary.new(line)
29
- filt_line = Rixmap::Binary.new([method])
31
+ filt_line = Rixmap::Binary.new()
30
32
  case method
31
33
  when ADAPTIVEFILTER_NONE
32
34
  filt_line += base_line
35
+ when ADAPTIVEFILTER_SUB
36
+ base_line.each_with_index do |byte, i|
37
+ prev_idx = i - @size
38
+ prev_byte = if prev_idx < 0
39
+ 0
40
+ else
41
+ base_line[prev_idx]
42
+ end
43
+ filt_line[i] = byte - prev_byte
44
+ end
45
+ when ADAPTIVEFILTER_UP
46
+ base_line.each_with_index do |byte, i|
47
+ filt_line[i] = byte - @prev[i].to_i
48
+ end
49
+ when ADAPTIVEFILTER_AVERAGE
50
+ base_line.each_with_index do |byte, i|
51
+ before_idx = i - @size
52
+ before_byte = if before_idx < 0
53
+ 0
54
+ else
55
+ base_line[before_idx]
56
+ end
57
+ prev_byte = @prev[i].to_i
58
+ filt_line[i] = byte - ((before_byte + prev_byte) / 2.0).floor
59
+ end
60
+ when ADAPTIVEFILTER_PEATH
61
+ base_line.each_with_index do |byte, i|
62
+ before_idx = i - @size
63
+ byte_a, byte_c = if before_idx < 0
64
+ [0, 0]
65
+ else
66
+ [base_line[before_idx], @prev[before_idx].to_i]
67
+ end
68
+ byte_b = @prev[i].to_i
69
+ filt_line[i] = byte - self.peath_predicator(byte_a, byte_b, byte_c)
70
+ end
33
71
  else
34
72
  raise NotImplementedError.new("Unsupported Filter Method: #{method}")
35
73
  end
36
74
 
37
75
  @prev = base_line
76
+ filt_line.unshift(method)
38
77
  return filt_line
39
78
  end
40
79
 
@@ -49,13 +88,68 @@ module Rixmap
49
88
  case method
50
89
  when ADAPTIVEFILTER_NONE
51
90
  recon_line += base_line
91
+ when ADAPTIVEFILTER_SUB
92
+ base_line.each_with_index do |byte, i|
93
+ prev_idx = i - @size
94
+ prev_byte = if prev_idx < 0
95
+ 0
96
+ else
97
+ recon_line[prev_idx]
98
+ end
99
+ recon_line[i] = byte + prev_byte
100
+ end
101
+ when ADAPTIVEFILTER_UP
102
+ base_line.each_with_index do |byte, i|
103
+ recon_line[i] = byte + @prev[i].to_i
104
+ end
105
+ when ADAPTIVEFILTER_AVERAGE
106
+ base_line.each_with_index do |byte, i|
107
+ before_idx = i - @size
108
+ before_byte = if before_idx < 0
109
+ 0
110
+ else
111
+ recon_line[before_idx]
112
+ end
113
+ prev_byte = @prev[i].to_i
114
+ recon_line[i] = byte + ((before_byte + prev_byte) / 2.0).floor
115
+ end
116
+ when ADAPTIVEFILTER_PEATH
117
+ base_line.each_with_index do |byte, i|
118
+ before_idx = i - @size
119
+ byte_a, byte_c = if before_idx < 0
120
+ [0, 0]
121
+ else
122
+ [recon_line[before_idx], @prev[before_idx].to_i]
123
+ end
124
+ byte_b = @prev[i].to_i
125
+ recon_line[i] = byte + self.peath_predicator(byte_a, byte_b, byte_c)
126
+ end
52
127
  else
53
128
  raise NotImplementedError.new("Unsupported Filter Method: #{method}")
54
129
  end
55
130
 
56
- @prev = base_line
131
+ @prev = recon_line
57
132
  return recon_line
58
133
  end
134
+
135
+ # Peathフィルタ用判定関数
136
+ #
137
+ # @see http://www.milk-island.net/document/png/#9Filter-type-4-Paeth
138
+ def peath_predicator(a, b, c)
139
+ p = a + b - c
140
+ pa = (p - a).abs
141
+ pb = (p - b).abs
142
+ pc = (p - c).abs
143
+ pr = if pa <= pb && pa <= pc
144
+ a
145
+ elsif pb <= pc
146
+ b
147
+ else
148
+ c
149
+ end
150
+ return pr
151
+ end
152
+ protected :peath_predicator
59
153
  end
60
154
 
61
155
  # PNG入出力実装クラス.
@@ -78,10 +172,42 @@ module Rixmap
78
172
  return true
79
173
  end
80
174
 
175
+ # ピクセルデータ圧縮時の圧縮レベル.
176
+ #
177
+ # 値としては {Zlib} モジュールの定数か、0~9の数値を指定します.
178
+ #
179
+ # @return [Integer] 圧縮レベル
180
+ attr_accessor :compression_level
181
+
182
+ # スキャンライン毎のフィルタリングメソッド.
183
+ #
184
+ # 値は以下のいずれかです.
185
+ #
186
+ # - {PNG::ADAPTIVEFILTER_NONE}
187
+ # - {PNG::ADAPTIVEFILTER_SUB}
188
+ # - {PNG::ADAPTIVEFILTER_UP}
189
+ # - {PNG::ADAPTIVEFILTER_AVERAGE}
190
+ # - {PNG::ADAPTIVEFILTER_PEATH}
191
+ #
192
+ # @return [Integer] フィルタリングメソッド
193
+ attr_accessor :filter_method
194
+
195
+ # PNG入出力オブジェクトを初期化します.
196
+ #
197
+ # @param [Hash] options オプションパラメータ
198
+ # @option options [Integer] :compression_level 圧縮レベル (0-9).
199
+ # @option options [Integer] :filter_method スキャンラインのフィルタリングメソッド
200
+ def initialize(options={})
201
+ @compression_level = Zlib::BEST_COMPRESSION
202
+ @filter_method = ADAPTIVEFILTER_UP
203
+ super(options)
204
+ end
205
+
81
206
  # 画像をPNG形式でエンコードします.
82
207
  #
83
208
  # @param [Rixmap::Image] image 対象画像
84
209
  # @param [Hash] options オプションパラメータ
210
+ # @option options [Integer] :filter_method スキャンラインのフィルタリングメソッド
85
211
  # @return [String] エンコードされた画像データ
86
212
  def encode(image, options={})
87
213
  # イメージヘッダ
@@ -96,6 +222,17 @@ module Rixmap
96
222
  # ピクセルデータ
97
223
  pixels = ''.force_encoding(Encoding::BINARY)
98
224
  filter = AdaptiveFilter.new(image.mode)
225
+ filter_method = nil
226
+ case options[:filter_method]
227
+ when ADAPTIVEFILTER_NONE, ADAPTIVEFILTER_SUB, ADAPTIVEFILTER_UP, ADAPTIVEFILTER_AVERAGE, ADAPTIVEFILTER_PEATH
228
+ filter_method = options[:filter_method].to_i
229
+ else
230
+ filter_method = @filter_method
231
+ end
232
+ compression_level = @compression_level
233
+ unless options[:compression_level].nil?
234
+ compression_level = options[:compression_level].to_i
235
+ end
99
236
 
100
237
  # 画像種別による処理
101
238
  case image.mode
@@ -111,34 +248,34 @@ module Rixmap
111
248
  # ピクセルを作成
112
249
  image.each_line do |line|
113
250
  # ByteArrayはto_bytesできる
114
- pixels.concat(filter.filt(line).to_str)
251
+ pixels.concat(filter.filt(line, filter_method).to_str)
115
252
  end
116
253
  when Rixmap::GRAYSCALE
117
254
  ihdr.colortype = COLORTYPE_GRAYSCALE
118
255
  image.each_line do |line|
119
- pixels.concat(filter.filt(line).to_str)
256
+ pixels.concat(filter.filt(line, filter_method).to_str)
120
257
  end
121
258
  when Rixmap::GRAYALPHA
122
259
  ihdr.colortype = COLORTYPE_GRAYSCALE_WITH_ALPHA
123
260
  image.each_line do |line|
124
- pixels.concat(filter.filt(line.to_s('LA')).to_str)
261
+ pixels.concat(filter.filt(line.to_s('LA'), filter_method).to_str)
125
262
  end
126
263
  when Rixmap::RGB
127
264
  ihdr.colortype = COLORTYPE_TRUECOLOR
128
265
  image.each_line do |line|
129
- pixels.concat(filter.filt(line.to_s('RGB')).to_str)
266
+ pixels.concat(filter.filt(line.to_s('RGB'), filter_method).to_str)
130
267
  end
131
268
  when Rixmap::RGBA
132
269
  ihdr.colortype = COLORTYPE_TRUECOLOR_WITH_ALPHA
133
270
  image.each_line do |line|
134
- pixels.concat(filter.filt(line.to_s('RGBA')).to_str)
271
+ pixels.concat(filter.filt(line.to_s('RGBA'), filter_method).to_str)
135
272
  end
136
273
  else
137
274
  raise ArgumentError.new("Unknown image mode: #{image.mode}")
138
275
  end
139
276
 
140
277
  # ピクセルを圧縮
141
- deflated_pixels = Zlib.deflate(pixels, Zlib::BEST_COMPRESSION)
278
+ deflated_pixels = Zlib.deflate(pixels, compression_level)
142
279
 
143
280
  # IDATチャンクを生成
144
281
  idat = Chunk::IDATChunk.new
@@ -284,5 +421,5 @@ end
284
421
 
285
422
 
286
423
  #==============================================================================#
287
- # $Id: imageio.rb,v 57b1fb2cd6a6 2014/04/20 12:21:27 chikuchikugonzalez $
424
+ # $Id: imageio.rb,v f933bbbed93e 2014/04/21 14:36:01 chikuchikugonzalez $
288
425
  # vim: set sts=2 ts=2 sw=2 expandtab:
@@ -10,7 +10,7 @@ module Rixmap
10
10
  VERSION_MINOR = 1
11
11
 
12
12
  # リビジョン番号のようなもの
13
- VERSION_TEENY = 0
13
+ VERSION_TEENY = 1
14
14
 
15
15
  # バージョン番号 (数値表現)
16
16
  VERSION_NUMBER = (VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | VERSION_TEENY
@@ -22,5 +22,5 @@ end
22
22
 
23
23
 
24
24
  #==============================================================================#
25
- # $Id: version.rb,v 431aac54543a 2014/04/20 15:12:27 chikuchikugonzalez $
25
+ # $Id: version.rb,v f933bbbed93e 2014/04/21 14:36:01 chikuchikugonzalez $
26
26
  # vim: set sts=2 ts=2 sw=2 expandtab:
data/src/rixmapcore.cxx CHANGED
@@ -1233,6 +1233,22 @@ static VALUE Mode_getDepth(VALUE self) {
1233
1233
  return INT2FIX(_this->getDepth());
1234
1234
  }
1235
1235
 
1236
+ /**
1237
+ * この画像形式に含まれるチャンネルリストを返します.
1238
+ *
1239
+ * @return [Array<String>] チャンネルリスト
1240
+ */
1241
+ static VALUE Mode_getChannels(VALUE self) {
1242
+ Rixmap::ModeData* _this = rixmap_unwrap<Rixmap::ModeData>(self);
1243
+ const Rixmap::ChannelArray& channels = _this->getChannels();
1244
+ VALUE items = rb_ary_new();
1245
+ for (auto it = channels.begin(); it != channels.end(); it++) {
1246
+ const char ch = static_cast<char>(*it);
1247
+ rb_ary_push(items, rb_str_new(&ch, 1));
1248
+ }
1249
+ return items;
1250
+ }
1251
+
1236
1252
  /**
1237
1253
  * RGBカラー形式かどうかを返します.
1238
1254
  *
@@ -3040,6 +3056,7 @@ void RixmapCore_Init() {
3040
3056
  rb_define_alloc_func(cRixmapMode, Mode_Alloc);
3041
3057
  rb_define_method(cRixmapMode, "name", RUBY_METHOD_FUNC(Mode_getName), 0);
3042
3058
  rb_define_method(cRixmapMode, "depth", RUBY_METHOD_FUNC(Mode_getDepth), 0);
3059
+ rb_define_method(cRixmapMode, "channels", RUBY_METHOD_FUNC(Mode_getChannels), 0);
3043
3060
  rb_define_method(cRixmapMode, "rgb?", RUBY_METHOD_FUNC(Mode_isRGBType), 0);
3044
3061
  rb_define_method(cRixmapMode, "grayscale?", RUBY_METHOD_FUNC(Mode_isGrayScaleType), 0);
3045
3062
  rb_define_method(cRixmapMode, "indexed?", RUBY_METHOD_FUNC(Mode_isIndexedType), 0);
@@ -3205,5 +3222,5 @@ void RixmapCore_Init() {
3205
3222
 
3206
3223
 
3207
3224
  //============================================================================//
3208
- // $Id: rixmapcore.cxx,v 5b9a0968eca5 2014/04/20 13:37:36 chikuchikugonzalez $
3225
+ // $Id: rixmapcore.cxx,v f933bbbed93e 2014/04/21 14:36:01 chikuchikugonzalez $
3209
3226
  // vim: set sts=4 ts=4 sw=4 expandtab foldmethod=marker:
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.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - chikuchikugonzalez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-20 00:00:00.000000000 Z
11
+ date: 2014-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yard
@@ -16,28 +16,34 @@ dependencies:
16
16
  requirements:
17
17
  - - '>='
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '0.8'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '0.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '>='
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 2.0.0
34
+ - - <
35
+ - !ruby/object:Gem::Version
36
+ version: 3.0.0
34
37
  type: :development
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - '>='
39
42
  - !ruby/object:Gem::Version
40
- version: '0'
43
+ version: 2.0.0
44
+ - - <
45
+ - !ruby/object:Gem::Version
46
+ version: 3.0.0
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: minitest
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -58,7 +64,12 @@ email: chikuchikugonzalez@gmail.com
58
64
  executables: []
59
65
  extensions:
60
66
  - src/extconf.rb
61
- extra_rdoc_files: []
67
+ extra_rdoc_files:
68
+ - src/rixmapcore.cxx
69
+ - src/rixmapio.cxx
70
+ - src/rixmapmain.cxx
71
+ - README.markdown
72
+ - LICENSE.txt
62
73
  files:
63
74
  - src/rixmapcore.cxx
64
75
  - src/rixmapio.cxx