psd_native 0.6.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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