diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/WebPImageReader.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/WebPImageReader.java
index a45329ae..021e2f76 100644
--- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/WebPImageReader.java
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/WebPImageReader.java
@@ -428,7 +428,7 @@ final class WebPImageReader extends ImageReaderBase {
}
private void readVP8Lossless(final WritableRaster raster, final ImageReadParam param) throws IOException {
- VP8LDecoder decoder = new VP8LDecoder(imageInput);
+ VP8LDecoder decoder = new VP8LDecoder(imageInput, DEBUG);
decoder.readVP8Lossless(raster, true);
}
@@ -443,7 +443,6 @@ final class WebPImageReader extends ImageReaderBase {
});
if (!frame.decode(raster, param)) {
- // TODO: Does this make any sense? Only happens if frame type is not still (0)
processWarningOccurred("Nothing to decode");
}
}
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 0f7e5f89..bbb40eac 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
@@ -41,7 +41,7 @@ import java.util.ArrayList;
import java.util.List;
import static com.twelvemonkeys.imageio.plugins.webp.RasterUtils.asByteRaster;
-import static java.lang.Math.abs;
+import static java.lang.Math.*;
/**
* VP8LDecoder.
@@ -49,14 +49,13 @@ import static java.lang.Math.abs;
* @author Harald Kuhr
*/
public final class VP8LDecoder {
-
private final ImageInputStream imageInput;
private final LSBBitReader lsbBitReader;
private final List transforms = new ArrayList<>();
private ColorCache colorCache;
- public VP8LDecoder(final ImageInputStream imageInput) {
+ public VP8LDecoder(final ImageInputStream imageInput, final boolean debug) {
this.imageInput = imageInput;
lsbBitReader = new LSBBitReader(imageInput);
}
@@ -275,7 +274,7 @@ public final class VP8LDecoder {
// Clamp the input value between 0 and 255.
private static int clamp(final int a) {
- return a < 0 ? 0 : a > 255 ? 255 : a;
+ return max(0, min(a, 255));
}
private static int clampAddSubtractFull(final int a, final int b, final int c) {
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/Globals.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/Globals.java
index e396655f..ab93943c 100644
--- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/Globals.java
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/Globals.java
@@ -499,8 +499,7 @@ final class Globals {
for (int i = 0; i < vp8DefaultCoefProbs.length; i++)
for (int j = 0; j < vp8DefaultCoefProbs[0].length; j++)
for (int k = 0; k < vp8DefaultCoefProbs[0][0].length; k++)
- for (int l = 0; l < vp8DefaultCoefProbs[0][0][0].length; l++)
- r[i][j][k][l] = vp8DefaultCoefProbs[i][j][k][l];
+ r[i][j][k] = vp8DefaultCoefProbs[i][j][k].clone();
return r;
}
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/LoopFilter.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/LoopFilter.java
index 000a0311..06f610a4 100644
--- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/LoopFilter.java
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/LoopFilter.java
@@ -145,16 +145,6 @@ final class LoopFilter {
return abs(p1 - p0) > threshold || abs(q1 - q0) > threshold;
}
-// public static void loopFilter(VP8Frame frame) {
-// if (frame.getFilterType() == 2) {
-// loopFilterUV(frame);
-// loopFilterY(frame);
-// }
-// else if (frame.getFilterType() == 1) {
-// loopFilterSimple(frame);
-// }
-// }
-
static void loopFilterBlock(final MacroBlock cmb, final MacroBlock lmb, final MacroBlock tmb, int frameType, boolean simpleFilter, int sharpness) {
if (simpleFilter) {
loopFilterSimpleBlock(cmb, lmb, tmb, sharpness);
@@ -165,23 +155,7 @@ final class LoopFilter {
}
}
-
- private static void loopFilterSimple(VP8Frame frame) {
- for (int y = 0; y < frame.getMacroBlockRows(); y++) {
-// frame.fireLFProgressUpdate((100.0f * ((float) (y + 1) / (float) (frame
-// .getMacroBlockRows()))));
- for (int x = 0; x < frame.getMacroBlockCols(); x++) {
- loopFilterSimpleBlock(frame.getMacroBlock(x, y),
- x > 0 ? frame.getMacroBlock(x - 1, y) : null,
- y > 0 ? frame.getMacroBlock(x, y - 1) : null,
- frame.getSharpnessLevel());
- }
- }
- }
-
static void loopFilterSimpleBlock(final MacroBlock cmb, final MacroBlock lmb, final MacroBlock tmb, final int sharpnessLevel) {
- // System.out.println("x: "+x+" y: "+y);
-// MacroBlock bmb = frame.getMacroBlock(x, y); // TODO: Same..?
int loop_filter_level = cmb.getFilterLevel();
if (loop_filter_level != 0) {
int interior_limit = cmb.getFilterLevel();
@@ -277,18 +251,6 @@ final class LoopFilter {
}
}
- private static void loopFilterUV(VP8Frame frame) {
- for (int y = 0; y < frame.getMacroBlockRows(); y++) {
- for (int x = 0; x < frame.getMacroBlockCols(); x++) {
- loopFilterUVBlock(frame.getMacroBlock(x, y),
- x > 0 ? frame.getMacroBlock(x - 1, y) : null,
- y > 0 ? frame.getMacroBlock(x, y - 1) : null,
- frame.getSharpnessLevel(), frame.getFrameType()
- );
- }
- }
- }
-
static void loopFilterUVBlock(final MacroBlock cmb, final MacroBlock lmb, final MacroBlock tmb, final int sharpnessLevel, final int frameType) {
int loop_filter_level = cmb.getFilterLevel();
if (loop_filter_level != 0) {
@@ -407,17 +369,6 @@ final class LoopFilter {
}
}
- private static void loopFilterY(VP8Frame frame) {
- for (int y = 0; y < frame.getMacroBlockRows(); y++) {
- for (int x = 0; x < frame.getMacroBlockCols(); x++) {
- loopFilterYBlock(frame.getMacroBlock(x, y),
- x > 0 ? frame.getMacroBlock(x - 1, y) : null,
- y > 0 ? frame.getMacroBlock(x, y - 1) : null,
- frame.getSharpnessLevel(), frame.getFrameType());
- }
- }
- }
-
static void loopFilterYBlock(final MacroBlock cmb, final MacroBlock lmb, final MacroBlock tmb, final int sharpnessLevel, final int frameType) {
int loop_filter_level = cmb.getFilterLevel();
@@ -587,9 +538,6 @@ final class LoopFilter {
if ((abs(seg.P0 - seg.Q0) * 2 + abs(seg.P1 - seg.Q1) / 2) <= edge_limit) {
common_adjust(true, seg); // use outer taps
}
- else {
- // TODO?
- }
}
private static void subblock_filter(int hev_threshold, // detect high edge variance
@@ -605,9 +553,6 @@ final class LoopFilter {
seg.P1 = s2u(p1 + a);
}
}
- else {
- // TODO?
- }
}
/* Convert pixel value (0 <= v <= 255) to an 8-bit signed number. */
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/SubBlock.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/SubBlock.java
index 4158ece7..8df51a01 100644
--- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/SubBlock.java
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/SubBlock.java
@@ -236,7 +236,6 @@ final class SubBlock {
}
public SubBlock getAbove() {
-
return above;
}
@@ -247,6 +246,7 @@ final class SubBlock {
&& plane == Plane.Y1) {
r = r + "\n " + Globals.getSubBlockModeAsString(mode);
}
+
return r;
}
@@ -260,12 +260,10 @@ final class SubBlock {
}
public int[][] getDiff() {
-
return diff;
}
public SubBlock getLeft() {
-
return left;
}
diff --git a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/VP8Frame.java b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/VP8Frame.java
index 48f05cca..5d56f5f5 100644
--- a/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/VP8Frame.java
+++ b/imageio/imageio-webp/src/main/java/com/twelvemonkeys/imageio/plugins/webp/vp8/VP8Frame.java
@@ -1060,22 +1060,24 @@ public final class VP8Frame {
private final byte[] rgb = new byte[4]; // Allow decoding into RGBA, leaving the alpha out.
private void copyBlock(final MacroBlock macroBlock, final WritableRaster byteRGBRaster, final ImageReadParam param) {
- // TODO: Consider doing YCbCr -> RGB in reader instead, or pass a flag to allow readRaster reading direct YUV/YCbCr values
+ int sourceYSubsampling = param != null ? param.getSourceYSubsampling() : 1;
+ int sourceXSubsampling = param != null ? param.getSourceXSubsampling() : 1;
// We might be copying into a smaller raster
int yStart = macroBlock.getY() * 16;
- int yEnd = Math.min(16, byteRGBRaster.getHeight() - yStart);
+ int yEnd = Math.min(16, byteRGBRaster.getHeight() * sourceYSubsampling - yStart);
int xStart = macroBlock.getX() * 16;
- int xEnd = Math.min(16, byteRGBRaster.getWidth() - xStart);
+ int xEnd = Math.min(16, byteRGBRaster.getWidth() * sourceXSubsampling - xStart);
- for (int y = 0; y < yEnd; y++) {
- for (int x = 0; x < xEnd; x++) {
+ for (int y = 0; y < yEnd; y += sourceYSubsampling) {
+ for (int x = 0; x < xEnd; x += sourceXSubsampling) {
yuv[0] = (byte) macroBlock.getSubBlock(SubBlock.Plane.Y1, x / 4, y / 4).getDest()[x % 4][y % 4];
yuv[1] = (byte) macroBlock.getSubBlock(SubBlock.Plane.U, (x / 2) / 4, (y / 2) / 4).getDest()[(x / 2) % 4][(y / 2) % 4];
yuv[2] = (byte) macroBlock.getSubBlock(SubBlock.Plane.V, (x / 2) / 4, (y / 2) / 4).getDest()[(x / 2) % 4][(y / 2) % 4];
+ // TODO: Consider doing YCbCr -> RGB in reader instead, or pass a flag to allow readRaster reading direct YUV/YCbCr values
convertYCbCr2RGB(yuv, rgb, 0);
- byteRGBRaster.setDataElements(xStart + x, yStart + y, rgb);
+ byteRGBRaster.setDataElements((xStart + x) / sourceXSubsampling, (yStart + y) / sourceYSubsampling, rgb);
}
}
}