Module: PSDNative::Compose

Defined in:
ext/psd_native/psd_native_ext.c

Class Method Summary collapse

Class Method Details

.color_burn(r_fg, r_bg, opts) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'ext/psd_native/compose.c', line 57

VALUE psd_native_compose_color_burn(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), color_burn_foreground(R(bg), R(fg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), color_burn_foreground(G(bg), G(fg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), color_burn_foreground(B(bg), B(fg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.color_dodge(r_fg, r_bg, opts) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'ext/psd_native/compose.c', line 134

VALUE psd_native_compose_color_dodge(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), color_dodge_foreground(R(bg), R(fg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), color_dodge_foreground(G(bg), G(fg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), color_dodge_foreground(B(bg), B(fg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.darken(r_fg, r_bg, opts) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'ext/psd_native/compose.c', line 23

VALUE psd_native_compose_darken(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = R(fg) <= R(bg) ? BLEND_CHANNEL(R(bg), R(fg), alpha.mix) : R(bg);
  new_g = G(fg) <= G(bg) ? BLEND_CHANNEL(G(bg), G(fg), alpha.mix) : G(bg);
  new_b = B(fg) <= B(bg) ? BLEND_CHANNEL(B(bg), B(fg), alpha.mix) : B(bg);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.difference(r_fg, r_bg, opts) ⇒ Object



341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'ext/psd_native/compose.c', line 341

VALUE psd_native_compose_difference(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), abs(R(bg) - R(fg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), abs(G(bg) - G(fg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), abs(B(bg) - B(fg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.exclusion(r_fg, r_bg, opts) ⇒ Object



358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'ext/psd_native/compose.c', line 358

VALUE psd_native_compose_exclusion(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), R(bg) + R(fg) - (R(bg) * R(fg) >> 7), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), G(bg) + G(fg) - (G(bg) * G(fg) >> 7), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), B(bg) + B(fg) - (B(bg) * B(fg) >> 7), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.hard_light(r_fg, r_bg, opts) ⇒ Object



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'ext/psd_native/compose.c', line 224

VALUE psd_native_compose_hard_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), hard_light_foreground(R(bg), R(fg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), hard_light_foreground(G(bg), G(fg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), hard_light_foreground(B(bg), B(fg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.hard_mix(r_fg, r_bg, opts) ⇒ Object



324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'ext/psd_native/compose.c', line 324

VALUE psd_native_compose_hard_mix(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), (R(bg) + R(fg) <= 255) ? 0 : 255, alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), (G(bg) + G(fg) <= 255) ? 0 : 255, alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), (B(bg) + B(fg) <= 255) ? 0 : 255, alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.lighten(r_fg, r_bg, opts) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'ext/psd_native/compose.c', line 100

VALUE psd_native_compose_lighten(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = (R(fg) >= R(bg)) ? BLEND_CHANNEL(R(bg), R(fg), alpha.mix) : R(bg);
  new_g = (G(fg) >= G(bg)) ? BLEND_CHANNEL(G(bg), G(fg), alpha.mix) : G(bg);
  new_b = (B(fg) >= B(bg)) ? BLEND_CHANNEL(B(bg), B(fg), alpha.mix) : B(bg);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.linear_burn(r_fg, r_bg, opts) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'ext/psd_native/compose.c', line 83

VALUE psd_native_compose_linear_burn(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), (R(fg) < (255 - R(bg))) ? 0 : R(fg) - (255 - R(bg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), (G(fg) < (255 - G(bg))) ? 0 : G(fg) - (255 - G(bg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), (B(fg) < (255 - B(bg))) ? 0 : B(fg) - (255 - B(bg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.linear_dodge(r_fg, r_bg, opts) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'ext/psd_native/compose.c', line 159

VALUE psd_native_compose_linear_dodge(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), (R(bg) + R(fg)) > 255 ? 255 : R(bg) + R(fg), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), (G(bg) + G(fg)) > 255 ? 255 : G(bg) + G(fg), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), (B(bg) + B(fg)) > 255 ? 255 : B(bg) + B(fg), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.linear_light(r_fg, r_bg, opts) ⇒ Object



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'ext/psd_native/compose.c', line 274

VALUE psd_native_compose_linear_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), linear_light_foreground(R(bg), R(fg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), linear_light_foreground(G(bg), G(fg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), linear_light_foreground(B(bg), B(fg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.multiply(r_fg, r_bg, opts) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'ext/psd_native/compose.c', line 40

VALUE psd_native_compose_multiply(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), R(fg) * R(bg) >> 8, alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), G(fg) * G(bg) >> 8, alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), B(fg) * B(bg) >> 8, alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.normal(r_fg, r_bg, opts) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'ext/psd_native/compose.c', line 6

VALUE psd_native_compose_normal(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), R(fg), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), G(fg), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), B(fg), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.overlay(r_fg, r_bg, opts) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'ext/psd_native/compose.c', line 176

VALUE psd_native_compose_overlay(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), overlay_foreground(R(bg), R(fg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), overlay_foreground(G(bg), G(fg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), overlay_foreground(B(bg), B(fg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.pin_light(r_fg, r_bg, opts) ⇒ Object



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'ext/psd_native/compose.c', line 299

VALUE psd_native_compose_pin_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), pin_light_foreground(R(bg), R(fg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), pin_light_foreground(G(bg), G(fg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), pin_light_foreground(B(bg), B(fg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.screen(r_fg, r_bg, opts) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'ext/psd_native/compose.c', line 117

VALUE psd_native_compose_screen(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), 255 - ((255 - R(bg)) * (255 - R(fg)) >> 8), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), 255 - ((255 - G(bg)) * (255 - G(fg)) >> 8), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), 255 - ((255 - B(bg)) * (255 - B(fg)) >> 8), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.soft_light(r_fg, r_bg, opts) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'ext/psd_native/compose.c', line 201

VALUE psd_native_compose_soft_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), soft_light_foreground(R(bg), R(fg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), soft_light_foreground(G(bg), G(fg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), soft_light_foreground(B(bg), B(fg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}

.vivid_light(r_fg, r_bg, opts) ⇒ Object



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'ext/psd_native/compose.c', line 249

VALUE psd_native_compose_vivid_light(VALUE self, VALUE r_fg, VALUE r_bg, VALUE opts) {
  PIXEL fg = FIX2UINT(r_fg);
  PIXEL bg = FIX2UINT(r_bg);
  PIXEL new_r, new_g, new_b;

  if (TRANSPARENT(bg)) return INT2FIX(apply_opacity(fg, &opts));
  if (TRANSPARENT(fg)) return r_bg;

  calculate_alphas(fg, bg, &opts);

  new_r = BLEND_CHANNEL(R(bg), vivid_light_foreground(R(bg), R(fg)), alpha.mix);
  new_g = BLEND_CHANNEL(G(bg), vivid_light_foreground(G(bg), G(fg)), alpha.mix);
  new_b = BLEND_CHANNEL(B(bg), vivid_light_foreground(B(bg), B(fg)), alpha.mix);

  return INT2FIX(BUILD_PIXEL(new_r, new_g, new_b, alpha.dst));
}