/*
* 作成日: 2009/04/05
*/
package jp.ac.fit.asura.nao.misc;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.util.ArrayList;
import java.util.List;
/**
* @author $Author: sey $
*
* @version $Id: $
*
*/
public class Pixmap {
protected int version;
protected byte[] data;
protected List<String> comments;
protected int width;
protected int height;
protected int depth;
/**
*
*/
public Pixmap() throws IOException {
comments = new ArrayList<String>();
}
public Pixmap(byte[] data, int width, int height, int depth) {
assert width * height * 3 == data.length;
comments = new ArrayList<String>();
this.data = data;
this.width = width;
this.height = height;
this.depth = depth;
this.version = 6;
}
public void write(String fileName) throws IOException {
OutputStream os = new FileOutputStream(fileName);
os.write("P6\n".getBytes());
os.write((width + " " + height + "\n").getBytes());
os.write("255\n".getBytes());
os.write(data, 0, data.length);
os.close();
}
public void read(InputStream is) throws IOException {
PushbackInputStream pbis = new PushbackInputStream(is);
if (!readMagic(pbis)) {
throw new IOException("Can't read magic.");
}
readHeaders(pbis);
readBody(pbis);
}
protected boolean readMagic(PushbackInputStream is) throws IOException {
int read;
skipWhitespaces(is);
read = is.read();
char ch = (char) read;
if (ch != 'P') {
is.unread(read);
return false;
}
read = is.read();
if (!Character.isDigit(ch)) {
is.unread(read);
return false;
}
version = Character.digit(ch, 10);
skipWhitespaces(is);
return true;
}
protected int skipWhitespaces(PushbackInputStream is) throws IOException {
int read;
int spaces = 0;
while ((read = is.read()) != -1) {
char ch = (char) read;
if (Character.isWhitespace(ch)) {
spaces++;
continue;
}
is.unread(read);
return spaces;
}
return spaces;
}
protected void readHeaders(PushbackInputStream is) throws IOException {
skipWhitespaces(is);
readComments(is);
width = readInt(is);
skipWhitespaces(is);
readComments(is);
height = readInt(is);
skipWhitespaces(is);
readComments(is);
depth = readInt(is);
is.read();
}
protected void readComments(PushbackInputStream is) throws IOException {
int read;
while ((read = is.read()) != -1) {
is.unread(read);
char ch = (char) read;
if (ch != '#') {
break;
}
comments.add(readLine(is));
skipWhitespaces(is);
}
}
protected String readLine(PushbackInputStream is) throws IOException {
StringBuilder sb = new StringBuilder();
int read;
while ((read = is.read()) != -1) {
char ch = (char) read;
if (ch == '\n')
return sb.toString();
if (ch == '\r') {
if ((read = is.read()) != '\n' && read != -1)
is.unread(read);
return sb.toString();
}
sb.append(ch);
}
return sb.toString();
}
protected int readInt(PushbackInputStream is) throws IOException,
NumberFormatException {
StringBuilder sb = new StringBuilder();
int read;
while ((read = is.read()) != -1) {
char ch = (char) read;
if (!Character.isDigit(ch)) {
is.unread(read);
break;
}
sb.append(ch);
}
return Integer.parseInt(sb.toString());
}
protected void readBody(PushbackInputStream is) throws IOException {
int length = calcLength();
data = new byte[length];
int read;
int offset = 0;
while ((read = is.read(data, offset, length)) > 0) {
offset += read;
length -= read;
}
}
protected int calcLength() {
return width * height;
}
/**
* @return comments
*/
public List<String> getComments() {
return comments;
}
public int getDepth() {
return depth;
}
public byte[] getData() {
return data;
}
/**
* @return height
*/
public int getHeight() {
return height;
}
/**
* @return version
*/
public int getVersion() {
return version;
}
/**
* @return width
*/
public int getWidth() {
return width;
}
}