in batik-codec/src/main/java/org/apache/batik/ext/awt/image/codec/png/PNGImageEncoder.java [858:1043]
public void encode(RenderedImage im) throws IOException {
this.image = im;
this.width = image.getWidth();
this.height = image.getHeight();
SampleModel sampleModel = image.getSampleModel();
int[] sampleSize = sampleModel.getSampleSize();
// Set bitDepth to a sentinel value
this.bitDepth = -1;
this.bitShift = 0;
// Allow user to override the bit depth of gray images
if (param instanceof PNGEncodeParam.Gray) {
PNGEncodeParam.Gray paramg = (PNGEncodeParam.Gray)param;
if (paramg.isBitDepthSet()) {
this.bitDepth = paramg.getBitDepth();
}
if (paramg.isBitShiftSet()) {
this.bitShift = paramg.getBitShift();
}
}
// Get bit depth from image if not set in param
if (this.bitDepth == -1) {
// Get bit depth from channel 0 of the image
this.bitDepth = sampleSize[0];
// Ensure all channels have the same bit depth
for (int i = 1; i < sampleSize.length; i++) {
if (sampleSize[i] != bitDepth) {
throw new RuntimeException();
}
}
// Round bit depth up to a power of 2
if (bitDepth > 2 && bitDepth < 4) {
bitDepth = 4;
} else if (bitDepth > 4 && bitDepth < 8) {
bitDepth = 8;
} else if (bitDepth > 8 && bitDepth < 16) {
bitDepth = 16;
} else if (bitDepth > 16) {
throw new RuntimeException();
}
}
this.numBands = sampleModel.getNumBands();
this.bpp = numBands*((bitDepth == 16) ? 2 : 1);
ColorModel colorModel = image.getColorModel();
if (colorModel instanceof IndexColorModel) {
if (bitDepth < 1 || bitDepth > 8) {
throw new RuntimeException();
}
if (sampleModel.getNumBands() != 1) {
throw new RuntimeException();
}
IndexColorModel icm = (IndexColorModel)colorModel;
int size = icm.getMapSize();
redPalette = new byte[size];
greenPalette = new byte[size];
bluePalette = new byte[size];
alphaPalette = new byte[size];
icm.getReds(redPalette);
icm.getGreens(greenPalette);
icm.getBlues(bluePalette);
icm.getAlphas(alphaPalette);
this.bpp = 1;
if (param == null) {
param = createGrayParam(redPalette,
greenPalette,
bluePalette,
alphaPalette);
}
// If param is still null, it can't be expressed as gray
if (param == null) {
param = new PNGEncodeParam.Palette();
}
if (param instanceof PNGEncodeParam.Palette) {
// If palette not set in param, create one from the ColorModel.
PNGEncodeParam.Palette parami = (PNGEncodeParam.Palette)param;
if (parami.isPaletteSet()) {
int[] palette = parami.getPalette();
size = palette.length/3;
int index = 0;
for (int i = 0; i < size; i++) {
redPalette[i] = (byte)palette[index++];
greenPalette[i] = (byte)palette[index++];
bluePalette[i] = (byte)palette[index++];
alphaPalette[i] = (byte)255;
}
}
this.colorType = PNG_COLOR_PALETTE;
} else if (param instanceof PNGEncodeParam.Gray) {
redPalette = greenPalette = bluePalette = alphaPalette = null;
this.colorType = PNG_COLOR_GRAY;
} else {
throw new RuntimeException();
}
} else if (numBands == 1) {
if (param == null) {
param = new PNGEncodeParam.Gray();
}
this.colorType = PNG_COLOR_GRAY;
} else if (numBands == 2) {
if (param == null) {
param = new PNGEncodeParam.Gray();
}
if (param.isTransparencySet()) {
skipAlpha = true;
numBands = 1;
if ((sampleSize[0] == 8) && (bitDepth < 8)) {
compressGray = true;
}
bpp = (bitDepth == 16) ? 2 : 1;
this.colorType = PNG_COLOR_GRAY;
} else {
if (this.bitDepth < 8) {
this.bitDepth = 8;
}
this.colorType = PNG_COLOR_GRAY_ALPHA;
}
} else if (numBands == 3) {
if (param == null) {
param = new PNGEncodeParam.RGB();
}
this.colorType = PNG_COLOR_RGB;
} else if (numBands == 4) {
if (param == null) {
param = new PNGEncodeParam.RGB();
}
if (param.isTransparencySet()) {
skipAlpha = true;
numBands = 3;
bpp = (bitDepth == 16) ? 6 : 3;
this.colorType = PNG_COLOR_RGB;
} else {
this.colorType = PNG_COLOR_RGB_ALPHA;
}
}
interlace = param.getInterlacing();
writeMagic();
writeIHDR();
writeCHRM();
writeGAMA();
writeICCP();
writeSBIT();
writeSRGB();
writePLTE();
writeHIST();
writeTRNS();
writeBKGD();
writePHYS();
writeSPLT();
writeTIME();
writeTEXT();
writeZTXT();
writePrivateChunks();
writeIDAT();
writeIEND();
dataOutput.flush();
dataOutput.close();
}