package com.vitco.importer;
import com.vitco.util.file.FileIn;
import com.vitco.util.file.RandomAccessFileIn;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* *.qb importer
*/
public class QbImporter extends AbstractImporter {
// constructor
public QbImporter(File file, String name) throws IOException {
super(file, name);
}
private static final int CODE_FLAG = 2;
private static final int NEXT_SLICE_FLAG = 6;
@Override
protected boolean read(FileIn fileIn, RandomAccessFileIn raf) throws IOException {
fileIn.readIntRevUnsigned(); //int version = fileIn.readIntRevUnsigned();
//System.out.println("version: " + version);
int colorFormat = fileIn.readIntRevUnsigned();
//System.out.println("colorFormat: " + colorFormat);
int zAxisOrientation = fileIn.readIntRevUnsigned();
//System.out.println("zAxisOrientation: " + zAxisOrientation);
int compressed = fileIn.readIntRevUnsigned();
//System.out.println("compressed: " + compressed);
fileIn.readIntRevUnsigned(); // int visibilityMaskEncoded = fileIn.readIntRevUnsigned();
//System.out.println("visibilityMaskEncoded: " + visibilityMaskEncoded);
int numMatrices = fileIn.readIntRevUnsigned();
//System.out.println("numMatrices: " + numMatrices);
for (int i = 0; i < numMatrices; i++) {
// read matrix name
int nameLength = fileIn.readByteUnsigned();
String name = fileIn.readASCIIString(nameLength);
addLayer(name);
//System.out.println("name: " + name);
// read matrix size
int sx = fileIn.readIntRevUnsigned();
int sy = fileIn.readIntRevUnsigned();
int sz = fileIn.readIntRevUnsigned();
//System.out.println(sx + " " + sy + " " + sz);
// read offset size
int cx = fileIn.readIntRev();
int cy = fileIn.readIntRev();
int cz = fileIn.readIntRev();
//System.out.println(cx + " " + cy + " " + cz);
ByteBuffer byteBuffer = ByteBuffer.allocate(4);
if (compressed == 0) { // uncompressed
for(int z = 0; z < sz; z++) {
for(int y = 0; y < sy; y++) {
for(int x = 0; x < sx; x++) {
int c1 = fileIn.readByteUnsigned();
int c2 = fileIn.readByteUnsigned();
int c3 = fileIn.readByteUnsigned();
int a = fileIn.readByteUnsigned(); // read visibility encoding
if (a != 0) { // if voxel is not invisible (this should work correctly in all cases)
int rgb = colorFormat == 0 ? new Color(c1,c2,c3).getRGB() : new Color(c3, c2, c1).getRGB();
if (zAxisOrientation == 1) {
addVoxel(x + cx, -y - cy, z + cz, rgb);
} else {
addVoxel(z + cz, -y - cy, x + cx, rgb);
}
}
}
}
}
} else { // compressed
int z = 0;
while (z < sz) {
int index = -1;
while (true) {
int data = fileIn.readIntRev();
if (data == NEXT_SLICE_FLAG) {
break;
} else if (data == CODE_FLAG) {
int count = fileIn.readIntRevUnsigned();
data = fileIn.readIntRev();
for (int j = 0; j < count; j++) {
int x = (index + 1)%sx;
int y = (index + 1)/sx;
index++;
byteBuffer.position(0);
byteBuffer.putInt(data);
int c1 = byteBuffer.get(3) & 0x0000FF;
int c2 = byteBuffer.get(2) & 0x0000FF;
int c3 = byteBuffer.get(1) & 0x0000FF;
int a = byteBuffer.get(0) & 0x0000FF; // read visibility encoding
if (a != 0) { // if voxel is not invisible
int rgb = colorFormat == 0 ? new Color(c1,c2,c3).getRGB() : new Color(c3, c2, c1).getRGB();
if (zAxisOrientation == 1) {
addVoxel(x + cx, -y - cy, z + cz, rgb);
} else {
addVoxel(z + cz, -y - cy, x + cx, rgb);
}
}
}
} else {
int x = (index + 1)%sx;
int y = (index + 1)/sx;
index++;
byteBuffer.position(0);
byteBuffer.putInt(data);
int c1 = byteBuffer.get(3) & 0x0000FF;
int c2 = byteBuffer.get(2) & 0x0000FF;
int c3 = byteBuffer.get(1) & 0x0000FF;
int a = byteBuffer.get(0) & 0x0000FF; // read visibility encoding
if (a != 0) { // if voxel is not invisible
int rgb = colorFormat == 0 ? new Color(c1,c2,c3).getRGB() : new Color(c3, c2, c1).getRGB();
if (zAxisOrientation == 1) {
addVoxel(x + cx, -y - cy, z + cz, rgb);
} else {
addVoxel(z + cz, -y - cy, x + cx, rgb);
}
}
}
}
z++;
}
}
}
return true;
}
}