oily_png 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oily_png (0.0.3)
5
- chunky_png (~> 0.10.1)
4
+ oily_png (0.0.4)
5
+ chunky_png (~> 0.10.2)
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- chunky_png (0.10.1)
10
+ chunky_png (0.10.2)
11
11
  rake (0.8.7)
12
12
  rspec (1.3.0)
13
13
 
@@ -15,7 +15,7 @@ PLATFORMS
15
15
  ruby
16
16
 
17
17
  DEPENDENCIES
18
- chunky_png (~> 0.10.1)
18
+ chunky_png (~> 0.10.2)
19
19
  oily_png!
20
20
  rake
21
21
  rspec (>= 1.3)
@@ -1,6 +1,7 @@
1
1
  = OilyPNG
2
2
 
3
- OilyPNG is a Ruby C extension to speed up the pure Ruby ChunkyPNG library.
3
+ OilyPNG is a Ruby C extension to speed up the pure Ruby ChunkyPNG library. It is a standalone
4
+ module, so it does not require LibPNG, ImageMagick or any other library.
4
5
 
5
6
  Currently it has an alternative implementation of decoding PNGs, making that operation much
6
7
  faster for PNG images that apply filtering. An alternative implementation for encoding is
@@ -1,2 +1,2 @@
1
1
  require 'mkmf'
2
- create_makefile('oily_png/png_decoding')
2
+ create_makefile('oily_png/oily_png_ext')
@@ -0,0 +1,26 @@
1
+ #include "oily_png_ext.h"
2
+
3
+ // Initialize the extension by creating the OilyPNG modules.
4
+ void Init_oily_png_ext() {
5
+ VALUE OilyPNG = rb_define_module("OilyPNG");
6
+
7
+ // Setup decoding
8
+ VALUE OilyPNG_PNGDecoding = rb_define_module_under(OilyPNG, "PNGDecoding");
9
+ rb_define_method(OilyPNG_PNGDecoding, "decode_png_image_pass", oily_png_decode_png_image_pass, 5);
10
+
11
+ // Setup encoding
12
+ VALUE OilyPNG_PNGEncoding = rb_define_module_under(OilyPNG, "PNGEncoding");
13
+ rb_define_method(OilyPNG_PNGEncoding, "encode_png_image_pass_to_stream", oily_png_encode_png_image_pass_to_stream, 3);
14
+ }
15
+
16
+ // Returns the number of bytes per pixel for a given color mode.
17
+ int oily_png_pixel_size(int color_mode) {
18
+ switch (color_mode) {
19
+ case OILY_PNG_COLOR_GRAYSCALE: return 1;
20
+ case OILY_PNG_COLOR_TRUECOLOR: return 3;
21
+ case OILY_PNG_COLOR_INDEXED: return 1;
22
+ case OILY_PNG_COLOR_GRAYSCALE_ALPHA: return 2;
23
+ case OILY_PNG_COLOR_TRUECOLOR_ALPHA: return 4;
24
+ default: return -1;
25
+ }
26
+ }
@@ -0,0 +1,30 @@
1
+ #ifndef OILY_PNG_EXT
2
+ #define OILY_PNG_EXT
3
+
4
+ #include "ruby.h"
5
+
6
+ // PNG color mode constants
7
+ #define OILY_PNG_COLOR_GRAYSCALE 0
8
+ #define OILY_PNG_COLOR_TRUECOLOR 2
9
+ #define OILY_PNG_COLOR_INDEXED 3
10
+ #define OILY_PNG_COLOR_GRAYSCALE_ALPHA 4
11
+ #define OILY_PNG_COLOR_TRUECOLOR_ALPHA 6
12
+
13
+ // PNG filter constants
14
+ #define OILY_PNG_FILTER_NONE 0
15
+ #define OILY_PNG_FILTER_SUB 1
16
+ #define OILY_PNG_FILTER_UP 2
17
+ #define OILY_PNG_FILTER_AVERAGE 3
18
+ #define OILY_PNG_FILTER_PAETH 4
19
+
20
+ // Type definitions
21
+ #define PIXEL unsigned int // Pixels use 32 bits unsigned integers
22
+ #define BYTE unsigned char // Bytes use 8 bits unsigned integers
23
+
24
+ #include "png_decoding.h"
25
+ #include "png_encoding.h"
26
+
27
+ void Init_oily_png_ext();
28
+ int oily_png_pixel_size(int color_mode);
29
+
30
+ #endif
@@ -1,48 +1,9 @@
1
- #include "ruby.h"
2
-
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
9
-
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
16
-
17
- // Type definitions
18
- #define PIXEL unsigned int
19
-
20
- void Init_png_decoding();
21
- VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALUE height, VALUE color_mode, VALUE start_pos);
1
+ #include "oily_png_ext.h"
22
2
 
23
3
  ////////////////////////////////////////////////////////////////////////////
24
4
 
25
- // Initialize the extension by creating the OilyPNG::PNGDecoding module
26
- void Init_png_decoding() {
27
- VALUE OilyPNG = rb_define_module("OilyPNG");
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);
30
- }
31
-
32
- // Returns the number of bytes per pixel for a given color mode.
33
- int oily_png_pixel_size(color_mode) {
34
- switch (color_mode) {
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;
40
- default: return -1;
41
- }
42
- }
43
-
44
5
  // 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) {
6
+ PIXEL oily_png_decode_pixel(int color_mode, BYTE* bytes, int byte_index, VALUE decoding_palette) {
46
7
  switch (color_mode) {
47
8
  case OILY_PNG_COLOR_GRAYSCALE:
48
9
  return (bytes[byte_index] << 24) + (bytes[byte_index] << 16) + (bytes[byte_index] << 8) + 0xff;
@@ -60,7 +21,7 @@ PIXEL oily_png_decode_pixel(int color_mode, unsigned char* bytes, int byte_index
60
21
  }
61
22
 
62
23
  // Decodes a SUB filtered scanline at the given position in the byte array
63
- void oily_png_filter_sub(unsigned char* bytes, int pos, int line_length, int pixel_size) {
24
+ void oily_png_decode_filter_sub(BYTE* bytes, int pos, int line_length, int pixel_size) {
64
25
  int i;
65
26
  for (i = 1 + pixel_size; i < line_length; i++) {
66
27
  bytes[pos + i] += bytes[pos + i - pixel_size]; // mod 256 ???
@@ -68,7 +29,7 @@ void oily_png_filter_sub(unsigned char* bytes, int pos, int line_length, int pix
68
29
  }
69
30
 
70
31
  // Decodes an UP filtered scanline at the given position in the byte array
71
- void oily_png_filter_up(unsigned char* bytes, int pos, int line_length, int pixel_size) {
32
+ void oily_png_decode_filter_up(BYTE* bytes, int pos, int line_length, int pixel_size) {
72
33
  int i;
73
34
  // The first line is not filtered because there is no privous line
74
35
  if (pos >= line_length) {
@@ -79,9 +40,9 @@ void oily_png_filter_up(unsigned char* bytes, int pos, int line_length, int pixe
79
40
  }
80
41
 
81
42
  // Decodes an AVERAGE filtered scanline at the given position in the byte array
82
- void oily_png_filter_average(unsigned char* bytes, int pos, int line_length, int pixel_size) {
43
+ void oily_png_decode_filter_average(BYTE* bytes, int pos, int line_length, int pixel_size) {
83
44
  int i;
84
- unsigned char a, b;
45
+ BYTE a, b;
85
46
  for (i = 1; i < line_length; i++) {
86
47
  a = (i > pixel_size) ? bytes[pos + i - pixel_size] : 0;
87
48
  b = (pos >= line_length) ? bytes[pos + i - line_length] : 0;
@@ -90,8 +51,8 @@ void oily_png_filter_average(unsigned char* bytes, int pos, int line_length, int
90
51
  }
91
52
 
92
53
  // Decodes a PAETH filtered scanline at the given position in the byte array
93
- void oily_png_filter_paeth(unsigned char* bytes, int pos, int line_length, int pixel_size) {
94
- unsigned char a, b, c, pr;
54
+ void oily_png_decode_filter_paeth(BYTE* bytes, int pos, int line_length, int pixel_size) {
55
+ BYTE a, b, c, pr;
95
56
  int i, p, pa, pb, pc;
96
57
  for (i = 1; i < line_length; i++) {
97
58
  a = (i > pixel_size) ? bytes[pos + i - pixel_size] : 0;
@@ -106,9 +67,11 @@ void oily_png_filter_paeth(unsigned char* bytes, int pos, int line_length, int p
106
67
  }
107
68
  }
108
69
 
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.
70
+ /*
71
+ Decodes an image pass from the given byte stream at the given position.
72
+ A normal PNG will only have one pass that consumes the entire stream, while an
73
+ interlaced image requires 7 passes which are loaded from different starting positions.
74
+ */
112
75
  VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALUE height, VALUE color_mode, VALUE start_pos) {
113
76
 
114
77
  int pixel_size = oily_png_pixel_size(FIX2INT(color_mode));
@@ -117,19 +80,24 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
117
80
 
118
81
  VALUE pixels = rb_ary_new();
119
82
 
120
- VALUE decoding_palette = Qnil;
121
- if (FIX2INT(color_mode) == OILY_PNG_COLOR_INDEXED) {
122
- decoding_palette = rb_funcall(self, rb_intern("decoding_palette"), 0);
83
+ if (RSTRING_LEN(stream) < pass_size + FIX2INT(start_pos)) {
84
+ exit(1);
123
85
  }
124
-
86
+
125
87
  // Copy the bytes for this pass from the stream to a separate location
126
88
  // so we can work on this byte array directly.
127
- unsigned char* pixelstream = RSTRING_PTR(stream);
128
- unsigned char* bytes = malloc(pass_size);
89
+ BYTE* pixelstream = (BYTE*) RSTRING_PTR(stream);
90
+ BYTE* bytes = ALLOCA_N(BYTE, pass_size);
129
91
  memcpy(bytes, pixelstream + FIX2INT(start_pos), pass_size);
130
92
 
93
+ // Get the decoding palette for indexed images.
94
+ VALUE decoding_palette = Qnil;
95
+ if (FIX2INT(color_mode) == OILY_PNG_COLOR_INDEXED) {
96
+ decoding_palette = rb_funcall(self, rb_intern("decoding_palette"), 0);
97
+ }
98
+
131
99
  int y, x, line_start, prev_line_start, byte_index, pixel_index;
132
- unsigned char filter;
100
+ BYTE filter;
133
101
  PIXEL pixel;
134
102
 
135
103
  for (y = 0; y < FIX2INT(height); y++) {
@@ -138,10 +106,10 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
138
106
  // Apply filering to the line
139
107
  switch (bytes[line_start]) {
140
108
  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;
109
+ case OILY_PNG_FILTER_SUB: oily_png_decode_filter_sub( bytes, line_start, line_size, pixel_size); break;
110
+ case OILY_PNG_FILTER_UP: oily_png_decode_filter_up( bytes, line_start, line_size, pixel_size); break;
111
+ case OILY_PNG_FILTER_AVERAGE: oily_png_decode_filter_average( bytes, line_start, line_size, pixel_size); break;
112
+ case OILY_PNG_FILTER_PAETH: oily_png_decode_filter_paeth( bytes, line_start, line_size, pixel_size); break;
145
113
  default: exit(1);
146
114
  }
147
115
 
@@ -157,9 +125,6 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
157
125
  }
158
126
  }
159
127
 
160
- // Get rid of the byte array.
161
- free(bytes);
162
-
163
128
  // Now, return a new ChunkyPNG::Canvas instance with the decoded pixels.
164
129
  return rb_funcall(self, rb_intern("new"), 3, width, height, pixels);
165
130
  }
@@ -0,0 +1,7 @@
1
+ #ifndef PNG_DECODING_H
2
+ #define PNG_DECODING_H
3
+
4
+ // Function to overwrite ChunkyPNG::Canvas::PNGDecoding.decode_png_image_pass
5
+ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALUE height, VALUE color_mode, VALUE start_pos);
6
+
7
+ #endif
@@ -0,0 +1,130 @@
1
+ #include "oily_png_ext.h"
2
+
3
+ PIXEL oily_png_encode_get_pixel(VALUE self, long index) {
4
+ VALUE pixels = rb_funcall(self, rb_intern("pixels"), 0);
5
+ return NUM2UINT(rb_ary_entry(pixels, index));
6
+ }
7
+
8
+ void oily_png_encode_pixel(PIXEL pixel, int color_mode, BYTE* bytes, int pos, VALUE palette) {
9
+ switch (color_mode) {
10
+ case OILY_PNG_COLOR_GRAYSCALE:
11
+ bytes[pos] = (BYTE) ((pixel & (PIXEL) 0xff000000) >> 24);
12
+ break;
13
+ case OILY_PNG_COLOR_TRUECOLOR:
14
+ bytes[pos + 0] = (BYTE) ((pixel & (PIXEL) 0xff000000) >> 24);
15
+ bytes[pos + 1] = (BYTE) ((pixel & (PIXEL) 0x00ff0000) >> 16);
16
+ bytes[pos + 2] = (BYTE) ((pixel & (PIXEL) 0x0000ff00) >> 8);
17
+ break;
18
+ case OILY_PNG_COLOR_INDEXED:
19
+ bytes[pos] = (BYTE) NUM2UINT(rb_funcall(palette, rb_intern("index"), 1, UINT2NUM(pixel)));
20
+ break;
21
+ case OILY_PNG_COLOR_GRAYSCALE_ALPHA:
22
+ bytes[pos + 0] = (BYTE) ((pixel & (PIXEL) 0xff000000) >> 24);
23
+ bytes[pos + 1] = (BYTE) ((pixel & (PIXEL) 0x000000ff));
24
+ break;
25
+ case OILY_PNG_COLOR_TRUECOLOR_ALPHA:
26
+ bytes[pos + 0] = (BYTE) ((pixel & (PIXEL) 0xff000000) >> 24);
27
+ bytes[pos + 1] = (BYTE) ((pixel & (PIXEL) 0x00ff0000) >> 16);
28
+ bytes[pos + 2] = (BYTE) ((pixel & (PIXEL) 0x0000ff00) >> 8);
29
+ bytes[pos + 3] = (BYTE) ((pixel & (PIXEL) 0x000000ff));
30
+ break;
31
+ default:
32
+ exit(1);
33
+ }
34
+ }
35
+
36
+ void oily_png_encode_filter_sub(BYTE* bytes, int pos, int line_size, int pixel_size) {
37
+ int x;
38
+ for (x = line_size - 1; x > pixel_size; x--) {
39
+ bytes[pos + x] -= bytes[pos + x - pixel_size];
40
+ }
41
+ }
42
+
43
+ void oily_png_encode_filter_up(BYTE* bytes, int pos, int line_size, int pixel_size) {
44
+ int x;
45
+ if (pos >= line_size) {
46
+ for (x = line_size - 1; x > 0; x--) {
47
+ bytes[pos + x] -= bytes[pos + x - line_size];
48
+ }
49
+ }
50
+ }
51
+
52
+ void oily_png_encode_filter_average(BYTE* bytes, int pos, int line_size, int pixel_size) {
53
+ int x; BYTE a, b;
54
+ for (x = line_size - 1; x > 0; x--) {
55
+ a = (x > pixel_size) ? bytes[pos + x - pixel_size] : 0;
56
+ b = (pos >= line_size) ? bytes[pos + x - line_size] : 0;
57
+ bytes[pos + x] -= ((a + b) >> 1);
58
+ }
59
+ }
60
+
61
+ void oily_png_encode_filter_paeth(BYTE* bytes, int pos, int line_size, int pixel_size) {
62
+ int x, p, pa, pb, pc; BYTE a, b, c, pr;
63
+ for (x = line_size - 1; x > 0; x--) {
64
+ a = (x > pixel_size) ? bytes[pos + x - pixel_size] : 0;
65
+ b = (pos >= line_size) ? bytes[pos + x - line_size] : 0;
66
+ c = (pos >= line_size && x > pixel_size) ? bytes[pos + x - line_size - pixel_size] : 0;
67
+ p = a + b - c;
68
+ pa = abs(p - a);
69
+ pb = abs(p - b);
70
+ pc = abs(p - c);
71
+ pr = (pa <= pb && pa <= pc) ? a : (pb <= pc ? b : c);
72
+ bytes[pos + x] -= pr;
73
+ }
74
+
75
+ }
76
+
77
+
78
+ /*
79
+ Encodes an image and append it to the stream.
80
+ A normal PNG will only have one pass and call this method once, while interlaced
81
+ images are split up in 7 distinct images. This method will be called for every one
82
+ of these images, reusing the stream.
83
+ */
84
+ VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE color_mode, VALUE filtering) {
85
+
86
+ // Get the data
87
+ int width = FIX2INT(rb_funcall(self, rb_intern("width"), 0));
88
+ int height = FIX2INT(rb_funcall(self, rb_intern("height"), 0));
89
+ VALUE pixels = rb_funcall(self, rb_intern("pixels"), 0);
90
+
91
+ VALUE palette = Qnil;
92
+ if (FIX2INT(color_mode) == OILY_PNG_COLOR_INDEXED) {
93
+ palette = rb_funcall(self, rb_intern("encoding_palette"), 0);
94
+ }
95
+
96
+ int pixel_size = oily_png_pixel_size(FIX2INT(color_mode));
97
+ int line_size = 1 + pixel_size * width;
98
+ int pass_size = line_size * height;
99
+
100
+ // Allocate memory for the byte array.
101
+ BYTE* bytes = ALLOCA_N(BYTE, pass_size);
102
+
103
+ PIXEL pixel;
104
+ int x, y, pos;
105
+ for (y = 0; y < height; y++) {
106
+ bytes[line_size * y] = FIX2INT(filtering);
107
+
108
+ for (x = 0; x < width; x++) {
109
+ pixel = NUM2UINT(rb_ary_entry(pixels, y * height + x));
110
+ pos = (line_size * y) + (pixel_size * x) + 1;
111
+ oily_png_encode_pixel(pixel, FIX2INT(color_mode), bytes, pos, palette);
112
+ }
113
+ }
114
+
115
+ if (FIX2INT(filtering) != OILY_PNG_FILTER_NONE) {
116
+ for (y = height - 1; y >= 0; y--) {
117
+ switch (FIX2INT(filtering)) {
118
+ case OILY_PNG_FILTER_SUB: oily_png_encode_filter_sub( bytes, line_size * y, line_size, pixel_size); break;
119
+ case OILY_PNG_FILTER_UP: oily_png_encode_filter_up( bytes, line_size * y, line_size, pixel_size); break;
120
+ case OILY_PNG_FILTER_AVERAGE: oily_png_encode_filter_average( bytes, line_size * y, line_size, pixel_size); break;
121
+ case OILY_PNG_FILTER_PAETH: oily_png_encode_filter_paeth( bytes, line_size * y, line_size, pixel_size); break;
122
+ default: exit(1);
123
+ }
124
+ }
125
+ }
126
+
127
+ rb_str_cat(stream, bytes, pass_size);
128
+
129
+ return Qnil;
130
+ }
@@ -0,0 +1,7 @@
1
+ #ifndef PNG_ENCODING_H
2
+ #define PNG_ENCODING_H
3
+
4
+ // Function to overwrite ChunkyPNG::Canvas::PNGEncoding.encode_png_image_pass_to_stream
5
+ VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE color_mode, VALUE filtering);
6
+
7
+ #endif
@@ -1,14 +1,17 @@
1
1
  require 'chunky_png'
2
- require 'oily_png/png_decoding'
3
2
 
4
3
  module OilyPNG
5
4
 
6
- VERSION = "0.0.3"
5
+ VERSION = "0.0.4"
7
6
 
8
7
  def self.included(base)
9
8
  base::Canvas.extend OilyPNG::PNGDecoding
9
+ base::Canvas.include OilyPNG::PNGEncoding
10
10
  end
11
11
 
12
12
  end
13
13
 
14
+ require 'oily_png/oily_png_ext'
15
+
16
+ # Include mixin into ChunkyPNG
14
17
  ChunkyPNG.send(:include, OilyPNG)
@@ -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.3"
7
+ s.version = "0.0.4"
8
8
  s.date = "2010-10-05"
9
9
 
10
10
  s.summary = "Native mixin to speed up ChunkyPNG"
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib", "ext"]
21
21
 
22
22
  s.required_rubygems_version = '1.3.7'
23
- s.add_runtime_dependency('chunky_png', '~> 0.10.1')
23
+ s.add_runtime_dependency('chunky_png', '~> 0.10.2')
24
24
 
25
25
  s.add_development_dependency('rake')
26
26
  s.add_development_dependency('rspec', '>= 1.3')
@@ -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/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)
33
+ s.files = %w(.gitignore Gemfile Gemfile.lock LICENSE README.rdoc Rakefile ext/oily_png/extconf.rb ext/oily_png/oily_png_ext.c ext/oily_png/oily_png_ext.h ext/oily_png/png_decoding.c ext/oily_png/png_decoding.h ext/oily_png/png_encoding.c ext/oily_png/png_encoding.h lib/oily_png.rb oily_png.gemspec spec/decoding_spec.rb spec/encoding_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 spec/encoding_spec.rb)
35
35
  end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe OilyPNG::PNGEncoding do
4
+
5
+ context 'encoding different color modes' do
6
+ before do
7
+ @canvas = ChunkyPNG::Canvas.from_file(resource_file('gray.png'))
8
+ @oily_canvas = OilyCanvas.from_canvas(@canvas)
9
+ end
10
+
11
+ it "should encode an image using grayscale correctly" do
12
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_GRAYSCALE, ChunkyPNG::FILTER_NONE)
13
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_GRAYSCALE, ChunkyPNG::FILTER_NONE)
14
+ stream1.should == stream2
15
+ end
16
+
17
+ it "should encode an image using grayscale alpha correctly" do
18
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_GRAYSCALE_ALPHA, ChunkyPNG::FILTER_NONE)
19
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_GRAYSCALE_ALPHA, ChunkyPNG::FILTER_NONE)
20
+ stream1.should == stream2
21
+ end
22
+
23
+ it "should encode an image using truecolor correctly" do
24
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_NONE)
25
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_NONE)
26
+ stream1.should == stream2
27
+ end
28
+
29
+ it "should encode an image using truecolor alpha correctly" do
30
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_TRUECOLOR_ALPHA, ChunkyPNG::FILTER_NONE)
31
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_TRUECOLOR_ALPHA, ChunkyPNG::FILTER_NONE)
32
+ stream1.should == stream2
33
+ end
34
+
35
+ it "should encode an image using indexed colors correctly" do
36
+ # Setup an encoding palette first
37
+ mock_palette = mock('palette', :index => 0xab)
38
+ @canvas.stub(:encoding_palette).and_return(mock_palette)
39
+ @oily_canvas.stub(:encoding_palette).and_return(mock_palette)
40
+
41
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_INDEXED, ChunkyPNG::FILTER_NONE)
42
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_INDEXED, ChunkyPNG::FILTER_NONE)
43
+ stream1.should == stream2
44
+ end
45
+ end
46
+
47
+ context 'encoding different filters' do
48
+ before do
49
+ @canvas = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
50
+ @oily_canvas = OilyCanvas.from_canvas(@canvas)
51
+ end
52
+
53
+ it "should encode correctly with no filtering" do
54
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_NONE)
55
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_NONE)
56
+ stream1.should == stream2
57
+ end
58
+
59
+ it "should encode correctly with sub filtering" do
60
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_SUB)
61
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_SUB)
62
+ stream1.should == stream2
63
+ end
64
+
65
+ it "should encode correctly with up filtering" do
66
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_UP)
67
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_UP)
68
+ stream1.should == stream2
69
+ end
70
+
71
+ it "should encode correctly with average filtering" do
72
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_AVERAGE)
73
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_AVERAGE)
74
+ stream1.should == stream2
75
+ end
76
+
77
+ it "should encode correctly with paeth filtering" do
78
+ @oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_PAETH)
79
+ @canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_PAETH)
80
+ stream1.should == stream2
81
+ end
82
+ end
83
+ end
@@ -5,10 +5,11 @@ Bundler.setup
5
5
 
6
6
  require 'spec'
7
7
  require 'chunky_png'
8
- require 'oily_png/png_decoding'
8
+ require 'oily_png/oily_png_ext'
9
9
 
10
10
  class OilyCanvas < ChunkyPNG::Canvas
11
11
  extend OilyPNG::PNGDecoding
12
+ include OilyPNG::PNGEncoding
12
13
  end
13
14
 
14
15
  module ResourceHelper
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: 25
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Willem van Bergen
@@ -24,12 +24,12 @@ dependencies:
24
24
  requirements:
25
25
  - - ~>
26
26
  - !ruby/object:Gem::Version
27
- hash: 53
27
+ hash: 51
28
28
  segments:
29
29
  - 0
30
30
  - 10
31
- - 1
32
- version: 0.10.1
31
+ - 2
32
+ version: 0.10.2
33
33
  requirement: *id001
34
34
  name: chunky_png
35
35
  prerelease: false
@@ -80,10 +80,16 @@ files:
80
80
  - README.rdoc
81
81
  - Rakefile
82
82
  - ext/oily_png/extconf.rb
83
+ - ext/oily_png/oily_png_ext.c
84
+ - ext/oily_png/oily_png_ext.h
83
85
  - ext/oily_png/png_decoding.c
86
+ - ext/oily_png/png_decoding.h
87
+ - ext/oily_png/png_encoding.c
88
+ - ext/oily_png/png_encoding.h
84
89
  - lib/oily_png.rb
85
90
  - oily_png.gemspec
86
91
  - spec/decoding_spec.rb
92
+ - spec/encoding_spec.rb
87
93
  - spec/resources/gray.png
88
94
  - spec/resources/operations.png
89
95
  - spec/spec_helper.rb
@@ -132,3 +138,4 @@ specification_version: 3
132
138
  summary: Native mixin to speed up ChunkyPNG
133
139
  test_files:
134
140
  - spec/decoding_spec.rb
141
+ - spec/encoding_spec.rb