From d22bed4c2927f119712103064d8630b293b34002 Mon Sep 17 00:00:00 2001 From: WangQiang Date: Thu, 2 Mar 2017 13:03:37 +0800 Subject: [PATCH] init --- .gitignore | 44 +- README.md | 9 + pom.xml | 25 + .../luciad/imageio/webp/VP8StatusCode.java | 38 ++ .../java/com/luciad/imageio/webp/WebP.java | 428 ++++++++++++++++++ .../imageio/webp/WebPImageReaderSpi.java | 106 +++++ .../imageio/webp/WebPImageWriterSpi.java | 110 +++++ .../luciad/imageio/webp/WebPReadParam.java | 200 ++++++++ .../com/luciad/imageio/webp/WebPReader.java | 151 ++++++ .../luciad/imageio/webp/WebPWriteParam.java | 337 ++++++++++++++ .../com/luciad/imageio/webp/WebPWriter.java | 72 +++ src/main/java/example/DecodingTest.java | 38 ++ src/main/java/example/EncodingTest.java | 36 ++ .../META-INF/lib/linux_32/libwebp-imageio.so | Bin 0 -> 1522682 bytes .../META-INF/lib/linux_64/libwebp-imageio.so | Bin 0 -> 2457147 bytes .../META-INF/lib/osx_32/libwebp-imageio.dylib | Bin 0 -> 907888 bytes .../META-INF/lib/osx_64/libwebp-imageio.dylib | Bin 0 -> 907888 bytes .../META-INF/lib/windows_32/webp-imageio.dll | Bin 0 -> 1515739 bytes .../META-INF/lib/windows_64/webp-imageio.dll | Bin 0 -> 2562034 bytes .../services/javax.imageio.spi.ImageReaderSpi | 1 + .../services/javax.imageio.spi.ImageWriterSpi | 1 + test_pic/test.jpg | Bin 0 -> 27929 bytes test_pic/test.png | Bin 0 -> 29596 bytes test_pic/test.webp | Bin 0 -> 10474 bytes 24 files changed, 1586 insertions(+), 10 deletions(-) create mode 100644 pom.xml create mode 100644 src/main/java/com/luciad/imageio/webp/VP8StatusCode.java create mode 100644 src/main/java/com/luciad/imageio/webp/WebP.java create mode 100644 src/main/java/com/luciad/imageio/webp/WebPImageReaderSpi.java create mode 100644 src/main/java/com/luciad/imageio/webp/WebPImageWriterSpi.java create mode 100644 src/main/java/com/luciad/imageio/webp/WebPReadParam.java create mode 100644 src/main/java/com/luciad/imageio/webp/WebPReader.java create mode 100644 src/main/java/com/luciad/imageio/webp/WebPWriteParam.java create mode 100644 src/main/java/com/luciad/imageio/webp/WebPWriter.java create mode 100644 src/main/java/example/DecodingTest.java create mode 100644 src/main/java/example/EncodingTest.java create mode 100755 src/main/resources/META-INF/lib/linux_32/libwebp-imageio.so create mode 100755 src/main/resources/META-INF/lib/linux_64/libwebp-imageio.so create mode 100755 src/main/resources/META-INF/lib/osx_32/libwebp-imageio.dylib create mode 100755 src/main/resources/META-INF/lib/osx_64/libwebp-imageio.dylib create mode 100755 src/main/resources/META-INF/lib/windows_32/webp-imageio.dll create mode 100755 src/main/resources/META-INF/lib/windows_64/webp-imageio.dll create mode 100644 src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi create mode 100644 src/main/resources/META-INF/services/javax.imageio.spi.ImageWriterSpi create mode 100644 test_pic/test.jpg create mode 100644 test_pic/test.png create mode 100644 test_pic/test.webp diff --git a/.gitignore b/.gitignore index 32858aa..0460bc2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,36 @@ -*.class - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar +# maven ignore +target/ *.war -*.ear +*.zip +*.tar +*.tar.gz -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* +# eclipse ignore +.settings/ +.project +.classpath +.tern-project + +# idea ignore +.idea/ +*.ipr +*.iml +*.iws + +# temp ignore +.svn/ +generated/ +.externalToolBuilders/ +logs/ +*.log +*.cache +*.diff +*.patch +*.tmp +*.java~ +*.properties~ +*.xml~ + +# system ignore +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/README.md b/README.md index 315e50b..e652840 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ # j-webp Java Image I/O reader and writer for the Google WebP image format. + +基于[webp project of Luciad](https://bitbucket.org/luciad/webp-imageio) 0.4.2版本修改. + +实际上只修改了`com.luciad.imageio.webp.WebP.loadNativeLibrary`这一个方法. +因为按他默认的加载方式, 需要把native的so/dll/dylib等文件放到OS对应的`java.library.path`对应的目录才能加载到, 这会给部署带来一些不便. + +所以我们这里换成了[native-lib-loader](https://github.com/scijava/native-lib-loader)自动加载, 编译构建好的包里已经包含了各种OS上的native文件, 使用时会自动加载. + +具体使用方法可参看`src/main/java/example`下的源码. \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..dcbafff --- /dev/null +++ b/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + net.wangq + webp + 1.0-SNAPSHOT + + + UTF-8 + 1.7 + 1.7 + + + + + org.scijava + native-lib-loader + 2.1.3 + + + + \ No newline at end of file diff --git a/src/main/java/com/luciad/imageio/webp/VP8StatusCode.java b/src/main/java/com/luciad/imageio/webp/VP8StatusCode.java new file mode 100644 index 0000000..0d1047e --- /dev/null +++ b/src/main/java/com/luciad/imageio/webp/VP8StatusCode.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013 Luciad (http://www.luciad.com) + * + * Licensed 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 com.luciad.imageio.webp; + +enum VP8StatusCode { + VP8_STATUS_OK, + VP8_STATUS_OUT_OF_MEMORY, + VP8_STATUS_INVALID_PARAM, + VP8_STATUS_BITSTREAM_ERROR, + VP8_STATUS_UNSUPPORTED_FEATURE, + VP8_STATUS_SUSPENDED, + VP8_STATUS_USER_ABORT, + VP8_STATUS_NOT_ENOUGH_DATA,; + + private static VP8StatusCode[] VALUES = values(); + + public static VP8StatusCode getStatusCode( int aValue ) { + if ( aValue >= 0 && aValue < VALUES.length ) { + return VALUES[ aValue ]; + } + else { + return null; + } + } +} diff --git a/src/main/java/com/luciad/imageio/webp/WebP.java b/src/main/java/com/luciad/imageio/webp/WebP.java new file mode 100644 index 0000000..cdda853 --- /dev/null +++ b/src/main/java/com/luciad/imageio/webp/WebP.java @@ -0,0 +1,428 @@ +/* + * Copyright 2013 Luciad (http://www.luciad.com) + * + * Licensed 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 com.luciad.imageio.webp; + +import org.scijava.nativelib.NativeLibraryUtil; + +import java.awt.image.*; +import java.io.IOException; +import java.nio.ByteOrder; +import java.util.Hashtable; + +final class WebP { + private static boolean NATIVE_LIBRARY_LOADED = false; + + static synchronized void loadNativeLibrary() { + if ( !NATIVE_LIBRARY_LOADED ) { + NATIVE_LIBRARY_LOADED = true; + NativeLibraryUtil.loadNativeLibrary(WebP.class, "webp-imageio"); + } + } + + static { + loadNativeLibrary(); + } + + private WebP() { + } + + public static BufferedImage decode( WebPReadParam aReadParam, byte[] aData, int aOffset, int aLength ) throws IOException { + if ( aReadParam == null ) { + throw new NullPointerException( "Decoder options may not be null" ); + } + + if ( aData == null ) { + throw new NullPointerException( "Input data may not be null" ); + } + + if ( aOffset + aLength > aData.length ) { + throw new IllegalArgumentException( "Offset/length exceeds array size" ); + } + + int[] out = new int[4]; + int[] pixels = decode( aReadParam.fPointer, aData, aOffset, aLength, out, ByteOrder.nativeOrder().equals( ByteOrder.BIG_ENDIAN ) ); + VP8StatusCode status = VP8StatusCode.getStatusCode( out[0] ); + switch ( status ) { + case VP8_STATUS_OK: + break; + case VP8_STATUS_OUT_OF_MEMORY: + throw new OutOfMemoryError(); + default: + throw new IOException( "Decode returned code " + status ); + } + + int width = out[1]; + int height = out[2]; + boolean alpha = out[3] != 0; + + ColorModel colorModel; + if ( alpha ) { + colorModel = new DirectColorModel( 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 ); + } else { + colorModel = new DirectColorModel( 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 ); + } + + SampleModel sampleModel = colorModel.createCompatibleSampleModel( width, height ); + DataBufferInt db = new DataBufferInt( pixels, width * height ); + WritableRaster raster = WritableRaster.createWritableRaster( sampleModel, db, null ); + + return new BufferedImage( colorModel, raster, false, new Hashtable() ); + } + + private static native int[] decode( long aDecoderOptionsPointer, byte[] aData, int aOffset, int aLength, int[] aFlags, boolean aBigEndian ); + + public static int[] getInfo( byte[] aData, int aOffset, int aLength ) throws IOException { + int[] out = new int[2]; + int result = getInfo( aData, aOffset, aLength, out ); + if (result == 0) { + throw new IOException( "Invalid WebP data" ); + } + + return out; + } + + private static native int getInfo( byte[] aData, int aOffset, int aLength, int[] aOut ); + + public static byte[] encode( WebPWriteParam aWriteParam, RenderedImage aImage ) throws IOException { + if ( aWriteParam == null ) { + throw new NullPointerException( "Encoder options may not be null" ); + } + + if ( aImage == null ) { + throw new NullPointerException( "Image may not be null" ); + } + + boolean encodeAlpha = hasTranslucency( aImage ); + if ( encodeAlpha ) { + byte[] rgbaData = getRGBA( aImage ); + return encodeRGBA( aWriteParam.getPointer(), rgbaData, aImage.getWidth(), aImage.getHeight(), aImage.getWidth() * 4 ); + } + else { + byte[] rgbData = getRGB( aImage ); + return encodeRGB( aWriteParam.getPointer(), rgbData, aImage.getWidth(), aImage.getHeight(), aImage.getWidth() * 3 ); + } + } + + private static native byte[] encodeRGBA( long aConfig, byte[] aRgbaData, int aWidth, int aHeight, int aStride ); + + private static native byte[] encodeRGB( long aConfig, byte[] aRgbaData, int aWidth, int aHeight, int aStride ); + + private static boolean hasTranslucency( RenderedImage aRi ) { + return aRi.getColorModel().hasAlpha(); + } + + private static int getShift( int aMask ) { + int shift = 0; + while ( ( ( aMask >> shift ) & 0x1 ) == 0 ) { + shift++; + } + return shift; + } + + private static byte[] getRGB( RenderedImage aRi ) throws IOException { + int width = aRi.getWidth(); + int height = aRi.getHeight(); + + ColorModel colorModel = aRi.getColorModel(); + if ( colorModel instanceof ComponentColorModel ) { + ComponentSampleModel sampleModel = ( ComponentSampleModel ) aRi.getSampleModel(); + int type = sampleModel.getTransferType(); + if ( type == DataBuffer.TYPE_BYTE ) { + return extractComponentRGBByte( width, height, sampleModel, ( ( DataBufferByte ) aRi.getData().getDataBuffer() ) ); + } + else if ( type == DataBuffer.TYPE_INT ) { + return extractComponentRGBInt( width, height, sampleModel, ( ( DataBufferInt ) aRi.getData().getDataBuffer() ) ); + } + else { + throw new IOException( "Incompatible image: " + aRi ); + } + } + else if ( colorModel instanceof DirectColorModel ) { + SinglePixelPackedSampleModel sampleModel = ( SinglePixelPackedSampleModel ) aRi.getSampleModel(); + int type = sampleModel.getTransferType(); + if ( type == DataBuffer.TYPE_INT ) { + return extractDirectRGBInt( width, height, ( DirectColorModel ) colorModel, sampleModel, ( ( DataBufferInt ) aRi.getData().getDataBuffer() ) ); + } + else { + throw new IOException( "Incompatible image: " + aRi ); + } + } + + return extractGenericRGB( aRi, width, height, colorModel ); + } + + private static byte[] extractGenericRGB( RenderedImage aRi, int aWidth, int aHeight, ColorModel aColorModel ) { + Object dataElements = null; + byte[] rgbData = new byte[ aWidth * aHeight * 3 ]; + for ( int b = 0, y = 0; y < aHeight; y++ ) { + for ( int x = 0; x < aWidth; x++, b += 3 ) { + dataElements = aRi.getData().getDataElements( x, y, dataElements ); + rgbData[ b ] = ( byte ) aColorModel.getRed( dataElements ); + rgbData[ b + 1 ] = ( byte ) aColorModel.getGreen( dataElements ); + rgbData[ b + 2 ] = ( byte ) aColorModel.getBlue( dataElements ); + } + } + return rgbData; + } + + private static byte[] extractDirectRGBInt( int aWidth, int aHeight, DirectColorModel aColorModel, SinglePixelPackedSampleModel aSampleModel, DataBufferInt aDataBuffer ) { + byte[] out = new byte[ aWidth * aHeight * 3 ]; + + int rMask = aColorModel.getRedMask(); + int gMask = aColorModel.getGreenMask(); + int bMask = aColorModel.getBlueMask(); + int rShift = getShift( rMask ); + int gShift = getShift( gMask ); + int bShift = getShift( bMask ); + int[] bank = aDataBuffer.getBankData()[ 0 ]; + int scanlineStride = aSampleModel.getScanlineStride(); + int scanIx = 0; + for ( int b = 0, y = 0; y < aHeight; y++ ) { + int pixIx = scanIx; + for ( int x = 0; x < aWidth; x++, b += 3 ) { + int pixel = bank[ pixIx++ ]; + out[ b ] = ( byte ) ( ( pixel & rMask ) >>> rShift ); + out[ b + 1 ] = ( byte ) ( ( pixel & gMask ) >>> gShift ); + out[ b + 2 ] = ( byte ) ( ( pixel & bMask ) >>> bShift ); + } + scanIx += scanlineStride; + } + return out; + } + + private static byte[] extractComponentRGBInt( int aWidth, int aHeight, ComponentSampleModel aSampleModel, DataBufferInt aDataBuffer ) { + byte[] out = new byte[ aWidth * aHeight * 3 ]; + + int[] bankIndices = aSampleModel.getBankIndices(); + int[] rBank = aDataBuffer.getBankData()[ bankIndices[ 0 ] ]; + int[] gBank = aDataBuffer.getBankData()[ bankIndices[ 1 ] ]; + int[] bBank = aDataBuffer.getBankData()[ bankIndices[ 2 ] ]; + + int[] bankOffsets = aSampleModel.getBandOffsets(); + int rScanIx = bankOffsets[ 0 ]; + int gScanIx = bankOffsets[ 1 ]; + int bScanIx = bankOffsets[ 2 ]; + + int pixelStride = aSampleModel.getPixelStride(); + int scanlineStride = aSampleModel.getScanlineStride(); + for ( int b = 0, y = 0; y < aHeight; y++ ) { + int rPixIx = rScanIx; + int gPixIx = gScanIx; + int bPixIx = bScanIx; + for ( int x = 0; x < aWidth; x++, b += 3 ) { + out[ b ] = ( byte ) rBank[ rPixIx ]; + rPixIx += pixelStride; + out[ b + 1 ] = ( byte ) gBank[ gPixIx ]; + gPixIx += pixelStride; + out[ b + 2 ] = ( byte ) bBank[ bPixIx ]; + bPixIx += pixelStride; + } + rScanIx += scanlineStride; + gScanIx += scanlineStride; + bScanIx += scanlineStride; + } + return out; + } + + private static byte[] extractComponentRGBByte( int aWidth, int aHeight, ComponentSampleModel aSampleModel, DataBufferByte aDataBuffer ) { + byte[] out = new byte[ aWidth * aHeight * 3 ]; + + int[] bankIndices = aSampleModel.getBankIndices(); + byte[] rBank = aDataBuffer.getBankData()[ bankIndices[ 0 ] ]; + byte[] gBank = aDataBuffer.getBankData()[ bankIndices[ 1 ] ]; + byte[] bBank = aDataBuffer.getBankData()[ bankIndices[ 2 ] ]; + + int[] bankOffsets = aSampleModel.getBandOffsets(); + int rScanIx = bankOffsets[ 0 ]; + int gScanIx = bankOffsets[ 1 ]; + int bScanIx = bankOffsets[ 2 ]; + + int pixelStride = aSampleModel.getPixelStride(); + int scanlineStride = aSampleModel.getScanlineStride(); + for ( int b = 0, y = 0; y < aHeight; y++ ) { + int rPixIx = rScanIx; + int gPixIx = gScanIx; + int bPixIx = bScanIx; + for ( int x = 0; x < aWidth; x++, b += 3 ) { + out[ b ] = rBank[ rPixIx ]; + rPixIx += pixelStride; + out[ b + 1 ] = gBank[ gPixIx ]; + gPixIx += pixelStride; + out[ b + 2 ] = bBank[ bPixIx ]; + bPixIx += pixelStride; + } + rScanIx += scanlineStride; + gScanIx += scanlineStride; + bScanIx += scanlineStride; + } + return out; + } + + private static byte[] getRGBA( RenderedImage aRi ) throws IOException { + int width = aRi.getWidth(); + int height = aRi.getHeight(); + + ColorModel colorModel = aRi.getColorModel(); + if ( colorModel instanceof ComponentColorModel ) { + ComponentSampleModel sampleModel = ( ComponentSampleModel ) aRi.getSampleModel(); + int type = sampleModel.getTransferType(); + if ( type == DataBuffer.TYPE_BYTE ) { + return extractComponentRGBAByte( width, height, sampleModel, ( ( DataBufferByte ) aRi.getData().getDataBuffer() ) ); + } + else if ( type == DataBuffer.TYPE_INT ) { + return extractComponentRGBAInt( width, height, sampleModel, ( ( DataBufferInt ) aRi.getData().getDataBuffer() ) ); + } + else { + throw new IOException( "Incompatible image: " + aRi ); + } + } + else if ( colorModel instanceof DirectColorModel ) { + SinglePixelPackedSampleModel sampleModel = ( SinglePixelPackedSampleModel ) aRi.getSampleModel(); + int type = sampleModel.getTransferType(); + if ( type == DataBuffer.TYPE_INT ) { + return extractDirectRGBAInt( width, height, ( DirectColorModel ) colorModel, sampleModel, ( ( DataBufferInt ) aRi.getData().getDataBuffer() ) ); + } + else { + throw new IOException( "Incompatible image: " + aRi ); + } + } + + return extractGenericRGBA( aRi, width, height, colorModel ); + } + + private static byte[] extractGenericRGBA( RenderedImage aRi, int aWidth, int aHeight, ColorModel aColorModel ) { + Object dataElements = null; + byte[] rgbData = new byte[ aWidth * aHeight * 4 ]; + for ( int b = 0, y = 0; y < aHeight; y++ ) { + for ( int x = 0; x < aWidth; x++, b += 4 ) { + dataElements = aRi.getData().getDataElements( x, y, dataElements ); + rgbData[ b ] = ( byte ) aColorModel.getRed( dataElements ); + rgbData[ b + 1 ] = ( byte ) aColorModel.getGreen( dataElements ); + rgbData[ b + 2 ] = ( byte ) aColorModel.getBlue( dataElements ); + rgbData[ b + 3 ] = ( byte ) aColorModel.getAlpha( dataElements ); + } + } + return rgbData; + } + + private static byte[] extractDirectRGBAInt( int aWidth, int aHeight, DirectColorModel aColorModel, SinglePixelPackedSampleModel aSampleModel, DataBufferInt aDataBuffer ) { + byte[] out = new byte[ aWidth * aHeight * 4 ]; + + int rMask = aColorModel.getRedMask(); + int gMask = aColorModel.getGreenMask(); + int bMask = aColorModel.getBlueMask(); + int aMask = aColorModel.getAlphaMask(); + int rShift = getShift( rMask ); + int gShift = getShift( gMask ); + int bShift = getShift( bMask ); + int aShift = getShift( aMask ); + int[] bank = aDataBuffer.getBankData()[ 0 ]; + int scanlineStride = aSampleModel.getScanlineStride(); + int scanIx = 0; + for ( int b = 0, y = 0; y < aHeight; y++ ) { + int pixIx = scanIx; + for ( int x = 0; x < aWidth; x++, b += 4 ) { + int pixel = bank[ pixIx++ ]; + out[ b ] = ( byte ) ( ( pixel & rMask ) >>> rShift ); + out[ b + 1 ] = ( byte ) ( ( pixel & gMask ) >>> gShift ); + out[ b + 2 ] = ( byte ) ( ( pixel & bMask ) >>> bShift ); + out[ b + 3 ] = ( byte ) ( ( pixel & aMask ) >>> aShift ); + } + scanIx += scanlineStride; + } + return out; + } + + private static byte[] extractComponentRGBAInt( int aWidth, int aHeight, ComponentSampleModel aSampleModel, DataBufferInt aDataBuffer ) { + byte[] out = new byte[ aWidth * aHeight * 4 ]; + + int[] bankIndices = aSampleModel.getBankIndices(); + int[] rBank = aDataBuffer.getBankData()[ bankIndices[ 0 ] ]; + int[] gBank = aDataBuffer.getBankData()[ bankIndices[ 1 ] ]; + int[] bBank = aDataBuffer.getBankData()[ bankIndices[ 2 ] ]; + int[] aBank = aDataBuffer.getBankData()[ bankIndices[ 3 ] ]; + + int[] bankOffsets = aSampleModel.getBandOffsets(); + int rScanIx = bankOffsets[ 0 ]; + int gScanIx = bankOffsets[ 1 ]; + int bScanIx = bankOffsets[ 2 ]; + int aScanIx = bankOffsets[ 3 ]; + + int pixelStride = aSampleModel.getPixelStride(); + int scanlineStride = aSampleModel.getScanlineStride(); + for ( int b = 0, y = 0; y < aHeight; y++ ) { + int rPixIx = rScanIx; + int gPixIx = gScanIx; + int bPixIx = bScanIx; + int aPixIx = aScanIx; + for ( int x = 0; x < aWidth; x++, b += 4 ) { + out[ b ] = ( byte ) rBank[ rPixIx ]; + rPixIx += pixelStride; + out[ b + 1 ] = ( byte ) gBank[ gPixIx ]; + gPixIx += pixelStride; + out[ b + 2 ] = ( byte ) bBank[ bPixIx ]; + bPixIx += pixelStride; + out[ b + 3 ] = ( byte ) aBank[ aPixIx ]; + aPixIx += pixelStride; + } + rScanIx += scanlineStride; + gScanIx += scanlineStride; + bScanIx += scanlineStride; + aScanIx += scanlineStride; + } + return out; + } + + private static byte[] extractComponentRGBAByte( int aWidth, int aHeight, ComponentSampleModel aSampleModel, DataBufferByte aDataBuffer ) { + byte[] out = new byte[ aWidth * aHeight * 4 ]; + + int[] bankIndices = aSampleModel.getBankIndices(); + byte[] rBank = aDataBuffer.getBankData()[ bankIndices[ 0 ] ]; + byte[] gBank = aDataBuffer.getBankData()[ bankIndices[ 1 ] ]; + byte[] bBank = aDataBuffer.getBankData()[ bankIndices[ 2 ] ]; + byte[] aBank = aDataBuffer.getBankData()[ bankIndices[ 3 ] ]; + + int[] bankOffsets = aSampleModel.getBandOffsets(); + int rScanIx = bankOffsets[ 0 ]; + int gScanIx = bankOffsets[ 1 ]; + int bScanIx = bankOffsets[ 2 ]; + int aScanIx = bankOffsets[ 3 ]; + + int pixelStride = aSampleModel.getPixelStride(); + int scanlineStride = aSampleModel.getScanlineStride(); + for ( int b = 0, y = 0; y < aHeight; y++ ) { + int rPixIx = rScanIx; + int gPixIx = gScanIx; + int bPixIx = bScanIx; + int aPixIx = aScanIx; + for ( int x = 0; x < aWidth; x++, b += 4 ) { + out[ b ] = rBank[ rPixIx ]; + rPixIx += pixelStride; + out[ b + 1 ] = gBank[ gPixIx ]; + gPixIx += pixelStride; + out[ b + 2 ] = bBank[ bPixIx ]; + bPixIx += pixelStride; + out[ b + 3 ] = aBank[ aPixIx ]; + aPixIx += pixelStride; + } + rScanIx += scanlineStride; + gScanIx += scanlineStride; + bScanIx += scanlineStride; + aScanIx += scanlineStride; + } + return out; + } +} diff --git a/src/main/java/com/luciad/imageio/webp/WebPImageReaderSpi.java b/src/main/java/com/luciad/imageio/webp/WebPImageReaderSpi.java new file mode 100644 index 0000000..dc539da --- /dev/null +++ b/src/main/java/com/luciad/imageio/webp/WebPImageReaderSpi.java @@ -0,0 +1,106 @@ +/* + * Copyright 2013 Luciad (http://www.luciad.com) + * + * Licensed 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 com.luciad.imageio.webp; + +import javax.imageio.ImageReader; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStream; +import java.io.IOException; +import java.nio.ByteOrder; +import java.util.Arrays; +import java.util.Locale; + +/** + * + */ +public class WebPImageReaderSpi extends ImageReaderSpi { + private static final byte[] RIFF = new byte[]{ 'R', 'I', 'F', 'F' }; + private static final byte[] WEBP = new byte[]{ 'W', 'E', 'B', 'P' }; + private static final byte[] VP8_ = new byte[]{ 'V', 'P', '8', ' ' }; + private static final byte[] VP8X = new byte[]{ 'V', 'P', '8', 'X' }; + + public WebPImageReaderSpi() { + super( + "Luciad", + "1.0", + new String[]{ "WebP", "webp" }, + new String[]{ "webp" }, + new String[]{ "image/webp" }, + WebPReader.class.getName(), + new Class[] { ImageInputStream.class }, + new String[]{ WebPImageWriterSpi.class.getName() }, + false, + null, + null, + null, + null, + false, + null, + null, + null, + null + ); + } + + @Override + public ImageReader createReaderInstance( Object extension ) throws IOException { + return new WebPReader( this ); + } + + @Override + public boolean canDecodeInput( Object source ) throws IOException { + if ( !( source instanceof ImageInputStream ) ) { + return false; + } + + ImageInputStream stream = ( ImageInputStream ) source; + byte[] b = new byte[ 4 ]; + ByteOrder oldByteOrder = stream.getByteOrder(); + stream.mark(); + stream.setByteOrder( ByteOrder.LITTLE_ENDIAN ); + + try { + stream.readFully( b ); + if ( !Arrays.equals( b, RIFF ) ) { + return false; + } + long chunkLength = stream.readUnsignedInt(); + long streamLength = stream.length(); + if ( streamLength != -1 && streamLength != chunkLength + 8 ) { + return false; + } + stream.readFully( b ); + if ( !Arrays.equals( b, WEBP ) ) { + return false; + } + + stream.readFully( b ); + if ( !Arrays.equals( b, VP8_ ) && !Arrays.equals( b, VP8X ) ) { + return false; + } + } finally { + stream.setByteOrder( oldByteOrder ); + stream.reset(); + } + + return true; + } + + @Override + public String getDescription( Locale locale ) { + return "WebP Reader"; + } +} diff --git a/src/main/java/com/luciad/imageio/webp/WebPImageWriterSpi.java b/src/main/java/com/luciad/imageio/webp/WebPImageWriterSpi.java new file mode 100644 index 0000000..78e92f4 --- /dev/null +++ b/src/main/java/com/luciad/imageio/webp/WebPImageWriterSpi.java @@ -0,0 +1,110 @@ +/* + * Copyright 2013 Luciad (http://www.luciad.com) + * + * Licensed 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 com.luciad.imageio.webp; + +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriter; +import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.stream.ImageOutputStream; +import java.awt.color.ColorSpace; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.ComponentSampleModel; +import java.awt.image.DataBuffer; +import java.awt.image.DirectColorModel; +import java.awt.image.SampleModel; +import java.awt.image.SinglePixelPackedSampleModel; +import java.io.IOException; +import java.util.Locale; + +/** + * + */ +public class WebPImageWriterSpi extends ImageWriterSpi { + public WebPImageWriterSpi() { + super( + "Luciad", + "1.0", + new String[]{ "WebP", "webp" }, + new String[]{ "webp" }, + new String[]{ "image/webp" }, + WebPReader.class.getName(), + new Class[]{ ImageOutputStream.class }, + new String[]{ WebPImageReaderSpi.class.getName() }, + false, + null, + null, + null, + null, + false, + null, + null, + null, + null + ); + } + + @Override + public boolean canEncodeImage( ImageTypeSpecifier type ) { + ColorModel colorModel = type.getColorModel(); + SampleModel sampleModel = type.getSampleModel(); + int transferType = sampleModel.getTransferType(); + + if ( colorModel instanceof ComponentColorModel ) { + if ( !( sampleModel instanceof ComponentSampleModel ) ) { + return false; + } + + if ( transferType != DataBuffer.TYPE_BYTE && transferType != DataBuffer.TYPE_INT ) { + return false; + } + } + else if ( colorModel instanceof DirectColorModel ) { + if ( !( sampleModel instanceof SinglePixelPackedSampleModel ) ) { + return false; + } + + if ( transferType != DataBuffer.TYPE_INT ) { + return false; + } + } + + ColorSpace colorSpace = colorModel.getColorSpace(); + if ( !( colorSpace.isCS_sRGB() ) ) { + return false; + } + + int[] sampleSize = sampleModel.getSampleSize(); + for ( int i = 0; i < sampleSize.length; i++ ) { + if ( sampleSize[ i ] > 8 ) { + return false; + } + } + + + return true; + } + + @Override + public ImageWriter createWriterInstance( Object extension ) throws IOException { + return new WebPWriter( this ); + } + + @Override + public String getDescription( Locale locale ) { + return "WebP Writer"; + } +} diff --git a/src/main/java/com/luciad/imageio/webp/WebPReadParam.java b/src/main/java/com/luciad/imageio/webp/WebPReadParam.java new file mode 100644 index 0000000..2db6712 --- /dev/null +++ b/src/main/java/com/luciad/imageio/webp/WebPReadParam.java @@ -0,0 +1,200 @@ +/* + * Copyright 2013 Luciad (http://www.luciad.com) + * + * Licensed 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 com.luciad.imageio.webp; + +import javax.imageio.ImageReadParam; + +public final class WebPReadParam extends ImageReadParam { + static { + WebP.loadNativeLibrary(); + } + + long fPointer; + + public WebPReadParam() { + fPointer = createDecoderOptions(); + if ( fPointer == 0 ) { + throw new OutOfMemoryError(); + } + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + deleteDecoderOptions( fPointer ); + fPointer = 0L; + } + + public int getCropHeight() { + return getCropHeight( fPointer ); + } + + public void setCropHeight( int aCropHeight ) { + setCropHeight( fPointer, aCropHeight ); + } + + public int getCropLeft() { + return getCropLeft( fPointer ); + } + + public void setCropLeft( int aCropLeft ) { + setCropLeft( fPointer, aCropLeft ); + } + + public int getCropTop() { + return getCropTop( fPointer ); + } + + public void setCropTop( int aCropTop ) { + setCropTop( fPointer, aCropTop ); + } + + public int getCropWidth() { + return getCropWidth( fPointer ); + } + + public void setCropWidth( int aCropWidth ) { + setCropWidth( fPointer, aCropWidth ); + } + + public boolean isForceRotation() { + return isForceRotation( fPointer ); + } + + public void setForceRotation( boolean aForceRotation ) { + setForceRotation( fPointer, aForceRotation ); + } + + public boolean isEnhancement() { + return !isNoEnhancement( fPointer ); + } + + public void setEnhancement( boolean aEnhancement ) { + setNoEnhancement( fPointer, !aEnhancement ); + } + + public boolean isFancyUpsampling() { + return !isNoFancyUpsampling( fPointer ); + } + + public void setFancyUpsampling( boolean aFancyUpsampling ) { + setNoFancyUpsampling( fPointer, !aFancyUpsampling ); + } + + public int getScaledHeight() { + return getScaledHeight( fPointer ); + } + + public void setScaledHeight( int aScaledHeight ) { + setScaledHeight( fPointer, aScaledHeight ); + } + + public int getScaledWidth() { + return getScaledWidth( fPointer ); + } + + public void setScaledWidth( int aScaledWidth ) { + setScaledWidth( fPointer, aScaledWidth ); + } + + public boolean isUseCropping() { + return isUseCropping( fPointer ); + } + + public void setUseCropping( boolean aUseCropping ) { + setUseCropping( fPointer, aUseCropping ); + } + + public boolean isUseScaling() { + return isUseScaling( fPointer ); + } + + public void setUseScaling( boolean aUseScaling ) { + setUseScaling( fPointer, aUseScaling ); + } + + public boolean isUseThreads() { + return isUseThreads( fPointer ); + } + + public void setUseThreads( boolean aUseThreads ) { + setUseThreads( fPointer, aUseThreads ); + } + + public boolean isBypassFiltering() { + return isBypassFiltering( fPointer ); + } + + public void setBypassFiltering( boolean aBypassFiltering ) { + setBypassFiltering( fPointer, aBypassFiltering ); + } + + private static native long createDecoderOptions(); + + private static native void deleteDecoderOptions( long aPointer ); + + private static native int getCropHeight( long aPointer ); + + private static native void setCropHeight( long aPointer, int aCropHeight ); + + private static native int getCropLeft( long aPointer ); + + private static native void setCropLeft( long aPointer, int aCropLeft ); + + private static native int getCropTop( long aPointer ); + + private static native void setCropTop( long aPointer, int aCropTop ); + + private static native int getCropWidth( long aPointer ); + + private static native void setCropWidth( long aPointer, int aCropWidth ); + + private static native boolean isForceRotation( long aPointer ); + + private static native void setForceRotation( long aPointer, boolean aForceRotation ); + + private static native boolean isNoEnhancement( long aPointer ); + + private static native void setNoEnhancement( long aPointer, boolean aNoEnhancement ); + + private static native boolean isNoFancyUpsampling( long aPointer ); + + private static native void setNoFancyUpsampling( long aPointer, boolean aFancyUpsampling ); + + private static native int getScaledHeight( long aPointer ); + + private static native void setScaledHeight( long aPointer, int aScaledHeight ); + + private static native int getScaledWidth( long aPointer ); + + private static native void setScaledWidth( long aPointer, int aScaledWidth ); + + private static native boolean isUseCropping( long aPointer ); + + private static native void setUseCropping( long aPointer, boolean aUseCropping ); + + private static native boolean isUseScaling( long aPointer ); + + private static native void setUseScaling( long aPointer, boolean aUseScaling ); + + private static native boolean isUseThreads( long aPointer ); + + private static native void setUseThreads( long aPointer, boolean aUseThreads ); + + private static native boolean isBypassFiltering( long aPointer ); + + private static native void setBypassFiltering( long aPointer, boolean aBypassFiltering ); +} diff --git a/src/main/java/com/luciad/imageio/webp/WebPReader.java b/src/main/java/com/luciad/imageio/webp/WebPReader.java new file mode 100644 index 0000000..6a83d28 --- /dev/null +++ b/src/main/java/com/luciad/imageio/webp/WebPReader.java @@ -0,0 +1,151 @@ +/* + * Copyright 2013 Luciad (http://www.luciad.com) + * + * Licensed 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 com.luciad.imageio.webp; + +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStream; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; + +class WebPReader extends ImageReader { + private byte[] fData; + private int fWidth; + private int fHeight; + + WebPReader( ImageReaderSpi originatingProvider ) { + super( originatingProvider ); + } + + @Override + public void setInput( Object input, boolean seekForwardOnly, boolean ignoreMetadata ) { + super.setInput( input, seekForwardOnly, ignoreMetadata ); + fData = null; + fWidth = -1; + fHeight = -1; + } + + @Override + public int getNumImages( boolean allowSearch ) throws IOException { + return 1; + } + + private void readHeader() throws IOException { + if ( fWidth != -1 && fHeight != -1 ) { + return; + } + + readData(); + int[] info = WebP.getInfo( fData, 0, fData.length ); + fWidth = info[ 0 ]; + fHeight = info[ 1 ]; + } + + private void readData() throws IOException { + if ( fData != null ) { + return; + } + + ImageInputStream input = ( ImageInputStream ) getInput(); + long length = input.length(); + if ( length > Integer.MAX_VALUE ) { + throw new IOException( "Cannot read image of size " + length ); + } + + if ( input.getStreamPosition() != 0L ) { + if ( isSeekForwardOnly() ) { + throw new IOException(); + } + else { + input.seek( 0 ); + } + } + + byte[] data; + if ( length > 0 ) { + data = new byte[ ( int ) length ]; + input.readFully( data ); + } + else { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[ 4096 ]; + int bytesRead; + while ( ( bytesRead = input.read( buffer ) ) != -1 ) { + out.write( buffer, 0, bytesRead ); + } + out.close(); + data = out.toByteArray(); + } + fData = data; + } + + private void checkIndex( int imageIndex ) { + if ( imageIndex != 0 ) { + throw new IndexOutOfBoundsException( "Invalid image index: " + imageIndex ); + } + } + + @Override + public int getWidth( int imageIndex ) throws IOException { + checkIndex( imageIndex ); + readHeader(); + return fWidth; + } + + @Override + public int getHeight( int imageIndex ) throws IOException { + checkIndex( imageIndex ); + readHeader(); + return fHeight; + } + + @Override + public IIOMetadata getStreamMetadata() throws IOException { + return null; + } + + @Override + public IIOMetadata getImageMetadata( int imageIndex ) throws IOException { + return null; + } + + @Override + public Iterator getImageTypes( int imageIndex ) throws IOException { + return Collections.singletonList( + ImageTypeSpecifier.createFromBufferedImageType( BufferedImage.TYPE_INT_ARGB ) + ).iterator(); + } + + @Override + public ImageReadParam getDefaultReadParam() { + return new WebPReadParam(); + } + + @Override + public BufferedImage read( int imageIndex, ImageReadParam param ) throws IOException { + checkIndex( imageIndex ); + readData(); + readHeader(); + WebPReadParam options = param != null ? (WebPReadParam) param : new WebPReadParam(); + return WebP.decode( options, fData, 0, fData.length ); + } +} diff --git a/src/main/java/com/luciad/imageio/webp/WebPWriteParam.java b/src/main/java/com/luciad/imageio/webp/WebPWriteParam.java new file mode 100644 index 0000000..2491e95 --- /dev/null +++ b/src/main/java/com/luciad/imageio/webp/WebPWriteParam.java @@ -0,0 +1,337 @@ +/* + * Copyright 2013 Luciad (http://www.luciad.com) + * + * Licensed 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 com.luciad.imageio.webp; + +import javax.imageio.ImageWriteParam; +import java.util.Locale; + +public class WebPWriteParam extends ImageWriteParam { + static { + WebP.loadNativeLibrary(); + } + + long fPointer; + private final int defaultLossless; + + public WebPWriteParam( Locale aLocale ) { + super( aLocale ); + fPointer = createConfig(); + if ( fPointer == 0 ) { + throw new OutOfMemoryError(); + } + defaultLossless = getLossless( fPointer ); + canWriteCompressed = true; + compressionTypes = new String[]{ + "Lossy", + "Lossless" + }; + compressionType = compressionTypes[defaultLossless]; + compressionQuality = getQuality( fPointer ) / 100f; + compressionMode = MODE_EXPLICIT; + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + deleteConfig( fPointer ); + fPointer = 0L; + } + + private static native long createConfig(); + + private static native void deleteConfig( long aPointer ); + + long getPointer() { + return fPointer; + } + + @Override + public float getCompressionQuality() { + return super.getCompressionQuality(); + } + + @Override + public void setCompressionQuality( float quality ) { + super.setCompressionQuality( quality ); + setQuality( fPointer, quality * 100f ); + } + + @Override + public void setCompressionType( String compressionType ) { + super.setCompressionType( compressionType ); + for ( int i = 0; i < compressionTypes.length; i++ ) { + if ( compressionTypes[i].equals( compressionType ) ) { + setLossless( fPointer, i ); + break; + } + } + + } + + @Override + public void unsetCompression() { + super.unsetCompression(); + setLossless( fPointer, defaultLossless ); + } + + public int getTargetSize() { + return getTargetSize( fPointer ); + } + + public void setTargetSize( int aTargetSize ) { + setTargetSize( fPointer, aTargetSize ); + } + + public float getTargetPSNR() { + return getTargetPSNR( fPointer ); + } + + public void setTargetPSNR( float aTargetPSNR ) { + setTargetPSNR( fPointer, aTargetPSNR ); + } + + public int getMethod() { + return getMethod( fPointer ); + } + + public void setMethod( int aMethod ) { + setMethod( fPointer, aMethod ); + } + + public int getSegments() { + return getSegments( fPointer ); + } + + public void setSegments( int aSegments ) { + setSegments( fPointer, aSegments ); + } + + public int getSnsStrength() { + return getSnsStrength( fPointer ); + } + + public void setSnsStrength( int aSnsStrength ) { + setSnsStrength( fPointer, aSnsStrength ); + } + + public int getFilterStrength() { + return getFilterStrength( fPointer ); + } + + public void setFilterStrength( int aFilterStrength ) { + setFilterStrength( fPointer, aFilterStrength ); + } + + public int getFilterSharpness() { + return getFilterSharpness( fPointer ); + } + + public void setFilterSharpness( int aFilterSharpness ) { + setFilterSharpness( fPointer, aFilterSharpness ); + } + + public int getFilterType() { + return getFilterType( fPointer ); + } + + public void setFilterType( int aFilterType ) { + setFilterType( fPointer, aFilterType ); + } + + public boolean isAutoAdjustFilterStrength() { + return getAutofilter( fPointer ) != 0; + } + + public void setAutoAdjustFilterStrength( boolean aAutofilter ) { + setAutofilter( fPointer, aAutofilter ? 1 : 0 ); + } + + public int getEntropyAnalysisPassCount() { + return getPass( fPointer ); + } + + public void setEntropyAnalysisPassCount( int aPass ) { + setPass( fPointer, aPass ); + } + + public boolean isShowCompressed() { + return getShowCompressed( fPointer ) != 0; + } + + public void setShowCompressed( boolean aShowCompressed ) { + setShowCompressed( fPointer, aShowCompressed ? 1 : 0 ); + } + + public int getPreprocessing() { + return getPreprocessing( fPointer ); + } + + public void setPreprocessing( int aPreprocessing ) { + setPreprocessing( fPointer, aPreprocessing ); + } + + public int getPartitions() { + return getPartitions( fPointer ); + } + + public void setPartitions( int aPartitions ) { + setPartitions( fPointer, aPartitions ); + } + + public int getPartitionLimit() { + return getPartitionLimit( fPointer ); + } + + public void setPartitionLimit( int aPartitionLimit ) { + setPartitionLimit( fPointer, aPartitionLimit ); + } + + public int getAlphaCompression() { + return getAlphaCompression( fPointer ); + } + + public void setAlphaCompression( int aAlphaCompression ) { + setAlphaCompression( fPointer, aAlphaCompression ); + } + + public int getAlphaFiltering() { + return getAlphaFiltering( fPointer ); + } + + public void setAlphaFiltering( int aAlphaFiltering ) { + setAlphaFiltering( fPointer, aAlphaFiltering ); + } + + public int getAlphaQuality() { + return getAlphaQuality( fPointer ); + } + + public void setAlphaQuality( int aAlphaQuality ) { + setAlphaQuality( fPointer, aAlphaQuality ); + } + + public boolean isEmulateJpegSize() { + return getEmulateJpegSize( fPointer ) != 0; + } + + public void setEmulateJpegSize( boolean aEmulateJpegSize ) { + setEmulateJpegSize( fPointer, aEmulateJpegSize ? 1 : 0 ); + } + + public int getThreadLevel() { + return getThreadLevel( fPointer ); + } + + public void setThreadLevel( int aThreadLevel ) { + setThreadLevel( fPointer, aThreadLevel ); + } + + public boolean isReduceMemoryUsage() { + return getLowMemory( fPointer ) != 0; + } + + public void setReduceMemoryUsage( boolean aLowMemory ) { + setLowMemory( fPointer, aLowMemory ? 1 : 0 ); + } + + private static native float getQuality( long aPointer ); + + private static native void setQuality( long aPointer, float aQuality ); + + private static native int getTargetSize( long aPointer ); + + private static native void setTargetSize( long aPointer, int aTargetSize ); + + private static native float getTargetPSNR( long aPointer ); + + private static native void setTargetPSNR( long aPointer, float aTargetPSNR ); + + private static native int getMethod( long aPointer ); + + private static native void setMethod( long aPointer, int aMethod ); + + private static native int getSegments( long aPointer ); + + private static native void setSegments( long aPointer, int aSegments ); + + private static native int getSnsStrength( long aPointer ); + + private static native void setSnsStrength( long aPointer, int aSnsStrength ); + + private static native int getFilterStrength( long aPointer ); + + private static native void setFilterStrength( long aPointer, int aFilterStrength ); + + private static native int getFilterSharpness( long aPointer ); + + private static native void setFilterSharpness( long aPointer, int aFilterSharpness ); + + private static native int getFilterType( long aPointer ); + + private static native void setFilterType( long aPointer, int aFilterType ); + + private static native int getAutofilter( long aPointer ); + + private static native void setAutofilter( long aPointer, int aAutofilter ); + + private static native int getPass( long aPointer ); + + private static native void setPass( long aPointer, int aPass ); + + private static native int getShowCompressed( long aPointer ); + + private static native void setShowCompressed( long aPointer, int aShowCompressed ); + + private static native int getPreprocessing( long aPointer ); + + private static native void setPreprocessing( long aPointer, int aPreprocessing ); + + private static native int getPartitions( long aPointer ); + + private static native void setPartitions( long aPointer, int aPartitions ); + + private static native int getPartitionLimit( long aPointer ); + + private static native void setPartitionLimit( long aPointer, int aPartitionLimit ); + + private static native int getAlphaCompression( long aPointer ); + + private static native void setAlphaCompression( long aPointer, int aAlphaCompression ); + + private static native int getAlphaFiltering( long aPointer ); + + private static native void setAlphaFiltering( long aPointer, int aAlphaFiltering ); + + private static native int getAlphaQuality( long aPointer ); + + private static native void setAlphaQuality( long aPointer, int aAlphaQuality ); + + private static native int getLossless( long aPointer ); + + private static native void setLossless( long aPointer, int aLossless ); + + private static native int getEmulateJpegSize( long aPointer ); + + private static native void setEmulateJpegSize( long aPointer, int aEmulateJpegSize ); + + private static native int getThreadLevel( long aPointer ); + + private static native void setThreadLevel( long aPointer, int aThreadLevel ); + + private static native int getLowMemory( long aPointer ); + + private static native void setLowMemory( long aPointer, int aLowMemory ); +} diff --git a/src/main/java/com/luciad/imageio/webp/WebPWriter.java b/src/main/java/com/luciad/imageio/webp/WebPWriter.java new file mode 100644 index 0000000..795fb4d --- /dev/null +++ b/src/main/java/com/luciad/imageio/webp/WebPWriter.java @@ -0,0 +1,72 @@ +/* + * Copyright 2013 Luciad (http://www.luciad.com) + * + * Licensed 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 com.luciad.imageio.webp; + +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 java.awt.image.RenderedImage; +import java.io.IOException; + +class WebPWriter extends ImageWriter { + WebPWriter( ImageWriterSpi originatingProvider ) { + super( originatingProvider ); + } + + @Override + public ImageWriteParam getDefaultWriteParam() { + return new WebPWriteParam( getLocale() ); + } + + @Override + public IIOMetadata convertImageMetadata( IIOMetadata inData, ImageTypeSpecifier imageType, ImageWriteParam param ) { + return null; + } + + @Override + public IIOMetadata convertStreamMetadata( IIOMetadata inData, ImageWriteParam param ) { + return null; + } + + @Override + public IIOMetadata getDefaultImageMetadata( ImageTypeSpecifier imageType, ImageWriteParam param ) { + return null; + } + + @Override + public IIOMetadata getDefaultStreamMetadata( ImageWriteParam param ) { + return null; + } + + @Override + public void write( IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param ) throws IOException { + if ( param == null ) { + param = getDefaultWriteParam(); + } + + WebPWriteParam writeParam = (WebPWriteParam) param; + + ImageOutputStream output = ( ImageOutputStream ) getOutput(); + RenderedImage ri = image.getRenderedImage(); + + byte[] encodedData = WebP.encode(writeParam, ri); + output.write( encodedData ); + } +} diff --git a/src/main/java/example/DecodingTest.java b/src/main/java/example/DecodingTest.java new file mode 100644 index 0000000..82b2466 --- /dev/null +++ b/src/main/java/example/DecodingTest.java @@ -0,0 +1,38 @@ +package example; + +import com.luciad.imageio.webp.WebPReadParam; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.FileImageInputStream; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +public class DecodingTest { + + public static void main(String args[]) throws IOException { + String inputWebpPath = "test_pic/test.webp"; + String outputJpgPath = "test_pic/test_.jpg"; + String outputJpegPath = "test_pic/test_.jpeg"; + String outputPngPath = "test_pic/test_.png"; + + // Obtain a WebP ImageReader instance + ImageReader reader = ImageIO.getImageReadersByMIMEType("image/webp").next(); + + // Configure decoding parameters + WebPReadParam readParam = new WebPReadParam(); + readParam.setBypassFiltering(true); + + // Configure the input on the ImageReader + reader.setInput(new FileImageInputStream(new File(inputWebpPath))); + + // Decode the image + BufferedImage image = reader.read(0, readParam); + + ImageIO.write(image, "png", new File(outputPngPath)); + ImageIO.write(image, "jpg", new File(outputJpgPath)); + ImageIO.write(image, "jpeg", new File(outputJpegPath)); + + } +} diff --git a/src/main/java/example/EncodingTest.java b/src/main/java/example/EncodingTest.java new file mode 100644 index 0000000..facad6d --- /dev/null +++ b/src/main/java/example/EncodingTest.java @@ -0,0 +1,36 @@ +package example; + +import com.luciad.imageio.webp.WebPWriteParam; + +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriter; +import javax.imageio.stream.FileImageOutputStream; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +public class EncodingTest { + + public static void main(String args[]) throws IOException { + String inputPngPath = "test_pic/test.png"; + String inputJpgPath = "test_pic/test.jpg"; + String outputWebpPath = "test_pic/test_.webp"; + + // Obtain an image to encode from somewhere + BufferedImage image = ImageIO.read(new File(inputJpgPath)); + + // Obtain a WebP ImageWriter instance + ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next(); + + // Configure encoding parameters + WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale()); + writeParam.setCompressionMode(WebPWriteParam.MODE_DEFAULT); + + // Configure the output on the ImageWriter + writer.setOutput(new FileImageOutputStream(new File(outputWebpPath))); + + // Encode + writer.write(null, new IIOImage(image, null, null), writeParam); + } +} diff --git a/src/main/resources/META-INF/lib/linux_32/libwebp-imageio.so b/src/main/resources/META-INF/lib/linux_32/libwebp-imageio.so new file mode 100755 index 0000000000000000000000000000000000000000..6b196f53850becba179101c8be97f14bc145f28d GIT binary patch literal 1522682 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