oily_png 0.0.2 → 0.0.3
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/.gitignore +3 -2
- data/Gemfile.lock +1 -1
- data/README.rdoc +23 -6
- data/ext/oily_png/extconf.rb +1 -10
- data/ext/oily_png/{decoding.c → png_decoding.c} +63 -48
- data/lib/oily_png.rb +2 -2
- data/oily_png.gemspec +3 -3
- data/spec/decoding_spec.rb +72 -0
- data/spec/resources/gray.png +0 -0
- data/spec/resources/operations.png +0 -0
- data/spec/spec_helper.rb +40 -0
- metadata +10 -6
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -1,9 +1,26 @@
|
|
1
|
-
|
1
|
+
= OilyPNG
|
2
2
|
|
3
|
-
|
3
|
+
OilyPNG is a Ruby C extension to speed up the pure Ruby ChunkyPNG library.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
Currently it has an alternative implementation of decoding PNGs, making that operation much
|
6
|
+
faster for PNG images that apply filtering. An alternative implementation for encoding is
|
7
|
+
planned.
|
8
|
+
|
9
|
+
*Warning*: this is my first C code in years. It may blow up your PC after leaking memory all
|
10
|
+
over the place, killing a kitten in the process. You have been warned.
|
11
|
+
|
12
|
+
== Usage
|
13
|
+
|
14
|
+
1. First install the gem and make it available to your project.
|
15
|
+
2. Use require "oily_png" instead of require "chunky_png"
|
16
|
+
3. Presto! Now use ChunkyPNG as you normally would and get an instant speedup.
|
17
|
+
|
18
|
+
See http://github.com/wvanbergen/chunky_png/wiki for more information on how to use the
|
19
|
+
ChunkyPNG API.
|
20
|
+
|
21
|
+
== About
|
22
|
+
|
23
|
+
License: MIT (see LICENSE)
|
24
|
+
|
25
|
+
This C module is written by Willem van Bergen with help from Dirkjan Bussink.
|
9
26
|
|
data/ext/oily_png/extconf.rb
CHANGED
@@ -1,11 +1,2 @@
|
|
1
|
-
# Loads mkmf which is used to make makefiles for Ruby extensions
|
2
1
|
require 'mkmf'
|
3
|
-
|
4
|
-
# paths = ['/opt/local', '/usr/local']
|
5
|
-
# lib_paths = paths.map { |p| p + '/lib' }
|
6
|
-
# inc_paths = paths.map { |p| p + '/include' }
|
7
|
-
|
8
|
-
# exit(1) unless find_library('png', 'png_get_io_ptr', *lib_paths) && find_header('png.h', *inc_paths)
|
9
|
-
|
10
|
-
# Create a makefile
|
11
|
-
create_makefile('oily_png/decoding')
|
2
|
+
create_makefile('oily_png/png_decoding')
|
@@ -1,65 +1,65 @@
|
|
1
1
|
#include "ruby.h"
|
2
2
|
|
3
|
-
//
|
4
|
-
|
3
|
+
// PNG color mode constants
|
4
|
+
#define OILY_PNG_COLOR_GRAYSCALE 0
|
5
|
+
#define OILY_PNG_COLOR_TRUECOLOR 2
|
6
|
+
#define OILY_PNG_COLOR_INDEXED 3
|
7
|
+
#define OILY_PNG_COLOR_GRAYSCALE_ALPHA 4
|
8
|
+
#define OILY_PNG_COLOR_TRUECOLOR_ALPHA 6
|
5
9
|
|
6
|
-
|
10
|
+
// PNG filter constants
|
11
|
+
#define OILY_PNG_FILTER_NONE 0
|
12
|
+
#define OILY_PNG_FILTER_SUB 1
|
13
|
+
#define OILY_PNG_FILTER_UP 2
|
14
|
+
#define OILY_PNG_FILTER_AVERAGE 3
|
15
|
+
#define OILY_PNG_FILTER_PAETH 4
|
7
16
|
|
17
|
+
// Type definitions
|
18
|
+
#define PIXEL unsigned int
|
19
|
+
|
20
|
+
void Init_png_decoding();
|
8
21
|
VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALUE height, VALUE color_mode, VALUE start_pos);
|
9
22
|
|
10
|
-
|
11
|
-
// COLOR_TRUECOLOR = 2
|
12
|
-
// COLOR_INDEXED = 3
|
13
|
-
// COLOR_GRAYSCALE_ALPHA = 4
|
14
|
-
// COLOR_TRUECOLOR_ALPHA = 6
|
15
|
-
//
|
16
|
-
// FILTERING_DEFAULT = 0
|
17
|
-
//
|
18
|
-
// COMPRESSION_DEFAULT = 0
|
19
|
-
//
|
20
|
-
// INTERLACING_NONE = 0
|
21
|
-
// INTERLACING_ADAM7 = 1
|
22
|
-
//
|
23
|
-
// FILTER_NONE = 0
|
24
|
-
// FILTER_SUB = 1
|
25
|
-
// FILTER_UP = 2
|
26
|
-
// FILTER_AVERAGE = 3
|
27
|
-
// FILTER_PAETH = 4
|
23
|
+
////////////////////////////////////////////////////////////////////////////
|
28
24
|
|
29
|
-
|
25
|
+
// Initialize the extension by creating the OilyPNG::PNGDecoding module
|
26
|
+
void Init_png_decoding() {
|
30
27
|
VALUE OilyPNG = rb_define_module("OilyPNG");
|
31
|
-
VALUE
|
32
|
-
rb_define_method(
|
28
|
+
VALUE OilyPNGPNGDecoding = rb_define_module_under(OilyPNG, "PNGDecoding");
|
29
|
+
rb_define_method(OilyPNGPNGDecoding, "decode_png_image_pass", oily_png_decode_png_image_pass, 5);
|
33
30
|
}
|
34
31
|
|
32
|
+
// Returns the number of bytes per pixel for a given color mode.
|
35
33
|
int oily_png_pixel_size(color_mode) {
|
36
34
|
switch (color_mode) {
|
37
|
-
case
|
38
|
-
case
|
39
|
-
case
|
40
|
-
case
|
41
|
-
case
|
35
|
+
case OILY_PNG_COLOR_GRAYSCALE: return 1;
|
36
|
+
case OILY_PNG_COLOR_TRUECOLOR: return 3;
|
37
|
+
case OILY_PNG_COLOR_INDEXED: return 1;
|
38
|
+
case OILY_PNG_COLOR_GRAYSCALE_ALPHA: return 2;
|
39
|
+
case OILY_PNG_COLOR_TRUECOLOR_ALPHA: return 4;
|
42
40
|
default: return -1;
|
43
41
|
}
|
44
42
|
}
|
45
43
|
|
46
|
-
|
44
|
+
// Decodes a pixel at the given position in the bytearray
|
45
|
+
PIXEL oily_png_decode_pixel(int color_mode, unsigned char* bytes, int byte_index, VALUE decoding_palette) {
|
47
46
|
switch (color_mode) {
|
48
|
-
case
|
47
|
+
case OILY_PNG_COLOR_GRAYSCALE:
|
49
48
|
return (bytes[byte_index] << 24) + (bytes[byte_index] << 16) + (bytes[byte_index] << 8) + 0xff;
|
50
|
-
case
|
49
|
+
case OILY_PNG_COLOR_TRUECOLOR:
|
51
50
|
return (bytes[byte_index] << 24) + (bytes[byte_index + 1] << 16) + (bytes[byte_index + 2] << 8) + 0xff;
|
52
|
-
case
|
51
|
+
case OILY_PNG_COLOR_INDEXED:
|
53
52
|
return NUM2UINT(rb_funcall(decoding_palette, rb_intern("[]"), 1, INT2FIX(bytes[byte_index])));
|
54
|
-
case
|
53
|
+
case OILY_PNG_COLOR_GRAYSCALE_ALPHA:
|
55
54
|
return (bytes[byte_index] << 24) + (bytes[byte_index] << 16) + (bytes[byte_index] << 8) + bytes[byte_index + 1];
|
56
|
-
case
|
55
|
+
case OILY_PNG_COLOR_TRUECOLOR_ALPHA:
|
57
56
|
return (bytes[byte_index] << 24) + (bytes[byte_index + 1] << 16) + (bytes[byte_index + 2] << 8) + bytes[byte_index + 3];
|
58
57
|
default:
|
59
58
|
exit(1);
|
60
59
|
}
|
61
60
|
}
|
62
61
|
|
62
|
+
// Decodes a SUB filtered scanline at the given position in the byte array
|
63
63
|
void oily_png_filter_sub(unsigned char* bytes, int pos, int line_length, int pixel_size) {
|
64
64
|
int i;
|
65
65
|
for (i = 1 + pixel_size; i < line_length; i++) {
|
@@ -67,8 +67,10 @@ void oily_png_filter_sub(unsigned char* bytes, int pos, int line_length, int pix
|
|
67
67
|
}
|
68
68
|
}
|
69
69
|
|
70
|
+
// Decodes an UP filtered scanline at the given position in the byte array
|
70
71
|
void oily_png_filter_up(unsigned char* bytes, int pos, int line_length, int pixel_size) {
|
71
72
|
int i;
|
73
|
+
// The first line is not filtered because there is no privous line
|
72
74
|
if (pos >= line_length) {
|
73
75
|
for (i = 1; i < line_length; i++) {
|
74
76
|
bytes[pos + i] += bytes[pos + i - line_length]; // mod 256 ???
|
@@ -76,33 +78,37 @@ void oily_png_filter_up(unsigned char* bytes, int pos, int line_length, int pixe
|
|
76
78
|
}
|
77
79
|
}
|
78
80
|
|
81
|
+
// Decodes an AVERAGE filtered scanline at the given position in the byte array
|
79
82
|
void oily_png_filter_average(unsigned char* bytes, int pos, int line_length, int pixel_size) {
|
80
83
|
int i;
|
81
84
|
unsigned char a, b;
|
82
85
|
for (i = 1; i < line_length; i++) {
|
83
86
|
a = (i > pixel_size) ? bytes[pos + i - pixel_size] : 0;
|
84
87
|
b = (pos >= line_length) ? bytes[pos + i - line_length] : 0;
|
85
|
-
bytes[pos + i] += (a + b) >> 1;
|
88
|
+
bytes[pos + i] += (a + b) >> 1; // mod 256 ???
|
86
89
|
}
|
87
90
|
}
|
88
91
|
|
92
|
+
// Decodes a PAETH filtered scanline at the given position in the byte array
|
89
93
|
void oily_png_filter_paeth(unsigned char* bytes, int pos, int line_length, int pixel_size) {
|
90
94
|
unsigned char a, b, c, pr;
|
91
95
|
int i, p, pa, pb, pc;
|
92
96
|
for (i = 1; i < line_length; i++) {
|
93
97
|
a = (i > pixel_size) ? bytes[pos + i - pixel_size] : 0;
|
94
98
|
b = (pos >= line_length) ? bytes[pos + i - line_length] : 0;
|
95
|
-
c = (pos >= line_length && i > pixel_size) ? bytes[pos + i - line_length - pixel_size] : 0;
|
99
|
+
c = (pos >= line_length && i > pixel_size) ? bytes[pos + i - line_length - pixel_size] : 0;
|
96
100
|
p = a + b - c;
|
97
101
|
pa = abs(p - a);
|
98
102
|
pb = abs(p - b);
|
99
103
|
pc = abs(p - c);
|
100
104
|
pr = (pa <= pb) ? (pa <= pc ? a : c) : (pb <= pc ? b : c);
|
101
|
-
bytes[pos + i] += pr;
|
105
|
+
bytes[pos + i] += pr; // mod 256 ???
|
102
106
|
}
|
103
107
|
}
|
104
108
|
|
105
|
-
|
109
|
+
// Decodes an image pass from the given byte stream at the given position.
|
110
|
+
// A normal PNG will only have one pass that consumes the entire stream, while an
|
111
|
+
// interlaced image requires 7 passes which are loaded from different starting positions.
|
106
112
|
VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALUE height, VALUE color_mode, VALUE start_pos) {
|
107
113
|
|
108
114
|
int pixel_size = oily_png_pixel_size(FIX2INT(color_mode));
|
@@ -112,31 +118,37 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
|
|
112
118
|
VALUE pixels = rb_ary_new();
|
113
119
|
|
114
120
|
VALUE decoding_palette = Qnil;
|
115
|
-
if (FIX2INT(color_mode) ==
|
121
|
+
if (FIX2INT(color_mode) == OILY_PNG_COLOR_INDEXED) {
|
116
122
|
decoding_palette = rb_funcall(self, rb_intern("decoding_palette"), 0);
|
117
123
|
}
|
118
124
|
|
125
|
+
// Copy the bytes for this pass from the stream to a separate location
|
126
|
+
// so we can work on this byte array directly.
|
119
127
|
unsigned char* pixelstream = RSTRING_PTR(stream);
|
120
128
|
unsigned char* bytes = malloc(pass_size);
|
121
129
|
memcpy(bytes, pixelstream + FIX2INT(start_pos), pass_size);
|
122
130
|
|
123
131
|
int y, x, line_start, prev_line_start, byte_index, pixel_index;
|
124
132
|
unsigned char filter;
|
125
|
-
|
133
|
+
PIXEL pixel;
|
126
134
|
|
127
135
|
for (y = 0; y < FIX2INT(height); y++) {
|
128
136
|
line_start = y * line_size;
|
129
|
-
filter = bytes[line_start];
|
130
137
|
|
131
|
-
|
132
|
-
|
133
|
-
case
|
134
|
-
case
|
135
|
-
case
|
136
|
-
case
|
138
|
+
// Apply filering to the line
|
139
|
+
switch (bytes[line_start]) {
|
140
|
+
case OILY_PNG_FILTER_NONE: break;
|
141
|
+
case OILY_PNG_FILTER_SUB: oily_png_filter_sub( bytes, line_start, line_size, pixel_size); break;
|
142
|
+
case OILY_PNG_FILTER_UP: oily_png_filter_up( bytes, line_start, line_size, pixel_size); break;
|
143
|
+
case OILY_PNG_FILTER_AVERAGE: oily_png_filter_average( bytes, line_start, line_size, pixel_size); break;
|
144
|
+
case OILY_PNG_FILTER_PAETH: oily_png_filter_paeth( bytes, line_start, line_size, pixel_size); break;
|
137
145
|
default: exit(1);
|
138
146
|
}
|
139
147
|
|
148
|
+
// Set the filter byte to 0 because the bytearray is now unfiltered.
|
149
|
+
bytes[line_start] = OILY_PNG_FILTER_NONE;
|
150
|
+
|
151
|
+
// Now, iterate over all bytes in this line and combine them into pixels
|
140
152
|
for (x = 0; x < FIX2INT(width); x++) {
|
141
153
|
pixel_index = FIX2INT(width) * y + x;
|
142
154
|
byte_index = line_start + 1 + (x * pixel_size);
|
@@ -145,7 +157,10 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
|
|
145
157
|
}
|
146
158
|
}
|
147
159
|
|
160
|
+
// Get rid of the byte array.
|
148
161
|
free(bytes);
|
162
|
+
|
163
|
+
// Now, return a new ChunkyPNG::Canvas instance with the decoded pixels.
|
149
164
|
return rb_funcall(self, rb_intern("new"), 3, width, height, pixels);
|
150
165
|
}
|
151
166
|
|
data/lib/oily_png.rb
CHANGED
data/oily_png.gemspec
CHANGED
@@ -4,7 +4,7 @@ Gem::Specification.new do |s|
|
|
4
4
|
|
5
5
|
# Do not change the version and date fields by hand. This will be done
|
6
6
|
# automatically by the gem release script.
|
7
|
-
s.version = "0.0.
|
7
|
+
s.version = "0.0.3"
|
8
8
|
s.date = "2010-10-05"
|
9
9
|
|
10
10
|
s.summary = "Native mixin to speed up ChunkyPNG"
|
@@ -30,6 +30,6 @@ Gem::Specification.new do |s|
|
|
30
30
|
|
31
31
|
# Do not change the files and test_files fields by hand. This will be done
|
32
32
|
# automatically by the gem release script.
|
33
|
-
s.files = %w(.gitignore Gemfile Gemfile.lock LICENSE README.rdoc Rakefile ext/oily_png/
|
34
|
-
s.test_files = %w()
|
33
|
+
s.files = %w(.gitignore Gemfile Gemfile.lock LICENSE README.rdoc Rakefile ext/oily_png/extconf.rb ext/oily_png/png_decoding.c lib/oily_png.rb oily_png.gemspec spec/decoding_spec.rb spec/resources/gray.png spec/resources/operations.png spec/spec_helper.rb tasks/github-gem.rake)
|
34
|
+
s.test_files = %w(spec/decoding_spec.rb)
|
35
35
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe OilyPNG::PNGDecoding do
|
4
|
+
|
5
|
+
it "should call Color.bytesize in the pure ruby version" do
|
6
|
+
ChunkyPNG::Color.should_receive(:bytesize).and_return(3)
|
7
|
+
ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should not call Color.bytesize in the native version" do
|
11
|
+
ChunkyPNG::Color.should_not_receive(:bytesize)
|
12
|
+
OilyCanvas.from_file(resource_file('operations.png'))
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'decoding different filtering methods' do
|
16
|
+
before(:all) { @reference = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))}
|
17
|
+
|
18
|
+
it "should decode NONE filtering exactly the same as ChunkyPNG" do
|
19
|
+
filtered_data = @reference.to_blob(:filtering => ChunkyPNG::FILTER_NONE)
|
20
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should decode SUB filtering exactly the same as ChunkyPNG" do
|
24
|
+
filtered_data = @reference.to_blob(:filtering => ChunkyPNG::FILTER_SUB)
|
25
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should decode UP filtering exactly the same as ChunkyPNG" do
|
29
|
+
filtered_data = @reference.to_blob(:filtering => ChunkyPNG::FILTER_UP)
|
30
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should decode AVERAGE filtering exactly the same as ChunkyPNG" do
|
34
|
+
filtered_data = @reference.to_blob(:filtering => ChunkyPNG::FILTER_AVERAGE)
|
35
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should decode PAETH filtering exactly the same as ChunkyPNG" do
|
39
|
+
filtered_data = @reference.to_blob(:filtering => ChunkyPNG::FILTER_PAETH)
|
40
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'decoding different color modes' do
|
45
|
+
before(:all) { @reference = ChunkyPNG::Canvas.from_file(resource_file('gray.png'))}
|
46
|
+
|
47
|
+
it "should decode RGBA images the same as ChunkyPNG" do
|
48
|
+
filtered_data = @reference.to_blob(:color_mode => ChunkyPNG::COLOR_TRUECOLOR_ALPHA)
|
49
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should decode RGB images exactly the same as ChunkyPNG" do
|
53
|
+
filtered_data = @reference.to_blob(:color_mode => ChunkyPNG::COLOR_TRUECOLOR)
|
54
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should decode indexed images exactly the same as ChunkyPNG" do
|
58
|
+
filtered_data = @reference.to_blob(:color_mode => ChunkyPNG::COLOR_INDEXED)
|
59
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should decode grayscale images exactly the same as ChunkyPNG" do
|
63
|
+
filtered_data = @reference.to_blob(:color_mode => ChunkyPNG::COLOR_GRAYSCALE)
|
64
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should decode grayscale images with transparency the same as ChunkyPNG" do
|
68
|
+
filtered_data = @reference.to_blob(:color_mode => ChunkyPNG::COLOR_GRAYSCALE_ALPHA)
|
69
|
+
ChunkyPNG::Canvas.from_blob(filtered_data).should == OilyCanvas.from_blob(filtered_data)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
Binary file
|
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Bundler.setup
|
5
|
+
|
6
|
+
require 'spec'
|
7
|
+
require 'chunky_png'
|
8
|
+
require 'oily_png/png_decoding'
|
9
|
+
|
10
|
+
class OilyCanvas < ChunkyPNG::Canvas
|
11
|
+
extend OilyPNG::PNGDecoding
|
12
|
+
end
|
13
|
+
|
14
|
+
module ResourceHelper
|
15
|
+
def resource_files
|
16
|
+
Dir[File.join(File.dirname(__FILE__), 'resources', '*.png')]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module CanvasHelper
|
21
|
+
|
22
|
+
def resource_file(name)
|
23
|
+
File.join(File.dirname(__FILE__), 'resources', name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def display(canvas)
|
27
|
+
filename = resource_file('_tmp.png')
|
28
|
+
canvas.to_datastream.save(filename)
|
29
|
+
`open #{filename}`
|
30
|
+
end
|
31
|
+
|
32
|
+
def reference_canvas(name)
|
33
|
+
ChunkyPNG::Canvas.from_file(resource_file("#{name}.png"))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Spec::Runner.configure do |config|
|
38
|
+
config.extend ResourceHelper
|
39
|
+
config.include CanvasHelper
|
40
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oily_png
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Willem van Bergen
|
@@ -79,10 +79,14 @@ files:
|
|
79
79
|
- LICENSE
|
80
80
|
- README.rdoc
|
81
81
|
- Rakefile
|
82
|
-
- ext/oily_png/decoding.c
|
83
82
|
- ext/oily_png/extconf.rb
|
83
|
+
- ext/oily_png/png_decoding.c
|
84
84
|
- lib/oily_png.rb
|
85
85
|
- oily_png.gemspec
|
86
|
+
- spec/decoding_spec.rb
|
87
|
+
- spec/resources/gray.png
|
88
|
+
- spec/resources/operations.png
|
89
|
+
- spec/spec_helper.rb
|
86
90
|
- tasks/github-gem.rake
|
87
91
|
has_rdoc: true
|
88
92
|
homepage: http://wiki.github.com/wvanbergen/oily_png
|
@@ -126,5 +130,5 @@ rubygems_version: 1.3.7
|
|
126
130
|
signing_key:
|
127
131
|
specification_version: 3
|
128
132
|
summary: Native mixin to speed up ChunkyPNG
|
129
|
-
test_files:
|
130
|
-
|
133
|
+
test_files:
|
134
|
+
- spec/decoding_spec.rb
|