axon 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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