Merge remote-tracking branch 'origin/master'

This commit is contained in:
Harald Kuhr
2018-09-07 21:07:23 +02:00
12 changed files with 372 additions and 129 deletions

View File

@@ -130,7 +130,7 @@ public abstract class AbstractMetadata extends IIOMetadata implements Cloneable
}
throw new IllegalArgumentException(
String.format("Bad format name: \"%s\". Expected one of %s", formatName, Arrays.toString(metadataFormatNames))
String.format("Unsupported format name: \"%s\". Expected one of %s", formatName, Arrays.toString(metadataFormatNames))
);
}

View File

@@ -101,8 +101,16 @@ public final class ColorSpaces {
private static final Map<Key, ICC_ColorSpace> cache = new LRUHashMap<>(10);
static {
// Force invocation of ProfileDeferralMgr.activateProfiles() to avoid JDK-6986863
ICC_Profile.getInstance(ColorSpace.CS_sRGB).getData();
try {
// Force invocation of ProfileDeferralMgr.activateProfiles() to avoid JDK-6986863
ICC_Profile.getInstance(ColorSpace.CS_sRGB).getData();
}
catch (Throwable disasters) {
System.err.println("ICC Color Profile not properly activated due to the exception below.");
System.err.println("Expect to see JDK-6986863 in action, and consider filing a bug report to your JRE provider.");
disasters.printStackTrace();
}
}
private ColorSpaces() {}

View File

@@ -68,10 +68,7 @@ final class JPEGLosslessDecoder {
private int xLoc;
private int yLoc;
private int mask;
private int[] outputData;
private int[] outputRedData;
private int[] outputGreenData;
private int[] outputBlueData;
private int[][] outputData;
private static final int IDCT_P[] = {
0, 5, 40, 16, 45, 2, 7, 42,
@@ -148,8 +145,6 @@ final class JPEGLosslessDecoder {
int[][] decode() throws IOException {
int current, scanNum = 0;
final int pred[] = new int[10];
int[][] outputRef;
xLoc = 0;
yLoc = 0;
@@ -218,32 +213,27 @@ final class JPEGLosslessDecoder {
xDim = frame.samplesPerLine;
yDim = frame.lines;
outputRef = new int[numComp][];
outputData = new int[numComp][];
// TODO: Support 4 components (RGBA/YCCA/CMYK/YCCK), others?
if (numComp == 1) {
outputData = new int[xDim * yDim];
outputRef[0] = outputData;
for (int componentIndex = 0; componentIndex < numComp; ++componentIndex) {
// not a good use of memory, but I had trouble packing bytes into int. some values exceeded 255.
outputData[componentIndex] = new int[xDim * yDim];
}
else {
outputRedData = new int[xDim * yDim]; // not a good use of memory, but I had trouble packing bytes into int. some values exceeded 255.
outputGreenData = new int[xDim * yDim];
outputBlueData = new int[xDim * yDim];
outputRef[0] = outputRedData;
outputRef[1] = outputGreenData;
outputRef[2] = outputBlueData;
final int firstValue[] = new int[numComp];
for (int i = 0; i < numComp; i++) {
firstValue[i] = (1 << (precision - 1));
}
final int pred[] = new int[numComp];
scanNum++;
while (true) { // Decode one scan
int temp[] = new int[1]; // to store remainder bits
int index[] = new int[1];
for (int i = 0; i < 10; i++) {
pred[i] = (1 << (precision - 1));
}
System.arraycopy(firstValue, 0, pred, 0, numComp);
if (restartInterval == 0) {
current = decode(pred, temp, index);
@@ -285,9 +275,10 @@ final class JPEGLosslessDecoder {
readNumber();
current = input.readUnsignedShort();
}
// TODO oe: 05.05.2018 Is it correct loop? Content of outputData from previous iteration is always lost.
} while ((current != JPEG.EOI) && ((xLoc < xDim) && (yLoc < yDim)) && (scanNum == 0));
return outputRef;
return outputData;
}
private void processWarningOccured(String warning) {
@@ -341,7 +332,7 @@ final class JPEGLosslessDecoder {
return decodeRGB(prev, temp, index);
}
else {
return -1;
return decodeAny(prev, temp, index);
}
}
@@ -353,6 +344,7 @@ final class JPEGLosslessDecoder {
prev[0] = (1 << (frame.samplePrecision - 1));
}
else {
final int[] outputData = this.outputData[0];
switch (selection) {
case 2:
prev[0] = getPreviousY(outputData);
@@ -399,6 +391,9 @@ final class JPEGLosslessDecoder {
}
private int decodeRGB(final int prev[], final int temp[], final int index[]) throws IOException {
final int[] outputRedData = outputData[0];
final int[] outputGreenData = outputData[1];
final int[] outputBlueData = outputData[2];
switch (selection) {
case 2:
prev[0] = getPreviousY(outputRedData);
@@ -437,6 +432,43 @@ final class JPEGLosslessDecoder {
break;
}
return decode0(prev, temp, index);
}
private int decodeAny(final int prev[], final int temp[], final int index[]) throws IOException {
for (int componentIndex = 0; componentIndex < outputData.length; ++componentIndex) {
final int[] outputData = this.outputData[componentIndex];
final int previous;
switch (selection) {
case 2:
previous = getPreviousY(outputData);
break;
case 3:
previous = getPreviousXY(outputData);
break;
case 4:
previous = (getPreviousX(outputData) + getPreviousY(outputData)) - getPreviousXY(outputData);
break;
case 5:
previous = getPreviousX(outputData) + ((getPreviousY(outputData) - getPreviousXY(outputData)) >> 1);
break;
case 6:
previous = getPreviousY(outputData) + ((getPreviousX(outputData) - getPreviousXY(outputData)) >> 1);
break;
case 7:
previous = (int) (((long) getPreviousX(outputData) + getPreviousY(outputData)) / 2);
break;
default:
previous = getPreviousX(outputData);
break;
}
prev[componentIndex] = previous;
}
return decode0(prev, temp, index);
}
private int decode0(int[] prev, int[] temp, int[] index) throws IOException {
int value, actab[], dctab[];
int qtab[];
@@ -694,14 +726,17 @@ final class JPEGLosslessDecoder {
if (numComp == 1) {
outputSingle(pred);
}
else {
else if (numComp == 3) {
outputRGB(pred);
}
else {
outputAny(pred);
}
}
private void outputSingle(final int pred[]) {
if ((xLoc < xDim) && (yLoc < yDim)) {
outputData[(yLoc * xDim) + xLoc] = mask & pred[0];
outputData[0][(yLoc * xDim) + xLoc] = mask & pred[0];
xLoc++;
if (xLoc >= xDim) {
@@ -713,9 +748,25 @@ final class JPEGLosslessDecoder {
private void outputRGB(final int pred[]) {
if ((xLoc < xDim) && (yLoc < yDim)) {
outputRedData[(yLoc * xDim) + xLoc] = pred[0];
outputGreenData[(yLoc * xDim) + xLoc] = pred[1];
outputBlueData[(yLoc * xDim) + xLoc] = pred[2];
final int index = (yLoc * xDim) + xLoc;
outputData[0][index] = pred[0];
outputData[1][index] = pred[1];
outputData[2][index] = pred[2];
xLoc++;
if (xLoc >= xDim) {
yLoc++;
xLoc = 0;
}
}
}
private void outputAny(final int pred[]) {
if ((xLoc < xDim) && (yLoc < yDim)) {
final int index = (yLoc * xDim) + xLoc;
for (int componentIndex = 0; componentIndex < outputData.length; ++componentIndex) {
outputData[componentIndex][index] = pred[componentIndex];
}
xLoc++;
if (xLoc >= xDim) {

View File

@@ -39,9 +39,12 @@ import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import java.nio.ByteOrder;
import java.util.Arrays;
import static com.twelvemonkeys.lang.Validate.notNull;
import static java.lang.String.format;
import static java.nio.ByteOrder.BIG_ENDIAN;
import static java.util.Arrays.asList;
/**
* TIFFStreamMetadata.
@@ -113,7 +116,7 @@ public final class TIFFStreamMetadata extends IIOMetadata {
}
}
private ByteOrder getByteOrder(final String value) throws IIOInvalidTreeException {
private ByteOrder getByteOrder(final String value) {
switch (value) {
case "BIG_ENDIAN":
return ByteOrder.BIG_ENDIAN;
@@ -138,6 +141,11 @@ public final class TIFFStreamMetadata extends IIOMetadata {
}
else if (streamMetadata != null) {
TIFFStreamMetadata metadata = new TIFFStreamMetadata();
Validate.isTrue(asList(streamMetadata.getMetadataFormatNames()).contains(metadata.nativeMetadataFormatName),
format("Unsupported stream metadata format, expected %s: %s", metadata.nativeMetadataFormatName,
Arrays.toString(streamMetadata.getMetadataFormatNames())));
// Will throw exception if stream format differs from native
metadata.mergeTree(metadata.nativeMetadataFormatName, streamMetadata.getAsTree(metadata.nativeMetadataFormatName));
imageOutput.setByteOrder(metadata.byteOrder);

View File

@@ -40,6 +40,7 @@ import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import java.nio.ByteOrder;
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFMedataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME;
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFStreamMetadata.SUN_NATIVE_STREAM_METADATA_FORMAT_NAME;
import static java.nio.ByteOrder.BIG_ENDIAN;
import static java.nio.ByteOrder.LITTLE_ENDIAN;
@@ -85,9 +86,10 @@ public class TIFFStreamMetadataTest {
}
@Test
public void testConfigureStreamForegin() throws IIOInvalidTreeException {
public void testConfigureStreamForeign() throws IIOInvalidTreeException {
ImageOutputStream stream = mock(ImageOutputStream.class);
IIOMetadata metadata = mock(IIOMetadata.class);
when(metadata.getMetadataFormatNames()).thenReturn(new String[]{SUN_NATIVE_STREAM_METADATA_FORMAT_NAME, "com_foo_supertiff_9.42"});
when(metadata.getAsTree(eq(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME))).thenReturn(createForeignTree(LITTLE_ENDIAN));
TIFFStreamMetadata.configureStreamByteOrder(metadata, stream);
@@ -95,6 +97,24 @@ public class TIFFStreamMetadataTest {
verify(stream, only()).setByteOrder(LITTLE_ENDIAN);
}
@Test
public void testConfigureStreamImageMetadata() throws IIOInvalidTreeException {
ImageOutputStream stream = mock(ImageOutputStream.class);
IIOMetadata metadata = mock(IIOMetadata.class);
when(metadata.getMetadataFormatNames()).thenReturn(new String[]{SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME});
try {
TIFFStreamMetadata.configureStreamByteOrder(metadata, stream);
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
assertNotNull(expected.getMessage());
assertTrue(expected.getMessage().toLowerCase().contains("unsupported stream metadata format"));
assertTrue(expected.getMessage().contains("expected " + SUN_NATIVE_STREAM_METADATA_FORMAT_NAME));
assertTrue(expected.getMessage().contains(SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME));
}
}
private IIOMetadataNode createForeignTree(ByteOrder order) {
IIOMetadataNode root = new IIOMetadataNode(SUN_NATIVE_STREAM_METADATA_FORMAT_NAME);
IIOMetadataNode byteOrder = new IIOMetadataNode("ByteOrder");