1 package ini
.trakem2
.imaging
;
3 import ini
.trakem2
.utils
.CachingThread
;
6 public static final int[] blend(final byte[] pi
, final byte[] pm
) {
7 final int[] p
= CachingThread
.getOrCreateIntArray(pi
.length
); // new int[pi.length];
8 for (int i
=0; i
<p
.length
; ++i
) {
9 final int c
= (pi
[i
]&0xff);
10 p
[i
] = ((pm
[i
]&0xff) << 24) | (c
<< 16) | (c
<< 8) | c
;
15 /** Puts the {@param pi} (the greyscale channel) into the R, G and B components of the returned {@code int[]}
16 * after having multiplied them by the {@param pm} (the alpha channel); the alpha channel gets inserted into
17 * the int[] as well. */
18 public static final int[] blendPre(final byte[] pi
, final byte[] pm
) {
19 final int[] p
= CachingThread
.getOrCreateIntArray(pi
.length
); // new int[pi.length];
20 for (int i
=0; i
<p
.length
; ++i
) {
21 final int a
= (pm
[i
]&0xff);
22 final double K
= a
/ 255.0;
23 final int c
= (int)((pi
[i
]&0xff) * K
+ 0.5);
24 p
[i
] = (a
<< 24) | (c
<< 16) | (c
<< 8) | c
;
29 public static final int[] blend(final byte[] r
, final byte[] g
, final byte[] b
, final byte[] a
) {
30 final int[] p
= CachingThread
.getOrCreateIntArray(r
.length
); // new int[r.length];
31 for (int i
=0; i
<p
.length
; ++i
) {
32 p
[i
] = ((a
[i
]&0xff) << 24) | ((r
[i
]&0xff) << 16) | ((g
[i
]&0xff) << 8) | (b
[i
]&0xff);
37 /** Pre-multiplies alpha. */
38 public static final int[] blendPre(final byte[] r
, final byte[] g
, final byte[] b
, final byte[] alpha
) {
39 final int[] p
= CachingThread
.getOrCreateIntArray(r
.length
); // new int[r.length];
40 for (int i
=0; i
<p
.length
; ++i
) {
41 final int a
= (alpha
[i
]&0xff);
42 final double K
= a
/ 255.0;
44 | (((int)((r
[i
]&0xff) * K
+ 0.5)) << 16)
45 | (((int)((g
[i
]&0xff) * K
+ 0.5)) << 8)
46 | ((int)((b
[i
]&0xff) * K
+ 0.5));
51 public static final int[] blend(final byte[] r
, final byte[] g
, final byte[] b
) {
52 final int[] p
= CachingThread
.getOrCreateIntArray(r
.length
); // new int[r.length];
53 for (int i
=0; i
<p
.length
; ++i
) {
54 p
[i
] = ((r
[i
]&0xff) << 16) | ((g
[i
]&0xff) << 8) | (b
[i
]&0xff);
60 /** Merges into alpha if outside is null, otherwise returns alpha as is. */
61 static public final byte[] merge(final byte[] alpha
, byte[] outside
) {
62 if (null == outside
) return alpha
;
63 for (int i
=0; i
<alpha
.length
; ++i
) {
64 alpha
[i
] = -1 == outside
[i
] ? alpha
[i
] : 0;
69 static public final byte[][] asRGBABytes(final int[] pixels
, final byte[] alpha
, byte[] outside
) {
70 merge(alpha
, outside
); // into alpha
71 final byte[] r
= CachingThread
.getOrCreateByteArray(pixels
.length
), // new byte[pixels.length],
72 g
= CachingThread
.getOrCreateByteArray(pixels
.length
), // new byte[pixels.length],
73 b
= CachingThread
.getOrCreateByteArray(pixels
.length
); // new byte[pixels.length];
74 for (int i
=0; i
<pixels
.length
; ++i
) {
75 final int x
= pixels
[i
];
76 r
[i
] = (byte)((x
>> 16)&0xff);
77 g
[i
] = (byte)((x
>> 8)&0xff);
78 b
[i
] = (byte) (x
&0xff);
80 return new byte[][]{r
, g
, b
, alpha
};
83 static public byte[][] asRGBBytes(final int[] pix
) {
84 final byte[] r
= CachingThread
.getOrCreateByteArray(pix
.length
), // new byte[pix.length],
85 g
= CachingThread
.getOrCreateByteArray(pix
.length
), // new byte[pix.length],
86 b
= CachingThread
.getOrCreateByteArray(pix
87 .length
); // new byte[pix.length];
88 for (int i
=0; i
<pix
.length
; ++i
) {
90 r
[i
] = (byte)((x
>> 16)&0xff);
91 g
[i
] = (byte)((x
>> 8)&0xff);
92 b
[i
] = (byte) (x
&0xff);
94 return new byte[][]{r
, g
, b
};