zpng 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -4
- data/Gemfile.lock +18 -16
- data/README.md +62 -48
- data/README.md.tpl +11 -1
- data/Rakefile +43 -0
- data/VERSION +1 -1
- data/lib/zpng/chunk.rb +114 -17
- data/lib/zpng/cli.rb +30 -5
- data/lib/zpng/color.rb +30 -0
- data/lib/zpng/image.rb +122 -19
- data/lib/zpng/scan_line.rb +138 -74
- data/samples/captcha_4bpp.png +0 -0
- data/spec/create_image_spec.rb +78 -0
- data/spec/crop_spec.rb +93 -0
- data/spec/image_spec.rb +54 -0
- data/spec/modify_spec.rb +2 -9
- data/spec/running_pixel_spec.rb +47 -0
- data/spec/spec_helper.rb +7 -1
- data/zpng.gemspec +17 -15
- metadata +57 -38
data/Gemfile
CHANGED
@@ -8,8 +8,7 @@ gem 'hexdump'
|
|
8
8
|
# Add dependencies to develop your gem here.
|
9
9
|
# Include everything needed to run rake, tests, features, etc.
|
10
10
|
group :development do
|
11
|
-
gem "rspec",
|
12
|
-
gem "bundler", "
|
13
|
-
gem "jeweler", "~> 1.
|
14
|
-
gem "rcov", ">= 0"
|
11
|
+
gem "rspec", ">= 2.8.0"
|
12
|
+
gem "bundler", ">= 1.0.0"
|
13
|
+
gem "jeweler", "~> 1.8.4"
|
15
14
|
end
|
data/Gemfile.lock
CHANGED
@@ -4,29 +4,31 @@ GEM
|
|
4
4
|
colorize (0.5.8)
|
5
5
|
diff-lcs (1.1.3)
|
6
6
|
git (1.2.5)
|
7
|
-
hexdump (0.2.
|
8
|
-
jeweler (1.
|
7
|
+
hexdump (0.2.3)
|
8
|
+
jeweler (1.8.4)
|
9
9
|
bundler (~> 1.0)
|
10
10
|
git (>= 1.2.5)
|
11
11
|
rake
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
rspec-
|
12
|
+
rdoc
|
13
|
+
json (1.7.5)
|
14
|
+
rake (10.0.2)
|
15
|
+
rdoc (3.12)
|
16
|
+
json (~> 1.4)
|
17
|
+
rspec (2.12.0)
|
18
|
+
rspec-core (~> 2.12.0)
|
19
|
+
rspec-expectations (~> 2.12.0)
|
20
|
+
rspec-mocks (~> 2.12.0)
|
21
|
+
rspec-core (2.12.1)
|
22
|
+
rspec-expectations (2.12.0)
|
23
|
+
diff-lcs (~> 1.1.3)
|
24
|
+
rspec-mocks (2.12.0)
|
22
25
|
|
23
26
|
PLATFORMS
|
24
27
|
ruby
|
25
28
|
|
26
29
|
DEPENDENCIES
|
27
|
-
bundler (
|
30
|
+
bundler (>= 1.0.0)
|
28
31
|
colorize
|
29
32
|
hexdump
|
30
|
-
jeweler (~> 1.
|
31
|
-
|
32
|
-
rspec (~> 2.8.0)
|
33
|
+
jeweler (~> 1.8.4)
|
34
|
+
rspec (>= 2.8.0)
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
zpng
|
1
|
+
zpng [![Build Status](https://secure.travis-ci.org/zed-0xff/zpng.png)](http://secure.travis-ci.org/zed-0xff/zpng) [![Dependency Status](https://gemnasium.com/zed-0xff/zpng.png)](https://gemnasium.com/zed-0xff/zpng)
|
2
2
|
======
|
3
3
|
|
4
4
|
|
@@ -15,14 +15,18 @@ Usage
|
|
15
15
|
|
16
16
|
# zpng -h
|
17
17
|
|
18
|
-
Usage: zpng [options]
|
18
|
+
Usage: zpng [options] filename.png
|
19
19
|
-v, --verbose Run verbosely (can be used multiple times)
|
20
20
|
-q, --quiet Silent any warnings (can be used multiple times)
|
21
|
-
-I, --info General image info
|
22
21
|
-C, --chunks Show file chunks (default)
|
22
|
+
-i, --info General image info (default)
|
23
23
|
-A, --ascii Try to display image as ASCII (works best with monochrome images)
|
24
24
|
-S, --scanlines Show scanlines info
|
25
25
|
-P, --palette Show palette
|
26
|
+
-E, --extract-chunk ID extract a single chunk
|
27
|
+
-U, --unpack-imagedata unpack Image Data (IDAT) chunk(s), output to stdout
|
28
|
+
-c, --crop GEOMETRY crop image, {WIDTH}x{HEIGHT}+{X}+{Y},
|
29
|
+
puts results on stdout unless --ascii given
|
26
30
|
|
27
31
|
### Info
|
28
32
|
|
@@ -35,15 +39,15 @@ Usage
|
|
35
39
|
|
36
40
|
# zpng --chunks qr_aux_chunks.png
|
37
41
|
|
38
|
-
[.]
|
39
|
-
[.]
|
40
|
-
[.]
|
41
|
-
[.]
|
42
|
-
[.]
|
43
|
-
[.]
|
44
|
-
[.]
|
45
|
-
[.]
|
46
|
-
[.]
|
42
|
+
[.] <Chunk #00 IHDR size= 13, crc=36a28ef4, width=35, height=35, depth=1, color=0, compression=0, filter=0, interlace=0, idx=0> CRC OK
|
43
|
+
[.] <Chunk #01 gAMA size= 4, crc=0bfc6105 > CRC OK
|
44
|
+
[.] <Chunk #02 sRGB size= 1, crc=aece1ce9 > CRC OK
|
45
|
+
[.] <Chunk #03 cHRM size= 32, crc=9cba513c > CRC OK
|
46
|
+
[.] <Chunk #04 pHYs size= 9, crc=46c96b3e > CRC OK
|
47
|
+
[.] <Chunk #05 IDAT size= 213, crc=5f3f1ff9 > CRC OK
|
48
|
+
[.] <Chunk #06 tEXt size= 37, crc=8d62fd1a > CRC OK
|
49
|
+
[.] <Chunk #07 tEXt size= 37, crc=fc3f45a6 > CRC OK
|
50
|
+
[.] <Chunk #08 IEND size= 0, crc=ae426082 > CRC OK
|
47
51
|
|
48
52
|
### ASCII
|
49
53
|
|
@@ -90,47 +94,47 @@ source image: ![qr_rgb.png](https://github.com/zed-0xff/zpng/raw/master/samples/
|
|
90
94
|
|
91
95
|
# zpng --scanlines qr_rgb.png
|
92
96
|
|
93
|
-
[#<ZPNG::ScanLine idx=0, bpp=24,
|
94
|
-
#<ZPNG::ScanLine idx=1, bpp=24,
|
95
|
-
#<ZPNG::ScanLine idx=2, bpp=24,
|
96
|
-
#<ZPNG::ScanLine idx=3, bpp=24,
|
97
|
-
#<ZPNG::ScanLine idx=4, bpp=24,
|
98
|
-
#<ZPNG::ScanLine idx=5, bpp=24,
|
99
|
-
#<ZPNG::ScanLine idx=6, bpp=24,
|
100
|
-
#<ZPNG::ScanLine idx=7, bpp=24,
|
101
|
-
#<ZPNG::ScanLine idx=8, bpp=24,
|
102
|
-
#<ZPNG::ScanLine idx=9, bpp=24,
|
103
|
-
#<ZPNG::ScanLine idx=10, bpp=24,
|
104
|
-
#<ZPNG::ScanLine idx=11, bpp=24,
|
105
|
-
#<ZPNG::ScanLine idx=12, bpp=24,
|
106
|
-
#<ZPNG::ScanLine idx=13, bpp=24,
|
107
|
-
#<ZPNG::ScanLine idx=14, bpp=24,
|
108
|
-
#<ZPNG::ScanLine idx=15, bpp=24,
|
109
|
-
#<ZPNG::ScanLine idx=16, bpp=24,
|
110
|
-
#<ZPNG::ScanLine idx=17, bpp=24,
|
111
|
-
#<ZPNG::ScanLine idx=18, bpp=24,
|
112
|
-
#<ZPNG::ScanLine idx=19, bpp=24,
|
113
|
-
#<ZPNG::ScanLine idx=20, bpp=24,
|
114
|
-
#<ZPNG::ScanLine idx=21, bpp=24,
|
115
|
-
#<ZPNG::ScanLine idx=22, bpp=24,
|
116
|
-
#<ZPNG::ScanLine idx=23, bpp=24,
|
117
|
-
#<ZPNG::ScanLine idx=24, bpp=24,
|
118
|
-
#<ZPNG::ScanLine idx=25, bpp=24,
|
119
|
-
#<ZPNG::ScanLine idx=26, bpp=24,
|
120
|
-
#<ZPNG::ScanLine idx=27, bpp=24,
|
121
|
-
#<ZPNG::ScanLine idx=28, bpp=24,
|
122
|
-
#<ZPNG::ScanLine idx=29, bpp=24,
|
123
|
-
#<ZPNG::ScanLine idx=30, bpp=24,
|
124
|
-
#<ZPNG::ScanLine idx=31, bpp=24,
|
125
|
-
#<ZPNG::ScanLine idx=32, bpp=24,
|
126
|
-
#<ZPNG::ScanLine idx=33, bpp=24,
|
127
|
-
#<ZPNG::ScanLine idx=34, bpp=24,
|
97
|
+
[#<ZPNG::ScanLine idx=0, bpp=24, offset=1, filter=1>,
|
98
|
+
#<ZPNG::ScanLine idx=1, bpp=24, offset=107, filter=4>,
|
99
|
+
#<ZPNG::ScanLine idx=2, bpp=24, offset=213, filter=4>,
|
100
|
+
#<ZPNG::ScanLine idx=3, bpp=24, offset=319, filter=4>,
|
101
|
+
#<ZPNG::ScanLine idx=4, bpp=24, offset=425, filter=2>,
|
102
|
+
#<ZPNG::ScanLine idx=5, bpp=24, offset=531, filter=2>,
|
103
|
+
#<ZPNG::ScanLine idx=6, bpp=24, offset=637, filter=4>,
|
104
|
+
#<ZPNG::ScanLine idx=7, bpp=24, offset=743, filter=0>,
|
105
|
+
#<ZPNG::ScanLine idx=8, bpp=24, offset=849, filter=1>,
|
106
|
+
#<ZPNG::ScanLine idx=9, bpp=24, offset=955, filter=0>,
|
107
|
+
#<ZPNG::ScanLine idx=10, bpp=24, offset=1061, filter=0>,
|
108
|
+
#<ZPNG::ScanLine idx=11, bpp=24, offset=1167, filter=0>,
|
109
|
+
#<ZPNG::ScanLine idx=12, bpp=24, offset=1273, filter=1>,
|
110
|
+
#<ZPNG::ScanLine idx=13, bpp=24, offset=1379, filter=2>,
|
111
|
+
#<ZPNG::ScanLine idx=14, bpp=24, offset=1485, filter=4>,
|
112
|
+
#<ZPNG::ScanLine idx=15, bpp=24, offset=1591, filter=0>,
|
113
|
+
#<ZPNG::ScanLine idx=16, bpp=24, offset=1697, filter=4>,
|
114
|
+
#<ZPNG::ScanLine idx=17, bpp=24, offset=1803, filter=0>,
|
115
|
+
#<ZPNG::ScanLine idx=18, bpp=24, offset=1909, filter=4>,
|
116
|
+
#<ZPNG::ScanLine idx=19, bpp=24, offset=2015, filter=4>,
|
117
|
+
#<ZPNG::ScanLine idx=20, bpp=24, offset=2121, filter=0>,
|
118
|
+
#<ZPNG::ScanLine idx=21, bpp=24, offset=2227, filter=1>,
|
119
|
+
#<ZPNG::ScanLine idx=22, bpp=24, offset=2333, filter=2>,
|
120
|
+
#<ZPNG::ScanLine idx=23, bpp=24, offset=2439, filter=0>,
|
121
|
+
#<ZPNG::ScanLine idx=24, bpp=24, offset=2545, filter=2>,
|
122
|
+
#<ZPNG::ScanLine idx=25, bpp=24, offset=2651, filter=1>,
|
123
|
+
#<ZPNG::ScanLine idx=26, bpp=24, offset=2757, filter=1>,
|
124
|
+
#<ZPNG::ScanLine idx=27, bpp=24, offset=2863, filter=4>,
|
125
|
+
#<ZPNG::ScanLine idx=28, bpp=24, offset=2969, filter=4>,
|
126
|
+
#<ZPNG::ScanLine idx=29, bpp=24, offset=3075, filter=4>,
|
127
|
+
#<ZPNG::ScanLine idx=30, bpp=24, offset=3181, filter=4>,
|
128
|
+
#<ZPNG::ScanLine idx=31, bpp=24, offset=3287, filter=2>,
|
129
|
+
#<ZPNG::ScanLine idx=32, bpp=24, offset=3393, filter=4>,
|
130
|
+
#<ZPNG::ScanLine idx=33, bpp=24, offset=3499, filter=4>,
|
131
|
+
#<ZPNG::ScanLine idx=34, bpp=24, offset=3605, filter=1>]
|
128
132
|
|
129
133
|
### Palette
|
130
134
|
|
131
135
|
# zpng --palette qr_plte_bw.png
|
132
136
|
|
133
|
-
|
137
|
+
<Chunk #02 PLTE size= 6, crc=55c2d37e >
|
134
138
|
00000000 ff ff ff 00 00 00 |......|
|
135
139
|
|
136
140
|
|
@@ -157,6 +161,16 @@ source image: ![qr_rgb.png](https://github.com/zed-0xff/zpng/raw/master/samples/
|
|
157
161
|
f << img.export
|
158
162
|
end
|
159
163
|
|
164
|
+
## Create 16x16 transparent PNG
|
165
|
+
|
166
|
+
#!/usr/bin/env ruby
|
167
|
+
require 'zpng'
|
168
|
+
include ZPNG
|
169
|
+
|
170
|
+
img = Image.new :width => 16, :height => 16
|
171
|
+
File.open("16x16.png","wb") do |f|
|
172
|
+
f << img.export
|
173
|
+
end
|
160
174
|
|
161
175
|
License
|
162
176
|
-------
|
data/README.md.tpl
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
zpng
|
1
|
+
zpng [![Build Status](https://secure.travis-ci.org/zed-0xff/zpng.png)](http://secure.travis-ci.org/zed-0xff/zpng) [![Dependency Status](https://gemnasium.com/zed-0xff/zpng.png)](https://gemnasium.com/zed-0xff/zpng)
|
2
2
|
======
|
3
3
|
|
4
4
|
|
@@ -61,6 +61,16 @@ source image: ![qr_rgb.png](https://github.com/zed-0xff/zpng/raw/master/samples/
|
|
61
61
|
f << img.export
|
62
62
|
end
|
63
63
|
|
64
|
+
## Create 16x16 transparent PNG
|
65
|
+
|
66
|
+
#!/usr/bin/env ruby
|
67
|
+
require 'zpng'
|
68
|
+
include ZPNG
|
69
|
+
|
70
|
+
img = Image.new :width => 16, :height => 16
|
71
|
+
File.open("16x16.png","wb") do |f|
|
72
|
+
f << img.export
|
73
|
+
end
|
64
74
|
|
65
75
|
License
|
66
76
|
-------
|
data/Rakefile
CHANGED
@@ -72,3 +72,46 @@ task :readme do
|
|
72
72
|
Dir.chdir '..'
|
73
73
|
File.open('README.md','w'){ |f| f << result }
|
74
74
|
end
|
75
|
+
|
76
|
+
desc "generate"
|
77
|
+
task :gen do
|
78
|
+
$:.unshift("./lib")
|
79
|
+
require 'zpng'
|
80
|
+
img = ZPNG::Image.new :width => 16, :height => 16, :bpp => 4
|
81
|
+
img.save "out.png"
|
82
|
+
end
|
83
|
+
|
84
|
+
Rake::Task[:console].clear
|
85
|
+
|
86
|
+
# from /usr/local/lib64/ruby/gems/1.9.1/gems/jeweler-1.8.4/lib/jeweler/tasks.rb
|
87
|
+
desc "Start IRB with all runtime dependencies loaded"
|
88
|
+
task :console, [:script] do |t,args|
|
89
|
+
# TODO move to a command
|
90
|
+
dirs = ['ext', 'lib'].select { |dir| File.directory?(dir) }
|
91
|
+
|
92
|
+
original_load_path = $LOAD_PATH
|
93
|
+
|
94
|
+
cmd = if File.exist?('Gemfile')
|
95
|
+
require 'bundler'
|
96
|
+
Bundler.setup(:default)
|
97
|
+
end
|
98
|
+
|
99
|
+
# add the project code directories
|
100
|
+
$LOAD_PATH.unshift(*dirs)
|
101
|
+
|
102
|
+
# clear ARGV so IRB is not confused
|
103
|
+
ARGV.clear
|
104
|
+
|
105
|
+
require 'irb'
|
106
|
+
|
107
|
+
# ZZZ actually added only these 2 lines
|
108
|
+
require 'zpng'
|
109
|
+
include ZPNG
|
110
|
+
|
111
|
+
# set the optional script to run
|
112
|
+
IRB.conf[:SCRIPT] = args.script
|
113
|
+
IRB.start
|
114
|
+
|
115
|
+
# return the $LOAD_PATH to it's original state
|
116
|
+
$LOAD_PATH.reject! { |path| !(original_load_path.include?(path)) }
|
117
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/lib/zpng/chunk.rb
CHANGED
@@ -18,25 +18,42 @@ module ZPNG
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def initialize
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
def initialize x = {}
|
22
|
+
if x.respond_to?(:read)
|
23
|
+
# IO
|
24
|
+
@size, @type = x.read(8).unpack('Na4')
|
25
|
+
@data = x.read(size)
|
26
|
+
@crc = x.read(4).to_s.unpack('N').first
|
27
|
+
elsif x.respond_to?(:[])
|
28
|
+
# Hash
|
29
|
+
%w'size type data crc'.each do |k|
|
30
|
+
instance_variable_set "@#{k}", x[k.to_sym]
|
31
|
+
end
|
32
|
+
if !@type && self.class.superclass == ZPNG::Chunk
|
33
|
+
# guess @type from self class name, e.g. ZPNG::Chunk::IHDR => "IHDR"
|
34
|
+
@type = self.class.to_s.split("::").last
|
35
|
+
end
|
36
|
+
if !@size && @data
|
37
|
+
# guess @size from @data
|
38
|
+
@size = @data.size
|
39
|
+
end
|
40
|
+
end
|
25
41
|
end
|
26
42
|
|
27
43
|
def export
|
28
44
|
@data = self.export_data # virtual
|
45
|
+
@size = @data.size # XXX hmm.. is it always is?
|
29
46
|
@crc = Zlib.crc32(data, Zlib.crc32(type))
|
30
47
|
[@size,@type].pack('Na4') + @data + [@crc].pack('N')
|
31
48
|
end
|
32
49
|
|
33
50
|
def export_data
|
34
51
|
#STDERR.puts "[!] Chunk::#{type} must realize 'export_data' virtual method".yellow if @size != 0
|
35
|
-
@data
|
52
|
+
@data || ''
|
36
53
|
end
|
37
54
|
|
38
55
|
def inspect
|
39
|
-
size = @size ? sprintf("%
|
56
|
+
size = @size ? sprintf("%6d",@size) : sprintf("%6s","???")
|
40
57
|
crc = @crc ? sprintf("%08x",@crc) : sprintf("%8s","???")
|
41
58
|
type = @type.to_s.gsub(/[^0-9a-z]/i){ |x| sprintf("\\x%02X",x.ord) }
|
42
59
|
sprintf "<Chunk #%02d %4s size=%s, crc=%s >", idx.to_i, type, size, crc
|
@@ -54,11 +71,16 @@ module ZPNG
|
|
54
71
|
COLOR_USED = 2
|
55
72
|
ALPHA_USED = 4
|
56
73
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
74
|
+
# put constants in the scope of ZPNG module
|
75
|
+
# to be able to create new images easily with
|
76
|
+
# include ZPNG
|
77
|
+
# img = Image.new :width => 16, :height => 16, :color => COLOR_RGB
|
78
|
+
|
79
|
+
ZPNG::COLOR_GRAYSCALE = 0 # Each pixel is a grayscale sample
|
80
|
+
ZPNG::COLOR_RGB = 2 # Each pixel is an R,G,B triple.
|
81
|
+
ZPNG::COLOR_INDEXED = 3 # Each pixel is a palette index; a PLTE chunk must appear.
|
82
|
+
ZPNG::COLOR_GRAY_ALPHA = 4 # Each pixel is a grayscale sample, followed by an alpha sample.
|
83
|
+
ZPNG::COLOR_RGBA = 6 # Each pixel is an R,G,B triple, followed by an alpha sample.
|
62
84
|
|
63
85
|
SAMPLES_PER_COLOR = {
|
64
86
|
COLOR_GRAYSCALE => 1,
|
@@ -68,11 +90,67 @@ module ZPNG
|
|
68
90
|
COLOR_RGBA => 4
|
69
91
|
}
|
70
92
|
|
93
|
+
# http://www.w3.org/TR/PNG/#table111
|
94
|
+
ALLOWED_DEPTHS = {
|
95
|
+
COLOR_GRAYSCALE => [ 1, 2, 4, 8, 16 ],
|
96
|
+
COLOR_RGB => [ 8, 16 ],
|
97
|
+
COLOR_INDEXED => [ 1, 2, 4, 8 ],
|
98
|
+
COLOR_GRAY_ALPHA => [ 8, 16 ],
|
99
|
+
COLOR_RGBA => [ 8, 16 ],
|
100
|
+
}
|
101
|
+
|
71
102
|
FORMAT = 'NNC5'
|
72
103
|
|
73
|
-
def initialize
|
104
|
+
def initialize x
|
74
105
|
super
|
75
|
-
|
106
|
+
vars = %w'width height depth color compression filter interlace' # order is important
|
107
|
+
if x.respond_to?(:read)
|
108
|
+
# IO
|
109
|
+
elsif x.respond_to?(:[])
|
110
|
+
# Hash
|
111
|
+
vars.each{ |k| instance_variable_set "@#{k}", x[k.to_sym] }
|
112
|
+
|
113
|
+
raise "[!] width not set" unless @width
|
114
|
+
raise "[!] height not set" unless @height
|
115
|
+
|
116
|
+
# allow easier image creation like
|
117
|
+
# img = Image.new :width => 16, :height => 16, :bpp => 4, :color => false
|
118
|
+
# img = Image.new :width => 16, :height => 16, :bpp => 1, :color => true
|
119
|
+
# img = Image.new :width => 16, :height => 16, :bpp => 32
|
120
|
+
if x[:bpp]
|
121
|
+
unless [true,false,nil].include?(@color)
|
122
|
+
raise "[!] :color must be either 'true' or 'false' when :bpp is set"
|
123
|
+
end
|
124
|
+
if @depth
|
125
|
+
raise "[!] don't use :depth when :bpp is set"
|
126
|
+
end
|
127
|
+
@color, @depth = case x[:bpp]
|
128
|
+
when 1,2,4,8; [ @color ? COLOR_INDEXED : COLOR_GRAYSCALE, x[:bpp] ]
|
129
|
+
when 16;
|
130
|
+
raise "[!] I don't know how to make COLOR 16 bpp PNG. do you?" if @color
|
131
|
+
[ COLOR_GRAY_ALPHA, 8 ]
|
132
|
+
when 24; [ COLOR_RGB, 8 ]
|
133
|
+
when 32; [ COLOR_RGBA, 8 ]
|
134
|
+
else
|
135
|
+
raise "[!] unsupported bpp=#{x[:bpp].inspect}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
@color ||= COLOR_RGBA
|
140
|
+
@depth ||= 8
|
141
|
+
@compression ||= 0
|
142
|
+
@filter ||= 0
|
143
|
+
@interlace ||= 0
|
144
|
+
|
145
|
+
unless ALLOWED_DEPTHS[@color].include?(@depth)
|
146
|
+
raise "[!] invalid color mode (#{@color.inspect}) / bit depth (#{@depth.inspect}) combination"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
if data
|
150
|
+
data.unpack(FORMAT).each_with_index do |value,idx|
|
151
|
+
instance_variable_set "@#{vars[idx]}", value
|
152
|
+
end
|
153
|
+
end
|
76
154
|
end
|
77
155
|
|
78
156
|
def export_data
|
@@ -109,13 +187,20 @@ module ZPNG
|
|
109
187
|
end
|
110
188
|
|
111
189
|
class PLTE < Chunk
|
190
|
+
attr_accessor :max_colors
|
191
|
+
|
112
192
|
def [] idx
|
113
193
|
rgb = @data[idx*3,3]
|
114
|
-
rgb && ZPNG::Color.new(*rgb.
|
194
|
+
rgb && ZPNG::Color.new(*rgb.unpack('C3'))
|
195
|
+
end
|
196
|
+
|
197
|
+
def []= idx, color
|
198
|
+
@data ||= ''
|
199
|
+
@data[idx*3,3] = [color.r, color.g, color.b].pack('C3')
|
115
200
|
end
|
116
201
|
|
117
202
|
def ncolors
|
118
|
-
@size/3
|
203
|
+
@data.to_s.size/3
|
119
204
|
end
|
120
205
|
|
121
206
|
def index color
|
@@ -125,11 +210,23 @@ module ZPNG
|
|
125
210
|
end
|
126
211
|
nil
|
127
212
|
end
|
128
|
-
end
|
129
213
|
|
130
|
-
|
214
|
+
def add color
|
215
|
+
raise "palette full, cannot add color #{ncolors}" if ncolors >= max_colors
|
216
|
+
idx = ncolors
|
217
|
+
self[idx] = color
|
218
|
+
idx
|
219
|
+
end
|
220
|
+
|
221
|
+
def find_or_add color
|
222
|
+
index(color) || add(color)
|
223
|
+
end
|
224
|
+
alias :<< :find_or_add
|
131
225
|
end
|
132
226
|
|
227
|
+
class IDAT < Chunk; end
|
228
|
+
class IEND < Chunk; end
|
229
|
+
|
133
230
|
class ZTXT < Chunk
|
134
231
|
attr_accessor :keyword, :comp_method, :text
|
135
232
|
def initialize *args
|