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 +4 -4
- data/Gemfile +0 -2
- data/ext/psd_native/blender.c +57 -0
- data/ext/psd_native/blender.h +6 -0
- data/ext/psd_native/canvas.c +9 -0
- data/ext/psd_native/canvas.h +6 -0
- data/ext/psd_native/clipping_mask.c +37 -42
- data/ext/psd_native/clipping_mask.h +1 -1
- data/ext/psd_native/compose.c +23 -18
- data/ext/psd_native/compose.h +1 -0
- data/ext/psd_native/file.c +20 -0
- data/ext/psd_native/file.h +9 -0
- data/ext/psd_native/image_mode_cmyk.c +31 -12
- data/ext/psd_native/image_mode_rgb.c +4 -2
- data/ext/psd_native/layer_raw.c +20 -0
- data/ext/psd_native/layer_raw.h +6 -0
- data/ext/psd_native/psd_native_ext.c +13 -14
- data/ext/psd_native/psd_native_ext.h +4 -4
- data/ext/psd_native/rle_decoding.c +7 -8
- data/ext/psd_native/rle_decoding.h +0 -1
- data/lib/psd_native/version.rb +1 -1
- data/lib/psd_native.rb +10 -4
- data/psd_native.gemspec +5 -7
- data/spec/image_spec.rb +58 -42
- metadata +35 -29
- data/ext/psd_native/build_preview.c +0 -58
- data/ext/psd_native/build_preview.h +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0267ebc332f459a2246da73dbb83ba072c6689a4
|
4
|
+
data.tar.gz: de14d32f2fe1a2ea603487364783085c5821266a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8934cedf3e9142a63974542b4fce9ab0b1c3c687626bfa735a289e6ecc2cf08b38232177fe59cf159ceea5578c7b51ceed6871be17869473145fcc79a7f0c3f
|
7
|
+
data.tar.gz: 558be83a9bde428df951a1377294badabf601a4c772bded8402eb75c5d3537619665781d263ad352a30cee5bb0c7ae9a361ed0809b61603547237b5e2e1d102e
|
data/Gemfile
CHANGED
@@ -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
|
+
}
|
@@ -1,60 +1,55 @@
|
|
1
1
|
#include "psd_native_ext.h"
|
2
2
|
|
3
|
-
VALUE
|
4
|
-
VALUE
|
5
|
-
if (rb_funcall(
|
6
|
-
return
|
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
|
12
|
-
VALUE
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
for (y = 0; y <
|
30
|
-
for (x = 0; x <
|
31
|
-
|
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
|
-
|
35
|
-
mask_y = y - mask_top;
|
40
|
+
loc = mask_y * mask_width + mask_x;
|
36
41
|
|
37
|
-
|
38
|
-
if (pixel == Qnil) {
|
42
|
+
if (loc > mask_pixel_length) {
|
39
43
|
alpha = 0;
|
40
44
|
} else {
|
41
|
-
alpha = A(FIX2UINT(
|
45
|
+
alpha = A(FIX2UINT(mask_pixels[loc]));
|
42
46
|
}
|
43
47
|
}
|
44
48
|
|
45
|
-
color = FIX2UINT(
|
46
|
-
|
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
|
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
|
}
|
data/ext/psd_native/compose.c
CHANGED
@@ -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 (
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
}
|
data/ext/psd_native/compose.h
CHANGED
@@ -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
|
+
}
|
@@ -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
|
-
|
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
|
-
|
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 =
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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 -
|
28
|
-
INT2FIX(255 -
|
29
|
-
INT2FIX(255 -
|
30
|
-
INT2FIX(255 -
|
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(
|
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
|
+
}
|
@@ -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
|
-
|
56
|
-
|
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
|
-
//
|
59
|
-
VALUE
|
60
|
-
|
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 "
|
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,
|
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
|
}
|
data/lib/psd_native/version.rb
CHANGED
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", ">=
|
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
|
-
|
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
|
-
|
15
|
-
expect(
|
16
|
-
expect(
|
17
|
-
expect(
|
18
|
-
expect(
|
19
|
-
expect(
|
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(
|
24
|
-
expect(
|
25
|
-
expect(
|
26
|
-
expect(
|
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(
|
25
|
+
expect(psd.image.to_png).to be_an_instance_of(ChunkyPNG::Canvas)
|
32
26
|
|
33
|
-
expect(
|
34
|
-
expect(
|
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(
|
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 "
|
43
|
-
|
44
|
-
|
45
|
-
|
36
|
+
describe "Renderer" do
|
37
|
+
before(:each) do
|
38
|
+
psd.parse!
|
39
|
+
end
|
46
40
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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.
|
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:
|
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:
|
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:
|
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: '
|
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: '
|
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/
|
141
|
-
- ext/psd_native/
|
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
|
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
|
-
}
|