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 +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
|
-
}
|