oily_png 0.0.3 → 0.0.4

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.
@@ -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