int bitsPerPixel = 24;
boolean isPalette = false;
int paletteEntries = 0;
IndexColorModel icm = null;
SampleModel sm = im.getSampleModel();
int numBands = sm.getNumBands();
ColorModel cm = im.getColorModel();
if (numBands != 1 && numBands != 3) {
throw new
IllegalArgumentException(JaiI18N.getString("BMPImageEncoder1"));
}
int sampleSize[] = sm.getSampleSize();
if (sampleSize[0] > 8) {
throw new RuntimeException(JaiI18N.getString("BMPImageEncoder2"));
}
for (int i=1; i<sampleSize.length; i++) {
if (sampleSize[i] != sampleSize[0]) {
throw
new RuntimeException(JaiI18N.getString("BMPImageEncoder3"));
}
}
// Float and Double data cannot be written in a BMP format.
int dataType = sm.getTransferType();
if (dataType != DataBuffer.TYPE_BYTE &&
!CodecUtils.isPackedByteImage(im)) {
throw new RuntimeException(JaiI18N.getString("BMPImageEncoder0"));
}
// Number of bytes that a scanline for the image written out will have.
int destScanlineBytes = w * numBands;
int compression = 0;
byte r[] = null, g[] = null, b[] = null, a[] = null;
if (cm instanceof IndexColorModel) {
isPalette = true;
icm = (IndexColorModel)cm;
paletteEntries = icm.getMapSize();
if (paletteEntries <= 2) {
bitsPerPixel = 1;
destScanlineBytes = (int)Math.ceil((double)w/8.0);
} else if (paletteEntries <= 16) {
bitsPerPixel = 4;
destScanlineBytes = (int)Math.ceil((double)w/2.0);
} else if (paletteEntries <= 256) {
bitsPerPixel = 8;
} else {
// Cannot be written as a Palette image. So write out as
// 24 bit image.
bitsPerPixel = 24;
isPalette = false;
paletteEntries = 0;
destScanlineBytes = w * 3;
}
if (isPalette == true) {
r = new byte[paletteEntries];
g = new byte[paletteEntries];
b = new byte[paletteEntries];
a = new byte[paletteEntries];
icm.getAlphas(a);
icm.getReds(r);
icm.getGreens(g);
icm.getBlues(b);
}
} else {
// Grey scale images
if (numBands == 1) {
isPalette = true;
paletteEntries = 256;
// int sampleSize[] = sm.getSampleSize();
bitsPerPixel = sampleSize[0];
destScanlineBytes = (int)Math.ceil((double)(w * bitsPerPixel) /
8.0);
r = new byte[256];
g = new byte[256];
b = new byte[256];
a = new byte[256];
for (int i = 0; i < 256; i++) {
r[i] = (byte)i;
g[i] = (byte)i;
b[i] = (byte)i;
//Fix 4672486: BMPEncoder writes wrong alpha lut into
// stream for gray-scale image
a[i] = (byte)255;
}
} else if (sm instanceof SinglePixelPackedSampleModel) {
bitsPerPixel = DataBuffer.getDataTypeSize(sm.getDataType());
destScanlineBytes = w * bitsPerPixel + 7 >> 3;
}
}
// actual writing of image data
int fileSize = 0;
int offset = 0;
int headerSize = 0;
int imageSize = 0;
int xPelsPerMeter = 0;
int yPelsPerMeter = 0;
int colorsUsed = 0;
int colorsImportant = paletteEntries;
int padding = 0;
// Calculate padding for each scanline
int remainder = destScanlineBytes % 4;
if (remainder != 0) {
padding = 4 - remainder;
}
switch (version) {
case BMPEncodeParam.VERSION_2:
offset = 26 + paletteEntries * 3;
headerSize = 12;
imageSize = (destScanlineBytes + padding) * h;
fileSize = imageSize + offset;
throw new
RuntimeException(JaiI18N.getString("BMPImageEncoder5"));
//break;
case BMPEncodeParam.VERSION_3:
// FileHeader is 14 bytes, BitmapHeader is 40 bytes,
// add palette size and that is where the data will begin
if (isCompressed && bitsPerPixel == 8) {
compression = 1;
} else if (isCompressed && bitsPerPixel == 4) {
compression = 2;
}
offset = 54 + paletteEntries * 4;
imageSize = (destScanlineBytes + padding) * h;
fileSize = imageSize + offset;
headerSize = 40;
break;
case BMPEncodeParam.VERSION_4:
headerSize = 108;
throw new
RuntimeException(JaiI18N.getString("BMPImageEncoder5"));
// break;
}
int redMask = 0, blueMask = 0, greenMask = 0;
if (cm instanceof DirectColorModel) {
redMask = ((DirectColorModel)cm).getRedMask();
greenMask = ((DirectColorModel)cm).getGreenMask();
blueMask = ((DirectColorModel)cm).getBlueMask();
destScanlineBytes = w;
compression = 3;
fileSize += 12;
offset += 12;
}
writeFileHeader(fileSize, offset);
writeInfoHeader(headerSize, bitsPerPixel);
// compression
writeDWord(compression);
// imageSize
writeDWord(imageSize);
// xPelsPerMeter
writeDWord(xPelsPerMeter);
// yPelsPerMeter
writeDWord(yPelsPerMeter);
// Colors Used
writeDWord(colorsUsed);
// Colors Important
writeDWord(colorsImportant);
if (compression == 3) {
writeDWord(redMask);
writeDWord(greenMask);
writeDWord(blueMask);
}
if (compression == 3) {
for (int i = 0; i < h; i++) {
int row = minY + i;
if (!isTopDown)
row = minY + h - i -1;
// Get the pixels
Rectangle srcRect =
new Rectangle(minX, row, w, 1);
Raster src = im.getData(srcRect);
SampleModel sm1 = src.getSampleModel();
int pos = 0;
int startX = srcRect.x - src.getSampleModelTranslateX();
int startY = srcRect.y - src.getSampleModelTranslateY();
if (sm1 instanceof SinglePixelPackedSampleModel) {
SinglePixelPackedSampleModel sppsm =