blob: 1f66945f3baec059ec3712e77d378a0d8402915f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2008 IBM Corporation and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Junji MAEDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.visualization.engines.lowvision.internal.io;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.WritableRaster;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.eclipse.actf.visualization.engines.lowvision.image.ImageUtil;
import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
import org.eclipse.actf.visualization.engines.lowvision.internal.util.DosUtil;
import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
public class BMPWriter {
private static final int DEFAULT_BITCOUNT = 24;
public static void writeInt2D(Int2D _i2d, String _fileName, int _bitCount)
throws LowVisionIOException {
writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _fileName,
_bitCount);
}
public static void writeInt2D(Int2D _i2d, String _fileName)
throws LowVisionIOException {
writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _fileName);
}
public static void writeInt2D(Int2D _i2d, OutputStream _os, int _bitCount)
throws LowVisionIOException {
writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _os, _bitCount);
}
public static void writeInt2D(Int2D _i2d, OutputStream _os)
throws LowVisionIOException {
writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _os);
}
public static void writeBufferedImage(BufferedImage _bi, String _fileName,
int _bitCount) throws LowVisionIOException {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(_fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new LowVisionIOException("The file was not found: "
+ _fileName);
}
writeBufferedImage(_bi, fos, _bitCount);
}
public static void writeBufferedImage(BufferedImage _bi, String _fileName)
throws LowVisionIOException {
writeBufferedImage(_bi, _fileName, DEFAULT_BITCOUNT);
}
public static void writeBufferedImage(BufferedImage _bi, OutputStream _os)
throws LowVisionIOException {
writeBufferedImage(_bi, _os, DEFAULT_BITCOUNT);
}
public static void writeBufferedImage(BufferedImage _bi, OutputStream _os,
int _bitCount) throws LowVisionIOException {
// only for BufferedImage.TYPE_INT_RGB
if (_bitCount != 16 && _bitCount != 24) {
throw new LowVisionIOException("Invalid bitCount: " + _bitCount);
}
int imageWidth = _bi.getWidth();
int imageHeight = _bi.getHeight();
int residual = 0;
if (_bitCount == 24) {
residual = imageWidth * 3 % 4; // 24bit
} else if (_bitCount == 16) {
residual = imageWidth * 2 % 4; // 16bit
}
int linePadding = 0;
if (residual > 0)
linePadding = 4 - residual;
int imageSize = 0;
if (_bitCount == 24) {
imageSize = (imageWidth * 3 + linePadding) * imageHeight;
} else if (_bitCount == 16) {
imageSize = (imageWidth * 2 + linePadding) * imageHeight;
}
int fileSize = imageSize + 54;
DataOutputStream dos = new DataOutputStream(_os);
try {
// magic number "BM"
dos.writeByte(0x42);
dos.writeByte(0x4d);
dos.writeInt(DosUtil.upsideDownInt(fileSize));
dos.writeInt(0);
dos.writeInt(DosUtil.upsideDownInt(54));
dos.writeInt(DosUtil.upsideDownInt(40));
dos.writeInt(DosUtil.upsideDownInt(imageWidth));
dos.writeInt(DosUtil.upsideDownInt(imageHeight));
dos.writeShort(DosUtil.upsideDownShort((short) 1));
dos.writeShort(DosUtil.upsideDownShort((short) _bitCount));
dos.writeInt(DosUtil.upsideDownInt(0));
dos.writeInt(DosUtil.upsideDownInt(imageSize));
dos.writeInt(DosUtil.upsideDownInt(4724));
dos.writeInt(DosUtil.upsideDownInt(4724));
dos.writeInt(DosUtil.upsideDownInt(0));
dos.writeInt(DosUtil.upsideDownInt(0));
} catch (IOException e) {
e.printStackTrace();
throw new LowVisionIOException(
"IO error occurred when writing header.");
}
WritableRaster srcRaster = _bi.copyData(null);
DataBufferInt srcBufInt = (DataBufferInt) (srcRaster.getDataBuffer());
int[] srcArray = srcBufInt.getData();
byte[][] destArray2d = null;
int srcIndex = 0;
if (_bitCount == 24) {
destArray2d = new byte[imageHeight][imageWidth * 3];
for (int j = imageHeight - 1; j >= 0; j--) {
for (int i = 0; i < imageWidth; i++) {
int rgb = srcArray[srcIndex];
destArray2d[j][i * 3] = (byte) (rgb & 0xff); // b
destArray2d[j][i * 3 + 1] = (byte) (rgb >> 8 & 0xff); // g
destArray2d[j][i * 3 + 2] = (byte) (rgb >> 16 & 0xff); // r
srcIndex++;
}
}
} else if (_bitCount == 16) {
destArray2d = new byte[imageHeight][imageWidth * 2];
for (int j = imageHeight - 1; j >= 0; j--) {
for (int i = 0; i < imageWidth; i++) {
int rgb = srcArray[srcIndex];
int r = (rgb >> 19) & 0x1f;
int g = (rgb >> 11) & 0x1f;
int b = (rgb >> 3) & 0x1f;
destArray2d[j][i * 2] = (byte) (((g & 0x7) << 5) | b);
destArray2d[j][i * 2 + 1] = (byte) ((r << 2) | ((g >> 3) & 0x3));
srcIndex++;
}
}
}
try {
for (int j = 0; j < imageHeight; j++) {
dos.write(destArray2d[j]);
for (int i = 0; i < linePadding; i++) {
dos.writeByte(0);
}
}
} catch (IOException e) {
e.printStackTrace();
throw new LowVisionIOException(
"IO error occurred while writing image data.");
}
try {
dos.close();
_os.close();
} catch (IOException e) {
e.printStackTrace();
throw new LowVisionIOException(
"IO error occurred when closing output streams.");
}
}
}