diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/VP8LDecoder.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/VP8LDecoder.java
index ade640b3..23bd8444 100644
--- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/VP8LDecoder.java
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/VP8LDecoder.java
@@ -32,6 +32,12 @@
package com.twelvemonkeys.imageio.plugins.webp.lossless;
import com.twelvemonkeys.imageio.plugins.webp.LSBBitReader;
+import com.twelvemonkeys.imageio.plugins.webp.lossless.transform.ColorIndexingTransform;
+import com.twelvemonkeys.imageio.plugins.webp.lossless.transform.ColorTransform;
+import com.twelvemonkeys.imageio.plugins.webp.lossless.transform.PredictorTransform;
+import com.twelvemonkeys.imageio.plugins.webp.lossless.transform.SubtractGreenTransform;
+import com.twelvemonkeys.imageio.plugins.webp.lossless.transform.Transform;
+import com.twelvemonkeys.imageio.plugins.webp.lossless.transform.TransformType;
import javax.imageio.IIOException;
import javax.imageio.stream.ImageInputStream;
@@ -40,7 +46,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import static com.twelvemonkeys.imageio.util.RasterUtils.asByteRaster;
import static java.lang.Math.*;
/**
@@ -97,58 +102,38 @@ public final class VP8LDecoder {
// TODO: Each transform type can only be present once in the stream.
switch (transformType) {
- case TransformType.PREDICTOR_TRANSFORM: {
+ case TransformType.PREDICTOR_TRANSFORM:
System.err.println("transformType: PREDICTOR_TRANSFORM");
-// int sizeBits = (int) readBits(3) + 2;
- int sizeBits = (int) lsbBitReader.readBits(3) + 2;
- int size = 1 << sizeBits;
-
- int blockWidth = size;
- int blockHeight = size;
-
-// int blockSize = divRoundUp(width, size);
- int blockSize = divRoundUp(xSize, size);
-
- for (int y = 0; y < ySize; y++) {
- for (int x = 0; x < xSize; x++) {
- int blockIndex = (y >> sizeBits) * blockSize + (x >> sizeBits);
- }
- }
-
- // Special rules:
- // Top-left pixel of image is predicted BLACK
- // Rest of top pixels is predicted L
- // Rest of leftmost pixels are predicted T
- // Rightmost pixels using TR, uses LEFTMOST pixel on SAME ROW (same distance as TR in memory!)
-
-// WritableRaster data = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, blockWidth, blockHeight, blockWidth, 1, new int[] {0}, null);
-// readVP8Lossless(data, false);
-//
- break;
- }
+ //Intentional Fallthrough
case TransformType.COLOR_TRANSFORM: {
// The two first transforms contains the exact same data, can be combined
- System.err.println("transformType: COLOR_TRANSFORM");
+ if (transformType == TransformType.COLOR_TRANSFORM) {
+ System.err.println("transformType: COLOR_TRANSFORM");
+ }
- int sizeBits = (int) lsbBitReader.readBits(3) + 2;
-// int size = 1 << sizeBits;
-
- // TODO: Understand difference between spec divRoundUp and impl VP8LSubSampleSize
+ byte sizeBits = (byte) (lsbBitReader.readBits(3) + 2);
int blockWidth = subSampleSize(xSize, sizeBits);
int blockHeight = subSampleSize(ySize, sizeBits);
- WritableRaster data = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, blockWidth, blockHeight, blockWidth, 1, new int[] {0}, null);
- readVP8Lossless(data, false);
+ WritableRaster raster =
+ Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, blockWidth, blockHeight, 4 * blockWidth, 4,
+ new int[] {0, 1, 2, 3}, null);
+ readVP8Lossless(raster, false);
- transforms.add(new Transform(transformType, ((DataBufferByte) data.getDataBuffer()).getData()));
+ //Keep data as raster for convenient (x,y) indexing
+ if (transformType == TransformType.PREDICTOR_TRANSFORM) {
+ transforms.add(0, new PredictorTransform(raster, sizeBits));
+ }
+ else {
+ transforms.add(0, new ColorTransform(raster, sizeBits));
+ }
break;
}
case TransformType.SUBTRACT_GREEN: {
System.err.println("transformType: SUBTRACT_GREEN");
// No data here
-
-// addGreenToBlueAndRed();
+ transforms.add(0, new SubtractGreenTransform());
break;
}
case TransformType.COLOR_INDEXING_TRANSFORM: {
@@ -167,41 +152,36 @@ public final class VP8LDecoder {
System.err.println("safeColorTableSize: " + safeColorTableSize);
- int[] colorTable = new int[safeColorTableSize];
+ byte[] colorTable = new byte[safeColorTableSize * 4];
// The color table can be obtained by reading an image,
// without the RIFF header, image size, and transforms,
// assuming a height of one pixel and a width of
// color_table_size. The color table is always
// subtraction-coded to reduce image entropy.
- // TODO: Read *without transforms*, using SUBTRACT_GREEN only!
- readVP8Lossless(asByteRaster(
- Raster.createPackedRaster(
- new DataBufferInt(colorTable, colorTableSize),
- colorTableSize, 1, colorTableSize,
- new int[] {0}, null
- )
- ), false);
+ readVP8Lossless(
+ Raster.createInterleavedRaster(
+ new DataBufferByte(colorTable, colorTableSize * 4),
+ colorTableSize, 1, colorTableSize * 4,
+ 4, new int[] {0, 1, 2, 3}, null)
+ , false);
- // TODO: We may not really need this value...
- // What we need is the number of pixels packed into each green sample (byte)
- int widthBits = colorTableSize > 16 ? 0 :
- colorTableSize > 4 ? 1 :
- colorTableSize > 2 ? 2 : 3;
+
+ //resolve subtraction code
+ for (int i = 4; i < colorTable.length; i++) {
+ colorTable[i] += colorTable[i - 4];
+ }
+
+ // The number of pixels packed into each green sample (byte)
+ byte widthBits = (byte) (colorTableSize > 16 ? 0 :
+ colorTableSize > 4 ? 1 :
+ colorTableSize > 2 ? 2 : 3);
xSize = subSampleSize(xSize, widthBits);
- /*
- // TODO: read ARGB
- int argb = 0;
-
- // Inverse transform
- // TODO: Expand to mutliple pixels?
- argb = colorTable[GREEN(argb)];
- */
-
+ // The colors components are stored in ARGB order at 4*index, 4*index + 1, 4*index + 2, 4*index + 3
// TODO: Can we use this to produce an image with IndexColorModel instead of expanding the values in-memory?
- transforms.add(new Transform(transformType, colorTable));
+ transforms.add(0, new ColorIndexingTransform(colorTable, widthBits));
break;
}
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/ColorIndexingTransform.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/ColorIndexingTransform.java
new file mode 100644
index 00000000..32d16009
--- /dev/null
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/ColorIndexingTransform.java
@@ -0,0 +1,18 @@
+package com.twelvemonkeys.imageio.plugins.webp.lossless.transform;
+
+import java.awt.image.*;
+
+public class ColorIndexingTransform implements Transform {
+
+ private final byte[] colorTable;
+ private final byte bits;
+
+ public ColorIndexingTransform(byte[] colorTable, byte bits) {
+ this.colorTable = colorTable;
+ this.bits = bits;
+ }
+
+ @Override
+ public void applyInverse(WritableRaster raster) {
+ }
+}
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/ColorTransform.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/ColorTransform.java
new file mode 100644
index 00000000..6ecb8e73
--- /dev/null
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/ColorTransform.java
@@ -0,0 +1,17 @@
+package com.twelvemonkeys.imageio.plugins.webp.lossless.transform;
+
+import java.awt.image.*;
+
+public class ColorTransform implements Transform {
+ private final Raster data;
+ private final byte bits;
+
+ public ColorTransform(Raster raster, byte bits) {
+ this.data = raster;
+ this.bits = bits;
+ }
+
+ @Override
+ public void applyInverse(WritableRaster raster) {
+ }
+}
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/PredictorMode.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/PredictorMode.java
similarity index 97%
rename from imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/PredictorMode.java
rename to imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/PredictorMode.java
index 907c4ed2..d3e0bca1 100644
--- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/PredictorMode.java
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/PredictorMode.java
@@ -29,7 +29,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-package com.twelvemonkeys.imageio.plugins.webp.lossless;
+package com.twelvemonkeys.imageio.plugins.webp.lossless.transform;
/**
* PredictorMode.
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/PredictorTransform.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/PredictorTransform.java
new file mode 100644
index 00000000..10d80911
--- /dev/null
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/PredictorTransform.java
@@ -0,0 +1,17 @@
+package com.twelvemonkeys.imageio.plugins.webp.lossless.transform;
+
+import java.awt.image.*;
+
+public class PredictorTransform implements Transform {
+ private final Raster data;
+ private final byte bits;
+
+ public PredictorTransform(Raster raster, byte bits) {
+ this.data = raster;
+ this.bits = bits;
+ }
+
+ @Override
+ public void applyInverse(WritableRaster raster) {
+ }
+}
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/SubtractGreenTransform.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/SubtractGreenTransform.java
new file mode 100644
index 00000000..63a5b982
--- /dev/null
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/SubtractGreenTransform.java
@@ -0,0 +1,11 @@
+package com.twelvemonkeys.imageio.plugins.webp.lossless.transform;
+
+import java.awt.image.*;
+
+public class SubtractGreenTransform implements Transform {
+
+
+ @Override
+ public void applyInverse(WritableRaster raster) {
+ }
+}
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/Transform.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/Transform.java
similarity index 82%
rename from imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/Transform.java
rename to imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/Transform.java
index d4aafa74..98394f1e 100644
--- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/Transform.java
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/Transform.java
@@ -29,27 +29,16 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-package com.twelvemonkeys.imageio.plugins.webp.lossless;
+package com.twelvemonkeys.imageio.plugins.webp.lossless.transform;
+
+import java.awt.image.WritableRaster;
/**
* Transform.
*
* @author Harald Kuhr
*/
-final class Transform {
- final int type;
- final Object data;
+public interface Transform {
- Transform(final int type, final Object data) {
- this.type = type;
- this.data = data;
- }
-
- byte[] getData() {
- return (byte[]) data;
- }
-
- int[] getColorMap() {
- return (int[]) data;
- }
+ void applyInverse(WritableRaster raster);
}
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/TransformType.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/TransformType.java
similarity index 94%
rename from imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/TransformType.java
rename to imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/TransformType.java
index 525a6fa8..18ba23e6 100644
--- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/TransformType.java
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/transform/TransformType.java
@@ -29,7 +29,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-package com.twelvemonkeys.imageio.plugins.webp.lossless;
+package com.twelvemonkeys.imageio.plugins.webp.lossless.transform;
/**
* TransformType.
@@ -37,7 +37,7 @@ package com.twelvemonkeys.imageio.plugins.webp.lossless;
* @author Harald Kuhr
*/
// Hmm.. Why doesn't SUBTRACT_GREEN follow the convention?
-interface TransformType {
+public interface TransformType {
int PREDICTOR_TRANSFORM = 0;
int COLOR_TRANSFORM = 1;
int SUBTRACT_GREEN = 2;