int minX = im.getMinX();
int minY = im.getMinY();
int width = im.getWidth();
int height = im.getHeight();
int tileHeight = im.getTileHeight();
SampleModel sampleModel = im.getSampleModel();
ColorModel colorModel = im.getColorModel();
String ls = (String)java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
lineSeparator = ls.getBytes();
int dataType = sampleModel.getTransferType();
if ((dataType == DataBuffer.TYPE_FLOAT) ||
(dataType == DataBuffer.TYPE_DOUBLE)) {
throw new RuntimeException(JaiI18N.getString("PNMImageEncoder0"));
}
// Raw data can only handle bytes, everything greater must be ASCII.
int[] sampleSize = sampleModel.getSampleSize();
int numBands = sampleModel.getNumBands();
// Colormap populated for non-bilevel IndexColorModel only.
byte[] reds = null;
byte[] greens = null;
byte[] blues = null;
// Flag indicating that PB data should be inverted before writing.
boolean isPBMInverted = false;
if (numBands == 1) {
if (colorModel instanceof IndexColorModel) {
IndexColorModel icm = (IndexColorModel)colorModel;
int mapSize = icm.getMapSize();
if (mapSize < (1 << sampleSize[0])) {
throw new RuntimeException(
JaiI18N.getString("PNMImageEncoder1"));
}
if(sampleSize[0] == 1) {
variant = PBM_RAW;
// Set PBM inversion flag if 1 maps to a higher color
// value than 0: PBM expects white-is-zero so if this
// does not obtain then inversion needs to occur.
isPBMInverted =
(icm.getRed(1) + icm.getGreen(1) + icm.getBlue(1)) >
(icm.getRed(0) + icm.getGreen(0) + icm.getBlue(0));
} else {
variant = PPM_RAW;
reds = new byte[mapSize];
greens = new byte[mapSize];
blues = new byte[mapSize];
icm.getReds(reds);
icm.getGreens(greens);
icm.getBlues(blues);
}
} else if (sampleSize[0] == 1) {
variant = PBM_RAW;
} else if (sampleSize[0] <= 8) {
variant = PGM_RAW;
} else {
variant = PGM_ASCII;
}
} else if (numBands == 3) {
if (sampleSize[0] <= 8 && sampleSize[1] <= 8 &&
sampleSize[2] <= 8) { // all 3 bands must be <= 8
variant = PPM_RAW;
} else {
variant = PPM_ASCII;
}
} else {
throw new RuntimeException(JaiI18N.getString("PNMImageEncoder2"));
}
// Read parameters
if (((PNMEncodeParam)param).getRaw()) {
if (!isRaw(variant)) {
boolean canUseRaw = true;
// Make sure sampleSize for all bands no greater than 8.
for (int i = 0; i < sampleSize.length; i++) {
if (sampleSize[i] > 8) {
canUseRaw = false;
break;
}
}
if (canUseRaw) {
variant += 0x3;
}
}
} else {
if (isRaw(variant)) {
variant -= 0x3;
}
}
maxValue = (1 << sampleSize[0]) - 1;
// Write PNM file.
output.write('P'); // magic value
output.write(variant);
output.write(lineSeparator);
output.write(COMMENT.getBytes()); // comment line
output.write(lineSeparator);
writeInteger(output, width); // width
output.write(SPACE);
writeInteger(output, height); // height
// Writ esample max value for non-binary images
if ((variant != PBM_RAW) && (variant != PBM_ASCII)) {
output.write(lineSeparator);
writeInteger(output, maxValue);
}
// The spec allows a single character between the
// last header value and the start of the raw data.
if (variant == PBM_RAW ||
variant == PGM_RAW ||
variant == PPM_RAW) {
output.write('\n');
}
// Set flag for optimal image writing case: row-packed data with
// correct band order if applicable.
boolean writeOptimal = false;
if (variant == PBM_RAW &&
sampleModel.getTransferType() == DataBuffer.TYPE_BYTE &&
sampleModel instanceof MultiPixelPackedSampleModel) {
MultiPixelPackedSampleModel mppsm =
(MultiPixelPackedSampleModel)sampleModel;
// Must have left-aligned bytes with unity bit stride.
if(mppsm.getDataBitOffset() == 0 &&
mppsm.getPixelBitStride() == 1) {
writeOptimal = true;
}
} else if ((variant == PGM_RAW || variant == PPM_RAW) &&
sampleModel instanceof ComponentSampleModel &&
!(colorModel instanceof IndexColorModel)) {
ComponentSampleModel csm =
(ComponentSampleModel)sampleModel;
// Pixel stride must equal band count.
if(csm.getPixelStride() == numBands) {
writeOptimal = true;
// Band offsets must equal band indices.
if(variant == PPM_RAW) {
int[] bandOffsets = csm.getBandOffsets();
for(int b = 0; b < numBands; b++) {
if(bandOffsets[b] != b) {
writeOptimal = false;
break;
}
}
}
}
}
// Write using an optimal approach if possible.
if(writeOptimal) {
int bytesPerRow = variant == PBM_RAW ?
(width + 7)/8 : width*sampleModel.getNumBands();
int numYTiles = im.getNumYTiles();
Rectangle imageBounds =
new Rectangle(im.getMinX(), im.getMinY(),
im.getWidth(), im.getHeight());
Rectangle stripRect =