-
Notifications
You must be signed in to change notification settings - Fork 0
/
SwizzleUtils.java
76 lines (61 loc) · 1.91 KB
/
SwizzleUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package jendgamexbox;
/**
*
* @author Slam
*/
public class SwizzleUtils {
private int[] generateSwizzleMasks(int width, int height) {
if (width <= 0 || (width & (width - 1)) != 0) {
throw new IllegalArgumentException("Width must be a power of 2");
}
if (height <= 0 || (height & (height - 1)) != 0) {
throw new IllegalArgumentException("Height must be a power of 2");
}
int x = 0, y = 0;
int bit = 1, maskBit = 1;
boolean done = false;
while (!done) {
done = true;
if (bit < width) {
x |= maskBit;
maskBit <<= 1;
done = false;
}
if (bit < height) {
y |= maskBit;
maskBit <<= 1;
done = false;
}
bit <<= 1;
}
return new int[]{x, y};
}
private int fillSwizzlePattern(int pattern, int value) {
int result = 0;
int bit = 1;
while (value != 0) {
if ((pattern & bit) != 0) {
result |= (value & 1) != 0 ? bit : 0;
value >>= 1;
}
bit <<= 1;
}
return result;
}
public byte[] unswizzle32(byte[] data, int width, int height) {
int[] masks = generateSwizzleMasks(width, height);
int maskX = masks[0];
int maskY = masks[1];
byte[] dstBuf = new byte[data.length];
for (int y = 0; y < height; y++) {
int srcYOffset = fillSwizzlePattern(maskY, y) * 4;
int dstYOffset = width * y * 4;
for (int x = 0; x < width; x++) {
int srcOffset = srcYOffset + fillSwizzlePattern(maskX, x) * 4;
int dstOffset = dstYOffset + x * 4;
System.arraycopy(data, srcOffset, dstBuf, dstOffset, 4);
}
}
return dstBuf;
}
}