use of javax.imageio.stream.MemoryCacheImageInputStream in project pdfbox by apache.
the class PDShadingType5 method collectTriangles.
@SuppressWarnings("squid:S1166")
@Override
List<ShadedTriangle> collectTriangles(AffineTransform xform, Matrix matrix) throws IOException {
COSDictionary dict = getCOSObject();
if (!(dict instanceof COSStream)) {
return Collections.emptyList();
}
PDRange rangeX = getDecodeForParameter(0);
PDRange rangeY = getDecodeForParameter(1);
if (rangeX == null || rangeY == null || Float.compare(rangeX.getMin(), rangeX.getMax()) == 0 || Float.compare(rangeY.getMin(), rangeY.getMax()) == 0) {
return Collections.emptyList();
}
int numPerRow = getVerticesPerRow();
PDRange[] colRange = new PDRange[getNumberOfColorComponents()];
for (int i = 0; i < colRange.length; ++i) {
colRange[i] = getDecodeForParameter(2 + i);
if (colRange[i] == null) {
throw new IOException("Range missing in shading /Decode entry");
}
}
List<Vertex> vlist = new ArrayList<>();
long maxSrcCoord = (long) Math.pow(2, getBitsPerCoordinate()) - 1;
long maxSrcColor = (long) Math.pow(2, getBitsPerComponent()) - 1;
COSStream cosStream = (COSStream) dict;
try (ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.createInputStream())) {
boolean eof = false;
while (!eof) {
Vertex p;
try {
p = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange, matrix, xform);
vlist.add(p);
} catch (EOFException ex) {
eof = true;
}
}
}
int rowNum = vlist.size() / numPerRow;
if (rowNum < 2) {
// must have at least two rows; if not, return empty list
return Collections.emptyList();
}
Vertex[][] latticeArray = new Vertex[rowNum][numPerRow];
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < numPerRow; j++) {
latticeArray[i][j] = vlist.get(i * numPerRow + j);
}
}
return createShadedTriangleList(rowNum, numPerRow, latticeArray);
}
use of javax.imageio.stream.MemoryCacheImageInputStream in project pdfbox by apache.
the class SampledImageReader method readRasterFromAny.
private static void readRasterFromAny(PDImage pdImage, WritableRaster raster) throws IOException {
final PDColorSpace colorSpace = pdImage.getColorSpace();
final int numComponents = colorSpace.getNumberOfComponents();
final int bitsPerComponent = pdImage.getBitsPerComponent();
final float[] decode = getDecodeArray(pdImage);
DecodeOptions options = new DecodeOptions();
// read bit stream
try (ImageInputStream iis = new MemoryCacheImageInputStream(pdImage.createInputStream(options))) {
final int inputWidth = pdImage.getWidth();
final int scanWidth = pdImage.getWidth();
final int scanHeight = pdImage.getHeight();
// create stream
final float sampleMax = (float) Math.pow(2, bitsPerComponent) - 1f;
final boolean isIndexed = colorSpace instanceof PDIndexed;
// calculate row padding
int padding = 0;
if (inputWidth * numComponents * bitsPerComponent % 8 > 0) {
padding = 8 - (inputWidth * numComponents * bitsPerComponent % 8);
}
// read stream
final boolean isShort = raster.getDataBuffer().getDataType() == DataBuffer.TYPE_USHORT;
assert !isIndexed || !isShort;
final byte[] srcColorValuesBytes = isShort ? null : new byte[numComponents];
final short[] srcColorValuesShort = isShort ? new short[numComponents] : null;
for (int y = 0; y < scanHeight; y++) {
for (int x = 0; x < scanWidth; x++) {
for (int c = 0; c < numComponents; c++) {
int value = (int) iis.readBits(bitsPerComponent);
// decode array
final float dMin = decode[c * 2];
final float dMax = decode[(c * 2) + 1];
// interpolate to domain
float output = dMin + (value * ((dMax - dMin) / sampleMax));
if (isIndexed) {
// indexed color spaces get the raw value, because the TYPE_BYTE
// below cannot be reversed by the color space without it having
// knowledge of the number of bits per component
srcColorValuesBytes[c] = (byte) Math.round(output);
} else {
if (isShort) {
// interpolate to TYPE_SHORT
int outputShort = Math.round(((output - Math.min(dMin, dMax)) / Math.abs(dMax - dMin)) * 65535f);
srcColorValuesShort[c] = (short) outputShort;
} else {
// interpolate to TYPE_BYTE
int outputByte = Math.round(((output - Math.min(dMin, dMax)) / Math.abs(dMax - dMin)) * 255f);
srcColorValuesBytes[c] = (byte) outputByte;
}
}
}
if (isShort) {
raster.setDataElements(x, y, srcColorValuesShort);
} else {
raster.setDataElements(x, y, srcColorValuesBytes);
}
}
// rows are padded to the nearest byte
iis.readBits(padding);
}
}
}
use of javax.imageio.stream.MemoryCacheImageInputStream in project pdfbox by apache.
the class SampledImageReader method fromAny.
// slower, general-purpose image conversion from any image format
private static BufferedImage fromAny(PDImage pdImage, WritableRaster raster, COSArray colorKey, Rectangle clipped, final int subsampling, final int width, final int height) throws IOException {
int currentSubsampling = subsampling;
final PDColorSpace colorSpace = pdImage.getColorSpace();
final int numComponents = colorSpace.getNumberOfComponents();
final int bitsPerComponent = pdImage.getBitsPerComponent();
final float[] decode = getDecodeArray(pdImage);
DecodeOptions options = new DecodeOptions(currentSubsampling);
options.setSourceRegion(clipped);
// read bit stream
try (ImageInputStream iis = new MemoryCacheImageInputStream(pdImage.createInputStream(options))) {
final int inputWidth;
final int startx;
final int starty;
final int scanWidth;
final int scanHeight;
if (options.isFilterSubsampled()) {
// Decode options were honored, and so there is no need for additional clipping or subsampling
inputWidth = width;
startx = 0;
starty = 0;
scanWidth = width;
scanHeight = height;
currentSubsampling = 1;
} else {
// Decode options not honored, so we need to clip and subsample ourselves.
inputWidth = pdImage.getWidth();
startx = clipped.x;
starty = clipped.y;
scanWidth = clipped.width;
scanHeight = clipped.height;
}
final float sampleMax = (float) Math.pow(2, bitsPerComponent) - 1f;
final boolean isIndexed = colorSpace instanceof PDIndexed;
// init color key mask
float[] colorKeyRanges = null;
BufferedImage colorKeyMask = null;
if (colorKey != null) {
colorKeyRanges = colorKey.toFloatArray();
colorKeyMask = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
}
// calculate row padding
int padding = 0;
if (inputWidth * numComponents * bitsPerComponent % 8 > 0) {
padding = 8 - (inputWidth * numComponents * bitsPerComponent % 8);
}
// read stream
byte[] srcColorValues = new byte[numComponents];
byte[] alpha = new byte[1];
for (int y = 0; y < starty + scanHeight; y++) {
for (int x = 0; x < startx + scanWidth; x++) {
boolean isMasked = true;
for (int c = 0; c < numComponents; c++) {
int value = (int) iis.readBits(bitsPerComponent);
// color key mask requires values before they are decoded
if (colorKeyRanges != null) {
isMasked &= value >= colorKeyRanges[c * 2] && value <= colorKeyRanges[c * 2 + 1];
}
// decode array
final float dMin = decode[c * 2];
final float dMax = decode[(c * 2) + 1];
// interpolate to domain
float output = dMin + (value * ((dMax - dMin) / sampleMax));
if (isIndexed) {
// indexed color spaces get the raw value, because the TYPE_BYTE
// below cannot be reversed by the color space without it having
// knowledge of the number of bits per component
srcColorValues[c] = (byte) Math.round(output);
} else {
// interpolate to TYPE_BYTE
int outputByte = Math.round(((output - Math.min(dMin, dMax)) / Math.abs(dMax - dMin)) * 255f);
srcColorValues[c] = (byte) outputByte;
}
}
// only write to output if within requested region and subsample.
if (x >= startx && y >= starty && x % currentSubsampling == 0 && y % currentSubsampling == 0) {
raster.setDataElements((x - startx) / currentSubsampling, (y - starty) / currentSubsampling, srcColorValues);
// set alpha channel in color key mask, if any
if (colorKeyMask != null) {
alpha[0] = (byte) (isMasked ? 255 : 0);
colorKeyMask.getRaster().setDataElements((x - startx) / currentSubsampling, (y - starty) / currentSubsampling, alpha);
}
}
}
// rows are padded to the nearest byte
iis.readBits(padding);
}
// use the color space to convert the image to RGB
BufferedImage rgbImage = colorSpace.toRGBImage(raster);
// apply color mask, if any
if (colorKeyMask != null) {
return applyColorKeyMask(rgbImage, colorKeyMask);
} else {
return rgbImage;
}
}
}
use of javax.imageio.stream.MemoryCacheImageInputStream in project pdfbox by apache.
the class PDMeshBasedShadingType method collectPatches.
/**
* Create a patch list from a data stream, the returned list contains all the patches contained in the data stream.
*
* @param xform transformation for user to device space
* @param matrix the pattern matrix concatenated with that of the parent content stream
* @param controlPoints number of control points, 12 for type 6 shading and 16 for type 7 shading
* @return the obtained patch list
* @throws IOException when something went wrong
*/
@SuppressWarnings({ "squid:S2583", "squid:S1166" })
final List<Patch> collectPatches(AffineTransform xform, Matrix matrix, int controlPoints) throws IOException {
COSDictionary dict = getCOSObject();
if (!(dict instanceof COSStream)) {
return Collections.emptyList();
}
PDRange rangeX = getDecodeForParameter(0);
PDRange rangeY = getDecodeForParameter(1);
if (rangeX == null || rangeY == null || Float.compare(rangeX.getMin(), rangeX.getMax()) == 0 || Float.compare(rangeY.getMin(), rangeY.getMax()) == 0) {
return Collections.emptyList();
}
int bitsPerFlag = getBitsPerFlag();
PDRange[] colRange = new PDRange[getNumberOfColorComponents()];
for (int i = 0; i < colRange.length; ++i) {
colRange[i] = getDecodeForParameter(2 + i);
if (colRange[i] == null) {
throw new IOException("Range missing in shading /Decode entry");
}
}
List<Patch> list = new ArrayList<>();
long maxSrcCoord = (long) Math.pow(2, getBitsPerCoordinate()) - 1;
long maxSrcColor = (long) Math.pow(2, getBitsPerComponent()) - 1;
COSStream cosStream = (COSStream) dict;
try (ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.createInputStream())) {
Point2D[] implicitEdge = new Point2D[4];
float[][] implicitCornerColor = new float[2][colRange.length];
byte flag = 0;
try {
flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
} catch (EOFException ex) {
LOG.error(ex);
return list;
}
boolean eof = false;
while (!eof) {
try {
boolean isFree = (flag == 0);
Patch current = readPatch(mciis, isFree, implicitEdge, implicitCornerColor, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange, matrix, xform, controlPoints);
if (current == null) {
break;
}
list.add(current);
flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
switch(flag) {
case 0:
break;
case 1:
implicitEdge = current.getFlag1Edge();
implicitCornerColor = current.getFlag1Color();
break;
case 2:
implicitEdge = current.getFlag2Edge();
implicitCornerColor = current.getFlag2Color();
break;
case 3:
implicitEdge = current.getFlag3Edge();
implicitCornerColor = current.getFlag3Color();
break;
default:
LOG.warn("bad flag: " + flag);
break;
}
} catch (EOFException ex) {
eof = true;
}
}
}
return list;
}
Aggregations