-
Notifications
You must be signed in to change notification settings - Fork 0
/
ByteWriter.pde
165 lines (136 loc) · 5.37 KB
/
ByteWriter.pde
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//ByteWriter - Last Update 23 May 2013
//This program was written by Jeroen Holtuis and Phillip Stearns,
//inspired by the LoomPreview application developed by Paul Kerchen.
//It's purpose is to provide a flexible tool for visualizing raw binary data.
//This preliminary program only offers translation of binary data to 0-8 bits per channel RGB
//shift+s to save output
// Jeroen Holthuis: http://www.jeroenholthuis.nl/
// Phillip Stearns: http://phillipstearns.com
// Paul Kerchen: http://github.com/kerchen
//Grayscale implementation is incomplete
//bitwise and bytewise offest implementation is incomplete
//color channel swapping is not implemented
//alpha channel is not implemented
byte imgBytes[];
//Set your bit resolution for the color channels
int bGray = 8; // bit resolution for pixel value in Grayscale mode
int bRed = 1; // set bit resolution for red channel pixel value in Color mode
int bGreen = 2; // set bit resolution for gree channel pixel value in Color mode
int bBlue = 1; // set bit resolution for blue channel pixel value in Color mode
int numChan;
int[] bitsInChan;
int bppGrayscale = bGray; //total number of bits per pixel
int bppColor = bRed + bGreen + bBlue; //total number of bits per pixel
int bitDepth = 0;
int modeValue = 1; // 0 for Grayscale, 1 for color;
String modeType = "init";
int imgWidth = 336; //set image width here
int imgHeight = 800; //optional
int imgLength = 0; //calculated later from file size and rendering method
int numPixel = 0; //calculated later from file size and rendering method
byte rawData[]; //contains raw file data
byte rawBits[]; //contains a binary representation of raw file data
byte groupedBits[]; //contains bits, grouped into a color byte, with bits length specified by bit resolutions for each (color) channel specified above
int numBits;
String fileName = "filename"; //give path and file name to render (keep under 30MB!!!) see "split" terminal command for MacOSX for help breaking files into managable chunks
//String[] letters = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
void setup(){
rawData = loadBytes(fileName); //loads file into array as bytes
numBits = rawData.length * 8; //stores file length in bits
rawBits = new byte[numBits];
/* if (modeValue == 0) {
bitDepth = bppGrayscale;
numPixel = numBits / bppGrayscale;
modeType = "grayscale";
numChan=1;
bitsInChan = new int[numChan];
bitsInChan[0] = bGray;
groupedBits = new byte[numPixel];
}
if (modeValue == 1) { */
bitDepth = bppColor;
numPixel = (numBits / bppColor);
modeType = "color";
numChan=3;
bitsInChan = new int[numChan];
bitsInChan[0] = bRed;
bitsInChan[1] = bGreen;
bitsInChan[2] = bBlue;
groupedBits = new byte[numPixel * 3];
//}
imgLength = numPixel / imgWidth; //calcutlate image length
size(imgWidth, imgLength);
storeBitsInArray();
bitsToRGB();
renderImageFromBytes();
save(fileName+ "_"+ bRed + "" + bGreen + "" + bBlue + "-RGB_" + imgWidth +"px" + ".tif");
println("File saved to: " + fileName+ "_"+ bRed + "" + bGreen + "" + bBlue + "-RGB_" + imgWidth +"px" + ".tif");
}
//Thar Be Functions Below!!!!
void renderImageFromBytes() {
PImage img = new PImage(imgWidth, imgLength);
img.loadPixels();
for (int i = 0; i < (img.pixels.length * 3); i += 3) {
img.pixels[i/3] = color((groupedBits[i] & 0xFF) * (255/(pow(2,bRed)-1)), (groupedBits[i+1] & 0xFF) * (255/(pow(2,bGreen)-1)), (groupedBits[i+2] & 0xFF) * (255/(pow(2,bBlue)-1)));
}
img.updatePixels();
image(img, 0, 0);
}
/*
void keyPressed() {
if (key == 'S'){
save(fileName+ "_"+ bRed + "" + bGreen + "" + bBlue + "-RGB_" + imgWidth +"px" + ".tif");
println("File saved");
}
}
*/
void storeBitsInArray(){ //converts raw data from an array of 8-bit bytes to bytes containing only 1-bit from the raw data stream
int k = 0;
for (int j=0 ; j < rawData.length ; j++){
for (int i=7 ; i>=0 ; i--){
rawBits[j * 8 + k] = byte(bitRead(rawData[j],i));
k++;
}
k=0;
}
}
void bitsToRGB() { //packs the bits stored in rawBits[] into variable 0-8 bit color channel values
int k = 0;
for (int j = 0; j < (rawBits.length - (bRed + bBlue + bGreen)); j += (bRed + bBlue + bGreen)) {
// RED packing
byte tempRedBytes[] = new byte[bRed];
for (int i = 0; i < bRed; i++) {
tempRedBytes[i] = rawBits[j + i];
}
byte redByte = storeBitsInByte(tempRedBytes);
groupedBits[k] = redByte;
// GREEN packing
byte tempGreenBytes[] = new byte[bGreen];
for (int i = 0; i < bGreen; i++) {
tempGreenBytes[i] = rawBits[j + i + bRed];
}
byte greenByte = storeBitsInByte(tempGreenBytes);
groupedBits[k+1] = greenByte;
// BLUE packing
byte tempBlueBytes[] = new byte[bBlue];
for (int i = 0; i < bBlue; i++) {
tempBlueBytes[i] = rawBits[j + i + bRed + bGreen];
}
byte blueByte = storeBitsInByte(tempBlueBytes);
groupedBits[k+2] = blueByte;
k+=3;
}
}
// Stores bits in a byte
byte storeBitsInByte(byte[] bits) { // send in maximum of 8 bits in array
byte bitBuffer = 0;
for (int i = 0; i < bits.length; i++) {
bitBuffer <<= 1;
bitBuffer += bits[i];
}
return bitBuffer;
}
int bitRead(byte b, int bitPos) {
int x = b & (1 << bitPos);
return x == 0 ? 0 : 1; // if-else conditional construction: if x is 0 return 0 else 1
}