clearAbortRequest();
processImageStarted(0);
if (param == null)
param = getDefaultWriteParam();
BMPImageWriteParam bmpParam = (BMPImageWriteParam)param;
// Default is using 24 bits per pixel.
int bitsPerPixel = 24;
boolean isPalette = false;
int paletteEntries = 0;
IndexColorModel icm = null;
RenderedImage input = null;
Raster inputRaster = null;
boolean writeRaster = image.hasRaster();
Rectangle sourceRegion = param.getSourceRegion();
SampleModel sampleModel = null;
ColorModel colorModel = null;
compImageSize = 0;
if (writeRaster) {
inputRaster = image.getRaster();
sampleModel = inputRaster.getSampleModel();
colorModel = ImageUtil.createColorModel(null, sampleModel);
if (sourceRegion == null)
sourceRegion = inputRaster.getBounds();
else
sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
} else {
input = image.getRenderedImage();
sampleModel = input.getSampleModel();
colorModel = input.getColorModel();
Rectangle rect = new Rectangle(input.getMinX(), input.getMinY(),
input.getWidth(), input.getHeight());
if (sourceRegion == null)
sourceRegion = rect;
else
sourceRegion = sourceRegion.intersection(rect);
}
IIOMetadata imageMetadata = image.getMetadata();
BMPMetadata bmpImageMetadata = null;
ImageTypeSpecifier imageType =
new ImageTypeSpecifier(colorModel, sampleModel);
if(imageMetadata != null) {
// Convert metadata.
bmpImageMetadata =
(BMPMetadata)convertImageMetadata(imageMetadata,
imageType, param);
} else {
// Use default.
bmpImageMetadata =
(BMPMetadata)getDefaultImageMetadata(imageType, param);
}
if (sourceRegion.isEmpty())
throw new RuntimeException(I18N.getString("BMPImageWrite0"));
int scaleX = param.getSourceXSubsampling();
int scaleY = param.getSourceYSubsampling();
int xOffset = param.getSubsamplingXOffset();
int yOffset = param.getSubsamplingYOffset();
// cache the data type;
int dataType = sampleModel.getDataType();
sourceRegion.translate(xOffset, yOffset);
sourceRegion.width -= xOffset;
sourceRegion.height -= yOffset;
int minX = sourceRegion.x / scaleX;
int minY = sourceRegion.y / scaleY;
w = (sourceRegion.width + scaleX - 1) / scaleX;
h = (sourceRegion.height + scaleY - 1) / scaleY;
xOffset = sourceRegion.x % scaleX;
yOffset = sourceRegion.y % scaleY;
Rectangle destinationRegion = new Rectangle(minX, minY, w, h);
boolean noTransform = destinationRegion.equals(sourceRegion);
// Raw data can only handle bytes, everything greater must be ASCII.
int[] sourceBands = param.getSourceBands();
boolean noSubband = true;
int numBands = sampleModel.getNumBands();
if (sourceBands != null) {
sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
colorModel = null;
noSubband = false;
numBands = sampleModel.getNumBands();
} else {
sourceBands = new int[numBands];
for (int i = 0; i < numBands; i++)
sourceBands[i] = i;
}
int[] bandOffsets = null;
boolean bgrOrder = true;
if (sampleModel instanceof ComponentSampleModel) {
bandOffsets = ((ComponentSampleModel)sampleModel).getBandOffsets();
if (sampleModel instanceof BandedSampleModel) {
// for images with BandedSampleModel we can not work
// with raster directly and must use writePixels()
bgrOrder = false;
} else {
// we can work with raster directly only in case of
// BGR component order.
// In any other case we must use writePixels()
for (int i = 0; i < bandOffsets.length; i++) {
bgrOrder &= (bandOffsets[i] == (bandOffsets.length - i - 1));
}
}
} else {
if (sampleModel instanceof SinglePixelPackedSampleModel) {
// BugId 4892214: we can not work with raster directly
// if image have different color order than RGB.
// We should use writePixels() for such images.
int[] bitOffsets = ((SinglePixelPackedSampleModel)sampleModel).getBitOffsets();
for (int i=0; i<bitOffsets.length-1; i++) {
bgrOrder &= bitOffsets[i] > bitOffsets[i+1];
}
}
}
if (bandOffsets == null) {
// we will use getPixels() to extract pixel data for writePixels()
// Please note that getPixels() provides rgb bands order.
bandOffsets = new int[numBands];
for (int i = 0; i < numBands; i++)
bandOffsets[i] = i;
}
noTransform &= bgrOrder;
int sampleSize[] = sampleModel.getSampleSize();
//XXX: check more
// Number of bytes that a scanline for the image written out will have.
int destScanlineBytes = w * numBands;
switch(bmpParam.getCompressionMode()) {
case ImageWriteParam.MODE_EXPLICIT:
compressionType = getCompressionType(bmpParam.getCompressionType());
break;
case ImageWriteParam.MODE_COPY_FROM_METADATA:
compressionType = bmpImageMetadata.compression;
break;
case ImageWriteParam.MODE_DEFAULT: