package com.pointcliki.dizgruntled.rez;
import org.newdawn.slick.Color;
import org.newdawn.slick.Image;
import org.newdawn.slick.ImageBuffer;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Vector2f;
public class MonolithPID {
protected MonolithFile fFile;
protected Image fImage;
protected Vector2f fOffset;
public MonolithPID(MonolithFile file) {
fFile = file;
}
public MonolithPID(Image image, Vector2f offset) {
fImage = image;
fOffset = offset;
}
/**
* Implementation based on http://www.fileformat.info/format/pcx/egff.htm
* @return The image represented by the file
*/
public Image image() {
if (fImage != null) return fImage;
if (fFile == null) return null;
// Parse info
byte[] data = fFile.data();
if (data == null) return null;
// Flags
int flags = MonolithResource.readInteger(data, 4);
boolean transparent = (flags & 1) == 1;
boolean rle = (flags & 32) == 32;
boolean ownPalette = (flags & 128) == 128;
// Extract offset
fOffset = new Vector2f(MonolithResource.readInteger(data, 16), MonolithResource.readInteger(data, 20));
if (!ownPalette) {
System.err.println("Expecting PIDs with own palette");
try {
fImage = new Image(0, 0);
} catch (SlickException e) {
e.printStackTrace();
}
return fImage;
}
// Extract dimensions
int w = MonolithResource.readInteger(data, 8);
int h = MonolithResource.readInteger(data, 12);
// Create a new image buffer to fill with pixels
ImageBuffer buf = new ImageBuffer(w, h);
// Extract palette
Color[] palette = new Color[256];
// Read
int len = data.length;
int n = 0;
for (int i = len - 768; i < len; i+= 3) {
int r = MonolithResource.readByte(data, i);
int g = MonolithResource.readByte(data, i + 1);
int b = MonolithResource.readByte(data, i + 2);
if (r == 255 && g == 0 && b == 132) palette[n] = new Color(0, 0, 0, 0);
else if (r == 252 && g == 2 && b == 132) palette[n] = new Color(0, 0, 0, 0);
else palette[n] = new Color(r, g, b);
n++;
}
n = 32;
int x = 0;
int y = 0;
if (rle) {
while (y < h) {
int b = MonolithResource.readByte(data, n);
n++;
if (b > 128) {
int i = b - 128;
while (i-- > 0 && y < h) {
fillPixel(buf, x, y, new Color(0, 0, 0, transparent ? 0: 1));
x++;
if (x == w) {
x = 0;
y++;
}
}
} else {
int i = b;
while (i-- > 0 && y < h) {
b = MonolithResource.readByte(data, n);
n++;
fillPixel(buf, x, y, palette[b]);
x++;
if (x == w) {
x = 0;
y++;
}
}
}
}
} else {
while (y < h) {
int b = MonolithResource.readByte(data, n);
n++;
int i;
if (b > 192) {
i = b - 192;
b = MonolithResource.readByte(data, n);
n++;
} else {
i = 1;
}
while (i-- > 0 && y < h) {fillPixel(buf, x, y, palette[b]);
x++;
if (x == w) {
x = 0;
y++;
}
}
}
}
fImage = new Image(buf);
return fImage;
}
public Vector2f offset() {
return fOffset;
}
protected void fillPixel(ImageBuffer buf, int x, int y, Color c) {
buf.setRGBA(x, y, (int) (c.r * 255), (int) (c.g * 255), (int) (c.b * 255), (int) (c.a * 255));
}
}