|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package com.sun.imageio.plugins.wbmp; |
|
|
|
import java.awt.Rectangle; |
|
import java.awt.image.BufferedImage; |
|
import java.awt.image.DataBufferByte; |
|
import java.awt.image.MultiPixelPackedSampleModel; |
|
import java.awt.image.Raster; |
|
import java.awt.image.WritableRaster; |
|
|
|
import javax.imageio.IIOException; |
|
import javax.imageio.ImageReader; |
|
import javax.imageio.ImageReadParam; |
|
import javax.imageio.ImageTypeSpecifier; |
|
import javax.imageio.metadata.IIOMetadata; |
|
import javax.imageio.spi.ImageReaderSpi; |
|
import javax.imageio.stream.ImageInputStream; |
|
|
|
import java.io.*; |
|
import java.util.ArrayList; |
|
import java.util.Iterator; |
|
|
|
import com.sun.imageio.plugins.common.I18N; |
|
import com.sun.imageio.plugins.common.ReaderUtil; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public class WBMPImageReader extends ImageReader { |
|
|
|
private ImageInputStream iis = null; |
|
|
|
|
|
private boolean gotHeader = false; |
|
|
|
|
|
private int width; |
|
|
|
|
|
private int height; |
|
|
|
private int wbmpType; |
|
|
|
private WBMPMetadata metadata; |
|
|
|
|
|
|
|
*/ |
|
public WBMPImageReader(ImageReaderSpi originator) { |
|
super(originator); |
|
} |
|
|
|
|
|
public void setInput(Object input, |
|
boolean seekForwardOnly, |
|
boolean ignoreMetadata) { |
|
super.setInput(input, seekForwardOnly, ignoreMetadata); |
|
iis = (ImageInputStream) input; |
|
gotHeader = false; |
|
} |
|
|
|
|
|
public int getNumImages(boolean allowSearch) throws IOException { |
|
if (iis == null) { |
|
throw new IllegalStateException(I18N.getString("GetNumImages0")); |
|
} |
|
if (seekForwardOnly && allowSearch) { |
|
throw new IllegalStateException(I18N.getString("GetNumImages1")); |
|
} |
|
return 1; |
|
} |
|
|
|
public int getWidth(int imageIndex) throws IOException { |
|
checkIndex(imageIndex); |
|
readHeader(); |
|
return width; |
|
} |
|
|
|
public int getHeight(int imageIndex) throws IOException { |
|
checkIndex(imageIndex); |
|
readHeader(); |
|
return height; |
|
} |
|
|
|
public boolean isRandomAccessEasy(int imageIndex) throws IOException { |
|
checkIndex(imageIndex); |
|
return true; |
|
} |
|
|
|
private void checkIndex(int imageIndex) { |
|
if (imageIndex != 0) { |
|
throw new IndexOutOfBoundsException(I18N.getString("WBMPImageReader0")); |
|
} |
|
} |
|
|
|
public void readHeader() throws IOException { |
|
if (gotHeader) |
|
return; |
|
|
|
if (iis == null) { |
|
throw new IllegalStateException("Input source not set!"); |
|
} |
|
|
|
metadata = new WBMPMetadata(); |
|
|
|
wbmpType = iis.readByte(); |
|
byte fixHeaderField = iis.readByte(); |
|
|
|
|
|
if (fixHeaderField != 0 |
|
|| !isValidWbmpType(wbmpType)) |
|
{ |
|
throw new IIOException(I18N.getString("WBMPImageReader2")); |
|
} |
|
|
|
metadata.wbmpType = wbmpType; |
|
|
|
|
|
width = ReaderUtil.readMultiByteInteger(iis); |
|
metadata.width = width; |
|
|
|
|
|
height = ReaderUtil.readMultiByteInteger(iis); |
|
metadata.height = height; |
|
|
|
gotHeader = true; |
|
} |
|
|
|
public Iterator getImageTypes(int imageIndex) |
|
throws IOException { |
|
checkIndex(imageIndex); |
|
readHeader(); |
|
|
|
BufferedImage bi = |
|
new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY); |
|
ArrayList list = new ArrayList(1); |
|
list.add(new ImageTypeSpecifier(bi)); |
|
return list.iterator(); |
|
} |
|
|
|
public ImageReadParam getDefaultReadParam() { |
|
return new ImageReadParam(); |
|
} |
|
|
|
public IIOMetadata getImageMetadata(int imageIndex) |
|
throws IOException { |
|
checkIndex(imageIndex); |
|
if (metadata == null) { |
|
readHeader(); |
|
} |
|
return metadata; |
|
} |
|
|
|
public IIOMetadata getStreamMetadata() throws IOException { |
|
return null; |
|
} |
|
|
|
public BufferedImage read(int imageIndex, ImageReadParam param) |
|
throws IOException { |
|
|
|
if (iis == null) { |
|
throw new IllegalStateException(I18N.getString("WBMPImageReader1")); |
|
} |
|
|
|
checkIndex(imageIndex); |
|
clearAbortRequest(); |
|
processImageStarted(imageIndex); |
|
if (param == null) |
|
param = getDefaultReadParam(); |
|
|
|
|
|
readHeader(); |
|
|
|
Rectangle sourceRegion = new Rectangle(0, 0, 0, 0); |
|
Rectangle destinationRegion = new Rectangle(0, 0, 0, 0); |
|
|
|
computeRegions(param, this.width, this.height, |
|
param.getDestination(), |
|
sourceRegion, |
|
destinationRegion); |
|
|
|
int scaleX = param.getSourceXSubsampling(); |
|
int scaleY = param.getSourceYSubsampling(); |
|
int xOffset = param.getSubsamplingXOffset(); |
|
int yOffset = param.getSubsamplingYOffset(); |
|
|
|
|
|
BufferedImage bi = param.getDestination(); |
|
|
|
if (bi == null) |
|
bi = new BufferedImage(destinationRegion.x + destinationRegion.width, |
|
destinationRegion.y + destinationRegion.height, |
|
BufferedImage.TYPE_BYTE_BINARY); |
|
|
|
boolean noTransform = |
|
destinationRegion.equals(new Rectangle(0, 0, width, height)) && |
|
destinationRegion.equals(new Rectangle(0, 0, bi.getWidth(), bi.getHeight())); |
|
|
|
|
|
WritableRaster tile = bi.getWritableTile(0, 0); |
|
|
|
|
|
MultiPixelPackedSampleModel sm = |
|
(MultiPixelPackedSampleModel)bi.getSampleModel(); |
|
|
|
if (noTransform) { |
|
if (abortRequested()) { |
|
processReadAborted(); |
|
return bi; |
|
} |
|
|
|
|
|
iis.read(((DataBufferByte)tile.getDataBuffer()).getData(), |
|
0, height*sm.getScanlineStride()); |
|
processImageUpdate(bi, |
|
0, 0, |
|
width, height, 1, 1, |
|
new int[]{0}); |
|
processImageProgress(100.0F); |
|
} else { |
|
int len = (this.width + 7) / 8; |
|
byte[] buf = new byte[len]; |
|
byte[] data = ((DataBufferByte)tile.getDataBuffer()).getData(); |
|
int lineStride = sm.getScanlineStride(); |
|
iis.skipBytes(len * sourceRegion.y); |
|
int skipLength = len * (scaleY - 1); |
|
|
|
|
|
int[] srcOff = new int[destinationRegion.width]; |
|
int[] destOff = new int[destinationRegion.width]; |
|
int[] srcPos = new int[destinationRegion.width]; |
|
int[] destPos = new int[destinationRegion.width]; |
|
|
|
for (int i = destinationRegion.x, x = sourceRegion.x, j = 0; |
|
i < destinationRegion.x + destinationRegion.width; |
|
i++, j++, x += scaleX) { |
|
srcPos[j] = x >> 3; |
|
srcOff[j] = 7 - (x & 7); |
|
destPos[j] = i >> 3; |
|
destOff[j] = 7 - (i & 7); |
|
} |
|
|
|
for (int j = 0, y = sourceRegion.y, |
|
k = destinationRegion.y * lineStride; |
|
j < destinationRegion.height; j++, y+=scaleY) { |
|
|
|
if (abortRequested()) |
|
break; |
|
iis.read(buf, 0, len); |
|
for (int i = 0; i < destinationRegion.width; i++) { |
|
|
|
int v = (buf[srcPos[i]] >> srcOff[i]) & 1; |
|
data[k + destPos[i]] |= v << destOff[i]; |
|
} |
|
|
|
k += lineStride; |
|
iis.skipBytes(skipLength); |
|
processImageUpdate(bi, |
|
0, j, |
|
destinationRegion.width, 1, 1, 1, |
|
new int[]{0}); |
|
processImageProgress(100.0F*j/destinationRegion.height); |
|
} |
|
} |
|
|
|
if (abortRequested()) |
|
processReadAborted(); |
|
else |
|
processImageComplete(); |
|
return bi; |
|
} |
|
|
|
public boolean canReadRaster() { |
|
return true; |
|
} |
|
|
|
public Raster readRaster(int imageIndex, |
|
ImageReadParam param) throws IOException { |
|
BufferedImage bi = read(imageIndex, param); |
|
return bi.getData(); |
|
} |
|
|
|
public void reset() { |
|
super.reset(); |
|
iis = null; |
|
gotHeader = false; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
boolean isValidWbmpType(int type) { |
|
return type == 0; |
|
} |
|
} |