mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 12:05:29 -04:00
Fix source region reading in VP8Frame.
This commit is contained in:
parent
6bac13eb84
commit
c1d4e474f0
@ -304,7 +304,7 @@ final class WebPImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
|
public BufferedImage read(final int imageIndex, final ImageReadParam param) throws IOException {
|
||||||
int width = getWidth(imageIndex);
|
int width = getWidth(imageIndex);
|
||||||
int height = getHeight(imageIndex);
|
int height = getHeight(imageIndex);
|
||||||
BufferedImage destination = getDestination(param, getImageTypes(imageIndex), width, height);
|
BufferedImage destination = getDestination(param, getImageTypes(imageIndex), width, height);
|
||||||
|
@ -35,6 +35,7 @@ import javax.imageio.IIOException;
|
|||||||
import javax.imageio.ImageReadParam;
|
import javax.imageio.ImageReadParam;
|
||||||
import javax.imageio.event.IIOReadProgressListener;
|
import javax.imageio.event.IIOReadProgressListener;
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.image.WritableRaster;
|
import java.awt.image.WritableRaster;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -328,25 +329,24 @@ public final class VP8Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ibc = 0;
|
int ibc = 0;
|
||||||
int num_part = 1 << multiTokenPartition;
|
int parts = 1 << multiTokenPartition;
|
||||||
|
|
||||||
// final boolean filter = getFilterType() > 0 && getFilterLevel() != 0;
|
Rectangle region = param != null && param.getSourceRegion() != null ? param.getSourceRegion() : raster.getBounds();
|
||||||
|
int sourceXSubsampling = param != null ? param.getSourceXSubsampling() : 1;
|
||||||
|
int sourceYSubsampling = param != null ? param.getSourceYSubsampling() : 1;
|
||||||
|
|
||||||
for (int row = 0; row < macroBlockRows; row++) {
|
for (int row = 0; row < macroBlockRows; row++) {
|
||||||
if (num_part > 1) {
|
if (parts > 1) {
|
||||||
tokenBoolDecoder = tokenBoolDecoders.get(ibc);
|
tokenBoolDecoder = tokenBoolDecoders.get(ibc);
|
||||||
tokenBoolDecoder.seek();
|
tokenBoolDecoder.seek();
|
||||||
|
|
||||||
decodeMacroBlockRow(row, raster, param);
|
|
||||||
|
|
||||||
ibc++;
|
ibc++;
|
||||||
if (ibc == num_part) {
|
if (ibc == parts) {
|
||||||
ibc = 0;
|
ibc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
decodeMacroBlockRow(row, raster, param);
|
decodeMacroBlockRow(row, raster, region, sourceXSubsampling, sourceYSubsampling);
|
||||||
}
|
|
||||||
|
|
||||||
fireProgressUpdate(row);
|
fireProgressUpdate(row);
|
||||||
}
|
}
|
||||||
@ -354,7 +354,8 @@ public final class VP8Frame {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decodeMacroBlockRow(final int mbRow, final WritableRaster raster, final ImageReadParam param) throws IOException {
|
private void decodeMacroBlockRow(final int mbRow, final WritableRaster raster, final Rectangle region,
|
||||||
|
final int xSubsampling, final int ySubsampling) throws IOException {
|
||||||
final boolean filter = filterLevel != 0;
|
final boolean filter = filterLevel != 0;
|
||||||
|
|
||||||
MacroBlock left = null;
|
MacroBlock left = null;
|
||||||
@ -372,7 +373,7 @@ public final class VP8Frame {
|
|||||||
LoopFilter.loopFilterBlock(mb, left, top, frameType, simpleFilter, sharpnessLevel);
|
LoopFilter.loopFilterBlock(mb, left, top, frameType, simpleFilter, sharpnessLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyBlock(mb, raster, param);
|
copyBlock(mb, raster, region, xSubsampling, ySubsampling);
|
||||||
|
|
||||||
left = mb;
|
left = mb;
|
||||||
}
|
}
|
||||||
@ -1059,25 +1060,34 @@ public final class VP8Frame {
|
|||||||
private final byte[] yuv = new byte[3];
|
private final byte[] yuv = new byte[3];
|
||||||
private final byte[] rgb = new byte[4]; // Allow decoding into RGBA, leaving the alpha out.
|
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) {
|
private void copyBlock(final MacroBlock macroBlock, final WritableRaster byteRGBRaster,
|
||||||
int sourceYSubsampling = param != null ? param.getSourceYSubsampling() : 1;
|
final Rectangle region, final int xSubsampling, final int ySubsampling) {
|
||||||
int sourceXSubsampling = param != null ? param.getSourceXSubsampling() : 1;
|
|
||||||
|
|
||||||
// We might be copying into a smaller raster
|
// We might be copying into a smaller raster
|
||||||
int yStart = macroBlock.getY() * 16;
|
int yStart = macroBlock.getY() * 16 - region.y;
|
||||||
int yEnd = Math.min(16, byteRGBRaster.getHeight() * sourceYSubsampling - yStart);
|
int yEnd = Math.min(16, byteRGBRaster.getHeight() * ySubsampling - yStart);
|
||||||
int xStart = macroBlock.getX() * 16;
|
int xStart = macroBlock.getX() * 16 - region.x;
|
||||||
int xEnd = Math.min(16, byteRGBRaster.getWidth() * sourceXSubsampling - xStart);
|
int xEnd = Math.min(16, byteRGBRaster.getWidth() * xSubsampling - xStart);
|
||||||
|
|
||||||
|
for (int y = 0; y < yEnd; y += ySubsampling) {
|
||||||
|
int dstY = (yStart + y) / ySubsampling;
|
||||||
|
if (dstY < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = 0; x < xEnd; x += xSubsampling) {
|
||||||
|
int dstX = (xStart + x) / xSubsampling;
|
||||||
|
if (dstX < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
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[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[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];
|
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
|
// TODO: Consider doing YCbCr -> RGB in reader instead, or pass a flag to allow readRaster reading direct YUV/YCbCr values
|
||||||
convertYCbCr2RGB(yuv, rgb, 0);
|
convertYCbCr2RGB(yuv, rgb, 0);
|
||||||
byteRGBRaster.setDataElements((xStart + x) / sourceXSubsampling, (yStart + y) / sourceYSubsampling, rgb);
|
byteRGBRaster.setDataElements(dstX, dstY, rgb);
|
||||||
|
// byteRGBRaster.setDataElements(dstX, dstY, yuv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user