From 7ab627a7545a473626921e93bab9a1a87c17900e Mon Sep 17 00:00:00 2001 From: Simon Kammermeier Date: Mon, 29 Aug 2022 18:00:09 +0200 Subject: [PATCH] Setup Huffman Table framework, decode meta groups --- .../plugins/webp/lossless/VP8LDecoder.java | 50 ++++++++++++++++++- .../lossless/huffman/HuffmanCodeGroup.java | 25 ++++++++++ .../webp/lossless/huffman/HuffmanInfo.java | 17 +++++++ .../webp/lossless/huffman/HuffmanTable.java | 16 ++++++ 4 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanCodeGroup.java create mode 100644 imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanInfo.java create mode 100644 imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanTable.java 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 bde0bb5e..08415316 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,8 @@ package com.twelvemonkeys.imageio.plugins.webp.lossless; import com.twelvemonkeys.imageio.plugins.webp.LSBBitReader; +import com.twelvemonkeys.imageio.plugins.webp.lossless.huffman.HuffmanCodeGroup; +import com.twelvemonkeys.imageio.plugins.webp.lossless.huffman.HuffmanInfo; 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; @@ -46,6 +48,8 @@ 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.max; /** * VP8LDecoder. @@ -83,7 +87,7 @@ public final class VP8LDecoder { } // Read Huffman codes - readHuffmanCodes(colorCacheBits, topLevel); + HuffmanInfo huffmanInfo = readHuffmanCodes(xSize, ySize, colorCacheBits, topLevel); ColorCache colorCache = null; @@ -191,8 +195,50 @@ public final class VP8LDecoder { return xSize; } - private void readHuffmanCodes(int colorCacheBits, boolean allowRecursion) { + private HuffmanInfo readHuffmanCodes(int xSize, int ySize, int colorCacheBits, boolean readMetaCodes) + throws IOException { + int huffmanGroupNum = 1; + int huffmanXSize; + int huffmanYSize; + int metaCodeBits = 0; + + WritableRaster huffmanMetaCodes = null; + if (readMetaCodes && lsbBitReader.readBit() == 1) { + //read in meta codes + metaCodeBits = (int) lsbBitReader.readBits(3) + 2; + huffmanXSize = subSampleSize(xSize, metaCodeBits); + huffmanYSize = subSampleSize(ySize, metaCodeBits); + + //Raster with elements as BARG (only the RG components encode the meta group) + WritableRaster packedRaster = Raster.createPackedRaster(DataBuffer.TYPE_INT, huffmanXSize, huffmanYSize, + new int[] {0x0000ff00, 0x000000ff, 0xff000000, 0x00ff0000}, null); + readVP8Lossless(asByteRaster(packedRaster), false); + + int[] data = ((DataBufferInt) packedRaster.getDataBuffer()).getData(); + //Max metaGroup is number of meta groups + int maxCode = Integer.MIN_VALUE; + for (int code : data) { + maxCode = max(maxCode, code & 0xffff); + } + huffmanGroupNum = maxCode + 1; + + /* + New Raster with just RG components exposed as single band allowing simple access of metaGroupIndex with + x,y lookup + */ + huffmanMetaCodes = Raster.createPackedRaster(packedRaster.getDataBuffer(), huffmanXSize, huffmanYSize, + huffmanXSize, new int[] {0xffff}, null); + + } + + HuffmanCodeGroup[] huffmanGroups = new HuffmanCodeGroup[huffmanGroupNum]; + + for (int i = 0; i < huffmanGroups.length; i++) { + huffmanGroups[i] = new HuffmanCodeGroup(lsbBitReader, colorCacheBits); + } + + return new HuffmanInfo(huffmanMetaCodes, metaCodeBits, huffmanGroups); } private static int subSampleSize(final int size, final int samplingBits) { diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanCodeGroup.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanCodeGroup.java new file mode 100644 index 00000000..bc1a629a --- /dev/null +++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanCodeGroup.java @@ -0,0 +1,25 @@ +package com.twelvemonkeys.imageio.plugins.webp.lossless.huffman; + +import com.twelvemonkeys.imageio.plugins.webp.LSBBitReader; + +import java.io.IOException; + +public class HuffmanCodeGroup { + /** + * Used for green, backward reference length and color cache + */ + public final HuffmanTable mainCode; + + public final HuffmanTable redCode; + public final HuffmanTable blueCode; + public final HuffmanTable alphaCode; + public final HuffmanTable distanceCode; + + public HuffmanCodeGroup(LSBBitReader lsbBitReader, int colorCacheBits) throws IOException { + mainCode = new HuffmanTable(lsbBitReader, 256 + 24 + (colorCacheBits > 0 ? 1 << colorCacheBits : 0)); + redCode = new HuffmanTable(lsbBitReader, 256); + blueCode = new HuffmanTable(lsbBitReader, 256); + alphaCode = new HuffmanTable(lsbBitReader, 256); + distanceCode = new HuffmanTable(lsbBitReader, 40); + } +} diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanInfo.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanInfo.java new file mode 100644 index 00000000..c06bc8ed --- /dev/null +++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanInfo.java @@ -0,0 +1,17 @@ +package com.twelvemonkeys.imageio.plugins.webp.lossless.huffman; + +import java.awt.image.*; + +public class HuffmanInfo { + public Raster huffmanMetaCodes; //Raster allows intuitive lookup by x and y + + public int metaCodeBits; + + public HuffmanCodeGroup[] huffmanGroups; + + public HuffmanInfo(Raster huffmanMetaCodes, int metaCodeBits, HuffmanCodeGroup[] huffmanGroups) { + this.huffmanMetaCodes = huffmanMetaCodes; + this.metaCodeBits = metaCodeBits; + this.huffmanGroups = huffmanGroups; + } +} \ No newline at end of file diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanTable.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanTable.java new file mode 100644 index 00000000..ae53ea57 --- /dev/null +++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/lossless/huffman/HuffmanTable.java @@ -0,0 +1,16 @@ +package com.twelvemonkeys.imageio.plugins.webp.lossless.huffman; + +import com.twelvemonkeys.imageio.plugins.webp.LSBBitReader; + +import java.io.IOException; + + +public class HuffmanTable { + + + public HuffmanTable(LSBBitReader lsbBitReader, int alphabetSize) throws IOException { + + } + + +}