oily_png 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,7 +13,22 @@ PIXEL oily_png_compose_color(PIXEL fg, PIXEL bg) {
13
13
  new_g = INT8_MULTIPLY(A_BYTE(fg), G_BYTE(fg)) + INT8_MULTIPLY(a_com, G_BYTE(bg));
14
14
  new_b = INT8_MULTIPLY(A_BYTE(fg), B_BYTE(fg)) + INT8_MULTIPLY(a_com, B_BYTE(bg));
15
15
  new_a = A_BYTE(fg) + a_com;
16
-
16
+
17
+ return BUILD_PIXEL(new_r, new_g, new_b, new_a);
18
+ }
19
+
20
+ PIXEL oily_png_color_interpolate_quick(PIXEL fg, PIXEL bg, int alpha) {
21
+ BYTE a_com, new_r, new_g, new_b, new_a;
22
+
23
+ if (alpha >= 255) return fg;
24
+ if (alpha <= 0) return bg;
25
+
26
+ a_com = 255 - alpha;
27
+ new_r = INT8_MULTIPLY(alpha, R_BYTE(fg)) + INT8_MULTIPLY(a_com, R_BYTE(bg));
28
+ new_g = INT8_MULTIPLY(alpha, G_BYTE(fg)) + INT8_MULTIPLY(a_com, G_BYTE(bg));
29
+ new_b = INT8_MULTIPLY(alpha, B_BYTE(fg)) + INT8_MULTIPLY(a_com, B_BYTE(bg));
30
+ new_a = INT8_MULTIPLY(alpha, A_BYTE(fg)) + INT8_MULTIPLY(a_com, A_BYTE(bg));
31
+
17
32
  return BUILD_PIXEL(new_r, new_g, new_b, new_a);
18
33
  }
19
34
 
@@ -23,12 +38,12 @@ VALUE oily_png_color_compose_quick(VALUE self, VALUE fg_color, VALUE bg_color) {
23
38
  }
24
39
 
25
40
  VALUE oily_png_color_r(VALUE self, VALUE value) {
26
- UNUSED_PARAMETER(self);
41
+ UNUSED_PARAMETER(self);
27
42
  return INT2FIX(R_BYTE(NUM2UINT(value)));
28
43
  }
29
44
 
30
45
  VALUE oily_png_color_g(VALUE self, VALUE value) {
31
- UNUSED_PARAMETER(self);
46
+ UNUSED_PARAMETER(self);
32
47
  return INT2FIX(G_BYTE(NUM2UINT(value)));
33
48
  }
34
49
 
@@ -9,15 +9,16 @@
9
9
  #define BUILD_PIXEL(r, g, b, a) (((PIXEL) (r) << 24) + ((PIXEL) (g) << 16) + ((PIXEL) (b) << 8) + (PIXEL) (a))
10
10
  #define INT8_MULTIPLY(a, b) (((((a) * (b) + 0x80) >> 8) + ((a) * (b) + 0x80)) >> 8)
11
11
 
12
- /*
12
+ /*
13
13
  Ruby replacement method for color composition using alpha transparency.
14
-
14
+
15
15
  This method should replace ChunkyPNG::Color.compose_quick
16
16
  */
17
17
  VALUE oily_png_color_compose_quick(VALUE self, VALUE fg_color, VALUE bg_color);
18
18
 
19
19
  /* Color composition using alpha transparency. */
20
20
  PIXEL oily_png_compose_color(PIXEL fg, PIXEL bg);
21
+ PIXEL oily_png_color_interpolate_quick(PIXEL fg, PIXEL bg, int alpha);
21
22
 
22
23
  /* Accessors */
23
24
  VALUE oily_png_color_r(VALUE self, VALUE pixel);
@@ -7,15 +7,16 @@ void Init_oily_png() {
7
7
  rb_define_private_method(OilyPNG_Canvas, "steps_residues", oily_png_canvas_steps_residues, 2);
8
8
  rb_define_private_method(OilyPNG_Canvas, "steps", oily_png_canvas_steps, 2);
9
9
  rb_define_method(OilyPNG_Canvas, "resample_nearest_neighbor!", oily_png_canvas_resample_nearest_neighbor_bang, 2);
10
+ rb_define_method(OilyPNG_Canvas, "resample_bilinear!", oily_png_canvas_resample_bilinear_bang, 2);
10
11
 
11
12
  // Setup decoding module
12
13
  VALUE OilyPNG_PNGDecoding = rb_define_module_under(OilyPNG, "PNGDecoding");
13
14
  rb_define_method(OilyPNG_PNGDecoding, "decode_png_image_pass", oily_png_decode_png_image_pass, 6);
14
-
15
+
15
16
  // Setup encoding module
16
17
  VALUE OilyPNG_PNGEncoding = rb_define_module_under(OilyPNG, "PNGEncoding");
17
18
  rb_define_method(OilyPNG_PNGEncoding, "encode_png_image_pass_to_stream", oily_png_encode_png_image_pass_to_stream, 4);
18
-
19
+
19
20
  // Setup Color module
20
21
  VALUE OilyPNG_Color = rb_define_module_under(OilyPNG, "Color");
21
22
  rb_define_method(OilyPNG_Color, "compose_quick", oily_png_color_compose_quick, 2);
@@ -23,7 +24,7 @@ void Init_oily_png() {
23
24
  rb_define_method(OilyPNG_Color, "g", oily_png_color_g, 1);
24
25
  rb_define_method(OilyPNG_Color, "b", oily_png_color_b, 1);
25
26
  rb_define_method(OilyPNG_Color, "a", oily_png_color_a, 1);
26
-
27
+
27
28
  // Setup Operations module
28
29
  VALUE OilyPNG_Operations = rb_define_module_under(OilyPNG, "Operations");
29
30
  rb_define_method(OilyPNG_Operations, "compose!", oily_png_compose_bang, -1);
@@ -75,10 +75,10 @@ VALUE oily_png_canvas_steps_residues(VALUE self, VALUE v_width, VALUE v_new_widt
75
75
  long width = NUM2LONG(v_width);
76
76
  long new_width = NUM2LONG(v_new_width);
77
77
 
78
-
78
+
79
79
  VALUE ret_steps = rb_ary_new2(new_width);
80
80
  VALUE ret_residues = rb_ary_new2(new_width);
81
-
81
+
82
82
 
83
83
  long *steps = ALLOC_N(long, new_width);
84
84
  long *residues = ALLOC_N(long, new_width);
@@ -91,7 +91,7 @@ VALUE oily_png_canvas_steps_residues(VALUE self, VALUE v_width, VALUE v_new_widt
91
91
  rb_ary_store(ret_steps, i, LONG2FIX(steps[i]));
92
92
  rb_ary_store(ret_residues, i, LONG2FIX(residues[i]));
93
93
  }
94
-
94
+
95
95
  /* This is an unprotected allocation; it will leak on exception.
96
96
  * However, rb_ary_store should not generate one as we have
97
97
  * pre-allocated the array.
@@ -116,7 +116,7 @@ VALUE oily_png_canvas_resample_nearest_neighbor_bang(VALUE self, VALUE v_new_wid
116
116
  long new_height = NUM2LONG(v_new_height);
117
117
 
118
118
  long self_width = NUM2LONG(rb_funcall(self, rb_intern("width"), 0));
119
- long self_height = NUM2LONG(rb_funcall(self, rb_intern("height"), 0));
119
+ long self_height = NUM2LONG(rb_funcall(self, rb_intern("height"), 0));
120
120
 
121
121
  VALUE pixels = rb_ary_new2(new_width*new_height);
122
122
  VALUE source = rb_iv_get(self, "@pixels");
@@ -150,4 +150,64 @@ VALUE oily_png_canvas_resample_nearest_neighbor_bang(VALUE self, VALUE v_new_wid
150
150
  rb_iv_set(self, "@height", LONG2NUM(new_height));
151
151
 
152
152
  return self;
153
- }
153
+ }
154
+
155
+ VALUE oily_png_canvas_resample_bilinear_bang(VALUE self, VALUE v_new_width, VALUE v_new_height) {
156
+ long new_width = NUM2LONG(v_new_width);
157
+ long new_height = NUM2LONG(v_new_height);
158
+
159
+ long self_width = NUM2LONG(rb_funcall(self, rb_intern("width"), 0));
160
+ long self_height = NUM2LONG(rb_funcall(self, rb_intern("height"), 0));
161
+
162
+ VALUE pixels = rb_ary_new2(new_width*new_height);
163
+ VALUE source = rb_iv_get(self, "@pixels");
164
+
165
+ long *index_x = ALLOC_N(long, new_width);
166
+ long *index_y = ALLOC_N(long, new_height);
167
+ long *interp_x = ALLOC_N(long, new_width);
168
+ long *interp_y = ALLOC_N(long, new_height);
169
+
170
+ oily_png_generate_steps_residues(self_width, new_width, index_x, interp_x);
171
+ oily_png_generate_steps_residues(self_height, new_height, index_y, interp_y);
172
+
173
+ long index = 0;
174
+ long x, y;
175
+ long y1, y2, x1, x2;
176
+ uint32_t y_residue, x_residue;
177
+ uint32_t pixel_11, pixel_21, pixel_12, pixel_22;
178
+ uint32_t pixel_top, pixel_bot;
179
+ for (y = 0; y < new_height; y++) {
180
+ y1 = index_y[y] < 0 ? 0 : index_y[y];
181
+ y2 = y1+1 >= self_height ? self_height-1 : y1+1;
182
+ y_residue = interp_y[y];
183
+
184
+ for (x = 0; x < new_width; x++) {
185
+ x1 = index_x[x] < 0 ? 0 : index_x[x];
186
+ x2 = x1+1 >= self_width ? self_height-1 : x1+1;
187
+ x_residue = interp_x[x];
188
+
189
+ pixel_11 = NUM2UINT(rb_ary_entry(source, y1*self_width + x1));
190
+ pixel_21 = NUM2UINT(rb_ary_entry(source, y1*self_width + x2));
191
+ pixel_12 = NUM2UINT(rb_ary_entry(source, y2*self_width + x1));
192
+ pixel_22 = NUM2UINT(rb_ary_entry(source, y2*self_width + x2));
193
+
194
+ pixel_top = oily_png_color_interpolate_quick(pixel_21, pixel_11, x_residue);
195
+ pixel_bot = oily_png_color_interpolate_quick(pixel_22, pixel_12, x_residue);
196
+
197
+ rb_ary_store(pixels, index++, UINT2NUM(oily_png_color_interpolate_quick(pixel_bot, pixel_top, y_residue)));
198
+ }
199
+ }
200
+
201
+ xfree(index_x);
202
+ xfree(index_y);
203
+ xfree(interp_x);
204
+ xfree(interp_y);
205
+ interp_x = NULL;
206
+ interp_y = NULL;
207
+
208
+ rb_iv_set(self, "@pixels", pixels);
209
+ rb_iv_set(self, "@width", LONG2NUM(new_width));
210
+ rb_iv_set(self, "@height", LONG2NUM(new_height));
211
+
212
+ return self;
213
+ }
@@ -8,7 +8,7 @@ void oily_png_generate_steps_residues(long width, long new_width, long *steps, l
8
8
 
9
9
  /*
10
10
  * Generates the interpolation steps through two values.
11
- *
11
+ *
12
12
  * Returns a Ruby Array
13
13
  */
14
14
  VALUE oily_png_canvas_steps_residues(VALUE self, VALUE width, VALUE new_width);
@@ -20,4 +20,6 @@ VALUE oily_png_canvas_steps(VALUE self, VALUE width, VALUE new_width);
20
20
  */
21
21
  VALUE oily_png_canvas_resample_nearest_neighbor_bang(VALUE self, VALUE new_width, VALUE new_height);
22
22
 
23
+ VALUE oily_png_canvas_resample_bilinear_bang(VALUE self, VALUE new_width, VALUE new_height);
24
+
23
25
  #endif
@@ -2,7 +2,7 @@ require 'chunky_png'
2
2
 
3
3
  module OilyPNG
4
4
 
5
- VERSION = "1.0.3"
5
+ VERSION = "1.1.0"
6
6
 
7
7
  def self.included(base)
8
8
  base::Canvas.send(:extend, OilyPNG::PNGDecoding)
@@ -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 = "1.0.3"
8
- s.date = "2013-01-19"
7
+ s.version = "1.1.0"
8
+ s.date = "2013-02-15"
9
9
 
10
10
  s.summary = "Native mixin to speed up ChunkyPNG"
11
11
  s.description = <<-EOT
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.extensions = ["ext/oily_png/extconf.rb"]
20
20
  s.require_paths = ["lib", "ext"]
21
21
 
22
- s.add_runtime_dependency('chunky_png', '~> 1.2.1')
22
+ s.add_runtime_dependency('chunky_png', '~> 1.2.7')
23
23
 
24
24
  s.add_development_dependency('rake')
25
25
  s.add_development_dependency('rake-compiler')
@@ -25,15 +25,27 @@ describe OilyPNG::Resampling do
25
25
  end
26
26
 
27
27
  it "should resample [0,1,2,3] to 99x45 as ChunkyPNG does" do
28
- ChunkyPNG::Canvas.new(2,2,[0,1,2,3]).resample_nearest_neighbor(99,45).should == OilyPNG::Canvas.new(2,2,[0,1,2,3]).resample_nearest_neighbor(99,45)
28
+ ChunkyPNG::Canvas.new(2,2,[0,1,2,3]).resample_nearest_neighbor(99,45).should == OilyPNG::Canvas.new(2,2,[0,1,2,3]).resample_nearest_neighbor(99,45)
29
29
  end
30
30
 
31
31
  it "should resample an image to 10x20 as ChunkyPNG does" do
32
32
  @reference.resample_nearest_neighbor(10,20).should == OilyPNG::Canvas.from_canvas(@reference).resample_nearest_neighbor(10,20)
33
33
  end
34
-
34
+
35
35
  it "should resample an image to 11x19 as ChunkyPNG does" do
36
36
  @reference.resample_nearest_neighbor(11,19).should == OilyPNG::Canvas.from_canvas(@reference).resample_nearest_neighbor(11,19)
37
37
  end
38
38
  end
39
+
40
+ describe '#resample_bilinear!' do
41
+ before(:all) { @reference = ChunkyPNG::Canvas.from_file(resource_file('nonsquare.png'))}
42
+
43
+ it "should resample an image to 10x20 as ChunkyPNG does" do
44
+ @reference.resample_bilinear(10,20).should == OilyPNG::Canvas.from_canvas(@reference).resample_bilinear(10,20)
45
+ end
46
+
47
+ it "should resample an image to 11x19 as ChunkyPNG does" do
48
+ @reference.resample_bilinear(11,19).should == OilyPNG::Canvas.from_canvas(@reference).resample_bilinear(11,19)
49
+ end
50
+ end
39
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oily_png
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-19 00:00:00.000000000 Z
12
+ date: 2013-02-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chunky_png
16
- requirement: &70150338537120 !ruby/object:Gem::Requirement
16
+ requirement: &70329825895620 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 1.2.1
21
+ version: 1.2.7
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70150338537120
24
+ version_requirements: *70329825895620
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70150338536620 !ruby/object:Gem::Requirement
27
+ requirement: &70329825894740 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70150338536620
35
+ version_requirements: *70329825894740
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake-compiler
38
- requirement: &70150338535960 !ruby/object:Gem::Requirement
38
+ requirement: &70329825892520 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70150338535960
46
+ version_requirements: *70329825892520
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70150338534780 !ruby/object:Gem::Requirement
49
+ requirement: &70329825890860 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '2'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70150338534780
57
+ version_requirements: *70329825890860
58
58
  description: ! ' This Ruby C extenstion defines a module that can be included into
59
59
  ChunkyPNG to improve its speed.
60
60