TMI-TIFF: Initial commit. Major work in progress. :-)

This commit is contained in:
Harald Kuhr
2012-05-22 00:00:11 +02:00
parent 9492ed67f1
commit 98361194ea
36 changed files with 2070 additions and 678 deletions

View File

@@ -1,189 +0,0 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.image.ImageUtil;
import com.twelvemonkeys.imageio.ImageReaderBase;
import org.apache.batik.ext.awt.image.codec.SeekableStream;
import org.apache.batik.ext.awt.image.codec.tiff.TIFFDecodeParam;
import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageDecoder;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.spi.ImageReaderSpi;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* TIFFImageReader class description.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haku $
* @version $Id: TIFFImageReader.java,v 1.0 29.jul.2004 12:52:33 haku Exp $
*/
// TODO: Massive clean-up
// TODO: Support raster decoding...
public class TIFFImageReader extends ImageReaderBase {
private TIFFImageDecoder decoder = null;
private List<RenderedImage> images = new ArrayList<RenderedImage>();
protected TIFFImageReader(final ImageReaderSpi pOriginatingProvider) {
super(pOriginatingProvider);
}
protected void resetMembers() {
decoder = null;
}
public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
// Decode image, convert and return as BufferedImage
RenderedImage image = readAsRenderedImage(pIndex, pParam);
return ImageUtil.toBuffered(image);
}
public RenderedImage readAsRenderedImage(int pIndex, ImageReadParam pParam) throws IOException {
init(pIndex);
processImageStarted(pIndex);
if (pParam == null) {
// Cache image for use by getWidth and getHeight methods
RenderedImage image;
if (images.size() > pIndex && images.get(pIndex) != null) {
image = images.get(pIndex);
}
else {
// Decode
image = decoder.decodeAsRenderedImage(pIndex);
// Make room
for (int i = images.size(); i < pIndex; i++) {
images.add(pIndex, null);
}
images.add(pIndex, image);
}
if (abortRequested()) {
processReadAborted();
return image;
}
processImageComplete();
return image;
}
else {
// TODO: Parameter conversion
decoder.setParam(new TIFFDecodeParam());
RenderedImage image = decoder.decodeAsRenderedImage(pIndex);
// Subsample and apply AOI
if (pParam.getSourceRegion() != null) {
image = fakeAOI(ImageUtil.toBuffered(image), pParam);
}
if (pParam.getSourceXSubsampling() > 1 || pParam.getSourceYSubsampling() > 1) {
image = ImageUtil.toBuffered(fakeSubsampling(ImageUtil.toBuffered(image), pParam));
}
processImageComplete();
return image;
}
}
private void init(int pIndex) throws IOException {
init();
checkBounds(pIndex);
}
protected void checkBounds(int index) throws IOException {
if (index < getMinIndex()){
throw new IndexOutOfBoundsException("index < minIndex");
}
else if (index >= getNumImages(true)) {
throw new IndexOutOfBoundsException("index > numImages");
}
}
private synchronized void init() {
if (decoder == null) {
if (imageInput == null) {
throw new IllegalStateException("input == null");
}
decoder = new TIFFImageDecoder(new SeekableStream() {
public int read() throws IOException {
return imageInput.read();
}
public int read(final byte[] pBytes, final int pStart, final int pLength) throws IOException {
return imageInput.read(pBytes, pStart, pLength);
}
public long getFilePointer() throws IOException {
return imageInput.getStreamPosition();
}
public void seek(final long pPos) throws IOException {
imageInput.seek(pPos);
}
}, null);
}
}
public int getWidth(int pIndex) throws IOException {
init(pIndex);
// TODO: Use cache...
return decoder.decodeAsRenderedImage(pIndex).getWidth();
}
public int getHeight(int pIndex) throws IOException {
init(pIndex);
// TODO: Use cache...
return decoder.decodeAsRenderedImage(pIndex).getHeight();
}
public Iterator<ImageTypeSpecifier> getImageTypes(final int imageIndex) throws IOException {
throw new UnsupportedOperationException("Method getImageTypes not implemented");// TODO: Implement
}
public int getNumImages(boolean allowSearch) throws IOException {
init();
if (allowSearch) {
return decoder.getNumPages();
}
return -1;
}
}

View File

@@ -1,125 +0,0 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.lang.SystemUtil;
import com.twelvemonkeys.imageio.util.IIOUtil;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ServiceRegistry;
import javax.imageio.stream.ImageInputStream;
import java.io.IOException;
import java.util.Locale;
/**
* TIFFImageReaderSpi
* <p/>
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: TIFFImageReaderSpi.java,v 1.1 2003/12/02 16:45:00 wmhakur Exp $
*/
public class TIFFImageReaderSpi extends ImageReaderSpi {
final static boolean TIFF_CLASSES_AVAILABLE = SystemUtil.isClassAvailable("com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReader");
/**
* Creates a {@code TIFFImageReaderSpi}.
*/
public TIFFImageReaderSpi() {
this(IIOUtil.getProviderInfo(TIFFImageReaderSpi.class));
}
private TIFFImageReaderSpi(final ProviderInfo pProviderInfo) {
super(
pProviderInfo.getVendorName(), // Vendor name
pProviderInfo.getVersion(), // Version
TIFF_CLASSES_AVAILABLE ? new String[]{"tiff", "TIFF"} : new String[] {""}, // Names
TIFF_CLASSES_AVAILABLE ? new String[]{"tiff", "tif"} : null, // Suffixes
TIFF_CLASSES_AVAILABLE ? new String[]{"image/tiff", "image/x-tiff"} : null, // Mime-types
"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReader", // Writer class name..?
ImageReaderSpi.STANDARD_INPUT_TYPE, // Output types
new String[]{"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriterSpi"}, // Writer SPI names
true, // Supports standard stream metadata format
null, // Native stream metadata format name
null, // Native stream metadata format class name
null, // Extra stream metadata format names
null, // Extra stream metadata format class names
true, // Supports standard image metadata format
null, // Native image metadata format name
null, // Native image metadata format class name
null, // Extra image metadata format names
null // Extra image metadata format class names
);
}
public boolean canDecodeInput(Object source) throws IOException {
return source instanceof ImageInputStream && TIFF_CLASSES_AVAILABLE && canDecode((ImageInputStream) source);
}
static boolean canDecode(ImageInputStream pInput) throws IOException {
try {
pInput.mark();
int byte0 = pInput.read(); // Byte order 1 (M or I)
int byte1 = pInput.read(); // Byte order 2 (always same as 1)
int byte2 = pInput.read(); // Version number 1 (M: 0, I: 42)
int byte3 = pInput.read(); // Version number 2 (M: 42, I: 0)
// Test for Motorola or Intel byte order, and version number == 42
if ((byte0 == 'M' && byte1 == 'M' && byte2 == 0 && byte3 == 42)
|| (byte0 == 'I' && byte1 == 'I' && byte2 == 42 && byte3 == 0)) {
return true;
}
}
finally {
pInput.reset();
}
return false;
}
public ImageReader createReaderInstance(Object extension) throws IOException {
return new TIFFImageReader(this);
}
public String getDescription(Locale locale) {
return "Tagged Image File Format (TIFF) image reader";
}
@SuppressWarnings({"deprecation"})
@Override
public void onRegistration(ServiceRegistry registry, Class<?> category) {
if (!TIFF_CLASSES_AVAILABLE) {
IIOUtil.deregisterProvider(registry, this, category);
}
}
}

View File

@@ -1,145 +0,0 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.image.ImageUtil;
import com.twelvemonkeys.imageio.ImageWriterBase;
import com.twelvemonkeys.imageio.util.IIOUtil;
import org.apache.batik.ext.awt.image.codec.ImageEncodeParam;
import org.apache.batik.ext.awt.image.codec.tiff.TIFFEncodeParam;
import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageEncoder;
import javax.imageio.IIOImage;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.spi.ImageWriterSpi;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.IOException;
/**
* TIFFImageWriter class description.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haku $
* @version $Id: TIFFImageWriter.java,v 1.0 29.jul.2004 12:52:54 haku Exp $
*/
public class TIFFImageWriter extends ImageWriterBase {
private TIFFImageEncoder encoder;
protected TIFFImageWriter(final ImageWriterSpi pProvider) {
super(pProvider);
}
@Override
public void setOutput(final Object output) {
encoder = null;
super.setOutput(output);
}
public IIOMetadata getDefaultImageMetadata(final ImageTypeSpecifier imageType, final ImageWriteParam param) {
throw new UnsupportedOperationException("Method getDefaultImageMetadata not implemented");// TODO: Implement
}
public IIOMetadata convertImageMetadata(final IIOMetadata inData, final ImageTypeSpecifier imageType, final ImageWriteParam param) {
throw new UnsupportedOperationException("Method convertImageMetadata not implemented");// TODO: Implement
}
public void write(final IIOMetadata pStreamMetadata, final IIOImage pImage, final ImageWriteParam pParam) throws IOException {
RenderedImage renderedImage = pImage.getRenderedImage();
init();
ImageEncodeParam param;
if (pParam != null) {
param = new TIFFEncodeParam();
// TODO: Convert params
encoder.setParam(param);
}
BufferedImage image;
// FIX: TIFFEnocder chokes on a any of the TYPE_INT_* types...
// (The TIFFEncoder expects int types to have 1 sample of size 32
// while there actually is 4 samples of size 8, according to the
// SampleModel...)
if (renderedImage instanceof BufferedImage && (
((BufferedImage) renderedImage).getType() == BufferedImage.TYPE_INT_ARGB
|| ((BufferedImage) renderedImage).getType() == BufferedImage.TYPE_INT_ARGB_PRE)) {
image = ImageUtil.toBuffered(renderedImage, BufferedImage.TYPE_4BYTE_ABGR);
}
else if (renderedImage instanceof BufferedImage && (
((BufferedImage) renderedImage).getType() == BufferedImage.TYPE_INT_BGR
|| ((BufferedImage) renderedImage).getType() == BufferedImage.TYPE_INT_RGB)) {
image = ImageUtil.toBuffered(renderedImage, BufferedImage.TYPE_3BYTE_BGR);
}
else {
image = ImageUtil.toBuffered(renderedImage);
}
image = fakeAOI(image, pParam);
image = ImageUtil.toBuffered(fakeSubsampling(image, pParam));
/*
System.out.println("Image: " + pImage);
SampleModel sampleModel = pImage.getSampleModel();
System.out.println("SampleModel: " + sampleModel);
int sampleSize[] = sampleModel.getSampleSize();
System.out.println("Samples: " + sampleSize.length);
for (int i = 0; i < sampleSize.length; i++) {
System.out.println("SampleSize[" + i + "]: " + sampleSize[i]);
}
int dataType = sampleModel.getDataType();
System.out.println("DataType: " + dataType);
*/
processImageStarted(0);
encoder.encode(image);
imageOutput.flush();
processImageComplete();
}
public void dispose() {
super.dispose();
encoder = null;
}
private synchronized void init() {
if (encoder == null) {
if (imageOutput == null) {
throw new IllegalStateException("output == null");
}
encoder = new TIFFImageEncoder(IIOUtil.createStreamAdapter(imageOutput), null);
}
}
}

View File

@@ -1,107 +0,0 @@
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.imageio.spi.ProviderInfo;
import com.twelvemonkeys.imageio.util.IIOUtil;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.spi.ServiceRegistry;
import java.io.IOException;
import java.util.Locale;
/**
* TIFFmageWriterSpi
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: TIFFImageWriterSpi.java,v 1.2 2004/01/14 15:21:44 wmhakur Exp $
*/
public class TIFFImageWriterSpi extends ImageWriterSpi {
/**
* Creates a {@code TIFFImageWriterSpi}.
*/
public TIFFImageWriterSpi() {
this(IIOUtil.getProviderInfo(TIFFImageWriterSpi.class));
}
private TIFFImageWriterSpi(final ProviderInfo pProviderInfo) {
super(
pProviderInfo.getVendorName(), // Vendor name
pProviderInfo.getVersion(), // Version
new String[]{"tiff", "TIFF"}, // Names
new String[]{"tif", "tiff"}, // Suffixes
new String[]{"image/tiff", "image/x-tiff"}, // Mime-types
"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriter", // Writer class name..?
STANDARD_OUTPUT_TYPE, // Output types
new String[]{"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi"}, // Reader SPI names
true, // Supports standard stream metadata format
null, // Native stream metadata format name
null, // Native stream metadata format class name
null, // Extra stream metadata format names
null, // Extra stream metadata format class names
true, // Supports standard image metadata format
null, // Native image metadata format name
null, // Native image metadata format class name
null, // Extra image metadata format names
null // Extra image metadata format class names
);
}
public boolean canEncodeImage(ImageTypeSpecifier type) {
return true;
}
public ImageWriter createWriterInstance(Object extension) throws IOException {
try {
return new TIFFImageWriter(this);
}
catch (Throwable t) {
// Wrap in IOException if the writer can't be instantiated.
// This makes the IIORegistry deregister this service provider
IOException exception = new IOException(t.getMessage());
exception.initCause(t);
throw exception;
}
}
public String getDescription(Locale locale) {
return "Tagged Image File Format (TIFF) image writer";
}
@SuppressWarnings({"deprecation"})
@Override
public void onRegistration(ServiceRegistry registry, Class<?> category) {
if (!TIFFImageReaderSpi.TIFF_CLASSES_AVAILABLE) {
IIOUtil.deregisterProvider(registry, this, category);
}
}
}

View File

@@ -1,3 +1,2 @@
com.twelvemonkeys.imageio.plugins.svg.SVGImageReaderSpi
com.twelvemonkeys.imageio.plugins.wmf.WMFImageReaderSpi
#com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi

View File

@@ -1 +0,0 @@
#com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriterSpi