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 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.6.0"
7
- s.date = "2010-02-25"
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.6.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 [String] The PNG encoded canvas as string.
120
- def encode_png_pixelstream(color_mode = ChunkyPNG::COLOR_TRUECOLOR, interlace = ChunkyPNG::INTERLACING_NONE)
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 [String] Th PNG encoded canvas as string.
136
- def encode_png_image_without_interlacing(color_mode)
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 [String] Th PNG encoded canvas as string.
150
- def encode_png_image_with_interlacing(color_mode)
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
- def encode_png_image_pass_to_stream(stream, color_mode)
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
- case color_mode
166
- when ChunkyPNG::COLOR_TRUECOLOR_ALPHA
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
- when ChunkyPNG::COLOR_TRUECOLOR
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 << encode_png_scanline_up(unencoded_bytes, previous_bytes, pixel_size).pack('C*')
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
@@ -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.6.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-02-25 00:00:00 -05:00
12
+ date: 2010-03-15 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency