#619: Fix WebP Y'CbCr->RGB conversion (now uses rec 601)

This commit is contained in:
Harald Kuhr
2021-08-26 16:47:51 +02:00
parent 6daca00fcd
commit 976e5d6210
9 changed files with 120 additions and 63 deletions
@@ -86,15 +86,7 @@ final class WebPImageReader extends ImageReaderBase {
@Override
public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
// TODO: Figure out why this makes the reader order of magnitudes faster (2-3x?)
// ...or, how to make VP8 decoder make longer reads/make a better FileImageInputStream...
super.setInput(input, seekForwardOnly, ignoreMetadata);
// try {
// super.setInput(new BufferedImageInputStream((ImageInputStream) input), seekForwardOnly, ignoreMetadata);
// }
// catch (IOException e) {
// throw new IOError(e);
// }
lsbBitReader = new LSBBitReader(imageInput);
}
@@ -344,7 +336,7 @@ final class WebPImageReader extends ImageReaderBase {
int reserved = (int) imageInput.readBits(2);
if (reserved != 0) {
// Spec says SHOULD be 0
throw new IIOException(String.format("Unexpected 'ALPH' chunk reserved value, expected 0: %d", reserved));
processWarningOccurred(String.format("Unexpected 'ALPH' chunk reserved value, expected 0: %d", reserved));
}
int preProcessing = (int) imageInput.readBits(2);
@@ -384,6 +376,9 @@ final class WebPImageReader extends ImageReaderBase {
case WebP.CHUNK_ICCP:
// Ignore, we already read this
case WebP.CHUNK_EXIF:
case WebP.CHUNK_XMP_:
// Ignore, we'll read this later
break;
case WebP.CHUNK_ANIM:
@@ -259,12 +259,7 @@ public final class VP8LDecoder {
abs(pGreen - GREEN(T)) + abs(pBlue - BLUE(T));
// Return either left or top, the one closer to the prediction.
if (pL < pT) {
return L;
}
else {
return T;
}
return pL < pT ? L : T;
}
private static int average2(final int a, final int b) {
@@ -42,7 +42,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static com.twelvemonkeys.imageio.color.YCbCrConverter.convertYCbCr2RGB;
import static com.twelvemonkeys.imageio.color.YCbCrConverter.convertRec601YCbCr2RGB;
public final class VP8Frame {
private static final int BLOCK_TYPES = 4;
@@ -54,8 +54,6 @@ public final class VP8Frame {
private IIOReadProgressListener listener = null;
// private int bufferCount;
// private int buffersToCreate = 1;
private final int[][][][] coefProbs;
private int filterLevel;
@@ -117,7 +115,6 @@ public final class VP8Frame {
int c = frame.readUnsignedByte();
frameType = getBitAsInt(c, 0);
// logger.log("Frame type: " + frameType);
if (frameType != 0) {
return false;
@@ -478,7 +475,6 @@ public final class VP8Frame {
}
public BufferedImage getDebugImageDiff() {
BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
WritableRaster imRas = bi.getWritableTile(0, 0);
for (int x = 0; x < getWidth(); x++) {
@@ -1037,12 +1033,12 @@ public final class VP8Frame {
int num_part = 1 << multiTokenPartition;
if (num_part > 1) {
partition += 3 * (num_part - 1);
partition += 3L * (num_part - 1);
}
for (int i = 0; i < num_part; i++) {
// Calculate the length of this partition. The last partition size is implicit.
if (i < num_part - 1) {
partitionSize = readPartitionSize(partitionsStart + (i * 3));
partitionSize = readPartitionSize(partitionsStart + (i * 3L));
bc.seek();
}
else {
@@ -1084,9 +1080,8 @@ public final class VP8Frame {
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);
convertRec601YCbCr2RGB(yuv, rgb, 0);
byteRGBRaster.setDataElements(dstX, dstY, rgb);
// byteRGBRaster.setDataElements(dstX, dstY, yuv);
}
}
}