chunky_png 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_DISABLE_SHARED_GEMS: "1"
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,22 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ chunky_png (0.9.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ gemcutter (0.6.1)
10
+ git (1.2.5)
11
+ rake (0.8.7)
12
+ rspec (1.3.0)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ chunky_png!
19
+ gemcutter
20
+ git
21
+ rake
22
+ rspec (>= 1.3)
data/README.rdoc CHANGED
@@ -19,10 +19,11 @@ Issue tracker:: http://github.com/wvanbergen/chunky_png/issues
19
19
  chosen automatically, based on the amount of used colors.
20
20
  * R/W access to the image's pixels.
21
21
  * R/W access to all image metadata that is stored in chunks.
22
- * Memory efficient (uses a Fixnum, i.e. 4 bytes of memory, per pixel)
22
+ * Memory efficient (uses a Fixnum, i.e. 4 or 8 bytes of memory per pixel, depending
23
+ on the hardware)
23
24
  * Reasonably fast for Ruby standards, by only using integer math and a highly
24
25
  optimized saving routine.
25
- * Interoperability with RMagick.
26
+ * Interoperability with RMagick if you really have to.
26
27
 
27
28
  == Classes
28
29
 
data/Rakefile CHANGED
@@ -1,4 +1,9 @@
1
1
  Dir['tasks/*.rake'].each { |file| load(file) }
2
2
 
3
+ require 'rubygems'
4
+ require 'bundler'
5
+
6
+ Bundler.setup
7
+
3
8
  GithubGem::RakeTasks.new(:gem)
4
9
  task :default => [:spec]
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.8.0"
7
- s.date = "2010-07-01"
6
+ s.version = "0.9.0"
7
+ s.date = "2010-08-18"
8
8
 
9
9
  s.summary = "Pure ruby library for read/write, chunk-level access to PNG files"
10
10
  s.description = <<-EOT
@@ -25,13 +25,16 @@ Gem::Specification.new do |s|
25
25
  s.email = ['willem@railsdoctors.com']
26
26
  s.homepage = 'http://wiki.github.com/wvanbergen/chunky_png'
27
27
 
28
- s.add_development_dependency('rspec', '>= 1.2.9')
28
+ s.add_development_dependency('rake')
29
+ s.add_development_dependency('rspec', '>= 1.3')
30
+ s.add_development_dependency('git')
31
+ s.add_development_dependency('gemcutter')
29
32
 
30
33
  s.rdoc_options << '--title' << s.name << '--main' << 'README.rdoc' << '--line-numbers' << '--inline-source'
31
34
  s.extra_rdoc_files = ['README.rdoc']
32
35
 
33
36
  # Do not change the files and test_files fields by hand. This will be done
34
37
  # automatically by the gem release script.
35
- s.files = %w(spec/spec_helper.rb spec/resources/ztxt_chunk.png spec/resources/text_chunk.png spec/resources/replaced.png spec/resources/pixelstream.rgb spec/resources/indexed_4bit.png spec/resources/gray_10x10_grayscale.png spec/resources/damaged_signature.png spec/resources/damaged_chunk.png spec/resources/clock_updated.png spec/chunky_png/canvas/png_encoding_spec.rb lib/chunky_png/canvas/stream_exporting.rb spec/resources/gray_10x10.png lib/chunky_png/color.rb lib/chunky_png/canvas/operations.rb spec/resources/clock.png .gitignore spec/resources/gray_10x10_truecolor_alpha.png spec/chunky_png/canvas_spec.rb LICENSE spec/resources/gray_10x10_truecolor.png spec/resources/composited.png spec/resources/clock_mask.png spec/chunky_png/color_spec.rb spec/chunky_png/canvas/adam7_interlacing_spec.rb lib/chunky_png/chunk.rb lib/chunky_png/canvas/stream_importing.rb lib/chunky_png/canvas/png_encoding.rb lib/chunky_png/canvas/adam7_interlacing.rb spec/resources/operations.png spec/chunky_png/canvas/png_decoding_spec.rb lib/chunky_png/canvas.rb Rakefile spec/resources/transparent_gray_10x10.png spec/resources/pixelstream.rgba spec/resources/cropped.png README.rdoc spec/resources/gray_10x10_indexed.png spec/resources/clock_base.png spec/resources/16x16_non_interlaced.png spec/chunky_png_spec.rb spec/chunky_png/canvas/drawing_spec.rb lib/chunky_png/palette.rb lib/chunky_png/datastream.rb chunky_png.gemspec tasks/github-gem.rake spec/resources/pixelstream_reference.png spec/resources/lines.png spec/resources/gray_10x10_grayscale_alpha.png spec/resources/16x16_interlaced.png spec/chunky_png/image_spec.rb lib/chunky_png/canvas/drawing.rb spec/resources/rect.png spec/resources/clock_mask_updated.png spec/resources/adam7.png lib/chunky_png/rmagick.rb lib/chunky_png/image.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png/datastream_spec.rb lib/chunky_png/canvas/png_decoding.rb lib/chunky_png.rb)
36
- s.test_files = %w(spec/chunky_png/canvas/png_encoding_spec.rb spec/chunky_png/canvas_spec.rb spec/chunky_png/color_spec.rb spec/chunky_png/canvas/adam7_interlacing_spec.rb spec/chunky_png/canvas/png_decoding_spec.rb spec/chunky_png_spec.rb spec/chunky_png/canvas/drawing_spec.rb spec/chunky_png/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png/datastream_spec.rb)
37
- end
38
+ s.files = %w(.bundle/config .gitignore Gemfile Gemfile.lock LICENSE README.rdoc Rakefile chunky_png.gemspec lib/chunky_png.rb lib/chunky_png/canvas.rb lib/chunky_png/canvas/adam7_interlacing.rb lib/chunky_png/canvas/drawing.rb lib/chunky_png/canvas/operations.rb lib/chunky_png/canvas/png_decoding.rb lib/chunky_png/canvas/png_encoding.rb lib/chunky_png/canvas/stream_exporting.rb lib/chunky_png/canvas/stream_importing.rb lib/chunky_png/chunk.rb lib/chunky_png/color.rb lib/chunky_png/datastream.rb lib/chunky_png/image.rb lib/chunky_png/palette.rb lib/chunky_png/rmagick.rb spec/chunky_png/canvas/adam7_interlacing_spec.rb spec/chunky_png/canvas/drawing_spec.rb spec/chunky_png/canvas/operations_spec.rb spec/chunky_png/canvas/png_decoding_spec.rb spec/chunky_png/canvas/png_encoding_spec.rb spec/chunky_png/canvas_spec.rb spec/chunky_png/color_spec.rb spec/chunky_png/datastream_spec.rb spec/chunky_png/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png_spec.rb spec/resources/16x16_interlaced.png spec/resources/16x16_non_interlaced.png spec/resources/adam7.png spec/resources/clock.png spec/resources/clock_base.png spec/resources/clock_flip_horizontally.png spec/resources/clock_flip_vertically.png spec/resources/clock_mask.png spec/resources/clock_mask_updated.png spec/resources/clock_rotate_180.png spec/resources/clock_rotate_left.png spec/resources/clock_rotate_right.png spec/resources/clock_stubbed.png spec/resources/clock_updated.png spec/resources/composited.png spec/resources/cropped.png spec/resources/damaged_chunk.png spec/resources/damaged_signature.png spec/resources/gray_10x10.png spec/resources/gray_10x10_grayscale.png spec/resources/gray_10x10_grayscale_alpha.png spec/resources/gray_10x10_indexed.png spec/resources/gray_10x10_truecolor.png spec/resources/gray_10x10_truecolor_alpha.png spec/resources/indexed_4bit.png spec/resources/lines.png spec/resources/operations.png spec/resources/pixelstream.rgb spec/resources/pixelstream.rgba spec/resources/pixelstream_reference.png spec/resources/rect.png spec/resources/replaced.png spec/resources/text_chunk.png spec/resources/transparent_gray_10x10.png spec/resources/ztxt_chunk.png spec/spec_helper.rb tasks/github-gem.rake)
39
+ s.test_files = %w(spec/chunky_png/canvas/adam7_interlacing_spec.rb spec/chunky_png/canvas/drawing_spec.rb spec/chunky_png/canvas/operations_spec.rb spec/chunky_png/canvas/png_decoding_spec.rb spec/chunky_png/canvas/png_encoding_spec.rb spec/chunky_png/canvas_spec.rb spec/chunky_png/color_spec.rb spec/chunky_png/datastream_spec.rb spec/chunky_png/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png_spec.rb)
40
+ end
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.8.0"
30
+ VERSION = "0.9.0"
31
31
 
32
32
  ###################################################
33
33
  # PNG international standard defined constants
@@ -51,19 +51,19 @@ module ChunkyPNG
51
51
  FILTER_UP = 2
52
52
  FILTER_AVERAGE = 3
53
53
  FILTER_PAETH = 4
54
-
54
+
55
55
  ###################################################
56
56
  # ChunkyPNG exception classes
57
57
  ###################################################
58
-
58
+
59
59
  # Default exception class for ChunkyPNG
60
60
  class Exception < ::StandardError
61
61
  end
62
-
62
+
63
63
  # Exception that is raised for an unsopported PNG image.
64
64
  class NotSupported < ChunkyPNG::Exception
65
65
  end
66
-
66
+
67
67
  # Exception that is raised if the PNG signature is not encountered at the
68
68
  # beginning of the file.
69
69
  class SignatureMismatch < ChunkyPNG::Exception
@@ -73,8 +73,11 @@ module ChunkyPNG
73
73
  class CRCMismatch < ChunkyPNG::Exception
74
74
  end
75
75
 
76
-
77
76
  # Exception that is raised if an expectation fails.
78
77
  class ExpectationFailed < ChunkyPNG::Exception
79
- end
78
+ end
79
+
80
+ # Exception that is raised if an expectation fails.
81
+ class OutOfBounds < ChunkyPNG::ExpectationFailed
82
+ end
80
83
  end
@@ -98,6 +98,7 @@ module ChunkyPNG
98
98
  # @param [Integer] y The y-coordinate of the pixel (row)
99
99
  # @param [ChunkyPNG::Color] pixel The new pixel for the provided coordinates.
100
100
  def []=(x, y, color)
101
+ assert_xy!(x, y)
101
102
  @pixels[y * width + x] = color
102
103
  end
103
104
 
@@ -106,16 +107,67 @@ module ChunkyPNG
106
107
  # @param [Integer] y The y-coordinate of the pixel (row)
107
108
  # @return [ChunkyPNG::Color] The current pixel at the provided coordinates.
108
109
  def [](x, y)
110
+ assert_xy!(x, y)
109
111
  @pixels[y * width + x]
110
112
  end
111
-
113
+
114
+ # Returns an extracted row as vector of pixels
115
+ # @param [Integer] y The 0-based row index
116
+ # @return [Array<Integer>] The vector of pixels in the requested row
117
+ def row(y)
118
+ assert_y!(y)
119
+ pixels.slice(y * width, width)
120
+ end
121
+
122
+ # Returns an extracted column as vector of pixels.
123
+ # @param [Integer] x The 0-based column index.
124
+ # @return [Array<Integer>] The vector of pixels in the requested column.
125
+ def column(x)
126
+ assert_x!(x)
127
+ (0...height).inject([]) { |pixels, y| pixels << self[x, y] }
128
+ end
129
+
130
+ # Replaces a row of pixels on this canvas.
131
+ # @param [Integer] y The 0-based row index.
132
+ # @param [Array<Integer>] vector The vector of pixels to replace the row with.
133
+ def replace_row!(y, vector)
134
+ assert_y!(y) && assert_width!(vector.length)
135
+ pixels[y * width, width] = vector
136
+ end
137
+
138
+ # Replaces a column of pixels on this canvas.
139
+ # @param [Integer] x The 0-based column index.
140
+ # @param [Array<Integer>] vector The vector of pixels to replace the column with.
141
+ def replace_column!(x, vector)
142
+ assert_x!(x) && assert_height!(vector.length)
143
+ for y in 0...height do
144
+ self[x, y] = vector[y]
145
+ end
146
+ end
147
+
112
148
  # Checks whether the given coordinates are in the range of the canvas
113
149
  # @param [Integer] x The x-coordinate of the pixel (column)
114
150
  # @param [Integer] y The y-coordinate of the pixel (row)
115
151
  # @return [true, false] True if the x and y coordinate are in the range
116
152
  # of this canvas.
117
- def include?(x, y)
118
- (0...width).include?(x) && (0...height).include?(y)
153
+ def include_xy?(x, y)
154
+ include_x?(x) && include_y?(y)
155
+ end
156
+
157
+ alias_method :include?, :include_xy?
158
+
159
+ # Checks whether the given y-coordinate is in the range of the canvas
160
+ # @param [Integer] y The y-coordinate of the pixel (row)
161
+ # @return [true, false] True if the y-coordinate is in the range of this canvas.
162
+ def include_y?(y)
163
+ y >= 0 && y < height
164
+ end
165
+
166
+ # Checks whether the given x-coordinate is in the range of the canvas
167
+ # @param [Integer] x The y-coordinate of the pixel (column)
168
+ # @return [true, false] True if the x-coordinate is in the range of this canvas.
169
+ def include_x?(x)
170
+ x >= 0 && x < width
119
171
  end
120
172
 
121
173
  # Returns the palette used for this canvas.
@@ -145,5 +197,52 @@ module ChunkyPNG
145
197
  def to_image
146
198
  ChunkyPNG::Image.from_canvas(self)
147
199
  end
200
+
201
+ #################################################################
202
+ # RUBY 1.8.6 compatibility
203
+ #################################################################
204
+
205
+ unless respond_to?(:tap)
206
+ def tap(&block)
207
+ yield(self)
208
+ self
209
+ end
210
+ end
211
+
212
+ protected
213
+
214
+ # Throws an exception if the x-coordinate is out of bounds.
215
+ def assert_x!(x)
216
+ raise ChunkyPNG::OutOfBounds, "Column index out of bounds!" unless include_x?(x)
217
+ return true
218
+ end
219
+
220
+ # Throws an exception if the y-coordinate is out of bounds.
221
+ def assert_y!(y)
222
+ raise ChunkyPNG::OutOfBounds, "Row index out of bounds!" unless include_y?(y)
223
+ return true
224
+ end
225
+
226
+ # Throws an exception if the x- or y-coordinate is out of bounds.
227
+ def assert_xy!(x, y)
228
+ raise ChunkyPNG::OutOfBounds, "Coordinates out of bounds!" unless include_xy?(x, y)
229
+ return true
230
+ end
231
+
232
+ def assert_height!(vector_length)
233
+ raise ChunkyPNG::ExpectationFailed, "The length of the vector does not match the canvas height!" if height != vector_length
234
+ return true
235
+ end
236
+
237
+ def assert_width!(vector_length)
238
+ raise ChunkyPNG::ExpectationFailed, "The length of the vector does not match the canvas width!" if width != vector_length
239
+ return true
240
+ end
241
+
242
+ def assert_size!(matrix_width, matrix_height)
243
+ raise ChunkyPNG::ExpectationFailed, "The width of the matrix does not match the canvas width!" if width != matrix_width
244
+ raise ChunkyPNG::ExpectationFailed, "The height of the matrix does not match the canvas height!" if height != matrix_height
245
+ return true
246
+ end
148
247
  end
149
248
  end
@@ -39,9 +39,9 @@ module ChunkyPNG
39
39
  e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
40
40
  x0 = x0 + sx if (e_acc <= e_acc_temp)
41
41
  w = 0xff - (e_acc >> 8)
42
- point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include?(x0, y0)
42
+ point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include_xy?(x0, y0)
43
43
  y0 = y0 + 1
44
- point(x0 + sx, y0, ChunkyPNG::Color.fade(color, 0xff - w)) if include?(x0 + sx, y0)
44
+ point(x0 + sx, y0, ChunkyPNG::Color.fade(color, 0xff - w)) if include_xy?(x0 + sx, y0)
45
45
  end
46
46
  point(x1, y1, color)
47
47
 
@@ -53,9 +53,9 @@ module ChunkyPNG
53
53
  e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
54
54
  y0 += 1 if (e_acc <= e_acc_temp)
55
55
  w = 0xff - (e_acc >> 8)
56
- point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include?(x0, y0)
56
+ point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include_xy?(x0, y0)
57
57
  x0 += sx
58
- point(x0, y0 + 1, ChunkyPNG::Color.fade(color, 0xff - w)) if include?(x0, y0 + 1)
58
+ point(x0, y0 + 1, ChunkyPNG::Color.fade(color, 0xff - w)) if include_xy?(x0, y0 + 1)
59
59
  end
60
60
  point(x1, y1, color)
61
61
  end
@@ -56,6 +56,46 @@ module ChunkyPNG
56
56
  raise ChunkyPNG::ExpectationFailed, "This is not a mask image!" if palette.opaque_palette.size != 1
57
57
  pixels.map! { |pixel| (new_color & 0xffffff00) | ChunkyPNG::Color.a(pixel) }
58
58
  end
59
+
60
+ def flip_horizontally
61
+ self.class.new(width, height).tap do |flipped|
62
+ for y in 0...height do
63
+ flipped.replace_row!(height - (y + 1), row(y))
64
+ end
65
+ end
66
+ end
67
+
68
+ def flip_vertically
69
+ self.class.new(width, height).tap do |flipped|
70
+ for x in 0...width do
71
+ flipped.replace_column!(width - (x + 1), column(x))
72
+ end
73
+ end
74
+ end
75
+
76
+ def rotate_right
77
+ self.class.new(height, width).tap do |rotated|
78
+ for i in 0...width do
79
+ rotated.replace_row!(i, column(i).reverse)
80
+ end
81
+ end
82
+ end
83
+
84
+ def rotate_left
85
+ self.class.new(height, width).tap do |rotated|
86
+ for i in 0...width do
87
+ rotated.replace_row!(width - (i + 1), column(i))
88
+ end
89
+ end
90
+ end
91
+
92
+ def rotate_180
93
+ self.class.new(width, height).tap do |flipped|
94
+ for y in 0...height do
95
+ flipped.replace_row!(height - (y + 1), row(y).reverse)
96
+ end
97
+ end
98
+ end
59
99
 
60
100
  protected
61
101
 
@@ -52,7 +52,18 @@ module ChunkyPNG
52
52
  alias :to_s :to_blob
53
53
 
54
54
  # Converts this Canvas to a datastream, so that it can be saved as a PNG image.
55
- # @param [Hash] constraints The constraints to use when encoding the canvas.
55
+ # @param [Hash, Symbol] constraints The constraints to use when encoding the canvas.
56
+ # This can either be a hash with different constraints, or a symbol which acts as a
57
+ # preset for some constraints. If no constraints are given, ChunkyPNG will decide
58
+ # for itself how to best create the PNG datastream.
59
+ # Supported presets are :fast_rgba for quickly saving images with transparency,
60
+ # :fast_rgb for quickly saving opaque images, and :best_compression to obtain the
61
+ # smallest possible filesize.
62
+ # @option constraints [Fixnum] :color_mode The color mode to use. Use one of the
63
+ # ChunkyPNG::COLOR_* constants.
64
+ # @option constraints [true, false] :interlace Whether to use interlacing.
65
+ # @option constraints [Fixnum] :compression The compression level for Zlib. This can be a
66
+ # value between 0 and 9, or a Zlib constant like Zlib::BEST_COMPRESSION.
56
67
  # @return [ChunkyPNG::Datastream] The PNG datastream containing the encoded canvas.
57
68
  # @see ChunkyPNG::Canvas::PNGEncoding#determine_png_encoding
58
69
  def to_datastream(constraints = {})
@@ -81,7 +92,8 @@ module ChunkyPNG
81
92
  # You can provide constraints for the encoding variables by passing a hash with
82
93
  # encoding variables to this method.
83
94
  #
84
- # @param [Hash] constraints The constraints for the encoding.
95
+ # @param [Hash, Symbol] constraints The constraints for the encoding. This can be a
96
+ # Hash or a preset symbol.
85
97
  # @return [Hash] A hash with encoding options for {ChunkyPNG::Canvas::PNGEncoding#to_datastream}
86
98
  def determine_png_encoding(constraints = {})
87
99
 
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ describe ChunkyPNG::Canvas::Operations do
4
+ describe '#crop' do
5
+ before(:each) do
6
+ @canvas = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
7
+ end
8
+
9
+ it "should crop the right pixels from the original canvas" do
10
+ cropped = @canvas.crop(10, 5, 4, 8)
11
+ cropped.should == reference_canvas('cropped')
12
+ end
13
+ end
14
+
15
+ describe '#compose' do
16
+ it "should compose pixels correctly" do
17
+ canvas = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
18
+ subcanvas = ChunkyPNG::Canvas.new(4, 8, ChunkyPNG::Color.rgba(0, 0, 0, 75))
19
+ canvas.compose(subcanvas, 8, 4)
20
+ canvas.should == reference_canvas('composited')
21
+ end
22
+
23
+ it "should compose a base image and mask correctly" do
24
+ base = reference_canvas('clock_base')
25
+ mask = reference_canvas('clock_mask_updated')
26
+ base.compose(mask).should == reference_canvas('clock_updated')
27
+ end
28
+ end
29
+
30
+ describe '#replace' do
31
+ before(:each) do
32
+ @canvas = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
33
+ end
34
+
35
+ it "should replace the correct pixels" do
36
+ subcanvas = ChunkyPNG::Canvas.new(3, 2, ChunkyPNG::Color.rgb(200, 255, 0))
37
+ @canvas.replace(subcanvas, 5, 4)
38
+ @canvas.should == reference_canvas('replaced')
39
+ end
40
+ end
41
+
42
+ describe '#change_theme_color!' do
43
+
44
+ before(:each) do
45
+ @theme_color = ChunkyPNG::Color.from_hex('#e10f7a')
46
+ @new_color = ChunkyPNG::Color.from_hex('#ff0000')
47
+ @canvas = reference_canvas('clock')
48
+ end
49
+
50
+ it "should change the theme color correctly" do
51
+ @canvas.change_theme_color!(@theme_color, @new_color)
52
+ @canvas.should == reference_canvas('clock_updated')
53
+ end
54
+ end
55
+
56
+ describe '#extract_mask' do
57
+ before(:each) do
58
+ @mask_color = ChunkyPNG::Color.from_hex('#e10f7a')
59
+ @canvas = reference_canvas('clock')
60
+ end
61
+
62
+ it "should create the correct base and mask image" do
63
+ base, mask = @canvas.extract_mask(@mask_color, ChunkyPNG::Color::WHITE)
64
+ base.should == reference_canvas('clock_base')
65
+ mask.should == reference_canvas('clock_mask')
66
+ end
67
+
68
+ it "should create a mask image with only one opaque color" do
69
+ base, mask = @canvas.extract_mask(@mask_color, ChunkyPNG::Color::WHITE)
70
+ mask.palette.opaque_palette.size.should == 1
71
+ end
72
+ end
73
+
74
+ describe '#change_mask_color!' do
75
+ before(:each) do
76
+ @new_color = ChunkyPNG::Color.from_hex('#ff0000')
77
+ @mask = reference_canvas('clock_mask')
78
+ end
79
+
80
+ it "should replace the mask color correctly" do
81
+ @mask.change_mask_color!(@new_color)
82
+ @mask.should == reference_canvas('clock_mask_updated')
83
+ end
84
+
85
+ it "should still only have one opaque color" do
86
+ @mask.change_mask_color!(@new_color)
87
+ @mask.palette.opaque_palette.size.should == 1
88
+ end
89
+ end
90
+
91
+ describe '#flip_horizontally' do
92
+ it "should flip the pixels horizontally" do
93
+ reference_canvas('clock_stubbed').flip_horizontally.should == reference_canvas('clock_flip_horizontally')
94
+ end
95
+ end
96
+
97
+ describe '#flip_vertically' do
98
+ it "should flip the pixels vertically" do
99
+ reference_canvas('clock_stubbed').flip_vertically.should == reference_canvas('clock_flip_vertically')
100
+ end
101
+ end
102
+
103
+ describe '#rotate_left' do
104
+ it "should rotate the pixels 90 degrees counter-clockwise" do
105
+ reference_canvas('clock_stubbed').rotate_left.should == reference_canvas('clock_rotate_left')
106
+ end
107
+ end
108
+
109
+ describe '#rotate_right' do
110
+ it "should rotate the pixels 90 degrees clockwise" do
111
+ reference_canvas('clock_stubbed').rotate_right.should == reference_canvas('clock_rotate_right')
112
+ end
113
+ end
114
+
115
+ describe '#rotate_180' do
116
+ it "should rotate the pixels 180 degrees" do
117
+ reference_canvas('clock_stubbed').rotate_180.should == reference_canvas('clock_rotate_180')
118
+ end
119
+ end
120
+ end
@@ -21,111 +21,48 @@ describe ChunkyPNG::Canvas do
21
21
  end
22
22
 
23
23
  describe '#to_rgba_stream' do
24
- before(:each) do
25
- File.open(resource_file('pixelstream.rgba'), 'rb') { |f| @reference_data = f.read }
26
- end
24
+ before { File.open(resource_file('pixelstream.rgba'), 'rb') { |f| @reference_data = f.read } }
27
25
 
28
26
  it "should load an image correctly from a datastream" do
29
- canvas = reference_canvas('pixelstream_reference')
30
- canvas.to_rgba_stream.should == @reference_data
27
+ reference_canvas('pixelstream_reference').to_rgba_stream.should == @reference_data
31
28
  end
32
29
  end
33
30
 
34
31
  describe '#to_rgb_stream' do
35
- before(:each) do
36
- File.open(resource_file('pixelstream.rgb'), 'rb') { |f| @reference_data = f.read }
37
- end
32
+ before { File.open(resource_file('pixelstream.rgb'), 'rb') { |f| @reference_data = f.read } }
38
33
 
39
34
  it "should load an image correctly from a datastream" do
40
- canvas = reference_canvas('pixelstream_reference')
41
- canvas.to_rgb_stream.should == @reference_data
35
+ reference_canvas('pixelstream_reference').to_rgb_stream.should == @reference_data
42
36
  end
43
37
  end
38
+
39
+ describe '#row' do
40
+ before { @canvas = reference_canvas('operations') }
44
41
 
45
- describe '#crop' do
46
- before(:each) do
47
- @canvas = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
42
+ it "should give an out of bounds exception when y-coordinate is out of bounds" do
43
+ lambda { @canvas.row(-1) }.should raise_error(ChunkyPNG::OutOfBounds)
44
+ lambda { @canvas.row(16) }.should raise_error(ChunkyPNG::OutOfBounds)
48
45
  end
49
46
 
50
- it "should crop the right pixels from the original canvas" do
51
- cropped = @canvas.crop(10, 5, 4, 8)
52
- cropped.should == reference_canvas('cropped')
47
+ it "should return the correct pixels" do
48
+ data = @canvas.row(0)
49
+ data.should have(@canvas.width).items
50
+ data.should == [65535, 268500991, 536936447, 805371903, 1073807359, 1342242815, 1610678271, 1879113727, 2147549183, 2415984639, 2684420095, 2952855551, 3221291007, 3489726463, 3758161919, 4026597375]
53
51
  end
54
52
  end
55
53
 
56
- describe '#compose' do
57
- it "should compose pixels correctly" do
58
- canvas = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
59
- subcanvas = ChunkyPNG::Canvas.new(4, 8, ChunkyPNG::Color.rgba(0, 0, 0, 75))
60
- canvas.compose(subcanvas, 8, 4)
61
- canvas.should == reference_canvas('composited')
62
- end
63
-
64
- it "should compose a base image and mask correctly" do
65
- base = reference_canvas('clock_base')
66
- mask = reference_canvas('clock_mask_updated')
67
- base.compose(mask).should == reference_canvas('clock_updated')
68
- end
69
- end
54
+ describe '#column' do
55
+ before { @canvas = reference_canvas('operations') }
70
56
 
71
- describe '#replace' do
72
- before(:each) do
73
- @canvas = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
57
+ it "should give an out of bounds exception when x-coordinate is out of bounds" do
58
+ lambda { @canvas.column(-1) }.should raise_error(ChunkyPNG::OutOfBounds)
59
+ lambda { @canvas.column(16) }.should raise_error(ChunkyPNG::OutOfBounds)
74
60
  end
75
61
 
76
- it "should replace the correct pixels" do
77
- subcanvas = ChunkyPNG::Canvas.new(3, 2, ChunkyPNG::Color.rgb(200, 255, 0))
78
- @canvas.replace(subcanvas, 5, 4)
79
- @canvas.should == reference_canvas('replaced')
80
- end
81
- end
82
-
83
- describe '#change_theme_color!' do
84
-
85
- before(:each) do
86
- @theme_color = ChunkyPNG::Color.from_hex('#e10f7a')
87
- @new_color = ChunkyPNG::Color.from_hex('#ff0000')
88
- @canvas = reference_canvas('clock')
89
- end
90
-
91
- it "should change the theme color correctly" do
92
- @canvas.change_theme_color!(@theme_color, @new_color)
93
- @canvas.should == reference_canvas('clock_updated')
94
- end
95
- end
96
-
97
- describe '#extract_mask' do
98
- before(:each) do
99
- @mask_color = ChunkyPNG::Color.from_hex('#e10f7a')
100
- @canvas = reference_canvas('clock')
101
- end
102
-
103
- it "should create the correct base and mask image" do
104
- base, mask = @canvas.extract_mask(@mask_color, ChunkyPNG::Color::WHITE)
105
- base.should == reference_canvas('clock_base')
106
- mask.should == reference_canvas('clock_mask')
107
- end
108
-
109
- it "should create a mask image with only one opaque color" do
110
- base, mask = @canvas.extract_mask(@mask_color, ChunkyPNG::Color::WHITE)
111
- mask.palette.opaque_palette.size.should == 1
112
- end
113
- end
114
-
115
- describe '#change_mask_color!' do
116
- before(:each) do
117
- @new_color = ChunkyPNG::Color.from_hex('#ff0000')
118
- @mask = reference_canvas('clock_mask')
119
- end
120
-
121
- it "should replace the mask color correctly" do
122
- @mask.change_mask_color!(@new_color)
123
- @mask.should == reference_canvas('clock_mask_updated')
124
- end
125
-
126
- it "should still only have one opaque color" do
127
- @mask.change_mask_color!(@new_color)
128
- @mask.palette.opaque_palette.size.should == 1
62
+ it "should return the correct pixels" do
63
+ data = @canvas.column(0)
64
+ data.should have(@canvas.height).items
65
+ data.should == [65535, 1114111, 2162687, 3211263, 4259839, 5308415, 6356991, 7405567, 8454143, 9502719, 10551295, 11599871, 12648447, 13697023, 14745599, 15794175]
129
66
  end
130
67
  end
131
68
  end
Binary file
Binary file
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
 
3
3
  require 'rubygems'
4
- require 'spec'
4
+ require 'bundler'
5
+
6
+ Bundler.setup
5
7
 
8
+ require 'spec'
6
9
  require 'chunky_png'
7
10
 
8
11
  module ResourceFileHelper
@@ -134,8 +134,8 @@ module GithubGem
134
134
  desc "Release the next version of the gem, by incrementing the last version segment by 1"
135
135
  task(:next => [:next_version] + release_tasks) { release_task }
136
136
 
137
- desc "Release the next version of the gem, using a bump increment (0.0.1)"
138
- task(:bump => [:next_bump_version] + release_tasks) { release_task }
137
+ desc "Release the next version of the gem, using a patch increment (0.0.1)"
138
+ task(:patch => [:next_patch_version] + release_tasks) { release_task }
139
139
 
140
140
  desc "Release the next version of the gem, using a minor increment (0.1.0)"
141
141
  task(:minor => [:next_minor_version] + release_tasks) { release_task }
@@ -152,7 +152,7 @@ module GithubGem
152
152
  task(:commit_modified_files) { commit_modified_files_task }
153
153
 
154
154
  task(:next_version) { next_version_task }
155
- task(:next_bump_version) { next_version_task(:bump) }
155
+ task(:next_patch_version) { next_version_task(:patch) }
156
156
  task(:next_minor_version) { next_version_task(:minor) }
157
157
  task(:next_major_version) { next_version_task(:major) }
158
158
 
@@ -187,7 +187,7 @@ module GithubGem
187
187
  next_version = newest_version.segments
188
188
  increment_index = case increment
189
189
  when :micro then 3
190
- when :bump then 2
190
+ when :patch then 2
191
191
  when :minor then 1
192
192
  when :major then 0
193
193
  else next_version.length - 1
@@ -217,7 +217,7 @@ module GithubGem
217
217
 
218
218
  def check_version_task
219
219
  raise "#{ENV['VERSION']} is not a valid version number!" if ENV['VERSION'] && !Gem::Version.correct?(ENV['VERSION'])
220
- proposed_version = Gem::Version.new(ENV['VERSION'] || gemspec.version)
220
+ proposed_version = Gem::Version.new(ENV['VERSION'].dup || gemspec.version)
221
221
  raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version >= proposed_version
222
222
  end
223
223
 
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chunky_png
3
3
  version: !ruby/object:Gem::Version
4
- hash: 63
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 8
7
+ - 9
9
8
  - 0
10
- version: 0.8.0
9
+ version: 0.9.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Willem van Bergen
@@ -15,25 +14,62 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-07-01 00:00:00 +02:00
17
+ date: 2010-08-18 00:00:00 -04:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
- name: rspec
23
- prerelease: false
21
+ name: rake
24
22
  requirement: &id001 !ruby/object:Gem::Requirement
25
23
  none: false
26
24
  requirements:
27
25
  - - ">="
28
26
  - !ruby/object:Gem::Version
29
- hash: 13
30
27
  segments:
31
- - 1
32
- - 2
33
- - 9
34
- version: 1.2.9
28
+ - 0
29
+ version: "0"
35
30
  type: :development
31
+ prerelease: false
36
32
  version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 1
42
+ - 3
43
+ version: "1.3"
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *id002
47
+ - !ruby/object:Gem::Dependency
48
+ name: git
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: gemcutter
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: *id004
37
73
  description: " This pure Ruby library can read and write PNG images without depending on an external \n image library, like RMagick. It tries to be memory efficient and reasonably fast.\n \n It supports reading and writing all PNG variants that are defined in the specification, \n with one limitation: only 8-bit color depth is supported. It supports all transparency, \n interlacing and filtering options the PNG specifications allows. It can also read and \n write textual metadata from PNG files. Low-level read/write access to PNG chunks is\n also possible.\n \n This library supports simple drawing on the image canvas and simple operations like alpha composition\n and cropping. Finally, it can import from and export to RMagick for interoperability. \n"
38
74
  email:
39
75
  - willem@railsdoctors.com
@@ -44,67 +80,77 @@ extensions: []
44
80
  extra_rdoc_files:
45
81
  - README.rdoc
46
82
  files:
47
- - spec/spec_helper.rb
48
- - spec/resources/ztxt_chunk.png
49
- - spec/resources/text_chunk.png
50
- - spec/resources/replaced.png
51
- - spec/resources/pixelstream.rgb
52
- - spec/resources/indexed_4bit.png
53
- - spec/resources/gray_10x10_grayscale.png
54
- - spec/resources/damaged_signature.png
55
- - spec/resources/damaged_chunk.png
56
- - spec/resources/clock_updated.png
57
- - spec/chunky_png/canvas/png_encoding_spec.rb
58
- - lib/chunky_png/canvas/stream_exporting.rb
59
- - spec/resources/gray_10x10.png
60
- - lib/chunky_png/color.rb
61
- - lib/chunky_png/canvas/operations.rb
62
- - spec/resources/clock.png
83
+ - .bundle/config
63
84
  - .gitignore
64
- - spec/resources/gray_10x10_truecolor_alpha.png
65
- - spec/chunky_png/canvas_spec.rb
85
+ - Gemfile
86
+ - Gemfile.lock
66
87
  - LICENSE
67
- - spec/resources/gray_10x10_truecolor.png
68
- - spec/resources/composited.png
69
- - spec/resources/clock_mask.png
70
- - spec/chunky_png/color_spec.rb
71
- - spec/chunky_png/canvas/adam7_interlacing_spec.rb
72
- - lib/chunky_png/chunk.rb
73
- - lib/chunky_png/canvas/stream_importing.rb
74
- - lib/chunky_png/canvas/png_encoding.rb
88
+ - README.rdoc
89
+ - Rakefile
90
+ - chunky_png.gemspec
91
+ - lib/chunky_png.rb
92
+ - lib/chunky_png/canvas.rb
75
93
  - lib/chunky_png/canvas/adam7_interlacing.rb
76
- - spec/resources/operations.png
94
+ - lib/chunky_png/canvas/drawing.rb
95
+ - lib/chunky_png/canvas/operations.rb
96
+ - lib/chunky_png/canvas/png_decoding.rb
97
+ - lib/chunky_png/canvas/png_encoding.rb
98
+ - lib/chunky_png/canvas/stream_exporting.rb
99
+ - lib/chunky_png/canvas/stream_importing.rb
100
+ - lib/chunky_png/chunk.rb
101
+ - lib/chunky_png/color.rb
102
+ - lib/chunky_png/datastream.rb
103
+ - lib/chunky_png/image.rb
104
+ - lib/chunky_png/palette.rb
105
+ - lib/chunky_png/rmagick.rb
106
+ - spec/chunky_png/canvas/adam7_interlacing_spec.rb
107
+ - spec/chunky_png/canvas/drawing_spec.rb
108
+ - spec/chunky_png/canvas/operations_spec.rb
77
109
  - spec/chunky_png/canvas/png_decoding_spec.rb
78
- - lib/chunky_png/canvas.rb
79
- - Rakefile
80
- - spec/resources/transparent_gray_10x10.png
81
- - spec/resources/pixelstream.rgba
110
+ - spec/chunky_png/canvas/png_encoding_spec.rb
111
+ - spec/chunky_png/canvas_spec.rb
112
+ - spec/chunky_png/color_spec.rb
113
+ - spec/chunky_png/datastream_spec.rb
114
+ - spec/chunky_png/image_spec.rb
115
+ - spec/chunky_png/rmagick_spec.rb
116
+ - spec/chunky_png_spec.rb
117
+ - spec/resources/16x16_interlaced.png
118
+ - spec/resources/16x16_non_interlaced.png
119
+ - spec/resources/adam7.png
120
+ - spec/resources/clock.png
121
+ - spec/resources/clock_base.png
122
+ - spec/resources/clock_flip_horizontally.png
123
+ - spec/resources/clock_flip_vertically.png
124
+ - spec/resources/clock_mask.png
125
+ - spec/resources/clock_mask_updated.png
126
+ - spec/resources/clock_rotate_180.png
127
+ - spec/resources/clock_rotate_left.png
128
+ - spec/resources/clock_rotate_right.png
129
+ - spec/resources/clock_stubbed.png
130
+ - spec/resources/clock_updated.png
131
+ - spec/resources/composited.png
82
132
  - spec/resources/cropped.png
83
- - README.rdoc
133
+ - spec/resources/damaged_chunk.png
134
+ - spec/resources/damaged_signature.png
135
+ - spec/resources/gray_10x10.png
136
+ - spec/resources/gray_10x10_grayscale.png
137
+ - spec/resources/gray_10x10_grayscale_alpha.png
84
138
  - spec/resources/gray_10x10_indexed.png
85
- - spec/resources/clock_base.png
86
- - spec/resources/16x16_non_interlaced.png
87
- - spec/chunky_png_spec.rb
88
- - spec/chunky_png/canvas/drawing_spec.rb
89
- - lib/chunky_png/palette.rb
90
- - lib/chunky_png/datastream.rb
91
- - chunky_png.gemspec
92
- - tasks/github-gem.rake
93
- - spec/resources/pixelstream_reference.png
139
+ - spec/resources/gray_10x10_truecolor.png
140
+ - spec/resources/gray_10x10_truecolor_alpha.png
141
+ - spec/resources/indexed_4bit.png
94
142
  - spec/resources/lines.png
95
- - spec/resources/gray_10x10_grayscale_alpha.png
96
- - spec/resources/16x16_interlaced.png
97
- - spec/chunky_png/image_spec.rb
98
- - lib/chunky_png/canvas/drawing.rb
143
+ - spec/resources/operations.png
144
+ - spec/resources/pixelstream.rgb
145
+ - spec/resources/pixelstream.rgba
146
+ - spec/resources/pixelstream_reference.png
99
147
  - spec/resources/rect.png
100
- - spec/resources/clock_mask_updated.png
101
- - spec/resources/adam7.png
102
- - lib/chunky_png/rmagick.rb
103
- - lib/chunky_png/image.rb
104
- - spec/chunky_png/rmagick_spec.rb
105
- - spec/chunky_png/datastream_spec.rb
106
- - lib/chunky_png/canvas/png_decoding.rb
107
- - lib/chunky_png.rb
148
+ - spec/resources/replaced.png
149
+ - spec/resources/text_chunk.png
150
+ - spec/resources/transparent_gray_10x10.png
151
+ - spec/resources/ztxt_chunk.png
152
+ - spec/spec_helper.rb
153
+ - tasks/github-gem.rake
108
154
  has_rdoc: true
109
155
  homepage: http://wiki.github.com/wvanbergen/chunky_png
110
156
  licenses: []
@@ -124,7 +170,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
124
170
  requirements:
125
171
  - - ">="
126
172
  - !ruby/object:Gem::Version
127
- hash: 3
173
+ hash: 2219291082232343403
128
174
  segments:
129
175
  - 0
130
176
  version: "0"
@@ -133,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
179
  requirements:
134
180
  - - ">="
135
181
  - !ruby/object:Gem::Version
136
- hash: 3
182
+ hash: 2219291082232343403
137
183
  segments:
138
184
  - 0
139
185
  version: "0"
@@ -145,13 +191,14 @@ signing_key:
145
191
  specification_version: 3
146
192
  summary: Pure ruby library for read/write, chunk-level access to PNG files
147
193
  test_files:
194
+ - spec/chunky_png/canvas/adam7_interlacing_spec.rb
195
+ - spec/chunky_png/canvas/drawing_spec.rb
196
+ - spec/chunky_png/canvas/operations_spec.rb
197
+ - spec/chunky_png/canvas/png_decoding_spec.rb
148
198
  - spec/chunky_png/canvas/png_encoding_spec.rb
149
199
  - spec/chunky_png/canvas_spec.rb
150
200
  - spec/chunky_png/color_spec.rb
151
- - spec/chunky_png/canvas/adam7_interlacing_spec.rb
152
- - spec/chunky_png/canvas/png_decoding_spec.rb
153
- - spec/chunky_png_spec.rb
154
- - spec/chunky_png/canvas/drawing_spec.rb
201
+ - spec/chunky_png/datastream_spec.rb
155
202
  - spec/chunky_png/image_spec.rb
156
203
  - spec/chunky_png/rmagick_spec.rb
157
- - spec/chunky_png/datastream_spec.rb
204
+ - spec/chunky_png_spec.rb