#694 BMP: Fixed subsampling for 24 bit/pixel case

This commit is contained in:
Harald Kuhr 2022-08-16 13:56:51 +02:00
parent 4170b393fa
commit a5c52a99b4
2 changed files with 39 additions and 30 deletions

View File

@ -30,22 +30,6 @@
package com.twelvemonkeys.imageio.plugins.bmp; package com.twelvemonkeys.imageio.plugins.bmp;
import com.twelvemonkeys.imageio.ImageReaderBase;
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
import com.twelvemonkeys.imageio.util.IIOUtil;
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
import com.twelvemonkeys.imageio.util.ProgressListenerBase;
import com.twelvemonkeys.io.LittleEndianDataInputStream;
import com.twelvemonkeys.io.enc.DecoderStream;
import com.twelvemonkeys.xml.XMLSerializer;
import javax.imageio.*;
import javax.imageio.event.IIOReadUpdateListener;
import javax.imageio.event.IIOReadWarningListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import java.awt.*; import java.awt.*;
import java.awt.color.ColorSpace; import java.awt.color.ColorSpace;
import java.awt.image.*; import java.awt.image.*;
@ -56,6 +40,27 @@ import java.nio.ByteOrder;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.event.IIOReadUpdateListener;
import javax.imageio.event.IIOReadWarningListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import com.twelvemonkeys.imageio.ImageReaderBase;
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
import com.twelvemonkeys.imageio.util.IIOUtil;
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
import com.twelvemonkeys.imageio.util.ProgressListenerBase;
import com.twelvemonkeys.io.LittleEndianDataInputStream;
import com.twelvemonkeys.io.enc.DecoderStream;
import com.twelvemonkeys.xml.XMLSerializer;
/** /**
* ImageReader for Microsoft Windows Bitmap (BMP) format. * ImageReader for Microsoft Windows Bitmap (BMP) format.
* *
@ -77,7 +82,7 @@ public final class BMPImageReader extends ImageReaderBase {
super(new BMPImageReaderSpi()); super(new BMPImageReaderSpi());
} }
protected BMPImageReader(final ImageReaderSpi pProvider) { BMPImageReader(final ImageReaderSpi pProvider) {
super(pProvider); super(pProvider);
} }
@ -358,14 +363,18 @@ public final class BMPImageReader extends ImageReaderBase {
processImageStarted(imageIndex); processImageStarted(imageIndex);
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
switch (header.getBitCount()) { int bitCount = header.getBitCount();
switch (bitCount) {
case 1: case 1:
case 2: case 2:
case 4: case 4:
case 8: case 8:
case 24: case 24:
byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData(); byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData();
readRowByte(input, height, srcRegion, xSub, ySub, rowDataByte, destRaster, clippedRow, y); int bitsPerSample = bitCount == 24 ? 8 : bitCount;
int samplesPerPixel = bitCount == 24 ? 3 : 1;
readRowByte(input, height, srcRegion, xSub, ySub, bitsPerSample, samplesPerPixel, rowDataByte, destRaster, clippedRow, y);
break; break;
case 16: case 16:
@ -379,7 +388,7 @@ public final class BMPImageReader extends ImageReaderBase {
break; break;
default: default:
throw new AssertionError("Unsupported pixel depth: " + header.getBitCount()); throw new AssertionError("Unsupported pixel depth: " + bitCount);
} }
processImageProgress(100f * y / height); processImageProgress(100f * y / height);
@ -476,6 +485,7 @@ public final class BMPImageReader extends ImageReaderBase {
} }
private void readRowByte(final DataInput input, final int height, final Rectangle srcRegion, final int xSub, final int ySub, private void readRowByte(final DataInput input, final int height, final Rectangle srcRegion, final int xSub, final int ySub,
int bitsPerSample, int samplesPerPixel,
final byte[] rowDataByte, final WritableRaster destChannel, final Raster srcChannel, final int y) throws IOException { final byte[] rowDataByte, final WritableRaster destChannel, final Raster srcChannel, final int y) throws IOException {
// Flip into position? // Flip into position?
int srcY = !header.topDown ? height - 1 - y : y; int srcY = !header.topDown ? height - 1 - y : y;
@ -492,9 +502,7 @@ public final class BMPImageReader extends ImageReaderBase {
// Subsample horizontal // Subsample horizontal
if (xSub != 1) { if (xSub != 1) {
for (int x = 0; x < srcRegion.width / xSub; x++) { IIOUtil.subsampleRow(rowDataByte, srcRegion.x, srcRegion.width, rowDataByte, 0, samplesPerPixel, bitsPerSample, xSub);
rowDataByte[srcRegion.x + x] = rowDataByte[srcRegion.x + x * xSub];
}
} }
destChannel.setDataElements(0, dstY, srcChannel); destChannel.setDataElements(0, dstY, srcChannel);

View File

@ -30,18 +30,19 @@
package com.twelvemonkeys.imageio.plugins.bmp; package com.twelvemonkeys.imageio.plugins.bmp;
import com.twelvemonkeys.imageio.spi.ImageReaderSpiBase; import static com.twelvemonkeys.imageio.util.IIOUtil.lookupProviderByName;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ServiceRegistry;
import javax.imageio.stream.ImageInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.Locale; import java.util.Locale;
import static com.twelvemonkeys.imageio.util.IIOUtil.lookupProviderByName; import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ServiceRegistry;
import javax.imageio.stream.ImageInputStream;
import com.twelvemonkeys.imageio.spi.ImageReaderSpiBase;
/** /**
* BMPImageReaderSpi * BMPImageReaderSpi
@ -116,7 +117,7 @@ public final class BMPImageReaderSpi extends ImageReaderSpiBase {
} }
} }
public ImageReader createReaderInstance(final Object pExtension) throws IOException { public ImageReader createReaderInstance(final Object pExtension) {
return new BMPImageReader(this); return new BMPImageReader(this);
} }