psd_native 0.6.0 → 1.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 960643fec9eb4c5832460760e567953247189174
4
- data.tar.gz: b3000995230c06cad6c95112e30e9be26d70c6aa
3
+ metadata.gz: 0267ebc332f459a2246da73dbb83ba072c6689a4
4
+ data.tar.gz: de14d32f2fe1a2ea603487364783085c5821266a
5
5
  SHA512:
6
- metadata.gz: 9da0d02c2b6eb361f3750d44d370ed165af072e03f0ee91a66721da8e516d23213d93e30586630dca03aeba5ffbf4581cf691caf3c480d21401bede582ed46de
7
- data.tar.gz: 5d2fc658099b074118b6890bcf0608a2be393fef2a415e1f2aba389500f6d6386bdb53c70b8ac0fca87214bc276d250e1015961082507f94260c3aacb36bde1c
6
+ metadata.gz: d8934cedf3e9142a63974542b4fce9ab0b1c3c687626bfa735a289e6ecc2cf08b38232177fe59cf159ceea5578c7b51ceed6871be17869473145fcc79a7f0c3f
7
+ data.tar.gz: 558be83a9bde428df951a1377294badabf601a4c772bded8402eb75c5d3537619665781d263ad352a30cee5bb0c7ae9a361ed0809b61603547237b5e2e1d102e
data/Gemfile CHANGED
@@ -1,6 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # gem 'psd', git: 'git@github.com:layervault/psd.rb'
4
-
5
3
  # Specify your gem's dependencies in psd_native.gemspec
6
4
  gemspec
@@ -0,0 +1,57 @@
1
+ #include "psd_native_ext.h"
2
+
3
+ VALUE psd_native_blender_compose_bang(VALUE self) {
4
+ psd_logger("debug", "Composing with native code");
5
+
6
+ VALUE Compose = rb_const_get(
7
+ rb_const_get(rb_cObject, rb_intern("PSD")),
8
+ rb_intern("Compose")
9
+ );
10
+
11
+ VALUE fg = rb_iv_get(self, "@fg");
12
+ VALUE bg = rb_iv_get(self, "@bg");
13
+
14
+ VALUE fg_canvas = rb_funcall(fg, rb_intern("canvas"), 0);
15
+ VALUE bg_canvas = rb_funcall(bg, rb_intern("canvas"), 0);
16
+
17
+ VALUE fg_pixels = rb_funcall(fg_canvas, rb_intern("pixels"), 0);
18
+ VALUE bg_pixels = rb_funcall(bg_canvas, rb_intern("pixels"), 0);
19
+ VALUE *bg_pixels_ptr = RARRAY_PTR(bg_pixels);
20
+
21
+ int fg_width = FIX2INT(rb_funcall(fg, rb_intern("width"), 0));
22
+ int bg_height = FIX2INT(rb_funcall(bg, rb_intern("height"), 0));
23
+ int bg_width = FIX2INT(rb_funcall(bg, rb_intern("width"), 0));
24
+
25
+ int offset_x = FIX2INT(rb_funcall(fg, rb_intern("left"), 0)) - FIX2INT(rb_funcall(bg, rb_intern("left"), 0));
26
+ int offset_y = FIX2INT(rb_funcall(fg, rb_intern("top"), 0)) - FIX2INT(rb_funcall(bg, rb_intern("top"), 0));
27
+
28
+ VALUE blending_mode = rb_intern_str(rb_funcall(rb_funcall(fg, rb_intern("node"), 0), rb_intern("blending_mode"), 0));
29
+ VALUE options = rb_funcall(self, rb_intern("compose_options"), 0);
30
+
31
+ int i, len, x, y, base_x, base_y;
32
+ VALUE color;
33
+ for (i = 0, len = RARRAY_LEN(fg_pixels); i < len; i++) {
34
+ x = (i % fg_width);
35
+ y = floor(i / fg_width);
36
+
37
+ base_x = x + offset_x;
38
+ base_y = y + offset_y;
39
+
40
+ if (base_x < 0 || base_y < 0 || base_x >= bg_width || base_y >= bg_height) {
41
+ continue;
42
+ }
43
+
44
+ color = rb_funcall(
45
+ Compose,
46
+ blending_mode,
47
+ 3,
48
+ rb_funcall(fg_canvas, rb_intern("[]"), 2, INT2FIX(x), INT2FIX(y)),
49
+ bg_pixels_ptr[base_y * bg_width + base_x],
50
+ options
51
+ );
52
+
53
+ rb_ary_store(bg_pixels, base_y * bg_width + base_x, color);
54
+ }
55
+
56
+ return Qnil;
57
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef PSD_NATIVE_BLENDER
2
+ #define PSD_NATIVE_BLENDER
3
+
4
+ VALUE psd_native_blender_compose_bang(VALUE self);
5
+
6
+ #endif
@@ -0,0 +1,9 @@
1
+ #include "psd_native_ext.h"
2
+
3
+ VALUE psd_canvas_to_pixel_array(VALUE canvas) {
4
+ return rb_funcall(
5
+ rb_funcall(canvas, rb_intern("canvas"), 0),
6
+ rb_intern("pixels"),
7
+ 0
8
+ );
9
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef PSD_NATIVE_CANVAS
2
+ #define PSD_NATIVE_CANVAS
3
+
4
+ VALUE psd_canvas_to_pixel_array(VALUE canvas);
5
+
6
+ #endif
@@ -1,60 +1,55 @@
1
1
  #include "psd_native_ext.h"
2
2
 
3
- VALUE psd_native_clipping_mask_apply(VALUE self) {
4
- VALUE layer = rb_iv_get(self, "@layer");
5
- if (rb_funcall(layer, rb_intern("clipped?"), 0) == Qfalse) {
6
- return rb_iv_get(self, "@png");
3
+ VALUE psd_native_clipping_mask_apply_bang(VALUE self) {
4
+ VALUE node = rb_iv_get(self, "@node");
5
+ if (rb_funcall(node, rb_intern("clipped?"), 0) == Qfalse) {
6
+ return Qnil;
7
7
  }
8
8
 
9
9
  psd_logger("debug", "Applying clipping mask with native code");
10
10
 
11
- VALUE *dim = RARRAY_PTR(rb_funcall(layer, rb_intern("document_dimensions"), 0));
12
- VALUE full_png = rb_funcall(self, rb_intern("compose_to_full"), 0);
13
-
14
- uint32_t width = FIX2UINT(dim[0]);
15
- uint32_t height = FIX2UINT(dim[1]);
16
- VALUE mask = rb_funcall(self, rb_intern("mask"), 0);
17
- VALUE pixel_data = rb_funcall(rb_funcall(mask, rb_intern("image"), 0), rb_intern("pixel_data"), 0);
18
- VALUE pixel;
19
- uint32_t color;
20
- int mask_top = FIX2INT(rb_funcall(mask, rb_intern("top"), 0)),
21
- mask_bottom = FIX2INT(rb_funcall(mask, rb_intern("bottom"), 0)),
22
- mask_left = FIX2INT(rb_funcall(mask, rb_intern("left"), 0)),
23
- mask_right = FIX2INT(rb_funcall(mask, rb_intern("right"), 0)),
24
- mask_width = FIX2INT(rb_funcall(mask, rb_intern("width"), 0)),
25
- alpha = 0,
26
- mask_x, mask_y;
27
-
28
- int x, y;
29
- for (y = 0; y < height; y++) {
30
- for (x = 0; x < width; x++) {
31
- if (y < mask_top || y > mask_bottom || x < mask_left || x > mask_right) {
11
+ VALUE canvas = rb_iv_get(self, "@canvas");
12
+ VALUE canvas_pixels = psd_canvas_to_pixel_array(canvas);
13
+ VALUE mask = rb_iv_get(self, "@mask");
14
+ VALUE *mask_pixels = RARRAY_PTR(psd_canvas_to_pixel_array(mask));
15
+
16
+ uint32_t canvas_width = FIX2UINT(rb_funcall(canvas, rb_intern("width"), 0));
17
+ uint32_t canvas_height = FIX2UINT(rb_funcall(canvas, rb_intern("height"), 0));
18
+ int canvas_left = FIX2INT(rb_funcall(canvas, rb_intern("left"), 0));
19
+ int canvas_top = FIX2INT(rb_funcall(canvas, rb_intern("top"), 0));
20
+
21
+ uint32_t mask_width = FIX2UINT(rb_funcall(mask, rb_intern("width"), 0));
22
+ uint32_t mask_height = FIX2UINT(rb_funcall(mask, rb_intern("height"), 0));
23
+ int mask_left = FIX2INT(rb_funcall(mask, rb_intern("left"), 0));
24
+ int mask_top = FIX2INT(rb_funcall(mask, rb_intern("top"), 0));
25
+ int mask_pixel_length = mask_width * mask_height;
26
+
27
+ int x, y, doc_x, doc_y, mask_x, mask_y;
28
+ uint32_t alpha, color, loc;
29
+ for (y = 0; y < canvas_height; y++) {
30
+ for (x = 0; x < canvas_width; x++) {
31
+ doc_x = canvas_left + x;
32
+ doc_y = canvas_top + y;
33
+
34
+ mask_x = doc_x - mask_left;
35
+ mask_y = doc_y - mask_top;
36
+
37
+ if (mask_x < 0 || mask_x > mask_width || mask_y < 0 || mask_y > mask_height) {
32
38
  alpha = 0;
33
39
  } else {
34
- mask_x = x - mask_left;
35
- mask_y = y - mask_top;
40
+ loc = mask_y * mask_width + mask_x;
36
41
 
37
- pixel = rb_ary_entry(pixel_data, mask_y * mask_width + mask_x);
38
- if (pixel == Qnil) {
42
+ if (loc > mask_pixel_length) {
39
43
  alpha = 0;
40
44
  } else {
41
- alpha = A(FIX2UINT(pixel));
45
+ alpha = A(FIX2UINT(mask_pixels[loc]));
42
46
  }
43
47
  }
44
48
 
45
- color = FIX2UINT(rb_funcall(full_png, rb_intern("[]"), 2, INT2FIX(x), INT2FIX(y)));
46
- color = (color & 0xffffff00) | (A(color) * alpha / 255);
47
- rb_funcall(full_png, rb_intern("set_pixel"), 3, INT2FIX(x), INT2FIX(y), INT2FIX(color));
49
+ color = FIX2UINT(rb_ary_entry(canvas_pixels, y * canvas_width + x));
50
+ rb_ary_store(canvas_pixels, y * canvas_width + x, INT2FIX((color & 0xffffff00) | (A(color) * alpha / 255)));
48
51
  }
49
52
  }
50
53
 
51
- return rb_funcall(
52
- full_png,
53
- rb_intern("crop!"),
54
- 4,
55
- rb_funcall(layer, rb_intern("left"), 0),
56
- rb_funcall(layer, rb_intern("top"), 0),
57
- rb_funcall(layer, rb_intern("width"), 0),
58
- rb_funcall(layer, rb_intern("height"), 0)
59
- );
54
+ return Qnil;
60
55
  }
@@ -1,6 +1,6 @@
1
1
  #ifndef PSD_NATIVE_CLIPPING_MASK
2
2
  #define PSD_NATIVE_CLIPPING_MASK
3
3
 
4
- VALUE psd_native_clipping_mask_apply(VALUE self);
4
+ VALUE psd_native_clipping_mask_apply_bang(VALUE self);
5
5
 
6
6
  #endif
@@ -8,7 +8,7 @@ VALUE psd_native_compose_normal(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts)
8
8
  PIXEL bg = FIX2UINT(r_bg);
9
9
  PIXEL new_r, new_g, new_b;
10
10
 
11
- if (OPAQUE(fg) || TRANSPARENT(bg)) return r_fg;
11
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
12
12
  if (TRANSPARENT(fg)) return r_bg;
13
13
 
14
14
  calculate_alphas(fg, bg, &opts);
@@ -25,7 +25,7 @@ VALUE psd_native_compose_darken(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts)
25
25
  PIXEL bg = FIX2UINT(r_bg);
26
26
  PIXEL new_r, new_g, new_b;
27
27
 
28
- if (TRANSPARENT(bg)) return r_fg;
28
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
29
29
  if (TRANSPARENT(fg)) return r_bg;
30
30
 
31
31
  calculate_alphas(fg, bg, &opts);
@@ -42,7 +42,7 @@ VALUE psd_native_compose_multiply(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts
42
42
  PIXEL bg = FIX2UINT(r_bg);
43
43
  PIXEL new_r, new_g, new_b;
44
44
 
45
- if (TRANSPARENT(bg)) return r_fg;
45
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
46
46
  if (TRANSPARENT(fg)) return r_bg;
47
47
 
48
48
  calculate_alphas(fg, bg, &opts);
@@ -59,7 +59,7 @@ VALUE psd_native_compose_color_burn(VALUE self, VALUE r_fg, VALUE r_bg, VALUE op
59
59
  PIXEL bg = FIX2UINT(r_bg);
60
60
  PIXEL new_r, new_g, new_b;
61
61
 
62
- if (TRANSPARENT(bg)) return r_fg;
62
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
63
63
  if (TRANSPARENT(fg)) return r_bg;
64
64
 
65
65
  calculate_alphas(fg, bg, &opts);
@@ -85,7 +85,7 @@ VALUE psd_native_compose_linear_burn(VALUE self, VALUE r_fg, VALUE r_bg, VALUE o
85
85
  PIXEL bg = FIX2UINT(r_bg);
86
86
  PIXEL new_r, new_g, new_b;
87
87
 
88
- if (TRANSPARENT(bg)) return r_fg;
88
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
89
89
  if (TRANSPARENT(fg)) return r_bg;
90
90
 
91
91
  calculate_alphas(fg, bg, &opts);
@@ -102,7 +102,7 @@ VALUE psd_native_compose_lighten(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts)
102
102
  PIXEL bg = FIX2UINT(r_bg);
103
103
  PIXEL new_r, new_g, new_b;
104
104
 
105
- if (TRANSPARENT(bg)) return r_fg;
105
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
106
106
  if (TRANSPARENT(fg)) return r_bg;
107
107
 
108
108
  calculate_alphas(fg, bg, &opts);
@@ -119,7 +119,7 @@ VALUE psd_native_compose_screen(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts)
119
119
  PIXEL bg = FIX2UINT(r_bg);
120
120
  PIXEL new_r, new_g, new_b;
121
121
 
122
- if (TRANSPARENT(bg)) return r_fg;
122
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
123
123
  if (TRANSPARENT(fg)) return r_bg;
124
124
 
125
125
  calculate_alphas(fg, bg, &opts);
@@ -136,7 +136,7 @@ VALUE psd_native_compose_color_dodge(VALUE self, VALUE r_fg, VALUE r_bg, VALUE o
136
136
  PIXEL bg = FIX2UINT(r_bg);
137
137
  PIXEL new_r, new_g, new_b;
138
138
 
139
- if (TRANSPARENT(bg)) return r_fg;
139
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
140
140
  if (TRANSPARENT(fg)) return r_bg;
141
141
 
142
142
  calculate_alphas(fg, bg, &opts);
@@ -161,7 +161,7 @@ VALUE psd_native_compose_linear_dodge(VALUE self, VALUE r_fg, VALUE r_bg, VALUE
161
161
  PIXEL bg = FIX2UINT(r_bg);
162
162
  PIXEL new_r, new_g, new_b;
163
163
 
164
- if (TRANSPARENT(bg)) return r_fg;
164
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
165
165
  if (TRANSPARENT(fg)) return r_bg;
166
166
 
167
167
  calculate_alphas(fg, bg, &opts);
@@ -178,7 +178,7 @@ VALUE psd_native_compose_overlay(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts)
178
178
  PIXEL bg = FIX2UINT(r_bg);
179
179
  PIXEL new_r, new_g, new_b;
180
180
 
181
- if (TRANSPARENT(bg)) return r_fg;
181
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
182
182
  if (TRANSPARENT(fg)) return r_bg;
183
183
 
184
184
  calculate_alphas(fg, bg, &opts);
@@ -203,7 +203,7 @@ VALUE psd_native_compose_soft_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE op
203
203
  PIXEL bg = FIX2UINT(r_bg);
204
204
  PIXEL new_r, new_g, new_b;
205
205
 
206
- if (TRANSPARENT(bg)) return r_fg;
206
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
207
207
  if (TRANSPARENT(fg)) return r_bg;
208
208
 
209
209
  calculate_alphas(fg, bg, &opts);
@@ -226,7 +226,7 @@ VALUE psd_native_compose_hard_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE op
226
226
  PIXEL bg = FIX2UINT(r_bg);
227
227
  PIXEL new_r, new_g, new_b;
228
228
 
229
- if (TRANSPARENT(bg)) return r_fg;
229
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
230
230
  if (TRANSPARENT(fg)) return r_bg;
231
231
 
232
232
  calculate_alphas(fg, bg, &opts);
@@ -251,7 +251,7 @@ VALUE psd_native_compose_vivid_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE o
251
251
  PIXEL bg = FIX2UINT(r_bg);
252
252
  PIXEL new_r, new_g, new_b;
253
253
 
254
- if (TRANSPARENT(bg)) return r_fg;
254
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
255
255
  if (TRANSPARENT(fg)) return r_bg;
256
256
 
257
257
  calculate_alphas(fg, bg, &opts);
@@ -276,7 +276,7 @@ VALUE psd_native_compose_linear_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE
276
276
  PIXEL bg = FIX2UINT(r_bg);
277
277
  PIXEL new_r, new_g, new_b;
278
278
 
279
- if (TRANSPARENT(bg)) return r_fg;
279
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
280
280
  if (TRANSPARENT(fg)) return r_bg;
281
281
 
282
282
  calculate_alphas(fg, bg, &opts);
@@ -301,7 +301,7 @@ VALUE psd_native_compose_pin_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opt
301
301
  PIXEL bg = FIX2UINT(r_bg);
302
302
  PIXEL new_r, new_g, new_b;
303
303
 
304
- if (TRANSPARENT(bg)) return r_fg;
304
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
305
305
  if (TRANSPARENT(fg)) return r_bg;
306
306
 
307
307
  calculate_alphas(fg, bg, &opts);
@@ -326,7 +326,7 @@ VALUE psd_native_compose_hard_mix(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts
326
326
  PIXEL bg = FIX2UINT(r_bg);
327
327
  PIXEL new_r, new_g, new_b;
328
328
 
329
- if (TRANSPARENT(bg)) return r_fg;
329
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
330
330
  if (TRANSPARENT(fg)) return r_bg;
331
331
 
332
332
  calculate_alphas(fg, bg, &opts);
@@ -343,7 +343,7 @@ VALUE psd_native_compose_difference(VALUE self, VALUE r_fg, VALUE r_bg, VALUE op
343
343
  PIXEL bg = FIX2UINT(r_bg);
344
344
  PIXEL new_r, new_g, new_b;
345
345
 
346
- if (TRANSPARENT(bg)) return r_fg;
346
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
347
347
  if (TRANSPARENT(fg)) return r_bg;
348
348
 
349
349
  calculate_alphas(fg, bg, &opts);
@@ -360,7 +360,7 @@ VALUE psd_native_compose_exclusion(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opt
360
360
  PIXEL bg = FIX2UINT(r_bg);
361
361
  PIXEL new_r, new_g, new_b;
362
362
 
363
- if (TRANSPARENT(bg)) return r_fg;
363
+ if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
364
364
  if (TRANSPARENT(fg)) return r_bg;
365
365
 
366
366
  calculate_alphas(fg, bg, &opts);
@@ -386,4 +386,9 @@ uint32_t calculate_opacity(VALUE *opts) {
386
386
  uint32_t fill_opacity = FIX2UINT(rb_hash_aref(*opts, ID2SYM(rb_intern("fill_opacity"))));
387
387
 
388
388
  return opacity * fill_opacity / 255;
389
+ }
390
+
391
+ PIXEL apply_opacity(PIXEL color, VALUE *opts) {
392
+ uint32_t opacity = calculate_opacity(opts);
393
+ return (color & 0xffffff00) | ((color & 0x000000ff) * opacity / 255);
389
394
  }
@@ -38,5 +38,6 @@ VALUE psd_native_compose_exclusion(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opt
38
38
  void calculate_alphas(uint32_t fg, uint32_t bg, VALUE *opts);
39
39
  uint32_t calculate_opacity(VALUE *opts);
40
40
  uint32_t blend_channel(uint32_t bg, uint32_t fg, uint32_t a);
41
+ uint32_t apply_opacity(uint32_t, VALUE *);
41
42
 
42
43
  #endif
@@ -0,0 +1,20 @@
1
+ #include "psd_native_ext.h"
2
+
3
+ VALUE psd_file_read_byte(VALUE self) {
4
+ // @file.read(1).bytes[0]
5
+ VALUE data = rb_funcall(psd_file(self), rb_intern("read"), 1, INT2FIX(1));
6
+ return RARRAY_PTR(rb_funcall(data, rb_intern("bytes"), 0))[0];
7
+ }
8
+
9
+ VALUE psd_file_read_bytes(VALUE self, int bytes) {
10
+ VALUE data = rb_funcall(psd_file(self), rb_intern("read"), 1, INT2FIX(bytes));
11
+ return rb_funcall(rb_funcall(data, rb_intern("bytes"), 0), rb_intern("to_a"), 0);
12
+ }
13
+
14
+ VALUE psd_file(VALUE self) {
15
+ return rb_iv_get(self, "@file");
16
+ }
17
+
18
+ int psd_file_tell(VALUE self) {
19
+ return FIX2INT(rb_funcall(psd_file(self), rb_intern("tell"), 0));
20
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef PSD_NATIVE_FILE
2
+ #define PSD_NATIVE_FILE
3
+
4
+ VALUE psd_file_read_byte(VALUE self);
5
+ VALUE psd_file_read_bytes(VALUE self, int bytes);
6
+ VALUE psd_file(VALUE self);
7
+ int psd_file_tell(VALUE self);
8
+
9
+ #endif
@@ -6,28 +6,47 @@ VALUE psd_native_combine_cmyk_channel(VALUE self) {
6
6
  uint32_t num_pixels = FIX2UINT(rb_iv_get(self, "@num_pixels"));
7
7
  uint32_t pixel_step = FIX2UINT(rb_funcall(self, rb_intern("pixel_step"), 0));
8
8
 
9
+ VALUE* channels_info = RARRAY_PTR(rb_iv_get(self, "@channels_info"));
9
10
  VALUE* channel_data = RARRAY_PTR(rb_iv_get(self, "@channel_data"));
10
11
  uint32_t channel_length = FIX2UINT(rb_iv_get(self, "@channel_length"));
11
- uint32_t channel_count = FIX2UINT(rb_funcall(self, rb_intern("channels"), 0));
12
+ int channel_count = RARRAY_LENINT(rb_iv_get(self, "@channels_info"));
12
13
 
13
- int i;
14
+ int i, j;
15
+ uint32_t val, c, m, y, k;
14
16
  uint32_t r, g, b;
15
- VALUE a, c, m, y, k, rgb;
17
+ uint32_t a = 255;
18
+ VALUE rgb;
19
+
20
+ int channel_ids[channel_count];
21
+ for (i = 0; i < channel_count; i++) {
22
+ channel_ids[i] = FIX2INT(rb_hash_aref(channels_info[i], ID2SYM(rb_intern("id"))));
23
+ }
16
24
 
17
25
  // Loop through every pixel in the image
18
26
  for (i = 0; i < num_pixels; i += pixel_step) {
19
- c = channel_data[i];
20
- m = channel_data[i + channel_length];
21
- y = channel_data[i + channel_length * 2];
22
- k = channel_data[i + channel_length * 3];
23
- a = (channel_count == 5 ? channel_data[i + channel_length * 4] : 255);
27
+ c = m = y = k = 0;
28
+ a = 255;
29
+
30
+ for (j = 0; j < channel_count; j++) {
31
+ if (channel_ids[j] == -2) continue;
32
+
33
+ val = FIX2UINT(channel_data[i + (channel_length * j)]);
34
+
35
+ switch (channel_ids[j]) {
36
+ case -1: a = val; break;
37
+ case 0: c = val; break;
38
+ case 1: m = val; break;
39
+ case 2: y = val; break;
40
+ case 3: k = val; break;
41
+ }
42
+ }
24
43
 
25
44
  rgb = psd_native_cmyk_to_rgb(
26
45
  self,
27
- INT2FIX(255 - FIX2INT(c)),
28
- INT2FIX(255 - FIX2INT(m)),
29
- INT2FIX(255 - FIX2INT(y)),
30
- INT2FIX(255 - FIX2INT(k))
46
+ INT2FIX(255 - c),
47
+ INT2FIX(255 - m),
48
+ INT2FIX(255 - y),
49
+ INT2FIX(255 - k)
31
50
  );
32
51
 
33
52
 
@@ -19,6 +19,8 @@ VALUE psd_native_combine_rgb_channel(VALUE self) {
19
19
  channel_ids[i] = FIX2INT(rb_hash_aref(channels_info[i], ID2SYM(rb_intern("id"))));
20
20
  }
21
21
 
22
+ VALUE pixel_data = rb_iv_get(self, "@pixel_data");
23
+
22
24
  // Loop through every pixel in the image
23
25
  for (i = 0; i < num_pixels; i += pixel_step) {
24
26
  color = 0x000000ff;
@@ -38,8 +40,8 @@ VALUE psd_native_combine_rgb_channel(VALUE self) {
38
40
  }
39
41
  }
40
42
 
41
- rb_ary_push(rb_iv_get(self, "@pixel_data"), INT2FIX(color));
43
+ rb_ary_push(pixel_data, INT2FIX(color));
42
44
  }
43
-
45
+
44
46
  return Qnil;
45
47
  }
@@ -0,0 +1,20 @@
1
+ #include "psd_native_ext.h"
2
+
3
+ VALUE psd_native_layer_raw_parse_raw_bang(VALUE self) {
4
+ psd_logger("debug", "Attempting to parse RAW encoded channel with native code...");
5
+
6
+ int chan_pos = FIX2INT(rb_iv_get(self, "@chan_pos"));
7
+ int chan_length = FIX2INT(rb_hash_aref(rb_iv_get(self, "@ch_info"), ID2SYM(rb_intern("length"))));
8
+ VALUE channel_data = rb_iv_get(self, "@channel_data");
9
+
10
+ VALUE data = psd_file_read_bytes(self, chan_length - 2);
11
+
12
+ int i, j = 0;
13
+ for (i = chan_pos; i < (chan_pos + chan_length - 2); i++) {
14
+ rb_ary_store(channel_data, i, rb_ary_entry(data, j++));
15
+ }
16
+
17
+ rb_iv_set(self, "@chan_pos", INT2FIX(chan_pos + chan_length - 2));
18
+
19
+ return Qnil;
20
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef PSD_NATIVE_LAYER_RAW
2
+ #define PSD_NATIVE_LAYER_RAW
3
+
4
+ VALUE psd_native_layer_raw_parse_raw_bang(VALUE self);
5
+
6
+ #endif
@@ -27,6 +27,10 @@ void Init_psd_native() {
27
27
  VALUE RLE = rb_define_module_under(ImageFormat, "RLE");
28
28
  rb_define_private_method(RLE, "decode_rle_channel", psd_native_decode_rle_channel, 0);
29
29
 
30
+ // RAW decoding
31
+ VALUE LayerRAW = rb_define_module_under(ImageFormat, "LayerRAW");
32
+ rb_define_private_method(LayerRAW, "parse_raw!", psd_native_layer_raw_parse_raw_bang, 0);
33
+
30
34
  // Color functions
31
35
  VALUE Color = rb_define_module_under(PSDNative, "Color");
32
36
  rb_define_module_function(Color, "cmyk_to_rgb", psd_native_cmyk_to_rgb, 4);
@@ -52,13 +56,16 @@ void Init_psd_native() {
52
56
  rb_define_module_function(Compose, "difference", psd_native_compose_difference, 3);
53
57
  rb_define_module_function(Compose, "exclusion", psd_native_compose_exclusion, 3);
54
58
 
55
- VALUE ClippingMask = rb_define_module_under(PSDNative, "ClippingMask");
56
- rb_define_method(ClippingMask, "apply", psd_native_clipping_mask_apply, 0);
59
+ // Renderer
60
+ VALUE Renderer = rb_define_module_under(PSDNative, "Renderer");
61
+
62
+ // Clipping Mask
63
+ VALUE ClippingMask = rb_define_module_under(Renderer, "ClippingMask");
64
+ rb_define_method(ClippingMask, "apply!", psd_native_clipping_mask_apply_bang, 0);
57
65
 
58
- // Build preview
59
- VALUE Node = rb_define_module_under(PSDNative, "Node");
60
- VALUE BuildPreview = rb_define_module_under(Node, "BuildPreview");
61
- rb_define_private_method(BuildPreview, "blend_pixels!", psd_native_build_preview_blend_pixels, 6);
66
+ // Blender
67
+ VALUE Blender = rb_define_module_under(Renderer, "Blender");
68
+ rb_define_method(Blender, "compose!", psd_native_blender_compose_bang, 0);
62
69
 
63
70
  // Util
64
71
  VALUE Util = rb_define_module_under(PSDNative, "Util");
@@ -71,12 +78,4 @@ void Init_psd_native() {
71
78
 
72
79
  void psd_logger(char* level, char* message) {
73
80
  rb_funcall(logger, rb_intern(level), 1, rb_str_new2(message));
74
- }
75
-
76
- VALUE psd_file(VALUE self) {
77
- return rb_iv_get(self, "@file");
78
- }
79
-
80
- int psd_file_tell(VALUE self) {
81
- return FIX2INT(rb_funcall(psd_file(self), rb_intern("tell"), 0));
82
81
  }
@@ -4,7 +4,6 @@
4
4
  #include "ruby.h"
5
5
 
6
6
  #define RSTRING_NOT_MODIFIED
7
- #define PSD_CONCURRENCY 4
8
7
 
9
8
  // Pixels use 32 bits unsigned integers
10
9
  // We borrow this from OilyPNG
@@ -12,6 +11,7 @@ typedef uint32_t PIXEL;
12
11
 
13
12
  // Our native mixins
14
13
  #include "util.h"
14
+ #include "file.h"
15
15
  #include "color.h"
16
16
  #include "clipping_mask.h"
17
17
  #include "compose.h"
@@ -19,12 +19,12 @@ typedef uint32_t PIXEL;
19
19
  #include "image_mode_greyscale.h"
20
20
  #include "image_mode_rgb.h"
21
21
  #include "rle_decoding.h"
22
- #include "build_preview.h"
22
+ #include "canvas.h"
23
+ #include "blender.h"
24
+ #include "layer_raw.h"
23
25
 
24
26
  void Init_psd_native();
25
27
  // VALUE psd_class();
26
28
  void psd_logger(char* level, char* message);
27
- VALUE psd_file(VALUE self);
28
- int psd_file_tell(VALUE self);
29
29
 
30
30
  #endif
@@ -2,7 +2,7 @@
2
2
 
3
3
  VALUE psd_native_decode_rle_channel(VALUE self) {
4
4
  int bytes, len, val;
5
- int i, j, k;
5
+ int i, j, k, l;
6
6
 
7
7
  int height = FIX2INT(rb_funcall(self, rb_intern("height"), 0));
8
8
  VALUE channel_data = rb_iv_get(self, "@channel_data");
@@ -10,6 +10,8 @@ VALUE psd_native_decode_rle_channel(VALUE self) {
10
10
  int line_index = FIX2INT(rb_iv_get(self, "@line_index"));
11
11
  int chan_pos = FIX2INT(rb_iv_get(self, "@chan_pos"));
12
12
 
13
+ VALUE byte_data;
14
+
13
15
  for (i = 0; i < height; i++) {
14
16
  bytes = FIX2INT(byte_counts[line_index + i]);
15
17
 
@@ -19,8 +21,11 @@ VALUE psd_native_decode_rle_channel(VALUE self) {
19
21
 
20
22
  if (len < 128) {
21
23
  len++;
24
+
25
+ l = 0;
26
+ byte_data = psd_file_read_bytes(self, len);
22
27
  for (k = chan_pos; k < chan_pos + len; k++) {
23
- rb_ary_store(channel_data, k, psd_file_read_byte(self));
28
+ rb_ary_store(channel_data, k, rb_ary_entry(byte_data, l++));
24
29
  }
25
30
 
26
31
  chan_pos += len;
@@ -42,10 +47,4 @@ VALUE psd_native_decode_rle_channel(VALUE self) {
42
47
 
43
48
  rb_iv_set(self, "@chan_pos", INT2FIX(chan_pos));
44
49
  return Qnil;
45
- }
46
-
47
- VALUE psd_file_read_byte(VALUE self) {
48
- // @file.read(1).bytes[0]
49
- VALUE data = rb_funcall(psd_file(self), rb_intern("read"), 1, INT2FIX(1));
50
- return RARRAY_PTR(rb_funcall(data, rb_intern("bytes"), 0))[0];
51
50
  }
@@ -2,6 +2,5 @@
2
2
  #define PSD_NATIVE_RLE_DECODING
3
3
 
4
4
  VALUE psd_native_decode_rle_channel(VALUE self);
5
- VALUE psd_file_read_byte(VALUE self);
6
5
 
7
6
  #endif
@@ -1,3 +1,3 @@
1
1
  module PSDNative
2
- VERSION = "0.6.0"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/psd_native.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "psd"
2
+ require "oily_png"
2
3
 
3
4
  module PSDNative
4
5
  def self.included(base)
@@ -6,14 +7,19 @@ module PSDNative
6
7
  base::Image.send(:include, PSDNative::ImageMode::CMYK)
7
8
  base::Image.send(:include, PSDNative::ImageMode::Greyscale)
8
9
  base::Image.send(:include, PSDNative::ImageFormat::RLE)
10
+ base::ChannelImage.send(:include, PSDNative::ImageFormat::LayerRAW)
9
11
  base::Color.send(:include, PSDNative::Color)
10
- base::Node.send(:include, PSDNative::Node::BuildPreview)
11
12
  base::Util.extend PSDNative::Util
12
13
 
13
- base::ClippingMask.class_eval do
14
- remove_method :apply
14
+ base::Renderer::ClippingMask.class_eval do
15
+ remove_method :apply!
15
16
  end
16
- base::ClippingMask.send(:include, PSDNative::ClippingMask)
17
+ base::Renderer::ClippingMask.send(:include, PSDNative::Renderer::ClippingMask)
18
+
19
+ base::Renderer::Blender.class_eval do
20
+ remove_method :compose!
21
+ end
22
+ base::Renderer::Blender.send(:include, PSDNative::Renderer::Blender)
17
23
  end
18
24
  end
19
25
 
data/psd_native.gemspec CHANGED
@@ -17,21 +17,19 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
 
20
+ spec.platform = Gem::Platform::RUBY
20
21
  spec.extensions = ["ext/psd_native/extconf.rb"]
21
22
  spec.require_paths = ["lib", "ext"]
22
23
 
23
- spec.add_runtime_dependency "psd", ">= 1.4.1"
24
+ spec.add_runtime_dependency "psd", ">= 2.0.0"
25
+ spec.add_runtime_dependency "oily_png", "~> 1.1"
24
26
 
25
27
  spec.add_development_dependency "bundler", "~> 1.3"
26
28
  spec.add_development_dependency "rake"
27
- spec.add_development_dependency "rake-compiler"
29
+ spec.add_development_dependency "rake-compiler", "~> 0.9"
28
30
 
29
31
  spec.test_files = Dir.glob("spec/**/*")
30
- spec.add_development_dependency 'rspec'
32
+ spec.add_development_dependency 'rspec', "~> 2.14"
31
33
  spec.add_development_dependency 'guard'
32
34
  spec.add_development_dependency 'guard-rspec'
33
-
34
- if RUBY_PLATFORM =~ /darwin/
35
- spec.add_development_dependency 'rb-fsevent', '~> 0.9'
36
- end
37
35
  end
data/spec/image_spec.rb CHANGED
@@ -1,70 +1,86 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Image Exporting' do
4
- before(:each) do
5
- class PSD::Image
6
- attr_accessor :pixel_data
7
- end
8
-
9
- @psd = PSD.new('spec/files/pixel.psd')
10
- end
4
+ let!(:psd) { PSD.new('spec/files/pixel.psd') }
11
5
 
12
6
  describe "the full preview image" do
13
7
  it "should successfully parse the image data" do
14
- @psd.parse!
15
- expect(@psd).to be_parsed
16
- expect(@psd.image).to_not be_nil
17
- expect(@psd.image.width).to eq(1)
18
- expect(@psd.image.height).to eq(1)
19
- expect(@psd.image.pixel_data).to eq([ChunkyPNG::Color.rgba(0, 100, 200, 255)])
8
+ psd.parse!
9
+ expect(psd).to be_parsed
10
+ expect(psd.image).to_not be_nil
11
+ expect(psd.image.width).to eq(1)
12
+ expect(psd.image.height).to eq(1)
13
+ expect(psd.image.pixel_data).to eq([ChunkyPNG::Color.rgba(0, 100, 200, 255)])
20
14
  end
21
15
 
22
16
  it "should be able to skip to the image" do
23
- expect(@psd).to_not be_parsed
24
- expect(@psd.image.width).to eq(1)
25
- expect(@psd.image.height).to eq(1)
26
- expect(@psd.image.pixel_data).to eq([ChunkyPNG::Color.rgba(0, 100, 200, 255)])
17
+ expect(psd).to_not be_parsed
18
+ expect(psd.image.width).to eq(1)
19
+ expect(psd.image.height).to eq(1)
20
+ expect(psd.image.pixel_data).to eq([ChunkyPNG::Color.rgba(0, 100, 200, 255)])
27
21
  end
28
22
 
29
23
  describe "as PNG" do
30
24
  it "should produce a valid PNG object" do
31
- expect(@psd.image.to_png).to be_an_instance_of(ChunkyPNG::Canvas)
25
+ expect(psd.image.to_png).to be_an_instance_of(ChunkyPNG::Canvas)
32
26
 
33
- expect(@psd.image.to_png.width).to eq(1)
34
- expect(@psd.image.to_png.height).to eq(1)
27
+ expect(psd.image.to_png.width).to eq(1)
28
+ expect(psd.image.to_png.height).to eq(1)
35
29
  expect(
36
- ChunkyPNG::Color.to_truecolor_alpha_bytes(@psd.image.to_png[0,0])
30
+ ChunkyPNG::Color.to_truecolor_alpha_bytes(psd.image.to_png[0,0])
37
31
  ).to eq([0, 100, 200, 255])
38
32
  end
39
33
  end
40
34
  end
41
35
 
42
- describe "layer images" do
43
- it "should successfully parse the image data" do
44
- @psd.options[:parse_layer_images] = true
45
- @psd.parse!
36
+ describe "Renderer" do
37
+ before(:each) do
38
+ psd.parse!
39
+ end
46
40
 
47
- image = @psd.tree.children.first.image
48
- expect(image).to be_an_instance_of(PSD::ChannelImage)
49
- expect(image.width).to eq(1)
50
- expect(image.height).to eq(1)
41
+ it "should be available via any tree node" do
42
+ [psd.tree, psd.tree.children.first].each do |node|
43
+ expect(node).to respond_to(:renderer)
44
+ expect(node).to respond_to(:to_png)
45
+ expect(node).to respond_to(:save_as_png)
46
+ end
47
+ end
51
48
 
52
- expect(image.pixel_data).to eq([ChunkyPNG::Color.rgba(0, 100, 200, 255)])
49
+ it "returns a Renderer object" do
50
+ [psd.tree, psd.tree.children.first].each do |node|
51
+ expect(node.renderer).to be_an_instance_of(PSD::Renderer)
52
+ end
53
53
  end
54
54
 
55
- describe "as PNG" do
56
- it "should produce a valid PNG object" do
57
- @psd.options[:parse_layer_images] = true
58
- @psd.parse!
55
+ it "produces a correct PNG" do
56
+ expect(psd.tree.to_png).to be_an_instance_of(ChunkyPNG::Canvas)
57
+ expect(psd.tree.to_png.pixels).to eq([ChunkyPNG::Color.rgba(0, 100, 200, 255)])
58
+ expect(psd.tree.to_png[0, 0]).to eq(ChunkyPNG::Color.rgba(0, 100, 200, 255))
59
+ end
59
60
 
60
- png = @psd.tree.children.first.image.to_png
61
- expect(png).to be_an_instance_of(ChunkyPNG::Canvas)
62
- expect(png.width).to eq(1)
63
- expect(png.height).to eq(1)
64
- expect(
65
- ChunkyPNG::Color.to_truecolor_alpha_bytes(png[0,0])
66
- ).to eq([0, 100, 200, 255])
61
+ describe "Canvas" do
62
+ before do
63
+ @node = psd.tree.children.first
64
+ @canvas = PSD::Renderer::Canvas.new(@node)
65
+ end
66
+
67
+ it 'is initialized properly' do
68
+ expect(@canvas.node).to be @node
69
+ expect(@canvas.width).to eq @node.width
70
+ expect(@canvas.height).to eq @node.height
71
+
72
+ expect(@canvas.opacity).to eq @node.opacity
73
+ expect(@canvas.fill_opacity).to eq @node.fill_opacity
74
+
75
+ expect(@canvas.canvas).to be_an_instance_of(ChunkyPNG::Canvas)
76
+ expect(@canvas.instance_variable_get(:@pixel_data)).to be_nil
77
+ expect(@canvas.canvas.pixels.length).to be 1
78
+ end
79
+
80
+ it 'delegates array methods to internal canvas' do
81
+ expect(@canvas[0, 0]).to eq ChunkyPNG::Color.rgba(0, 100, 200, 255)
82
+ expect(@canvas).to respond_to(:[]=)
67
83
  end
68
84
  end
69
85
  end
70
- end
86
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: psd_native
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan LeFevre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-25 00:00:00.000000000 Z
11
+ date: 2014-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: psd
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '>='
18
18
  - !ruby/object:Gem::Version
19
- version: 1.4.1
19
+ version: 2.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
- version: 1.4.1
26
+ version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: oily_png
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -56,30 +70,30 @@ dependencies:
56
70
  name: rake-compiler
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - '>='
73
+ - - ~>
60
74
  - !ruby/object:Gem::Version
61
- version: '0'
75
+ version: '0.9'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - '>='
80
+ - - ~>
67
81
  - !ruby/object:Gem::Version
68
- version: '0'
82
+ version: '0.9'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - '>='
87
+ - - ~>
74
88
  - !ruby/object:Gem::Version
75
- version: '0'
89
+ version: '2.14'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - '>='
94
+ - - ~>
81
95
  - !ruby/object:Gem::Version
82
- version: '0'
96
+ version: '2.14'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: guard
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -108,20 +122,6 @@ dependencies:
108
122
  - - '>='
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: rb-fsevent
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ~>
116
- - !ruby/object:Gem::Version
117
- version: '0.9'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ~>
123
- - !ruby/object:Gem::Version
124
- version: '0.9'
125
125
  description: Native mixins to speed up PSD.rb
126
126
  email:
127
127
  - ryan@layervault.com
@@ -137,8 +137,10 @@ files:
137
137
  - LICENSE.txt
138
138
  - README.md
139
139
  - Rakefile
140
- - ext/psd_native/build_preview.c
141
- - ext/psd_native/build_preview.h
140
+ - ext/psd_native/blender.c
141
+ - ext/psd_native/blender.h
142
+ - ext/psd_native/canvas.c
143
+ - ext/psd_native/canvas.h
142
144
  - ext/psd_native/clipping_mask.c
143
145
  - ext/psd_native/clipping_mask.h
144
146
  - ext/psd_native/color.c
@@ -146,12 +148,16 @@ files:
146
148
  - ext/psd_native/compose.c
147
149
  - ext/psd_native/compose.h
148
150
  - ext/psd_native/extconf.rb
151
+ - ext/psd_native/file.c
152
+ - ext/psd_native/file.h
149
153
  - ext/psd_native/image_mode_cmyk.c
150
154
  - ext/psd_native/image_mode_cmyk.h
151
155
  - ext/psd_native/image_mode_greyscale.c
152
156
  - ext/psd_native/image_mode_greyscale.h
153
157
  - ext/psd_native/image_mode_rgb.c
154
158
  - ext/psd_native/image_mode_rgb.h
159
+ - ext/psd_native/layer_raw.c
160
+ - ext/psd_native/layer_raw.h
155
161
  - ext/psd_native/psd_native_ext.c
156
162
  - ext/psd_native/psd_native_ext.h
157
163
  - ext/psd_native/rle_decoding.c
@@ -193,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
193
199
  version: '0'
194
200
  requirements: []
195
201
  rubyforge_project:
196
- rubygems_version: 2.1.11
202
+ rubygems_version: 2.2.1
197
203
  signing_key:
198
204
  specification_version: 4
199
205
  summary: Native C mixins to speed up the slowest parts of PSD.rb
@@ -1,58 +0,0 @@
1
- #include "psd_native_ext.h"
2
-
3
- VALUE psd_native_build_preview_blend_pixels(
4
- VALUE self,
5
- VALUE blending_mode,
6
- VALUE layer,
7
- VALUE base,
8
- VALUE other,
9
- VALUE r_offset_x,
10
- VALUE r_offset_y) {
11
-
12
- int x, y, base_x, base_y, offset_x, offset_y;
13
- uint32_t width, height, base_width, base_height;
14
- VALUE color;
15
- VALUE Compose = rb_const_get(rb_const_get(rb_cObject, rb_intern("PSD")), rb_intern("Compose"));
16
-
17
- width = FIX2UINT(rb_funcall(other, rb_intern("width"), 0));
18
- height = FIX2UINT(rb_funcall(other, rb_intern("height"), 0));
19
- base_width = FIX2UINT(rb_funcall(base, rb_intern("width"), 0));
20
- base_height = FIX2UINT(rb_funcall(base, rb_intern("height"), 0));
21
- offset_x = FIX2INT(r_offset_x);
22
- offset_y = FIX2INT(r_offset_y);
23
-
24
- VALUE opacity = rb_hash_new();
25
- rb_hash_aset(
26
- opacity,
27
- ID2SYM(rb_intern("opacity")),
28
- rb_funcall(layer, rb_intern("opacity"), 0)
29
- );
30
-
31
- rb_hash_aset(
32
- opacity,
33
- ID2SYM(rb_intern("fill_opacity")),
34
- rb_funcall(layer, rb_intern("fill_opacity"), 0)
35
- );
36
-
37
- for (y = 0; y < height; y++) {
38
- for (x = 0; x < width; x++) {
39
- base_x = x + offset_x;
40
- base_y = y + offset_y;
41
-
42
- if (base_x < 0 || base_y < 0 || base_x >= base_width || base_y >= base_height) continue;
43
-
44
- color = rb_funcall(
45
- Compose,
46
- rb_intern_str(blending_mode),
47
- 3,
48
- rb_funcall(other, rb_intern("[]"), 2, INT2FIX(x), INT2FIX(y)),
49
- rb_funcall(base, rb_intern("[]"), 2, INT2FIX(base_x), INT2FIX(base_y)),
50
- opacity
51
- );
52
-
53
- rb_funcall(base, rb_intern("[]="), 3, INT2FIX(base_x), INT2FIX(base_y), color);
54
- }
55
- }
56
-
57
- return Qnil;
58
- }
@@ -1,6 +0,0 @@
1
- #ifndef PSD_NATIVE_BUILD_PREVIEW
2
- #define PSD_NATIVE_BUILD_PREVIEW
3
-
4
- VALUE psd_native_build_preview_blend_pixels(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
5
-
6
- #endif