diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
commit | edbf3b6af777b721cd2a1ef461947e51e88241e1 (patch) | |
tree | f09427b843b192cccf8c3b5328cb81dddf6489fa /awt/org/apache/harmony/x/imageio | |
parent | d5193d9394c5e58176d7bcdf50ef017f8a3b9e1e (diff) | |
download | frameworks_native-edbf3b6af777b721cd2a1ef461947e51e88241e1.zip frameworks_native-edbf3b6af777b721cd2a1ef461947e51e88241e1.tar.gz frameworks_native-edbf3b6af777b721cd2a1ef461947e51e88241e1.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'awt/org/apache/harmony/x/imageio')
22 files changed, 2274 insertions, 0 deletions
diff --git a/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java b/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java new file mode 100644 index 0000000..498e1bb --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java @@ -0,0 +1,124 @@ +/* + * 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. + */ + +/* + * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL. + * All changes made to this file manually will be overwritten + * if this tool runs again. Better make changes in the template file. + */ + +package org.apache.harmony.x.imageio.internal.nls; + +import org.apache.harmony.luni.util.MsgHelp; + +/** + * This class retrieves strings from a resource bundle and returns them, + * formatting them with MessageFormat when required. + * <p> + * It is used by the system classes to provide national language support, by + * looking up messages in the <code> + * org.apache.harmony.x.imageio.internal.nls.messages + * </code> + * resource bundle. Note that if this file is not available, or an invalid key + * is looked up, or resource bundle support is not available, the key itself + * will be returned as the associated message. This means that the <em>KEY</em> + * should a reasonable human-readable (english) string. + * + */ +public class Messages { + + private static final String sResource = + "org.apache.harmony.x.imageio.internal.nls.messages"; //$NON-NLS-1$ + + /** + * Retrieves a message which has no arguments. + * + * @param msg + * String the key to look up. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg) { + return MsgHelp.getString(sResource, msg); + } + + /** + * Retrieves a message which takes 1 argument. + * + * @param msg + * String the key to look up. + * @param arg + * Object the object to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, Object arg) { + return getString(msg, new Object[] { arg }); + } + + /** + * Retrieves a message which takes 1 integer argument. + * + * @param msg + * String the key to look up. + * @param arg + * int the integer to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, int arg) { + return getString(msg, new Object[] { Integer.toString(arg) }); + } + + /** + * Retrieves a message which takes 1 character argument. + * + * @param msg + * String the key to look up. + * @param arg + * char the character to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, char arg) { + return getString(msg, new Object[] { String.valueOf(arg) }); + } + + /** + * Retrieves a message which takes 2 arguments. + * + * @param msg + * String the key to look up. + * @param arg1 + * Object an object to insert in the formatted output. + * @param arg2 + * Object another object to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, Object arg1, Object arg2) { + return getString(msg, new Object[] { arg1, arg2 }); + } + + /** + * Retrieves a message which takes several arguments. + * + * @param msg + * String the key to look up. + * @param args + * Object[] the objects to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, Object[] args) { + return MsgHelp.getString(sResource, msg, args); + } +} diff --git a/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties b/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties new file mode 100644 index 0000000..8a49dd8 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties @@ -0,0 +1,18 @@ +# 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. +# + +# messages for EN locale +imageio.1=Wrong bitDepth-numBands composition
\ No newline at end of file diff --git a/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java b/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java new file mode 100644 index 0000000..caeefdd --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java @@ -0,0 +1,94 @@ +/* + * 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.harmony.x.imageio.metadata; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.imageio.metadata.IIOMetadataFormat; +import javax.imageio.metadata.IIOMetadataFormatImpl; + +public class IIOMetadataUtils { + private IIOMetadataUtils() {} + + public static IIOMetadataFormat instantiateMetadataFormat( + String formatName, boolean standardFormatSupported, + String nativeMetadataFormatName, String nativeMetadataFormatClassName, + String [] extraMetadataFormatNames, String [] extraMetadataFormatClassNames + ) { + if (formatName == null) { + throw new IllegalArgumentException("formatName == null!"); + } + if (formatName.equals(IIOMetadataFormatImpl.standardMetadataFormatName)) { + if (standardFormatSupported) { + return IIOMetadataFormatImpl.getStandardFormatInstance(); + } + } + + String className = null; + + if (formatName.equals(nativeMetadataFormatName)) { + className = nativeMetadataFormatClassName; + } else if (extraMetadataFormatNames != null) { + for (int i = 0; i < extraMetadataFormatNames.length; i++) { + if (formatName.equals(extraMetadataFormatNames[i])) { + className = extraMetadataFormatClassNames[i]; + break; + } + } + } + + if (className == null) { + throw new IllegalArgumentException("Unsupported format name"); + } + + // Get the context class loader and try to use it first + ClassLoader contextClassloader = AccessController.doPrivileged( + new PrivilegedAction<ClassLoader>() { + public ClassLoader run() { + return Thread.currentThread().getContextClassLoader(); + } + }); + + Class cls; + + try { + cls = Class.forName(className, true, contextClassloader); + } catch (ClassNotFoundException e) { + try { + // Use current class loader + cls = Class.forName(className); + } catch (ClassNotFoundException e1) { + throw new IllegalStateException ("Can't obtain format"); + } + } + + try { + //???AWT: + //Method getInstance = cls.getMethod("getInstance"); + //return (IIOMetadataFormat) getInstance.invoke(null); + return null; + } catch (Exception e) { + IllegalStateException e1 = new IllegalStateException("Can't obtain format"); + e1.initCause(e); // Add some details to the message + throw e1; + } + } +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java new file mode 100644 index 0000000..051f906 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java @@ -0,0 +1,115 @@ +/* + * 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. + */ +/** + * @author Rustem Rafikov + * @version $Revision: 1.2 $ + */ +package org.apache.harmony.x.imageio.plugins.jpeg; + +import javax.imageio.stream.ImageInputStream; + +import org.apache.harmony.awt.gl.image.DecodingImageSource; + +import java.io.InputStream; +import java.io.IOException; + +/** + * This allows usage of the java2d jpegdecoder with ImageInputStream in + * the JPEGImageReader. Temporary, only to make JPEGImageReader#read(..) + * working. + * + */ +public class IISDecodingImageSource extends DecodingImageSource { + + private final InputStream is; + + public IISDecodingImageSource(ImageInputStream iis) { + is = new IISToInputStreamWrapper(iis); + } + + @Override + protected boolean checkConnection() { + return true; + } + + @Override + protected InputStream getInputStream() { + return is; + } + + static class IISToInputStreamWrapper extends InputStream { + + private ImageInputStream input; + + public IISToInputStreamWrapper(ImageInputStream input) { + this.input=input; + } + + @Override + public int read() throws IOException { + return input.read(); + } + + @Override + public int read(byte[] b) throws IOException { + return input.read(b); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + return input.read(b, off, len); + } + + @Override + public long skip(long n) throws IOException { + return input.skipBytes(n); + } + + @Override + public boolean markSupported() { + return true; // This is orig + + // ???AWT: FIXME + // This is an error in Harmony. Not all input streams + // have mark support and it is not ok to just return true. + // There should be an input.markSupported(). However, if + // this call returns false, nothing works anymore. + + // The backside is that BitmapFactory uses a call to markSupport() + // to find out if it needs to warp the stream in a + // BufferedInputStream to get mark support, and this fails! + + // Currently, the hack is in BitmapFactory, where we always + // wrap the stream in a BufferedInputStream. + } + + @Override + public void mark(int readlimit) { + input.mark(); + } + + @Override + public void reset() throws IOException { + input.reset(); + } + + @Override + public void close() throws IOException { + input.close(); + } + } +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java new file mode 100644 index 0000000..067a825 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java @@ -0,0 +1,44 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.2 $ + */ +package org.apache.harmony.x.imageio.plugins.jpeg; + +public class JPEGConsts { + + private JPEGConsts() {} + + public static final int SOI = 0xD8; + + //-- IJG (Independed JPEG Group) color spaces + public static final int JCS_UNKNOW = 0; + public static final int JCS_GRAYSCALE = 1; + public static final int JCS_RGB = 2; + public static final int JCS_YCbCr = 3; + public static final int JCS_CMYK = 4; + public static final int JCS_YCC = 5; + public static final int JCS_RGBA = 6; + public static final int JCS_YCbCrA = 7; + public static final int JCS_YCCA = 10; + public static final int JCS_YCCK = 11; + + public static int[][] BAND_OFFSETS = {{}, {0}, {0, 1}, {0, 1, 2}, {0, 1, 2, 3}}; + + public static final float DEFAULT_JPEG_COMPRESSION_QUALITY = 0.75f; +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java new file mode 100644 index 0000000..110ed23 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java @@ -0,0 +1,126 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.4 $ + */ +package org.apache.harmony.x.imageio.plugins.jpeg; + + +import javax.imageio.ImageReader; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.plugins.jpeg.JPEGImageReadParam; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.spi.ImageReaderSpi; + +import org.apache.harmony.awt.gl.image.DecodingImageSource; +import org.apache.harmony.awt.gl.image.OffscreenImage; + +import java.io.IOException; +import java.util.Iterator; +import java.awt.image.BufferedImage; + +/** + * This implementation uses org.apache.harmony.awt.gl.image.JpegDecoder to read + * an image. The only implemented method is read(..); + * + * TODO: Implements generic decoder to be used by javad2 and imageio + * + * @see org.apache.harmony.awt.gl.image.JpegDecoder + * @see org.apache.harmony.x.imageio.plugins.jpeg.IISDecodingImageSource + */ +public class JPEGImageReader extends ImageReader { + + ImageInputStream iis; + + public JPEGImageReader(ImageReaderSpi imageReaderSpi) { + super(imageReaderSpi); + } + + @Override + public int getHeight(int i) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public int getWidth(int i) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public int getNumImages(boolean b) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public Iterator<ImageTypeSpecifier> getImageTypes(int i) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public IIOMetadata getStreamMetadata() throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public IIOMetadata getImageMetadata(int i) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public BufferedImage read(int i, ImageReadParam imageReadParam) throws IOException { + if (iis == null) { + throw new IllegalArgumentException("input stream == null"); + } + + DecodingImageSource source = new IISDecodingImageSource(iis); + OffscreenImage image = new OffscreenImage(source); + source.addConsumer(image); + source.load(); + // The interrupted flag should be cleared because ImageDecoder interrupts + // current thread while decoding. The same technique is used in + // ImageLoader#run(). Another solution can be to create + // a separate decoding thread. However, decoder keeps its own pool + // of threads so creating a new thread will be just a waste of resources. + Thread.interrupted(); + return image.getBufferedImage(); + } + + @Override + public BufferedImage read(int i) throws IOException { + return read(i, null); + } + + @Override + public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) { + super.setInput(input, seekForwardOnly, ignoreMetadata); + iis = (ImageInputStream) input; + } + + @Override + public ImageReadParam getDefaultReadParam() { + return new JPEGImageReadParam(); + } +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java new file mode 100644 index 0000000..c719ce7 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java @@ -0,0 +1,86 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.3 $ + */ +package org.apache.harmony.x.imageio.plugins.jpeg; + +import java.io.IOException; +import java.util.Locale; +import javax.imageio.ImageReader; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.spi.ServiceRegistry; +import javax.imageio.stream.ImageInputStream; + +public class JPEGImageReaderSpi extends ImageReaderSpi { + + public JPEGImageReaderSpi() { + super(JPEGSpiConsts.vendorName, JPEGSpiConsts.version, + JPEGSpiConsts.names, JPEGSpiConsts.suffixes, + JPEGSpiConsts.MIMETypes, JPEGSpiConsts.readerClassName, + STANDARD_INPUT_TYPE, JPEGSpiConsts.writerSpiNames, + JPEGSpiConsts.supportsStandardStreamMetadataFormat, + JPEGSpiConsts.nativeStreamMetadataFormatName, + JPEGSpiConsts.nativeStreamMetadataFormatClassName, + JPEGSpiConsts.extraStreamMetadataFormatNames, + JPEGSpiConsts.extraStreamMetadataFormatClassNames, + JPEGSpiConsts.supportsStandardImageMetadataFormat, + JPEGSpiConsts.nativeImageMetadataFormatName, + JPEGSpiConsts.nativeImageMetadataFormatClassName, + JPEGSpiConsts.extraImageMetadataFormatNames, + JPEGSpiConsts.extraImageMetadataFormatClassNames); + } + + + @Override + public boolean canDecodeInput(Object source) throws IOException { + ImageInputStream markable = (ImageInputStream) source; + try { + markable.mark(); + + byte[] signature = new byte[3]; + markable.seek(0); + markable.read(signature, 0, 3); + markable.reset(); + + if ((signature[0] & 0xFF) == 0xFF && + (signature[1] & 0xFF) == JPEGConsts.SOI && + (signature[2] & 0xFF) == 0xFF) { // JPEG + return true; + } + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + @Override + public ImageReader createReaderInstance(Object extension) throws IOException { + return new JPEGImageReader(this); + } + + @Override + public String getDescription(Locale locale) { + return "DRL JPEG decoder"; + } + + @Override + public void onRegistration(ServiceRegistry registry, Class<?> category) { + // super.onRegistration(registry, category); + } +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java new file mode 100644 index 0000000..ae3e876 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java @@ -0,0 +1,402 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.3 $ + */ +package org.apache.harmony.x.imageio.plugins.jpeg; + +import com.android.internal.awt.ImageOutputStreamWrapper; + +import javax.imageio.ImageWriter; +import javax.imageio.IIOImage; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriteParam; +import javax.imageio.plugins.jpeg.JPEGImageWriteParam; +import javax.imageio.stream.ImageOutputStream; +import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.metadata.IIOMetadata; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Bitmap.CompressFormat; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.awt.image.*; +import java.awt.*; +import java.awt.color.ColorSpace; + +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.3 $ + */ +public class JPEGImageWriter extends ImageWriter { + + // /* ???AWT: Debugging + private static final boolean DEBUG = false; + private static Bitmap bm; + public static Bitmap getBitmap() { + return bm; + } + private static BufferedImage bufImg; + public static BufferedImage getBufImage() { + return bufImg; + } + static private RenderedImage renImg; + static public RenderedImage getRenImage() { + return renImg; + } + // */ + + private long cinfo; + private RenderedImage image; + private Raster sourceRaster; + private WritableRaster scanRaster; + private int srcXOff = 0; + private int srcYOff = 0; + private int srcWidth; + private int srcHeight; + + //-- y step for image subsampling + private int deltaY = 1; + //-- x step for image subsampling + private int deltaX = 1; + + private ImageOutputStream ios; + + public JPEGImageWriter(ImageWriterSpi imageWriterSpi) { + super(imageWriterSpi); + //???AWT: cinfo = initCompressionObj(); + cinfo = System.currentTimeMillis(); + } + + static { + //???AWT + /* + System.loadLibrary("jpegencoder"); + initWriterIds(ImageOutputStream.class); + */ + } + + @Override + public void write(IIOMetadata iioMetadata, IIOImage iioImage, ImageWriteParam param) + throws IOException { + + if (ios == null) { + throw new IllegalArgumentException("ios == null"); + } + if (iioImage == null) { + throw new IllegalArgumentException("Image equals null"); + } + + RenderedImage img = null; + if (!iioImage.hasRaster()) { + img = iioImage.getRenderedImage(); + if (img instanceof BufferedImage) { + sourceRaster = ((BufferedImage) img).getRaster(); + } else { + sourceRaster = img.getData(); + } + } else { + sourceRaster = iioImage.getRaster(); + } + + // AWT???: Debugging + if (DEBUG) { + if( img==null ) { + System.out.println("****J: Image is NULL"); + } else { + renImg = img; + bufImg = (BufferedImage)img; + } + } + + int numBands = sourceRaster.getNumBands(); + int sourceIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getSourceCSType(img); + + srcWidth = sourceRaster.getWidth(); + srcHeight = sourceRaster.getHeight(); + + int destWidth = srcWidth; + int destHeight = srcHeight; + + boolean progressive = false; + + if (param != null) { + Rectangle reg = param.getSourceRegion(); + if (reg != null) { + srcXOff = reg.x; + srcYOff = reg.y; + + srcWidth = reg.width + srcXOff > srcWidth + ? srcWidth - srcXOff + : reg.width; + srcHeight = reg.height + srcYOff > srcHeight + ? srcHeight - srcYOff + : reg.height; + } + + //-- TODO uncomment when JPEGImageWriteParam be implemented + //-- Only default progressive mode yet + // progressive = param.getProgressiveMode() == ImageWriteParam.MODE_DEFAULT; + + //-- def is 1 + deltaX = param.getSourceXSubsampling(); + deltaY = param.getSourceYSubsampling(); + + //-- def is 0 + int offsetX = param.getSubsamplingXOffset(); + int offsetY = param.getSubsamplingYOffset(); + + srcXOff += offsetX; + srcYOff += offsetY; + srcWidth -= offsetX; + srcHeight -= offsetY; + + destWidth = (srcWidth + deltaX - 1) / deltaX; + destHeight = (srcHeight + deltaY - 1) / deltaY; + } + + //-- default DQTs (see JPEGQTable java doc and JPEG spec K1 & K2 tables) + //-- at http://www.w3.org/Graphics/JPEG/itu-t81.pdf + //-- Only figuring out how to set DQT in IJG library for future metadata + //-- support. IJG def tables are the same. + //JPEGQTable[] dqt = new JPEGQTable[2]; +// int[][] dqt = null; +// int[][] dqt = new int[2][]; +// dqt[0] = JPEGQTable.K1Div2Luminance.getTable(); +// dqt[1] = JPEGQTable.K2Div2Chrominance.getTable(); + + //???AWT: I think we don't need this amymore + /* + //-- using default color space + //-- TODO: Take destination cs from param or use default if there is no cs + int destIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getDestinationCSType(img); + + DataBufferByte dbuffer = new DataBufferByte(numBands * srcWidth); + + scanRaster = Raster.createInterleavedRaster(dbuffer, srcWidth, 1, + numBands * srcWidth, numBands, JPEGConsts.BAND_OFFSETS[numBands], null); + + encode(dbuffer.getData(), srcWidth, destWidth, destHeight, deltaX, + sourceIJGCs, destIJGCs, numBands, progressive, + null, cinfo); + */ + + SampleModel model = sourceRaster.getSampleModel(); + + if (model instanceof SinglePixelPackedSampleModel) { + DataBufferInt ibuf = (DataBufferInt)sourceRaster.getDataBuffer(); + int[] pixels = ibuf.getData(); + + // Create a bitmap with the pixel + bm = Bitmap.createBitmap(pixels, srcWidth, srcHeight, Bitmap.Config.ARGB_8888); + + // Use Bitmap.compress() to write the image + ImageOutputStreamWrapper iosw = new ImageOutputStreamWrapper(ios); + bm.compress(CompressFormat.JPEG, 100, iosw); + } else { + // ???AWT: Add support for other color models + throw new RuntimeException("Color model not supported yet"); + } + + } + + @Override + public void dispose() { + super.dispose(); + if (cinfo != 0) { + //???AWT: dispose(cinfo); + cinfo = 0; + ios = null; + } + } + + + public IIOMetadata getDefaultStreamMetadata(ImageWriteParam imageWriteParam) { + throw new UnsupportedOperationException("not supported yet"); + } + + public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam) { + throw new UnsupportedOperationException("not supported yet"); + } + + @Override + public IIOMetadata convertStreamMetadata(IIOMetadata iioMetadata, ImageWriteParam imageWriteParam) { + throw new UnsupportedOperationException("not supported yet"); + } + + @Override + public IIOMetadata convertImageMetadata(IIOMetadata iioMetadata, ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam) { + throw new UnsupportedOperationException("not supported yet"); + } + + @Override + public void setOutput(Object output) { + super.setOutput(output); + ios = (ImageOutputStream) output; + //???AWT: setIOS(ios, cinfo); + sourceRaster = null; + scanRaster = null; + srcXOff = 0; + srcYOff = 0; + srcWidth = 0; + srcHeight = 0; + deltaY = 1; + } + + /** + * Frees resources + * @param structPointer + */ + //???AWT: private native void dispose(long structPointer); + + /** + * Inits methods Ids for native to java callbacks + * @param iosClass + */ + //???AWT: private native static void initWriterIds(Class<ImageOutputStream> iosClass); + + /** + * Inits compression objects + * @return pointer to the native structure + */ + //???AWT: private native long initCompressionObj(); + + /** + * Sets image output stream in IJG layer + * @param stream + */ + //???AWT: private native void setIOS(ImageOutputStream stream, long structPointer); + + /** + * Runs encoding process. + * + * @param data image data buffer to encode + * @param srcWidth - source width + * @param width - destination width + * @param height destination height + * @param deltaX - x subsampling step + * @param inColorSpace - original color space + * @param outColorSpace - destination color space + * @param numBands - number of bands + * @param cinfo - native handler + * @return + */ + //???AWT: + /* + private native boolean encode(byte[] data, int srcWidth, + int width, int height, int deltaX, + int inColorSpace, int outColorSpace, + int numBands, boolean progressive, + int[][] dqt, + long cinfo); + */ + + /** + * Callback for getting a next scanline + * @param scanline scan line number + */ + @SuppressWarnings("unused") + private void getScanLine(int scanline) { + //-- TODO: processImageProgress in ImageWriter + Raster child = sourceRaster.createChild(srcXOff, + srcYOff + scanline * deltaY, srcWidth, 1, 0, 0, null); + + scanRaster.setRect(child); + } + + /** + * Maps color space types to IJG color spaces + * @param image + * @return + */ + private int getSourceCSType(RenderedImage image) { + int type = JPEGConsts.JCS_UNKNOW; + ColorModel cm = image.getColorModel(); + + if (null == cm) { + return type; + } + + if (cm instanceof IndexColorModel) { + throw new UnsupportedOperationException("IndexColorModel is not supported yet"); + } + + boolean hasAlpha = cm.hasAlpha(); + ColorSpace cs = cm.getColorSpace(); + switch(cs.getType()) { + case ColorSpace.TYPE_GRAY: + type = JPEGConsts.JCS_GRAYSCALE; + break; + case ColorSpace.TYPE_RGB: + type = hasAlpha ? JPEGConsts.JCS_RGBA : JPEGConsts.JCS_RGB; + break; + case ColorSpace.TYPE_YCbCr: + type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr; + break; + case ColorSpace.TYPE_3CLR: + type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC; + break; + case ColorSpace.TYPE_CMYK: + type = JPEGConsts.JCS_CMYK; + break; + } + return type; + } + + /** + * Returns destination color space. + * (YCbCr[A] for RGB) + * + * @param image + * @return + */ + private int getDestinationCSType(RenderedImage image) { + int type = JPEGConsts.JCS_UNKNOW; + ColorModel cm = image.getColorModel(); + if (null != cm) { + boolean hasAlpha = cm.hasAlpha(); + ColorSpace cs = cm.getColorSpace(); + + switch(cs.getType()) { + case ColorSpace.TYPE_GRAY: + type = JPEGConsts.JCS_GRAYSCALE; + break; + case ColorSpace.TYPE_RGB: + type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr; + break; + case ColorSpace.TYPE_YCbCr: + type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr; + break; + case ColorSpace.TYPE_3CLR: + type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC; + break; + case ColorSpace.TYPE_CMYK: + type = JPEGConsts.JCS_CMYK; + break; + } + } + return type; + } + + public ImageWriteParam getDefaultWriteParam() { + return new JPEGImageWriteParam(getLocale()); + } +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java new file mode 100644 index 0000000..b7990e0 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java @@ -0,0 +1,56 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.3 $ + */ +package org.apache.harmony.x.imageio.plugins.jpeg; + +import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.ImageWriter; +import javax.imageio.ImageTypeSpecifier; +import java.io.IOException; +import java.util.Locale; + +public class JPEGImageWriterSpi extends ImageWriterSpi { + + public JPEGImageWriterSpi() { + super(JPEGSpiConsts.vendorName, JPEGSpiConsts.version, + JPEGSpiConsts.names, JPEGSpiConsts.suffixes, JPEGSpiConsts.MIMETypes, + JPEGSpiConsts.writerClassName, STANDARD_OUTPUT_TYPE, + JPEGSpiConsts.readerSpiNames, JPEGSpiConsts.supportsStandardStreamMetadataFormat /*TODO: support st. metadata format*/, + JPEGSpiConsts.nativeStreamMetadataFormatName, JPEGSpiConsts.nativeStreamMetadataFormatClassName, + JPEGSpiConsts.extraStreamMetadataFormatNames, JPEGSpiConsts.extraStreamMetadataFormatClassNames, + JPEGSpiConsts.supportsStandardImageMetadataFormat, JPEGSpiConsts.nativeImageMetadataFormatName, JPEGSpiConsts.nativeImageMetadataFormatClassName, + JPEGSpiConsts.extraImageMetadataFormatNames, JPEGSpiConsts.extraImageMetadataFormatClassNames); + } + + @Override + public boolean canEncodeImage(ImageTypeSpecifier imageTypeSpecifier) { + return true; + } + + @Override + public ImageWriter createWriterInstance(Object o) throws IOException { + return new JPEGImageWriter(this); + } + + @Override + public String getDescription(Locale locale) { + return "DRL JPEG Encoder"; + } +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java new file mode 100644 index 0000000..c3b4a50 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java @@ -0,0 +1,57 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.2 $ + */ +package org.apache.harmony.x.imageio.plugins.jpeg; + +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.2 $ + */ +public class JPEGSpiConsts { + private JPEGSpiConsts() {} + + public static final String vendorName = "Intel Corporation"; + public static final String version = "0.1 beta"; + + static final String readerClassName = "org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReader"; + static final String writerClassName = "org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriter"; + + static final String[] names = {"jpeg", "jpg", "JPEG", "JPG"}; + static final String[] suffixes = {"jpeg", "jpg"}; + static final String[] MIMETypes = {"image/jpeg"}; + + static final String[] writerSpiNames = {"org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriterSpi"}; + static final String[] readerSpiNames = {"org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReaderSpi"}; + + //-- TODO fill this stuff with correct data + static final boolean supportsStandardStreamMetadataFormat = false; + static final String nativeStreamMetadataFormatName = null; + static final String nativeStreamMetadataFormatClassName = null; + static final String[] extraStreamMetadataFormatNames = null; + static final String[] extraStreamMetadataFormatClassNames = null; + static final boolean supportsStandardImageMetadataFormat = false; + static final String nativeImageMetadataFormatName = + "org.apache.harmony.x.imageio.plugins.jpeg.MyFormatMetadata_1.0"; + static final String nativeImageMetadataFormatClassName = + "org.apache.harmony.x.imageio.plugins.jpeg.MyFormatMetadata"; + static final String[] extraImageMetadataFormatNames = null; + static final String[] extraImageMetadataFormatClassNames = null; + +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java new file mode 100644 index 0000000..480041c --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java @@ -0,0 +1,106 @@ +/* + * 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.harmony.x.imageio.plugins.png; + +import org.apache.harmony.awt.gl.image.DecodingImageSource; +import org.apache.harmony.awt.gl.image.OffscreenImage; +import org.apache.harmony.x.imageio.plugins.jpeg.IISDecodingImageSource; + +import javax.imageio.ImageReader; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageReadParam; +import javax.imageio.plugins.jpeg.JPEGImageReadParam; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.metadata.IIOMetadata; +import java.io.IOException; +import java.util.Iterator; +import java.awt.image.BufferedImage; + +public class PNGImageReader extends ImageReader { + ImageInputStream iis; + + public PNGImageReader(ImageReaderSpi imageReaderSpi) { + super(imageReaderSpi); + } + + public int getNumImages(boolean allowSearch) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + public int getWidth(int imageIndex) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + public int getHeight(int imageIndex) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public IIOMetadata getStreamMetadata() throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public IIOMetadata getImageMetadata(int imageIndex) throws IOException { + //-- TODO imlement + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public BufferedImage read(int i, ImageReadParam imageReadParam) throws IOException { + if (iis == null) { + throw new IllegalArgumentException("input stream == null"); + } + + DecodingImageSource source = new IISDecodingImageSource(iis); + OffscreenImage image = new OffscreenImage(source); + source.addConsumer(image); + source.load(); + // The interrupted flag should be cleared because ImageDecoder interrupts + // current thread while decoding (due its architecture). + Thread.interrupted(); + return image.getBufferedImage(); + } + + @Override + public BufferedImage read(int i) throws IOException { + return read(i, null); + } + + @Override + public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) { + super.setInput(input, seekForwardOnly, ignoreMetadata); + iis = (ImageInputStream) input; + } + + @Override + public ImageReadParam getDefaultReadParam() { + return new ImageReadParam(); + } +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java new file mode 100644 index 0000000..50f8b10 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java @@ -0,0 +1,88 @@ +/* + * 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.harmony.x.imageio.plugins.png; + +import org.apache.harmony.x.imageio.plugins.jpeg.JPEGSpiConsts; + +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.spi.ServiceRegistry; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; +import java.io.IOException; +import java.util.Locale; + +public class PNGImageReaderSpi extends ImageReaderSpi { + static final String PNG_NAMES[] = new String[] {"png", "PNG"}; + static final String PNG_SUFFIXES[] = new String[] {"png"}; + static final String PNG_MIME_TYPES[] = new String[] {"image/png"}; + static final String PNG_READER_CLASS_NAME = "org.apache.harmony.x.imageio.plugins.png.PNGImageReader"; + static final String PNG_READER_SPI_NAMES[] = {"org.apache.harmony.x.imageio.plugins.png.PNGImageReaderSpi"}; + + public PNGImageReaderSpi() { + super( + JPEGSpiConsts.vendorName, JPEGSpiConsts.version, + PNG_NAMES, PNG_SUFFIXES, + PNG_MIME_TYPES, PNG_READER_CLASS_NAME, + STANDARD_INPUT_TYPE, null, + false, null, + null, null, + null, false, + null, null, + null, null + ); + } + + @Override + public boolean canDecodeInput(Object source) throws IOException { + ImageInputStream markable = (ImageInputStream) source; + markable.mark(); + + byte[] signature = new byte[8]; + markable.seek(0); + + int nBytes = markable.read(signature, 0, 8); + if(nBytes != 8) markable.read(signature, nBytes, 8-nBytes); + markable.reset(); + + // PNG signature: 137 80 78 71 13 10 26 10 + return (signature[0] & 0xFF) == 137 && + (signature[1] & 0xFF) == 80 && + (signature[2] & 0xFF) == 78 && + (signature[3] & 0xFF) == 71 && + (signature[4] & 0xFF) == 13 && + (signature[5] & 0xFF) == 10 && + (signature[6] & 0xFF) == 26 && + (signature[7] & 0xFF) == 10; + } + + @Override + public ImageReader createReaderInstance(Object extension) throws IOException { + return new PNGImageReader(this); + } + + @Override + public String getDescription(Locale locale) { + return "DRL PNG decoder"; + } + + @Override + public void onRegistration(ServiceRegistry registry, Class<?> category) { + super.onRegistration(registry, category); + } +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java new file mode 100644 index 0000000..e2a8d7d --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java @@ -0,0 +1,247 @@ +/* + * 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. + */ +/** + * @author Viskov Nikolay + * @version $Revision$ + */ +package org.apache.harmony.x.imageio.plugins.png; + +import com.android.internal.awt.ImageOutputStreamWrapper; + +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.IndexColorModel; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; +import java.awt.image.SampleModel; +import java.awt.image.SinglePixelPackedSampleModel; +import java.awt.image.WritableRaster; +import java.io.IOException; + +import javax.imageio.IIOImage; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.stream.ImageOutputStream; + +import org.apache.harmony.x.imageio.internal.nls.Messages; + +import org.apache.harmony.luni.util.NotImplementedException; + +import android.graphics.Bitmap; +import android.graphics.Bitmap.CompressFormat; + +public class PNGImageWriter extends ImageWriter { + + // /* ???AWT: Debugging + private static final boolean DEBUG = false; + private static Bitmap bm; + public static Bitmap getBitmap() { + return bm; + } + // */ + + private static int[][] BAND_OFFSETS = { + {}, { + 0 }, { + 0, 1 }, { + 0, 1, 2 }, { + 0, 1, 2, 3 } }; + + // Each pixel is a grayscale sample. + private static final int PNG_COLOR_TYPE_GRAY = 0; + // Each pixel is an R,G,B triple. + private static final int PNG_COLOR_TYPE_RGB = 2; + // Each pixel is a palette index, a PLTE chunk must appear. + private static final int PNG_COLOR_TYPE_PLTE = 3; + // Each pixel is a grayscale sample, followed by an alpha sample. + private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4; + // Each pixel is an R,G,B triple, followed by an alpha sample. + private static final int PNG_COLOR_TYPE_RGBA = 6; + + //???AWT: private static native void initIDs(Class<ImageOutputStream> iosClass); + + static { + //???AWT + /* + System.loadLibrary("pngencoder"); //$NON-NLS-1$ + initIDs(ImageOutputStream.class); + */ + } + + /* + private native int encode(byte[] input, int bytesInBuffer, int bytePixelSize, Object ios, int imageWidth, + int imageHeight, int bitDepth, int colorType, int[] palette, int i, boolean b); + */ + + protected PNGImageWriter(ImageWriterSpi iwSpi) { + super(iwSpi); + } + + @Override + public IIOMetadata convertStreamMetadata(IIOMetadata arg0, ImageWriteParam arg1) { + throw new NotImplementedException(); + } + + @Override + public IIOMetadata convertImageMetadata(IIOMetadata arg0, ImageTypeSpecifier arg1, ImageWriteParam arg2) { + throw new NotImplementedException(); + } + + @Override + public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier arg0, ImageWriteParam arg1) { + throw new NotImplementedException(); + } + + @Override + public IIOMetadata getDefaultStreamMetadata(ImageWriteParam arg0) { + throw new NotImplementedException(); + } + + @Override + public void write(IIOMetadata streamMetadata, IIOImage iioImage, ImageWriteParam param) throws IOException { + if (output == null) { + throw new IllegalStateException("Output not been set"); + } + if (iioImage == null) { + throw new IllegalArgumentException("Image equals null"); + } + // AWT???: I think this is not needed anymore + // if (iioImage.hasRaster() && !canWriteRasters()) { + // throw new UnsupportedOperationException("Can't write raster"); + //}// ImageOutputStreamImpl + + Raster sourceRaster; + RenderedImage img = null; + if (!iioImage.hasRaster()) { + img = iioImage.getRenderedImage(); + if (img instanceof BufferedImage) { + sourceRaster = ((BufferedImage) img).getRaster(); + } else { + sourceRaster = img.getData(); + } + } else { + sourceRaster = iioImage.getRaster(); + } + + SampleModel model = sourceRaster.getSampleModel(); + int srcWidth = sourceRaster.getWidth(); + int srcHeight = sourceRaster.getHeight(); + int numBands = model.getNumBands(); + + ColorModel colorModel = img.getColorModel(); + int pixelSize = colorModel.getPixelSize(); + int bytePixelSize = pixelSize / 8; + int bitDepth = pixelSize / numBands; + + // byte per band + int bpb = bitDepth > 8 ? 2 : 1; + + boolean isInterlace = true; + if (param instanceof PNGImageWriterParam) { + isInterlace = ((PNGImageWriterParam) param).getInterlace(); + } + + int colorType = PNG_COLOR_TYPE_GRAY; + int[] palette = null; + + if (colorModel instanceof IndexColorModel) { + if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) { +// Wrong bitDepth-numBands composition + throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$ + } + if (numBands != 1) { +// Wrong bitDepth-numBands composition + throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$ + } + + IndexColorModel icm = (IndexColorModel) colorModel; + palette = new int[icm.getMapSize()]; + icm.getRGBs(palette); + colorType = PNG_COLOR_TYPE_PLTE; + } + else if (numBands == 1) { + if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) { +// Wrong bitDepth-numBands composition + throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$ + } + colorType = PNG_COLOR_TYPE_GRAY; + } + else if (numBands == 2) { + if (bitDepth != 8 && bitDepth != 16) { +// Wrong bitDepth-numBands composition + throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$ + } + colorType = PNG_COLOR_TYPE_GRAY_ALPHA; + } + else if (numBands == 3) { + if (bitDepth != 8 && bitDepth != 16) { +// Wrong bitDepth-numBands composition + throw new IllegalArgumentException(Messages.getString("imageio.1")); //$NON-NLS-1$ + } + colorType = PNG_COLOR_TYPE_RGB; + } + else if (numBands == 4) { + if (bitDepth != 8 && bitDepth != 16) { + //Wrong bitDepth-numBands composition + throw new IllegalArgumentException(Messages.getString("imageio.1")); //$NON-NLS-1$ + } + colorType = PNG_COLOR_TYPE_RGBA; + } + + /* ???AWT: I think this is not needed anymore + int dbufferLenght = bytePixelSize * imageHeight * imageWidth; + DataBufferByte dbuffer = new DataBufferByte(dbufferLenght); + + WritableRaster scanRaster = Raster.createInterleavedRaster(dbuffer, imageWidth, imageHeight, bpb * numBands + * imageWidth, bpb * numBands, BAND_OFFSETS[numBands], null); + + scanRaster.setRect(((BufferedImage) image).getRaster()// image.getData() + .createChild(0, 0, imageWidth, imageHeight, 0, 0, null)); + */ + + if (DEBUG) { + System.out.println("**** raster:" + sourceRaster); + System.out.println("**** model:" + model); + System.out.println("**** type:" + colorType); + } + + if (model instanceof SinglePixelPackedSampleModel) { + DataBufferInt ibuf = (DataBufferInt)sourceRaster.getDataBuffer(); + int[] pixels = ibuf.getData(); + + // Create a bitmap with the pixel + bm = Bitmap.createBitmap(pixels, srcWidth, srcHeight, Bitmap.Config.ARGB_8888); + + // Use Bitmap.compress() to write the image + ImageOutputStream ios = (ImageOutputStream) getOutput(); + ImageOutputStreamWrapper iosw = new ImageOutputStreamWrapper(ios); + bm.compress(CompressFormat.PNG, 100, iosw); + } else { + // ???AWT: Add support for other color models + throw new RuntimeException("Color model not supported yet"); + } + } + + public ImageWriteParam getDefaultWriteParam() { + return new PNGImageWriterParam(); + } +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java new file mode 100644 index 0000000..bf3a000 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java @@ -0,0 +1,41 @@ +/* + * 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. + */ +/** + * @author Viskov Nikolay + * @version $Revision$ + */ +package org.apache.harmony.x.imageio.plugins.png; + +import javax.imageio.ImageWriteParam; + +public class PNGImageWriterParam extends ImageWriteParam { + + private boolean isInterlace = true; + + public PNGImageWriterParam() { + super(); + } + + public boolean getInterlace() { + return isInterlace; + } + + public void setInterlace(boolean b) { + isInterlace = b; + } + +} diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java new file mode 100644 index 0000000..6eed14d --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java @@ -0,0 +1,113 @@ +/* + * 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. + */ +/** + * @author Viskov Nikolay + * @version $Revision$ + */ +package org.apache.harmony.x.imageio.plugins.png; + +import java.awt.image.ColorModel; +import java.awt.image.DataBufferByte; +import java.awt.image.IndexColorModel; +import java.io.IOException; +import java.util.Locale; + +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriter; +import javax.imageio.spi.ImageWriterSpi; + +public class PNGImageWriterSpi extends ImageWriterSpi { + + public PNGImageWriterSpi() { + super("Intel Corporation",// vendorName + "1.0",// version + new String[] { + "png", "PNG" },// names + new String[] { + "png", "PNG" },// suffixes + new String[] { + "image/png" },// MIMETypes + "org.apache.harmony.x.imageio.plugins.png.PNGImageWriter",// writerClassName + STANDARD_OUTPUT_TYPE,// outputTypes + new String[] { + "org.apache.harmony.x.imageio.plugins.png.PNGImageWriterSpi" },// readerSpiNames + false,// supportsStandardStreamMetadataFormat + null,// nativeStreamMetadataFormatName + null,// nativeStreamMetadataFormatClassName + null,// extraStreamMetadataFormatNames + null,// extraStreamMetadataFormatClassNames + false,// supportsStandardImageMetadataFormat + null,// nativeImageMetadataFormatName + null,// nativeImageMetadataFormatClassName + null,// extraImageMetadataFormatNames + null// extraImageMetadataFormatClassNames + ); + } + + @Override + public boolean canEncodeImage(ImageTypeSpecifier type) { + boolean canEncode = true; + + int numBands = type.getSampleModel().getNumBands(); + + ColorModel colorModel = type.getColorModel(); + + int bitDepth = colorModel.getPixelSize() / numBands; + + if (colorModel instanceof IndexColorModel) { + if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) { + canEncode = false; + } + if (numBands != 1) { + canEncode = false; + } + } + else if (numBands == 1) { + if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) { + canEncode = false; + } + } + else if (numBands == 2) { + if (bitDepth != 8 && bitDepth != 16) { + canEncode = false; + } + } + else if (numBands == 3) { + if (bitDepth != 8 && bitDepth != 16) { + canEncode = false; + } + } + else if (numBands == 4) { + if (bitDepth != 8 && bitDepth != 16) { + canEncode = false; + } + } + + return canEncode; + } + + @Override + public ImageWriter createWriterInstance(Object arg0) throws IOException { + return new PNGImageWriter(this); + } + + @Override + public String getDescription(Locale arg0) { + return "DRL PNG encoder"; + } + +} diff --git a/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java new file mode 100644 index 0000000..d4fdd76 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java @@ -0,0 +1,53 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.2 $ + */ +package org.apache.harmony.x.imageio.spi; + +import javax.imageio.spi.ImageInputStreamSpi; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.FileImageOutputStream; +import javax.imageio.stream.FileImageInputStream; +import java.io.File; +import java.io.IOException; +import java.util.Locale; + +public class FileIISSpi extends ImageInputStreamSpi { + private static final String vendor = "Apache"; + + private static final String ver = "0.1"; + + public FileIISSpi() { + super(vendor, ver, File.class); + } + + @Override + public ImageInputStream createInputStreamInstance(Object input, boolean useCache, + File cacheDir) throws IOException { + if (File.class.isInstance(input)) { + return new FileImageInputStream((File) input); + } + throw new IllegalArgumentException("input is not an instance of java.io.File"); + } + + @Override + public String getDescription(Locale locale) { + return "File IIS Spi"; + } +} diff --git a/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java new file mode 100644 index 0000000..acda6a1 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java @@ -0,0 +1,52 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.2 $ + */ +package org.apache.harmony.x.imageio.spi; + +import javax.imageio.spi.ImageOutputStreamSpi; +import javax.imageio.stream.ImageOutputStream; +import javax.imageio.stream.FileImageOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.Locale; + +public class FileIOSSpi extends ImageOutputStreamSpi { + private static final String vendor = "Apache"; + + private static final String ver = "0.1"; + + public FileIOSSpi() { + super(vendor, ver, File.class); + } + + @Override + public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache, + File cacheDir) throws IOException { + if (output instanceof File) { + return new FileImageOutputStream((File) output); + } + throw new IllegalArgumentException("output is not instance of File"); + } + + @Override + public String getDescription(Locale locale) { + return "File IOS Spi"; + } +} diff --git a/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java new file mode 100644 index 0000000..ed2fef0 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java @@ -0,0 +1,59 @@ +/* + * 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.harmony.x.imageio.spi; + +import javax.imageio.spi.ImageInputStreamSpi; +import javax.imageio.stream.*; +import java.io.OutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; + +public class InputStreamIISSpi extends ImageInputStreamSpi { + private static final String vendor = "Apache"; + + private static final String ver = "0.1"; + + public InputStreamIISSpi() { + super(vendor, ver, InputStream.class); + } + + @Override + public String getDescription(Locale locale) { + return "Output Stream IOS Spi"; + } + + @Override + public boolean canUseCacheFile() { + return true; + } + + @Override + public ImageInputStream createInputStreamInstance(Object input, boolean useCache, File cacheDir) throws IOException { + if (input instanceof InputStream) { + if (useCache) { + return new FileCacheImageInputStream((InputStream) input, cacheDir); + } else { + return new MemoryCacheImageInputStream((InputStream) input); + } + } + throw new IllegalArgumentException("Output is not an instance of InputStream"); + } +} diff --git a/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java new file mode 100644 index 0000000..dd1e88d --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java @@ -0,0 +1,60 @@ +/* + * 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.harmony.x.imageio.spi; + +import javax.imageio.spi.ImageOutputStreamSpi; +import javax.imageio.stream.ImageOutputStream; +import javax.imageio.stream.FileCacheImageOutputStream; +import javax.imageio.stream.MemoryCacheImageOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Locale; + +public class OutputStreamIOSSpi extends ImageOutputStreamSpi { + private static final String vendor = "Apache"; + + private static final String ver = "0.1"; + + public OutputStreamIOSSpi() { + super(vendor, ver, OutputStream.class); + } + + @Override + public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache, File cacheDir) throws IOException { + if (output instanceof OutputStream) { + if (useCache) { + return new FileCacheImageOutputStream((OutputStream) output, cacheDir); + } else { + return new MemoryCacheImageOutputStream((OutputStream) output); + } + } + throw new IllegalArgumentException("Output is not an instance of OutputStream"); + } + + @Override + public String getDescription(Locale locale) { + return "Output Stream IOS Spi"; + } + + @Override + public boolean canUseCacheFile() { + return true; + } +} diff --git a/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java new file mode 100644 index 0000000..f97eb87 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java @@ -0,0 +1,54 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.2 $ + */ +package org.apache.harmony.x.imageio.spi; + +import javax.imageio.spi.ImageInputStreamSpi; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.FileImageInputStream; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Locale; + +public class RAFIISSpi extends ImageInputStreamSpi { + private static final String vendor = "Apache"; + + private static final String ver = "0.1"; + + public RAFIISSpi() { + super(vendor, ver, RandomAccessFile.class); + } + + @Override + public ImageInputStream createInputStreamInstance(Object input, boolean useCache, + File cacheDir) throws IOException { + if (RandomAccessFile.class.isInstance(input)) { + return new FileImageInputStream((RandomAccessFile) input); + } + throw new IllegalArgumentException( + "input is not an instance of java.io.RandomAccessFile"); + } + + @Override + public String getDescription(Locale locale) { + return "RandomAccessFile IIS Spi"; + } +} diff --git a/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java new file mode 100644 index 0000000..a9d3649 --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java @@ -0,0 +1,53 @@ +/* + * 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. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.2 $ + */ +package org.apache.harmony.x.imageio.spi; + +import javax.imageio.spi.ImageOutputStreamSpi; +import javax.imageio.stream.ImageOutputStream; +import javax.imageio.stream.FileImageOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Locale; + +public class RAFIOSSpi extends ImageOutputStreamSpi { + private static final String vendor = "Apache"; + + private static final String ver = "0.1"; + + public RAFIOSSpi() { + super(vendor, ver, RandomAccessFile.class); + } + + @Override + public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache, + File cacheDir) throws IOException { + if (output instanceof RandomAccessFile) { + return new FileImageOutputStream((RandomAccessFile) output); + } + throw new IllegalArgumentException("output is not instance of java.io.RandomAccessFile"); + } + + @Override + public String getDescription(Locale locale) { + return "RandomAccessFile IOS Spi"; + } +} diff --git a/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java b/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java new file mode 100644 index 0000000..64f7b2a --- /dev/null +++ b/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java @@ -0,0 +1,226 @@ +/* + * 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.harmony.x.imageio.stream; + +import java.util.ArrayList; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public final class RandomAccessMemoryCache { + private static final int BLOCK_SHIFT = 9; + private static final int BLOCK_SIZE = 1 << BLOCK_SHIFT; + private static final int BLOCK_MASK = BLOCK_SIZE - 1; + + private long length; + + private int firstUndisposed = 0; + + private ArrayList<byte[]> blocks = new ArrayList<byte[]>(); + + public RandomAccessMemoryCache() { + } + + public long length() { + return length; + } + + public void close() { + blocks.clear(); + length = 0; + } + + private void grow(long pos) { + int blocksNeeded = (int)(pos >> BLOCK_SHIFT) - blocks.size() + 1; + for (int i=0; i < blocksNeeded; i++) { + blocks.add(new byte[BLOCK_SIZE]); + } + + length = pos + 1; + } + + public void putData(int oneByte, long pos) { + if (pos >= length) { + grow(pos); + } + + byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT)); + block[(int)(pos & BLOCK_MASK)] = (byte) oneByte; + } + + public void putData(byte[] buffer, int offset, int count, long pos) { + if (count > buffer.length - offset || count < 0 || offset < 0) { + throw new IndexOutOfBoundsException(); + } + if (count == 0){ + return; + } + + long lastPos = pos + count - 1; + if (lastPos >= length) { + grow(lastPos); + } + + while (count > 0) { + byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT)); + int blockOffset = (int)(pos & BLOCK_MASK); + int toCopy = Math.min(BLOCK_SIZE - blockOffset, count); + System.arraycopy(buffer, offset, block, blockOffset, toCopy); + pos += toCopy; + count -= toCopy; + offset += toCopy; + } + } + + public int getData(long pos) { + if (pos >= length) { + return -1; + } + + byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT)); + return block[(int)(pos & BLOCK_MASK)] & 0xFF; + } + + public int getData(byte[] buffer, int offset, int count, long pos) { + if (count > buffer.length - offset || count < 0 || offset < 0) { + throw new IndexOutOfBoundsException(); + } + if (count == 0) { + return 0; + } + if (pos >= length) { + return -1; + } + + if (count + pos > length) { + count = (int) (length - pos); + } + + byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT)); + int nbytes = Math.min(count, BLOCK_SIZE - (int)(pos & BLOCK_MASK)); + System.arraycopy(block, (int)(pos & BLOCK_MASK), buffer, offset, nbytes); + + return nbytes; + } + /* + public void seek(long pos) throws IOException { + if (pos < 0) { + throw new IOException("seek position is negative"); + } + this.pos = pos; + } + + public void readFully(byte[] buffer) throws IOException { + readFully(buffer, 0, buffer.length); + } + + public void readFully(byte[] buffer, int offset, int count) throws IOException { + if (0 <= offset && offset <= buffer.length && 0 <= count && count <= buffer.length - offset) { + while (count > 0) { + int result = read(buffer, offset, count); + if (result >= 0) { + offset += result; + count -= result; + } else { + throw new EOFException(); + } + } + } else { + throw new IndexOutOfBoundsException(); + } + } + + public long getFilePointer() { + return pos; + } +*/ + + public void freeBefore(long pos) { + int blockIdx = (int)(pos >> BLOCK_SHIFT); + if (blockIdx <= firstUndisposed) { // Nothing to do + return; + } + + for (int i = firstUndisposed; i < blockIdx; i++) { + blocks.set(i, null); + } + + firstUndisposed = blockIdx; + } + + public int appendData(InputStream is, int count) throws IOException { + if (count <= 0) { + return 0; + } + + long startPos = length; + long lastPos = length + count - 1; + grow(lastPos); // Changes length + + int blockIdx = (int)(startPos >> BLOCK_SHIFT); + int offset = (int) (startPos & BLOCK_MASK); + + int bytesAppended = 0; + + while (count > 0) { + byte[] block = blocks.get(blockIdx); + int toCopy = Math.min(BLOCK_SIZE - offset, count); + count -= toCopy; + + while (toCopy > 0) { + int bytesRead = is.read(block, offset, toCopy); + + if (bytesRead < 0) { + length -= (count - bytesAppended); + return bytesAppended; + } + + toCopy -= bytesRead; + offset += bytesRead; + } + + blockIdx++; + offset = 0; + } + + return count; + } + + public void getData(OutputStream os, int count, long pos) throws IOException { + if (pos + count > length) { + throw new IndexOutOfBoundsException("Argument out of cache"); + } + + int blockIdx = (int)(pos >> BLOCK_SHIFT); + int offset = (int) (pos & BLOCK_MASK); + if (blockIdx < firstUndisposed) { + throw new IndexOutOfBoundsException("The requested data are already disposed"); + } + + while (count > 0) { + byte[] block = blocks.get(blockIdx); + int toWrite = Math.min(BLOCK_SIZE - offset, count); + os.write(block, offset, toWrite); + + blockIdx++; + offset = 0; + count -= toWrite; + } + } +} |