org.apache.xmlgraphics.image.codec.tiff.ImageInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.fop Show documentation
Show all versions of org.apache.fop Show documentation
The core maven build properties
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.xmlgraphics.image.codec.tiff;
import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.RenderedImage;
final class ImageInfo {
// Default values
private static final int DEFAULT_ROWS_PER_STRIP = 8;
private final int numExtraSamples;
private final ExtraSamplesType extraSampleType;
private final ImageType imageType;
private final int colormapSize;
private final char[] colormap;
private final int tileWidth;
private final int tileHeight;
private final int numTiles;
private final long bytesPerRow;
private final long bytesPerTile;
private ImageInfo(ImageInfoBuilder builder) {
this.numExtraSamples = builder.numExtraSamples;
this.extraSampleType = builder.extraSampleType;
this.imageType = builder.imageType;
this.colormapSize = builder.colormapSize;
this.colormap = copyColormap(builder.colormap);
this.tileWidth = builder.tileWidth;
this.tileHeight = builder.tileHeight;
this.numTiles = builder.numTiles;
this.bytesPerRow = builder.bytesPerRow;
this.bytesPerTile = builder.bytesPerTile;
}
private static char[] copyColormap(char[] colorMap) {
if (colorMap == null) {
return null;
}
char[] copy = new char[colorMap.length];
System.arraycopy(colorMap, 0, copy, 0, colorMap.length);
return copy;
}
private static int getNumberOfExtraSamplesForColorSpace(ColorSpace colorSpace,
ImageType imageType, int numBands) {
if (imageType == ImageType.GENERIC) {
return numBands - 1;
} else if (numBands > 1) {
return numBands - colorSpace.getNumComponents();
} else {
return 0;
}
}
private static char[] createColormap(final int sizeOfColormap, byte[] r, byte[] g, byte[] b) {
int redIndex = 0;
int greenIndex = sizeOfColormap;
int blueIndex = 2 * sizeOfColormap;
char[] colormap = new char[sizeOfColormap * 3];
for (int i = 0; i < sizeOfColormap; i++) {
// beware of sign extended bytes
colormap[redIndex++] = convertColorToColormapChar(0xff & r[i]);
colormap[greenIndex++] = convertColorToColormapChar(0xff & g[i]);
colormap[blueIndex++] = convertColorToColormapChar(0xff & b[i]);
}
return colormap;
}
private static char convertColorToColormapChar(int color) {
return (char) (color << 8 | color);
}
int getNumberOfExtraSamples() {
return numExtraSamples;
}
ExtraSamplesType getExtraSamplesType() {
return extraSampleType;
}
ImageType getType() {
return imageType;
}
int getColormapSize() {
return colormapSize;
}
char[] getColormap() {
return copyColormap(colormap);
}
int getTileWidth() {
return tileWidth;
}
int getTileHeight() {
return tileHeight;
}
int getNumTiles() {
return numTiles;
}
long getBytesPerRow() {
return bytesPerRow;
}
long getBytesPerTile() {
return bytesPerTile;
}
static ImageInfo newInstance(RenderedImage im, int dataTypeSize, int numBands,
ColorModel colorModel, TIFFEncodeParam params) {
ImageInfoBuilder builder = new ImageInfoBuilder();
if (colorModel instanceof IndexColorModel) { // Bilevel or palette
IndexColorModel indexColorModel = (IndexColorModel) colorModel;
int colormapSize = indexColorModel.getMapSize();
byte[] r = new byte[colormapSize];
indexColorModel.getReds(r);
byte[] g = new byte[colormapSize];
indexColorModel.getGreens(g);
byte[] b = new byte[colormapSize];
indexColorModel.getBlues(b);
builder.imageType = ImageType.getTypeFromRGB(colormapSize, r, g, b, dataTypeSize,
numBands);
if (builder.imageType == ImageType.PALETTE) {
builder.colormap = createColormap(colormapSize, r, g, b);
builder.colormapSize = colormapSize * 3;
}
} else if (colorModel == null) {
if (dataTypeSize == 1 && numBands == 1) { // bilevel
builder.imageType = ImageType.BILEVEL_BLACK_IS_ZERO;
} else {
builder.imageType = ImageType.GENERIC;
builder.numExtraSamples = numBands > 1 ? numBands - 1 : 0;
}
} else {
ColorSpace colorSpace = colorModel.getColorSpace();
builder.imageType = ImageType.getTypeFromColorSpace(colorSpace, params);
builder.numExtraSamples = getNumberOfExtraSamplesForColorSpace(colorSpace,
builder.imageType, numBands);
builder.extraSampleType = ExtraSamplesType.getValue(colorModel,
builder.numExtraSamples);
}
// Initialize tile dimensions.
final int width = im.getWidth();
final int height = im.getHeight();
if (params.getWriteTiled()) {
builder.tileWidth = params.getTileWidth() > 0 ? params.getTileWidth() : width;
builder.tileHeight = params.getTileHeight() > 0 ? params.getTileHeight() : height;
// NB: Parentheses are used in this statement for correct rounding.
builder.numTiles = ((width + builder.tileWidth - 1) / builder.tileWidth)
* ((height + builder.tileHeight - 1) / builder.tileHeight);
} else {
builder.tileWidth = width;
builder.tileHeight = params.getTileHeight() > 0 ? params.getTileHeight()
: DEFAULT_ROWS_PER_STRIP;
builder.numTiles = (int) Math.ceil(height / (double) builder.tileHeight);
}
builder.setBytesPerRow(dataTypeSize, numBands)
.setBytesPerTile();
return builder.build();
}
private static final class ImageInfoBuilder {
private ImageType imageType = ImageType.UNSUPPORTED;
private int numExtraSamples;
private char[] colormap;
private int colormapSize;
private ExtraSamplesType extraSampleType = ExtraSamplesType.UNSPECIFIED;
private int tileWidth;
private int tileHeight;
private int numTiles;
private long bytesPerRow;
private long bytesPerTile;
private ImageInfoBuilder setBytesPerRow(int dataTypeSize, int numBands) {
bytesPerRow = (long) Math.ceil((dataTypeSize / 8.0) * tileWidth * numBands);
return this;
}
private ImageInfoBuilder setBytesPerTile() {
bytesPerTile = bytesPerRow * tileHeight;
return this;
}
private ImageInfo build() {
return new ImageInfo(this);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy