chunky_png 0.6.0 → 0.7.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/chunky_png.gemspec +2 -2
- data/lib/chunky_png.rb +1 -1
- data/lib/chunky_png/canvas/png_encoding.rb +29 -19
- data/lib/chunky_png/chunk.rb +2 -2
- data/spec/chunky_png/canvas/png_encoding_spec.rb +21 -0
- metadata +2 -2
data/chunky_png.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
|
4
4
|
# Do not change the version and date fields by hand. This will be done
|
5
5
|
# automatically by the gem release script.
|
6
|
-
s.version = "0.
|
7
|
-
s.date = "2010-
|
6
|
+
s.version = "0.7.0"
|
7
|
+
s.date = "2010-03-15"
|
8
8
|
|
9
9
|
s.summary = "Pure ruby library for read/write, chunk-level access to PNG files"
|
10
10
|
s.description = <<-EOT
|
data/lib/chunky_png.rb
CHANGED
@@ -27,7 +27,7 @@ module ChunkyPNG
|
|
27
27
|
|
28
28
|
# The current version of ChunkyPNG. This value will be updated automatically
|
29
29
|
# by them gem:release rake task.
|
30
|
-
VERSION = "0.
|
30
|
+
VERSION = "0.7.0"
|
31
31
|
|
32
32
|
###################################################
|
33
33
|
# PNG international standard defined constants
|
@@ -67,8 +67,8 @@ module ChunkyPNG
|
|
67
67
|
ds.transparency_chunk = encoding_palette.to_trns_chunk unless encoding_palette.opaque?
|
68
68
|
end
|
69
69
|
|
70
|
-
data = encode_png_pixelstream(encoding[:color_mode], encoding[:interlace])
|
71
|
-
ds.data_chunks = Chunk::ImageData.split_in_chunks(data)
|
70
|
+
data = encode_png_pixelstream(encoding[:color_mode], encoding[:interlace], encoding[:compression])
|
71
|
+
ds.data_chunks = Chunk::ImageData.split_in_chunks(data, encoding[:compression])
|
72
72
|
ds.end_chunk = Chunk::End.new
|
73
73
|
return ds
|
74
74
|
end
|
@@ -86,9 +86,11 @@ module ChunkyPNG
|
|
86
86
|
def determine_png_encoding(constraints = {})
|
87
87
|
|
88
88
|
if constraints == :fast_rgb
|
89
|
-
encoding = { :color_mode => ChunkyPNG::COLOR_TRUECOLOR }
|
89
|
+
encoding = { :color_mode => ChunkyPNG::COLOR_TRUECOLOR, :compression => Zlib::BEST_SPEED }
|
90
90
|
elsif constraints == :fast_rgba
|
91
|
-
encoding = { :color_mode => ChunkyPNG::COLOR_TRUECOLOR_ALPHA }
|
91
|
+
encoding = { :color_mode => ChunkyPNG::COLOR_TRUECOLOR_ALPHA, :compression => Zlib::BEST_SPEED }
|
92
|
+
elsif constraints == :best_compression
|
93
|
+
encoding = { :compression => Zlib::BEST_COMPRESSION }
|
92
94
|
else
|
93
95
|
encoding = constraints
|
94
96
|
end
|
@@ -103,6 +105,8 @@ module ChunkyPNG
|
|
103
105
|
encoding[:color_mode] ||= encoding_palette.best_colormode
|
104
106
|
end
|
105
107
|
|
108
|
+
encoding[:compression] ||= Zlib::DEFAULT_COMPRESSION
|
109
|
+
|
106
110
|
encoding[:interlace] = case encoding[:interlace]
|
107
111
|
when nil, false, ChunkyPNG::INTERLACING_NONE then ChunkyPNG::INTERLACING_NONE
|
108
112
|
when true, ChunkyPNG::INTERLACING_ADAM7 then ChunkyPNG::INTERLACING_ADAM7
|
@@ -116,26 +120,28 @@ module ChunkyPNG
|
|
116
120
|
# mode, possibly with interlacing.
|
117
121
|
# @param [Integer] color_mode The color mode to use for encoding.
|
118
122
|
# @param [Integer] interlace The interlacing method to use.
|
119
|
-
# @param [
|
120
|
-
|
123
|
+
# @param [Integer] compression The Zlib compression level.
|
124
|
+
# @return [String] The PNG encoded canvas as string.
|
125
|
+
def encode_png_pixelstream(color_mode = ChunkyPNG::COLOR_TRUECOLOR, interlace = ChunkyPNG::INTERLACING_NONE, compression = ZLib::DEFAULT_COMPRESSION)
|
121
126
|
|
122
127
|
if color_mode == ChunkyPNG::COLOR_INDEXED && (encoding_palette.nil? || !encoding_palette.can_encode?)
|
123
128
|
raise "This palette is not suitable for encoding!"
|
124
129
|
end
|
125
130
|
|
126
131
|
case interlace
|
127
|
-
when ChunkyPNG::INTERLACING_NONE then encode_png_image_without_interlacing(color_mode)
|
128
|
-
when ChunkyPNG::INTERLACING_ADAM7 then encode_png_image_with_interlacing(color_mode)
|
132
|
+
when ChunkyPNG::INTERLACING_NONE then encode_png_image_without_interlacing(color_mode, compression)
|
133
|
+
when ChunkyPNG::INTERLACING_ADAM7 then encode_png_image_with_interlacing(color_mode, compression)
|
129
134
|
else raise "Unknown interlacing method!"
|
130
135
|
end
|
131
136
|
end
|
132
137
|
|
133
138
|
# Encodes the canvas according to the PNG format specification with a given color mode.
|
134
139
|
# @param [Integer] color_mode The color mode to use for encoding.
|
135
|
-
# @param [
|
136
|
-
|
140
|
+
# @param [Integer] compression The Zlib compression level.
|
141
|
+
# @return [String] The PNG encoded canvas as string.
|
142
|
+
def encode_png_image_without_interlacing(color_mode, compression = ZLib::DEFAULT_COMPRESSION)
|
137
143
|
stream = ""
|
138
|
-
encode_png_image_pass_to_stream(stream, color_mode)
|
144
|
+
encode_png_image_pass_to_stream(stream, color_mode, compression)
|
139
145
|
stream
|
140
146
|
end
|
141
147
|
|
@@ -146,13 +152,14 @@ module ChunkyPNG
|
|
146
152
|
# one by one, concatenating the resulting strings.
|
147
153
|
#
|
148
154
|
# @param [Integer] color_mode The color mode to use for encoding.
|
149
|
-
# @param [
|
150
|
-
|
155
|
+
# @param [Integer] compression The Zlib compression level.
|
156
|
+
# @return [String] The PNG encoded canvas as string.
|
157
|
+
def encode_png_image_with_interlacing(color_mode, compression = ZLib::DEFAULT_COMPRESSION)
|
151
158
|
stream = ""
|
152
159
|
0.upto(6) do |pass|
|
153
160
|
subcanvas = self.class.adam7_extract_pass(pass, self)
|
154
161
|
subcanvas.encoding_palette = encoding_palette
|
155
|
-
subcanvas.encode_png_image_pass_to_stream(stream, color_mode)
|
162
|
+
subcanvas.encode_png_image_pass_to_stream(stream, color_mode, compression)
|
156
163
|
end
|
157
164
|
stream
|
158
165
|
end
|
@@ -160,17 +167,20 @@ module ChunkyPNG
|
|
160
167
|
# Encodes the canvas to a stream, in a given color mode.
|
161
168
|
# @param [String, IO, :<<] stream The stream to write to.
|
162
169
|
# @param [Integer] color_mode The color mode to use for encoding.
|
163
|
-
|
170
|
+
# @param [Integer] compression The Zlib compression level.
|
171
|
+
def encode_png_image_pass_to_stream(stream, color_mode, compression = ZLib::DEFAULT_COMPRESSION)
|
164
172
|
|
165
|
-
|
166
|
-
|
173
|
+
if compression < Zlib::BEST_COMPRESSION && color_mode == ChunkyPNG::COLOR_TRUECOLOR_ALPHA
|
174
|
+
# Fast RGBA saving routine
|
167
175
|
stream << pixels.pack("xN#{width}" * height)
|
168
176
|
|
169
|
-
|
177
|
+
elsif compression < Zlib::BEST_COMPRESSION && color_mode == ChunkyPNG::COLOR_TRUECOLOR
|
178
|
+
# Fast RGB saving routine
|
170
179
|
line_packer = 'x' + ('NX' * width)
|
171
180
|
stream << pixels.pack(line_packer * height)
|
172
181
|
|
173
182
|
else
|
183
|
+
# Normal saving routine
|
174
184
|
pixel_size = Color.bytesize(color_mode)
|
175
185
|
pixel_encoder = case color_mode
|
176
186
|
when ChunkyPNG::COLOR_TRUECOLOR then lambda { |color| Color.to_truecolor_bytes(color) }
|
@@ -184,7 +194,7 @@ module ChunkyPNG
|
|
184
194
|
previous_bytes = Array.new(pixel_size * width, 0)
|
185
195
|
each_scanline do |line|
|
186
196
|
unencoded_bytes = line.map(&pixel_encoder).flatten
|
187
|
-
stream <<
|
197
|
+
stream << encode_png_scanline_paeth(unencoded_bytes, previous_bytes, pixel_size).pack('C*')
|
188
198
|
previous_bytes = unencoded_bytes
|
189
199
|
end
|
190
200
|
end
|
data/lib/chunky_png/chunk.rb
CHANGED
@@ -191,8 +191,8 @@ module ChunkyPNG
|
|
191
191
|
Zlib::Inflate.inflate(data_chunks.map { |c| c.content }.join(''))
|
192
192
|
end
|
193
193
|
|
194
|
-
def self.split_in_chunks(data, chunk_size = 2147483647)
|
195
|
-
streamdata = Zlib::Deflate.deflate(data)
|
194
|
+
def self.split_in_chunks(data, level = Zlib::DEFAULT_COMPRESSION, chunk_size = 2147483647)
|
195
|
+
streamdata = Zlib::Deflate.deflate(data, level)
|
196
196
|
# TODO: Split long streamdata over multiple chunks
|
197
197
|
[ ChunkyPNG::Chunk::ImageData.new('IDAT', streamdata) ]
|
198
198
|
end
|
@@ -30,6 +30,27 @@ describe ChunkyPNG::Canvas::PNGEncoding do
|
|
30
30
|
|
31
31
|
File.unlink(filename)
|
32
32
|
end
|
33
|
+
|
34
|
+
it "should save an image using the normal routine correctly" do
|
35
|
+
canvas = reference_canvas('operations')
|
36
|
+
Zlib::Deflate.should_receive(:deflate).with(anything, Zlib::DEFAULT_COMPRESSION).and_return('')
|
37
|
+
canvas.to_blob
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
it "should save an image using the :best_compression routine correctly" do
|
42
|
+
canvas = reference_canvas('operations')
|
43
|
+
canvas.should_not_receive(:encode_png_scanline)
|
44
|
+
Zlib::Deflate.should_receive(:deflate).with(anything, Zlib::BEST_SPEED).and_return('')
|
45
|
+
canvas.to_blob(:fast_rgba)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should save an image using the :best_compression routine correctly" do
|
49
|
+
canvas = reference_canvas('operations')
|
50
|
+
canvas.should_receive(:encode_png_scanline_paeth).at_least(:once).and_return([5, 0, 0, 0, 0, 0, 0])
|
51
|
+
Zlib::Deflate.should_receive(:deflate).with(anything, Zlib::BEST_COMPRESSION).and_return('')
|
52
|
+
canvas.to_blob(:best_compression)
|
53
|
+
end
|
33
54
|
end
|
34
55
|
|
35
56
|
describe '#encode_scanline' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chunky_png
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Willem van Bergen
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-15 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|