chunky_png 1.0.0.rc1 → 1.0.0.rc2
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/.yardopts +2 -0
- data/chunky_png.gemspec +2 -2
- data/lib/chunky_png.rb +94 -28
- data/lib/chunky_png/canvas.rb +10 -7
- data/lib/chunky_png/canvas/drawing.rb +15 -2
- data/lib/chunky_png/canvas/operations.rb +44 -24
- data/lib/chunky_png/canvas/png_decoding.rb +6 -6
- data/lib/chunky_png/canvas/png_encoding.rb +7 -5
- data/lib/chunky_png/canvas/resampling.rb +9 -3
- data/lib/chunky_png/color.rb +19 -19
- data/lib/chunky_png/dimension.rb +10 -3
- data/lib/chunky_png/point.rb +9 -4
- data/lib/chunky_png/vector.rb +95 -8
- data/spec/chunky_png/canvas/drawing_spec.rb +17 -19
- data/spec/chunky_png/canvas/operations_spec.rb +46 -0
- data/spec/chunky_png/canvas/resampling_spec.rb +33 -0
- data/spec/chunky_png/dimension_spec.rb +10 -5
- data/spec/chunky_png/point_spec.rb +7 -2
- data/spec/chunky_png/vector_spec.rb +59 -13
- metadata +3 -3
data/.yardopts
CHANGED
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 = "1.0.0.
|
7
|
-
s.date = "2011-02
|
6
|
+
s.version = "1.0.0.rc2"
|
7
|
+
s.date = "2011-03-02"
|
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
@@ -4,59 +4,96 @@ require 'zlib'
|
|
4
4
|
require 'stringio'
|
5
5
|
require 'enumerator'
|
6
6
|
|
7
|
-
#
|
8
|
-
require 'chunky_png/compatibility'
|
9
|
-
|
10
|
-
# PNG file structure
|
11
|
-
require 'chunky_png/datastream'
|
12
|
-
require 'chunky_png/chunk'
|
13
|
-
|
14
|
-
# Colors
|
15
|
-
require 'chunky_png/palette'
|
16
|
-
require 'chunky_png/color'
|
17
|
-
|
18
|
-
# Geometry
|
19
|
-
require 'chunky_png/point'
|
20
|
-
require 'chunky_png/vector'
|
21
|
-
require 'chunky_png/dimension'
|
22
|
-
|
23
|
-
# Canvas / Image classes
|
24
|
-
require 'chunky_png/canvas'
|
25
|
-
require 'chunky_png/image'
|
26
|
-
|
27
|
-
# ChunkyPNG - the pury ruby library to access PNG files.
|
7
|
+
# ChunkyPNG - the pure ruby library to access PNG files.
|
28
8
|
#
|
29
9
|
# The ChunkyPNG module defines some constants that are used in the
|
30
|
-
# PNG specification
|
10
|
+
# PNG specification, specifies some exception classes, and serves as
|
11
|
+
# a namespace for all the other modules and classes in this library.
|
12
|
+
#
|
13
|
+
# {ChunkyPNG::Image}:: class to represent PNG images, including metadata.
|
14
|
+
# {ChunkyPNG::Canvas}:: class to represent the image's canvas.
|
15
|
+
# {ChunkyPNG::Color}:: module to work with color values.
|
16
|
+
# {ChunkyPNG::Palette}:: represents the palette of colors used on a {ChunkyPNG::Canvas}.
|
17
|
+
# {ChunkyPNG::Datastream}:: represents the internal structure of a PNG {ChunkyPNG::Image}.
|
18
|
+
# {ChunkyPNG::Color}:: represents one chunk of data within a {ChunkyPNG::Datastream}.
|
19
|
+
# {ChunkyPNG::Point}:: geometry helper class representing a 2-dimensional point.
|
20
|
+
# {ChunkyPNG::Dimension}:: geometry helper class representing a dimension (i.e. width x height).
|
21
|
+
# {ChunkyPNG::Vector}:: geometry helper class representing a series of points.
|
31
22
|
#
|
32
23
|
# @author Willem van Bergen
|
33
24
|
module ChunkyPNG
|
34
25
|
|
35
|
-
# The current version of ChunkyPNG. This value will be updated
|
36
|
-
# by them gem:release rake task.
|
37
|
-
VERSION = "1.0.0.
|
26
|
+
# The current version of ChunkyPNG. This value will be updated
|
27
|
+
# automatically by them <tt>gem:release</tt> rake task.
|
28
|
+
VERSION = "1.0.0.rc2"
|
38
29
|
|
39
30
|
###################################################
|
40
31
|
# PNG international standard defined constants
|
41
32
|
###################################################
|
42
33
|
|
34
|
+
# Indicates that the PNG image uses grayscale colors, i.e. only a
|
35
|
+
# single teint channel.
|
36
|
+
# @private
|
43
37
|
COLOR_GRAYSCALE = 0
|
38
|
+
|
39
|
+
# Indicates that the PNG image uses true color, composed of a red
|
40
|
+
# green and blue channel.
|
41
|
+
# @private
|
44
42
|
COLOR_TRUECOLOR = 2
|
43
|
+
|
44
|
+
# Indicates that the PNG image uses indexed colors, where the values
|
45
|
+
# point to colors defined on a palette.
|
46
|
+
# @private
|
45
47
|
COLOR_INDEXED = 3
|
48
|
+
|
49
|
+
# Indicates that the PNG image uses grayscale colors with opacity, i.e.
|
50
|
+
# a teint channel with an alpha channel.
|
51
|
+
# @private
|
46
52
|
COLOR_GRAYSCALE_ALPHA = 4
|
53
|
+
|
54
|
+
# Indicates that the PNG image uses true color with opacity, composed of
|
55
|
+
# a red, green and blue channel, and an alpha value.
|
56
|
+
# @private
|
47
57
|
COLOR_TRUECOLOR_ALPHA = 6
|
48
58
|
|
49
|
-
|
50
|
-
|
59
|
+
# Indicates that the PNG specification's default compression
|
60
|
+
# method is used (Zlib/Deflate)
|
61
|
+
# @private
|
51
62
|
COMPRESSION_DEFAULT = 0
|
52
63
|
|
64
|
+
# Indicates that the image does not use interlacing.
|
65
|
+
# @private
|
53
66
|
INTERLACING_NONE = 0
|
67
|
+
|
68
|
+
# Indicates that the image uses Adam7 interlacing.
|
69
|
+
# @private
|
54
70
|
INTERLACING_ADAM7 = 1
|
55
71
|
|
72
|
+
### Filter method constants
|
73
|
+
|
74
|
+
# Indicates that the PNG specification's default filtering are
|
75
|
+
# being used in the image.
|
76
|
+
# @private
|
77
|
+
FILTERING_DEFAULT = 0
|
78
|
+
|
79
|
+
# Indicates that no filtering is used for the scanline.
|
80
|
+
# @private
|
56
81
|
FILTER_NONE = 0
|
82
|
+
|
83
|
+
# Indicates that SUB filtering is used for the scanline.
|
84
|
+
# @private
|
57
85
|
FILTER_SUB = 1
|
86
|
+
|
87
|
+
# Indicates that UP filtering is used for the scanline.
|
88
|
+
# @private
|
58
89
|
FILTER_UP = 2
|
90
|
+
|
91
|
+
# Indicates that AVERAGE filtering is used for the scanline.
|
92
|
+
# @private
|
59
93
|
FILTER_AVERAGE = 3
|
94
|
+
|
95
|
+
# Indicates that PAETH filtering is used for the scanline.
|
96
|
+
# @private
|
60
97
|
FILTER_PAETH = 4
|
61
98
|
|
62
99
|
###################################################
|
@@ -88,6 +125,35 @@ module ChunkyPNG
|
|
88
125
|
class OutOfBounds < ChunkyPNG::ExpectationFailed
|
89
126
|
end
|
90
127
|
|
128
|
+
# Empty byte array. This basically is an empty string, but with the encoding
|
129
|
+
# set correctly to ASCII-8BIT (binary) in Ruby 1.9.
|
130
|
+
# @return [String] An empty string, with encoding set to binary in Ruby 1.9
|
131
|
+
# @private
|
91
132
|
EMPTY_BYTEARRAY = String.method_defined?(:force_encoding) ? "".force_encoding('ASCII-8BIT').freeze : "".freeze
|
92
|
-
|
133
|
+
|
134
|
+
# Null-byte, with the encoding set correctly to ASCII-8BIT (binary) in Ruby 1.9.
|
135
|
+
# @return [String] A binary string, consisting of one NULL-byte.
|
136
|
+
# @private
|
137
|
+
EXTRA_BYTE = String.method_defined?(:force_encoding) ? "\0".force_encoding('ASCII-8BIT') : "\0"
|
93
138
|
end
|
139
|
+
|
140
|
+
|
141
|
+
# Ruby 1.8 / 1.9 compatibility
|
142
|
+
require 'chunky_png/compatibility'
|
143
|
+
|
144
|
+
# PNG file structure
|
145
|
+
require 'chunky_png/datastream'
|
146
|
+
require 'chunky_png/chunk'
|
147
|
+
|
148
|
+
# Colors
|
149
|
+
require 'chunky_png/palette'
|
150
|
+
require 'chunky_png/color'
|
151
|
+
|
152
|
+
# Geometry
|
153
|
+
require 'chunky_png/point'
|
154
|
+
require 'chunky_png/vector'
|
155
|
+
require 'chunky_png/dimension'
|
156
|
+
|
157
|
+
# Canvas / Image classes
|
158
|
+
require 'chunky_png/canvas'
|
159
|
+
require 'chunky_png/image'
|
data/lib/chunky_png/canvas.rb
CHANGED
@@ -71,17 +71,17 @@ module ChunkyPNG
|
|
71
71
|
|
72
72
|
@width, @height = width, height
|
73
73
|
|
74
|
-
if initial.kind_of?(
|
75
|
-
@pixels = Array.new(width * height, initial)
|
76
|
-
elsif initial.kind_of?(Array) && initial.length == width * height
|
74
|
+
if initial.kind_of?(Array) && initial.length == width * height
|
77
75
|
@pixels = initial
|
78
76
|
else
|
79
|
-
|
77
|
+
@pixels = Array.new(width * height, ChunkyPNG::Color(initial))
|
80
78
|
end
|
81
79
|
end
|
82
80
|
|
83
81
|
# Initializes a new Canvas instances when being cloned.
|
84
82
|
# @param [ChunkyPNG::Canvas] other The canvas to duplicate
|
83
|
+
# @return [void]
|
84
|
+
# @private
|
85
85
|
def initialize_copy(other)
|
86
86
|
@width, @height = other.width, other.height
|
87
87
|
@pixels = other.pixels.dup
|
@@ -184,7 +184,7 @@ module ChunkyPNG
|
|
184
184
|
# Returns a single pixel from this canvas, without checking bounds. The return value for
|
185
185
|
# this method is undefined if the coordinates are out of bounds.
|
186
186
|
# @param (see #[])
|
187
|
-
# @return [
|
187
|
+
# @return [Integer] The current pixel at the provided coordinates.
|
188
188
|
def get_pixel(x, y)
|
189
189
|
@pixels[y * width + x]
|
190
190
|
end
|
@@ -208,6 +208,7 @@ module ChunkyPNG
|
|
208
208
|
# Replaces a row of pixels on this canvas.
|
209
209
|
# @param [Integer] y The 0-based row index.
|
210
210
|
# @param [Array<Integer>] vector The vector of pixels to replace the row with.
|
211
|
+
# @return [void]
|
211
212
|
def replace_row!(y, vector)
|
212
213
|
assert_y!(y) && assert_width!(vector.length)
|
213
214
|
pixels[y * width, width] = vector
|
@@ -216,6 +217,7 @@ module ChunkyPNG
|
|
216
217
|
# Replaces a column of pixels on this canvas.
|
217
218
|
# @param [Integer] x The 0-based column index.
|
218
219
|
# @param [Array<Integer>] vector The vector of pixels to replace the column with.
|
220
|
+
# @return [void]
|
219
221
|
def replace_column!(x, vector)
|
220
222
|
assert_x!(x) && assert_height!(vector.length)
|
221
223
|
for y in 0...height do
|
@@ -227,7 +229,7 @@ module ChunkyPNG
|
|
227
229
|
# @param [ChunkyPNG::Point, Array, Hash, String] point_like The point to check.
|
228
230
|
# @return [true, false] True if the x and y coordinates of the point are
|
229
231
|
# within the limits of this canvas.
|
230
|
-
# @see ChunkyPNG
|
232
|
+
# @see ChunkyPNG.Point
|
231
233
|
def include_point?(*point_like)
|
232
234
|
dimension.include?(ChunkyPNG::Point(*point_like))
|
233
235
|
end
|
@@ -279,6 +281,7 @@ module ChunkyPNG
|
|
279
281
|
|
280
282
|
# Alternative implementation of the inspect method.
|
281
283
|
# @return [String] A nicely formatted string representation of this canvas.
|
284
|
+
# @private
|
282
285
|
def inspect
|
283
286
|
inspected = "<#{self.class.name} #{width}x#{height} ["
|
284
287
|
for y in 0...height
|
@@ -291,7 +294,7 @@ module ChunkyPNG
|
|
291
294
|
|
292
295
|
# Replaces the image, given a new width, new height, and a new pixel array.
|
293
296
|
def replace_canvas!(new_width, new_height, new_pixels)
|
294
|
-
raise
|
297
|
+
raise ArgumentError, "The provided pixel array should have #{new_width * new_height} items" unless new_pixels.length == new_width * new_height
|
295
298
|
@width, @height, @pixels = new_width, new_height, new_pixels
|
296
299
|
return self
|
297
300
|
end
|
@@ -22,7 +22,8 @@ module ChunkyPNG
|
|
22
22
|
def compose_pixel(*args)
|
23
23
|
point = args.length == 2 ? ChunkyPNG::Point(args.first) : ChunkyPNG::Point(args[0], args[1])
|
24
24
|
return unless include?(point)
|
25
|
-
|
25
|
+
color = ChunkyPNG::Color(args.last)
|
26
|
+
set_pixel(point.x, point.y, ChunkyPNG::Color.compose(color, get_pixel(point.x, point.y)))
|
26
27
|
end
|
27
28
|
|
28
29
|
# Draws an anti-aliased line using Xiaolin Wu's algorithm.
|
@@ -36,6 +37,9 @@ module ChunkyPNG
|
|
36
37
|
# Set to false when drawing multiplelines in a path.
|
37
38
|
# @return [ChunkyPNG::Canvas] Itself, with the line drawn.
|
38
39
|
def line_xiaolin_wu(x0, y0, x1, y1, stroke_color, inclusive = true)
|
40
|
+
|
41
|
+
stroke_color = ChunkyPNG::Color(stroke_color)
|
42
|
+
|
39
43
|
dx = x1 - x0
|
40
44
|
sx = dx < 0 ? -1 : 1
|
41
45
|
dx *= sx
|
@@ -103,7 +107,10 @@ module ChunkyPNG
|
|
103
107
|
def polygon(path, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
|
104
108
|
|
105
109
|
vector = ChunkyPNG::Vector(*path)
|
106
|
-
raise
|
110
|
+
raise ArgumentError, "A polygon requires at least 3 points" if path.length < 3
|
111
|
+
|
112
|
+
stroke_color = ChunkyPNG::Color(stroke_color)
|
113
|
+
fill_color = ChunkyPNG::Color(fill_color)
|
107
114
|
|
108
115
|
# Fill
|
109
116
|
unless fill_color == ChunkyPNG::Color::TRANSPARENT
|
@@ -143,6 +150,9 @@ module ChunkyPNG
|
|
143
150
|
# @return [ChunkyPNG::Canvas] Itself, with the rectangle drawn.
|
144
151
|
def rect(x0, y0, x1, y1, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
|
145
152
|
|
153
|
+
stroke_color = ChunkyPNG::Color(stroke_color)
|
154
|
+
fill_color = ChunkyPNG::Color(fill_color)
|
155
|
+
|
146
156
|
# Fill
|
147
157
|
unless fill_color == ChunkyPNG::Color::TRANSPARENT
|
148
158
|
[x0, x1].min.upto([x0, x1].max) do |x|
|
@@ -171,6 +181,9 @@ module ChunkyPNG
|
|
171
181
|
# @return [ChunkyPNG::Canvas] Itself, with the circle drawn.
|
172
182
|
def circle(x0, y0, radius, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
|
173
183
|
|
184
|
+
stroke_color = ChunkyPNG::Color(stroke_color)
|
185
|
+
fill_color = ChunkyPNG::Color(fill_color)
|
186
|
+
|
174
187
|
f = 1 - radius
|
175
188
|
ddF_x = 1
|
176
189
|
ddF_y = -2 * radius
|
@@ -110,15 +110,7 @@ module ChunkyPNG
|
|
110
110
|
# @raise [ChunkyPNG::OutOfBounds] when the crop dimensions plus the given coordinates
|
111
111
|
# are bigger then the original image.
|
112
112
|
def crop(x, y, crop_width, crop_height)
|
113
|
-
|
114
|
-
raise ChunkyPNG::OutOfBounds, "Image width is too small!" if crop_width + x > width
|
115
|
-
raise ChunkyPNG::OutOfBounds, "Image width is too small!" if crop_height + y > height
|
116
|
-
|
117
|
-
new_pixels = []
|
118
|
-
for cy in 0...crop_height do
|
119
|
-
new_pixels += pixels.slice((cy + y) * width + x, crop_width)
|
120
|
-
end
|
121
|
-
ChunkyPNG::Canvas.new(crop_width, crop_height, new_pixels)
|
113
|
+
dup.crop!(x, y, crop_width, crop_height)
|
122
114
|
end
|
123
115
|
|
124
116
|
# Crops an image, given the coordinates and size of the image that needs to be cut out.
|
@@ -208,30 +200,58 @@ module ChunkyPNG
|
|
208
200
|
alias_method :mirror!, :flip_vertically!
|
209
201
|
alias_method :mirror, :flip_vertically
|
210
202
|
|
211
|
-
#
|
212
|
-
#
|
203
|
+
# Returns a new canvas instance that is rotated 90 degrees clockwise.
|
204
|
+
#
|
205
|
+
# This method will return a new canvas and leaves the original intact.
|
206
|
+
# See {#rotate_right!} for the in place version.
|
213
207
|
#
|
214
|
-
# @return [ChunkyPNG::Canvas]
|
208
|
+
# @return [ChunkyPNG::Canvas] A clockwise-rotated copy.
|
215
209
|
def rotate_right
|
210
|
+
dup.rotate_right!
|
211
|
+
end
|
212
|
+
|
213
|
+
# Rotates the image 90 degrees clockwise in place.
|
214
|
+
#
|
215
|
+
# This method will change the current canvas. See {#rotate_right} for
|
216
|
+
# a version that leaves th current canvas intact
|
217
|
+
#
|
218
|
+
# @return [ChunkyPNG::Canvas] Itself, but rotated clockwise.
|
219
|
+
def rotate_right!
|
216
220
|
rotated = self.class.new(height, width)
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
return rotated
|
221
|
+
new_pixels = []
|
222
|
+
0.upto(width - 1) { |i| new_pixels += column(i).reverse }
|
223
|
+
replace_canvas!(height, width, new_pixels)
|
221
224
|
end
|
222
225
|
|
223
|
-
|
226
|
+
alias_method :rotate_clockwise, :rotate_right
|
227
|
+
alias_method :rotate_clockwise!, :rotate_right!
|
228
|
+
|
229
|
+
# Returns an image that is rotated 90 degrees counter-clockwise.
|
230
|
+
#
|
224
231
|
# This method will leave the original object intact and return a new canvas.
|
232
|
+
# See {#rotate_left!} for the in place version.
|
225
233
|
#
|
226
|
-
# @return [ChunkyPNG::Canvas]
|
234
|
+
# @return [ChunkyPNG::Canvas] A rotated copy of itself.
|
227
235
|
def rotate_left
|
228
|
-
|
229
|
-
for i in 0...width do
|
230
|
-
rotated.replace_row!(width - (i + 1), column(i))
|
231
|
-
end
|
232
|
-
return rotated
|
236
|
+
dup.rotate_left!
|
233
237
|
end
|
234
|
-
|
238
|
+
|
239
|
+
# Rotates the image 90 degrees counter-clockwise in place.
|
240
|
+
#
|
241
|
+
# This method will change the original canvas. See {#rotate_left} for a
|
242
|
+
# version that leaves the canvas intact and returns a new rototed canvas
|
243
|
+
# instead.
|
244
|
+
#
|
245
|
+
# @return [ChunkyPNG::Canvas] Itself, but rotated.
|
246
|
+
def rotate_left!
|
247
|
+
new_pixels = []
|
248
|
+
(width - 1).downto(0) { |i| new_pixels += column(i) }
|
249
|
+
replace_canvas!(height, width, new_pixels)
|
250
|
+
end
|
251
|
+
|
252
|
+
alias_method :rotate_counter_clockwise, :rotate_left
|
253
|
+
alias_method :rotate_counter_clockwise!, :rotate_left!
|
254
|
+
|
235
255
|
# Rotates the image 180 degrees.
|
236
256
|
# This method will leave the original object intact and return a new canvas.
|
237
257
|
#
|
@@ -409,7 +409,7 @@ module ChunkyPNG
|
|
409
409
|
# if this is the first scanline of the image.
|
410
410
|
# @param [Integer] line_length The number of bytes in the scanline, discounting the filter method byte.
|
411
411
|
# @param [Integer] pixel_size The number of bytes used per pixel, based on the color mode.
|
412
|
-
# @return [
|
412
|
+
# @return [void]
|
413
413
|
def decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
|
414
414
|
case stream.getbyte(pos)
|
415
415
|
when ChunkyPNG::FILTER_NONE; # noop
|
@@ -423,7 +423,7 @@ module ChunkyPNG
|
|
423
423
|
|
424
424
|
# Decodes a scanline that wasn't encoded using filtering. This is a no-op.
|
425
425
|
# @params (see #decode_png_str_scanline)
|
426
|
-
# @return [
|
426
|
+
# @return [void]
|
427
427
|
def decode_png_str_scanline_sub_none(stream, pos, prev_pos, line_length, pixel_size)
|
428
428
|
# noop - this method shouldn't get called.
|
429
429
|
end
|
@@ -431,7 +431,7 @@ module ChunkyPNG
|
|
431
431
|
# Decodes a scanline in a pxielstream that was encoded using SUB filtering.
|
432
432
|
# This will chnage the pixelstream to have unfiltered values.
|
433
433
|
# @params (see #decode_png_str_scanline)
|
434
|
-
# @return [
|
434
|
+
# @return [void]
|
435
435
|
def decode_png_str_scanline_sub(stream, pos, prev_pos, line_length, pixel_size)
|
436
436
|
for i in 1..line_length do
|
437
437
|
stream.setbyte(pos + i, (stream.getbyte(pos + i) + (i > pixel_size ? stream.getbyte(pos + i - pixel_size) : 0)) & 0xff)
|
@@ -441,7 +441,7 @@ module ChunkyPNG
|
|
441
441
|
# Decodes a scanline in a pxielstream that was encoded using UP filtering.
|
442
442
|
# This will chnage the pixelstream to have unfiltered values.
|
443
443
|
# @params (see #decode_png_str_scanline)
|
444
|
-
# @return [
|
444
|
+
# @return [void]
|
445
445
|
def decode_png_str_scanline_up(stream, pos, prev_pos, line_length, pixel_size)
|
446
446
|
for i in 1..line_length do
|
447
447
|
up = prev_pos ? stream.getbyte(prev_pos + i) : 0
|
@@ -452,7 +452,7 @@ module ChunkyPNG
|
|
452
452
|
# Decodes a scanline in a pxielstream that was encoded using AVERAGE filtering.
|
453
453
|
# This will chnage the pixelstream to have unfiltered values.
|
454
454
|
# @params (see #decode_png_str_scanline)
|
455
|
-
# @return [
|
455
|
+
# @return [void]
|
456
456
|
def decode_png_str_scanline_average(stream, pos, prev_pos, line_length, pixel_size)
|
457
457
|
for i in 1..line_length do
|
458
458
|
a = (i > pixel_size) ? stream.getbyte(pos + i - pixel_size) : 0
|
@@ -464,7 +464,7 @@ module ChunkyPNG
|
|
464
464
|
# Decodes a scanline in a pxielstream that was encoded using PAETH filtering.
|
465
465
|
# This will chnage the pixelstream to have unfiltered values.
|
466
466
|
# @params (see #decode_png_str_scanline)
|
467
|
-
# @return [
|
467
|
+
# @return [void]
|
468
468
|
def decode_png_str_scanline_paeth(stream, pos, prev_pos, line_length, pixel_size)
|
469
469
|
for i in 1..line_length do
|
470
470
|
cur_pos = pos + i
|
@@ -30,6 +30,7 @@ module ChunkyPNG
|
|
30
30
|
# Writes the canvas to an IO stream, encoded as a PNG image.
|
31
31
|
# @param [IO] io The output stream to write to.
|
32
32
|
# @param constraints (see ChunkyPNG::Canvas::PNGEncoding#to_datastream)
|
33
|
+
# @return [void]
|
33
34
|
def write(io, constraints = {})
|
34
35
|
to_datastream(constraints).write(io)
|
35
36
|
end
|
@@ -37,6 +38,7 @@ module ChunkyPNG
|
|
37
38
|
# Writes the canvas to a file, encoded as a PNG image.
|
38
39
|
# @param [String] filname The file to save the PNG image to.
|
39
40
|
# @param constraints (see ChunkyPNG::Canvas::PNGEncoding#to_datastream)
|
41
|
+
# @return [void]
|
40
42
|
def save(filename, constraints = {})
|
41
43
|
File.open(filename, 'wb') { |io| write(io, constraints) }
|
42
44
|
end
|
@@ -379,14 +381,14 @@ module ChunkyPNG
|
|
379
381
|
# @param [Integer] line_width The number of bytes in this scanline, without counting the filtering
|
380
382
|
# method byte.
|
381
383
|
# @param [Integer] pixel_size The number of bytes used per pixel.
|
382
|
-
# @return [
|
384
|
+
# @return [void]
|
383
385
|
def encode_png_str_scanline_none(stream, pos, prev_pos, line_width, pixel_size)
|
384
386
|
# noop - this method shouldn't get called at all.
|
385
387
|
end
|
386
388
|
|
387
389
|
# Encodes a scanline of a pixelstream using SUB filtering. This will modify the stream.
|
388
390
|
# @param (see #encode_png_str_scanline_none)
|
389
|
-
# @return [
|
391
|
+
# @return [void]
|
390
392
|
def encode_png_str_scanline_sub(stream, pos, prev_pos, line_width, pixel_size)
|
391
393
|
line_width.downto(1) do |i|
|
392
394
|
a = (i > pixel_size) ? stream.getbyte(pos + i - pixel_size) : 0
|
@@ -397,7 +399,7 @@ module ChunkyPNG
|
|
397
399
|
|
398
400
|
# Encodes a scanline of a pixelstream using UP filtering. This will modify the stream.
|
399
401
|
# @param (see #encode_png_str_scanline_none)
|
400
|
-
# @return [
|
402
|
+
# @return [void]
|
401
403
|
def encode_png_str_scanline_up(stream, pos, prev_pos, line_width, pixel_size)
|
402
404
|
line_width.downto(1) do |i|
|
403
405
|
b = prev_pos ? stream.getbyte(prev_pos + i) : 0
|
@@ -408,7 +410,7 @@ module ChunkyPNG
|
|
408
410
|
|
409
411
|
# Encodes a scanline of a pixelstream using AVERAGE filtering. This will modify the stream.
|
410
412
|
# @param (see #encode_png_str_scanline_none)
|
411
|
-
# @return [
|
413
|
+
# @return [void]
|
412
414
|
def encode_png_str_scanline_average(stream, pos, prev_pos, line_width, pixel_size)
|
413
415
|
line_width.downto(1) do |i|
|
414
416
|
a = (i > pixel_size) ? stream.getbyte(pos + i - pixel_size) : 0
|
@@ -420,7 +422,7 @@ module ChunkyPNG
|
|
420
422
|
|
421
423
|
# Encodes a scanline of a pixelstream using PAETH filtering. This will modify the stream.
|
422
424
|
# @param (see #encode_png_str_scanline_none)
|
423
|
-
# @return [
|
425
|
+
# @return [void]
|
424
426
|
def encode_png_str_scanline_paeth(stream, pos, prev_pos, line_width, pixel_size)
|
425
427
|
line_width.downto(1) do |i|
|
426
428
|
a = (i > pixel_size) ? stream.getbyte(pos + i - pixel_size) : 0
|