chunky_png 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -16,7 +16,7 @@ Issue tracker:: http://github.com/wvanbergen/chunky_png/issues
16
16
  color modes and all transparency, interlacing and filtering options.
17
17
  * Encodes images supports all color modes (true color, grayscale and indexed)
18
18
  and transparency for all these color modes. The best color mode will be
19
- chosen automatically, based on the image's colors.
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
22
  * Memory efficient (uses a Fixnum, i.e. 4 bytes of memory, per pixel)
@@ -26,12 +26,12 @@ Issue tracker:: http://github.com/wvanbergen/chunky_png/issues
26
26
 
27
27
  == Classes
28
28
 
29
- The main classes used within ChunkyPNG are:
29
+ The main classes and modules used within ChunkyPNG are:
30
30
 
31
31
  <tt>ChunkyPNG::Image</tt> :: create PNG images from scratch or based on another PNG image.
32
32
  <tt>ChunkyPNG::Datastream</tt> :: low-level read and write access to PNG images from or to a file or stream.
33
33
  <tt>ChunkyPNG::Canvas</tt> :: represents an image canvas as a matrix of pixels.
34
- <tt>ChunkyPNG::Color</tt> :: represents a, RGBA color
34
+ <tt>ChunkyPNG::Color</tt> :: to handle Fixnums as color values.
35
35
 
36
36
  == Usage
37
37
 
@@ -53,19 +53,17 @@ The main classes used within ChunkyPNG are:
53
53
  image = ChunkyPNG::Image.from_file('with_metadata.png')
54
54
  puts image.metadata['Title']
55
55
  image.metadata['Author'] = 'Willem van Bergen'
56
- image.save('with_metadata.png') # Overwrite
56
+ image.save('with_metadata.png') # Overwrite file
57
57
 
58
58
  # Low level access to PNG chunks
59
59
  png_stream = ChunkyPNG::Datastream.from_file('filename.png')
60
60
  png_stream.each_chunk { |chunk| p chunk.type }
61
61
 
62
- (Note: this is subject to change while work is in progress)
63
-
64
62
  == About
65
63
 
66
64
  The library is written by Willem van Bergen for Floorplanner.com, and released
67
65
  under the MIT license (see LICENSE). Please contact me for questions or
68
- remarks. Patches are greatly appreciated! :-)
66
+ remarks. Patches are greatly appreciated!
69
67
 
70
68
  P.S.: The name of this library is intentionally similar to Chunky Bacon and
71
- Chunky GIF. Use Google if you want to know _why.
69
+ Chunky GIF. Use Google if you want to know _why. :-)
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.5.3"
7
- s.date = "2010-01-17"
6
+ s.version = "0.5.4"
7
+ s.date = "2010-01-18"
8
8
 
9
9
  s.summary = "Pure ruby library for read/write, chunk-level access to PNG files"
10
10
  s.description = <<-EOT
@@ -32,6 +32,6 @@ Gem::Specification.new do |s|
32
32
 
33
33
  # Do not change the files and test_files fields by hand. This will be done
34
34
  # 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/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 .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/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/16x16_non_interlaced.png spec/chunky_png_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/gray_10x10_grayscale_alpha.png spec/resources/16x16_interlaced.png spec/chunky_png/image_spec.rb lib/chunky_png/canvas/drawing.rb 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/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png/datastream_spec.rb)
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/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 .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/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/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/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
37
  end
data/lib/chunky_png.rb CHANGED
@@ -16,15 +16,17 @@ require 'chunky_png/canvas/drawing'
16
16
  require 'chunky_png/canvas'
17
17
  require 'chunky_png/image'
18
18
 
19
- # ChunkyPNG
19
+ # ChunkyPNG - the pury ruby library to access PNG files.
20
20
  #
21
21
  # The ChunkyPNG module defines some constants that are used in the
22
22
  # PNG specification.
23
+ #
24
+ # @author Willem van Bergen
23
25
  module ChunkyPNG
24
26
 
25
27
  # The current version of ChunkyPNG. This value will be updated automatically
26
28
  # by them gem:release rake task.
27
- VERSION = "0.5.3"
29
+ VERSION = "0.5.4"
28
30
 
29
31
  ###################################################
30
32
  # PNG international standard defined constants
@@ -108,6 +108,15 @@ module ChunkyPNG
108
108
  def [](x, y)
109
109
  @pixels[y * width + x]
110
110
  end
111
+
112
+ # Checks whether the given coordinates are in the range of the canvas
113
+ # @param [Integer] x The x-coordinate of the pixel (column)
114
+ # @param [Integer] y The y-coordinate of the pixel (row)
115
+ # @return [true, false] True if the x and y coordinate are in the range
116
+ # of this canvas.
117
+ def include?(x, y)
118
+ (0...width).include?(x) && (0...height).include?(y)
119
+ end
111
120
 
112
121
  # Returns the palette used for this canvas.
113
122
  # @return [ChunkyPNG::Palette] A pallete which contains all the colors that are
@@ -131,7 +140,8 @@ module ChunkyPNG
131
140
  # EXPORTING
132
141
  #################################################################
133
142
 
134
- # Creates an ChunkyPNG::Image object from this canvas
143
+ # Creates an ChunkyPNG::Image object from this canvas.
144
+ # @return [ChunkyPNG::Image] This canvas wrapped in an Image instance.
135
145
  def to_image
136
146
  ChunkyPNG::Image.from_canvas(self)
137
147
  end
@@ -3,6 +3,66 @@ module ChunkyPNG
3
3
 
4
4
  module Drawing
5
5
 
6
+ # Sets a point on the canvas by composing a pixel with its background color.
7
+ def point(x, y, color)
8
+ self[x, y] = ChunkyPNG::Color.compose(color, self[x, y])
9
+ end
10
+
11
+ # Draws an anti-aliased line using Xiaolin Wu's algorithm.
12
+ #
13
+ def line_xiaolin_wu(x0, y0, x1, y1, color)
14
+ y0, y1, x0, x1 = y1, y0, x1, x0 if y0 > y1
15
+ dx = x1 - x0
16
+ sx = dx < 0 ? -1 : 1
17
+ dx *= sx
18
+ dy = y1 - y0
19
+
20
+ if dy == 0 # vertical line
21
+ Range.new(*[x0,x1].sort).each do |x|
22
+ point(x, y0, color)
23
+ end
24
+ elsif dx == 0 # horizontal line
25
+ (y0..y1).each do |y|
26
+ point(x0, y, color)
27
+ end
28
+ elsif dx == dy # diagonal
29
+ x0.step(x1, sx) do |x|
30
+ point(x, y0, color)
31
+ y0 += 1
32
+ end
33
+
34
+ elsif dy > dx # vertical displacement
35
+ point(x0, y0, color)
36
+ e_acc = 0
37
+ e = ((dx << 16) / dy.to_f).round
38
+ (y0...y1-1).each do |i|
39
+ e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
40
+ x0 = x0 + sx if (e_acc <= e_acc_temp)
41
+ w = 0xff - (e_acc >> 8)
42
+ point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include?(x0, y0)
43
+ y0 = y0 + 1
44
+ point(x0 + sx, y0, ChunkyPNG::Color.fade(color, 0xff - w)) if include?(x0 + sx, y0)
45
+ end
46
+ point(x1, y1, color)
47
+
48
+ else # horizontal displacement
49
+ point(x0, y0, color)
50
+ e_acc = 0
51
+ e = (dy << 16) / dx
52
+ (dx - 1).downto(0) do |i|
53
+ e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
54
+ y0 += 1 if (e_acc <= e_acc_temp)
55
+ w = 0xff - (e_acc >> 8)
56
+ point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include?(x0, y0)
57
+ x0 += sx
58
+ point(x0, y0 + 1, ChunkyPNG::Color.fade(color, 0xff - w)) if include?(x0, y0 + 1)
59
+ end
60
+ point(x1, y1, color)
61
+ end
62
+ end
63
+
64
+ alias :line :line_xiaolin_wu
65
+
6
66
  end
7
67
  end
8
68
  end
@@ -141,7 +141,8 @@ module ChunkyPNG
141
141
  end
142
142
 
143
143
  # Passes to this canvas of pixel values line by line.
144
- # @yield [Array<Fixnum>] An line of fixnums reprsenting pixels
144
+ # @yield [line] Yields the scanlines of this image one by one.
145
+ # @yieldparam [Array<Fixnum>] line An line of fixnums representing pixels
145
146
  def each_scanline(&block)
146
147
  for line_no in 0...height do
147
148
  scanline = pixels[width * line_no, width]
@@ -9,6 +9,8 @@ module ChunkyPNG
9
9
  # represented by the {ChunkyPNG::Chunk::Header} class. These specialized
10
10
  # classes help accessing the content of the chunk. All other chunks are
11
11
  # represented by the {ChunkyPNG::Chunk::Generic} class.
12
+ #
13
+ # @see ChunkyPNG::Datastream
12
14
  module Chunk
13
15
 
14
16
  # Reads a chunk from an IO stream.
@@ -37,37 +39,79 @@ module ChunkyPNG
37
39
  raise "Chuck CRC mismatch!" if found_crc != expected_crc
38
40
  end
39
41
 
42
+ # The base chunk class is the superclass for every chunk type. It contains
43
+ # methods to write the chunk to an output stream.
44
+ #
45
+ # A subclass should implement the +content+ method, which gets called when
46
+ # the chunk gets written to a PNG datastream
47
+ #
48
+ # @abstract
40
49
  class Base
50
+
51
+ # The four-character type indicator for the chunk. This field is used to
52
+ # find the correct class for a chunk when it is loaded from a PNG stream.
53
+ # @return [String]
41
54
  attr_accessor :type
42
55
 
56
+ # Initializes the chunk instance.
57
+ # @param [String] type The four character chunk type indicator.
58
+ # @param [Hash] attributes A hash of attributes to set on this chunk.
43
59
  def initialize(type, attributes = {})
44
60
  self.type = type
45
61
  attributes.each { |k, v| send("#{k}=", v) }
46
62
  end
47
63
 
64
+ # Writes the chunk to the IO stream, using the provided content.
65
+ # The checksum will be calculated and appended to the stream.
66
+ # @param [IO] io The IO stream to write to.
67
+ # @param [String] content The content for this chunk.
48
68
  def write_with_crc(io, content)
49
69
  io << [content.length].pack('N') << type << content
50
70
  io << [Zlib.crc32(content, Zlib.crc32(type))].pack('N')
51
71
  end
52
72
 
73
+ # Writes the chunk to the IO stream.
74
+ #
75
+ # It will call te +content+ method to get the content for this chunk,
76
+ # and will calculate and append the checksum automatically.
77
+ # @param [IO] io The IO stream to write to.
53
78
  def write(io)
54
79
  write_with_crc(io, content || '')
55
80
  end
56
81
  end
57
82
 
83
+ # The Generic chunk type will read the content from the chunk as it,
84
+ # and will write it back as it was read.
58
85
  class Generic < Base
59
86
 
87
+ # The attribute to store the content from the chunk, which gets
88
+ # written by the +write+ method.
60
89
  attr_accessor :content
61
90
 
91
+
62
92
  def initialize(type, content = '')
63
93
  super(type, :content => content)
64
94
  end
65
95
 
96
+ # Creates an instance, given the chunk's type and content.
97
+ # @param [String] type The four character chunk type indicator.
98
+ # @param [String] content The content read from the chunk.
99
+ # @return [ChunkyPNG::Chunk::Generic] The new chunk instance.
66
100
  def self.read(type, content)
67
101
  self.new(type, content)
68
102
  end
69
103
  end
70
104
 
105
+ # The header (IHDR) chunk is the first chunk of every PNG image, and
106
+ # contains information about the image: i.e. its width, height, color
107
+ # depth, color mode, compression method, filtering method and interlace
108
+ # method.
109
+ #
110
+ # ChunkyPNG supports all values for these variables that are defined in
111
+ # the PNG spec, except for color depth: Only 8-bit depth images are
112
+ # supported. Note that it is still possible to access the chunk for such
113
+ # an image, but ChunkyPNG will raise an exception if you try to access
114
+ # the pixel data.
71
115
  class Header < Base
72
116
 
73
117
  attr_accessor :width, :height, :depth, :color, :compression, :filtering, :interlace
@@ -81,35 +125,63 @@ module ChunkyPNG
81
125
  @interlace ||= ChunkyPNG::INTERLACING_NONE
82
126
  end
83
127
 
128
+ # Reads the 13 bytes of content from the header chunk to set the image attributes.
129
+ # @param [String] type The four character chunk type indicator (= "IHDR").
130
+ # @param [String] content The 13 bytes of content read from the chunk.
131
+ # @return [ChunkyPNG::Chunk::End] The new Header chunk instance with the
132
+ # variables set to the values according to the content.
84
133
  def self.read(type, content)
85
134
  fields = content.unpack('NNC5')
86
135
  self.new(:width => fields[0], :height => fields[1], :depth => fields[2], :color => fields[3],
87
136
  :compression => fields[4], :filtering => fields[5], :interlace => fields[6])
88
137
  end
89
138
 
139
+ # Returns the content for this chunk when it gets written to a file, by packing the
140
+ # image information variables into the correct format.
141
+ # @return [String] The 13-byte content for the header chunk.
90
142
  def content
91
143
  [width, height, depth, color, compression, filtering, interlace].pack('NNC5')
92
144
  end
93
145
  end
94
146
 
147
+ # The End (IEND) chunk indicates the last chunk of a PNG stream. It does not
148
+ # contain any data.
95
149
  class End < Base
150
+
96
151
  def initialize
97
152
  super('IEND')
98
153
  end
99
-
154
+
155
+ # Reads the END chunk. It will check if the content is empty.
156
+ # @param [String] type The four character chunk type indicator (= "IEND").
157
+ # @param [String] content The content read from the chunk. Should be empty.
158
+ # @return [ChunkyPNG::Chunk::End] The new End chunk instance.
159
+ # @raise [RuntimeError] Raises an exception if the content was not empty.
100
160
  def self.read(type, content)
101
161
  raise 'The IEND chunk should be empty!' if content != ''
102
162
  self.new
103
163
  end
104
164
 
165
+ # Returns an empty string, because this chunk should always be empty.
166
+ # @return [""] An empty string.
105
167
  def content
106
168
  ''
107
169
  end
108
170
  end
109
171
 
172
+ # The Palette (PLTE) chunk contains the image's palette, i.e. the
173
+ # 8-bit RGB colors this image is using.
174
+ #
175
+ # @see ChunkyPNG::Chunk::Transparency
176
+ # @see ChunkyPNG::Palette
110
177
  class Palette < Generic
111
178
  end
112
179
 
180
+ # A transparency (tRNS) chunk contains the alpha channel for the colors
181
+ # defined in the Palette (PLTE) chunk
182
+ #
183
+ # @see ChunkyPNG::Chunk::Palette
184
+ # @see ChunkyPNG::Palette
113
185
  class Transparency < Generic
114
186
  end
115
187
 
@@ -126,6 +198,14 @@ module ChunkyPNG
126
198
  end
127
199
  end
128
200
 
201
+ # The Text (tEXt) chunk contains keyword/value metadata about the PNG stream.
202
+ # In this chunk, the value is stored uncompressed.
203
+ #
204
+ # The tEXt chunk only supports Latin-1 encoded textual data. If you need UTF-8
205
+ # support, check out the InternationalText chunk type.
206
+ #
207
+ # @see ChunkyPNG::Chunk::CompressedText
208
+ # @see ChunkyPNG::Chunk::InternationalText
129
209
  class Text < Base
130
210
 
131
211
  attr_accessor :keyword, :value
@@ -140,17 +220,27 @@ module ChunkyPNG
140
220
  new(keyword, value)
141
221
  end
142
222
 
223
+ # Creates the content to write to the stream, by concatenating the keyword
224
+ # with the value, joined by a null character.
225
+ #
226
+ # @return The content that should be written to the datastream.
143
227
  def content
144
228
  [keyword, value].pack('Z*a*')
145
229
  end
146
230
  end
147
231
 
232
+ # The CompressedText (zTXt) chunk contains keyword/value metadata about
233
+ # the PNG stream. In this chunk, the value is compressed using Deflate
234
+ # compression.
235
+ #
236
+ # @see ChunkyPNG::Chunk::CompressedText
237
+ # @see ChunkyPNG::Chunk::InternationalText
148
238
  class CompressedText < Base
149
239
 
150
240
  attr_accessor :keyword, :value
151
241
 
152
242
  def initialize(keyword, value)
153
- super('tEXt')
243
+ super('zTXt')
154
244
  @keyword, @value = keyword, value
155
245
  end
156
246
 
@@ -160,17 +250,37 @@ module ChunkyPNG
160
250
  new(keyword, Zlib::Inflate.inflate(value))
161
251
  end
162
252
 
253
+ # Creates the content to write to the stream, by concatenating the keyword
254
+ # with the deflated value, joined by a null character.
255
+ #
256
+ # @return The content that should be written to the datastream.
163
257
  def content
164
258
  [keyword, ChunkyPNG::COMPRESSION_DEFAULT, Zlib::Deflate.deflate(value)].pack('Z*Ca*')
165
259
  end
166
260
  end
167
261
 
262
+ # The Text (iTXt) chunk contains keyword/value metadata about the PNG stream.
263
+ # The metadata in this chunk can be encoded using UTF-8 characters. Moreover,
264
+ # it is possible to define the language of the metadata, and give a translation
265
+ # of the keyword name. Finally, it supports bot compressed and uncompressed
266
+ # values.
267
+ #
268
+ # @todo This chunk is currently not implemented, but merely read and written
269
+ # back intact.
270
+ #
271
+ # @see ChunkyPNG::Chunk::Text
272
+ # @see ChunkyPNG::Chunk::CompressedText
168
273
  class InternationalText < Generic
274
+
169
275
  # TODO
170
276
  end
171
277
 
172
- # Maps chunk types to classes.
173
- # If a chunk type is not given in this hash, a generic chunk type will be used.
278
+ # Maps chunk types to classes, based on the four byte chunk type indicator at the
279
+ # beginning of a chunk.
280
+ #
281
+ # If a chunk type is not specified in this hash, the Generic chunk type will be used.
282
+ #
283
+ # @see ChunkyPNG::Chunk.read
174
284
  CHUNK_TYPES = {
175
285
  'IHDR' => Header, 'IEND' => End, 'IDAT' => ImageData, 'PLTE' => Palette, 'tRNS' => Transparency,
176
286
  'tEXt' => Text, 'zTXt' => CompressedText, 'iTXt' => InternationalText
@@ -46,7 +46,7 @@ module ChunkyPNG
46
46
  def grayscale_alpha(teint, a)
47
47
  teint << 24 | teint << 16 | teint << 8 | a
48
48
  end
49
-
49
+
50
50
  ####################################################################
51
51
  # COLOR IMPORTING
52
52
  ####################################################################
@@ -222,6 +222,15 @@ module ChunkyPNG
222
222
  (fg + bg) >> 1
223
223
  end
224
224
 
225
+ # Lowers the intensity of a color, by lowering its alpha by a given factor.
226
+ # @param [Fixnum] color The color to adjust.
227
+ # @param [Fixnum] factor Fade factor as an integer between 0 and 255.
228
+ # @return [Fixnum] The faded color.
229
+ def fade(color, factor)
230
+ new_alpha = int8_mult(a(color), factor)
231
+ (color & 0xffffff00) | new_alpha
232
+ end
233
+
225
234
  ####################################################################
226
235
  # CONVERSIONS
227
236
  ####################################################################
@@ -44,9 +44,9 @@ module ChunkyPNG
44
44
  @data_chunks = []
45
45
  end
46
46
 
47
- #############################################
47
+ ##############################################################################
48
48
  # LOADING DATASTREAMS
49
- #############################################
49
+ ##############################################################################
50
50
 
51
51
  class << self
52
52
 
@@ -102,16 +102,17 @@ module ChunkyPNG
102
102
  end
103
103
  end
104
104
 
105
- #############################################
105
+ ##################################################################################
106
106
  # CHUNKS
107
- #############################################
107
+ ##################################################################################
108
108
 
109
109
  # Enumerates the chunks in this datastream.
110
110
  #
111
111
  # This will iterate over the chunks using the order in which the chunks
112
112
  # should appear in the PNG file.
113
113
  #
114
- # @yield [ChunkyPNG::Chunk::Base] The chunks in this datastrean, one by one.
114
+ # @yield [chunk] Yields the chunks in this datastrean, one by one in the correct order.
115
+ # @yieldparam [ChunkyPNG::Chunk::Base] chunk A chunk in this datastream.
115
116
  # @see ChunkyPNG::Datastream#chunks
116
117
  def each_chunk
117
118
  yield(header_chunk)
@@ -138,9 +139,9 @@ module ChunkyPNG
138
139
  metadata
139
140
  end
140
141
 
141
- #############################################
142
+ ##################################################################################
142
143
  # WRITING DATASTREAMS
143
- #############################################
144
+ ##################################################################################
144
145
 
145
146
  # Writes the datastream to the given output stream.
146
147
  # @param [IO] io The output stream to write to.
@@ -9,7 +9,7 @@ module ChunkyPNG
9
9
  #
10
10
  # @example
11
11
  #
12
- # require 'rmagick
12
+ # require 'rmagick'
13
13
  # require 'chunky_png/rmagick'
14
14
  #
15
15
  # canvas = ChunkyPNG::Canvas.from_file('filename.png')
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe ChunkyPNG::Canvas::Drawing do
4
+
5
+ describe '#point' do
6
+ it "should compose colors correctly" do
7
+ canvas = ChunkyPNG::Canvas.new(1, 1, ChunkyPNG::Color.rgb(200, 150, 100))
8
+ canvas.point(0,0, ChunkyPNG::Color.rgba(100, 150, 200, 128))
9
+ canvas[0,0].should == ChunkyPNG::Color.rgb(150, 150, 150)
10
+ end
11
+ end
12
+
13
+ describe '#line' do
14
+ it "should draw lines correctly with anti-aliasing" do
15
+ canvas = ChunkyPNG::Canvas.new(32, 32, ChunkyPNG::Color::WHITE)
16
+
17
+ canvas.line( 0, 0, 31, 31, ChunkyPNG::Color::BLACK)
18
+ canvas.line( 0, 31, 31, 0, ChunkyPNG::Color::BLACK)
19
+ canvas.line(15, 31, 15, 0, ChunkyPNG::Color.rgba(200, 0, 0, 128))
20
+ canvas.line( 0, 15, 31, 15, ChunkyPNG::Color.rgba(200, 0, 0, 128))
21
+ canvas.line( 0, 15, 31, 31, ChunkyPNG::Color.rgba( 0, 200, 0, 128))
22
+ canvas.line( 0, 15, 31, 0, ChunkyPNG::Color.rgba( 0, 200, 0, 128))
23
+ canvas.line(15, 0, 31, 31, ChunkyPNG::Color.rgba( 0, 0, 200, 128))
24
+ canvas.line(15, 0, 0, 31, ChunkyPNG::Color.rgba( 0, 0, 200, 128))
25
+
26
+ canvas.should == reference_canvas('lines')
27
+ end
28
+ end
29
+ end
Binary file
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.5.3
4
+ version: 0.5.4
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-01-17 00:00:00 +01:00
12
+ date: 2010-01-18 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -69,11 +69,13 @@ files:
69
69
  - spec/resources/gray_10x10_indexed.png
70
70
  - spec/resources/16x16_non_interlaced.png
71
71
  - spec/chunky_png_spec.rb
72
+ - spec/chunky_png/canvas/drawing_spec.rb
72
73
  - lib/chunky_png/palette.rb
73
74
  - lib/chunky_png/datastream.rb
74
75
  - chunky_png.gemspec
75
76
  - tasks/github-gem.rake
76
77
  - spec/resources/pixelstream_reference.png
78
+ - spec/resources/lines.png
77
79
  - spec/resources/gray_10x10_grayscale_alpha.png
78
80
  - spec/resources/16x16_interlaced.png
79
81
  - spec/chunky_png/image_spec.rb
@@ -125,6 +127,7 @@ test_files:
125
127
  - spec/chunky_png/canvas/adam7_interlacing_spec.rb
126
128
  - spec/chunky_png/canvas/png_decoding_spec.rb
127
129
  - spec/chunky_png_spec.rb
130
+ - spec/chunky_png/canvas/drawing_spec.rb
128
131
  - spec/chunky_png/image_spec.rb
129
132
  - spec/chunky_png/rmagick_spec.rb
130
133
  - spec/chunky_png/datastream_spec.rb