oily_png 0.0.6 → 0.0.7

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/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oily_png (0.0.6)
4
+ oily_png (0.0.7)
5
5
  chunky_png (~> 0.10.2)
6
6
 
7
7
  GEM
data/README.rdoc CHANGED
@@ -3,7 +3,9 @@
3
3
  OilyPNG is a Ruby C extension to speed up the pure Ruby ChunkyPNG library. It is a standalone
4
4
  module, so it does not require LibPNG, ImageMagick or any other library. Currently it has an
5
5
  alternative implementation of decoding and encoding PNGs, making these operations much
6
- faster for PNG images that apply filtering.
6
+ faster, especially for PNG images that apply filtering.
7
+
8
+ Performance comparison: http://gist.github.com/611255
7
9
 
8
10
  *Warning*: this is my first C code in years. It may blow up your PC after leaking memory all
9
11
  over the place, killing a kitten in the process. You have been warned.
@@ -94,7 +94,7 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
94
94
  }
95
95
 
96
96
  // Select the pixel decoder function for this color mode.
97
- PIXEL (*pixel_decoder)(int, BYTE*, int, VALUE);
97
+ PIXEL (*pixel_decoder)(int, BYTE*, int, VALUE) = NULL;
98
98
  switch (FIX2INT(color_mode)) {
99
99
  case OILY_PNG_COLOR_GRAYSCALE: pixel_decoder = &oily_png_decode_pixel_grayscale; break;
100
100
  case OILY_PNG_COLOR_TRUECOLOR: pixel_decoder = &oily_png_decode_pixel_truecolor; break;
@@ -1,33 +1,35 @@
1
1
  #include "oily_png_ext.h"
2
2
 
3
- void oily_png_encode_pixel(PIXEL pixel, int color_mode, BYTE* bytes, int pos, VALUE palette) {
4
- switch (color_mode) {
5
- case OILY_PNG_COLOR_GRAYSCALE:
6
- bytes[pos] = R_BYTE(pixel);
7
- break;
8
- case OILY_PNG_COLOR_TRUECOLOR:
9
- bytes[pos + 0] = R_BYTE(pixel);
10
- bytes[pos + 1] = G_BYTE(pixel);
11
- bytes[pos + 2] = B_BYTE(pixel);
12
- break;
13
- case OILY_PNG_COLOR_INDEXED:
14
- bytes[pos] = (BYTE) NUM2UINT(rb_funcall(palette, rb_intern("index"), 1, UINT2NUM(pixel)));
15
- break;
16
- case OILY_PNG_COLOR_GRAYSCALE_ALPHA:
17
- bytes[pos + 0] = R_BYTE(pixel);
18
- bytes[pos + 1] = A_BYTE(pixel);
19
- break;
20
- case OILY_PNG_COLOR_TRUECOLOR_ALPHA:
21
- bytes[pos + 0] = R_BYTE(pixel);
22
- bytes[pos + 1] = G_BYTE(pixel);
23
- bytes[pos + 2] = B_BYTE(pixel);
24
- bytes[pos + 3] = A_BYTE(pixel);
25
- break;
26
- default:
27
- rb_raise(rb_eRuntimeError, "Unsupported color mode: %d", color_mode);
28
- }
3
+ ///// Pixel encoding functions //////////////////////////////////////////
4
+
5
+ void oily_png_encode_pixel_grayscale(PIXEL pixel, BYTE* bytes, int pos, VALUE palette) {
6
+ bytes[pos] = R_BYTE(pixel);
29
7
  }
30
8
 
9
+ void oily_png_encode_pixel_grayscale_alpha(PIXEL pixel, BYTE* bytes, int pos, VALUE palette) {
10
+ bytes[pos + 0] = R_BYTE(pixel);
11
+ bytes[pos + 1] = A_BYTE(pixel);
12
+ }
13
+
14
+ void oily_png_encode_pixel_truecolor(PIXEL pixel, BYTE* bytes, int pos, VALUE palette) {
15
+ bytes[pos + 0] = R_BYTE(pixel);
16
+ bytes[pos + 1] = G_BYTE(pixel);
17
+ bytes[pos + 2] = B_BYTE(pixel);
18
+ }
19
+
20
+ void oily_png_encode_pixel_truecolor_alpha(PIXEL pixel, BYTE* bytes, int pos, VALUE palette) {
21
+ bytes[pos + 0] = R_BYTE(pixel);
22
+ bytes[pos + 1] = G_BYTE(pixel);
23
+ bytes[pos + 2] = B_BYTE(pixel);
24
+ bytes[pos + 3] = A_BYTE(pixel);
25
+ }
26
+
27
+ void oily_png_encode_pixel_indexed(PIXEL pixel, BYTE* bytes, int pos, VALUE palette) {
28
+ bytes[pos] = (BYTE) NUM2UINT(rb_funcall(palette, rb_intern("index"), 1, UINT2NUM(pixel)));
29
+ }
30
+
31
+ ///// Scanline filtering functions //////////////////////////////////////////
32
+
31
33
  void oily_png_encode_filter_sub(BYTE* bytes, int pos, int line_size, int pixel_size) {
32
34
  int x;
33
35
  for (x = line_size - 1; x > pixel_size; x--) {
@@ -66,7 +68,6 @@ void oily_png_encode_filter_paeth(BYTE* bytes, int pos, int line_size, int pixel
66
68
  pr = (pa <= pb && pa <= pc) ? a : (pb <= pc ? b : c);
67
69
  FILTER_BYTE(bytes[pos + x], pr);
68
70
  }
69
-
70
71
  }
71
72
 
72
73
  VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE color_mode, VALUE filtering) {
@@ -80,6 +81,7 @@ VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE c
80
81
  rb_raise(rb_eRuntimeError, "The number of pixels does not match the canvas dimensions.");
81
82
  }
82
83
 
84
+ // Get the encoding palette if we're encoding to an indexed bytestream.
83
85
  VALUE palette = Qnil;
84
86
  if (FIX2INT(color_mode) == OILY_PNG_COLOR_INDEXED) {
85
87
  palette = rb_funcall(self, rb_intern("encoding_palette"), 0);
@@ -92,6 +94,18 @@ VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE c
92
94
  // Allocate memory for the byte array.
93
95
  BYTE* bytes = ALLOCA_N(BYTE, pass_size);
94
96
 
97
+ // Select out pixel encoder function based on the color mode.
98
+ void (*pixel_encoder)(PIXEL, BYTE*, int, VALUE) = NULL;
99
+ switch (FIX2INT(color_mode)) {
100
+ case OILY_PNG_COLOR_GRAYSCALE: pixel_encoder = &oily_png_encode_pixel_grayscale; break;
101
+ case OILY_PNG_COLOR_TRUECOLOR: pixel_encoder = &oily_png_encode_pixel_truecolor; break;
102
+ case OILY_PNG_COLOR_INDEXED: pixel_encoder = &oily_png_encode_pixel_indexed; break;
103
+ case OILY_PNG_COLOR_GRAYSCALE_ALPHA: pixel_encoder = &oily_png_encode_pixel_grayscale_alpha; break;
104
+ case OILY_PNG_COLOR_TRUECOLOR_ALPHA: pixel_encoder = &oily_png_encode_pixel_truecolor_alpha; break;
105
+ default: rb_raise(rb_eRuntimeError, "Unsupported color mode: %d", color_mode);
106
+ }
107
+
108
+ // Loop over all the pixels to encode them into the byte array.
95
109
  PIXEL pixel;
96
110
  int x, y, pos;
97
111
  for (y = 0; y < height; y++) {
@@ -100,22 +114,30 @@ VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE c
100
114
  for (x = 0; x < width; x++) {
101
115
  pixel = NUM2UINT(rb_ary_entry(pixels, y * height + x));
102
116
  pos = (line_size * y) + (pixel_size * x) + 1;
103
- oily_png_encode_pixel(pixel, FIX2INT(color_mode), bytes, pos, palette);
117
+ pixel_encoder(pixel, bytes, pos, palette);
104
118
  }
105
119
  }
106
120
 
121
+ // Check if we are going to apply any filtering
107
122
  if (FIX2INT(filtering) != OILY_PNG_FILTER_NONE) {
123
+
124
+ // Assign the chosen filter function to the scanline_filter variable.
125
+ void (*scanline_filter)(BYTE*, int, int, int) = NULL;
126
+ switch (FIX2INT(filtering)) {
127
+ case OILY_PNG_FILTER_SUB: scanline_filter = &oily_png_encode_filter_sub; break;
128
+ case OILY_PNG_FILTER_UP: scanline_filter = &oily_png_encode_filter_up; break;
129
+ case OILY_PNG_FILTER_AVERAGE: scanline_filter = &oily_png_encode_filter_average; break;
130
+ case OILY_PNG_FILTER_PAETH: scanline_filter = &oily_png_encode_filter_paeth; break;
131
+ default: rb_raise(rb_eRuntimeError, "Unsupported filter type: %d", FIX2INT(filtering));
132
+ }
133
+
134
+ // Now, apply the scanline_filter function to every line, backwards.
108
135
  for (y = height - 1; y >= 0; y--) {
109
- switch (FIX2INT(filtering)) {
110
- case OILY_PNG_FILTER_SUB: oily_png_encode_filter_sub( bytes, line_size * y, line_size, pixel_size); break;
111
- case OILY_PNG_FILTER_UP: oily_png_encode_filter_up( bytes, line_size * y, line_size, pixel_size); break;
112
- case OILY_PNG_FILTER_AVERAGE: oily_png_encode_filter_average( bytes, line_size * y, line_size, pixel_size); break;
113
- case OILY_PNG_FILTER_PAETH: oily_png_encode_filter_paeth( bytes, line_size * y, line_size, pixel_size); break;
114
- default: rb_raise(rb_eRuntimeError, "Unsupported filter type: %d", FIX2INT(filtering));
115
- }
136
+ scanline_filter(bytes, line_size * y, line_size, pixel_size);
116
137
  }
117
138
  }
118
139
 
140
+ // Append to encoded image pass to the output stream.
119
141
  rb_str_cat(stream, (char*) bytes, pass_size);
120
142
  return Qnil;
121
143
  }
data/lib/oily_png.rb CHANGED
@@ -2,7 +2,7 @@ require 'chunky_png'
2
2
 
3
3
  module OilyPNG
4
4
 
5
- VERSION = "0.0.6"
5
+ VERSION = "0.0.7"
6
6
 
7
7
  def self.included(base)
8
8
  base::Canvas.send(:extend, OilyPNG::PNGDecoding)
data/oily_png.gemspec CHANGED
@@ -4,8 +4,8 @@ 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.6"
8
- s.date = "2010-10-06"
7
+ s.version = "0.0.7"
8
+ s.date = "2010-10-07"
9
9
 
10
10
  s.summary = "Native mixin to speed up ChunkyPNG"
11
11
  s.description = <<-EOT
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: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Willem van Bergen
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-06 00:00:00 +02:00
18
+ date: 2010-10-07 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency