mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 03:55:28 -04:00
#304 TIFF JPEG Lossless support
This commit is contained in:
parent
2e90e4b897
commit
3b76d9fcfd
@ -148,7 +148,7 @@ class JPEGImage10Metadata extends AbstractMetadata {
|
||||
if (segment instanceof Frame) {
|
||||
Frame sofSegment = (Frame) segment;
|
||||
IIOMetadataNode colorSpaceType = new IIOMetadataNode("ColorSpaceType");
|
||||
colorSpaceType.setAttribute("name", sofSegment.componentsInFrame() == 1 ? "Gray" : "RGB"); // TODO YCC, YCCK, CMYK etc
|
||||
colorSpaceType.setAttribute("name", sofSegment.componentsInFrame() == 1 ? "GRAY" : "RGB"); // TODO YCC, YCCK, CMYK etc
|
||||
chroma.appendChild(colorSpaceType);
|
||||
|
||||
IIOMetadataNode numChannels = new IIOMetadataNode("NumChannels");
|
||||
|
@ -352,10 +352,24 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
JPEGColorSpace sourceCSType = getSourceCSType(getJFIF(), adobeDCT, sof);
|
||||
|
||||
if (sof.marker == JPEG.SOF3) {
|
||||
// Read image as lossless
|
||||
if (DEBUG) {
|
||||
System.out.println("Reading using Lossless decoder");
|
||||
}
|
||||
|
||||
// TODO: What about stream position?
|
||||
// TODO: Param handling: Source region, offset, subsampling, destination, destination type, etc....
|
||||
// Read image as lossless
|
||||
return new JPEGLosslessDecoderWrapper(this).readImage(segments, imageInput);
|
||||
BufferedImage bufferedImage = new JPEGLosslessDecoderWrapper(this).readImage(segments, imageInput);
|
||||
|
||||
// TODO: This is QnD, move param handling to lossless wrapper
|
||||
// TODO: Create test!
|
||||
BufferedImage destination = param != null ? param.getDestination() : null;
|
||||
if (destination != null) {
|
||||
destination.getRaster().setDataElements(0, 0, bufferedImage.getRaster());
|
||||
return destination;
|
||||
}
|
||||
|
||||
return bufferedImage;
|
||||
}
|
||||
|
||||
// We need to apply ICC profile unless the profile is sRGB/default gray (whatever that is)
|
||||
@ -382,6 +396,18 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
return delegate.read(imageIndex, param);
|
||||
}
|
||||
|
||||
static void drawOnto(final BufferedImage pDestination, final Image pSource) {
|
||||
Graphics2D g = pDestination.createGraphics();
|
||||
try {
|
||||
g.setComposite(AlphaComposite.Src);
|
||||
g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
|
||||
g.drawImage(pSource, 0, 0, null);
|
||||
}
|
||||
finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage readImageAsRasterAndReplaceColorProfile(int imageIndex, ImageReadParam param, Frame startOfFrame, JPEGColorSpace csType, ICC_Profile profile) throws IOException {
|
||||
int origWidth = getWidth(imageIndex);
|
||||
int origHeight = getHeight(imageIndex);
|
||||
|
@ -33,10 +33,9 @@ import com.twelvemonkeys.imageio.stream.BufferedImageInputStream;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.DataBufferUShort;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.*;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@ -71,7 +70,7 @@ final class JPEGLosslessDecoderWrapper {
|
||||
* - 16Bit, Grayscale -> BufferedImage.TYPE_USHORT_GRAY
|
||||
*
|
||||
* @param segments segments
|
||||
* @param input input stream which contains a jpeg lossless data
|
||||
* @param input input stream which contains JPEG Lossless data
|
||||
* @return if successfully a BufferedImage is returned
|
||||
* @throws IOException is thrown if the decoder failed or a conversion is not supported
|
||||
*/
|
||||
@ -92,8 +91,11 @@ final class JPEGLosslessDecoderWrapper {
|
||||
switch (decoder.getPrecision()) {
|
||||
case 8:
|
||||
return to8Bit1ComponentGrayScale(decoded, width, height);
|
||||
case 10:
|
||||
case 12:
|
||||
case 14:
|
||||
case 16:
|
||||
return to16Bit1ComponentGrayScale(decoded, width, height);
|
||||
return to16Bit1ComponentGrayScale(decoded, decoder.getPrecision(), width, height);
|
||||
}
|
||||
}
|
||||
// 3 components, assumed to be RGB
|
||||
@ -121,12 +123,20 @@ final class JPEGLosslessDecoderWrapper {
|
||||
* precision: 16 bit, componentCount = 1
|
||||
*
|
||||
* @param decoded data buffer
|
||||
* @param precision
|
||||
* @param width of the image
|
||||
* @param height of the image
|
||||
* @return a BufferedImage.TYPE_USHORT_GRAY
|
||||
* @param height of the image @return a BufferedImage.TYPE_USHORT_GRAY
|
||||
*/
|
||||
private BufferedImage to16Bit1ComponentGrayScale(int[][] decoded, int width, int height) {
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY);
|
||||
private BufferedImage to16Bit1ComponentGrayScale(int[][] decoded, int precision, int width, int height) {
|
||||
BufferedImage image;
|
||||
if (precision == 16) {
|
||||
image = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY);
|
||||
}
|
||||
else {
|
||||
ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] {precision}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_USHORT);
|
||||
image = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(width, height), colorModel.isAlphaPremultiplied(), null);
|
||||
}
|
||||
|
||||
short[] imageBuffer = ((DataBufferUShort) image.getRaster().getDataBuffer()).getData();
|
||||
|
||||
for (int i = 0; i < imageBuffer.length; i++) {
|
||||
|
@ -21,6 +21,11 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-metadata</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-jpeg</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
|
@ -38,6 +38,7 @@ import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.iptc.IPTCReader;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
|
||||
import com.twelvemonkeys.imageio.metadata.psd.PSD;
|
||||
import com.twelvemonkeys.imageio.metadata.psd.PSDReader;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.Rational;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
|
||||
@ -51,6 +52,7 @@ import com.twelvemonkeys.io.FastByteArrayOutputStream;
|
||||
import com.twelvemonkeys.io.LittleEndianDataInputStream;
|
||||
import com.twelvemonkeys.io.enc.DecoderStream;
|
||||
import com.twelvemonkeys.io.enc.PackBitsDecoder;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.imageio.*;
|
||||
@ -239,9 +241,97 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
|
||||
if (Arrays.equals(foo.getBytes(StandardCharsets.US_ASCII), Arrays.copyOf(value, foo.length()))) {
|
||||
System.err.println("foo: " + foo);
|
||||
// int offset = foo.length() + 1;
|
||||
// ImageInputStream input = new ByteArrayImageInputStream(value, offset, value.length - offset);
|
||||
int offset = foo.length() + 1;
|
||||
ImageInputStream input = new ByteArrayImageInputStream(value, offset, value.length - offset);
|
||||
// input.setByteOrder(ByteOrder.LITTLE_ENDIAN); // TODO: WHY???!
|
||||
|
||||
while (input.getStreamPosition() < value.length - offset) {
|
||||
int resourceId = input.readInt();
|
||||
if (resourceId != PSD.RESOURCE_TYPE) {
|
||||
System.err.println("Not a PSD resource: " + resourceId);
|
||||
break;
|
||||
}
|
||||
|
||||
int resourceKey = input.readInt();
|
||||
System.err.println("resourceKey: " + intToStr(resourceKey));
|
||||
long resourceLength = input.readUnsignedInt();
|
||||
System.err.println("resourceLength: " + resourceLength);
|
||||
|
||||
long pad = (4 - (resourceLength % 4)) % 4;
|
||||
long resourceLengthPadded = resourceLength + pad; // Padded to 32 bit boundary, possibly 64 bit for 8B64 resources
|
||||
long streamPosition = input.getStreamPosition();
|
||||
|
||||
if (resourceKey == ('L' << 24 | 'a' << 16 | 'y' << 8 | 'r')) {
|
||||
short count = input.readShort();
|
||||
System.err.println("layer count: " + count);
|
||||
|
||||
for (int layer = 0; layer < count; layer++) {
|
||||
int top = input.readInt();
|
||||
int left = input.readInt();
|
||||
int bottom = input.readInt();
|
||||
int right = input.readInt();
|
||||
System.err.printf("%d, %d, %d, %d\n", top, left, bottom, right);
|
||||
|
||||
short channels = input.readShort();
|
||||
System.err.println("channels: " + channels);
|
||||
|
||||
for (int channel = 0; channel < channels; channel++) {
|
||||
short channelId = input.readShort();
|
||||
System.err.println("channelId: " + channelId);
|
||||
long channelLength = input.readUnsignedInt();
|
||||
System.err.println("channelLength: " + channelLength);
|
||||
}
|
||||
|
||||
System.err.println("8BIM: " + intToStr(input.readInt()));
|
||||
int blendMode = input.readInt();
|
||||
System.err.println("blend mode key: " + intToStr(blendMode));
|
||||
|
||||
int opacity = input.readUnsignedByte();
|
||||
System.err.println("opacity: " + opacity);
|
||||
int clipping = input.readUnsignedByte();
|
||||
System.err.println("clipping: " + clipping);
|
||||
byte flags = input.readByte();
|
||||
System.err.printf("flags: 0x%02x\n", flags);
|
||||
input.readByte(); // Pad
|
||||
|
||||
long layerExtraDataLength = input.readUnsignedInt();
|
||||
long pos = input.getStreamPosition();
|
||||
System.err.println("length: " + layerExtraDataLength);
|
||||
|
||||
long layerMaskSize = input.readUnsignedInt();
|
||||
input.skipBytes(layerMaskSize);
|
||||
long layerBlendingRangesSize = input.readUnsignedInt();
|
||||
input.skipBytes(layerBlendingRangesSize);
|
||||
|
||||
String layerName = readPascalString(input);
|
||||
System.err.println("layerName: " + layerName);
|
||||
int mod = (layerName.length() + 1) % 4; // len + 1 for null-term
|
||||
System.err.println("mod: " + mod);
|
||||
if (mod != 0) {
|
||||
input.skipBytes(4 - mod);
|
||||
}
|
||||
System.err.println("input.getStreamPosition(): " + input.getStreamPosition());
|
||||
|
||||
// TODO: More data here
|
||||
System.err.println(TIFFReader.HexDump.dump(0, value, (int) (offset + input.getStreamPosition()), 64));;
|
||||
|
||||
input.seek(pos + layerExtraDataLength);
|
||||
}
|
||||
|
||||
|
||||
// long len = input.readUnsignedInt();
|
||||
// System.err.println("len: " + len);
|
||||
//
|
||||
// int count = input.readUnsignedShort();
|
||||
// System.err.println("count: " + count);
|
||||
|
||||
System.err.println(TIFFReader.HexDump.dump(0, value, (int) (offset + input.getStreamPosition()), 64));;
|
||||
|
||||
}
|
||||
input.seek(streamPosition + resourceLengthPadded);
|
||||
System.out.println("input.getStreamPosition(): " + input.getStreamPosition());
|
||||
}
|
||||
|
||||
// Directory psd2 = new PSDReader().read(input);
|
||||
// System.err.println("-----------------------------------------------------------------------------");
|
||||
// System.err.println("psd2: " + psd2);
|
||||
@ -251,6 +341,30 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
}
|
||||
}
|
||||
|
||||
static String readPascalString(final DataInput pInput) throws IOException {
|
||||
int length = pInput.readUnsignedByte();
|
||||
|
||||
if (length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[length];
|
||||
pInput.readFully(bytes);
|
||||
|
||||
return StringUtil.decode(bytes, 0, bytes.length, "ASCII");
|
||||
}
|
||||
|
||||
static String intToStr(int value) {
|
||||
return new String(
|
||||
new byte[]{
|
||||
(byte) ((value & 0xff000000) >>> 24),
|
||||
(byte) ((value & 0x00ff0000) >> 16),
|
||||
(byte) ((value & 0x0000ff00) >> 8),
|
||||
(byte) ((value & 0x000000ff))
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void readIFD(final int imageIndex) throws IOException {
|
||||
readMetadata();
|
||||
checkBounds(imageIndex);
|
||||
@ -1048,7 +1162,18 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
// Otherwise, it's likely CMYK or some other interpretation we don't need to convert.
|
||||
// We'll have to use readAsRaster and later apply color space conversion ourselves
|
||||
Raster raster = jpegReader.readRaster(0, jpegParam);
|
||||
normalizeColor(interpretation, ((DataBufferByte) raster.getDataBuffer()).getData());
|
||||
// TODO: Refactor + duplicate this for all JPEG-in-TIFF cases
|
||||
switch (raster.getTransferType()) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
normalizeColor(interpretation, ((DataBufferByte) raster.getDataBuffer()).getData());
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
normalizeColor(interpretation, ((DataBufferUShort) raster.getDataBuffer()).getData());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported transfer type: " + raster.getTransferType());
|
||||
}
|
||||
|
||||
destination.getRaster().setDataElements(offset.x, offset.y, raster);
|
||||
}
|
||||
}
|
||||
@ -1081,9 +1206,8 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
int mode = getValueAsIntWithDefault(TIFF.TAG_OLD_JPEG_PROC, TIFFExtension.JPEG_PROC_BASELINE);
|
||||
switch (mode) {
|
||||
case TIFFExtension.JPEG_PROC_BASELINE:
|
||||
break; // Supported
|
||||
case TIFFExtension.JPEG_PROC_LOSSLESS:
|
||||
throw new IIOException("Unsupported TIFF JPEGProcessingMode: Lossless (14)");
|
||||
break; // Supported
|
||||
default:
|
||||
throw new IIOException("Unknown TIFF JPEGProcessingMode value: " + mode);
|
||||
}
|
||||
@ -1350,7 +1474,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
return jpegReader.getImageMetadata(0);
|
||||
}
|
||||
catch (IIOException e) {
|
||||
processWarningOccurred("Could not read metadata metadata JPEG compressed TIFF: " + e.getMessage() + " colors may look incorrect");
|
||||
processWarningOccurred("Could not read metadata for JPEG compressed TIFF (" + e.getMessage() + "): Colors may look incorrect");
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -1391,20 +1515,8 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
private ImageReader createJPEGDelegate() throws IOException {
|
||||
// TIFF is strictly ISO JPEG, so we should probably stick to the standard reader
|
||||
ImageReaderSpi jpegProvider = lookupProviderByName(IIORegistry.getDefaultInstance(), "com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi");
|
||||
|
||||
if (jpegProvider != null) {
|
||||
return jpegProvider.createReaderInstance();
|
||||
}
|
||||
|
||||
// Fall back to default reader below
|
||||
if (DEBUG) {
|
||||
System.err.println("Could not create " + "com.sun.imageio.plugins.jpeg.JPEGImageReader"
|
||||
+ ", falling back to default JPEG capable ImageReader");
|
||||
}
|
||||
|
||||
// If we can't get the standard reader, fall back to the default (first) reader
|
||||
// We'll just use the default (first) reader
|
||||
// If it's the TwelveMonkeys one, we will be able to read JPEG Lossless etc.
|
||||
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JPEG");
|
||||
if (!readers.hasNext()) {
|
||||
throw new IIOException("Could not instantiate JPEGImageReader");
|
||||
@ -1415,28 +1527,17 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
|
||||
private static InputStream createJFIFStream(int bands, int stripTileWidth, int stripTileHeight, byte[][] qTables, byte[][] dcTables, byte[][] acTables) throws IOException {
|
||||
FastByteArrayOutputStream stream = new FastByteArrayOutputStream(
|
||||
2 + 2 + 2 + 6 + 3 * bands +
|
||||
2 +
|
||||
5 * qTables.length + qTables.length * qTables[0].length +
|
||||
5 * dcTables.length + dcTables.length * dcTables[0].length +
|
||||
5 * acTables.length + acTables.length * acTables[0].length +
|
||||
2 + 2 + 6 + 3 * bands +
|
||||
8 + 2 * bands
|
||||
);
|
||||
|
||||
DataOutputStream out = new DataOutputStream(stream);
|
||||
|
||||
out.writeShort(JPEG.SOI);
|
||||
out.writeShort(JPEG.SOF0);
|
||||
out.writeShort(2 + 6 + 3 * bands); // SOF0 len
|
||||
out.writeByte(8); // bits TODO: Consult raster/transfer type or BitsPerSample for 12/16 bits support
|
||||
out.writeShort(stripTileHeight); // height
|
||||
out.writeShort(stripTileWidth); // width
|
||||
out.writeByte(bands); // Number of components
|
||||
|
||||
for (int comp = 0; comp < bands; comp++) {
|
||||
out.writeByte(comp); // Component id
|
||||
out.writeByte(comp == 0 ? 0x22 : 0x11); // h/v subsampling TODO: FixMe, consult YCbCrSubsampling
|
||||
out.writeByte(comp); // Q table selector TODO: Consider merging if tables are equal
|
||||
}
|
||||
|
||||
// TODO: Consider merging if tables are equal
|
||||
for (int tableIndex = 0; tableIndex < qTables.length; tableIndex++) {
|
||||
@ -1465,6 +1566,19 @@ public final class TIFFImageReader extends ImageReaderBase {
|
||||
out.write(table); // Table data
|
||||
}
|
||||
|
||||
out.writeShort(JPEG.SOF0);
|
||||
out.writeShort(2 + 6 + 3 * bands); // SOF0 len
|
||||
out.writeByte(8); // bits TODO: Consult raster/transfer type or BitsPerSample for 12/16 bits support
|
||||
out.writeShort(stripTileHeight); // height
|
||||
out.writeShort(stripTileWidth); // width
|
||||
out.writeByte(bands); // Number of components
|
||||
|
||||
for (int comp = 0; comp < bands; comp++) {
|
||||
out.writeByte(comp); // Component id
|
||||
out.writeByte(comp == 0 ? 0x22 : 0x11); // h/v subsampling TODO: FixMe, consult YCbCrSubsampling
|
||||
out.writeByte(comp); // Q table selector TODO: Consider merging if tables are equal
|
||||
}
|
||||
|
||||
out.writeShort(JPEG.SOS);
|
||||
out.writeShort(6 + 2 * bands); // SOS length
|
||||
out.writeByte(bands); // Num comp
|
||||
|
@ -149,11 +149,15 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
|
||||
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-contig-16.tif"), new Dimension(73, 43)), // CMYK 16 bit/sample
|
||||
// Separated (CMYK) Planar (PlanarConfiguration: 2)
|
||||
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-planar-08.tif"), new Dimension(73, 43)), // CMYK 8 bit/sample
|
||||
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-planar-16.tif"), new Dimension(73, 43)) // CMYK 16 bit/sample
|
||||
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-planar-16.tif"), new Dimension(73, 43)), // CMYK 16 bit/sample
|
||||
new TestData(getClassLoaderResource("/tiff/jpeg-lossless-8bit-gray.tif"), new Dimension(512, 512)), // Lossless JPEG Gray, 8 bit/sample
|
||||
new TestData(getClassLoaderResource("/tiff/jpeg-lossless-12bit-gray.tif"), new Dimension(512, 512)), // Lossless JPEG Gray, 12 bit/sample
|
||||
new TestData(getClassLoaderResource("/tiff/jpeg-lossless-16bit-gray.tif"), new Dimension(512, 512)), // Lossless JPEG Gray, 16 bit/sample
|
||||
new TestData(getClassLoaderResource("/tiff/jpeg-lossless-24bit-rgb"), new Dimension(512, 512)) // Lossless JPEG RGB, 8 bit/sample
|
||||
);
|
||||
}
|
||||
|
||||
protected List<TestData> getUnsupportedTestData() {
|
||||
private List<TestData> getUnsupportedTestData() {
|
||||
return Arrays.asList(
|
||||
// RGB Interleaved (PlanarConfiguration: 1)
|
||||
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-02.tif"), new Dimension(73, 43)), // RGB 2 bit/sample
|
||||
@ -265,7 +269,7 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
|
||||
|
||||
assertNotNull(image);
|
||||
assertEquals(testData.getDimension(0), new Dimension(image.getWidth(), image.getHeight()));
|
||||
verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("metadata"));
|
||||
verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("JPEG"));
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
imageio/imageio-tiff/src/test/resources/tiff/jpeg-lossless-12bit-gray.tif
Executable file
BIN
imageio/imageio-tiff/src/test/resources/tiff/jpeg-lossless-12bit-gray.tif
Executable file
Binary file not shown.
BIN
imageio/imageio-tiff/src/test/resources/tiff/jpeg-lossless-16bit-gray.tif
Executable file
BIN
imageio/imageio-tiff/src/test/resources/tiff/jpeg-lossless-16bit-gray.tif
Executable file
Binary file not shown.
BIN
imageio/imageio-tiff/src/test/resources/tiff/jpeg-lossless-24bit-rgb
Executable file
BIN
imageio/imageio-tiff/src/test/resources/tiff/jpeg-lossless-24bit-rgb
Executable file
Binary file not shown.
BIN
imageio/imageio-tiff/src/test/resources/tiff/jpeg-lossless-8bit-gray.tif
Executable file
BIN
imageio/imageio-tiff/src/test/resources/tiff/jpeg-lossless-8bit-gray.tif
Executable file
Binary file not shown.
@ -135,6 +135,12 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>imageio-jpeg</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
|
Loading…
x
Reference in New Issue
Block a user