axon 0.0.2 → 0.1.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/CHANGELOG.rdoc +9 -3
- data/README.rdoc +29 -36
- data/Rakefile +26 -21
- data/TODO.rdoc +1 -6
- data/ext/axon/axon.c +6 -15
- data/ext/axon/extconf.rb +19 -9
- data/ext/axon/interpolation.c +147 -0
- data/ext/axon/jpeg.c +1207 -0
- data/ext/axon/png.c +542 -0
- data/lib/axon.rb +235 -32
- data/lib/axon/cropper.rb +80 -18
- data/lib/axon/fit.rb +69 -19
- data/lib/axon/generators.rb +109 -0
- data/lib/axon/scalers.rb +160 -0
- data/test/helper.rb +151 -6
- data/test/reader_tests.rb +37 -82
- data/test/scaler_tests.rb +102 -0
- data/test/stress_helper.rb +58 -0
- data/test/stress_tests.rb +8 -5
- data/test/test_bilinear_scaler.rb +60 -2
- data/test/test_cropper.rb +68 -1
- data/test/test_fit.rb +35 -0
- data/test/test_generators.rb +21 -0
- data/test/test_image.rb +61 -0
- data/test/test_jpeg_reader.rb +96 -94
- data/test/test_jpeg_writer.rb +95 -8
- data/test/test_nearest_neighbor_scaler.rb +28 -4
- data/test/test_png_reader.rb +12 -8
- data/test/test_png_writer.rb +8 -6
- data/test/writer_tests.rb +129 -111
- metadata +71 -128
- data/.gemtest +0 -0
- data/ext/axon/bilinear_interpolation.c +0 -115
- data/ext/axon/interpolation.h +0 -7
- data/ext/axon/jpeg_common.c +0 -118
- data/ext/axon/jpeg_common.h +0 -37
- data/ext/axon/jpeg_native_writer.c +0 -248
- data/ext/axon/jpeg_reader.c +0 -774
- data/ext/axon/nearest_neighbor_interpolation.c +0 -50
- data/ext/axon/png_common.c +0 -21
- data/ext/axon/png_common.h +0 -18
- data/ext/axon/png_native_writer.c +0 -166
- data/ext/axon/png_reader.c +0 -381
- data/lib/axon/axon.so +0 -0
- data/lib/axon/bilinear_scaler.rb +0 -60
- data/lib/axon/jpeg_writer.rb +0 -41
- data/lib/axon/nearest_neighbor_scaler.rb +0 -39
- data/lib/axon/png_writer.rb +0 -35
- data/lib/axon/scaler.rb +0 -41
- data/lib/axon/solid.rb +0 -23
- data/test/_test_readme.rb +0 -34
- data/test/test_exif.rb +0 -39
- data/test/test_generator.rb +0 -10
- data/test/test_icc.rb +0 -18
- data/test/test_jpeg.rb +0 -9
- data/test/test_png.rb +0 -9
data/lib/axon/axon.so
DELETED
Binary file
|
data/lib/axon/bilinear_scaler.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
module Axon
|
2
|
-
class BilinearScaler < Scaler
|
3
|
-
include BilinearScaling
|
4
|
-
include Image
|
5
|
-
include Enumerable
|
6
|
-
|
7
|
-
def each
|
8
|
-
source_y = 0
|
9
|
-
destination_y = 0
|
10
|
-
sample_y = 0
|
11
|
-
|
12
|
-
each_scanline_with_next do |sl1, sl2|
|
13
|
-
while sample_y.to_i == source_y
|
14
|
-
yield interpolate_scanline(sl1, sl2, sample_y)
|
15
|
-
|
16
|
-
destination_y += 1
|
17
|
-
sample_y = destination_y / @height_ratio
|
18
|
-
end
|
19
|
-
|
20
|
-
source_y += 1
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
# Yields each scanline with the following scanline. The final scanline is
|
27
|
-
# yielded with itself.
|
28
|
-
|
29
|
-
def each_scanline_with_next
|
30
|
-
last_sl = nil
|
31
|
-
|
32
|
-
each_scanline_with_padding do |scanline|
|
33
|
-
yield last_sl, scanline if last_sl
|
34
|
-
last_sl = scanline
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# Adds a one pixel padding to the right of the image and one pixel of
|
39
|
-
# padding to the bottom by duplicating the last pixels.
|
40
|
-
|
41
|
-
def each_scanline_with_padding
|
42
|
-
last = nil
|
43
|
-
components = @image.components
|
44
|
-
|
45
|
-
@image.each do |scanline|
|
46
|
-
scanline << scanline[-components, components] # bonus pixel
|
47
|
-
yield scanline
|
48
|
-
last = scanline
|
49
|
-
end
|
50
|
-
|
51
|
-
yield last # bonus scanline
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
module Image
|
56
|
-
def scale_bilinear(*args)
|
57
|
-
BilinearScaler.new(self, *args)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
data/lib/axon/jpeg_writer.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
|
-
module Axon
|
4
|
-
class JPEGWriter
|
5
|
-
include JPEGNativeWriter
|
6
|
-
|
7
|
-
attr_accessor :quality, :icc_profile, :exif
|
8
|
-
attr_reader :io, :bufsize, :image
|
9
|
-
|
10
|
-
def initialize(image)
|
11
|
-
@image = image
|
12
|
-
@quality = nil
|
13
|
-
@icc_profile = nil
|
14
|
-
@exif = nil
|
15
|
-
end
|
16
|
-
|
17
|
-
def write(io, bufsize = nil)
|
18
|
-
@bufsize = bufsize || 512
|
19
|
-
@io = io
|
20
|
-
jpeg_native_write
|
21
|
-
end
|
22
|
-
|
23
|
-
def data
|
24
|
-
s = StringIO.new
|
25
|
-
s.set_encoding 'BINARY' if s.respond_to?(:set_encoding)
|
26
|
-
|
27
|
-
write(s)
|
28
|
-
s.string
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
module Image
|
33
|
-
def to_jpeg(*args)
|
34
|
-
JPEGWriter.new self, *args
|
35
|
-
end
|
36
|
-
|
37
|
-
def write_jpeg(io)
|
38
|
-
JPEGWriter.new(self).write(io)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module Axon
|
2
|
-
class NearestNeighborScaler < Scaler
|
3
|
-
include NearestNeighborScaling
|
4
|
-
include Image
|
5
|
-
include Enumerable
|
6
|
-
|
7
|
-
def each
|
8
|
-
dest_y = 0
|
9
|
-
sample_y = 0
|
10
|
-
|
11
|
-
@image.each_with_index do |scanline, orig_y|
|
12
|
-
while sample_y == orig_y
|
13
|
-
yield interpolate_scanline(scanline)
|
14
|
-
dest_y += 1
|
15
|
-
sample_y = (dest_y / @height_ratio).to_i
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def _interpolate_scanline(scanline)
|
23
|
-
dest_sl = ''
|
24
|
-
|
25
|
-
scanline.size.times do |dest_x|
|
26
|
-
sample_x = (dest_x / @width_ratio).to_i
|
27
|
-
dest_sl << scanline[sample_x * components, components]
|
28
|
-
end
|
29
|
-
|
30
|
-
return dest_sl
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
module Image
|
35
|
-
def scale_nearest_neighbor(*args)
|
36
|
-
NearestNeighborScaler.new(self, *args)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/lib/axon/png_writer.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
|
-
module Axon
|
4
|
-
class PNGWriter
|
5
|
-
include PNGNativeWriter
|
6
|
-
|
7
|
-
attr_reader :image
|
8
|
-
|
9
|
-
def initialize(image)
|
10
|
-
@image = image
|
11
|
-
end
|
12
|
-
|
13
|
-
def write(io)
|
14
|
-
png_native_write(io)
|
15
|
-
end
|
16
|
-
|
17
|
-
def data
|
18
|
-
s = StringIO.new
|
19
|
-
s.set_encoding 'BINARY' if s.respond_to?(:set_encoding)
|
20
|
-
|
21
|
-
write(s)
|
22
|
-
s.string
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
module Image
|
27
|
-
def to_png
|
28
|
-
PNGWriter.new self
|
29
|
-
end
|
30
|
-
|
31
|
-
def write_png(io)
|
32
|
-
PNGWriter.new(self).write(io)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/axon/scaler.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
module Axon
|
2
|
-
class Scaler
|
3
|
-
attr_reader :width, :height
|
4
|
-
|
5
|
-
def initialize(image, *args)
|
6
|
-
@image = image
|
7
|
-
|
8
|
-
if args.size == 1
|
9
|
-
init_ratio(args[0])
|
10
|
-
elsif args.size == 2
|
11
|
-
init_dims(args[0], args[1])
|
12
|
-
else
|
13
|
-
raise ArgumentError, "Must give one or two arguments"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def components
|
18
|
-
@image.components
|
19
|
-
end
|
20
|
-
|
21
|
-
def color_model
|
22
|
-
@image.color_model
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def init_ratio(ratio)
|
28
|
-
@width_ratio = @height_ratio = ratio.to_f
|
29
|
-
@width = (@image.width * ratio).floor
|
30
|
-
@height = (@image.height * ratio).floor
|
31
|
-
end
|
32
|
-
|
33
|
-
def init_dims(width, height)
|
34
|
-
@width_ratio = width.to_f / @image.width
|
35
|
-
@width = width
|
36
|
-
|
37
|
-
@height_ratio = height.to_f / @image.height
|
38
|
-
@height = height
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/lib/axon/solid.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
module Axon
|
2
|
-
class Solid
|
3
|
-
include Image
|
4
|
-
include Enumerable
|
5
|
-
attr_reader :width, :height, :color_model, :components
|
6
|
-
|
7
|
-
def initialize(width, height, color=nil, color_model=nil)
|
8
|
-
@width, @height = width, height
|
9
|
-
@color = color || "\x00\x00\x00"
|
10
|
-
@color_model = color_model || :RGB
|
11
|
-
@components = @color.size
|
12
|
-
end
|
13
|
-
|
14
|
-
def each
|
15
|
-
sl = @color * width
|
16
|
-
height.times { yield sl }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
module Image
|
21
|
-
# empty
|
22
|
-
end
|
23
|
-
end
|
data/test/_test_readme.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module Axon
|
4
|
-
class TestReader < AxonTestCase
|
5
|
-
def setup
|
6
|
-
data = Solid.new(100, 200, "\x0A\x14\x69").to_jpeg.data
|
7
|
-
@io_in = StringIO.new(data)
|
8
|
-
@io_out = StringIO.new
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_short_chained_example
|
12
|
-
|
13
|
-
# Short, chained example. Reads a JPEG from io_in and writes scaled png to
|
14
|
-
# io_out.
|
15
|
-
Axon.JPEG(@io_in).fit(100, 100).write_png(@io_out)
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_longer_example
|
19
|
-
# Even longer example, reads the JPEG header, looks at properties and header
|
20
|
-
# values, sets decompression options, scales the image, sets compression
|
21
|
-
# options, and writes a JPEG.
|
22
|
-
image = Axon.JPEG(@io_in, [:APP2])
|
23
|
-
|
24
|
-
puts image.width
|
25
|
-
puts image.height
|
26
|
-
puts image[:APP2]
|
27
|
-
image.scale_denom = 4
|
28
|
-
|
29
|
-
jpeg = image.fit(100, 100).to_jpeg
|
30
|
-
jpeg.quality = 88
|
31
|
-
jpeg.write(@io_out)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
data/test/test_exif.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module Axon
|
4
|
-
class TestExif < AxonTestCase
|
5
|
-
def test_exif_roundtrip
|
6
|
-
random_data = ""
|
7
|
-
(100).times do
|
8
|
-
random_data << [rand].pack('d') # 800 bytes random data
|
9
|
-
end
|
10
|
-
|
11
|
-
writer = @image.to_jpeg
|
12
|
-
writer.exif = random_data
|
13
|
-
|
14
|
-
image_with_exif = Axon.JPEG(writer.data)
|
15
|
-
assert_equal random_data, image_with_exif.exif
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_exif_with_icc_roundtrip
|
19
|
-
random_icc_data = ""
|
20
|
-
(2**16).times do # a little larger than one jpeg segment
|
21
|
-
random_icc_data << [rand].pack('d') # 8 bytes random data
|
22
|
-
end
|
23
|
-
|
24
|
-
random_exif_data = ""
|
25
|
-
(100).times do
|
26
|
-
random_exif_data << [rand].pack('d') # 800 bytes random data
|
27
|
-
end
|
28
|
-
|
29
|
-
writer = @image.to_jpeg
|
30
|
-
writer.icc_profile = random_icc_data
|
31
|
-
writer.exif = random_exif_data
|
32
|
-
|
33
|
-
image_with_exif_and_icc = Axon.JPEG(writer.data)
|
34
|
-
|
35
|
-
assert_equal random_exif_data, image_with_exif_and_icc.exif
|
36
|
-
assert_equal random_icc_data, image_with_exif_and_icc.icc_profile
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/test/test_generator.rb
DELETED
data/test/test_icc.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module Axon
|
4
|
-
class TestICC < AxonTestCase
|
5
|
-
def test_large_icc_roundtrip
|
6
|
-
random_data = ""
|
7
|
-
(2**16).times do # a little larger than one jpeg segment
|
8
|
-
random_data << [rand].pack('d') # 8 bytes random data
|
9
|
-
end
|
10
|
-
|
11
|
-
writer = @image.to_jpeg
|
12
|
-
writer.icc_profile = random_data
|
13
|
-
|
14
|
-
image_with_icc = Axon.JPEG(writer.data)
|
15
|
-
assert_equal random_data, image_with_icc.icc_profile
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
data/test/test_jpeg.rb
DELETED